/* GStreamer IMX video compositor plugin
 * Copyright (c) 2015-2016, Freescale Semiconductor, Inc. All rights reserved.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <string.h>
#include <gst/allocators/gstphymemmeta.h>
#include <gst/allocators/gstdmabuf.h>
#ifdef USE_ION
#include <gst/allocators/gstionmemory.h>
#endif
#include "gstimxcompositorpad.h"
#include "gstimxcompositor.h"
#include "imx_2d_device.h"

#define ENABLE_OBSCURED_CHECKING

#define DEFAULT_IMXCOMPOSITOR_PAD_XPOS   0
#define DEFAULT_IMXCOMPOSITOR_PAD_YPOS   0
#define DEFAULT_IMXCOMPOSITOR_PAD_WIDTH  0
#define DEFAULT_IMXCOMPOSITOR_PAD_HEIGHT 0
#define DEFAULT_IMXCOMPOSITOR_PAD_ROTATE IMX_2D_ROTATION_0
#define DEFAULT_IMXCOMPOSITOR_PAD_ALPHA  1.0
#define DEFAULT_IMXCOMPOSITOR_PAD_KEEP_RATIO  FALSE
#define SINK_TEMP_BUFFER_INIT_SIZE              (1920*1088*2)

GST_DEBUG_CATEGORY_EXTERN (gst_imxcompositor_debug);

GType gst_imx_compositor_rotation_get_type(void) {
  static GType gst_imx_compositor_rotation_type = 0;

  if (!gst_imx_compositor_rotation_type) {
    static GEnumValue rotation_values[] = {
      {IMX_2D_ROTATION_0, "No rotation", "none"},
      {IMX_2D_ROTATION_90, "Rotate 90 degrees", "rotate-90"},
      {IMX_2D_ROTATION_180, "Rotate 180 degrees", "rotate-180"},
      {IMX_2D_ROTATION_270, "Rotate 270 degrees", "rotate-270"},
      {IMX_2D_ROTATION_HFLIP, "Flip horizontally", "horizontal-flip"},
      {IMX_2D_ROTATION_VFLIP, "Flip vertically", "vertical-flip"},
      {0, NULL, NULL },
    };

    gst_imx_compositor_rotation_type =
        g_enum_register_static("ImxCompositorRotationMode", rotation_values);
  }

  return gst_imx_compositor_rotation_type;
}

enum
{
  PROP_IMXCOMPOSITOR_PAD_0,
  PROP_IMXCOMPOSITOR_PAD_XPOS,
  PROP_IMXCOMPOSITOR_PAD_YPOS,
  PROP_IMXCOMPOSITOR_PAD_WIDTH,
  PROP_IMXCOMPOSITOR_PAD_HEIGHT,
  PROP_IMXCOMPOSITOR_PAD_ALPHA,
  PROP_IMXCOMPOSITOR_PAD_ROTATE,
  PROP_IMXCOMPOSITOR_PAD_DEINTERLACE,
  PROP_IMXCOMPOSITOR_PAD_KEEP_RATIO
};

G_DEFINE_TYPE (GstImxCompositorPad, gst_imxcompositor_pad, \
                GST_TYPE_VIDEO_AGGREGATOR_PAD);

static void
gst_imxcompositor_pad_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec)
{
  GstImxCompositorPad *pad = GST_IMXCOMPOSITOR_PAD (object);

  switch (prop_id) {
    case PROP_IMXCOMPOSITOR_PAD_XPOS:
      g_value_set_int (value, pad->xpos);
      break;
    case PROP_IMXCOMPOSITOR_PAD_YPOS:
      g_value_set_int (value, pad->ypos);
      break;
    case PROP_IMXCOMPOSITOR_PAD_WIDTH:
      g_value_set_int (value, pad->width);
      break;
    case PROP_IMXCOMPOSITOR_PAD_HEIGHT:
      g_value_set_int (value, pad->height);
      break;
    case PROP_IMXCOMPOSITOR_PAD_ROTATE:
      g_value_set_enum (value, pad->rotate);
      break;
    case PROP_IMXCOMPOSITOR_PAD_ALPHA:
    {
      GstImxCompositor* comp = (GstImxCompositor*)gst_pad_get_parent(pad);
      if (comp->capabilities & IMX_2D_DEVICE_CAP_ALPHA) {
        g_value_set_double (value, pad->alpha);
      } else {
        g_value_set_double (value, 1.0);
        g_print("!This device don't support alpha blending!\n");
      }
    }
      break;
    case PROP_IMXCOMPOSITOR_PAD_KEEP_RATIO:
      g_value_set_boolean(value, pad->keep_ratio);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static void
gst_imxcompositor_pad_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec)
{
  GstImxCompositorPad *pad = GST_IMXCOMPOSITOR_PAD (object);

  switch (prop_id) {
    case PROP_IMXCOMPOSITOR_PAD_XPOS:
      pad->xpos = g_value_get_int (value);
      break;
    case PROP_IMXCOMPOSITOR_PAD_YPOS:
      pad->ypos = g_value_get_int (value);
      break;
    case PROP_IMXCOMPOSITOR_PAD_ALPHA:
    {
      GstImxCompositor* comp = (GstImxCompositor*)gst_pad_get_parent(pad);
      if (comp->capabilities & IMX_2D_DEVICE_CAP_ALPHA) {
        pad->alpha = g_value_get_double (value);
      } else {
        pad->alpha = 1.0;
        g_print("!This device don't support alpha blending, "
            "pad alpha setting will be ignored!\n");
      }
      gst_object_unref(comp);
    }
      break;
    case PROP_IMXCOMPOSITOR_PAD_WIDTH:
      pad->width = g_value_get_int (value);
      break;
    case PROP_IMXCOMPOSITOR_PAD_HEIGHT:
      pad->height = g_value_get_int (value);
      break;
    case PROP_IMXCOMPOSITOR_PAD_ROTATE:
      pad->rotate = g_value_get_enum (value);
      break;
    case PROP_IMXCOMPOSITOR_PAD_KEEP_RATIO:
      pad->keep_ratio = g_value_get_boolean(value);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static void
gst_imxcompositor_pad_finalize (GObject * object)
{
  GstImxCompositorPad *pad = GST_IMXCOMPOSITOR_PAD (object);

  if (pad->sink_tmp_buf) {
    gst_buffer_unref(pad->sink_tmp_buf);
    pad->sink_tmp_buf = NULL;
  }

  if (pad->sink_pool) {
    gst_buffer_pool_set_active (pad->sink_pool, FALSE);
    gst_object_unref (pad->sink_pool);
    pad->sink_pool = NULL;
  }

  G_OBJECT_CLASS (gst_imxcompositor_pad_parent_class)->finalize (object);
}

void
gst_imxcompositor_pad_get_output_size (GstVideoAggregator * vagg,
    GstImxCompositorPad * comp_pad, gint * width, gint * height)
{
  GstVideoAggregatorPad *vagg_pad = GST_VIDEO_AGGREGATOR_PAD (comp_pad);
  gint pad_width, pad_height;
  guint dar_n, dar_d;
  gint v_width, v_height;
  GstVideoCropMeta *in_crop = NULL;

  if (!vagg || !comp_pad || !width || !height)
    return;

  *width = comp_pad->width;
  *height = comp_pad->height;

  if (!vagg_pad->info.finfo || !vagg->info.finfo)
    return;

  v_width = GST_VIDEO_INFO_WIDTH (&vagg_pad->info);
  v_height = GST_VIDEO_INFO_HEIGHT (&vagg_pad->info);

  if (vagg_pad->buffer) {
    in_crop = gst_buffer_get_video_crop_meta(vagg_pad->buffer);
    if (in_crop != NULL) {
      GST_LOG_OBJECT (vagg_pad, "input crop meta: (%d, %d, %d, %d)",
          in_crop->x, in_crop->y, in_crop->width, in_crop->height);
      if ((in_crop->x >= v_width) || (in_crop->y >= v_height)) {
        *width = *height = 0;
        return;
      }

      v_width = MIN(in_crop->width, (v_width - in_crop->x));
      v_height = MIN(in_crop->height, (v_height - in_crop->y));
    }
  }

  pad_width = comp_pad->width <= 0 ? v_width : comp_pad->width;
  pad_height = comp_pad->height <= 0 ? v_height : comp_pad->height;

  gst_video_calculate_display_ratio (&dar_n, &dar_d, pad_width, pad_height,
      GST_VIDEO_INFO_PAR_N (&vagg_pad->info),
      GST_VIDEO_INFO_PAR_D (&vagg_pad->info),
      GST_VIDEO_INFO_PAR_N (&vagg->info), GST_VIDEO_INFO_PAR_D (&vagg->info)
      );

  GST_LOG_OBJECT (comp_pad, "scaling %ux%u by %u/%u (%u/%u / %u/%u)", pad_width,
      pad_height, dar_n, dar_d, GST_VIDEO_INFO_PAR_N (&vagg_pad->info),
      GST_VIDEO_INFO_PAR_D (&vagg_pad->info),
      GST_VIDEO_INFO_PAR_N (&vagg->info), GST_VIDEO_INFO_PAR_D (&vagg->info));

  if (pad_height % dar_n == 0) {
    pad_width = gst_util_uint64_scale_int (pad_height, dar_n, dar_d);
  } else if (pad_width % dar_d == 0) {
    pad_height = gst_util_uint64_scale_int (pad_width, dar_d, dar_n);
  } else {
    pad_width = gst_util_uint64_scale_int (pad_height, dar_n, dar_d);
  }

  *width = pad_width;
  *height = pad_height;
}

static gboolean
gst_imxcompositor_pad_set_info (GstVideoAggregatorPad * pad,
    GstVideoAggregator * vagg G_GNUC_UNUSED,
    GstVideoInfo * current_info, GstVideoInfo * wanted_info)
{
  GstImxCompositor *comp = (GstImxCompositor *)(vagg);
  GstImxCompositorPad *cpad = (GstImxCompositorPad *)(pad);
  gchar *colorimetry, *best_colorimetry;
  const gchar *chroma, *best_chroma;
  gint width, height;

  if (!current_info->finfo)
    return TRUE;

  if (GST_VIDEO_INFO_FORMAT (current_info) == GST_VIDEO_FORMAT_UNKNOWN)
    return TRUE;

  colorimetry = gst_video_colorimetry_to_string (&(current_info->colorimetry));
  chroma = gst_video_chroma_to_string (current_info->chroma_site);

  best_colorimetry =
      gst_video_colorimetry_to_string (&(wanted_info->colorimetry));
  best_chroma = gst_video_chroma_to_string (wanted_info->chroma_site);

  gst_imxcompositor_pad_get_output_size (vagg, cpad, &width, &height);

  if (GST_VIDEO_INFO_FORMAT(wanted_info) != GST_VIDEO_INFO_FORMAT(current_info)
      || g_strcmp0 (colorimetry, best_colorimetry)
      || g_strcmp0 (chroma, best_chroma)
      || width != current_info->width || height != current_info->height) {
    GstVideoInfo tmp_info;

    gst_video_info_set_format (&tmp_info, GST_VIDEO_INFO_FORMAT (wanted_info),
        width, height);
    tmp_info.chroma_site = wanted_info->chroma_site;
    tmp_info.colorimetry = wanted_info->colorimetry;
    tmp_info.par_n = vagg->info.par_n;
    tmp_info.par_d = vagg->info.par_d;
    tmp_info.fps_n = current_info->fps_n;
    tmp_info.fps_d = current_info->fps_d;
    tmp_info.flags = current_info->flags;
    tmp_info.interlace_mode = current_info->interlace_mode;

    GST_DEBUG_OBJECT (pad, "This pad will be converted from %d to %d",
        GST_VIDEO_INFO_FORMAT (current_info),
        GST_VIDEO_INFO_FORMAT (&tmp_info));

    cpad->info = tmp_info;
  } else {
    cpad->info = *current_info;
    GST_DEBUG_OBJECT (pad, "This pad will not need conversion");
  }
  g_free (colorimetry);
  g_free (best_colorimetry);

  return TRUE;
}

static gboolean
is_rectangle_contained (GstVideoRectangle rect1, GstVideoRectangle rect2)
{
  if ((rect2.x <= rect1.x) && (rect2.y <= rect1.y) &&
      ((rect2.x + rect2.w) >= (rect1.x + rect1.w)) &&
      ((rect2.y + rect2.h) >= (rect1.y + rect1.h)))
    return TRUE;
  return FALSE;
}

static GstVideoRectangle
clamp_rectangle (GstVideoRectangle rect, gint outer_width, gint outer_height)
{
  gint x2 = rect.x + rect.w;
  gint y2 = rect.y + rect.h;
  GstVideoRectangle clamped;

  clamped.x = CLAMP (rect.x, 0, outer_width);
  clamped.y = CLAMP (rect.y, 0, outer_height);
  clamped.w = CLAMP (x2, 0, outer_width) - clamped.x;
  clamped.h = CLAMP (y2, 0, outer_height) - clamped.y;

  return clamped;
}

static gboolean
gst_imxcompositor_pad_prepare_frame (GstVideoAggregatorPad * pad,
    GstVideoAggregator * vagg)
{
  GstImxCompositor *imxcomp = (GstImxCompositor *)(vagg);
  GstImxCompositorPad *cpad = (GstImxCompositorPad *)(pad);
  GstVideoFrame *frame;
  gint width, height;
  GstVideoRectangle video_area;
  GstVideoRectangle clamp;
  gint o_width, o_height;
  GstVideoCropMeta *in_crop = NULL;

  if (!pad->buffer)
    return TRUE;

  gst_imxcompositor_pad_get_output_size (vagg, cpad, &width, &height);

  if (cpad->alpha == 0.0) {
    GST_DEBUG_OBJECT (vagg, "Pad has alpha 0.0, not converting frame");
    pad->aggregated_frame = NULL;
    return TRUE;
  }

  cpad->src_crop.x = 0;
  cpad->src_crop.y = 0;
  cpad->src_crop.w = GST_VIDEO_INFO_WIDTH (&pad->info);
  cpad->src_crop.h = GST_VIDEO_INFO_HEIGHT (&pad->info);

  in_crop = gst_buffer_get_video_crop_meta(pad->buffer);
  if (in_crop != NULL) {
    GST_LOG_OBJECT (pad, "input crop meta: (%d, %d, %d, %d)",
        in_crop->x, in_crop->y, in_crop->width, in_crop->height);
    if ((in_crop->x >= cpad->src_crop.w) || (in_crop->y >= cpad->src_crop.h)) {
      pad->aggregated_frame = NULL;
      return TRUE;
    }

    cpad->src_crop.x = in_crop->x;
    cpad->src_crop.y = in_crop->y;
    cpad->src_crop.w = MIN(in_crop->width, (cpad->src_crop.w - in_crop->x));
    cpad->src_crop.h = MIN(in_crop->height, (cpad->src_crop.h - in_crop->y));
  }

  video_area.x = cpad->xpos;
  video_area.y = cpad->ypos;
  video_area.w = width;
  video_area.h = height;

  if (cpad->keep_ratio) {
    GstVideoRectangle s_rect, d_rect, result;
    s_rect.x = s_rect.y = 0;
    s_rect.w = cpad->src_crop.w;
    s_rect.h = cpad->src_crop.h;
    d_rect.x = d_rect.y = 0;
    d_rect.w = width;
    d_rect.h = height;
    if (cpad->rotate == IMX_2D_ROTATION_90 ||
        cpad->rotate == IMX_2D_ROTATION_270) {
      gint tmp = d_rect.w;
      d_rect.w = d_rect.h;
      d_rect.h = tmp;
    }

    gst_video_sink_center_rect (s_rect, d_rect, &result, TRUE);

    if (cpad->rotate == IMX_2D_ROTATION_90 ||
        cpad->rotate == IMX_2D_ROTATION_270) {
      video_area.x += result.y;
      video_area.y += result.x;
      video_area.w = result.h;
      video_area.h = result.w;
    } else {
      video_area.x += result.x;
      video_area.y += result.y;
      video_area.w = result.w;
      video_area.h = result.h;
    }
  }

  o_width = GST_VIDEO_INFO_WIDTH (&vagg->info);
  o_height = GST_VIDEO_INFO_HEIGHT (&vagg->info);
  clamp = clamp_rectangle (video_area, o_width, o_height);

  if (clamp.w == 0 || clamp.h == 0) {
    GST_DEBUG_OBJECT (vagg, "Resulting frame is zero-width or zero-height "
        "(w: %i, h: %i), skipping", clamp.w, clamp.h);
    pad->aggregated_frame = NULL;
    return TRUE;
  }

  cpad->dst_crop = clamp;
  cpad->src_crop.x = cpad->src_crop.x +
         (cpad->dst_crop.x - video_area.x) * cpad->src_crop.w / video_area.w;
  cpad->src_crop.y = cpad->src_crop.y +
         (cpad->dst_crop.y - video_area.y) * cpad->src_crop.h / video_area.h;
  cpad->src_crop.w = cpad->dst_crop.w * cpad->src_crop.w / video_area.w;
  cpad->src_crop.h = cpad->dst_crop.h * cpad->src_crop.h / video_area.h;

#ifdef ENABLE_OBSCURED_CHECKING
  gboolean frame_obscured = FALSE;
  GList *l;

  GST_OBJECT_LOCK (vagg);
  /* Check if this frame is obscured by a higher-zorder frame */
  for (l = GST_ELEMENT (vagg)->sinkpads; l; l = l->next) {
    GstVideoRectangle frame2_rect;
    GstVideoAggregatorPad *pad2 = l->data;
    GstImxCompositorPad *cpad2 = (GstImxCompositorPad *)(pad2);
    gint pad2_width, pad2_height;

    if (pad2->zorder > pad->zorder && pad2->buffer && cpad2->alpha == 1.0 &&
        !GST_VIDEO_INFO_HAS_ALPHA (&pad2->info)) {
      gst_imxcompositor_pad_get_output_size (vagg, cpad2,
                                              &pad2_width, &pad2_height);

      frame2_rect.x = cpad2->xpos;
      frame2_rect.y = cpad2->ypos;
      frame2_rect.w = pad2_width;
      frame2_rect.h = pad2_height;

      if (is_rectangle_contained (clamp, frame2_rect)) {
        frame_obscured = TRUE;
        GST_DEBUG_OBJECT (pad, "%ix%i@(%i,%i) obscured by %s %ix%i@(%i,%i) "
            "in output of size %ix%i; skipping frame", clamp.w, clamp.h,
            clamp.x, clamp.y, GST_PAD_NAME (pad2), frame2_rect.w,
            frame2_rect.h, frame2_rect.x, frame2_rect.y, o_width, o_height);
        break;
      }
    }
  }
  GST_OBJECT_UNLOCK (vagg);

  if (frame_obscured) {
    pad->aggregated_frame = NULL;
    return TRUE;
  }
