adaptive: extract variant info
[platform/upstream/gstreamer.git] / gst-libs / gst / adaptivedemux / gstadaptivedemux.h
1 /* GStreamer
2  *
3  * Copyright (C) 2014 Samsung Electronics. All rights reserved.
4  *   Author: Thiago Santos <thiagoss@osg.samsung.com>
5  *
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.
10  *
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.
15  *
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.
20  */
21
22 #ifndef _GST_ADAPTIVE_DEMUX_H_
23 #define _GST_ADAPTIVE_DEMUX_H_
24
25 #include <gst/gst.h>
26 #include <gst/base/gstadapter.h>
27 #include <gst/uridownloader/gsturidownloader.h>
28
29 G_BEGIN_DECLS
30
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)
44
45 #define GST_ADAPTIVE_DEMUX_STREAM_CAST(obj) ((GstAdaptiveDemuxStream *)obj)
46
47 /**
48  * GST_ADAPTIVE_DEMUX_SINK_NAME:
49  *
50  * The name of the templates for the sink pad.
51  */
52 #define GST_ADAPTIVE_DEMUX_SINK_NAME    "sink"
53
54 /**
55  * GST_ADAPTIVE_DEMUX_SINK_PAD:
56  * @obj: a #GstAdaptiveDemux
57  *
58  * Gives the pointer to the sink #GstPad object of the element.
59  */
60 #define GST_ADAPTIVE_DEMUX_SINK_PAD(obj)        (((GstAdaptiveDemux *) (obj))->sinkpad)
61
62 #define GST_ADAPTIVE_DEMUX_STREAM_PAD(obj)      (((GstAdaptiveDemuxStream *) (obj))->pad)
63
64 #define GST_ADAPTIVE_DEMUX_STREAM_NEED_HEADER(obj) (((GstAdaptiveDemuxStream *) (obj))->need_header)
65
66 /**
67  * GST_ADAPTIVE_DEMUX_STATISTICS_MESSAGE_NAME:
68  *
69  * Name of the ELEMENT type messages posted by dashdemux with statistics.
70  *
71  * Since: 1.6
72  */
73 #define GST_ADAPTIVE_DEMUX_STATISTICS_MESSAGE_NAME "adaptive-streaming-statistics"
74 #ifdef TIZEN_FEATURE_ADAPTIVE_MODIFICATION
75 #define GST_ADAPTIVE_DEMUX_VARIANT_MESSAGE_NAME "adaptive-streaming-variant"
76 #endif
77
78 #define GST_ELEMENT_ERROR_FROM_ERROR(el, msg, err) G_STMT_START { \
79   gchar *__dbg = g_strdup_printf ("%s: %s", msg, err->message);         \
80   GST_WARNING_OBJECT (el, "error: %s", __dbg);                          \
81   gst_element_message_full (GST_ELEMENT(el), GST_MESSAGE_ERROR,         \
82     err->domain, err->code,                                             \
83     NULL, __dbg, __FILE__, GST_FUNCTION, __LINE__);                     \
84   g_clear_error (&err); \
85 } G_STMT_END
86
87 #define GST_ADAPTIVE_DEMUX_FLOW_END_OF_FRAGMENT GST_FLOW_CUSTOM_SUCCESS_1
88 #ifdef TIZEN_FEATURE_ADAPTIVE_MODIFICATION
89 #define DEFAULT_ADAPTIVE_RETRY -1
90 #define DEFAULT_ADAPTIVE_TIMEOUT -1
91 #define PLAYLIST_ADAPTIVE_RETRY 3
92 #define PLAYLIST_ADAPTIVE_TIMEOUT 2
93 #define DEFAULT_ADAPTIVE_VARIANT -1
94 #endif
95
96 typedef struct _GstAdaptiveDemuxStreamFragment GstAdaptiveDemuxStreamFragment;
97 typedef struct _GstAdaptiveDemuxStream GstAdaptiveDemuxStream;
98 typedef struct _GstAdaptiveDemux GstAdaptiveDemux;
99 typedef struct _GstAdaptiveDemuxClass GstAdaptiveDemuxClass;
100 typedef struct _GstAdaptiveDemuxPrivate GstAdaptiveDemuxPrivate;
101 #ifdef TIZEN_FEATURE_AVOID_PAD_SWITCHING
102 typedef GstPad* (*GstAdaptiveDemuxStreamCreatePadFunc)(GstAdaptiveDemuxStream * stream);
103 #endif
104
105 struct _GstAdaptiveDemuxStreamFragment
106 {
107   GstClockTime timestamp;
108   GstClockTime duration;
109
110   gchar *uri;
111   gint64 range_start;
112   gint64 range_end;
113
114   /* when chunked downloading is used, may be be updated need_another_chunk() */
115   guint chunk_size;
116
117   /* when headers are needed */
118   gchar *header_uri;
119   gint64 header_range_start;
120   gint64 header_range_end;
121
122   /* when index is needed */
123   gchar *index_uri;
124   gint64 index_range_start;
125   gint64 index_range_end;
126
127   /* Nominal bitrate as provided by
128    * sub-class or calculated by base-class */
129   guint bitrate;
130
131   gboolean finished;
132 };
133
134 struct _GstAdaptiveDemuxStream
135 {
136   GstPad *pad;
137   GstPad *internal_pad;
138
139   GstAdaptiveDemux *demux;
140
141 #ifdef TIZEN_FEATURE_AVOID_PAD_SWITCHING
142   gint stream_id_counter;
143 #endif
144   GstSegment segment;
145
146   GstCaps *pending_caps;
147   GstEvent *pending_segment;
148   GstTagList *pending_tags;
149   gboolean need_header;
150   GList *pending_events;
151
152   GstFlowReturn last_ret;
153   GError *last_error;
154
155   GstTask *download_task;
156   GRecMutex download_lock;
157
158   gboolean restart_download;
159   gboolean discont;
160
161   gboolean downloading_first_buffer;
162   gboolean downloading_header;
163   gboolean downloading_index;
164
165   gboolean bitrate_changed;
166
167   /* download tooling */
168   GstElement *src;
169   guint last_status_code;
170   GstPad *src_srcpad;
171   GstElement *uri_handler;
172   GstElement *queue;
173   GMutex fragment_download_lock;
174   GCond fragment_download_cond;
175   gboolean download_finished;   /* protected by fragment_download_lock */
176   gboolean cancelled;           /* protected by fragment_download_lock */
177   gboolean src_at_ready;     /* protected by fragment_download_lock */
178   gboolean starting_fragment;
179   gboolean first_fragment_buffer;
180   gint64 download_start_time;
181   gint64 download_total_bytes;
182   guint64 current_download_rate;
183
184   /* amount of data downloaded in current fragment (pre-queue2) */
185   guint64 fragment_bytes_downloaded;
186   /* bitrate of the previous fragment (pre-queue2) */
187   guint64 last_bitrate;
188   /* latency (request to first byte) and full download time (request to EOS)
189    * of previous fragment (pre-queue2) */
190   GstClockTime last_latency;
191   GstClockTime last_download_time;
192
193   /* Average for the last fragments */
194   guint64 moving_bitrate;
195   guint moving_index;
196   guint64 *fragment_bitrates;
197
198   GstAdaptiveDemuxStreamFragment fragment;
199
200   guint download_error_count;
201
202   /* TODO check if used */
203   gboolean eos;
204
205   gboolean do_block; /* TRUE if stream should block on preroll */
206 };
207
208 /**
209  * GstAdaptiveDemux:
210  *
211  * The opaque #GstAdaptiveDemux data structure.
212  */
213 struct _GstAdaptiveDemux
214 {
215   /*< private >*/
216   GstBin     bin;
217
218   gboolean running;
219
220   gsize stream_struct_size;
221
222   /*< protected >*/
223   GstPad         *sinkpad;
224
225   GstUriDownloader *downloader;
226
227   GList *streams;
228   GList *prepared_streams;
229   GList *next_streams;
230
231   GstSegment segment;
232
233   gchar *manifest_uri;
234   gchar *manifest_base_uri;
235 #ifdef TIZEN_FEATURE_ADAPTIVE_MODIFICATION
236   gchar *user_agent;
237   gchar **cookies;
238 #endif
239
240   /* Properties */
241   gfloat bitrate_limit;         /* limit of the available bitrate to use */
242   guint connection_speed;
243
244   gboolean have_group_id;
245   guint group_id;
246
247   /* Realtime clock */
248   GstClock *realtime_clock;
249   gint64 clock_offset; /* offset between realtime_clock and UTC (in usec) */
250
251   /* < private > */
252   GstAdaptiveDemuxPrivate *priv;
253 #ifdef TIZEN_FEATURE_ADAPTIVE_MODIFICATION
254   gint max_bandwidth;
255   gint max_width;
256   gint max_height;
257 #endif
258 };
259
260 /**
261  * GstAdaptiveDemuxClass:
262  *
263  */
264 struct _GstAdaptiveDemuxClass
265 {
266   /*< private >*/
267   GstBinClass bin_class;
268
269   /*< public >*/
270
271   /**
272    * process_manifest: Parse the manifest
273    * @demux: #GstAdaptiveDemux
274    * @manifest: the manifest to be parsed
275    *
276    * Parse the manifest and add the created streams using
277    * gst_adaptive_demux_stream_new()
278    *
279    * Returns: #TRUE if successful
280    */
281   gboolean      (*process_manifest) (GstAdaptiveDemux * demux, GstBuffer * manifest);
282
283   /**
284    * get_manifest_update_interval:
285    * @demux: #GstAdaptiveDemux
286    *
287    * Used during live streaming, the subclass should return the interval
288    * between successive manifest updates
289    *
290    * Returns: the update interval in microseconds
291    */
292   gint64        (*get_manifest_update_interval) (GstAdaptiveDemux * demux);
293
294   /**
295    * update_manifest:
296    * @demux: #GstAdaptiveDemux
297    *
298    * During live streaming, this will be called for the subclass to update its
299    * manifest with the new version. By default it fetches the manifest URI
300    * and passes it to GstAdaptiveDemux::update_manifest_data().
301    *
302    * Returns: #GST_FLOW_OK is all succeeded, #GST_FLOW_EOS if the stream ended
303    *          or #GST_FLOW_ERROR if an error happened
304    */
305   GstFlowReturn (*update_manifest) (GstAdaptiveDemux * demux);
306
307   /**
308    * update_manifest_data:
309    * @demux: #GstAdaptiveDemux
310    * @buf: Downloaded manifest data
311    *
312    * During live streaming, this will be called for the subclass to update its
313    * manifest with the new version
314    *
315    * Returns: #GST_FLOW_OK is all succeeded, #GST_FLOW_EOS if the stream ended
316    *          or #GST_FLOW_ERROR if an error happened
317    */
318   GstFlowReturn (*update_manifest_data) (GstAdaptiveDemux * demux, GstBuffer * buf);
319
320   gboolean      (*is_live)          (GstAdaptiveDemux * demux);
321   GstClockTime  (*get_duration)     (GstAdaptiveDemux * demux);
322
323   /**
324    * reset:
325    * @demux: #GstAdaptiveDemux
326    *
327    * Reset the internal state of the subclass, getting ready to restart with
328    * a new stream afterwards
329    */
330   void          (*reset)            (GstAdaptiveDemux * demux);
331
332   /**
333    * seek:
334    * @demux: #GstAdaptiveDemux
335    * @seek: a seek #GstEvent
336    *
337    * The demuxer should seek on all its streams to the specified position
338    * in the seek event
339    *
340    * Returns: #TRUE if successful
341    */
342   gboolean      (*seek)             (GstAdaptiveDemux * demux, GstEvent * seek);
343
344   /**
345    * has_next_period:
346    * @demux: #GstAdaptiveDemux
347    *
348    * Checks if there is a next period following the current one.
349    * DASH can have multiple medias chained in its manifest, when one finishes
350    * this function is called to verify if there is a new period to be played
351    * in sequence.
352    *
353    * Returns: #TRUE if there is another period
354    */
355   gboolean      (*has_next_period)  (GstAdaptiveDemux * demux);
356   /**
357    * advance_period:
358    * @demux: #GstAdaptiveDemux
359    *
360    * Advances the manifest to the next period. New streams should be created
361    * using gst_adaptive_demux_stream_new().
362    */
363   void          (*advance_period)  (GstAdaptiveDemux * demux);
364
365   void          (*stream_free)     (GstAdaptiveDemuxStream * stream);
366   GstFlowReturn (*stream_seek)     (GstAdaptiveDemuxStream * stream, gboolean forward, GstSeekFlags flags, GstClockTime target_ts, GstClockTime * final_ts);
367   gboolean      (*stream_has_next_fragment)  (GstAdaptiveDemuxStream * stream);
368   GstFlowReturn (*stream_advance_fragment) (GstAdaptiveDemuxStream * stream);
369
370   /**
371    * need_another_chunk:
372    * @stream: #GstAdaptiveDemuxStream
373    *
374    * If chunked downloading is used (chunk_size != 0) this is called once as
375    * chunk is finished to decide whether more has to be downloaded or not.
376    * May update chunk_size to a different value
377    */
378   gboolean      (*need_another_chunk) (GstAdaptiveDemuxStream * stream);
379
380   /**
381    * stream_update_fragment_info:
382    * @stream: #GstAdaptiveDemuxStream
383    *
384    * Requests the stream to set the information about the current fragment to its
385    * current fragment struct
386    *
387    * Returns: #GST_FLOW_OK in success, #GST_FLOW_ERROR on error and #GST_FLOW_EOS
388    *          if there is no fragment.
389    */
390   GstFlowReturn (*stream_update_fragment_info) (GstAdaptiveDemuxStream * stream);
391   /**
392    * stream_select_bitrate:
393    * @stream: #GstAdaptiveDemuxStream
394    * @bitrate: the bitrate to select (in bytes per second)
395    *
396    * The stream should try to select the bitrate that is the greater, but not
397    * greater than the requested bitrate. If it needs a codec change it should
398    * create the new stream using gst_adaptive_demux_stream_new(). If it only
399    * needs a caps change it should set the new caps using
400    * gst_adaptive_demux_stream_set_caps().
401    *
402    * Returns: #TRUE if the stream changed bitrate, #FALSE otherwise
403    */
404   gboolean      (*stream_select_bitrate) (GstAdaptiveDemuxStream * stream, guint64 bitrate);
405   /**
406    * stream_get_fragment_waiting_time:
407    * @stream: #GstAdaptiveDemuxStream
408    *
409    * For live streams, requests how much time should be waited before starting
410    * to download the fragment. This is useful to avoid downloading a fragment that
411    * isn't available yet.
412    *
413    * Returns: The waiting time in microsseconds
414    */
415   gint64        (*stream_get_fragment_waiting_time) (GstAdaptiveDemuxStream * stream);
416
417   /**
418    * start_fragment:
419    * @demux: #GstAdaptiveDemux
420    * @stream: #GstAdaptiveDemuxStream
421    *
422    * Notifies the subclass that the given stream is starting the download
423    * of a new fragment. Can be used to reset/init internal state that is
424    * needed before each fragment, like decryption engines.
425    *
426    * Returns: #TRUE if successful.
427    */
428   gboolean      (*start_fragment) (GstAdaptiveDemux * demux, GstAdaptiveDemuxStream * stream);
429   /**
430    * finish_fragment:
431    * @demux: #GstAdaptiveDemux
432    * @stream: #GstAdaptiveDemuxStream
433    *
434    * Notifies the subclass that a fragment download was finished.
435    * It can be used to cleanup internal state after a fragment and
436    * also push any pending data before moving to the next fragment.
437    */
438   GstFlowReturn (*finish_fragment) (GstAdaptiveDemux * demux, GstAdaptiveDemuxStream * stream);
439   /**
440    * data_received:
441    * @demux: #GstAdaptiveDemux
442    * @stream: #GstAdaptiveDemuxStream
443    * @buffer: #GstBuffer
444    *
445    * Notifies the subclass that a fragment chunk was downloaded. The subclass
446    * can look at the data and modify/push data as desired.
447    *
448    * Returns: #GST_FLOW_OK if successful, #GST_FLOW_ERROR in case of error.
449    */
450   GstFlowReturn (*data_received) (GstAdaptiveDemux * demux, GstAdaptiveDemuxStream * stream, GstBuffer * buffer);
451
452   /**
453    * get_live_seek_range:
454    * @demux: #GstAdaptiveDemux
455    * @start: pointer to put the start position allowed to seek to
456    * @stop: pointer to put the stop position allowed to seek to
457    *
458    * Gets the allowed seek start and stop positions for the current live stream
459    *
460    * Return: %TRUE if successful
461    */
462   gboolean (*get_live_seek_range) (GstAdaptiveDemux * demux, gint64 * start, gint64 * stop);
463
464   /**
465    * get_presentation_offset:
466    * @demux: #GstAdaptiveDemux
467    * @stream: #GstAdaptiveDemuxStream
468    *
469    * Gets the delay to apply to @stream.
470    *
471    * Return: a #GstClockTime representing the (positive) time offset to apply to
472    * @stream.
473    */
474   GstClockTime (*get_presentation_offset) (GstAdaptiveDemux *demux, GstAdaptiveDemuxStream *stream);
475
476   /**
477    * get_period_start_time:
478    * @demux: #GstAdaptiveDemux
479    *
480    * Gets the start time of the current period. Timestamps are resetting to 0
481    * after each period but we have to maintain a continuous stream and running
482    * time so need to know the start time of the current period.
483    *
484    * Return: a #GstClockTime representing the start time of the currently
485    * selected period.
486    */
487   GstClockTime (*get_period_start_time) (GstAdaptiveDemux *demux);
488
489   /**
490    * requires_periodical_playlist_update:
491    * @demux: #GstAdaptiveDemux
492    *
493    * Some adaptive streaming protocols allow the client to download
494    * the playlist once and build up the fragment list based on the
495    * current fragment metadata. For those protocols the demuxer
496    * doesn't need to periodically refresh the playlist. This vfunc
497    * is relevant only for live playback scenarios.
498    *
499    * Return: %TRUE if the playlist needs to be refreshed periodically by the demuxer.
500    */
501   gboolean (*requires_periodical_playlist_update) (GstAdaptiveDemux * demux);
502 };
503
504 GType    gst_adaptive_demux_get_type (void);
505
506 void     gst_adaptive_demux_set_stream_struct_size (GstAdaptiveDemux * demux,
507                                                     gsize struct_size);
508
509
510 GstAdaptiveDemuxStream *gst_adaptive_demux_stream_new (GstAdaptiveDemux * demux,
511                                                        GstPad * pad);
512 GstAdaptiveDemuxStream *gst_adaptive_demux_find_stream_for_pad (GstAdaptiveDemux * demux,
513                                                                 GstPad * pad);
514 void gst_adaptive_demux_stream_set_caps (GstAdaptiveDemuxStream * stream,
515                                          GstCaps * caps);
516 void gst_adaptive_demux_stream_set_tags (GstAdaptiveDemuxStream * stream,
517                                          GstTagList * tags);
518 void gst_adaptive_demux_stream_fragment_clear (GstAdaptiveDemuxStreamFragment * f);
519
520 GstFlowReturn gst_adaptive_demux_stream_push_buffer (GstAdaptiveDemuxStream * stream, GstBuffer * buffer);
521 GstFlowReturn
522 gst_adaptive_demux_stream_advance_fragment (GstAdaptiveDemux * demux,
523     GstAdaptiveDemuxStream * stream, GstClockTime duration);
524 void gst_adaptive_demux_stream_queue_event (GstAdaptiveDemuxStream * stream,
525     GstEvent * event);
526
527 GstClockTime gst_adaptive_demux_get_monotonic_time (GstAdaptiveDemux * demux);
528 GDateTime *gst_adaptive_demux_get_client_now_utc (GstAdaptiveDemux * demux);
529
530 #ifdef TIZEN_FEATURE_AVOID_PAD_SWITCHING
531 gboolean gst_adaptive_demux_stream_check_switch_pad (GstAdaptiveDemuxStream * stream,
532     GstCaps * caps, GstAdaptiveDemuxStreamCreatePadFunc create_pad_func);
533 #endif
534
535 G_END_DECLS
536
537 #endif
538