buffer-sharing: supports <video/x-vaapi-sharing> on video buffer
authorWind Yuan <feng.yuan@intel.com>
Fri, 11 Jan 2013 05:41:11 +0000 (13:41 +0800)
committerMarko Ollonen <marko.ollonen@ixonos.com>
Mon, 14 Jan 2013 08:51:20 +0000 (10:51 +0200)
Change-Id: I00d9e58b7ecb643a0af81290af4d25f534388526

gst-libs/gst/camera/gstmfldcamerasrc.c
gst/mfldv4l2cam/gstv4l2camsrc.c
gst/mfldv4l2cam/gstv4l2camsrc.h
gst/mfldv4l2cam/v4l2camsrc_calls.c

index a97a476..112b268 100644 (file)
@@ -1052,7 +1052,11 @@ gst_camerasrc_get_caps_info (GstCameraSrc * camerasrc, GstCaps * caps,
   *fps_n = gst_value_get_fraction_numerator (framerate);
   *fps_d = gst_value_get_fraction_denominator (framerate);
 
-  if (!strcmp (mimetype, "video/x-raw-yuv")) {
+  if (!strcmp (mimetype, "video/x-vaapi-sharing")) {
+    fourcc = V4L2_PIX_FMT_NV21;
+    outsize = GST_ROUND_UP_4 (*w) * GST_ROUND_UP_2 (*h);
+    outsize += (GST_ROUND_UP_4 (*w) * *h) / 2;
+  } else if (!strcmp (mimetype, "video/x-raw-yuv")) {
     gst_structure_get_fourcc (structure, "format", &fourcc);
 
     switch (fourcc) {
index a8e4f4f..679804c 100644 (file)
@@ -141,6 +141,15 @@ typedef enum
 #define DEFAULT_DEBUG_FLAGS    0
 #define C_FLAGS(v) ((guint) v)
 
+
+static const char* surface_string =
+    "video/x-vaapi-sharing, "
+    "type = vaapi, "
+    "width  = (int) [ 1, MAX ], "
+    "height = (int) [ 1, MAX ], "
+    "framerate = (fraction) [ 0, MAX ]";
+
+
 GType
 gst_camera_input_sensor_get_type (void)
 {
@@ -588,6 +597,9 @@ gst_v4l2camsrc_get_caps (GstCameraSrc * camsrc)
     }
   }
 
+  GstStructure * structure = gst_structure_from_string(surface_string, NULL);
+  gst_caps_append_structure (ret, structure);
+
   v4l2camsrc->probed_caps = gst_caps_ref (ret);
 
   GST_INFO_OBJECT(v4l2camsrc, "use GST_DEBUG >= 5 for probed caps");
@@ -677,6 +689,8 @@ gst_v4l2camsrc_get_all_caps (void)
         gst_caps_append_structure (caps, structure);
       }
     }
+    structure = gst_structure_from_string(surface_string, NULL);
+    gst_caps_append_structure (caps, structure);
   }
 
   return gst_caps_ref (caps);
index 7bf516d..596401c 100644 (file)
@@ -196,6 +196,7 @@ struct _GstMFLDV4l2CamSrcBufferPool
   gint video_fd;           /* a dup(2) of the v4l2object's video_fd */
   guint *queued;
   GCond* data_cond;
+  gboolean is_vaapi_sharing;
 };
 
 /**
index 4183012..4a43687 100644 (file)
@@ -105,7 +105,7 @@ static gint find_item (const gint table[], const gint item);
 
 #define GST_TYPE_V4L2CAMSRC_BUFFER (gst_v4l2camsrc_buffer_get_type())
 #define GST_IS_V4L2CAMSRC_BUFFER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_V4L2CAMSRC_BUFFER))
-#define GST_V4L2CAMSRC_BUFFER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_V4L2CAMSRC_BUFFER, GstCameraBuffer))
+#define GST_V4L2CAMSRC_BUFFER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_V4L2CAMSRC_BUFFER, GstV4l2Buffer))
 
 /* Local functions */
 static gboolean
@@ -149,6 +149,8 @@ gst_v4l2camsrc_buffer_finalize (GstV4l2Buffer * buffer)
     pool->num_live_buffers--;
 
   if (pool->running) {
+    if (pool->is_vaapi_sharing && buffer->gbuffer)
+      GST_BUFFER_DATA(buffer) = GST_BUFFER_DATA(buffer->gbuffer);
     if (ioctl (pool->video_fd, VIDIOC_QBUF, vbuffer) < 0) {
       GST_WARNING ("could not requeue buffer %p %d", buffer, index);
     } else {
@@ -176,7 +178,8 @@ gst_v4l2camsrc_buffer_finalize (GstV4l2Buffer * buffer)
       if (buffer->gbuffer) {
         /* It was allocated with gst_pad_alloc_buffer */
         /* FIXME temporal fix for double free error */
-        //gst_buffer_unref (buffer->gbuffer);
+        if (pool->is_vaapi_sharing)
+          gst_buffer_unref (buffer->gbuffer);
         buffer->gbuffer = NULL;
       } else {
         /* It was allocated with posix_memalign */
@@ -409,6 +412,7 @@ gst_v4l2camsrc_buffer_pool_init (GstMFLDV4l2CamSrcBufferPool * pool,
   pool->running = FALSE;
   pool->num_live_buffers = 0;
   pool->data_cond = g_cond_new ();
+  pool->is_vaapi_sharing = FALSE;
 }
 
 /*
@@ -467,6 +471,9 @@ gst_v4l2camsrc_buffer_pool_new (GstMFLDV4l2CamSrc * v4l2camsrc, gint fd,
   if (pool->video_fd < 0)
     goto dup_failed;
 
+  GstStructure *structure = gst_caps_get_structure (caps, 0);
+  if (structure && gst_structure_has_name(structure, "video/x-vaapi-sharing"))
+    pool->is_vaapi_sharing = TRUE;
 
   pool->buffer_count = v4l2camsrc->num_buffers;
   pool->buffers = g_new0 (GstV4l2Buffer *, pool->buffer_count);
@@ -587,6 +594,7 @@ gst_v4l2camsrc_buffer_pool_destroy (GstMFLDV4l2CamSrcBufferPool * pool,
 
   g_mutex_lock (pool->lock);
   pool->running = FALSE;
+  pool->is_vaapi_sharing = FALSE;
   g_mutex_unlock (pool->lock);
 
   GST_DEBUG ("destroy pool");
@@ -2287,6 +2295,8 @@ gst_v4l2camsrc_grab_frame (GstCameraSrc * camsrc, GstBuffer ** buf,
     /* this will requeue */
     gst_buffer_unref (pool_buffer);
   } else {
+    if (v4l2camsrc->pool->is_vaapi_sharing)
+        GST_BUFFER_DATA(pool_buffer) = (GST_V4L2CAMSRC_BUFFER(pool_buffer))->gbuffer;
     *buf = pool_buffer;
   }