/*
 * 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/gstvideopool.h>
#include <gst/allocators/gstdmabuf.h>
#include "gstosink.h"
#include "osink_object.h"
#include "gstosinkallocator.h"
#ifdef USE_ION
#include <gst/allocators/gstionmemory.h>
#endif
#include <gst/allocators/gstphymemmeta.h>
#include "gstimxvideooverlay.h"
#include "imxoverlaycompositionmeta.h"

#define ALIGNMENT (16)
#define ISALIGNED(a, b) (!(a & (b-1)))
#define ALIGNTO(a, b) ((a + (b-1)) & (~(b-1)))

GST_DEBUG_CATEGORY (overlay_sink_debug);
#define GST_CAT_DEFAULT overlay_sink_debug

enum
{
  OVERLAY_SINK_PROP_0,
  OVERLAY_SINK_PROP_COMPOSITION_META_ENABLE,
  OVERLAY_SINK_PROP_DISP_ON_0,
  OVERLAY_SINK_PROP_DISPWIN_X_0,
  OVERLAY_SINK_PROP_DISPWIN_Y_0,
  OVERLAY_SINK_PROP_DISPWIN_W_0,
  OVERLAY_SINK_PROP_DISPWIN_H_0,
  OVERLAY_SINK_PROP_ROTATION_0,
  OVERLAY_SINK_PROP_DISP_UPDATE_0,
  OVERLAY_SINK_PROP_KEEP_VIDEO_RATIO_0,
  OVERLAY_SINK_PROP_ZORDER_0,
  OVERLAY_SINK_PROP_DISP_MAX_0
};

#define OVERLAY_SINK_PROP_DISP_LENGTH (OVERLAY_SINK_PROP_DISP_MAX_0-OVERLAY_SINK_PROP_DISP_ON_0)
#define OVERLAY_SINK_COMPOMETA_DEFAULT     TRUE

static GstFlowReturn
gst_overlay_sink_show_frame (GstBaseSink * bsink, GstBuffer * buffer);

GST_IMPLEMENT_VIDEO_OVERLAY_METHODS (GstOverlaySink, gst_overlay_sink);

static gboolean overlay_sink_update_video_geo(GstElement * object, GstVideoRectangle win_rect) {
  GstOverlaySink *osink = GST_OVERLAY_SINK (object);
  if (osink->overlay[0].x == win_rect.x && osink->overlay[0].y == win_rect.y &&
      osink->overlay[0].w == win_rect.w && osink->overlay[0].h == win_rect.h)
    return TRUE;

  osink->overlay[0].x = win_rect.x;
  osink->overlay[0].y = win_rect.y;
  osink->overlay[0].w = win_rect.w;
  osink->overlay[0].h = win_rect.h;

  osink->config[0] = TRUE;
  if (((GstBaseSink*)osink)->eos || GST_STATE(object) == GST_STATE_PAUSED) {
    gst_overlay_sink_show_frame((GstBaseSink *)osink, osink->prv_buffer);
  }

  return TRUE;
}

static void overlay_sink_config_global_alpha(GObject * object, guint alpha)
{
  GstOverlaySink *osink = GST_OVERLAY_SINK (object);
  if (osink && osink->osink_obj)
    osink_object_set_global_alpha(osink->osink_obj, 0, alpha);
}

static void overlay_sink_config_color_key(GObject * object, gboolean enable, guint color_key)
{
  GstOverlaySink *osink = GST_OVERLAY_SINK (object);
  if (osink && osink->osink_obj)
    osink_object_set_color_key(osink->osink_obj, 0, enable, color_key);
}

#define gst_overlay_sink_parent_class parent_class
G_DEFINE_TYPE_WITH_CODE (GstOverlaySink, gst_overlay_sink, GST_TYPE_VIDEO_SINK,
    G_IMPLEMENT_INTERFACE (GST_TYPE_VIDEO_OVERLAY,
        gst_overlay_sink_video_overlay_interface_init));

//G_DEFINE_TYPE (GstOverlaySink, gst_overlay_sink, GST_TYPE_VIDEO_SINK);

static gint
gst_overlay_sink_output_config (GstOverlaySink *sink, gint idx) 
{
  if (sink->overlay[idx].rot != 0) {
    if (sink->overlay[idx].x < 0 || sink->overlay[idx].y < 0
        || (sink->overlay[idx].x + sink->overlay[idx].w) > sink->disp_info[idx].width
        || (sink->overlay[idx].y + sink->overlay[idx].h) > sink->disp_info[idx].height) {
      g_print ("not support video out of screen if orientation is not landscape.\n");
      memcpy(&sink->overlay[idx], &sink->pre_overlay_info[idx], sizeof(OverlayInfo));
      return -1;
    }
  }

  sink->surface_info.dst.left = sink->overlay[idx].x;
  sink->surface_info.dst.top = sink->overlay[idx].y;
  sink->surface_info.dst.right = sink->overlay[idx].w + sink->surface_info.dst.left;
  sink->surface_info.dst.bottom = sink->overlay[idx].h + sink->surface_info.dst.top;
  sink->surface_info.rot = sink->overlay[idx].rot;
  sink->surface_info.keep_ratio = sink->overlay[idx].keep_ratio;
  sink->surface_info.zorder = sink->overlay[idx].zorder;

  memcpy(&sink->pre_overlay_info[idx], &sink->overlay[idx], sizeof(OverlayInfo));
  return 0;
}

static void
gst_overlay_sink_set_property (GObject * object,
    guint prop_id, const GValue * value, GParamSpec * pspec)
{
  GstOverlaySink *sink = GST_OVERLAY_SINK (object);
  guint idx, prop; 
  gint val;

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

  if (prop_id == OVERLAY_SINK_PROP_COMPOSITION_META_ENABLE) {
    sink->composition_meta_enable = g_value_get_boolean(value);
    return;
  }

  idx = (prop_id - OVERLAY_SINK_PROP_DISP_ON_0) / OVERLAY_SINK_PROP_DISP_LENGTH;
  prop = prop_id - idx * OVERLAY_SINK_PROP_DISP_LENGTH;
  switch (prop) {
    case OVERLAY_SINK_PROP_DISP_ON_0:
      sink->disp_on[idx] = g_value_get_boolean (value);
      break;
    case OVERLAY_SINK_PROP_DISPWIN_X_0:
      sink->overlay[idx].x = g_value_get_int (value);
      break;
    case OVERLAY_SINK_PROP_DISPWIN_Y_0:
      sink->overlay[idx].y = g_value_get_int (value);
      break;
    case OVERLAY_SINK_PROP_DISPWIN_W_0:
      sink->overlay[idx].w = g_value_get_int (value);
      break;
    case OVERLAY_SINK_PROP_DISPWIN_H_0:
      sink->overlay[idx].h = g_value_get_int (value);
      break;
    case OVERLAY_SINK_PROP_ROTATION_0:
      sink->overlay[idx].rot = g_value_get_enum (value);
      break;
    case OVERLAY_SINK_PROP_DISP_UPDATE_0:
      sink->config[idx] = g_value_get_boolean (value);
      if (sink->config[idx] &&
          (((GstBaseSink*)sink)->eos || GST_STATE(sink) == GST_STATE_PAUSED)) {
        gst_overlay_sink_show_frame((GstBaseSink *)sink, sink->prv_buffer);
        sink->config[idx] = FALSE;
      }
      break;
    case OVERLAY_SINK_PROP_KEEP_VIDEO_RATIO_0:
      sink->overlay[idx].keep_ratio = g_value_get_boolean (value);
      break;
    case OVERLAY_SINK_PROP_ZORDER_0:
      sink->overlay[idx].zorder = g_value_get_int (value);
      break;
    default:
      break;
  }

  return;
}

static void
gst_overlay_sink_get_property (GObject * object,
    guint prop_id, GValue * value, GParamSpec * pspec)
{
  GstOverlaySink *sink = GST_OVERLAY_SINK (object);
  guint idx, prop; 

  GST_DEBUG_OBJECT (sink, "get_property (%d).", prop_id);

  if (prop_id == OVERLAY_SINK_PROP_COMPOSITION_META_ENABLE) {
    g_value_set_boolean(value, sink->composition_meta_enable);
    return;
  }

  idx = (prop_id - OVERLAY_SINK_PROP_DISP_ON_0) / OVERLAY_SINK_PROP_DISP_LENGTH;
  prop = prop_id - idx * OVERLAY_SINK_PROP_DISP_LENGTH;
  switch (prop) {
    case OVERLAY_SINK_PROP_DISP_ON_0:
      g_value_set_boolean (value, sink->disp_on[idx]);
      break;
    case OVERLAY_SINK_PROP_DISPWIN_X_0:
      g_value_set_int (value, sink->overlay[idx].x);
      break;
    case OVERLAY_SINK_PROP_DISPWIN_Y_0:
      g_value_set_int (value, sink->overlay[idx].y);
      break;
    case OVERLAY_SINK_PROP_DISPWIN_W_0:
      g_value_set_int (value, sink->overlay[idx].w);
      break;
    case OVERLAY_SINK_PROP_DISPWIN_H_0:
      g_value_set_int (value, sink->overlay[idx].h);
      break;
    case OVERLAY_SINK_PROP_ROTATION_0:
      g_value_set_enum (value, sink->overlay[idx].rot);
      break;
    case OVERLAY_SINK_PROP_DISP_UPDATE_0:
      g_value_set_boolean (value, sink->config[idx]);
      break;
    case OVERLAY_SINK_PROP_KEEP_VIDEO_RATIO_0:
      g_value_set_boolean (value, sink->overlay[idx].keep_ratio);
      break;
    case OVERLAY_SINK_PROP_ZORDER_0:
      g_value_set_int (value, sink->overlay[idx].zorder);
      break;
    default:
      break;
  }

  return;
}

static GstStateChangeReturn
gst_overlay_sink_change_state (GstElement * element, GstStateChange transition)
{
  GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
  GstOverlaySink *sink = GST_OVERLAY_SINK (element);

  GST_DEBUG_OBJECT (sink, "%d -> %d",
      GST_STATE_TRANSITION_CURRENT (transition),
      GST_STATE_TRANSITION_NEXT (transition));

  switch (transition) {
    case GST_STATE_CHANGE_NULL_TO_READY:
        sink->osink_obj = osink_object_new ();
        if (!sink->osink_obj) {
          GST_ERROR_OBJECT (sink, "create osink object failed.");
          return GST_STATE_CHANGE_FAILURE;

        }
        break;
    case GST_STATE_CHANGE_READY_TO_PAUSED:
        {
          gint i;
          gboolean display_enabled = FALSE;

          //put enable display in READY->PAUSE as playbin will change videosink
          //to ready state even for pure audio playback, this will cause overlaysink
          //show black screen in enable_display call
          sink->disp_count = osink_object_get_display_count (sink->osink_obj);
          for (i=0; i<sink->disp_count; i++) {
            osink_object_get_display_info (sink->osink_obj, &sink->disp_info[i], i);
            if (sink->disp_on[i]) {
              if (osink_object_enable_display (sink->osink_obj, i) < 0) {
                GST_ERROR_OBJECT (sink, "enable display %s failed.", sink->disp_info[i].name);
                sink->disp_on[i] = FALSE;
                continue;
              }

              display_enabled = TRUE;

              if (sink->overlay[i].w == 0) {
                if (sink->overlay[i].x > 0)
                  sink->overlay[i].w = sink->disp_info[i].width - sink->overlay[i].x;
                else
                  sink->overlay[i].w = sink->disp_info[i].width;
              }

              if (sink->overlay[i].h == 0) {
                if (sink->overlay[i].y > 0)
                  sink->overlay[i].h = sink->disp_info[i].height - sink->overlay[i].h;
                else
                  sink->overlay[i].h = sink->disp_info[i].height;
              }
            }
          }

          if (!display_enabled) {
            GST_ERROR_OBJECT (sink, "No display enabled.");
            osink_object_unref (sink->osink_obj);
            sink->osink_obj = NULL;
            return GST_STATE_CHANGE_FAILURE;
          }

          sink->frame_showed = 0;
          sink->run_time = 0;

          gst_imx_video_overlay_start (sink->imxoverlay);
        }
      break;
    default:
      break;
  }

  ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);

  switch (transition) {
    case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
      sink->run_time = gst_element_get_start_time (GST_ELEMENT (sink));
      break;
    case GST_STATE_CHANGE_PAUSED_TO_READY:
      {
        gint i;

        gst_imx_video_overlay_stop (sink->imxoverlay);

        if (sink->prv_buffer) {
          gst_buffer_unref (sink->prv_buffer);
          sink->prv_buffer = NULL;
        }

        for (i=0; i<sink->disp_count; i++) {
          if (sink->hoverlay[i]) {
            if (sink->run_time > 0) {
              gint64 blited = osink_object_get_overlay_showed_frames (sink->osink_obj, sink->hoverlay[i]);
              g_print ("Total showed frames (%lld), display %s blited (%lld), playing for (%"GST_TIME_FORMAT"), fps (%.3f).\n",
                  sink->frame_showed, sink->disp_info[i].name, blited, GST_TIME_ARGS (sink->run_time),
                  (gfloat)GST_SECOND * blited / sink->run_time);
            }
            osink_object_destroy_overlay (sink->osink_obj, sink->hoverlay[i]);
            sink->hoverlay[i] = NULL;
          }
        }

        if (sink->pool) {
          // only deactivate pool if pool activated by own, up stream element
          // may still using it
          if (sink->pool_activated) {
            gst_buffer_pool_set_active (sink->pool, FALSE);
            sink->pool_activated = FALSE;
          }
          gst_object_unref (sink->pool);
          sink->pool = NULL;
        }

        if (sink->allocator) {
          gst_object_unref (sink->allocator);
          sink->allocator = NULL;
        }
      }
      break;
    case GST_STATE_CHANGE_READY_TO_NULL:
      {
        if (sink->osink_obj)
          osink_object_unref (sink->osink_obj);
        sink->osink_obj = NULL;
        sink->frame_showed = 0;
        sink->run_time = 0;
      }
      break;
    default:
      break;
  }

  return ret;
}

static gboolean
gst_overlay_sink_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 gint
gst_overlay_sink_setup_buffer_pool (GstOverlaySink *sink, GstCaps *caps)
{
  GstStructure *structure;
  GstVideoInfo info;

  if (sink->pool) {
    GST_DEBUG_OBJECT (sink, "already have a pool (%p).", sink->pool);
    return 0;
  }

  if (!gst_video_info_from_caps (&info, caps)) {
    GST_ERROR_OBJECT (sink, "invalid caps.");
    return -1;
  }

  sink->pool = gst_video_buffer_pool_new ();
  if (!sink->pool) {
    GST_ERROR_OBJECT (sink, "New video buffer pool failed.\n");
    return -1;
  }
  GST_DEBUG_OBJECT (sink, "create buffer pool(%p).", sink->pool);

  if (!sink->allocator) {
#ifdef USE_ION
    sink->allocator = gst_ion_allocator_obtain ();
#endif
    if (!sink->allocator) {
      sink->allocator = gst_osink_allocator_new (sink->osink_obj);
    }
    if (!sink->allocator) {
      GST_ERROR_OBJECT (sink, "New osink allocator failed.\n");
      return -1;
    }
    GST_DEBUG_OBJECT (sink, "create allocator(%p).", sink->allocator);
  }

  structure = gst_buffer_pool_get_config (sink->pool);

  // buffer alignment configuration
  gint w = GST_VIDEO_INFO_WIDTH (&info);
  gint h = GST_VIDEO_INFO_HEIGHT (&info);
  if (!ISALIGNED (w, ALIGNMENT) || !ISALIGNED (h, ALIGNMENT)) {
    GstVideoAlignment alignment;

    memset (&alignment, 0, sizeof (GstVideoAlignment));
    alignment.padding_right = ALIGNTO (w, ALIGNMENT) - w;
    alignment.padding_bottom = ALIGNTO (h, ALIGNMENT) - h;

    GST_DEBUG ("align buffer pool, w(%d) h(%d), padding_right (%d), padding_bottom (%d)",
        w, h, alignment.padding_right, alignment.padding_bottom);

    gst_buffer_pool_config_add_option (structure, GST_BUFFER_POOL_OPTION_VIDEO_META);
    gst_buffer_pool_config_add_option (structure, GST_BUFFER_POOL_OPTION_VIDEO_ALIGNMENT);
    gst_buffer_pool_config_set_video_alignment (structure, &alignment);
  }

  gst_buffer_pool_config_set_params (structure, caps, info.size, sink->min_buffers, sink->max_buffers);
  gst_buffer_pool_config_set_allocator (structure, sink->allocator, NULL);
  if (!gst_buffer_pool_set_config (sink->pool, structure)) {
    GST_ERROR_OBJECT (sink, "set buffer pool failed.\n");
    return -1;
  }

  return 0;
}

static gboolean
gst_overlay_sink_set_caps (GstBaseSink * bsink, GstCaps * caps)
{
  GstOverlaySink *sink = GST_OVERLAY_SINK (bsink);
  GstVideoInfo info;
  gint i, w, h;

  if (!gst_video_info_from_caps (&info, caps)) {
    GST_ERROR_OBJECT (sink, "invalid caps.");
    return FALSE;
  }

  GST_DEBUG_OBJECT (sink, "set caps %" GST_PTR_FORMAT, caps);

  w = GST_VIDEO_INFO_WIDTH (&info);
  h = GST_VIDEO_INFO_HEIGHT (&info);

  sink->w = w;
  sink->h = h;

  sink->cropmeta.x = 0;
  sink->cropmeta.y = 0;
  sink->cropmeta.width = w;
  sink->cropmeta.height = h;

  sink->surface_info.fmt = GST_VIDEO_INFO_FORMAT (&info);
  sink->surface_info.src.left = 0;
  sink->surface_info.src.top = 0;
  sink->surface_info.src.right = w;
  sink->surface_info.src.bottom = h;
  sink->surface_info.src.width = w;
  sink->surface_info.src.height = h;
  sink->surface_info.alpha = 0xFF;

  /* one video frame which allocate by VPU may arrived before propose_allocation.
   * need check alignment for the video frame. */
  sink->pool_alignment_checked = FALSE;

  for (i=0; i<sink->disp_count; i++) {
    if (sink->disp_on[i]) {
      gst_overlay_sink_output_config (sink, i);
      if (sink->hoverlay[i] == NULL) {
        sink->hoverlay[i] = (gpointer)osink_object_create_overlay (sink->osink_obj, i, &sink->surface_info);
        if (!sink->hoverlay[i]) {
          GST_ERROR_OBJECT (sink, "create overlay for display %s failed.", sink->disp_info[i].name);
        }
      }
      else {
        if (osink_object_config_overlay (sink->osink_obj, sink->hoverlay[i], &sink->surface_info) < 0 ) {
          GST_ERROR_OBJECT (sink, "configure overlay for display %s failed.", sink->disp_info[i].name);
          osink_object_destroy_overlay (sink->osink_obj, sink->hoverlay[i]);
          sink->hoverlay[i] = NULL;
        }
      }
    }
  }

  gst_imx_video_overlay_prepare_window_handle (sink->imxoverlay, TRUE);

  return TRUE;
}

