amlv4l2dec: add a new interface for getting and sending cc data [1/1]
PD#SH-19658
Problem:
add a new interface for getting and sending cc data
Solution:
add the process for getting and sending cc data
Verify:
yocto-4.0-smarthome
Signed-off-by: zengliang.li <zengliang.li@amlogic.com>
Change-Id: If7a0d23e872a95b99df995e276a0204672577066
diff --git a/src/gstamlv4l2videodec.c b/src/gstamlv4l2videodec.c
index 415b187..b528334 100644
--- a/src/gstamlv4l2videodec.c
+++ b/src/gstamlv4l2videodec.c
@@ -57,6 +57,8 @@
}
#endif
+#define GST_AML_V4L2_CC_IMPORT_QUARK gst_aml_v4l2_buffer_pool_cc_import_quark ()
+
#ifndef ABSDIFF
#define ABSDIFF(a,b) (((a) > (b)) ? ((a) - (b)) : ((b) - (a)))
#endif
@@ -143,6 +145,13 @@
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
}
break;
+ case PROP_CC_DATA:
+ if (!gst_aml_v4l2_object_set_property_helper(self->v4l2capture,
+ prop_id, value, pspec))
+ {
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+ }
+ break;
#if GST_IMPORT_LGE_PROP
case LGE_RESOURCE_INFO:
{
@@ -210,7 +219,13 @@
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
}
break;
-
+ case PROP_CC_DATA:
+ if (!gst_aml_v4l2_object_get_property_helper(self->v4l2capture,
+ prop_id, value, pspec))
+ {
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+ }
+ break;
#if GST_IMPORT_LGE_PROP
case LGE_DECODE_SIZE:
{
@@ -949,6 +964,57 @@
}
}
+static GQuark
+gst_aml_v4l2_buffer_pool_cc_import_quark (void)
+{
+ static GQuark quark = 0;
+
+ if (quark == 0)
+ quark = g_quark_from_string ("GstAmlV4l2BufferPoolCcUsePtrData");
+
+ return quark;
+}
+
+static gboolean
+foreach_cc_buffer_list_match_pts_func(GList *list , GstVideoCodecFrame *frame)
+{
+ GList *l;
+ if (g_list_length (list) > 0)
+ {
+ for (l = list; l != NULL; l = l->next)
+ {
+ GstBuffer *cc_buffer = l->data;
+ if (GST_BUFFER_TIMESTAMP (frame->output_buffer) == GST_BUFFER_TIMESTAMP (cc_buffer))
+ {
+ gst_mini_object_set_qdata (GST_MINI_OBJECT (frame->output_buffer), GST_AML_V4L2_CC_IMPORT_QUARK,
+ gst_buffer_ref(cc_buffer), (GDestroyNotify) gst_buffer_unref);
+ #if 0
+ //Debug code:dump cc data
+ GstMapInfo gst_map;
+ gst_buffer_map(cc_buffer,&gst_map,GST_MAP_READ);
+ int fd=open("/data/test/cc1.data",O_RDWR |O_CREAT|O_APPEND,0777);
+ if (gst_map.size>0)
+ write(fd,gst_map.data,gst_map.size);
+ close(fd);
+ gst_buffer_unmap(cc_buffer,&gst_map);
+ #endif
+ GST_DEBUG("match success");
+ return TRUE;
+ }
+ else
+ {
+ GST_DEBUG("match fail");
+ }
+ }
+ GST_WARNING("no match frame in the bufferlist");
+ }
+ else
+ {
+ GST_WARNING("list is null,can not foreach");
+ }
+ return FALSE;
+}
+
static void
gst_aml_v4l2_video_dec_loop(GstVideoDecoder *decoder)
{
@@ -1106,6 +1172,7 @@
}
ret = gst_buffer_pool_acquire_buffer(pool, &buffer, NULL);
+
//calculate a new pts for interlace stream
if (ret == GST_FLOW_OK && self->v4l2capture->info.interlace_mode == GST_VIDEO_INTERLACE_MODE_INTERLEAVED)
{
@@ -1146,6 +1213,12 @@
}
}
+ if (ret == GST_AML_V4L2_FLOW_CC_DATA)
+ {
+ GST_DEBUG_OBJECT(decoder, "continue get cc data ");
+ continue;
+ }
+
if (ret == GST_AML_V4L2_FLOW_SOURCE_CHANGE)
{
GST_LOG_OBJECT(decoder, "Get GST_AML_V4L2_FLOW_SOURCE_CHANGE");
@@ -1173,7 +1246,7 @@
return;
}
- } while (ret == GST_AML_V4L2_FLOW_CORRUPTED_BUFFER);
+ } while ((ret == GST_AML_V4L2_FLOW_CORRUPTED_BUFFER) || (ret == GST_AML_V4L2_FLOW_CC_DATA));
if (ret != GST_FLOW_OK)
goto beach;
@@ -1206,6 +1279,33 @@
frame->pts = GST_BUFFER_TIMESTAMP(buffer);
frame->duration = GST_BUFFER_DURATION(buffer);
buffer = NULL;
+
+ GST_DEBUG_OBJECT (decoder,"enable_cc_data:%d",self->v4l2capture->enable_cc_data);
+ if (self->v4l2capture->enable_cc_data)
+ {
+ if (foreach_cc_buffer_list_match_pts_func(v4l2_pool->cc_buffer_list, frame))
+ {
+ GST_DEBUG("cc buffer and frame bind success");
+ GstBuffer *cc_buffer = gst_mini_object_get_qdata (GST_MINI_OBJECT (frame->output_buffer),
+ GST_AML_V4L2_CC_IMPORT_QUARK);
+ #if 0
+ //Debug code:dump cc data
+ GstMapInfo gst_map;
+ gst_buffer_map(cc_buffer,&gst_map,GST_MAP_READ);
+ int fd=open("/data/test/cc2.data",O_RDWR |O_CREAT|O_APPEND,0777);
+ if (gst_map.size>0)
+ write(fd,gst_map.data,gst_map.size);
+ close(fd);
+ gst_buffer_unmap(cc_buffer,&gst_map);
+ #endif
+ v4l2_pool->cc_buffer_list = g_list_remove(v4l2_pool->cc_buffer_list,cc_buffer);
+ gst_buffer_unref(cc_buffer);
+ }
+ else
+ {
+ GST_WARNING("bufferlist is empty or no match frame in the bufferlist");
+ }
+ }
ret = gst_video_decoder_finish_frame(decoder, frame);
if (ret != GST_FLOW_OK)