3 * Copyright (C) 2014 Samsung Electronics. All rights reserved.
4 * Author: Thiago Santos <thiagoss@osg.samsung.com>
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
19 * Boston, MA 02110-1301, USA.
22 #ifndef _GST_ADAPTIVE_DEMUX_H_
23 #define _GST_ADAPTIVE_DEMUX_H_
26 #include <gst/base/gstadapter.h>
27 #include <gst/uridownloader/gsturidownloader.h>
31 #define GST_TYPE_ADAPTIVE_DEMUX \
32 (gst_adaptive_demux_get_type())
33 #define GST_ADAPTIVE_DEMUX(obj) \
34 (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_ADAPTIVE_DEMUX,GstAdaptiveDemux))
35 #define GST_ADAPTIVE_DEMUX_CLASS(klass) \
36 (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_ADAPTIVE_DEMUX,GstAdaptiveDemuxClass))
37 #define GST_ADAPTIVE_DEMUX_GET_CLASS(obj) \
38 (G_TYPE_INSTANCE_GET_CLASS((obj),GST_TYPE_ADAPTIVE_DEMUX,GstAdaptiveDemuxClass))
39 #define GST_IS_ADAPTIVE_DEMUX(obj) \
40 (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_ADAPTIVE_DEMUX))
41 #define GST_IS_ADAPTIVE_DEMUX_CLASS(obj) \
42 (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_ADAPTIVE_DEMUX))
43 #define GST_ADAPTIVE_DEMUX_CAST(obj) ((GstAdaptiveDemux *)obj)
45 #define GST_ADAPTIVE_DEMUX_STREAM_CAST(obj) ((GstAdaptiveDemuxStream *)obj)
48 * GST_ADAPTIVE_DEMUX_SINK_NAME:
50 * The name of the templates for the sink pad.
52 #define GST_ADAPTIVE_DEMUX_SINK_NAME "sink"
55 * GST_ADAPTIVE_DEMUX_SINK_PAD:
56 * @obj: a #GstAdaptiveDemux
58 * Gives the pointer to the sink #GstPad object of the element.
60 #define GST_ADAPTIVE_DEMUX_SINK_PAD(obj) (((GstAdaptiveDemux *) (obj))->sinkpad)
62 #define GST_ADAPTIVE_DEMUX_STREAM_PAD(obj) (((GstAdaptiveDemuxStream *) (obj))->pad)
64 #define GST_ADAPTIVE_DEMUX_STREAM_NEED_HEADER(obj) (((GstAdaptiveDemuxStream *) (obj))->need_header)
67 * GST_ADAPTIVE_DEMUX_STATISTICS_MESSAGE_NAME:
69 * Name of the ELEMENT type messages posted by dashdemux with statistics.
73 #define GST_ADAPTIVE_DEMUX_STATISTICS_MESSAGE_NAME "adaptive-streaming-statistics"
75 #define GST_ELEMENT_ERROR_FROM_ERROR(el, msg, err) G_STMT_START { \
76 gchar *__dbg = g_strdup_printf ("%s: %s", msg, err->message); \
77 GST_WARNING_OBJECT (el, "error: %s", __dbg); \
78 gst_element_message_full (GST_ELEMENT(el), GST_MESSAGE_ERROR, \
79 err->domain, err->code, \
80 NULL, __dbg, __FILE__, GST_FUNCTION, __LINE__); \
81 g_clear_error (&err); \
84 typedef struct _GstAdaptiveDemuxStreamFragment GstAdaptiveDemuxStreamFragment;
85 typedef struct _GstAdaptiveDemuxStream GstAdaptiveDemuxStream;
86 typedef struct _GstAdaptiveDemux GstAdaptiveDemux;
87 typedef struct _GstAdaptiveDemuxClass GstAdaptiveDemuxClass;
88 typedef struct _GstAdaptiveDemuxPrivate GstAdaptiveDemuxPrivate;
90 struct _GstAdaptiveDemuxStreamFragment
92 GstClockTime timestamp;
93 GstClockTime duration;
99 /* when headers are needed */
101 gint64 header_range_start;
102 gint64 header_range_end;
104 /* when index is needed */
106 gint64 index_range_start;
107 gint64 index_range_end;
109 /* Nominal bitrate as provided by
110 * sub-class or calculated by base-class */
114 struct _GstAdaptiveDemuxStream
117 GstPad *internal_pad;
119 GstAdaptiveDemux *demux;
123 GstCaps *pending_caps;
124 GstEvent *pending_segment;
125 GstTagList *pending_tags;
126 gboolean need_header;
127 GList *pending_events;
129 GstFlowReturn last_ret;
132 GstTask *download_task;
133 GRecMutex download_lock;
135 gboolean restart_download;
138 gboolean downloading_first_buffer;
139 gboolean downloading_header;
140 gboolean downloading_index;
142 gboolean bitrate_changed;
144 /* download tooling */
147 GstElement *uri_handler;
149 GMutex fragment_download_lock;
150 GCond fragment_download_cond;
151 gboolean download_finished; /* protected by fragment_download_lock */
152 gboolean cancelled; /* protected by fragment_download_lock */
153 gboolean starting_fragment;
154 gboolean first_fragment_buffer;
155 gint64 download_start_time;
156 gint64 download_chunk_start_time;
157 gint64 download_total_time;
158 gint64 download_total_bytes;
159 guint64 current_download_rate;
161 /* Average for the last fragments */
162 guint64 moving_bitrate;
164 guint64 *fragment_bitrates;
166 GstAdaptiveDemuxStreamFragment fragment;
168 guint download_error_count;
170 /* TODO check if used */
177 * The opaque #GstAdaptiveDemux data structure.
179 struct _GstAdaptiveDemux
184 gsize stream_struct_size;
189 GstUriDownloader *downloader;
197 gchar *manifest_base_uri;
200 gfloat bitrate_limit; /* limit of the available bitrate to use */
201 guint connection_speed;
203 gboolean have_group_id;
207 GstClock *realtime_clock;
208 gint64 clock_offset; /* offset between realtime_clock and UTC (in usec) */
211 GstAdaptiveDemuxPrivate *priv;
215 * GstAdaptiveDemuxClass:
218 struct _GstAdaptiveDemuxClass
221 GstBinClass bin_class;
226 * process_manifest: Parse the manifest
227 * @demux: #GstAdaptiveDemux
228 * @manifest: the manifest to be parsed
230 * Parse the manifest and add the created streams using
231 * gst_adaptive_demux_stream_new()
233 * Returns: #TRUE if successful
235 gboolean (*process_manifest) (GstAdaptiveDemux * demux, GstBuffer * manifest);
238 * get_manifest_update_interval:
239 * @demux: #GstAdaptiveDemux
241 * Used during live streaming, the subclass should return the interval
242 * between successive manifest updates
244 * Returns: the update interval in microseconds
246 gint64 (*get_manifest_update_interval) (GstAdaptiveDemux * demux);
250 * @demux: #GstAdaptiveDemux
252 * During live streaming, this will be called for the subclass to update its
253 * manifest with the new version. By default it fetches the manifest URI
254 * and passes it to GstAdaptiveDemux::update_manifest_data().
256 * Returns: #GST_FLOW_OK is all succeeded, #GST_FLOW_EOS if the stream ended
257 * or #GST_FLOW_ERROR if an error happened
259 GstFlowReturn (*update_manifest) (GstAdaptiveDemux * demux);
262 * update_manifest_data:
263 * @demux: #GstAdaptiveDemux
264 * @buf: Downloaded manifest data
266 * During live streaming, this will be called for the subclass to update its
267 * manifest with the new version
269 * Returns: #GST_FLOW_OK is all succeeded, #GST_FLOW_EOS if the stream ended
270 * or #GST_FLOW_ERROR if an error happened
272 GstFlowReturn (*update_manifest_data) (GstAdaptiveDemux * demux, GstBuffer * buf);
274 gboolean (*is_live) (GstAdaptiveDemux * demux);
275 GstClockTime (*get_duration) (GstAdaptiveDemux * demux);
279 * @demux: #GstAdaptiveDemux
281 * Reset the internal state of the subclass, getting ready to restart with
282 * a new stream afterwards
284 void (*reset) (GstAdaptiveDemux * demux);
288 * @demux: #GstAdaptiveDemux
289 * @seek: a seek #GstEvent
291 * The demuxer should seek on all its streams to the specified position
294 * Returns: #TRUE if successful
296 gboolean (*seek) (GstAdaptiveDemux * demux, GstEvent * seek);
300 * @demux: #GstAdaptiveDemux
302 * Checks if there is a next period following the current one.
303 * DASH can have multiple medias chained in its manifest, when one finishes
304 * this function is called to verify if there is a new period to be played
307 * Returns: #TRUE if there is another period
309 gboolean (*has_next_period) (GstAdaptiveDemux * demux);
312 * @demux: #GstAdaptiveDemux
314 * Advances the manifest to the next period. New streams should be created
315 * using gst_adaptive_demux_stream_new().
317 void (*advance_period) (GstAdaptiveDemux * demux);
319 void (*stream_free) (GstAdaptiveDemuxStream * stream);
320 GstFlowReturn (*stream_seek) (GstAdaptiveDemuxStream * stream, gboolean forward, GstSeekFlags flags, GstClockTime target_ts, GstClockTime * final_ts);
321 gboolean (*stream_has_next_fragment) (GstAdaptiveDemuxStream * stream);
322 GstFlowReturn (*stream_advance_fragment) (GstAdaptiveDemuxStream * stream);
324 * stream_update_fragment_info:
325 * @stream: #GstAdaptiveDemuxStream
327 * Requests the stream to set the information about the current fragment to its
328 * current fragment struct
330 * Returns: #GST_FLOW_OK in success, #GST_FLOW_ERROR on error and #GST_FLOW_EOS
331 * if there is no fragment.
333 GstFlowReturn (*stream_update_fragment_info) (GstAdaptiveDemuxStream * stream);
335 * stream_select_bitrate:
336 * @stream: #GstAdaptiveDemuxStream
337 * @bitrate: the bitrate to select (in bytes per second)
339 * The stream should try to select the bitrate that is the greater, but not
340 * greater than the requested bitrate. If it needs a codec change it should
341 * create the new stream using gst_adaptive_demux_stream_new(). If it only
342 * needs a caps change it should set the new caps using
343 * gst_adaptive_demux_stream_set_caps().
345 * Returns: #TRUE if the stream changed bitrate, #FALSE otherwise
347 gboolean (*stream_select_bitrate) (GstAdaptiveDemuxStream * stream, guint64 bitrate);
349 * stream_get_fragment_waiting_time:
350 * @stream: #GstAdaptiveDemuxStream
352 * For live streams, requests how much time should be waited before starting
353 * to download the fragment. This is useful to avoid downloading a fragment that
354 * isn't available yet.
356 * Returns: The waiting time in microsseconds
358 gint64 (*stream_get_fragment_waiting_time) (GstAdaptiveDemuxStream * stream);
362 * @demux: #GstAdaptiveDemux
363 * @stream: #GstAdaptiveDemuxStream
365 * Notifies the subclass that the given stream is starting the download
366 * of a new fragment. Can be used to reset/init internal state that is
367 * needed before each fragment, like decryption engines.
369 * Returns: #TRUE if successful.
371 gboolean (*start_fragment) (GstAdaptiveDemux * demux, GstAdaptiveDemuxStream * stream);
374 * @demux: #GstAdaptiveDemux
375 * @stream: #GstAdaptiveDemuxStream
377 * Notifies the subclass that a fragment download was finished.
378 * It can be used to cleanup internal state after a fragment and
379 * also push any pending data before moving to the next fragment.
381 GstFlowReturn (*finish_fragment) (GstAdaptiveDemux * demux, GstAdaptiveDemuxStream * stream);
384 * @demux: #GstAdaptiveDemux
385 * @stream: #GstAdaptiveDemuxStream
386 * @buffer: #GstBuffer
388 * Notifies the subclass that a fragment chunk was downloaded. The subclass
389 * can look at the data and modify/push data as desired.
391 * Returns: #GST_FLOW_OK if successful, #GST_FLOW_ERROR in case of error.
393 GstFlowReturn (*data_received) (GstAdaptiveDemux * demux, GstAdaptiveDemuxStream * stream, GstBuffer * buffer);
396 * get_live_seek_range:
397 * @demux: #GstAdaptiveDemux
398 * @start: pointer to put the start position allowed to seek to
399 * @stop: pointer to put the stop position allowed to seek to
401 * Gets the allowed seek start and stop positions for the current live stream
403 * Return: %TRUE if successful
405 gboolean (*get_live_seek_range) (GstAdaptiveDemux * demux, gint64 * start, gint64 * stop);
408 * get_presentation_offset:
409 * @demux: #GstAdaptiveDemux
410 * @stream: #GstAdaptiveDemuxStream
412 * Gets the delay to apply to @stream.
414 * Return: a #GstClockTime representing the (positive) time offset to apply to
417 GstClockTime (*get_presentation_offset) (GstAdaptiveDemux *demux, GstAdaptiveDemuxStream *stream);
420 * get_period_start_time:
421 * @demux: #GstAdaptiveDemux
423 * Gets the start time of the current period. Timestamps are resetting to 0
424 * after each period but we have to maintain a continuous stream and running
425 * time so need to know the start time of the current period.
427 * Return: a #GstClockTime representing the start time of the currently
430 GstClockTime (*get_period_start_time) (GstAdaptiveDemux *demux);
433 GType gst_adaptive_demux_get_type (void);
435 void gst_adaptive_demux_set_stream_struct_size (GstAdaptiveDemux * demux,
439 GstAdaptiveDemuxStream *gst_adaptive_demux_stream_new (GstAdaptiveDemux * demux,
441 GstAdaptiveDemuxStream *gst_adaptive_demux_find_stream_for_pad (GstAdaptiveDemux * demux,
443 void gst_adaptive_demux_stream_set_caps (GstAdaptiveDemuxStream * stream,
445 void gst_adaptive_demux_stream_set_tags (GstAdaptiveDemuxStream * stream,
447 void gst_adaptive_demux_stream_fragment_clear (GstAdaptiveDemuxStreamFragment * f);
449 GstFlowReturn gst_adaptive_demux_stream_push_buffer (GstAdaptiveDemuxStream * stream, GstBuffer * buffer);
451 gst_adaptive_demux_stream_advance_fragment (GstAdaptiveDemux * demux,
452 GstAdaptiveDemuxStream * stream, GstClockTime duration);
453 void gst_adaptive_demux_stream_queue_event (GstAdaptiveDemuxStream * stream,
456 GstClockTime gst_adaptive_demux_get_monotonic_time (GstAdaptiveDemux * demux);
457 GDateTime *gst_adaptive_demux_get_client_now_utc (GstAdaptiveDemux * demux);