FFmpeg
Loading...
Searching...
No Matches
imfdec.c
Go to the documentation of this file.
1/*
2 * This file is part of FFmpeg.
3 *
4 * FFmpeg is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * FFmpeg is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with FFmpeg; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18
19/*
20 *
21 * Copyright (c) Sandflow Consulting LLC
22 *
23 * Redistribution and use in source and binary forms, with or without
24 * modification, are permitted provided that the following conditions are met:
25 *
26 * * Redistributions of source code must retain the above copyright notice, this
27 * list of conditions and the following disclaimer.
28 * * Redistributions in binary form must reproduce the above copyright notice,
29 * this list of conditions and the following disclaimer in the documentation
30 * and/or other materials provided with the distribution.
31 *
32 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
33 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
34 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
35 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
36 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
37 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
38 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
39 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
40 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
41 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
42 * POSSIBILITY OF SUCH DAMAGE.
43 */
44
45/**
46 * Demuxes an IMF Composition
47 *
48 * References
49 * OV 2067-0:2018 - SMPTE Overview Document - Interoperable Master Format
50 * ST 2067-2:2020 - SMPTE Standard - Interoperable Master Format — Core Constraints
51 * ST 2067-3:2020 - SMPTE Standard - Interoperable Master Format — Composition Playlist
52 * ST 2067-5:2020 - SMPTE Standard - Interoperable Master Format — Essence Component
53 * ST 2067-20:2016 - SMPTE Standard - Interoperable Master Format — Application #2
54 * ST 2067-21:2020 - SMPTE Standard - Interoperable Master Format — Application #2 Extended
55 * ST 2067-102:2017 - SMPTE Standard - Interoperable Master Format — Common Image Pixel Color Schemes
56 * ST 429-9:2007 - SMPTE Standard - D-Cinema Packaging — Asset Mapping and File Segmentation
57 *
58 * @author Marc-Antoine Arnaud
59 * @author Valentin Noel
60 * @author Nicholas Vanderzwet
61 * @file
62 * @ingroup lavu_imf
63 */
64
65#include "avio_internal.h"
66#include "demux.h"
67#include "imf.h"
68#include "internal.h"
69#include "libavcodec/packet.h"
70#include "libavutil/avstring.h"
71#include "libavutil/bprint.h"
73#include "libavutil/mem.h"
74#include "libavutil/opt.h"
75#include <inttypes.h>
76#include <libxml/parser.h>
77
78#define AVRATIONAL_FORMAT "%d/%d"
79#define AVRATIONAL_ARG(rational) rational.num, rational.den
80
81/**
82 * IMF Asset locator
83 */
88
89/**
90 * IMF Asset locator map
91 * Results from the parsing of one or more ASSETMAP XML files
92 */
97
99 IMFAssetLocator *locator; /**< Location of the resource */
100 FFIMFTrackFileResource *resource; /**< Underlying IMF CPL resource */
101 AVFormatContext *ctx; /**< Context associated with the resource */
102 AVRational start_time; /**< inclusive start time of the resource on the CPL timeline (s) */
103 AVRational end_time; /**< exclusive end time of the resource on the CPL timeline (s) */
104 AVRational ts_offset; /**< start_time minus the entry point into the resource (s) */
106
108 int32_t index; /**< Track index in playlist */
109 AVRational current_timestamp; /**< Current temporal position */
110 AVRational duration; /**< Overall duration */
111 uint32_t resource_count; /**< Number of resources (<= INT32_MAX) */
112 unsigned int resources_alloc_sz; /**< Size of the buffer holding the resource */
113 IMFVirtualTrackResourcePlaybackCtx *resources; /**< Buffer holding the resources */
114 int32_t current_resource_index; /**< Index of the current resource in resources,
115 or < 0 if a current resource has yet to be selected */
117
129
130static int imf_uri_is_url(const char *string)
131{
132 return strstr(string, "://") != NULL;
133}
134
135static int imf_uri_is_unix_abs_path(const char *string)
136{
137 return string[0] == '/';
138}
139
140static int imf_uri_is_dos_abs_path(const char *string)
141{
142 /* Absolute path case: `C:\path\to\somewhere` */
143 if (string[1] == ':' && string[2] == '\\')
144 return 1;
145
146 /* Absolute path case: `C:/path/to/somewhere` */
147 if (string[1] == ':' && string[2] == '/')
148 return 1;
149
150 /* Network path case: `\\path\to\somewhere` */
151 if (string[0] == '\\' && string[1] == '\\')
152 return 1;
153
154 return 0;
155}
156
157static int imf_time_to_ts(int64_t *ts, AVRational t, AVRational time_base)
158{
159 int dst_num;
160 int dst_den;
162
163 r = av_div_q(t, time_base);
164
165 if ((av_reduce(&dst_num, &dst_den, r.num, r.den, INT64_MAX) != 1))
166 return 1;
167
168 if (dst_den != 1)
169 return 1;
170
171 *ts = dst_num;
172
173 return 0;
174}
175
176/**
177 * Parse a ASSETMAP XML file to extract the UUID-URI mapping of assets.
178 * @param s the current format context, if any (can be NULL).
179 * @param doc the XML document to be parsed.
180 * @param asset_map pointer on the IMFAssetLocatorMap to fill.
181 * @param base_url the url of the asset map XML file, if any (can be NULL).
182 * @return a negative value in case of error, 0 otherwise.
183 */
185 xmlDocPtr doc,
186 IMFAssetLocatorMap *asset_map,
187 const char *base_url)
188{
189 xmlNodePtr asset_map_element = NULL;
190 xmlNodePtr node = NULL;
191 xmlNodePtr asset_element = NULL;
192 unsigned long elem_count;
193 char *uri;
194 int ret = 0;
195 IMFAssetLocator *asset = NULL;
196 void *tmp;
197
198 asset_map_element = xmlDocGetRootElement(doc);
199
200 if (!asset_map_element) {
201 av_log(s, AV_LOG_ERROR, "Unable to parse asset map XML - missing root node\n");
202 return AVERROR_INVALIDDATA;
203 }
204
205 if (asset_map_element->type != XML_ELEMENT_NODE || av_strcasecmp(asset_map_element->name, "AssetMap")) {
206 av_log(s, AV_LOG_ERROR, "Unable to parse asset map XML - wrong root node name[%s] type[%d]\n",
207 asset_map_element->name, (int)asset_map_element->type);
208 return AVERROR_INVALIDDATA;
209 }
210
211 /* parse asset locators */
212 if (!(node = ff_imf_xml_get_child_element_by_name(asset_map_element, "AssetList"))) {
213 av_log(s, AV_LOG_ERROR, "Unable to parse asset map XML - missing AssetList node\n");
214 return AVERROR_INVALIDDATA;
215 }
216 elem_count = xmlChildElementCount(node);
217 if (elem_count > UINT32_MAX
218 || asset_map->asset_count > UINT32_MAX - elem_count)
219 return AVERROR(ENOMEM);
220 tmp = av_realloc_array(asset_map->assets,
221 elem_count + asset_map->asset_count,
222 sizeof(IMFAssetLocator));
223 if (!tmp) {
224 av_log(s, AV_LOG_ERROR, "Cannot allocate IMF asset locators\n");
225 return AVERROR(ENOMEM);
226 }
227 asset_map->assets = tmp;
228
229 asset_element = xmlFirstElementChild(node);
230 while (asset_element) {
231 if (av_strcasecmp(asset_element->name, "Asset") != 0)
232 continue;
233
234 asset = &(asset_map->assets[asset_map->asset_count]);
235
236 if (!(node = ff_imf_xml_get_child_element_by_name(asset_element, "Id"))) {
237 av_log(s, AV_LOG_ERROR, "Unable to parse asset map XML - missing Id node\n");
238 return AVERROR_INVALIDDATA;
239 }
240
241 if (ff_imf_xml_read_uuid(node, asset->uuid)) {
242 av_log(s, AV_LOG_ERROR, "Could not parse UUID from asset in asset map.\n");
243 return AVERROR_INVALIDDATA;
244 }
245
246 av_log(s, AV_LOG_DEBUG, "Found asset id: " AV_PRI_URN_UUID "\n", AV_UUID_ARG(asset->uuid));
247
248 if (!(node = ff_imf_xml_get_child_element_by_name(asset_element, "ChunkList"))) {
249 av_log(s, AV_LOG_ERROR, "Unable to parse asset map XML - missing ChunkList node\n");
250 return AVERROR_INVALIDDATA;
251 }
252
253 if (!(node = ff_imf_xml_get_child_element_by_name(node, "Chunk"))) {
254 av_log(s, AV_LOG_ERROR, "Unable to parse asset map XML - missing Chunk node\n");
255 return AVERROR_INVALIDDATA;
256 }
257
258 xmlNodePtr path_node = ff_imf_xml_get_child_element_by_name(node, "Path");
259 if (!path_node) {
260 av_log(s, AV_LOG_ERROR, "Unable to parse asset map XML - missing Path element in Chunk\n");
262 break;
263 }
264 uri = xmlNodeGetContent(path_node);
265 if (!uri || !uri[0]) {
266 av_log(s, AV_LOG_ERROR, "Unable to parse asset map XML - empty Path element in Chunk\n");
267 xmlFree(uri);
269 break;
270 }
271
273 asset->absolute_uri = av_append_path_component(base_url, uri);
274 else
275 asset->absolute_uri = av_strdup(uri);
276 xmlFree(uri);
277 if (!asset->absolute_uri)
278 return AVERROR(ENOMEM);
279
280 av_log(s, AV_LOG_DEBUG, "Found asset absolute URI: %s\n", asset->absolute_uri);
281
282 asset_map->asset_count++;
283 asset_element = xmlNextElementSibling(asset_element);
284 }
285
286 return ret;
287}
288
289/**
290 * Initializes an IMFAssetLocatorMap structure.
291 */
293{
294 asset_map->assets = NULL;
295 asset_map->asset_count = 0;
296}
297
298/**
299 * Free a IMFAssetLocatorMap pointer.
300 */
302{
303 for (uint32_t i = 0; i < asset_map->asset_count; i++)
304 av_freep(&asset_map->assets[i].absolute_uri);
305
306 av_freep(&asset_map->assets);
307}
308
309static int parse_assetmap(AVFormatContext *s, const char *url)
310{
311 IMFContext *c = s->priv_data;
312 AVIOContext *in = NULL;
313 struct AVBPrint buf;
315 xmlDoc *doc = NULL;
316 const char *base_url;
317 char *tmp_str = NULL;
318 int ret;
319
320 av_log(s, AV_LOG_DEBUG, "Asset Map URL: %s\n", url);
321
322 av_dict_copy(&opts, c->avio_opts, 0);
323 ret = s->io_open(s, &in, url, AVIO_FLAG_READ, &opts);
325 if (ret < 0)
326 return ret;
327
328 av_bprint_init(&buf, 0, INT_MAX); // xmlReadMemory uses integer length
329
330 ret = avio_read_to_bprint(in, &buf, SIZE_MAX);
331 if (ret < 0 || !avio_feof(in)) {
332 av_log(s, AV_LOG_ERROR, "Unable to read to asset map '%s'\n", url);
333 if (ret == 0)
335 goto clean_up;
336 }
337
338 LIBXML_TEST_VERSION
339
340 tmp_str = av_strdup(url);
341 if (!tmp_str) {
342 ret = AVERROR(ENOMEM);
343 goto clean_up;
344 }
345 base_url = av_dirname(tmp_str);
346
347 doc = xmlReadMemory(buf.str, buf.len, url, NULL, 0);
348
349 ret = parse_imf_asset_map_from_xml_dom(s, doc, &c->asset_locator_map, base_url);
350 if (!ret)
351 av_log(s, AV_LOG_DEBUG, "Found %d assets from %s\n",
352 c->asset_locator_map.asset_count, url);
353
354 xmlFreeDoc(doc);
355
356clean_up:
357 if (tmp_str)
358 av_freep(&tmp_str);
359 ff_format_io_close(s, &in);
361 return ret;
362}
363
365{
366 for (uint32_t i = 0; i < asset_map->asset_count; i++) {
367 if (memcmp(asset_map->assets[i].uuid, uuid, 16) == 0)
368 return &(asset_map->assets[i]);
369 }
370 return NULL;
371}
372
375 int32_t resource_index)
376{
377 IMFContext *c = s->priv_data;
378 int ret = 0;
379 int64_t seek_offset = 0;
381 AVStream *st;
382 IMFVirtualTrackResourcePlaybackCtx *track_resource = track->resources + resource_index;
383
384 if (track_resource->ctx) {
385 av_log(s, AV_LOG_DEBUG, "Input context already opened for %s.\n",
386 track_resource->locator->absolute_uri);
387 return 0;
388 }
389
390 track_resource->ctx = avformat_alloc_context();
391 if (!track_resource->ctx)
392 return AVERROR(ENOMEM);
393
394 track_resource->ctx->io_open = s->io_open;
395 track_resource->ctx->io_close2 = s->io_close2;
396 track_resource->ctx->opaque = s->opaque;
397 track_resource->ctx->flags |= s->flags & ~AVFMT_FLAG_CUSTOM_IO;
398
399 if ((ret = ff_copy_whiteblacklists(track_resource->ctx, s)) < 0)
400 goto cleanup;
401
402 if ((ret = av_opt_set(track_resource->ctx, "format_whitelist", "mxf", 0)))
403 goto cleanup;
404
405 if ((ret = av_dict_copy(&opts, c->avio_opts, 0)) < 0)
406 goto cleanup;
407
408 ret = avformat_open_input(&track_resource->ctx,
409 track_resource->locator->absolute_uri,
410 NULL,
411 &opts);
412 if (ret < 0) {
413 av_log(s, AV_LOG_ERROR, "Could not open %s input context: %s\n",
414 track_resource->locator->absolute_uri, av_err2str(ret));
415 goto cleanup;
416 }
418
419 /* make sure there is only one stream in the file */
420
421 if (track_resource->ctx->nb_streams != 1) {
423 goto cleanup;
424 }
425
426 st = track_resource->ctx->streams[0];
427
428 /* Determine the seek offset into the Track File, taking into account:
429 * - the current timestamp within the virtual track
430 * - the entry point of the resource
431 */
432 if (imf_time_to_ts(&seek_offset,
433 av_sub_q(track->current_timestamp, track_resource->ts_offset),
434 st->time_base))
435 av_log(s, AV_LOG_WARNING, "Incoherent stream timebase " AVRATIONAL_FORMAT
436 "and composition timeline position: " AVRATIONAL_FORMAT "\n",
438
439 if (seek_offset) {
440 av_log(s, AV_LOG_DEBUG, "Seek at resource %s entry point: %" PRIi64 "\n",
441 track_resource->locator->absolute_uri, seek_offset);
442 ret = avformat_seek_file(track_resource->ctx, 0, seek_offset, seek_offset, seek_offset, 0);
443 if (ret < 0) {
444 av_log(s,
446 "Could not seek at %" PRId64 "on %s: %s\n",
447 seek_offset,
448 track_resource->locator->absolute_uri,
449 av_err2str(ret));
450 avformat_close_input(&track_resource->ctx);
451 return ret;
452 }
453 }
454
455 return 0;
456
457cleanup:
459 avformat_free_context(track_resource->ctx);
460 track_resource->ctx = NULL;
461 return ret;
462}
463
465 FFIMFTrackFileResource *track_file_resource,
467{
468 IMFContext *c = s->priv_data;
469 IMFAssetLocator *asset_locator;
470 void *tmp;
471
472 asset_locator = find_asset_map_locator(&c->asset_locator_map, track_file_resource->track_file_uuid);
473 if (!asset_locator) {
474 av_log(s, AV_LOG_ERROR, "Could not find asset locator for UUID: " AV_PRI_URN_UUID "\n",
475 AV_UUID_ARG(track_file_resource->track_file_uuid));
476 return AVERROR_INVALIDDATA;
477 }
478
479 av_log(s,
481 "Found locator for " AV_PRI_URN_UUID ": %s\n",
482 AV_UUID_ARG(asset_locator->uuid),
483 asset_locator->absolute_uri);
484
485 if (track->resource_count > INT32_MAX - track_file_resource->base.repeat_count
486 || (track->resource_count + track_file_resource->base.repeat_count)
487 > INT_MAX / sizeof(IMFVirtualTrackResourcePlaybackCtx))
488 return AVERROR(ENOMEM);
490 &track->resources_alloc_sz,
491 (track->resource_count + track_file_resource->base.repeat_count)
493 if (!tmp)
494 return AVERROR(ENOMEM);
495 track->resources = tmp;
496
497 for (uint32_t i = 0; i < track_file_resource->base.repeat_count; i++) {
499
500 vt_ctx.locator = asset_locator;
501 vt_ctx.resource = track_file_resource;
502 vt_ctx.ctx = NULL;
503 vt_ctx.start_time = track->duration;
504 vt_ctx.ts_offset = av_sub_q(vt_ctx.start_time,
505 av_div_q(av_make_q((int)track_file_resource->base.entry_point, 1),
506 track_file_resource->base.edit_rate));
507 vt_ctx.end_time = av_add_q(track->duration,
508 av_make_q((int)track_file_resource->base.duration
509 * track_file_resource->base.edit_rate.den,
510 track_file_resource->base.edit_rate.num));
511 track->resources[track->resource_count++] = vt_ctx;
512 track->duration = vt_ctx.end_time;
513 }
514
515 return 0;
516}
517
519{
520 for (uint32_t i = 0; i < track->resource_count; i++)
522
523 av_freep(&track->resources);
524}
525
527 FFIMFTrackFileVirtualTrack *virtual_track,
529{
530 IMFContext *c = s->priv_data;
532 void *tmp;
533 int ret = 0;
534
535 if (!(track = av_mallocz(sizeof(IMFVirtualTrackPlaybackCtx))))
536 return AVERROR(ENOMEM);
537 track->current_resource_index = -1;
538 track->index = track_index;
539 track->duration = av_make_q(0, 1);
540
541 if (!virtual_track->resource_count) {
542 av_log(s, AV_LOG_ERROR, "Virtual track has no resources\n");
544 goto clean_up;
545 }
546
547 for (uint32_t i = 0; i < virtual_track->resource_count; i++) {
548 av_log(s,
550 "Open stream from file " AV_PRI_URN_UUID ", stream %d\n",
551 AV_UUID_ARG(virtual_track->resources[i].track_file_uuid),
552 i);
553 if ((ret = open_track_file_resource(s, &virtual_track->resources[i], track)) != 0) {
554 av_log(s,
556 "Could not open image track resource " AV_PRI_URN_UUID "\n",
557 AV_UUID_ARG(virtual_track->resources[i].track_file_uuid));
558 goto clean_up;
559 }
560 }
561
562 track->current_timestamp = av_make_q(0, track->duration.den);
563
564 if (c->track_count == UINT32_MAX) {
565 ret = AVERROR(ENOMEM);
566 goto clean_up;
567 }
568 tmp = av_realloc_array(c->tracks, c->track_count + 1, sizeof(IMFVirtualTrackPlaybackCtx *));
569 if (!tmp) {
570 ret = AVERROR(ENOMEM);
571 goto clean_up;
572 }
573 c->tracks = tmp;
574 c->tracks[c->track_count++] = track;
575
576 return 0;
577
578clean_up:
580 av_free(track);
581 return ret;
582}
583
585{
586 IMFContext *c = s->priv_data;
587 int ret = 0;
588
589 for (uint32_t i = 0; i < c->track_count; i++) {
590 AVStream *asset_stream;
591 AVStream *first_resource_stream;
592
593 /* Open the first resource of the track to get stream information */
594 ret = open_track_resource_context(s, c->tracks[i], 0);
595 if (ret)
596 return ret;
597 first_resource_stream = c->tracks[i]->resources[0].ctx->streams[0];
598 av_log(s, AV_LOG_DEBUG, "Open the first resource of track %d\n", c->tracks[i]->index);
599
600 asset_stream = ff_stream_clone(s, first_resource_stream);
601 if (!asset_stream) {
602 av_log(s, AV_LOG_ERROR, "Could not clone stream\n");
603 return AVERROR(ENOMEM);
604 }
605
606 asset_stream->id = i;
607 asset_stream->nb_frames = 0;
608 avpriv_set_pts_info(asset_stream,
609 first_resource_stream->pts_wrap_bits,
610 first_resource_stream->time_base.num,
611 first_resource_stream->time_base.den);
612 asset_stream->duration = (int64_t)av_q2d(av_mul_q(c->tracks[i]->duration,
613 av_inv_q(asset_stream->time_base)));
614 }
615
616 return 0;
617}
618
620{
621 IMFContext *c = s->priv_data;
623 int ret;
624
625 if (c->cpl->main_image_2d_track) {
626 if ((ret = open_virtual_track(s, c->cpl->main_image_2d_track, track_index++)) != 0) {
627 av_log(s, AV_LOG_ERROR, "Could not open image track " AV_PRI_URN_UUID "\n",
628 AV_UUID_ARG(c->cpl->main_image_2d_track->base.id_uuid));
629 return ret;
630 }
631 }
632
633 for (uint32_t i = 0; i < c->cpl->main_audio_track_count; i++) {
634 if ((ret = open_virtual_track(s, &c->cpl->main_audio_tracks[i], track_index++)) != 0) {
635 av_log(s, AV_LOG_ERROR, "Could not open audio track " AV_PRI_URN_UUID "\n",
636 AV_UUID_ARG(c->cpl->main_audio_tracks[i].base.id_uuid));
637 return ret;
638 }
639 }
640
642}
643
645{
646 IMFContext *c = s->priv_data;
647 char *asset_map_path;
648 char *tmp_str;
650 char tc_buf[AV_TIMECODE_STR_SIZE];
651 int ret = 0;
652
653 c->interrupt_callback = &s->interrupt_callback;
654 tmp_str = av_strdup(s->url);
655 if (!tmp_str)
656 return AVERROR(ENOMEM);
657 c->base_url = av_strdup(av_dirname(tmp_str));
658 av_freep(&tmp_str);
659 if (!c->base_url)
660 return AVERROR(ENOMEM);
661
662 if ((ret = ffio_copy_url_options(s->pb, &c->avio_opts)) < 0)
663 return ret;
664
665 av_log(s, AV_LOG_DEBUG, "start parsing IMF CPL: %s\n", s->url);
666
667 if ((ret = ff_imf_parse_cpl(s, s->pb, &c->cpl)) < 0)
668 return ret;
669
670 tcr = av_dict_get(s->metadata, "timecode", NULL, 0);
671 if (!tcr && c->cpl->tc) {
672 ret = av_dict_set(&s->metadata, "timecode",
673 av_timecode_make_string(c->cpl->tc, tc_buf, 0), 0);
674 if (ret)
675 return ret;
676 av_log(s, AV_LOG_INFO, "Setting timecode to IMF CPL timecode %s\n", tc_buf);
677 }
678
679 av_log(s,
681 "parsed IMF CPL: " AV_PRI_URN_UUID "\n",
682 AV_UUID_ARG(c->cpl->id_uuid));
683
684 if (!c->asset_map_paths) {
685 c->asset_map_paths = av_append_path_component(c->base_url, "ASSETMAP.xml");
686 if (!c->asset_map_paths) {
687 ret = AVERROR(ENOMEM);
688 return ret;
689 }
690 av_log(s, AV_LOG_DEBUG, "No asset maps provided, using the default ASSETMAP.xml\n");
691 }
692
693 /* Parse each asset map XML file */
694 imf_asset_locator_map_init(&c->asset_locator_map);
695 asset_map_path = av_strtok(c->asset_map_paths, ",", &tmp_str);
696 while (asset_map_path != NULL) {
697 av_log(s, AV_LOG_DEBUG, "start parsing IMF Asset Map: %s\n", asset_map_path);
698
699 if ((ret = parse_assetmap(s, asset_map_path)))
700 return ret;
701
702 asset_map_path = av_strtok(NULL, ",", &tmp_str);
703 }
704
705 av_log(s, AV_LOG_DEBUG, "parsed IMF Asset Maps\n");
706
707 if ((ret = open_cpl_tracks(s)))
708 return ret;
709
710 av_log(s, AV_LOG_DEBUG, "parsed IMF package\n");
711
712 return 0;
713}
714
716{
717 IMFContext *c = s->priv_data;
719 AVRational minimum_timestamp = av_make_q(INT32_MAX, 1);
720
721 for (uint32_t i = c->track_count; i > 0; i--) {
722 av_log(s, AV_LOG_TRACE, "Compare track %d timestamp " AVRATIONAL_FORMAT
723 " to minimum " AVRATIONAL_FORMAT
724 " (over duration: " AVRATIONAL_FORMAT ")\n", i,
725 AVRATIONAL_ARG(c->tracks[i - 1]->current_timestamp),
726 AVRATIONAL_ARG(minimum_timestamp),
727 AVRATIONAL_ARG(c->tracks[i - 1]->duration));
728
729 if (av_cmp_q(c->tracks[i - 1]->current_timestamp, minimum_timestamp) <= 0) {
730 track = c->tracks[i - 1];
731 minimum_timestamp = track->current_timestamp;
732 }
733 }
734
735 return track;
736}
737
739{
740 *resource = NULL;
741
742 if (av_cmp_q(track->current_timestamp, track->duration) >= 0) {
743 av_log(s, AV_LOG_DEBUG, "Reached the end of the virtual track\n");
744 return AVERROR_EOF;
745 }
746
747 av_log(s,
749 "Looking for track %d resource for timestamp = %lf / %lf\n",
750 track->index,
752 av_q2d(track->duration));
753 for (uint32_t i = 0; i < track->resource_count; i++) {
754
755 if (av_cmp_q(track->resources[i].end_time, track->current_timestamp) > 0) {
756 av_log(s, AV_LOG_DEBUG, "Found resource %d in track %d to read at timestamp %lf: "
757 "entry=%" PRIu32 ", duration=%" PRIu32 ", editrate=" AVRATIONAL_FORMAT "\n",
758 i, track->index, av_q2d(track->current_timestamp),
762
763 if (track->current_resource_index != i) {
764 int ret;
765
766 av_log(s, AV_LOG_TRACE, "Switch resource on track %d: re-open context\n",
767 track->index);
768
769 ret = open_track_resource_context(s, track, i);
770 if (ret != 0)
771 return ret;
772 if (track->current_resource_index > 0)
774 track->current_resource_index = i;
775 }
776
777 *resource = track->resources + track->current_resource_index;
778 return 0;
779 }
780 }
781
782 av_log(s, AV_LOG_ERROR, "Could not find IMF track resource to read\n");
784}
785
787{
789 int ret = 0;
791 int64_t delta_ts;
792 AVStream *st;
793 AVRational next_timestamp;
794
796
797 if (!track) {
798 av_log(s, AV_LOG_ERROR, "No track found for playback\n");
799 return AVERROR_INVALIDDATA;
800 }
801
802 av_log(s, AV_LOG_DEBUG, "Found track %d to read at timestamp %lf\n",
803 track->index, av_q2d(track->current_timestamp));
804
805 ret = get_resource_context_for_timestamp(s, track, &resource);
806 if (ret)
807 return ret;
808
809 ret = av_read_frame(resource->ctx, pkt);
810 if (ret)
811 return ret;
812
813 av_log(s, AV_LOG_DEBUG, "Got packet: pts=%" PRId64 ", dts=%" PRId64
814 ", duration=%" PRId64 ", stream_index=%d, pos=%" PRId64
815 ", time_base=" AVRATIONAL_FORMAT "\n", pkt->pts, pkt->dts, pkt->duration,
816 pkt->stream_index, pkt->pos, AVRATIONAL_ARG(pkt->time_base));
817
818 /* IMF resources contain only one stream */
819
820 if (pkt->stream_index != 0)
821 return AVERROR_INVALIDDATA;
822 st = resource->ctx->streams[0];
823
824 pkt->stream_index = track->index;
825
826 /* adjust the packet PTS and DTS based on the temporal position of the resource within the timeline */
827
828 ret = imf_time_to_ts(&delta_ts, resource->ts_offset, st->time_base);
829
830 if (!ret) {
831 if (pkt->pts != AV_NOPTS_VALUE)
832 pkt->pts += delta_ts;
833 if (pkt->dts != AV_NOPTS_VALUE)
834 pkt->dts += delta_ts;
835 } else {
836 av_log(s, AV_LOG_WARNING, "Incoherent time stamp " AVRATIONAL_FORMAT
837 " for time base " AVRATIONAL_FORMAT,
838 AVRATIONAL_ARG(resource->ts_offset),
839 AVRATIONAL_ARG(pkt->time_base));
840 }
841
842 /* advance the track timestamp by the packet duration */
843
844 next_timestamp = av_add_q(track->current_timestamp,
845 av_mul_q(av_make_q((int)pkt->duration, 1), st->time_base));
846
847 /* if necessary, clamp the next timestamp to the end of the current resource */
848
849 if (av_cmp_q(next_timestamp, resource->end_time) > 0) {
850
851 int64_t new_pkt_dur;
852
853 /* shrink the packet duration */
854
855 ret = imf_time_to_ts(&new_pkt_dur,
856 av_sub_q(resource->end_time, track->current_timestamp),
857 st->time_base);
858
859 if (!ret)
860 pkt->duration = new_pkt_dur;
861 else
862 av_log(s, AV_LOG_WARNING, "Incoherent time base in packet duration calculation\n");
863
864 /* shrink the packet itself for audio essence */
865
867
869 /* AV_CODEC_ID_PCM_S24LE is the only PCM format supported in IMF */
870 /* in this case, explicitly shrink the packet */
871
872 int bytes_per_sample = av_get_exact_bits_per_sample(st->codecpar->codec_id) >> 3;
873 int64_t nbsamples = av_rescale_q(pkt->duration,
874 st->time_base,
876 av_shrink_packet(pkt, nbsamples * st->codecpar->ch_layout.nb_channels * bytes_per_sample);
877
878 } else {
879 /* in all other cases, use side data to skip samples */
880 int64_t skip_samples;
881
882 ret = imf_time_to_ts(&skip_samples,
883 av_sub_q(next_timestamp, resource->end_time),
885
886 if (ret || skip_samples < 0 || skip_samples > UINT32_MAX) {
887 av_log(s, AV_LOG_WARNING, "Cannot skip audio samples\n");
888 } else {
889 uint8_t *side_data = av_packet_new_side_data(pkt, AV_PKT_DATA_SKIP_SAMPLES, 10);
890 if (!side_data)
891 return AVERROR(ENOMEM);
892
893 AV_WL32(side_data + 4, skip_samples); /* skip from end of this packet */
894 side_data[6] = 1; /* reason for end is convergence */
895 }
896 }
897
898 next_timestamp = resource->end_time;
899
900 } else {
901 av_log(s, AV_LOG_WARNING, "Non-audio packet duration reduced\n");
902 }
903 }
904
905 track->current_timestamp = next_timestamp;
906
907 return 0;
908}
909
911{
912 IMFContext *c = s->priv_data;
913
914 av_log(s, AV_LOG_DEBUG, "Close IMF package\n");
915 av_dict_free(&c->avio_opts);
916 av_freep(&c->base_url);
917 imf_asset_locator_map_deinit(&c->asset_locator_map);
918 ff_imf_cpl_free(c->cpl);
919
920 for (uint32_t i = 0; i < c->track_count; i++) {
922 av_freep(&c->tracks[i]);
923 }
924
925 av_freep(&c->tracks);
926
927 return 0;
928}
929
930static int imf_probe(const AVProbeData *p)
931{
932 if (!strstr(p->buf, "<CompositionPlaylist"))
933 return 0;
934
935 /* check for a ContentTitle element without including ContentTitleText,
936 * which is used by the D-Cinema CPL.
937 */
938 if (!strstr(p->buf, "ContentTitle>"))
939 return 0;
940
941 return AVPROBE_SCORE_MAX;
942}
943
944static int coherent_ts(int64_t ts, AVRational in_tb, AVRational out_tb)
945{
946 int dst_num;
947 int dst_den;
948 int ret;
949
950 ret = av_reduce(&dst_num, &dst_den, ts * in_tb.num * out_tb.den,
951 in_tb.den * out_tb.num, INT64_MAX);
952 if (!ret || dst_den != 1)
953 return 0;
954
955 return 1;
956}
957
958static int imf_seek(AVFormatContext *s, int stream_index, int64_t min_ts,
959 int64_t ts, int64_t max_ts, int flags)
960{
961 IMFContext *c = s->priv_data;
962 uint32_t i;
963
965 return AVERROR(ENOSYS);
966
967 /* rescale timestamps to Composition edit units */
968 if (stream_index < 0)
970 av_make_q(c->cpl->edit_rate.den, c->cpl->edit_rate.num),
971 &min_ts, &ts, &max_ts);
972 else
973 ff_rescale_interval(s->streams[stream_index]->time_base,
974 av_make_q(c->cpl->edit_rate.den, c->cpl->edit_rate.num),
975 &min_ts, &ts, &max_ts);
976
977 /* requested timestamp bounds are too close */
978 if (max_ts < min_ts)
979 return -1;
980
981 /* clamp requested timestamp to provided bounds */
982 ts = FFMAX(FFMIN(ts, max_ts), min_ts);
983
984 av_log(s, AV_LOG_DEBUG, "Seeking to Composition Playlist edit unit %" PRIi64 "\n", ts);
985
986 /* set the dts of each stream and temporal offset of each track */
987 for (i = 0; i < c->track_count; i++) {
988 AVStream *st = s->streams[i];
989 IMFVirtualTrackPlaybackCtx *t = c->tracks[i];
990 int64_t dts;
991
992 if (!coherent_ts(ts, av_make_q(c->cpl->edit_rate.den, c->cpl->edit_rate.num),
993 st->time_base))
994 av_log(s, AV_LOG_WARNING, "Seek position is not coherent across tracks\n");
995
996 dts = av_rescale(ts,
997 st->time_base.den * c->cpl->edit_rate.den,
998 st->time_base.num * c->cpl->edit_rate.num);
999
1000 av_log(s, AV_LOG_DEBUG, "Seeking to dts=%" PRId64 " on stream_index=%d\n",
1001 dts, i);
1002
1003 t->current_timestamp = av_mul_q(av_make_q(dts, 1), st->time_base);
1004 if (t->current_resource_index >= 0) {
1006 t->current_resource_index = -1;
1007 }
1008 }
1009
1010 return 0;
1011}
1012
1013static const AVOption imf_options[] = {
1014 {
1015 .name = "assetmaps",
1016 .help = "Comma-separated paths to ASSETMAP files."
1017 "If not specified, the `ASSETMAP.xml` file in the same "
1018 "directory as the CPL is used.",
1019 .offset = offsetof(IMFContext, asset_map_paths),
1020 .type = AV_OPT_TYPE_STRING,
1021 .default_val = {.str = NULL},
1023 },
1024 {NULL},
1025};
1026
1027static const AVClass imf_class = {
1028 .class_name = "imf",
1029 .item_name = av_default_item_name,
1030 .option = imf_options,
1031 .version = LIBAVUTIL_VERSION_INT,
1032};
1033
1035 .p.name = "imf",
1036 .p.long_name = NULL_IF_CONFIG_SMALL("IMF (Interoperable Master Format)"),
1037 .p.flags = AVFMT_NO_BYTE_SEEK,
1038 .p.priv_class = &imf_class,
1039 .flags_internal = FF_INFMT_FLAG_INIT_CLEANUP,
1040 .priv_data_size = sizeof(IMFContext),
1045 .read_seek2 = imf_seek,
1046};
const FFInputFormat ff_imf_demuxer
Definition imfdec.c:1034
static AVDictionary * opts
int32_t
int ff_format_io_close(AVFormatContext *s, AVIOContext **pb)
Definition avformat.c:961
int ff_copy_whiteblacklists(AVFormatContext *dst, const AVFormatContext *src)
Copies the whilelists from one context to the other.
Definition avformat.c:879
void avpriv_set_pts_info(AVStream *st, int pts_wrap_bits, unsigned int pts_num, unsigned int pts_den)
Set the time base and wrapping info for a given stream.
Definition avformat.c:834
AVStream * ff_stream_clone(AVFormatContext *dst_ctx, const AVStream *src)
Create a new stream and copy to it all parameters from a source stream, with the exception of the ind...
Definition avformat.c:251
#define AVPROBE_SCORE_MAX
maximum score
Definition avformat.h:483
#define AVFMT_NO_BYTE_SEEK
Format does not allow seeking by bytes.
Definition avformat.h:506
#define AVSEEK_FLAG_BYTE
seeking based on position in bytes
Definition avformat.h:2617
#define AVSEEK_FLAG_FRAME
seeking based on frame number
Definition avformat.h:2619
#define AVFMT_FLAG_CUSTOM_IO
The caller has supplied a custom AVIOContext, don't avio_close() it.
Definition avformat.h:1492
#define AVIO_FLAG_READ
read-only
Definition avio.h:617
int avio_feof(AVIOContext *s)
Similar to feof() but also returns nonzero on read errors.
Definition aviobuf.c:349
int avio_read_to_bprint(AVIOContext *h, struct AVBPrint *pb, size_t max_size)
Read contents of h into print buffer, up to max_size bytes, or up to EOF.
Definition aviobuf.c:1254
int ffio_copy_url_options(AVIOContext *pb, AVDictionary **avio_opts)
Read url related dictionary options from the AVIOContext and write to the given dictionary.
Definition aviobuf.c:994
static int read_packet(void *opaque, uint8_t *buf, int buf_size)
void av_bprint_init(AVBPrint *buf, unsigned size_init, unsigned size_max)
Definition bprint.c:69
AVBPrint public header.
#define flags(name, subs,...)
Definition cbs_h264.c:74
#define i(width, name, range_min, range_max)
Definition cbs_h264.c:63
#define s(width, name)
Definition cbs_vp9.c:198
static int read_probe(const AVProbeData *p)
Definition cdg.c:30
#define NULL
Definition coverity.c:32
long long int64_t
Definition coverity.c:34
void ff_rescale_interval(AVRational tb_in, AVRational tb_out, int64_t *min_ts, int64_t *ts, int64_t *max_ts)
Rescales a timestamp and the endpoints of an interval to which the temstamp belongs,...
Definition seek.c:752
#define FF_INFMT_FLAG_INIT_CLEANUP
For an FFInputFormat with this flag set read_close() needs to be called by the caller upon read_heade...
Definition demux.h:35
static AVPacket * pkt
static int read_header(FFV1Context *f, RangeCoder *c)
Definition ffv1dec.c:578
static av_cold void cleanup(FlashSV2Context *s)
#define AV_OPT_FLAG_DECODING_PARAM
A generic parameter which can be set by the user for demuxing or decoding.
Definition opt.h:355
@ AV_OPT_TYPE_STRING
Underlying C type is a uint8_t* that is either NULL or points to a C string allocated with the av_mal...
Definition opt.h:275
int av_get_exact_bits_per_sample(enum AVCodecID codec_id)
Return codec bits per sample.
Definition utils.c:461
@ AV_CODEC_ID_PCM_S24LE
Definition codec_id.h:342
@ AV_PKT_DATA_SKIP_SAMPLES
Recommends skipping the specified number of samples.
Definition packet.h:153
uint8_t * av_packet_new_side_data(AVPacket *pkt, enum AVPacketSideDataType type, size_t size)
Allocate new information of a packet.
Definition packet.c:231
void av_shrink_packet(AVPacket *pkt, int size)
Reduce packet size, correctly zeroing padding.
Definition packet.c:113
AVFormatContext * avformat_alloc_context(void)
Allocate an AVFormatContext.
Definition options.c:165
void avformat_free_context(AVFormatContext *s)
Free an AVFormatContext and all its streams.
Definition avformat.c:150
int avformat_seek_file(AVFormatContext *s, int stream_index, int64_t min_ts, int64_t ts, int64_t max_ts, int flags)
Seek to timestamp ts.
Definition seek.c:664
int av_read_frame(AVFormatContext *s, AVPacket *pkt)
Return the next frame of a stream.
Definition demux.c:1588
int avformat_open_input(AVFormatContext **ps, const char *url, const AVInputFormat *fmt, AVDictionary **options)
Open an input stream and read the header.
Definition demux.c:231
void avformat_close_input(AVFormatContext **s)
Close an opened input AVFormatContext.
Definition demux.c:377
int av_bprint_finalize(AVBPrint *buf, char **ret_str)
Finalize a print buffer.
Definition bprint.c:235
void av_dict_free(AVDictionary **pm)
Free all the memory allocated for an AVDictionary struct and all keys and values.
Definition dict.c:233
AVDictionaryEntry * av_dict_get(const AVDictionary *m, const char *key, const AVDictionaryEntry *prev, int flags)
Get a dictionary entry with matching key.
Definition dict.c:60
int av_dict_copy(AVDictionary **dst, const AVDictionary *src, int flags)
Copy entries from one AVDictionary struct into another.
Definition dict.c:247
int av_dict_set(AVDictionary **pm, const char *key, const char *value, int flags)
Set the given entry in *pm, overwriting an existing entry.
Definition dict.c:86
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition error.h:61
#define AVERROR_STREAM_NOT_FOUND
Stream not found.
Definition error.h:67
#define AVERROR_EOF
End of file.
Definition error.h:57
#define av_err2str(errnum)
Convenience macro, the return value should be used only directly in function arguments but never stan...
Definition error.h:122
#define AVERROR(e)
Definition error.h:45
#define AV_LOG_TRACE
Extremely verbose debugging, useful for libav* development.
Definition log.h:236
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition log.h:231
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition log.h:216
#define AV_LOG_INFO
Standard information.
Definition log.h:221
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition log.h:210
const char * av_default_item_name(void *ptr)
Return the context name.
Definition log.c:241
AVRational av_add_q(AVRational b, AVRational c)
Add two rationals.
Definition rational.c:93
AVRational av_mul_q(AVRational b, AVRational c)
Multiply two rationals.
Definition rational.c:80
int av_reduce(int *dst_num, int *dst_den, int64_t num, int64_t den, int64_t max)
Reduce a fraction.
Definition rational.c:35
static AVRational av_make_q(int num, int den)
Create an AVRational.
Definition rational.h:71
static double av_q2d(AVRational a)
Convert an AVRational to a double.
Definition rational.h:104
static int av_cmp_q(AVRational a, AVRational b)
Compare two rationals.
Definition rational.h:89
static av_always_inline AVRational av_inv_q(AVRational q)
Invert a rational.
Definition rational.h:159
AVRational av_sub_q(AVRational b, AVRational c)
Subtract one rational from another.
Definition rational.c:101
AVRational av_div_q(AVRational b, AVRational c)
Divide one rational by another.
Definition rational.c:88
int64_t av_rescale(int64_t a, int64_t b, int64_t c)
Rescale a 64-bit integer with rounding to nearest.
int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq)
Rescale a 64-bit integer by 2 rational numbers.
void * av_fast_realloc(void *ptr, unsigned int *size, size_t min_size)
Reallocate the given buffer if it is not large enough, otherwise do nothing.
Definition mem.c:495
void * av_realloc_array(void *ptr, size_t nmemb, size_t size)
Definition mem.c:217
@ AVMEDIA_TYPE_AUDIO
Definition avutil.h:201
char * av_strtok(char *s, const char *delim, char **saveptr)
Split the string into several tokens which can be accessed by successive calls to av_strtok().
Definition avstring.c:179
int av_strcasecmp(const char *a, const char *b)
Locale-independent case-insensitive compare.
Definition avstring.c:208
const char * av_dirname(char *path)
Thread safe dirname.
Definition avstring.c:271
char * av_append_path_component(const char *path, const char *component)
Append path component to the existing path.
Definition avstring.c:292
#define AV_NOPTS_VALUE
Undefined timestamp value.
Definition avutil.h:247
#define AV_TIME_BASE_Q
Internal time base represented as fractional value.
Definition avutil.h:263
#define LIBAVUTIL_VERSION_INT
Definition version.h:85
int av_opt_set(void *obj, const char *name, const char *val, int search_flags)
Definition opt.c:887
Public header file for the processing of Interoperable Master Format (IMF) packages.
xmlNodePtr ff_imf_xml_get_child_element_by_name(xmlNodePtr parent, const char *name_utf8)
Returns the first child element with the specified local name.
Definition imf_cpl.c:59
int ff_imf_parse_cpl(void *log_ctx, AVIOContext *in, FFIMFCPL **cpl)
Parse an IMF Composition Playlist document into the FFIMFCPL data structure.
Definition imf_cpl.c:875
void ff_imf_cpl_free(FFIMFCPL *cpl)
Deletes an FFIMFCPL data structure previously instantiated with ff_imf_cpl_alloc().
Definition imf_cpl.c:846
int ff_imf_xml_read_uuid(xmlNodePtr element, AVUUID uuid)
Reads a UUID from an XML element.
Definition imf_cpl.c:73
static void imf_asset_locator_map_init(IMFAssetLocatorMap *asset_map)
Initializes an IMFAssetLocatorMap structure.
Definition imfdec.c:292
static int imf_uri_is_url(const char *string)
Definition imfdec.c:130
static int set_context_streams_from_tracks(AVFormatContext *s)
Definition imfdec.c:584
static int imf_uri_is_unix_abs_path(const char *string)
Definition imfdec.c:135
static const AVClass imf_class
Definition imfdec.c:1027
#define AVRATIONAL_FORMAT
Definition imfdec.c:78
static int imf_uri_is_dos_abs_path(const char *string)
Definition imfdec.c:140
static int coherent_ts(int64_t ts, AVRational in_tb, AVRational out_tb)
Definition imfdec.c:944
static int imf_time_to_ts(int64_t *ts, AVRational t, AVRational time_base)
Definition imfdec.c:157
#define AVRATIONAL_ARG(rational)
Definition imfdec.c:79
static const AVOption imf_options[]
Definition imfdec.c:1013
static int imf_read_header(AVFormatContext *s)
Definition imfdec.c:644
static IMFAssetLocator * find_asset_map_locator(IMFAssetLocatorMap *asset_map, AVUUID uuid)
Definition imfdec.c:364
static int imf_read_packet(AVFormatContext *s, AVPacket *pkt)
Definition imfdec.c:786
static int open_track_file_resource(AVFormatContext *s, FFIMFTrackFileResource *track_file_resource, IMFVirtualTrackPlaybackCtx *track)
Definition imfdec.c:464
static int open_cpl_tracks(AVFormatContext *s)
Definition imfdec.c:619
static void imf_asset_locator_map_deinit(IMFAssetLocatorMap *asset_map)
Free a IMFAssetLocatorMap pointer.
Definition imfdec.c:301
static int open_virtual_track(AVFormatContext *s, FFIMFTrackFileVirtualTrack *virtual_track, int32_t track_index)
Definition imfdec.c:526
static int imf_close(AVFormatContext *s)
Definition imfdec.c:910
static int parse_assetmap(AVFormatContext *s, const char *url)
Definition imfdec.c:309
static IMFVirtualTrackPlaybackCtx * get_next_track_with_minimum_timestamp(AVFormatContext *s)
Definition imfdec.c:715
static int imf_probe(const AVProbeData *p)
Definition imfdec.c:930
static int get_resource_context_for_timestamp(AVFormatContext *s, IMFVirtualTrackPlaybackCtx *track, IMFVirtualTrackResourcePlaybackCtx **resource)
Definition imfdec.c:738
static int parse_imf_asset_map_from_xml_dom(AVFormatContext *s, xmlDocPtr doc, IMFAssetLocatorMap *asset_map, const char *base_url)
Parse a ASSETMAP XML file to extract the UUID-URI mapping of assets.
Definition imfdec.c:184
static void imf_virtual_track_playback_context_deinit(IMFVirtualTrackPlaybackCtx *track)
Definition imfdec.c:518
static int imf_seek(AVFormatContext *s, int stream_index, int64_t min_ts, int64_t ts, int64_t max_ts, int flags)
Definition imfdec.c:958
static int open_track_resource_context(AVFormatContext *s, IMFVirtualTrackPlaybackCtx *track, int32_t resource_index)
Definition imfdec.c:373
#define r
Definition input.c:42
#define AV_WL32(p, v)
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
Definition internal.h:88
static av_cold int read_close(AVFormatContext *ctx)
Definition libcdio.c:143
#define FFMIN(a, b)
Definition macros.h:49
#define FFMAX(a, b)
Definition macros.h:47
Memory handling functions.
#define av_strdup(s)
Definition ops_static.c:55
AVOptions.
int nb_channels
Number of channels in this layout.
Describe the class of an AVClass context structure.
Definition log.h:76
AVChannelLayout ch_layout
The channel layout and number of channels.
Definition codec_par.h:207
enum AVMediaType codec_type
General type of the encoded data.
Definition codec_par.h:53
enum AVCodecID codec_id
Specific type of the encoded data (the codec used).
Definition codec_par.h:57
int sample_rate
The number of audio samples per second.
Definition codec_par.h:213
Format I/O context.
Definition avformat.h:1333
unsigned int nb_streams
Number of elements in AVFormatContext.streams.
Definition avformat.h:1389
int(* io_close2)(struct AVFormatContext *s, AVIOContext *pb)
A callback for closing the streams opened with AVFormatContext.io_open().
Definition avformat.h:1963
int flags
Flags modifying the (de)muxer behaviour.
Definition avformat.h:1484
void * opaque
User data.
Definition avformat.h:1912
AVStream ** streams
A list of all streams in the file.
Definition avformat.h:1401
int(* io_open)(struct AVFormatContext *s, AVIOContext **pb, const char *url, int flags, AVDictionary **options)
A callback for opening new IO streams.
Definition avformat.h:1953
Bytestream IO Context.
Definition avio.h:160
Callback for checking whether to abort blocking functions.
Definition avio.h:59
AVOption.
Definition opt.h:428
This structure stores compressed data.
Definition packet.h:580
This structure contains the data a format has to probe a file.
Definition avformat.h:471
Rational number (pair of numerator and denominator).
Definition rational.h:58
int num
Numerator.
Definition rational.h:59
int den
Denominator.
Definition rational.h:60
Stream structure.
Definition avformat.h:766
AVCodecParameters * codecpar
Codec parameters associated with this stream.
Definition avformat.h:789
int64_t nb_frames
number of frames in this stream if known or 0
Definition avformat.h:827
int64_t duration
Decoding: duration of the stream, in stream time base.
Definition avformat.h:825
int id
Format-specific stream ID.
Definition avformat.h:778
int pts_wrap_bits
Number of bits in timestamps.
Definition avformat.h:909
AVRational time_base
This is the fundamental unit of time (in seconds) in terms of which frame timestamps are represented.
Definition avformat.h:805
AVRational edit_rate
BaseResourceType/EditRate.
Definition imf.h:69
uint32_t duration
BaseResourceType/Duration.
Definition imf.h:71
uint32_t repeat_count
BaseResourceType/RepeatCount.
Definition imf.h:72
uint32_t entry_point
BaseResourceType/EntryPoint.
Definition imf.h:70
IMF Composition Playlist.
Definition imf.h:130
IMF Composition Playlist Track File Resource.
Definition imf.h:78
FFIMFBaseResource base
Definition imf.h:79
AVUUID track_file_uuid
TrackFileResourceType/TrackFileId.
Definition imf.h:80
IMF Composition Playlist Virtual Track that consists of Track File Resources.
Definition imf.h:111
FFIMFTrackFileResource * resources
Resource elements of the Virtual Track.
Definition imf.h:114
uint32_t resource_count
Number of Resource elements present in the Virtual Track.
Definition imf.h:113
IMF Asset locator map Results from the parsing of one or more ASSETMAP XML files.
Definition imfdec.c:93
uint32_t asset_count
Definition imfdec.c:94
IMFAssetLocator * assets
Definition imfdec.c:95
IMF Asset locator.
Definition imfdec.c:84
char * absolute_uri
Definition imfdec.c:86
AVUUID uuid
Definition imfdec.c:85
const char * base_url
Definition imfdec.c:120
IMFAssetLocatorMap asset_locator_map
Definition imfdec.c:125
FFIMFCPL * cpl
Definition imfdec.c:124
uint32_t track_count
Definition imfdec.c:126
AVDictionary * avio_opts
Definition imfdec.c:123
AVIOInterruptCB * interrupt_callback
Definition imfdec.c:122
char * asset_map_paths
Definition imfdec.c:121
IMFVirtualTrackPlaybackCtx ** tracks
Definition imfdec.c:127
AVRational duration
Overall duration.
Definition imfdec.c:110
AVRational current_timestamp
Current temporal position.
Definition imfdec.c:109
uint32_t resource_count
Number of resources (<= INT32_MAX)
Definition imfdec.c:111
int32_t current_resource_index
Index of the current resource in resources, or < 0 if a current resource has yet to be selected.
Definition imfdec.c:114
int32_t index
Track index in playlist.
Definition imfdec.c:108
IMFVirtualTrackResourcePlaybackCtx * resources
Buffer holding the resources.
Definition imfdec.c:113
unsigned int resources_alloc_sz
Size of the buffer holding the resource.
Definition imfdec.c:112
AVRational end_time
exclusive end time of the resource on the CPL timeline (s)
Definition imfdec.c:103
AVFormatContext * ctx
Context associated with the resource.
Definition imfdec.c:101
IMFAssetLocator * locator
Location of the resource.
Definition imfdec.c:99
FFIMFTrackFileResource * resource
Underlying IMF CPL resource.
Definition imfdec.c:100
AVRational ts_offset
start_time minus the entry point into the resource (s)
Definition imfdec.c:104
AVRational start_time
inclusive start time of the resource on the CPL timeline (s)
Definition imfdec.c:102
#define av_free(p)
#define av_mallocz(s)
#define av_freep(p)
#define av_log(a,...)
static uint8_t tmp[40]
Definition aes_ctr.c:52
char * av_timecode_make_string(const AVTimecode *tc, char *buf, int framenum_arg)
Load timecode string in buf.
Definition timecode.c:104
#define AV_TIMECODE_STR_SIZE
Definition timecode.h:33
#define AV_PRI_URN_UUID
Definition uuid.h:43
#define AV_UUID_ARG(x)
Definition uuid.h:51
uint8_t AVUUID[AV_UUID_LEN]
Definition uuid.h:60
static int track_index(VividasDemuxContext *viv, AVFormatContext *s, const uint8_t *buf, unsigned size)
Definition vividas.c:438
static double c[64]