#endif

  frame = g_slice_new0 (GstVideoFrame);

  if (!gst_video_frame_map (frame, &pad->buffer_vinfo, pad->buffer,
          GST_MAP_READ)) {
    GST_WARNING_OBJECT (vagg, "Could not map input buffer");
    g_slice_free (GstVideoFrame, frame);
    return FALSE;
  }

  /* Check if need copy input frame */
  if (!(gst_buffer_is_phymem(pad->buffer)
        || gst_is_dmabuf_memory (gst_buffer_peek_memory (pad->buffer, 0)))) {
    GST_DEBUG_OBJECT (pad, "copy input frame to physical continues memory");
    GstVideoInfo info;
    GstCaps *caps = gst_video_info_to_caps(&frame->info);
    gst_video_info_from_caps(&info, caps); //update the size info
    gst_caps_unref(caps);

    if (!imxcomp->allocator) {
#ifdef USE_ION
      imxcomp->allocator = gst_ion_allocator_obtain ();
#endif
    }

    if (!imxcomp->allocator)
      imxcomp->allocator =
          gst_imx_2d_device_allocator_new((gpointer)(imxcomp->device));

    if (!cpad->sink_tmp_buf) {
      cpad->sink_tmp_buf = gst_buffer_new_allocate(imxcomp->allocator,
          SINK_TEMP_BUFFER_INIT_SIZE, NULL);
      cpad->sink_tmp_buf_size = SINK_TEMP_BUFFER_INIT_SIZE;
    }

    if (cpad->sink_tmp_buf && info.size > SINK_TEMP_BUFFER_INIT_SIZE) {
      if (cpad->sink_tmp_buf)
        gst_buffer_unref(cpad->sink_tmp_buf);
      cpad->sink_tmp_buf = gst_buffer_new_allocate(imxcomp->allocator,
          info.size, NULL);
      cpad->sink_tmp_buf_size = info.size;
    }

    if (cpad->sink_tmp_buf) {
      GstVideoFrame *copy_frame = g_slice_new0 (GstVideoFrame);
      gst_video_frame_map(copy_frame, &info, cpad->sink_tmp_buf, GST_MAP_WRITE);
      gst_video_frame_copy(copy_frame, frame);
      gst_video_frame_unmap (frame);
      g_slice_free (GstVideoFrame, frame);
      frame = copy_frame;

      if (imxcomp->composition_meta_enable
              && imx_video_overlay_composition_has_meta(pad->buffer)) {
        imx_video_overlay_composition_remove_meta(cpad->sink_tmp_buf);
        imx_video_overlay_composition_copy_meta(cpad->sink_tmp_buf, pad->buffer,
            frame->info.width, frame->info.height,
            frame->info.width, frame->info.height);
      }
    } else {
      GST_ERROR_OBJECT (pad,
          "Can't get input buffer,ignore this frame,continue next");
      gst_video_frame_unmap (frame);
      g_slice_free (GstVideoFrame, frame);
      pad->aggregated_frame = NULL;
      return TRUE;
    }
  }

  if (cpad->sink_pool_update) {
    memset (&cpad->align, 0, sizeof(GstVideoAlignment));
    if (cpad->sink_pool && gst_buffer_pool_is_active (cpad->sink_pool)) {
      GstStructure *config = gst_buffer_pool_get_config (cpad->sink_pool);

      if (gst_buffer_pool_config_has_option (config,
          GST_BUFFER_POOL_OPTION_VIDEO_ALIGNMENT)) {
        gst_buffer_pool_config_get_video_alignment (config, &cpad->align);
        GST_DEBUG_OBJECT (pad, "input pool has alignment (%d, %d) , (%d, %d)",
            cpad->align.padding_left, cpad->align.padding_top,
            cpad->align.padding_right, cpad->align.padding_bottom);
      }
      gst_structure_free (config);
    } else {
      GstPhyMemMeta *phymemmeta = GST_PHY_MEM_META_GET (pad->buffer);
      if (phymemmeta) {
        cpad->align.padding_right = phymemmeta->x_padding;
        cpad->align.padding_bottom = phymemmeta->y_padding;
        GST_DEBUG_OBJECT (pad, "physical memory meta x_padding: %d "
            "y_padding: %d",phymemmeta->x_padding, phymemmeta->y_padding);
      }
    }
    cpad->sink_pool_update = FALSE;
  }

  GstSegment *seg = &((GstAggregatorPad*)pad)->segment;
  GstClockTime timestamp = GST_BUFFER_TIMESTAMP (pad->buffer);
  gint64 stream_time =
      gst_segment_to_stream_time (seg, GST_FORMAT_TIME, timestamp);
  /* sync object properties on stream time */
  if (GST_CLOCK_TIME_IS_VALID (stream_time))
    gst_object_sync_values (GST_OBJECT (pad), stream_time);

  pad->aggregated_frame = frame;

  return TRUE;
}

