fakesink: get buffer end time based on framerate 42/192042/5 accepted/tizen/unified/20181113.163358 submit/tizen/20181107.091634
authorEunhae Choi <eunhae1.choi@samsung.com>
Mon, 29 Oct 2018 06:59:15 +0000 (15:59 +0900)
committerEunhae Choi <eunhae1.choi@samsung.com>
Mon, 29 Oct 2018 07:17:17 +0000 (16:17 +0900)
- update end time based on the framerate information as other video sink
  not to export invalid video buffer which does not have proper duration
  via handoff signal.

Change-Id: I47f54c9255cb2c59a61d3403a230d6449700fce1

packaging/gstreamer.spec
plugins/elements/gstfakesink.c
plugins/elements/gstfakesink.h

index 7aa1ccf..6bd0e2b 100644 (file)
@@ -72,6 +72,7 @@ export CFLAGS="%{optflags} \
        -DTIZEN_FEATURE_MQ_MODIFICATION_EXTRA_SIZE_TIME\
        -DTIZEN_FEATURE_BASEPARSE_MODIFICATION\
        -DTIZEN_FEATURE_QUEUE_MODIFICATION\
+        -DTIZEN_FEATURE_FAKESINK_MODIFICATION\
 %if "%{tizen_profile_name}" == "tv"
        -DTIZEN_PROFILE_TV\
        -DRVU_LIVESTREAMING_OPTIMIZATION\
index b71f20f..27f83f7 100644 (file)
@@ -69,6 +69,10 @@ enum
 #define DEFAULT_CAN_ACTIVATE_PUSH TRUE
 #define DEFAULT_CAN_ACTIVATE_PULL FALSE
 #define DEFAULT_NUM_BUFFERS -1
+#ifdef TIZEN_FEATURE_FAKESINK_MODIFICATION
+#define DEFAULT_NUMER_FPS 0
+#define DEFAULT_DEN_FPS 1
+#endif
 
 enum
 {
@@ -134,6 +138,11 @@ static GstFlowReturn gst_fake_sink_render (GstBaseSink * bsink,
     GstBuffer * buffer);
 static gboolean gst_fake_sink_event (GstBaseSink * bsink, GstEvent * event);
 static gboolean gst_fake_sink_query (GstBaseSink * bsink, GstQuery * query);
+#ifdef TIZEN_FEATURE_FAKESINK_MODIFICATION
+static gboolean gst_fake_sink_set_caps (GstBaseSink * bsink, GstCaps * caps);
+static void gst_fake_sink_get_times (GstBaseSink * bsink, GstBuffer * buf,
+    GstClockTime * start, GstClockTime * end);
+#endif
 
 static guint gst_fake_sink_signals[LAST_SIGNAL] = { 0 };
 
@@ -241,6 +250,10 @@ gst_fake_sink_class_init (GstFakeSinkClass * klass)
   gstbase_sink_class->preroll = GST_DEBUG_FUNCPTR (gst_fake_sink_preroll);
   gstbase_sink_class->render = GST_DEBUG_FUNCPTR (gst_fake_sink_render);
   gstbase_sink_class->query = GST_DEBUG_FUNCPTR (gst_fake_sink_query);
+#ifdef TIZEN_FEATURE_FAKESINK_MODIFICATION
+  gstbase_sink_class->set_caps = GST_DEBUG_FUNCPTR (gst_fake_sink_set_caps);
+  gstbase_sink_class->get_times = GST_DEBUG_FUNCPTR (gst_fake_sink_get_times);
+#endif
 }
 
 static void
@@ -252,6 +265,10 @@ gst_fake_sink_init (GstFakeSink * fakesink)
   fakesink->state_error = DEFAULT_STATE_ERROR;
   fakesink->signal_handoffs = DEFAULT_SIGNAL_HANDOFFS;
   fakesink->num_buffers = DEFAULT_NUM_BUFFERS;
+#ifdef TIZEN_FEATURE_FAKESINK_MODIFICATION
+  fakesink->fps_n = DEFAULT_NUMER_FPS;
+  fakesink->fps_d = DEFAULT_DEN_FPS;
+#endif
 
   gst_base_sink_set_sync (GST_BASE_SINK (fakesink), DEFAULT_SYNC);
   gst_base_sink_set_drop_out_of_segment (GST_BASE_SINK (fakesink),
@@ -540,6 +557,62 @@ gst_fake_sink_query (GstBaseSink * bsink, GstQuery * query)
   return ret;
 }
 
+#ifdef TIZEN_FEATURE_FAKESINK_MODIFICATION
+static gboolean
+gst_fake_sink_set_caps (GstBaseSink * bsink, GstCaps * caps)
+{
+  GstFakeSink *sink;
+  GstStructure *structure;
+  const gchar *name;
+  gint fps_n, fps_d;
+
+  sink = GST_FAKE_SINK (bsink);
+  GST_DEBUG_OBJECT (sink, "set caps %" GST_PTR_FORMAT, caps);
+
+  structure = gst_caps_get_structure(caps, 0);
+  name = gst_structure_get_name(structure);
+
+  if (g_strrstr(name, "video/")) {
+    if (gst_structure_get_fraction (structure, "framerate", &fps_n, &fps_d)) {
+      if (fps_n == 0) {
+        /* in case of variable framerate, need to check max-framerate value */
+        gst_structure_get_fraction (structure, "max-framerate", &fps_n, &fps_d);
+      }
+      sink->fps_n = fps_n;
+      sink->fps_d = fps_d;
+    } else {
+      GST_DEBUG_OBJECT (sink, "framerate is unspecified");
+    }
+  }
+
+  return TRUE;
+}
+
+static void
+gst_fake_sink_get_times (GstBaseSink * bsink, GstBuffer * buf,
+    GstClockTime * start, GstClockTime * end)
+{
+  /* to check valid buffer based on the start and end time */
+  GstFakeSink *sink;
+
+  sink = GST_FAKE_SINK (bsink);
+
+  if (GST_BUFFER_TIMESTAMP_IS_VALID (buf)) {
+    *start = GST_BUFFER_TIMESTAMP (buf);
+
+    if (GST_BUFFER_DURATION_IS_VALID (buf)) {
+      *end = *start + GST_BUFFER_DURATION (buf);
+    } else {
+      if (sink->fps_n > 0) {
+        *end =
+            *start + gst_util_uint64_scale_int (GST_SECOND, sink->fps_d,
+            sink->fps_n);
+      }
+    }
+  }
+}
+#endif
+
 static GstStateChangeReturn
 gst_fake_sink_change_state (GstElement * element, GstStateChange transition)
 {
index 72b3671..b5b6be6 100644 (file)
@@ -73,15 +73,20 @@ typedef struct _GstFakeSinkClass GstFakeSinkClass;
  * The opaque #GstFakeSink data structure.
  */
 struct _GstFakeSink {
-  GstBaseSink          element;
+  GstBaseSink element;
 
-  gboolean             silent;
-  gboolean             dump;
-  gboolean             signal_handoffs;
+  gboolean    silent;
+  gboolean    dump;
+  gboolean    signal_handoffs;
   GstFakeSinkStateError state_error;
-  gchar                        *last_message;
-  gint                  num_buffers;
-  gint                  num_buffers_left;
+  gchar       *last_message;
+  gint        num_buffers;
+  gint        num_buffers_left;
+
+#ifdef TIZEN_FEATURE_FAKESINK_MODIFICATION
+  gint        fps_n;
+  gint        fps_d;
+#endif
 };
 
 struct _GstFakeSinkClass {