/* GStreamer IMX video convert plugin
 * Copyright (c) 2014-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 <gst/video/video.h>
#include <gst/allocators/gstdmabuf.h>
#include <gst/allocators/gstallocatorphymem.h>
#ifdef USE_ION
#include <gst/allocators/gstionmemory.h>
#endif
#include <gst/allocators/gstphymemmeta.h>
#include "gstimxvideoconvert.h"

#define IMX_VCT_IN_POOL_MAX_BUFFERS   30

#define GST_IMX_VCT_PARAMS_QDATA   g_quark_from_static_string("imxvct-params")

#define GST_IMX_VIDEO_ROTATION_DEFAULT      IMX_2D_ROTATION_0
#define GST_IMX_VIDEO_DEINTERLACE_DEFAULT   IMX_2D_DEINTERLACE_NONE
#define GST_IMX_VIDEO_COMPOMETA_DEFAULT              FALSE
#define GST_IMX_VIDEO_COMPOMETA_IN_PLACE_DEFAULT     FALSE

#define GST_IMX_CONVERT_UNREF_BUFFER(buffer) {\
    if (buffer) {                             \
      GST_LOG ("unref buffer (%p)", buffer);  \
      gst_buffer_unref(buffer);               \
      buffer = NULL;                          \
    }                                         \
  }

#define GST_IMX_CONVERT_UNREF_POOL(pool)  {   \
    if (pool) {                               \
      GST_LOG ("unref pool (%p)", pool);      \
      gst_buffer_pool_set_active (pool, FALSE);\
      gst_object_unref(pool);                 \
      pool = NULL;                            \
    }                                         \
  }

/* properties utility*/
enum {
  PROP_0,
  PROP_OUTPUT_ROTATE,
  PROP_DEINTERLACE_MODE,
  PROP_COMPOSITION_META_ENABLE,
  PROP_COMPOSITION_META_IN_PLACE
};

static GstElementClass *parent_class = NULL;

GST_DEBUG_CATEGORY (imxvideoconvert_debug);
#define GST_CAT_DEFAULT imxvideoconvert_debug

GType gst_imx_video_convert_rotation_get_type(void) {
  static GType gst_imx_video_convert_rotation_type = 0;

  if (!gst_imx_video_convert_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_video_convert_rotation_type =
        g_enum_register_static("ImxVideoConvertRotationMode", rotation_values);
  }

  return gst_imx_video_convert_rotation_type;
}

GType gst_imx_video_convert_deinterlace_get_type(void) {
  static GType gst_imx_video_convert_deinterlace_type = 0;

  if (!gst_imx_video_convert_deinterlace_type) {
    static GEnumValue deinterlace_values[] = {
      { IMX_2D_DEINTERLACE_NONE, "No deinterlace", "none" },
      { IMX_2D_DEINTERLACE_LOW_MOTION,
          "low-motion deinterlace", "low-motion" },
      { IMX_2D_DEINTERLACE_MID_MOTION,
          "midium-motion deinterlace", "mid-motion" },
      { IMX_2D_DEINTERLACE_HIGH_MOTION,
          "high-motion deinterlace", "high-motion" },
      { 0, NULL, NULL },
    };

    gst_imx_video_convert_deinterlace_type =
        g_enum_register_static("ImxVideoConvertDeinterlaceMode",
                                deinterlace_values);
  }

  return gst_imx_video_convert_deinterlace_type;
}

static void gst_imx_video_convert_set_property (GObject * object,
    guint prop_id, const GValue * value, GParamSpec * pspec)
{
  GstImxVideoConvert *imxvct = (GstImxVideoConvert *) (object);
  Imx2DDevice *device = imxvct->device;

  GST_DEBUG_OBJECT (imxvct, "set_property (%d).", prop_id);

  if (!device)
    return;

  switch (prop_id) {
    case PROP_OUTPUT_ROTATE:
      imxvct->rotate = g_value_get_enum (value);
      break;
    case PROP_DEINTERLACE_MODE:
      imxvct->deinterlace = g_value_get_enum (value);
      break;
    case PROP_COMPOSITION_META_ENABLE:
      imxvct->composition_meta_enable = g_value_get_boolean(value);
      break;
    case PROP_COMPOSITION_META_IN_PLACE:
      imxvct->in_place = g_value_get_boolean(value);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }

  //TODO if property changed, it may affect the passthrough, so we need
  // reconfig the pipeline, send a reconfig event for caps re-negotiation.
}

