Fixing caps negotiation issue in videoconvert
authorBarun Kumar Singh <barun.singh@samsung.com>
Fri, 11 Dec 2015 11:23:23 +0000 (16:53 +0530)
committerBarun Kumar Singh <barun.singh@samsung.com>
Mon, 14 Dec 2015 09:07:57 +0000 (14:37 +0530)
Adding review comments.

Signed-off-by: Barun Kr. Singh <barun.singh@samsung.com>
Change-Id: I92340394b460496c6b66e34496a88cc8d8caa54f

gst-libs/gst/video/Makefile.am
gst-libs/gst/video/video-converter.c
gst/videoconvert/gsttbmbufferpool.c
gst/videoconvert/gsttbmbufferpool.h
gst/videoconvert/gstvideoconvert.c
gst/videoconvert/gstvideoconvert.h

index 2b266d4..165878d 100644 (file)
@@ -92,6 +92,13 @@ libgstvideo_@GST_API_VERSION@_la_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) $(GST_BASE_
 libgstvideo_@GST_API_VERSION@_la_LIBADD = $(GST_BASE_LIBS) $(GST_LIBS) $(ORC_LIBS) $(LIBM)
 libgstvideo_@GST_API_VERSION@_la_LDFLAGS = $(GST_LIB_LDFLAGS) $(GST_ALL_LDFLAGS) $(GST_LT_LDFLAGS)
 
+if BOARD_USE_TBM_BUF
+libgstvideo_@GST_API_VERSION@_la_CFLAGS += -DUSE_TBM_BUFFER $(MMCOMMON_CFLAGS) $(TBM_CFLAGS)
+libgstvideo_@GST_API_VERSION@_la_LIBADD += $(TBM_LIBS) $(MM_COMMON_LIBS)
+libgstvideo_@GST_API_VERSION@_la_LDFLAGS += $(TBM_LDFLAGS) $(MM_COMMON_LDFLAGS)
+endif
+
+
 include $(top_srcdir)/common/gst-glib-gen.mak
 
 if HAVE_INTROSPECTION
index 31d51e4..4b58285 100644 (file)
@@ -27,6 +27,7 @@
 #include <glib.h>
 #include <string.h>
 #include <math.h>
+#include <mmf/mm_types.h>
 
 #include "video-orc.h"
 
@@ -3899,6 +3900,62 @@ convert_scale_planes (GstVideoConverter * convert,
   convert_fill_border (convert, dest);
 }
 
+static void
+convert_I420_SN12 (GstVideoConverter * convert, GstVideoFrame * src,
+    const GstVideoFrame *dest )
+{
+  MMVideoBuffer *mm_video_buf = NULL;
+  GstMemory *mem = NULL;
+  void *mm_data = NULL;
+  guint8 *mY, *mUV, *Y, *U, *V;
+  gint l1, l2;
+  gboolean interlaced = GST_VIDEO_FRAME_IS_INTERLACED (src);
+
+  gint width = convert->in_width;
+  gint height = convert->in_height;
+
+  mY = mUV = Y = U = V = NULL;
+
+  if(gst_buffer_n_memory(dest->buffer) >= 2) {
+      GstMapInfo map_info = GST_MAP_INFO_INIT;
+      mem = gst_buffer_peek_memory (dest->buffer, 1);
+      if (mem != NULL) {
+          gst_memory_map(mem, &map_info, GST_MAP_WRITE);
+          mm_data = map_info.data;
+          gst_memory_unmap(mem, &map_info);
+          mm_video_buf = (MMVideoBuffer*) mm_data;
+      }
+  }
+
+  /* convert from I420 TO SN12/NV12 format here.. */
+  if(mm_video_buf == NULL) {
+      GST_ERROR(" mm_video_buffer is NULL");
+      return;
+  }
+  mY = mm_video_buf->data[0];
+  mUV = mm_video_buf->data[1];
+
+  for (int i = 0; i < GST_ROUND_DOWN_2 (height); i += 2) {
+    GET_LINE_OFFSETS (interlaced, i, l1, l2);
+
+    Y = FRAME_GET_Y_LINE (src, l1);
+    memcpy(mY, Y, width);
+    mY += width;
+    Y = FRAME_GET_Y_LINE (src, l2);
+    memcpy(mY, Y, width);
+    mY += width;
+
+    U = FRAME_GET_U_LINE (src, i >> 1);
+    V = FRAME_GET_V_LINE (src, i >> 1);
+    for(int j = 0; j < (width + 1) / 2; j++) {
+        *mUV++ = *U++;
+        *mUV++ = *V++;
+    }
+  }
+
+}
+
+
 static GstVideoFormat
 get_scale_format (GstVideoFormat format, gint plane)
 {
@@ -3976,6 +4033,8 @@ get_scale_format (GstVideoFormat format, gint plane)
     case GST_VIDEO_FORMAT_A422_10LE:
     case GST_VIDEO_FORMAT_A444_10BE:
     case GST_VIDEO_FORMAT_A444_10LE:
+    case GST_VIDEO_FORMAT_SN12:
+    case GST_VIDEO_FORMAT_ST12:
       res = format;
       g_assert_not_reached ();
       break;
@@ -4024,6 +4083,11 @@ setup_scale (GstVideoConverter * convert)
   in_format = GST_VIDEO_INFO_FORMAT (in_info);
   out_format = GST_VIDEO_INFO_FORMAT (out_info);
 
+  if(out_format == GST_VIDEO_FORMAT_SN12) {
+    /* do nothing for SN12 output format */
+    return TRUE;
+  }
+
   switch (in_format) {
     case GST_VIDEO_FORMAT_RGB15:
     case GST_VIDEO_FORMAT_RGB16:
@@ -4040,6 +4104,8 @@ setup_scale (GstVideoConverter * convert)
         return FALSE;
       }
       break;
+    case GST_VIDEO_FORMAT_SN12:
+      return TRUE; /* do nothing for SN12 format */
     default:
       break;
   }
@@ -4369,6 +4435,8 @@ static const VideoTransform transforms[] = {
       TRUE, FALSE, FALSE, FALSE, 0, 0, convert_scale_planes},
   {GST_VIDEO_FORMAT_I420, GST_VIDEO_FORMAT_Y444, FALSE, FALSE, FALSE, TRUE,
       TRUE, FALSE, FALSE, FALSE, 0, 0, convert_scale_planes},
+  {GST_VIDEO_FORMAT_I420, GST_VIDEO_FORMAT_SN12, FALSE, FALSE, FALSE, TRUE,
+      TRUE, FALSE, FALSE, FALSE, 0, 0, convert_I420_SN12},
   {GST_VIDEO_FORMAT_I420, GST_VIDEO_FORMAT_GRAY8, FALSE, FALSE, FALSE, TRUE,
       TRUE, FALSE, FALSE, FALSE, 0, 0, convert_scale_planes},
   {GST_VIDEO_FORMAT_I420, GST_VIDEO_FORMAT_A420, FALSE, FALSE, FALSE, TRUE,
index c874825..ac5132b 100644 (file)
@@ -2,29 +2,76 @@
 #include "gsttbmbufferpool.h"
 #include <gst/video/gstvideofilter.h>
 
-static GQuark gst_mm_buffer_data_quark = 0;
+int new_calc_plane(int width, int height)
+{
+    int mbX, mbY;
+
+    mbX = DIV_ROUND_UP(width, S5P_FIMV_NUM_PIXELS_IN_MB_ROW);
+    mbY = DIV_ROUND_UP(height, S5P_FIMV_NUM_PIXELS_IN_MB_COL);
+
+    if (width * height < S5P_FIMV_MAX_FRAME_SIZE)
+      mbY = (mbY + 1) / 2 * 2;
+
+    return ((mbX * S5P_FIMV_NUM_PIXELS_IN_MB_COL) *
+     (mbY * S5P_FIMV_NUM_PIXELS_IN_MB_ROW));
+}
+
+int new_calc_yplane(int width, int height)
+{
+    return (ALIGN_TO_4KB(new_calc_plane(width, height) +
+              S5P_FIMV_D_ALIGN_PLANE_SIZE));
+}
 
+int new_calc_uvplane(int width, int height)
+{
+    return (ALIGN_TO_4KB((new_calc_plane(width, height) >> 1) +
+              S5P_FIMV_D_ALIGN_PLANE_SIZE));
+}
 
-int calc_yplane(int width, int height)
+int
+calc_plane(int width, int height)
 {
     int mbX, mbY;
 
-    mbX = DIV_ROUND_UP(width, 16);
-    mbY = DIV_ROUND_UP(height, 16);
+    mbX = ALIGN(width, S5P_FIMV_NV12MT_HALIGN);
+    mbY = ALIGN(height, S5P_FIMV_NV12MT_VALIGN);
 
-    return (ALIGN((mbX * mbY) * 256, 256) + 256);
+    return ALIGN(mbX * mbY, S5P_FIMV_DEC_BUF_ALIGN);
 }
 
-int calc_uvplane(int width, int height)
+int
+calc_yplane(int width, int height)
 {
     int mbX, mbY;
 
-    mbX = DIV_ROUND_UP(width, 16);
-    mbY = DIV_ROUND_UP(height, 16);
+    mbX = ALIGN(width + 24, S5P_FIMV_NV12MT_HALIGN);
+    mbY = ALIGN(height + 16, S5P_FIMV_NV12MT_VALIGN);
 
-    return (ALIGN((mbX * mbY) * 128, 256) + 128);
+    return ALIGN(mbX * mbY, S5P_FIMV_DEC_BUF_ALIGN);
 }
 
+int
+calc_uvplane(int width, int height)
+{
+    int mbX, mbY;
+
+    mbX = ALIGN(width + 16, S5P_FIMV_NV12MT_HALIGN);
+    mbY = ALIGN(height + 4, S5P_FIMV_NV12MT_VALIGN);
+
+    return ALIGN((mbX * mbY)>>1, S5P_FIMV_DEC_BUF_ALIGN);
+}
+
+int
+gst_calculate_y_size(int width, int height)
+{
+   return CHOOSE_MAX_SIZE(calc_yplane(width,height),new_calc_yplane(width,height));
+}
+
+int
+gst_calculate_uv_size(int width, int height)
+{
+   return CHOOSE_MAX_SIZE(calc_uvplane(width,height),new_calc_uvplane(width,height));
+}
 
 static GstMemory *
 gst_mm_memory_allocator_alloc_dummy (GstAllocator * allocator, gsize size,
@@ -143,7 +190,7 @@ gst_mm_buffer_pool_stop (GstBufferPool * bpool)
 {
   GstMMBufferPool *pool = GST_MM_BUFFER_POOL (bpool);
 
-  if(gst_buffer_pool_is_active (bpool) == TRUE)
+  if(gst_buffer_pool_is_active (pool) == TRUE)
       return FALSE;
   /* Remove any buffers that are there */
   if(pool->buffers != NULL){
@@ -163,6 +210,8 @@ gst_mm_buffer_pool_stop (GstBufferPool * bpool)
 static const gchar **
 gst_mm_buffer_pool_get_options (GstBufferPool * bpool)
 {
+  static const gchar *raw_video_options[] =
+      { GST_BUFFER_POOL_OPTION_VIDEO_META, NULL };
   static const gchar *options[] = { NULL };
   return options;
 }
@@ -203,6 +252,13 @@ no_caps:
     GST_WARNING_OBJECT (pool, "no caps in config");
     return FALSE;
   }
+wrong_video_caps:
+  {
+    GST_OBJECT_UNLOCK (pool);
+    GST_WARNING_OBJECT (pool,
+        "failed getting geometry from caps %" GST_PTR_FORMAT, caps);
+    return FALSE;
+  }
 }
 
 static GstFlowReturn
@@ -222,7 +278,7 @@ gst_mm_buffer_pool_alloc_buffer (GstBufferPool * bpool,
   mm_buf = (GstMMBuffer*) malloc(sizeof(GstMMBuffer));
   mem = gst_mm_memory_allocator_alloc (pool->allocator, 0, mm_buf);
   buf = gst_buffer_new ();
-  buf->pool = bpool;
+  buf->pool = pool;
   mem->size = sizeof(GstMMBuffer);
   mem->offset = 0;
   gst_buffer_append_memory (buf, mem);
@@ -235,7 +291,7 @@ gst_mm_buffer_pool_alloc_buffer (GstBufferPool * bpool,
         GST_VIDEO_INFO_N_PLANES (&pool->video_info), offset, stride);
 
   g_ptr_array_add (pool->buffers, buf);
-  GST_DEBUG(" buffer:[%p], mm_buffer:[%p], mem:[%p] width:[%d] height:[%d]",buf, mm_buf, mem, GST_VIDEO_INFO_WIDTH (&pool->video_info),GST_VIDEO_INFO_HEIGHT (&pool->video_info));
+  GST_ERROR(" buffer:[%p], mm_buffer:[%p], mem:[%p] width:[%d] height:[%d]",buf, mm_buf, mem, GST_VIDEO_INFO_WIDTH (&pool->video_info),GST_VIDEO_INFO_HEIGHT (&pool->video_info));
 
   gst_mini_object_set_qdata (GST_MINI_OBJECT_CAST (buf),
       gst_mm_buffer_data_quark, mm_buf, NULL);
@@ -248,17 +304,16 @@ gst_mm_buffer_pool_alloc_buffer (GstBufferPool * bpool,
     mm_video_buf->type = MM_VIDEO_BUFFER_TYPE_TBM_BO;
     mm_video_buf->plane_num = 2;
     /* Setting Y plane size */
-    mm_video_buf->size[0] = calc_yplane(width, height);
+    mm_video_buf->size[0] = gst_calculate_y_size(width, height);
     /* Setting UV plane size */
-    mm_video_buf->size[1] = calc_uvplane(width, height);
+    mm_video_buf->size[1] = gst_calculate_uv_size(width, height);
     mm_video_buf->handle.bo[0] = tbm_bo_alloc(pool->hTBMBufMgr, mm_video_buf->size[0], TBM_BO_WC);
     mm_video_buf->handle.bo[1] = tbm_bo_alloc(pool->hTBMBufMgr, mm_video_buf->size[1], TBM_BO_WC);
 
     mm_video_buf->handle.dmabuf_fd[0] = (tbm_bo_get_handle(mm_video_buf->handle.bo[0], TBM_DEVICE_MM)).u32;
     mm_video_buf->handle.dmabuf_fd[1] = (tbm_bo_get_handle(mm_video_buf->handle.bo[1], TBM_DEVICE_MM)).u32;
-
-    mm_video_buf->handle.paddr[0] = (tbm_bo_map(mm_video_buf->handle.bo[0], TBM_DEVICE_CPU,TBM_OPTION_WRITE)).ptr;
-    mm_video_buf->handle.paddr[1] = (tbm_bo_map(mm_video_buf->handle.bo[1], TBM_DEVICE_CPU,TBM_OPTION_WRITE)).ptr;
+    mm_video_buf->data[0] = (tbm_bo_map(mm_video_buf->handle.bo[0], TBM_DEVICE_CPU,TBM_OPTION_WRITE)).ptr;
+    mm_video_buf->data[1] = (tbm_bo_map(mm_video_buf->handle.bo[1], TBM_DEVICE_CPU,TBM_OPTION_WRITE)).ptr;
     /* Setting stride height & width for Y plane */
     mm_video_buf->stride_height[0] = mm_video_buf->height[0] = height;
     mm_video_buf->stride_width[0] = mm_video_buf->width[0] = width;
index 5ff3e37..ee2f78d 100644 (file)
@@ -15,9 +15,6 @@
 #include <tbm_bufmgr.h>
 #endif
 
-#define ALIGN(x, a)       (((x) + (a) - 1) & ~((a) - 1))
-#define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d))
-
 typedef struct _GstMMVideoMemory                GstMMVideoMemory;
 typedef struct _GstMMVideoMemoryAllocator       GstMMVideoMemoryAllocator;
 typedef struct _GstMMVideoMemoryAllocatorClass  GstMMVideoMemoryAllocatorClass;
@@ -51,7 +48,7 @@ struct _GstMMBuffer
 #define GST_MM_VIDEO_MEMORY_TYPE "mmvideobuffer"
 
 
-/*static GQuark gst_mm_buffer_data_quark = 0;*/
+static GQuark gst_mm_buffer_data_quark = 0;
 
 #define GST_MM_BUFFER_POOL(pool) ((GstMMBufferPool *) pool)
 typedef struct _GstMMBufferPool GstMMBufferPool;
@@ -102,12 +99,35 @@ struct _GstMMBufferPoolClass
 GstBufferPool *
 gst_mm_buffer_pool_new (GstElement * element );
 
-int
-calc_yplane(int width, int height);
+#ifdef USE_TBM_BUFFER
+
+/*MFC Buffer alignment macros*/
+#define S5P_FIMV_DEC_BUF_ALIGN                  (8 * 1024)
+#define S5P_FIMV_ENC_BUF_ALIGN                  (8 * 1024)
+#define S5P_FIMV_NV12M_HALIGN                   16
+#define S5P_FIMV_NV12M_LVALIGN                  16
+#define S5P_FIMV_NV12M_CVALIGN                  8
+#define S5P_FIMV_NV12MT_HALIGN                  128
+#define S5P_FIMV_NV12MT_VALIGN                  64
+#define S5P_FIMV_NV12M_SALIGN                   2048
+#define S5P_FIMV_NV12MT_SALIGN                  8192
 
-int
-calc_uvplane(int width, int height);
+#define ALIGN(x, a)       (((x) + (a) - 1) & ~((a) - 1))
 
+/* Buffer alignment defines */
+#define SZ_1M                                   0x00100000
+#define S5P_FIMV_D_ALIGN_PLANE_SIZE             64
+
+#define S5P_FIMV_MAX_FRAME_SIZE                 (2 * SZ_1M)
+#define S5P_FIMV_NUM_PIXELS_IN_MB_ROW           16
+#define S5P_FIMV_NUM_PIXELS_IN_MB_COL           16
+
+/* Macro */
+#define ALIGN_TO_4KB(x)   ((((x) + (1 << 12) - 1) >> 12) << 12)
+#define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d))
+#define CHOOSE_MAX_SIZE(a,b) ((a) > (b) ? (a) : (b))
+
+#endif
 
 #if 0
 
index 11d560d..8bf9578 100644 (file)
 #include <gst/video/gstvideometa.h>
 #include <gst/video/gstvideopool.h>
 
+#ifdef USE_TBM_BUFFER
+#include <mm_types.h>
+#include "gsttbmbufferpool.h"
+#endif
+
 #include <string.h>
 
 GST_DEBUG_CATEGORY (videoconvert_debug);
@@ -83,13 +88,20 @@ enum
 };
 
 #define CSP_VIDEO_CAPS GST_VIDEO_CAPS_MAKE (GST_VIDEO_FORMATS_ALL) ";" \
-    GST_VIDEO_CAPS_MAKE_WITH_FEATURES ("ANY", GST_VIDEO_FORMATS_ALL)
+    GST_VIDEO_CAPS_MAKE_WITH_FEATURES ("ANY", GST_VIDEO_FORMATS_ALL) ";" \
+    GST_VIDEO_CAPS_MAKE("{ SUYV , SYVY , S420 , ITLV }") ";" \
+    GST_VIDEO_CAPS_MAKE_WITH_FEATURES ("ANY", "{ SUYV , SYVY , S420 , ITLV }")
+
+#define CSP_VIDEO_SRC_CAPS GST_VIDEO_CAPS_MAKE (GST_VIDEO_FORMATS_ALL) ";" \
+    GST_VIDEO_CAPS_MAKE_WITH_FEATURES ("ANY", GST_VIDEO_FORMATS_ALL) ";" \
+    GST_VIDEO_CAPS_MAKE("{ SUYV , SYVY , S420 , ITLV , SN12 }") ";" \
+    GST_VIDEO_CAPS_MAKE_WITH_FEATURES ("ANY", "{ SUYV , SYVY , S420 , ITLV , SN12 }")
 
 static GstStaticPadTemplate gst_video_convert_src_template =
 GST_STATIC_PAD_TEMPLATE ("src",
     GST_PAD_SRC,
     GST_PAD_ALWAYS,
-    GST_STATIC_CAPS (CSP_VIDEO_CAPS)
+    GST_STATIC_CAPS (CSP_VIDEO_SRC_CAPS)
     );
 
 static GstStaticPadTemplate gst_video_convert_sink_template =
@@ -110,6 +122,13 @@ static gboolean gst_video_convert_set_info (GstVideoFilter * filter,
 static GstFlowReturn gst_video_convert_transform_frame (GstVideoFilter * filter,
     GstVideoFrame * in_frame, GstVideoFrame * out_frame);
 
+#ifdef USE_TBM_BUFFER
+static gboolean gst_video_convert_decide_allocation (GstBaseTransform * bsrc,
+    GstQuery * query);
+static GstFlowReturn gst_video_convert_prepare_output_buffer (GstBaseTransform * trans,
+    GstBuffer *input, GstBuffer **outbuf);
+#endif
+
 /* copies the given caps */
 static GstCaps *
 gst_video_convert_caps_remove_format_info (GstCaps * caps)
@@ -494,7 +513,13 @@ gst_video_convert_finalize (GObject * obj)
   if (space->convert) {
     gst_video_converter_free (space->convert);
   }
-
+#ifdef USE_TBM_BUFFER
+  if(space->tbm_buffer_pool) {
+     gst_buffer_pool_set_active (space->tbm_buffer_pool, FALSE);
+     gst_object_unref (space->tbm_buffer_pool);
+     space->tbm_buffer_pool = NULL;
+  }
+#endif
   G_OBJECT_CLASS (parent_class)->finalize (obj);
 }
 
@@ -537,6 +562,11 @@ gst_video_convert_class_init (GstVideoConvertClass * klass)
   gstvideofilter_class->transform_frame =
       GST_DEBUG_FUNCPTR (gst_video_convert_transform_frame);
 
+#ifdef USE_TBM_BUFFER
+  gstbasetransform_class->decide_allocation = gst_video_convert_decide_allocation;
+  gstbasetransform_class->prepare_output_buffer = gst_video_convert_prepare_output_buffer;
+#endif
+
   g_object_class_install_property (gobject_class, PROP_DITHER,
       g_param_spec_enum ("dither", "Dither", "Apply dithering while converting",
           gst_video_dither_method_get_type (), DEFAULT_PROP_DITHER,
@@ -581,6 +611,9 @@ gst_video_convert_class_init (GstVideoConvertClass * klass)
 static void
 gst_video_convert_init (GstVideoConvert * space)
 {
+#ifdef USE_TBM_BUFFER
+  space->tbm_buffer_pool = NULL;
+#endif
   space->dither = DEFAULT_PROP_DITHER;
   space->dither_quantization = DEFAULT_PROP_DITHER_QUANTIZATION;
   space->chroma_resampler = DEFAULT_PROP_CHROMA_RESAMPLER;
@@ -688,12 +721,90 @@ gst_video_convert_transform_frame (GstVideoFilter * filter,
       "doing colorspace conversion from %s -> to %s",
       GST_VIDEO_INFO_NAME (&filter->in_info),
       GST_VIDEO_INFO_NAME (&filter->out_info));
-
   gst_video_converter_frame (space->convert, in_frame, out_frame);
 
   return GST_FLOW_OK;
 }
 
+#ifdef USE_TBM_BUFFER
+
+static gboolean
+gst_video_convert_decide_allocation (GstBaseTransform * trans,
+    GstQuery * query)
+{
+
+  GstVideoConvert *vc = NULL;
+  GstVideoFilter *filter = GST_VIDEO_FILTER_CAST (trans);
+  vc = GST_VIDEO_CONVERT_CAST(trans);
+
+  if(filter->out_info.finfo->format == GST_VIDEO_FORMAT_SN12 ) {
+
+          guint size, min, max;
+          GstStructure *config;
+          GstCaps *caps = NULL;
+#if 0
+          if (gst_query_get_n_allocation_pools (query) > 0) {
+              gst_query_parse_nth_allocation_pool (query, 0, &vc->tbm_buffer_pool, &size, &min, &max);
+
+              /* adjust size */
+              size = MAX (size, sizeof(MMVideoBuffer));
+
+          } else {
+              vc->tbm_buffer_pool = NULL;
+              min = max = 0;
+          }
+#endif
+          size = sizeof(MMVideoBuffer);
+          if(vc->tbm_buffer_pool == NULL) {
+              min = 8;
+              max = 13;
+              GST_DEBUG("[%s]CREATING VIDEO_BUFFER_POOL",__FUNCTION__);
+              vc->tbm_buffer_pool = gst_mm_buffer_pool_new(trans);
+          }
+          config = gst_buffer_pool_get_config (vc->tbm_buffer_pool);
+
+          gst_query_parse_allocation (query, &caps, NULL);
+          if (caps)
+              gst_buffer_pool_config_set_params (config, caps, size, min, max);
+
+          if (gst_query_find_allocation_meta (query, GST_VIDEO_META_API_TYPE, NULL)) {
+              gst_buffer_pool_config_add_option (config,
+                  GST_BUFFER_POOL_OPTION_VIDEO_META);
+          }
+
+          gst_buffer_pool_set_config (vc->tbm_buffer_pool, config);
+
+          gst_query_add_allocation_pool (query, vc->tbm_buffer_pool, size, min, max);
+
+          gst_buffer_pool_set_active(vc->tbm_buffer_pool,TRUE);
+
+          GST_DEBUG("[%s]BUFFER_POOL max:[%d], min:[%d]",__FUNCTION__, max, min);
+  }
+  return GST_BASE_TRANSFORM_CLASS (parent_class)->decide_allocation (trans, query);
+
+}
+
+static GstFlowReturn
+gst_video_convert_prepare_output_buffer (GstBaseTransform * trans,
+    GstBuffer *input, GstBuffer **outbuf)
+{
+  GstBuffer *out_buffer = NULL;
+  GstVideoConvert *vc = NULL;
+  GstVideoFilter *filter = GST_VIDEO_FILTER_CAST (trans);
+
+  vc = GST_VIDEO_CONVERT_CAST(trans);
+
+  if(filter->out_info.finfo->format == GST_VIDEO_FORMAT_SN12 ) {
+      if(gst_buffer_pool_acquire_buffer(vc->tbm_buffer_pool,outbuf,0) != GST_FLOW_OK) {
+        GST_ERROR("[%s] memory prepare failed.",__FUNCTION__);
+        return GST_FLOW_ERROR;
+      }
+      return GST_FLOW_OK;
+    } else
+        return GST_BASE_TRANSFORM_CLASS (parent_class)->prepare_output_buffer(trans, input, outbuf);
+}
+#endif
+
 static gboolean
 plugin_init (GstPlugin * plugin)
 {
index 78678df..7343e5d 100644 (file)
@@ -56,6 +56,7 @@ struct _GstVideoConvert {
   GstVideoGammaMode gamma_mode;
   GstVideoPrimariesMode primaries_mode;
   gdouble alpha_value;
+  GstBufferPool *tbm_buffer_pool;
 };
 
 struct _GstVideoConvertClass