• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include <gst/adaptivedemux/adaptive-demux-prelude.h>
29 
30 G_BEGIN_DECLS
31 
32 #define GST_TYPE_ADAPTIVE_DEMUX \
33   (gst_adaptive_demux_get_type())
34 #define GST_ADAPTIVE_DEMUX(obj) \
35   (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_ADAPTIVE_DEMUX,GstAdaptiveDemux))
36 #define GST_ADAPTIVE_DEMUX_CLASS(klass) \
37   (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_ADAPTIVE_DEMUX,GstAdaptiveDemuxClass))
38 #define GST_ADAPTIVE_DEMUX_GET_CLASS(obj) \
39   (G_TYPE_INSTANCE_GET_CLASS((obj),GST_TYPE_ADAPTIVE_DEMUX,GstAdaptiveDemuxClass))
40 #define GST_IS_ADAPTIVE_DEMUX(obj) \
41   (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_ADAPTIVE_DEMUX))
42 #define GST_IS_ADAPTIVE_DEMUX_CLASS(obj) \
43   (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_ADAPTIVE_DEMUX))
44 #define GST_ADAPTIVE_DEMUX_CAST(obj) ((GstAdaptiveDemux *)obj)
45 
46 #define GST_ADAPTIVE_DEMUX_STREAM_CAST(obj) ((GstAdaptiveDemuxStream *)obj)
47 
48 /**
49  * GST_ADAPTIVE_DEMUX_SINK_NAME:
50  *
51  * The name of the templates for the sink pad.
52  */
53 #define GST_ADAPTIVE_DEMUX_SINK_NAME    "sink"
54 
55 /**
56  * GST_ADAPTIVE_DEMUX_SINK_PAD:
57  * @obj: a #GstAdaptiveDemux
58  *
59  * Gives the pointer to the sink #GstPad object of the element.
60  */
61 #define GST_ADAPTIVE_DEMUX_SINK_PAD(obj)        (((GstAdaptiveDemux *) (obj))->sinkpad)
62 
63 #define GST_ADAPTIVE_DEMUX_IN_TRICKMODE_KEY_UNITS(obj) ((((GstAdaptiveDemux*)(obj))->segment.flags & GST_SEGMENT_FLAG_TRICKMODE_KEY_UNITS) == GST_SEGMENT_FLAG_TRICKMODE_KEY_UNITS)
64 
65 #define GST_ADAPTIVE_DEMUX_STREAM_PAD(obj)      (((GstAdaptiveDemuxStream *) (obj))->pad)
66 
67 #define GST_ADAPTIVE_DEMUX_STREAM_NEED_HEADER(obj) (((GstAdaptiveDemuxStream *) (obj))->need_header)
68 
69 /**
70  * GST_ADAPTIVE_DEMUX_STATISTICS_MESSAGE_NAME:
71  *
72  * Name of the ELEMENT type messages posted by dashdemux with statistics.
73  *
74  * Since: 1.6
75  */
76 #define GST_ADAPTIVE_DEMUX_STATISTICS_MESSAGE_NAME "adaptive-streaming-statistics"
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 /* DEPRECATED */
88 #define GST_ADAPTIVE_DEMUX_FLOW_END_OF_FRAGMENT GST_FLOW_CUSTOM_SUCCESS_1
89 
90 typedef struct _GstAdaptiveDemuxStreamFragment GstAdaptiveDemuxStreamFragment;
91 typedef struct _GstAdaptiveDemuxStream GstAdaptiveDemuxStream;
92 typedef struct _GstAdaptiveDemux GstAdaptiveDemux;
93 typedef struct _GstAdaptiveDemuxClass GstAdaptiveDemuxClass;
94 typedef struct _GstAdaptiveDemuxPrivate GstAdaptiveDemuxPrivate;
95 
96 #ifdef OHOS_EXT_FUNC
97 // ohos.ext.func.0028
98 typedef struct _GstAdaptiveDemuxBitrateInfo GstAdaptiveDemuxBitrateInfo;
99 struct _GstAdaptiveDemuxBitrateInfo {
100   guint *bitrate_list;
101   guint bitrate_num;
102 };
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   GstSegment segment;
142 
143   GstCaps *pending_caps;
144   GstEvent *pending_segment;
145   GstTagList *pending_tags;
146   gboolean need_header;
147   GList *pending_events;
148 
149   GstFlowReturn last_ret;
150   GError *last_error;
151 
152   GstTask *download_task;
153   GRecMutex download_lock;
154 
155   gboolean restart_download;
156   gboolean discont;
157 
158   gboolean downloading_first_buffer;
159   gboolean downloading_header;
160   gboolean downloading_index;
161 
162   gboolean bitrate_changed;
163 
164   /* download tooling */
165   GstElement *src;
166   guint last_status_code;
167   GstPad *src_srcpad;
168   GstElement *uri_handler;
169   GstElement *queue;
170   GMutex fragment_download_lock;
171   GCond fragment_download_cond;
172   gboolean download_finished;   /* protected by fragment_download_lock */
173   gboolean cancelled; /* protected by fragment_download_lock */
174   gboolean replaced; /* replaced in a bitrate switch (used with cancelled) */
175   gboolean src_at_ready;     /* protected by fragment_download_lock */
176   gboolean starting_fragment;
177   gboolean first_fragment_buffer;
178   gint64 download_start_time;
179   gint64 download_total_bytes;
180   guint64 current_download_rate;
181 
182   /* amount of data downloaded in current fragment (pre-queue2) */
183   guint64 fragment_bytes_downloaded;
184   /* bitrate of the previous fragment (pre-queue2) */
185   guint64 last_bitrate;
186   /* latency (request to first byte) and full download time (request to EOS)
187    * of previous fragment (pre-queue2) */
188   GstClockTime last_latency;
189   GstClockTime last_download_time;
190 
191   /* Average for the last fragments */
192   guint64 moving_bitrate;
193   guint moving_index;
194   guint64 *fragment_bitrates;
195 
196   /* QoS data : UNUSED !!! */
197   GstClockTime qos_earliest_time;
198 
199   GstAdaptiveDemuxStreamFragment fragment;
200 
201   guint download_error_count;
202 
203   /* TODO check if used */
204   gboolean eos;
205 
206   gboolean do_block; /* TRUE if stream should block on preroll */
207 };
208 
209 /**
210  * GstAdaptiveDemux:
211  *
212  * The opaque #GstAdaptiveDemux data structure.
213  */
214 struct _GstAdaptiveDemux
215 {
216   /*< private >*/
217   GstBin     bin;
218 
219   gint running;
220 
221   gsize stream_struct_size;
222 
223   /*< protected >*/
224   GstPad         *sinkpad;
225 
226   GstUriDownloader *downloader;
227 
228   GList *streams;
229   GList *prepared_streams;
230   GList *next_streams;
231 
232   GstSegment segment;
233 
234   gchar *manifest_uri;
235   gchar *manifest_base_uri;
236 
237   /* Properties */
238   gfloat bitrate_limit;         /* limit of the available bitrate to use */
239   guint connection_speed;
240 
241   gboolean have_group_id;
242   guint group_id;
243 
244   /* Realtime clock */
245   GstClock *realtime_clock;
246   gint64 clock_offset; /* offset between realtime_clock and UTC (in usec) */
247 
248   /* < private > */
249   GstAdaptiveDemuxPrivate *priv;
250 };
251 
252 /**
253  * GstAdaptiveDemuxClass:
254  *
255  */
256 struct _GstAdaptiveDemuxClass
257 {
258   /*< private >*/
259   GstBinClass bin_class;
260 
261   /*< public >*/
262 
263   /**
264    * process_manifest: Parse the manifest
265    * @demux: #GstAdaptiveDemux
266    * @manifest: the manifest to be parsed
267    *
268    * Parse the manifest and add the created streams using
269    * gst_adaptive_demux_stream_new()
270    *
271    * Returns: %TRUE if successful
272    */
273   gboolean      (*process_manifest) (GstAdaptiveDemux * demux, GstBuffer * manifest);
274 
275   /**
276    * get_manifest_update_interval:
277    * @demux: #GstAdaptiveDemux
278    *
279    * Used during live streaming, the subclass should return the interval
280    * between successive manifest updates
281    *
282    * Returns: the update interval in microseconds
283    */
284   gint64        (*get_manifest_update_interval) (GstAdaptiveDemux * demux);
285 
286   /**
287    * update_manifest:
288    * @demux: #GstAdaptiveDemux
289    *
290    * During live streaming, this will be called for the subclass to update its
291    * manifest with the new version. By default it fetches the manifest URI
292    * and passes it to GstAdaptiveDemux::update_manifest_data().
293    *
294    * Returns: #GST_FLOW_OK is all succeeded, #GST_FLOW_EOS if the stream ended
295    *          or #GST_FLOW_ERROR if an error happened
296    */
297   GstFlowReturn (*update_manifest) (GstAdaptiveDemux * demux);
298 
299   /**
300    * update_manifest_data:
301    * @demux: #GstAdaptiveDemux
302    * @buf: Downloaded manifest data
303    *
304    * During live streaming, this will be called for the subclass to update its
305    * manifest with the new version
306    *
307    * Returns: #GST_FLOW_OK is all succeeded, #GST_FLOW_EOS if the stream ended
308    *          or #GST_FLOW_ERROR if an error happened
309    */
310   GstFlowReturn (*update_manifest_data) (GstAdaptiveDemux * demux, GstBuffer * buf);
311 
312   gboolean      (*is_live)          (GstAdaptiveDemux * demux);
313   GstClockTime  (*get_duration)     (GstAdaptiveDemux * demux);
314 
315   /**
316    * reset:
317    * @demux: #GstAdaptiveDemux
318    *
319    * Reset the internal state of the subclass, getting ready to restart with
320    * a new stream afterwards
321    */
322   void          (*reset)            (GstAdaptiveDemux * demux);
323 
324   /**
325    * seek:
326    * @demux: #GstAdaptiveDemux
327    * @seek: a seek #GstEvent
328    *
329    * The demuxer should seek on all its streams to the specified position
330    * in the seek event
331    *
332    * Returns: %TRUE if successful
333    */
334   gboolean      (*seek)             (GstAdaptiveDemux * demux, GstEvent * seek);
335 
336   /**
337    * has_next_period:
338    * @demux: #GstAdaptiveDemux
339    *
340    * Checks if there is a next period following the current one.
341    * DASH can have multiple medias chained in its manifest, when one finishes
342    * this function is called to verify if there is a new period to be played
343    * in sequence.
344    *
345    * Returns: %TRUE if there is another period
346    */
347   gboolean      (*has_next_period)  (GstAdaptiveDemux * demux);
348   /**
349    * advance_period:
350    * @demux: #GstAdaptiveDemux
351    *
352    * Advances the manifest to the next period. New streams should be created
353    * using gst_adaptive_demux_stream_new().
354    */
355   void          (*advance_period)  (GstAdaptiveDemux * demux);
356 
357   void          (*stream_free)     (GstAdaptiveDemuxStream * stream);
358   GstFlowReturn (*stream_seek)     (GstAdaptiveDemuxStream * stream, gboolean forward, GstSeekFlags flags, GstClockTime target_ts, GstClockTime * final_ts);
359   gboolean      (*stream_has_next_fragment)  (GstAdaptiveDemuxStream * stream);
360   GstFlowReturn (*stream_advance_fragment) (GstAdaptiveDemuxStream * stream);
361 
362   /**
363    * need_another_chunk:
364    * @stream: #GstAdaptiveDemuxStream
365    *
366    * If chunked downloading is used (chunk_size != 0) this is called once a
367    * chunk is finished to decide whether more has to be downloaded or not.
368    * May update chunk_size to a different value
369    */
370   gboolean      (*need_another_chunk) (GstAdaptiveDemuxStream * stream);
371 
372   /**
373    * stream_update_fragment_info:
374    * @stream: #GstAdaptiveDemuxStream
375    *
376    * Requests the stream to set the information about the current fragment to its
377    * current fragment struct
378    *
379    * Returns: #GST_FLOW_OK in success, #GST_FLOW_ERROR on error and #GST_FLOW_EOS
380    *          if there is no fragment.
381    */
382   GstFlowReturn (*stream_update_fragment_info) (GstAdaptiveDemuxStream * stream);
383   /**
384    * stream_select_bitrate:
385    * @stream: #GstAdaptiveDemuxStream
386    * @bitrate: the bitrate to select (in bytes per second)
387    *
388    * The stream should try to select the bitrate that is the greater, but not
389    * greater than the requested bitrate. If it needs a codec change it should
390    * create the new stream using gst_adaptive_demux_stream_new(). If it only
391    * needs a caps change it should set the new caps using
392    * gst_adaptive_demux_stream_set_caps().
393    *
394    * Returns: %TRUE if the stream changed bitrate, %FALSE otherwise
395    */
396   gboolean      (*stream_select_bitrate) (GstAdaptiveDemuxStream * stream, guint64 bitrate);
397   /**
398    * stream_get_fragment_waiting_time:
399    * @stream: #GstAdaptiveDemuxStream
400    *
401    * For live streams, requests how much time should be waited before starting
402    * to download the fragment. This is useful to avoid downloading a fragment that
403    * isn't available yet.
404    *
405    * Returns: The waiting time in microseconds
406    */
407   gint64        (*stream_get_fragment_waiting_time) (GstAdaptiveDemuxStream * stream);
408 
409   /**
410    * start_fragment:
411    * @demux: #GstAdaptiveDemux
412    * @stream: #GstAdaptiveDemuxStream
413    *
414    * Notifies the subclass that the given stream is starting the download
415    * of a new fragment. Can be used to reset/init internal state that is
416    * needed before each fragment, like decryption engines.
417    *
418    * Returns: %TRUE if successful.
419    */
420   gboolean      (*start_fragment) (GstAdaptiveDemux * demux, GstAdaptiveDemuxStream * stream);
421   /**
422    * finish_fragment:
423    * @demux: #GstAdaptiveDemux
424    * @stream: #GstAdaptiveDemuxStream
425    *
426    * Notifies the subclass that a fragment download was finished.
427    * It can be used to cleanup internal state after a fragment and
428    * also push any pending data before moving to the next fragment.
429    */
430   GstFlowReturn (*finish_fragment) (GstAdaptiveDemux * demux, GstAdaptiveDemuxStream * stream);
431   /**
432    * data_received:
433    * @demux: #GstAdaptiveDemux
434    * @stream: #GstAdaptiveDemuxStream
435    * @buffer: #GstBuffer
436    *
437    * Notifies the subclass that a fragment chunk was downloaded. The subclass
438    * can look at the data and modify/push data as desired.
439    *
440    * Returns: #GST_FLOW_OK if successful, #GST_FLOW_ERROR in case of error.
441    */
442   GstFlowReturn (*data_received) (GstAdaptiveDemux * demux, GstAdaptiveDemuxStream * stream, GstBuffer * buffer);
443 
444   /**
445    * get_live_seek_range:
446    * @demux: #GstAdaptiveDemux
447    * @start: pointer to put the start position allowed to seek to
448    * @stop: pointer to put the stop position allowed to seek to
449    *
450    * Gets the allowed seek start and stop positions for the current live stream
451    *
452    * Return: %TRUE if successful
453    */
454   gboolean (*get_live_seek_range) (GstAdaptiveDemux * demux, gint64 * start, gint64 * stop);
455 
456   /**
457    * get_presentation_offset:
458    * @demux: #GstAdaptiveDemux
459    * @stream: #GstAdaptiveDemuxStream
460    *
461    * Gets the delay to apply to @stream.
462    *
463    * Return: a #GstClockTime representing the (positive) time offset to apply to
464    * @stream.
465    */
466   GstClockTime (*get_presentation_offset) (GstAdaptiveDemux *demux, GstAdaptiveDemuxStream *stream);
467 
468   /**
469    * get_period_start_time:
470    * @demux: #GstAdaptiveDemux
471    *
472    * Gets the start time of the current period. Timestamps are resetting to 0
473    * after each period but we have to maintain a continuous stream and running
474    * time so need to know the start time of the current period.
475    *
476    * Return: a #GstClockTime representing the start time of the currently
477    * selected period.
478    */
479   GstClockTime (*get_period_start_time) (GstAdaptiveDemux *demux);
480 
481   /**
482    * requires_periodical_playlist_update:
483    * @demux: #GstAdaptiveDemux
484    *
485    * Some adaptive streaming protocols allow the client to download
486    * the playlist once and build up the fragment list based on the
487    * current fragment metadata. For those protocols the demuxer
488    * doesn't need to periodically refresh the playlist. This vfunc
489    * is relevant only for live playback scenarios.
490    *
491    * Return: %TRUE if the playlist needs to be refreshed periodically by the demuxer.
492    */
493   gboolean (*requires_periodical_playlist_update) (GstAdaptiveDemux * demux);
494 
495 #ifdef OHOS_EXT_FUNC
496   // ohos.ext.func.0028
497   gboolean (*get_bitrate_info) (GstAdaptiveDemux *demux, GstAdaptiveDemuxBitrateInfo * bitrate_info);
498 #endif
499 };
500 
501 GST_ADAPTIVE_DEMUX_API
502 GType    gst_adaptive_demux_get_type (void);
503 
504 GST_ADAPTIVE_DEMUX_API
505 void     gst_adaptive_demux_set_stream_struct_size (GstAdaptiveDemux * demux,
506                                                     gsize struct_size);
507 
508 
509 GST_ADAPTIVE_DEMUX_API
510 GstAdaptiveDemuxStream *gst_adaptive_demux_stream_new (GstAdaptiveDemux * demux,
511                                                        GstPad * pad);
512 
513 GST_ADAPTIVE_DEMUX_API
514 GstAdaptiveDemuxStream *gst_adaptive_demux_find_stream_for_pad (GstAdaptiveDemux * demux,
515                                                                 GstPad * pad);
516 
517 GST_ADAPTIVE_DEMUX_API
518 void gst_adaptive_demux_stream_set_caps (GstAdaptiveDemuxStream * stream,
519                                          GstCaps * caps);
520 
521 GST_ADAPTIVE_DEMUX_API
522 void gst_adaptive_demux_stream_set_tags (GstAdaptiveDemuxStream * stream,
523                                          GstTagList * tags);
524 
525 GST_ADAPTIVE_DEMUX_API
526 void gst_adaptive_demux_stream_fragment_clear (GstAdaptiveDemuxStreamFragment * f);
527 
528 GST_ADAPTIVE_DEMUX_API
529 GstFlowReturn gst_adaptive_demux_stream_push_buffer (GstAdaptiveDemuxStream * stream, GstBuffer * buffer);
530 
531 GST_ADAPTIVE_DEMUX_API
532 GstFlowReturn
533 gst_adaptive_demux_stream_advance_fragment (GstAdaptiveDemux * demux,
534     GstAdaptiveDemuxStream * stream, GstClockTime duration);
535 
536 GST_ADAPTIVE_DEMUX_API
537 void gst_adaptive_demux_stream_queue_event (GstAdaptiveDemuxStream * stream,
538     GstEvent * event);
539 
540 GST_ADAPTIVE_DEMUX_API
541 GstClockTime gst_adaptive_demux_get_monotonic_time (GstAdaptiveDemux * demux);
542 
543 GST_ADAPTIVE_DEMUX_API
544 GDateTime *gst_adaptive_demux_get_client_now_utc (GstAdaptiveDemux * demux);
545 
546 GST_ADAPTIVE_DEMUX_API
547 gboolean gst_adaptive_demux_is_running (GstAdaptiveDemux * demux);
548 
549 GST_ADAPTIVE_DEMUX_API
550 GstClockTime gst_adaptive_demux_get_qos_earliest_time (GstAdaptiveDemux *demux);
551 
552 G_END_DECLS
553 
554 #endif
555 
556