static void gst_imx_video_convert_get_property (GObject * object,
    guint prop_id, GValue * value, GParamSpec * pspec)
{
  GstImxVideoConvert *imxvct = (GstImxVideoConvert *) (object);
  Imx2DDevice *device = imxvct->device;

  if (!device)
    return;

  switch (prop_id) {
    case PROP_OUTPUT_ROTATE:
      g_value_set_enum (value, imxvct->rotate);
      break;
    case PROP_DEINTERLACE_MODE:
      g_value_set_enum (value, imxvct->deinterlace);
      break;
    case PROP_COMPOSITION_META_ENABLE:
      g_value_set_boolean(value, imxvct->composition_meta_enable);
      break;
    case PROP_COMPOSITION_META_IN_PLACE:
      g_value_set_boolean(value, imxvct->in_place);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static void gst_imx_video_convert_finalize (GObject * object)
{
  GstImxVideoConvert *imxvct = (GstImxVideoConvert *) (object);
  GstStructure *config;
  GstImxVideoConvertClass *klass =
        (GstImxVideoConvertClass *) G_OBJECT_GET_CLASS (imxvct);

  imx_video_overlay_composition_deinit(&imxvct->video_comp);

  GST_IMX_CONVERT_UNREF_BUFFER (imxvct->in_buf);
  GST_IMX_CONVERT_UNREF_POOL (imxvct->in_pool);
  GST_IMX_CONVERT_UNREF_POOL (imxvct->self_out_pool);
  if (imxvct->allocator) {
    gst_object_unref (imxvct->allocator);
    imxvct->allocator = NULL;
  }

  if (imxvct->device) {
    imxvct->device->close(imxvct->device);
    if (klass->in_plugin)
      klass->in_plugin->destroy(imxvct->device);
    imxvct->device = NULL;
  }

  G_OBJECT_CLASS (parent_class)->finalize ((GObject *) (imxvct));
}

static gboolean
imx_video_convert_src_event(GstBaseTransform *transform, GstEvent *event)
{
  gdouble a;
  GstStructure *structure;
  GstVideoFilter *filter = GST_VIDEO_FILTER_CAST(transform);

  GST_TRACE("%s event", GST_EVENT_TYPE_NAME(event));

  switch (GST_EVENT_TYPE(event)) {
    case GST_EVENT_NAVIGATION:
      if ((filter->in_info.width != filter->out_info.width) ||
          (filter->in_info.height != filter->out_info.height)) {
        event =
            GST_EVENT(gst_mini_object_make_writable(GST_MINI_OBJECT(event)));

        structure = (GstStructure *)gst_event_get_structure(event);
        if (gst_structure_get_double(structure, "pointer_x", &a)) {
          gst_structure_set(
            structure, "pointer_x", G_TYPE_DOUBLE,
            a * filter->in_info.width / filter->out_info.width,
            NULL
          );
        }

        if (gst_structure_get_double(structure, "pointer_y", &a)) {
          gst_structure_set(
            structure, "pointer_y", G_TYPE_DOUBLE,
            a * filter->in_info.height / filter->out_info.height,
            NULL
          );
        }
      }
      break;
    default:
      break;
  }

  return GST_BASE_TRANSFORM_CLASS(parent_class)->src_event(transform, event);
}

static GstCaps* imx_video_convert_transform_caps(GstBaseTransform *transform,
                     GstPadDirection direction, GstCaps *caps, GstCaps *filter)
{
  GstCaps *tmp, *tmp2, *result;
  GstStructure *st;
  gint i, n;

  GST_DEBUG("transform caps: %" GST_PTR_FORMAT, caps);
  GST_DEBUG("filter: %" GST_PTR_FORMAT, filter);
  GST_DEBUG("direction: %d", direction);

  /* Get all possible caps that we can transform to */
  /* copies the given caps */
  tmp = gst_caps_new_empty();
  n = gst_caps_get_size(caps);

  for (i = 0; i < n; i++) {
    st = gst_caps_get_structure(caps, i);

    if ((i > 0) && gst_caps_is_subset_structure(tmp, st))
      continue;

    st = gst_structure_copy(st);

    gst_structure_set(st, "width", GST_TYPE_INT_RANGE, 64, G_MAXINT32,
                          "height", GST_TYPE_INT_RANGE, 64, G_MAXINT32, NULL);

    gst_structure_remove_fields(st, "format", NULL);

    /* if pixel aspect ratio, make a range of it*/
    if (gst_structure_has_field(st, "pixel-aspect-ratio")) {
      gst_structure_set(st, "pixel-aspect-ratio",
          GST_TYPE_FRACTION_RANGE, 1, G_MAXINT32, G_MAXINT32, 1, NULL);
    }

    gst_caps_append_structure(tmp, st);
  }

  GstImxVideoConvert *imxvct = (GstImxVideoConvert *) (transform);

  imx_video_overlay_composition_add_caps(tmp);

  GST_DEBUG("transformed: %" GST_PTR_FORMAT, tmp);

  if (filter) {
    tmp2 = gst_caps_intersect_full(filter, tmp, GST_CAPS_INTERSECT_FIRST);
    gst_caps_unref(tmp);
    tmp = tmp2;
  }

  result = tmp;

  GST_DEBUG("return caps: %" GST_PTR_FORMAT, result);

  return result;
}

#ifdef COMPARE_CONVERT_LOSS
/* calculate how much loss a conversion would be */
/* This loss calculation comes from gstvideoconvert.c of base plugins */
static gint get_format_conversion_loss(GstBaseTransform * base,
                                       GstVideoFormat in_name,
                                       GstVideoFormat out_name)
{
#define SCORE_FORMAT_CHANGE       1
#define SCORE_DEPTH_CHANGE        1
#define SCORE_ALPHA_CHANGE        1
#define SCORE_CHROMA_W_CHANGE     1
#define SCORE_CHROMA_H_CHANGE     1
#define SCORE_PALETTE_CHANGE      1

#define SCORE_COLORSPACE_LOSS     2     /* RGB <-> YUV */
#define SCORE_DEPTH_LOSS          4     /* change bit depth */
#define SCORE_ALPHA_LOSS          8     /* lose the alpha channel */
#define SCORE_CHROMA_W_LOSS      16     /* vertical sub-sample */
#define SCORE_CHROMA_H_LOSS      32     /* horizontal sub-sample */
#define SCORE_PALETTE_LOSS       64     /* convert to palette format */
#define SCORE_COLOR_LOSS        128     /* convert to GRAY */

#define COLORSPACE_MASK (GST_VIDEO_FORMAT_FLAG_YUV | \
                         GST_VIDEO_FORMAT_FLAG_RGB | GST_VIDEO_FORMAT_FLAG_GRAY)
#define ALPHA_MASK      (GST_VIDEO_FORMAT_FLAG_ALPHA)
#define PALETTE_MASK    (GST_VIDEO_FORMAT_FLAG_PALETTE)

  gint loss = G_MAXINT32;
  GstVideoFormatFlags in_flags, out_flags;
  const GstVideoFormatInfo *in_info = gst_video_format_get_info(in_name);
  const GstVideoFormatInfo *out_info = gst_video_format_get_info(out_name);

  if (!in_info || !out_info)
    return G_MAXINT32;

  /* accept input format immediately without loss */
  if (in_info == out_info) {
    GST_LOG("same format %s", GST_VIDEO_FORMAT_INFO_NAME(in_info));
    return 0;
  }

  loss = SCORE_FORMAT_CHANGE;

  in_flags = GST_VIDEO_FORMAT_INFO_FLAGS (in_info);
  in_flags &= ~GST_VIDEO_FORMAT_FLAG_LE;
  in_flags &= ~GST_VIDEO_FORMAT_FLAG_COMPLEX;
  in_flags &= ~GST_VIDEO_FORMAT_FLAG_UNPACK;

  out_flags = GST_VIDEO_FORMAT_INFO_FLAGS (out_info);
  out_flags &= ~GST_VIDEO_FORMAT_FLAG_LE;
  out_flags &= ~GST_VIDEO_FORMAT_FLAG_COMPLEX;
  out_flags &= ~GST_VIDEO_FORMAT_FLAG_UNPACK;

  if ((out_flags & PALETTE_MASK) != (in_flags & PALETTE_MASK)) {
    loss += SCORE_PALETTE_CHANGE;
    if (out_flags & PALETTE_MASK)
      loss += SCORE_PALETTE_LOSS;
  }

  if ((out_flags & COLORSPACE_MASK) != (in_flags & COLORSPACE_MASK)) {
    loss += SCORE_COLORSPACE_LOSS;
    if (out_flags & GST_VIDEO_FORMAT_FLAG_GRAY)
      loss += SCORE_COLOR_LOSS;
  }

  if ((out_flags & ALPHA_MASK) != (in_flags & ALPHA_MASK)) {
    loss += SCORE_ALPHA_CHANGE;
    if (in_flags & ALPHA_MASK)
      loss += SCORE_ALPHA_LOSS;
  }

  if ((in_info->h_sub[1]) != (out_info->h_sub[1])) {
    loss += SCORE_CHROMA_H_CHANGE;
    if ((in_info->h_sub[1]) < (out_info->h_sub[1]))
      loss += SCORE_CHROMA_H_LOSS;
  }
  if ((in_info->w_sub[1]) != (out_info->w_sub[1])) {
    loss += SCORE_CHROMA_W_CHANGE;
    if ((in_info->w_sub[1]) < (out_info->w_sub[1]))
      loss += SCORE_CHROMA_W_LOSS;
  }

  if ((in_info->bits) != (out_info->bits)) {
    loss += SCORE_DEPTH_CHANGE;
    if ((in_info->bits) > (out_info->bits))
      loss += SCORE_DEPTH_LOSS;
  }

  GST_LOG("%s -> %s, loss = %d", GST_VIDEO_FORMAT_INFO_NAME(in_info),
                  GST_VIDEO_FORMAT_INFO_NAME(out_info), loss);
  return loss;
}
#endif

static GstCaps* imx_video_convert_caps_from_fmt_list(GList* list)
{
  gint i;
  GstCaps *caps = NULL;

  for (i=0; i<g_list_length (list); i++) {
    GstVideoFormat fmt = (GstVideoFormat)g_list_nth_data(list, i);

    if (caps) {
      GstCaps *newcaps = gst_caps_new_simple("video/x-raw",
          "format", G_TYPE_STRING, gst_video_format_to_string(fmt), NULL);
      gst_caps_append (caps, newcaps);
    } else {
      caps = gst_caps_new_simple("video/x-raw",
          "format", G_TYPE_STRING, gst_video_format_to_string(fmt), NULL);
    }
  }

  caps = gst_caps_simplify(caps);

  imx_video_overlay_composition_add_caps(caps);

  return caps;
}

static guint imx_video_convert_fixate_format_caps(GstBaseTransform *transform,
                                            GstCaps *caps, GstCaps *othercaps)
{
  GstStructure *outs;
  GstStructure *tests;
  const GValue *format;
  GstVideoFormat out_fmt = GST_VIDEO_FORMAT_UNKNOWN;
  const GstVideoFormatInfo *out_info = NULL;
  const gchar *fmt_name;
  GstStructure *ins;
  const gchar *in_interlace;
  gboolean interlace = FALSE;
  GstCaps *new_caps;

  GstImxVideoConvert *imxvct = (GstImxVideoConvert *)(transform);
  Imx2DDevice *device = imxvct->device;

  //the input caps should fixed alreay, and only have caps0
  ins = gst_caps_get_structure(caps, 0);
  outs = gst_caps_get_structure(othercaps, 0);

  in_interlace = gst_structure_get_string(ins, "interlace-mode");
  if (in_interlace && (g_strcmp0(in_interlace, "interleaved") == 0
                       || g_strcmp0(in_interlace, "mixed") == 0)) {
    interlace = TRUE;
  }

  /* if rotate or deinterlace enabled & interleaved input,
   * then passthrough is not possible, we need limit the othercaps
   * with device conversion limitation
   */
  if (imxvct->rotate != IMX_2D_ROTATION_0 ||
      (imxvct->deinterlace != IMX_2D_DEINTERLACE_NONE && interlace)) {
    GList* list = device->get_supported_out_fmts(device);
    GstCaps *out_caps = imx_video_convert_caps_from_fmt_list(list);
    g_list_free(list);

    new_caps = gst_caps_intersect_full(othercaps, out_caps,
                                       GST_CAPS_INTERSECT_FIRST);
    gst_caps_unref(out_caps);
  } else {
    new_caps = gst_caps_copy(othercaps);
  }

#ifdef COMPARE_CONVERT_LOSS
  GstVideoFormat in_fmt;
  gint min_loss = G_MAXINT32;
  gint loss;
  guint i, j;

  fmt_name = gst_structure_get_string(ins, "format");
  if (!fmt_name) {
    gst_caps_unref(new_caps);
    return -1;
  }

  GST_LOG("source format : %s", fmt_name);

  in_fmt = gst_video_format_from_string(fmt_name);

  for (i = 0; i < gst_caps_get_size(new_caps); i++) {
    tests = gst_caps_get_structure(new_caps, i);
    format = gst_structure_get_value(tests, "format");
    if (!format) {
      gst_caps_unref(new_caps);
      return -1;
    }

    if (GST_VALUE_HOLDS_LIST(format)) {
      for (j = 0; j < gst_value_list_get_size(format); j++) {
        const GValue *val = gst_value_list_get_value(format, j);
        if (G_VALUE_HOLDS_STRING(val)) {
          out_fmt = gst_video_format_from_string(g_value_get_string(val));
          loss = get_format_conversion_loss(transform, in_fmt, out_fmt);
          if (loss < min_loss) {
            out_info = gst_video_format_get_info(out_fmt);
            min_loss = loss;
          }

          if (min_loss == 0)
            break;
        }
      }
    } else if (G_VALUE_HOLDS_STRING(format)) {
      out_fmt = gst_video_format_from_string(g_value_get_string(format));
      loss = get_format_conversion_loss(transform, in_fmt, out_fmt);
      if (loss < min_loss) {
        out_info = gst_video_format_get_info(out_fmt);
        min_loss = loss;
      }
    }

    if (min_loss == 0)
      break;
  }
#else
  format =
      gst_structure_get_value(gst_caps_get_structure(new_caps, 0), "format");
  if (format) {
    if (GST_VALUE_HOLDS_LIST(format)) {
      format = gst_value_list_get_value(format, 0);
    }
    out_fmt = gst_video_format_from_string(g_value_get_string(format));
    out_info = gst_video_format_get_info(out_fmt);
  }
#endif

  gst_caps_unref(new_caps);

  if (out_info) {
    fmt_name = GST_VIDEO_FORMAT_INFO_NAME(out_info);
    gst_structure_set(outs, "format", G_TYPE_STRING, fmt_name, NULL);
    GST_LOG("out format %s", fmt_name);
    return 0;
  } else {
    gst_structure_set(outs, "format", G_TYPE_STRING, "UNKNOWN", NULL);
    GST_LOG("out format not match");
    return -1;
  }
}

static GstCaps* imx_video_convert_fixate_caps(GstBaseTransform *transform,
    GstPadDirection direction, GstCaps *caps, GstCaps *othercaps)
{
  GstStructure *ins, *outs;
  GValue const *from_par, *to_par;
  GValue fpar = { 0, }, tpar = { 0, };
  const gchar *in_format;
  const GstVideoFormatInfo *in_info, *out_info = NULL;
  gint min_loss = G_MAXINT32;
  guint i, capslen;

  g_return_val_if_fail(gst_caps_is_fixed (caps), othercaps);

  othercaps = gst_caps_make_writable(othercaps);

  GST_DEBUG("fixate othercaps: %" GST_PTR_FORMAT, othercaps);
  GST_DEBUG("based on caps: %" GST_PTR_FORMAT, caps);
  GST_DEBUG("direction: %d", direction);

  ins = gst_caps_get_structure(caps, 0);
  outs = gst_caps_get_structure(othercaps, 0);

  from_par = gst_structure_get_value(ins, "pixel-aspect-ratio");
  to_par = gst_structure_get_value(outs, "pixel-aspect-ratio");

  /* If no par info, then set some assuming value  */
  if (!from_par || !to_par) {
    if (direction == GST_PAD_SINK) {
      if (!from_par) {
        g_value_init(&fpar, GST_TYPE_FRACTION);
        gst_value_set_fraction(&fpar, 1, 1);
        from_par = &fpar;
      }
      if (!to_par) {
        g_value_init(&tpar, GST_TYPE_FRACTION_RANGE);
        gst_value_set_fraction_range_full(&tpar, 1, G_MAXINT32, G_MAXINT32, 1);
        to_par = &tpar;
      }
    } else {
      if (!to_par) {
        g_value_init(&tpar, GST_TYPE_FRACTION);
        gst_value_set_fraction(&tpar, 1, 1);
        to_par = &tpar;
        gst_structure_set(outs, "pixel-aspect-ratio",
                          GST_TYPE_FRACTION, 1, 1, NULL);
      }
      if (!from_par) {
        g_value_init(&fpar, GST_TYPE_FRACTION);
        gst_value_set_fraction (&fpar, 1, 1);
        from_par = &fpar;
      }
    }
  }

  /* from_par should be fixed now */
  gint from_w, from_h, from_par_n, from_par_d, to_par_n, to_par_d;
  gint w = 0, h = 0;
  gint from_dar_n, from_dar_d;
  gint num, den;
  GstStructure *tmp;
  gint set_w, set_h, set_par_n, set_par_d;

  from_par_n = gst_value_get_fraction_numerator(from_par);
  from_par_d = gst_value_get_fraction_denominator(from_par);

  gst_structure_get_int(ins, "width", &from_w);
  gst_structure_get_int(ins, "height", &from_h);

  gst_structure_get_int(outs, "width", &w);
  gst_structure_get_int(outs, "height", &h);

  /* if both width and height are already fixed, we can do nothing */
  if (w && h) {
    guint dar_n, dar_d;
    GST_DEBUG("dimensions already set to %dx%d", w, h);

    if (!gst_value_is_fixed(to_par)) {
      if (gst_video_calculate_display_ratio(&dar_n, &dar_d,
          from_w, from_h, from_par_n, from_par_d, w, h)) {
        GST_DEBUG("fixating to_par to %d/%d", dar_n, dar_d);

        if (gst_structure_has_field(outs, "pixel-aspect-ratio")) {
          gst_structure_fixate_field_nearest_fraction(outs,
                                        "pixel-aspect-ratio", dar_n, dar_d);
        } else if (dar_n != dar_d) {
          gst_structure_set(outs, "pixel-aspect-ratio",
                            GST_TYPE_FRACTION, dar_n, dar_d, NULL);
        }
      }
    }

    goto done;
  }

  /* Calculate input DAR */
  gst_util_fraction_multiply(from_w, from_h, from_par_n, from_par_d,
                              &from_dar_n, &from_dar_d);
  GST_LOG("Input DAR is %d/%d", from_dar_n, from_dar_d);

  /* If either width or height are fixed, choose a height or width and PAR */
  if (h) {
    GST_DEBUG("height is fixed (%d)", h);

    /* If the PAR is fixed, choose the width that match DAR */
    if (gst_value_is_fixed(to_par)) {
      to_par_n = gst_value_get_fraction_numerator(to_par);
      to_par_d = gst_value_get_fraction_denominator(to_par);
      GST_DEBUG("PAR is fixed %d/%d", to_par_n, to_par_d);

      gst_util_fraction_multiply(from_dar_n, from_dar_d,
                                 to_par_d, to_par_n, &num, &den);
      w = (guint) gst_util_uint64_scale_int(h, num, den);
      gst_structure_fixate_field_nearest_int(outs, "width", w);
    } else {
      /* The PAR is not fixed, Check if we can keep the input width */
      tmp = gst_structure_copy(outs);
      gst_structure_fixate_field_nearest_int(tmp, "width", from_w);
      gst_structure_get_int(tmp, "width", &set_w);
      gst_util_fraction_multiply(from_dar_n, from_dar_d, h, set_w,
                                 &to_par_n, &to_par_d);

      if (!gst_structure_has_field(tmp, "pixel-aspect-ratio"))
        gst_structure_set_value(tmp, "pixel-aspect-ratio", to_par);

      gst_structure_fixate_field_nearest_fraction(tmp, "pixel-aspect-ratio",
                                                  to_par_n, to_par_d);
      gst_structure_get_fraction(tmp, "pixel-aspect-ratio",
                                  &set_par_n, &set_par_d);
      gst_structure_free(tmp);

      /* Check if the adjusted PAR is accepted */
      if (set_par_n == to_par_n && set_par_d == to_par_d) {
        if (gst_structure_has_field(outs, "pixel-aspect-ratio")
            || set_par_n != set_par_d) {
          gst_structure_set(outs, "width", G_TYPE_INT, set_w,
           "pixel-aspect-ratio", GST_TYPE_FRACTION, set_par_n, set_par_d, NULL);
        }
      } else {
        /* scale the width to the new PAR and check if the adjusted width is
         * accepted. If all that fails we can't keep the DAR */
        gst_util_fraction_multiply(from_dar_n, from_dar_d, set_par_d, set_par_n,
                                  &num, &den);

        w = (guint) gst_util_uint64_scale_int(h, num, den);
        gst_structure_fixate_field_nearest_int(outs, "width", w);
        if (gst_structure_has_field(outs, "pixel-aspect-ratio")
            || set_par_n != set_par_d) {
          gst_structure_set(outs, "pixel-aspect-ratio", GST_TYPE_FRACTION,
                            set_par_n, set_par_d, NULL);
        }
      }
    }
  } else if (w) {
    GST_DEBUG("width is fixed (%d)", w);

    /* If the PAR is fixed, choose the height that match the DAR */
    if (gst_value_is_fixed(to_par)) {
      to_par_n = gst_value_get_fraction_numerator(to_par);
      to_par_d = gst_value_get_fraction_denominator(to_par);
      GST_DEBUG("PAR is fixed %d/%d", to_par_n, to_par_d);

      gst_util_fraction_multiply(from_dar_n, from_dar_d, to_par_d, to_par_n,
                                 &num, &den);
      h = (guint) gst_util_uint64_scale_int(w, den, num);
      gst_structure_fixate_field_nearest_int(outs, "height", h);
    } else {
      /* Check if we can keep the input height */
      tmp = gst_structure_copy(outs);
      gst_structure_fixate_field_nearest_int(tmp, "height", from_h);
      gst_structure_get_int(tmp, "height", &set_h);
      gst_util_fraction_multiply(from_dar_n, from_dar_d, set_h, w,
                                 &to_par_n, &to_par_d);

      if (!gst_structure_has_field(tmp, "pixel-aspect-ratio"))
        gst_structure_set_value(tmp, "pixel-aspect-ratio", to_par);
      gst_structure_fixate_field_nearest_fraction(tmp, "pixel-aspect-ratio",
                                                  to_par_n, to_par_d);
      gst_structure_get_fraction(tmp, "pixel-aspect-ratio",
                                 &set_par_n, &set_par_d);
      gst_structure_free(tmp);

      /* Check if the adjusted PAR is accepted */
      if (set_par_n == to_par_n && set_par_d == to_par_d) {
        if (gst_structure_has_field(outs, "pixel-aspect-ratio")
            || set_par_n != set_par_d) {
          gst_structure_set(outs, "height", G_TYPE_INT, set_h,
           "pixel-aspect-ratio", GST_TYPE_FRACTION, set_par_n, set_par_d, NULL);
        }
      } else {
        /* scale the height to the new PAR and check if the adjusted width
         * is accepted. If all that fails we can't keep the DAR */
        gst_util_fraction_multiply(from_dar_n, from_dar_d, set_par_d, set_par_n,
                                    &num, &den);

        h = (guint) gst_util_uint64_scale_int(w, den, num);
        gst_structure_fixate_field_nearest_int(outs, "height", h);
        if (gst_structure_has_field(outs, "pixel-aspect-ratio")
            || set_par_n != set_par_d) {
          gst_structure_set(outs, "pixel-aspect-ratio", GST_TYPE_FRACTION,
              set_par_n, set_par_d, NULL);
        }
      }
    }
  } else {
    /* both h and w not fixed */
    if (gst_value_is_fixed(to_par)) {
      gint f_h, f_w;
      to_par_n = gst_value_get_fraction_numerator(to_par);
      to_par_d = gst_value_get_fraction_denominator(to_par);

      /* Calculate scale factor for the PAR change */
      gst_util_fraction_multiply(from_dar_n, from_dar_d, to_par_n, to_par_d,
                                 &num, &den);

      /* Try to keep the input height (because of interlacing) */
      tmp = gst_structure_copy(outs);
      gst_structure_fixate_field_nearest_int(tmp, "height", from_h);
      gst_structure_get_int(tmp, "height", &set_h);
      w = (guint) gst_util_uint64_scale_int(set_h, num, den);
      gst_structure_fixate_field_nearest_int(tmp, "width", w);
      gst_structure_get_int(tmp, "width", &set_w);
      gst_structure_free(tmp);

      if (set_w == w) {
        gst_structure_set(outs, "width", G_TYPE_INT, set_w,
                          "height", G_TYPE_INT, set_h, NULL);
      } else {
        f_h = set_h;
        f_w = set_w;

        /* If the former failed, try to keep the input width at least */
        tmp = gst_structure_copy(outs);
        gst_structure_fixate_field_nearest_int(tmp, "width", from_w);
        gst_structure_get_int(tmp, "width", &set_w);
        h = (guint) gst_util_uint64_scale_int(set_w, den, num);
        gst_structure_fixate_field_nearest_int(tmp, "height", h);
        gst_structure_get_int(tmp, "height", &set_h);
        gst_structure_free(tmp);

        if (set_h == h)
          gst_structure_set(outs, "width", G_TYPE_INT, set_w,
                            "height", G_TYPE_INT, set_h, NULL);
        else
          gst_structure_set(outs, "width", G_TYPE_INT, f_w,
                            "height", G_TYPE_INT, f_h, NULL);
      }
    } else {
      gint tmp2;
      /* width, height and PAR are not fixed but passthrough is not possible */
      /* try to keep the height and width as good as possible and scale PAR */
      tmp = gst_structure_copy(outs);
      gst_structure_fixate_field_nearest_int(tmp, "height", from_h);
      gst_structure_get_int(tmp, "height", &set_h);
      gst_structure_fixate_field_nearest_int(tmp, "width", from_w);
      gst_structure_get_int(tmp, "width", &set_w);

      gst_util_fraction_multiply(from_dar_n, from_dar_d, set_h, set_w,
                                 &to_par_n, &to_par_d);

      if (!gst_structure_has_field(tmp, "pixel-aspect-ratio"))
        gst_structure_set_value(tmp, "pixel-aspect-ratio", to_par);
      gst_structure_fixate_field_nearest_fraction(tmp, "pixel-aspect-ratio",
                                                  to_par_n, to_par_d);
      gst_structure_get_fraction(tmp, "pixel-aspect-ratio",
                                 &set_par_n, &set_par_d);
      gst_structure_free(tmp);

      if (set_par_n == to_par_n && set_par_d == to_par_d) {
        gst_structure_set(outs, "width", G_TYPE_INT, set_w,
                                "height", G_TYPE_INT, set_h, NULL);
        if (gst_structure_has_field(outs, "pixel-aspect-ratio")
            || set_par_n != set_par_d) {
          gst_structure_set(outs, "pixel-aspect-ratio", GST_TYPE_FRACTION,
                            set_par_n, set_par_d, NULL);
        }
      } else {
        /* Otherwise try to scale width to keep the DAR with the set
         * PAR and height */
        gst_util_fraction_multiply(from_dar_n, from_dar_d, set_par_d, set_par_n,
                                   &num, &den);

        w = (guint) gst_util_uint64_scale_int(set_h, num, den);
        tmp = gst_structure_copy(outs);
        gst_structure_fixate_field_nearest_int(tmp, "width", w);
        gst_structure_get_int(tmp, "width", &tmp2);
        gst_structure_free(tmp);

        if (tmp2 == w) {
          gst_structure_set(outs, "width", G_TYPE_INT, tmp2,
                                  "height", G_TYPE_INT, set_h, NULL);
          if (gst_structure_has_field(outs, "pixel-aspect-ratio")
              || set_par_n != set_par_d) {
            gst_structure_set(outs, "pixel-aspect-ratio", GST_TYPE_FRACTION,
                              set_par_n, set_par_d, NULL);
          }
        } else {
          /* then try the same with the height */
          h = (guint) gst_util_uint64_scale_int(set_w, den, num);
          tmp = gst_structure_copy(outs);
          gst_structure_fixate_field_nearest_int(tmp, "height", h);
          gst_structure_get_int(tmp, "height", &tmp2);
          gst_structure_free(tmp);

          if (tmp2 == h) {
            gst_structure_set(outs, "width", G_TYPE_INT, set_w,
                                    "height", G_TYPE_INT, tmp2, NULL);
            if (gst_structure_has_field(outs, "pixel-aspect-ratio")
                || set_par_n != set_par_d) {
              gst_structure_set(outs, "pixel-aspect-ratio", GST_TYPE_FRACTION,
                                set_par_n, set_par_d, NULL);
            }
          } else {
            /* Don't keep the DAR, take the nearest values from the first try */
            gst_structure_set(outs, "width", G_TYPE_INT, set_w,
                                    "height", G_TYPE_INT, set_h, NULL);
            if (gst_structure_has_field(outs, "pixel-aspect-ratio")
                || set_par_n != set_par_d) {
              gst_structure_set(outs, "pixel-aspect-ratio", GST_TYPE_FRACTION,
                                set_par_n, set_par_d, NULL);
            }
          }
        }
      }
    }
  }

done:
  if (from_par == &fpar)
    g_value_unset(&fpar);
  if (to_par == &tpar)
    g_value_unset(&tpar);

  imx_video_convert_fixate_format_caps(transform, caps, othercaps);
  othercaps = gst_caps_fixate (othercaps);

  GST_DEBUG("fixated othercaps to %" GST_PTR_FORMAT, othercaps);

  return othercaps;
}

static gboolean
gst_imx_video_convert_filter_meta (GstBaseTransform * trans, GstQuery * query,
    GType api, const GstStructure * params)
{
  /* propose all metadata upstream */
  return TRUE;
}

static void
imx_video_convert_set_pool_alignment(GstCaps *caps, GstBufferPool *pool)
{
  GstVideoInfo info;
  GstVideoAlignment alignment;
  GstStructure *config = gst_buffer_pool_get_config(pool);
  gst_video_info_from_caps (&info, caps);

  memset (&alignment, 0, sizeof (GstVideoAlignment));

  gint w = GST_VIDEO_INFO_WIDTH (&info);
  gint h = GST_VIDEO_INFO_HEIGHT (&info);
  if (!ISALIGNED (w, ALIGNMENT) || !ISALIGNED (h, ALIGNMENT)) {
    alignment.padding_right = ALIGNTO (w, ALIGNMENT) - w;
    alignment.padding_bottom = ALIGNTO (h, ALIGNMENT) - h;
  }

  GST_DEBUG ("pool(%p), [%d, %d]:padding_right (%d), padding_bottom (%d)",
      pool, w, h, alignment.padding_right, alignment.padding_bottom);

  if (!gst_buffer_pool_config_has_option (config, \
        GST_BUFFER_POOL_OPTION_VIDEO_META)) {
    gst_buffer_pool_config_add_option (config,
        GST_BUFFER_POOL_OPTION_VIDEO_META);
  }
  if (!gst_buffer_pool_config_has_option (config,
            GST_BUFFER_POOL_OPTION_VIDEO_ALIGNMENT)) {
    gst_buffer_pool_config_add_option (config,
        GST_BUFFER_POOL_OPTION_VIDEO_ALIGNMENT);
  }

  gst_buffer_pool_config_set_video_alignment (config, &alignment);
  gst_buffer_pool_set_config(pool, config);
}

static gboolean
imx_video_convert_buffer_pool_is_ok (GstBufferPool * pool, GstCaps * newcaps,
    gint size)
{
  GstCaps *oldcaps;
  GstStructure *config;
  guint bsize;
  gboolean ret;

  config = gst_buffer_pool_get_config (pool);
  gst_buffer_pool_config_get_params (config, &oldcaps, &bsize, NULL, NULL);
  ret = (size <= bsize) && gst_caps_is_equal (newcaps, oldcaps);
  gst_structure_free (config);

  return ret;
}

static GstBufferPool*
gst_imx_video_convert_create_bufferpool(GstImxVideoConvert *imxvct,
                    GstCaps *caps, guint size, guint min, guint max)
{
  GstBufferPool *pool;
  GstStructure *config;

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

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

    if (!imxvct->allocator) {
      GST_ERROR ("new imx video convert allocator failed.");
      gst_buffer_pool_set_active (pool, FALSE);
      gst_object_unref (pool);
      return NULL;
    }

    config = gst_buffer_pool_get_config(pool);
    gst_buffer_pool_config_set_params(config, caps, size, min, max);
    gst_buffer_pool_config_set_allocator(config, imxvct->allocator, NULL);
    gst_buffer_pool_config_add_option(config,
                                      GST_BUFFER_POOL_OPTION_VIDEO_META);
    if (!gst_buffer_pool_set_config(pool, config)) {
      GST_ERROR ("set buffer pool config failed.");
      gst_buffer_pool_set_active (pool, FALSE);
      gst_object_unref (pool);
      return NULL;
    }
  }

  imx_video_convert_set_pool_alignment(caps, pool);

  GST_LOG ("created a buffer pool (%p).", pool);
  return pool;
}

