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 #ifdef OHOS_EXT_FUNC 209 // ohos.ext.func.0033 210 gint errcode; 211 #endif 212 }; 213 214 /** 215 * GstAdaptiveDemux: 216 * 217 * The opaque #GstAdaptiveDemux data structure. 218 */ 219 struct _GstAdaptiveDemux 220 { 221 /*< private >*/ 222 GstBin bin; 223 224 gint running; 225 226 gsize stream_struct_size; 227 228 /*< protected >*/ 229 GstPad *sinkpad; 230 231 GstUriDownloader *downloader; 232 233 GList *streams; 234 GList *prepared_streams; 235 GList *next_streams; 236 237 GstSegment segment; 238 239 gchar *manifest_uri; 240 gchar *manifest_base_uri; 241 242 /* Properties */ 243 gfloat bitrate_limit; /* limit of the available bitrate to use */ 244 guint connection_speed; 245 #ifdef OHOS_EXT_FUNC 246 // ohos.ext.func.0043 Clear data in the multiqueue to speed up switching bitrate 247 GstClockTime slice_position; 248 #endif 249 250 gboolean have_group_id; 251 guint group_id; 252 253 /* Realtime clock */ 254 GstClock *realtime_clock; 255 gint64 clock_offset; /* offset between realtime_clock and UTC (in usec) */ 256 257 /* < private > */ 258 GstAdaptiveDemuxPrivate *priv; 259 }; 260 261 /** 262 * GstAdaptiveDemuxClass: 263 * 264 */ 265 struct _GstAdaptiveDemuxClass 266 { 267 /*< private >*/ 268 GstBinClass bin_class; 269 270 /*< public >*/ 271 272 /** 273 * process_manifest: Parse the manifest 274 * @demux: #GstAdaptiveDemux 275 * @manifest: the manifest to be parsed 276 * 277 * Parse the manifest and add the created streams using 278 * gst_adaptive_demux_stream_new() 279 * 280 * Returns: %TRUE if successful 281 */ 282 gboolean (*process_manifest) (GstAdaptiveDemux * demux, GstBuffer * manifest); 283 284 /** 285 * get_manifest_update_interval: 286 * @demux: #GstAdaptiveDemux 287 * 288 * Used during live streaming, the subclass should return the interval 289 * between successive manifest updates 290 * 291 * Returns: the update interval in microseconds 292 */ 293 gint64 (*get_manifest_update_interval) (GstAdaptiveDemux * demux); 294 295 /** 296 * update_manifest: 297 * @demux: #GstAdaptiveDemux 298 * 299 * During live streaming, this will be called for the subclass to update its 300 * manifest with the new version. By default it fetches the manifest URI 301 * and passes it to GstAdaptiveDemux::update_manifest_data(). 302 * 303 * Returns: #GST_FLOW_OK is all succeeded, #GST_FLOW_EOS if the stream ended 304 * or #GST_FLOW_ERROR if an error happened 305 */ 306 GstFlowReturn (*update_manifest) (GstAdaptiveDemux * demux); 307 308 /** 309 * update_manifest_data: 310 * @demux: #GstAdaptiveDemux 311 * @buf: Downloaded manifest data 312 * 313 * During live streaming, this will be called for the subclass to update its 314 * manifest with the new version 315 * 316 * Returns: #GST_FLOW_OK is all succeeded, #GST_FLOW_EOS if the stream ended 317 * or #GST_FLOW_ERROR if an error happened 318 */ 319 GstFlowReturn (*update_manifest_data) (GstAdaptiveDemux * demux, GstBuffer * buf); 320 321 gboolean (*is_live) (GstAdaptiveDemux * demux); 322 GstClockTime (*get_duration) (GstAdaptiveDemux * demux); 323 324 /** 325 * reset: 326 * @demux: #GstAdaptiveDemux 327 * 328 * Reset the internal state of the subclass, getting ready to restart with 329 * a new stream afterwards 330 */ 331 void (*reset) (GstAdaptiveDemux * demux); 332 333 /** 334 * seek: 335 * @demux: #GstAdaptiveDemux 336 * @seek: a seek #GstEvent 337 * 338 * The demuxer should seek on all its streams to the specified position 339 * in the seek event 340 * 341 * Returns: %TRUE if successful 342 */ 343 gboolean (*seek) (GstAdaptiveDemux * demux, GstEvent * seek); 344 345 /** 346 * has_next_period: 347 * @demux: #GstAdaptiveDemux 348 * 349 * Checks if there is a next period following the current one. 350 * DASH can have multiple medias chained in its manifest, when one finishes 351 * this function is called to verify if there is a new period to be played 352 * in sequence. 353 * 354 * Returns: %TRUE if there is another period 355 */ 356 gboolean (*has_next_period) (GstAdaptiveDemux * demux); 357 /** 358 * advance_period: 359 * @demux: #GstAdaptiveDemux 360 * 361 * Advances the manifest to the next period. New streams should be created 362 * using gst_adaptive_demux_stream_new(). 363 */ 364 void (*advance_period) (GstAdaptiveDemux * demux); 365 366 void (*stream_free) (GstAdaptiveDemuxStream * stream); 367 GstFlowReturn (*stream_seek) (GstAdaptiveDemuxStream * stream, gboolean forward, GstSeekFlags flags, GstClockTime target_ts, GstClockTime * final_ts); 368 gboolean (*stream_has_next_fragment) (GstAdaptiveDemuxStream * stream); 369 GstFlowReturn (*stream_advance_fragment) (GstAdaptiveDemuxStream * stream); 370 371 /** 372 * need_another_chunk: 373 * @stream: #GstAdaptiveDemuxStream 374 * 375 * If chunked downloading is used (chunk_size != 0) this is called once a 376 * chunk is finished to decide whether more has to be downloaded or not. 377 * May update chunk_size to a different value 378 */ 379 gboolean (*need_another_chunk) (GstAdaptiveDemuxStream * stream); 380 381 /** 382 * stream_update_fragment_info: 383 * @stream: #GstAdaptiveDemuxStream 384 * 385 * Requests the stream to set the information about the current fragment to its 386 * current fragment struct 387 * 388 * Returns: #GST_FLOW_OK in success, #GST_FLOW_ERROR on error and #GST_FLOW_EOS 389 * if there is no fragment. 390 */ 391 GstFlowReturn (*stream_update_fragment_info) (GstAdaptiveDemuxStream * stream); 392 /** 393 * stream_select_bitrate: 394 * @stream: #GstAdaptiveDemuxStream 395 * @bitrate: the bitrate to select (in bytes per second) 396 * 397 * The stream should try to select the bitrate that is the greater, but not 398 * greater than the requested bitrate. If it needs a codec change it should 399 * create the new stream using gst_adaptive_demux_stream_new(). If it only 400 * needs a caps change it should set the new caps using 401 * gst_adaptive_demux_stream_set_caps(). 402 * 403 * Returns: %TRUE if the stream changed bitrate, %FALSE otherwise 404 */ 405 gboolean (*stream_select_bitrate) (GstAdaptiveDemuxStream * stream, guint64 bitrate); 406 /** 407 * stream_get_fragment_waiting_time: 408 * @stream: #GstAdaptiveDemuxStream 409 * 410 * For live streams, requests how much time should be waited before starting 411 * to download the fragment. This is useful to avoid downloading a fragment that 412 * isn't available yet. 413 * 414 * Returns: The waiting time in microseconds 415 */ 416 gint64 (*stream_get_fragment_waiting_time) (GstAdaptiveDemuxStream * stream); 417 418 #ifdef OHOS_EXT_FUNC 419 // ohos.ext.func.0042 report selectBitrateDone 420 gint (*get_current_bandwidth) (GstAdaptiveDemuxStream * stream); 421 guint64 (*get_current_position) (GstAdaptiveDemuxStream * stream); 422 #endif 423 424 /** 425 * start_fragment: 426 * @demux: #GstAdaptiveDemux 427 * @stream: #GstAdaptiveDemuxStream 428 * 429 * Notifies the subclass that the given stream is starting the download 430 * of a new fragment. Can be used to reset/init internal state that is 431 * needed before each fragment, like decryption engines. 432 * 433 * Returns: %TRUE if successful. 434 */ 435 gboolean (*start_fragment) (GstAdaptiveDemux * demux, GstAdaptiveDemuxStream * stream); 436 /** 437 * finish_fragment: 438 * @demux: #GstAdaptiveDemux 439 * @stream: #GstAdaptiveDemuxStream 440 * 441 * Notifies the subclass that a fragment download was finished. 442 * It can be used to cleanup internal state after a fragment and 443 * also push any pending data before moving to the next fragment. 444 */ 445 GstFlowReturn (*finish_fragment) (GstAdaptiveDemux * demux, GstAdaptiveDemuxStream * stream); 446 /** 447 * data_received: 448 * @demux: #GstAdaptiveDemux 449 * @stream: #GstAdaptiveDemuxStream 450 * @buffer: #GstBuffer 451 * 452 * Notifies the subclass that a fragment chunk was downloaded. The subclass 453 * can look at the data and modify/push data as desired. 454 * 455 * Returns: #GST_FLOW_OK if successful, #GST_FLOW_ERROR in case of error. 456 */ 457 GstFlowReturn (*data_received) (GstAdaptiveDemux * demux, GstAdaptiveDemuxStream * stream, GstBuffer * buffer); 458 459 /** 460 * get_live_seek_range: 461 * @demux: #GstAdaptiveDemux 462 * @start: pointer to put the start position allowed to seek to 463 * @stop: pointer to put the stop position allowed to seek to 464 * 465 * Gets the allowed seek start and stop positions for the current live stream 466 * 467 * Return: %TRUE if successful 468 */ 469 gboolean (*get_live_seek_range) (GstAdaptiveDemux * demux, gint64 * start, gint64 * stop); 470 471 /** 472 * get_presentation_offset: 473 * @demux: #GstAdaptiveDemux 474 * @stream: #GstAdaptiveDemuxStream 475 * 476 * Gets the delay to apply to @stream. 477 * 478 * Return: a #GstClockTime representing the (positive) time offset to apply to 479 * @stream. 480 */ 481 GstClockTime (*get_presentation_offset) (GstAdaptiveDemux *demux, GstAdaptiveDemuxStream *stream); 482 483 /** 484 * get_period_start_time: 485 * @demux: #GstAdaptiveDemux 486 * 487 * Gets the start time of the current period. Timestamps are resetting to 0 488 * after each period but we have to maintain a continuous stream and running 489 * time so need to know the start time of the current period. 490 * 491 * Return: a #GstClockTime representing the start time of the currently 492 * selected period. 493 */ 494 GstClockTime (*get_period_start_time) (GstAdaptiveDemux *demux); 495 496 /** 497 * requires_periodical_playlist_update: 498 * @demux: #GstAdaptiveDemux 499 * 500 * Some adaptive streaming protocols allow the client to download 501 * the playlist once and build up the fragment list based on the 502 * current fragment metadata. For those protocols the demuxer 503 * doesn't need to periodically refresh the playlist. This vfunc 504 * is relevant only for live playback scenarios. 505 * 506 * Return: %TRUE if the playlist needs to be refreshed periodically by the demuxer. 507 */ 508 gboolean (*requires_periodical_playlist_update) (GstAdaptiveDemux * demux); 509 510 #ifdef OHOS_EXT_FUNC 511 // ohos.ext.func.0028 512 gboolean (*get_bitrate_info) (GstAdaptiveDemux *demux, GstAdaptiveDemuxBitrateInfo * bitrate_info); 513 #endif 514 }; 515 516 GST_ADAPTIVE_DEMUX_API 517 GType gst_adaptive_demux_get_type (void); 518 519 GST_ADAPTIVE_DEMUX_API 520 void gst_adaptive_demux_set_stream_struct_size (GstAdaptiveDemux * demux, 521 gsize struct_size); 522 523 524 GST_ADAPTIVE_DEMUX_API 525 GstAdaptiveDemuxStream *gst_adaptive_demux_stream_new (GstAdaptiveDemux * demux, 526 GstPad * pad); 527 528 GST_ADAPTIVE_DEMUX_API 529 GstAdaptiveDemuxStream *gst_adaptive_demux_find_stream_for_pad (GstAdaptiveDemux * demux, 530 GstPad * pad); 531 532 GST_ADAPTIVE_DEMUX_API 533 void gst_adaptive_demux_stream_set_caps (GstAdaptiveDemuxStream * stream, 534 GstCaps * caps); 535 536 GST_ADAPTIVE_DEMUX_API 537 void gst_adaptive_demux_stream_set_tags (GstAdaptiveDemuxStream * stream, 538 GstTagList * tags); 539 540 GST_ADAPTIVE_DEMUX_API 541 void gst_adaptive_demux_stream_fragment_clear (GstAdaptiveDemuxStreamFragment * f); 542 543 GST_ADAPTIVE_DEMUX_API 544 GstFlowReturn gst_adaptive_demux_stream_push_buffer (GstAdaptiveDemuxStream * stream, GstBuffer * buffer); 545 546 GST_ADAPTIVE_DEMUX_API 547 GstFlowReturn 548 gst_adaptive_demux_stream_advance_fragment (GstAdaptiveDemux * demux, 549 GstAdaptiveDemuxStream * stream, GstClockTime duration); 550 551 GST_ADAPTIVE_DEMUX_API 552 void gst_adaptive_demux_stream_queue_event (GstAdaptiveDemuxStream * stream, 553 GstEvent * event); 554 555 GST_ADAPTIVE_DEMUX_API 556 GstClockTime gst_adaptive_demux_get_monotonic_time (GstAdaptiveDemux * demux); 557 558 GST_ADAPTIVE_DEMUX_API 559 GDateTime *gst_adaptive_demux_get_client_now_utc (GstAdaptiveDemux * demux); 560 561 GST_ADAPTIVE_DEMUX_API 562 gboolean gst_adaptive_demux_is_running (GstAdaptiveDemux * demux); 563 564 GST_ADAPTIVE_DEMUX_API 565 GstClockTime gst_adaptive_demux_get_qos_earliest_time (GstAdaptiveDemux *demux); 566 567 G_END_DECLS 568 569 #endif 570 571