tsdemux: implement preliminary support for the bitrate query
authorMatthew Waters <matthew@centricular.com>
Mon, 28 May 2018 15:06:09 +0000 (01:06 +1000)
committerEdward Hervey <bilboed@bilboed.com>
Wed, 7 Nov 2018 15:09:21 +0000 (15:09 +0000)
Return the size / total duration as a ballpark estimate.

https://gitlab.freedesktop.org/gstreamer/gst-plugins-base/issues/60

gst/mpegtsdemux/mpegtsbase.c
gst/mpegtsdemux/mpegtsbase.h
gst/mpegtsdemux/tsdemux.c

index 5180c2e..1a68f86 100644 (file)
@@ -83,6 +83,10 @@ static GstFlowReturn mpegts_base_chain (GstPad * pad, GstObject * parent,
     GstBuffer * buf);
 static gboolean mpegts_base_sink_event (GstPad * pad, GstObject * parent,
     GstEvent * event);
+static gboolean mpegts_base_sink_query (GstPad * pad, GstObject * parent,
+    GstQuery * query);
+static gboolean mpegts_base_default_sink_query (MpegTSBase * base,
+    GstQuery * query);
 static GstStateChangeReturn mpegts_base_change_state (GstElement * element,
     GstStateChange transition);
 static gboolean mpegts_base_get_tags_from_eit (MpegTSBase * base,
@@ -138,6 +142,7 @@ mpegts_base_class_init (MpegTSBaseClass * klass)
           "Parse private sections", FALSE,
           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
 
+  klass->sink_query = GST_DEBUG_FUNCPTR (mpegts_base_default_sink_query);
 }
 
 static void
@@ -228,6 +233,7 @@ mpegts_base_init (MpegTSBase * base)
       mpegts_base_sink_activate_mode);
   gst_pad_set_chain_function (base->sinkpad, mpegts_base_chain);
   gst_pad_set_event_function (base->sinkpad, mpegts_base_sink_event);
+  gst_pad_set_query_function (base->sinkpad, mpegts_base_sink_query);
   gst_element_add_pad (GST_ELEMENT (base), base->sinkpad);
 
   base->disposed = FALSE;
@@ -1356,6 +1362,23 @@ mpegts_base_sink_event (GstPad * pad, GstObject * parent, GstEvent * event)
   return res;
 }
 
+static gboolean
+mpegts_base_default_sink_query (MpegTSBase * base, GstQuery * query)
+{
+  return gst_pad_query_default (base->sinkpad, GST_OBJECT (base), query);
+}
+
+static gboolean
+mpegts_base_sink_query (GstPad * pad, GstObject * parent, GstQuery * query)
+{
+  MpegTSBase *base = GST_MPEGTS_BASE (parent);
+
+  GST_DEBUG_OBJECT (base, "Got query %s",
+      gst_query_type_get_name (GST_QUERY_TYPE (query)));
+
+  return GST_MPEGTS_BASE_GET_CLASS (base)->sink_query (base, query);
+}
+
 static GstFlowReturn
 mpegts_base_chain (GstPad * pad, GstObject * parent, GstBuffer * buf)
 {
index 80a454f..5775cdd 100644 (file)
@@ -211,6 +211,9 @@ struct _MpegTSBaseClass {
   void (*nit_info) (GstStructure *nit);
   void (*sdt_info) (GstStructure *sdt);
   void (*eit_info) (GstStructure *eit);
+
+  /* takes ownership of @query */
+  gboolean (*sink_query) (MpegTSBase *base, GstQuery * query);
 };
 
 #define MPEGTS_BIT_SET(field, offs)    ((field)[(offs) >> 3] |=  (1 << ((offs) & 0x7)))
index e5c78e7..64f9d0b 100644 (file)
@@ -322,6 +322,7 @@ static void gst_ts_demux_stream_flush (TSDemuxStream * stream,
     GstTSDemux * demux, gboolean hard);
 
 static gboolean push_event (MpegTSBase * base, GstEvent * event);
+static gboolean sink_query (MpegTSBase * base, GstQuery * query);
 static void gst_ts_demux_check_and_sync_streams (GstTSDemux * demux,
     GstClockTime time);
 
@@ -394,6 +395,7 @@ gst_ts_demux_class_init (GstTSDemuxClass * klass)
   ts_class->reset = GST_DEBUG_FUNCPTR (gst_ts_demux_reset);
   ts_class->push = GST_DEBUG_FUNCPTR (gst_ts_demux_push);
   ts_class->push_event = GST_DEBUG_FUNCPTR (push_event);
+  ts_class->sink_query = GST_DEBUG_FUNCPTR (sink_query);
   ts_class->program_started = GST_DEBUG_FUNCPTR (gst_ts_demux_program_started);
   ts_class->program_stopped = GST_DEBUG_FUNCPTR (gst_ts_demux_program_stopped);
   ts_class->update_program = GST_DEBUG_FUNCPTR (gst_ts_demux_update_program);
@@ -1002,6 +1004,41 @@ push_event (MpegTSBase * base, GstEvent * event)
   return TRUE;
 }
 
+static gboolean
+sink_query (MpegTSBase * base, GstQuery * query)
+{
+  GstTSDemux *demux = (GstTSDemux *) base;
+  gboolean res = FALSE;
+
+  switch (GST_QUERY_TYPE (query)) {
+    case GST_QUERY_BITRATE:{
+      gint64 size_bytes;
+      GstClockTime duration;
+
+      if (gst_pad_peer_query_duration (base->sinkpad, GST_FORMAT_BYTES,
+              &size_bytes) && size_bytes > 0) {
+        if (gst_ts_demux_get_duration (demux, &duration) && duration > 0
+            && duration != GST_CLOCK_TIME_NONE) {
+          guint bitrate =
+              gst_util_uint64_scale (8 * size_bytes, GST_SECOND, duration);
+
+          GST_LOG_OBJECT (demux, "bitrate query byte length: %" G_GINT64_FORMAT
+              " duration %" GST_TIME_FORMAT " resulting in a bitrate of %u",
+              size_bytes, GST_TIME_ARGS (duration), bitrate);
+          gst_query_set_bitrate (query, bitrate);
+          res = TRUE;
+        }
+      }
+      break;
+    }
+    default:
+      res = GST_MPEGTS_BASE_CLASS (parent_class)->sink_query (base, query);
+      break;
+  }
+
+  return res;
+}
+
 static inline void
 add_iso639_language_to_tags (TSDemuxStream * stream, gchar * lang_code)
 {