static gboolean
gst_overlay_sink_propose_allocation (GstBaseSink * bsink, GstQuery * query)
{
  GstOverlaySink *sink = GST_OVERLAY_SINK (bsink);
  guint size = 0;
  GstCaps *caps;
  gboolean need_pool;
  GstCaps *pcaps;
  GstStructure *config;

  gst_query_parse_allocation (query, &caps, &need_pool);

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

    GST_DEBUG_OBJECT (sink, "prosal set caps %" GST_PTR_FORMAT, caps);

    if (sink->pool) {
      // check caps, if caps not change, reuse previous pool
      config = gst_buffer_pool_get_config (sink->pool);
      gst_buffer_pool_config_get_params (config, &pcaps, &size, NULL, NULL);

      if (!gst_caps_is_equal (pcaps, caps)) {
        if (sink->prv_buffer) {
          gst_buffer_unref (sink->prv_buffer);
          sink->prv_buffer = NULL;
        }

        gst_buffer_pool_set_active (sink->pool, FALSE);
        gst_object_unref (sink->pool);
        sink->pool = NULL;
      }
      gst_structure_free (config);
    }

    if (!sink->pool) {
      if (gst_overlay_sink_setup_buffer_pool (sink, caps) < 0) {
        GST_ERROR_OBJECT (sink, "setup buffer pool failed.");
        return FALSE;
      }

      sink->pool_alignment_checked = FALSE;
      sink->no_phy_buffer = FALSE;
    }

    if (sink->pool) {
      config = gst_buffer_pool_get_config (sink->pool);
      gst_buffer_pool_config_get_params (config, &pcaps, &size, NULL, NULL);
      gst_structure_free (config);

      GST_DEBUG_OBJECT (sink, "propose_allocation, pool(%p).", sink->pool);

      gst_query_add_allocation_pool (query, sink->pool, size, sink->min_buffers, sink->max_buffers);
      gst_query_add_allocation_param (query, sink->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 (sink->composition_meta_enable)
    imx_video_overlay_composition_add_query_meta (query);

  return TRUE;
}

static gboolean
gst_overlay_sink_incrop_changed_and_set (GstVideoCropMeta *src, GstVideoCropMeta *dest)
{
  if (src->x != dest->x || src->y != dest->y || src->width != dest->width || src->height != dest->height) {
    dest->x = src->x;
    dest->y = src->y;
    dest->width = src->width;
    dest->height = src->height;
    return TRUE;
  }

  return FALSE;
}

static gint
gst_overlay_sink_input_config (GstOverlaySink *sink) 
{
  gint i;

  GST_DEBUG_OBJECT (sink, "cropmeta (%d, %d) --> (%d, %d)", 
      sink->cropmeta.x, sink->cropmeta.y, sink->cropmeta.width, sink->cropmeta.height);

  sink->surface_info.src.width = sink->video_align.padding_left + sink->w + sink->video_align.padding_right;
  sink->surface_info.src.height = sink->video_align.padding_top + sink->h + sink->video_align.padding_bottom;
  sink->surface_info.src.left = sink->video_align.padding_left + sink->cropmeta.x;
  sink->surface_info.src.top = sink->video_align.padding_top + sink->cropmeta.y;
  sink->surface_info.src.right = sink->surface_info.src.left + MIN (sink->w, sink->cropmeta.width);
  sink->surface_info.src.bottom = sink->surface_info.src.top + MIN (sink->h, sink->cropmeta.height);

  for (i=0; i<sink->disp_count; i++) {
    sink->config[i] = TRUE;
  }

  return 0;
}

static gint
gst_overlay_sink_check_alignment (GstOverlaySink *sink, GstBuffer *buffer)
{
  if (!sink->pool_alignment_checked) {
    /* one video frame which allocate by VPU will arrived video sink when video 
     * track selection. But pool still active and the pool is used for previous
     * video track. So check video physical meta first, if no, check pool. */
    GstPhyMemMeta *phymemmeta = NULL;
    memset (&sink->video_align, 0, sizeof(GstVideoAlignment));

    phymemmeta = GST_PHY_MEM_META_GET (buffer);
    if (phymemmeta) {
      sink->video_align.padding_right = phymemmeta->x_padding;
      sink->video_align.padding_bottom = phymemmeta->y_padding;
      GST_DEBUG_OBJECT (sink, "physical memory meta x_padding: %d y_padding: %d",
          phymemmeta->x_padding, phymemmeta->y_padding);
    } else {
      if (sink->pool && gst_buffer_pool_is_active (sink->pool)) {
        GstStructure *config;
        config = gst_buffer_pool_get_config (sink->pool);

        if (gst_buffer_pool_config_has_option (config, GST_BUFFER_POOL_OPTION_VIDEO_ALIGNMENT)) {
          gst_buffer_pool_config_get_video_alignment (config, &sink->video_align);
          GST_DEBUG_OBJECT (sink, "pool has alignment (%d, %d) , (%d, %d)",
              sink->video_align.padding_left, sink->video_align.padding_top,
              sink->video_align.padding_right, sink->video_align.padding_bottom);
        } else {
          GstCaps *caps = NULL;
          GstVideoInfo info;
          gst_buffer_pool_config_get_params(config, &caps, NULL, NULL, NULL);
          if (gst_video_info_from_caps(&info, caps)) {
            if (info.width > sink->w)
              sink->video_align.padding_right = info.width - sink->w;
            if (info.height > sink->h)
              sink->video_align.padding_bottom = info.height - sink->h;
          }
        }
        gst_structure_free (config);
      } else {
        GstVideoMeta *meta = gst_buffer_get_video_meta(buffer);
        if (meta) {
          if (meta->width > sink->w)
            sink->video_align.padding_right = meta->width - sink->w;
          switch (meta->format) {
            case GST_VIDEO_FORMAT_YUY2:
            case GST_VIDEO_FORMAT_YVYU:
            case GST_VIDEO_FORMAT_UYVY:
              if (meta->stride[0]/2 > sink->w)
                sink->video_align.padding_right = meta->stride[0]/2 - sink->w;
              break;
            default:
              GST_WARNING_OBJECT (sink, "Add more format to check stride.");
              break;
          }
          if (meta->height > sink->h)
            sink->video_align.padding_bottom = meta->height - sink->h;
          GST_DEBUG_OBJECT(sink, "video align right %d, bottom %d",
            sink->video_align.padding_right, sink->video_align.padding_bottom);
        }
      }
    }

    sink->pool_alignment_checked = TRUE;
    gst_overlay_sink_input_config (sink);
  }

  return 0;
}

static gint
gst_overlay_sink_get_surface_buffer (GstBuffer *gstbuffer, SurfaceBuffer *surface_buffer)
{
  PhyMemBlock * memblk;
  guint i, n_mem;

  if (!gstbuffer || ! surface_buffer)
    return -1;

  if (gst_is_dmabuf_memory (gst_buffer_peek_memory (gstbuffer, 0))) {
    memset (&surface_buffer->mem, 0, sizeof(PhyMemBlock));
    n_mem = gst_buffer_n_memory (gstbuffer);
    for (i = 0; i < n_mem; i++)
      surface_buffer->fd[i] = gst_dmabuf_memory_get_fd (gst_buffer_peek_memory (gstbuffer, i));
  } else if (gst_buffer_is_phymem (gstbuffer)) {
    memblk = gst_buffer_query_phymem_block (gstbuffer);
    if (!memblk) {
      GST_ERROR ("Can't get physical memory block from gstbuffer (%p).", gstbuffer);
      return -1;
    }

    surface_buffer->mem.size = memblk->size;
    surface_buffer->mem.vaddr = memblk->vaddr;
    surface_buffer->mem.paddr = memblk->paddr;
    surface_buffer->buf = NULL;
  } else if (GST_MEMORY_IS_PHYSICALLY_CONTIGUOUS(gst_buffer_peek_memory (gstbuffer, 0))) {
    GstMapInfo minfo;
    gst_buffer_map (gstbuffer, &minfo, GST_MAP_READ);
    memset (&surface_buffer->mem, 0, sizeof(PhyMemBlock));
    surface_buffer->mem.vaddr = minfo.data;
    surface_buffer->mem.size = minfo.size;
    gst_buffer_unmap (gstbuffer, &minfo);
  } else {
    GST_ERROR ("Shouldn't be here");
    return -1;
  }

  return 0;
}

static GstFlowReturn
gst_overlay_sink_show_frame (GstBaseSink * bsink, GstBuffer * buffer)
{
  GstOverlaySink *sink = GST_OVERLAY_SINK (bsink);
  gboolean not_overlay_buffer = FALSE;
  GstVideoCropMeta *cropmeta = NULL;
  GstVideoFrameFlags flags = GST_VIDEO_FRAME_FLAG_NONE;
  SurfaceBuffer surface_buffer = {0};
  gint i;
  GstVideoInfo info;
  GstCaps *caps = gst_pad_get_current_caps (GST_VIDEO_SINK_PAD (sink));
  gst_video_info_from_caps (&info, caps);

  if(!buffer)
  {
    GST_ERROR_OBJECT (sink, "Invalid buffer pointer.");
    gst_caps_unref (caps);
    return GST_FLOW_ERROR;
  }

  cropmeta = gst_buffer_get_video_crop_meta (buffer);
  surface_buffer.fd[0] = -1;

  if (!(gst_buffer_is_phymem (buffer)
        || gst_is_dmabuf_memory (gst_buffer_peek_memory (buffer, 0))
        || GST_MEMORY_IS_PHYSICALLY_CONTIGUOUS(gst_buffer_peek_memory (buffer, 0)))) {
    GST_DEBUG ("copy input frame to physical continues memory");
    // check if physical continues buffer
    GstBuffer *buffer2 = NULL;
    GstVideoFrame frame1, frame2;

    GST_DEBUG_OBJECT (sink, "not physical buffer.");

    gst_video_frame_map (&frame1, &info, buffer, GST_MAP_READ);

    GstCaps *new_caps = gst_video_info_to_caps(&frame1.info);
    gst_video_info_from_caps(&info, new_caps); //update the size info

    if (!sink->pool ||
        !gst_overlay_sink_buffer_pool_is_ok(sink->pool, new_caps,info.size))
    {
      if (sink->pool) {
        gst_object_unref(sink->pool);
        sink->pool = NULL;
      }
      gst_overlay_sink_setup_buffer_pool (sink, new_caps);
      GST_DEBUG_OBJECT(sink, "creating new input pool");
      gst_caps_unref (new_caps);

      if (!sink->pool) {
        gst_caps_unref (caps);
        return GST_FLOW_ERROR;
      }
    } else {
      gst_caps_unref (new_caps);
    }

    if (gst_buffer_pool_set_active (sink->pool, TRUE) != TRUE) {
      GST_ERROR_OBJECT (sink, "active pool(%p) failed.", sink->pool);
      gst_caps_unref (caps);
      return GST_FLOW_ERROR;
    }

    sink->pool_activated = TRUE;
    gst_buffer_pool_acquire_buffer (sink->pool, &buffer2, NULL);
    if (!buffer2) {
      GST_ERROR_OBJECT (sink, "acquire buffer from pool(%p) failed.", sink->pool);
      gst_caps_unref (caps);
      return GST_FLOW_ERROR;
    }

    gst_video_frame_map (&frame2, &info, buffer2, GST_MAP_WRITE);
    gst_video_frame_copy (&frame2, &frame1);
    gst_video_frame_unmap (&frame1);
    gst_video_frame_unmap (&frame2);

    GstVideoMeta *meta = gst_buffer_get_video_meta(buffer);
    if (meta) {
      gst_buffer_add_video_meta(buffer2, meta->flags,
                                meta->format, meta->width, meta->height);
    }

    if (sink->composition_meta_enable
        && imx_video_overlay_composition_has_meta(buffer)) {
      imx_video_overlay_composition_copy_meta(buffer2, buffer,
          info.width, info.height, info.width, info.height);
    }

    buffer = buffer2;
    sink->no_phy_buffer = TRUE;
  } else {
    gst_buffer_ref (buffer);
    sink->no_phy_buffer = FALSE;
  }

  gst_caps_unref (caps);

  if (gst_overlay_sink_get_surface_buffer (buffer, &surface_buffer) < 0) {
    GST_ERROR_OBJECT (sink, "Can't get surface buffer from gst buffer (%p).", buffer);
    if (sink->prv_buffer)
      gst_buffer_unref (sink->prv_buffer);
    sink->prv_buffer = buffer;
    return GST_FLOW_OK;
  }

  if (sink->composition_meta_enable
      && imx_video_overlay_composition_has_meta(buffer)) {
    surface_buffer.buf = buffer;
  } else {
    surface_buffer.buf = NULL;
  }

  GST_DEBUG_OBJECT (sink, "show gstbuffer (%p), surface_buffer vaddr (%p) paddr (%p).",
      buffer, surface_buffer.mem.vaddr, surface_buffer.mem.paddr);

  gst_overlay_sink_check_alignment (sink, buffer);

  if ((cropmeta && gst_overlay_sink_incrop_changed_and_set (cropmeta, &sink->cropmeta))) {
    gst_overlay_sink_input_config (sink);
  }

  for (i=0; i<sink->disp_count; i++) {
    if (sink->disp_on[i]) {
      if (sink->config[i]) {
        GST_DEBUG_OBJECT (sink, "config display %s for surface updated.", sink->disp_info[i].name);
        gst_overlay_sink_output_config (sink, i);
        osink_object_config_overlay (sink->osink_obj, sink->hoverlay[i], &sink->surface_info);
        sink->config[i] = FALSE;
      }

      if (osink_object_update_overlay (sink->osink_obj, sink->hoverlay[i], &surface_buffer) < 0) {
        GST_ERROR_OBJECT (sink, "update overlay buffer (%p) for display (%s) failed.", buffer, sink->disp_info[i].name);
      }
    }
  }

  if (sink->no_phy_buffer && sink->prv_buffer && sink->composition_meta_enable
      && imx_video_overlay_composition_has_meta(sink->prv_buffer)) {
    imx_video_overlay_composition_remove_meta(sink->prv_buffer);
  }
  if (sink->prv_buffer)
    gst_buffer_unref (sink->prv_buffer);

  sink->prv_buffer = buffer;

  sink->frame_showed ++;

  return GST_FLOW_OK;
}

static void
gst_overlay_sink_finalize (GstOverlaySink * overlay_sink)
{
  if (overlay_sink->imxoverlay) {
    gst_imx_video_overlay_finalize (overlay_sink->imxoverlay);
    overlay_sink->imxoverlay = NULL;
  }

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

static void
gst_overlay_sink_install_properties (GObjectClass *gobject_class)
{
  gpointer osink_obj = (gpointer)osink_object_new ();
  gint display_count = 0;
  gint prop, i;
  gchar *prop_name;
  gboolean defaul_value = FALSE;

  if (!osink_obj)
    return;

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

  display_count = osink_object_get_display_count (osink_obj);
  prop = OVERLAY_SINK_PROP_DISP_ON_0;

  for (i = 0; i < display_count; i++) {
    prop = i * OVERLAY_SINK_PROP_DISP_LENGTH + OVERLAY_SINK_PROP_DISP_ON_0;
    gchar *name;
    DisplayInfo info;

    if (osink_object_get_display_info (osink_obj, &info, i) < 0) {
      name = "UNKNOWN";
      info.width = info.height = G_MAXINT32;
    } else {
      name = info.name;
    }
    
    prop_name = g_strdup_printf ("display-%s", name);
    if (i == 0)
      defaul_value = TRUE;
    g_object_class_install_property (gobject_class, prop,
        g_param_spec_boolean (prop_name,
          prop_name,
          "enable/disable show video to the display", defaul_value, G_PARAM_READWRITE));
    g_free (prop_name);
    prop++;

    if (i == 0)
      prop_name = g_strdup_printf ("overlay-left");
    else
      prop_name = g_strdup_printf ("overlay-left-%d", i);
    g_object_class_install_property (gobject_class, prop,
        g_param_spec_int (prop_name,
          prop_name,
          "get/set the left position of the video to the display",
          G_MININT32, G_MAXINT32, 0, G_PARAM_READWRITE));
    g_free (prop_name);
    prop++;

    if (i == 0)
      prop_name = g_strdup_printf ("overlay-top");
    else
      prop_name = g_strdup_printf ("overlay-top-%d", i);
    g_object_class_install_property (gobject_class, prop,
        g_param_spec_int (prop_name,
          prop_name,
          "get/set the right postion of the video to the display",
          G_MININT32, G_MAXINT32, 0, G_PARAM_READWRITE));
    g_free (prop_name);
    prop++;

    if (i == 0)
      prop_name = g_strdup_printf ("overlay-width");
    else
      prop_name = g_strdup_printf ("overlay-width-%d", i);
    g_object_class_install_property (gobject_class, prop,
        g_param_spec_int (prop_name,
          prop_name,
          "get/set the width of the video to the display",
          0, G_MAXINT32, info.width, G_PARAM_READWRITE));
    g_free (prop_name);
    prop++;

    if (i == 0)
      prop_name = g_strdup_printf ("overlay-height");
    else
      prop_name = g_strdup_printf ("overlay-height-%d", i);
    g_object_class_install_property (gobject_class, prop,
        g_param_spec_int (prop_name,
          prop_name,
          "get/set the height of the video to the display",
          0, G_MAXINT32, info.height, G_PARAM_READWRITE));
    g_free (prop_name);
    prop++;

    if (i == 0)
      prop_name = g_strdup_printf ("rotate");
    else
      prop_name = g_strdup_printf ("rotate-%d", i);
    g_object_class_install_property (gobject_class, prop,
        g_param_spec_enum (prop_name,
          prop_name,
          "get/set the rotation of the video", GST_TYPE_IMX_ROTATE_METHOD, DEFAULT_IMX_ROTATE_METHOD,
          G_PARAM_READWRITE));
    g_free (prop_name);
    prop++;

    if (i == 0)
      prop_name = g_strdup_printf ("reconfig");
    else
      prop_name = g_strdup_printf ("reconfig-%d", i);
    g_object_class_install_property (gobject_class, prop,
        g_param_spec_boolean (prop_name,
          prop_name,
          "trigger reconfig of video output x/y/w/h/rot in the fly", FALSE, G_PARAM_READWRITE));
    g_free (prop_name);
    prop++;

    if (i == 0)
      prop_name = g_strdup_printf ("force-aspect-ratio");
    else
      prop_name = g_strdup_printf ("force-aspect-ratio-%d", i);
    g_object_class_install_property (gobject_class, prop,
        g_param_spec_boolean (prop_name, "Force aspect ratio",
          "When enabled, scaling will respect original aspect ratio",
          TRUE, G_PARAM_READWRITE));
    g_free (prop_name);
    prop++;

    if (i == 0)
      prop_name = g_strdup_printf ("zorder");
    else
      prop_name = g_strdup_printf ("zorder-%d", i);
    g_object_class_install_property (gobject_class, prop,
        g_param_spec_int (prop_name, prop_name, "get/set overlay zorder",
        0, G_MAXINT, 0, G_PARAM_READWRITE));
    g_free (prop_name);
    prop++;
  }

  osink_object_unref (osink_obj);

  return;
}

static GstCaps*
gst_overlay_sink_get_static_caps ()
{
  GstCaps *caps;
  gint i;

#define CAPS_NUM 9
  gchar *caps_str[] = {
    (gchar*)GST_VIDEO_CAPS_MAKE("I420"),
    (gchar*)GST_VIDEO_CAPS_MAKE("NV12"),
    (gchar*)GST_VIDEO_CAPS_MAKE("YV12"),
    (gchar*)GST_VIDEO_CAPS_MAKE("NV16"),
    (gchar*)GST_VIDEO_CAPS_MAKE("UYVY"),
    (gchar*)GST_VIDEO_CAPS_MAKE("YUY2"),
    (gchar*)GST_VIDEO_CAPS_MAKE("RGB16"),
    (gchar*)GST_VIDEO_CAPS_MAKE("RGBA"),
    (gchar*)GST_VIDEO_CAPS_MAKE("RGBx")
  };

  /* make a list of all available caps */
  caps = gst_caps_new_empty ();
  for(i=0; i<CAPS_NUM; i++) {
    GstStructure *structure = gst_structure_from_string(caps_str[i], NULL);
    gst_caps_append_structure (caps, structure);
  }

  caps = gst_caps_simplify(caps);

  imx_video_overlay_composition_add_caps(caps);

  return caps;
}

static GstCaps *gst_overlay_sink_get_caps (GstBaseSink *sink, GstCaps* filter)
{
  GstOverlaySink *overlay_sink = GST_OVERLAY_SINK (sink);
  GstCaps *tmp;

  GstCaps *caps = gst_overlay_sink_get_static_caps();
  if (!overlay_sink->composition_meta_enable)
    imx_video_overlay_composition_remove_caps(caps);

  if (filter) {
    tmp = gst_caps_intersect (caps, filter);
    gst_caps_unref(caps);
    caps = tmp;
  }

  return caps;
}

//type functions

static void
gst_overlay_sink_class_init (GstOverlaySinkClass * klass)
{
  GObjectClass *gobject_class;
  GstElementClass *element_class;
  GstBaseSinkClass *basesink_class;
  GstVideoSinkClass *videosink_class;

  gobject_class = G_OBJECT_CLASS (klass);
  element_class = GST_ELEMENT_CLASS (klass);
  basesink_class = GST_BASE_SINK_CLASS (klass);
  videosink_class = GST_VIDEO_SINK_CLASS (klass);

  gobject_class->finalize = (GObjectFinalizeFunc) gst_overlay_sink_finalize;
  gobject_class->set_property = gst_overlay_sink_set_property;
  gobject_class->get_property = gst_overlay_sink_get_property;

  element_class->change_state = gst_overlay_sink_change_state;

  gst_overlay_sink_install_properties (gobject_class);

  gst_element_class_add_pad_template (element_class,
      gst_pad_template_new ("sink", GST_PAD_SINK, GST_PAD_ALWAYS, gst_overlay_sink_get_static_caps ()));

  basesink_class->get_caps = GST_DEBUG_FUNCPTR (gst_overlay_sink_get_caps);
  basesink_class->set_caps = GST_DEBUG_FUNCPTR (gst_overlay_sink_set_caps);
  basesink_class->propose_allocation = GST_DEBUG_FUNCPTR (gst_overlay_sink_propose_allocation);
  videosink_class->show_frame = GST_DEBUG_FUNCPTR (gst_overlay_sink_show_frame);

  gst_element_class_set_static_metadata (element_class,
      "IMX Video (video compositor) Sink", "Sink/Video",
      "Composite multiple video frames into one and display on IMX SoC", IMX_GST_PLUGIN_AUTHOR);

}

static void
gst_overlay_sink_init (GstOverlaySink * overlay_sink)
{
  gint i;

  overlay_sink->osink_obj = NULL;
  overlay_sink->pool = NULL;
  overlay_sink->allocator = NULL;
  overlay_sink->min_buffers = 3;
  overlay_sink->max_buffers = 30;
  overlay_sink->prv_buffer = NULL;
  memset (&overlay_sink->surface_info, 0, sizeof (SurfaceInfo));

  for (i=0; i<MAX_DISPLAY; i++) {
    overlay_sink->hoverlay[i] = NULL;
    overlay_sink->disp_on[i] = FALSE;
    overlay_sink->config[i] = FALSE;
    memset(&overlay_sink->overlay[i], 0, sizeof (OverlayInfo));
    overlay_sink->overlay[i].keep_ratio = TRUE;
    memset(&overlay_sink->pre_overlay_info[i], 0, sizeof (OverlayInfo));
  }

  overlay_sink->disp_on[0] = TRUE;
  overlay_sink->no_phy_buffer = FALSE;
  overlay_sink->pool_activated = FALSE;
  overlay_sink->pool_alignment_checked = FALSE;
  overlay_sink->composition_meta_enable = OVERLAY_SINK_COMPOMETA_DEFAULT;

  overlay_sink->imxoverlay = gst_imx_video_overlay_init ((GstElement *)overlay_sink,
                                              overlay_sink_update_video_geo,
                                              overlay_sink_config_color_key,
                                              overlay_sink_config_global_alpha);

  g_print("====== OVERLAYSINK: %s build on %s %s. ======\n",  (VERSION),__DATE__,__TIME__);

}


static gboolean
plugin_init (GstPlugin * plugin)
{
  GST_DEBUG_CATEGORY_INIT (overlay_sink_debug, "overlaysink", 0, "Freescale IMX video overlay(compositor) sink element");

  if (HAS_G2D()) {
    if (!gst_element_register (plugin, "overlaysink", IMX_GST_PLUGIN_RANK + 1,
          GST_TYPE_OVERLAY_SINK))
      return FALSE;

    return TRUE; 
  } else {
    return FALSE;
  }
}

IMX_GST_PLUGIN_DEFINE (overlaysink, "IMX SoC video compositing sink", plugin_init);

