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