static gboolean
imx_video_convert_propose_allocation(GstBaseTransform *transform,
                                      GstQuery *decide_query, GstQuery *query)
{
  GstImxVideoConvert *imxvct = (GstImxVideoConvert *)(transform);
  GstBufferPool *pool;
  GstVideoInfo info;
  guint size = 0;
  GstCaps *caps;
  gboolean need_pool;

  /* passthrough, we're done */
  if (decide_query == NULL) {
    GST_DEBUG ("doing passthrough query");
    if (imxvct->composition_meta_enable && imxvct->in_place) {
      imx_video_overlay_composition_add_query_meta (query);
    }
    return gst_pad_peer_query (transform->srcpad, query);
  } else {
    guint i, n_metas;
    /* non-passthrough, copy all metadata, decide_query does not contain the
     * metadata anymore that depends on the buffer memory */
    n_metas = gst_query_get_n_allocation_metas (decide_query);
    for (i = 0; i < n_metas; i++) {
      GType api;
      const GstStructure *params;
      api = gst_query_parse_nth_allocation_meta (decide_query, i, &params);
      gst_query_add_allocation_meta (query, api, params);
    }
  }

  gst_query_parse_allocation (query, &caps, &need_pool);

  if (need_pool) {
    if (caps == NULL) {
      GST_ERROR_OBJECT (imxvct, "no caps specified.");
      return FALSE;
    }

    if (!gst_video_info_from_caps (&info, caps))
      return FALSE;

    size = GST_VIDEO_INFO_SIZE (&info);
    GST_IMX_CONVERT_UNREF_BUFFER (imxvct->in_buf);
    GST_IMX_CONVERT_UNREF_POOL(imxvct->in_pool);
    GST_DEBUG_OBJECT(imxvct, "creating new input pool");
    pool = gst_imx_video_convert_create_bufferpool(imxvct, caps, size, 1,
                                                   IMX_VCT_IN_POOL_MAX_BUFFERS);
    imxvct->in_pool = pool;
    imxvct->pool_config_update = TRUE;

    if (pool) {
      GST_DEBUG_OBJECT (imxvct, "propose_allocation, pool(%p).", pool);
      GstStructure *config = gst_buffer_pool_get_config (pool);
      gst_buffer_pool_config_get_params (config, &caps, &size, NULL, NULL);
      gst_structure_free (config);

      gst_query_add_allocation_pool (query, pool, size, 1,
                                     IMX_VCT_IN_POOL_MAX_BUFFERS);
      gst_query_add_allocation_param (query, imxvct->allocator, NULL);
    } else {
      return FALSE;
    }
  }

  gst_query_add_allocation_meta (query, GST_VIDEO_META_API_TYPE, NULL);
  gst_query_add_allocation_meta (query, GST_VIDEO_CROP_META_API_TYPE, NULL);

  if (imxvct->composition_meta_enable)
    imx_video_overlay_composition_add_query_meta (query);

  return TRUE;
}

