mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-30 05:31:15 +00:00
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:
parent
52f2054386
commit
aa3d7de98b
3 changed files with 63 additions and 0 deletions
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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)))
|
||||||
|
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue