mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-31 03:29:50 +00:00
mssdemux: handle src pad queries fir duration and latency
Add a src pad query handler to get the duration from the manifest and report it upstream. Also adds a simple handler for latency queries
This commit is contained in:
parent
0f1ef317f0
commit
33d872916b
3 changed files with 96 additions and 0 deletions
|
@ -69,6 +69,8 @@ gst_mss_demux_change_state (GstElement * element, GstStateChange transition);
|
|||
static GstFlowReturn gst_mss_demux_chain (GstPad * pad, GstBuffer * buffer);
|
||||
static GstFlowReturn gst_mss_demux_event (GstPad * pad, GstEvent * event);
|
||||
|
||||
static gboolean gst_mss_demux_src_query (GstPad * pad, GstQuery * query);
|
||||
|
||||
static void gst_mss_demux_stream_loop (GstMssDemuxStream * stream);
|
||||
|
||||
static void gst_mss_demux_process_manifest (GstMssDemux * mssdemux);
|
||||
|
@ -293,6 +295,63 @@ gst_mss_demux_event (GstPad * pad, GstEvent * event)
|
|||
return ret;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_mss_demux_src_query (GstPad * pad, GstQuery * query)
|
||||
{
|
||||
GstMssDemux *mssdemux;
|
||||
gboolean ret = FALSE;
|
||||
|
||||
if (query == NULL)
|
||||
return FALSE;
|
||||
|
||||
mssdemux = GST_MSS_DEMUX (GST_PAD_PARENT (pad));
|
||||
|
||||
switch (query->type) {
|
||||
case GST_QUERY_DURATION:{
|
||||
GstClockTime duration = -1;
|
||||
GstFormat fmt;
|
||||
|
||||
gst_query_parse_duration (query, &fmt, NULL);
|
||||
if (fmt == GST_FORMAT_TIME && mssdemux->manifest) {
|
||||
/* TODO should we use the streams accumulated duration? */
|
||||
guint64 dur = gst_mss_manifest_get_duration (mssdemux->manifest);
|
||||
guint64 timescale = gst_mss_manifest_get_timescale (mssdemux->manifest);
|
||||
|
||||
if (dur != -1 && timescale != -1)
|
||||
duration =
|
||||
(GstClockTime) gst_util_uint64_scale_round (dur, GST_SECOND,
|
||||
timescale);
|
||||
|
||||
if (GST_CLOCK_TIME_IS_VALID (duration) && duration > 0) {
|
||||
gst_query_set_duration (query, GST_FORMAT_TIME, duration);
|
||||
ret = TRUE;
|
||||
}
|
||||
}
|
||||
GST_INFO_OBJECT (mssdemux, "GST_QUERY_DURATION returns %s with duration %"
|
||||
GST_TIME_FORMAT, ret ? "TRUE" : "FALSE", GST_TIME_ARGS (duration));
|
||||
break;
|
||||
}
|
||||
case GST_QUERY_LATENCY:
|
||||
gst_query_set_latency (query, FALSE, 0, -1);
|
||||
ret = TRUE;
|
||||
break;
|
||||
default:
|
||||
/* Don't fordward queries upstream because of the special nature of this
|
||||
* "demuxer", which relies on the upstream element only to be fed
|
||||
* the Manifest
|
||||
*/
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
_set_src_pad_functions (GstPad * pad)
|
||||
{
|
||||
gst_pad_set_query_function (pad, GST_DEBUG_FUNCPTR (gst_mss_demux_src_query));
|
||||
}
|
||||
|
||||
static void
|
||||
gst_mss_demux_create_streams (GstMssDemux * mssdemux)
|
||||
{
|
||||
|
@ -338,6 +397,8 @@ gst_mss_demux_create_streams (GstMssDemux * mssdemux)
|
|||
continue;
|
||||
}
|
||||
|
||||
_set_src_pad_functions (srcpad);
|
||||
|
||||
stream = gst_mss_demux_stream_new (mssdemux, manifeststream, srcpad);
|
||||
mssdemux->streams = g_slist_append (mssdemux->streams, stream);
|
||||
}
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
#define MSS_PROP_BITRATE "Bitrate"
|
||||
#define MSS_PROP_DURATION "d"
|
||||
#define MSS_PROP_NUMBER "n"
|
||||
#define MSS_PROP_STREAM_DURATION "Duration"
|
||||
#define MSS_PROP_TIME "t"
|
||||
#define MSS_PROP_TIMESCALE "TimeScale"
|
||||
#define MSS_PROP_URL "Url"
|
||||
|
@ -463,6 +464,38 @@ gst_mss_stream_get_timescale (GstMssStream * stream)
|
|||
return ts;
|
||||
}
|
||||
|
||||
guint64
|
||||
gst_mss_manifest_get_timescale (GstMssManifest * manifest)
|
||||
{
|
||||
gchar *timescale;
|
||||
guint64 ts = DEFAULT_TIMESCALE;
|
||||
|
||||
timescale =
|
||||
(gchar *) xmlGetProp (manifest->xmlrootnode,
|
||||
(xmlChar *) MSS_PROP_TIMESCALE);
|
||||
if (timescale) {
|
||||
ts = strtoull (timescale, NULL, 10);
|
||||
g_free (timescale);
|
||||
}
|
||||
return ts;
|
||||
}
|
||||
|
||||
guint64
|
||||
gst_mss_manifest_get_duration (GstMssManifest * manifest)
|
||||
{
|
||||
gchar *duration;
|
||||
guint64 dur = -1;
|
||||
|
||||
duration =
|
||||
(gchar *) xmlGetProp (manifest->xmlrootnode,
|
||||
(xmlChar *) MSS_PROP_STREAM_DURATION);
|
||||
if (duration) {
|
||||
dur = strtoull (duration, NULL, 10);
|
||||
g_free (duration);
|
||||
}
|
||||
return dur;
|
||||
}
|
||||
|
||||
GstCaps *
|
||||
gst_mss_stream_get_caps (GstMssStream * stream)
|
||||
{
|
||||
|
|
|
@ -41,6 +41,8 @@ typedef enum _GstMssStreamType {
|
|||
GstMssManifest * gst_mss_manifest_new (const GstBuffer * data);
|
||||
void gst_mss_manifest_free (GstMssManifest * manifest);
|
||||
GSList * gst_mss_manifest_get_streams (GstMssManifest * manifest);
|
||||
guint64 gst_mss_manifest_get_timescale (GstMssManifest * manifest);
|
||||
guint64 gst_mss_manifest_get_duration (GstMssManifest * manifest);
|
||||
|
||||
GstMssStreamType gst_mss_stream_get_type (GstMssStream *stream);
|
||||
GstCaps * gst_mss_stream_get_caps (GstMssStream * stream);
|
||||
|
|
Loading…
Reference in a new issue