static gboolean imx_video_convert_decide_allocation(GstBaseTransform *transform,
                                                     GstQuery *query)
{
  GstImxVideoConvert *imxvct = (GstImxVideoConvert *)(transform);
  GstCaps *outcaps;
  GstBufferPool *pool = NULL;
  guint size, num, min = 0, max = 0;
  GstStructure *config = NULL;
  GstVideoInfo vinfo;
  gboolean new_pool = TRUE;
  GstAllocator *allocator = NULL;

  gst_query_parse_allocation(query, &outcaps, NULL);
  gst_video_info_init(&vinfo);
  gst_video_info_from_caps(&vinfo, outcaps);
  num = gst_query_get_n_allocation_pools(query);
  size = vinfo.size;

  GST_DEBUG_OBJECT(imxvct, "number of allocation pools: %d", num);

  /* if downstream element provided buffer pool with phy buffers */
  if (num > 0) {
    guint i = 0;
    for (; i < num; ++i) {
      gst_query_parse_nth_allocation_pool(query, i, &pool, &size, &min, &max);
      if (pool) {
        config = gst_buffer_pool_get_config(pool);
        gst_buffer_pool_config_get_allocator(config, &allocator, NULL);
        if (allocator && GST_IS_ALLOCATOR_PHYMEM(allocator)) {
          size = MAX(size, vinfo.size);
          new_pool = FALSE;
          break;
        } else {
          GST_LOG_OBJECT (imxvct, "no phy allocator in output pool (%p)", pool);
        }

        if (config) {
          gst_structure_free (config);
          config = NULL;
        }

        allocator = NULL;
        gst_object_unref (pool);
      }
    }
  }

  size = MAX(size, vinfo.size);
  size = PAGE_ALIGN(size);

  if (max == 0)
    if (min < 3)
      max = min = 3;
    else
      max = min;

  /* downstream doesn't provide a pool or the pool has no ability to allocate
   * physical memory buffers, we need create new pool */
  if (new_pool) {
    GST_IMX_CONVERT_UNREF_POOL(imxvct->self_out_pool);
    GST_DEBUG_OBJECT(imxvct, "creating new output pool");
    pool = gst_imx_video_convert_create_bufferpool(imxvct, outcaps, size,
                                                   min, max);
    imxvct->self_out_pool = pool;
    config = gst_buffer_pool_get_config (pool);
    gst_buffer_pool_set_active(pool, TRUE);
  } else {
    // check the requirement of output alignment
    imx_video_convert_set_pool_alignment(outcaps, pool);
  }

  imxvct->out_pool = pool;
  gst_buffer_pool_config_get_params (config, &outcaps, &size, &min, &max);

  GST_DEBUG_OBJECT(imxvct, "pool config:  outcaps: %" GST_PTR_FORMAT "  "
      "size: %u  min buffers: %u  max buffers: %u", outcaps, size, min, max);
  gst_structure_free (config);

  if (pool) {
    if (num > 0)
      gst_query_set_nth_allocation_pool(query, 0, pool, size, min, max);
    else
      gst_query_add_allocation_pool(query, pool, size, min, max);

    if (!new_pool)
      gst_object_unref (pool);
  }

  return TRUE;
}

static gboolean imx_video_convert_set_info(GstVideoFilter *filter,
                                    GstCaps *in, GstVideoInfo *in_info,
                                    GstCaps *out, GstVideoInfo *out_info)
{
  GstImxVideoConvert *imxvct = (GstImxVideoConvert *)(filter);
  Imx2DDevice *device = imxvct->device;
  GstStructure *ins, *outs;
  const gchar *from_interlace;

  if (!device)
    return FALSE;

  ins = gst_caps_get_structure(in, 0);
  outs = gst_caps_get_structure(out, 0);

  /* if interlaced and we enabled deinterlacing, make it progressive */
  from_interlace = gst_structure_get_string(ins, "interlace-mode");
  if (from_interlace &&
      (g_strcmp0(from_interlace, "interleaved") == 0
          || g_strcmp0(from_interlace, "mixed") == 0)) {
    if (IMX_2D_DEINTERLACE_NONE != imxvct->deinterlace) {
      gst_structure_set(outs,
          "interlace-mode", G_TYPE_STRING, "progressive", NULL);
      gst_base_transform_set_passthrough((GstBaseTransform*)filter, FALSE);
    }
  }

  if (IMX_2D_ROTATION_0 != imxvct->rotate)
    gst_base_transform_set_passthrough((GstBaseTransform*)filter, FALSE);

/* can't remove since caps fixed
  if (gst_structure_get_string(outs, "colorimetry")) {
    GST_DEBUG("try to remove colorimetry");
    gst_structure_remove_fields(outs,"colorimetry", NULL);
  }

  if (gst_structure_get_string(outs, "chroma-site")) {
    GST_DEBUG("try to remove chroma-site");
    gst_structure_remove_fields(outs,"chroma-site", NULL);
  }
*/

  if (!imxvct->composition_meta_enable || imxvct->in_place) {
    //if src and sink caps only has video overlay composition feature difference
    //then force to work in pass through mode.
    GstCapsFeatures *in_f, *out_f;
    in_f = gst_caps_get_features(in, 0);
    out_f = gst_caps_get_features(out, 0);
    if (in_f && !gst_caps_features_is_equal(in_f, out_f)) {
      GstCapsFeatures *f = gst_caps_features_new(
          GST_CAPS_FEATURE_MEMORY_SYSTEM_MEMORY,
          GST_CAPS_FEATURE_META_GST_VIDEO_OVERLAY_COMPOSITION, NULL);
      GstCaps *copy_out = gst_caps_copy(out);
      gst_caps_set_features(copy_out, 0, f);
      if (gst_caps_is_equal(in, copy_out)) {
        gst_base_transform_set_passthrough((GstBaseTransform*)filter, TRUE);
      }
      gst_caps_unref(copy_out);
    }
  }

  GST_DEBUG ("set info from %" GST_PTR_FORMAT " to %" GST_PTR_FORMAT, in, out);

  return TRUE;
}

