mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-27 04:01:08 +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;
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -529,7 +529,7 @@ gst_dash_demux_get_period_start_time (GstAdaptiveDemux * 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
|
||||
|
@ -778,14 +778,14 @@ gst_dash_demux_setup_all_streams (GstDashDemux * demux)
|
|||
gst_mpd_client_get_period_index (demux->client));
|
||||
|
||||
/* 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)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
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;
|
||||
GstActiveStream *active_stream;
|
||||
GstCaps *caps;
|
||||
|
@ -794,7 +794,8 @@ gst_dash_demux_setup_all_streams (GstDashDemux * demux)
|
|||
gchar *lang = 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)
|
||||
continue;
|
||||
|
||||
|
@ -1036,7 +1037,7 @@ gst_dash_demux_process_manifest (GstAdaptiveDemux * demux, GstBuffer * buf)
|
|||
|
||||
if (gst_buffer_map (buf, &mapinfo, GST_MAP_READ)) {
|
||||
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,
|
||||
NULL)) {
|
||||
ret = TRUE;
|
||||
|
@ -1232,7 +1233,7 @@ gst_dash_demux_stream_update_headers_info (GstAdaptiveDemuxStream * stream)
|
|||
|
||||
if (path != NULL) {
|
||||
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);
|
||||
g_free (path);
|
||||
path = NULL;
|
||||
|
@ -1244,7 +1245,7 @@ gst_dash_demux_stream_update_headers_info (GstAdaptiveDemuxStream * stream)
|
|||
|
||||
if (path != NULL) {
|
||||
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);
|
||||
g_free (path);
|
||||
}
|
||||
|
@ -1501,9 +1502,9 @@ gst_dash_demux_stream_seek (GstAdaptiveDemuxStream * stream, gboolean forward,
|
|||
if (is_isobmff) {
|
||||
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 =
|
||||
gst_mpd_parser_get_stream_presentation_offset (dashdemux->client,
|
||||
gst_mpd_client_get_stream_presentation_offset (dashdemux->client,
|
||||
dashstream->index);
|
||||
|
||||
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) ||
|
||||
ABS (base_demux->segment.rate) <= 1.0) {
|
||||
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_framerate_n, demux->max_video_framerate_d);
|
||||
} else {
|
||||
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,
|
||||
demux->max_video_height, demux->max_video_framerate_n,
|
||||
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 (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) {
|
||||
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);
|
||||
|
||||
/* 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;
|
||||
|
||||
/* 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;
|
||||
} else if (dashdemux->trickmode_no_audio != trickmode_no_audio) {
|
||||
/* 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;
|
||||
|
||||
/* 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);
|
||||
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;
|
||||
guint period_idx;
|
||||
GList *iter;
|
||||
|
@ -2490,7 +2491,7 @@ gst_dash_demux_update_manifest_data (GstAdaptiveDemux * demux,
|
|||
/* _get_next_fragment_timestamp() returned relative timestamp to
|
||||
* corresponding period start, but _client_stream_seek expects absolute
|
||||
* 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),
|
||||
"Current position: %" GST_TIME_FORMAT ", updating to %"
|
||||
|
|
|
@ -34,7 +34,7 @@
|
|||
#include <gst/adaptivedemux/gstadaptivedemux.h>
|
||||
#include <gst/base/gstadapter.h>
|
||||
#include <gst/base/gstdataqueue.h>
|
||||
#include "gstmpdparser.h"
|
||||
#include "gstmpdclient.h"
|
||||
#include <gst/isoff/gstisoff.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/uridownloader/gsturidownloader.h>
|
||||
#include <gst/base/gstadapter.h>
|
||||
#include "gstmpdhelper.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
typedef struct _GstMpdClient GstMpdClient;
|
||||
typedef struct _GstActiveStream GstActiveStream;
|
||||
typedef struct _GstStreamPeriod GstStreamPeriod;
|
||||
typedef struct _GstMediaFragmentInfo GstMediaFragmentInfo;
|
||||
|
@ -50,10 +50,7 @@ typedef struct _GstSegmentListNode GstSegmentListNode;
|
|||
typedef struct _GstSegmentTemplateNode GstSegmentTemplateNode;
|
||||
typedef struct _GstSegmentURLNode GstSegmentURLNode;
|
||||
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 _GstProgramInformationNode GstProgramInformationNode;
|
||||
typedef struct _GstMetricsRangeNode GstMetricsRangeNode;
|
||||
|
@ -65,8 +62,6 @@ typedef struct _GstSegmentBaseType GstSegmentBaseType;
|
|||
typedef struct _GstURLType GstURLType;
|
||||
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)
|
||||
|
||||
|
@ -78,22 +73,6 @@ typedef enum
|
|||
GST_STREAM_APPLICATION /* application stream (optional): for timed text/subtitles */
|
||||
} 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
|
||||
{
|
||||
|
@ -120,30 +99,6 @@ struct _GstBaseURL
|
|||
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
|
||||
{
|
||||
guint64 t;
|
||||
|
@ -160,14 +115,14 @@ struct _GstSegmentTimelineNode
|
|||
struct _GstURLType
|
||||
{
|
||||
gchar *sourceURL;
|
||||
GstRange *range;
|
||||
GstXMLRange *range;
|
||||
};
|
||||
|
||||
struct _GstSegmentBaseType
|
||||
{
|
||||
guint timescale;
|
||||
guint64 presentationTimeOffset;
|
||||
GstRange *indexRange;
|
||||
GstXMLRange *indexRange;
|
||||
gboolean indexRangeExact;
|
||||
/* Initialization node */
|
||||
GstURLType *Initialization;
|
||||
|
@ -211,9 +166,9 @@ struct _GstSegmentTemplateNode
|
|||
struct _GstSegmentURLNode
|
||||
{
|
||||
gchar *media;
|
||||
GstRange *mediaRange;
|
||||
GstXMLRange *mediaRange;
|
||||
gchar *index;
|
||||
GstRange *indexRange;
|
||||
GstXMLRange *indexRange;
|
||||
};
|
||||
|
||||
struct _GstRepresentationBaseType
|
||||
|
@ -221,16 +176,16 @@ struct _GstRepresentationBaseType
|
|||
gchar *profiles;
|
||||
guint width;
|
||||
guint height;
|
||||
GstRatio *sar;
|
||||
GstFrameRate *minFrameRate;
|
||||
GstFrameRate *maxFrameRate;
|
||||
GstFrameRate *frameRate;
|
||||
GstXMLRatio *sar;
|
||||
GstXMLFrameRate *minFrameRate;
|
||||
GstXMLFrameRate *maxFrameRate;
|
||||
GstXMLFrameRate *frameRate;
|
||||
gchar *audioSamplingRate;
|
||||
gchar *mimeType;
|
||||
gchar *segmentProfiles;
|
||||
gchar *codecs;
|
||||
gdouble maximumSAPPeriod;
|
||||
GstSAPType startWithSAP;
|
||||
GstMPDSAPType startWithSAP;
|
||||
gdouble maxPlayoutRate;
|
||||
gboolean codingDependency;
|
||||
gchar *scanType;
|
||||
|
@ -285,7 +240,7 @@ struct _GstContentComponentNode
|
|||
guint id;
|
||||
gchar *lang; /* LangVectorType RFC 5646 */
|
||||
gchar *contentType;
|
||||
GstRatio *par;
|
||||
GstXMLRatio *par;
|
||||
/* list of Accessibility DescriptorType nodes */
|
||||
GList *Accessibility;
|
||||
/* list of Role DescriptorType nodes */
|
||||
|
@ -302,16 +257,16 @@ struct _GstAdaptationSetNode
|
|||
guint group;
|
||||
gchar *lang; /* LangVectorType RFC 5646 */
|
||||
gchar *contentType;
|
||||
GstRatio *par;
|
||||
GstXMLRatio *par;
|
||||
guint minBandwidth;
|
||||
guint maxBandwidth;
|
||||
guint minWidth;
|
||||
guint maxWidth;
|
||||
guint minHeight;
|
||||
guint maxHeight;
|
||||
GstConditionalUintType *segmentAlignment;
|
||||
GstConditionalUintType *subsegmentAlignment;
|
||||
GstSAPType subsegmentStartsWithSAP;
|
||||
GstXMLConditionalUintType *segmentAlignment;
|
||||
GstXMLConditionalUintType *subsegmentAlignment;
|
||||
GstMPDSAPType subsegmentStartsWithSAP;
|
||||
gboolean bitstreamSwitching;
|
||||
/* list of Accessibility DescriptorType nodes */
|
||||
GList *Accessibility;
|
||||
|
@ -502,106 +457,35 @@ struct _GstActiveStream
|
|||
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 */
|
||||
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 */
|
||||
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_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);
|
||||
/* navigation functions */
|
||||
GstStreamMimeType gst_mpdparser_representation_get_mimetype (GstAdaptationSetNode * adapt_set, GstRepresentationNode * rep);
|
||||
|
||||
/* 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);
|
||||
/* Memory management */
|
||||
void gst_mpdparser_free_mpd_node (GstMPDNode * mpd_node);
|
||||
void gst_mpdparser_free_period_node (GstPeriodNode * period_node);
|
||||
void gst_mpdparser_free_adaptation_set_node (GstAdaptationSetNode * adaptation_set_node);
|
||||
void gst_mpdparser_free_segment_list_node (GstSegmentListNode * segment_list_node);
|
||||
void gst_mpdparser_free_stream_period (GstStreamPeriod * stream_period);
|
||||
void gst_mpdparser_free_media_segment (GstMediaSegment * media_segment);
|
||||
void gst_mpdparser_free_active_stream (GstActiveStream * active_stream);
|
||||
void gst_mpdparser_free_base_url_node (GstBaseURL * base_url_node);
|
||||
|
||||
/* Representation selection */
|
||||
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);
|
||||
gint gst_mpdparser_get_rep_idx_with_min_bandwidth (GList * Representations);
|
||||
|
||||
/* 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);
|
||||
/* Active stream methods*/
|
||||
void gst_mpdparser_init_active_stream_segments (GstActiveStream * stream);
|
||||
gchar *gst_mpdparser_get_mediaURL (GstActiveStream * stream, GstSegmentURLNode * segmentURL);
|
||||
const gchar *gst_mpdparser_get_initializationURL (GstActiveStream * stream, GstURLType * InitializationURL);
|
||||
|
||||
/*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
|
||||
|
||||
#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 = [
|
||||
'gstdashdemux.c',
|
||||
'gstxmlhelper.c',
|
||||
'gstmpdhelper.c',
|
||||
'gstmpdparser.c',
|
||||
'gstmpdclient.c',
|
||||
'gstplugin.c',
|
||||
]
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue