mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-20 08:41:07 +00:00
adaptivedemux: Allow subclasses to override how a new manifest would be downloaded
This commit is contained in:
parent
c1f98daa74
commit
0cd3938345
6 changed files with 82 additions and 48 deletions
|
@ -214,7 +214,7 @@ static gboolean gst_dash_demux_stream_select_bitrate (GstAdaptiveDemuxStream *
|
||||||
static gint64
|
static gint64
|
||||||
gst_dash_demux_get_manifest_update_interval (GstAdaptiveDemux * demux);
|
gst_dash_demux_get_manifest_update_interval (GstAdaptiveDemux * demux);
|
||||||
static GstFlowReturn
|
static GstFlowReturn
|
||||||
gst_dash_demux_update_manifest (GstAdaptiveDemux * demux, GstBuffer * buf);
|
gst_dash_demux_update_manifest_data (GstAdaptiveDemux * demux, GstBuffer * buf);
|
||||||
static gint64
|
static gint64
|
||||||
gst_dash_demux_stream_get_fragment_waiting_time (GstAdaptiveDemuxStream *
|
gst_dash_demux_stream_get_fragment_waiting_time (GstAdaptiveDemuxStream *
|
||||||
stream);
|
stream);
|
||||||
|
@ -354,7 +354,8 @@ gst_dash_demux_class_init (GstDashDemuxClass * klass)
|
||||||
gstadaptivedemux_class->seek = gst_dash_demux_seek;
|
gstadaptivedemux_class->seek = gst_dash_demux_seek;
|
||||||
|
|
||||||
gstadaptivedemux_class->process_manifest = gst_dash_demux_process_manifest;
|
gstadaptivedemux_class->process_manifest = gst_dash_demux_process_manifest;
|
||||||
gstadaptivedemux_class->update_manifest = gst_dash_demux_update_manifest;
|
gstadaptivedemux_class->update_manifest_data =
|
||||||
|
gst_dash_demux_update_manifest_data;
|
||||||
gstadaptivedemux_class->get_manifest_update_interval =
|
gstadaptivedemux_class->get_manifest_update_interval =
|
||||||
gst_dash_demux_get_manifest_update_interval;
|
gst_dash_demux_get_manifest_update_interval;
|
||||||
|
|
||||||
|
@ -1145,7 +1146,8 @@ gst_dash_demux_get_manifest_update_interval (GstAdaptiveDemux * demux)
|
||||||
}
|
}
|
||||||
|
|
||||||
static GstFlowReturn
|
static GstFlowReturn
|
||||||
gst_dash_demux_update_manifest (GstAdaptiveDemux * demux, GstBuffer * buffer)
|
gst_dash_demux_update_manifest_data (GstAdaptiveDemux * demux,
|
||||||
|
GstBuffer * buffer)
|
||||||
{
|
{
|
||||||
GstDashDemux *dashdemux = GST_DASH_DEMUX_CAST (demux);
|
GstDashDemux *dashdemux = GST_DASH_DEMUX_CAST (demux);
|
||||||
GstMpdClient *new_client = NULL;
|
GstMpdClient *new_client = NULL;
|
||||||
|
|
|
@ -100,8 +100,8 @@ static gint64 gst_hls_demux_get_manifest_update_interval (GstAdaptiveDemux *
|
||||||
demux);
|
demux);
|
||||||
static gboolean gst_hls_demux_process_manifest (GstAdaptiveDemux * demux,
|
static gboolean gst_hls_demux_process_manifest (GstAdaptiveDemux * demux,
|
||||||
GstBuffer * buf);
|
GstBuffer * buf);
|
||||||
static GstFlowReturn gst_hls_demux_update_manifest (GstAdaptiveDemux * demux,
|
static GstFlowReturn gst_hls_demux_update_manifest_data (GstAdaptiveDemux *
|
||||||
GstBuffer * buf);
|
demux, GstBuffer * buf);
|
||||||
static gboolean gst_hls_demux_seek (GstAdaptiveDemux * demux, GstEvent * seek);
|
static gboolean gst_hls_demux_seek (GstAdaptiveDemux * demux, GstEvent * seek);
|
||||||
static gboolean
|
static gboolean
|
||||||
gst_hls_demux_start_fragment (GstAdaptiveDemux * demux,
|
gst_hls_demux_start_fragment (GstAdaptiveDemux * demux,
|
||||||
|
@ -186,7 +186,8 @@ gst_hls_demux_class_init (GstHLSDemuxClass * klass)
|
||||||
adaptivedemux_class->get_manifest_update_interval =
|
adaptivedemux_class->get_manifest_update_interval =
|
||||||
gst_hls_demux_get_manifest_update_interval;
|
gst_hls_demux_get_manifest_update_interval;
|
||||||
adaptivedemux_class->process_manifest = gst_hls_demux_process_manifest;
|
adaptivedemux_class->process_manifest = gst_hls_demux_process_manifest;
|
||||||
adaptivedemux_class->update_manifest = gst_hls_demux_update_manifest;
|
adaptivedemux_class->update_manifest_data =
|
||||||
|
gst_hls_demux_update_manifest_data;
|
||||||
adaptivedemux_class->reset = gst_hls_demux_reset;
|
adaptivedemux_class->reset = gst_hls_demux_reset;
|
||||||
adaptivedemux_class->seek = gst_hls_demux_seek;
|
adaptivedemux_class->seek = gst_hls_demux_seek;
|
||||||
adaptivedemux_class->stream_has_next_fragment =
|
adaptivedemux_class->stream_has_next_fragment =
|
||||||
|
@ -400,7 +401,7 @@ gst_hls_demux_seek (GstAdaptiveDemux * demux, GstEvent * seek)
|
||||||
}
|
}
|
||||||
|
|
||||||
static GstFlowReturn
|
static GstFlowReturn
|
||||||
gst_hls_demux_update_manifest (GstAdaptiveDemux * demux, GstBuffer * buf)
|
gst_hls_demux_update_manifest_data (GstAdaptiveDemux * demux, GstBuffer * buf)
|
||||||
{
|
{
|
||||||
GstHLSDemux *hlsdemux = GST_HLS_DEMUX_CAST (demux);
|
GstHLSDemux *hlsdemux = GST_HLS_DEMUX_CAST (demux);
|
||||||
if (!gst_hls_demux_update_playlist (hlsdemux, TRUE, NULL))
|
if (!gst_hls_demux_update_playlist (hlsdemux, TRUE, NULL))
|
||||||
|
|
|
@ -135,7 +135,8 @@ static gboolean gst_mss_demux_seek (GstAdaptiveDemux * demux, GstEvent * seek);
|
||||||
static gint64
|
static gint64
|
||||||
gst_mss_demux_get_manifest_update_interval (GstAdaptiveDemux * demux);
|
gst_mss_demux_get_manifest_update_interval (GstAdaptiveDemux * demux);
|
||||||
static GstFlowReturn
|
static GstFlowReturn
|
||||||
gst_mss_demux_update_manifest (GstAdaptiveDemux * demux, GstBuffer * buffer);
|
gst_mss_demux_update_manifest_data (GstAdaptiveDemux * demux,
|
||||||
|
GstBuffer * buffer);
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gst_mss_demux_class_init (GstMssDemuxClass * klass)
|
gst_mss_demux_class_init (GstMssDemuxClass * klass)
|
||||||
|
@ -188,7 +189,8 @@ gst_mss_demux_class_init (GstMssDemuxClass * klass)
|
||||||
gst_mss_demux_stream_select_bitrate;
|
gst_mss_demux_stream_select_bitrate;
|
||||||
gstadaptivedemux_class->stream_update_fragment_info =
|
gstadaptivedemux_class->stream_update_fragment_info =
|
||||||
gst_mss_demux_stream_update_fragment_info;
|
gst_mss_demux_stream_update_fragment_info;
|
||||||
gstadaptivedemux_class->update_manifest = gst_mss_demux_update_manifest;
|
gstadaptivedemux_class->update_manifest_data =
|
||||||
|
gst_mss_demux_update_manifest_data;
|
||||||
|
|
||||||
GST_DEBUG_CATEGORY_INIT (mssdemux_debug, "mssdemux", 0, "mssdemux plugin");
|
GST_DEBUG_CATEGORY_INIT (mssdemux_debug, "mssdemux", 0, "mssdemux plugin");
|
||||||
}
|
}
|
||||||
|
@ -546,7 +548,8 @@ gst_mss_demux_get_manifest_update_interval (GstAdaptiveDemux * demux)
|
||||||
}
|
}
|
||||||
|
|
||||||
static GstFlowReturn
|
static GstFlowReturn
|
||||||
gst_mss_demux_update_manifest (GstAdaptiveDemux * demux, GstBuffer * buffer)
|
gst_mss_demux_update_manifest_data (GstAdaptiveDemux * demux,
|
||||||
|
GstBuffer * buffer)
|
||||||
{
|
{
|
||||||
GstMssDemux *mssdemux = GST_MSS_DEMUX_CAST (demux);
|
GstMssDemux *mssdemux = GST_MSS_DEMUX_CAST (demux);
|
||||||
|
|
||||||
|
|
|
@ -724,7 +724,8 @@ _gst_mss_stream_audio_caps_from_qualitylevel_xml (GstMssStreamQuality * q)
|
||||||
gst_structure_set (structure, "rate", G_TYPE_INT, rate, NULL);
|
gst_structure_set (structure, "rate", G_TYPE_INT, rate, NULL);
|
||||||
|
|
||||||
if (q->bitrate)
|
if (q->bitrate)
|
||||||
gst_structure_set (structure, "bitrate", G_TYPE_INT, (int) q->bitrate, NULL);
|
gst_structure_set (structure, "bitrate", G_TYPE_INT, (int) q->bitrate,
|
||||||
|
NULL);
|
||||||
|
|
||||||
if (codec_data)
|
if (codec_data)
|
||||||
gst_structure_set (structure, "codec_data", GST_TYPE_BUFFER, codec_data,
|
gst_structure_set (structure, "codec_data", GST_TYPE_BUFFER, codec_data,
|
||||||
|
|
|
@ -106,7 +106,7 @@ enum GstAdaptiveDemuxFlowReturn
|
||||||
struct _GstAdaptiveDemuxPrivate
|
struct _GstAdaptiveDemuxPrivate
|
||||||
{
|
{
|
||||||
GstAdapter *input_adapter;
|
GstAdapter *input_adapter;
|
||||||
GstBuffer *manifest_buffer;
|
gboolean have_manifest;
|
||||||
|
|
||||||
GstUriDownloader *downloader;
|
GstUriDownloader *downloader;
|
||||||
|
|
||||||
|
@ -167,6 +167,8 @@ gst_adaptive_demux_stream_get_fragment_waiting_time (GstAdaptiveDemux * demux,
|
||||||
GstAdaptiveDemuxStream * stream);
|
GstAdaptiveDemuxStream * stream);
|
||||||
static GstFlowReturn gst_adaptive_demux_update_manifest (GstAdaptiveDemux *
|
static GstFlowReturn gst_adaptive_demux_update_manifest (GstAdaptiveDemux *
|
||||||
demux);
|
demux);
|
||||||
|
static GstFlowReturn
|
||||||
|
gst_adaptive_demux_update_manifest_default (GstAdaptiveDemux * demux);
|
||||||
static gboolean gst_adaptive_demux_has_next_period (GstAdaptiveDemux * demux);
|
static gboolean gst_adaptive_demux_has_next_period (GstAdaptiveDemux * demux);
|
||||||
static void gst_adaptive_demux_advance_period (GstAdaptiveDemux * demux);
|
static void gst_adaptive_demux_advance_period (GstAdaptiveDemux * demux);
|
||||||
|
|
||||||
|
@ -314,6 +316,7 @@ gst_adaptive_demux_class_init (GstAdaptiveDemuxClass * klass)
|
||||||
|
|
||||||
klass->data_received = gst_adaptive_demux_stream_data_received_default;
|
klass->data_received = gst_adaptive_demux_stream_data_received_default;
|
||||||
klass->finish_fragment = gst_adaptive_demux_stream_finish_fragment_default;
|
klass->finish_fragment = gst_adaptive_demux_stream_finish_fragment_default;
|
||||||
|
klass->update_manifest = gst_adaptive_demux_update_manifest_default;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -419,6 +422,7 @@ gst_adaptive_demux_sink_event (GstPad * pad, GstObject * parent,
|
||||||
gboolean query_res;
|
gboolean query_res;
|
||||||
gboolean ret = TRUE;
|
gboolean ret = TRUE;
|
||||||
gsize available;
|
gsize available;
|
||||||
|
GstBuffer *manifest_buffer;
|
||||||
|
|
||||||
demux_class = GST_ADAPTIVE_DEMUX_GET_CLASS (demux);
|
demux_class = GST_ADAPTIVE_DEMUX_GET_CLASS (demux);
|
||||||
available = gst_adapter_available (demux->priv->input_adapter);
|
available = gst_adapter_available (demux->priv->input_adapter);
|
||||||
|
@ -460,16 +464,19 @@ gst_adaptive_demux_sink_event (GstPad * pad, GstObject * parent,
|
||||||
gst_query_unref (query);
|
gst_query_unref (query);
|
||||||
|
|
||||||
/* Let the subclass parse the manifest */
|
/* Let the subclass parse the manifest */
|
||||||
demux->priv->manifest_buffer =
|
manifest_buffer =
|
||||||
gst_adapter_take_buffer (demux->priv->input_adapter, available);
|
gst_adapter_take_buffer (demux->priv->input_adapter, available);
|
||||||
if (!demux_class->process_manifest (demux, demux->priv->manifest_buffer)) {
|
if (!demux_class->process_manifest (demux, manifest_buffer)) {
|
||||||
/* In most cases, this will happen if we set a wrong url in the
|
/* In most cases, this will happen if we set a wrong url in the
|
||||||
* source element and we have received the 404 HTML response instead of
|
* source element and we have received the 404 HTML response instead of
|
||||||
* the manifest */
|
* the manifest */
|
||||||
GST_ELEMENT_ERROR (demux, STREAM, DECODE, ("Invalid manifest."),
|
GST_ELEMENT_ERROR (demux, STREAM, DECODE, ("Invalid manifest."),
|
||||||
(NULL));
|
(NULL));
|
||||||
ret = FALSE;
|
ret = FALSE;
|
||||||
|
} else {
|
||||||
|
demux->priv->have_manifest = TRUE;
|
||||||
}
|
}
|
||||||
|
gst_buffer_unref (manifest_buffer);
|
||||||
|
|
||||||
gst_element_post_message (GST_ELEMENT_CAST (demux),
|
gst_element_post_message (GST_ELEMENT_CAST (demux),
|
||||||
gst_message_new_element (GST_OBJECT_CAST (demux),
|
gst_message_new_element (GST_OBJECT_CAST (demux),
|
||||||
|
@ -578,10 +585,7 @@ gst_adaptive_demux_reset (GstAdaptiveDemux * demux)
|
||||||
demux->manifest_base_uri = NULL;
|
demux->manifest_base_uri = NULL;
|
||||||
|
|
||||||
gst_adapter_clear (demux->priv->input_adapter);
|
gst_adapter_clear (demux->priv->input_adapter);
|
||||||
if (demux->priv->manifest_buffer) {
|
demux->priv->have_manifest = FALSE;
|
||||||
gst_buffer_unref (demux->priv->manifest_buffer);
|
|
||||||
demux->priv->manifest_buffer = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
gst_segment_init (&demux->segment, GST_FORMAT_TIME);
|
gst_segment_init (&demux->segment, GST_FORMAT_TIME);
|
||||||
|
|
||||||
|
@ -1101,7 +1105,7 @@ gst_adaptive_demux_src_query (GstPad * pad, GstObject * parent,
|
||||||
|
|
||||||
GST_MANIFEST_LOCK (demux);
|
GST_MANIFEST_LOCK (demux);
|
||||||
gst_query_parse_duration (query, &fmt, NULL);
|
gst_query_parse_duration (query, &fmt, NULL);
|
||||||
if (fmt == GST_FORMAT_TIME && demux->priv->manifest_buffer != NULL) {
|
if (fmt == GST_FORMAT_TIME && demux->priv->have_manifest) {
|
||||||
duration = demux_class->get_duration (demux);
|
duration = demux_class->get_duration (demux);
|
||||||
|
|
||||||
if (GST_CLOCK_TIME_IS_VALID (duration) && duration > 0) {
|
if (GST_CLOCK_TIME_IS_VALID (duration) && duration > 0) {
|
||||||
|
@ -1118,7 +1122,7 @@ gst_adaptive_demux_src_query (GstPad * pad, GstObject * parent,
|
||||||
gboolean live = FALSE;
|
gboolean live = FALSE;
|
||||||
|
|
||||||
GST_MANIFEST_LOCK (demux);
|
GST_MANIFEST_LOCK (demux);
|
||||||
live = demux->priv->manifest_buffer && gst_adaptive_demux_is_live (demux);
|
live = demux->priv->have_manifest && gst_adaptive_demux_is_live (demux);
|
||||||
GST_MANIFEST_UNLOCK (demux);
|
GST_MANIFEST_UNLOCK (demux);
|
||||||
|
|
||||||
gst_query_set_latency (query, live, 0, -1);
|
gst_query_set_latency (query, live, 0, -1);
|
||||||
|
@ -1131,7 +1135,7 @@ gst_adaptive_demux_src_query (GstPad * pad, GstObject * parent,
|
||||||
gint64 start = 0;
|
gint64 start = 0;
|
||||||
|
|
||||||
GST_MANIFEST_LOCK (demux);
|
GST_MANIFEST_LOCK (demux);
|
||||||
if (demux->priv->manifest_buffer == NULL) {
|
if (demux->priv->have_manifest) {
|
||||||
GST_MANIFEST_UNLOCK (demux);
|
GST_MANIFEST_UNLOCK (demux);
|
||||||
return FALSE; /* can't answer without manifest */
|
return FALSE; /* can't answer without manifest */
|
||||||
}
|
}
|
||||||
|
@ -2470,7 +2474,7 @@ gst_adaptive_demux_stream_get_fragment_waiting_time (GstAdaptiveDemux *
|
||||||
}
|
}
|
||||||
|
|
||||||
static GstFlowReturn
|
static GstFlowReturn
|
||||||
gst_adaptive_demux_update_manifest (GstAdaptiveDemux * demux)
|
gst_adaptive_demux_update_manifest_default (GstAdaptiveDemux * demux)
|
||||||
{
|
{
|
||||||
GstAdaptiveDemuxClass *klass = GST_ADAPTIVE_DEMUX_GET_CLASS (demux);
|
GstAdaptiveDemuxClass *klass = GST_ADAPTIVE_DEMUX_GET_CLASS (demux);
|
||||||
GstFragment *download;
|
GstFragment *download;
|
||||||
|
@ -2493,31 +2497,11 @@ gst_adaptive_demux_update_manifest (GstAdaptiveDemux * demux)
|
||||||
|
|
||||||
buffer = gst_fragment_get_buffer (download);
|
buffer = gst_fragment_get_buffer (download);
|
||||||
g_object_unref (download);
|
g_object_unref (download);
|
||||||
ret = klass->update_manifest (demux, buffer);
|
ret = klass->update_manifest_data (demux, buffer);
|
||||||
if (ret == GST_FLOW_OK) {
|
gst_buffer_unref (buffer);
|
||||||
GstClockTime duration;
|
GST_MANIFEST_UNLOCK (demux);
|
||||||
gst_buffer_unref (demux->priv->manifest_buffer);
|
/* FIXME: Should the manifest uri vars be reverted to original
|
||||||
demux->priv->manifest_buffer = buffer;
|
* values if updating fails? */
|
||||||
|
|
||||||
/* Send an updated duration message */
|
|
||||||
duration = klass->get_duration (demux);
|
|
||||||
|
|
||||||
GST_MANIFEST_UNLOCK (demux);
|
|
||||||
if (duration != GST_CLOCK_TIME_NONE) {
|
|
||||||
GST_DEBUG_OBJECT (demux,
|
|
||||||
"Sending duration message : %" GST_TIME_FORMAT,
|
|
||||||
GST_TIME_ARGS (duration));
|
|
||||||
gst_element_post_message (GST_ELEMENT (demux),
|
|
||||||
gst_message_new_duration_changed (GST_OBJECT (demux)));
|
|
||||||
} else {
|
|
||||||
GST_DEBUG_OBJECT (demux,
|
|
||||||
"Duration unknown, can not send the duration message");
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
GST_MANIFEST_UNLOCK (demux);
|
|
||||||
gst_buffer_unref (buffer);
|
|
||||||
/* Should the manifest uri vars be reverted to original values? */
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
ret = GST_FLOW_NOT_LINKED;
|
ret = GST_FLOW_NOT_LINKED;
|
||||||
}
|
}
|
||||||
|
@ -2525,6 +2509,35 @@ gst_adaptive_demux_update_manifest (GstAdaptiveDemux * demux)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static GstFlowReturn
|
||||||
|
gst_adaptive_demux_update_manifest (GstAdaptiveDemux * demux)
|
||||||
|
{
|
||||||
|
GstAdaptiveDemuxClass *klass = GST_ADAPTIVE_DEMUX_GET_CLASS (demux);
|
||||||
|
GstFlowReturn ret;
|
||||||
|
|
||||||
|
ret = klass->update_manifest (demux);
|
||||||
|
|
||||||
|
if (ret == GST_FLOW_OK) {
|
||||||
|
GstClockTime duration;
|
||||||
|
GST_MANIFEST_LOCK (demux);
|
||||||
|
/* Send an updated duration message */
|
||||||
|
duration = klass->get_duration (demux);
|
||||||
|
GST_MANIFEST_UNLOCK (demux);
|
||||||
|
if (duration != GST_CLOCK_TIME_NONE) {
|
||||||
|
GST_DEBUG_OBJECT (demux,
|
||||||
|
"Sending duration message : %" GST_TIME_FORMAT,
|
||||||
|
GST_TIME_ARGS (duration));
|
||||||
|
gst_element_post_message (GST_ELEMENT (demux),
|
||||||
|
gst_message_new_duration_changed (GST_OBJECT (demux)));
|
||||||
|
} else {
|
||||||
|
GST_DEBUG_OBJECT (demux,
|
||||||
|
"Duration unknown, can not send the duration message");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
gst_adaptive_demux_stream_fragment_clear (GstAdaptiveDemuxStreamFragment * f)
|
gst_adaptive_demux_stream_fragment_clear (GstAdaptiveDemuxStreamFragment * f)
|
||||||
{
|
{
|
||||||
|
|
|
@ -237,9 +237,23 @@ struct _GstAdaptiveDemuxClass
|
||||||
* Returns: the update interval in microseconds
|
* Returns: the update interval in microseconds
|
||||||
*/
|
*/
|
||||||
gint64 (*get_manifest_update_interval) (GstAdaptiveDemux * demux);
|
gint64 (*get_manifest_update_interval) (GstAdaptiveDemux * demux);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* update_manifest:
|
* update_manifest:
|
||||||
* @demux: #GstAdaptiveDemux
|
* @demux: #GstAdaptiveDemux
|
||||||
|
*
|
||||||
|
* During live streaming, this will be called for the subclass to update its
|
||||||
|
* manifest with the new version. By default it fetches the manifest URI
|
||||||
|
* and passes it to GstAdaptiveDemux::update_manifest_data().
|
||||||
|
*
|
||||||
|
* Returns: #GST_FLOW_OK is all succeeded, #GST_FLOW_EOS if the stream ended
|
||||||
|
* or #GST_FLOW_ERROR if an error happened
|
||||||
|
*/
|
||||||
|
GstFlowReturn (*update_manifest) (GstAdaptiveDemux * demux);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* update_manifest_data:
|
||||||
|
* @demux: #GstAdaptiveDemux
|
||||||
* @buf: Downloaded manifest data
|
* @buf: Downloaded manifest data
|
||||||
*
|
*
|
||||||
* During live streaming, this will be called for the subclass to update its
|
* During live streaming, this will be called for the subclass to update its
|
||||||
|
@ -248,7 +262,7 @@ struct _GstAdaptiveDemuxClass
|
||||||
* Returns: #GST_FLOW_OK is all succeeded, #GST_FLOW_EOS if the stream ended
|
* Returns: #GST_FLOW_OK is all succeeded, #GST_FLOW_EOS if the stream ended
|
||||||
* or #GST_FLOW_ERROR if an error happened
|
* or #GST_FLOW_ERROR if an error happened
|
||||||
*/
|
*/
|
||||||
GstFlowReturn (*update_manifest) (GstAdaptiveDemux * demux, GstBuffer * buf);
|
GstFlowReturn (*update_manifest_data) (GstAdaptiveDemux * demux, GstBuffer * buf);
|
||||||
|
|
||||||
gboolean (*is_live) (GstAdaptiveDemux * demux);
|
gboolean (*is_live) (GstAdaptiveDemux * demux);
|
||||||
GstClockTime (*get_duration) (GstAdaptiveDemux * demux);
|
GstClockTime (*get_duration) (GstAdaptiveDemux * demux);
|
||||||
|
|
Loading…
Reference in a new issue