Adding review comments.
Signed-off-by: Barun Kr. Singh <barun.singh@samsung.com>
Change-Id: I92340394b460496c6b66e34496a88cc8d8caa54f
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
#include <glib.h>
#include <string.h>
#include <math.h>
+#include <mmf/mm_types.h>
#include "video-orc.h"
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)
{
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;
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:
return FALSE;
}
break;
+ case GST_VIDEO_FORMAT_SN12:
+ return TRUE; /* do nothing for SN12 format */
default:
break;
}
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,
#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,
{
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){
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;
}
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
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);
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);
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;
#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;
#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;
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
#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);
};
#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 =
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)
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);
}
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,
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;
"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)
{
GstVideoGammaMode gamma_mode;
GstVideoPrimariesMode primaries_mode;
gdouble alpha_value;
+ GstBufferPool *tbm_buffer_pool;
};
struct _GstVideoConvertClass