tsdemux: implement preliminary support for the bitrate query

Return the size / total duration as a ballpark estimate.

https://gitlab.freedesktop.org/gstreamer/gst-plugins-base/issues/60
This commit is contained in:
Matthew Waters 2018-05-29 01:06:09 +10:00 committed by Edward Hervey
parent 52f2054386
commit aa3d7de98b
3 changed files with 63 additions and 0 deletions

View file

@ -83,6 +83,10 @@ static GstFlowReturn mpegts_base_chain (GstPad * pad, GstObject * parent,
GstBuffer * buf); GstBuffer * buf);
static gboolean mpegts_base_sink_event (GstPad * pad, GstObject * parent, static gboolean mpegts_base_sink_event (GstPad * pad, GstObject * parent,
GstEvent * event); 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, static GstStateChangeReturn mpegts_base_change_state (GstElement * element,
GstStateChange transition); GstStateChange transition);
static gboolean mpegts_base_get_tags_from_eit (MpegTSBase * base, static gboolean mpegts_base_get_tags_from_eit (MpegTSBase * base,
@ -138,6 +142,7 @@ mpegts_base_class_init (MpegTSBaseClass * klass)
"Parse private sections", FALSE, "Parse private sections", FALSE,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
klass->sink_query = GST_DEBUG_FUNCPTR (mpegts_base_default_sink_query);
} }
static void static void
@ -228,6 +233,7 @@ mpegts_base_init (MpegTSBase * base)
mpegts_base_sink_activate_mode); mpegts_base_sink_activate_mode);
gst_pad_set_chain_function (base->sinkpad, mpegts_base_chain); gst_pad_set_chain_function (base->sinkpad, mpegts_base_chain);
gst_pad_set_event_function (base->sinkpad, mpegts_base_sink_event); 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); gst_element_add_pad (GST_ELEMENT (base), base->sinkpad);
base->disposed = FALSE; base->disposed = FALSE;
@ -1356,6 +1362,23 @@ mpegts_base_sink_event (GstPad * pad, GstObject * parent, GstEvent * event)
return res; 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 static GstFlowReturn
mpegts_base_chain (GstPad * pad, GstObject * parent, GstBuffer * buf) mpegts_base_chain (GstPad * pad, GstObject * parent, GstBuffer * buf)
{ {

View file

@ -211,6 +211,9 @@ struct _MpegTSBaseClass {
void (*nit_info) (GstStructure *nit); void (*nit_info) (GstStructure *nit);
void (*sdt_info) (GstStructure *sdt); void (*sdt_info) (GstStructure *sdt);
void (*eit_info) (GstStructure *eit); 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))) #define MPEGTS_BIT_SET(field, offs) ((field)[(offs) >> 3] |= (1 << ((offs) & 0x7)))

View file

@ -322,6 +322,7 @@ static void gst_ts_demux_stream_flush (TSDemuxStream * stream,
GstTSDemux * demux, gboolean hard); GstTSDemux * demux, gboolean hard);
static gboolean push_event (MpegTSBase * base, GstEvent * event); 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, static void gst_ts_demux_check_and_sync_streams (GstTSDemux * demux,
GstClockTime time); 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->reset = GST_DEBUG_FUNCPTR (gst_ts_demux_reset);
ts_class->push = GST_DEBUG_FUNCPTR (gst_ts_demux_push); ts_class->push = GST_DEBUG_FUNCPTR (gst_ts_demux_push);
ts_class->push_event = GST_DEBUG_FUNCPTR (push_event); 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_started = GST_DEBUG_FUNCPTR (gst_ts_demux_program_started);
ts_class->program_stopped = GST_DEBUG_FUNCPTR (gst_ts_demux_program_stopped); ts_class->program_stopped = GST_DEBUG_FUNCPTR (gst_ts_demux_program_stopped);
ts_class->update_program = GST_DEBUG_FUNCPTR (gst_ts_demux_update_program); ts_class->update_program = GST_DEBUG_FUNCPTR (gst_ts_demux_update_program);
@ -1002,6 +1004,41 @@ push_event (MpegTSBase * base, GstEvent * event)
return TRUE; 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 static inline void
add_iso639_language_to_tags (TSDemuxStream * stream, gchar * lang_code) add_iso639_language_to_tags (TSDemuxStream * stream, gchar * lang_code)
{ {