static void
gst_imxcompositor_pad_clean_frame (GstVideoAggregatorPad * pad,
    GstVideoAggregator * vagg)
{
  if (pad->aggregated_frame) {
    gst_video_frame_unmap (pad->aggregated_frame);
    g_slice_free (GstVideoFrame, pad->aggregated_frame);
    pad->aggregated_frame = NULL;
  }
}

static void
gst_imxcompositor_pad_class_init (GstImxCompositorPadClass * klass)
{
  GObjectClass *gobject_class = (GObjectClass *) klass;
  GstVideoAggregatorPadClass *vaggpadclass =
      (GstVideoAggregatorPadClass *) klass;

  gobject_class->set_property = gst_imxcompositor_pad_set_property;
  gobject_class->get_property = gst_imxcompositor_pad_get_property;
  gobject_class->finalize = gst_imxcompositor_pad_finalize;

  g_object_class_install_property (gobject_class, PROP_IMXCOMPOSITOR_PAD_XPOS,
      g_param_spec_int ("xpos", "X Position", "X Position of the picture",
          G_MININT32, G_MAXINT32, DEFAULT_IMXCOMPOSITOR_PAD_XPOS,
          G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE | G_PARAM_STATIC_STRINGS));
  g_object_class_install_property (gobject_class, PROP_IMXCOMPOSITOR_PAD_YPOS,
      g_param_spec_int ("ypos", "Y Position", "Y Position of the picture",
          G_MININT32, G_MAXINT32, DEFAULT_IMXCOMPOSITOR_PAD_YPOS,
          G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE | G_PARAM_STATIC_STRINGS));
  g_object_class_install_property (gobject_class, PROP_IMXCOMPOSITOR_PAD_WIDTH,
      g_param_spec_int ("width", "Width", "Target width of the picture",
          G_MININT32, G_MAXINT32, DEFAULT_IMXCOMPOSITOR_PAD_WIDTH,
          G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE | G_PARAM_STATIC_STRINGS));
  g_object_class_install_property (gobject_class, PROP_IMXCOMPOSITOR_PAD_HEIGHT,
      g_param_spec_int ("height", "Height", "Target height of the picture",
          G_MININT32, G_MAXINT32, DEFAULT_IMXCOMPOSITOR_PAD_HEIGHT,
          G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE | G_PARAM_STATIC_STRINGS));
  g_object_class_install_property (gobject_class, PROP_IMXCOMPOSITOR_PAD_ROTATE,
      g_param_spec_enum("rotate", "input rotation",
        "Rotation that shall be applied to input frames",
        gst_imx_compositor_rotation_get_type(),
        DEFAULT_IMXCOMPOSITOR_PAD_ROTATE,
        G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE | G_PARAM_STATIC_STRINGS));
  g_object_class_install_property (gobject_class, PROP_IMXCOMPOSITOR_PAD_ALPHA,
      g_param_spec_double ("alpha", "Alpha", "Alpha of the picture", 0.0, 1.0,
          DEFAULT_IMXCOMPOSITOR_PAD_ALPHA,
          G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE | G_PARAM_STATIC_STRINGS));
  g_object_class_install_property (gobject_class,
      PROP_IMXCOMPOSITOR_PAD_KEEP_RATIO,
      g_param_spec_boolean ("keep-ratio", "Keep Aspect Ratio",
          "Keep the video aspect ratio after resize",
          DEFAULT_IMXCOMPOSITOR_PAD_KEEP_RATIO,
          G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE | G_PARAM_STATIC_STRINGS));

  vaggpadclass->set_info = GST_DEBUG_FUNCPTR (gst_imxcompositor_pad_set_info);
  vaggpadclass->prepare_frame =
      GST_DEBUG_FUNCPTR (gst_imxcompositor_pad_prepare_frame);
  vaggpadclass->clean_frame =
      GST_DEBUG_FUNCPTR (gst_imxcompositor_pad_clean_frame);
}

static void
gst_imxcompositor_pad_init (GstImxCompositorPad * compo_pad)
{
  compo_pad->xpos = DEFAULT_IMXCOMPOSITOR_PAD_XPOS;
  compo_pad->ypos = DEFAULT_IMXCOMPOSITOR_PAD_YPOS;
  compo_pad->width = DEFAULT_IMXCOMPOSITOR_PAD_WIDTH;
  compo_pad->height = DEFAULT_IMXCOMPOSITOR_PAD_HEIGHT;
  compo_pad->rotate = DEFAULT_IMXCOMPOSITOR_PAD_ROTATE;
  compo_pad->alpha = DEFAULT_IMXCOMPOSITOR_PAD_ALPHA;
  compo_pad->keep_ratio = DEFAULT_IMXCOMPOSITOR_PAD_KEEP_RATIO;
  compo_pad->sink_pool = NULL;
  compo_pad->sink_tmp_buf = NULL;
  compo_pad->sink_tmp_buf_size = 0;
  memset(&compo_pad->align, 0, sizeof(GstVideoAlignment));
}
