FFmpeg
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 "imf.h"
67 #include "internal.h"
68 #include "libavcodec/packet.h"
69 #include "libavutil/avstring.h"
70 #include "libavutil/bprint.h"
71 #include "libavutil/intreadwrite.h"
72 #include "libavutil/opt.h"
73 #include "mxf.h"
74 #include "url.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  */
84 typedef struct IMFAssetLocator {
86  char *absolute_uri;
88 
89 /**
90  * IMF Asset locator map
91  * Results from the parsing of one or more ASSETMAP XML files
92  */
93 typedef struct IMFAssetLocatorMap {
94  uint32_t asset_count;
97 
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 
118 typedef struct IMFContext {
119  const AVClass *class;
120  const char *base_url;
126  uint32_t track_count;
128 } IMFContext;
129 
130 static int imf_uri_is_url(const char *string)
131 {
132  return strstr(string, "://") != NULL;
133 }
134 
135 static int imf_uri_is_unix_abs_path(const char *string)
136 {
137  return string[0] == '/';
138 }
139 
140 static int imf_uri_is_dos_abs_path(const char *string)
141 {
142  /* Absolute path case: `C:\path\to\somwhere` */
143  if (string[1] == ':' && string[2] == '\\')
144  return 1;
145 
146  /* Absolute path case: `C:/path/to/somwhere` */
147  if (string[1] == ':' && string[2] == '/')
148  return 1;
149 
150  /* Network path case: `\\path\to\somwhere` */
151  if (string[0] == '\\' && string[1] == '\\')
152  return 1;
153 
154  return 0;
155 }
156 
157 /**
158  * Parse a ASSETMAP XML file to extract the UUID-URI mapping of assets.
159  * @param s the current format context, if any (can be NULL).
160  * @param doc the XML document to be parsed.
161  * @param asset_map pointer on the IMFAssetLocatorMap to fill.
162  * @param base_url the url of the asset map XML file, if any (can be NULL).
163  * @return a negative value in case of error, 0 otherwise.
164  */
166  xmlDocPtr doc,
167  IMFAssetLocatorMap *asset_map,
168  const char *base_url)
169 {
170  xmlNodePtr asset_map_element = NULL;
171  xmlNodePtr node = NULL;
172  xmlNodePtr asset_element = NULL;
173  unsigned long elem_count;
174  char *uri;
175  int ret = 0;
176  IMFAssetLocator *asset = NULL;
177  void *tmp;
178 
179  asset_map_element = xmlDocGetRootElement(doc);
180 
181  if (!asset_map_element) {
182  av_log(s, AV_LOG_ERROR, "Unable to parse asset map XML - missing root node\n");
183  return AVERROR_INVALIDDATA;
184  }
185 
186  if (asset_map_element->type != XML_ELEMENT_NODE || av_strcasecmp(asset_map_element->name, "AssetMap")) {
187  av_log(s,
188  AV_LOG_ERROR,
189  "Unable to parse asset map XML - wrong root node name[%s] type[%d]\n",
190  asset_map_element->name,
191  (int)asset_map_element->type);
192  return AVERROR_INVALIDDATA;
193  }
194 
195  /* parse asset locators */
196  if (!(node = ff_imf_xml_get_child_element_by_name(asset_map_element, "AssetList"))) {
197  av_log(s, AV_LOG_ERROR, "Unable to parse asset map XML - missing AssetList node\n");
198  return AVERROR_INVALIDDATA;
199  }
200  elem_count = xmlChildElementCount(node);
201  if (elem_count > UINT32_MAX
202  || asset_map->asset_count > UINT32_MAX - elem_count)
203  return AVERROR(ENOMEM);
204  tmp = av_realloc_array(asset_map->assets,
205  elem_count + asset_map->asset_count,
206  sizeof(IMFAssetLocator));
207  if (!tmp) {
208  av_log(s, AV_LOG_ERROR, "Cannot allocate IMF asset locators\n");
209  return AVERROR(ENOMEM);
210  }
211  asset_map->assets = tmp;
212 
213  asset_element = xmlFirstElementChild(node);
214  while (asset_element) {
215  if (av_strcasecmp(asset_element->name, "Asset") != 0)
216  continue;
217 
218  asset = &(asset_map->assets[asset_map->asset_count]);
219 
220  if (ff_imf_xml_read_uuid(ff_imf_xml_get_child_element_by_name(asset_element, "Id"), asset->uuid)) {
221  av_log(s, AV_LOG_ERROR, "Could not parse UUID from asset in asset map.\n");
222  return AVERROR_INVALIDDATA;
223  }
224 
225  av_log(s, AV_LOG_DEBUG, "Found asset id: " FF_IMF_UUID_FORMAT "\n", UID_ARG(asset->uuid));
226 
227  if (!(node = ff_imf_xml_get_child_element_by_name(asset_element, "ChunkList"))) {
228  av_log(s, AV_LOG_ERROR, "Unable to parse asset map XML - missing ChunkList node\n");
229  return AVERROR_INVALIDDATA;
230  }
231 
232  if (!(node = ff_imf_xml_get_child_element_by_name(node, "Chunk"))) {
233  av_log(s, AV_LOG_ERROR, "Unable to parse asset map XML - missing Chunk node\n");
234  return AVERROR_INVALIDDATA;
235  }
236 
237  uri = xmlNodeGetContent(ff_imf_xml_get_child_element_by_name(node, "Path"));
239  asset->absolute_uri = av_append_path_component(base_url, uri);
240  else
241  asset->absolute_uri = av_strdup(uri);
242  xmlFree(uri);
243  if (!asset->absolute_uri)
244  return AVERROR(ENOMEM);
245 
246  av_log(s, AV_LOG_DEBUG, "Found asset absolute URI: %s\n", asset->absolute_uri);
247 
248  asset_map->asset_count++;
249  asset_element = xmlNextElementSibling(asset_element);
250  }
251 
252  return ret;
253 }
254 
255 /**
256  * Initializes an IMFAssetLocatorMap structure.
257  */
259 {
260  asset_map->assets = NULL;
261  asset_map->asset_count = 0;
262 }
263 
264 /**
265  * Free a IMFAssetLocatorMap pointer.
266  */
268 {
269  for (uint32_t i = 0; i < asset_map->asset_count; i++)
270  av_freep(&asset_map->assets[i].absolute_uri);
271 
272  av_freep(&asset_map->assets);
273 }
274 
275 static int parse_assetmap(AVFormatContext *s, const char *url)
276 {
277  IMFContext *c = s->priv_data;
278  AVIOContext *in = NULL;
279  struct AVBPrint buf;
281  xmlDoc *doc = NULL;
282  const char *base_url;
283  char *tmp_str = NULL;
284  int ret;
285 
286  av_log(s, AV_LOG_DEBUG, "Asset Map URL: %s\n", url);
287 
288  av_dict_copy(&opts, c->avio_opts, 0);
289  ret = s->io_open(s, &in, url, AVIO_FLAG_READ, &opts);
290  av_dict_free(&opts);
291  if (ret < 0)
292  return ret;
293 
294  av_bprint_init(&buf, 0, INT_MAX); // xmlReadMemory uses integer length
295 
296  ret = avio_read_to_bprint(in, &buf, SIZE_MAX);
297  if (ret < 0 || !avio_feof(in)) {
298  av_log(s, AV_LOG_ERROR, "Unable to read to asset map '%s'\n", url);
299  if (ret == 0)
301  goto clean_up;
302  }
303 
304  LIBXML_TEST_VERSION
305 
306  tmp_str = av_strdup(url);
307  if (!tmp_str) {
308  ret = AVERROR(ENOMEM);
309  goto clean_up;
310  }
311  base_url = av_dirname(tmp_str);
312 
313  doc = xmlReadMemory(buf.str, buf.len, url, NULL, 0);
314 
315  ret = parse_imf_asset_map_from_xml_dom(s, doc, &c->asset_locator_map, base_url);
316  if (!ret)
317  av_log(s,
318  AV_LOG_DEBUG,
319  "Found %d assets from %s\n",
320  c->asset_locator_map.asset_count,
321  url);
322 
323  xmlFreeDoc(doc);
324 
325 clean_up:
326  if (tmp_str)
327  av_freep(&tmp_str);
328  ff_format_io_close(s, &in);
329  av_bprint_finalize(&buf, NULL);
330  return ret;
331 }
332 
334 {
335  for (uint32_t i = 0; i < asset_map->asset_count; i++) {
336  if (memcmp(asset_map->assets[i].uuid, uuid, 16) == 0)
337  return &(asset_map->assets[i]);
338  }
339  return NULL;
340 }
341 
343  IMFVirtualTrackResourcePlaybackCtx *track_resource)
344 {
345  IMFContext *c = s->priv_data;
346  int ret = 0;
347  int64_t entry_point;
349  AVStream *st;
350 
351  if (track_resource->ctx) {
352  av_log(s,
353  AV_LOG_DEBUG,
354  "Input context already opened for %s.\n",
355  track_resource->locator->absolute_uri);
356  return 0;
357  }
358 
359  track_resource->ctx = avformat_alloc_context();
360  if (!track_resource->ctx)
361  return AVERROR(ENOMEM);
362 
363  track_resource->ctx->io_open = s->io_open;
364  track_resource->ctx->io_close = s->io_close;
365  track_resource->ctx->io_close2 = s->io_close2;
366  track_resource->ctx->flags |= s->flags & ~AVFMT_FLAG_CUSTOM_IO;
367 
368  if ((ret = ff_copy_whiteblacklists(track_resource->ctx, s)) < 0)
369  goto cleanup;
370 
371  if ((ret = av_opt_set(track_resource->ctx, "format_whitelist", "mxf", 0)))
372  goto cleanup;
373 
374  if ((ret = av_dict_copy(&opts, c->avio_opts, 0)) < 0)
375  goto cleanup;
376 
377  ret = avformat_open_input(&track_resource->ctx,
378  track_resource->locator->absolute_uri,
379  NULL,
380  &opts);
381  if (ret < 0) {
382  av_log(s,
383  AV_LOG_ERROR,
384  "Could not open %s input context: %s\n",
385  track_resource->locator->absolute_uri,
386  av_err2str(ret));
387  goto cleanup;
388  }
389  av_dict_free(&opts);
390 
391  /* make sure there is only one stream in the file */
392 
393  if (track_resource->ctx->nb_streams != 1) {
395  goto cleanup;
396  }
397 
398  st = track_resource->ctx->streams[0];
399 
400  /* Warn if the resource time base does not match the file time base */
401  if (av_cmp_q(st->time_base, av_inv_q(track_resource->resource->base.edit_rate)))
402  av_log(s,
404  "Incoherent source stream timebase " AVRATIONAL_FORMAT
405  "regarding resource edit rate: " AVRATIONAL_FORMAT,
406  st->time_base.num,
407  st->time_base.den,
408  track_resource->resource->base.edit_rate.den,
409  track_resource->resource->base.edit_rate.num);
410 
411  entry_point = av_rescale_q(track_resource->resource->base.entry_point, st->time_base,
412  av_inv_q(track_resource->resource->base.edit_rate));
413 
414  if (entry_point) {
415  av_log(s,
416  AV_LOG_DEBUG,
417  "Seek at resource %s entry point: %" PRIu32 "\n",
418  track_resource->locator->absolute_uri,
419  track_resource->resource->base.entry_point);
420  ret = avformat_seek_file(track_resource->ctx, 0, entry_point, entry_point, entry_point, 0);
421  if (ret < 0) {
422  av_log(s,
423  AV_LOG_ERROR,
424  "Could not seek at %" PRId64 "on %s: %s\n",
425  entry_point,
426  track_resource->locator->absolute_uri,
427  av_err2str(ret));
428  avformat_close_input(&track_resource->ctx);
429  return ret;
430  }
431  }
432 
433  return 0;
434 
435 cleanup:
436  av_dict_free(&opts);
437  avformat_free_context(track_resource->ctx);
438  track_resource->ctx = NULL;
439  return ret;
440 }
441 
443  FFIMFTrackFileResource *track_file_resource,
445 {
446  IMFContext *c = s->priv_data;
447  IMFAssetLocator *asset_locator;
448  void *tmp;
449 
450  asset_locator = find_asset_map_locator(&c->asset_locator_map, track_file_resource->track_file_uuid);
451  if (!asset_locator) {
452  av_log(s,
453  AV_LOG_ERROR,
454  "Could not find asset locator for UUID: " FF_IMF_UUID_FORMAT "\n",
455  UID_ARG(track_file_resource->track_file_uuid));
456  return AVERROR_INVALIDDATA;
457  }
458 
459  av_log(s,
460  AV_LOG_DEBUG,
461  "Found locator for " FF_IMF_UUID_FORMAT ": %s\n",
462  UID_ARG(asset_locator->uuid),
463  asset_locator->absolute_uri);
464 
465  if (track->resource_count > INT32_MAX - track_file_resource->base.repeat_count
466  || (track->resource_count + track_file_resource->base.repeat_count)
467  > INT_MAX / sizeof(IMFVirtualTrackResourcePlaybackCtx))
468  return AVERROR(ENOMEM);
469  tmp = av_fast_realloc(track->resources,
470  &track->resources_alloc_sz,
471  (track->resource_count + track_file_resource->base.repeat_count)
473  if (!tmp)
474  return AVERROR(ENOMEM);
475  track->resources = tmp;
476 
477  for (uint32_t i = 0; i < track_file_resource->base.repeat_count; i++) {
479 
480  vt_ctx.locator = asset_locator;
481  vt_ctx.resource = track_file_resource;
482  vt_ctx.ctx = NULL;
483  vt_ctx.start_time = track->duration;
484  vt_ctx.ts_offset = av_sub_q(vt_ctx.start_time,
485  av_div_q(av_make_q((int)track_file_resource->base.entry_point, 1),
486  track_file_resource->base.edit_rate));
487  vt_ctx.end_time = av_add_q(track->duration,
488  av_make_q((int)track_file_resource->base.duration
489  * track_file_resource->base.edit_rate.den,
490  track_file_resource->base.edit_rate.num));
491  track->resources[track->resource_count++] = vt_ctx;
492  track->duration = vt_ctx.end_time;
493  }
494 
495  return 0;
496 }
497 
499 {
500  for (uint32_t i = 0; i < track->resource_count; i++)
502 
503  av_freep(&track->resources);
504 }
505 
507  FFIMFTrackFileVirtualTrack *virtual_track,
509 {
510  IMFContext *c = s->priv_data;
512  void *tmp;
513  int ret = 0;
514 
515  if (!(track = av_mallocz(sizeof(IMFVirtualTrackPlaybackCtx))))
516  return AVERROR(ENOMEM);
517  track->current_resource_index = -1;
518  track->index = track_index;
519  track->duration = av_make_q(0, 1);
520 
521  for (uint32_t i = 0; i < virtual_track->resource_count; i++) {
522  av_log(s,
523  AV_LOG_DEBUG,
524  "Open stream from file " FF_IMF_UUID_FORMAT ", stream %d\n",
525  UID_ARG(virtual_track->resources[i].track_file_uuid),
526  i);
527  if ((ret = open_track_file_resource(s, &virtual_track->resources[i], track)) != 0) {
528  av_log(s,
529  AV_LOG_ERROR,
530  "Could not open image track resource " FF_IMF_UUID_FORMAT "\n",
531  UID_ARG(virtual_track->resources[i].track_file_uuid));
532  goto clean_up;
533  }
534  }
535 
536  track->current_timestamp = av_make_q(0, track->duration.den);
537 
538  if (c->track_count == UINT32_MAX) {
539  ret = AVERROR(ENOMEM);
540  goto clean_up;
541  }
542  tmp = av_realloc_array(c->tracks, c->track_count + 1, sizeof(IMFVirtualTrackPlaybackCtx *));
543  if (!tmp) {
544  ret = AVERROR(ENOMEM);
545  goto clean_up;
546  }
547  c->tracks = tmp;
548  c->tracks[c->track_count++] = track;
549 
550  return 0;
551 
552 clean_up:
554  av_free(track);
555  return ret;
556 }
557 
559 {
560  IMFContext *c = s->priv_data;
561  int ret = 0;
562 
563  for (uint32_t i = 0; i < c->track_count; i++) {
564  AVStream *asset_stream;
565  AVStream *first_resource_stream;
566 
567  /* Open the first resource of the track to get stream information */
568  ret = open_track_resource_context(s, &c->tracks[i]->resources[0]);
569  if (ret)
570  return ret;
571  first_resource_stream = c->tracks[i]->resources[0].ctx->streams[0];
572  av_log(s, AV_LOG_DEBUG, "Open the first resource of track %d\n", c->tracks[i]->index);
573 
574  /* Copy stream information */
575  asset_stream = avformat_new_stream(s, NULL);
576  if (!asset_stream) {
577  av_log(s, AV_LOG_ERROR, "Could not create stream\n");
578  return AVERROR(ENOMEM);
579  }
580  asset_stream->id = i;
581  ret = avcodec_parameters_copy(asset_stream->codecpar, first_resource_stream->codecpar);
582  if (ret < 0) {
583  av_log(s, AV_LOG_ERROR, "Could not copy stream parameters\n");
584  return ret;
585  }
586  avpriv_set_pts_info(asset_stream,
587  first_resource_stream->pts_wrap_bits,
588  first_resource_stream->time_base.num,
589  first_resource_stream->time_base.den);
590  asset_stream->duration = (int64_t)av_q2d(av_mul_q(c->tracks[i]->duration,
591  av_inv_q(asset_stream->time_base)));
592  }
593 
594  return 0;
595 }
596 
598 {
599  IMFContext *c = s->priv_data;
600  int32_t track_index = 0;
601  int ret;
602 
603  if (c->cpl->main_image_2d_track) {
604  if ((ret = open_virtual_track(s, c->cpl->main_image_2d_track, track_index++)) != 0) {
605  av_log(s,
606  AV_LOG_ERROR,
607  "Could not open image track " FF_IMF_UUID_FORMAT "\n",
608  UID_ARG(c->cpl->main_image_2d_track->base.id_uuid));
609  return ret;
610  }
611  }
612 
613  for (uint32_t i = 0; i < c->cpl->main_audio_track_count; i++) {
614  if ((ret = open_virtual_track(s, &c->cpl->main_audio_tracks[i], track_index++)) != 0) {
615  av_log(s,
616  AV_LOG_ERROR,
617  "Could not open audio track " FF_IMF_UUID_FORMAT "\n",
618  UID_ARG(c->cpl->main_audio_tracks[i].base.id_uuid));
619  return ret;
620  }
621  }
622 
624 }
625 
627 {
628  IMFContext *c = s->priv_data;
629  char *asset_map_path;
630  char *tmp_str;
631  int ret = 0;
632 
633  c->interrupt_callback = &s->interrupt_callback;
634  tmp_str = av_strdup(s->url);
635  if (!tmp_str)
636  return AVERROR(ENOMEM);
637  c->base_url = av_strdup(av_dirname(tmp_str));
638  av_freep(&tmp_str);
639  if (!c->base_url)
640  return AVERROR(ENOMEM);
641 
642  if ((ret = ffio_copy_url_options(s->pb, &c->avio_opts)) < 0)
643  return ret;
644 
645  av_log(s, AV_LOG_DEBUG, "start parsing IMF CPL: %s\n", s->url);
646 
647  if ((ret = ff_imf_parse_cpl(s->pb, &c->cpl)) < 0)
648  return ret;
649 
650  av_log(s,
651  AV_LOG_DEBUG,
652  "parsed IMF CPL: " FF_IMF_UUID_FORMAT "\n",
653  UID_ARG(c->cpl->id_uuid));
654 
655  if (!c->asset_map_paths) {
656  c->asset_map_paths = av_append_path_component(c->base_url, "ASSETMAP.xml");
657  if (!c->asset_map_paths) {
658  ret = AVERROR(ENOMEM);
659  return ret;
660  }
661  av_log(s, AV_LOG_DEBUG, "No asset maps provided, using the default ASSETMAP.xml\n");
662  }
663 
664  /* Parse each asset map XML file */
665  imf_asset_locator_map_init(&c->asset_locator_map);
666  asset_map_path = av_strtok(c->asset_map_paths, ",", &tmp_str);
667  while (asset_map_path != NULL) {
668  av_log(s, AV_LOG_DEBUG, "start parsing IMF Asset Map: %s\n", asset_map_path);
669 
670  if ((ret = parse_assetmap(s, asset_map_path)))
671  return ret;
672 
673  asset_map_path = av_strtok(NULL, ",", &tmp_str);
674  }
675 
676  av_log(s, AV_LOG_DEBUG, "parsed IMF Asset Maps\n");
677 
678  if ((ret = open_cpl_tracks(s)))
679  return ret;
680 
681  av_log(s, AV_LOG_DEBUG, "parsed IMF package\n");
682 
683  return 0;
684 }
685 
687 {
688  IMFContext *c = s->priv_data;
690 
691  AVRational minimum_timestamp = av_make_q(INT32_MAX, 1);
692  for (uint32_t i = c->track_count; i > 0; i--) {
693  av_log(s,
694  AV_LOG_DEBUG,
695  "Compare track %d timestamp " AVRATIONAL_FORMAT
696  " to minimum " AVRATIONAL_FORMAT
697  " (over duration: " AVRATIONAL_FORMAT
698  ")\n",
699  i,
700  AVRATIONAL_ARG(c->tracks[i - 1]->current_timestamp),
701  AVRATIONAL_ARG(minimum_timestamp),
702  AVRATIONAL_ARG(c->tracks[i - 1]->duration));
703 
704  if (av_cmp_q(c->tracks[i - 1]->current_timestamp, minimum_timestamp) <= 0) {
705  track = c->tracks[i - 1];
706  minimum_timestamp = track->current_timestamp;
707  }
708  }
709 
710  av_log(s,
711  AV_LOG_DEBUG,
712  "Found next track to read: %d (timestamp: %lf / %lf)\n",
713  track->index,
714  av_q2d(track->current_timestamp),
715  av_q2d(minimum_timestamp));
716  return track;
717 }
718 
720 {
721  *resource = NULL;
722 
723  if (av_cmp_q(track->current_timestamp, track->duration) >= 0) {
724  av_log(s, AV_LOG_DEBUG, "Reached the end of the virtual track\n");
725  return AVERROR_EOF;
726  }
727 
728  av_log(s,
729  AV_LOG_DEBUG,
730  "Looking for track %d resource for timestamp = %lf / %lf\n",
731  track->index,
732  av_q2d(track->current_timestamp),
733  av_q2d(track->duration));
734  for (uint32_t i = 0; i < track->resource_count; i++) {
735 
736  if (av_cmp_q(track->resources[i].end_time, track->current_timestamp) > 0) {
737  av_log(s,
738  AV_LOG_DEBUG,
739  "Found resource %d in track %d to read at timestamp %lf: "
740  "entry=%" PRIu32
741  ", duration=%" PRIu32
742  ", editrate=" AVRATIONAL_FORMAT,
743  i,
744  track->index,
745  av_q2d(track->current_timestamp),
747  track->resources[i].resource->base.duration,
749 
750  if (track->current_resource_index != i) {
751  int ret;
752 
753  av_log(s,
754  AV_LOG_DEBUG,
755  "Switch resource on track %d: re-open context\n",
756  track->index);
757 
759  if (ret != 0)
760  return ret;
761  if (track->current_resource_index > 0)
763  track->current_resource_index = i;
764  }
765 
766  *resource = track->resources + track->current_resource_index;
767  return 0;
768  }
769  }
770 
771  av_log(s, AV_LOG_ERROR, "Could not find IMF track resource to read\n");
773 }
774 
775 static int imf_time_to_ts(int64_t *ts, AVRational t, AVRational time_base)
776 {
777  int dst_num;
778  int dst_den;
779  AVRational r;
780 
781  r = av_div_q(t, time_base);
782 
783  if ((av_reduce(&dst_num, &dst_den, r.num, r.den, INT64_MAX) != 1))
784  return 1;
785 
786  if (dst_den != 1)
787  return 1;
788 
789  *ts = dst_num;
790 
791  return 0;
792 }
793 
795 {
797  int ret = 0;
799  int64_t delta_ts;
800  AVStream *st;
801  AVRational next_timestamp;
802 
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  av_log(s, AV_LOG_ERROR, "Failed to read frame\n");
812  return ret;
813  }
814 
815  av_log(s, AV_LOG_DEBUG, "Got packet: pts=%" PRId64 ", dts=%" PRId64
816  ", duration=%" PRId64 ", stream_index=%d, pos=%" PRId64
817  ", time_base=" AVRATIONAL_FORMAT "\n", pkt->pts, pkt->dts, pkt->duration,
819 
820  /* IMF resources contain only one stream */
821 
822  if (pkt->stream_index != 0)
823  return AVERROR_INVALIDDATA;
824  st = resource->ctx->streams[0];
825 
826  pkt->stream_index = track->index;
827 
828  /* adjust the packet PTS and DTS based on the temporal position of the resource within the timeline */
829 
830  ret = imf_time_to_ts(&delta_ts, resource->ts_offset, st->time_base);
831 
832  if (!ret) {
833  if (pkt->pts != AV_NOPTS_VALUE)
834  pkt->pts += delta_ts;
835  if (pkt->dts != AV_NOPTS_VALUE)
836  pkt->dts += delta_ts;
837  } else {
838  av_log(s, AV_LOG_WARNING, "Incoherent time stamp " AVRATIONAL_FORMAT " for time base " AVRATIONAL_FORMAT,
839  resource->ts_offset.num, resource->ts_offset.den, pkt->time_base.num,
840  pkt->time_base.den);
841  }
842 
843  /* advance the track timestamp by the packet duration */
844 
845  next_timestamp = av_add_q(track->current_timestamp,
846  av_mul_q(av_make_q((int)pkt->duration, 1), st->time_base));
847 
848  /* if necessary, clamp the next timestamp to the end of the current resource */
849 
850  if (av_cmp_q(next_timestamp, resource->end_time) > 0) {
851 
852  int64_t new_pkt_dur;
853 
854  /* shrink the packet duration */
855 
856  ret = imf_time_to_ts(&new_pkt_dur,
857  av_sub_q(resource->end_time, track->current_timestamp),
858  st->time_base);
859 
860  if (!ret)
861  pkt->duration = new_pkt_dur;
862  else
863  av_log(s, AV_LOG_WARNING, "Incoherent time base in packet duration calculation");
864 
865  /* shrink the packet itself for audio essence */
866 
867  if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
868 
870  /* AV_CODEC_ID_PCM_S24LE is the only PCM format supported in IMF */
871  /* in this case, explicitly shrink the packet */
872 
873  int bytes_per_sample = av_get_exact_bits_per_sample(st->codecpar->codec_id) >> 3;
874  int64_t nbsamples = av_rescale_q(pkt->duration,
875  st->time_base,
876  av_make_q(1, st->codecpar->sample_rate));
877  av_shrink_packet(pkt, nbsamples * st->codecpar->channels * bytes_per_sample);
878 
879  } else {
880  /* in all other cases, use side data to skip samples */
881  int64_t skip_samples;
882 
883  ret = imf_time_to_ts(&skip_samples,
884  av_sub_q(next_timestamp, resource->end_time),
885  av_make_q(1, st->codecpar->sample_rate));
886 
887  if (ret || skip_samples < 0 || skip_samples > UINT32_MAX) {
888  av_log(s, AV_LOG_WARNING, "Cannot skip audio samples");
889  } else {
890  uint8_t *side_data = av_packet_new_side_data(pkt, AV_PKT_DATA_SKIP_SAMPLES, 10);
891  if (!side_data)
892  return AVERROR(ENOMEM);
893 
894  AV_WL32(side_data + 4, skip_samples); /* skip from end of this packet */
895  side_data[6] = 1; /* reason for end is convergence */
896  }
897  }
898 
899  next_timestamp = resource->end_time;
900 
901  } else {
902  av_log(s, AV_LOG_WARNING, "Non-audio packet duration reduced");
903  }
904  }
905 
906  track->current_timestamp = next_timestamp;
907 
908  return 0;
909 }
910 
912 {
913  IMFContext *c = s->priv_data;
914 
915  av_log(s, AV_LOG_DEBUG, "Close IMF package\n");
916  av_dict_free(&c->avio_opts);
917  av_freep(&c->base_url);
918  imf_asset_locator_map_deinit(&c->asset_locator_map);
919  ff_imf_cpl_free(c->cpl);
920 
921  for (uint32_t i = 0; i < c->track_count; i++) {
923  av_freep(&c->tracks[i]);
924  }
925 
926  av_freep(&c->tracks);
927 
928  return 0;
929 }
930 
931 static int imf_probe(const AVProbeData *p)
932 {
933  if (!strstr(p->buf, "<CompositionPlaylist"))
934  return 0;
935 
936  /* check for a ContentTitle element without including ContentTitleText,
937  * which is used by the D-Cinema CPL.
938  */
939  if (!strstr(p->buf, "ContentTitle>"))
940  return 0;
941 
942  return AVPROBE_SCORE_MAX;
943 }
944 
945 static const AVOption imf_options[] = {
946  {
947  .name = "assetmaps",
948  .help = "Comma-separated paths to ASSETMAP files."
949  "If not specified, the `ASSETMAP.xml` file in the same "
950  "directory as the CPL is used.",
951  .offset = offsetof(IMFContext, asset_map_paths),
952  .type = AV_OPT_TYPE_STRING,
953  .default_val = {.str = NULL},
955  },
956  {NULL},
957 };
958 
959 static const AVClass imf_class = {
960  .class_name = "imf",
961  .item_name = av_default_item_name,
962  .option = imf_options,
963  .version = LIBAVUTIL_VERSION_INT,
964 };
965 
967  .name = "imf",
968  .long_name = NULL_IF_CONFIG_SMALL("IMF (Interoperable Master Format)"),
969  .flags = AVFMT_EXPERIMENTAL,
970  .flags_internal = FF_FMT_INIT_CLEANUP,
971  .priv_class = &imf_class,
972  .priv_data_size = sizeof(IMFContext),
977 };
FFIMFTrackFileVirtualTrack::resources
FFIMFTrackFileResource * resources
Resource elements of the Virtual Track.
Definition: imf.h:121
AV_LOG_WARNING
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:186
IMFVirtualTrackResourcePlaybackCtx::ts_offset
AVRational ts_offset
Definition: imfdec.c:104
ffio_copy_url_options
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:1023
FF_FMT_INIT_CLEANUP
#define FF_FMT_INIT_CLEANUP
For an AVInputFormat with this flag set read_close() needs to be called by the caller upon read_heade...
Definition: internal.h:49
r
const char * r
Definition: vf_curves.c:116
AVERROR
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later. That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another. Frame references ownership and permissions
opt.h
avformat_new_stream
AVStream * avformat_new_stream(AVFormatContext *s, const AVCodec *c)
Add a new stream to a media file.
Definition: utils.c:768
AVCodecParameters::codec_type
enum AVMediaType codec_type
General type of the encoded data.
Definition: codec_par.h:56
AV_WL32
#define AV_WL32(p, v)
Definition: intreadwrite.h:426
av_bprint_finalize
int av_bprint_finalize(AVBPrint *buf, char **ret_str)
Finalize a print buffer.
Definition: bprint.c:234
set_context_streams_from_tracks
static int set_context_streams_from_tracks(AVFormatContext *s)
Definition: imfdec.c:558
av_bprint_init
void av_bprint_init(AVBPrint *buf, unsigned size_init, unsigned size_max)
Definition: bprint.c:68
parse_assetmap
static int parse_assetmap(AVFormatContext *s, const char *url)
Definition: imfdec.c:275
track_index
static int track_index(VividasDemuxContext *viv, AVFormatContext *s, uint8_t *buf, unsigned size)
Definition: vividas.c:435
AVERROR_EOF
#define AVERROR_EOF
End of file.
Definition: error.h:57
IMFVirtualTrackResourcePlaybackCtx
Definition: imfdec.c:98
av_div_q
AVRational av_div_q(AVRational b, AVRational c)
Divide one rational by another.
Definition: rational.c:88
imf_close
static int imf_close(AVFormatContext *s)
Definition: imfdec.c:911
av_strcasecmp
int av_strcasecmp(const char *a, const char *b)
Locale-independent case-insensitive compare.
Definition: avstring.c:215
tmp
static uint8_t tmp[11]
Definition: aes_ctr.c:26
cleanup
static av_cold void cleanup(FlashSV2Context *s)
Definition: flashsv2enc.c:128
AVFormatContext::streams
AVStream ** streams
A list of all streams in the file.
Definition: avformat.h:1268
FFIMFTrackFileVirtualTrack::resource_count
uint32_t resource_count
Number of Resource elements present in the Virtual Track.
Definition: imf.h:120
AVOption
AVOption.
Definition: opt.h:247
AVFMT_FLAG_CUSTOM_IO
#define AVFMT_FLAG_CUSTOM_IO
The caller has supplied a custom AVIOContext, don't avio_close() it.
Definition: avformat.h:1326
IMFVirtualTrackResourcePlaybackCtx::start_time
AVRational start_time
Definition: imfdec.c:102
IMFContext::asset_locator_map
IMFAssetLocatorMap asset_locator_map
Definition: imfdec.c:125
imf_probe
static int imf_probe(const AVProbeData *p)
Definition: imfdec.c:931
AVPacket::duration
int64_t duration
Duration of this packet in AVStream->time_base units, 0 if unknown.
Definition: packet.h:391
AVDictionary
Definition: dict.c:30
av_sub_q
AVRational av_sub_q(AVRational b, AVRational c)
Subtract one rational from another.
Definition: rational.c:101
av_read_frame
int av_read_frame(AVFormatContext *s, AVPacket *pkt)
Return the next frame of a stream.
Definition: demux.c:1412
IMFContext::asset_map_paths
char * asset_map_paths
Definition: imfdec.c:121
IMFAssetLocatorMap::asset_count
uint32_t asset_count
Definition: imfdec.c:94
AVIOInterruptCB
Callback for checking whether to abort blocking functions.
Definition: avio.h:58
imf_uri_is_unix_abs_path
static int imf_uri_is_unix_abs_path(const char *string)
Definition: imfdec.c:135
av_append_path_component
char * av_append_path_component(const char *path, const char *component)
Append path component to the existing path.
Definition: avstring.c:304
AVPROBE_SCORE_MAX
#define AVPROBE_SCORE_MAX
maximum score
Definition: avformat.h:459
avformat_close_input
void avformat_close_input(AVFormatContext **s)
Close an opened input AVFormatContext.
Definition: demux.c:355
AVRATIONAL_ARG
#define AVRATIONAL_ARG(rational)
Definition: imfdec.c:79
mxf.h
AVCodecParameters::channels
int channels
Audio only.
Definition: codec_par.h:166
imf_uri_is_dos_abs_path
static int imf_uri_is_dos_abs_path(const char *string)
Definition: imfdec.c:140
IMFVirtualTrackPlaybackCtx::resource_count
uint32_t resource_count
Number of resources (<= INT32_MAX)
Definition: imfdec.c:111
av_shrink_packet
void av_shrink_packet(AVPacket *pkt, int size)
Reduce packet size, correctly zeroing padding.
Definition: avpacket.c:114
ff_imf_cpl_free
void ff_imf_cpl_free(FFIMFCPL *cpl)
Deletes an FFIMFCPL data structure previously instantiated with ff_imf_cpl_alloc().
Definition: imf_cpl.c:769
read_close
static av_cold int read_close(AVFormatContext *ctx)
Definition: libcdio.c:141
FFIMFBaseResource::duration
uint32_t duration
BaseResourceType/Duration.
Definition: imf.h:78
ff_imf_xml_get_child_element_by_name
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
av_opt_set
int av_opt_set(void *obj, const char *name, const char *val, int search_flags)
Definition: opt.c:468
AVStream::duration
int64_t duration
Decoding: duration of the stream, in stream time base.
Definition: avformat.h:985
av_reduce
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
AVRational::num
int num
Numerator.
Definition: rational.h:59
av_dirname
const char * av_dirname(char *path)
Thread safe dirname.
Definition: avstring.c:283
open_track_file_resource
static int open_track_file_resource(AVFormatContext *s, FFIMFTrackFileResource *track_file_resource, IMFVirtualTrackPlaybackCtx *track)
Definition: imfdec.c:442
IMFContext::track_count
uint32_t track_count
Definition: imfdec.c:126
pkt
AVPacket * pkt
Definition: movenc.c:59
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:180
AVInputFormat
Definition: avformat.h:650
FFIMFTrackFileVirtualTrack
IMF Composition Playlist Virtual Track that consists of Track File Resources.
Definition: imf.h:118
avformat_open_input
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:207
IMFVirtualTrackPlaybackCtx::current_timestamp
AVRational current_timestamp
Current temporal position.
Definition: imfdec.c:109
UID_ARG
#define UID_ARG(x)
Definition: mxf.h:129
av_fast_realloc
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:504
ff_imf_xml_read_uuid
int ff_imf_xml_read_uuid(xmlNodePtr element, uint8_t uuid[16])
Reads a UUID from an XML element.
Definition: imf_cpl.c:73
intreadwrite.h
s
#define s(width, name)
Definition: cbs_vp9.c:257
avio_read_to_bprint
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:1343
av_realloc_array
void * av_realloc_array(void *ptr, size_t nmemb, size_t size)
Definition: mem.c:224
AVFormatContext::flags
int flags
Flags modifying the (de)muxer behaviour.
Definition: avformat.h:1318
AVInputFormat::name
const char * name
A comma separated list of short names for the format.
Definition: avformat.h:655
AVProbeData::buf
unsigned char * buf
Buffer must have AVPROBE_PADDING_SIZE of extra allocated bytes filled with zero.
Definition: avformat.h:449
AVMEDIA_TYPE_AUDIO
@ AVMEDIA_TYPE_AUDIO
Definition: avutil.h:202
av_q2d
static double av_q2d(AVRational a)
Convert an AVRational to a double.
Definition: rational.h:104
av_strtok
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:186
imf_options
static const AVOption imf_options[]
Definition: imfdec.c:945
AV_LOG_DEBUG
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:201
av_rescale_q
int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq)
Rescale a 64-bit integer by 2 rational numbers.
Definition: mathematics.c:141
IMFVirtualTrackResourcePlaybackCtx::locator
IMFAssetLocator * locator
Definition: imfdec.c:99
IMFAssetLocator
IMF Asset locator.
Definition: imfdec.c:84
IMFVirtualTrackPlaybackCtx
Definition: imfdec.c:107
get_next_track_with_minimum_timestamp
static IMFVirtualTrackPlaybackCtx * get_next_track_with_minimum_timestamp(AVFormatContext *s)
Definition: imfdec.c:686
IMFVirtualTrackResourcePlaybackCtx::resource
FFIMFTrackFileResource * resource
Definition: imfdec.c:100
AVFormatContext
Format I/O context.
Definition: avformat.h:1200
internal.h
IMFVirtualTrackResourcePlaybackCtx::ctx
AVFormatContext * ctx
Definition: imfdec.c:101
opts
AVDictionary * opts
Definition: movenc.c:50
AVStream::codecpar
AVCodecParameters * codecpar
Codec parameters associated with this stream.
Definition: avformat.h:1095
LIBAVUTIL_VERSION_INT
#define LIBAVUTIL_VERSION_INT
Definition: version.h:85
read_header
static int read_header(FFV1Context *f)
Definition: ffv1dec.c:527
AVClass
Describe the class of an AVClass context structure.
Definition: log.h:66
AVStream::time_base
AVRational time_base
This is the fundamental unit of time (in seconds) in terms of which frame timestamps are represented.
Definition: avformat.h:965
NULL
#define NULL
Definition: coverity.c:32
read_probe
static int read_probe(const AVProbeData *pd)
Definition: jvdec.c:55
find_asset_map_locator
static IMFAssetLocator * find_asset_map_locator(IMFAssetLocatorMap *asset_map, FFIMFUUID uuid)
Definition: imfdec.c:333
AVRational
Rational number (pair of numerator and denominator).
Definition: rational.h:58
av_default_item_name
const char * av_default_item_name(void *ptr)
Return the context name.
Definition: log.c:235
AVProbeData
This structure contains the data a format has to probe a file.
Definition: avformat.h:447
imf_uri_is_url
static int imf_uri_is_url(const char *string)
Definition: imfdec.c:130
IMFContext::interrupt_callback
AVIOInterruptCB * interrupt_callback
Definition: imfdec.c:122
get_resource_context_for_timestamp
static int get_resource_context_for_timestamp(AVFormatContext *s, IMFVirtualTrackPlaybackCtx *track, IMFVirtualTrackResourcePlaybackCtx **resource)
Definition: imfdec.c:719
ff_imf_demuxer
const AVInputFormat ff_imf_demuxer
Definition: imfdec.c:966
c
Undefined Behavior In the C some operations are like signed integer dereferencing freed accessing outside allocated Undefined Behavior must not occur in a C it is not safe even if the output of undefined operations is unused The unsafety may seem nit picking but Optimizing compilers have in fact optimized code on the assumption that no undefined Behavior occurs Optimizing code based on wrong assumptions can and has in some cases lead to effects beyond the output of computations The signed integer overflow problem in speed critical code Code which is highly optimized and works with signed integers sometimes has the problem that often the output of the computation does not c
Definition: undefined.txt:32
AVCodecParameters::sample_rate
int sample_rate
Audio only.
Definition: codec_par.h:170
IMFAssetLocator::absolute_uri
char * absolute_uri
Definition: imfdec.c:86
IMFVirtualTrackResourcePlaybackCtx::end_time
AVRational end_time
Definition: imfdec.c:103
AVFormatContext::nb_streams
unsigned int nb_streams
Number of elements in AVFormatContext.streams.
Definition: avformat.h:1256
imf_read_packet
static int imf_read_packet(AVFormatContext *s, AVPacket *pkt)
Definition: imfdec.c:794
av_get_exact_bits_per_sample
int av_get_exact_bits_per_sample(enum AVCodecID codec_id)
Return codec bits per sample.
Definition: utils.c:491
FFIMFBaseResource::edit_rate
AVRational edit_rate
BaseResourceType/EditRate.
Definition: imf.h:76
AVIOContext
Bytestream IO Context.
Definition: avio.h:161
AV_CODEC_ID_PCM_S24LE
@ AV_CODEC_ID_PCM_S24LE
Definition: codec_id.h:326
imf_asset_locator_map_deinit
static void imf_asset_locator_map_deinit(IMFAssetLocatorMap *asset_map)
Free a IMFAssetLocatorMap pointer.
Definition: imfdec.c:267
NULL_IF_CONFIG_SMALL
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
Definition: internal.h:117
avformat_alloc_context
AVFormatContext * avformat_alloc_context(void)
Allocate an AVFormatContext.
Definition: options.c:154
IMFContext::cpl
FFIMFCPL * cpl
Definition: imfdec.c:124
av_err2str
#define av_err2str(errnum)
Convenience macro, the return value should be used only directly in function arguments but never stan...
Definition: error.h:121
imf_asset_locator_map_init
static void imf_asset_locator_map_init(IMFAssetLocatorMap *asset_map)
Initializes an IMFAssetLocatorMap structure.
Definition: imfdec.c:258
ff_copy_whiteblacklists
int ff_copy_whiteblacklists(AVFormatContext *dst, const AVFormatContext *src)
Copies the whilelists from one context to the other.
Definition: utils.c:115
av_make_q
static AVRational av_make_q(int num, int den)
Create an AVRational.
Definition: rational.h:71
avformat_seek_file
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:656
AV_NOPTS_VALUE
#define AV_NOPTS_VALUE
Undefined timestamp value.
Definition: avutil.h:248
AVOption::name
const char * name
Definition: opt.h:248
AVPacket::dts
int64_t dts
Decompression timestamp in AVStream->time_base units; the time at which the packet is decompressed.
Definition: packet.h:372
av_dict_free
void av_dict_free(AVDictionary **pm)
Free all the memory allocated for an AVDictionary struct and all keys and values.
Definition: dict.c:203
open_cpl_tracks
static int open_cpl_tracks(AVFormatContext *s)
Definition: imfdec.c:597
AVRATIONAL_FORMAT
#define AVRATIONAL_FORMAT
Definition: imfdec.c:78
FFIMFBaseResource::repeat_count
uint32_t repeat_count
BaseResourceType/RepeatCount.
Definition: imf.h:79
IMFVirtualTrackPlaybackCtx::current_resource_index
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
ff_imf_parse_cpl
int ff_imf_parse_cpl(AVIOContext *in, FFIMFCPL **cpl)
Parse an IMF Composition Playlist document into the FFIMFCPL data structure.
Definition: imf_cpl.c:795
avcodec_parameters_copy
int avcodec_parameters_copy(AVCodecParameters *dst, const AVCodecParameters *src)
Copy the contents of src to dst.
Definition: codec_par.c:72
bprint.h
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:271
AVPacket::pts
int64_t pts
Presentation timestamp in AVStream->time_base units; the time at which the decompressed packet will b...
Definition: packet.h:366
avio_internal.h
packet.h
FFIMFBaseResource::entry_point
uint32_t entry_point
BaseResourceType/EntryPoint.
Definition: imf.h:77
imf_read_header
static int imf_read_header(AVFormatContext *s)
Definition: imfdec.c:626
AV_OPT_FLAG_DECODING_PARAM
#define AV_OPT_FLAG_DECODING_PARAM
a generic parameter which can be set by the user for demuxing or decoding
Definition: opt.h:278
url.h
av_mallocz
void * av_mallocz(size_t size)
Allocate a memory block with alignment suitable for all memory accesses (including vectors if availab...
Definition: mem.c:263
AVFMT_EXPERIMENTAL
#define AVFMT_EXPERIMENTAL
The muxer/demuxer is experimental and should be used with caution.
Definition: avformat.h:472
av_inv_q
static av_always_inline AVRational av_inv_q(AVRational q)
Invert a rational.
Definition: rational.h:159
AV_PKT_DATA_SKIP_SAMPLES
@ AV_PKT_DATA_SKIP_SAMPLES
Recommmends skipping the specified number of samples.
Definition: packet.h:156
imf_virtual_track_playback_context_deinit
static void imf_virtual_track_playback_context_deinit(IMFVirtualTrackPlaybackCtx *track)
Definition: imfdec.c:498
IMFVirtualTrackPlaybackCtx::index
int32_t index
Track index in playlist.
Definition: imfdec.c:108
parse_imf_asset_map_from_xml_dom
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:165
FFIMFUUID
uint8_t FFIMFUUID[16]
UUID as defined in IETF RFC 422.
Definition: imf.h:70
imf_time_to_ts
static int imf_time_to_ts(int64_t *ts, AVRational t, AVRational time_base)
Definition: imfdec.c:775
av_cmp_q
static int av_cmp_q(AVRational a, AVRational b)
Compare two rationals.
Definition: rational.h:89
AVStream::id
int id
Format-specific stream ID.
Definition: avformat.h:949
ret
ret
Definition: filter_design.txt:187
read_packet
static int read_packet(void *opaque, uint8_t *buf, int buf_size)
Definition: avio_reading.c:42
FFIMFTrackFileResource::track_file_uuid
FFIMFUUID track_file_uuid
TrackFileResourceType/TrackFileId.
Definition: imf.h:87
AVStream
Stream structure.
Definition: avformat.h:935
IMFAssetLocatorMap
IMF Asset locator map Results from the parsing of one or more ASSETMAP XML files.
Definition: imfdec.c:93
AVClass::class_name
const char * class_name
The name of the class; usually it is the same name as the context structure type to which the AVClass...
Definition: log.h:71
IMFContext
Definition: imfdec.c:118
open_track_resource_context
static int open_track_resource_context(AVFormatContext *s, IMFVirtualTrackResourcePlaybackCtx *track_resource)
Definition: imfdec.c:342
IMFVirtualTrackPlaybackCtx::duration
AVRational duration
Overall duration.
Definition: imfdec.c:110
IMFVirtualTrackPlaybackCtx::resources_alloc_sz
unsigned int resources_alloc_sz
Size of the buffer holding the resource.
Definition: imfdec.c:112
FFIMFTrackFileResource
IMF Composition Playlist Track File Resource.
Definition: imf.h:85
av_packet_new_side_data
uint8_t * av_packet_new_side_data(AVPacket *pkt, enum AVPacketSideDataType type, size_t size)
Allocate new information of a packet.
Definition: avpacket.c:232
AVERROR_STREAM_NOT_FOUND
#define AVERROR_STREAM_NOT_FOUND
Stream not found.
Definition: error.h:67
AVRational::den
int den
Denominator.
Definition: rational.h:60
avformat_free_context
void avformat_free_context(AVFormatContext *s)
Free an AVFormatContext and all its streams.
Definition: utils.c:688
open_virtual_track
static int open_virtual_track(AVFormatContext *s, FFIMFTrackFileVirtualTrack *virtual_track, int32_t track_index)
Definition: imfdec.c:506
AVFormatContext::io_close
void(* io_close)(struct AVFormatContext *s, AVIOContext *pb)
A callback for closing the streams opened with AVFormatContext.io_open().
Definition: avformat.h:1765
IMFContext::avio_opts
AVDictionary * avio_opts
Definition: imfdec.c:123
AVFormatContext::io_open
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:1759
avpriv_set_pts_info
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: utils.c:1196
av_mul_q
AVRational av_mul_q(AVRational b, AVRational c)
Multiply two rationals.
Definition: rational.c:80
AVPacket::stream_index
int stream_index
Definition: packet.h:375
imf_class
static const AVClass imf_class
Definition: imfdec.c:959
AVIO_FLAG_READ
#define AVIO_FLAG_READ
read-only
Definition: avio.h:621
av_strdup
char * av_strdup(const char *s)
Duplicate a string.
Definition: mem.c:279
IMFContext::tracks
IMFVirtualTrackPlaybackCtx ** tracks
Definition: imfdec.c:127
av_free
#define av_free(p)
Definition: tableprint_vlc.h:34
av_add_q
AVRational av_add_q(AVRational b, AVRational c)
Add two rationals.
Definition: rational.c:93
AVCodecParameters::codec_id
enum AVCodecID codec_id
Specific type of the encoded data (the codec used).
Definition: codec_par.h:60
AVPacket
This structure stores compressed data.
Definition: packet.h:350
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:35
av_dict_copy
int av_dict_copy(AVDictionary **dst, const AVDictionary *src, int flags)
Copy entries from one AVDictionary struct into another.
Definition: dict.c:217
AVPacket::pos
int64_t pos
byte position in stream, -1 if unknown
Definition: packet.h:393
AVFormatContext::io_close2
int(* io_close2)(struct AVFormatContext *s, AVIOContext *pb)
A callback for closing the streams opened with AVFormatContext.io_open().
Definition: avformat.h:1806
int32_t
int32_t
Definition: audioconvert.c:56
IMFContext::base_url
const char * base_url
Definition: imfdec.c:120
FFIMFCPL
IMF Composition Playlist.
Definition: imf.h:137
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:28
imf.h
Public header file for the processing of Interoperable Master Format (IMF) packages.
AVERROR_INVALIDDATA
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:61
IMFVirtualTrackPlaybackCtx::resources
IMFVirtualTrackResourcePlaybackCtx * resources
Buffer holding the resources.
Definition: imfdec.c:113
avstring.h
IMFAssetLocator::uuid
FFIMFUUID uuid
Definition: imfdec.c:85
AV_OPT_TYPE_STRING
@ AV_OPT_TYPE_STRING
Definition: opt.h:228
AVStream::pts_wrap_bits
int pts_wrap_bits
Number of bits in timestamps.
Definition: avformat.h:1104
FFIMFTrackFileResource::base
FFIMFBaseResource base
Definition: imf.h:86
FF_IMF_UUID_FORMAT
#define FF_IMF_UUID_FORMAT
Definition: imf.h:63
ff_format_io_close
int ff_format_io_close(AVFormatContext *s, AVIOContext **pb)
Definition: utils.c:1848
AVPacket::time_base
AVRational time_base
Time base of the packet's timestamps.
Definition: packet.h:417
IMFAssetLocatorMap::assets
IMFAssetLocator * assets
Definition: imfdec.c:95
avio_feof
int avio_feof(AVIOContext *s)
Similar to feof() but also returns nonzero on read errors.
Definition: aviobuf.c:375