static GstFlowReturn imx_video_convert_transform_frame(GstVideoFilter *filter,
    GstVideoFrame *in, GstVideoFrame *out)
{
  GstImxVideoConvert *imxvct = (GstImxVideoConvert *)(filter);
  Imx2DDevice *device = imxvct->device;
  GstVideoFrame *input_frame = in;
  GstPhyMemMeta *phymemmeta = NULL;
  GstCaps *caps;
  GstVideoFrame temp_in_frame;
  Imx2DFrame src = {0}, dst = {0};
  PhyMemBlock src_mem = {0}, dst_mem = {0};
  guint i, n_mem;
  GstVideoCropMeta *in_crop = NULL, *out_crop = NULL;
  GstVideoInfo info;

  if (!device)
    return GST_FLOW_ERROR;

  if (!(gst_buffer_is_phymem(out->buffer)
        || gst_is_dmabuf_memory (gst_buffer_peek_memory (out->buffer, 0)))) {
    GST_ERROR ("out buffer is not phy memory or DMA Buf");
    return GST_FLOW_ERROR;
  }

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

    if (!imxvct->in_pool ||
        !imx_video_convert_buffer_pool_is_ok(imxvct->in_pool, caps,info.size)) {
      GST_IMX_CONVERT_UNREF_POOL(imxvct->in_pool);
      GST_DEBUG_OBJECT(imxvct, "creating new input pool");
      imxvct->in_pool = gst_imx_video_convert_create_bufferpool(imxvct, caps,
          info.size, 1, IMX_VCT_IN_POOL_MAX_BUFFERS);
    }

    gst_caps_unref (caps);

    if (imxvct->in_pool && !imxvct->in_buf) {
      gst_buffer_pool_set_active(imxvct->in_pool, TRUE);
      GstFlowReturn ret = gst_buffer_pool_acquire_buffer(imxvct->in_pool,
                                                  &(imxvct->in_buf), NULL);
      if (ret != GST_FLOW_OK)
        GST_ERROR("error acquiring input buffer: %s", gst_flow_get_name(ret));
      else
        GST_LOG ("created input buffer (%p)", imxvct->in_buf);
    }

    if (imxvct->in_buf) {
      gst_video_frame_map(&temp_in_frame, &info, imxvct->in_buf, GST_MAP_WRITE);
      gst_video_frame_copy(&temp_in_frame, in);
      input_frame = &temp_in_frame;
      gst_video_frame_unmap(&temp_in_frame);

      if (imxvct->composition_meta_enable
              && imx_video_overlay_composition_has_meta(in->buffer)) {
        imx_video_overlay_composition_remove_meta(imxvct->in_buf);
        imx_video_overlay_composition_copy_meta(imxvct->in_buf, in->buffer,
            in->info.width, in->info.height, in->info.width, in->info.height);
      }
    } else {
      GST_ERROR ("Can't get input buffer");
      return GST_FLOW_ERROR;
    }
  }

  if (imxvct->pool_config_update) {
    //alignment check
    memset (&imxvct->in_video_align, 0, sizeof(GstVideoAlignment));
    phymemmeta = GST_PHY_MEM_META_GET (input_frame->buffer);
    if (phymemmeta) {
      imxvct->in_video_align.padding_right = phymemmeta->x_padding;
      imxvct->in_video_align.padding_bottom = phymemmeta->y_padding;
      GST_DEBUG_OBJECT (imxvct, "physical memory meta x_padding: %d y_padding: %d",
          phymemmeta->x_padding, phymemmeta->y_padding);
    } else if (imxvct->in_pool) {
      GstStructure *config = gst_buffer_pool_get_config (imxvct->in_pool);
      memset (&imxvct->in_video_align, 0, sizeof(GstVideoAlignment));

      if (gst_buffer_pool_config_has_option (config,
          GST_BUFFER_POOL_OPTION_VIDEO_ALIGNMENT)) {
        gst_buffer_pool_config_get_video_alignment (config,
            &imxvct->in_video_align);
        GST_DEBUG ("input pool has alignment (%d, %d) , (%d, %d)",
          imxvct->in_video_align.padding_left,
          imxvct->in_video_align.padding_top,
          imxvct->in_video_align.padding_right,
          imxvct->in_video_align.padding_bottom);
      }

      gst_structure_free (config);
    }

    if (imxvct->out_pool) {
      GstStructure *config = gst_buffer_pool_get_config (imxvct->out_pool);
      memset (&imxvct->out_video_align, 0, sizeof(GstVideoAlignment));

      if (gst_buffer_pool_config_has_option (config,
          GST_BUFFER_POOL_OPTION_VIDEO_ALIGNMENT)) {
        gst_buffer_pool_config_get_video_alignment (config,
            &imxvct->out_video_align);
        GST_DEBUG ("output pool has alignment (%d, %d) , (%d, %d)",
          imxvct->out_video_align.padding_left,
          imxvct->out_video_align.padding_top,
          imxvct->out_video_align.padding_right,
          imxvct->out_video_align.padding_bottom);
      }

      gst_structure_free (config);
    }

    /* set physical memory padding info */
    if (imxvct->self_out_pool && gst_buffer_is_writable (out->buffer)) {
      phymemmeta = GST_PHY_MEM_META_ADD (out->buffer);
      phymemmeta->x_padding = imxvct->out_video_align.padding_right;
      phymemmeta->y_padding = imxvct->out_video_align.padding_bottom;
      GST_DEBUG_OBJECT (imxvct, "out physical memory meta x_padding: %d y_padding: %d",
          phymemmeta->x_padding, phymemmeta->y_padding);
    }

    imxvct->pool_config_update = FALSE;
  }

  caps = gst_pad_get_current_caps (GST_BASE_TRANSFORM_SINK_PAD(imxvct));
  gst_video_info_from_caps(&info, caps);
  gst_caps_unref (caps);

  src.info.fmt = GST_VIDEO_INFO_FORMAT(&(in->info));
  src.info.w = in->info.width + imxvct->in_video_align.padding_left +
              imxvct->in_video_align.padding_right;
  src.info.h = in->info.height + imxvct->in_video_align.padding_top +
              imxvct->in_video_align.padding_bottom;
  src.info.stride = in->info.stride[0];

  gint ret = device->config_input(device, &src.info);

  GST_LOG ("Input: %s, %dx%d(%d)", GST_VIDEO_FORMAT_INFO_NAME(in->info.finfo),
      src.info.w, src.info.h, src.info.stride);

  dst.info.fmt = GST_VIDEO_INFO_FORMAT(&(out->info));
  dst.info.w = out->info.width + imxvct->out_video_align.padding_left +
                imxvct->out_video_align.padding_right;
  dst.info.h = out->info.height + imxvct->out_video_align.padding_top +
                imxvct->out_video_align.padding_bottom;
  dst.info.stride = out->info.stride[0];

  ret |= device->config_output(device, &dst.info);

  GST_LOG ("Output: %s, %dx%d", GST_VIDEO_FORMAT_INFO_NAME(out->info.finfo),
      out->info.width, out->info.height);

  if (ret != 0)
    return GST_FLOW_ERROR;

  if (gst_is_dmabuf_memory (gst_buffer_peek_memory (input_frame->buffer, 0))) {
    src.mem = &src_mem;
    n_mem = gst_buffer_n_memory (input_frame->buffer);
    for (i = 0; i < n_mem; i++)
      src.fd[i] = gst_dmabuf_memory_get_fd (gst_buffer_peek_memory (input_frame->buffer, i));
  } else
    src.mem = gst_buffer_query_phymem_block (input_frame->buffer);
  src.alpha = 0xFF;
  src.crop.x = 0;
  src.crop.y = 0;
  src.crop.w = info.width;
  src.crop.h = info.height;
  src.rotate = imxvct->rotate;

  in_crop = gst_buffer_get_video_crop_meta(in->buffer);
  if (in_crop != NULL) {
    GST_LOG ("input crop meta: (%d, %d, %d, %d).", in_crop->x, in_crop->y,
        in_crop->width, in_crop->height);
    if ((in_crop->x >= info.width) || (in_crop->y >= info.height))
      return GST_FLOW_ERROR;

    src.crop.x += in_crop->x;
    src.crop.y += in_crop->y;
    src.crop.w = MIN(in_crop->width, (info.width - in_crop->x));
    src.crop.h = MIN(in_crop->height, (info.height - in_crop->y));
  }

  //rotate and de-interlace setting
  if (device->set_rotate(device, imxvct->rotate) < 0) {
    GST_WARNING_OBJECT (imxvct, "set rotate failed");
    return GST_FLOW_ERROR;
  }

  if (device->set_deinterlace(device, imxvct->deinterlace) < 0) {
    GST_WARNING_OBJECT (imxvct, "set deinterlace mode failed");
    return GST_FLOW_ERROR;
  }

  switch (in->info.interlace_mode) {
    case GST_VIDEO_INTERLACE_MODE_INTERLEAVED:
      GST_TRACE("input stream is interleaved");
      src.interlace_type = IMX_2D_INTERLACE_INTERLEAVED;
      break;
    case GST_VIDEO_INTERLACE_MODE_MIXED:
    {
      GST_TRACE("input stream is mixed");
      GstVideoMeta *video_meta = in->meta;
      if (video_meta != NULL) {
        if (video_meta->flags & GST_VIDEO_FRAME_FLAG_INTERLACED) {
          GST_TRACE("frame has video metadata and INTERLACED flag");
          src.interlace_type = IMX_2D_INTERLACE_INTERLEAVED;
        }
      }
      break;
    }
    case GST_VIDEO_INTERLACE_MODE_PROGRESSIVE:
      GST_TRACE("input stream is progressive");
      break;
    case GST_VIDEO_INTERLACE_MODE_FIELDS:
      GST_TRACE("input stream is 2-fields");
      src.interlace_type = IMX_2D_INTERLACE_FIELDS;
      break;
    default:
      src.interlace_type = IMX_2D_INTERLACE_PROGRESSIVE;
      break;
  }

  if (gst_is_dmabuf_memory (gst_buffer_peek_memory (out->buffer, 0))) {
    dst.mem = &dst_mem;
    n_mem = gst_buffer_n_memory (out->buffer);
    for (i = 0; i < n_mem; i++)
      dst.fd[i] = gst_dmabuf_memory_get_fd (gst_buffer_peek_memory (out->buffer, i));
  } else 
    dst.mem = gst_buffer_query_phymem_block (out->buffer);
  dst.alpha = 0xFF;
  dst.interlace_type = IMX_2D_INTERLACE_PROGRESSIVE;
  dst.crop.x = 0;
  dst.crop.y = 0;
  dst.crop.w = out->info.width;
  dst.crop.h = out->info.height;

  out_crop = gst_buffer_get_video_crop_meta(out->buffer);
  if (out_crop != NULL) {
    GST_LOG ("output crop meta: (%d, %d, %d, %d).", out_crop->x, out_crop->y,
        out_crop->width, out_crop->height);
    if ((out_crop->x >= out->info.width) || (out_crop->y >= out->info.height))
      return GST_FLOW_ERROR;

    dst.crop.x += out_crop->x;
    dst.crop.y += out_crop->y;
    dst.crop.w = MIN(out_crop->width, (out->info.width - out_crop->x));
    dst.crop.h = MIN(out_crop->height, (out->info.height - out_crop->y));
  }

  //convert
  if (device->convert(device, &dst, &src) == 0) {
    GST_TRACE ("frame conversion done");

    if (imxvct->composition_meta_enable) {
      if (imx_video_overlay_composition_has_meta(in->buffer)) {
        VideoCompositionVideoInfo in_v, out_v;
        memset (&in_v, 0, sizeof(VideoCompositionVideoInfo));
        memset (&out_v, 0, sizeof(VideoCompositionVideoInfo));
        in_v.buf = in->buffer;
        in_v.fmt = src.info.fmt;
        in_v.width = src.info.w;
        in_v.height = src.info.h;
        in_v.stride = src.info.stride;
        in_v.rotate = src.rotate;
        in_v.crop_x = src.crop.x;
        in_v.crop_y = src.crop.y;
        in_v.crop_w = src.crop.w;
        in_v.crop_h = src.crop.h;

        out_v.mem = dst.mem;
        out_v.fmt = dst.info.fmt;
        out_v.width = dst.info.w;
        out_v.height = dst.info.h;
        out_v.stride = dst.info.stride;
        out_v.rotate = IMX_2D_ROTATION_0;
        out_v.crop_x = dst.crop.x;
        out_v.crop_y = dst.crop.y;
        out_v.crop_w = dst.crop.w;
        out_v.crop_h = dst.crop.h;

        memcpy(&out_v.align, &(imxvct->out_video_align),
                sizeof(GstVideoAlignment));

        gint cnt = imx_video_overlay_composition_composite(&imxvct->video_comp,
                                                          &in_v, &out_v, FALSE);

        if (cnt >= 0) {
          imx_video_overlay_composition_remove_meta(out->buffer);
          GST_DEBUG ("processed %d video overlay composition buffers", cnt);
        } else {
          GST_WARNING ("video overlay composition meta handling failed");
        }
      }
    } else {
      if (imx_video_overlay_composition_has_meta(in->buffer) &&
          !imx_video_overlay_composition_has_meta(out->buffer)) {
        imx_video_overlay_composition_copy_meta(out->buffer, in->buffer,
            src.crop.w, src.crop.h, dst.crop.w, dst.crop.h);
      }
    }

    return GST_FLOW_OK;
  }

  return GST_FLOW_ERROR;
}

