v4l2videodec: Send flush buffer event when EOS
[platform/upstream/gst-plugins-good.git] / sys / v4l2 / gstv4l2videodec.c
index 39f845c..7642085 100644 (file)
@@ -51,6 +51,9 @@ enum
 {
   PROP_0,
   V4L2_STD_OBJECT_PROPS
+#ifdef TIZEN_FEATURE_V4L2_TBM_SUPPORT
+  , PROP_TBM_OUTPUT
+#endif /* TIZEN_FEATURE_V4L2_TBM_SUPPORT */
 };
 
 #define gst_v4l2_video_dec_parent_class parent_class
@@ -59,6 +62,23 @@ G_DEFINE_ABSTRACT_TYPE (GstV4l2VideoDec, gst_v4l2_video_dec,
 
 static GstFlowReturn gst_v4l2_video_dec_finish (GstVideoDecoder * decoder);
 
+#ifdef TIZEN_FEATURE_V4L2_TBM_SUPPORT
+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_V4L2_TBM_SUPPORT */
 static void
 gst_v4l2_video_dec_set_property (GObject * object,
     guint prop_id, const GValue * value, GParamSpec * pspec)
@@ -72,6 +92,13 @@ gst_v4l2_video_dec_set_property (GObject * object,
         G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       }
       break;
+#ifdef TIZEN_FEATURE_V4L2_TBM_SUPPORT
+    case PROP_TBM_OUTPUT:
+      self->v4l2capture->tbm_output = g_value_get_boolean (value);
+      GST_INFO_OBJECT (self, "tbm output [%d]", self->v4l2capture->tbm_output);
+      break;
+#endif /* TIZEN_FEATURE_V4L2_TBM_SUPPORT */
+
 
       /* By default, only set on output */
     default:
@@ -96,6 +123,12 @@ gst_v4l2_video_dec_get_property (GObject * object,
         G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       }
       break;
+#ifdef TIZEN_FEATURE_V4L2_TBM_SUPPORT
+    case PROP_TBM_OUTPUT:
+      GST_INFO_OBJECT (self, "tbm output [%d]", self->v4l2capture->tbm_output);
+      g_value_set_boolean (value, self->v4l2capture->tbm_output);
+      break;
+#endif /* TIZEN_FEATURE_V4L2_TBM_SUPPORT */
 
       /* By default read from output */
     default:
@@ -198,6 +231,9 @@ gst_v4l2_video_dec_stop (GstVideoDecoder * decoder)
 
   /* Should have been flushed already */
   g_assert (g_atomic_int_get (&self->active) == FALSE);
+#ifdef TIZEN_FEATURE_V4L2_TBM_SUPPORT
+  gst_v4l2_video_dec_flush_buffer_event (decoder);
+#endif /* TIZEN_FEATURE_V4L2_TBM_SUPPORT */
 
   gst_v4l2_object_stop (self->v4l2output);
   gst_v4l2_object_stop (self->v4l2capture);
@@ -311,6 +347,9 @@ gst_v4l2_video_dec_flush (GstVideoDecoder * decoder)
   if (self->v4l2output->pool)
     gst_v4l2_buffer_pool_flush (self->v4l2output->pool);
 
+#ifdef TIZEN_FEATURE_V4L2_TBM_SUPPORT
+  gst_v4l2_video_dec_flush_buffer_event (decoder);
+#endif /* TIZEN_FEATURE_V4L2_TBM_SUPPORT */
   /* 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. */
@@ -519,6 +558,10 @@ gst_v4l2_video_dec_loop (GstVideoDecoder * decoder)
 beach:
   GST_DEBUG_OBJECT (decoder, "Leaving output thread: %s",
       gst_flow_get_name (ret));
+#ifdef TIZEN_FEATURE_V4L2_TBM_SUPPORT
+  if (ret == GST_FLOW_EOS)
+    gst_v4l2_video_dec_flush_buffer_event (decoder);
+#endif
 
   gst_buffer_replace (&buffer, NULL);
   self->output_flow = ret;
@@ -570,6 +613,12 @@ gst_v4l2_video_dec_handle_frame (GstVideoDecoder * decoder,
   gboolean processed = FALSE;
   GstBuffer *tmp;
   GstTaskState task_state;
+#ifdef TIZEN_FEATURE_V4L2_TBM_SUPPORT
+  GstStructure *structure = NULL;
+  const gchar *caps_format = NULL;
+  GstMessage *msg = NULL;
+  GstV4l2BufferPool *capture_pool = NULL;
+#endif /* TIZEN_FEATURE_V4L2_TBM_SUPPORT */
 
   GST_DEBUG_OBJECT (self, "Handling frame %d", frame->system_frame_number);
 
@@ -669,6 +718,19 @@ gst_v4l2_video_dec_handle_frame (GstVideoDecoder * decoder,
     caps = gst_caps_fixate (caps);
 
     GST_DEBUG_OBJECT (self, "Chosen decoded caps: %" GST_PTR_FORMAT, caps);
+#ifdef TIZEN_FEATURE_V4L2_TBM_SUPPORT
+    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_V4L2_TBM_SUPPORT */
 
     /* Try to set negotiated format, on success replace acquired format */
     if (gst_v4l2_object_set_format (self->v4l2capture, caps, &error))
@@ -695,6 +757,18 @@ gst_v4l2_video_dec_handle_frame (GstVideoDecoder * decoder,
     if (!gst_buffer_pool_set_active (GST_BUFFER_POOL (self->v4l2capture->pool),
             TRUE))
       goto activate_failed;
+#ifdef TIZEN_FEATURE_V4L2_TBM_SUPPORT
+    capture_pool = GST_V4L2_BUFFER_POOL (self->v4l2capture->pool);
+
+    msg = gst_message_new_element (GST_OBJECT_CAST (decoder),
+        gst_structure_new ("prepare-decode-buffers",
+            "num_buffers", G_TYPE_INT, capture_pool->num_allocated,
+            "extra_num_buffers", G_TYPE_INT, capture_pool->num_allocated - 2, NULL));
+
+    gst_element_post_message (GST_ELEMENT_CAST (decoder), msg);
+
+    GST_WARNING_OBJECT (self, "output buffer[%d]", capture_pool->num_allocated);
+#endif /* TIZEN_FEATURE_V4L2_TBM_SUPPORT */
   }
 
   task_state = gst_pad_get_task_state (GST_VIDEO_DECODER_SRC_PAD (self));
@@ -965,6 +1039,9 @@ gst_v4l2_video_dec_subinstance_init (GTypeInstance * instance, gpointer g_class)
       GST_OBJECT (GST_VIDEO_DECODER_SRC_PAD (self)),
       V4L2_BUF_TYPE_VIDEO_CAPTURE, klass->default_device,
       gst_v4l2_get_input, gst_v4l2_set_input, NULL);
+#ifdef TIZEN_FEATURE_V4L2_TBM_SUPPORT
+  self->v4l2capture->tbm_output = TRUE;
+#endif /* TIZEN_FEATURE_V4L2_TBM_SUPPORT */
 }
 
 static void
@@ -1017,6 +1094,12 @@ gst_v4l2_video_dec_class_init (GstV4l2VideoDecClass * klass)
       GST_DEBUG_FUNCPTR (gst_v4l2_video_dec_change_state);
 
   gst_v4l2_object_install_m2m_properties_helper (gobject_class);
+#ifdef TIZEN_FEATURE_V4L2_TBM_SUPPORT
+  g_object_class_install_property (gobject_class, PROP_TBM_OUTPUT,
+      g_param_spec_boolean ("tbm-output", "Enable TBM for output buffer",
+          "It works for only DMABUF mode.",
+          TRUE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+#endif /* TIZEN_FEATURE_V4L2_TBM_SUPPORT */
 }
 
 static void
@@ -1168,6 +1251,7 @@ gst_v4l2_video_dec_register (GstPlugin * plugin, const gchar * basename,
     type_info.instance_init = gst_v4l2_video_dec_subinstance_init;
 
     subtype = g_type_register_static (type, type_name, &type_info, 0);
+
     if (!gst_element_register (plugin, type_name, GST_RANK_PRIMARY + 1,
             subtype))
       GST_WARNING ("Failed to register plugin '%s'", type_name);