AC_SUBST(TWOLAME_LIBS)
])
+PKG_CHECK_MODULES(TBM, libtbm)
+AC_SUBST(TBM_CFLAGS)
+AC_SUBST(TBM_LIBS)
dnl *** vpx ***
translit(dnm, m, l) AM_CONDITIONAL(USE_VPX, vpx)
Name: gst-plugins-good
Version: 1.16.2
-Release: 14
+Release: 15
License: LGPL-2.1+
Summary: GStreamer Streaming-Media Framework Plug-Ins
Url: http://gstreamer.freedesktop.org/
%endif
BuildRequires: pkgconfig(vconf)
BuildRequires: pkgconfig(gio-2.0)
+BuildRequires: pkgconfig(libtbm)
Requires: gst-plugins-base >= 1.0.0
Requires: gstreamer >= 1.0.5
-DTIZEN_FEATURE_AVIDEMUX_MODIFICATION\
-DTIZEN_FEATURE_USE_LIBV4L2\
-DTIZEN_FEATURE_V4L2_ADDITIONAL_CID_SUPPORT\
+ -DTIZEN_FEATURE_TBM_SUPPORT_FOR_V4L2_DECODER\
-fstack-protector-strong\
-Wl,-z,relro\
-D_FORTIFY_SOURCE=2"
%if "%{tizen_profile_name}" != "tv"
--with-libv4l2 \
%endif
- --disable-v4l2-probe\
+ --enable-v4l2-probe\
--disable-gtk-doc\
--with-gtk=3.0\
--disable-monoscope\
$(GST_CFLAGS) \
$(X_CFLAGS) \
$(LIBV4L2_CFLAGS) \
+ $(TBM_CFLAGS) \
$(GUDEV_CFLAGS)
libgstvideo4linux2_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
$(GST_LIBS) \
$(LIBV4L2_LIBS) \
$(GUDEV_LIBS) \
+ $(TBM_LIBS) \
$(LIBRT)
noinst_HEADERS = \
GstStructure *alt_t = NULL;
switch (format.pixelformat) {
+#ifdef TIZEN_FEATURE_TBM_SUPPORT_FOR_V4L2_DECODER
+ case V4L2_PIX_FMT_YUV420:
+ alt_t = gst_structure_copy (template);
+ gst_structure_set (alt_t, "format", G_TYPE_STRING, "S420", NULL);
+ break;
+ case V4L2_PIX_FMT_NV12:
+ alt_t = gst_structure_copy (template);
+ gst_structure_set (alt_t, "format", G_TYPE_STRING, "SN12", NULL);
+ break;
+#endif /* TIZEN_FEATURE_TBM_SUPPORT_FOR_V4L2_DECODER */
case V4L2_PIX_FMT_RGB32:
alt_t = gst_structure_copy (template);
gst_structure_set (alt_t, "format", G_TYPE_STRING, "ARGB", NULL);
#include <sys/types.h>
#include <sys/mman.h>
#include <unistd.h>
+#ifdef TIZEN_FEATURE_TBM_SUPPORT_FOR_V4L2_DECODER
+#include <tbm_surface.h>
+#include <tbm_surface_internal.h>
+#endif /* TIZEN_FEATURE_TBM_SUPPORT_FOR_V4L2_DECODER */
#define GST_V4L2_MEMORY_TYPE "V4l2Memory"
if (mem)
gst_memory_unref (mem);
}
+#ifdef TIZEN_FEATURE_TBM_SUPPORT_FOR_V4L2_DECODER
+ if (group->surface) {
+ GST_INFO ("unref surface[%p]", group->surface);
+ tbm_surface_destroy (group->surface);
+ group->surface = NULL;
+ }
+#endif /* TIZEN_FEATURE_TBM_SUPPORT_FOR_V4L2_DECODER */
g_slice_free (GstV4l2MemoryGroup, group);
}
GstV4l2Allocator *allocator = (GstV4l2Allocator *) obj;
GST_LOG_OBJECT (obj, "called");
+#ifdef TIZEN_FEATURE_TBM_SUPPORT_FOR_V4L2_DECODER
+ if (allocator->bufmgr) {
+ GST_INFO_OBJECT (obj, "deinit tbm bufmgr %p", allocator->bufmgr);
+ tbm_bufmgr_deinit (allocator->bufmgr);
+ allocator->bufmgr = NULL;
+ }
+#endif /* TIZEN_FEATURE_TBM_SUPPORT_FOR_V4L2_DECODER */
gst_atomic_queue_unref (allocator->free_queue);
gst_object_unref (allocator->obj->element);
}
}
-
+#ifdef TIZEN_FEATURE_TBM_SUPPORT_FOR_V4L2_DECODER
+static tbm_format __get_tbm_format (GstVideoFormat gst_format)
+{
+ switch (gst_format) {
+ case GST_VIDEO_FORMAT_NV12:
+ case GST_VIDEO_FORMAT_SN12:
+ return TBM_FORMAT_NV12;
+ case GST_VIDEO_FORMAT_I420:
+ case GST_VIDEO_FORMAT_S420:
+ default:
+ return TBM_FORMAT_YUV420;
+ }
+}
+#endif /* TIZEN_FEATURE_TBM_SUPPORT_FOR_V4L2_DECODER */
GstV4l2Allocator *
gst_v4l2_allocator_new (GstObject * parent, GstV4l2Object * v4l2object)
GST_OBJECT_FLAG_SET (allocator, flags);
+#ifdef TIZEN_FEATURE_TBM_SUPPORT_FOR_V4L2_DECODER
+ if (!V4L2_TYPE_IS_OUTPUT (v4l2object->type) &&
+ v4l2object->mode == GST_V4L2_IO_DMABUF) {
+ tbm_surface_h tmp_surface = NULL;
+ int width = GST_VIDEO_INFO_WIDTH (&v4l2object->info);
+ int height = GST_VIDEO_INFO_HEIGHT (&v4l2object->info);
+
+ tmp_surface = tbm_surface_create (width, height,
+ __get_tbm_format (GST_VIDEO_INFO_FORMAT (&v4l2object->info)));
+ if (tmp_surface) {
+ tbm_surface_get_info (tmp_surface, &allocator->s_info);
+ GST_INFO_OBJECT (allocator, "[%dx%d] -> tbm surface info[%dx%d]",
+ width, height, allocator->s_info.width, allocator->s_info.height);
+ tbm_surface_destroy (tmp_surface);
+ } else {
+ GST_ERROR_OBJECT (allocator, "[%dx%d] surface failed", width, height);
+ }
+
+ allocator->bufmgr = tbm_bufmgr_init (-1);
+ if (!allocator->bufmgr) {
+ GST_ERROR_OBJECT (allocator, "tbm bufmgr failed");
+ gst_object_unref (allocator);
+ return NULL;
+ }
+ }
+#endif /* TIZEN_FEATURE_TBM_SUPPORT_FOR_V4L2_DECODER */
return allocator;
}
GstV4l2Object *obj = allocator->obj;
GstV4l2MemoryGroup *group;
gint i;
+#ifdef TIZEN_FEATURE_TBM_SUPPORT_FOR_V4L2_DECODER
+ tbm_bo bos[VIDEO_MAX_PLANES] = {NULL, };
+#endif /* TIZEN_FEATURE_TBM_SUPPORT_FOR_V4L2_DECODER */
g_return_val_if_fail (allocator->memory == V4L2_MEMORY_MMAP, NULL);
NULL, group->planes[i].length, 0, group->planes[i].data_offset,
group->planes[i].length - group->planes[i].data_offset, i, NULL,
expbuf.fd, group);
+#ifdef TIZEN_FEATURE_TBM_SUPPORT_FOR_V4L2_DECODER
+ bos[i] = tbm_bo_import_fd (allocator->bufmgr, expbuf.fd);
+ GST_INFO_OBJECT (allocator, "obj[%p,i:%d]: fd[%d] -> bo[%p]",
+ obj, expbuf.index, expbuf.fd, bos[i]);
+#endif /* TIZEN_FEATURE_TBM_SUPPORT_FOR_V4L2_DECODER */
} else {
/* Take back the allocator reference */
gst_object_ref (allocator);
group->mem[i] = dma_mem;
}
+#ifdef TIZEN_FEATURE_TBM_SUPPORT_FOR_V4L2_DECODER
+ if (!group->surface) {
+ group->surface = tbm_surface_internal_create_with_bos (&allocator->s_info, bos, group->n_mem);
+ GST_INFO_OBJECT (allocator, "new surface[%p] in memory group[%p]", group->surface, group);
+ }
+ /* release bos - they will be kept in surface. */
+ for (i = 0 ; i < VIDEO_MAX_PLANES && bos[i] ; i++)
+ tbm_bo_unref (bos[i]);
+#endif /* TIZEN_FEATURE_TBM_SUPPORT_FOR_V4L2_DECODER */
+
gst_v4l2_allocator_reset_size (allocator, group);
return group;
#include "ext/videodev2.h"
#include <gst/gst.h>
#include <gst/gstatomicqueue.h>
+#ifdef TIZEN_FEATURE_TBM_SUPPORT_FOR_V4L2_DECODER
+#include <tbm_surface.h>
+#include <tbm_surface_internal.h>
+#endif /* TIZEN_FEATURE_TBM_SUPPORT_FOR_V4L2_DECODER */
G_BEGIN_DECLS
gint mems_allocated;
struct v4l2_buffer buffer;
struct v4l2_plane planes[VIDEO_MAX_PLANES];
+#ifdef TIZEN_FEATURE_TBM_SUPPORT_FOR_V4L2_DECODER
+ tbm_surface_h surface;
+#endif /* TIZEN_FEATURE_TBM_SUPPORT_FOR_V4L2_DECODER */
};
struct _GstV4l2Allocator
GstV4l2MemoryGroup * groups[VIDEO_MAX_FRAME];
GstAtomicQueue *free_queue;
GstAtomicQueue *pending_queue;
-
+#ifdef TIZEN_FEATURE_TBM_SUPPORT_FOR_V4L2_DECODER
+ tbm_bufmgr bufmgr;
+ tbm_surface_info_s s_info;
+ gint live_buffer_count;
+#endif /* TIZEN_FEATURE_TBM_SUPPORT_FOR_V4L2_DECODER */
};
struct _GstV4l2AllocatorClass {
#include "gstv4l2object.h"
#include "gst/gst-i18n-plugin.h"
#include <gst/glib-compat-private.h>
+#ifdef TIZEN_FEATURE_TBM_SUPPORT_FOR_V4L2_DECODER
+#include <gst/allocators/gsttizenmemory.h>
+#endif /* TIZEN_FEATURE_TBM_SUPPORT_FOR_V4L2_DECODER */
GST_DEBUG_CATEGORY_STATIC (v4l2bufferpool_debug);
GST_DEBUG_CATEGORY_STATIC (CAT_PERFORMANCE);
#define GST_V4L2_IMPORT_QUARK gst_v4l2_buffer_pool_import_quark ()
-
/*
* GstV4l2BufferPool:
*/
static void gst_v4l2_buffer_pool_release_buffer (GstBufferPool * bpool,
GstBuffer * buffer);
+#ifdef TIZEN_FEATURE_TBM_SUPPORT_FOR_V4L2_DECODER
+typedef struct _GstV4l2TizenBuffer GstV4l2TizenBuffer;
+struct _GstV4l2TizenBuffer {
+ int index;
+ GstBuffer *gst_buffer;
+ GstBuffer *v4l2_buffer;
+ GstV4l2BufferPool *v4l2_pool;
+};
+
+static void gst_v4l2_tizen_buffer_finalize (GstV4l2TizenBuffer *tizen_buffer)
+{
+ GstV4l2BufferPool *pool = NULL;
+
+ if (!tizen_buffer) {
+ GST_ERROR ("NULL buffer");
+ return;
+ }
+
+ pool = tizen_buffer->v4l2_pool;
+
+ gst_v4l2_buffer_pool_release_buffer (GST_BUFFER_POOL_CAST (pool), tizen_buffer->v4l2_buffer);
+
+ g_mutex_lock (&pool->buffer_lock);
+
+ pool->live_buffer_count--;
+
+ GST_DEBUG_OBJECT (pool, "release buffer[%d][tizen:%p,v4l2:%p,gst:%p], live[%d]",
+ tizen_buffer->index, tizen_buffer, tizen_buffer->v4l2_buffer,
+ tizen_buffer->gst_buffer, pool->live_buffer_count);
+
+ g_cond_signal (&pool->buffer_cond);
+
+ g_mutex_unlock (&pool->buffer_lock);
+}
+
+static GstV4l2TizenBuffer *gst_v4l2_tizen_buffer_new (GstBuffer *v4l2_buffer, int index, GstV4l2BufferPool *v4l2_pool)
+{
+ GstV4l2TizenBuffer *tizen_buffer = NULL;
+ GstMemory *memory = NULL;
+
+ tizen_buffer = g_new0 (GstV4l2TizenBuffer, 1);
+ tizen_buffer->index = index;
+ tizen_buffer->v4l2_buffer = v4l2_buffer;
+ tizen_buffer->gst_buffer = gst_buffer_new ();
+ tizen_buffer->v4l2_pool = v4l2_pool;
+
+ memory = gst_tizen_allocator_alloc_surface (v4l2_pool->tallocator,
+ &v4l2_pool->obj->info, v4l2_pool->vallocator->groups[index]->surface, (gpointer)tizen_buffer,
+ (GDestroyNotify)gst_v4l2_tizen_buffer_finalize);
+
+ gst_buffer_append_memory (tizen_buffer->gst_buffer, memory);
+ gst_buffer_set_size (tizen_buffer->gst_buffer, v4l2_pool->vallocator->s_info.size);
+
+ g_mutex_lock (&v4l2_pool->buffer_lock);
+
+ v4l2_pool->live_buffer_count++;
+
+ GST_DEBUG_OBJECT (v4l2_pool, "new buffer[tizen:%p,v4l2:%p,gst:%p], size[%d], live[%d]",
+ tizen_buffer, v4l2_buffer, tizen_buffer->gst_buffer,
+ v4l2_pool->vallocator->s_info.size, v4l2_pool->live_buffer_count);
+
+ g_mutex_unlock (&v4l2_pool->buffer_lock);
+
+ return tizen_buffer;
+}
+#endif /* TIZEN_FEATURE_TBM_SUPPORT_FOR_V4L2_DECODER */
static gboolean
gst_v4l2_is_buffer_valid (GstBuffer * buffer, GstV4l2MemoryGroup ** out_group)
case GST_V4L2_IO_USERPTR:
case GST_V4L2_IO_DMABUF:
case GST_V4L2_IO_DMABUF_IMPORT:
+#ifndef TIZEN_FEATURE_TBM_SUPPORT_FOR_V4L2_DECODER
if (!V4L2_TYPE_IS_OUTPUT (pool->obj->type)) {
guint i;
for (i = 0; i < pool->num_allocated; i++)
gst_v4l2_buffer_pool_resurrect_buffer (pool);
}
+#endif /* TIZEN_FEATURE_TBM_SUPPORT_FOR_V4L2_DECODER */
if (obj->ioctl (pool->video_fd, VIDIOC_STREAMON, &obj->type) < 0)
goto streamon_failed;
GstBufferPoolClass *pclass = GST_BUFFER_POOL_CLASS (parent_class);
GstV4l2Object *obj = pool->obj;
gint i;
+#ifdef TIZEN_FEATURE_TBM_SUPPORT_FOR_V4L2_DECODER
+ gint64 end_time = 0;
+#endif /* TIZEN_FEATURE_TBM_SUPPORT_FOR_V4L2_DECODER */
if (!pool->streaming)
return;
+#ifdef TIZEN_FEATURE_TBM_SUPPORT_FOR_V4L2_DECODER
+ if (!V4L2_TYPE_IS_OUTPUT(pool->obj->type)) {
+ g_mutex_lock (&pool->buffer_lock);
+
+ GST_INFO_OBJECT (pool, "live buffer[%d]", pool->live_buffer_count);
+
+ if (pool->live_buffer_count > 0) {
+ end_time = g_get_monotonic_time () + G_TIME_SPAN_SECOND;
+
+ do {
+ GST_WARNING_OBJECT (pool, "wait for live buffer[%d]", pool->live_buffer_count);
+
+ if (!g_cond_wait_until (&pool->buffer_cond, &pool->buffer_lock, end_time)) {
+ GST_ERROR_OBJECT (pool, "failed to wait live buffer[%d]", pool->live_buffer_count);
+ break;
+ }
+
+ GST_WARNING_OBJECT (pool, "signal received, check again : live count[%d]",
+ pool->live_buffer_count);
+ } while (pool->live_buffer_count > 0);
+ }
+
+ g_mutex_unlock (&pool->buffer_lock);
+ }
+#endif /* TIZEN_FEATURE_TBM_SUPPORT_FOR_V4L2_DECODER */
switch (obj->mode) {
case GST_V4L2_IO_MMAP:
case GST_V4L2_IO_USERPTR:
GstVideoMeta *vmeta;
gsize size;
gint i;
+#ifdef TIZEN_FEATURE_TBM_SUPPORT_FOR_V4L2_DECODER
+ GstV4l2TizenBuffer *tizen_buffer = NULL;
+#endif /* TIZEN_FEATURE_TBM_SUPPORT_FOR_V4L2_DECODER */
if ((res = gst_v4l2_buffer_pool_poll (pool, wait)) < GST_FLOW_OK)
goto poll_failed;
GST_BUFFER_OFFSET (outbuf) = group->buffer.sequence;
GST_BUFFER_OFFSET_END (outbuf) = group->buffer.sequence + 1;
+#ifdef TIZEN_FEATURE_TBM_SUPPORT_FOR_V4L2_DECODER
+ if (group->surface) {
+ tizen_buffer = gst_v4l2_tizen_buffer_new (outbuf, group->buffer.index, pool);
+ if (!tizen_buffer) {
+ GST_ERROR_OBJECT (pool, "tizen buffer failed for index[%d]", group->buffer.index);
+ goto no_buffer;
+ }
+ outbuf = tizen_buffer->gst_buffer;
+ }
+#endif /* TIZEN_FEATURE_TBM_SUPPORT_FOR_V4L2_DECODER */
done:
*buffer = outbuf;
gst_object_unref (pool->allocator);
pool->allocator = NULL;
+#ifdef TIZEN_FEATURE_TBM_SUPPORT_FOR_V4L2_DECODER
+ g_cond_clear (&pool->buffer_cond);
+ g_mutex_clear (&pool->buffer_lock);
+
+ if (pool->tallocator)
+ gst_object_unref (pool->tallocator);
+ pool->tallocator = NULL;
+#endif /* TIZEN_FEATURE_TBM_SUPPORT_FOR_V4L2_DECODER */
if (pool->other_pool)
gst_object_unref (pool->other_pool);
pool->other_pool = NULL;
pool->obj = obj;
pool->can_poll_device = TRUE;
+#ifdef TIZEN_FEATURE_TBM_SUPPORT_FOR_V4L2_DECODER
+ pool->tallocator = gst_tizen_allocator_new ();
+ if (pool->tallocator == NULL)
+ goto allocator_failed;
+
+ g_mutex_init (&pool->buffer_lock);
+ g_cond_init (&pool->buffer_cond);
+#endif /* TIZEN_FEATURE_TBM_SUPPORT_FOR_V4L2_DECODER */
pool->vallocator = gst_v4l2_allocator_new (GST_OBJECT (pool), obj);
if (pool->vallocator == NULL)
goto allocator_failed;
}
allocator_failed:
{
+#ifdef TIZEN_FEATURE_TBM_SUPPORT_FOR_V4L2_DECODER
+ if (pool->tallocator) {
+ gst_object_unref (pool->tallocator);
+ pool->tallocator = NULL;
+ }
+#endif /* TIZEN_FEATURE_TBM_SUPPORT_FOR_V4L2_DECODER */
GST_ERROR_OBJECT (pool, "Failed to create V4L2 allocator");
gst_object_unref (pool);
return NULL;
if (GST_V4L2_IS_M2M (obj->device_caps))
goto eos;
}
-
+#ifdef TIZEN_FEATURE_TBM_SUPPORT_FOR_V4L2_DECODER
+ if (pool->obj->mode == GST_V4L2_IO_DMABUF) {
+ gst_buffer_unref (*buf);
+ *buf = tmp;
+ } else {
+#endif /* TIZEN_FEATURE_TBM_SUPPORT_FOR_V4L2_DECODER */
ret = gst_v4l2_buffer_pool_copy_buffer (pool, *buf, tmp);
/* an queue the buffer again after the copy */
gst_v4l2_buffer_pool_release_buffer (bpool, tmp);
+#ifdef TIZEN_FEATURE_TBM_SUPPORT_FOR_V4L2_DECODER
+ }
+#endif /* TIZEN_FEATURE_TBM_SUPPORT_FOR_V4L2_DECODER */
if (ret != GST_FLOW_OK)
goto copy_failed;
GstV4l2Allocator *vallocator;
GstAllocator *allocator;
+#ifdef TIZEN_FEATURE_TBM_SUPPORT_FOR_V4L2_DECODER
+ GstAllocator *tallocator;
+ gint live_buffer_count;
+ GMutex buffer_lock;
+ GCond buffer_cond;
+#endif /* TIZEN_FEATURE_TBM_SUPPORT_FOR_V4L2_DECODER */
GstAllocationParams params;
GstBufferPool *other_pool;
guint size;
if (v4l2object->ioctl (v4l2object->video_fd, VIDIOC_G_CTRL, &control) == 0) {
GST_DEBUG_OBJECT (v4l2object->dbg_obj,
"driver requires a minimum of %d buffers", control.value);
+#ifdef TIZEN_FEATURE_TBM_SUPPORT_FOR_V4L2_DECODER
+#define DEFAULT_DECODER_OUTPUT_BUFFER_COUNT 5
+ if (!V4L2_TYPE_IS_OUTPUT (v4l2object->type) && control.value == 1) {
+ v4l2object->min_buffers = DEFAULT_DECODER_OUTPUT_BUFFER_COUNT;
+ GST_WARNING_OBJECT (v4l2object->dbg_obj, "but SET MIN BUFFER COUNT[%d] and it will be [%d] later",
+ v4l2object->min_buffers, v4l2object->min_buffers + 1);
+ }
+#else /* TIZEN_FEATURE_TBM_SUPPORT_FOR_V4L2_DECODER */
v4l2object->min_buffers = control.value;
+#endif /* TIZEN_FEATURE_TBM_SUPPORT_FOR_V4L2_DECODER */
} else {
v4l2object->min_buffers = 0;
}
}
switch (gst_v4l2_formats[i].format) {
+#ifdef TIZEN_FEATURE_TBM_SUPPORT_FOR_V4L2_DECODER
+ case V4L2_PIX_FMT_YUV420:
+ alt_s = gst_structure_copy (structure);
+ gst_structure_set (alt_s, "format", G_TYPE_STRING, "S420", NULL);
+ break;
+ case V4L2_PIX_FMT_NV12:
+ alt_s = gst_structure_copy (structure);
+ gst_structure_set (alt_s, "format", G_TYPE_STRING, "SN12", NULL);
+ break;
+#endif /* TIZEN_FEATURE_TBM_SUPPORT_FOR_V4L2_DECODER */
case V4L2_PIX_FMT_RGB32:
alt_s = gst_structure_copy (structure);
gst_structure_set (alt_s, "format", G_TYPE_STRING, "ARGB", NULL);
if (g_str_equal (mimetype, "video/x-raw")) {
switch (GST_VIDEO_INFO_FORMAT (info)) {
case GST_VIDEO_FORMAT_I420:
+#ifdef TIZEN_FEATURE_TBM_SUPPORT_FOR_V4L2_DECODER
+ case GST_VIDEO_FORMAT_S420:
+#endif /* TIZEN_FEATURE_TBM_SUPPORT_FOR_V4L2_DECODER */
fourcc = V4L2_PIX_FMT_YUV420;
fourcc_nc = V4L2_PIX_FMT_YUV420M;
break;
fourcc = V4L2_PIX_FMT_YUV422P;
break;
case GST_VIDEO_FORMAT_NV12:
+#ifdef TIZEN_FEATURE_TBM_SUPPORT_FOR_V4L2_DECODER
+ case GST_VIDEO_FORMAT_SN12:
+#endif /* TIZEN_FEATURE_TBM_SUPPORT_FOR_V4L2_DECODER */
fourcc = V4L2_PIX_FMT_NV12;
fourcc_nc = V4L2_PIX_FMT_NV12M;
break;
if (tmp)
gst_caps_append (ret, tmp);
+#ifdef TIZEN_FEATURE_TBM_SUPPORT_FOR_V4L2_DECODER
+ if (format->pixelformat == V4L2_PIX_FMT_NV12 ||
+ format->pixelformat == V4L2_PIX_FMT_YUV420) {
+ GstStructure *alt_s = gst_structure_copy (template);
+
+ if (format->pixelformat == V4L2_PIX_FMT_NV12)
+ gst_structure_set (alt_s, "format", G_TYPE_STRING, "SN12", NULL);
+ else
+ gst_structure_set (alt_s, "format", G_TYPE_STRING, "S420", NULL);
+
+ tmp = gst_v4l2_object_probe_caps_for_format (v4l2object,
+ format->pixelformat, alt_s);
+
+ if (tmp)
+ gst_caps_append (ret, tmp);
+
+ gst_structure_free (alt_s);
+ }
+#endif /* TIZEN_FEATURE_TBM_SUPPORT_FOR_V4L2_DECODER */
gst_structure_free (template);
}
GstAllocator *allocator = NULL;
GstAllocationParams params = { 0 };
+#ifdef TIZEN_FEATURE_TBM_SUPPORT_FOR_V4L2_DECODER
+ GST_INFO_OBJECT (obj->dbg_obj, "decide allocation - %s",
+ V4L2_TYPE_IS_OUTPUT (obj->type) ? "output" : "capture");
+#else /* TIZEN_FEATURE_TBM_SUPPORT_FOR_V4L2_DECODER */
GST_DEBUG_OBJECT (obj->dbg_obj, "decide allocation");
+#endif /* TIZEN_FEATURE_TBM_SUPPORT_FOR_V4L2_DECODER */
g_return_val_if_fail (obj->type == V4L2_BUF_TYPE_VIDEO_CAPTURE ||
obj->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE, FALSE);
static GstFlowReturn gst_v4l2_video_dec_finish (GstVideoDecoder * decoder);
+#ifdef TIZEN_FEATURE_TBM_SUPPORT_FOR_V4L2_DECODER
+static void gst_v4l2_video_dec_flush_buffer_event (GstVideoDecoder * decoder)
+{
+ gboolean ret = FALSE;
+
+ if (!decoder) {
+ GST_ERROR("no decoder");
+ return;
+ }
+
+ ret = gst_pad_push_event (decoder->srcpad,
+ gst_event_new_custom (GST_EVENT_CUSTOM_DOWNSTREAM | GST_EVENT_TYPE_SERIALIZED,
+ gst_structure_new_empty("tizen/flush-buffer")));
+
+ GST_WARNING_OBJECT(decoder, "event push ret[%d] for flush-buffer", ret);
+}
+#endif /* TIZEN_FEATURE_TBM_SUPPORT_FOR_V4L2_DECODER */
static void
gst_v4l2_video_dec_set_property (GObject * object,
guint prop_id, const GValue * value, GParamSpec * pspec)
/* Should have been flushed already */
g_assert (g_atomic_int_get (&self->active) == FALSE);
+#ifdef TIZEN_FEATURE_TBM_SUPPORT_FOR_V4L2_DECODER
+ gst_v4l2_video_dec_flush_buffer_event (decoder);
+#endif /* TIZEN_FEATURE_TBM_SUPPORT_FOR_V4L2_DECODER */
gst_v4l2_object_stop (self->v4l2output);
gst_v4l2_object_stop (self->v4l2capture);
if (self->v4l2output->pool)
gst_v4l2_buffer_pool_flush (self->v4l2output->pool);
+#ifdef TIZEN_FEATURE_TBM_SUPPORT_FOR_V4L2_DECODER
+ gst_v4l2_video_dec_flush_buffer_event (decoder);
+#endif /* TIZEN_FEATURE_TBM_SUPPORT_FOR_V4L2_DECODER */
/* gst_v4l2_buffer_pool_flush() calls streamon the capture pool and must be
* called after gst_v4l2_object_unlock_stop() stopped flushing the buffer
* pool. */
gboolean processed = FALSE;
GstBuffer *tmp;
GstTaskState task_state;
+#ifdef TIZEN_FEATURE_TBM_SUPPORT_FOR_V4L2_DECODER
+ GstStructure *structure = NULL;
+ const gchar *caps_format = NULL;
+#endif /* TIZEN_FEATURE_TBM_SUPPORT_FOR_V4L2_DECODER */
GST_DEBUG_OBJECT (self, "Handling frame %d", frame->system_frame_number);
caps = gst_caps_fixate (caps);
GST_DEBUG_OBJECT (self, "Chosen decoded caps: %" GST_PTR_FORMAT, caps);
+#ifdef TIZEN_FEATURE_TBM_SUPPORT_FOR_V4L2_DECODER
+ structure = gst_caps_get_structure (caps, 0);
+ caps_format = gst_structure_get_string (structure, "format");
+
+ if (!strcmp (caps_format, "I420")) {
+ GST_INFO_OBJECT (self, "I420 -> S420");
+ gst_caps_set_simple (caps, "format", G_TYPE_STRING, "S420", NULL);
+ } else if (!strcmp (caps_format, "NV12")) {
+ GST_INFO_OBJECT (self, "NV12 -> SN12");
+ gst_caps_set_simple (caps, "format", G_TYPE_STRING, "SN12", NULL);
+ }
+ GST_INFO_OBJECT (self, "Updated decoded caps: %" GST_PTR_FORMAT, caps);
+#endif /* TIZEN_FEATURE_TBM_SUPPORT_FOR_V4L2_DECODER */
/* Try to set negotiated format, on success replace acquired format */
if (gst_v4l2_object_set_format (self->v4l2capture, caps, &error))