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)