mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-30 05:31:15 +00:00
dash: split mpdparser, mpdclient and xmlhelper
provide a separate namespace for mpd helper for xml parsing and the real mpd parsing.
This commit is contained in:
parent
4eac9d0ae6
commit
86b251b7d1
12 changed files with 5127 additions and 4920 deletions
|
@ -520,7 +520,7 @@ gst_dash_demux_get_presentation_offset (GstAdaptiveDemux * demux,
|
||||||
GstDashDemuxStream *dashstream = (GstDashDemuxStream *) stream;
|
GstDashDemuxStream *dashstream = (GstDashDemuxStream *) stream;
|
||||||
GstDashDemux *dashdemux = GST_DASH_DEMUX_CAST (demux);
|
GstDashDemux *dashdemux = GST_DASH_DEMUX_CAST (demux);
|
||||||
|
|
||||||
return gst_mpd_parser_get_stream_presentation_offset (dashdemux->client,
|
return gst_mpd_client_get_stream_presentation_offset (dashdemux->client,
|
||||||
dashstream->index);
|
dashstream->index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -529,7 +529,7 @@ gst_dash_demux_get_period_start_time (GstAdaptiveDemux * demux)
|
||||||
{
|
{
|
||||||
GstDashDemux *dashdemux = GST_DASH_DEMUX_CAST (demux);
|
GstDashDemux *dashdemux = GST_DASH_DEMUX_CAST (demux);
|
||||||
|
|
||||||
return gst_mpd_parser_get_period_start_time (dashdemux->client);
|
return gst_mpd_client_get_period_start_time (dashdemux->client);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -778,14 +778,14 @@ gst_dash_demux_setup_all_streams (GstDashDemux * demux)
|
||||||
gst_mpd_client_get_period_index (demux->client));
|
gst_mpd_client_get_period_index (demux->client));
|
||||||
|
|
||||||
/* clean old active stream list, if any */
|
/* clean old active stream list, if any */
|
||||||
gst_active_streams_free (demux->client);
|
gst_mpd_client_active_streams_free (demux->client);
|
||||||
|
|
||||||
if (!gst_dash_demux_setup_mpdparser_streams (demux, demux->client)) {
|
if (!gst_dash_demux_setup_mpdparser_streams (demux, demux->client)) {
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (demux, "Creating stream objects");
|
GST_DEBUG_OBJECT (demux, "Creating stream objects");
|
||||||
for (i = 0; i < gst_mpdparser_get_nb_active_stream (demux->client); i++) {
|
for (i = 0; i < gst_mpd_client_get_nb_active_stream (demux->client); i++) {
|
||||||
GstDashDemuxStream *stream;
|
GstDashDemuxStream *stream;
|
||||||
GstActiveStream *active_stream;
|
GstActiveStream *active_stream;
|
||||||
GstCaps *caps;
|
GstCaps *caps;
|
||||||
|
@ -794,7 +794,8 @@ gst_dash_demux_setup_all_streams (GstDashDemux * demux)
|
||||||
gchar *lang = NULL;
|
gchar *lang = NULL;
|
||||||
GstTagList *tags = NULL;
|
GstTagList *tags = NULL;
|
||||||
|
|
||||||
active_stream = gst_mpdparser_get_active_stream_by_index (demux->client, i);
|
active_stream =
|
||||||
|
gst_mpd_client_get_active_stream_by_index (demux->client, i);
|
||||||
if (active_stream == NULL)
|
if (active_stream == NULL)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -1036,7 +1037,7 @@ gst_dash_demux_process_manifest (GstAdaptiveDemux * demux, GstBuffer * buf)
|
||||||
|
|
||||||
if (gst_buffer_map (buf, &mapinfo, GST_MAP_READ)) {
|
if (gst_buffer_map (buf, &mapinfo, GST_MAP_READ)) {
|
||||||
manifest = (gchar *) mapinfo.data;
|
manifest = (gchar *) mapinfo.data;
|
||||||
if (gst_mpd_parse (dashdemux->client, manifest, mapinfo.size)) {
|
if (gst_mpd_client_parse (dashdemux->client, manifest, mapinfo.size)) {
|
||||||
if (gst_mpd_client_setup_media_presentation (dashdemux->client, 0, 0,
|
if (gst_mpd_client_setup_media_presentation (dashdemux->client, 0, 0,
|
||||||
NULL)) {
|
NULL)) {
|
||||||
ret = TRUE;
|
ret = TRUE;
|
||||||
|
@ -1232,7 +1233,7 @@ gst_dash_demux_stream_update_headers_info (GstAdaptiveDemuxStream * stream)
|
||||||
|
|
||||||
if (path != NULL) {
|
if (path != NULL) {
|
||||||
stream->fragment.header_uri =
|
stream->fragment.header_uri =
|
||||||
gst_uri_join_strings (gst_mpdparser_get_baseURL (dashdemux->client,
|
gst_uri_join_strings (gst_mpd_client_get_baseURL (dashdemux->client,
|
||||||
dashstream->index), path);
|
dashstream->index), path);
|
||||||
g_free (path);
|
g_free (path);
|
||||||
path = NULL;
|
path = NULL;
|
||||||
|
@ -1244,7 +1245,7 @@ gst_dash_demux_stream_update_headers_info (GstAdaptiveDemuxStream * stream)
|
||||||
|
|
||||||
if (path != NULL) {
|
if (path != NULL) {
|
||||||
stream->fragment.index_uri =
|
stream->fragment.index_uri =
|
||||||
gst_uri_join_strings (gst_mpdparser_get_baseURL (dashdemux->client,
|
gst_uri_join_strings (gst_mpd_client_get_baseURL (dashdemux->client,
|
||||||
dashstream->index), path);
|
dashstream->index), path);
|
||||||
g_free (path);
|
g_free (path);
|
||||||
}
|
}
|
||||||
|
@ -1501,9 +1502,9 @@ gst_dash_demux_stream_seek (GstAdaptiveDemuxStream * stream, gboolean forward,
|
||||||
if (is_isobmff) {
|
if (is_isobmff) {
|
||||||
GstClockTime period_start, offset;
|
GstClockTime period_start, offset;
|
||||||
|
|
||||||
period_start = gst_mpd_parser_get_period_start_time (dashdemux->client);
|
period_start = gst_mpd_client_get_period_start_time (dashdemux->client);
|
||||||
offset =
|
offset =
|
||||||
gst_mpd_parser_get_stream_presentation_offset (dashdemux->client,
|
gst_mpd_client_get_stream_presentation_offset (dashdemux->client,
|
||||||
dashstream->index);
|
dashstream->index);
|
||||||
|
|
||||||
if (G_UNLIKELY (ts < period_start))
|
if (G_UNLIKELY (ts < period_start))
|
||||||
|
@ -2198,12 +2199,12 @@ gst_dash_demux_stream_select_bitrate (GstAdaptiveDemuxStream * stream,
|
||||||
if (GST_ADAPTIVE_DEMUX_IN_TRICKMODE_KEY_UNITS (base_demux) ||
|
if (GST_ADAPTIVE_DEMUX_IN_TRICKMODE_KEY_UNITS (base_demux) ||
|
||||||
ABS (base_demux->segment.rate) <= 1.0) {
|
ABS (base_demux->segment.rate) <= 1.0) {
|
||||||
new_index =
|
new_index =
|
||||||
gst_mpdparser_get_rep_idx_with_max_bandwidth (rep_list, bitrate,
|
gst_mpd_client_get_rep_idx_with_max_bandwidth (rep_list, bitrate,
|
||||||
demux->max_video_width, demux->max_video_height,
|
demux->max_video_width, demux->max_video_height,
|
||||||
demux->max_video_framerate_n, demux->max_video_framerate_d);
|
demux->max_video_framerate_n, demux->max_video_framerate_d);
|
||||||
} else {
|
} else {
|
||||||
new_index =
|
new_index =
|
||||||
gst_mpdparser_get_rep_idx_with_max_bandwidth (rep_list,
|
gst_mpd_client_get_rep_idx_with_max_bandwidth (rep_list,
|
||||||
bitrate / ABS (base_demux->segment.rate), demux->max_video_width,
|
bitrate / ABS (base_demux->segment.rate), demux->max_video_width,
|
||||||
demux->max_video_height, demux->max_video_framerate_n,
|
demux->max_video_height, demux->max_video_framerate_n,
|
||||||
demux->max_video_framerate_d);
|
demux->max_video_framerate_d);
|
||||||
|
@ -2211,7 +2212,7 @@ gst_dash_demux_stream_select_bitrate (GstAdaptiveDemuxStream * stream,
|
||||||
|
|
||||||
/* if no representation has the required bandwidth, take the lowest one */
|
/* if no representation has the required bandwidth, take the lowest one */
|
||||||
if (new_index == -1)
|
if (new_index == -1)
|
||||||
new_index = gst_mpdparser_get_rep_idx_with_min_bandwidth (rep_list);
|
new_index = gst_mpd_client_get_rep_idx_with_min_bandwidth (rep_list);
|
||||||
|
|
||||||
if (new_index != active_stream->representation_idx) {
|
if (new_index != active_stream->representation_idx) {
|
||||||
GstRepresentationNode *rep = g_list_nth_data (rep_list, new_index);
|
GstRepresentationNode *rep = g_list_nth_data (rep_list, new_index);
|
||||||
|
@ -2346,7 +2347,7 @@ gst_dash_demux_seek (GstAdaptiveDemux * demux, GstEvent * seek)
|
||||||
GST_DEBUG_OBJECT (demux, "Seeking to Period %d", current_period);
|
GST_DEBUG_OBJECT (demux, "Seeking to Period %d", current_period);
|
||||||
|
|
||||||
/* clean old active stream list, if any */
|
/* clean old active stream list, if any */
|
||||||
gst_active_streams_free (dashdemux->client);
|
gst_mpd_client_active_streams_free (dashdemux->client);
|
||||||
dashdemux->trickmode_no_audio = trickmode_no_audio;
|
dashdemux->trickmode_no_audio = trickmode_no_audio;
|
||||||
|
|
||||||
/* setup video, audio and subtitle streams, starting from the new Period */
|
/* setup video, audio and subtitle streams, starting from the new Period */
|
||||||
|
@ -2356,7 +2357,7 @@ gst_dash_demux_seek (GstAdaptiveDemux * demux, GstEvent * seek)
|
||||||
streams = demux->next_streams;
|
streams = demux->next_streams;
|
||||||
} else if (dashdemux->trickmode_no_audio != trickmode_no_audio) {
|
} else if (dashdemux->trickmode_no_audio != trickmode_no_audio) {
|
||||||
/* clean old active stream list, if any */
|
/* clean old active stream list, if any */
|
||||||
gst_active_streams_free (dashdemux->client);
|
gst_mpd_client_active_streams_free (dashdemux->client);
|
||||||
dashdemux->trickmode_no_audio = trickmode_no_audio;
|
dashdemux->trickmode_no_audio = trickmode_no_audio;
|
||||||
|
|
||||||
/* setup video, audio and subtitle streams, starting from the new Period */
|
/* setup video, audio and subtitle streams, starting from the new Period */
|
||||||
|
@ -2404,7 +2405,7 @@ gst_dash_demux_update_manifest_data (GstAdaptiveDemux * demux,
|
||||||
new_client->mpd_base_uri = g_strdup (demux->manifest_base_uri);
|
new_client->mpd_base_uri = g_strdup (demux->manifest_base_uri);
|
||||||
gst_buffer_map (buffer, &mapinfo, GST_MAP_READ);
|
gst_buffer_map (buffer, &mapinfo, GST_MAP_READ);
|
||||||
|
|
||||||
if (gst_mpd_parse (new_client, (gchar *) mapinfo.data, mapinfo.size)) {
|
if (gst_mpd_client_parse (new_client, (gchar *) mapinfo.data, mapinfo.size)) {
|
||||||
const gchar *period_id;
|
const gchar *period_id;
|
||||||
guint period_idx;
|
guint period_idx;
|
||||||
GList *iter;
|
GList *iter;
|
||||||
|
@ -2490,7 +2491,7 @@ gst_dash_demux_update_manifest_data (GstAdaptiveDemux * demux,
|
||||||
/* _get_next_fragment_timestamp() returned relative timestamp to
|
/* _get_next_fragment_timestamp() returned relative timestamp to
|
||||||
* corresponding period start, but _client_stream_seek expects absolute
|
* corresponding period start, but _client_stream_seek expects absolute
|
||||||
* MPD time. */
|
* MPD time. */
|
||||||
ts += gst_mpd_parser_get_period_start_time (dashdemux->client);
|
ts += gst_mpd_client_get_period_start_time (dashdemux->client);
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (GST_ADAPTIVE_DEMUX_STREAM_PAD (demux_stream),
|
GST_DEBUG_OBJECT (GST_ADAPTIVE_DEMUX_STREAM_PAD (demux_stream),
|
||||||
"Current position: %" GST_TIME_FORMAT ", updating to %"
|
"Current position: %" GST_TIME_FORMAT ", updating to %"
|
||||||
|
|
|
@ -34,7 +34,7 @@
|
||||||
#include <gst/adaptivedemux/gstadaptivedemux.h>
|
#include <gst/adaptivedemux/gstadaptivedemux.h>
|
||||||
#include <gst/base/gstadapter.h>
|
#include <gst/base/gstadapter.h>
|
||||||
#include <gst/base/gstdataqueue.h>
|
#include <gst/base/gstdataqueue.h>
|
||||||
#include "gstmpdparser.h"
|
#include "gstmpdclient.h"
|
||||||
#include <gst/isoff/gstisoff.h>
|
#include <gst/isoff/gstisoff.h>
|
||||||
#include <gst/uridownloader/gsturidownloader.h>
|
#include <gst/uridownloader/gsturidownloader.h>
|
||||||
|
|
||||||
|
|
2915
ext/dash/gstmpdclient.c
Normal file
2915
ext/dash/gstmpdclient.c
Normal file
File diff suppressed because it is too large
Load diff
142
ext/dash/gstmpdclient.h
Normal file
142
ext/dash/gstmpdclient.h
Normal file
|
@ -0,0 +1,142 @@
|
||||||
|
/* GStreamer
|
||||||
|
*
|
||||||
|
* Copyright (C) 2019 Collabora Ltd.
|
||||||
|
* Author: Stéphane Cerveau <scerveau@collabora.com>
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Library General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Library General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Library General Public
|
||||||
|
* License along with this library (COPYING); if not, write to the
|
||||||
|
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||||
|
* Boston, MA 02111-1307, USA.
|
||||||
|
*/
|
||||||
|
#ifndef __GST_MPDCLIENT_H__
|
||||||
|
#define __GST_MPDCLIENT_H__
|
||||||
|
|
||||||
|
#include "gstmpdparser.h"
|
||||||
|
|
||||||
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
#define GST_MPD_CLIENT_LOCK(c) g_mutex_lock (&c->lock);
|
||||||
|
#define GST_MPD_CLIENT_UNLOCK(c) g_mutex_unlock (&c->lock);
|
||||||
|
|
||||||
|
typedef struct _GstMpdClient GstMpdClient;
|
||||||
|
|
||||||
|
struct _GstMpdClient
|
||||||
|
{
|
||||||
|
GstMPDNode *mpd_node; /* active MPD manifest file */
|
||||||
|
|
||||||
|
GList *periods; /* list of GstStreamPeriod */
|
||||||
|
guint period_idx; /* index of current Period */
|
||||||
|
|
||||||
|
GList *active_streams; /* list of GstActiveStream */
|
||||||
|
|
||||||
|
guint update_failed_count;
|
||||||
|
gchar *mpd_uri; /* manifest file URI */
|
||||||
|
gchar *mpd_base_uri; /* base URI for resolving relative URIs.
|
||||||
|
* this will be different for redirects */
|
||||||
|
|
||||||
|
/* profiles */
|
||||||
|
gboolean profile_isoff_ondemand;
|
||||||
|
|
||||||
|
GstUriDownloader * downloader;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Basic initialization/deinitialization functions */
|
||||||
|
GstMpdClient *gst_mpd_client_new (void);
|
||||||
|
void gst_mpd_client_active_streams_free (GstMpdClient * client);
|
||||||
|
void gst_mpd_client_free (GstMpdClient * client);
|
||||||
|
|
||||||
|
/* main mpd parsing methods from xml data */
|
||||||
|
gboolean gst_mpd_client_parse (GstMpdClient * client, const gchar * data, gint size);
|
||||||
|
|
||||||
|
void gst_mpd_client_set_uri_downloader (GstMpdClient * client, GstUriDownloader * download);
|
||||||
|
void gst_mpd_client_check_profiles (GstMpdClient * client);
|
||||||
|
void gst_mpd_client_fetch_on_load_external_resources (GstMpdClient * client);
|
||||||
|
|
||||||
|
/* Streaming management */
|
||||||
|
gboolean gst_mpd_client_setup_media_presentation (GstMpdClient *client, GstClockTime time, gint period_index, const gchar *period_id);
|
||||||
|
gboolean gst_mpd_client_setup_streaming (GstMpdClient * client, GstAdaptationSetNode * adapt_set);
|
||||||
|
gboolean gst_mpd_client_setup_representation (GstMpdClient *client, GstActiveStream *stream, GstRepresentationNode *representation);
|
||||||
|
|
||||||
|
GstClockTime gst_mpd_client_get_next_fragment_duration (GstMpdClient * client, GstActiveStream * stream);
|
||||||
|
GstClockTime gst_mpd_client_get_media_presentation_duration (GstMpdClient *client);
|
||||||
|
GstClockTime gst_mpd_client_get_maximum_segment_duration (GstMpdClient * client);
|
||||||
|
gboolean gst_mpd_client_get_last_fragment_timestamp_end (GstMpdClient * client, guint stream_idx, GstClockTime * ts);
|
||||||
|
gboolean gst_mpd_client_get_next_fragment_timestamp (GstMpdClient * client, guint stream_idx, GstClockTime * ts);
|
||||||
|
gboolean gst_mpd_client_get_next_fragment (GstMpdClient *client, guint indexStream, GstMediaFragmentInfo * fragment);
|
||||||
|
gboolean gst_mpd_client_get_next_header (GstMpdClient *client, gchar **uri, guint stream_idx, gint64 * range_start, gint64 * range_end);
|
||||||
|
gboolean gst_mpd_client_get_next_header_index (GstMpdClient *client, gchar **uri, guint stream_idx, gint64 * range_start, gint64 * range_end);
|
||||||
|
gboolean gst_mpd_client_is_live (GstMpdClient * client);
|
||||||
|
gboolean gst_mpd_client_stream_seek (GstMpdClient * client, GstActiveStream * stream, gboolean forward, GstSeekFlags flags, GstClockTime ts, GstClockTime * final_ts);
|
||||||
|
gboolean gst_mpd_client_seek_to_time (GstMpdClient * client, GDateTime * time);
|
||||||
|
GstClockTime gst_mpd_client_get_stream_presentation_offset (GstMpdClient *client, guint stream_idx);
|
||||||
|
gchar** gst_mpd_client_get_utc_timing_sources (GstMpdClient *client, guint methods, GstMPDUTCTimingType *selected_method);
|
||||||
|
GstClockTime gst_mpd_client_get_period_start_time (GstMpdClient *client);
|
||||||
|
|
||||||
|
/* Period selection */
|
||||||
|
guint gst_mpd_client_get_period_index_at_time (GstMpdClient * client, GstDateTime * time);
|
||||||
|
gboolean gst_mpd_client_set_period_index (GstMpdClient *client, guint period_idx);
|
||||||
|
gboolean gst_mpd_client_set_period_id (GstMpdClient *client, const gchar * period_id);
|
||||||
|
guint gst_mpd_client_get_period_index (GstMpdClient *client);
|
||||||
|
const gchar *gst_mpd_client_get_period_id (GstMpdClient *client);
|
||||||
|
gboolean gst_mpd_client_has_next_period (GstMpdClient *client);
|
||||||
|
gboolean gst_mpd_client_has_previous_period (GstMpdClient * client);
|
||||||
|
|
||||||
|
/* Representation selection */
|
||||||
|
gint gst_mpd_client_get_rep_idx_with_max_bandwidth (GList *Representations, gint64 max_bandwidth, gint max_video_width, gint max_video_height, gint max_video_framerate_n, gint max_video_framerate_d);
|
||||||
|
gint gst_mpd_client_get_rep_idx_with_min_bandwidth (GList * Representations);
|
||||||
|
|
||||||
|
GstDateTime *
|
||||||
|
gst_mpd_client_get_availability_start_time (GstMpdClient * client);
|
||||||
|
|
||||||
|
/* URL management */
|
||||||
|
const gchar *gst_mpd_client_get_baseURL (GstMpdClient *client, guint indexStream);
|
||||||
|
gchar *gst_mpd_client_parse_baseURL (GstMpdClient * client, GstActiveStream * stream, gchar ** query);
|
||||||
|
|
||||||
|
/* Active stream */
|
||||||
|
guint gst_mpd_client_get_nb_active_stream (GstMpdClient *client);
|
||||||
|
GstActiveStream *gst_mpd_client_get_active_stream_by_index (GstMpdClient *client, guint stream_idx);
|
||||||
|
gboolean gst_mpd_client_active_stream_contains_subtitles (GstActiveStream * stream);
|
||||||
|
|
||||||
|
/* AdaptationSet */
|
||||||
|
guint gst_mpd_client_get_nb_adaptationSet (GstMpdClient *client);
|
||||||
|
GList * gst_mpd_client_get_adaptation_sets (GstMpdClient * client);
|
||||||
|
|
||||||
|
/* Segment */
|
||||||
|
gboolean gst_mpd_client_has_next_segment (GstMpdClient * client, GstActiveStream * stream, gboolean forward);
|
||||||
|
GstFlowReturn gst_mpd_client_advance_segment (GstMpdClient * client, GstActiveStream * stream, gboolean forward);
|
||||||
|
void gst_mpd_client_seek_to_first_segment (GstMpdClient * client);
|
||||||
|
GstDateTime *gst_mpd_client_get_next_segment_availability_start_time (GstMpdClient * client, GstActiveStream * stream);
|
||||||
|
|
||||||
|
/* Get audio/video stream parameters (caps, width, height, rate, number of channels) */
|
||||||
|
GstCaps * gst_mpd_client_get_stream_caps (GstActiveStream * stream);
|
||||||
|
gboolean gst_mpd_client_get_bitstream_switching_flag (GstActiveStream * stream);
|
||||||
|
guint gst_mpd_client_get_video_stream_width (GstActiveStream * stream);
|
||||||
|
guint gst_mpd_client_get_video_stream_height (GstActiveStream * stream);
|
||||||
|
gboolean gst_mpd_client_get_video_stream_framerate (GstActiveStream * stream, gint * fps_num, gint * fps_den);
|
||||||
|
guint gst_mpd_client_get_audio_stream_rate (GstActiveStream * stream);
|
||||||
|
guint gst_mpd_client_get_audio_stream_num_channels (GstActiveStream * stream);
|
||||||
|
|
||||||
|
/* Support multi language */
|
||||||
|
guint gst_mpd_client_get_list_and_nb_of_audio_language (GstMpdClient *client, GList **lang);
|
||||||
|
|
||||||
|
gint64 gst_mpd_client_calculate_time_difference (const GstDateTime * t1, const GstDateTime * t2);
|
||||||
|
GstDateTime *gst_mpd_client_add_time_difference (GstDateTime * t1, gint64 usecs);
|
||||||
|
gint64 gst_mpd_client_parse_default_presentation_delay(GstMpdClient * client, const gchar * default_presentation_delay);
|
||||||
|
|
||||||
|
/* profiles */
|
||||||
|
gboolean gst_mpd_client_has_isoff_ondemand_profile (GstMpdClient *client);
|
||||||
|
|
||||||
|
|
||||||
|
G_END_DECLS
|
||||||
|
|
||||||
|
#endif /* __GST_MPDCLIENT_H__ */
|
78
ext/dash/gstmpdhelper.c
Normal file
78
ext/dash/gstmpdhelper.c
Normal file
|
@ -0,0 +1,78 @@
|
||||||
|
/* GStreamer
|
||||||
|
*
|
||||||
|
* Copyright (C) 2019 Collabora Ltd.
|
||||||
|
* Author: Stéphane Cerveau <scerveau@collabora.com>
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "gstmpdhelper.h"
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
gst_mpd_helper_get_mpd_type (xmlNode * a_node,
|
||||||
|
const gchar * property_name, GstMPDFileType * property_value)
|
||||||
|
{
|
||||||
|
xmlChar *prop_string;
|
||||||
|
gboolean exists = FALSE;
|
||||||
|
|
||||||
|
*property_value = GST_MPD_FILE_TYPE_STATIC; /* default */
|
||||||
|
prop_string = xmlGetProp (a_node, (const xmlChar *) property_name);
|
||||||
|
if (prop_string) {
|
||||||
|
if (xmlStrcmp (prop_string, (xmlChar *) "OnDemand") == 0
|
||||||
|
|| xmlStrcmp (prop_string, (xmlChar *) "static") == 0) {
|
||||||
|
exists = TRUE;
|
||||||
|
*property_value = GST_MPD_FILE_TYPE_STATIC;
|
||||||
|
GST_LOG (" - %s: static", property_name);
|
||||||
|
} else if (xmlStrcmp (prop_string, (xmlChar *) "Live") == 0
|
||||||
|
|| xmlStrcmp (prop_string, (xmlChar *) "dynamic") == 0) {
|
||||||
|
exists = TRUE;
|
||||||
|
*property_value = GST_MPD_FILE_TYPE_DYNAMIC;
|
||||||
|
GST_LOG (" - %s: dynamic", property_name);
|
||||||
|
} else {
|
||||||
|
GST_WARNING ("failed to parse MPD type property %s from xml string %s",
|
||||||
|
property_name, prop_string);
|
||||||
|
}
|
||||||
|
xmlFree (prop_string);
|
||||||
|
}
|
||||||
|
|
||||||
|
return exists;
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
gst_mpd_helper_get_SAP_type (xmlNode * a_node,
|
||||||
|
const gchar * property_name, GstMPDSAPType * property_value)
|
||||||
|
{
|
||||||
|
xmlChar *prop_string;
|
||||||
|
guint prop_SAP_type = 0;
|
||||||
|
gboolean exists = FALSE;
|
||||||
|
|
||||||
|
prop_string = xmlGetProp (a_node, (const xmlChar *) property_name);
|
||||||
|
if (prop_string) {
|
||||||
|
if (sscanf ((gchar *) prop_string, "%u", &prop_SAP_type) == 1
|
||||||
|
&& prop_SAP_type <= 6) {
|
||||||
|
exists = TRUE;
|
||||||
|
*property_value = (GstMPDSAPType) prop_SAP_type;
|
||||||
|
GST_LOG (" - %s: %u", property_name, prop_SAP_type);
|
||||||
|
} else {
|
||||||
|
GST_WARNING
|
||||||
|
("failed to parse unsigned integer property %s from xml string %s",
|
||||||
|
property_name, prop_string);
|
||||||
|
}
|
||||||
|
xmlFree (prop_string);
|
||||||
|
}
|
||||||
|
|
||||||
|
return exists;
|
||||||
|
}
|
49
ext/dash/gstmpdhelper.h
Normal file
49
ext/dash/gstmpdhelper.h
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
/* GStreamer
|
||||||
|
*
|
||||||
|
* Copyright (C) 2019 Collabora Ltd.
|
||||||
|
* Author: Stéphane Cerveau <scerveau@collabora.com>
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Library General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Library General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Library General Public
|
||||||
|
* License along with this library (COPYING); if not, write to the
|
||||||
|
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||||
|
* Boston, MA 02111-1307, USA.
|
||||||
|
*/
|
||||||
|
#ifndef __GST_MPDHELPER_H__
|
||||||
|
#define __GST_MPDHELPER_H__
|
||||||
|
|
||||||
|
#include "gstxmlhelper.h"
|
||||||
|
|
||||||
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
GST_MPD_FILE_TYPE_STATIC,
|
||||||
|
GST_MPD_FILE_TYPE_DYNAMIC
|
||||||
|
} GstMPDFileType;
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
GST_SAP_TYPE_0 = 0,
|
||||||
|
GST_SAP_TYPE_1,
|
||||||
|
GST_SAP_TYPE_2,
|
||||||
|
GST_SAP_TYPE_3,
|
||||||
|
GST_SAP_TYPE_4,
|
||||||
|
GST_SAP_TYPE_5,
|
||||||
|
GST_SAP_TYPE_6
|
||||||
|
} GstMPDSAPType;
|
||||||
|
|
||||||
|
|
||||||
|
gboolean gst_mpd_helper_get_mpd_type (xmlNode * a_node, const gchar * property_name, GstMPDFileType * property_value);
|
||||||
|
gboolean gst_mpd_helper_get_SAP_type (xmlNode * a_node, const gchar * property_name, GstMPDSAPType * property_value);
|
||||||
|
G_END_DECLS
|
||||||
|
#endif /* __GST_MPDHELPER_H__ */
|
File diff suppressed because it is too large
Load diff
|
@ -30,10 +30,10 @@
|
||||||
#include <gst/gst.h>
|
#include <gst/gst.h>
|
||||||
#include <gst/uridownloader/gsturidownloader.h>
|
#include <gst/uridownloader/gsturidownloader.h>
|
||||||
#include <gst/base/gstadapter.h>
|
#include <gst/base/gstadapter.h>
|
||||||
|
#include "gstmpdhelper.h"
|
||||||
|
|
||||||
G_BEGIN_DECLS
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
typedef struct _GstMpdClient GstMpdClient;
|
|
||||||
typedef struct _GstActiveStream GstActiveStream;
|
typedef struct _GstActiveStream GstActiveStream;
|
||||||
typedef struct _GstStreamPeriod GstStreamPeriod;
|
typedef struct _GstStreamPeriod GstStreamPeriod;
|
||||||
typedef struct _GstMediaFragmentInfo GstMediaFragmentInfo;
|
typedef struct _GstMediaFragmentInfo GstMediaFragmentInfo;
|
||||||
|
@ -50,10 +50,7 @@ typedef struct _GstSegmentListNode GstSegmentListNode;
|
||||||
typedef struct _GstSegmentTemplateNode GstSegmentTemplateNode;
|
typedef struct _GstSegmentTemplateNode GstSegmentTemplateNode;
|
||||||
typedef struct _GstSegmentURLNode GstSegmentURLNode;
|
typedef struct _GstSegmentURLNode GstSegmentURLNode;
|
||||||
typedef struct _GstBaseURL GstBaseURL;
|
typedef struct _GstBaseURL GstBaseURL;
|
||||||
typedef struct _GstRange GstRange;
|
|
||||||
typedef struct _GstRatio GstRatio;
|
|
||||||
typedef struct _GstFrameRate GstFrameRate;
|
|
||||||
typedef struct _GstConditionalUintType GstConditionalUintType;
|
|
||||||
typedef struct _GstSubsetNode GstSubsetNode;
|
typedef struct _GstSubsetNode GstSubsetNode;
|
||||||
typedef struct _GstProgramInformationNode GstProgramInformationNode;
|
typedef struct _GstProgramInformationNode GstProgramInformationNode;
|
||||||
typedef struct _GstMetricsRangeNode GstMetricsRangeNode;
|
typedef struct _GstMetricsRangeNode GstMetricsRangeNode;
|
||||||
|
@ -65,8 +62,6 @@ typedef struct _GstSegmentBaseType GstSegmentBaseType;
|
||||||
typedef struct _GstURLType GstURLType;
|
typedef struct _GstURLType GstURLType;
|
||||||
typedef struct _GstMultSegmentBaseType GstMultSegmentBaseType;
|
typedef struct _GstMultSegmentBaseType GstMultSegmentBaseType;
|
||||||
|
|
||||||
#define GST_MPD_CLIENT_LOCK(c) g_mutex_lock (&c->lock);
|
|
||||||
#define GST_MPD_CLIENT_UNLOCK(c) g_mutex_unlock (&c->lock);
|
|
||||||
|
|
||||||
#define GST_MPD_DURATION_NONE ((guint64)-1)
|
#define GST_MPD_DURATION_NONE ((guint64)-1)
|
||||||
|
|
||||||
|
@ -78,22 +73,6 @@ typedef enum
|
||||||
GST_STREAM_APPLICATION /* application stream (optional): for timed text/subtitles */
|
GST_STREAM_APPLICATION /* application stream (optional): for timed text/subtitles */
|
||||||
} GstStreamMimeType;
|
} GstStreamMimeType;
|
||||||
|
|
||||||
typedef enum
|
|
||||||
{
|
|
||||||
GST_MPD_FILE_TYPE_STATIC,
|
|
||||||
GST_MPD_FILE_TYPE_DYNAMIC
|
|
||||||
} GstMPDFileType;
|
|
||||||
|
|
||||||
typedef enum
|
|
||||||
{
|
|
||||||
GST_SAP_TYPE_0 = 0,
|
|
||||||
GST_SAP_TYPE_1,
|
|
||||||
GST_SAP_TYPE_2,
|
|
||||||
GST_SAP_TYPE_3,
|
|
||||||
GST_SAP_TYPE_4,
|
|
||||||
GST_SAP_TYPE_5,
|
|
||||||
GST_SAP_TYPE_6
|
|
||||||
} GstSAPType;
|
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
|
@ -120,30 +99,6 @@ struct _GstBaseURL
|
||||||
gchar *byteRange;
|
gchar *byteRange;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _GstRange
|
|
||||||
{
|
|
||||||
guint64 first_byte_pos;
|
|
||||||
guint64 last_byte_pos;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct _GstRatio
|
|
||||||
{
|
|
||||||
guint num;
|
|
||||||
guint den;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct _GstFrameRate
|
|
||||||
{
|
|
||||||
guint num;
|
|
||||||
guint den;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct _GstConditionalUintType
|
|
||||||
{
|
|
||||||
gboolean flag;
|
|
||||||
guint value;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct _GstSNode
|
struct _GstSNode
|
||||||
{
|
{
|
||||||
guint64 t;
|
guint64 t;
|
||||||
|
@ -160,14 +115,14 @@ struct _GstSegmentTimelineNode
|
||||||
struct _GstURLType
|
struct _GstURLType
|
||||||
{
|
{
|
||||||
gchar *sourceURL;
|
gchar *sourceURL;
|
||||||
GstRange *range;
|
GstXMLRange *range;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _GstSegmentBaseType
|
struct _GstSegmentBaseType
|
||||||
{
|
{
|
||||||
guint timescale;
|
guint timescale;
|
||||||
guint64 presentationTimeOffset;
|
guint64 presentationTimeOffset;
|
||||||
GstRange *indexRange;
|
GstXMLRange *indexRange;
|
||||||
gboolean indexRangeExact;
|
gboolean indexRangeExact;
|
||||||
/* Initialization node */
|
/* Initialization node */
|
||||||
GstURLType *Initialization;
|
GstURLType *Initialization;
|
||||||
|
@ -211,9 +166,9 @@ struct _GstSegmentTemplateNode
|
||||||
struct _GstSegmentURLNode
|
struct _GstSegmentURLNode
|
||||||
{
|
{
|
||||||
gchar *media;
|
gchar *media;
|
||||||
GstRange *mediaRange;
|
GstXMLRange *mediaRange;
|
||||||
gchar *index;
|
gchar *index;
|
||||||
GstRange *indexRange;
|
GstXMLRange *indexRange;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _GstRepresentationBaseType
|
struct _GstRepresentationBaseType
|
||||||
|
@ -221,16 +176,16 @@ struct _GstRepresentationBaseType
|
||||||
gchar *profiles;
|
gchar *profiles;
|
||||||
guint width;
|
guint width;
|
||||||
guint height;
|
guint height;
|
||||||
GstRatio *sar;
|
GstXMLRatio *sar;
|
||||||
GstFrameRate *minFrameRate;
|
GstXMLFrameRate *minFrameRate;
|
||||||
GstFrameRate *maxFrameRate;
|
GstXMLFrameRate *maxFrameRate;
|
||||||
GstFrameRate *frameRate;
|
GstXMLFrameRate *frameRate;
|
||||||
gchar *audioSamplingRate;
|
gchar *audioSamplingRate;
|
||||||
gchar *mimeType;
|
gchar *mimeType;
|
||||||
gchar *segmentProfiles;
|
gchar *segmentProfiles;
|
||||||
gchar *codecs;
|
gchar *codecs;
|
||||||
gdouble maximumSAPPeriod;
|
gdouble maximumSAPPeriod;
|
||||||
GstSAPType startWithSAP;
|
GstMPDSAPType startWithSAP;
|
||||||
gdouble maxPlayoutRate;
|
gdouble maxPlayoutRate;
|
||||||
gboolean codingDependency;
|
gboolean codingDependency;
|
||||||
gchar *scanType;
|
gchar *scanType;
|
||||||
|
@ -285,7 +240,7 @@ struct _GstContentComponentNode
|
||||||
guint id;
|
guint id;
|
||||||
gchar *lang; /* LangVectorType RFC 5646 */
|
gchar *lang; /* LangVectorType RFC 5646 */
|
||||||
gchar *contentType;
|
gchar *contentType;
|
||||||
GstRatio *par;
|
GstXMLRatio *par;
|
||||||
/* list of Accessibility DescriptorType nodes */
|
/* list of Accessibility DescriptorType nodes */
|
||||||
GList *Accessibility;
|
GList *Accessibility;
|
||||||
/* list of Role DescriptorType nodes */
|
/* list of Role DescriptorType nodes */
|
||||||
|
@ -302,16 +257,16 @@ struct _GstAdaptationSetNode
|
||||||
guint group;
|
guint group;
|
||||||
gchar *lang; /* LangVectorType RFC 5646 */
|
gchar *lang; /* LangVectorType RFC 5646 */
|
||||||
gchar *contentType;
|
gchar *contentType;
|
||||||
GstRatio *par;
|
GstXMLRatio *par;
|
||||||
guint minBandwidth;
|
guint minBandwidth;
|
||||||
guint maxBandwidth;
|
guint maxBandwidth;
|
||||||
guint minWidth;
|
guint minWidth;
|
||||||
guint maxWidth;
|
guint maxWidth;
|
||||||
guint minHeight;
|
guint minHeight;
|
||||||
guint maxHeight;
|
guint maxHeight;
|
||||||
GstConditionalUintType *segmentAlignment;
|
GstXMLConditionalUintType *segmentAlignment;
|
||||||
GstConditionalUintType *subsegmentAlignment;
|
GstXMLConditionalUintType *subsegmentAlignment;
|
||||||
GstSAPType subsegmentStartsWithSAP;
|
GstMPDSAPType subsegmentStartsWithSAP;
|
||||||
gboolean bitstreamSwitching;
|
gboolean bitstreamSwitching;
|
||||||
/* list of Accessibility DescriptorType nodes */
|
/* list of Accessibility DescriptorType nodes */
|
||||||
GList *Accessibility;
|
GList *Accessibility;
|
||||||
|
@ -502,106 +457,35 @@ struct _GstActiveStream
|
||||||
GstClockTime presentationTimeOffset; /* presentation time offset of the current segment */
|
GstClockTime presentationTimeOffset; /* presentation time offset of the current segment */
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _GstMpdClient
|
|
||||||
{
|
|
||||||
GstMPDNode *mpd_node; /* active MPD manifest file */
|
|
||||||
|
|
||||||
GList *periods; /* list of GstStreamPeriod */
|
|
||||||
guint period_idx; /* index of current Period */
|
|
||||||
|
|
||||||
GList *active_streams; /* list of GstActiveStream */
|
|
||||||
|
|
||||||
guint update_failed_count;
|
|
||||||
gchar *mpd_uri; /* manifest file URI */
|
|
||||||
gchar *mpd_base_uri; /* base URI for resolving relative URIs.
|
|
||||||
* this will be different for redirects */
|
|
||||||
|
|
||||||
/* profiles */
|
|
||||||
gboolean profile_isoff_ondemand;
|
|
||||||
|
|
||||||
GstUriDownloader * downloader;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Basic initialization/deinitialization functions */
|
|
||||||
GstMpdClient *gst_mpd_client_new (void);
|
|
||||||
void gst_active_streams_free (GstMpdClient * client);
|
|
||||||
void gst_mpd_client_free (GstMpdClient * client);
|
|
||||||
void gst_media_fragment_info_clear (GstMediaFragmentInfo * fragment);
|
|
||||||
|
|
||||||
void gst_mpd_client_set_uri_downloader (GstMpdClient * client, GstUriDownloader * download);
|
|
||||||
|
|
||||||
/* MPD file parsing */
|
/* MPD file parsing */
|
||||||
gboolean gst_mpd_parse (GstMpdClient *client, const gchar *data, gint size);
|
gboolean gst_mpdparser_get_mpd_node (GstMPDNode ** mpd_node, const gchar * data, gint size);
|
||||||
|
GstSegmentListNode * gst_mpdparser_get_external_segment_list (const gchar * data, gint size, GstSegmentListNode * parent);
|
||||||
|
GList * gst_mpdparser_get_external_periods (const gchar * data, gint size);
|
||||||
|
GList * gst_mpdparser_get_external_adaptation_sets (const gchar * data, gint size, GstPeriodNode* period);
|
||||||
|
|
||||||
/* Streaming management */
|
/* navigation functions */
|
||||||
gboolean gst_mpd_client_setup_media_presentation (GstMpdClient *client, GstClockTime time, gint period_index, const gchar *period_id);
|
GstStreamMimeType gst_mpdparser_representation_get_mimetype (GstAdaptationSetNode * adapt_set, GstRepresentationNode * rep);
|
||||||
gboolean gst_mpd_client_setup_streaming (GstMpdClient * client, GstAdaptationSetNode * adapt_set);
|
|
||||||
gboolean gst_mpd_client_setup_representation (GstMpdClient *client, GstActiveStream *stream, GstRepresentationNode *representation);
|
|
||||||
GstClockTime gst_mpd_client_get_next_fragment_duration (GstMpdClient * client, GstActiveStream * stream);
|
|
||||||
GstClockTime gst_mpd_client_get_media_presentation_duration (GstMpdClient *client);
|
|
||||||
GstClockTime gst_mpd_client_get_maximum_segment_duration (GstMpdClient * client);
|
|
||||||
gboolean gst_mpd_client_get_last_fragment_timestamp_end (GstMpdClient * client, guint stream_idx, GstClockTime * ts);
|
|
||||||
gboolean gst_mpd_client_get_next_fragment_timestamp (GstMpdClient * client, guint stream_idx, GstClockTime * ts);
|
|
||||||
gboolean gst_mpd_client_get_next_fragment (GstMpdClient *client, guint indexStream, GstMediaFragmentInfo * fragment);
|
|
||||||
gboolean gst_mpd_client_get_next_header (GstMpdClient *client, gchar **uri, guint stream_idx, gint64 * range_start, gint64 * range_end);
|
|
||||||
gboolean gst_mpd_client_get_next_header_index (GstMpdClient *client, gchar **uri, guint stream_idx, gint64 * range_start, gint64 * range_end);
|
|
||||||
gboolean gst_mpd_client_is_live (GstMpdClient * client);
|
|
||||||
gboolean gst_mpd_client_stream_seek (GstMpdClient * client, GstActiveStream * stream, gboolean forward, GstSeekFlags flags, GstClockTime ts, GstClockTime * final_ts);
|
|
||||||
gboolean gst_mpd_client_seek_to_time (GstMpdClient * client, GDateTime * time);
|
|
||||||
GstClockTime gst_mpd_parser_get_stream_presentation_offset (GstMpdClient *client, guint stream_idx);
|
|
||||||
gchar** gst_mpd_client_get_utc_timing_sources (GstMpdClient *client, guint methods, GstMPDUTCTimingType *selected_method);
|
|
||||||
GstClockTime gst_mpd_parser_get_period_start_time (GstMpdClient *client);
|
|
||||||
|
|
||||||
/* Period selection */
|
/* Memory management */
|
||||||
guint gst_mpd_client_get_period_index_at_time (GstMpdClient * client, GstDateTime * time);
|
void gst_mpdparser_free_mpd_node (GstMPDNode * mpd_node);
|
||||||
gboolean gst_mpd_client_set_period_index (GstMpdClient *client, guint period_idx);
|
void gst_mpdparser_free_period_node (GstPeriodNode * period_node);
|
||||||
gboolean gst_mpd_client_set_period_id (GstMpdClient *client, const gchar * period_id);
|
void gst_mpdparser_free_adaptation_set_node (GstAdaptationSetNode * adaptation_set_node);
|
||||||
guint gst_mpd_client_get_period_index (GstMpdClient *client);
|
void gst_mpdparser_free_segment_list_node (GstSegmentListNode * segment_list_node);
|
||||||
const gchar *gst_mpd_client_get_period_id (GstMpdClient *client);
|
void gst_mpdparser_free_stream_period (GstStreamPeriod * stream_period);
|
||||||
gboolean gst_mpd_client_has_next_period (GstMpdClient *client);
|
void gst_mpdparser_free_media_segment (GstMediaSegment * media_segment);
|
||||||
gboolean gst_mpd_client_has_previous_period (GstMpdClient * client);
|
void gst_mpdparser_free_active_stream (GstActiveStream * active_stream);
|
||||||
|
void gst_mpdparser_free_base_url_node (GstBaseURL * base_url_node);
|
||||||
|
|
||||||
/* Representation selection */
|
/* Active stream methods*/
|
||||||
gint gst_mpdparser_get_rep_idx_with_max_bandwidth (GList *Representations, gint64 max_bandwidth, gint max_video_width, gint max_video_height, gint max_video_framerate_n, gint max_video_framerate_d);
|
void gst_mpdparser_init_active_stream_segments (GstActiveStream * stream);
|
||||||
gint gst_mpdparser_get_rep_idx_with_min_bandwidth (GList * Representations);
|
gchar *gst_mpdparser_get_mediaURL (GstActiveStream * stream, GstSegmentURLNode * segmentURL);
|
||||||
|
const gchar *gst_mpdparser_get_initializationURL (GstActiveStream * stream, GstURLType * InitializationURL);
|
||||||
/* URL management */
|
|
||||||
const gchar *gst_mpdparser_get_baseURL (GstMpdClient *client, guint indexStream);
|
|
||||||
|
|
||||||
/* Active stream */
|
|
||||||
guint gst_mpdparser_get_nb_active_stream (GstMpdClient *client);
|
|
||||||
GstActiveStream *gst_mpdparser_get_active_stream_by_index (GstMpdClient *client, guint stream_idx);
|
|
||||||
gboolean gst_mpd_client_active_stream_contains_subtitles (GstActiveStream * stream);
|
|
||||||
|
|
||||||
/* AdaptationSet */
|
|
||||||
guint gst_mpdparser_get_nb_adaptationSet (GstMpdClient *client);
|
|
||||||
GList * gst_mpd_client_get_adaptation_sets (GstMpdClient * client);
|
|
||||||
|
|
||||||
/* Segment */
|
|
||||||
gboolean gst_mpd_client_has_next_segment (GstMpdClient * client, GstActiveStream * stream, gboolean forward);
|
|
||||||
GstFlowReturn gst_mpd_client_advance_segment (GstMpdClient * client, GstActiveStream * stream, gboolean forward);
|
|
||||||
void gst_mpd_client_seek_to_first_segment (GstMpdClient * client);
|
|
||||||
GstDateTime *gst_mpd_client_get_next_segment_availability_start_time (GstMpdClient * client, GstActiveStream * stream);
|
|
||||||
|
|
||||||
/* Get audio/video stream parameters (caps, width, height, rate, number of channels) */
|
|
||||||
GstCaps * gst_mpd_client_get_stream_caps (GstActiveStream * stream);
|
|
||||||
gboolean gst_mpd_client_get_bitstream_switching_flag (GstActiveStream * stream);
|
|
||||||
guint gst_mpd_client_get_video_stream_width (GstActiveStream * stream);
|
|
||||||
guint gst_mpd_client_get_video_stream_height (GstActiveStream * stream);
|
|
||||||
gboolean gst_mpd_client_get_video_stream_framerate (GstActiveStream * stream, gint * fps_num, gint * fps_den);
|
|
||||||
guint gst_mpd_client_get_audio_stream_rate (GstActiveStream * stream);
|
|
||||||
guint gst_mpd_client_get_audio_stream_num_channels (GstActiveStream * stream);
|
|
||||||
|
|
||||||
/* Support multi language */
|
|
||||||
guint gst_mpdparser_get_list_and_nb_of_audio_language (GstMpdClient *client, GList **lang);
|
|
||||||
|
|
||||||
gint64 gst_mpd_client_calculate_time_difference (const GstDateTime * t1, const GstDateTime * t2);
|
|
||||||
GstDateTime *gst_mpd_client_add_time_difference (GstDateTime * t1, gint64 usecs);
|
|
||||||
gint64 gst_mpd_client_parse_default_presentation_delay(GstMpdClient * client, const gchar * default_presentation_delay);
|
|
||||||
|
|
||||||
/* profiles */
|
|
||||||
gboolean gst_mpd_client_has_isoff_ondemand_profile (GstMpdClient *client);
|
|
||||||
|
|
||||||
|
/*Helper methods */
|
||||||
|
gchar *gst_mpdparser_build_URL_from_template (const gchar * url_template, const gchar * id, guint number, guint bandwidth, guint64 time);
|
||||||
|
const gchar *gst_mpdparser_mimetype_to_caps (const gchar * mimeType);
|
||||||
|
GstUri *combine_urls (GstUri * base, GList * list, gchar ** query, guint idx);
|
||||||
|
int strncmp_ext (const char *s1, const char *s2);
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
#endif /* __GST_MPDPARSER_H__ */
|
#endif /* __GST_MPDPARSER_H__ */
|
||||||
|
|
1024
ext/dash/gstxmlhelper.c
Normal file
1024
ext/dash/gstxmlhelper.c
Normal file
File diff suppressed because it is too large
Load diff
113
ext/dash/gstxmlhelper.h
Normal file
113
ext/dash/gstxmlhelper.h
Normal file
|
@ -0,0 +1,113 @@
|
||||||
|
/* GStreamer
|
||||||
|
*
|
||||||
|
* Copyright (C) 2019 Collabora Ltd.
|
||||||
|
* Author: Stéphane Cerveau <scerveau@collabora.com>
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Library General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Library General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Library General Public
|
||||||
|
* License along with this library (COPYING); if not, write to the
|
||||||
|
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||||
|
* Boston, MA 02111-1307, USA.
|
||||||
|
*/
|
||||||
|
#ifndef __GST_XMLHELPER_H__
|
||||||
|
#define __GST_XMLHELPER_H__
|
||||||
|
|
||||||
|
#include <libxml/parser.h>
|
||||||
|
#include <libxml/tree.h>
|
||||||
|
#include <gst/gst.h>
|
||||||
|
|
||||||
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
typedef struct _GstXMLRange GstXMLRange;
|
||||||
|
typedef struct _GstXMLRatio GstXMLRatio;
|
||||||
|
typedef struct _GstXMLFrameRate GstXMLFrameRate;
|
||||||
|
typedef struct _GstXMLConditionalUintType GstXMLConditionalUintType;
|
||||||
|
|
||||||
|
struct _GstXMLRange
|
||||||
|
{
|
||||||
|
guint64 first_byte_pos;
|
||||||
|
guint64 last_byte_pos;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct _GstXMLRatio
|
||||||
|
{
|
||||||
|
guint num;
|
||||||
|
guint den;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct _GstXMLFrameRate
|
||||||
|
{
|
||||||
|
guint num;
|
||||||
|
guint den;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct _GstXMLConditionalUintType
|
||||||
|
{
|
||||||
|
gboolean flag;
|
||||||
|
guint value;
|
||||||
|
};
|
||||||
|
|
||||||
|
GstXMLRange *gst_xml_helper_clone_range (GstXMLRange * range);
|
||||||
|
|
||||||
|
/* XML property get method */
|
||||||
|
gboolean gst_xml_helper_get_prop_validated_string (xmlNode * a_node,
|
||||||
|
const gchar * property_name, gchar ** property_value,
|
||||||
|
gboolean (*validator) (const char *));
|
||||||
|
gboolean gst_xml_helper_get_prop_string (xmlNode * a_node,
|
||||||
|
const gchar * property_name, gchar ** property_value);
|
||||||
|
gboolean gst_xml_helper_get_prop_string_stripped (xmlNode * a_node,
|
||||||
|
const gchar * property_name, gchar ** property_value);
|
||||||
|
gboolean gst_xml_helper_get_ns_prop_string (xmlNode * a_node,
|
||||||
|
const gchar * ns_name, const gchar * property_name,
|
||||||
|
gchar ** property_value);
|
||||||
|
gboolean gst_xml_helper_get_prop_string_vector_type (xmlNode * a_node,
|
||||||
|
const gchar * property_name, gchar *** property_value);
|
||||||
|
gboolean gst_xml_helper_get_prop_signed_integer (xmlNode * a_node,
|
||||||
|
const gchar * property_name, gint default_val, gint * property_value);
|
||||||
|
gboolean gst_xml_helper_get_prop_unsigned_integer (xmlNode * a_node,
|
||||||
|
const gchar * property_name, guint default_val, guint * property_value);
|
||||||
|
gboolean gst_xml_helper_get_prop_unsigned_integer_64 (xmlNode *
|
||||||
|
a_node, const gchar * property_name, guint64 default_val,
|
||||||
|
guint64 * property_value);
|
||||||
|
gboolean gst_xml_helper_get_prop_uint_vector_type (xmlNode * a_node,
|
||||||
|
const gchar * property_name, guint ** property_value, guint * value_size);
|
||||||
|
gboolean gst_xml_helper_get_prop_double (xmlNode * a_node,
|
||||||
|
const gchar * property_name, gdouble * property_value);
|
||||||
|
gboolean gst_xml_helper_get_prop_boolean (xmlNode * a_node,
|
||||||
|
const gchar * property_name, gboolean default_val,
|
||||||
|
gboolean * property_value);
|
||||||
|
gboolean gst_xml_helper_get_prop_range (xmlNode * a_node,
|
||||||
|
const gchar * property_name, GstXMLRange ** property_value);
|
||||||
|
gboolean gst_xml_helper_get_prop_ratio (xmlNode * a_node,
|
||||||
|
const gchar * property_name, GstXMLRatio ** property_value);
|
||||||
|
gboolean gst_xml_helper_get_prop_framerate (xmlNode * a_node,
|
||||||
|
const gchar * property_name, GstXMLFrameRate ** property_value);
|
||||||
|
gboolean gst_xml_helper_get_prop_cond_uint (xmlNode * a_node,
|
||||||
|
const gchar * property_name, GstXMLConditionalUintType ** property_value);
|
||||||
|
gboolean gst_xml_helper_get_prop_dateTime (xmlNode * a_node,
|
||||||
|
const gchar * property_name, GstDateTime ** property_value);
|
||||||
|
gboolean gst_xml_helper_get_prop_duration (xmlNode * a_node,
|
||||||
|
const gchar * property_name, guint64 default_value,
|
||||||
|
guint64 * property_value);
|
||||||
|
gboolean gst_xml_helper_get_prop_string_no_whitespace (xmlNode * a_node,
|
||||||
|
const gchar * property_name, gchar ** property_value);
|
||||||
|
|
||||||
|
/* XML node get method */
|
||||||
|
gboolean gst_xml_helper_get_node_content (xmlNode * a_node,
|
||||||
|
gchar ** content);
|
||||||
|
gchar *gst_xml_helper_get_node_namespace (xmlNode * a_node,
|
||||||
|
const gchar * prefix);
|
||||||
|
gboolean gst_xml_helper_get_node_as_string (xmlNode * a_node,
|
||||||
|
gchar ** content);
|
||||||
|
|
||||||
|
G_END_DECLS
|
||||||
|
#endif /* __GST_XMLHELPER_H__ */
|
|
@ -1,6 +1,9 @@
|
||||||
dash_sources = [
|
dash_sources = [
|
||||||
'gstdashdemux.c',
|
'gstdashdemux.c',
|
||||||
|
'gstxmlhelper.c',
|
||||||
|
'gstmpdhelper.c',
|
||||||
'gstmpdparser.c',
|
'gstmpdparser.c',
|
||||||
|
'gstmpdclient.c',
|
||||||
'gstplugin.c',
|
'gstplugin.c',
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue