mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-06-05 06:58:56 +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_chain (GstPad * pad, GstBuffer * buffer);
|
||||||
static GstFlowReturn gst_mss_demux_event (GstPad * pad, GstEvent * event);
|
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_stream_loop (GstMssDemuxStream * stream);
|
||||||
|
|
||||||
static void gst_mss_demux_process_manifest (GstMssDemux * mssdemux);
|
static void gst_mss_demux_process_manifest (GstMssDemux * mssdemux);
|
||||||
|
@ -293,6 +295,63 @@ gst_mss_demux_event (GstPad * pad, GstEvent * event)
|
||||||
return ret;
|
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
|
static void
|
||||||
gst_mss_demux_create_streams (GstMssDemux * mssdemux)
|
gst_mss_demux_create_streams (GstMssDemux * mssdemux)
|
||||||
{
|
{
|
||||||
|
@ -338,6 +397,8 @@ gst_mss_demux_create_streams (GstMssDemux * mssdemux)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_set_src_pad_functions (srcpad);
|
||||||
|
|
||||||
stream = gst_mss_demux_stream_new (mssdemux, manifeststream, srcpad);
|
stream = gst_mss_demux_stream_new (mssdemux, manifeststream, srcpad);
|
||||||
mssdemux->streams = g_slist_append (mssdemux->streams, stream);
|
mssdemux->streams = g_slist_append (mssdemux->streams, stream);
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,6 +38,7 @@
|
||||||
#define MSS_PROP_BITRATE "Bitrate"
|
#define MSS_PROP_BITRATE "Bitrate"
|
||||||
#define MSS_PROP_DURATION "d"
|
#define MSS_PROP_DURATION "d"
|
||||||
#define MSS_PROP_NUMBER "n"
|
#define MSS_PROP_NUMBER "n"
|
||||||
|
#define MSS_PROP_STREAM_DURATION "Duration"
|
||||||
#define MSS_PROP_TIME "t"
|
#define MSS_PROP_TIME "t"
|
||||||
#define MSS_PROP_TIMESCALE "TimeScale"
|
#define MSS_PROP_TIMESCALE "TimeScale"
|
||||||
#define MSS_PROP_URL "Url"
|
#define MSS_PROP_URL "Url"
|
||||||
|
@ -463,6 +464,38 @@ gst_mss_stream_get_timescale (GstMssStream * stream)
|
||||||
return ts;
|
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 *
|
GstCaps *
|
||||||
gst_mss_stream_get_caps (GstMssStream * stream)
|
gst_mss_stream_get_caps (GstMssStream * stream)
|
||||||
{
|
{
|
||||||
|
|
|
@ -41,6 +41,8 @@ typedef enum _GstMssStreamType {
|
||||||
GstMssManifest * gst_mss_manifest_new (const GstBuffer * data);
|
GstMssManifest * gst_mss_manifest_new (const GstBuffer * data);
|
||||||
void gst_mss_manifest_free (GstMssManifest * manifest);
|
void gst_mss_manifest_free (GstMssManifest * manifest);
|
||||||
GSList * gst_mss_manifest_get_streams (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);
|
GstMssStreamType gst_mss_stream_get_type (GstMssStream *stream);
|
||||||
GstCaps * gst_mss_stream_get_caps (GstMssStream * stream);
|
GstCaps * gst_mss_stream_get_caps (GstMssStream * stream);
|
||||||
|
|
Loading…
Reference in a new issue