static GstFlowReturn
imx_video_convert_transform_frame_ip(GstVideoFilter *filter, GstVideoFrame *in)
{
  GstImxVideoConvert *imxvct = (GstImxVideoConvert *)(filter);
  GstPhyMemMeta *phymemmeta = NULL;

  if (imxvct->composition_meta_enable) {
  if (!(gst_buffer_is_phymem(in->buffer)
        || gst_is_dmabuf_memory (gst_buffer_peek_memory (in->buffer, 0)))) {
      gpointer state = NULL;
      GstMeta *meta;
      GstVideoOverlayCompositionMeta *compmeta;

      while ((meta = gst_buffer_iterate_meta (in->buffer, &state))) {
        if (meta->info &&
            meta->info->api == GST_VIDEO_OVERLAY_COMPOSITION_META_API_TYPE) {
          compmeta = (GstVideoOverlayCompositionMeta*)meta;
          if (GST_IS_VIDEO_OVERLAY_COMPOSITION (compmeta->overlay)) {
            gst_video_overlay_composition_blend (compmeta->overlay, in);
          }
        }
      }

      imx_video_overlay_composition_remove_meta(in->buffer);
      return GST_FLOW_OK;
    } else if (imx_video_overlay_composition_has_meta(in->buffer)) {
      if (imxvct->pool_config_update) {
        if (imxvct->in_pool && gst_buffer_pool_is_active (imxvct->in_pool)) {
          GstStructure *config = gst_buffer_pool_get_config (imxvct->in_pool);
          memset (&imxvct->in_video_align, 0, sizeof(GstVideoAlignment));
          if (gst_buffer_pool_config_has_option (config,
              GST_BUFFER_POOL_OPTION_VIDEO_ALIGNMENT)) {
            gst_buffer_pool_config_get_video_alignment (config,
                &imxvct->in_video_align);
          }

          gst_structure_free (config);
        } else {
          memset (&imxvct->in_video_align, 0, sizeof(GstVideoAlignment));
          phymemmeta = GST_PHY_MEM_META_GET (in->buffer);
          if (phymemmeta) {
            imxvct->in_video_align.padding_right = phymemmeta->x_padding;
            imxvct->in_video_align.padding_bottom = phymemmeta->y_padding;
          }
        }

        imxvct->pool_config_update = FALSE;
      }

      gint crop_x = 0;
      gint crop_y = 0;
      guint crop_w = in->info.width;
      guint crop_h = in->info.height;

      GstVideoCropMeta *in_crop = gst_buffer_get_video_crop_meta(in->buffer);
      if (in_crop != NULL) {
        if ((in_crop->x < in->info.width) && (in_crop->y < in->info.height)) {
          crop_x += in_crop->x;
          crop_y += in_crop->y;
          crop_w = MIN(in_crop->width, (in->info.width - in_crop->x));
          crop_h = MIN(in_crop->height, (in->info.height - in_crop->y));
        }
      }

      VideoCompositionVideoInfo in_v, out_v;
      PhyMemBlock src_mem = {0};
      guint i, n_mem;

      memset (&in_v, 0, sizeof(VideoCompositionVideoInfo));
      memset (&out_v, 0, sizeof(VideoCompositionVideoInfo));
      in_v.buf = in->buffer;
      in_v.fmt = out_v.fmt = GST_VIDEO_INFO_FORMAT(&(in->info));
      in_v.width = out_v.width = in->info.width;
      in_v.height = out_v.height = in->info.height;
      in_v.stride = out_v.stride = in->info.stride[0];
      in_v.rotate = out_v.rotate = IMX_2D_ROTATION_0;
      in_v.crop_x = out_v.crop_x = crop_x;
      in_v.crop_y = out_v.crop_y = crop_y;
      in_v.crop_w = out_v.crop_w = crop_w;
      in_v.crop_h = out_v.crop_h = crop_h;

      if (gst_is_dmabuf_memory (gst_buffer_peek_memory (in->buffer, 0))) {
        out_v.mem = &src_mem;
        n_mem = gst_buffer_n_memory (in->buffer);
        for (i = 0; i < n_mem; i++)
          out_v.fd[i] = gst_dmabuf_memory_get_fd (gst_buffer_peek_memory (in->buffer, i));
      } else
        out_v.mem = gst_buffer_query_phymem_block (in->buffer);
      memcpy(&out_v.align, &(imxvct->in_video_align),sizeof(GstVideoAlignment));

      gint cnt = imx_video_overlay_composition_composite(&imxvct->video_comp,
                                                         &in_v, &out_v, TRUE);

      if (cnt >= 0) {
        imx_video_overlay_composition_remove_meta(in->buffer);
        GST_DEBUG ("processed %d video overlay composition buffers", cnt);
      } else {
        GST_WARNING ("video overlay composition meta handling failed");
      }
    } else {
      GST_DEBUG("no video overlay composition meta");
    }
  }

  return GST_FLOW_OK;
}

static void
gst_imx_video_convert_class_init (GstImxVideoConvertClass * klass)
{
  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
  GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
  GstBaseTransformClass *base_transform_class = GST_BASE_TRANSFORM_CLASS(klass);
  GstVideoFilterClass *video_filter_class = GST_VIDEO_FILTER_CLASS(klass);
  GstCaps *caps;

  Imx2DDeviceInfo *in_plugin = (Imx2DDeviceInfo *)
      g_type_get_qdata (G_OBJECT_CLASS_TYPE (klass), GST_IMX_VCT_PARAMS_QDATA);
  g_assert (in_plugin != NULL);

  Imx2DDevice* dev = in_plugin->create(in_plugin->device_type);
  if (!dev)
    return;

  gchar longname[64] = {0};
  gchar desc[64] = {0};
  gint capabilities = dev->get_capabilities(dev);

  snprintf(longname, 32, "IMX %s Video Converter", in_plugin->name);
  snprintf(desc, 64, "Video CSC/Resize/Rotate%s",
      (capabilities&IMX_2D_DEVICE_CAP_DEINTERLACE) ? "/Deinterlace." : ".");
  gst_element_class_set_static_metadata (element_class, longname,
        "Filter/Converter/Video", desc, IMX_GST_PLUGIN_AUTHOR);

  GList *list = dev->get_supported_in_fmts(dev);
  caps = imx_video_convert_caps_from_fmt_list(list);
  g_list_free(list);

  if (!caps) {
    GST_ERROR ("Couldn't create caps for device '%s'", in_plugin->name);
    caps = gst_caps_new_empty_simple ("video/x-raw");
  }
  gst_element_class_add_pad_template (element_class,
      gst_pad_template_new ("sink", GST_PAD_SINK, GST_PAD_ALWAYS, caps));

#ifdef PASSTHOUGH_FOR_UNSUPPORTED_OUTPUT_FORMAT
  gst_element_class_add_pad_template (element_class,
      gst_pad_template_new ("src", GST_PAD_SRC, GST_PAD_ALWAYS,
                            gst_caps_copy(caps)));
#else
  list = dev->get_supported_out_fmts(dev);
  caps = imx_video_convert_caps_from_fmt_list(list);
  g_list_free(list);

  if (!caps) {
    GST_ERROR ("Couldn't create caps for device '%s'", in_plugin->name);
    caps = gst_caps_new_empty_simple ("video/x-raw");
  }
  gst_element_class_add_pad_template (element_class,
      gst_pad_template_new ("src", GST_PAD_SRC, GST_PAD_ALWAYS, caps));
#endif
  klass->in_plugin = in_plugin;

  parent_class = g_type_class_peek_parent (klass);

  gobject_class->finalize = gst_imx_video_convert_finalize;
  gobject_class->set_property = gst_imx_video_convert_set_property;
  gobject_class->get_property = gst_imx_video_convert_get_property;

  if (capabilities & IMX_2D_DEVICE_CAP_ROTATE) {
    g_object_class_install_property (gobject_class, PROP_OUTPUT_ROTATE,
        g_param_spec_enum("rotation", "Output rotation",
          "Rotation that shall be applied to output frames",
          gst_imx_video_convert_rotation_get_type(),
          GST_IMX_VIDEO_ROTATION_DEFAULT,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
  }

  if (capabilities & IMX_2D_DEVICE_CAP_DEINTERLACE) {
    g_object_class_install_property (gobject_class, PROP_DEINTERLACE_MODE,
        g_param_spec_enum("deinterlace", "Deinterlace mode",
          "Deinterlacing mode to be used for incoming frames "
          "(ignored if frames are not interlaced)",
          gst_imx_video_convert_deinterlace_get_type(),
          GST_IMX_VIDEO_DEINTERLACE_DEFAULT,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
  }

  g_object_class_install_property (gobject_class, PROP_COMPOSITION_META_ENABLE,
      g_param_spec_boolean("composition-meta-enable", "Enable composition meta",
        "Enable overlay composition meta processing",
        GST_IMX_VIDEO_COMPOMETA_DEFAULT,
        G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  g_object_class_install_property (gobject_class,
      PROP_COMPOSITION_META_IN_PLACE,
      g_param_spec_boolean("in-place", "Handle composition meta in place",
        "Handle composition meta in place in pass through mode, "
        "video overlay composition will blended onto input buffer",
        GST_IMX_VIDEO_COMPOMETA_IN_PLACE_DEFAULT,
        G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  in_plugin->destroy(dev);

  base_transform_class->src_event =
      GST_DEBUG_FUNCPTR(imx_video_convert_src_event);
  base_transform_class->transform_caps =
      GST_DEBUG_FUNCPTR(imx_video_convert_transform_caps);
  base_transform_class->fixate_caps =
      GST_DEBUG_FUNCPTR(imx_video_convert_fixate_caps);
  base_transform_class->filter_meta =
      GST_DEBUG_FUNCPTR (gst_imx_video_convert_filter_meta);
  base_transform_class->propose_allocation =
      GST_DEBUG_FUNCPTR(imx_video_convert_propose_allocation);
  base_transform_class->decide_allocation =
      GST_DEBUG_FUNCPTR(imx_video_convert_decide_allocation);
  video_filter_class->set_info =
      GST_DEBUG_FUNCPTR(imx_video_convert_set_info);
  video_filter_class->transform_frame =
      GST_DEBUG_FUNCPTR(imx_video_convert_transform_frame);
  video_filter_class->transform_frame_ip =
      GST_DEBUG_FUNCPTR(imx_video_convert_transform_frame_ip);

  base_transform_class->passthrough_on_same_caps = TRUE;
}

static void
gst_imx_video_convert_init (GstImxVideoConvert * imxvct)
{
  GstImxVideoConvertClass *klass =
      (GstImxVideoConvertClass *) G_OBJECT_GET_CLASS (imxvct);

  if (klass->in_plugin)
    imxvct->device = klass->in_plugin->create(klass->in_plugin->device_type);

  if (imxvct->device) {
    if (imxvct->device->open(imxvct->device) < 0) {
      GST_ERROR ("Open video process device failed.");
    } else {
      imxvct->in_buf = NULL;
      imxvct->in_pool = NULL;
      imxvct->out_pool = NULL;
      imxvct->self_out_pool = NULL;
      imxvct->pool_config_update = TRUE;
      imxvct->rotate = IMX_2D_ROTATION_0;
      imxvct->deinterlace = IMX_2D_DEINTERLACE_NONE;
      imxvct->composition_meta_enable = GST_IMX_VIDEO_COMPOMETA_DEFAULT;
      imxvct->in_place = GST_IMX_VIDEO_COMPOMETA_IN_PLACE_DEFAULT;
      imx_video_overlay_composition_init(&imxvct->video_comp, imxvct->device);
    }
  } else {
    GST_ERROR ("Create video process device failed.");
  }
}

static gboolean gst_imx_video_convert_register (GstPlugin * plugin)
{
  GTypeInfo tinfo = {
    sizeof (GstImxVideoConvertClass),
    NULL,
    NULL,
    (GClassInitFunc) gst_imx_video_convert_class_init,
    NULL,
    NULL,
    sizeof (GstImxVideoConvert),
    0,
    (GInstanceInitFunc) gst_imx_video_convert_init,
  };

  GType type;
  gchar *t_name;

  const Imx2DDeviceInfo *in_plugin = imx_get_2d_devices();

  while (in_plugin->name) {
    GST_LOG ("Registering %s video converter", in_plugin->name);

    if (!in_plugin->is_exist()) {
      GST_WARNING("device %s not exist", in_plugin->name);
      in_plugin++;
      continue;
    }

    t_name = g_strdup_printf ("imxvideoconvert_%s", in_plugin->name);
    type = g_type_from_name (t_name);

    if (!type) {
      type = g_type_register_static (GST_TYPE_VIDEO_FILTER, t_name, &tinfo, 0);
      g_type_set_qdata (type, GST_IMX_VCT_PARAMS_QDATA, (gpointer) in_plugin);
    }

    if (!gst_element_register (plugin, t_name, IMX_GST_PLUGIN_RANK, type)) {
      GST_ERROR ("Failed to register %s", t_name);
      g_free (t_name);
      return FALSE;
    }
    g_free (t_name);

    in_plugin++;
  }

  return TRUE;
}

static gboolean plugin_init (GstPlugin * plugin)
{
  GST_DEBUG_CATEGORY_INIT (imxvideoconvert_debug, "imxvideoconvert", 0,
      "Freescale IMX Video Convert element");

  return gst_imx_video_convert_register (plugin);
}

IMX_GST_PLUGIN_DEFINE(imxvideoconvert, "IMX Video Convert Plugins",plugin_init);
