FFmpeg
mov.c
Go to the documentation of this file.
1 /*
2  * MOV demuxer
3  * Copyright (c) 2001 Fabrice Bellard
4  * Copyright (c) 2009 Baptiste Coudurier <baptiste dot coudurier at gmail dot com>
5  *
6  * first version by Francois Revol <revol@free.fr>
7  * seek function by Gael Chardon <gael.dev@4now.net>
8  *
9  * This file is part of FFmpeg.
10  *
11  * FFmpeg is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU Lesser General Public
13  * License as published by the Free Software Foundation; either
14  * version 2.1 of the License, or (at your option) any later version.
15  *
16  * FFmpeg is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19  * Lesser General Public License for more details.
20  *
21  * You should have received a copy of the GNU Lesser General Public
22  * License along with FFmpeg; if not, write to the Free Software
23  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
24  */
25 
26 #include "config_components.h"
27 
28 #include <inttypes.h>
29 #include <limits.h>
30 #include <stdint.h>
31 
32 #include "libavutil/attributes.h"
33 #include "libavutil/bprint.h"
35 #include "libavutil/dovi_meta.h"
36 #include "libavutil/internal.h"
37 #include "libavutil/intreadwrite.h"
38 #include "libavutil/intfloat.h"
39 #include "libavutil/mathematics.h"
40 #include "libavutil/avassert.h"
41 #include "libavutil/avstring.h"
42 #include "libavutil/dict.h"
43 #include "libavutil/display.h"
44 #include "libavutil/mem.h"
45 #include "libavutil/opt.h"
46 #include "libavutil/aes.h"
47 #include "libavutil/aes_ctr.h"
48 #include "libavutil/pixdesc.h"
49 #include "libavutil/sha.h"
50 #include "libavutil/spherical.h"
51 #include "libavutil/stereo3d.h"
52 #include "libavutil/timecode.h"
53 #include "libavutil/uuid.h"
54 #include "libavcodec/ac3tab.h"
55 #include "libavcodec/exif.h"
56 #include "libavcodec/flac.h"
57 #include "libavcodec/hevc/hevc.h"
59 #include "libavcodec/mlp_parse.h"
60 #include "avformat.h"
61 #include "internal.h"
62 #include "avio_internal.h"
63 #include "demux.h"
64 #include "dvdclut.h"
65 #include "iamf_parse.h"
66 #include "iamf_reader.h"
67 #include "dovi_isom.h"
68 #include "riff.h"
69 #include "isom.h"
70 #include "libavcodec/get_bits.h"
71 #include "id3v1.h"
72 #include "mov_chan.h"
73 #include "replaygain.h"
74 
75 #if CONFIG_ZLIB
76 #include <zlib.h>
77 #endif
78 
79 #include "qtpalette.h"
80 
81 /* those functions parse an atom */
82 /* links atom IDs to parse functions */
83 typedef struct MOVParseTableEntry {
84  uint32_t type;
85  int (*parse)(MOVContext *ctx, AVIOContext *pb, MOVAtom atom);
87 
88 static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom);
89 static int mov_read_mfra(MOVContext *c, AVIOContext *f);
91 
93  unsigned len, const char *key)
94 {
95  char buf[16];
96 
97  short current, total = 0;
98  avio_rb16(pb); // unknown
99  current = avio_rb16(pb);
100  if (len >= 6)
101  total = avio_rb16(pb);
102  if (!total)
103  snprintf(buf, sizeof(buf), "%d", current);
104  else
105  snprintf(buf, sizeof(buf), "%d/%d", current, total);
106  c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
107  av_dict_set(&c->fc->metadata, key, buf, 0);
108 
109  return 0;
110 }
111 
113  unsigned len, const char *key)
114 {
115  /* bypass padding bytes */
116  avio_r8(pb);
117  avio_r8(pb);
118  avio_r8(pb);
119 
120  c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
121  av_dict_set_int(&c->fc->metadata, key, avio_r8(pb), 0);
122 
123  return 0;
124 }
125 
127  unsigned len, const char *key)
128 {
129  c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
130  av_dict_set_int(&c->fc->metadata, key, avio_r8(pb), 0);
131 
132  return 0;
133 }
134 
136  unsigned len, const char *key)
137 {
138  short genre;
139 
140  avio_r8(pb); // unknown
141 
142  genre = avio_r8(pb);
143  if (genre < 1 || genre > ID3v1_GENRE_MAX)
144  return 0;
145  c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
146  av_dict_set(&c->fc->metadata, key, ff_id3v1_genre_str[genre-1], 0);
147 
148  return 0;
149 }
150 
151 static const uint32_t mac_to_unicode[128] = {
152  0x00C4,0x00C5,0x00C7,0x00C9,0x00D1,0x00D6,0x00DC,0x00E1,
153  0x00E0,0x00E2,0x00E4,0x00E3,0x00E5,0x00E7,0x00E9,0x00E8,
154  0x00EA,0x00EB,0x00ED,0x00EC,0x00EE,0x00EF,0x00F1,0x00F3,
155  0x00F2,0x00F4,0x00F6,0x00F5,0x00FA,0x00F9,0x00FB,0x00FC,
156  0x2020,0x00B0,0x00A2,0x00A3,0x00A7,0x2022,0x00B6,0x00DF,
157  0x00AE,0x00A9,0x2122,0x00B4,0x00A8,0x2260,0x00C6,0x00D8,
158  0x221E,0x00B1,0x2264,0x2265,0x00A5,0x00B5,0x2202,0x2211,
159  0x220F,0x03C0,0x222B,0x00AA,0x00BA,0x03A9,0x00E6,0x00F8,
160  0x00BF,0x00A1,0x00AC,0x221A,0x0192,0x2248,0x2206,0x00AB,
161  0x00BB,0x2026,0x00A0,0x00C0,0x00C3,0x00D5,0x0152,0x0153,
162  0x2013,0x2014,0x201C,0x201D,0x2018,0x2019,0x00F7,0x25CA,
163  0x00FF,0x0178,0x2044,0x20AC,0x2039,0x203A,0xFB01,0xFB02,
164  0x2021,0x00B7,0x201A,0x201E,0x2030,0x00C2,0x00CA,0x00C1,
165  0x00CB,0x00C8,0x00CD,0x00CE,0x00CF,0x00CC,0x00D3,0x00D4,
166  0xF8FF,0x00D2,0x00DA,0x00DB,0x00D9,0x0131,0x02C6,0x02DC,
167  0x00AF,0x02D8,0x02D9,0x02DA,0x00B8,0x02DD,0x02DB,0x02C7,
168 };
169 
171  char *dst, int dstlen)
172 {
173  char *p = dst;
174  char *end = dst+dstlen-1;
175  int i;
176 
177  for (i = 0; i < len; i++) {
178  uint8_t t, c = avio_r8(pb);
179 
180  if (p >= end)
181  continue;
182 
183  if (c < 0x80)
184  *p++ = c;
185  else if (p < end)
186  PUT_UTF8(mac_to_unicode[c-0x80], t, if (p < end) *p++ = t;);
187  }
188  *p = 0;
189  return p - dst;
190 }
191 
192 /**
193  * Get the requested item.
194  */
195 static HEIFItem *get_heif_item(MOVContext *c, unsigned id)
196 {
197  HEIFItem *item = NULL;
198 
199  for (int i = 0; i < c->nb_heif_item; i++) {
200  if (!c->heif_item[i] || c->heif_item[i]->item_id != id)
201  continue;
202 
203  item = c->heif_item[i];
204  break;
205  }
206 
207  return item;
208 }
209 
210 /**
211  * Get the current stream in the parsing process. This can either be the
212  * latest stream added to the context, or the stream referenced by an item.
213  */
215 {
216  AVStream *st = NULL;
217  HEIFItem *item;
218 
219  if (c->fc->nb_streams < 1)
220  return NULL;
221 
222  if (c->cur_item_id == -1)
223  return c->fc->streams[c->fc->nb_streams-1];
224 
225  item = get_heif_item(c, c->cur_item_id);
226  if (item)
227  st = item->st;
228 
229  return st;
230 }
231 
232 static int mov_read_covr(MOVContext *c, AVIOContext *pb, int type, int len)
233 {
234  AVStream *st;
235  MOVStreamContext *sc;
236  enum AVCodecID id;
237  int ret;
238 
239  switch (type) {
240  case 0xd: id = AV_CODEC_ID_MJPEG; break;
241  case 0xe: id = AV_CODEC_ID_PNG; break;
242  case 0x1b: id = AV_CODEC_ID_BMP; break;
243  default:
244  av_log(c->fc, AV_LOG_WARNING, "Unknown cover type: 0x%x.\n", type);
245  avio_skip(pb, len);
246  return 0;
247  }
248 
249  sc = av_mallocz(sizeof(*sc));
250  if (!sc)
251  return AVERROR(ENOMEM);
252  ret = ff_add_attached_pic(c->fc, NULL, pb, NULL, len);
253  if (ret < 0) {
254  av_free(sc);
255  return ret;
256  }
257  st = c->fc->streams[c->fc->nb_streams - 1];
258  st->priv_data = sc;
259  sc->id = st->id;
260  sc->refcount = 1;
261 
262  if (st->attached_pic.size >= 8 && id != AV_CODEC_ID_BMP) {
263  if (AV_RB64(st->attached_pic.data) == 0x89504e470d0a1a0a) {
264  id = AV_CODEC_ID_PNG;
265  } else {
266  id = AV_CODEC_ID_MJPEG;
267  }
268  }
269  st->codecpar->codec_id = id;
270 
271  return 0;
272 }
273 
274 // 3GPP TS 26.244
275 static int mov_metadata_loci(MOVContext *c, AVIOContext *pb, unsigned len)
276 {
277  char language[4] = { 0 };
278  char buf[200], place[100];
279  uint16_t langcode = 0;
280  double longitude, latitude, altitude;
281  const char *key = "location";
282 
283  if (len < 4 + 2 + 1 + 1 + 4 + 4 + 4) {
284  av_log(c->fc, AV_LOG_ERROR, "loci too short\n");
285  return AVERROR_INVALIDDATA;
286  }
287 
288  avio_skip(pb, 4); // version+flags
289  langcode = avio_rb16(pb);
290  ff_mov_lang_to_iso639(langcode, language);
291  len -= 6;
292 
293  len -= avio_get_str(pb, len, place, sizeof(place));
294  if (len < 1) {
295  av_log(c->fc, AV_LOG_ERROR, "place name too long\n");
296  return AVERROR_INVALIDDATA;
297  }
298  avio_skip(pb, 1); // role
299  len -= 1;
300 
301  if (len < 12) {
302  av_log(c->fc, AV_LOG_ERROR,
303  "loci too short (%u bytes left, need at least %d)\n", len, 12);
304  return AVERROR_INVALIDDATA;
305  }
306  longitude = ((int32_t) avio_rb32(pb)) / (float) (1 << 16);
307  latitude = ((int32_t) avio_rb32(pb)) / (float) (1 << 16);
308  altitude = ((int32_t) avio_rb32(pb)) / (float) (1 << 16);
309 
310  // Try to output in the same format as the ?xyz field
311  snprintf(buf, sizeof(buf), "%+08.4f%+09.4f", latitude, longitude);
312  if (altitude)
313  av_strlcatf(buf, sizeof(buf), "%+f", altitude);
314  av_strlcatf(buf, sizeof(buf), "/%s", place);
315 
316  if (*language && strcmp(language, "und")) {
317  char key2[16];
318  snprintf(key2, sizeof(key2), "%s-%s", key, language);
319  av_dict_set(&c->fc->metadata, key2, buf, 0);
320  }
321  c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
322  return av_dict_set(&c->fc->metadata, key, buf, 0);
323 }
324 
325 static int mov_metadata_hmmt(MOVContext *c, AVIOContext *pb, unsigned len)
326 {
327  int i, n_hmmt;
328 
329  if (len < 2)
330  return 0;
331  if (c->ignore_chapters)
332  return 0;
333 
334  n_hmmt = avio_rb32(pb);
335  if (n_hmmt > len / 4)
336  return AVERROR_INVALIDDATA;
337  for (i = 0; i < n_hmmt && !pb->eof_reached; i++) {
338  int moment_time = avio_rb32(pb);
339  avpriv_new_chapter(c->fc, i, av_make_q(1, 1000), moment_time, AV_NOPTS_VALUE, NULL);
340  }
341  if (avio_feof(pb))
342  return AVERROR_INVALIDDATA;
343  return 0;
344 }
345 
347 {
348  char tmp_key[AV_FOURCC_MAX_STRING_SIZE] = {0};
349  char key2[32], language[4] = {0};
350  char *str = NULL;
351  const char *key = NULL;
352  uint16_t langcode = 0;
353  uint32_t data_type = 0, str_size_alloc;
354  uint64_t str_size;
355  int (*parse)(MOVContext*, AVIOContext*, unsigned, const char*) = NULL;
356  int raw = 0;
357  int num = 0;
359 
360  if (c->trak_index >= 0 && c->trak_index < c->fc->nb_streams)
361  metadata = &c->fc->streams[c->trak_index]->metadata;
362  else
363  metadata = &c->fc->metadata;
364 
365  switch (atom.type) {
366  case MKTAG( '@','P','R','M'): key = "premiere_version"; raw = 1; break;
367  case MKTAG( '@','P','R','Q'): key = "quicktime_version"; raw = 1; break;
368  case MKTAG( 'X','M','P','_'):
369  if (c->export_xmp) { key = "xmp"; raw = 1; } break;
370  case MKTAG( 'a','A','R','T'): key = "album_artist"; break;
371  case MKTAG( 'a','k','I','D'): key = "account_type";
373  case MKTAG( 'a','p','I','D'): key = "account_id"; break;
374  case MKTAG( 'c','a','t','g'): key = "category"; break;
375  case MKTAG( 'c','p','i','l'): key = "compilation";
377  case MKTAG( 'c','p','r','t'): key = "copyright"; break;
378  case MKTAG( 'd','e','s','c'): key = "description"; break;
379  case MKTAG( 'd','i','s','k'): key = "disc";
381  case MKTAG( 'e','g','i','d'): key = "episode_uid";
383  case MKTAG( 'F','I','R','M'): key = "firmware"; raw = 1; break;
384  case MKTAG( 'g','n','r','e'): key = "genre";
385  parse = mov_metadata_gnre; break;
386  case MKTAG( 'h','d','v','d'): key = "hd_video";
388  case MKTAG( 'H','M','M','T'):
389  return mov_metadata_hmmt(c, pb, atom.size);
390  case MKTAG( 'k','e','y','w'): key = "keywords"; break;
391  case MKTAG( 'l','d','e','s'): key = "synopsis"; break;
392  case MKTAG( 'l','o','c','i'):
393  return mov_metadata_loci(c, pb, atom.size);
394  case MKTAG( 'm','a','n','u'): key = "make"; break;
395  case MKTAG( 'm','o','d','l'): key = "model"; break;
396  case MKTAG( 'n','a','m','e'): key = "name"; break;
397  case MKTAG( 'p','c','s','t'): key = "podcast";
399  case MKTAG( 'p','g','a','p'): key = "gapless_playback";
401  case MKTAG( 'p','u','r','d'): key = "purchase_date"; break;
402  case MKTAG( 'r','t','n','g'): key = "rating";
404  case MKTAG( 's','o','a','a'): key = "sort_album_artist"; break;
405  case MKTAG( 's','o','a','l'): key = "sort_album"; break;
406  case MKTAG( 's','o','a','r'): key = "sort_artist"; break;
407  case MKTAG( 's','o','c','o'): key = "sort_composer"; break;
408  case MKTAG( 's','o','n','m'): key = "sort_name"; break;
409  case MKTAG( 's','o','s','n'): key = "sort_show"; break;
410  case MKTAG( 's','t','i','k'): key = "media_type";
412  case MKTAG( 't','r','k','n'): key = "track";
414  case MKTAG( 't','v','e','n'): key = "episode_id"; break;
415  case MKTAG( 't','v','e','s'): key = "episode_sort";
417  case MKTAG( 't','v','n','n'): key = "network"; break;
418  case MKTAG( 't','v','s','h'): key = "show"; break;
419  case MKTAG( 't','v','s','n'): key = "season_number";
421  case MKTAG(0xa9,'A','R','T'): key = "artist"; break;
422  case MKTAG(0xa9,'P','R','D'): key = "producer"; break;
423  case MKTAG(0xa9,'a','l','b'): key = "album"; break;
424  case MKTAG(0xa9,'a','u','t'): key = "artist"; break;
425  case MKTAG(0xa9,'c','h','p'): key = "chapter"; break;
426  case MKTAG(0xa9,'c','m','t'): key = "comment"; break;
427  case MKTAG(0xa9,'c','o','m'): key = "composer"; break;
428  case MKTAG(0xa9,'c','p','y'): key = "copyright"; break;
429  case MKTAG(0xa9,'d','a','y'): key = "date"; break;
430  case MKTAG(0xa9,'d','i','r'): key = "director"; break;
431  case MKTAG(0xa9,'d','i','s'): key = "disclaimer"; break;
432  case MKTAG(0xa9,'e','d','1'): key = "edit_date"; break;
433  case MKTAG(0xa9,'e','n','c'): key = "encoder"; break;
434  case MKTAG(0xa9,'f','m','t'): key = "original_format"; break;
435  case MKTAG(0xa9,'g','e','n'): key = "genre"; break;
436  case MKTAG(0xa9,'g','r','p'): key = "grouping"; break;
437  case MKTAG(0xa9,'h','s','t'): key = "host_computer"; break;
438  case MKTAG(0xa9,'i','n','f'): key = "comment"; break;
439  case MKTAG(0xa9,'l','y','r'): key = "lyrics"; break;
440  case MKTAG(0xa9,'m','a','k'): key = "make"; break;
441  case MKTAG(0xa9,'m','o','d'): key = "model"; break;
442  case MKTAG(0xa9,'n','a','m'): key = "title"; break;
443  case MKTAG(0xa9,'o','p','e'): key = "original_artist"; break;
444  case MKTAG(0xa9,'p','r','d'): key = "producer"; break;
445  case MKTAG(0xa9,'p','r','f'): key = "performers"; break;
446  case MKTAG(0xa9,'r','e','q'): key = "playback_requirements"; break;
447  case MKTAG(0xa9,'s','r','c'): key = "original_source"; break;
448  case MKTAG(0xa9,'s','t','3'): key = "subtitle"; break;
449  case MKTAG(0xa9,'s','w','r'): key = "encoder"; break;
450  case MKTAG(0xa9,'t','o','o'): key = "encoder"; break;
451  case MKTAG(0xa9,'t','r','k'): key = "track"; break;
452  case MKTAG(0xa9,'u','r','l'): key = "URL"; break;
453  case MKTAG(0xa9,'w','r','n'): key = "warning"; break;
454  case MKTAG(0xa9,'w','r','t'): key = "composer"; break;
455  case MKTAG(0xa9,'x','y','z'): key = "location"; break;
456  }
457 retry:
458  if (c->itunes_metadata && atom.size > 8) {
459  int data_size = avio_rb32(pb);
460  int tag = avio_rl32(pb);
461  if (tag == MKTAG('d','a','t','a') && data_size <= atom.size && data_size >= 16) {
462  data_type = avio_rb32(pb); // type
463  avio_rb32(pb); // unknown
464  str_size = data_size - 16;
465  atom.size -= 16;
466 
467  if (!key && c->found_hdlr_mdta && c->meta_keys) {
468  uint32_t index = av_bswap32(atom.type); // BE number has been read as LE
469  if (index < c->meta_keys_count && index > 0) {
470  key = c->meta_keys[index];
471  } else if (atom.type != MKTAG('c', 'o', 'v', 'r')) {
472  av_log(c->fc, AV_LOG_WARNING,
473  "The index of 'data' is out of range: %"PRId32" < 1 or >= %d.\n",
474  index, c->meta_keys_count);
475  }
476  }
477  if (atom.type == MKTAG('c', 'o', 'v', 'r') ||
478  (key && !strcmp(key, "com.apple.quicktime.artwork"))) {
479  int ret = mov_read_covr(c, pb, data_type, str_size);
480  if (ret < 0) {
481  av_log(c->fc, AV_LOG_ERROR, "Error parsing cover art.\n");
482  return ret;
483  }
484  atom.size -= str_size;
485  if (atom.size > 8)
486  goto retry;
487  return ret;
488  }
489  } else return 0;
490  } else if (atom.size > 4 && (key || c->export_all) && !c->itunes_metadata && !raw) {
491  str_size = avio_rb16(pb); // string length
492  if (str_size > atom.size) {
493  raw = 1;
494  avio_seek(pb, -2, SEEK_CUR);
495  av_log(c->fc, AV_LOG_WARNING, "UDTA parsing failed retrying raw\n");
496  goto retry;
497  }
498  langcode = avio_rb16(pb);
499  ff_mov_lang_to_iso639(langcode, language);
500  atom.size -= 4;
501  } else
502  str_size = atom.size;
503 
504  if (c->export_all && !key) {
505  key = av_fourcc_make_string(tmp_key, atom.type);
506  }
507 
508  if (!key)
509  return 0;
510  if (atom.size < 0 || str_size >= INT_MAX/2)
511  return AVERROR_INVALIDDATA;
512 
513  // Allocates enough space if data_type is a int32 or float32 number, otherwise
514  // worst-case requirement for output string in case of utf8 coded input
515  num = (data_type >= 21 && data_type <= 23);
516  str_size_alloc = (num ? 512 : (raw ? str_size : str_size * 2)) + 1;
517  str = av_mallocz(str_size_alloc);
518  if (!str)
519  return AVERROR(ENOMEM);
520 
521  if (parse)
522  parse(c, pb, str_size, key);
523  else {
524  if (!raw && (data_type == 3 || (data_type == 0 && (langcode < 0x400 || langcode == 0x7fff)))) { // MAC Encoded
525  mov_read_mac_string(c, pb, str_size, str, str_size_alloc);
526  } else if (data_type == 21) { // BE signed integer, variable size
527  int val = 0;
528  if (str_size == 1)
529  val = (int8_t)avio_r8(pb);
530  else if (str_size == 2)
531  val = (int16_t)avio_rb16(pb);
532  else if (str_size == 3)
533  val = ((int32_t)(avio_rb24(pb)<<8))>>8;
534  else if (str_size == 4)
535  val = (int32_t)avio_rb32(pb);
536  if (snprintf(str, str_size_alloc, "%d", val) >= str_size_alloc) {
537  av_log(c->fc, AV_LOG_ERROR,
538  "Failed to store the number (%d) in string.\n", val);
539  av_free(str);
540  return AVERROR_INVALIDDATA;
541  }
542  } else if (data_type == 22) { // BE unsigned integer, variable size
543  unsigned int val = 0;
544  if (str_size == 1)
545  val = avio_r8(pb);
546  else if (str_size == 2)
547  val = avio_rb16(pb);
548  else if (str_size == 3)
549  val = avio_rb24(pb);
550  else if (str_size == 4)
551  val = avio_rb32(pb);
552  if (snprintf(str, str_size_alloc, "%u", val) >= str_size_alloc) {
553  av_log(c->fc, AV_LOG_ERROR,
554  "Failed to store the number (%u) in string.\n", val);
555  av_free(str);
556  return AVERROR_INVALIDDATA;
557  }
558  } else if (data_type == 23 && str_size >= 4) { // BE float32
559  float val = av_int2float(avio_rb32(pb));
560  if (snprintf(str, str_size_alloc, "%f", val) >= str_size_alloc) {
561  av_log(c->fc, AV_LOG_ERROR,
562  "Failed to store the float32 number (%f) in string.\n", val);
563  av_free(str);
564  return AVERROR_INVALIDDATA;
565  }
566  } else if (data_type > 1 && data_type != 4) {
567  // data_type can be 0 if not set at all above. data_type 1 means
568  // UTF8 and 4 means "UTF8 sort". For any other type (UTF16 or e.g.
569  // a picture), don't return it blindly in a string that is supposed
570  // to be UTF8 text.
571  av_log(c->fc, AV_LOG_WARNING, "Skipping unhandled metadata %s of type %"PRIu32"\n", key, data_type);
572  av_free(str);
573  return 0;
574  } else {
575  int ret = ffio_read_size(pb, str, str_size);
576  if (ret < 0) {
577  av_free(str);
578  return ret;
579  }
580  str[str_size] = 0;
581  }
582  c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
583  if (c->itunes_metadata && av_dict_get(*metadata, key, NULL, 0))
585  av_dict_set(metadata, key, str, c->itunes_metadata ? AV_DICT_APPEND : 0);
586  if (*language && strcmp(language, "und")) {
587  snprintf(key2, sizeof(key2), "%s-%s", key, language);
588  av_dict_set(metadata, key2, str, 0);
589  }
590  if (!strcmp(key, "encoder")) {
591  int major, minor, micro;
592  if (sscanf(str, "HandBrake %d.%d.%d", &major, &minor, &micro) == 3) {
593  c->handbrake_version = 1000000*major + 1000*minor + micro;
594  }
595  }
596 
597  atom.size -= str_size;
598  av_freep(&str);
599 
600  // Read remaining data atoms for multi-valued iTunes tags (e.g. multiple
601  // artists stored as multiple data atoms within one tag atom), consistent
602  // with the existing covr path.
603  // Note: multiple sibling tag atoms with the same key (e.g. three separate
604  // ©ART atoms under ilst) are handled by the AV_DICT_APPEND logic above,
605  // since mov_read_udta_string() is called once per tag atom.
606  if (c->itunes_metadata && atom.size > 8)
607  goto retry;
608  }
609 
610  av_freep(&str);
611  return 0;
612 }
613 
615 {
616  int64_t start;
617  int i, nb_chapters, str_len, version;
618  char str[256+1];
619  int ret;
620 
621  if (c->ignore_chapters)
622  return 0;
623 
624  if ((atom.size -= 5) < 0)
625  return 0;
626 
627  version = avio_r8(pb);
628  avio_rb24(pb);
629  if (version)
630  avio_rb32(pb); // ???
631  nb_chapters = avio_r8(pb);
632 
633  for (i = 0; i < nb_chapters; i++) {
634  if (atom.size < 9)
635  return 0;
636 
637  start = avio_rb64(pb);
638  str_len = avio_r8(pb);
639 
640  if ((atom.size -= 9+str_len) < 0)
641  return 0;
642 
643  ret = ffio_read_size(pb, str, str_len);
644  if (ret < 0)
645  return ret;
646  str[str_len] = 0;
647  avpriv_new_chapter(c->fc, i, (AVRational){1,10000000}, start, AV_NOPTS_VALUE, str);
648  }
649  return 0;
650 }
651 
652 #define MIN_DATA_ENTRY_BOX_SIZE 12
654 {
655  AVStream *st;
656  MOVStreamContext *sc;
657  int entries, i, j;
658 
659  if (c->fc->nb_streams < 1)
660  return 0;
661  st = c->fc->streams[c->fc->nb_streams-1];
662  sc = st->priv_data;
663 
664  avio_rb32(pb); // version + flags
665  entries = avio_rb32(pb);
666  if (!entries ||
667  entries > (atom.size - 1) / MIN_DATA_ENTRY_BOX_SIZE + 1 ||
668  entries >= UINT_MAX / sizeof(*sc->drefs))
669  return AVERROR_INVALIDDATA;
670 
671  for (i = 0; i < sc->drefs_count; i++) {
672  MOVDref *dref = &sc->drefs[i];
673  av_freep(&dref->path);
674  av_freep(&dref->dir);
675  }
676  av_free(sc->drefs);
677  sc->drefs_count = 0;
678  sc->drefs = av_mallocz(entries * sizeof(*sc->drefs));
679  if (!sc->drefs)
680  return AVERROR(ENOMEM);
681  sc->drefs_count = entries;
682 
683  for (i = 0; i < entries; i++) {
684  MOVDref *dref = &sc->drefs[i];
685  uint32_t size = avio_rb32(pb);
686  int64_t next = avio_tell(pb);
687 
688  if (size < 12 || next < 0 || next > INT64_MAX - size)
689  return AVERROR_INVALIDDATA;
690 
691  next += size - 4;
692 
693  dref->type = avio_rl32(pb);
694  avio_rb32(pb); // version + flags
695 
696  if (dref->type == MKTAG('a','l','i','s') && size > 150) {
697  /* macintosh alias record */
698  uint16_t volume_len, len;
699  int16_t type;
700  int ret;
701 
702  avio_skip(pb, 10);
703 
704  volume_len = avio_r8(pb);
705  volume_len = FFMIN(volume_len, 27);
706  ret = ffio_read_size(pb, dref->volume, 27);
707  if (ret < 0)
708  return ret;
709  dref->volume[volume_len] = 0;
710  av_log(c->fc, AV_LOG_DEBUG, "volume %s, len %d\n", dref->volume, volume_len);
711 
712  avio_skip(pb, 12);
713 
714  len = avio_r8(pb);
715  len = FFMIN(len, 63);
716  ret = ffio_read_size(pb, dref->filename, 63);
717  if (ret < 0)
718  return ret;
719  dref->filename[len] = 0;
720  av_log(c->fc, AV_LOG_DEBUG, "filename %s, len %d\n", dref->filename, len);
721 
722  avio_skip(pb, 16);
723 
724  /* read next level up_from_alias/down_to_target */
725  dref->nlvl_from = avio_rb16(pb);
726  dref->nlvl_to = avio_rb16(pb);
727  av_log(c->fc, AV_LOG_DEBUG, "nlvl from %d, nlvl to %d\n",
728  dref->nlvl_from, dref->nlvl_to);
729 
730  avio_skip(pb, 16);
731 
732  for (type = 0; type != -1 && avio_tell(pb) < next; ) {
733  if (avio_feof(pb))
734  return AVERROR_EOF;
735  type = avio_rb16(pb);
736  len = avio_rb16(pb);
737  av_log(c->fc, AV_LOG_DEBUG, "type %d, len %d\n", type, len);
738  if (len&1)
739  len += 1;
740  if (type == 2) { // absolute path
741  av_free(dref->path);
742  dref->path = av_mallocz(len+1);
743  if (!dref->path)
744  return AVERROR(ENOMEM);
745 
746  ret = ffio_read_size(pb, dref->path, len);
747  if (ret < 0) {
748  av_freep(&dref->path);
749  return ret;
750  }
751  if (len > volume_len && !strncmp(dref->path, dref->volume, volume_len)) {
752  len -= volume_len;
753  memmove(dref->path, dref->path+volume_len, len);
754  dref->path[len] = 0;
755  }
756  // trim string of any ending zeros
757  for (j = len - 1; j >= 0; j--) {
758  if (dref->path[j] == 0)
759  len--;
760  else
761  break;
762  }
763  for (j = 0; j < len; j++)
764  if (dref->path[j] == ':' || dref->path[j] == 0)
765  dref->path[j] = '/';
766  av_log(c->fc, AV_LOG_DEBUG, "path %s\n", dref->path);
767  } else if (type == 0) { // directory name
768  av_free(dref->dir);
769  dref->dir = av_malloc(len+1);
770  if (!dref->dir)
771  return AVERROR(ENOMEM);
772 
773  ret = ffio_read_size(pb, dref->dir, len);
774  if (ret < 0) {
775  av_freep(&dref->dir);
776  return ret;
777  }
778  dref->dir[len] = 0;
779  for (j = 0; j < len; j++)
780  if (dref->dir[j] == ':')
781  dref->dir[j] = '/';
782  av_log(c->fc, AV_LOG_DEBUG, "dir %s\n", dref->dir);
783  } else
784  avio_skip(pb, len);
785  }
786  } else {
787  av_log(c->fc, AV_LOG_DEBUG, "Unknown dref type 0x%08"PRIx32" size %"PRIu32"\n",
788  dref->type, size);
789  entries--;
790  i--;
791  }
792  avio_seek(pb, next, SEEK_SET);
793  }
794  return 0;
795 }
796 
798 {
799  AVStream *st;
800  uint32_t type;
801  uint32_t ctype;
802  int64_t title_size;
803  char *title_str;
804  int ret;
805 
806  avio_r8(pb); /* version */
807  avio_rb24(pb); /* flags */
808 
809  /* component type */
810  ctype = avio_rl32(pb);
811  type = avio_rl32(pb); /* component subtype */
812 
813  av_log(c->fc, AV_LOG_TRACE, "ctype=%s\n", av_fourcc2str(ctype));
814  av_log(c->fc, AV_LOG_TRACE, "stype=%s\n", av_fourcc2str(type));
815 
816  if (c->trak_index < 0) { // meta not inside a trak
817  if (type == MKTAG('m','d','t','a')) {
818  c->found_hdlr_mdta = 1;
819  }
820  return 0;
821  }
822 
823  st = c->fc->streams[c->fc->nb_streams-1];
824 
825  if (type == MKTAG('v','i','d','e'))
827  else if (type == MKTAG('s','o','u','n'))
829  else if (type == MKTAG('m','1','a',' '))
831  else if ((type == MKTAG('s','u','b','p')) || (type == MKTAG('c','l','c','p')))
833 
834  avio_rb32(pb); /* component manufacture */
835  avio_rb32(pb); /* component flags */
836  avio_rb32(pb); /* component flags mask */
837 
838  title_size = atom.size - 24;
839  if (title_size > 0) {
840  if (title_size > FFMIN(INT_MAX, SIZE_MAX-1))
841  return AVERROR_INVALIDDATA;
842  title_str = av_malloc(title_size + 1); /* Add null terminator */
843  if (!title_str)
844  return AVERROR(ENOMEM);
845 
846  ret = ffio_read_size(pb, title_str, title_size);
847  if (ret < 0) {
848  av_freep(&title_str);
849  return ret;
850  }
851  title_str[title_size] = 0;
852  if (title_str[0]) {
853  int off = (!c->isom && title_str[0] == title_size - 1);
854  // flag added so as to not set stream handler name if already set from mdia->hdlr
855  av_dict_set(&st->metadata, "handler_name", title_str + off, AV_DICT_DONT_OVERWRITE);
856  }
857  av_freep(&title_str);
858  }
859 
860  return 0;
861 }
862 
864 {
865  return ff_mov_read_esds(c->fc, pb);
866 }
867 
869 {
870  AVStream *st;
871  AVPacketSideData *sd;
872  enum AVAudioServiceType *ast;
873  int ac3info, acmod, lfeon, bsmod;
874  uint64_t mask;
875 
876  if (c->fc->nb_streams < 1)
877  return 0;
878  st = c->fc->streams[c->fc->nb_streams-1];
879 
883  sizeof(*ast), 0);
884  if (!sd)
885  return AVERROR(ENOMEM);
886 
887  ast = (enum AVAudioServiceType*)sd->data;
888  ac3info = avio_rb24(pb);
889  bsmod = (ac3info >> 14) & 0x7;
890  acmod = (ac3info >> 11) & 0x7;
891  lfeon = (ac3info >> 10) & 0x1;
892 
894  if (lfeon)
898 
899  *ast = bsmod;
900  if (st->codecpar->ch_layout.nb_channels > 1 && bsmod == 0x7)
902 
903  return 0;
904 }
905 
906 #if CONFIG_IAMFDEC
907 static int mov_read_iacb(MOVContext *c, AVIOContext *pb, MOVAtom atom)
908 {
909  AVStream *st;
910  MOVStreamContext *sc;
911  FFIOContext b;
912  AVIOContext *descriptor_pb;
914  IAMFContext *iamf;
916  unsigned descriptors_size;
917  int nb_frames, disposition;
918  int version, ret;
919 
920  if (atom.size < 5)
921  return AVERROR_INVALIDDATA;
922 
923  if (c->fc->nb_streams < 1)
924  return 0;
925 
926  version = avio_r8(pb);
927  if (version != 1) {
928  av_log(c->fc, AV_LOG_ERROR, "%s configurationVersion %d",
929  version < 1 ? "invalid" : "unsupported", version);
930  return AVERROR_INVALIDDATA;
931  }
932 
933  descriptors_size = ffio_read_leb(pb);
934  if (!descriptors_size || descriptors_size > INT_MAX)
935  return AVERROR_INVALIDDATA;
936 
937  st = c->fc->streams[c->fc->nb_streams - 1];
938  sc = st->priv_data;
939 
940  if (st->codecpar->extradata) {
941  av_log(c->fc, AV_LOG_WARNING, "ignoring iacb\n");
942  return 0;
943  }
944 
945  sc->iamf = av_mallocz(sizeof(*sc->iamf));
946  if (!sc->iamf)
947  return AVERROR(ENOMEM);
948  iamf = &sc->iamf->iamf;
949 
950  ret = ff_alloc_extradata(st->codecpar, descriptors_size);
951  if (ret < 0)
952  return ret;
953 
954  ret = avio_read(pb, st->codecpar->extradata, descriptors_size);
955  if (ret != descriptors_size)
956  return ret < 0 ? ret : AVERROR_INVALIDDATA;
957 
958  ffio_init_read_context(&b, st->codecpar->extradata, descriptors_size);
959  descriptor_pb = &b.pub;
960 
961  ret = ff_iamfdec_read_descriptors(iamf, descriptor_pb, descriptors_size, c->fc);
962  if (ret < 0)
963  return ret;
964 
965  metadata = st->metadata;
966  st->metadata = NULL;
967  start_time = st->start_time;
968  nb_frames = st->nb_frames;
969  duration = st->duration;
970  disposition = st->disposition;
971 
972  for (int i = 0; i < iamf->nb_audio_elements; i++) {
973  IAMFAudioElement *audio_element = iamf->audio_elements[i];
974  const AVIAMFAudioElement *element;
975  AVStreamGroup *stg =
977 
978  if (!stg) {
979  ret = AVERROR(ENOMEM);
980  goto fail;
981  }
982 
984  stg->id = audio_element->audio_element_id;
985  /* Transfer ownership */
986  element = stg->params.iamf_audio_element = audio_element->element;
987  audio_element->element = NULL;
988 
989  for (int j = 0; j < audio_element->nb_substreams; j++) {
990  IAMFSubStream *substream = &audio_element->substreams[j];
991  AVStream *stream;
992 
993  if (!i && !j) {
994  if (audio_element->layers[0].substream_count != 1)
995  disposition &= ~AV_DISPOSITION_DEFAULT;
996  stream = st;
997  } else
998  stream = avformat_new_stream(c->fc, NULL);
999  if (!stream) {
1000  ret = AVERROR(ENOMEM);
1001  goto fail;
1002  }
1003 
1004  stream->start_time = start_time;
1005  stream->nb_frames = nb_frames;
1006  stream->duration = duration;
1007  stream->disposition = disposition;
1008  if (stream != st) {
1009  stream->priv_data = sc;
1010  sc->refcount++;
1011  }
1012 
1015  if (i || j) {
1017  if (audio_element->layers[0].substream_count == 1)
1018  stream->disposition &= ~AV_DISPOSITION_DEFAULT;
1019  }
1020 
1021  ret = avcodec_parameters_copy(stream->codecpar, substream->codecpar);
1022  if (ret < 0)
1023  goto fail;
1024 
1025  stream->id = substream->audio_substream_id;
1026 
1027  avpriv_set_pts_info(st, 64, 1, sc->time_scale);
1028 
1029  ret = avformat_stream_group_add_stream(stg, stream);
1030  if (ret < 0)
1031  goto fail;
1032  }
1033 
1034  ret = av_dict_copy(&stg->metadata, metadata, 0);
1035  if (ret < 0)
1036  goto fail;
1037  }
1038 
1039  for (int i = 0; i < iamf->nb_mix_presentations; i++) {
1040  IAMFMixPresentation *mix_presentation = iamf->mix_presentations[i];
1041  const AVIAMFMixPresentation *mix = mix_presentation->cmix;
1042  AVStreamGroup *stg =
1044 
1045  if (!stg) {
1046  ret = AVERROR(ENOMEM);
1047  goto fail;
1048  }
1049 
1051  stg->id = mix_presentation->mix_presentation_id;
1052  /* Transfer ownership */
1053  stg->params.iamf_mix_presentation = mix_presentation->mix;
1054  mix_presentation->mix = NULL;
1055 
1056  for (int j = 0; j < mix->nb_submixes; j++) {
1057  const AVIAMFSubmix *submix = mix->submixes[j];
1058 
1059  for (int k = 0; k < submix->nb_elements; k++) {
1060  const AVIAMFSubmixElement *submix_element = submix->elements[k];
1061  const AVStreamGroup *audio_element = NULL;
1062 
1063  for (int l = 0; l < c->fc->nb_stream_groups; l++)
1064  if (c->fc->stream_groups[l]->type == AV_STREAM_GROUP_PARAMS_IAMF_AUDIO_ELEMENT &&
1065  c->fc->stream_groups[l]->id == submix_element->audio_element_id) {
1066  audio_element = c->fc->stream_groups[l];
1067  break;
1068  }
1069  av_assert0(audio_element);
1070 
1071  for (int l = 0; l < audio_element->nb_streams; l++) {
1072  ret = avformat_stream_group_add_stream(stg, audio_element->streams[l]);
1073  if (ret < 0 && ret != AVERROR(EEXIST))
1074  goto fail;
1075  }
1076  }
1077  }
1078 
1079  ret = av_dict_copy(&stg->metadata, metadata, 0);
1080  if (ret < 0)
1081  goto fail;
1082  }
1083 
1084  ret = 0;
1085 fail:
1087 
1088  return ret;
1089 }
1090 #endif
1091 
1093 {
1094  AVStream *st;
1095  int32_t sample_rate;
1096 
1097  if (atom.size < 8 || c->fc->nb_streams < 1)
1098  return 0;
1099 
1100  st = c->fc->streams[c->fc->nb_streams-1];
1101  if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO) {
1102  av_log(c->fc, AV_LOG_WARNING, "'srat' within non-audio sample entry, skip\n");
1103  return 0;
1104  }
1105 
1106  if (!c->isom) {
1107  av_log(c->fc, AV_LOG_WARNING, "'srat' within non-isom, skip\n");
1108  return 0;
1109  }
1110 
1111  avio_skip(pb, 4); // version+flags
1112  sample_rate = avio_rb32(pb);
1113  if (sample_rate > 0) {
1114  av_log(c->fc, AV_LOG_DEBUG,
1115  "overwrite sample rate from %d to %d by 'srat'\n",
1116  st->codecpar->sample_rate, sample_rate);
1117  st->codecpar->sample_rate = sample_rate;
1118  } else {
1119  av_log(c->fc, AV_LOG_WARNING,
1120  "ignore invalid sample rate %d in 'srat'\n", sample_rate);
1121  }
1122 
1123  return 0;
1124 }
1125 
1127 {
1128  AVStream *st;
1129  AVPacketSideData *sd;
1130  enum AVAudioServiceType *ast;
1131  int eac3info, acmod, lfeon, bsmod;
1132  uint64_t mask;
1133 
1134  if (c->fc->nb_streams < 1)
1135  return 0;
1136  st = c->fc->streams[c->fc->nb_streams-1];
1137 
1141  sizeof(*ast), 0);
1142  if (!sd)
1143  return AVERROR(ENOMEM);
1144 
1145  ast = (enum AVAudioServiceType*)sd->data;
1146 
1147  /* No need to parse fields for additional independent substreams and its
1148  * associated dependent substreams since libavcodec's E-AC-3 decoder
1149  * does not support them yet. */
1150  avio_rb16(pb); /* data_rate and num_ind_sub */
1151  eac3info = avio_rb24(pb);
1152  bsmod = (eac3info >> 12) & 0x1f;
1153  acmod = (eac3info >> 9) & 0x7;
1154  lfeon = (eac3info >> 8) & 0x1;
1155 
1157  if (lfeon)
1161 
1162  *ast = bsmod;
1163  if (st->codecpar->ch_layout.nb_channels > 1 && bsmod == 0x7)
1165 
1166  return 0;
1167 }
1168 
1169 /* Maps the DTS `StreamConstruction` field (ETSI TS 102 114 Table E-2) to the
1170  * coarse FFmpeg DTS profile enum. Extension-substream XLL maps to HD_MA;
1171  * extension-substream XXCH, X96, or XBR maps to HD_HRA; core-substream XCH or
1172  * XXCH maps to ES; core-substream X96 maps to 96/24; a core component alone
1173  * maps to DTS; and extension-substream LBR maps to Express. Value 0 (undefined)
1174  * and values outside 1..21 map to AV_PROFILE_UNKNOWN. */
1175 static int mov_dts_stream_construction_to_profile(unsigned int sc)
1176 {
1177  static const int profile[22] = {
1178  [ 1] = AV_PROFILE_DTS, /* core Core */
1179  [ 2] = AV_PROFILE_DTS_ES, /* core Core + core XCH */
1180  [ 3] = AV_PROFILE_DTS_ES, /* core Core + core XXCH */
1181  [ 4] = AV_PROFILE_DTS_96_24, /* core Core + core X96 */
1182  [ 5] = AV_PROFILE_DTS_HD_HRA, /* core Core + ext XXCH */
1183  [ 6] = AV_PROFILE_DTS_HD_HRA, /* core Core + ext XBR */
1184  [ 7] = AV_PROFILE_DTS_HD_HRA, /* core Core + core XCH + ext XBR */
1185  [ 8] = AV_PROFILE_DTS_HD_HRA, /* core Core + core XXCH + ext XBR */
1186  [ 9] = AV_PROFILE_DTS_HD_HRA, /* core Core + ext XXCH + ext XBR */
1187  [10] = AV_PROFILE_DTS_HD_HRA, /* core Core + ext X96 */
1188  [11] = AV_PROFILE_DTS_HD_HRA, /* core Core + core XCH + ext X96 */
1189  [12] = AV_PROFILE_DTS_HD_HRA, /* core Core + core XXCH + ext X96 */
1190  [13] = AV_PROFILE_DTS_HD_HRA, /* core Core + ext XXCH + ext X96 */
1191  [14] = AV_PROFILE_DTS_HD_MA, /* core Core + ext XLL */
1192  [15] = AV_PROFILE_DTS_HD_MA, /* core Core + core XCH + ext XLL */
1193  [16] = AV_PROFILE_DTS_HD_MA, /* core Core + core X96 + ext XLL */
1194  [17] = AV_PROFILE_DTS_HD_MA, /* ext XLL */
1195  [18] = AV_PROFILE_DTS_EXPRESS, /* ext LBR */
1196  [19] = AV_PROFILE_DTS, /* ext Core */
1197  [20] = AV_PROFILE_DTS_HD_HRA, /* ext Core + ext XXCH */
1198  [21] = AV_PROFILE_DTS_HD_MA, /* ext Core + ext XLL */
1199  };
1200  if (!sc || sc > 21)
1201  return AV_PROFILE_UNKNOWN;
1202  return profile[sc];
1203 }
1204 
1205 /* Maps the 16-bit DTS `ChannelLayout` bitmask (ETSI TS 102 114 Table E-5) to an
1206  * ffmpeg channel mask. Pair bits follow Table 7-10 / DCA_SPEAKER_PAIR_*;
1207  * LwRw (0x0400) and LssRss (0x0800) must not collapse onto SIDE like LsRs. */
1208 static uint64_t mov_dts_channel_layout_to_mask(unsigned int code)
1209 {
1210  static const struct { unsigned int dts; uint64_t av; } map[] = {
1211  { 0x0001, AV_CH_FRONT_CENTER },
1212  { 0x0002, AV_CH_FRONT_LEFT | AV_CH_FRONT_RIGHT },
1213  { 0x0004, AV_CH_SIDE_LEFT | AV_CH_SIDE_RIGHT },
1214  { 0x0008, AV_CH_LOW_FREQUENCY },
1215  { 0x0010, AV_CH_BACK_CENTER },
1217  { 0x0040, AV_CH_BACK_LEFT | AV_CH_BACK_RIGHT },
1218  { 0x0080, AV_CH_TOP_FRONT_CENTER },
1219  { 0x0100, AV_CH_TOP_CENTER },
1221  { 0x0400, AV_CH_WIDE_LEFT | AV_CH_WIDE_RIGHT },
1223  { 0x1000, AV_CH_LOW_FREQUENCY_2 },
1225  { 0x4000, AV_CH_TOP_BACK_CENTER },
1227  };
1228  uint64_t mask = 0;
1229  int i;
1230  for (i = 0; i < FF_ARRAY_ELEMS(map); i++)
1231  if (code & map[i].dts)
1232  mask |= map[i].av;
1233  return mask;
1234 }
1235 
1237 {
1238 #define DDTS_SIZE 20
1239  uint8_t buf[DDTS_SIZE + AV_INPUT_BUFFER_PADDING_SIZE];
1240  AVStream *st = NULL;
1241  uint32_t frame_duration_code = 0;
1242  uint32_t channel_layout_code = 0;
1243  uint64_t channel_layout_mask;
1244  unsigned int stream_construction;
1245  unsigned int representation_type;
1246  GetBitContext gb;
1247  int ret;
1248 
1249  if ((ret = ffio_read_size(pb, buf, DDTS_SIZE)) < 0)
1250  return ret;
1251 
1252  init_get_bits(&gb, buf, 8 * DDTS_SIZE);
1253 
1254  if (c->fc->nb_streams < 1) {
1255  return 0;
1256  }
1257  st = c->fc->streams[c->fc->nb_streams-1];
1258 
1259  st->codecpar->sample_rate = get_bits_long(&gb, 32);
1260  if (st->codecpar->sample_rate <= 0) {
1261  av_log(c->fc, AV_LOG_ERROR, "Invalid sample rate %d\n", st->codecpar->sample_rate);
1262  return AVERROR_INVALIDDATA;
1263  }
1264  skip_bits_long(&gb, 32); /* max bitrate */
1265  st->codecpar->bit_rate = get_bits_long(&gb, 32);
1266  st->codecpar->bits_per_coded_sample = get_bits(&gb, 8);
1267  frame_duration_code = get_bits(&gb, 2);
1268  stream_construction = get_bits(&gb, 5); /* Table E-2 - profile source */
1269  skip_bits(&gb, 1); /* CoreLFEPresent */
1270  skip_bits(&gb, 6); /* CoreLayout */
1271  skip_bits(&gb, 14); /* CoreSize */
1272  skip_bits(&gb, 1); /* StereoDownmix */
1273  representation_type = get_bits(&gb, 3);
1274  channel_layout_code = get_bits(&gb, 16);
1275 
1276  st->codecpar->frame_size =
1277  (frame_duration_code == 0) ? 512 :
1278  (frame_duration_code == 1) ? 1024 :
1279  (frame_duration_code == 2) ? 2048 :
1280  (frame_duration_code == 3) ? 4096 : 0;
1281 
1282  /* Publish StreamConstruction as codecpar->profile, including for encrypted
1283  * tracks where frame headers cannot be inspected. */
1284  st->codecpar->profile = mov_dts_stream_construction_to_profile(stream_construction);
1285 
1286  channel_layout_mask = mov_dts_channel_layout_to_mask(channel_layout_code);
1287  if (channel_layout_mask) {
1289  av_channel_layout_from_mask(&st->codecpar->ch_layout, channel_layout_mask);
1290  } else if (representation_type == 2 || representation_type == 3) {
1293  }
1294 
1295  return 0;
1296 }
1297 
1299 {
1300  AVStream *st;
1301 
1302  if (c->fc->nb_streams < 1)
1303  return 0;
1304  st = c->fc->streams[c->fc->nb_streams-1];
1305 
1306  if (atom.size < 16)
1307  return 0;
1308 
1309  /* skip version and flags */
1310  avio_skip(pb, 4);
1311 
1312  ff_mov_read_chan(c->fc, pb, st, atom.size - 4);
1313 
1314  return 0;
1315 }
1316 
1318 {
1319  int64_t end = av_sat_add64(avio_tell(pb), atom.size);
1320  int version, flags;
1321  int ret;
1322  AVStream *st;
1323 
1324  if (c->fc->nb_streams < 1)
1325  return 0;
1326  st = c->fc->streams[c->fc->nb_streams-1];
1327 
1328  version = avio_r8(pb);
1329  flags = avio_rb24(pb);
1330  if (version > 1 || flags != 0) {
1331  av_log(c->fc, AV_LOG_WARNING,
1332  "Unsupported 'chnl' box with version %d, flags: %#x\n",
1333  version, flags);
1334  return 0;
1335  }
1336 
1337  ret = ff_mov_read_chnl(c->fc, pb, st, version);
1338  if (ret < 0) {
1339  avio_seek(pb, end, SEEK_SET);
1340  return 0;
1341  }
1342 
1343  if (avio_tell(pb) != end) {
1344  av_log(c->fc, AV_LOG_WARNING, "skip %" PRId64 " bytes of unknown data inside chnl\n",
1345  end - avio_tell(pb));
1346  avio_seek(pb, end, SEEK_SET);
1347  }
1348  return ret;
1349 }
1350 
1352 {
1353  AVStream *st;
1354  int ret;
1355 
1356  if (c->fc->nb_streams < 1)
1357  return 0;
1358  st = c->fc->streams[c->fc->nb_streams-1];
1359 
1360  if ((ret = ff_get_wav_header(c->fc, pb, st->codecpar, atom.size, 0)) < 0)
1361  av_log(c->fc, AV_LOG_WARNING, "get_wav_header failed\n");
1362 
1363  return ret;
1364 }
1365 
1367 {
1368  AVStream *st;
1369  HEIFItem *item;
1370  AVPacketSideData *sd;
1371  int width, height, err = 0;
1372  AVRational aperture_width, aperture_height, horiz_off, vert_off;
1373  AVRational pc_x, pc_y;
1374  uint64_t top, bottom, left, right;
1375 
1376  item = get_heif_item(c, c->cur_item_id);
1377  st = get_curr_st(c);
1378  if (!st)
1379  return 0;
1380 
1381  width = st->codecpar->width;
1382  height = st->codecpar->height;
1383  if ((!width || !height) && item) {
1384  width = item->width;
1385  height = item->height;
1386  }
1387  if (!width || !height) {
1388  err = AVERROR_INVALIDDATA;
1389  goto fail;
1390  }
1391 
1392  aperture_width.num = avio_rb32(pb);
1393  aperture_width.den = avio_rb32(pb);
1394  aperture_height.num = avio_rb32(pb);
1395  aperture_height.den = avio_rb32(pb);
1396 
1397  horiz_off.num = avio_rb32(pb);
1398  horiz_off.den = avio_rb32(pb);
1399  vert_off.num = avio_rb32(pb);
1400  vert_off.den = avio_rb32(pb);
1401 
1402  if (aperture_width.num < 0 || aperture_width.den < 0 ||
1403  aperture_height.num < 0 || aperture_height.den < 0 ||
1404  horiz_off.den < 0 || vert_off.den < 0) {
1405  err = AVERROR_INVALIDDATA;
1406  goto fail;
1407  }
1408  if ((av_cmp_q((AVRational) { width, 1 }, aperture_width) < 0) ||
1409  (av_cmp_q((AVRational) { height, 1 }, aperture_height) < 0)) {
1410  err = AVERROR_INVALIDDATA;
1411  goto fail;
1412  }
1413  av_log(c->fc, AV_LOG_TRACE, "clap: apertureWidth %d/%d, apertureHeight %d/%d "
1414  "horizOff %d/%d vertOff %d/%d\n",
1415  aperture_width.num, aperture_width.den, aperture_height.num, aperture_height.den,
1416  horiz_off.num, horiz_off.den, vert_off.num, vert_off.den);
1417 
1418  pc_x = av_mul_q((AVRational) { width - 1, 1 }, (AVRational) { 1, 2 });
1419  pc_x = av_add_q(pc_x, horiz_off);
1420  pc_y = av_mul_q((AVRational) { height - 1, 1 }, (AVRational) { 1, 2 });
1421  pc_y = av_add_q(pc_y, vert_off);
1422 
1423  aperture_width = av_sub_q(aperture_width, (AVRational) { 1, 1 });
1424  aperture_width = av_mul_q(aperture_width, (AVRational) { 1, 2 });
1425  aperture_height = av_sub_q(aperture_height, (AVRational) { 1, 1 });
1426  aperture_height = av_mul_q(aperture_height, (AVRational) { 1, 2 });
1427 
1428  left = av_q2d(av_sub_q(pc_x, aperture_width));
1429  right = av_q2d(av_add_q(pc_x, aperture_width));
1430  top = av_q2d(av_sub_q(pc_y, aperture_height));
1431  bottom = av_q2d(av_add_q(pc_y, aperture_height));
1432 
1433  if (bottom > (height - 1) ||
1434  right > (width - 1)) {
1435  err = AVERROR_INVALIDDATA;
1436  goto fail;
1437  }
1438 
1439  bottom = height - 1 - bottom;
1440  right = width - 1 - right;
1441 
1442  if (!(left | right | top | bottom))
1443  return 0;
1444 
1445  if ((left + right) >= width ||
1446  (top + bottom) >= height) {
1447  err = AVERROR_INVALIDDATA;
1448  goto fail;
1449  }
1450 
1454  sizeof(uint32_t) * 4, 0);
1455  if (!sd)
1456  return AVERROR(ENOMEM);
1457 
1458  AV_WL32A(sd->data, top);
1459  AV_WL32A(sd->data + 4, bottom);
1460  AV_WL32A(sd->data + 8, left);
1461  AV_WL32A(sd->data + 12, right);
1462 
1463 fail:
1464  if (err < 0) {
1465  int explode = !!(c->fc->error_recognition & AV_EF_EXPLODE);
1466  av_log(c->fc, explode ? AV_LOG_ERROR : AV_LOG_WARNING, "Invalid clap box\n");
1467  if (!explode)
1468  err = 0;
1469  }
1470 
1471  return err;
1472 }
1473 
1474 /* This atom overrides any previously set aspect ratio */
1476 {
1477  const int num = avio_rb32(pb);
1478  const int den = avio_rb32(pb);
1479  AVStream *st;
1480  MOVStreamContext *sc;
1481 
1482  if (c->fc->nb_streams < 1)
1483  return 0;
1484  st = c->fc->streams[c->fc->nb_streams-1];
1485  sc = st->priv_data;
1486 
1487  av_log(c->fc, AV_LOG_TRACE, "pasp: hSpacing %d, vSpacing %d\n", num, den);
1488 
1489  if (den != 0) {
1490  sc->h_spacing = num;
1491  sc->v_spacing = den;
1492  }
1493  return 0;
1494 }
1495 
1496 /* this atom contains actual media data */
1498 {
1499  if (atom.size == 0) /* wrong one (MP4) */
1500  return 0;
1501  c->found_mdat=1;
1502  return 0; /* now go for moov */
1503 }
1504 
1505 #define DRM_BLOB_SIZE 56
1506 
1508 {
1509  uint8_t intermediate_key[20];
1510  uint8_t intermediate_iv[20];
1511  uint8_t input[64];
1512  uint8_t output[64];
1513  uint8_t file_checksum[20];
1514  uint8_t calculated_checksum[20];
1515  char checksum_string[2 * sizeof(file_checksum) + 1];
1516  struct AVSHA *sha;
1517  int i;
1518  int ret = 0;
1519  uint8_t *activation_bytes = c->activation_bytes;
1520  uint8_t *fixed_key = c->audible_fixed_key;
1521 
1522  c->aax_mode = 1;
1523 
1524  sha = av_sha_alloc();
1525  if (!sha)
1526  return AVERROR(ENOMEM);
1527  av_free(c->aes_decrypt);
1528  c->aes_decrypt = av_aes_alloc();
1529  if (!c->aes_decrypt) {
1530  ret = AVERROR(ENOMEM);
1531  goto fail;
1532  }
1533 
1534  /* drm blob processing */
1535  avio_read(pb, output, 8); // go to offset 8, absolute position 0x251
1537  avio_read(pb, output, 4); // go to offset 4, absolute position 0x28d
1538  ret = ffio_read_size(pb, file_checksum, 20);
1539  if (ret < 0)
1540  goto fail;
1541 
1542  // required by external tools
1543  ff_data_to_hex(checksum_string, file_checksum, sizeof(file_checksum), 1);
1544  av_log(c->fc, AV_LOG_INFO, "[aax] file checksum == %s\n", checksum_string);
1545 
1546  /* verify activation data */
1547  if (!activation_bytes) {
1548  av_log(c->fc, AV_LOG_WARNING, "[aax] activation_bytes option is missing!\n");
1549  ret = 0; /* allow ffprobe to continue working on .aax files */
1550  goto fail;
1551  }
1552  if (c->activation_bytes_size != 4) {
1553  av_log(c->fc, AV_LOG_FATAL, "[aax] activation_bytes value needs to be 4 bytes!\n");
1554  ret = AVERROR(EINVAL);
1555  goto fail;
1556  }
1557 
1558  /* verify fixed key */
1559  if (c->audible_fixed_key_size != 16) {
1560  av_log(c->fc, AV_LOG_FATAL, "[aax] audible_fixed_key value needs to be 16 bytes!\n");
1561  ret = AVERROR(EINVAL);
1562  goto fail;
1563  }
1564 
1565  /* AAX (and AAX+) key derivation */
1566  av_sha_init(sha, 160);
1567  av_sha_update(sha, fixed_key, 16);
1568  av_sha_update(sha, activation_bytes, 4);
1569  av_sha_final(sha, intermediate_key);
1570  av_sha_init(sha, 160);
1571  av_sha_update(sha, fixed_key, 16);
1572  av_sha_update(sha, intermediate_key, 20);
1573  av_sha_update(sha, activation_bytes, 4);
1574  av_sha_final(sha, intermediate_iv);
1575  av_sha_init(sha, 160);
1576  av_sha_update(sha, intermediate_key, 16);
1577  av_sha_update(sha, intermediate_iv, 16);
1578  av_sha_final(sha, calculated_checksum);
1579  if (memcmp(calculated_checksum, file_checksum, 20)) { // critical error
1580  av_log(c->fc, AV_LOG_ERROR, "[aax] mismatch in checksums!\n");
1582  goto fail;
1583  }
1584  av_aes_init(c->aes_decrypt, intermediate_key, 128, 1);
1585  av_aes_crypt(c->aes_decrypt, output, input, DRM_BLOB_SIZE >> 4, intermediate_iv, 1);
1586  for (i = 0; i < 4; i++) {
1587  // file data (in output) is stored in big-endian mode
1588  if (activation_bytes[i] != output[3 - i]) { // critical error
1589  av_log(c->fc, AV_LOG_ERROR, "[aax] error in drm blob decryption!\n");
1591  goto fail;
1592  }
1593  }
1594  memcpy(c->file_key, output + 8, 16);
1595  memcpy(input, output + 26, 16);
1596  av_sha_init(sha, 160);
1597  av_sha_update(sha, input, 16);
1598  av_sha_update(sha, c->file_key, 16);
1599  av_sha_update(sha, fixed_key, 16);
1600  av_sha_final(sha, c->file_iv);
1601 
1602 fail:
1603  av_free(sha);
1604 
1605  return ret;
1606 }
1607 
1609 {
1610  if (c->audible_key_size != 16) {
1611  av_log(c->fc, AV_LOG_FATAL, "[aaxc] audible_key value needs to be 16 bytes!\n");
1612  return AVERROR(EINVAL);
1613  }
1614 
1615  if (c->audible_iv_size != 16) {
1616  av_log(c->fc, AV_LOG_FATAL, "[aaxc] audible_iv value needs to be 16 bytes!\n");
1617  return AVERROR(EINVAL);
1618  }
1619 
1620  c->aes_decrypt = av_aes_alloc();
1621  if (!c->aes_decrypt) {
1622  return AVERROR(ENOMEM);
1623  }
1624 
1625  memcpy(c->file_key, c->audible_key, 16);
1626  memcpy(c->file_iv, c->audible_iv, 16);
1627  c->aax_mode = 1;
1628 
1629  return 0;
1630 }
1631 
1632 // Audible AAX (and AAX+) bytestream decryption
1633 static int aax_filter(uint8_t *input, int size, MOVContext *c)
1634 {
1635  int blocks = 0;
1636  unsigned char iv[16];
1637 
1638  memcpy(iv, c->file_iv, 16); // iv is overwritten
1639  blocks = size >> 4; // trailing bytes are not encrypted!
1640  av_aes_init(c->aes_decrypt, c->file_key, 128, 1);
1641  av_aes_crypt(c->aes_decrypt, input, input, blocks, iv, 1);
1642 
1643  return 0;
1644 }
1645 
1646 /* read major brand, minor version and compatible brands and store them as metadata */
1648 {
1649  uint32_t minor_ver;
1650  int comp_brand_size;
1651  char* comp_brands_str;
1652  uint8_t type[5] = {0};
1653  int ret = ffio_read_size(pb, type, 4);
1654  if (ret < 0)
1655  return ret;
1656  if (c->fc->nb_streams) {
1657  if (c->fc->strict_std_compliance >= FF_COMPLIANCE_STRICT)
1658  return AVERROR_INVALIDDATA;
1659  av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate FTYP\n");
1660  return 0;
1661  }
1662 
1663  if (strcmp(type, "qt "))
1664  c->isom = 1;
1665  av_log(c->fc, AV_LOG_DEBUG, "ISO: File Type Major Brand: %.4s\n",(char *)&type);
1666  av_dict_set(&c->fc->metadata, "major_brand", type, 0);
1667  minor_ver = avio_rb32(pb); /* minor version */
1668  av_dict_set_int(&c->fc->metadata, "minor_version", minor_ver, 0);
1669 
1670  comp_brand_size = atom.size - 8;
1671  if (comp_brand_size < 0 || comp_brand_size == INT_MAX)
1672  return AVERROR_INVALIDDATA;
1673  comp_brands_str = av_malloc(comp_brand_size + 1); /* Add null terminator */
1674  if (!comp_brands_str)
1675  return AVERROR(ENOMEM);
1676 
1677  ret = ffio_read_size(pb, comp_brands_str, comp_brand_size);
1678  if (ret < 0) {
1679  av_freep(&comp_brands_str);
1680  return ret;
1681  }
1682  comp_brands_str[comp_brand_size] = 0;
1683  av_dict_set(&c->fc->metadata, "compatible_brands",
1684  comp_brands_str, AV_DICT_DONT_STRDUP_VAL);
1685 
1686  // Logic for handling Audible's .aaxc files
1687  if (!strcmp(type, "aaxc")) {
1688  mov_aaxc_crypto(c);
1689  }
1690 
1691  return 0;
1692 }
1693 
1694 /* this atom should contain all header atoms */
1696 {
1697  int ret;
1698 
1699  if (c->found_moov) {
1700  av_log(c->fc, AV_LOG_WARNING, "Found duplicated MOOV Atom. Skipped it\n");
1701  avio_skip(pb, atom.size);
1702  return 0;
1703  }
1704 
1705  if ((ret = mov_read_default(c, pb, atom)) < 0)
1706  return ret;
1707  /* we parsed the 'moov' atom, we can terminate the parsing as soon as we find the 'mdat' */
1708  /* so we don't parse the whole file if over a network */
1709  c->found_moov=1;
1710  return 0; /* now go for mdat */
1711 }
1712 
1714  MOVFragmentIndex *frag_index,
1715  int index,
1716  int id)
1717 {
1718  int i;
1719  MOVFragmentIndexItem * item;
1720 
1721  if (index < 0 || index >= frag_index->nb_items)
1722  return NULL;
1723  item = &frag_index->item[index];
1724  for (i = 0; i < item->nb_stream_info; i++)
1725  if (item->stream_info[i].id == id)
1726  return &item->stream_info[i];
1727 
1728  // This shouldn't happen
1729  return NULL;
1730 }
1731 
1732 static void set_frag_stream(MOVFragmentIndex *frag_index, int id)
1733 {
1734  int i;
1735  MOVFragmentIndexItem * item;
1736 
1737  if (frag_index->current < 0 ||
1738  frag_index->current >= frag_index->nb_items)
1739  return;
1740 
1741  item = &frag_index->item[frag_index->current];
1742  for (i = 0; i < item->nb_stream_info; i++)
1743  if (item->stream_info[i].id == id) {
1744  item->current = i;
1745  return;
1746  }
1747 
1748  // id not found. This shouldn't happen.
1749  item->current = -1;
1750 }
1751 
1753  MOVFragmentIndex *frag_index)
1754 {
1755  MOVFragmentIndexItem *item;
1756  if (frag_index->current < 0 ||
1757  frag_index->current >= frag_index->nb_items)
1758  return NULL;
1759 
1760  item = &frag_index->item[frag_index->current];
1761  if (item->current >= 0 && item->current < item->nb_stream_info)
1762  return &item->stream_info[item->current];
1763 
1764  // This shouldn't happen
1765  return NULL;
1766 }
1767 
1769 {
1770  int a, b, m;
1771  int64_t moof_offset;
1772 
1773  // Optimize for appending new entries
1774  if (!frag_index->nb_items ||
1775  frag_index->item[frag_index->nb_items - 1].moof_offset < offset)
1776  return frag_index->nb_items;
1777 
1778  a = -1;
1779  b = frag_index->nb_items;
1780 
1781  while (b - a > 1) {
1782  m = (a + b) >> 1;
1783  moof_offset = frag_index->item[m].moof_offset;
1784  if (moof_offset >= offset)
1785  b = m;
1786  if (moof_offset <= offset)
1787  a = m;
1788  }
1789  return b;
1790 }
1791 
1793 {
1794  av_assert0(frag_stream_info);
1795  if (frag_stream_info->sidx_pts != AV_NOPTS_VALUE)
1796  return frag_stream_info->sidx_pts;
1797  if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE)
1798  return frag_stream_info->first_tfra_pts;
1799  return frag_stream_info->tfdt_dts;
1800 }
1801 
1803  MOVFragmentIndex *frag_index, int index)
1804 {
1805  MOVFragmentStreamInfo * frag_stream_info;
1806  MOVStreamContext *sc = dst_st->priv_data;
1807  int64_t timestamp;
1808  int i, j;
1809 
1810  // If the stream is referenced by any sidx, limit the search
1811  // to fragments that referenced this stream in the sidx
1812  if (sc->has_sidx) {
1813  frag_stream_info = get_frag_stream_info(frag_index, index, sc->id);
1814  if (!frag_stream_info)
1815  return AV_NOPTS_VALUE;
1816  if (frag_stream_info->sidx_pts != AV_NOPTS_VALUE)
1817  return frag_stream_info->sidx_pts;
1818  if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE)
1819  return frag_stream_info->first_tfra_pts;
1820  return frag_stream_info->sidx_pts;
1821  }
1822 
1823  for (i = 0; i < frag_index->item[index].nb_stream_info; i++) {
1824  if (dst_st->id != frag_index->item[index].stream_info[i].id)
1825  continue;
1826  AVStream *frag_stream = NULL;
1827  frag_stream_info = &frag_index->item[index].stream_info[i];
1828  for (j = 0; j < s->nb_streams; j++) {
1829  MOVStreamContext *sc2 = s->streams[j]->priv_data;
1830  if (sc2->id == frag_stream_info->id)
1831  frag_stream = s->streams[j];
1832  }
1833  if (!frag_stream) {
1834  av_log(s, AV_LOG_WARNING, "No stream matching sidx ID found.\n");
1835  continue;
1836  }
1837  timestamp = get_stream_info_time(frag_stream_info);
1838  if (timestamp != AV_NOPTS_VALUE)
1839  return av_rescale_q(timestamp, frag_stream->time_base, dst_st->time_base);
1840  }
1841  return AV_NOPTS_VALUE;
1842 }
1843 
1845  AVStream *st, int64_t timestamp)
1846 {
1847  int a, b, m, m0;
1848  int64_t frag_time;
1849 
1850  a = -1;
1851  b = frag_index->nb_items;
1852 
1853  while (b - a > 1) {
1854  m0 = m = (a + b) >> 1;
1855 
1856  while (m < b &&
1857  (frag_time = get_frag_time(s, st, frag_index, m)) == AV_NOPTS_VALUE)
1858  m++;
1859 
1860  if (m < b && frag_time <= timestamp)
1861  a = m;
1862  else
1863  b = m0;
1864  }
1865 
1866  return a;
1867 }
1868 
1870 {
1871  int index, i;
1872  MOVFragmentIndexItem * item;
1873  MOVFragmentStreamInfo * frag_stream_info;
1874 
1875  // If moof_offset already exists in frag_index, return index to it
1876  index = search_frag_moof_offset(&c->frag_index, offset);
1877  if (index < c->frag_index.nb_items &&
1878  c->frag_index.item[index].moof_offset == offset)
1879  return index;
1880 
1881  // offset is not yet in frag index.
1882  // Insert new item at index (sorted by moof offset)
1883  item = av_fast_realloc(c->frag_index.item,
1884  &c->frag_index.allocated_size,
1885  (c->frag_index.nb_items + 1) *
1886  sizeof(*c->frag_index.item));
1887  if (!item)
1888  return -1;
1889  c->frag_index.item = item;
1890 
1891  frag_stream_info = av_realloc_array(NULL, c->fc->nb_streams,
1892  sizeof(*item->stream_info));
1893  if (!frag_stream_info)
1894  return -1;
1895 
1896  for (i = 0; i < c->fc->nb_streams; i++) {
1897  // Avoid building frag index if streams lack track id.
1898  MOVStreamContext *sc = c->fc->streams[i]->priv_data;
1899  if (sc->id < 0) {
1900  av_free(frag_stream_info);
1901  return AVERROR_INVALIDDATA;
1902  }
1903 
1904  frag_stream_info[i].id = sc->id;
1905  frag_stream_info[i].sidx_pts = AV_NOPTS_VALUE;
1906  frag_stream_info[i].tfdt_dts = AV_NOPTS_VALUE;
1907  frag_stream_info[i].next_trun_dts = AV_NOPTS_VALUE;
1908  frag_stream_info[i].first_tfra_pts = AV_NOPTS_VALUE;
1909  frag_stream_info[i].index_base = -1;
1910  frag_stream_info[i].index_entry = -1;
1911  frag_stream_info[i].encryption_index = NULL;
1912  frag_stream_info[i].stsd_id = -1;
1913  }
1914 
1915  if (index < c->frag_index.nb_items)
1916  memmove(c->frag_index.item + index + 1, c->frag_index.item + index,
1917  (c->frag_index.nb_items - index) * sizeof(*c->frag_index.item));
1918 
1919  item = &c->frag_index.item[index];
1920  item->headers_read = 0;
1921  item->current = 0;
1922  item->nb_stream_info = c->fc->nb_streams;
1923  item->moof_offset = offset;
1924  item->stream_info = frag_stream_info;
1925  c->frag_index.nb_items++;
1926 
1927  return index;
1928 }
1929 
1930 static void fix_frag_index_entries(MOVFragmentIndex *frag_index, int index,
1931  int id, int entries)
1932 {
1933  int i;
1934  MOVFragmentStreamInfo * frag_stream_info;
1935 
1936  if (index < 0)
1937  return;
1938  for (i = index; i < frag_index->nb_items; i++) {
1939  frag_stream_info = get_frag_stream_info(frag_index, i, id);
1940  if (frag_stream_info && frag_stream_info->index_entry >= 0)
1941  frag_stream_info->index_entry += entries;
1942  }
1943 }
1944 
1946 {
1947  // Set by mov_read_tfhd(). mov_read_trun() will reject files missing tfhd.
1948  c->fragment.found_tfhd = 0;
1949 
1950  if (!c->has_looked_for_mfra && c->use_mfra_for > 0) {
1951  c->has_looked_for_mfra = 1;
1952  if (pb->seekable & AVIO_SEEKABLE_NORMAL) {
1953  int ret;
1954  av_log(c->fc, AV_LOG_VERBOSE, "stream has moof boxes, will look "
1955  "for a mfra\n");
1956  if ((ret = mov_read_mfra(c, pb)) < 0) {
1957  av_log(c->fc, AV_LOG_VERBOSE, "found a moof box but failed to "
1958  "read the mfra (may be a live ismv)\n");
1959  }
1960  } else {
1961  av_log(c->fc, AV_LOG_VERBOSE, "found a moof box but stream is not "
1962  "seekable, can not look for mfra\n");
1963  }
1964  }
1965  c->fragment.moof_offset = c->fragment.implicit_offset = avio_tell(pb) - 8;
1966  av_log(c->fc, AV_LOG_TRACE, "moof offset %"PRIx64"\n", c->fragment.moof_offset);
1967  c->frag_index.current = update_frag_index(c, c->fragment.moof_offset);
1968  return mov_read_default(c, pb, atom);
1969 }
1970 
1972 {
1973  int64_t time;
1974  if (version == 1) {
1975  time = avio_rb64(pb);
1976  avio_rb64(pb);
1977  if (time < 0) {
1978  av_log(c->fc, AV_LOG_DEBUG, "creation_time is negative\n");
1979  return;
1980  }
1981  } else {
1982  time = avio_rb32(pb);
1983  avio_rb32(pb); /* modification time */
1984  if (time > 0 && time < 2082844800) {
1985  av_log(c->fc, AV_LOG_WARNING, "Detected creation time before 1970, parsing as unix timestamp.\n");
1986  time += 2082844800;
1987  }
1988  }
1989  if (time) {
1990  time -= 2082844800; /* seconds between 1904-01-01 and Epoch */
1991 
1992  if ((int64_t)(time * 1000000ULL) / 1000000 != time) {
1993  av_log(c->fc, AV_LOG_DEBUG, "creation_time is not representable\n");
1994  return;
1995  }
1996 
1997  ff_dict_set_timestamp(metadata, "creation_time", time * 1000000);
1998  }
1999 }
2000 
2002 {
2003  AVStream *st;
2004  MOVStreamContext *sc;
2005  int version;
2006  char language[4] = {0};
2007  unsigned lang;
2008 
2009  if (c->fc->nb_streams < 1)
2010  return 0;
2011  st = c->fc->streams[c->fc->nb_streams-1];
2012  sc = st->priv_data;
2013 
2014  if (sc->time_scale) {
2015  av_log(c->fc, AV_LOG_ERROR, "Multiple mdhd?\n");
2016  return AVERROR_INVALIDDATA;
2017  }
2018 
2019  version = avio_r8(pb);
2020  if (version > 1) {
2021  avpriv_request_sample(c->fc, "Version %d", version);
2022  return AVERROR_PATCHWELCOME;
2023  }
2024  avio_rb24(pb); /* flags */
2026 
2027  sc->time_scale = avio_rb32(pb);
2028  if (sc->time_scale <= 0) {
2029  av_log(c->fc, AV_LOG_ERROR, "Invalid mdhd time scale %d, defaulting to 1\n", sc->time_scale);
2030  sc->time_scale = 1;
2031  }
2032  st->duration = (version == 1) ? avio_rb64(pb) : avio_rb32(pb); /* duration */
2033 
2034  if ((version == 1 && st->duration == UINT64_MAX) ||
2035  (version != 1 && st->duration == UINT32_MAX)) {
2036  st->duration = 0;
2037  }
2038 
2039  lang = avio_rb16(pb); /* language */
2040  if (ff_mov_lang_to_iso639(lang, language))
2041  av_dict_set(&st->metadata, "language", language, 0);
2042  avio_rb16(pb); /* quality */
2043 
2044  return 0;
2045 }
2046 
2048 {
2049  int i;
2050  int version = avio_r8(pb); /* version */
2051  avio_rb24(pb); /* flags */
2052 
2053  mov_metadata_creation_time(c, pb, &c->fc->metadata, version);
2054  c->time_scale = avio_rb32(pb); /* time scale */
2055  if (c->time_scale <= 0) {
2056  av_log(c->fc, AV_LOG_ERROR, "Invalid mvhd time scale %d, defaulting to 1\n", c->time_scale);
2057  c->time_scale = 1;
2058  }
2059  av_log(c->fc, AV_LOG_TRACE, "time scale = %i\n", c->time_scale);
2060 
2061  c->duration = (version == 1) ? avio_rb64(pb) : avio_rb32(pb); /* duration */
2062  avio_rb32(pb); /* preferred scale */
2063 
2064  avio_rb16(pb); /* preferred volume */
2065 
2066  avio_skip(pb, 10); /* reserved */
2067 
2068  /* movie display matrix, store it in main context and use it later on */
2069  for (i = 0; i < 3; i++) {
2070  c->movie_display_matrix[i][0] = avio_rb32(pb); // 16.16 fixed point
2071  c->movie_display_matrix[i][1] = avio_rb32(pb); // 16.16 fixed point
2072  c->movie_display_matrix[i][2] = avio_rb32(pb); // 2.30 fixed point
2073  }
2074 
2075  avio_rb32(pb); /* preview time */
2076  avio_rb32(pb); /* preview duration */
2077  avio_rb32(pb); /* poster time */
2078  avio_rb32(pb); /* selection time */
2079  avio_rb32(pb); /* selection duration */
2080  avio_rb32(pb); /* current time */
2081  avio_rb32(pb); /* next track ID */
2082 
2083  return 0;
2084 }
2085 
2087 {
2088  AVStream *st;
2089 
2090  if (fc->nb_streams < 1)
2091  return;
2092  st = fc->streams[fc->nb_streams-1];
2093 
2094  switch (st->codecpar->codec_id) {
2095  case AV_CODEC_ID_PCM_S16BE:
2097  break;
2098  case AV_CODEC_ID_PCM_S24BE:
2100  break;
2101  case AV_CODEC_ID_PCM_S32BE:
2103  break;
2104  case AV_CODEC_ID_PCM_F32BE:
2106  break;
2107  case AV_CODEC_ID_PCM_F64BE:
2109  break;
2110  default:
2111  break;
2112  }
2113 }
2114 
2116 {
2117  int little_endian = avio_rb16(pb) & 0xFF;
2118  av_log(c->fc, AV_LOG_TRACE, "enda %d\n", little_endian);
2119  if (little_endian == 1)
2121  return 0;
2122 }
2123 
2125 {
2126  int format_flags;
2127  int version, flags;
2128  int pcm_sample_size;
2129  AVFormatContext *fc = c->fc;
2130  AVStream *st;
2131  MOVStreamContext *sc;
2132 
2133  if (atom.size < 6) {
2134  av_log(c->fc, AV_LOG_ERROR, "Empty pcmC box\n");
2135  return AVERROR_INVALIDDATA;
2136  }
2137 
2138  version = avio_r8(pb);
2139  flags = avio_rb24(pb);
2140 
2141  if (version != 0 || flags != 0) {
2142  av_log(c->fc, AV_LOG_ERROR,
2143  "Unsupported 'pcmC' box with version %d, flags: %x",
2144  version, flags);
2145  return AVERROR_INVALIDDATA;
2146  }
2147 
2148  format_flags = avio_r8(pb);
2149  pcm_sample_size = avio_r8(pb);
2150 
2151  if (fc->nb_streams < 1)
2152  return AVERROR_INVALIDDATA;
2153 
2154  st = fc->streams[fc->nb_streams - 1];
2155  sc = st->priv_data;
2156 
2157  if (sc->format == MOV_MP4_FPCM_TAG) {
2158  switch (pcm_sample_size) {
2159  case 32:
2161  break;
2162  case 64:
2164  break;
2165  default:
2166  av_log(fc, AV_LOG_ERROR, "invalid pcm_sample_size %d for %s\n",
2167  pcm_sample_size,
2168  av_fourcc2str(sc->format));
2169  return AVERROR_INVALIDDATA;
2170  }
2171  } else if (sc->format == MOV_MP4_IPCM_TAG) {
2172  switch (pcm_sample_size) {
2173  case 16:
2175  break;
2176  case 24:
2178  break;
2179  case 32:
2181  break;
2182  default:
2183  av_log(fc, AV_LOG_ERROR, "invalid pcm_sample_size %d for %s\n",
2184  pcm_sample_size,
2185  av_fourcc2str(sc->format));
2186  return AVERROR_INVALIDDATA;
2187  }
2188  } else {
2189  av_log(fc, AV_LOG_ERROR, "'pcmC' with invalid sample entry '%s'\n",
2190  av_fourcc2str(sc->format));
2191  return AVERROR_INVALIDDATA;
2192  }
2193 
2194  if (format_flags & 1) // indicates little-endian format. If not present, big-endian format is used
2197 
2198  return 0;
2199 }
2200 
2202 {
2203  AVStream *st;
2204  HEIFItem *item = NULL;
2205  char color_parameter_type[5] = { 0 };
2206  uint16_t color_primaries, color_trc, color_matrix;
2207  int ret;
2208 
2209  st = get_curr_st(c);
2210  if (!st) {
2211  item = get_heif_item(c, c->cur_item_id);
2212  if (!item)
2213  return 0;
2214  }
2215 
2216  ret = ffio_read_size(pb, color_parameter_type, 4);
2217  if (ret < 0)
2218  return ret;
2219  if (strncmp(color_parameter_type, "nclx", 4) &&
2220  strncmp(color_parameter_type, "nclc", 4) &&
2221  strncmp(color_parameter_type, "prof", 4)) {
2222  av_log(c->fc, AV_LOG_WARNING, "unsupported color_parameter_type %s\n",
2223  color_parameter_type);
2224  return 0;
2225  }
2226 
2227  if (!strncmp(color_parameter_type, "prof", 4)) {
2228  AVPacketSideData *sd;
2229  uint8_t *icc_profile;
2230  if (st) {
2234  atom.size - 4, 0);
2235  if (!sd)
2236  return AVERROR(ENOMEM);
2237  icc_profile = sd->data;
2238  } else {
2239  if (c->heif_icc_profile_items >= c->fc->max_streams) {
2240  av_log(c->fc, AV_LOG_WARNING,
2241  "HEIF ICC profile copies exceed cap %d; ignoring further items\n",
2242  c->fc->max_streams);
2243  return 0;
2244  }
2245  av_freep(&item->icc_profile);
2246  icc_profile = item->icc_profile = av_malloc(atom.size - 4);
2247  if (!icc_profile) {
2248  item->icc_profile_size = 0;
2249  return AVERROR(ENOMEM);
2250  }
2251  item->icc_profile_size = atom.size - 4;
2252  c->heif_icc_profile_items++;
2253  }
2254  ret = ffio_read_size(pb, icc_profile, atom.size - 4);
2255  if (ret < 0)
2256  return ret;
2257  } else if (st) {
2258  color_primaries = avio_rb16(pb);
2259  color_trc = avio_rb16(pb);
2260  color_matrix = avio_rb16(pb);
2261 
2262  av_log(c->fc, AV_LOG_TRACE,
2263  "%s: pri %d trc %d matrix %d",
2264  color_parameter_type, color_primaries, color_trc, color_matrix);
2265 
2266  if (!strncmp(color_parameter_type, "nclx", 4)) {
2267  uint8_t color_range = avio_r8(pb) >> 7;
2268  av_log(c->fc, AV_LOG_TRACE, " full %"PRIu8"", color_range);
2269  if (color_range)
2271  else
2273  }
2274 
2277  if (!av_color_transfer_name(color_trc))
2278  color_trc = AVCOL_TRC_UNSPECIFIED;
2279  if (!av_color_space_name(color_matrix))
2280  color_matrix = AVCOL_SPC_UNSPECIFIED;
2281 
2283  st->codecpar->color_trc = color_trc;
2284  st->codecpar->color_space = color_matrix;
2285  av_log(c->fc, AV_LOG_TRACE, "\n");
2286  }
2287  return 0;
2288 }
2289 
2291 {
2292  AVStream *st;
2293  unsigned mov_field_order;
2294  enum AVFieldOrder decoded_field_order = AV_FIELD_UNKNOWN;
2295 
2296  if (c->fc->nb_streams < 1) // will happen with jp2 files
2297  return 0;
2298  st = c->fc->streams[c->fc->nb_streams-1];
2299  if (atom.size < 2)
2300  return AVERROR_INVALIDDATA;
2301  mov_field_order = avio_rb16(pb);
2302  if ((mov_field_order & 0xFF00) == 0x0100)
2303  decoded_field_order = AV_FIELD_PROGRESSIVE;
2304  else if ((mov_field_order & 0xFF00) == 0x0200) {
2305  switch (mov_field_order & 0xFF) {
2306  case 0x01: decoded_field_order = AV_FIELD_TT;
2307  break;
2308  case 0x06: decoded_field_order = AV_FIELD_BB;
2309  break;
2310  case 0x09: decoded_field_order = AV_FIELD_TB;
2311  break;
2312  case 0x0E: decoded_field_order = AV_FIELD_BT;
2313  break;
2314  }
2315  }
2316  if (decoded_field_order == AV_FIELD_UNKNOWN && mov_field_order) {
2317  av_log(c->fc, AV_LOG_ERROR, "Unknown MOV field order 0x%04x\n", mov_field_order);
2318  }
2319  st->codecpar->field_order = decoded_field_order;
2320 
2321  return 0;
2322 }
2323 
2325 {
2326  int err = 0;
2327  uint64_t size = (uint64_t)par->extradata_size + atom.size + 8 + AV_INPUT_BUFFER_PADDING_SIZE;
2328  if (size > INT_MAX || (uint64_t)atom.size > INT_MAX)
2329  return AVERROR_INVALIDDATA;
2330  if ((err = av_reallocp(&par->extradata, size)) < 0) {
2331  par->extradata_size = 0;
2332  return err;
2333  }
2335  return 0;
2336 }
2337 
2338 /* Read a whole atom into the extradata return the size of the atom read, possibly truncated if != atom.size */
2340  AVCodecParameters *par, uint8_t *buf)
2341 {
2342  int64_t result = atom.size;
2343  int err;
2344 
2345  AV_WB32(buf , atom.size + 8);
2346  AV_WL32(buf + 4, atom.type);
2347  err = ffio_read_size(pb, buf + 8, atom.size);
2348  if (err < 0) {
2349  par->extradata_size -= atom.size;
2350  return err;
2351  } else if (err < atom.size) {
2352  av_log(c->fc, AV_LOG_WARNING, "truncated extradata\n");
2353  par->extradata_size -= atom.size - err;
2354  result = err;
2355  }
2356  memset(buf + 8 + err, 0, AV_INPUT_BUFFER_PADDING_SIZE);
2357  return result;
2358 }
2359 
2360 /* FIXME modify QDM2/SVQ3/H.264 decoders to take full atom as extradata */
2362  enum AVCodecID codec_id)
2363 {
2364  AVStream *st;
2365  uint64_t original_size;
2366  int err;
2367 
2368  if (c->fc->nb_streams < 1) // will happen with jp2 files
2369  return 0;
2370  st = c->fc->streams[c->fc->nb_streams-1];
2371 
2372  if (st->codecpar->codec_id != codec_id)
2373  return 0; /* unexpected codec_id - don't mess with extradata */
2374 
2375  original_size = st->codecpar->extradata_size;
2376  err = mov_realloc_extradata(st->codecpar, atom);
2377  if (err)
2378  return err;
2379 
2380  err = mov_read_atom_into_extradata(c, pb, atom, st->codecpar, st->codecpar->extradata + original_size);
2381  if (err < 0)
2382  return err;
2383  return 0; // Note: this is the original behavior to ignore truncation.
2384 }
2385 
2386 /* wrapper functions for reading ALAC/AVS/MJPEG/MJPEG2000 extradata atoms only for those codecs */
2388 {
2389  return mov_read_extradata(c, pb, atom, AV_CODEC_ID_ALAC);
2390 }
2391 
2393 {
2394  return mov_read_extradata(c, pb, atom, AV_CODEC_ID_CAVS);
2395 }
2396 
2398 {
2399  return mov_read_extradata(c, pb, atom, AV_CODEC_ID_JPEG2000);
2400 }
2401 
2403 {
2404  return mov_read_extradata(c, pb, atom, AV_CODEC_ID_R10K);
2405 }
2406 
2408 {
2409  int ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_AVUI);
2410  if (!ret)
2411  ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_DNXHD);
2412  return ret;
2413 }
2414 
2416 {
2417  int ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_TARGA_Y216);
2418 
2419  if (!ret && c->fc->nb_streams >= 1) {
2420  AVCodecParameters *par = c->fc->streams[c->fc->nb_streams-1]->codecpar;
2421  if (par->extradata_size >= 40) {
2422  par->height = AV_RB16(&par->extradata[36]);
2423  par->width = AV_RB16(&par->extradata[38]);
2424  }
2425  }
2426  return ret;
2427 }
2428 
2430 {
2431  if (c->fc->nb_streams >= 1) {
2432  AVStream *const st = c->fc->streams[c->fc->nb_streams - 1];
2433  FFStream *const sti = ffstream(st);
2434  AVCodecParameters *par = st->codecpar;
2435 
2436  if (par->codec_tag == MKTAG('A', 'V', 'i', 'n') &&
2437  par->codec_id == AV_CODEC_ID_H264 &&
2438  atom.size > 11) {
2439  int cid;
2440  avio_skip(pb, 10);
2441  cid = avio_rb16(pb);
2442  /* For AVID AVCI50, force width of 1440 to be able to select the correct SPS and PPS */
2443  if (cid == 0xd4d || cid == 0xd4e)
2444  par->width = 1440;
2445  return 0;
2446  } else if ((par->codec_tag == MKTAG('A', 'V', 'd', '1') ||
2447  par->codec_tag == MKTAG('A', 'V', 'j', '2') ||
2448  par->codec_tag == MKTAG('A', 'V', 'd', 'n')) &&
2449  atom.size >= 24) {
2450  int num, den;
2451  avio_skip(pb, 12);
2452  num = avio_rb32(pb);
2453  den = avio_rb32(pb);
2454  if (num <= 0 || den <= 0)
2455  return 0;
2456  switch (avio_rb32(pb)) {
2457  case 2:
2458  if (den >= INT_MAX / 2)
2459  return 0;
2460  den *= 2;
2462  case 1:
2463  sti->display_aspect_ratio = (AVRational){ num, den };
2465  default:
2466  return 0;
2467  }
2468  }
2469  }
2470 
2471  return mov_read_avid(c, pb, atom);
2472 }
2473 
2475 {
2476  int ret = 0;
2477  int length = 0;
2478  uint64_t original_size;
2479  if (c->fc->nb_streams >= 1) {
2480  AVCodecParameters *par = c->fc->streams[c->fc->nb_streams-1]->codecpar;
2481  if (par->codec_id == AV_CODEC_ID_H264)
2482  return 0;
2483  if (atom.size == 16) {
2484  original_size = par->extradata_size;
2485  ret = mov_realloc_extradata(par, atom);
2486  if (!ret) {
2487  length = mov_read_atom_into_extradata(c, pb, atom, par, par->extradata + original_size);
2488  if (length == atom.size) {
2489  const uint8_t range_value = par->extradata[original_size + 19];
2490  switch (range_value) {
2491  case 1:
2493  break;
2494  case 2:
2496  break;
2497  default:
2498  av_log(c->fc, AV_LOG_WARNING, "ignored unknown aclr value (%d)\n", range_value);
2499  break;
2500  }
2501  ff_dlog(c->fc, "color_range: %d\n", par->color_range);
2502  } else {
2503  /* For some reason the whole atom was not added to the extradata */
2504  av_log(c->fc, AV_LOG_ERROR, "aclr not decoded - incomplete atom\n");
2505  }
2506  } else {
2507  av_log(c->fc, AV_LOG_ERROR, "aclr not decoded - unable to add atom to extradata\n");
2508  }
2509  } else {
2510  av_log(c->fc, AV_LOG_WARNING, "aclr not decoded - unexpected size %"PRId64"\n", atom.size);
2511  }
2512  }
2513 
2514  return ret;
2515 }
2516 
2518 {
2519  return mov_read_extradata(c, pb, atom, AV_CODEC_ID_SVQ3);
2520 }
2521 
2523 {
2524  AVStream *st;
2525  int ret;
2526 
2527  if (c->fc->nb_streams < 1)
2528  return 0;
2529  st = c->fc->streams[c->fc->nb_streams-1];
2530 
2531  if ((uint64_t)atom.size > (1<<30))
2532  return AVERROR_INVALIDDATA;
2533 
2534  if (st->codecpar->codec_id == AV_CODEC_ID_QDM2 ||
2537  // pass all frma atom to codec, needed at least for QDMC and QDM2
2538  ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size);
2539  if (ret < 0)
2540  return ret;
2541  } else if (atom.size > 8) { /* to read frma, esds atoms */
2542  if (st->codecpar->codec_id == AV_CODEC_ID_ALAC && atom.size >= 24) {
2543  uint64_t buffer;
2544  ret = ffio_ensure_seekback(pb, 8);
2545  if (ret < 0)
2546  return ret;
2547  buffer = avio_rb64(pb);
2548  atom.size -= 8;
2549  if ( (buffer & 0xFFFFFFFF) == MKBETAG('f','r','m','a')
2550  && buffer >> 32 <= atom.size
2551  && buffer >> 32 >= 8) {
2552  avio_skip(pb, -8);
2553  atom.size += 8;
2554  } else if (!st->codecpar->extradata_size) {
2555 #define ALAC_EXTRADATA_SIZE 36
2557  if (!st->codecpar->extradata)
2558  return AVERROR(ENOMEM);
2561  AV_WB32(st->codecpar->extradata + 4, MKTAG('a','l','a','c'));
2562  AV_WB64(st->codecpar->extradata + 12, buffer);
2563  avio_read(pb, st->codecpar->extradata + 20, 16);
2564  avio_skip(pb, atom.size - 24);
2565  return 0;
2566  }
2567  }
2568  if ((ret = mov_read_default(c, pb, atom)) < 0)
2569  return ret;
2570  } else
2571  avio_skip(pb, atom.size);
2572  return 0;
2573 }
2574 
2575 /**
2576  * This function reads atom content and puts data in extradata without tag
2577  * nor size unlike mov_read_extradata.
2578  */
2580 {
2581  AVStream *st;
2582  int ret;
2583 
2584  st = get_curr_st(c);
2585  if (!st)
2586  return 0;
2587 
2588  if ((uint64_t)atom.size > (1<<30))
2589  return AVERROR_INVALIDDATA;
2590 
2591  if (atom.type == MKTAG('v','v','c','C')) {
2592  avio_skip(pb, 4);
2593  atom.size -= 4;
2594  }
2595 
2596  if (atom.size >= 10) {
2597  // Broken files created by legacy versions of libavformat will
2598  // wrap a whole fiel atom inside of a glbl atom.
2599  unsigned size = avio_rb32(pb);
2600  unsigned type = avio_rl32(pb);
2601  if (avio_feof(pb))
2602  return AVERROR_INVALIDDATA;
2603  avio_seek(pb, -8, SEEK_CUR);
2604  if (type == MKTAG('f','i','e','l') && size == atom.size)
2605  return mov_read_default(c, pb, atom);
2606  }
2607  if (st->codecpar->extradata_size > 1 && st->codecpar->extradata) {
2608  av_log(c->fc, AV_LOG_WARNING, "ignoring multiple glbl\n");
2609  return 0;
2610  }
2611  ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size);
2612  if (ret < 0)
2613  return ret;
2614  if (atom.type == MKTAG('h','v','c','C') && st->codecpar->codec_tag == MKTAG('d','v','h','1'))
2615  /* HEVC-based Dolby Vision derived from hvc1.
2616  Happens to match with an identifier
2617  previously utilized for DV. Thus, if we have
2618  the hvcC extradata box available as specified,
2619  set codec to HEVC */
2621 
2622  return 0;
2623 }
2624 
2626 {
2627  AVStream *st;
2628  uint8_t profile_level;
2629  int ret;
2630 
2631  if (c->fc->nb_streams < 1)
2632  return 0;
2633  st = c->fc->streams[c->fc->nb_streams-1];
2634 
2635  if (atom.size >= (1<<28) || atom.size < 7)
2636  return AVERROR_INVALIDDATA;
2637 
2638  profile_level = avio_r8(pb);
2639  if ((profile_level & 0xf0) != 0xc0)
2640  return 0;
2641 
2642  avio_seek(pb, 6, SEEK_CUR);
2643  ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size - 7);
2644  if (ret < 0)
2645  return ret;
2646 
2647  return 0;
2648 }
2649 
2650 static int mov_find_tref_id(const MovTref *tag, uint32_t id)
2651 {
2652  for (int i = 0; i < tag->nb_id; i++) {
2653  if (tag->id[i] == id)
2654  return 1;
2655  }
2656  return 0;
2657 }
2658 
2659 static int mov_add_tref_id(MovTref *tag, uint32_t id)
2660 {
2661  int ret = mov_find_tref_id(tag, id);
2662 
2663  if (!ret) {
2664  uint32_t *tmp = av_realloc_array(tag->id, tag->nb_id + 1, sizeof(*tag->id));
2665  if (!tmp)
2666  return AVERROR(ENOMEM);
2667  tag->id = tmp;
2668  tag->id[tag->nb_id++] = id;
2669  }
2670 
2671  return 0;
2672 }
2673 
2674 static MovTref *mov_find_tref_tag(const MOVStreamContext *sc, uint32_t name)
2675 {
2676  for (int i = 0; i < sc->nb_tref_tags; i++) {
2677  MovTref *entry = &sc->tref_tags[i];
2678 
2679  if (entry->name == name)
2680  return entry;
2681  }
2682  return NULL;
2683 }
2684 
2686 {
2688 
2689  if (!tag) {
2691  sizeof(*sc->tref_tags));
2692  if (!tmp)
2693  return NULL;
2694  sc->tref_tags = tmp;
2695  tag = &sc->tref_tags[sc->nb_tref_tags++];
2696  *tag = (MovTref){ .name = name };
2697  }
2698 
2699  return tag;
2700 }
2701 
2703 {
2704  AVStream* st;
2705  MOVStreamContext* sc;
2706 
2707  if (c->fc->nb_streams < 1)
2708  return 0;
2709 
2710  if (atom.size > 4) {
2711  av_log(c->fc, AV_LOG_ERROR, "Only a single tref of type cdsc is supported\n");
2712  return AVERROR_PATCHWELCOME;
2713  }
2714  if (atom.size < 4)
2715  return AVERROR_INVALIDDATA;
2716 
2717  st = get_curr_st(c);
2718  if (!st)
2719  return AVERROR_INVALIDDATA;
2720  sc = st->priv_data;
2721 
2722  MovTref *tag = mov_add_tref_tag(sc, atom.type);
2723  if (!tag)
2724  return AVERROR(ENOMEM);
2725 
2726  int ret = mov_add_tref_id(tag, avio_rb32(pb));
2727  if (ret < 0)
2728  return ret;
2729 
2730  return 0;
2731 }
2732 
2734 {
2735  AVStream* st;
2736  MOVStreamContext* sc;
2737 
2738  if (c->fc->nb_streams < 1)
2739  return 0;
2740 
2741  /* For SBAS this should be fine - though beware if someone implements a
2742  * tref atom processor that doesn't drop down to default then this may
2743  * be lost. */
2744  if (atom.size > 4) {
2745  av_log(c->fc, AV_LOG_ERROR, "Only a single tref of type sbas is supported\n");
2746  return AVERROR_PATCHWELCOME;
2747  }
2748  if (atom.size < 4)
2749  return AVERROR_INVALIDDATA;
2750 
2751  st = c->fc->streams[c->fc->nb_streams - 1];
2752  sc = st->priv_data;
2753 
2754  MovTref *tag = mov_add_tref_tag(sc, atom.type);
2755  if (!tag)
2756  return AVERROR(ENOMEM);
2757 
2758  int ret = mov_add_tref_id(tag, avio_rb32(pb));
2759  if (ret < 0)
2760  return ret;
2761 
2762  return 0;
2763 }
2764 
2766 {
2767  AVStream* st;
2768  MOVStreamContext* sc;
2769 
2770  if (c->fc->nb_streams < 1)
2771  return 0;
2772 
2773  if (atom.size > 4)
2774  av_log(c->fc, AV_LOG_WARNING, "More than one vdep reference is not supported.\n");
2775  if (atom.size < 4)
2776  return AVERROR_INVALIDDATA;
2777 
2778  st = c->fc->streams[c->fc->nb_streams - 1];
2779  sc = st->priv_data;
2780 
2781  MovTref *tag = mov_add_tref_tag(sc, atom.type);
2782  if (!tag)
2783  return AVERROR(ENOMEM);
2784 
2785  int ret = mov_add_tref_id(tag, avio_rb32(pb));
2786  if (ret < 0)
2787  return ret;
2788 
2789  return 0;
2790 }
2791 
2792 /**
2793  * An strf atom is a BITMAPINFOHEADER struct. This struct is 40 bytes itself,
2794  * but can have extradata appended at the end after the 40 bytes belonging
2795  * to the struct.
2796  */
2798 {
2799  AVStream *st;
2800  int ret;
2801 
2802  if (c->fc->nb_streams < 1)
2803  return 0;
2804  if (atom.size <= 40)
2805  return 0;
2806  st = c->fc->streams[c->fc->nb_streams-1];
2807 
2808  if ((uint64_t)atom.size > (1<<30))
2809  return AVERROR_INVALIDDATA;
2810 
2811  avio_skip(pb, 40);
2812  ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size - 40);
2813  if (ret < 0)
2814  return ret;
2815 
2816  return 0;
2817 }
2818 
2820 {
2821  AVStream *st;
2822  MOVStreamContext *sc;
2823  unsigned int i, entries;
2824 
2825  if (c->trak_index < 0) {
2826  av_log(c->fc, AV_LOG_WARNING, "STCO outside TRAK\n");
2827  return 0;
2828  }
2829  if (c->fc->nb_streams < 1)
2830  return 0;
2831  st = c->fc->streams[c->fc->nb_streams-1];
2832  sc = st->priv_data;
2833 
2834  avio_r8(pb); /* version */
2835  avio_rb24(pb); /* flags */
2836 
2837  // Clamp allocation size for `chunk_offsets` -- don't throw an error for an
2838  // invalid count since the EOF path doesn't throw either.
2839  entries = avio_rb32(pb);
2840  entries =
2841  FFMIN(entries,
2842  FFMAX(0, (atom.size - 8) /
2843  (atom.type == MKTAG('s', 't', 'c', 'o') ? 4 : 8)));
2844 
2845  if (!entries)
2846  return 0;
2847 
2848  if (sc->chunk_offsets) {
2849  av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicated STCO atom\n");
2850  return 0;
2851  }
2852 
2853  av_free(sc->chunk_offsets);
2854  sc->chunk_count = 0;
2855  sc->chunk_offsets = av_malloc_array(entries, sizeof(*sc->chunk_offsets));
2856  if (!sc->chunk_offsets)
2857  return AVERROR(ENOMEM);
2858  sc->chunk_count = entries;
2859 
2860  if (atom.type == MKTAG('s','t','c','o'))
2861  for (i = 0; i < entries && !pb->eof_reached; i++)
2862  sc->chunk_offsets[i] = avio_rb32(pb);
2863  else if (atom.type == MKTAG('c','o','6','4'))
2864  for (i = 0; i < entries && !pb->eof_reached; i++) {
2865  sc->chunk_offsets[i] = avio_rb64(pb);
2866  if (sc->chunk_offsets[i] < 0) {
2867  av_log(c->fc, AV_LOG_WARNING, "Impossible chunk_offset\n");
2868  sc->chunk_offsets[i] = 0;
2869  }
2870  }
2871  else
2872  return AVERROR_INVALIDDATA;
2873 
2874  sc->chunk_count = i;
2875 
2876  if (pb->eof_reached) {
2877  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STCO atom\n");
2878  return AVERROR_EOF;
2879  }
2880 
2881  return 0;
2882 }
2883 
2884 static int mov_codec_id(AVStream *st, uint32_t format)
2885 {
2887 
2888  if (id <= 0 &&
2889  ((format & 0xFFFF) == 'm' + ('s' << 8) ||
2890  (format & 0xFFFF) == 'T' + ('S' << 8)))
2892 
2893  if (st->codecpar->codec_type != AVMEDIA_TYPE_VIDEO && id > 0) {
2895  } else if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO &&
2896  /* skip old ASF MPEG-4 tag */
2897  format && format != MKTAG('m','p','4','s')) {
2899  if (id <= 0)
2901  if (id > 0)
2903  else if (st->codecpar->codec_type == AVMEDIA_TYPE_DATA ||
2905  st->codecpar->codec_id == AV_CODEC_ID_NONE)) {
2907  if (id <= 0) {
2909  AV_CODEC_ID_TTML : id;
2910  }
2911 
2912  if (id > 0)
2914  else
2916  }
2917  }
2918 
2919  st->codecpar->codec_tag = format;
2920 
2921  return id;
2922 }
2923 
2925  AVStream *st, MOVStreamContext *sc)
2926 {
2927  uint8_t codec_name[32] = { 0 };
2928  int64_t stsd_start;
2929  unsigned int len;
2930  uint32_t id = 0;
2931 
2932  /* The first 16 bytes of the video sample description are already
2933  * read in ff_mov_read_stsd_entries() */
2934  stsd_start = avio_tell(pb) - 16;
2935 
2936  if (c->isom) {
2937  avio_skip(pb, 2); /* pre_defined */
2938  avio_skip(pb, 2); /* reserved */
2939  avio_skip(pb, 12); /* pre_defined */
2940  } else {
2941  avio_rb16(pb); /* version */
2942  avio_rb16(pb); /* revision level */
2943  id = avio_rl32(pb); /* vendor */
2944  av_dict_set(&st->metadata, "vendor_id", av_fourcc2str(id), 0);
2945  avio_rb32(pb); /* temporal quality */
2946  avio_rb32(pb); /* spatial quality */
2947  }
2948 
2949  st->codecpar->width = avio_rb16(pb); /* width */
2950  st->codecpar->height = avio_rb16(pb); /* height */
2951 
2952  avio_rb32(pb); /* horiz resolution */
2953  avio_rb32(pb); /* vert resolution */
2954  avio_rb32(pb); /* data size, always 0 */
2955  avio_rb16(pb); /* frames per samples */
2956 
2957  len = avio_r8(pb); /* codec name, pascal string */
2958  if (len > 31)
2959  len = 31;
2960  mov_read_mac_string(c, pb, len, codec_name, sizeof(codec_name));
2961  if (len < 31)
2962  avio_skip(pb, 31 - len);
2963 
2964  if (codec_name[0])
2965  av_dict_set(&st->metadata, "encoder", codec_name, 0);
2966 
2967  /* codec_tag YV12 triggers an UV swap in rawdec.c */
2968  if (!strncmp(codec_name, "Planar Y'CbCr 8-bit 4:2:0", 25)) {
2969  st->codecpar->codec_tag = MKTAG('I', '4', '2', '0');
2970  st->codecpar->width &= ~1;
2971  st->codecpar->height &= ~1;
2972  }
2973  /* Flash Media Server uses tag H.263 with Sorenson Spark */
2974  if (st->codecpar->codec_tag == MKTAG('H','2','6','3') &&
2975  !strncmp(codec_name, "Sorenson H263", 13))
2977 
2978  st->codecpar->bits_per_coded_sample = avio_rb16(pb); /* depth */
2979 
2980  avio_seek(pb, stsd_start, SEEK_SET);
2981 
2982  if (ff_get_qtpalette(st->codecpar->codec_id, pb, sc->palette)) {
2983  st->codecpar->bits_per_coded_sample &= 0x1F;
2984  sc->has_palette = 1;
2985  }
2986 }
2987 
2989  AVStream *st, MOVStreamContext *sc)
2990 {
2991  int bits_per_sample, flags;
2992  uint16_t version = avio_rb16(pb);
2993  uint32_t id = 0;
2994  AVDictionaryEntry *compatible_brands = av_dict_get(c->fc->metadata, "compatible_brands", NULL, AV_DICT_MATCH_CASE);
2995  int channel_count;
2996 
2997  if (c->isom)
2998  avio_skip(pb, 6); /* reserved */
2999  else {
3000  avio_rb16(pb); /* revision level */
3001  id = avio_rl32(pb); /* vendor */
3002  av_dict_set(&st->metadata, "vendor_id", av_fourcc2str(id), 0);
3003  }
3004 
3005  channel_count = avio_rb16(pb);
3006 
3008  st->codecpar->ch_layout.nb_channels = channel_count;
3009  st->codecpar->bits_per_coded_sample = avio_rb16(pb); /* sample size */
3010  av_log(c->fc, AV_LOG_TRACE, "audio channels %d\n", channel_count);
3011 
3012  sc->audio_cid = avio_rb16(pb);
3013  avio_rb16(pb); /* packet size = 0 */
3014 
3015  st->codecpar->sample_rate = ((avio_rb32(pb) >> 16));
3016 
3017  // Read QT version 1 fields. In version 0 these do not exist.
3018  av_log(c->fc, AV_LOG_TRACE, "version =%d, isom =%d\n", version, c->isom);
3019  if (!c->isom ||
3020  (compatible_brands && strstr(compatible_brands->value, "qt ")) ||
3021  (sc->stsd_version == 0 && version > 0)) {
3022  if (version == 1) {
3023  sc->samples_per_frame = avio_rb32(pb);
3024  avio_rb32(pb); /* bytes per packet */
3025  sc->bytes_per_frame = avio_rb32(pb);
3026  avio_rb32(pb); /* bytes per sample */
3027  } else if (version == 2) {
3028  avio_rb32(pb); /* sizeof struct only */
3030  channel_count = avio_rb32(pb);
3032  st->codecpar->ch_layout.nb_channels = channel_count;
3033  avio_rb32(pb); /* always 0x7F000000 */
3035 
3036  flags = avio_rb32(pb); /* lpcm format specific flag */
3037  sc->bytes_per_frame = avio_rb32(pb);
3038  sc->samples_per_frame = avio_rb32(pb);
3039  if (st->codecpar->codec_tag == MKTAG('l','p','c','m'))
3040  st->codecpar->codec_id =
3042  flags);
3043  }
3044  if (version == 0 || (version == 1 && sc->audio_cid != -2)) {
3045  /* can't correctly handle variable sized packet as audio unit */
3046  switch (st->codecpar->codec_id) {
3047  case AV_CODEC_ID_MP2:
3048  case AV_CODEC_ID_MP3:
3050  break;
3051  }
3052  }
3053  }
3054 
3055  if (sc->format == 0) {
3056  if (st->codecpar->bits_per_coded_sample == 8)
3057  st->codecpar->codec_id = mov_codec_id(st, MKTAG('r','a','w',' '));
3058  else if (st->codecpar->bits_per_coded_sample == 16)
3059  st->codecpar->codec_id = mov_codec_id(st, MKTAG('t','w','o','s'));
3060  }
3061 
3062  switch (st->codecpar->codec_id) {
3063  case AV_CODEC_ID_PCM_S8:
3064  case AV_CODEC_ID_PCM_U8:
3065  if (st->codecpar->bits_per_coded_sample == 16)
3067  break;
3068  case AV_CODEC_ID_PCM_S16LE:
3069  case AV_CODEC_ID_PCM_S16BE:
3070  if (st->codecpar->bits_per_coded_sample == 8)
3072  else if (st->codecpar->bits_per_coded_sample == 24)
3073  st->codecpar->codec_id =
3076  else if (st->codecpar->bits_per_coded_sample == 32)
3077  st->codecpar->codec_id =
3080  break;
3081  /* set values for old format before stsd version 1 appeared */
3082  case AV_CODEC_ID_MACE3:
3083  sc->samples_per_frame = 6;
3085  break;
3086  case AV_CODEC_ID_MACE6:
3087  sc->samples_per_frame = 6;
3089  break;
3091  sc->samples_per_frame = 64;
3093  break;
3094  case AV_CODEC_ID_GSM:
3095  sc->samples_per_frame = 160;
3096  sc->bytes_per_frame = 33;
3097  break;
3098  default:
3099  break;
3100  }
3101 
3102  bits_per_sample = av_get_bits_per_sample(st->codecpar->codec_id);
3103  if (bits_per_sample && (bits_per_sample >> 3) * (uint64_t)st->codecpar->ch_layout.nb_channels <= INT_MAX) {
3104  st->codecpar->bits_per_coded_sample = bits_per_sample;
3105  sc->sample_size = (bits_per_sample >> 3) * st->codecpar->ch_layout.nb_channels;
3106  }
3107 }
3108 
3110  AVStream *st, MOVStreamContext *sc,
3111  int64_t size)
3112 {
3113  // ttxt stsd contains display flags, justification, background
3114  // color, fonts, and default styles, so fake an atom to read it
3115  MOVAtom fake_atom = { .size = size };
3116  // mp4s contains a regular esds atom, dfxp ISMV TTML has no content
3117  // in extradata unlike stpp MP4 TTML.
3118  if (st->codecpar->codec_tag != AV_RL32("mp4s") &&
3120  mov_read_glbl(c, pb, fake_atom);
3121  st->codecpar->width = sc->width;
3122  st->codecpar->height = sc->height;
3123 }
3124 
3126  AVStream *st, MOVStreamContext *sc,
3127  int64_t size)
3128 {
3129  int ret;
3130 
3131  if (st->codecpar->codec_tag == MKTAG('t','m','c','d')) {
3132  if ((int)size != size)
3133  return AVERROR(ENOMEM);
3134 
3135  ret = ff_get_extradata(c->fc, st->codecpar, pb, size);
3136  if (ret < 0)
3137  return ret;
3138  if (size > 16) {
3139  MOVStreamContext *tmcd_ctx = st->priv_data;
3140  int val;
3141  val = AV_RB32(st->codecpar->extradata + 4);
3142  tmcd_ctx->tmcd_flags = val;
3143  st->avg_frame_rate.num = AV_RB32(st->codecpar->extradata + 8); /* timescale */
3144  st->avg_frame_rate.den = AV_RB32(st->codecpar->extradata + 12); /* frameDuration */
3145  tmcd_ctx->tmcd_nb_frames = st->codecpar->extradata[16]; /* number of frames */
3146  if (size > 30) {
3147  uint32_t len = AV_RB32(st->codecpar->extradata + 18); /* name atom length */
3148  uint32_t format = AV_RB32(st->codecpar->extradata + 22);
3149  if (format == AV_RB32("name") && (int64_t)size >= (int64_t)len + 18) {
3150  uint16_t str_size = AV_RB16(st->codecpar->extradata + 26); /* string length */
3151  if (str_size > 0 && size >= (int)str_size + 30 &&
3152  st->codecpar->extradata[30] /* Don't add empty string */) {
3153  char *reel_name = av_malloc(str_size + 1);
3154  if (!reel_name)
3155  return AVERROR(ENOMEM);
3156  memcpy(reel_name, st->codecpar->extradata + 30, str_size);
3157  reel_name[str_size] = 0; /* Add null terminator */
3158  av_dict_set(&st->metadata, "reel_name", reel_name,
3160  }
3161  }
3162  }
3163  }
3164  } else if (st->codecpar->codec_id == AV_CODEC_ID_ITUT_T35) {
3165  int t35_identifier_length = avio_r8(pb);
3166 
3167  if (t35_identifier_length <= 0 || t35_identifier_length >= size)
3168  return AVERROR_INVALIDDATA;
3169 
3170  ret = ff_get_extradata(c->fc, st->codecpar, pb, t35_identifier_length);
3171  if (ret < 0)
3172  return ret;
3173 
3174  int hrsd_len = size - t35_identifier_length - 1;
3175  if (hrsd_len > 0) {
3176  uint8_t *hrsd_str = av_malloc(hrsd_len + 1);
3177  if (!hrsd_str)
3178  return AVERROR(ENOMEM);
3179 
3180  ret = ffio_read_size(pb, hrsd_str, hrsd_len);
3181  if (ret < 0) {
3182  av_free(hrsd_str);
3183  return ret;
3184  }
3185  if (hrsd_str[0]) {
3186  hrsd_str[hrsd_len] = 0;
3187  ret = av_dict_set(&st->metadata, "description", hrsd_str, AV_DICT_DONT_OVERWRITE);
3188  }
3189  av_free(hrsd_str);
3190  }
3191  } else {
3192  /* other codec type, just skip (rtp, mp4s ...) */
3193  avio_skip(pb, size);
3194  }
3195  return 0;
3196 }
3197 
3199  AVStream *st, MOVStreamContext *sc)
3200 {
3201  FFStream *const sti = ffstream(st);
3202 
3203  if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
3204  !st->codecpar->sample_rate && sc->time_scale > 1)
3205  st->codecpar->sample_rate = sc->time_scale;
3206 
3207  /* special codec parameters handling */
3208  switch (st->codecpar->codec_id) {
3209 #if CONFIG_DV_DEMUXER
3210  case AV_CODEC_ID_DVAUDIO:
3211  if (c->dv_fctx) {
3212  avpriv_request_sample(c->fc, "multiple DV audio streams");
3213  return AVERROR(ENOSYS);
3214  }
3215 
3216  c->dv_fctx = avformat_alloc_context();
3217  if (!c->dv_fctx) {
3218  av_log(c->fc, AV_LOG_ERROR, "dv demux context alloc error\n");
3219  return AVERROR(ENOMEM);
3220  }
3221  c->dv_demux = avpriv_dv_init_demux(c->dv_fctx);
3222  if (!c->dv_demux) {
3223  av_log(c->fc, AV_LOG_ERROR, "dv demux context init error\n");
3224  return AVERROR(ENOMEM);
3225  }
3226  sc->dv_audio_container = 1;
3228  break;
3229 #endif
3230  /* no ifdef since parameters are always those */
3231  case AV_CODEC_ID_QCELP:
3234  // force sample rate for qcelp when not stored in mov
3235  if (st->codecpar->codec_tag != MKTAG('Q','c','l','p'))
3236  st->codecpar->sample_rate = 8000;
3237  // FIXME: Why is the following needed for some files?
3238  sc->samples_per_frame = 160;
3239  if (!sc->bytes_per_frame)
3240  sc->bytes_per_frame = 35;
3241  break;
3242  case AV_CODEC_ID_AMR_NB:
3245  /* force sample rate for amr, stsd in 3gp does not store sample rate */
3246  st->codecpar->sample_rate = 8000;
3247  break;
3248  case AV_CODEC_ID_AMR_WB:
3251  st->codecpar->sample_rate = 16000;
3252  break;
3253  case AV_CODEC_ID_MP2:
3254  case AV_CODEC_ID_MP3:
3255  /* force type after stsd for m1a hdlr */
3257  break;
3258  case AV_CODEC_ID_GSM:
3259  case AV_CODEC_ID_ADPCM_MS:
3261  case AV_CODEC_ID_ILBC:
3262  case AV_CODEC_ID_MACE3:
3263  case AV_CODEC_ID_MACE6:
3264  case AV_CODEC_ID_QDM2:
3266  break;
3267  case AV_CODEC_ID_ALAC:
3268  if (st->codecpar->extradata_size == 36) {
3269  int channel_count = AV_RB8(st->codecpar->extradata + 21);
3270  if (st->codecpar->ch_layout.nb_channels != channel_count) {
3273  st->codecpar->ch_layout.nb_channels = channel_count;
3274  }
3275  st->codecpar->sample_rate = AV_RB32(st->codecpar->extradata + 32);
3276  }
3277  break;
3278  case AV_CODEC_ID_AC3:
3279  case AV_CODEC_ID_EAC3:
3281  case AV_CODEC_ID_VC1:
3282  case AV_CODEC_ID_VP8:
3283  case AV_CODEC_ID_VP9:
3285  break;
3287  case AV_CODEC_ID_PRORES:
3288  case AV_CODEC_ID_APV:
3289  case AV_CODEC_ID_EVC:
3290  case AV_CODEC_ID_LCEVC:
3291  case AV_CODEC_ID_AV1:
3292  /* field_order detection of H264 requires parsing */
3293  case AV_CODEC_ID_H264:
3295  break;
3296  default:
3297  break;
3298  }
3299  return 0;
3300 }
3301 
3303  int codec_tag, int format,
3304  int64_t size)
3305 {
3306  if (codec_tag &&
3307  (codec_tag != format &&
3308  // AVID 1:1 samples with differing data format and codec tag exist
3309  (codec_tag != AV_RL32("AV1x") || format != AV_RL32("AVup")) &&
3310  // prores is allowed to have differing data format and codec tag
3311  codec_tag != AV_RL32("apcn") && codec_tag != AV_RL32("apch") &&
3312  // so is dv (sigh)
3313  codec_tag != AV_RL32("dvpp") && codec_tag != AV_RL32("dvcp") &&
3314  (c->fc->video_codec_id ? ff_codec_get_id(ff_codec_movvideo_tags, format) != c->fc->video_codec_id
3315  : codec_tag != MKTAG('j','p','e','g')))) {
3316  /* Multiple fourcc, we skip JPEG. This is not correct, we should
3317  * export it as a separate AVStream but this needs a few changes
3318  * in the MOV demuxer, patch welcome. */
3319 
3320  av_log(c->fc, AV_LOG_WARNING, "multiple fourcc not supported\n");
3321  avio_skip(pb, size);
3322  return 1;
3323  }
3324 
3325  return 0;
3326 }
3327 
3329 {
3330  int ret;
3331 
3332  /* special codec parameters handling */
3333  switch (st->codecpar->codec_id) {
3334  case AV_CODEC_ID_H264:
3335  // done for ai5q, ai52, ai55, ai1q, ai12 and ai15.
3336  if (!st->codecpar->extradata_size && TAG_IS_AVCI(st->codecpar->codec_tag)) {
3338  if (ret < 0)
3339  return ret;
3340  }
3341  break;
3342  default:
3343  break;
3344  }
3345 
3346  return 0;
3347 }
3348 
3350 {
3351  AVStream *st;
3352  MOVStreamContext *sc;
3353  int pseudo_stream_id;
3354 
3355  av_assert0 (c->fc->nb_streams >= 1);
3356  st = c->fc->streams[c->fc->nb_streams-1];
3357  sc = st->priv_data;
3358 
3359  for (pseudo_stream_id = 0;
3360  pseudo_stream_id < entries && !pb->eof_reached;
3361  pseudo_stream_id++) {
3362  //Parsing Sample description table
3363  enum AVCodecID id;
3364  int ret, dref_id = 1;
3365  MOVAtom a = { AV_RL32("stsd") };
3366  int64_t start_pos = avio_tell(pb);
3367  int64_t size = avio_rb32(pb); /* size */
3368  uint32_t format = avio_rl32(pb); /* data format */
3369 
3370  if (size >= 16) {
3371  avio_rb32(pb); /* reserved */
3372  avio_rb16(pb); /* reserved */
3373  dref_id = avio_rb16(pb);
3374  } else if (size <= 7) {
3375  av_log(c->fc, AV_LOG_ERROR,
3376  "invalid size %"PRId64" in stsd\n", size);
3377  return AVERROR_INVALIDDATA;
3378  }
3379 
3381  size - (avio_tell(pb) - start_pos))) {
3382  sc->stsd_count++;
3383  continue;
3384  }
3385 
3386  sc->pseudo_stream_id = st->codecpar->codec_tag ? -1 : pseudo_stream_id;
3387  sc->dref_id= dref_id;
3388  sc->format = format;
3389 
3390  id = mov_codec_id(st, format);
3391 
3392  av_log(c->fc, AV_LOG_TRACE,
3393  "size=%"PRId64" 4CC=%s codec_type=%d\n", size,
3395 
3396  st->codecpar->codec_id = id;
3398  mov_parse_stsd_video(c, pb, st, sc);
3399  } else if (st->codecpar->codec_type==AVMEDIA_TYPE_AUDIO) {
3400  mov_parse_stsd_audio(c, pb, st, sc);
3401  if (st->codecpar->sample_rate < 0) {
3402  av_log(c->fc, AV_LOG_ERROR, "Invalid sample rate %d\n", st->codecpar->sample_rate);
3403  return AVERROR_INVALIDDATA;
3404  }
3405  if (st->codecpar->ch_layout.nb_channels < 0) {
3406  av_log(c->fc, AV_LOG_ERROR, "Invalid channels %d\n", st->codecpar->ch_layout.nb_channels);
3407  return AVERROR_INVALIDDATA;
3408  }
3409  } else if (st->codecpar->codec_type==AVMEDIA_TYPE_SUBTITLE){
3410  mov_parse_stsd_subtitle(c, pb, st, sc,
3411  size - (avio_tell(pb) - start_pos));
3412  } else {
3413  ret = mov_parse_stsd_data(c, pb, st, sc,
3414  size - (avio_tell(pb) - start_pos));
3415  if (ret < 0)
3416  return ret;
3417  }
3418  /* this will read extra atoms at the end (wave, alac, damr, avcC, hvcC, SMI ...) */
3419  a.size = size - (avio_tell(pb) - start_pos);
3420  if (a.size > 8) {
3421  if ((ret = mov_read_default(c, pb, a)) < 0)
3422  return ret;
3423  } else if (a.size > 0)
3424  avio_skip(pb, a.size);
3425 
3426  ret = mov_finalize_stsd_entry(c, st);
3427  if (ret < 0)
3428  return ret;
3429 
3430  if (sc->extradata && st->codecpar->extradata) {
3431  int extra_size = st->codecpar->extradata_size;
3432 
3433  /* Move the current stream extradata to the stream context one. */
3434  sc->extradata_size[pseudo_stream_id] = extra_size;
3435  sc->extradata[pseudo_stream_id] = st->codecpar->extradata;
3436  st->codecpar->extradata = NULL;
3437  st->codecpar->extradata_size = 0;
3438  }
3439  sc->stsd_count++;
3440  }
3441 
3442  if (pb->eof_reached) {
3443  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSD atom\n");
3444  return AVERROR_EOF;
3445  }
3446 
3447  return 0;
3448 }
3449 
3451 {
3452  AVStream *st;
3453  MOVStreamContext *sc;
3454  int ret, entries;
3455 
3456  if (c->fc->nb_streams < 1)
3457  return 0;
3458  st = c->fc->streams[c->fc->nb_streams - 1];
3459  sc = st->priv_data;
3460 
3461  if (sc->extradata) {
3462  av_log(c->fc, AV_LOG_ERROR,
3463  "Duplicate stsd found in this track.\n");
3464  return AVERROR_INVALIDDATA;
3465  }
3466 
3467  sc->stsd_version = avio_r8(pb);
3468  avio_rb24(pb); /* flags */
3469  entries = avio_rb32(pb);
3470 
3471  /* Each entry contains a size (4 bytes) and format (4 bytes). */
3472  if (entries <= 0 || entries > atom.size / 8 || entries > 1024) {
3473  av_log(c->fc, AV_LOG_ERROR, "invalid STSD entries %d\n", entries);
3474  return AVERROR_INVALIDDATA;
3475  }
3476 
3477  /* Prepare space for hosting multiple extradata. */
3478  sc->extradata = av_calloc(entries, sizeof(*sc->extradata));
3479  if (!sc->extradata)
3480  return AVERROR(ENOMEM);
3481 
3482  sc->extradata_size = av_calloc(entries, sizeof(*sc->extradata_size));
3483  if (!sc->extradata_size) {
3484  ret = AVERROR(ENOMEM);
3485  goto fail;
3486  }
3487 
3488  ret = ff_mov_read_stsd_entries(c, pb, entries);
3489  if (ret < 0)
3490  goto fail;
3491 
3492  /* Restore back the primary extradata. */
3493  av_freep(&st->codecpar->extradata);
3494  st->codecpar->extradata_size = sc->extradata_size[0];
3495  if (sc->extradata_size[0]) {
3497  if (!st->codecpar->extradata)
3498  return AVERROR(ENOMEM);
3499  memcpy(st->codecpar->extradata, sc->extradata[0], sc->extradata_size[0]);
3500  }
3501 
3502  return mov_finalize_stsd_codec(c, pb, st, sc);
3503 fail:
3504  if (sc->extradata) {
3505  int j;
3506  for (j = 0; j < sc->stsd_count; j++)
3507  av_freep(&sc->extradata[j]);
3508  }
3509 
3510  sc->stsd_count = 0;
3511  av_freep(&sc->extradata);
3512  av_freep(&sc->extradata_size);
3513  return ret;
3514 }
3515 
3517 {
3518  AVStream *st;
3519  MOVStreamContext *sc;
3520  unsigned int i, entries;
3521 
3522  if (c->trak_index < 0) {
3523  av_log(c->fc, AV_LOG_WARNING, "STSC outside TRAK\n");
3524  return 0;
3525  }
3526 
3527  if (c->fc->nb_streams < 1)
3528  return 0;
3529  st = c->fc->streams[c->fc->nb_streams-1];
3530  sc = st->priv_data;
3531 
3532  avio_r8(pb); /* version */
3533  avio_rb24(pb); /* flags */
3534 
3535  entries = avio_rb32(pb);
3536  if ((uint64_t)entries * 12 + 4 > atom.size)
3537  return AVERROR_INVALIDDATA;
3538 
3539  av_log(c->fc, AV_LOG_TRACE, "track[%u].stsc.entries = %u\n", c->fc->nb_streams - 1, entries);
3540 
3541  if (!entries)
3542  return 0;
3543  if (sc->stsc_data) {
3544  av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicated STSC atom\n");
3545  return 0;
3546  }
3547  av_free(sc->stsc_data);
3548  sc->stsc_count = 0;
3549  sc->stsc_data = av_malloc_array(entries, sizeof(*sc->stsc_data));
3550  if (!sc->stsc_data)
3551  return AVERROR(ENOMEM);
3552 
3553  for (i = 0; i < entries && !pb->eof_reached; i++) {
3554  sc->stsc_data[i].first = avio_rb32(pb);
3555  sc->stsc_data[i].count = avio_rb32(pb);
3556  sc->stsc_data[i].id = avio_rb32(pb);
3557  }
3558 
3559  sc->stsc_count = i;
3560  for (i = sc->stsc_count - 1; i < UINT_MAX; i--) {
3561  int64_t first_min = i + 1;
3562  if ((i+1 < sc->stsc_count && sc->stsc_data[i].first >= sc->stsc_data[i+1].first) ||
3563  (i > 0 && sc->stsc_data[i].first <= sc->stsc_data[i-1].first) ||
3564  sc->stsc_data[i].first < first_min ||
3565  sc->stsc_data[i].count < 1 ||
3566  sc->stsc_data[i].id < 1) {
3567  av_log(c->fc, AV_LOG_WARNING, "STSC entry %d is invalid (first=%d count=%d id=%d)\n", i, sc->stsc_data[i].first, sc->stsc_data[i].count, sc->stsc_data[i].id);
3568  if (i+1 >= sc->stsc_count) {
3569  if (sc->stsc_data[i].count == 0 && i > 0) {
3570  sc->stsc_count --;
3571  continue;
3572  }
3573  sc->stsc_data[i].first = FFMAX(sc->stsc_data[i].first, first_min);
3574  if (i > 0 && sc->stsc_data[i].first <= sc->stsc_data[i-1].first)
3575  sc->stsc_data[i].first = FFMIN(sc->stsc_data[i-1].first + 1LL, INT_MAX);
3576  sc->stsc_data[i].count = FFMAX(sc->stsc_data[i].count, 1);
3577  sc->stsc_data[i].id = FFMAX(sc->stsc_data[i].id, 1);
3578  continue;
3579  }
3580  av_assert0(sc->stsc_data[i+1].first >= 2);
3581  // We replace this entry by the next valid
3582  sc->stsc_data[i].first = sc->stsc_data[i+1].first - 1;
3583  sc->stsc_data[i].count = sc->stsc_data[i+1].count;
3584  sc->stsc_data[i].id = sc->stsc_data[i+1].id;
3585  }
3586  }
3587 
3588  if (pb->eof_reached) {
3589  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSC atom\n");
3590  return AVERROR_EOF;
3591  }
3592 
3593  return 0;
3594 }
3595 
3596 static inline int mov_stsc_index_valid(unsigned int index, unsigned int count)
3597 {
3598  return index < count - 1;
3599 }
3600 
3601 /* Compute the samples value for the stsc entry at the given index. */
3602 static inline int64_t mov_get_stsc_samples(MOVStreamContext *sc, unsigned int index)
3603 {
3604  int chunk_count;
3605 
3607  chunk_count = sc->stsc_data[index + 1].first - sc->stsc_data[index].first;
3608  else {
3609  // Validation for stsc / stco happens earlier in mov_read_stsc + mov_read_trak.
3611  chunk_count = sc->chunk_count - (sc->stsc_data[index].first - 1);
3612  }
3613 
3614  return sc->stsc_data[index].count * (int64_t)chunk_count;
3615 }
3616 
3618 {
3619  AVStream *st;
3620  MOVStreamContext *sc;
3621  unsigned i, entries;
3622 
3623  if (c->trak_index < 0) {
3624  av_log(c->fc, AV_LOG_WARNING, "STPS outside TRAK\n");
3625  return 0;
3626  }
3627 
3628  if (c->fc->nb_streams < 1)
3629  return 0;
3630  st = c->fc->streams[c->fc->nb_streams-1];
3631  sc = st->priv_data;
3632 
3633  avio_rb32(pb); // version + flags
3634 
3635  entries = avio_rb32(pb);
3636  if (sc->stps_data)
3637  av_log(c->fc, AV_LOG_WARNING, "Duplicated STPS atom\n");
3638  av_free(sc->stps_data);
3639  sc->stps_count = 0;
3640  sc->stps_data = av_malloc_array(entries, sizeof(*sc->stps_data));
3641  if (!sc->stps_data)
3642  return AVERROR(ENOMEM);
3643 
3644  for (i = 0; i < entries && !pb->eof_reached; i++) {
3645  sc->stps_data[i] = avio_rb32(pb);
3646  }
3647 
3648  sc->stps_count = i;
3649 
3650  if (pb->eof_reached) {
3651  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STPS atom\n");
3652  return AVERROR_EOF;
3653  }
3654 
3655  return 0;
3656 }
3657 
3659 {
3660  AVStream *st;
3661  FFStream *sti;
3662  MOVStreamContext *sc;
3663  unsigned int i, entries;
3664 
3665  if (c->trak_index < 0) {
3666  av_log(c->fc, AV_LOG_WARNING, "STSS outside TRAK\n");
3667  return 0;
3668  }
3669 
3670  if (c->fc->nb_streams < 1)
3671  return 0;
3672  st = c->fc->streams[c->fc->nb_streams-1];
3673  sti = ffstream(st);
3674  sc = st->priv_data;
3675 
3676  avio_r8(pb); /* version */
3677  avio_rb24(pb); /* flags */
3678 
3679  entries = avio_rb32(pb);
3680 
3681  av_log(c->fc, AV_LOG_TRACE, "keyframe_count = %u\n", entries);
3682 
3683  if (!entries) {
3684  sc->keyframe_absent = 1;
3685  if (!sti->need_parsing && st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
3687  return 0;
3688  }
3689  if (sc->keyframes)
3690  av_log(c->fc, AV_LOG_WARNING, "Duplicated STSS atom\n");
3691  if (entries >= UINT_MAX / sizeof(int))
3692  return AVERROR_INVALIDDATA;
3693  av_freep(&sc->keyframes);
3694  sc->keyframe_count = 0;
3695  sc->keyframes = av_malloc_array(entries, sizeof(*sc->keyframes));
3696  if (!sc->keyframes)
3697  return AVERROR(ENOMEM);
3698 
3699  for (i = 0; i < entries && !pb->eof_reached; i++) {
3700  sc->keyframes[i] = avio_rb32(pb);
3701  }
3702 
3703  sc->keyframe_count = i;
3704 
3705  if (pb->eof_reached) {
3706  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSS atom\n");
3707  return AVERROR_EOF;
3708  }
3709 
3710  return 0;
3711 }
3712 
3714 {
3715  AVStream *st;
3716  MOVStreamContext *sc;
3717  unsigned int i, entries, sample_size, field_size, num_bytes;
3718  GetBitContext gb;
3719  unsigned char* buf;
3720  int ret;
3721 
3722  if (c->trak_index < 0) {
3723  av_log(c->fc, AV_LOG_WARNING, "STSZ outside TRAK\n");
3724  return 0;
3725  }
3726 
3727  if (c->fc->nb_streams < 1)
3728  return 0;
3729  st = c->fc->streams[c->fc->nb_streams-1];
3730  sc = st->priv_data;
3731 
3732  avio_r8(pb); /* version */
3733  avio_rb24(pb); /* flags */
3734 
3735  if (atom.type == MKTAG('s','t','s','z')) {
3736  sample_size = avio_rb32(pb);
3737  if (!sc->sample_size) /* do not overwrite value computed in stsd */
3738  sc->sample_size = sample_size;
3739  sc->stsz_sample_size = sample_size;
3740  field_size = 32;
3741  } else {
3742  sample_size = 0;
3743  avio_rb24(pb); /* reserved */
3744  field_size = avio_r8(pb);
3745  }
3746  entries = avio_rb32(pb);
3747 
3748  av_log(c->fc, AV_LOG_TRACE, "sample_size = %u sample_count = %u\n", sc->sample_size, entries);
3749 
3750  sc->sample_count = entries;
3751  if (sample_size)
3752  return 0;
3753 
3754  if (field_size != 4 && field_size != 8 && field_size != 16 && field_size != 32) {
3755  av_log(c->fc, AV_LOG_ERROR, "Invalid sample field size %u\n", field_size);
3756  return AVERROR_INVALIDDATA;
3757  }
3758 
3759  if (!entries)
3760  return 0;
3761  if (entries >= (INT_MAX - 4 - 8 * AV_INPUT_BUFFER_PADDING_SIZE) / field_size)
3762  return AVERROR_INVALIDDATA;
3763  if (sc->sample_sizes)
3764  av_log(c->fc, AV_LOG_WARNING, "Duplicated STSZ atom\n");
3765  av_free(sc->sample_sizes);
3766  sc->sample_count = 0;
3767  sc->sample_sizes = av_malloc_array(entries, sizeof(*sc->sample_sizes));
3768  if (!sc->sample_sizes)
3769  return AVERROR(ENOMEM);
3770 
3771  num_bytes = (entries*field_size+4)>>3;
3772 
3773  buf = av_malloc(num_bytes+AV_INPUT_BUFFER_PADDING_SIZE);
3774  if (!buf) {
3775  av_freep(&sc->sample_sizes);
3776  return AVERROR(ENOMEM);
3777  }
3778 
3779  ret = ffio_read_size(pb, buf, num_bytes);
3780  if (ret < 0) {
3781  av_freep(&sc->sample_sizes);
3782  av_free(buf);
3783  av_log(c->fc, AV_LOG_WARNING, "STSZ atom truncated\n");
3784  return 0;
3785  }
3786 
3787  init_get_bits(&gb, buf, 8*num_bytes);
3788 
3789  for (i = 0; i < entries; i++) {
3790  sc->sample_sizes[i] = get_bits_long(&gb, field_size);
3791  if (sc->sample_sizes[i] > INT64_MAX - sc->data_size) {
3792  av_free(buf);
3793  av_log(c->fc, AV_LOG_ERROR, "Sample size overflow in STSZ\n");
3794  return AVERROR_INVALIDDATA;
3795  }
3796  sc->data_size += sc->sample_sizes[i];
3797  }
3798 
3799  sc->sample_count = i;
3800 
3801  av_free(buf);
3802 
3803  return 0;
3804 }
3805 
3807 {
3808  AVStream *st;
3809  MOVStreamContext *sc;
3810  unsigned int i, entries;
3811  int64_t duration = 0;
3812  int64_t total_sample_count = 0;
3813  int64_t current_dts = 0;
3814  int64_t corrected_dts = 0;
3815 
3816  if (c->trak_index < 0) {
3817  av_log(c->fc, AV_LOG_WARNING, "STTS outside TRAK\n");
3818  return 0;
3819  }
3820 
3821  if (c->fc->nb_streams < 1)
3822  return 0;
3823  st = c->fc->streams[c->fc->nb_streams-1];
3824  sc = st->priv_data;
3825 
3826  avio_r8(pb); /* version */
3827  avio_rb24(pb); /* flags */
3828  entries = avio_rb32(pb);
3829 
3830  av_log(c->fc, AV_LOG_TRACE, "track[%u].stts.entries = %u\n",
3831  c->fc->nb_streams-1, entries);
3832 
3833  if (sc->stts_data)
3834  av_log(c->fc, AV_LOG_WARNING, "Duplicated STTS atom\n");
3835  av_freep(&sc->stts_data);
3836  sc->stts_count = 0;
3837  if (entries >= INT_MAX / sizeof(*sc->stts_data))
3838  return AVERROR(ENOMEM);
3839 
3840  for (i = 0; i < entries && !pb->eof_reached; i++) {
3841  unsigned int sample_duration;
3842  unsigned int sample_count;
3843  unsigned int min_entries = FFMIN(FFMAX(i + 1, 1024 * 1024), entries);
3844  MOVStts *stts_data = av_fast_realloc(sc->stts_data, &sc->stts_allocated_size,
3845  min_entries * sizeof(*sc->stts_data));
3846  if (!stts_data) {
3847  av_freep(&sc->stts_data);
3848  sc->stts_count = 0;
3849  return AVERROR(ENOMEM);
3850  }
3851  sc->stts_count = min_entries;
3852  sc->stts_data = stts_data;
3853 
3854  sample_count = avio_rb32(pb);
3855  sample_duration = avio_rb32(pb);
3856 
3857  sc->stts_data[i].count= sample_count;
3858  sc->stts_data[i].duration= sample_duration;
3859 
3860  av_log(c->fc, AV_LOG_TRACE, "sample_count=%u, sample_duration=%u\n",
3861  sample_count, sample_duration);
3862 
3863  /* STTS sample offsets are uint32 but some files store it as int32
3864  * with negative values used to correct DTS delays.
3865  There may be abnormally large values as well. */
3866  if (sample_duration > c->max_stts_delta) {
3867  // assume high delta is a correction if negative when cast as int32
3868  int32_t delta_magnitude = (int32_t)sample_duration;
3869  av_log(c->fc, AV_LOG_WARNING, "Too large sample offset %u in stts entry %u with count %u in st:%d. Clipping to 1.\n",
3870  sample_duration, i, sample_count, st->index);
3871  sc->stts_data[i].duration = 1;
3872  corrected_dts = av_sat_add64(corrected_dts, (delta_magnitude < 0 ? (int64_t)delta_magnitude : 1) * sample_count);
3873  } else {
3874  corrected_dts += sample_duration * (uint64_t)sample_count;
3875  }
3876 
3877  current_dts += sc->stts_data[i].duration * (uint64_t)sample_count;
3878 
3879  if (current_dts > corrected_dts) {
3880  int64_t drift = av_sat_sub64(current_dts, corrected_dts) / FFMAX(sample_count, 1);
3881  uint32_t correction = (sc->stts_data[i].duration > drift) ? drift : sc->stts_data[i].duration - 1;
3882  current_dts -= correction * (uint64_t)sample_count;
3883  sc->stts_data[i].duration -= correction;
3884  }
3885 
3886  duration+=(int64_t)sc->stts_data[i].duration*(uint64_t)sc->stts_data[i].count;
3887  total_sample_count+=sc->stts_data[i].count;
3888  }
3889 
3890  sc->stts_count = i;
3891 
3892  if (duration > 0 &&
3893  duration <= INT64_MAX - sc->duration_for_fps &&
3894  total_sample_count <= INT_MAX - sc->nb_frames_for_fps) {
3895  sc->duration_for_fps += duration;
3896  sc->nb_frames_for_fps += total_sample_count;
3897  }
3898 
3899  if (pb->eof_reached) {
3900  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STTS atom\n");
3901  return AVERROR_EOF;
3902  }
3903 
3904  st->nb_frames= total_sample_count;
3905  if (duration)
3906  st->duration= FFMIN(st->duration, duration);
3907 
3908  // All samples have zero duration. They have higher chance be chose by
3909  // mov_find_next_sample, which leads to seek again and again.
3910  //
3911  // It's AVERROR_INVALIDDATA actually, but such files exist in the wild.
3912  // So only mark data stream as discarded for safety.
3913  if (!duration && sc->stts_count &&
3915  av_log(c->fc, AV_LOG_WARNING,
3916  "All samples in data stream index:id [%d:%d] have zero "
3917  "duration, stream set to be discarded by default. Override "
3918  "using AVStream->discard or -discard for ffmpeg command.\n",
3919  st->index, sc->id);
3920  st->discard = AVDISCARD_ALL;
3921  }
3922  sc->track_end = duration;
3923  return 0;
3924 }
3925 
3927 {
3928  AVStream *st;
3929  MOVStreamContext *sc;
3930  unsigned int i;
3931  int64_t entries;
3932 
3933  if (c->fc->nb_streams < 1)
3934  return 0;
3935  st = c->fc->streams[c->fc->nb_streams - 1];
3936  sc = st->priv_data;
3937 
3938  avio_r8(pb); /* version */
3939  avio_rb24(pb); /* flags */
3940  entries = atom.size - 4;
3941 
3942  av_log(c->fc, AV_LOG_TRACE, "track[%u].sdtp.entries = %" PRId64 "\n",
3943  c->fc->nb_streams - 1, entries);
3944 
3945  if (sc->sdtp_data)
3946  av_log(c->fc, AV_LOG_WARNING, "Duplicated SDTP atom\n");
3947  av_freep(&sc->sdtp_data);
3948  sc->sdtp_count = 0;
3949 
3950  if (entries < 0 || entries > UINT_MAX)
3951  return AVERROR(ERANGE);
3952 
3953  sc->sdtp_data = av_malloc(entries);
3954  if (!sc->sdtp_data)
3955  return AVERROR(ENOMEM);
3956 
3957  for (i = 0; i < entries && !pb->eof_reached; i++)
3958  sc->sdtp_data[i] = avio_r8(pb);
3959  sc->sdtp_count = i;
3960 
3961  return 0;
3962 }
3963 
3964 static void mov_update_dts_shift(MOVStreamContext *sc, int duration, void *logctx)
3965 {
3966  if (duration < 0) {
3967  if (duration == INT_MIN) {
3968  av_log(logctx, AV_LOG_WARNING, "mov_update_dts_shift(): dts_shift set to %d\n", INT_MAX);
3969  duration++;
3970  }
3971  sc->dts_shift = FFMAX(sc->dts_shift, -duration);
3972  }
3973 }
3974 
3976 {
3977  AVStream *st;
3978  MOVStreamContext *sc;
3979  unsigned int i, entries, ctts_count = 0;
3980 
3981  if (c->trak_index < 0) {
3982  av_log(c->fc, AV_LOG_WARNING, "CTTS outside TRAK\n");
3983  return 0;
3984  }
3985 
3986  if (c->fc->nb_streams < 1)
3987  return 0;
3988  st = c->fc->streams[c->fc->nb_streams-1];
3989  sc = st->priv_data;
3990 
3991  avio_r8(pb); /* version */
3992  avio_rb24(pb); /* flags */
3993  entries = avio_rb32(pb);
3994 
3995  av_log(c->fc, AV_LOG_TRACE, "track[%u].ctts.entries = %u\n", c->fc->nb_streams - 1, entries);
3996 
3997  if (!entries)
3998  return 0;
3999  if (entries >= UINT_MAX / sizeof(*sc->ctts_data))
4000  return AVERROR_INVALIDDATA;
4001  av_freep(&sc->ctts_data);
4002  sc->ctts_data = av_fast_realloc(NULL, &sc->ctts_allocated_size, entries * sizeof(*sc->ctts_data));
4003  if (!sc->ctts_data)
4004  return AVERROR(ENOMEM);
4005 
4006  for (i = 0; i < entries && !pb->eof_reached; i++) {
4007  MOVCtts *ctts_data;
4008  const size_t min_size_needed = (ctts_count + 1) * sizeof(MOVCtts);
4009  const size_t requested_size =
4010  min_size_needed > sc->ctts_allocated_size ?
4011  FFMAX(min_size_needed, 2 * sc->ctts_allocated_size) :
4012  min_size_needed;
4013  int count = avio_rb32(pb);
4014  int duration = avio_rb32(pb);
4015 
4016  if (count <= 0) {
4017  av_log(c->fc, AV_LOG_TRACE,
4018  "ignoring CTTS entry with count=%d duration=%d\n",
4019  count, duration);
4020  continue;
4021  }
4022 
4023  if (ctts_count >= UINT_MAX / sizeof(MOVCtts) - 1)
4024  return AVERROR(ENOMEM);
4025 
4026  ctts_data = av_fast_realloc(sc->ctts_data, &sc->ctts_allocated_size, requested_size);
4027 
4028  if (!ctts_data)
4029  return AVERROR(ENOMEM);
4030 
4031  sc->ctts_data = ctts_data;
4032 
4033  ctts_data[ctts_count].count = count;
4034  ctts_data[ctts_count].offset = duration;
4035  ctts_count++;
4036 
4037  av_log(c->fc, AV_LOG_TRACE, "count=%d, duration=%d\n",
4038  count, duration);
4039 
4040  if (i+2<entries)
4041  mov_update_dts_shift(sc, duration, c->fc);
4042  }
4043 
4044  sc->ctts_count = ctts_count;
4045 
4046  if (pb->eof_reached) {
4047  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted CTTS atom\n");
4048  return AVERROR_EOF;
4049  }
4050 
4051  av_log(c->fc, AV_LOG_TRACE, "dts shift %d\n", sc->dts_shift);
4052 
4053  return 0;
4054 }
4055 
4057 {
4058  AVStream *st;
4059  MOVStreamContext *sc;
4060  uint8_t version;
4061  uint32_t grouping_type;
4062  uint32_t default_length;
4063  av_unused uint32_t default_group_description_index;
4064  uint32_t entry_count;
4065 
4066  if (c->fc->nb_streams < 1)
4067  return 0;
4068  st = c->fc->streams[c->fc->nb_streams - 1];
4069  sc = st->priv_data;
4070 
4071  version = avio_r8(pb); /* version */
4072  avio_rb24(pb); /* flags */
4073  grouping_type = avio_rl32(pb);
4074 
4075  /*
4076  * This function only supports "sync" boxes, but the code is able to parse
4077  * other boxes (such as "tscl", "tsas" and "stsa")
4078  */
4079  if (grouping_type != MKTAG('s','y','n','c'))
4080  return 0;
4081 
4082  default_length = version >= 1 ? avio_rb32(pb) : 0;
4083  default_group_description_index = version >= 2 ? avio_rb32(pb) : 0;
4084  entry_count = avio_rb32(pb);
4085 
4086  av_freep(&sc->sgpd_sync);
4087  sc->sgpd_sync_count = entry_count;
4088  sc->sgpd_sync = av_calloc(entry_count, sizeof(*sc->sgpd_sync));
4089  if (!sc->sgpd_sync)
4090  return AVERROR(ENOMEM);
4091 
4092  for (uint32_t i = 0; i < entry_count && !pb->eof_reached; i++) {
4093  uint32_t description_length = default_length;
4094  if (version >= 1 && default_length == 0)
4095  description_length = avio_rb32(pb);
4096  if (grouping_type == MKTAG('s','y','n','c')) {
4097  const uint8_t nal_unit_type = avio_r8(pb) & 0x3f;
4098  sc->sgpd_sync[i] = nal_unit_type;
4099  description_length -= 1;
4100  }
4101  avio_skip(pb, description_length);
4102  }
4103 
4104  if (pb->eof_reached) {
4105  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted SGPD atom\n");
4106  return AVERROR_EOF;
4107  }
4108 
4109  return 0;
4110 }
4111 
4113 {
4114  AVStream *st;
4115  MOVStreamContext *sc;
4116  unsigned int i, entries;
4117  uint8_t version;
4118  uint32_t grouping_type;
4119  MOVSbgp *table, **tablep;
4120  int *table_count;
4121 
4122  if (c->fc->nb_streams < 1)
4123  return 0;
4124  st = c->fc->streams[c->fc->nb_streams-1];
4125  sc = st->priv_data;
4126 
4127  version = avio_r8(pb); /* version */
4128  avio_rb24(pb); /* flags */
4129  grouping_type = avio_rl32(pb);
4130 
4131  if (grouping_type == MKTAG('r','a','p',' ')) {
4132  tablep = &sc->rap_group;
4133  table_count = &sc->rap_group_count;
4134  } else if (grouping_type == MKTAG('s','y','n','c')) {
4135  tablep = &sc->sync_group;
4136  table_count = &sc->sync_group_count;
4137  } else {
4138  return 0;
4139  }
4140 
4141  if (version == 1)
4142  avio_rb32(pb); /* grouping_type_parameter */
4143 
4144  entries = avio_rb32(pb);
4145  if (!entries)
4146  return 0;
4147  if (*tablep)
4148  av_log(c->fc, AV_LOG_WARNING, "Duplicated SBGP %s atom\n", av_fourcc2str(grouping_type));
4149  av_freep(tablep);
4150  table = av_malloc_array(entries, sizeof(*table));
4151  if (!table)
4152  return AVERROR(ENOMEM);
4153  *tablep = table;
4154 
4155  for (i = 0; i < entries && !pb->eof_reached; i++) {
4156  table[i].count = avio_rb32(pb); /* sample_count */
4157  table[i].index = avio_rb32(pb); /* group_description_index */
4158  }
4159 
4160  *table_count = i;
4161 
4162  if (pb->eof_reached) {
4163  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted SBGP atom\n");
4164  return AVERROR_EOF;
4165  }
4166 
4167  return 0;
4168 }
4169 
4170 /**
4171  * Get ith edit list entry (media time, duration).
4172  */
4174  const MOVStreamContext *msc,
4175  unsigned int edit_list_index,
4176  int64_t *edit_list_media_time,
4177  int64_t *edit_list_duration,
4178  int64_t global_timescale)
4179 {
4180  if (edit_list_index == msc->elst_count) {
4181  return 0;
4182  }
4183  *edit_list_media_time = msc->elst_data[edit_list_index].time;
4184  *edit_list_duration = msc->elst_data[edit_list_index].duration;
4185 
4186  /* duration is in global timescale units;convert to msc timescale */
4187  if (global_timescale == 0) {
4188  avpriv_request_sample(mov->fc, "Support for mvhd.timescale = 0 with editlists");
4189  return 0;
4190  }
4191  *edit_list_duration = av_rescale(*edit_list_duration, msc->time_scale,
4192  global_timescale);
4193 
4194  if (*edit_list_duration + (uint64_t)*edit_list_media_time > INT64_MAX)
4195  *edit_list_duration = 0;
4196 
4197  return 1;
4198 }
4199 
4200 /**
4201  * Find the closest previous frame to the timestamp_pts, in e_old index
4202  * entries. Searching for just any frame / just key frames can be controlled by
4203  * last argument 'flag'.
4204  * Note that if ctts_data is not NULL, we will always search for a key frame
4205  * irrespective of the value of 'flag'. If we don't find any keyframe, we will
4206  * return the first frame of the video.
4207  *
4208  * Here the timestamp_pts is considered to be a presentation timestamp and
4209  * the timestamp of index entries are considered to be decoding timestamps.
4210  *
4211  * Returns 0 if successful in finding a frame, else returns -1.
4212  * Places the found index corresponding output arg.
4213  *
4214  * If ctts_old is not NULL, then refines the searched entry by searching
4215  * backwards from the found timestamp, to find the frame with correct PTS.
4216  *
4217  * Places the found ctts_index and ctts_sample in corresponding output args.
4218  */
4220  AVIndexEntry *e_old,
4221  int nb_old,
4222  MOVTimeToSample *tts_data,
4223  int64_t tts_count,
4224  int64_t timestamp_pts,
4225  int flag,
4226  int64_t* index,
4227  int64_t* tts_index,
4228  int64_t* tts_sample)
4229 {
4230  MOVStreamContext *msc = st->priv_data;
4231  FFStream *const sti = ffstream(st);
4232  AVIndexEntry *e_keep = sti->index_entries;
4233  int nb_keep = sti->nb_index_entries;
4234  int64_t i = 0;
4235 
4236  av_assert0(index);
4237 
4238  // If dts_shift > 0, then all the index timestamps will have to be offset by
4239  // at least dts_shift amount to obtain PTS.
4240  // Hence we decrement the searched timestamp_pts by dts_shift to find the closest index element.
4241  if (msc->dts_shift > 0) {
4242  timestamp_pts -= msc->dts_shift;
4243  }
4244 
4245  sti->index_entries = e_old;
4246  sti->nb_index_entries = nb_old;
4247  *index = av_index_search_timestamp(st, timestamp_pts, flag | AVSEEK_FLAG_BACKWARD);
4248 
4249  // Keep going backwards in the index entries until the timestamp is the same.
4250  if (*index >= 0) {
4251  for (i = *index; i > 0 && e_old[i].timestamp == e_old[i - 1].timestamp;
4252  i--) {
4253  if ((flag & AVSEEK_FLAG_ANY) ||
4254  (e_old[i - 1].flags & AVINDEX_KEYFRAME)) {
4255  *index = i - 1;
4256  }
4257  }
4258  }
4259 
4260  // If we have CTTS then refine the search, by searching backwards over PTS
4261  // computed by adding corresponding CTTS durations to index timestamps.
4262  if (msc->ctts_count && *index >= 0) {
4263  av_assert0(tts_index);
4264  av_assert0(tts_sample);
4265  // Find out the ctts_index for the found frame.
4266  *tts_index = 0;
4267  *tts_sample = 0;
4268  for (int64_t index_tts_count = 0; index_tts_count < *index; index_tts_count++) {
4269  if (*tts_index < tts_count) {
4270  (*tts_sample)++;
4271  if (tts_data[*tts_index].count == *tts_sample) {
4272  (*tts_index)++;
4273  *tts_sample = 0;
4274  }
4275  }
4276  }
4277 
4278  while (*index >= 0 && (*tts_index) >= 0 && (*tts_index) < tts_count) {
4279  // Find a "key frame" with PTS <= timestamp_pts (So that we can decode B-frames correctly).
4280  // No need to add dts_shift to the timestamp here because timestamp_pts has already been
4281  // compensated by dts_shift above.
4282  if ((e_old[*index].timestamp + tts_data[*tts_index].offset) <= timestamp_pts &&
4283  (e_old[*index].flags & AVINDEX_KEYFRAME)) {
4284  break;
4285  }
4286 
4287  (*index)--;
4288  if (*tts_sample == 0) {
4289  (*tts_index)--;
4290  if (*tts_index >= 0)
4291  *tts_sample = tts_data[*tts_index].count - 1;
4292  } else {
4293  (*tts_sample)--;
4294  }
4295  }
4296  }
4297 
4298  /* restore AVStream state*/
4299  sti->index_entries = e_keep;
4300  sti->nb_index_entries = nb_keep;
4301  return *index >= 0 ? 0 : -1;
4302 }
4303 
4304 /**
4305  * Add index entry with the given values, to the end of ffstream(st)->index_entries.
4306  * Returns the new size ffstream(st)->index_entries if successful, else returns -1.
4307  *
4308  * This function is similar to ff_add_index_entry in libavformat/utils.c
4309  * except that here we are always unconditionally adding an index entry to
4310  * the end, instead of searching the entries list and skipping the add if
4311  * there is an existing entry with the same timestamp.
4312  * This is needed because the mov_fix_index calls this func with the same
4313  * unincremented timestamp for successive discarded frames.
4314  */
4316  int size, int distance, int flags)
4317 {
4318  FFStream *const sti = ffstream(st);
4319  AVIndexEntry *entries, *ie;
4320  int64_t index = -1;
4321  const size_t min_size_needed = (sti->nb_index_entries + 1) * sizeof(AVIndexEntry);
4322 
4323  // Double the allocation each time, to lower memory fragmentation.
4324  // Another difference from ff_add_index_entry function.
4325  const size_t requested_size =
4326  min_size_needed > sti->index_entries_allocated_size ?
4327  FFMAX(min_size_needed, 2 * sti->index_entries_allocated_size) :
4328  min_size_needed;
4329 
4330  if (sti->nb_index_entries + 1U >= UINT_MAX / sizeof(AVIndexEntry))
4331  return -1;
4332 
4333  entries = av_fast_realloc(sti->index_entries,
4335  requested_size);
4336  if (!entries)
4337  return -1;
4338 
4339  sti->index_entries = entries;
4340 
4341  index = sti->nb_index_entries++;
4342  ie= &entries[index];
4343 
4344  ie->pos = pos;
4345  ie->timestamp = timestamp;
4346  ie->min_distance= distance;
4347  ie->size= size;
4348  ie->flags = flags;
4349  return index;
4350 }
4351 
4352 /**
4353  * Rewrite timestamps of index entries in the range [end_index - frame_duration_buffer_size, end_index)
4354  * by subtracting end_ts successively by the amounts given in frame_duration_buffer.
4355  */
4356 static void fix_index_entry_timestamps(AVStream* st, int end_index, int64_t end_ts,
4357  int64_t* frame_duration_buffer,
4358  int frame_duration_buffer_size) {
4359  FFStream *const sti = ffstream(st);
4360  int i = 0;
4361  av_assert0(end_index >= 0 && end_index <= sti->nb_index_entries);
4362  for (i = 0; i < frame_duration_buffer_size; i++) {
4363  end_ts -= frame_duration_buffer[frame_duration_buffer_size - 1 - i];
4364  sti->index_entries[end_index - 1 - i].timestamp = end_ts;
4365  }
4366 }
4367 
4368 static int add_tts_entry(MOVTimeToSample **tts_data, unsigned int *tts_count, unsigned int *allocated_size,
4369  int count, int offset, unsigned int duration)
4370 {
4371  MOVTimeToSample *tts_buf_new;
4372  const size_t min_size_needed = (*tts_count + 1) * sizeof(MOVTimeToSample);
4373  const size_t requested_size =
4374  min_size_needed > *allocated_size ?
4375  FFMAX(min_size_needed, 2 * (*allocated_size)) :
4376  min_size_needed;
4377 
4378  if ((unsigned)(*tts_count) >= UINT_MAX / sizeof(MOVTimeToSample) - 1)
4379  return -1;
4380 
4381  tts_buf_new = av_fast_realloc(*tts_data, allocated_size, requested_size);
4382 
4383  if (!tts_buf_new)
4384  return -1;
4385 
4386  *tts_data = tts_buf_new;
4387 
4388  tts_buf_new[*tts_count].count = count;
4389  tts_buf_new[*tts_count].offset = offset;
4390  tts_buf_new[*tts_count].duration = duration;
4391 
4392  *tts_count = (*tts_count) + 1;
4393  return 0;
4394 }
4395 
4396 #define MAX_REORDER_DELAY 16
4398 {
4399  MOVStreamContext *msc = st->priv_data;
4400  FFStream *const sti = ffstream(st);
4401  int ctts_ind = 0;
4402  int ctts_sample = 0;
4403  int64_t pts_buf[MAX_REORDER_DELAY + 1]; // Circular buffer to sort pts.
4404  int buf_start = 0;
4405  int j, r, num_swaps;
4406 
4407  for (j = 0; j < MAX_REORDER_DELAY + 1; j++)
4408  pts_buf[j] = INT64_MIN;
4409 
4410  if (st->codecpar->video_delay <= 0 && msc->ctts_count &&
4412  st->codecpar->video_delay = 0;
4413  for (int ind = 0; ind < sti->nb_index_entries && ctts_ind < msc->tts_count; ++ind) {
4414  // Point j to the last elem of the buffer and insert the current pts there.
4415  j = buf_start;
4416  buf_start = (buf_start + 1);
4417  if (buf_start == MAX_REORDER_DELAY + 1)
4418  buf_start = 0;
4419 
4420  pts_buf[j] = sti->index_entries[ind].timestamp + msc->tts_data[ctts_ind].offset;
4421 
4422  // The timestamps that are already in the sorted buffer, and are greater than the
4423  // current pts, are exactly the timestamps that need to be buffered to output PTS
4424  // in correct sorted order.
4425  // Hence the video delay (which is the buffer size used to sort DTS and output PTS),
4426  // can be computed as the maximum no. of swaps any particular timestamp needs to
4427  // go through, to keep this buffer in sorted order.
4428  num_swaps = 0;
4429  while (j != buf_start) {
4430  r = j - 1;
4431  if (r < 0) r = MAX_REORDER_DELAY;
4432  if (pts_buf[j] < pts_buf[r]) {
4433  FFSWAP(int64_t, pts_buf[j], pts_buf[r]);
4434  ++num_swaps;
4435  } else {
4436  break;
4437  }
4438  j = r;
4439  }
4440  st->codecpar->video_delay = FFMAX(st->codecpar->video_delay, num_swaps);
4441 
4442  ctts_sample++;
4443  if (ctts_sample == msc->tts_data[ctts_ind].count) {
4444  ctts_ind++;
4445  ctts_sample = 0;
4446  }
4447  }
4448  av_log(c->fc, AV_LOG_DEBUG, "Setting codecpar->delay to %d for stream st: %d\n",
4449  st->codecpar->video_delay, st->index);
4450  }
4451 }
4452 
4454 {
4455  sc->current_sample++;
4456  sc->current_index++;
4457  if (sc->index_ranges &&
4458  sc->current_index >= sc->current_index_range->end &&
4459  sc->current_index_range->end) {
4460  sc->current_index_range++;
4462  }
4463 }
4464 
4466 {
4467  sc->current_sample--;
4468  sc->current_index--;
4469  if (sc->index_ranges &&
4471  sc->current_index_range > sc->index_ranges) {
4472  sc->current_index_range--;
4473  sc->current_index = sc->current_index_range->end - 1;
4474  }
4475 }
4476 
4477 static void mov_current_sample_set(MOVStreamContext *sc, int current_sample)
4478 {
4479  int64_t range_size;
4480 
4481  sc->current_sample = current_sample;
4482  sc->current_index = current_sample;
4483  if (!sc->index_ranges) {
4484  return;
4485  }
4486 
4487  for (sc->current_index_range = sc->index_ranges;
4488  sc->current_index_range->end;
4489  sc->current_index_range++) {
4490  range_size = sc->current_index_range->end - sc->current_index_range->start;
4491  if (range_size > current_sample) {
4492  sc->current_index = sc->current_index_range->start + current_sample;
4493  break;
4494  }
4495  current_sample -= range_size;
4496  }
4497 }
4498 
4499 /**
4500  * Fix ffstream(st)->index_entries, so that it contains only the entries (and the entries
4501  * which are needed to decode them) that fall in the edit list time ranges.
4502  * Also fixes the timestamps of the index entries to match the timeline
4503  * specified the edit lists.
4504  */
4505 static void mov_fix_index(MOVContext *mov, AVStream *st)
4506 {
4507  MOVStreamContext *msc = st->priv_data;
4508  FFStream *const sti = ffstream(st);
4509  AVIndexEntry *e_old = sti->index_entries;
4510  int nb_old = sti->nb_index_entries;
4511  const AVIndexEntry *e_old_end = e_old + nb_old;
4512  const AVIndexEntry *current = NULL;
4513  MOVTimeToSample *tts_data_old = msc->tts_data;
4514  int64_t tts_index_old = 0;
4515  int64_t tts_sample_old = 0;
4516  int64_t tts_count_old = msc->tts_count;
4517  int64_t edit_list_media_time = 0;
4518  int64_t edit_list_duration = 0;
4519  int64_t frame_duration = 0;
4520  int64_t edit_list_dts_counter = 0;
4521  int64_t edit_list_dts_entry_end = 0;
4522  int64_t edit_list_start_tts_sample = 0;
4523  int64_t curr_cts;
4524  int64_t curr_ctts = 0;
4525  int64_t empty_edits_sum_duration = 0;
4526  int64_t edit_list_index = 0;
4527  int64_t index;
4528  int flags;
4529  int64_t start_dts = 0;
4530  int64_t edit_list_start_encountered = 0;
4531  int64_t search_timestamp = 0;
4532  int64_t* frame_duration_buffer = NULL;
4533  int num_discarded_begin = 0;
4534  int first_non_zero_audio_edit = -1;
4535  int packet_skip_samples = 0;
4536  MOVIndexRange *current_index_range = NULL;
4537  int found_keyframe_after_edit = 0;
4538  int found_non_empty_edit = 0;
4539 
4540  if (!msc->elst_data || msc->elst_count <= 0 || nb_old <= 0) {
4541  return;
4542  }
4543 
4544  // allocate the index ranges array
4545  msc->index_ranges = av_malloc_array(msc->elst_count + 1,
4546  sizeof(msc->index_ranges[0]));
4547  if (!msc->index_ranges) {
4548  av_log(mov->fc, AV_LOG_ERROR, "Cannot allocate index ranges buffer\n");
4549  return;
4550  }
4551  msc->current_index_range = msc->index_ranges;
4552 
4553  // Clean AVStream from traces of old index
4554  sti->index_entries = NULL;
4556  sti->nb_index_entries = 0;
4557 
4558  // Clean time to sample fields of MOVStreamContext
4559  msc->tts_data = NULL;
4560  msc->tts_count = 0;
4561  msc->tts_index = 0;
4562  msc->tts_sample = 0;
4563  msc->tts_allocated_size = 0;
4564 
4565  // Reinitialize min_corrected_pts so that it can be computed again.
4566  msc->min_corrected_pts = -1;
4567 
4568  // If the dts_shift is positive (in case of negative ctts values in mov),
4569  // then negate the DTS by dts_shift
4570  if (msc->dts_shift > 0) {
4571  edit_list_dts_entry_end -= msc->dts_shift;
4572  av_log(mov->fc, AV_LOG_DEBUG, "Shifting DTS by %d because of negative CTTS.\n", msc->dts_shift);
4573  }
4574 
4575  start_dts = edit_list_dts_entry_end;
4576 
4577  while (get_edit_list_entry(mov, msc, edit_list_index, &edit_list_media_time,
4578  &edit_list_duration, mov->time_scale)) {
4579  av_log(mov->fc, AV_LOG_DEBUG, "Processing st: %d, edit list %"PRId64" - media time: %"PRId64", duration: %"PRId64"\n",
4580  st->index, edit_list_index, edit_list_media_time, edit_list_duration);
4581  edit_list_index++;
4582  edit_list_dts_counter = edit_list_dts_entry_end;
4583  edit_list_dts_entry_end = av_sat_add64(edit_list_dts_entry_end, edit_list_duration);
4584  if (edit_list_dts_entry_end == INT64_MAX) {
4585  av_log(mov->fc, AV_LOG_ERROR, "Cannot calculate dts entry length with duration %"PRId64"\n",
4586  edit_list_duration);
4587  break;
4588  }
4589  num_discarded_begin = 0;
4590  if (!found_non_empty_edit && edit_list_media_time == -1) {
4591  empty_edits_sum_duration += edit_list_duration;
4592  continue;
4593  }
4594  found_non_empty_edit = 1;
4595 
4596  // If we encounter a non-negative edit list reset the skip_samples/initial_padding fields and set them
4597  // according to the edit list below.
4598  if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
4599  if (first_non_zero_audio_edit < 0) {
4600  first_non_zero_audio_edit = 1;
4601  } else {
4602  first_non_zero_audio_edit = 0;
4603  }
4604 
4605  if (first_non_zero_audio_edit > 0)
4606  sti->skip_samples = st->codecpar->initial_padding = 0;
4607  }
4608 
4609  // While reordering frame index according to edit list we must handle properly
4610  // the scenario when edit list entry starts from none key frame.
4611  // We find closest previous key frame and preserve it and consequent frames in index.
4612  // All frames which are outside edit list entry time boundaries will be dropped after decoding.
4613  search_timestamp = edit_list_media_time;
4614  if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
4615  // Audio decoders like AAC need need a decoder delay samples previous to the current sample,
4616  // to correctly decode this frame. Hence for audio we seek to a frame 1 sec. before the
4617  // edit_list_media_time to cover the decoder delay.
4618  search_timestamp = FFMAX(search_timestamp - msc->time_scale, e_old[0].timestamp);
4619  }
4620 
4621  if (find_prev_closest_index(st, e_old, nb_old, tts_data_old, tts_count_old, search_timestamp, 0,
4622  &index, &tts_index_old, &tts_sample_old) < 0) {
4623  av_log(mov->fc, AV_LOG_WARNING,
4624  "st: %d edit list: %"PRId64" Missing key frame while searching for timestamp: %"PRId64"\n",
4625  st->index, edit_list_index, search_timestamp);
4626  if (find_prev_closest_index(st, e_old, nb_old, tts_data_old, tts_count_old, search_timestamp, AVSEEK_FLAG_ANY,
4627  &index, &tts_index_old, &tts_sample_old) < 0) {
4628  av_log(mov->fc, AV_LOG_WARNING,
4629  "st: %d edit list %"PRId64" Cannot find an index entry before timestamp: %"PRId64".\n",
4630  st->index, edit_list_index, search_timestamp);
4631  index = 0;
4632  tts_index_old = 0;
4633  tts_sample_old = 0;
4634  }
4635  }
4636  current = e_old + index;
4637  edit_list_start_tts_sample = tts_sample_old;
4638 
4639  // Iterate over index and arrange it according to edit list
4640  edit_list_start_encountered = 0;
4641  found_keyframe_after_edit = 0;
4642  for (; current < e_old_end; current++, index++) {
4643  // check if frame outside edit list mark it for discard
4644  frame_duration = (current + 1 < e_old_end) ?
4645  ((current + 1)->timestamp - current->timestamp) : edit_list_duration;
4646 
4647  flags = current->flags;
4648 
4649  // frames (pts) before or after edit list
4650  curr_cts = current->timestamp + msc->dts_shift;
4651  curr_ctts = 0;
4652 
4653  if (tts_data_old && tts_index_old < tts_count_old) {
4654  curr_ctts = tts_data_old[tts_index_old].offset;
4655  av_log(mov->fc, AV_LOG_TRACE, "stts: %"PRId64" ctts: %"PRId64", tts_index: %"PRId64", tts_count: %"PRId64"\n",
4656  curr_cts, curr_ctts, tts_index_old, tts_count_old);
4657  curr_cts += curr_ctts;
4658  tts_sample_old++;
4659  if (tts_sample_old == tts_data_old[tts_index_old].count) {
4660  if (add_tts_entry(&msc->tts_data, &msc->tts_count,
4661  &msc->tts_allocated_size,
4662  tts_data_old[tts_index_old].count - edit_list_start_tts_sample,
4663  tts_data_old[tts_index_old].offset, tts_data_old[tts_index_old].duration) == -1) {
4664  av_log(mov->fc, AV_LOG_ERROR, "Cannot add Time To Sample entry %"PRId64" - {%"PRId64", %d}\n",
4665  tts_index_old,
4666  tts_data_old[tts_index_old].count - edit_list_start_tts_sample,
4667  tts_data_old[tts_index_old].offset);
4668  break;
4669  }
4670  tts_index_old++;
4671  tts_sample_old = 0;
4672  edit_list_start_tts_sample = 0;
4673  }
4674  }
4675 
4676  if (curr_cts < edit_list_media_time || curr_cts >= (edit_list_duration + edit_list_media_time)) {
4678  curr_cts < edit_list_media_time && curr_cts + frame_duration > edit_list_media_time &&
4679  first_non_zero_audio_edit > 0) {
4680  packet_skip_samples = edit_list_media_time - curr_cts;
4681  sti->skip_samples += packet_skip_samples;
4682 
4683  // Shift the index entry timestamp by packet_skip_samples to be correct.
4684  edit_list_dts_counter -= packet_skip_samples;
4685  if (edit_list_start_encountered == 0) {
4686  edit_list_start_encountered = 1;
4687  // Make timestamps strictly monotonically increasing for audio, by rewriting timestamps for
4688  // discarded packets.
4689  if (frame_duration_buffer) {
4690  fix_index_entry_timestamps(st, sti->nb_index_entries, edit_list_dts_counter,
4691  frame_duration_buffer, num_discarded_begin);
4692  av_freep(&frame_duration_buffer);
4693  }
4694  }
4695 
4696  av_log(mov->fc, AV_LOG_DEBUG, "skip %d audio samples from curr_cts: %"PRId64"\n", packet_skip_samples, curr_cts);
4697  } else {
4699  av_log(mov->fc, AV_LOG_DEBUG, "drop a frame at curr_cts: %"PRId64" @ %"PRId64"\n", curr_cts, index);
4700 
4701  if (edit_list_start_encountered == 0) {
4702  num_discarded_begin++;
4703  frame_duration_buffer = av_realloc(frame_duration_buffer,
4704  num_discarded_begin * sizeof(int64_t));
4705  if (!frame_duration_buffer) {
4706  av_log(mov->fc, AV_LOG_ERROR, "Cannot reallocate frame duration buffer\n");
4707  break;
4708  }
4709  frame_duration_buffer[num_discarded_begin - 1] = frame_duration;
4710 
4711  // Increment skip_samples for the first non-zero audio edit list
4712  if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
4713  first_non_zero_audio_edit > 0 && st->codecpar->codec_id != AV_CODEC_ID_VORBIS) {
4714  sti->skip_samples += frame_duration;
4715  }
4716  }
4717  }
4718  } else {
4719  if (msc->min_corrected_pts < 0) {
4720  msc->min_corrected_pts = edit_list_dts_counter + curr_ctts + msc->dts_shift;
4721  } else {
4722  msc->min_corrected_pts = FFMIN(msc->min_corrected_pts, edit_list_dts_counter + curr_ctts + msc->dts_shift);
4723  }
4724  if (edit_list_start_encountered == 0) {
4725  edit_list_start_encountered = 1;
4726  // Make timestamps strictly monotonically increasing by rewriting timestamps for
4727  // discarded packets.
4728  if (frame_duration_buffer) {
4729  fix_index_entry_timestamps(st, sti->nb_index_entries, edit_list_dts_counter,
4730  frame_duration_buffer, num_discarded_begin);
4731  av_freep(&frame_duration_buffer);
4732  }
4733  }
4734  }
4735 
4736  if (add_index_entry(st, current->pos, edit_list_dts_counter, current->size,
4737  current->min_distance, flags) == -1) {
4738  av_log(mov->fc, AV_LOG_ERROR, "Cannot add index entry\n");
4739  break;
4740  }
4741 
4742  // Update the index ranges array
4743  if (!current_index_range || index != current_index_range->end) {
4744  current_index_range = current_index_range ? current_index_range + 1
4745  : msc->index_ranges;
4746  current_index_range->start = index;
4747  }
4748  current_index_range->end = index + 1;
4749 
4750  // Only start incrementing DTS in frame_duration amounts, when we encounter a frame in edit list.
4751  if (edit_list_start_encountered > 0) {
4752  edit_list_dts_counter = edit_list_dts_counter + frame_duration;
4753  }
4754 
4755  // Break when found first key frame after edit entry completion
4756  if ((curr_cts + frame_duration >= (edit_list_duration + edit_list_media_time)) &&
4758  if (msc->ctts_count) {
4759  // If we have CTTS and this is the first keyframe after edit elist,
4760  // wait for one more, because there might be trailing B-frames after this I-frame
4761  // that do belong to the edit.
4762  if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO && found_keyframe_after_edit == 0) {
4763  found_keyframe_after_edit = 1;
4764  continue;
4765  }
4766  if (tts_sample_old != 0) {
4767  if (add_tts_entry(&msc->tts_data, &msc->tts_count,
4768  &msc->tts_allocated_size,
4769  tts_sample_old - edit_list_start_tts_sample,
4770  tts_data_old[tts_index_old].offset, tts_data_old[tts_index_old].duration) == -1) {
4771  av_log(mov->fc, AV_LOG_ERROR, "Cannot add Time To Sample entry %"PRId64" - {%"PRId64", %d}\n",
4772  tts_index_old, tts_sample_old - edit_list_start_tts_sample,
4773  tts_data_old[tts_index_old].offset);
4774  break;
4775  }
4776  }
4777  }
4778  break;
4779  }
4780  }
4781  }
4782  // If there are empty edits, then msc->min_corrected_pts might be positive
4783  // intentionally. So we subtract the sum duration of empty edits here.
4784  msc->min_corrected_pts -= empty_edits_sum_duration;
4785 
4786  // If the minimum pts turns out to be greater than zero after fixing the index, then we subtract the
4787  // dts by that amount to make the first pts zero.
4788  if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
4789  if (msc->min_corrected_pts > 0) {
4790  av_log(mov->fc, AV_LOG_DEBUG, "Offset DTS by %"PRId64" to make first pts zero.\n", msc->min_corrected_pts);
4791  for (int i = 0; i < sti->nb_index_entries; ++i)
4793  }
4794  }
4795  // Start time should be equal to zero or the duration of any empty edits.
4796  st->start_time = empty_edits_sum_duration;
4797 
4798  // Update av stream length, if it ends up shorter than the track's media duration
4799  st->duration = FFMIN(st->duration, edit_list_dts_entry_end - start_dts);
4801 
4802  // Free the old index and the old CTTS structures
4803  av_free(e_old);
4804  av_free(tts_data_old);
4805  av_freep(&frame_duration_buffer);
4806 
4807  // Null terminate the index ranges array
4808  current_index_range = current_index_range ? current_index_range + 1
4809  : msc->index_ranges;
4810  current_index_range->start = 0;
4811  current_index_range->end = 0;
4812  msc->current_index = msc->index_ranges[0].start;
4813 }
4814 
4815 static uint32_t get_sgpd_sync_index(const MOVStreamContext *sc, int nal_unit_type)
4816 {
4817  for (uint32_t i = 0; i < sc->sgpd_sync_count; i++)
4818  if (sc->sgpd_sync[i] == nal_unit_type)
4819  return i + 1;
4820  return 0;
4821 }
4822 
4824 {
4825  int k;
4826  int sample_id = 0;
4827  uint32_t cra_index;
4828  MOVStreamContext *sc = st->priv_data;
4829 
4830  if (st->codecpar->codec_id != AV_CODEC_ID_HEVC || !sc->sync_group_count)
4831  return 0;
4832 
4833  /* Build an unrolled index of the samples */
4834  sc->sample_offsets_count = 0;
4835  for (uint32_t i = 0; i < sc->ctts_count; i++) {
4836  if (sc->ctts_data[i].count > INT_MAX - sc->sample_offsets_count)
4837  return AVERROR(ENOMEM);
4838  sc->sample_offsets_count += sc->ctts_data[i].count;
4839  }
4840  av_freep(&sc->sample_offsets);
4842  if (!sc->sample_offsets)
4843  return AVERROR(ENOMEM);
4844  k = 0;
4845  for (uint32_t i = 0; i < sc->ctts_count; i++)
4846  for (int j = 0; j < sc->ctts_data[i].count; j++)
4847  sc->sample_offsets[k++] = sc->ctts_data[i].offset;
4848 
4849  /* The following HEVC NAL type reveal the use of open GOP sync points
4850  * (TODO: BLA types may also be concerned) */
4851  cra_index = get_sgpd_sync_index(sc, HEVC_NAL_CRA_NUT); /* Clean Random Access */
4852  if (!cra_index)
4853  return 0;
4854 
4855  /* Build a list of open-GOP key samples */
4856  sc->open_key_samples_count = 0;
4857  for (uint32_t i = 0; i < sc->sync_group_count; i++)
4858  if (sc->sync_group[i].index == cra_index) {
4859  if (sc->sync_group[i].count > INT_MAX - sc->open_key_samples_count)
4860  return AVERROR(ENOMEM);
4862  }
4863  av_freep(&sc->open_key_samples);
4865  if (!sc->open_key_samples)
4866  return AVERROR(ENOMEM);
4867  k = 0;
4868  for (uint32_t i = 0; i < sc->sync_group_count; i++) {
4869  const MOVSbgp *sg = &sc->sync_group[i];
4870  if (sg->index == cra_index)
4871  for (uint32_t j = 0; j < sg->count; j++)
4872  sc->open_key_samples[k++] = sample_id;
4873  if (sg->count > INT_MAX - sample_id)
4874  return AVERROR_PATCHWELCOME;
4875  sample_id += sg->count;
4876  }
4877 
4878  /* Identify the minimal time step between samples */
4879  sc->min_sample_duration = UINT_MAX;
4880  for (uint32_t i = 0; i < sc->stts_count; i++)
4882 
4883  return 0;
4884 }
4885 
4886 #define MOV_MERGE_CTTS 1
4887 #define MOV_MERGE_STTS 2
4888 /*
4889  * Merge stts and ctts arrays into a new combined array.
4890  * stts_count and ctts_count may be left untouched as they will be
4891  * used to check for the presence of either of them.
4892  */
4893 static int mov_merge_tts_data(MOVContext *mov, AVStream *st, int flags)
4894 {
4895  MOVStreamContext *sc = st->priv_data;
4896  int ctts = sc->ctts_data && (flags & MOV_MERGE_CTTS);
4897  int stts = sc->stts_data && (flags & MOV_MERGE_STTS);
4898  int idx = 0;
4899 
4900  if (!sc->ctts_data && !sc->stts_data)
4901  return 0;
4902  // Expand time to sample entries such that we have a 1-1 mapping with samples
4903  if (!sc->sample_count || sc->sample_count >= UINT_MAX / sizeof(*sc->tts_data))
4904  return -1;
4905 
4906  if (ctts) {
4908  sc->sample_count * sizeof(*sc->tts_data));
4909  if (!sc->tts_data)
4910  return -1;
4911 
4912  memset(sc->tts_data, 0, sc->tts_allocated_size);
4913 
4914  for (int i = 0; i < sc->ctts_count &&
4915  idx < sc->sample_count; i++)
4916  for (int j = 0; j < sc->ctts_data[i].count &&
4917  idx < sc->sample_count; j++) {
4918  sc->tts_data[idx].offset = sc->ctts_data[i].offset;
4919  sc->tts_data[idx++].count = 1;
4920  }
4921 
4922  sc->tts_count = idx;
4923  } else
4924  sc->ctts_count = 0;
4925  av_freep(&sc->ctts_data);
4926  sc->ctts_allocated_size = 0;
4927 
4928  idx = 0;
4929  if (stts) {
4931  sc->sample_count * sizeof(*sc->tts_data));
4932  if (!tts_data)
4933  return -1;
4934 
4935  if (!sc->tts_data)
4936  memset(tts_data, 0, sc->tts_allocated_size);
4937  sc->tts_data = tts_data;
4938 
4939  for (int i = 0; i < sc->stts_count &&
4940  idx < sc->sample_count; i++)
4941  for (int j = 0; j < sc->stts_data[i].count &&
4942  idx < sc->sample_count; j++) {
4943  sc->tts_data[idx].duration = sc->stts_data[i].duration;
4944  sc->tts_data[idx++].count = 1;
4945  }
4946 
4947  sc->tts_count = FFMAX(sc->tts_count, idx);
4948  } else
4949  sc->stts_count = 0;
4950  av_freep(&sc->stts_data);
4951  sc->stts_allocated_size = 0;
4952 
4953  return 0;
4954 }
4955 
4956 static void mov_build_index(MOVContext *mov, AVStream *st)
4957 {
4958  MOVStreamContext *sc = st->priv_data;
4959  FFStream *const sti = ffstream(st);
4960  int64_t current_offset;
4961  int64_t current_dts = 0;
4962  unsigned int stts_index = 0;
4963  unsigned int stsc_index = 0;
4964  unsigned int stss_index = 0;
4965  unsigned int stps_index = 0;
4966  unsigned int i, j;
4967  uint64_t stream_size = 0;
4968 
4969  int ret = build_open_gop_key_points(st);
4970  if (ret < 0)
4971  return;
4972 
4973  if (sc->elst_count) {
4974  int i, edit_start_index = 0, multiple_edits = 0;
4975  int64_t empty_duration = 0; // empty duration of the first edit list entry
4976  int64_t start_time = 0; // start time of the media
4977 
4978  for (i = 0; i < sc->elst_count; i++) {
4979  const MOVElst *e = &sc->elst_data[i];
4980  if (i == 0 && e->time == -1) {
4981  /* if empty, the first entry is the start time of the stream
4982  * relative to the presentation itself */
4983  empty_duration = e->duration;
4984  edit_start_index = 1;
4985  } else if (i == edit_start_index && e->time >= 0) {
4986  start_time = e->time;
4987  } else {
4988  multiple_edits = 1;
4989  }
4990  }
4991 
4992  if (multiple_edits && !mov->advanced_editlist) {
4994  av_log(mov->fc, AV_LOG_WARNING, "multiple edit list entries, "
4995  "not supported in fragmented MP4 files\n");
4996  else
4997  av_log(mov->fc, AV_LOG_WARNING, "multiple edit list entries, "
4998  "Use -advanced_editlist to correctly decode otherwise "
4999  "a/v desync might occur\n");
5000  }
5001 
5002  /* adjust first dts according to edit list */
5003  if ((empty_duration || start_time) && mov->time_scale > 0) {
5004  if (empty_duration)
5005  empty_duration = av_rescale(empty_duration, sc->time_scale, mov->time_scale);
5006 
5007  if (av_sat_sub64(start_time, empty_duration) != start_time - (uint64_t)empty_duration)
5008  av_log(mov->fc, AV_LOG_WARNING, "start_time - empty_duration is not representable\n");
5009 
5010  sc->time_offset = start_time - (uint64_t)empty_duration;
5012  if (!mov->advanced_editlist)
5013  current_dts = -av_clip64(sc->time_offset, -INT64_MAX, INT64_MAX);
5014  }
5015 
5016  if (!multiple_edits && !mov->advanced_editlist &&
5019  (AVRational){1, st->codecpar->sample_rate});
5020  }
5021 
5022  /* only use old uncompressed audio chunk demuxing when stts specifies it */
5023  if (!(st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
5024  sc->stts_count == 1 && sc->stts_data && sc->stts_data[0].duration == 1)) {
5025  unsigned int current_sample = 0;
5026  unsigned int stts_sample = 0;
5027  unsigned int sample_size;
5028  unsigned int distance = 0;
5029  unsigned int rap_group_index = 0;
5030  unsigned int rap_group_sample = 0;
5031  int rap_group_present = sc->rap_group_count && sc->rap_group;
5032  int key_off = (sc->keyframe_count && sc->keyframes[0] > 0) || (sc->stps_count && sc->stps_data[0] > 0);
5033 
5034  av_assert0(sc->dts_shift >= 0);
5035  if (current_dts < INT64_MIN + sc->dts_shift)
5036  return;
5037  current_dts -= sc->dts_shift;
5038  if (!sc->sample_count || sti->nb_index_entries || sc->tts_count)
5039  return;
5040  if (sc->sample_count >= UINT_MAX / sizeof(*sti->index_entries) - sti->nb_index_entries)
5041  return;
5042  if (av_reallocp_array(&sti->index_entries,
5043  sti->nb_index_entries + sc->sample_count,
5044  sizeof(*sti->index_entries)) < 0) {
5045  sti->nb_index_entries = 0;
5046  return;
5047  }
5048  sti->index_entries_allocated_size = (sti->nb_index_entries + sc->sample_count) * sizeof(*sti->index_entries);
5049 
5051  if (ret < 0)
5052  return;
5053 
5054  for (i = 0; i < sc->chunk_count; i++) {
5055  int64_t next_offset = i+1 < sc->chunk_count ? sc->chunk_offsets[i+1] : INT64_MAX;
5056  current_offset = sc->chunk_offsets[i];
5057  while (mov_stsc_index_valid(stsc_index, sc->stsc_count) &&
5058  i + 1 == sc->stsc_data[stsc_index + 1].first)
5059  stsc_index++;
5060 
5061  if (next_offset > current_offset && sc->sample_size>0 && sc->sample_size < sc->stsz_sample_size &&
5062  sc->stsc_data[stsc_index].count * (int64_t)sc->stsz_sample_size > next_offset - current_offset) {
5063  av_log(mov->fc, AV_LOG_WARNING, "STSZ sample size %d invalid (too large), ignoring\n", sc->stsz_sample_size);
5064  sc->stsz_sample_size = sc->sample_size;
5065  }
5066  if (sc->stsz_sample_size>0 && sc->stsz_sample_size < sc->sample_size) {
5067  av_log(mov->fc, AV_LOG_WARNING, "STSZ sample size %d invalid (too small), ignoring\n", sc->stsz_sample_size);
5068  sc->stsz_sample_size = sc->sample_size;
5069  }
5070 
5071  for (j = 0; j < sc->stsc_data[stsc_index].count; j++) {
5072  int keyframe = 0;
5073  if (current_sample >= sc->sample_count) {
5074  av_log(mov->fc, AV_LOG_ERROR, "wrong sample count\n");
5075  return;
5076  }
5077 
5078  if (!sc->keyframe_absent && (!sc->keyframe_count || current_sample+key_off == sc->keyframes[stss_index])) {
5079  keyframe = 1;
5080  if (stss_index + 1 < sc->keyframe_count)
5081  stss_index++;
5082  } else if (sc->stps_count && current_sample+key_off == sc->stps_data[stps_index]) {
5083  keyframe = 1;
5084  if (stps_index + 1 < sc->stps_count)
5085  stps_index++;
5086  }
5087  if (rap_group_present && rap_group_index < sc->rap_group_count) {
5088  if (sc->rap_group[rap_group_index].index > 0)
5089  keyframe = 1;
5090  if (++rap_group_sample == sc->rap_group[rap_group_index].count) {
5091  rap_group_sample = 0;
5092  rap_group_index++;
5093  }
5094  }
5095  if (sc->keyframe_absent
5096  && !sc->stps_count
5097  && !rap_group_present
5098  && (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO || (i==0 && j==0)))
5099  keyframe = 1;
5100  if (keyframe)
5101  distance = 0;
5102  sample_size = sc->stsz_sample_size > 0 ? sc->stsz_sample_size : sc->sample_sizes[current_sample];
5103  if (current_offset > INT64_MAX - sample_size) {
5104  av_log(mov->fc, AV_LOG_ERROR, "Current offset %"PRId64" or sample size %u is too large\n",
5105  current_offset,
5106  sample_size);
5107  return;
5108  }
5109 
5110  if (sc->pseudo_stream_id == -1 ||
5111  sc->stsc_data[stsc_index].id - 1 == sc->pseudo_stream_id) {
5112  AVIndexEntry *e;
5113  if (sample_size > 0x3FFFFFFF) {
5114  av_log(mov->fc, AV_LOG_ERROR, "Sample size %u is too large\n", sample_size);
5115  return;
5116  }
5117  e = &sti->index_entries[sti->nb_index_entries++];
5118  e->pos = current_offset;
5119  e->timestamp = current_dts;
5120  e->size = sample_size;
5121  e->min_distance = distance;
5122  e->flags = keyframe ? AVINDEX_KEYFRAME : 0;
5123  av_log(mov->fc, AV_LOG_TRACE, "AVIndex stream %d, sample %u, offset %"PRIx64", dts %"PRId64", "
5124  "size %u, distance %u, keyframe %d\n", st->index, current_sample,
5125  current_offset, current_dts, sample_size, distance, keyframe);
5126  if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && sti->nb_index_entries < 100)
5127  ff_rfps_add_frame(mov->fc, st, current_dts);
5128  }
5129 
5130  current_offset += sample_size;
5131  stream_size += sample_size;
5132 
5133  if (current_dts > INT64_MAX - sc->tts_data[stts_index].duration)
5134  return;
5135  current_dts += sc->tts_data[stts_index].duration;
5136 
5137  distance++;
5138  stts_sample++;
5139  current_sample++;
5140  if (stts_index + 1 < sc->tts_count && stts_sample == sc->tts_data[stts_index].count) {
5141  stts_sample = 0;
5142  stts_index++;
5143  }
5144  }
5145  }
5146  if (st->duration > 0)
5147  st->codecpar->bit_rate = stream_size*8*sc->time_scale/st->duration;
5148  } else {
5149  unsigned chunk_samples, total = 0;
5150 
5151  if (!sc->chunk_count || sc->tts_count)
5152  return;
5153 
5154  // compute total chunk count
5155  for (i = 0; i < sc->stsc_count; i++) {
5156  unsigned count, chunk_count;
5157 
5158  chunk_samples = sc->stsc_data[i].count;
5159  if (i != sc->stsc_count - 1 &&
5160  sc->samples_per_frame && chunk_samples % sc->samples_per_frame) {
5161  av_log(mov->fc, AV_LOG_ERROR, "error unaligned chunk\n");
5162  return;
5163  }
5164 
5165  if (sc->samples_per_frame >= 160) { // gsm
5166  count = chunk_samples / sc->samples_per_frame;
5167  } else if (sc->samples_per_frame > 1) {
5168  unsigned samples = (1024/sc->samples_per_frame)*sc->samples_per_frame;
5169  count = (chunk_samples+samples-1) / samples;
5170  } else {
5171  count = (chunk_samples+1023) / 1024;
5172  }
5173 
5174  if (mov_stsc_index_valid(i, sc->stsc_count))
5175  chunk_count = sc->stsc_data[i+1].first - sc->stsc_data[i].first;
5176  else
5177  chunk_count = sc->chunk_count - (sc->stsc_data[i].first - 1);
5178  total += chunk_count * count;
5179  }
5180 
5181  av_log(mov->fc, AV_LOG_TRACE, "chunk count %u\n", total);
5182  if (total >= UINT_MAX / sizeof(*sti->index_entries) - sti->nb_index_entries)
5183  return;
5184  if (av_reallocp_array(&sti->index_entries,
5185  sti->nb_index_entries + total,
5186  sizeof(*sti->index_entries)) < 0) {
5187  sti->nb_index_entries = 0;
5188  return;
5189  }
5190  sti->index_entries_allocated_size = (sti->nb_index_entries + total) * sizeof(*sti->index_entries);
5191 
5192  // populate index
5193  for (i = 0; i < sc->chunk_count; i++) {
5194  current_offset = sc->chunk_offsets[i];
5195  if (mov_stsc_index_valid(stsc_index, sc->stsc_count) &&
5196  i + 1 == sc->stsc_data[stsc_index + 1].first)
5197  stsc_index++;
5198  chunk_samples = sc->stsc_data[stsc_index].count;
5199 
5200  while (chunk_samples > 0) {
5201  AVIndexEntry *e;
5202  unsigned size, samples;
5203 
5204  if (sc->samples_per_frame > 1 && !sc->bytes_per_frame) {
5206  "Zero bytes per frame, but %d samples per frame",
5207  sc->samples_per_frame);
5208  return;
5209  }
5210 
5211  if (sc->samples_per_frame >= 160) { // gsm
5212  samples = sc->samples_per_frame;
5213  size = sc->bytes_per_frame;
5214  } else {
5215  if (sc->samples_per_frame > 1) {
5216  samples = FFMIN((1024 / sc->samples_per_frame)*
5217  sc->samples_per_frame, chunk_samples);
5219  } else {
5220  samples = FFMIN(1024, chunk_samples);
5221  size = samples * sc->sample_size;
5222  }
5223  }
5224 
5225  if (sti->nb_index_entries >= total) {
5226  av_log(mov->fc, AV_LOG_ERROR, "wrong chunk count %u\n", total);
5227  return;
5228  }
5229  if (size > 0x3FFFFFFF) {
5230  av_log(mov->fc, AV_LOG_ERROR, "Sample size %u is too large\n", size);
5231  return;
5232  }
5233  e = &sti->index_entries[sti->nb_index_entries++];
5234  e->pos = current_offset;
5235  e->timestamp = current_dts;
5236  e->size = size;
5237  e->min_distance = 0;
5238  e->flags = AVINDEX_KEYFRAME;
5239  av_log(mov->fc, AV_LOG_TRACE, "AVIndex stream %d, chunk %u, offset %"PRIx64", dts %"PRId64", "
5240  "size %u, duration %u\n", st->index, i, current_offset, current_dts,
5241  size, samples);
5242 
5243  current_offset += size;
5244  if (current_dts > INT64_MAX - samples)
5245  return;
5246  current_dts += samples;
5247  chunk_samples -= samples;
5248  }
5249  }
5250 
5252  if (ret < 0)
5253  return;
5254  }
5255 
5256  if (!mov->ignore_editlist && mov->advanced_editlist) {
5257  // Fix index according to edit lists.
5258  mov_fix_index(mov, st);
5259  }
5260 
5261  // Update start time of the stream.
5264  if (sc->tts_data) {
5265  st->start_time = av_sat_add64(st->start_time, sc->tts_data[0].offset);
5266  }
5267  }
5268 
5269  mov_estimate_video_delay(mov, st);
5270 }
5271 
5272 static int test_same_origin(const char *src, const char *ref) {
5273  char src_proto[64];
5274  char ref_proto[64];
5275  char src_auth[256];
5276  char ref_auth[256];
5277  char src_host[256];
5278  char ref_host[256];
5279  int src_port=-1;
5280  int ref_port=-1;
5281 
5282  av_url_split(src_proto, sizeof(src_proto), src_auth, sizeof(src_auth), src_host, sizeof(src_host), &src_port, NULL, 0, src);
5283  av_url_split(ref_proto, sizeof(ref_proto), ref_auth, sizeof(ref_auth), ref_host, sizeof(ref_host), &ref_port, NULL, 0, ref);
5284 
5285  if (strlen(src) == 0) {
5286  return -1;
5287  } else if (strlen(src_auth) + 1 >= sizeof(src_auth) ||
5288  strlen(ref_auth) + 1 >= sizeof(ref_auth) ||
5289  strlen(src_host) + 1 >= sizeof(src_host) ||
5290  strlen(ref_host) + 1 >= sizeof(ref_host)) {
5291  return 0;
5292  } else if (strcmp(src_proto, ref_proto) ||
5293  strcmp(src_auth, ref_auth) ||
5294  strcmp(src_host, ref_host) ||
5295  src_port != ref_port) {
5296  return 0;
5297  } else
5298  return 1;
5299 }
5300 
5301 static int mov_open_dref(MOVContext *c, AVIOContext **pb, const char *src, MOVDref *ref)
5302 {
5303  /* try relative path, we do not try the absolute because it can leak information about our
5304  system to an attacker */
5305  if (ref->nlvl_to > 0 && ref->nlvl_from > 0) {
5306  char filename[1025];
5307  const char *src_path;
5308  int i, l;
5309 
5310  /* find a source dir */
5311  src_path = strrchr(src, '/');
5312  if (src_path)
5313  src_path++;
5314  else
5315  src_path = src;
5316 
5317  /* find a next level down to target */
5318  for (i = 0, l = strlen(ref->path) - 1; l >= 0; l--)
5319  if (ref->path[l] == '/') {
5320  if (i == ref->nlvl_to - 1)
5321  break;
5322  else
5323  i++;
5324  }
5325 
5326  /* compose filename if next level down to target was found */
5327  if (i == ref->nlvl_to - 1 && src_path - src < sizeof(filename)) {
5328  memcpy(filename, src, src_path - src);
5329  filename[src_path - src] = 0;
5330 
5331  for (i = 1; i < ref->nlvl_from; i++)
5332  av_strlcat(filename, "../", sizeof(filename));
5333 
5334  av_strlcat(filename, ref->path + l + 1, sizeof(filename));
5335  if (!c->use_absolute_path) {
5336  int same_origin = test_same_origin(src, filename);
5337 
5338  if (!same_origin) {
5339  av_log(c->fc, AV_LOG_ERROR,
5340  "Reference with mismatching origin, %s not tried for security reasons, "
5341  "set demuxer option use_absolute_path to allow it anyway\n",
5342  ref->path);
5343  return AVERROR(ENOENT);
5344  }
5345 
5346  if (strstr(ref->path + l + 1, "..") ||
5347  strstr(ref->path + l + 1, ":") ||
5348  (ref->nlvl_from > 1 && same_origin < 0) ||
5349  (filename[0] == '/' && src_path == src))
5350  return AVERROR(ENOENT);
5351  }
5352 
5353  if (strlen(filename) + 1 == sizeof(filename))
5354  return AVERROR(ENOENT);
5355  if (!c->fc->io_open(c->fc, pb, filename, AVIO_FLAG_READ, NULL))
5356  return 0;
5357  }
5358  } else if (c->use_absolute_path) {
5359  av_log(c->fc, AV_LOG_WARNING, "Using absolute path on user request, "
5360  "this is a possible security issue\n");
5361  if (!c->fc->io_open(c->fc, pb, ref->path, AVIO_FLAG_READ, NULL))
5362  return 0;
5363  } else {
5364  av_log(c->fc, AV_LOG_ERROR,
5365  "Absolute path %s not tried for security reasons, "
5366  "set demuxer option use_absolute_path to allow absolute paths\n",
5367  ref->path);
5368  }
5369 
5370  return AVERROR(ENOENT);
5371 }
5372 
5374 {
5375  if (sc->time_scale <= 0) {
5376  av_log(c->fc, AV_LOG_WARNING, "stream %d, timescale not set\n", sc->ffindex);
5377  sc->time_scale = c->time_scale;
5378  if (sc->time_scale <= 0)
5379  sc->time_scale = 1;
5380  }
5381 }
5382 
5383 #if CONFIG_IAMFDEC
5384 static int mov_update_iamf_streams(MOVContext *c, const AVStream *st)
5385 {
5386  const MOVStreamContext *sc = st->priv_data;
5387  const IAMFContext *iamf = &sc->iamf->iamf;
5388 
5389  for (int i = 0; i < iamf->nb_audio_elements; i++) {
5390  const AVStreamGroup *stg = NULL;
5391 
5392  for (int j = 0; j < c->fc->nb_stream_groups; j++)
5393  if (c->fc->stream_groups[j]->id == iamf->audio_elements[i]->audio_element_id)
5394  stg = c->fc->stream_groups[j];
5395  av_assert0(stg);
5396 
5397  for (int j = 0; j < stg->nb_streams; j++) {
5398  const FFStream *sti = cffstream(st);
5399  AVStream *out = stg->streams[j];
5400  FFStream *out_sti = ffstream(stg->streams[j]);
5401 
5402  out->codecpar->bit_rate = 0;
5403 
5404  if (out == st)
5405  continue;
5406 
5407  out->time_base = st->time_base;
5408  out->start_time = st->start_time;
5409  out->duration = st->duration;
5410  out->nb_frames = st->nb_frames;
5411  out->discard = st->discard;
5412 
5413  av_assert0(!out_sti->index_entries);
5415  if (!out_sti->index_entries)
5416  return AVERROR(ENOMEM);
5417 
5419  out_sti->nb_index_entries = sti->nb_index_entries;
5420  out_sti->skip_samples = sti->skip_samples;
5421  memcpy(out_sti->index_entries, sti->index_entries, sti->index_entries_allocated_size);
5422  }
5423  }
5424 
5425  return 0;
5426 }
5427 #endif
5428 
5429 static int sanity_checks(void *log_obj, MOVStreamContext *sc, int index)
5430 {
5431  if ((sc->chunk_count && (!sc->stts_count || !sc->stsc_count ||
5432  (!sc->sample_size && !sc->sample_count))) ||
5433  (sc->sample_count && (!sc->chunk_count ||
5434  (!sc->sample_size && !sc->sample_sizes)))) {
5435  av_log(log_obj, AV_LOG_ERROR, "stream %d, missing mandatory atoms, broken header\n",
5436  index);
5437  return 1;
5438  }
5439 
5440  if (sc->stsc_count && sc->stsc_data[ sc->stsc_count - 1 ].first > sc->chunk_count) {
5441  av_log(log_obj, AV_LOG_ERROR, "stream %d, contradictionary STSC and STCO\n",
5442  index);
5443  return 2;
5444  }
5445  return 0;
5446 }
5447 
5449 {
5450  AVStream *st;
5451  MOVStreamContext *sc;
5452  int ret;
5453 
5454  st = avformat_new_stream(c->fc, NULL);
5455  if (!st) return AVERROR(ENOMEM);
5456  st->id = -1;
5457  sc = av_mallocz(sizeof(MOVStreamContext));
5458  if (!sc) return AVERROR(ENOMEM);
5459 
5460  st->priv_data = sc;
5462  sc->ffindex = st->index;
5463  c->trak_index = st->index;
5464  sc->refcount = 1;
5465 
5466  if ((ret = mov_read_default(c, pb, atom)) < 0)
5467  return ret;
5468 
5469  c->trak_index = -1;
5470 
5471  // Here stsc refers to a chunk not described in stco. This is technically invalid,
5472  // but we can overlook it (clearing stsc) whenever stts_count == 0 (indicating no samples).
5473  if (!sc->chunk_count && !sc->stts_count && sc->stsc_count) {
5474  sc->stsc_count = 0;
5475  av_freep(&sc->stsc_data);
5476  }
5477 
5478  ret = sanity_checks(c->fc, sc, st->index);
5479  if (ret)
5480  return ret > 1 ? AVERROR_INVALIDDATA : 0;
5481 
5482  fix_timescale(c, sc);
5483 
5484  avpriv_set_pts_info(st, 64, 1, sc->time_scale);
5485 
5486  /*
5487  * Advanced edit list support does not work with fragemented MP4s, which
5488  * have stsc, stsz, stco, and stts with zero entries in the moov atom.
5489  * In these files, trun atoms may be streamed in.
5490  */
5491  if (!sc->stts_count && c->advanced_editlist) {
5492 
5493  av_log(c->fc, AV_LOG_VERBOSE, "advanced_editlist does not work with fragmented "
5494  "MP4. disabling.\n");
5495  c->advanced_editlist = 0;
5496  c->advanced_editlist_autodisabled = 1;
5497  }
5498 
5499  mov_build_index(c, st);
5500 
5501 #if CONFIG_IAMFDEC
5502  if (sc->iamf) {
5503  ret = mov_update_iamf_streams(c, st);
5504  if (ret < 0)
5505  return ret;
5506  }
5507 #endif
5508 
5509  if (sc->dref_id-1 < sc->drefs_count && sc->drefs[sc->dref_id-1].path) {
5510  MOVDref *dref = &sc->drefs[sc->dref_id - 1];
5511  if (c->enable_drefs) {
5512  if (mov_open_dref(c, &sc->pb, c->fc->url, dref) < 0)
5513  av_log(c->fc, AV_LOG_ERROR,
5514  "stream %d, error opening alias: path='%s', dir='%s', "
5515  "filename='%s', volume='%s', nlvl_from=%d, nlvl_to=%d\n",
5516  st->index, dref->path, dref->dir, dref->filename,
5517  dref->volume, dref->nlvl_from, dref->nlvl_to);
5518  } else {
5519  av_log(c->fc, AV_LOG_WARNING,
5520  "Skipped opening external track: "
5521  "stream %d, alias: path='%s', dir='%s', "
5522  "filename='%s', volume='%s', nlvl_from=%d, nlvl_to=%d."
5523  "Set enable_drefs to allow this.\n",
5524  st->index, dref->path, dref->dir, dref->filename,
5525  dref->volume, dref->nlvl_from, dref->nlvl_to);
5526  }
5527  } else {
5528  sc->pb = c->fc->pb;
5529  sc->pb_is_copied = 1;
5530  }
5531 
5532  if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
5533  int stts_constant = sc->stts_count && sc->tts_count;
5534  if (sc->h_spacing && sc->v_spacing)
5536  sc->h_spacing, sc->v_spacing, INT_MAX);
5537  if (!st->sample_aspect_ratio.num && st->codecpar->width && st->codecpar->height &&
5538  sc->height && sc->width &&
5539  (st->codecpar->width != sc->width || st->codecpar->height != sc->height)) {
5541  (int64_t)st->codecpar->height * sc->width,
5542  (int64_t)st->codecpar->width * sc->height, INT_MAX);
5543  }
5544 
5545 #if FF_API_R_FRAME_RATE
5546  for (unsigned int i = 1; sc->stts_count && i + 1 < sc->tts_count; i++) {
5547  if (sc->tts_data[i].duration == sc->tts_data[0].duration)
5548  continue;
5549  stts_constant = 0;
5550  }
5551  if (stts_constant)
5553  sc->time_scale, sc->tts_data[0].duration, INT_MAX);
5554 #endif
5555  }
5556 
5557 #if CONFIG_H261_DECODER || CONFIG_H263_DECODER || CONFIG_MPEG4_DECODER
5558  switch (st->codecpar->codec_id) {
5559 #if CONFIG_H261_DECODER
5560  case AV_CODEC_ID_H261:
5561 #endif
5562 #if CONFIG_H263_DECODER
5563  case AV_CODEC_ID_H263:
5564 #endif
5565 #if CONFIG_MPEG4_DECODER
5566  case AV_CODEC_ID_MPEG4:
5567 #endif
5568  st->codecpar->width = 0; /* let decoder init width/height */
5569  st->codecpar->height= 0;
5570  break;
5571  }
5572 #endif
5573 
5574  // If the duration of the mp3 packets is not constant, then they could need a parser
5575  if (st->codecpar->codec_id == AV_CODEC_ID_MP3
5576  && sc->time_scale == st->codecpar->sample_rate) {
5577  int stts_constant = 1;
5578  for (int i = 1; sc->stts_count && i < sc->tts_count; i++) {
5579  if (sc->tts_data[i].duration == sc->tts_data[0].duration)
5580  continue;
5581  stts_constant = 0;
5582  }
5583  if (!stts_constant)
5585  }
5586  /* Do not need those anymore. */
5587  av_freep(&sc->chunk_offsets);
5588  av_freep(&sc->sample_sizes);
5589  av_freep(&sc->keyframes);
5590  av_freep(&sc->stps_data);
5591  av_freep(&sc->elst_data);
5592  av_freep(&sc->rap_group);
5593  av_freep(&sc->sync_group);
5594  av_freep(&sc->sgpd_sync);
5595 
5596  return 0;
5597 }
5598 
5600 {
5601  int ret;
5602  c->itunes_metadata = 1;
5603  ret = mov_read_default(c, pb, atom);
5604  c->itunes_metadata = 0;
5605  return ret;
5606 }
5607 
5609 {
5610  uint32_t count;
5611  uint32_t i;
5612 
5613  if (atom.size < 8)
5614  return 0;
5615 
5616  avio_skip(pb, 4);
5617  count = avio_rb32(pb);
5618  atom.size -= 8;
5619  if (count >= UINT_MAX / sizeof(*c->meta_keys)) {
5620  av_log(c->fc, AV_LOG_ERROR,
5621  "The 'keys' atom with the invalid key count: %"PRIu32"\n", count);
5622  return AVERROR_INVALIDDATA;
5623  }
5624 
5625  c->meta_keys_count = count + 1;
5626  c->meta_keys = av_mallocz(c->meta_keys_count * sizeof(*c->meta_keys));
5627  if (!c->meta_keys)
5628  return AVERROR(ENOMEM);
5629 
5630  for (i = 1; i <= count; ++i) {
5631  uint32_t key_size = avio_rb32(pb);
5632  uint32_t type = avio_rl32(pb);
5633  if (key_size < 8 || key_size > atom.size) {
5634  av_log(c->fc, AV_LOG_ERROR,
5635  "The key# %"PRIu32" in meta has invalid size:"
5636  "%"PRIu32"\n", i, key_size);
5637  return AVERROR_INVALIDDATA;
5638  }
5639  atom.size -= key_size;
5640  key_size -= 8;
5641  if (type != MKTAG('m','d','t','a')) {
5642  avio_skip(pb, key_size);
5643  continue;
5644  }
5645  c->meta_keys[i] = av_mallocz(key_size + 1);
5646  if (!c->meta_keys[i])
5647  return AVERROR(ENOMEM);
5648  avio_read(pb, c->meta_keys[i], key_size);
5649  }
5650 
5651  return 0;
5652 }
5653 
5655 {
5656  int64_t end = av_sat_add64(avio_tell(pb), atom.size);
5657  uint8_t *key = NULL, *val = NULL, *mean = NULL;
5658  int i;
5659  int ret = 0;
5660  AVStream *st;
5661 
5662  if (c->fc->nb_streams < 1)
5663  return 0;
5664  st = c->fc->streams[c->fc->nb_streams-1];
5665 
5666  for (i = 0; i < 3; i++) {
5667  uint8_t **p;
5668  uint32_t len, tag;
5669 
5670  if (end - avio_tell(pb) <= 12)
5671  break;
5672 
5673  len = avio_rb32(pb);
5674  tag = avio_rl32(pb);
5675  avio_skip(pb, 4); // flags
5676 
5677  if (len < 12 || len - 12 > end - avio_tell(pb))
5678  break;
5679  len -= 12;
5680 
5681  if (tag == MKTAG('m', 'e', 'a', 'n'))
5682  p = &mean;
5683  else if (tag == MKTAG('n', 'a', 'm', 'e'))
5684  p = &key;
5685  else if (tag == MKTAG('d', 'a', 't', 'a') && len > 4) {
5686  avio_skip(pb, 4);
5687  len -= 4;
5688  p = &val;
5689  } else
5690  break;
5691 
5692  if (*p)
5693  break;
5694 
5695  *p = av_malloc(len + 1);
5696  if (!*p) {
5697  ret = AVERROR(ENOMEM);
5698  break;
5699  }
5700  ret = ffio_read_size(pb, *p, len);
5701  if (ret < 0) {
5702  av_freep(p);
5703  break;
5704  }
5705  (*p)[len] = 0;
5706  }
5707 
5708  if (mean && key && val) {
5709  if (strcmp(key, "iTunSMPB") == 0) {
5710  int priming, remainder, samples;
5711  if(sscanf(val, "%*X %X %X %X", &priming, &remainder, &samples) == 3){
5712  if(priming>0 && priming<16384)
5713  st->codecpar->initial_padding = priming = av_rescale_q(priming, st->time_base,
5714  (AVRational){ 1, st->codecpar->sample_rate });
5715  if (remainder > 0) {
5717  (AVRational){ 1, st->codecpar->sample_rate });
5718  remainder = av_rescale_q(remainder, st->time_base,
5719  (AVRational){ 1, st->codecpar->sample_rate });
5721  (AVRational){ 1, st->codecpar->sample_rate });
5722  if (duration > remainder && duration > samples) {
5723  ffstream(st)->first_discard_sample = duration - remainder;
5725  }
5726  }
5727  av_log(c->fc, AV_LOG_DEBUG, "Parsed iTunSMPB: priming %d, remainder %d samples %d\n",
5728  priming, remainder, samples);
5729  }
5730  }
5731  if (strcmp(mean, "com.apple.iTunes") == 0 &&
5732  strcmp(key, "DISCSUBTITLE") == 0) {
5733  av_dict_set(&c->fc->metadata, "disc_subtitle", val,
5735  val = NULL;
5736  }
5737  if (strcmp(key, "cdec") != 0) {
5738  av_dict_set(&c->fc->metadata, key, val,
5740  key = val = NULL;
5741  }
5742  } else {
5743  av_log(c->fc, AV_LOG_VERBOSE,
5744  "Unhandled or malformed custom metadata of size %"PRId64"\n", atom.size);
5745  }
5746 
5747  avio_seek(pb, end, SEEK_SET);
5748  av_freep(&key);
5749  av_freep(&val);
5750  av_freep(&mean);
5751  return ret;
5752 }
5753 
5755 {
5756  MOVStreamContext *sc;
5757  AVStream *st;
5758 
5759  st = avformat_new_stream(c->fc, NULL);
5760  if (!st)
5761  return AVERROR(ENOMEM);
5762  sc = av_mallocz(sizeof(MOVStreamContext));
5763  if (!sc)
5764  goto fail;
5765 
5766  item->st = st;
5767  st->id = item->item_id;
5768  st->priv_data = sc;
5770  st->codecpar->codec_id = mov_codec_id(st, item->type);
5771  sc->id = st->id;
5772  sc->ffindex = st->index;
5773  st->avg_frame_rate.num = st->avg_frame_rate.den = 1;
5774  st->time_base.num = st->time_base.den = 1;
5775  st->nb_frames = 1;
5776  sc->time_scale = 1;
5777  sc->pb = c->fc->pb;
5778  sc->pb_is_copied = 1;
5779  sc->refcount = 1;
5780 
5781  if (item->name)
5782  av_dict_set(&st->metadata, "title", item->name, 0);
5783 
5784  // Populate the necessary fields used by mov_build_index.
5785  sc->stsc_data = av_malloc_array(1, sizeof(*sc->stsc_data));
5786  if (!sc->stsc_data)
5787  goto fail;
5788  sc->stsc_count = 1;
5789  sc->stsc_data[0].first = 1;
5790  sc->stsc_data[0].count = 1;
5791  sc->stsc_data[0].id = 1;
5792  sc->chunk_offsets = av_malloc_array(1, sizeof(*sc->chunk_offsets));
5793  if (!sc->chunk_offsets)
5794  goto fail;
5795  sc->chunk_count = 1;
5796  sc->stts_data = av_malloc_array(1, sizeof(*sc->stts_data));
5797  if (!sc->stts_data)
5798  goto fail;
5799  sc->stts_count = 1;
5800  sc->stts_data[0].count = 1;
5801  // Not used for still images. But needed by mov_build_index.
5802  sc->stts_data[0].duration = 0;
5803 
5804  return 0;
5805 fail:
5806  mov_free_stream_context(c->fc, st);
5807  ff_remove_stream(c->fc, st);
5808  item->st = NULL;
5809 
5810  return AVERROR(ENOMEM);
5811 }
5812 
5814 {
5815  while (atom.size > 8) {
5816  uint32_t tag;
5817  if (avio_feof(pb))
5818  return AVERROR_EOF;
5819  tag = avio_rl32(pb);
5820  atom.size -= 4;
5821  if (tag == MKTAG('h','d','l','r')) {
5822  avio_seek(pb, -8, SEEK_CUR);
5823  atom.size += 8;
5824  return mov_read_default(c, pb, atom);
5825  }
5826  }
5827  return 0;
5828 }
5829 
5830 // return 1 when matrix is identity, 0 otherwise
5831 #define IS_MATRIX_IDENT(matrix) \
5832  ( (matrix)[0][0] == (1 << 16) && \
5833  (matrix)[1][1] == (1 << 16) && \
5834  (matrix)[2][2] == (1 << 30) && \
5835  !(matrix)[0][1] && !(matrix)[0][2] && \
5836  !(matrix)[1][0] && !(matrix)[1][2] && \
5837  !(matrix)[2][0] && !(matrix)[2][1])
5838 
5840 {
5841  int i, j, e;
5842  int width;
5843  int height;
5844  int display_matrix[3][3];
5845  int res_display_matrix[3][3] = { { 0 } };
5846  AVStream *st;
5847  MOVStreamContext *sc;
5848  int version;
5849  int flags;
5850 
5851  if (c->fc->nb_streams < 1)
5852  return 0;
5853  st = c->fc->streams[c->fc->nb_streams-1];
5854  sc = st->priv_data;
5855 
5856  // Each stream (trak) should have exactly 1 tkhd. This catches bad files and
5857  // avoids corrupting AVStreams mapped to an earlier tkhd.
5858  if (st->id != -1)
5859  return AVERROR_INVALIDDATA;
5860 
5861  version = avio_r8(pb);
5862  flags = avio_rb24(pb);
5864 
5865  if (version == 1) {
5866  avio_rb64(pb);
5867  avio_rb64(pb);
5868  } else {
5869  avio_rb32(pb); /* creation time */
5870  avio_rb32(pb); /* modification time */
5871  }
5872  st->id = (int)avio_rb32(pb); /* track id (NOT 0 !)*/
5873  sc->id = st->id;
5874  avio_rb32(pb); /* reserved */
5875 
5876  /* highlevel (considering edits) duration in movie timebase */
5877  (version == 1) ? avio_rb64(pb) : avio_rb32(pb);
5878  avio_rb32(pb); /* reserved */
5879  avio_rb32(pb); /* reserved */
5880 
5881  avio_rb16(pb); /* layer */
5882  avio_rb16(pb); /* alternate group */
5883  avio_rb16(pb); /* volume */
5884  avio_rb16(pb); /* reserved */
5885 
5886  //read in the display matrix (outlined in ISO 14496-12, Section 6.2.2)
5887  // they're kept in fixed point format through all calculations
5888  // save u,v,z to store the whole matrix in the AV_PKT_DATA_DISPLAYMATRIX
5889  // side data, but the scale factor is not needed to calculate aspect ratio
5890  for (i = 0; i < 3; i++) {
5891  display_matrix[i][0] = avio_rb32(pb); // 16.16 fixed point
5892  display_matrix[i][1] = avio_rb32(pb); // 16.16 fixed point
5893  display_matrix[i][2] = avio_rb32(pb); // 2.30 fixed point
5894  }
5895 
5896  width = avio_rb32(pb); // 16.16 fixed point track width
5897  height = avio_rb32(pb); // 16.16 fixed point track height
5898  sc->width = width >> 16;
5899  sc->height = height >> 16;
5900 
5901  // apply the moov display matrix (after the tkhd one)
5902  for (i = 0; i < 3; i++) {
5903  const int sh[3] = { 16, 16, 30 };
5904  for (j = 0; j < 3; j++) {
5905  for (e = 0; e < 3; e++) {
5906  res_display_matrix[i][j] +=
5907  ((int64_t) display_matrix[i][e] *
5908  c->movie_display_matrix[e][j]) >> sh[e];
5909  }
5910  }
5911  }
5912 
5913  // save the matrix when it is not the default identity
5914  if (!IS_MATRIX_IDENT(res_display_matrix)) {
5915  av_freep(&sc->display_matrix);
5916  sc->display_matrix = av_malloc(sizeof(int32_t) * 9);
5917  if (!sc->display_matrix)
5918  return AVERROR(ENOMEM);
5919 
5920  for (i = 0; i < 3; i++)
5921  for (j = 0; j < 3; j++)
5922  sc->display_matrix[i * 3 + j] = res_display_matrix[i][j];
5923  }
5924 
5925  // transform the display width/height according to the matrix
5926  // to keep the same scale, use [width height 1<<16]
5927  if (width && height && sc->display_matrix) {
5928  double disp_transform[2];
5929 
5930  for (i = 0; i < 2; i++)
5931  disp_transform[i] = hypot(sc->display_matrix[0 + i],
5932  sc->display_matrix[3 + i]);
5933 
5934  if (disp_transform[0] > 1 && disp_transform[1] > 1 &&
5935  disp_transform[0] < (1<<24) && disp_transform[1] < (1<<24) &&
5936  fabs((disp_transform[0] / disp_transform[1]) - 1.0) > 0.01)
5938  disp_transform[0] / disp_transform[1],
5939  INT_MAX);
5940  }
5941  return 0;
5942 }
5943 
5945 {
5946  MOVFragment *frag = &c->fragment;
5947  MOVTrackExt *trex = NULL;
5948  int flags, track_id, i;
5949  MOVFragmentStreamInfo * frag_stream_info;
5950 
5951  avio_r8(pb); /* version */
5952  flags = avio_rb24(pb);
5953 
5954  track_id = avio_rb32(pb);
5955  if (!track_id)
5956  return AVERROR_INVALIDDATA;
5957  for (i = 0; i < c->trex_count; i++)
5958  if (c->trex_data[i].track_id == track_id) {
5959  trex = &c->trex_data[i];
5960  break;
5961  }
5962  if (!trex) {
5963  av_log(c->fc, AV_LOG_WARNING, "could not find corresponding trex (id %u)\n", track_id);
5964  return 0;
5965  }
5966  c->fragment.found_tfhd = 1;
5967  frag->track_id = track_id;
5968  set_frag_stream(&c->frag_index, track_id);
5969 
5972  frag->moof_offset : frag->implicit_offset;
5973  frag->stsd_id = flags & MOV_TFHD_STSD_ID ? avio_rb32(pb) : trex->stsd_id;
5974 
5976  avio_rb32(pb) : trex->duration;
5977  frag->size = flags & MOV_TFHD_DEFAULT_SIZE ?
5978  avio_rb32(pb) : trex->size;
5979  frag->flags = flags & MOV_TFHD_DEFAULT_FLAGS ?
5980  avio_rb32(pb) : trex->flags;
5981  av_log(c->fc, AV_LOG_TRACE, "frag flags 0x%x\n", frag->flags);
5982 
5983  frag_stream_info = get_current_frag_stream_info(&c->frag_index);
5984  if (frag_stream_info) {
5985  frag_stream_info->next_trun_dts = AV_NOPTS_VALUE;
5986  frag_stream_info->stsd_id = frag->stsd_id;
5987  }
5988  return 0;
5989 }
5990 
5992 {
5993  unsigned i, num;
5994  void *new_tracks;
5995 
5996  num = atom.size / 4;
5997  if (!(new_tracks = av_malloc_array(num, sizeof(int))))
5998  return AVERROR(ENOMEM);
5999 
6000  av_free(c->chapter_tracks);
6001  c->chapter_tracks = new_tracks;
6002  c->nb_chapter_tracks = num;
6003 
6004  for (i = 0; i < num && !pb->eof_reached; i++)
6005  c->chapter_tracks[i] = avio_rb32(pb);
6006 
6007  c->nb_chapter_tracks = i;
6008 
6009  return 0;
6010 }
6011 
6013 {
6014  MOVTrackExt *trex;
6015  int err;
6016 
6017  if ((uint64_t)c->trex_count+1 >= UINT_MAX / sizeof(*c->trex_data))
6018  return AVERROR_INVALIDDATA;
6019  if ((err = av_reallocp_array(&c->trex_data, c->trex_count + 1,
6020  sizeof(*c->trex_data))) < 0) {
6021  c->trex_count = 0;
6022  return err;
6023  }
6024 
6025  c->fc->duration = AV_NOPTS_VALUE; // the duration from mvhd is not representing the whole file when fragments are used.
6026 
6027  trex = &c->trex_data[c->trex_count++];
6028  avio_r8(pb); /* version */
6029  avio_rb24(pb); /* flags */
6030  trex->track_id = avio_rb32(pb);
6031  trex->stsd_id = avio_rb32(pb);
6032  trex->duration = avio_rb32(pb);
6033  trex->size = avio_rb32(pb);
6034  trex->flags = avio_rb32(pb);
6035  return 0;
6036 }
6037 
6039 {
6040  MOVFragment *frag = &c->fragment;
6041  AVStream *st = NULL;
6042  MOVStreamContext *sc;
6043  int version, i;
6044  MOVFragmentStreamInfo * frag_stream_info;
6045  int64_t base_media_decode_time;
6046 
6047  for (i = 0; i < c->fc->nb_streams; i++) {
6048  sc = c->fc->streams[i]->priv_data;
6049  if (sc->id == frag->track_id) {
6050  st = c->fc->streams[i];
6051  break;
6052  }
6053  }
6054  if (!st) {
6055  av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %u\n", frag->track_id);
6056  return 0;
6057  }
6058  sc = st->priv_data;
6059  if (sc->pseudo_stream_id + 1 != frag->stsd_id && sc->pseudo_stream_id != -1)
6060  return 0;
6061  version = avio_r8(pb);
6062  avio_rb24(pb); /* flags */
6063  if (version) {
6064  base_media_decode_time = avio_rb64(pb);
6065  } else {
6066  base_media_decode_time = avio_rb32(pb);
6067  }
6068 
6069  frag_stream_info = get_current_frag_stream_info(&c->frag_index);
6070  if (frag_stream_info)
6071  frag_stream_info->tfdt_dts = base_media_decode_time;
6072  sc->track_end = base_media_decode_time;
6073 
6074  return 0;
6075 }
6076 
6078 {
6079  MOVFragment *frag = &c->fragment;
6080  AVStream *st = NULL;
6081  FFStream *sti = NULL;
6082  MOVStreamContext *sc;
6083  MOVTimeToSample *tts_data;
6084  uint64_t offset;
6085  int64_t dts, pts = AV_NOPTS_VALUE;
6086  int data_offset = 0;
6087  unsigned entries, first_sample_flags = frag->flags;
6088  int flags, distance, i;
6089  int64_t prev_dts = AV_NOPTS_VALUE;
6090  int next_frag_index = -1, index_entry_pos;
6091  size_t requested_size;
6092  size_t old_allocated_size;
6093  AVIndexEntry *new_entries;
6094  MOVFragmentStreamInfo * frag_stream_info;
6095 
6096  if (!frag->found_tfhd) {
6097  av_log(c->fc, AV_LOG_ERROR, "trun track id unknown, no tfhd was found\n");
6098  return AVERROR_INVALIDDATA;
6099  }
6100 
6101  for (i = 0; i < c->fc->nb_streams; i++) {
6102  sc = c->fc->streams[i]->priv_data;
6103  if (sc->id == frag->track_id) {
6104  st = c->fc->streams[i];
6105  sti = ffstream(st);
6106  break;
6107  }
6108  }
6109  if (!st) {
6110  av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %u\n", frag->track_id);
6111  return 0;
6112  }
6113  sc = st->priv_data;
6114  if (sc->pseudo_stream_id+1 != frag->stsd_id && sc->pseudo_stream_id != -1)
6115  return 0;
6116 
6117  // Find the next frag_index index that has a valid index_entry for
6118  // the current track_id.
6119  //
6120  // A valid index_entry means the trun for the fragment was read
6121  // and it's samples are in index_entries at the given position.
6122  // New index entries will be inserted before the index_entry found.
6123  index_entry_pos = sti->nb_index_entries;
6124  for (i = c->frag_index.current + 1; i < c->frag_index.nb_items; i++) {
6125  frag_stream_info = get_frag_stream_info(&c->frag_index, i, frag->track_id);
6126  if (frag_stream_info && frag_stream_info->index_entry >= 0) {
6127  next_frag_index = i;
6128  index_entry_pos = frag_stream_info->index_entry;
6129  break;
6130  }
6131  }
6132  av_assert0(index_entry_pos <= sti->nb_index_entries);
6133 
6134  avio_r8(pb); /* version */
6135  flags = avio_rb24(pb);
6136  entries = avio_rb32(pb);
6137  av_log(c->fc, AV_LOG_TRACE, "flags 0x%x entries %u\n", flags, entries);
6138 
6139  if ((uint64_t)entries+sc->tts_count >= UINT_MAX/sizeof(*sc->tts_data))
6140  return AVERROR_INVALIDDATA;
6141  if (flags & MOV_TRUN_DATA_OFFSET) data_offset = avio_rb32(pb);
6142  if (flags & MOV_TRUN_FIRST_SAMPLE_FLAGS) first_sample_flags = avio_rb32(pb);
6143 
6144  frag_stream_info = get_current_frag_stream_info(&c->frag_index);
6145  if (frag_stream_info) {
6146  if (frag_stream_info->next_trun_dts != AV_NOPTS_VALUE) {
6147  dts = frag_stream_info->next_trun_dts - sc->time_offset;
6148  } else if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE &&
6149  c->use_mfra_for == FF_MOV_FLAG_MFRA_PTS) {
6150  pts = frag_stream_info->first_tfra_pts;
6151  av_log(c->fc, AV_LOG_DEBUG, "found mfra time %"PRId64
6152  ", using it for pts\n", pts);
6153  } else if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE &&
6154  c->use_mfra_for == FF_MOV_FLAG_MFRA_DTS) {
6155  dts = frag_stream_info->first_tfra_pts;
6156  av_log(c->fc, AV_LOG_DEBUG, "found mfra time %"PRId64
6157  ", using it for dts\n", pts);
6158  } else {
6159  int has_tfdt = frag_stream_info->tfdt_dts != AV_NOPTS_VALUE;
6160  int has_sidx = frag_stream_info->sidx_pts != AV_NOPTS_VALUE;
6161  int fallback_tfdt = !c->use_tfdt && !has_sidx && has_tfdt;
6162  int fallback_sidx = c->use_tfdt && !has_tfdt && has_sidx;
6163 
6164  if (fallback_sidx) {
6165  av_log(c->fc, AV_LOG_DEBUG, "use_tfdt set but no tfdt found, using sidx instead\n");
6166  }
6167  if (fallback_tfdt) {
6168  av_log(c->fc, AV_LOG_DEBUG, "use_tfdt not set but no sidx found, using tfdt instead\n");
6169  }
6170 
6171  if (has_tfdt && c->use_tfdt || fallback_tfdt) {
6172  dts = frag_stream_info->tfdt_dts - sc->time_offset;
6173  av_log(c->fc, AV_LOG_DEBUG, "found tfdt time %"PRId64
6174  ", using it for dts\n", dts);
6175  } else if (has_sidx && !c->use_tfdt || fallback_sidx) {
6176  // FIXME: sidx earliest_presentation_time is *PTS*, s.b.
6177  // pts = frag_stream_info->sidx_pts;
6178  dts = frag_stream_info->sidx_pts;
6179  av_log(c->fc, AV_LOG_DEBUG, "found sidx time %"PRId64
6180  ", using it for dts\n", frag_stream_info->sidx_pts);
6181  } else {
6182  dts = sc->track_end - sc->time_offset;
6183  av_log(c->fc, AV_LOG_DEBUG, "found track end time %"PRId64
6184  ", using it for dts\n", dts);
6185  }
6186  }
6187  } else {
6188  dts = sc->track_end - sc->time_offset;
6189  av_log(c->fc, AV_LOG_DEBUG, "found track end time %"PRId64
6190  ", using it for dts\n", dts);
6191  }
6192  offset = frag->base_data_offset + data_offset;
6193  distance = 0;
6194  av_log(c->fc, AV_LOG_TRACE, "first sample flags 0x%x\n", first_sample_flags);
6195 
6196  // realloc space for new index entries
6197  if ((uint64_t)sti->nb_index_entries + entries >= UINT_MAX / sizeof(AVIndexEntry)) {
6198  entries = UINT_MAX / sizeof(AVIndexEntry) - sti->nb_index_entries;
6199  av_log(c->fc, AV_LOG_ERROR, "Failed to add index entry\n");
6200  }
6201  if (entries == 0)
6202  return 0;
6203 
6204  requested_size = (sti->nb_index_entries + entries) * sizeof(AVIndexEntry);
6205  new_entries = av_fast_realloc(sti->index_entries,
6207  requested_size);
6208  if (!new_entries)
6209  return AVERROR(ENOMEM);
6210  sti->index_entries= new_entries;
6211 
6212  requested_size = (sti->nb_index_entries + entries) * sizeof(*sc->tts_data);
6213  old_allocated_size = sc->tts_allocated_size;
6214  tts_data = av_fast_realloc(sc->tts_data, &sc->tts_allocated_size,
6215  requested_size);
6216  if (!tts_data)
6217  return AVERROR(ENOMEM);
6218  sc->tts_data = tts_data;
6219 
6220  // In case there were samples without time to sample entries, ensure they get
6221  // zero valued entries. This ensures clips which mix boxes with and
6222  // without time to sample entries don't pickup uninitialized data.
6223  memset((uint8_t*)(sc->tts_data) + old_allocated_size, 0,
6224  sc->tts_allocated_size - old_allocated_size);
6225 
6226  if (index_entry_pos < sti->nb_index_entries) {
6227  // Make hole in index_entries and tts_data for new samples
6228  memmove(sti->index_entries + index_entry_pos + entries,
6229  sti->index_entries + index_entry_pos,
6230  sizeof(*sti->index_entries) *
6231  (sti->nb_index_entries - index_entry_pos));
6232  memmove(sc->tts_data + index_entry_pos + entries,
6233  sc->tts_data + index_entry_pos,
6234  sizeof(*sc->tts_data) * (sc->tts_count - index_entry_pos));
6235  if (index_entry_pos < sc->current_sample) {
6236  sc->current_sample += entries;
6237  }
6238  }
6239 
6240  sti->nb_index_entries += entries;
6241  sc->tts_count = sti->nb_index_entries;
6242  sc->stts_count = sti->nb_index_entries;
6243  if (flags & MOV_TRUN_SAMPLE_CTS)
6244  sc->ctts_count = sti->nb_index_entries;
6245 
6246  // Record the index_entry position in frag_index of this fragment
6247  if (frag_stream_info) {
6248  frag_stream_info->index_entry = index_entry_pos;
6249  if (frag_stream_info->index_base < 0)
6250  frag_stream_info->index_base = index_entry_pos;
6251  }
6252 
6253  if (index_entry_pos > 0)
6254  prev_dts = sti->index_entries[index_entry_pos-1].timestamp;
6255 
6256  for (i = 0; i < entries && !pb->eof_reached; i++) {
6257  unsigned sample_size = frag->size;
6258  int sample_flags = i ? frag->flags : first_sample_flags;
6259  unsigned sample_duration = frag->duration;
6260  unsigned ctts_duration = 0;
6261  int keyframe = 0;
6262  int index_entry_flags = 0;
6263 
6264  if (flags & MOV_TRUN_SAMPLE_DURATION) sample_duration = avio_rb32(pb);
6265  if (flags & MOV_TRUN_SAMPLE_SIZE) sample_size = avio_rb32(pb);
6266  if (flags & MOV_TRUN_SAMPLE_FLAGS) sample_flags = avio_rb32(pb);
6267  if (flags & MOV_TRUN_SAMPLE_CTS) ctts_duration = avio_rb32(pb);
6268 
6269  mov_update_dts_shift(sc, ctts_duration, c->fc);
6270  if (pts != AV_NOPTS_VALUE) {
6271  dts = pts - sc->dts_shift;
6272  if (flags & MOV_TRUN_SAMPLE_CTS) {
6273  dts -= ctts_duration;
6274  } else {
6275  dts -= sc->time_offset;
6276  }
6277  av_log(c->fc, AV_LOG_DEBUG,
6278  "pts %"PRId64" calculated dts %"PRId64
6279  " sc->dts_shift %d ctts.duration %d"
6280  " sc->time_offset %"PRId64
6281  " flags & MOV_TRUN_SAMPLE_CTS %d\n",
6282  pts, dts,
6283  sc->dts_shift, ctts_duration,
6285  pts = AV_NOPTS_VALUE;
6286  }
6287 
6288  keyframe =
6289  !(sample_flags & (MOV_FRAG_SAMPLE_FLAG_IS_NON_SYNC |
6291  if (keyframe) {
6292  distance = 0;
6293  index_entry_flags |= AVINDEX_KEYFRAME;
6294  }
6295  // Fragments can overlap in time. Discard overlapping frames after
6296  // decoding.
6297  if (prev_dts >= dts)
6298  index_entry_flags |= AVINDEX_DISCARD_FRAME;
6299 
6300  sti->index_entries[index_entry_pos].pos = offset;
6301  sti->index_entries[index_entry_pos].timestamp = dts;
6302  sti->index_entries[index_entry_pos].size = sample_size;
6303  sti->index_entries[index_entry_pos].min_distance = distance;
6304  sti->index_entries[index_entry_pos].flags = index_entry_flags;
6305 
6306  sc->tts_data[index_entry_pos].count = 1;
6307  sc->tts_data[index_entry_pos].offset = ctts_duration;
6308  sc->tts_data[index_entry_pos].duration = sample_duration;
6309  index_entry_pos++;
6310 
6311  av_log(c->fc, AV_LOG_TRACE, "AVIndex stream %d, sample %d, offset %"PRIx64", dts %"PRId64", "
6312  "size %u, distance %d, keyframe %d\n", st->index,
6313  index_entry_pos, offset, dts, sample_size, distance, keyframe);
6314  distance++;
6315  if (av_sat_add64(dts, sample_duration) != dts + (uint64_t)sample_duration)
6316  return AVERROR_INVALIDDATA;
6317  if (!sample_size)
6318  return AVERROR_INVALIDDATA;
6319  dts += sample_duration;
6320  offset += sample_size;
6321  sc->data_size += sample_size;
6322 
6323  if (sample_duration <= INT64_MAX - sc->duration_for_fps &&
6324  1 <= INT_MAX - sc->nb_frames_for_fps
6325  ) {
6326  sc->duration_for_fps += sample_duration;
6327  sc->nb_frames_for_fps ++;
6328  }
6329  }
6330  if (frag_stream_info)
6331  frag_stream_info->next_trun_dts = dts + sc->time_offset;
6332  if (i < entries) {
6333  // EOF found before reading all entries. Fix the hole this would
6334  // leave in index_entries and tts_data
6335  int gap = entries - i;
6336  memmove(sti->index_entries + index_entry_pos,
6337  sti->index_entries + index_entry_pos + gap,
6338  sizeof(*sti->index_entries) *
6339  (sti->nb_index_entries - (index_entry_pos + gap)));
6340  memmove(sc->tts_data + index_entry_pos,
6341  sc->tts_data + index_entry_pos + gap,
6342  sizeof(*sc->tts_data) *
6343  (sc->tts_count - (index_entry_pos + gap)));
6344 
6345  sti->nb_index_entries -= gap;
6346  sc->tts_count -= gap;
6347  if (index_entry_pos < sc->current_sample) {
6348  sc->current_sample -= gap;
6349  }
6350  entries = i;
6351  }
6352 
6353  // The end of this new fragment may overlap in time with the start
6354  // of the next fragment in index_entries. Mark the samples in the next
6355  // fragment that overlap with AVINDEX_DISCARD_FRAME
6356  prev_dts = AV_NOPTS_VALUE;
6357  if (index_entry_pos > 0)
6358  prev_dts = sti->index_entries[index_entry_pos-1].timestamp;
6359  for (int i = index_entry_pos; i < sti->nb_index_entries; i++) {
6360  if (prev_dts < sti->index_entries[i].timestamp)
6361  break;
6363  }
6364 
6365  // If a hole was created to insert the new index_entries into,
6366  // the index_entry recorded for all subsequent moof must
6367  // be incremented by the number of entries inserted.
6368  fix_frag_index_entries(&c->frag_index, next_frag_index,
6369  frag->track_id, entries);
6370 
6371  if (pb->eof_reached) {
6372  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted TRUN atom\n");
6373  return AVERROR_EOF;
6374  }
6375 
6376  frag->implicit_offset = offset;
6377 
6378  sc->track_end = dts + sc->time_offset;
6379  if (st->duration < sc->track_end)
6380  st->duration = sc->track_end;
6381 
6382  return 0;
6383 }
6384 
6386 {
6387  int64_t stream_size = avio_size(pb);
6388  int64_t offset = av_sat_add64(avio_tell(pb), atom.size), pts, timestamp;
6389  uint8_t version, is_complete;
6390  int64_t offadd;
6391  unsigned i, j, track_id, item_count;
6392  AVStream *st = NULL;
6393  AVStream *ref_st = NULL;
6394  MOVStreamContext *sc, *ref_sc = NULL;
6395  AVRational timescale;
6396 
6397  version = avio_r8(pb);
6398  if (version > 1) {
6399  avpriv_request_sample(c->fc, "sidx version %u", version);
6400  return 0;
6401  }
6402 
6403  avio_rb24(pb); // flags
6404 
6405  track_id = avio_rb32(pb); // Reference ID
6406  for (i = 0; i < c->fc->nb_streams; i++) {
6407  sc = c->fc->streams[i]->priv_data;
6408  if (sc->id == track_id) {
6409  st = c->fc->streams[i];
6410  break;
6411  }
6412  }
6413  if (!st) {
6414  av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %d\n", track_id);
6415  return 0;
6416  }
6417 
6418  sc = st->priv_data;
6419 
6420  timescale = av_make_q(1, avio_rb32(pb));
6421 
6422  if (timescale.den <= 0) {
6423  av_log(c->fc, AV_LOG_ERROR, "Invalid sidx timescale 1/%d\n", timescale.den);
6424  return AVERROR_INVALIDDATA;
6425  }
6426 
6427  if (version == 0) {
6428  pts = avio_rb32(pb);
6429  offadd= avio_rb32(pb);
6430  } else {
6431  pts = avio_rb64(pb);
6432  offadd= avio_rb64(pb);
6433  }
6434  if (av_sat_add64(offset, offadd) != offset + (uint64_t)offadd)
6435  return AVERROR_INVALIDDATA;
6436 
6437  offset += (uint64_t)offadd;
6438 
6439  avio_rb16(pb); // reserved
6440 
6441  item_count = avio_rb16(pb);
6442  if (item_count == 0)
6443  return AVERROR_INVALIDDATA;
6444 
6445  for (i = 0; i < item_count; i++) {
6446  int index;
6447  MOVFragmentStreamInfo * frag_stream_info;
6448  uint32_t size = avio_rb32(pb);
6449  uint32_t duration = avio_rb32(pb);
6450  if (size & 0x80000000) {
6451  avpriv_request_sample(c->fc, "sidx reference_type 1");
6452  return AVERROR_PATCHWELCOME;
6453  }
6454  avio_rb32(pb); // sap_flags
6455  timestamp = av_rescale_q(pts, timescale, st->time_base);
6456 
6458  frag_stream_info = get_frag_stream_info(&c->frag_index, index, track_id);
6459  if (frag_stream_info)
6460  frag_stream_info->sidx_pts = timestamp;
6461 
6462  if (av_sat_add64(offset, size) != offset + (uint64_t)size ||
6463  av_sat_add64(pts, duration) != pts + (uint64_t)duration
6464  )
6465  return AVERROR_INVALIDDATA;
6466  offset += size;
6467  pts += duration;
6468  }
6469 
6470  st->duration = sc->track_end = pts;
6471 
6472  sc->has_sidx = 1;
6473 
6474  // See if the remaining bytes are just an mfra which we can ignore.
6475  is_complete = offset == stream_size;
6476  if (!is_complete && (pb->seekable & AVIO_SEEKABLE_NORMAL) && stream_size > 0 ) {
6477  int64_t ret;
6478  int64_t original_pos = avio_tell(pb);
6479  if (!c->have_read_mfra_size) {
6480  if ((ret = avio_seek(pb, stream_size - 4, SEEK_SET)) < 0)
6481  return ret;
6482  c->mfra_size = avio_rb32(pb);
6483  c->have_read_mfra_size = 1;
6484  if ((ret = avio_seek(pb, original_pos, SEEK_SET)) < 0)
6485  return ret;
6486  }
6487  if (offset == stream_size - c->mfra_size)
6488  is_complete = 1;
6489  }
6490 
6491  if (is_complete) {
6492  // Find first entry in fragment index that came from an sidx.
6493  // This will pretty much always be the first entry.
6494  for (i = 0; i < c->frag_index.nb_items; i++) {
6495  MOVFragmentIndexItem * item = &c->frag_index.item[i];
6496  for (j = 0; ref_st == NULL && j < item->nb_stream_info; j++) {
6497  MOVFragmentStreamInfo * si;
6498  si = &item->stream_info[j];
6499  if (si->sidx_pts != AV_NOPTS_VALUE) {
6500  ref_st = c->fc->streams[j];
6501  ref_sc = ref_st->priv_data;
6502  break;
6503  }
6504  }
6505  }
6506  if (ref_st) for (i = 0; i < c->fc->nb_streams; i++) {
6507  st = c->fc->streams[i];
6508  sc = st->priv_data;
6509  if (!sc->has_sidx) {
6510  st->duration = sc->track_end = av_rescale(ref_st->duration, sc->time_scale, ref_sc->time_scale);
6511  }
6512  }
6513 
6514  if (offadd == 0)
6515  c->frag_index.complete = 1;
6516  }
6517 
6518  return 0;
6519 }
6520 
6521 /* this atom should be null (from specs), but some buggy files put the 'moov' atom inside it... */
6522 /* like the files created with Adobe Premiere 5.0, for samples see */
6523 /* http://graphics.tudelft.nl/~wouter/publications/soundtests/ */
6525 {
6526  int err;
6527 
6528  if (atom.size < 8)
6529  return 0; /* continue */
6530  if (avio_rb32(pb) != 0) { /* 0 sized mdat atom... use the 'wide' atom size */
6531  avio_skip(pb, atom.size - 4);
6532  return 0;
6533  }
6534  atom.type = avio_rl32(pb);
6535  atom.size -= 8;
6536  if (atom.type != MKTAG('m','d','a','t')) {
6537  avio_skip(pb, atom.size);
6538  return 0;
6539  }
6540  err = mov_read_mdat(c, pb, atom);
6541  return err;
6542 }
6543 
6545 {
6546 #if CONFIG_ZLIB
6547  FFIOContext ctx;
6548  uint8_t *cmov_data;
6549  uint8_t *moov_data; /* uncompressed data */
6550  long cmov_len, moov_len;
6551  int ret = -1;
6552 
6553  avio_rb32(pb); /* dcom atom */
6554  if (avio_rl32(pb) != MKTAG('d','c','o','m'))
6555  return AVERROR_INVALIDDATA;
6556  if (avio_rl32(pb) != MKTAG('z','l','i','b')) {
6557  av_log(c->fc, AV_LOG_ERROR, "unknown compression for cmov atom !\n");
6558  return AVERROR_INVALIDDATA;
6559  }
6560  avio_rb32(pb); /* cmvd atom */
6561  if (avio_rl32(pb) != MKTAG('c','m','v','d'))
6562  return AVERROR_INVALIDDATA;
6563  moov_len = avio_rb32(pb); /* uncompressed size */
6564  cmov_len = atom.size - 6 * 4;
6565 
6566  cmov_data = av_malloc(cmov_len);
6567  if (!cmov_data)
6568  return AVERROR(ENOMEM);
6569  moov_data = av_malloc(moov_len);
6570  if (!moov_data) {
6571  av_free(cmov_data);
6572  return AVERROR(ENOMEM);
6573  }
6574  ret = ffio_read_size(pb, cmov_data, cmov_len);
6575  if (ret < 0)
6576  goto free_and_return;
6577 
6579  if (uncompress (moov_data, (uLongf *) &moov_len, (const Bytef *)cmov_data, cmov_len) != Z_OK)
6580  goto free_and_return;
6581  ffio_init_read_context(&ctx, moov_data, moov_len);
6582  ctx.pub.seekable = AVIO_SEEKABLE_NORMAL;
6583  atom.type = MKTAG('m','o','o','v');
6584  atom.size = moov_len;
6585  ret = mov_read_default(c, &ctx.pub, atom);
6586 free_and_return:
6587  av_free(moov_data);
6588  av_free(cmov_data);
6589  return ret;
6590 #else
6591  av_log(c->fc, AV_LOG_ERROR, "this file requires zlib support compiled in\n");
6592  return AVERROR(ENOSYS);
6593 #endif
6594 }
6595 
6596 /* edit list atom */
6598 {
6599  MOVStreamContext *sc;
6600  int i, edit_count, version;
6601  int64_t elst_entry_size;
6602 
6603  if (c->fc->nb_streams < 1 || c->ignore_editlist)
6604  return 0;
6605  sc = c->fc->streams[c->fc->nb_streams-1]->priv_data;
6606 
6607  version = avio_r8(pb); /* version */
6608  avio_rb24(pb); /* flags */
6609  edit_count = avio_rb32(pb); /* entries */
6610  atom.size -= 8;
6611 
6612  elst_entry_size = version == 1 ? 20 : 12;
6613  if (atom.size != edit_count * elst_entry_size) {
6614  if (c->fc->strict_std_compliance >= FF_COMPLIANCE_STRICT) {
6615  av_log(c->fc, AV_LOG_ERROR, "Invalid edit list entry_count: %d for elst atom of size: %"PRId64" bytes.\n",
6616  edit_count, atom.size + 8);
6617  return AVERROR_INVALIDDATA;
6618  } else {
6619  edit_count = atom.size / elst_entry_size;
6620  if (edit_count * elst_entry_size != atom.size) {
6621  av_log(c->fc, AV_LOG_WARNING, "ELST atom of %"PRId64" bytes, bigger than %d entries.\n", atom.size, edit_count);
6622  }
6623  }
6624  }
6625 
6626  if (!edit_count)
6627  return 0;
6628  if (sc->elst_data)
6629  av_log(c->fc, AV_LOG_WARNING, "Duplicated ELST atom\n");
6630  av_free(sc->elst_data);
6631  sc->elst_count = 0;
6632  sc->elst_data = av_malloc_array(edit_count, sizeof(*sc->elst_data));
6633  if (!sc->elst_data)
6634  return AVERROR(ENOMEM);
6635 
6636  av_log(c->fc, AV_LOG_TRACE, "track[%u].edit_count = %i\n", c->fc->nb_streams - 1, edit_count);
6637  for (i = 0; i < edit_count && atom.size > 0 && !pb->eof_reached; i++) {
6638  MOVElst *e = &sc->elst_data[i];
6639 
6640  if (version == 1) {
6641  e->duration = avio_rb64(pb);
6642  e->time = avio_rb64(pb);
6643  atom.size -= 16;
6644  } else {
6645  e->duration = avio_rb32(pb); /* segment duration */
6646  e->time = (int32_t)avio_rb32(pb); /* media time */
6647  atom.size -= 8;
6648  }
6649  e->rate = avio_rb32(pb) / 65536.0;
6650  atom.size -= 4;
6651  av_log(c->fc, AV_LOG_TRACE, "duration=%"PRId64" time=%"PRId64" rate=%f\n",
6652  e->duration, e->time, e->rate);
6653 
6654  if (e->time < 0 && e->time != -1 &&
6655  c->fc->strict_std_compliance >= FF_COMPLIANCE_STRICT) {
6656  av_log(c->fc, AV_LOG_ERROR, "Track %d, edit %d: Invalid edit list media time=%"PRId64"\n",
6657  c->fc->nb_streams-1, i, e->time);
6658  return AVERROR_INVALIDDATA;
6659  }
6660  if (e->duration < 0) {
6661  av_log(c->fc, AV_LOG_ERROR, "Track %d, edit %d: Invalid edit list duration=%"PRId64"\n",
6662  c->fc->nb_streams-1, i, e->duration);
6663  return AVERROR_INVALIDDATA;
6664  }
6665  }
6666  sc->elst_count = i;
6667 
6668  return 0;
6669 }
6670 
6672 {
6673  MOVStreamContext *sc;
6674  int err;
6675 
6676  if (c->fc->nb_streams < 1)
6677  return AVERROR_INVALIDDATA;
6678  sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
6679 
6680  if (atom.size % sizeof(uint32_t))
6681  return AVERROR_INVALIDDATA;
6682 
6683  MovTref *tag = mov_add_tref_tag(sc, atom.type);
6684  if (!tag)
6685  return AVERROR(ENOMEM);
6686 
6687  int nb_timecode_track = atom.size >> 2;
6688  for (int i = 0; i < nb_timecode_track; i++) {
6689  if (avio_feof(pb))
6690  return AVERROR_INVALIDDATA;
6691  err = mov_add_tref_id(tag, avio_rb32(pb));
6692  if (err < 0)
6693  return err;
6694  }
6695 
6696  return 0;
6697 }
6698 
6700 {
6701  AVStream *st;
6702  int version, color_range, color_primaries, color_trc, color_space;
6703 
6704  if (c->fc->nb_streams < 1)
6705  return 0;
6706  st = c->fc->streams[c->fc->nb_streams - 1];
6707 
6708  if (atom.size < 5) {
6709  av_log(c->fc, AV_LOG_ERROR, "Empty VP Codec Configuration box\n");
6710  return AVERROR_INVALIDDATA;
6711  }
6712 
6713  version = avio_r8(pb);
6714  if (version != 1) {
6715  av_log(c->fc, AV_LOG_WARNING, "Unsupported VP Codec Configuration box version %d\n", version);
6716  return 0;
6717  }
6718  avio_skip(pb, 3); /* flags */
6719 
6720  avio_skip(pb, 2); /* profile + level */
6721  color_range = avio_r8(pb); /* bitDepth, chromaSubsampling, videoFullRangeFlag */
6722  color_primaries = avio_r8(pb);
6723  color_trc = avio_r8(pb);
6724  color_space = avio_r8(pb);
6725  if (avio_rb16(pb)) /* codecIntializationDataSize */
6726  return AVERROR_INVALIDDATA;
6727 
6730  if (!av_color_transfer_name(color_trc))
6731  color_trc = AVCOL_TRC_UNSPECIFIED;
6732  if (!av_color_space_name(color_space))
6733  color_space = AVCOL_SPC_UNSPECIFIED;
6734 
6737  st->codecpar->color_trc = color_trc;
6738  st->codecpar->color_space = color_space;
6739 
6740  return 0;
6741 }
6742 
6744 {
6745  MOVStreamContext *sc;
6746  int i, version;
6747 
6748  if (c->fc->nb_streams < 1)
6749  return AVERROR_INVALIDDATA;
6750 
6751  sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
6752 
6753  if (atom.size < 5) {
6754  av_log(c->fc, AV_LOG_ERROR, "Empty Mastering Display Metadata box\n");
6755  return AVERROR_INVALIDDATA;
6756  }
6757 
6758  version = avio_r8(pb);
6759  if (version) {
6760  av_log(c->fc, AV_LOG_WARNING, "Unsupported Mastering Display Metadata box version %d\n", version);
6761  return 0;
6762  }
6763  if (sc->mastering) {
6764  av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicate Mastering Display Metadata\n");
6765  return 0;
6766  }
6767 
6768  avio_skip(pb, 3); /* flags */
6769 
6771  if (!sc->mastering)
6772  return AVERROR(ENOMEM);
6773 
6774  for (i = 0; i < 3; i++) {
6775  sc->mastering->display_primaries[i][0] = av_make_q(avio_rb16(pb), 1 << 16);
6776  sc->mastering->display_primaries[i][1] = av_make_q(avio_rb16(pb), 1 << 16);
6777  }
6778  sc->mastering->white_point[0] = av_make_q(avio_rb16(pb), 1 << 16);
6779  sc->mastering->white_point[1] = av_make_q(avio_rb16(pb), 1 << 16);
6780 
6781  sc->mastering->max_luminance = av_make_q(avio_rb32(pb), 1 << 8);
6782  sc->mastering->min_luminance = av_make_q(avio_rb32(pb), 1 << 14);
6783 
6784  sc->mastering->has_primaries = 1;
6785  sc->mastering->has_luminance = 1;
6786 
6787  return 0;
6788 }
6789 
6791 {
6792  MOVStreamContext *sc;
6793  const int mapping[3] = {1, 2, 0};
6794  const int chroma_den = 50000;
6795  const int luma_den = 10000;
6796  int i;
6797 
6798  if (c->fc->nb_streams < 1)
6799  return AVERROR_INVALIDDATA;
6800 
6801  sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
6802 
6803  if (atom.size < 24) {
6804  av_log(c->fc, AV_LOG_ERROR, "Invalid Mastering Display Color Volume box\n");
6805  return AVERROR_INVALIDDATA;
6806  }
6807 
6808  if (sc->mastering) {
6809  av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicate Mastering Display Color Volume\n");
6810  return 0;
6811  }
6812 
6814  if (!sc->mastering)
6815  return AVERROR(ENOMEM);
6816 
6817  for (i = 0; i < 3; i++) {
6818  const int j = mapping[i];
6819  sc->mastering->display_primaries[j][0] = av_make_q(avio_rb16(pb), chroma_den);
6820  sc->mastering->display_primaries[j][1] = av_make_q(avio_rb16(pb), chroma_den);
6821  }
6822  sc->mastering->white_point[0] = av_make_q(avio_rb16(pb), chroma_den);
6823  sc->mastering->white_point[1] = av_make_q(avio_rb16(pb), chroma_den);
6824 
6825  sc->mastering->max_luminance = av_make_q(avio_rb32(pb), luma_den);
6826  sc->mastering->min_luminance = av_make_q(avio_rb32(pb), luma_den);
6827 
6828  sc->mastering->has_luminance = 1;
6829  sc->mastering->has_primaries = 1;
6830 
6831  return 0;
6832 }
6833 
6835 {
6836  MOVStreamContext *sc;
6837  int version;
6838 
6839  if (c->fc->nb_streams < 1)
6840  return AVERROR_INVALIDDATA;
6841 
6842  sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
6843 
6844  if (atom.size < 5) {
6845  av_log(c->fc, AV_LOG_ERROR, "Empty Content Light Level box\n");
6846  return AVERROR_INVALIDDATA;
6847  }
6848 
6849  version = avio_r8(pb);
6850  if (version) {
6851  av_log(c->fc, AV_LOG_WARNING, "Unsupported Content Light Level box version %d\n", version);
6852  return 0;
6853  }
6854  avio_skip(pb, 3); /* flags */
6855 
6856  if (sc->coll){
6857  av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicate COLL\n");
6858  return 0;
6859  }
6860 
6862  if (!sc->coll)
6863  return AVERROR(ENOMEM);
6864 
6865  sc->coll->MaxCLL = avio_rb16(pb);
6866  sc->coll->MaxFALL = avio_rb16(pb);
6867 
6868  return 0;
6869 }
6870 
6872 {
6873  MOVStreamContext *sc;
6874 
6875  if (c->fc->nb_streams < 1)
6876  return AVERROR_INVALIDDATA;
6877 
6878  sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
6879 
6880  if (atom.size < 4) {
6881  av_log(c->fc, AV_LOG_ERROR, "Empty Content Light Level Info box\n");
6882  return AVERROR_INVALIDDATA;
6883  }
6884 
6885  if (sc->coll){
6886  av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicate CLLI/COLL\n");
6887  return 0;
6888  }
6889 
6891  if (!sc->coll)
6892  return AVERROR(ENOMEM);
6893 
6894  sc->coll->MaxCLL = avio_rb16(pb);
6895  sc->coll->MaxFALL = avio_rb16(pb);
6896 
6897  return 0;
6898 }
6899 
6901 {
6902  MOVStreamContext *sc;
6903  const int illuminance_den = 10000;
6904  const int ambient_den = 50000;
6905  if (c->fc->nb_streams < 1)
6906  return AVERROR_INVALIDDATA;
6907  sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
6908  if (atom.size < 6) {
6909  av_log(c->fc, AV_LOG_ERROR, "Empty Ambient Viewing Environment Info box\n");
6910  return AVERROR_INVALIDDATA;
6911  }
6912  if (sc->ambient){
6913  av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicate AMVE\n");
6914  return 0;
6915  }
6917  if (!sc->ambient)
6918  return AVERROR(ENOMEM);
6919  sc->ambient->ambient_illuminance = av_make_q(avio_rb32(pb), illuminance_den);
6920  sc->ambient->ambient_light_x = av_make_q(avio_rb16(pb), ambient_den);
6921  sc->ambient->ambient_light_y = av_make_q(avio_rb16(pb), ambient_den);
6922  return 0;
6923 }
6924 
6926 {
6927  AVStream *st;
6928  MOVStreamContext *sc;
6929  enum AVStereo3DType type;
6930  int mode;
6931 
6932  if (c->fc->nb_streams < 1)
6933  return 0;
6934 
6935  st = c->fc->streams[c->fc->nb_streams - 1];
6936  sc = st->priv_data;
6937 
6938  if (atom.size < 5) {
6939  av_log(c->fc, AV_LOG_ERROR, "Empty stereoscopic video box\n");
6940  return AVERROR_INVALIDDATA;
6941  }
6942 
6943  if (sc->stereo3d)
6944  return AVERROR_INVALIDDATA;
6945 
6946  avio_skip(pb, 4); /* version + flags */
6947 
6948  mode = avio_r8(pb);
6949  switch (mode) {
6950  case 0:
6951  type = AV_STEREO3D_2D;
6952  break;
6953  case 1:
6955  break;
6956  case 2:
6958  break;
6959  default:
6960  av_log(c->fc, AV_LOG_WARNING, "Unknown st3d mode value %d\n", mode);
6961  return 0;
6962  }
6963 
6965  if (!sc->stereo3d)
6966  return AVERROR(ENOMEM);
6967 
6968  sc->stereo3d->type = type;
6969  return 0;
6970 }
6971 
6973 {
6974  AVStream *st;
6975  MOVStreamContext *sc;
6976  int size = 0;
6977  int64_t remaining;
6978  uint32_t tag = 0;
6980 
6981  if (c->fc->nb_streams < 1)
6982  return 0;
6983 
6984  st = c->fc->streams[c->fc->nb_streams - 1];
6985  sc = st->priv_data;
6986 
6987  remaining = atom.size;
6988  while (remaining > 0) {
6989  size = avio_rb32(pb);
6990  if (size < 8 || size > remaining ) {
6991  av_log(c->fc, AV_LOG_ERROR, "Invalid child size in pack box\n");
6992  return AVERROR_INVALIDDATA;
6993  }
6994 
6995  tag = avio_rl32(pb);
6996  switch (tag) {
6997  case MKTAG('p','k','i','n'): {
6998  if (size != 16) {
6999  av_log(c->fc, AV_LOG_ERROR, "Invalid size of pkin box: %d\n", size);
7000  return AVERROR_INVALIDDATA;
7001  }
7002  avio_skip(pb, 1); // version
7003  avio_skip(pb, 3); // flags
7004 
7005  tag = avio_rl32(pb);
7006  switch (tag) {
7007  case MKTAG('s','i','d','e'):
7009  break;
7010  case MKTAG('o','v','e','r'):
7012  break;
7013  case 0:
7014  // This means value will be set in another layer
7015  break;
7016  default:
7017  av_log(c->fc, AV_LOG_WARNING, "Unknown tag in pkin: %s\n",
7018  av_fourcc2str(tag));
7019  avio_skip(pb, size - 8);
7020  break;
7021  }
7022 
7023  break;
7024  }
7025  default:
7026  av_log(c->fc, AV_LOG_WARNING, "Unknown tag in pack: %s\n",
7027  av_fourcc2str(tag));
7028  avio_skip(pb, size - 8);
7029  break;
7030  }
7031  remaining -= size;
7032  }
7033 
7034  if (remaining != 0) {
7035  av_log(c->fc, AV_LOG_ERROR, "Broken pack box\n");
7036  return AVERROR_INVALIDDATA;
7037  }
7038 
7039  if (type == AV_STEREO3D_2D)
7040  return 0;
7041 
7042  if (!sc->stereo3d) {
7044  if (!sc->stereo3d)
7045  return AVERROR(ENOMEM);
7046  }
7047 
7048  sc->stereo3d->type = type;
7049 
7050  return 0;
7051 }
7052 
7054 {
7055  AVStream *st;
7056  MOVStreamContext *sc;
7057  int size, version, layout;
7058  int32_t yaw, pitch, roll;
7059  uint32_t l = 0, t = 0, r = 0, b = 0;
7060  uint32_t tag, padding = 0;
7061  enum AVSphericalProjection projection;
7062 
7063  if (c->fc->nb_streams < 1)
7064  return 0;
7065 
7066  st = c->fc->streams[c->fc->nb_streams - 1];
7067  sc = st->priv_data;
7068 
7069  if (atom.size < 8) {
7070  av_log(c->fc, AV_LOG_ERROR, "Empty spherical video box\n");
7071  return AVERROR_INVALIDDATA;
7072  }
7073 
7074  size = avio_rb32(pb);
7075  if (size <= 12 || size > atom.size)
7076  return AVERROR_INVALIDDATA;
7077 
7078  tag = avio_rl32(pb);
7079  if (tag != MKTAG('s','v','h','d')) {
7080  av_log(c->fc, AV_LOG_ERROR, "Missing spherical video header\n");
7081  return 0;
7082  }
7083  version = avio_r8(pb);
7084  if (version != 0) {
7085  av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
7086  version);
7087  return 0;
7088  }
7089  avio_skip(pb, 3); /* flags */
7090  avio_skip(pb, size - 12); /* metadata_source */
7091 
7092  size = avio_rb32(pb);
7093  if (size > atom.size)
7094  return AVERROR_INVALIDDATA;
7095 
7096  tag = avio_rl32(pb);
7097  if (tag != MKTAG('p','r','o','j')) {
7098  av_log(c->fc, AV_LOG_ERROR, "Missing projection box\n");
7099  return 0;
7100  }
7101 
7102  size = avio_rb32(pb);
7103  if (size > atom.size)
7104  return AVERROR_INVALIDDATA;
7105 
7106  tag = avio_rl32(pb);
7107  if (tag != MKTAG('p','r','h','d')) {
7108  av_log(c->fc, AV_LOG_ERROR, "Missing projection header box\n");
7109  return 0;
7110  }
7111  version = avio_r8(pb);
7112  if (version != 0) {
7113  av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
7114  version);
7115  return 0;
7116  }
7117  avio_skip(pb, 3); /* flags */
7118 
7119  /* 16.16 fixed point */
7120  yaw = avio_rb32(pb);
7121  pitch = avio_rb32(pb);
7122  roll = avio_rb32(pb);
7123 
7124  size = avio_rb32(pb);
7125  if (size > atom.size)
7126  return AVERROR_INVALIDDATA;
7127 
7128  tag = avio_rl32(pb);
7129  version = avio_r8(pb);
7130  if (version != 0) {
7131  av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
7132  version);
7133  return 0;
7134  }
7135  avio_skip(pb, 3); /* flags */
7136  switch (tag) {
7137  case MKTAG('c','b','m','p'):
7138  layout = avio_rb32(pb);
7139  if (layout) {
7140  av_log(c->fc, AV_LOG_WARNING,
7141  "Unsupported cubemap layout %d\n", layout);
7142  return 0;
7143  }
7144  projection = AV_SPHERICAL_CUBEMAP;
7145  padding = avio_rb32(pb);
7146  break;
7147  case MKTAG('e','q','u','i'):
7148  t = avio_rb32(pb);
7149  b = avio_rb32(pb);
7150  l = avio_rb32(pb);
7151  r = avio_rb32(pb);
7152 
7153  if (b >= UINT_MAX - t || r >= UINT_MAX - l) {
7154  av_log(c->fc, AV_LOG_ERROR,
7155  "Invalid bounding rectangle coordinates "
7156  "%"PRIu32",%"PRIu32",%"PRIu32",%"PRIu32"\n", l, t, r, b);
7157  return AVERROR_INVALIDDATA;
7158  }
7159 
7160  if (l || t || r || b)
7161  projection = AV_SPHERICAL_EQUIRECTANGULAR_TILE;
7162  else
7163  projection = AV_SPHERICAL_EQUIRECTANGULAR;
7164  break;
7165  default:
7166  av_log(c->fc, AV_LOG_ERROR, "Unknown projection type: %s\n", av_fourcc2str(tag));
7167  return 0;
7168  }
7169 
7171  if (!sc->spherical)
7172  return AVERROR(ENOMEM);
7173 
7174  sc->spherical->projection = projection;
7175 
7176  sc->spherical->yaw = yaw;
7177  sc->spherical->pitch = pitch;
7178  sc->spherical->roll = roll;
7179 
7180  sc->spherical->padding = padding;
7181 
7182  sc->spherical->bound_left = l;
7183  sc->spherical->bound_top = t;
7184  sc->spherical->bound_right = r;
7185  sc->spherical->bound_bottom = b;
7186 
7187  return 0;
7188 }
7189 
7191 {
7192  AVStream *st;
7193  MOVStreamContext *sc;
7194  int size;
7195  uint32_t tag;
7196  enum AVSphericalProjection projection;
7197 
7198  if (c->fc->nb_streams < 1)
7199  return 0;
7200 
7201  st = c->fc->streams[c->fc->nb_streams - 1];
7202  sc = st->priv_data;
7203 
7204  if (atom.size < 16) {
7205  av_log(c->fc, AV_LOG_ERROR, "Invalid size for proj box: %"PRIu64"\n", atom.size);
7206  return AVERROR_INVALIDDATA;
7207  }
7208 
7209  size = avio_rb32(pb);
7210  if (size < 16) {
7211  av_log(c->fc, AV_LOG_ERROR, "Invalid size for prji box: %d\n", size);
7212  return AVERROR_INVALIDDATA;
7213  } else if (size > 16) {
7214  av_log(c->fc, AV_LOG_WARNING, "Box has more bytes (%d) than prji box required (16) \n", size);
7215  }
7216 
7217  tag = avio_rl32(pb);
7218  if (tag != MKTAG('p','r','j','i')) {
7219  av_log(c->fc, AV_LOG_ERROR, "Invalid child box of proj box: %s\n",
7220  av_fourcc2str(tag));
7221  return AVERROR_INVALIDDATA;
7222  }
7223 
7224  // version and flags, only support (0, 0)
7225  unsigned n = avio_rl32(pb);
7226  if (n != 0) {
7227  av_log(c->fc, AV_LOG_ERROR, "prji version %u, flag %u are not supported\n",
7228  n & 0xFF, n >> 8);
7229  return AVERROR_PATCHWELCOME;
7230  }
7231 
7232  tag = avio_rl32(pb);
7233  switch (tag) {
7234  case MKTAG('r','e','c','t'):
7235  projection = AV_SPHERICAL_RECTILINEAR;
7236  break;
7237  case MKTAG('e','q','u','i'):
7238  projection = AV_SPHERICAL_EQUIRECTANGULAR;
7239  break;
7240  case MKTAG('h','e','q','u'):
7241  projection = AV_SPHERICAL_HALF_EQUIRECTANGULAR;
7242  break;
7243  case MKTAG('f','i','s','h'):
7244  projection = AV_SPHERICAL_FISHEYE;
7245  break;
7246  case MKTAG('p','r','i','m'):
7247  projection = AV_SPHERICAL_PARAMETRIC_IMMERSIVE;
7248  break;
7249  default:
7250  av_log(c->fc, AV_LOG_ERROR, "Invalid projection type in prji box: %s\n", av_fourcc2str(tag));
7251  return AVERROR_INVALIDDATA;
7252  }
7253 
7255  if (!sc->spherical)
7256  return AVERROR(ENOMEM);
7257 
7258  sc->spherical->projection = projection;
7259 
7260  return 0;
7261 }
7262 
7264 {
7265  AVStream *st;
7266  MOVStreamContext *sc;
7267  int size, flags = 0;
7268  int64_t remaining;
7269  uint32_t tag, baseline = 0;
7272  enum AVStereo3DPrimaryEye primary_eye = AV_PRIMARY_EYE_NONE;
7273  AVRational horizontal_disparity_adjustment = { 0, 1 };
7274 
7275  if (c->fc->nb_streams < 1)
7276  return 0;
7277 
7278  st = c->fc->streams[c->fc->nb_streams - 1];
7279  sc = st->priv_data;
7280 
7281  remaining = atom.size;
7282  while (remaining > 0) {
7283  size = avio_rb32(pb);
7284  if (size < 8 || size > remaining ) {
7285  av_log(c->fc, AV_LOG_ERROR, "Invalid child size in eyes box\n");
7286  return AVERROR_INVALIDDATA;
7287  }
7288 
7289  tag = avio_rl32(pb);
7290  switch (tag) {
7291  case MKTAG('s','t','r','i'): {
7292  int has_right, has_left;
7293  uint8_t tmp;
7294  if (size != 13) {
7295  av_log(c->fc, AV_LOG_ERROR, "Invalid size of stri box: %d\n", size);
7296  return AVERROR_INVALIDDATA;
7297  }
7298  avio_skip(pb, 1); // version
7299  avio_skip(pb, 3); // flags
7300 
7301  tmp = avio_r8(pb);
7302 
7303  // eye_views_reversed
7304  if (tmp & 8) {
7306  }
7307  // has_additional_views
7308  if (tmp & 4) {
7309  // skip...
7310  }
7311 
7312  has_right = tmp & 2; // has_right_eye_view
7313  has_left = tmp & 1; // has_left_eye_view
7314 
7315  if (has_left && has_right)
7316  view = AV_STEREO3D_VIEW_PACKED;
7317  else if (has_left)
7318  view = AV_STEREO3D_VIEW_LEFT;
7319  else if (has_right)
7320  view = AV_STEREO3D_VIEW_RIGHT;
7321  if (has_left || has_right)
7323 
7324  break;
7325  }
7326  case MKTAG('h','e','r','o'): {
7327  int tmp;
7328  if (size != 13) {
7329  av_log(c->fc, AV_LOG_ERROR, "Invalid size of hero box: %d\n", size);
7330  return AVERROR_INVALIDDATA;
7331  }
7332  avio_skip(pb, 1); // version
7333  avio_skip(pb, 3); // flags
7334 
7335  tmp = avio_r8(pb);
7336  if (tmp == 0)
7337  primary_eye = AV_PRIMARY_EYE_NONE;
7338  else if (tmp == 1)
7339  primary_eye = AV_PRIMARY_EYE_LEFT;
7340  else if (tmp == 2)
7341  primary_eye = AV_PRIMARY_EYE_RIGHT;
7342  else
7343  av_log(c->fc, AV_LOG_WARNING, "Unknown hero eye type: %d\n", tmp);
7344 
7345  break;
7346  }
7347  case MKTAG('c','a','m','s'): {
7348  uint32_t subtag;
7349  int subsize;
7350  if (size != 24) {
7351  av_log(c->fc, AV_LOG_ERROR, "Invalid size of cams box: %d\n", size);
7352  return AVERROR_INVALIDDATA;
7353  }
7354 
7355  subsize = avio_rb32(pb);
7356  if (subsize != 16) {
7357  av_log(c->fc, AV_LOG_ERROR, "Invalid size of blin box: %d\n", size);
7358  return AVERROR_INVALIDDATA;
7359  }
7360 
7361  subtag = avio_rl32(pb);
7362  if (subtag != MKTAG('b','l','i','n')) {
7363  av_log(c->fc, AV_LOG_ERROR, "Expected blin box, got %s\n",
7364  av_fourcc2str(subtag));
7365  return AVERROR_INVALIDDATA;
7366  }
7367 
7368  avio_skip(pb, 1); // version
7369  avio_skip(pb, 3); // flags
7370 
7371  baseline = avio_rb32(pb);
7372 
7373  break;
7374  }
7375  case MKTAG('c','m','f','y'): {
7376  uint32_t subtag;
7377  int subsize;
7378  int32_t adjustment;
7379  if (size != 24) {
7380  av_log(c->fc, AV_LOG_ERROR, "Invalid size of cmfy box: %d\n", size);
7381  return AVERROR_INVALIDDATA;
7382  }
7383 
7384  subsize = avio_rb32(pb);
7385  if (subsize != 16) {
7386  av_log(c->fc, AV_LOG_ERROR, "Invalid size of dadj box: %d\n", size);
7387  return AVERROR_INVALIDDATA;
7388  }
7389 
7390  subtag = avio_rl32(pb);
7391  if (subtag != MKTAG('d','a','d','j')) {
7392  av_log(c->fc, AV_LOG_ERROR, "Expected dadj box, got %s\n",
7393  av_fourcc2str(subtag));
7394  return AVERROR_INVALIDDATA;
7395  }
7396 
7397  avio_skip(pb, 1); // version
7398  avio_skip(pb, 3); // flags
7399 
7400  adjustment = (int32_t) avio_rb32(pb);
7401 
7402  horizontal_disparity_adjustment.num = (int) adjustment;
7403  horizontal_disparity_adjustment.den = 10000;
7404 
7405  break;
7406  }
7407  default:
7408  av_log(c->fc, AV_LOG_WARNING, "Unknown tag in eyes: %s\n",
7409  av_fourcc2str(tag));
7410  avio_skip(pb, size - 8);
7411  break;
7412  }
7413  remaining -= size;
7414  }
7415 
7416  if (remaining != 0) {
7417  av_log(c->fc, AV_LOG_ERROR, "Broken eyes box\n");
7418  return AVERROR_INVALIDDATA;
7419  }
7420 
7421  if (type == AV_STEREO3D_2D)
7422  return 0;
7423 
7424  if (!sc->stereo3d) {
7426  if (!sc->stereo3d)
7427  return AVERROR(ENOMEM);
7428  }
7429 
7430  sc->stereo3d->flags = flags;
7431  sc->stereo3d->type = type;
7432  sc->stereo3d->view = view;
7433  sc->stereo3d->primary_eye = primary_eye;
7434  sc->stereo3d->baseline = baseline;
7435  sc->stereo3d->horizontal_disparity_adjustment = horizontal_disparity_adjustment;
7436 
7437  return 0;
7438 }
7439 
7441 {
7442  int size;
7443  int64_t remaining;
7444  uint32_t tag;
7445 
7446  if (c->fc->nb_streams < 1)
7447  return 0;
7448 
7449  if (atom.size < 8) {
7450  av_log(c->fc, AV_LOG_ERROR, "Empty video extension usage box\n");
7451  return AVERROR_INVALIDDATA;
7452  }
7453 
7454  remaining = atom.size;
7455  while (remaining > 0) {
7456  size = avio_rb32(pb);
7457  if (size < 8 || size > remaining ) {
7458  av_log(c->fc, AV_LOG_ERROR, "Invalid child size in vexu box\n");
7459  return AVERROR_INVALIDDATA;
7460  }
7461 
7462  tag = avio_rl32(pb);
7463  switch (tag) {
7464  case MKTAG('p','r','o','j'): {
7465  MOVAtom proj = { tag, size - 8 };
7466  int ret = mov_read_vexu_proj(c, pb, proj);
7467  if (ret < 0)
7468  return ret;
7469  break;
7470  }
7471  case MKTAG('e','y','e','s'): {
7472  MOVAtom eyes = { tag, size - 8 };
7473  int ret = mov_read_eyes(c, pb, eyes);
7474  if (ret < 0)
7475  return ret;
7476  break;
7477  }
7478  case MKTAG('p','a','c','k'): {
7479  MOVAtom pack = { tag, size - 8 };
7480  int ret = mov_read_pack(c, pb, pack);
7481  if (ret < 0)
7482  return ret;
7483  break;
7484  }
7485  default:
7486  av_log(c->fc, AV_LOG_WARNING, "Unknown tag in vexu: %s\n",
7487  av_fourcc2str(tag));
7488  avio_skip(pb, size - 8);
7489  break;
7490  }
7491  remaining -= size;
7492  }
7493 
7494  if (remaining != 0) {
7495  av_log(c->fc, AV_LOG_ERROR, "Broken vexu box\n");
7496  return AVERROR_INVALIDDATA;
7497  }
7498 
7499  return 0;
7500 }
7501 
7503 {
7504  AVStream *st;
7505  MOVStreamContext *sc;
7506 
7507  if (c->fc->nb_streams < 1)
7508  return 0;
7509 
7510  st = c->fc->streams[c->fc->nb_streams - 1];
7511  sc = st->priv_data;
7512 
7513  if (atom.size != 4) {
7514  av_log(c->fc, AV_LOG_ERROR, "Invalid size of hfov box: %"PRIu64"\n", atom.size);
7515  return AVERROR_INVALIDDATA;
7516  }
7517 
7518 
7519  if (!sc->stereo3d) {
7521  if (!sc->stereo3d)
7522  return AVERROR(ENOMEM);
7523  }
7524 
7526  sc->stereo3d->horizontal_field_of_view.den = 1000; // thousands of a degree
7527 
7528  return 0;
7529 }
7530 
7532 {
7533  int ret = 0;
7534  uint8_t *buffer = av_malloc(len + 1);
7535  const char *val;
7536 
7537  if (!buffer)
7538  return AVERROR(ENOMEM);
7539  buffer[len] = '\0';
7540 
7541  ret = ffio_read_size(pb, buffer, len);
7542  if (ret < 0)
7543  goto out;
7544 
7545  /* Check for mandatory keys and values, try to support XML as best-effort */
7546  if (!sc->spherical &&
7547  av_stristr(buffer, "<GSpherical:StitchingSoftware>") &&
7548  (val = av_stristr(buffer, "<GSpherical:Spherical>")) &&
7549  av_stristr(val, "true") &&
7550  (val = av_stristr(buffer, "<GSpherical:Stitched>")) &&
7551  av_stristr(val, "true") &&
7552  (val = av_stristr(buffer, "<GSpherical:ProjectionType>")) &&
7553  av_stristr(val, "equirectangular")) {
7555  if (!sc->spherical)
7556  goto out;
7557 
7559 
7560  if (av_stristr(buffer, "<GSpherical:StereoMode>") && !sc->stereo3d) {
7561  enum AVStereo3DType mode;
7562 
7563  if (av_stristr(buffer, "left-right"))
7565  else if (av_stristr(buffer, "top-bottom"))
7567  else
7568  mode = AV_STEREO3D_2D;
7569 
7571  if (!sc->stereo3d)
7572  goto out;
7573 
7574  sc->stereo3d->type = mode;
7575  }
7576 
7577  /* orientation */
7578  val = av_stristr(buffer, "<GSpherical:InitialViewHeadingDegrees>");
7579  if (val)
7580  sc->spherical->yaw = strtol(val, NULL, 10) * (1 << 16);
7581  val = av_stristr(buffer, "<GSpherical:InitialViewPitchDegrees>");
7582  if (val)
7583  sc->spherical->pitch = strtol(val, NULL, 10) * (1 << 16);
7584  val = av_stristr(buffer, "<GSpherical:InitialViewRollDegrees>");
7585  if (val)
7586  sc->spherical->roll = strtol(val, NULL, 10) * (1 << 16);
7587  }
7588 
7589 out:
7590  av_free(buffer);
7591  return ret;
7592 }
7593 
7595 {
7596  AVStream *st;
7597  MOVStreamContext *sc;
7598  int64_t ret;
7599  AVUUID uuid;
7600  static const AVUUID uuid_isml_manifest = {
7601  0xa5, 0xd4, 0x0b, 0x30, 0xe8, 0x14, 0x11, 0xdd,
7602  0xba, 0x2f, 0x08, 0x00, 0x20, 0x0c, 0x9a, 0x66
7603  };
7604  static const AVUUID uuid_xmp = {
7605  0xbe, 0x7a, 0xcf, 0xcb, 0x97, 0xa9, 0x42, 0xe8,
7606  0x9c, 0x71, 0x99, 0x94, 0x91, 0xe3, 0xaf, 0xac
7607  };
7608  static const AVUUID uuid_spherical = {
7609  0xff, 0xcc, 0x82, 0x63, 0xf8, 0x55, 0x4a, 0x93,
7610  0x88, 0x14, 0x58, 0x7a, 0x02, 0x52, 0x1f, 0xdd,
7611  };
7612 
7613  if (atom.size < AV_UUID_LEN || atom.size >= FFMIN(INT_MAX, SIZE_MAX))
7614  return AVERROR_INVALIDDATA;
7615 
7616  if (c->fc->nb_streams < 1)
7617  return 0;
7618  st = c->fc->streams[c->fc->nb_streams - 1];
7619  sc = st->priv_data;
7620 
7621  ret = ffio_read_size(pb, uuid, AV_UUID_LEN);
7622  if (ret < 0)
7623  return ret;
7624  if (av_uuid_equal(uuid, uuid_isml_manifest)) {
7625  uint8_t *buffer, *ptr;
7626  char *endptr;
7627  size_t len = atom.size - AV_UUID_LEN;
7628 
7629  if (len < 4) {
7630  return AVERROR_INVALIDDATA;
7631  }
7632  ret = avio_skip(pb, 4); // zeroes
7633  len -= 4;
7634 
7635  buffer = av_mallocz(len + 1);
7636  if (!buffer) {
7637  return AVERROR(ENOMEM);
7638  }
7639  ret = ffio_read_size(pb, buffer, len);
7640  if (ret < 0) {
7641  av_free(buffer);
7642  return ret;
7643  }
7644 
7645  ptr = buffer;
7646  while ((ptr = av_stristr(ptr, "systemBitrate=\""))) {
7647  ptr += sizeof("systemBitrate=\"") - 1;
7648  c->bitrates_count++;
7649  c->bitrates = av_realloc_f(c->bitrates, c->bitrates_count, sizeof(*c->bitrates));
7650  if (!c->bitrates) {
7651  c->bitrates_count = 0;
7652  av_free(buffer);
7653  return AVERROR(ENOMEM);
7654  }
7655  errno = 0;
7656  ret = strtol(ptr, &endptr, 10);
7657  if (ret < 0 || errno || *endptr != '"') {
7658  c->bitrates[c->bitrates_count - 1] = 0;
7659  } else {
7660  c->bitrates[c->bitrates_count - 1] = ret;
7661  }
7662  }
7663 
7664  av_free(buffer);
7665  } else if (av_uuid_equal(uuid, uuid_xmp)) {
7666  uint8_t *buffer;
7667  size_t len = atom.size - AV_UUID_LEN;
7668  if (c->export_xmp) {
7669  buffer = av_mallocz(len + 1);
7670  if (!buffer) {
7671  return AVERROR(ENOMEM);
7672  }
7673  ret = ffio_read_size(pb, buffer, len);
7674  if (ret < 0) {
7675  av_free(buffer);
7676  return ret;
7677  }
7678  buffer[len] = '\0';
7679  av_dict_set(&c->fc->metadata, "xmp",
7681  } else {
7682  // skip all uuid atom, which makes it fast for long uuid-xmp file
7683  ret = avio_skip(pb, len);
7684  if (ret < 0)
7685  return ret;
7686  }
7687  } else if (av_uuid_equal(uuid, uuid_spherical)) {
7688  size_t len = atom.size - AV_UUID_LEN;
7689  ret = mov_parse_uuid_spherical(sc, pb, len);
7690  if (ret < 0)
7691  return ret;
7692  if (!sc->spherical)
7693  av_log(c->fc, AV_LOG_WARNING, "Invalid spherical metadata found\n");
7694  }
7695 
7696  return 0;
7697 }
7698 
7700 {
7701  int ret;
7702  uint8_t content[16];
7703 
7704  if (atom.size < 8)
7705  return 0;
7706 
7707  ret = ffio_read_size(pb, content, FFMIN(sizeof(content), atom.size));
7708  if (ret < 0)
7709  return ret;
7710 
7711  if ( !c->found_moov
7712  && !c->found_mdat
7713  && !memcmp(content, "Anevia\x1A\x1A", 8)
7714  && c->use_mfra_for == FF_MOV_FLAG_MFRA_AUTO) {
7715  c->use_mfra_for = FF_MOV_FLAG_MFRA_PTS;
7716  }
7717 
7718  return 0;
7719 }
7720 
7722 {
7723  uint32_t format = avio_rl32(pb);
7724  MOVStreamContext *sc;
7725  enum AVCodecID id;
7726  AVStream *st;
7727 
7728  if (c->fc->nb_streams < 1)
7729  return 0;
7730  st = c->fc->streams[c->fc->nb_streams - 1];
7731  sc = st->priv_data;
7732 
7733  switch (sc->format)
7734  {
7735  case MKTAG('e','n','c','v'): // encrypted video
7736  case MKTAG('e','n','c','a'): // encrypted audio
7737  id = mov_codec_id(st, format);
7738  if (st->codecpar->codec_id != AV_CODEC_ID_NONE &&
7739  st->codecpar->codec_id != id) {
7740  av_log(c->fc, AV_LOG_WARNING,
7741  "ignoring 'frma' atom of '%.4s', stream has codec id %d\n",
7742  (char*)&format, st->codecpar->codec_id);
7743  break;
7744  }
7745 
7746  st->codecpar->codec_id = id;
7747  sc->format = format;
7748  break;
7749 
7750  default:
7751  if (format != sc->format) {
7752  av_log(c->fc, AV_LOG_WARNING,
7753  "ignoring 'frma' atom of '%.4s', stream format is '%.4s'\n",
7754  (char*)&format, (char*)&sc->format);
7755  }
7756  break;
7757  }
7758 
7759  return 0;
7760 }
7761 
7762 /**
7763  * Gets the current encryption info and associated current stream context. If
7764  * we are parsing a track fragment, this will return the specific encryption
7765  * info for this fragment; otherwise this will return the global encryption
7766  * info for the current stream.
7767  */
7769 {
7770  MOVFragmentStreamInfo *frag_stream_info;
7771  AVStream *st;
7772  int i;
7773 
7774  frag_stream_info = get_current_frag_stream_info(&c->frag_index);
7775  if (frag_stream_info) {
7776  for (i = 0; i < c->fc->nb_streams; i++) {
7777  *sc = c->fc->streams[i]->priv_data;
7778  if ((*sc)->id == frag_stream_info->id) {
7779  st = c->fc->streams[i];
7780  break;
7781  }
7782  }
7783  if (i == c->fc->nb_streams)
7784  return 0;
7785  *sc = st->priv_data;
7786 
7787  if (!frag_stream_info->encryption_index) {
7788  // If this stream isn't encrypted, don't create the index.
7789  if (!(*sc)->cenc.default_encrypted_sample)
7790  return 0;
7791  frag_stream_info->encryption_index = av_mallocz(sizeof(*frag_stream_info->encryption_index));
7792  if (!frag_stream_info->encryption_index)
7793  return AVERROR(ENOMEM);
7794  }
7795  *encryption_index = frag_stream_info->encryption_index;
7796  return 1;
7797  } else {
7798  // No current track fragment, using stream level encryption info.
7799 
7800  if (c->fc->nb_streams < 1)
7801  return 0;
7802  st = c->fc->streams[c->fc->nb_streams - 1];
7803  *sc = st->priv_data;
7804 
7805  if (!(*sc)->cenc.encryption_index) {
7806  // If this stream isn't encrypted, don't create the index.
7807  if (!(*sc)->cenc.default_encrypted_sample)
7808  return 0;
7809  (*sc)->cenc.encryption_index = av_mallocz(sizeof(*frag_stream_info->encryption_index));
7810  if (!(*sc)->cenc.encryption_index)
7811  return AVERROR(ENOMEM);
7812  }
7813 
7814  *encryption_index = (*sc)->cenc.encryption_index;
7815  return 1;
7816  }
7817 }
7818 
7820 {
7821  int i, ret;
7822  unsigned int subsample_count;
7823  AVSubsampleEncryptionInfo *subsamples;
7824 
7825  if (!sc->cenc.default_encrypted_sample) {
7826  av_log(c->fc, AV_LOG_ERROR, "Missing schm or tenc\n");
7827  return AVERROR_INVALIDDATA;
7828  }
7829 
7830  if (sc->cenc.per_sample_iv_size || use_subsamples) {
7832  if (!*sample)
7833  return AVERROR(ENOMEM);
7834  } else
7835  *sample = NULL;
7836 
7837  if (sc->cenc.per_sample_iv_size != 0) {
7838  if ((ret = ffio_read_size(pb, (*sample)->iv, sc->cenc.per_sample_iv_size)) < 0) {
7839  av_log(c->fc, AV_LOG_ERROR, "failed to read the initialization vector\n");
7841  *sample = NULL;
7842  return ret;
7843  }
7844  }
7845 
7846  if (use_subsamples) {
7847  subsample_count = avio_rb16(pb);
7848  av_free((*sample)->subsamples);
7849  (*sample)->subsamples = av_calloc(subsample_count, sizeof(*subsamples));
7850  if (!(*sample)->subsamples) {
7852  *sample = NULL;
7853  return AVERROR(ENOMEM);
7854  }
7855 
7856  for (i = 0; i < subsample_count && !pb->eof_reached; i++) {
7857  (*sample)->subsamples[i].bytes_of_clear_data = avio_rb16(pb);
7858  (*sample)->subsamples[i].bytes_of_protected_data = avio_rb32(pb);
7859  }
7860 
7861  if (pb->eof_reached) {
7862  av_log(c->fc, AV_LOG_ERROR, "hit EOF while reading sub-sample encryption info\n");
7864  *sample = NULL;
7865  return AVERROR_INVALIDDATA;
7866  }
7867  (*sample)->subsample_count = subsample_count;
7868  }
7869 
7870  return 0;
7871 }
7872 
7874 {
7875  AVEncryptionInfo **encrypted_samples;
7876  MOVEncryptionIndex *encryption_index;
7877  MOVStreamContext *sc;
7878  int use_subsamples, ret;
7879  unsigned int sample_count, i, alloc_size = 0;
7880 
7881  ret = get_current_encryption_info(c, &encryption_index, &sc);
7882  if (ret != 1)
7883  return ret;
7884 
7885  if (encryption_index->nb_encrypted_samples) {
7886  // This can happen if we have both saio/saiz and senc atoms.
7887  av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in senc\n");
7888  return 0;
7889  }
7890 
7891  avio_r8(pb); /* version */
7892  use_subsamples = avio_rb24(pb) & 0x02; /* flags */
7893 
7894  sample_count = avio_rb32(pb);
7895  if (sample_count >= INT_MAX / sizeof(*encrypted_samples))
7896  return AVERROR(ENOMEM);
7897 
7898  for (i = 0; i < sample_count; i++) {
7899  unsigned int min_samples = FFMIN(FFMAX(i + 1, 1024 * 1024), sample_count);
7900  encrypted_samples = av_fast_realloc(encryption_index->encrypted_samples, &alloc_size,
7901  min_samples * sizeof(*encrypted_samples));
7902  if (encrypted_samples) {
7903  encryption_index->encrypted_samples = encrypted_samples;
7904 
7906  c, pb, sc, &encryption_index->encrypted_samples[i], use_subsamples);
7907  } else {
7908  ret = AVERROR(ENOMEM);
7909  }
7910  if (pb->eof_reached) {
7911  av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading senc\n");
7912  if (ret >= 0)
7913  av_encryption_info_free(encryption_index->encrypted_samples[i]);
7915  }
7916 
7917  if (ret < 0) {
7918  for (; i > 0; i--)
7919  av_encryption_info_free(encryption_index->encrypted_samples[i - 1]);
7920  av_freep(&encryption_index->encrypted_samples);
7921  return ret;
7922  }
7923  }
7924  encryption_index->nb_encrypted_samples = sample_count;
7925 
7926  return 0;
7927 }
7928 
7930 {
7931  AVEncryptionInfo **sample, **encrypted_samples;
7932  int64_t prev_pos;
7933  size_t sample_count, sample_info_size, i;
7934  int ret = 0;
7935  unsigned int alloc_size = 0;
7936 
7937  if (encryption_index->nb_encrypted_samples)
7938  return 0;
7939  sample_count = encryption_index->auxiliary_info_sample_count;
7940  if (encryption_index->auxiliary_offsets_count != 1) {
7941  av_log(c->fc, AV_LOG_ERROR, "Multiple auxiliary info chunks are not supported\n");
7942  return AVERROR_PATCHWELCOME;
7943  }
7944  if (sample_count >= INT_MAX / sizeof(*encrypted_samples))
7945  return AVERROR(ENOMEM);
7946 
7947  prev_pos = avio_tell(pb);
7948  if (!(pb->seekable & AVIO_SEEKABLE_NORMAL) ||
7949  avio_seek(pb, encryption_index->auxiliary_offsets[0], SEEK_SET) != encryption_index->auxiliary_offsets[0]) {
7950  av_log(c->fc, AV_LOG_INFO, "Failed to seek for auxiliary info, will only parse senc atoms for encryption info\n");
7951  goto finish;
7952  }
7953 
7954  for (i = 0; i < sample_count && !pb->eof_reached; i++) {
7955  unsigned int min_samples = FFMIN(FFMAX(i + 1, 1024 * 1024), sample_count);
7956  encrypted_samples = av_fast_realloc(encryption_index->encrypted_samples, &alloc_size,
7957  min_samples * sizeof(*encrypted_samples));
7958  if (!encrypted_samples) {
7959  ret = AVERROR(ENOMEM);
7960  goto finish;
7961  }
7962  encryption_index->encrypted_samples = encrypted_samples;
7963 
7964  sample = &encryption_index->encrypted_samples[i];
7965  sample_info_size = encryption_index->auxiliary_info_default_size
7966  ? encryption_index->auxiliary_info_default_size
7967  : encryption_index->auxiliary_info_sizes[i];
7968 
7969  ret = mov_read_sample_encryption_info(c, pb, sc, sample, sample_info_size > sc->cenc.per_sample_iv_size);
7970  if (ret < 0)
7971  goto finish;
7972  }
7973  if (pb->eof_reached) {
7974  av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading auxiliary info\n");
7976  } else {
7977  encryption_index->nb_encrypted_samples = sample_count;
7978  }
7979 
7980 finish:
7981  avio_seek(pb, prev_pos, SEEK_SET);
7982  if (ret < 0) {
7983  for (; i > 0; i--) {
7984  av_encryption_info_free(encryption_index->encrypted_samples[i - 1]);
7985  }
7986  av_freep(&encryption_index->encrypted_samples);
7987  }
7988  return ret;
7989 }
7990 
7992 {
7993  MOVEncryptionIndex *encryption_index;
7994  MOVStreamContext *sc;
7995  int ret;
7996  unsigned int sample_count, aux_info_type, aux_info_param;
7997 
7998  ret = get_current_encryption_info(c, &encryption_index, &sc);
7999  if (ret != 1)
8000  return ret;
8001 
8002  if (encryption_index->nb_encrypted_samples) {
8003  // This can happen if we have both saio/saiz and senc atoms.
8004  av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in saiz\n");
8005  return 0;
8006  }
8007 
8008  if (encryption_index->auxiliary_info_sample_count) {
8009  av_log(c->fc, AV_LOG_ERROR, "Duplicate saiz atom\n");
8010  return AVERROR_INVALIDDATA;
8011  }
8012 
8013  avio_r8(pb); /* version */
8014  if (avio_rb24(pb) & 0x01) { /* flags */
8015  aux_info_type = avio_rb32(pb);
8016  aux_info_param = avio_rb32(pb);
8017  if (sc->cenc.default_encrypted_sample) {
8018  if (aux_info_type != sc->cenc.default_encrypted_sample->scheme) {
8019  av_log(c->fc, AV_LOG_DEBUG, "Ignoring saiz box with non-zero aux_info_type\n");
8020  return 0;
8021  }
8022  if (aux_info_param != 0) {
8023  av_log(c->fc, AV_LOG_DEBUG, "Ignoring saiz box with non-zero aux_info_type_parameter\n");
8024  return 0;
8025  }
8026  } else {
8027  // Didn't see 'schm' or 'tenc', so this isn't encrypted.
8028  if ((aux_info_type == MKBETAG('c','e','n','c') ||
8029  aux_info_type == MKBETAG('c','e','n','s') ||
8030  aux_info_type == MKBETAG('c','b','c','1') ||
8031  aux_info_type == MKBETAG('c','b','c','s')) &&
8032  aux_info_param == 0) {
8033  av_log(c->fc, AV_LOG_ERROR, "Saw encrypted saiz without schm/tenc\n");
8034  return AVERROR_INVALIDDATA;
8035  } else {
8036  return 0;
8037  }
8038  }
8039  } else if (!sc->cenc.default_encrypted_sample) {
8040  // Didn't see 'schm' or 'tenc', so this isn't encrypted.
8041  return 0;
8042  }
8043 
8044  encryption_index->auxiliary_info_default_size = avio_r8(pb);
8045  sample_count = avio_rb32(pb);
8046 
8047  if (encryption_index->auxiliary_info_default_size == 0) {
8048  if (sample_count == 0)
8049  return AVERROR_INVALIDDATA;
8050 
8051  encryption_index->auxiliary_info_sizes = av_malloc(sample_count);
8052  if (!encryption_index->auxiliary_info_sizes)
8053  return AVERROR(ENOMEM);
8054 
8055  ret = avio_read(pb, encryption_index->auxiliary_info_sizes, sample_count);
8056  if (ret != sample_count) {
8057  av_freep(&encryption_index->auxiliary_info_sizes);
8058 
8059  if (ret >= 0)
8061  av_log(c->fc, AV_LOG_ERROR, "Failed to read the auxiliary info, %s\n",
8062  av_err2str(ret));
8063  return ret;
8064  }
8065  }
8066  encryption_index->auxiliary_info_sample_count = sample_count;
8067 
8068  if (encryption_index->auxiliary_offsets_count) {
8069  return mov_parse_auxiliary_info(c, sc, pb, encryption_index);
8070  }
8071 
8072  return 0;
8073 }
8074 
8076 {
8077  uint64_t *auxiliary_offsets;
8078  MOVEncryptionIndex *encryption_index;
8079  MOVStreamContext *sc;
8080  int i, ret;
8081  unsigned int version, entry_count, aux_info_type, aux_info_param;
8082  unsigned int alloc_size = 0;
8083 
8084  ret = get_current_encryption_info(c, &encryption_index, &sc);
8085  if (ret != 1)
8086  return ret;
8087 
8088  if (encryption_index->nb_encrypted_samples) {
8089  // This can happen if we have both saio/saiz and senc atoms.
8090  av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in saio\n");
8091  return 0;
8092  }
8093 
8094  if (encryption_index->auxiliary_offsets_count) {
8095  av_log(c->fc, AV_LOG_ERROR, "Duplicate saio atom\n");
8096  return AVERROR_INVALIDDATA;
8097  }
8098 
8099  version = avio_r8(pb); /* version */
8100  if (avio_rb24(pb) & 0x01) { /* flags */
8101  aux_info_type = avio_rb32(pb);
8102  aux_info_param = avio_rb32(pb);
8103  if (sc->cenc.default_encrypted_sample) {
8104  if (aux_info_type != sc->cenc.default_encrypted_sample->scheme) {
8105  av_log(c->fc, AV_LOG_DEBUG, "Ignoring saio box with non-zero aux_info_type\n");
8106  return 0;
8107  }
8108  if (aux_info_param != 0) {
8109  av_log(c->fc, AV_LOG_DEBUG, "Ignoring saio box with non-zero aux_info_type_parameter\n");
8110  return 0;
8111  }
8112  } else {
8113  // Didn't see 'schm' or 'tenc', so this isn't encrypted.
8114  if ((aux_info_type == MKBETAG('c','e','n','c') ||
8115  aux_info_type == MKBETAG('c','e','n','s') ||
8116  aux_info_type == MKBETAG('c','b','c','1') ||
8117  aux_info_type == MKBETAG('c','b','c','s')) &&
8118  aux_info_param == 0) {
8119  av_log(c->fc, AV_LOG_ERROR, "Saw encrypted saio without schm/tenc\n");
8120  return AVERROR_INVALIDDATA;
8121  } else {
8122  return 0;
8123  }
8124  }
8125  } else if (!sc->cenc.default_encrypted_sample) {
8126  // Didn't see 'schm' or 'tenc', so this isn't encrypted.
8127  return 0;
8128  }
8129 
8130  entry_count = avio_rb32(pb);
8131  if (entry_count >= INT_MAX / sizeof(*auxiliary_offsets))
8132  return AVERROR(ENOMEM);
8133 
8134  for (i = 0; i < entry_count && !pb->eof_reached; i++) {
8135  unsigned int min_offsets = FFMIN(FFMAX(i + 1, 1024), entry_count);
8136  auxiliary_offsets = av_fast_realloc(
8137  encryption_index->auxiliary_offsets, &alloc_size,
8138  min_offsets * sizeof(*auxiliary_offsets));
8139  if (!auxiliary_offsets) {
8140  av_freep(&encryption_index->auxiliary_offsets);
8141  return AVERROR(ENOMEM);
8142  }
8143  encryption_index->auxiliary_offsets = auxiliary_offsets;
8144 
8145  if (version == 0) {
8146  encryption_index->auxiliary_offsets[i] = avio_rb32(pb);
8147  } else {
8148  encryption_index->auxiliary_offsets[i] = avio_rb64(pb);
8149  }
8150  if (c->frag_index.current >= 0) {
8151  encryption_index->auxiliary_offsets[i] += c->fragment.base_data_offset;
8152  }
8153  }
8154 
8155  if (pb->eof_reached) {
8156  av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading saio\n");
8157  av_freep(&encryption_index->auxiliary_offsets);
8158  return AVERROR_INVALIDDATA;
8159  }
8160 
8161  encryption_index->auxiliary_offsets_count = entry_count;
8162 
8163  if (encryption_index->auxiliary_info_sample_count) {
8164  return mov_parse_auxiliary_info(c, sc, pb, encryption_index);
8165  }
8166 
8167  return 0;
8168 }
8169 
8171 {
8172  AVEncryptionInitInfo *info, *old_init_info;
8173  uint8_t **key_ids;
8174  AVStream *st;
8175  const AVPacketSideData *old_side_data;
8176  uint8_t *side_data, *extra_data;
8177  size_t side_data_size;
8178  int ret = 0;
8179  unsigned int version, kid_count, extra_data_size, alloc_size = 0;
8180 
8181  if (c->fc->nb_streams < 1)
8182  return 0;
8183  st = c->fc->streams[c->fc->nb_streams-1];
8184 
8185  version = avio_r8(pb); /* version */
8186  avio_rb24(pb); /* flags */
8187 
8188  info = av_encryption_init_info_alloc(/* system_id_size */ 16, /* num_key_ids */ 0,
8189  /* key_id_size */ 16, /* data_size */ 0);
8190  if (!info)
8191  return AVERROR(ENOMEM);
8192 
8193  if ((ret = ffio_read_size(pb, info->system_id, 16)) < 0) {
8194  av_log(c->fc, AV_LOG_ERROR, "Failed to read the system id\n");
8195  goto finish;
8196  }
8197 
8198  if (version > 0) {
8199  kid_count = avio_rb32(pb);
8200  if (kid_count >= INT_MAX / sizeof(*key_ids)) {
8201  ret = AVERROR(ENOMEM);
8202  goto finish;
8203  }
8204 
8205  for (unsigned int i = 0; i < kid_count && !pb->eof_reached; i++) {
8206  unsigned int min_kid_count = FFMIN(FFMAX(i + 1, 1024), kid_count);
8207  key_ids = av_fast_realloc(info->key_ids, &alloc_size,
8208  min_kid_count * sizeof(*key_ids));
8209  if (!key_ids) {
8210  ret = AVERROR(ENOMEM);
8211  goto finish;
8212  }
8213  info->key_ids = key_ids;
8214 
8215  info->key_ids[i] = av_mallocz(16);
8216  if (!info->key_ids[i]) {
8217  ret = AVERROR(ENOMEM);
8218  goto finish;
8219  }
8220  info->num_key_ids = i + 1;
8221 
8222  if ((ret = ffio_read_size(pb, info->key_ids[i], 16)) < 0) {
8223  av_log(c->fc, AV_LOG_ERROR, "Failed to read the key id\n");
8224  goto finish;
8225  }
8226  }
8227 
8228  if (pb->eof_reached) {
8229  av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading pssh\n");
8231  goto finish;
8232  }
8233  }
8234 
8235  extra_data_size = avio_rb32(pb);
8236  extra_data = av_malloc(extra_data_size);
8237  if (!extra_data) {
8238  ret = AVERROR(ENOMEM);
8239  goto finish;
8240  }
8241  ret = avio_read(pb, extra_data, extra_data_size);
8242  if (ret != extra_data_size) {
8243  av_free(extra_data);
8244 
8245  if (ret >= 0)
8247  goto finish;
8248  }
8249 
8250  av_freep(&info->data); // malloc(0) may still allocate something.
8251  info->data = extra_data;
8252  info->data_size = extra_data_size;
8253 
8254  // If there is existing initialization data, append to the list.
8257  if (old_side_data) {
8258  old_init_info = av_encryption_init_info_get_side_data(old_side_data->data, old_side_data->size);
8259  if (old_init_info) {
8260  // Append to the end of the list.
8261  for (AVEncryptionInitInfo *cur = old_init_info;; cur = cur->next) {
8262  if (!cur->next) {
8263  cur->next = info;
8264  break;
8265  }
8266  }
8267  info = old_init_info;
8268  } else {
8269  // Assume existing side-data will be valid, so the only error we could get is OOM.
8270  ret = AVERROR(ENOMEM);
8271  goto finish;
8272  }
8273  }
8274 
8275  side_data = av_encryption_init_info_add_side_data(info, &side_data_size);
8276  if (!side_data) {
8277  ret = AVERROR(ENOMEM);
8278  goto finish;
8279  }
8283  side_data, side_data_size, 0))
8284  av_free(side_data);
8285 
8286 finish:
8288  return ret;
8289 }
8290 
8292 {
8293  AVStream *st;
8294  MOVStreamContext *sc;
8295 
8296  if (c->fc->nb_streams < 1)
8297  return 0;
8298  st = c->fc->streams[c->fc->nb_streams-1];
8299  sc = st->priv_data;
8300 
8301  if (sc->pseudo_stream_id != 0) {
8302  av_log(c->fc, AV_LOG_ERROR, "schm boxes are only supported in first sample descriptor\n");
8303  return AVERROR_PATCHWELCOME;
8304  }
8305 
8306  if (atom.size < 8)
8307  return AVERROR_INVALIDDATA;
8308 
8309  avio_rb32(pb); /* version and flags */
8310 
8311  if (!sc->cenc.default_encrypted_sample) {
8313  if (!sc->cenc.default_encrypted_sample) {
8314  return AVERROR(ENOMEM);
8315  }
8316  }
8317 
8319  return 0;
8320 }
8321 
8323 {
8324  AVStream *st;
8325  MOVStreamContext *sc;
8326  unsigned int version, pattern, is_protected, iv_size;
8327 
8328  if (c->fc->nb_streams < 1)
8329  return 0;
8330  st = c->fc->streams[c->fc->nb_streams-1];
8331  sc = st->priv_data;
8332 
8333  if (sc->pseudo_stream_id != 0) {
8334  av_log(c->fc, AV_LOG_ERROR, "tenc atom are only supported in first sample descriptor\n");
8335  return AVERROR_PATCHWELCOME;
8336  }
8337 
8338  if (!sc->cenc.default_encrypted_sample) {
8340  if (!sc->cenc.default_encrypted_sample) {
8341  return AVERROR(ENOMEM);
8342  }
8343  }
8344 
8345  if (atom.size < 20)
8346  return AVERROR_INVALIDDATA;
8347 
8348  version = avio_r8(pb); /* version */
8349  avio_rb24(pb); /* flags */
8350 
8351  avio_r8(pb); /* reserved */
8352  pattern = avio_r8(pb);
8353 
8354  if (version > 0) {
8355  sc->cenc.default_encrypted_sample->crypt_byte_block = pattern >> 4;
8356  sc->cenc.default_encrypted_sample->skip_byte_block = pattern & 0xf;
8357  }
8358 
8359  is_protected = avio_r8(pb);
8360  if (is_protected && !sc->cenc.encryption_index) {
8361  // The whole stream should be by-default encrypted.
8363  if (!sc->cenc.encryption_index)
8364  return AVERROR(ENOMEM);
8365  }
8366  sc->cenc.per_sample_iv_size = avio_r8(pb);
8367  if (sc->cenc.per_sample_iv_size != 0 && sc->cenc.per_sample_iv_size != 8 &&
8368  sc->cenc.per_sample_iv_size != 16) {
8369  av_log(c->fc, AV_LOG_ERROR, "invalid per-sample IV size value\n");
8370  return AVERROR_INVALIDDATA;
8371  }
8372  if (avio_read(pb, sc->cenc.default_encrypted_sample->key_id, 16) != 16) {
8373  av_log(c->fc, AV_LOG_ERROR, "failed to read the default key ID\n");
8374  return AVERROR_INVALIDDATA;
8375  }
8376 
8377  if (is_protected && !sc->cenc.per_sample_iv_size) {
8378  iv_size = avio_r8(pb);
8379  if (iv_size != 8 && iv_size != 16) {
8380  av_log(c->fc, AV_LOG_ERROR, "invalid default_constant_IV_size in tenc atom\n");
8381  return AVERROR_INVALIDDATA;
8382  }
8383 
8384  if (avio_read(pb, sc->cenc.default_encrypted_sample->iv, iv_size) != iv_size) {
8385  av_log(c->fc, AV_LOG_ERROR, "failed to read the default IV\n");
8386  return AVERROR_INVALIDDATA;
8387  }
8388  }
8389 
8390  return 0;
8391 }
8392 
8394 {
8395  AVStream *st;
8396  int last, type, size, ret;
8397  uint8_t buf[4];
8398 
8399  if (c->fc->nb_streams < 1)
8400  return 0;
8401  st = c->fc->streams[c->fc->nb_streams-1];
8402 
8403  if ((uint64_t)atom.size > (1<<30) || atom.size < 42)
8404  return AVERROR_INVALIDDATA;
8405 
8406  /* Check FlacSpecificBox version. */
8407  if (avio_r8(pb) != 0)
8408  return AVERROR_INVALIDDATA;
8409 
8410  avio_rb24(pb); /* Flags */
8411 
8412  if (avio_read(pb, buf, sizeof(buf)) != sizeof(buf)) {
8413  av_log(c->fc, AV_LOG_ERROR, "failed to read FLAC metadata block header\n");
8414  return pb->error < 0 ? pb->error : AVERROR_INVALIDDATA;
8415  }
8416  flac_parse_block_header(buf, &last, &type, &size);
8417 
8419  av_log(c->fc, AV_LOG_ERROR, "STREAMINFO must be first FLACMetadataBlock\n");
8420  return AVERROR_INVALIDDATA;
8421  }
8422 
8423  ret = ff_get_extradata(c->fc, st->codecpar, pb, size);
8424  if (ret < 0)
8425  return ret;
8426 
8427  if (!last)
8428  av_log(c->fc, AV_LOG_WARNING, "non-STREAMINFO FLACMetadataBlock(s) ignored\n");
8429 
8430  return 0;
8431 }
8432 
8433 static int get_key_from_kid(uint8_t* out, int len, MOVContext *c, AVEncryptionInfo *sample) {
8434  AVDictionaryEntry *key_entry_hex;
8435  char kid_hex[16*2+1];
8436 
8437  if (c->decryption_default_key && c->decryption_default_key_len != len) {
8438  av_log(c->fc, AV_LOG_ERROR, "invalid default decryption key length: got %d, expected %d\n", c->decryption_default_key_len, len);
8439  return -1;
8440  }
8441 
8442  if (!c->decryption_keys) {
8443  av_assert0(c->decryption_default_key);
8444  memcpy(out, c->decryption_default_key, len);
8445  return 0;
8446  }
8447 
8448  if (sample->key_id_size != 16) {
8449  av_log(c->fc, AV_LOG_ERROR, "invalid key ID size: got %u, expected 16\n", sample->key_id_size);
8450  return -1;
8451  }
8452 
8453  ff_data_to_hex(kid_hex, sample->key_id, 16, 1);
8454  key_entry_hex = av_dict_get(c->decryption_keys, kid_hex, NULL, AV_DICT_DONT_STRDUP_KEY|AV_DICT_DONT_STRDUP_VAL);
8455  if (!key_entry_hex) {
8456  if (!c->decryption_default_key) {
8457  av_log(c->fc, AV_LOG_ERROR, "unable to find KID %s\n", kid_hex);
8458  return -1;
8459  }
8460  memcpy(out, c->decryption_default_key, len);
8461  return 0;
8462  }
8463  if (strlen(key_entry_hex->value) != len*2) {
8464  return -1;
8465  }
8466  ff_hex_to_data(out, key_entry_hex->value);
8467  return 0;
8468 }
8469 
8471 {
8472  int i, ret;
8473  int bytes_of_protected_data;
8474  uint8_t decryption_key[AES_CTR_KEY_SIZE];
8475 
8476  if (!sc->cenc.aes_ctr) {
8477  ret = get_key_from_kid(decryption_key, sizeof(decryption_key), c, sample);
8478  if (ret < 0) {
8479  return ret;
8480  }
8481 
8482  /* initialize the cipher */
8483  sc->cenc.aes_ctr = av_aes_ctr_alloc();
8484  if (!sc->cenc.aes_ctr) {
8485  return AVERROR(ENOMEM);
8486  }
8487 
8488  ret = av_aes_ctr_init(sc->cenc.aes_ctr, decryption_key);
8489  if (ret < 0) {
8490  return ret;
8491  }
8492  }
8493 
8495 
8496  if (!sample->subsample_count) {
8497  /* decrypt the whole packet */
8499  return 0;
8500  }
8501 
8502  for (i = 0; i < sample->subsample_count; i++) {
8503  if (sample->subsamples[i].bytes_of_clear_data + (int64_t)sample->subsamples[i].bytes_of_protected_data > size) {
8504  av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n");
8505  return AVERROR_INVALIDDATA;
8506  }
8507 
8508  /* skip the clear bytes */
8509  input += sample->subsamples[i].bytes_of_clear_data;
8510  size -= sample->subsamples[i].bytes_of_clear_data;
8511 
8512  /* decrypt the encrypted bytes */
8513 
8514  bytes_of_protected_data = sample->subsamples[i].bytes_of_protected_data;
8515  av_aes_ctr_crypt(sc->cenc.aes_ctr, input, input, bytes_of_protected_data);
8516 
8517  input += bytes_of_protected_data;
8518  size -= bytes_of_protected_data;
8519  }
8520 
8521  if (size > 0) {
8522  av_log(c->fc, AV_LOG_ERROR, "leftover packet bytes after subsample processing\n");
8523  return AVERROR_INVALIDDATA;
8524  }
8525 
8526  return 0;
8527 }
8528 
8530 {
8531  int i, ret;
8532  int num_of_encrypted_blocks;
8533  uint8_t iv[16];
8534  uint8_t decryption_key[16];
8535 
8536  if (!sc->cenc.aes_ctx) {
8537  ret = get_key_from_kid(decryption_key, sizeof(decryption_key), c, sample);
8538  if (ret < 0) {
8539  return ret;
8540  }
8541 
8542  /* initialize the cipher */
8543  sc->cenc.aes_ctx = av_aes_alloc();
8544  if (!sc->cenc.aes_ctx) {
8545  return AVERROR(ENOMEM);
8546  }
8547 
8548  ret = av_aes_init(sc->cenc.aes_ctx, decryption_key, 16 * 8, 1);
8549  if (ret < 0) {
8550  return ret;
8551  }
8552  }
8553 
8554  memcpy(iv, sample->iv, 16);
8555 
8556  /* whole-block full sample encryption */
8557  if (!sample->subsample_count) {
8558  /* decrypt the whole packet */
8559  av_aes_crypt(sc->cenc.aes_ctx, input, input, size/16, iv, 1);
8560  return 0;
8561  }
8562 
8563  for (i = 0; i < sample->subsample_count; i++) {
8564  if (sample->subsamples[i].bytes_of_clear_data + (int64_t)sample->subsamples[i].bytes_of_protected_data > size) {
8565  av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n");
8566  return AVERROR_INVALIDDATA;
8567  }
8568 
8569  if (sample->subsamples[i].bytes_of_protected_data % 16) {
8570  av_log(c->fc, AV_LOG_ERROR, "subsample BytesOfProtectedData is not a multiple of 16\n");
8571  return AVERROR_INVALIDDATA;
8572  }
8573 
8574  /* skip the clear bytes */
8575  input += sample->subsamples[i].bytes_of_clear_data;
8576  size -= sample->subsamples[i].bytes_of_clear_data;
8577 
8578  /* decrypt the encrypted bytes */
8579  num_of_encrypted_blocks = sample->subsamples[i].bytes_of_protected_data/16;
8580  if (num_of_encrypted_blocks > 0) {
8581  av_aes_crypt(sc->cenc.aes_ctx, input, input, num_of_encrypted_blocks, iv, 1);
8582  }
8583  input += sample->subsamples[i].bytes_of_protected_data;
8584  size -= sample->subsamples[i].bytes_of_protected_data;
8585  }
8586 
8587  if (size > 0) {
8588  av_log(c->fc, AV_LOG_ERROR, "leftover packet bytes after subsample processing\n");
8589  return AVERROR_INVALIDDATA;
8590  }
8591 
8592  return 0;
8593 }
8594 
8596 {
8597  int i, ret, rem_bytes;
8598  uint8_t *data;
8599  uint8_t decryption_key[AES_CTR_KEY_SIZE];
8600 
8601  if (!sc->cenc.aes_ctr) {
8602  ret = get_key_from_kid(decryption_key, sizeof(decryption_key), c, sample);
8603  if (ret < 0) {
8604  return ret;
8605  }
8606 
8607  /* initialize the cipher */
8608  sc->cenc.aes_ctr = av_aes_ctr_alloc();
8609  if (!sc->cenc.aes_ctr) {
8610  return AVERROR(ENOMEM);
8611  }
8612 
8613  ret = av_aes_ctr_init(sc->cenc.aes_ctr, decryption_key);
8614  if (ret < 0) {
8615  return ret;
8616  }
8617  }
8618 
8620 
8621  /* whole-block full sample encryption */
8622  if (!sample->subsample_count) {
8623  /* decrypt the whole packet */
8625  return 0;
8626  } else if (!sample->crypt_byte_block && !sample->skip_byte_block) {
8627  av_log(c->fc, AV_LOG_ERROR, "pattern encryption is not present in 'cens' scheme\n");
8628  return AVERROR_INVALIDDATA;
8629  }
8630 
8631  for (i = 0; i < sample->subsample_count; i++) {
8632  if (sample->subsamples[i].bytes_of_clear_data + (int64_t)sample->subsamples[i].bytes_of_protected_data > size) {
8633  av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n");
8634  return AVERROR_INVALIDDATA;
8635  }
8636 
8637  /* skip the clear bytes */
8638  input += sample->subsamples[i].bytes_of_clear_data;
8639  size -= sample->subsamples[i].bytes_of_clear_data;
8640 
8641  /* decrypt the encrypted bytes */
8642  data = input;
8643  rem_bytes = sample->subsamples[i].bytes_of_protected_data;
8644  while (rem_bytes > 0) {
8645  if (rem_bytes < 16*sample->crypt_byte_block) {
8646  break;
8647  }
8648  av_aes_ctr_crypt(sc->cenc.aes_ctr, data, data, 16*sample->crypt_byte_block);
8649  data += 16*sample->crypt_byte_block;
8650  rem_bytes -= 16*sample->crypt_byte_block;
8651  data += FFMIN(16*sample->skip_byte_block, rem_bytes);
8652  rem_bytes -= FFMIN(16*sample->skip_byte_block, rem_bytes);
8653  }
8654  input += sample->subsamples[i].bytes_of_protected_data;
8655  size -= sample->subsamples[i].bytes_of_protected_data;
8656  }
8657 
8658  if (size > 0) {
8659  av_log(c->fc, AV_LOG_ERROR, "leftover packet bytes after subsample processing\n");
8660  return AVERROR_INVALIDDATA;
8661  }
8662 
8663  return 0;
8664 }
8665 
8667 {
8668  int i, ret, rem_bytes;
8669  uint8_t iv[16];
8670  uint8_t *data;
8671  uint8_t decryption_key[16];
8672 
8673  if (!sc->cenc.aes_ctx) {
8674  ret = get_key_from_kid(decryption_key, sizeof(decryption_key), c, sample);
8675  if (ret < 0) {
8676  return ret;
8677  }
8678 
8679  /* initialize the cipher */
8680  sc->cenc.aes_ctx = av_aes_alloc();
8681  if (!sc->cenc.aes_ctx) {
8682  return AVERROR(ENOMEM);
8683  }
8684 
8685  ret = av_aes_init(sc->cenc.aes_ctx, decryption_key, 16 * 8, 1);
8686  if (ret < 0) {
8687  return ret;
8688  }
8689  }
8690 
8691  /* whole-block full sample encryption */
8692  if (!sample->subsample_count) {
8693  /* decrypt the whole packet */
8694  memcpy(iv, sample->iv, 16);
8695  av_aes_crypt(sc->cenc.aes_ctx, input, input, size/16, iv, 1);
8696  return 0;
8697  } else if (!sample->crypt_byte_block && !sample->skip_byte_block) {
8698  av_log(c->fc, AV_LOG_ERROR, "pattern encryption is not present in 'cbcs' scheme\n");
8699  return AVERROR_INVALIDDATA;
8700  }
8701 
8702  for (i = 0; i < sample->subsample_count; i++) {
8703  if (sample->subsamples[i].bytes_of_clear_data + (int64_t)sample->subsamples[i].bytes_of_protected_data > size) {
8704  av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n");
8705  return AVERROR_INVALIDDATA;
8706  }
8707 
8708  /* skip the clear bytes */
8709  input += sample->subsamples[i].bytes_of_clear_data;
8710  size -= sample->subsamples[i].bytes_of_clear_data;
8711 
8712  /* decrypt the encrypted bytes */
8713  memcpy(iv, sample->iv, 16);
8714  data = input;
8715  rem_bytes = sample->subsamples[i].bytes_of_protected_data;
8716  while (rem_bytes > 0) {
8717  if (rem_bytes < 16*sample->crypt_byte_block) {
8718  break;
8719  }
8720  av_aes_crypt(sc->cenc.aes_ctx, data, data, sample->crypt_byte_block, iv, 1);
8721  data += 16*sample->crypt_byte_block;
8722  rem_bytes -= 16*sample->crypt_byte_block;
8723  data += FFMIN(16*sample->skip_byte_block, rem_bytes);
8724  rem_bytes -= FFMIN(16*sample->skip_byte_block, rem_bytes);
8725  }
8726  input += sample->subsamples[i].bytes_of_protected_data;
8727  size -= sample->subsamples[i].bytes_of_protected_data;
8728  }
8729 
8730  if (size > 0) {
8731  av_log(c->fc, AV_LOG_ERROR, "leftover packet bytes after subsample processing\n");
8732  return AVERROR_INVALIDDATA;
8733  }
8734 
8735  return 0;
8736 }
8737 
8739 {
8740  if (sample->scheme == MKBETAG('c','e','n','c') && !sample->crypt_byte_block && !sample->skip_byte_block) {
8741  return cenc_scheme_decrypt(c, sc, sample, input, size);
8742  } else if (sample->scheme == MKBETAG('c','b','c','1') && !sample->crypt_byte_block && !sample->skip_byte_block) {
8743  return cbc1_scheme_decrypt(c, sc, sample, input, size);
8744  } else if (sample->scheme == MKBETAG('c','e','n','s')) {
8745  return cens_scheme_decrypt(c, sc, sample, input, size);
8746  } else if (sample->scheme == MKBETAG('c','b','c','s')) {
8747  return cbcs_scheme_decrypt(c, sc, sample, input, size);
8748  } else {
8749  av_log(c->fc, AV_LOG_ERROR, "invalid encryption scheme\n");
8750  return AVERROR_INVALIDDATA;
8751  }
8752 }
8753 
8755 {
8756  int current = frag_index->current;
8757 
8758  if (!frag_index->nb_items)
8759  return NULL;
8760 
8761  // Check frag_index->current is the right one for pkt. It can out of sync.
8762  if (current >= 0 && current < frag_index->nb_items) {
8763  if (frag_index->item[current].moof_offset < pkt->pos &&
8764  (current + 1 == frag_index->nb_items ||
8765  frag_index->item[current + 1].moof_offset > pkt->pos))
8766  return get_frag_stream_info(frag_index, current, id);
8767  }
8768 
8769 
8770  for (int i = 0; i < frag_index->nb_items; i++) {
8771  if (frag_index->item[i].moof_offset > pkt->pos)
8772  break;
8773  current = i;
8774  }
8775  frag_index->current = current;
8776  return get_frag_stream_info(frag_index, current, id);
8777 }
8778 
8779 static int cenc_filter(MOVContext *mov, AVStream* st, MOVStreamContext *sc, AVPacket *pkt, int current_index)
8780 {
8781  MOVFragmentStreamInfo *frag_stream_info;
8782  MOVEncryptionIndex *encryption_index;
8783  AVEncryptionInfo *encrypted_sample;
8784  int encrypted_index, ret;
8785 
8786  frag_stream_info = get_frag_stream_info_from_pkt(&mov->frag_index, pkt, sc->id);
8787  encrypted_index = current_index;
8788  encryption_index = NULL;
8789  if (frag_stream_info) {
8790  // Note this only supports encryption info in the first sample descriptor.
8791  if (frag_stream_info->stsd_id == 1) {
8792  if (frag_stream_info->encryption_index) {
8793  encrypted_index = current_index - frag_stream_info->index_base;
8794  encryption_index = frag_stream_info->encryption_index;
8795  } else {
8796  encryption_index = sc->cenc.encryption_index;
8797  }
8798  }
8799  } else {
8800  encryption_index = sc->cenc.encryption_index;
8801  }
8802 
8803  if (encryption_index) {
8804  if (encryption_index->auxiliary_info_sample_count &&
8805  !encryption_index->nb_encrypted_samples) {
8806  av_log(mov->fc, AV_LOG_ERROR, "saiz atom found without saio\n");
8807  return AVERROR_INVALIDDATA;
8808  }
8809  if (encryption_index->auxiliary_offsets_count &&
8810  !encryption_index->nb_encrypted_samples) {
8811  av_log(mov->fc, AV_LOG_ERROR, "saio atom found without saiz\n");
8812  return AVERROR_INVALIDDATA;
8813  }
8814 
8815  encrypted_sample = NULL;
8816  if (!encryption_index->nb_encrypted_samples) {
8817  // Full-sample encryption with default settings.
8818  encrypted_sample = sc->cenc.default_encrypted_sample;
8819  } else if (encrypted_index >= 0 && encrypted_index < encryption_index->nb_encrypted_samples) {
8820  // Per-sample setting override.
8821  encrypted_sample = encryption_index->encrypted_samples[encrypted_index];
8822  if (!encrypted_sample) {
8823  encrypted_sample = sc->cenc.default_encrypted_sample;
8824  }
8825  }
8826 
8827  if (!encrypted_sample) {
8828  av_log(mov->fc, AV_LOG_ERROR, "Incorrect number of samples in encryption info\n");
8829  return AVERROR_INVALIDDATA;
8830  }
8831 
8832  if (mov->decryption_keys || mov->decryption_default_key) {
8833  return cenc_decrypt(mov, sc, encrypted_sample, pkt->data, pkt->size);
8834  } else {
8835  size_t size;
8836  uint8_t *side_data = av_encryption_info_add_side_data(encrypted_sample, &size);
8837  if (!side_data)
8838  return AVERROR(ENOMEM);
8840  if (ret < 0)
8841  av_free(side_data);
8842  return ret;
8843  }
8844  }
8845 
8846  return 0;
8847 }
8848 
8850 {
8851  const int OPUS_SEEK_PREROLL_MS = 80;
8852  int ret;
8853  AVStream *st;
8854  size_t size;
8855  uint16_t pre_skip;
8856 
8857  if (c->fc->nb_streams < 1)
8858  return 0;
8859  st = c->fc->streams[c->fc->nb_streams-1];
8860 
8861  if ((uint64_t)atom.size > (1<<30) || atom.size < 11 || st->codecpar->extradata)
8862  return AVERROR_INVALIDDATA;
8863 
8864  /* Check OpusSpecificBox version. */
8865  if (avio_r8(pb) != 0) {
8866  av_log(c->fc, AV_LOG_ERROR, "unsupported OpusSpecificBox version\n");
8867  return AVERROR_INVALIDDATA;
8868  }
8869 
8870  /* OpusSpecificBox size plus magic for Ogg OpusHead header. */
8871  size = atom.size + 8;
8872 
8873  if ((ret = ff_alloc_extradata(st->codecpar, size)) < 0)
8874  return ret;
8875 
8876  AV_WL32A(st->codecpar->extradata, MKTAG('O','p','u','s'));
8877  AV_WL32A(st->codecpar->extradata + 4, MKTAG('H','e','a','d'));
8878  AV_WB8(st->codecpar->extradata + 8, 1); /* OpusHead version */
8879  if ((ret = ffio_read_size(pb, st->codecpar->extradata + 9, size - 9)) < 0) {
8880  av_freep(&st->codecpar->extradata);
8881  st->codecpar->extradata_size = 0;
8882  return ret;
8883  }
8884 
8885  /* OpusSpecificBox is stored in big-endian, but OpusHead is
8886  little-endian; aside from the preceding magic and version they're
8887  otherwise currently identical. Data after output gain at offset 16
8888  doesn't need to be bytewapped. */
8889  pre_skip = AV_RB16A(st->codecpar->extradata + 10);
8890  AV_WL16A(st->codecpar->extradata + 10, pre_skip);
8891  AV_WL32A(st->codecpar->extradata + 12, AV_RB32A(st->codecpar->extradata + 12));
8892  AV_WL16A(st->codecpar->extradata + 16, AV_RB16A(st->codecpar->extradata + 16));
8893 
8894  st->codecpar->initial_padding = pre_skip;
8896  (AVRational){1, 1000},
8897  (AVRational){1, 48000});
8898 
8899  return 0;
8900 }
8901 
8903 {
8904  AVStream *st;
8905  unsigned format_info;
8906  int channel_assignment, channel_assignment1, channel_assignment2;
8907  int ratebits;
8908  uint64_t chmask;
8909 
8910  if (c->fc->nb_streams < 1)
8911  return 0;
8912  st = c->fc->streams[c->fc->nb_streams-1];
8913 
8914  if (atom.size < 10)
8915  return AVERROR_INVALIDDATA;
8916 
8917  format_info = avio_rb32(pb);
8918 
8919  ratebits = (format_info >> 28) & 0xF;
8920  channel_assignment1 = (format_info >> 15) & 0x1F;
8921  channel_assignment2 = format_info & 0x1FFF;
8922  if (channel_assignment2)
8923  channel_assignment = channel_assignment2;
8924  else
8925  channel_assignment = channel_assignment1;
8926 
8927  st->codecpar->frame_size = 40 << (ratebits & 0x7);
8928  st->codecpar->sample_rate = mlp_samplerate(ratebits);
8929 
8931  chmask = truehd_layout(channel_assignment);
8933 
8934  return 0;
8935 }
8936 
8938 {
8939  AVStream *st;
8940  uint8_t buf[ISOM_DVCC_DVVC_SIZE];
8941  int ret;
8942  int64_t read_size = atom.size;
8943 
8944  if (c->fc->nb_streams < 1)
8945  return 0;
8946  st = c->fc->streams[c->fc->nb_streams-1];
8947 
8948  // At most 24 bytes
8949  read_size = FFMIN(read_size, ISOM_DVCC_DVVC_SIZE);
8950 
8951  if ((ret = ffio_read_size(pb, buf, read_size)) < 0)
8952  return ret;
8953 
8954  return ff_isom_parse_dvcc_dvvc(c->fc, st, buf, read_size);
8955 }
8956 
8958 {
8959  AVStream *st;
8960  AVPacketSideData *sd;
8961  int ret;
8962 
8963  if (c->fc->nb_streams < 1)
8964  return 0;
8965  st = c->fc->streams[c->fc->nb_streams - 1];
8966 
8967  if (atom.size < 23 || atom.size > INT_MAX - AV_INPUT_BUFFER_PADDING_SIZE)
8968  return AVERROR_INVALIDDATA;
8969 
8973  atom.size, 0);
8974  if (!sd)
8975  return AVERROR(ENOMEM);
8976 
8977  ret = ffio_read_size(pb, sd->data, atom.size);
8978  if (ret < 0)
8979  return ret;
8980 
8981  return 0;
8982 }
8983 
8985 {
8986  AVStream *st;
8987  uint8_t *buf;
8988  int ret, old_size, num_arrays;
8989 
8990  if (c->fc->nb_streams < 1)
8991  return 0;
8992  st = c->fc->streams[c->fc->nb_streams-1];
8993 
8994  if (!st->codecpar->extradata_size)
8995  // TODO: handle lhvC when present before hvcC
8996  return 0;
8997 
8998  if (atom.size < 6 || st->codecpar->extradata_size < 23 ||
8999  atom.size > INT_MAX - AV_INPUT_BUFFER_PADDING_SIZE) {
9000  return AVERROR_INVALIDDATA;
9001  }
9002 
9004  if (!buf)
9005  return AVERROR(ENOMEM);
9006  memset(buf + atom.size, 0, AV_INPUT_BUFFER_PADDING_SIZE);
9007 
9008  ret = ffio_read_size(pb, buf, atom.size);
9009  if (ret < 0) {
9010  av_free(buf);
9011  av_log(c->fc, AV_LOG_WARNING, "lhvC atom truncated\n");
9012  return 0;
9013  }
9014 
9015  num_arrays = buf[5];
9016  old_size = st->codecpar->extradata_size;
9017  atom.size -= 8 /* account for mov_realloc_extradata offsetting */
9018  + 6 /* lhvC bytes before the arrays*/;
9019 
9020  ret = mov_realloc_extradata(st->codecpar, atom);
9021  if (ret < 0) {
9022  av_free(buf);
9023  return ret;
9024  }
9025 
9026  st->codecpar->extradata[22] += num_arrays;
9027  memcpy(st->codecpar->extradata + old_size, buf + 6, atom.size + 8);
9028 
9030 
9031  av_free(buf);
9032  return 0;
9033 }
9034 
9036 {
9037  AVFormatContext *ctx = c->fc;
9038  AVStream *st = NULL;
9039  AVBPrint scheme_buf, value_buf;
9040  int64_t scheme_str_len = 0, value_str_len = 0;
9041  int version, flags, ret = AVERROR_BUG;
9042  int64_t size = atom.size;
9043 
9044  if (atom.size < 6)
9045  // 4 bytes for version + flags, 2x 1 byte for null
9046  return AVERROR_INVALIDDATA;
9047 
9048  if (c->fc->nb_streams < 1)
9049  return 0;
9050  st = c->fc->streams[c->fc->nb_streams-1];
9051 
9052  version = avio_r8(pb);
9053  flags = avio_rb24(pb);
9054  size -= 4;
9055 
9056  if (version != 0 || flags != 0) {
9058  "Unsupported 'kind' box with version %d, flags: %x",
9059  version, flags);
9060  return AVERROR_INVALIDDATA;
9061  }
9062 
9063  av_bprint_init(&scheme_buf, 0, AV_BPRINT_SIZE_UNLIMITED);
9064  av_bprint_init(&value_buf, 0, AV_BPRINT_SIZE_UNLIMITED);
9065 
9066  if ((scheme_str_len = ff_read_string_to_bprint_overwrite(pb, &scheme_buf,
9067  size)) < 0) {
9068  ret = scheme_str_len;
9069  goto cleanup;
9070  }
9071 
9072  if (scheme_str_len + 1 >= size) {
9073  // we need to have another string, even if nullptr.
9074  // we check with + 1 since we expect that if size was not hit,
9075  // an additional null was read.
9077  goto cleanup;
9078  }
9079 
9080  size -= scheme_str_len + 1;
9081 
9082  if ((value_str_len = ff_read_string_to_bprint_overwrite(pb, &value_buf,
9083  size)) < 0) {
9084  ret = value_str_len;
9085  goto cleanup;
9086  }
9087 
9088  if (value_str_len == size) {
9089  // in case of no trailing null, box is not valid.
9091  goto cleanup;
9092  }
9093 
9095  "%s stream %d KindBox(scheme: %s, value: %s)\n",
9097  st->index,
9098  scheme_buf.str, value_buf.str);
9099 
9100  for (int i = 0; ff_mov_track_kind_table[i].scheme_uri; i++) {
9102  if (!av_strstart(scheme_buf.str, map.scheme_uri, NULL))
9103  continue;
9104 
9105  for (int j = 0; map.value_maps[j].disposition; j++) {
9106  const struct MP4TrackKindValueMapping value_map = map.value_maps[j];
9107  if (!av_strstart(value_buf.str, value_map.value, NULL))
9108  continue;
9109 
9110  st->disposition |= value_map.disposition;
9111  }
9112  }
9113 
9114  ret = 0;
9115 
9116 cleanup:
9117 
9118  av_bprint_finalize(&scheme_buf, NULL);
9119  av_bprint_finalize(&value_buf, NULL);
9120 
9121  return ret;
9122 }
9123 
9125 {
9126  AVStream *st;
9127  AVChannelLayout ch_layout = { 0 };
9128  int ret, i, version, type;
9129  int ambisonic_order, channel_order, normalization, channel_count;
9130  int ambi_channels, non_diegetic_channels;
9131 
9132  if (c->fc->nb_streams < 1)
9133  return 0;
9134 
9135  st = c->fc->streams[c->fc->nb_streams - 1];
9136 
9137  if (atom.size < 16) {
9138  av_log(c->fc, AV_LOG_ERROR, "SA3D audio box too small\n");
9139  return AVERROR_INVALIDDATA;
9140  }
9141 
9142  version = avio_r8(pb);
9143  if (version) {
9144  av_log(c->fc, AV_LOG_WARNING, "Unsupported SA3D box version %d\n", version);
9145  return 0;
9146  }
9147 
9148  type = avio_r8(pb);
9149  if (type & 0x7f) {
9150  av_log(c->fc, AV_LOG_WARNING,
9151  "Unsupported ambisonic type %d\n", type & 0x7f);
9152  return 0;
9153  }
9154  non_diegetic_channels = (type >> 7) * 2; // head_locked_stereo
9155 
9156  ambisonic_order = avio_rb32(pb);
9157 
9158  channel_order = avio_r8(pb);
9159  if (channel_order) {
9160  av_log(c->fc, AV_LOG_WARNING,
9161  "Unsupported channel_order %d\n", channel_order);
9162  return 0;
9163  }
9164 
9165  normalization = avio_r8(pb);
9166  if (normalization) {
9167  av_log(c->fc, AV_LOG_WARNING,
9168  "Unsupported normalization %d\n", normalization);
9169  return 0;
9170  }
9171 
9172  channel_count = avio_rb32(pb);
9173  if (ambisonic_order < 0 || ambisonic_order > 31 ||
9174  channel_count != ((ambisonic_order + 1LL) * (ambisonic_order + 1LL) +
9175  non_diegetic_channels)) {
9176  av_log(c->fc, AV_LOG_ERROR,
9177  "Invalid number of channels (%d / %d)\n",
9178  channel_count, ambisonic_order);
9179  return 0;
9180  }
9181  ambi_channels = channel_count - non_diegetic_channels;
9182 
9183  ret = av_channel_layout_custom_init(&ch_layout, channel_count);
9184  if (ret < 0)
9185  return 0;
9186 
9187  for (i = 0; i < channel_count; i++) {
9188  unsigned channel = avio_rb32(pb);
9189 
9190  if (channel >= channel_count) {
9191  av_log(c->fc, AV_LOG_ERROR, "Invalid channel index (%d / %d)\n",
9192  channel, ambisonic_order);
9193  av_channel_layout_uninit(&ch_layout);
9194  return 0;
9195  }
9196  if (channel >= ambi_channels)
9197  ch_layout.u.map[i].id = channel - ambi_channels;
9198  else
9199  ch_layout.u.map[i].id = AV_CHAN_AMBISONIC_BASE + channel;
9200  }
9201 
9203  if (ret < 0) {
9204  av_channel_layout_uninit(&ch_layout);
9205  return 0;
9206  }
9207 
9209  st->codecpar->ch_layout = ch_layout;
9210 
9211  return 0;
9212 }
9213 
9215 {
9216  AVStream *st;
9217  int version;
9218 
9219  if (c->fc->nb_streams < 1)
9220  return 0;
9221 
9222  st = c->fc->streams[c->fc->nb_streams - 1];
9223 
9224  if (atom.size < 5) {
9225  av_log(c->fc, AV_LOG_ERROR, "Empty SAND audio box\n");
9226  return AVERROR_INVALIDDATA;
9227  }
9228 
9229  version = avio_r8(pb);
9230  if (version) {
9231  av_log(c->fc, AV_LOG_WARNING, "Unsupported SAND box version %d\n", version);
9232  return 0;
9233  }
9234 
9236 
9237  return 0;
9238 }
9239 
9240 static int rb_size(AVIOContext *pb, int64_t *value, int size)
9241 {
9242  if (size == 0)
9243  *value = 0;
9244  else if (size == 1)
9245  *value = avio_r8(pb);
9246  else if (size == 2)
9247  *value = avio_rb16(pb);
9248  else if (size == 4)
9249  *value = avio_rb32(pb);
9250  else if (size == 8) {
9251  *value = avio_rb64(pb);
9252  if (*value < 0)
9253  return -1;
9254  } else
9255  return -1;
9256  return size;
9257 }
9258 
9260 {
9261  avio_rb32(pb); // version & flags.
9262  c->primary_item_id = avio_rb16(pb);
9263  av_log(c->fc, AV_LOG_TRACE, "pitm: primary_item_id %d\n", c->primary_item_id);
9264  return atom.size;
9265 }
9266 
9268 {
9269  c->idat_offset = avio_tell(pb);
9270  return 0;
9271 }
9272 
9274 {
9275  HEIFItem **heif_item;
9276  int version, offset_size, length_size, base_offset_size, index_size;
9277  int item_count, extent_count;
9278  int64_t base_offset, extent_offset, extent_length;
9279  uint8_t value;
9280 
9281  if (c->found_iloc) {
9282  av_log(c->fc, AV_LOG_INFO, "Duplicate iloc box found\n");
9283  return 0;
9284  }
9285 
9286  version = avio_r8(pb);
9287  avio_rb24(pb); // flags.
9288 
9289  value = avio_r8(pb);
9290  offset_size = (value >> 4) & 0xF;
9291  length_size = value & 0xF;
9292  value = avio_r8(pb);
9293  base_offset_size = (value >> 4) & 0xF;
9294  index_size = !version ? 0 : (value & 0xF);
9295  if (index_size) {
9296  avpriv_report_missing_feature(c->fc, "iloc: index_size != 0");
9297  return AVERROR_PATCHWELCOME;
9298  }
9299  item_count = (version < 2) ? avio_rb16(pb) : avio_rb32(pb);
9300 
9301  heif_item = av_realloc_array(c->heif_item, FFMAX(item_count, c->nb_heif_item), sizeof(*c->heif_item));
9302  if (!heif_item)
9303  return AVERROR(ENOMEM);
9304  c->heif_item = heif_item;
9305  if (item_count > c->nb_heif_item)
9306  memset(&c->heif_item[c->nb_heif_item], 0,
9307  sizeof(*c->heif_item) * (item_count - c->nb_heif_item));
9308  c->nb_heif_item = FFMAX(c->nb_heif_item, item_count);
9309 
9310  av_log(c->fc, AV_LOG_TRACE, "iloc: item_count %d\n", item_count);
9311  for (int i = 0; i < item_count; i++) {
9312  HEIFItem *item = NULL;
9313  int item_id = (version < 2) ? avio_rb16(pb) : avio_rb32(pb);
9314  int offset_type = (version > 0) ? avio_rb16(pb) & 0xf : 0;
9315  int j;
9316 
9317  if (avio_feof(pb))
9318  return AVERROR_INVALIDDATA;
9319  if (offset_type > 1) {
9320  avpriv_report_missing_feature(c->fc, "iloc offset type %d", offset_type);
9321  return AVERROR_PATCHWELCOME;
9322  }
9323 
9324  avio_rb16(pb); // data_reference_index.
9325  if (rb_size(pb, &base_offset, base_offset_size) < 0)
9326  return AVERROR_INVALIDDATA;
9327  extent_count = avio_rb16(pb);
9328  if (extent_count > 1) {
9329  // For still AVIF images, we only support one extent item.
9330  avpriv_report_missing_feature(c->fc, "iloc: extent_count > 1");
9331  return AVERROR_PATCHWELCOME;
9332  }
9333 
9334  if (rb_size(pb, &extent_offset, offset_size) < 0 ||
9335  rb_size(pb, &extent_length, length_size) < 0 ||
9336  base_offset > INT64_MAX - extent_offset)
9337  return AVERROR_INVALIDDATA;
9338 
9339  for (j = 0; j < c->nb_heif_item; j++) {
9340  item = c->heif_item[j];
9341  if (!item)
9342  item = c->heif_item[j] = av_mallocz(sizeof(*item));
9343  else if (item->item_id != item_id)
9344  continue;
9345  break;
9346  }
9347  if (!item)
9348  return AVERROR(ENOMEM);
9349  if (j == c->nb_heif_item)
9350  return AVERROR_INVALIDDATA;
9351 
9352  item->item_id = item_id;
9353 
9354  if (offset_type == 1)
9355  item->is_idat_relative = 1;
9356  item->extent_length = extent_length;
9357  item->extent_offset = base_offset + extent_offset;
9358  av_log(c->fc, AV_LOG_TRACE, "iloc: item_idx %d, item->item_id %d, offset_type %d, "
9359  "extent_offset %"PRId64", extent_length %"PRId64"\n",
9360  i, item->item_id, offset_type, item->extent_offset, item->extent_length);
9361  }
9362 
9363  c->found_iloc = 1;
9364  return atom.size;
9365 }
9366 
9368 {
9369  HEIFItem *item = NULL;
9370  AVBPrint item_name;
9371  int64_t size = atom.size;
9372  uint32_t item_type;
9373  int item_id;
9374  int i, version, ret;
9375 
9376  version = avio_r8(pb);
9377  avio_rb24(pb); // flags.
9378  size -= 4;
9379  if (size < 0)
9380  return AVERROR_INVALIDDATA;
9381 
9382  if (version < 2) {
9383  avpriv_report_missing_feature(c->fc, "infe version < 2");
9384  avio_skip(pb, size);
9385  return 1;
9386  }
9387 
9388  item_id = version > 2 ? avio_rb32(pb) : avio_rb16(pb);
9389  avio_rb16(pb); // item_protection_index
9390  item_type = avio_rl32(pb);
9391  size -= 8;
9392  if (size < 1)
9393  return AVERROR_INVALIDDATA;
9394 
9397  if (ret < 0) {
9399  return ret;
9400  }
9401 
9402  av_log(c->fc, AV_LOG_TRACE, "infe: item_id %d, item_type %s, item_name %s\n",
9403  item_id, av_fourcc2str(item_type), item_name.str);
9404 
9405  size -= ret + 1;
9406  if (size > 0)
9407  avio_skip(pb, size);
9408 
9409  for (i = 0; i < c->nb_heif_item; i++) {
9410  item = c->heif_item[i];
9411  if (!item)
9412  item = c->heif_item[i] = av_mallocz(sizeof(*item));
9413  else if (item->item_id != item_id)
9414  continue;
9415  break;
9416  }
9417  if (!item) {
9419  return AVERROR(ENOMEM);
9420  }
9421  if (i == c->nb_heif_item) {
9423  return AVERROR_INVALIDDATA;
9424  }
9425 
9426  av_freep(&item->name);
9427  av_bprint_finalize(&item_name, ret ? &item->name : NULL);
9428  item->item_id = item_id;
9429  item->type = item_type;
9430 
9431  switch (item_type) {
9432  case MKTAG('a','v','0','1'):
9433  case MKTAG('j','p','e','g'):
9434  case MKTAG('h','v','c','1'):
9435  ret = heif_add_stream(c, item);
9436  if (ret < 0)
9437  return ret;
9438  break;
9439  }
9440 
9441  return 0;
9442 }
9443 
9445 {
9446  HEIFItem **heif_item;
9447  int entry_count;
9448  int version, got_stream = 0, ret, i;
9449 
9450  if (c->found_iinf) {
9451  av_log(c->fc, AV_LOG_WARNING, "Duplicate iinf box found\n");
9452  return 0;
9453  }
9454 
9455  version = avio_r8(pb);
9456  avio_rb24(pb); // flags.
9457  entry_count = version ? avio_rb32(pb) : avio_rb16(pb);
9458 
9459  heif_item = av_realloc_array(c->heif_item, FFMAX(entry_count, c->nb_heif_item), sizeof(*c->heif_item));
9460  if (!heif_item)
9461  return AVERROR(ENOMEM);
9462  c->heif_item = heif_item;
9463  if (entry_count > c->nb_heif_item)
9464  memset(&c->heif_item[c->nb_heif_item], 0,
9465  sizeof(*c->heif_item) * (entry_count - c->nb_heif_item));
9466  c->nb_heif_item = FFMAX(c->nb_heif_item, entry_count);
9467 
9468  for (i = 0; i < entry_count; i++) {
9469  MOVAtom infe;
9470 
9471  infe.size = avio_rb32(pb) - 8;
9472  infe.type = avio_rl32(pb);
9473  if (avio_feof(pb)) {
9475  goto fail;
9476  }
9477  ret = mov_read_infe(c, pb, infe);
9478  if (ret < 0)
9479  goto fail;
9480  if (!ret)
9481  got_stream = 1;
9482  }
9483 
9484  c->found_iinf = got_stream;
9485  return 0;
9486 fail:
9487  for (; i >= 0; i--) {
9488  HEIFItem *item = c->heif_item[i];
9489 
9490  if (!item)
9491  continue;
9492 
9493  av_freep(&item->name);
9494  }
9495  return ret;
9496 }
9497 
9499 {
9500  HEIFItem *item = NULL;
9501  HEIFGrid *grid;
9502  int entries, i;
9503  int from_item_id = version ? avio_rb32(pb) : avio_rb16(pb);
9504  int ret = 0;
9505 
9506  for (int i = 0; i < c->nb_heif_grid; i++) {
9507  if (c->heif_grid[i].item->item_id == from_item_id) {
9508  av_log(c->fc, AV_LOG_ERROR, "More than one 'dimg' box "
9509  "referencing the same Derived Image item\n");
9510  return AVERROR_INVALIDDATA;
9511  }
9512  }
9513  for (int i = 0; i < c->nb_heif_item; i++) {
9514  if (!c->heif_item[i] || c->heif_item[i]->item_id != from_item_id)
9515  continue;
9516  item = c->heif_item[i];
9517 
9518  switch (item->type) {
9519  case MKTAG('g','r','i','d'):
9520  case MKTAG('i','o','v','l'):
9521  break;
9522  default:
9523  avpriv_report_missing_feature(c->fc, "Derived Image item of type %s",
9524  av_fourcc2str(item->type));
9525  return 0;
9526  }
9527  break;
9528  }
9529  if (!item) {
9530  av_log(c->fc, AV_LOG_ERROR, "Missing grid information\n");
9531  return AVERROR_INVALIDDATA;
9532  }
9533 
9534  entries = avio_rb16(pb);
9535  if (!entries) {
9536  av_log(c->fc, AV_LOG_ERROR,
9537  "Derived image item references no input images\n");
9538  return AVERROR_INVALIDDATA;
9539  }
9540 
9541  grid = av_realloc_array(c->heif_grid, c->nb_heif_grid + 1U,
9542  sizeof(*c->heif_grid));
9543  if (!grid)
9544  return AVERROR(ENOMEM);
9545  c->heif_grid = grid;
9546  grid = &grid[c->nb_heif_grid];
9547 
9548  grid->tile_id_list = av_malloc_array(entries, sizeof(*grid->tile_id_list));
9549  grid->tile_idx_list = av_calloc(entries, sizeof(*grid->tile_idx_list));
9550  grid->tile_item_list = av_calloc(entries, sizeof(*grid->tile_item_list));
9551  if (!grid->tile_id_list || !grid->tile_item_list || !grid->tile_idx_list) {
9552  ret = AVERROR(ENOMEM);
9553  goto fail;
9554  }
9555  /* 'to' item ids */
9556  for (i = 0; i < entries; i++) {
9557  grid->tile_id_list[i] = version ? avio_rb32(pb) : avio_rb16(pb);
9558 
9559  if (avio_feof(pb)) {
9561  goto fail;
9562  }
9563  }
9564 
9565  grid->nb_tiles = entries;
9566  grid->item = item;
9567  ++c->nb_heif_grid;
9568 
9569  av_log(c->fc, AV_LOG_TRACE, "dimg: from_item_id %d, entries %d\n",
9570  from_item_id, entries);
9571 
9572  return 0;
9573 fail:
9574  av_freep(&grid->tile_id_list);
9575  av_freep(&grid->tile_idx_list);
9576  av_freep(&grid->tile_item_list);
9577 
9578  return ret;
9579 }
9580 
9581 static int mov_read_iref_cdsc(MOVContext *c, AVIOContext *pb, uint32_t type, int version, uint32_t size)
9582 {
9583  HEIFItem *from_item = NULL;
9584  int entries;
9585  int item_id_size = version ? 4 : 2;
9586  int from_item_id = version ? avio_rb32(pb) : avio_rb16(pb);
9587  const HEIFItemRef ref = { type, from_item_id };
9588 
9589  from_item = get_heif_item(c, from_item_id);
9590  if (!from_item) {
9591  av_log(c->fc, AV_LOG_ERROR, "Missing stream referenced by thmb item\n");
9592  return AVERROR_INVALIDDATA;
9593  }
9594 
9595  entries = avio_rb16(pb);
9596  if ((int64_t)entries * item_id_size > (int64_t)size - item_id_size - 2) {
9597  av_log(c->fc, AV_LOG_ERROR, "iref %s entry count %d exceeds the sub-box size\n",
9598  av_fourcc2str(type), entries);
9599  return AVERROR_INVALIDDATA;
9600  }
9601  /* 'to' item ids */
9602  for (int i = 0; i < entries; i++) {
9603  HEIFItem *item = get_heif_item(c, version ? avio_rb32(pb) : avio_rb16(pb));
9604 
9605  if (avio_feof(pb))
9606  return AVERROR_INVALIDDATA;
9607 
9608  if (!item) {
9609  av_log(c->fc, AV_LOG_WARNING, "Missing stream referenced by %s item\n",
9610  av_fourcc2str(type));
9611  continue;
9612  }
9613 
9614  if (!av_dynarray2_add((void **)&item->iref_list, &item->nb_iref_list,
9615  sizeof(*item->iref_list), (const uint8_t *)&ref))
9616  return AVERROR(ENOMEM);
9617  }
9618 
9619  av_log(c->fc, AV_LOG_TRACE, "%s: from_item_id %d, entries %d\n",
9620  av_fourcc2str(type), from_item_id, entries);
9621 
9622  return 0;
9623 }
9624 
9626 {
9627  int version = avio_r8(pb);
9628  int ret;
9629 
9630  avio_rb24(pb); // flags
9631  atom.size -= 4;
9632 
9633  if (version > 1) {
9634  av_log(c->fc, AV_LOG_WARNING, "Unknown iref box version %d\n", version);
9635  return 0;
9636  }
9637 
9638  while (atom.size) {
9639  int64_t next = avio_tell(pb);
9640  uint32_t type, size = avio_rb32(pb);
9641 
9642  if (size < 14 || size > atom.size || next > INT64_MAX - size)
9643  return AVERROR_INVALIDDATA;
9644 
9645  next += size;
9646  type = avio_rl32(pb);
9647  switch (type) {
9648  case MKTAG('d','i','m','g'):
9649  ret = mov_read_iref_dimg(c, pb, version);
9650  if (ret < 0)
9651  return ret;
9652  break;
9653  case MKTAG('c','d','s','c'):
9654  case MKTAG('t','h','m','b'):
9655  ret = mov_read_iref_cdsc(c, pb, type, version, size - 8);
9656  if (ret < 0)
9657  return ret;
9658  break;
9659  default:
9660  av_log(c->fc, AV_LOG_DEBUG, "Unknown iref type %s size %"PRIu32"\n",
9661  av_fourcc2str(type), size);
9662  }
9663 
9664  atom.size -= size;
9665  avio_seek(pb, next, SEEK_SET);
9666  }
9667  return 0;
9668 }
9669 
9671 {
9672  HEIFItem *item;
9673  uint32_t width, height;
9674 
9675  avio_r8(pb); /* version */
9676  avio_rb24(pb); /* flags */
9677  width = avio_rb32(pb);
9678  height = avio_rb32(pb);
9679 
9680  av_log(c->fc, AV_LOG_TRACE, "ispe: item_id %d, width %"PRIu32", height %"PRIu32"\n",
9681  c->cur_item_id, width, height);
9682 
9683  if (!width || !height || width > INT_MAX || height > INT_MAX) {
9684  av_log(c->fc, AV_LOG_ERROR, "Invalid ispe dimensions %"PRIu32"x%"PRIu32"\n",
9685  width, height);
9686  return AVERROR_INVALIDDATA;
9687  }
9688 
9689  item = get_heif_item(c, c->cur_item_id);
9690  if (item) {
9691  item->width = width;
9692  item->height = height;
9693  }
9694 
9695  return 0;
9696 }
9697 
9699 {
9700  HEIFItem *item;
9701  int angle;
9702 
9703  angle = avio_r8(pb) & 0x3;
9704 
9705  av_log(c->fc, AV_LOG_TRACE, "irot: item_id %d, angle %u\n",
9706  c->cur_item_id, angle);
9707 
9708  item = get_heif_item(c, c->cur_item_id);
9709  if (item) {
9710  // angle * 90 specifies the angle (in anti-clockwise direction)
9711  // in units of degrees.
9712  item->rotation = angle * 90;
9713  }
9714 
9715  return 0;
9716 }
9717 
9719 {
9720  HEIFItem *item;
9721  int axis;
9722 
9723  axis = avio_r8(pb) & 0x1;
9724 
9725  av_log(c->fc, AV_LOG_TRACE, "imir: item_id %d, axis %u\n",
9726  c->cur_item_id, axis);
9727 
9728  item = get_heif_item(c, c->cur_item_id);
9729  if (item) {
9730  item->hflip = axis;
9731  item->vflip = !axis;
9732  }
9733 
9734  return 0;
9735 }
9736 
9738 {
9739  typedef struct MOVAtoms {
9740  FFIOContext b;
9741  uint32_t type;
9742  int64_t size;
9743  uint8_t *data;
9744  } MOVAtoms;
9745  MOVAtoms *atoms = NULL;
9746  MOVAtom a;
9747  unsigned count;
9748  int nb_atoms = 0;
9749  int version, flags;
9750  int ret;
9751 
9752  a.size = avio_rb32(pb);
9753  a.type = avio_rl32(pb);
9754 
9755  if (a.size < 8 || a.type != MKTAG('i','p','c','o'))
9756  return AVERROR_INVALIDDATA;
9757 
9758  a.size -= 8;
9759  while (a.size >= 8) {
9760  MOVAtoms *ref = av_dynarray2_add((void**)&atoms, &nb_atoms, sizeof(MOVAtoms), NULL);
9761  if (!ref) {
9762  ret = AVERROR(ENOMEM);
9763  goto fail;
9764  }
9765  ref->data = NULL;
9766  ref->size = avio_rb32(pb);
9767  ref->type = avio_rl32(pb);
9768  if (ref->size > a.size || ref->size < 8)
9769  break;
9770  ref->data = av_malloc(ref->size);
9771  if (!ref->data) {
9773  goto fail;
9774  }
9775  av_log(c->fc, AV_LOG_TRACE, "ipco: index %d, box type %s\n", nb_atoms, av_fourcc2str(ref->type));
9776  avio_seek(pb, -8, SEEK_CUR);
9777  if (avio_read(pb, ref->data, ref->size) != ref->size) {
9779  goto fail;
9780  }
9781  ffio_init_read_context(&ref->b, ref->data, ref->size);
9782  a.size -= ref->size;
9783  }
9784 
9785  if (a.size) {
9787  goto fail;
9788  }
9789 
9790  a.size = avio_rb32(pb);
9791  a.type = avio_rl32(pb);
9792 
9793  if (a.size < 8 || a.type != MKTAG('i','p','m','a')) {
9795  goto fail;
9796  }
9797 
9798  version = avio_r8(pb);
9799  flags = avio_rb24(pb);
9800  count = avio_rb32(pb);
9801 
9802  for (int i = 0; i < count; i++) {
9803  int item_id = version ? avio_rb32(pb) : avio_rb16(pb);
9804  int assoc_count = avio_r8(pb);
9805 
9806  if (avio_feof(pb)) {
9808  goto fail;
9809  }
9810 
9811  for (int j = 0; j < assoc_count; j++) {
9812  MOVAtoms *ref;
9813  int index = avio_r8(pb) & 0x7f;
9814  if (flags & 1) {
9815  index <<= 8;
9816  index |= avio_r8(pb);
9817  }
9818  if (index > nb_atoms || index <= 0) {
9820  goto fail;
9821  }
9822  ref = &atoms[--index];
9823 
9824  av_log(c->fc, AV_LOG_TRACE, "ipma: property_index %d, item_id %d, item_type %s\n",
9825  index + 1, item_id, av_fourcc2str(ref->type));
9826 
9827  c->cur_item_id = item_id;
9828 
9829  ret = mov_read_default(c, &ref->b.pub,
9830  (MOVAtom) { .size = ref->size,
9831  .type = MKTAG('i','p','c','o') });
9832  if (ret < 0)
9833  goto fail;
9834  ffio_init_read_context(&ref->b, ref->data, ref->size);
9835  }
9836  }
9837 
9838  ret = 0;
9839 fail:
9840  c->cur_item_id = -1;
9841  for (int i = 0; i < nb_atoms; i++)
9842  av_free(atoms[i].data);
9843  av_free(atoms);
9844 
9845  return ret;
9846 }
9847 
9849 { MKTAG('A','C','L','R'), mov_read_aclr },
9850 { MKTAG('A','P','R','G'), mov_read_avid },
9851 { MKTAG('A','A','L','P'), mov_read_avid },
9852 { MKTAG('A','R','E','S'), mov_read_ares },
9853 { MKTAG('a','v','s','s'), mov_read_avss },
9854 { MKTAG('a','v','1','C'), mov_read_glbl },
9855 { MKTAG('c','h','p','l'), mov_read_chpl },
9856 { MKTAG('c','o','6','4'), mov_read_stco },
9857 { MKTAG('c','o','l','r'), mov_read_colr },
9858 { MKTAG('c','t','t','s'), mov_read_ctts }, /* composition time to sample */
9859 { MKTAG('d','i','n','f'), mov_read_default },
9860 { MKTAG('D','p','x','E'), mov_read_dpxe },
9861 { MKTAG('d','r','e','f'), mov_read_dref },
9862 { MKTAG('e','d','t','s'), mov_read_default },
9863 { MKTAG('e','l','s','t'), mov_read_elst },
9864 { MKTAG('e','n','d','a'), mov_read_enda },
9865 { MKTAG('f','i','e','l'), mov_read_fiel },
9866 { MKTAG('a','d','r','m'), mov_read_adrm },
9867 { MKTAG('f','t','y','p'), mov_read_ftyp },
9868 { MKTAG('g','l','b','l'), mov_read_glbl },
9869 { MKTAG('h','d','l','r'), mov_read_hdlr },
9870 { MKTAG('i','l','s','t'), mov_read_ilst },
9871 { MKTAG('j','p','2','h'), mov_read_jp2h },
9872 { MKTAG('m','d','a','t'), mov_read_mdat },
9873 { MKTAG('m','d','h','d'), mov_read_mdhd },
9874 { MKTAG('m','d','i','a'), mov_read_default },
9875 { MKTAG('m','e','t','a'), mov_read_meta },
9876 { MKTAG('m','i','n','f'), mov_read_default },
9877 { MKTAG('m','o','o','f'), mov_read_moof },
9878 { MKTAG('m','o','o','v'), mov_read_moov },
9879 { MKTAG('m','v','e','x'), mov_read_default },
9880 { MKTAG('m','v','h','d'), mov_read_mvhd },
9881 { MKTAG('S','M','I',' '), mov_read_svq3 },
9882 { MKTAG('a','l','a','c'), mov_read_alac }, /* alac specific atom */
9883 { MKTAG('a','v','c','C'), mov_read_glbl },
9884 { MKTAG('p','a','s','p'), mov_read_pasp },
9885 { MKTAG('c','l','a','p'), mov_read_clap },
9886 { MKTAG('c','d','s','c'), mov_read_cdsc },
9887 { MKTAG('s','b','a','s'), mov_read_sbas },
9888 { MKTAG('v','d','e','p'), mov_read_vdep },
9889 { MKTAG('s','i','d','x'), mov_read_sidx },
9890 { MKTAG('s','t','b','l'), mov_read_default },
9891 { MKTAG('s','t','c','o'), mov_read_stco },
9892 { MKTAG('s','t','p','s'), mov_read_stps },
9893 { MKTAG('s','t','r','f'), mov_read_strf },
9894 { MKTAG('s','t','s','c'), mov_read_stsc },
9895 { MKTAG('s','t','s','d'), mov_read_stsd }, /* sample description */
9896 { MKTAG('s','t','s','s'), mov_read_stss }, /* sync sample */
9897 { MKTAG('s','t','s','z'), mov_read_stsz }, /* sample size */
9898 { MKTAG('s','t','t','s'), mov_read_stts },
9899 { MKTAG('s','t','z','2'), mov_read_stsz }, /* compact sample size */
9900 { MKTAG('s','d','t','p'), mov_read_sdtp }, /* independent and disposable samples */
9901 { MKTAG('t','k','h','d'), mov_read_tkhd }, /* track header */
9902 { MKTAG('t','f','d','t'), mov_read_tfdt },
9903 { MKTAG('t','f','h','d'), mov_read_tfhd }, /* track fragment header */
9904 { MKTAG('t','r','a','k'), mov_read_trak },
9905 { MKTAG('t','r','a','f'), mov_read_default },
9906 { MKTAG('t','r','e','f'), mov_read_default },
9907 { MKTAG('t','m','c','d'), mov_read_tmcd },
9908 { MKTAG('c','h','a','p'), mov_read_chap },
9909 { MKTAG('t','r','e','x'), mov_read_trex },
9910 { MKTAG('t','r','u','n'), mov_read_trun },
9911 { MKTAG('u','d','t','a'), mov_read_default },
9912 { MKTAG('w','a','v','e'), mov_read_wave },
9913 { MKTAG('e','s','d','s'), mov_read_esds },
9914 { MKTAG('d','a','c','3'), mov_read_dac3 }, /* AC-3 info */
9915 { MKTAG('d','e','c','3'), mov_read_dec3 }, /* EAC-3 info */
9916 { MKTAG('d','d','t','s'), mov_read_ddts }, /* DTS audio descriptor */
9917 { MKTAG('w','i','d','e'), mov_read_wide }, /* place holder */
9918 { MKTAG('w','f','e','x'), mov_read_wfex },
9919 { MKTAG('c','m','o','v'), mov_read_cmov },
9920 { MKTAG('c','h','a','n'), mov_read_chan }, /* channel layout from quicktime */
9921 { MKTAG('c','h','n','l'), mov_read_chnl }, /* channel layout from ISO-14496-12 */
9922 { MKTAG('d','v','c','1'), mov_read_dvc1 },
9923 { MKTAG('s','g','p','d'), mov_read_sgpd },
9924 { MKTAG('s','b','g','p'), mov_read_sbgp },
9925 { MKTAG('h','v','c','C'), mov_read_glbl },
9926 { MKTAG('v','v','c','C'), mov_read_glbl },
9927 { MKTAG('u','u','i','d'), mov_read_uuid },
9928 { MKTAG('C','i','n', 0x8e), mov_read_targa_y216 },
9929 { MKTAG('f','r','e','e'), mov_read_free },
9930 { MKTAG('-','-','-','-'), mov_read_custom },
9931 { MKTAG('s','i','n','f'), mov_read_default },
9932 { MKTAG('f','r','m','a'), mov_read_frma },
9933 { MKTAG('s','e','n','c'), mov_read_senc },
9934 { MKTAG('s','a','i','z'), mov_read_saiz },
9935 { MKTAG('s','a','i','o'), mov_read_saio },
9936 { MKTAG('p','s','s','h'), mov_read_pssh },
9937 { MKTAG('s','c','h','m'), mov_read_schm },
9938 { MKTAG('s','c','h','i'), mov_read_default },
9939 { MKTAG('t','e','n','c'), mov_read_tenc },
9940 { MKTAG('d','f','L','a'), mov_read_dfla },
9941 { MKTAG('s','t','3','d'), mov_read_st3d }, /* stereoscopic 3D video box */
9942 { MKTAG('s','v','3','d'), mov_read_sv3d }, /* spherical video box */
9943 { MKTAG('v','e','x','u'), mov_read_vexu }, /* video extension usage */
9944 { MKTAG('h','f','o','v'), mov_read_hfov },
9945 { MKTAG('d','O','p','s'), mov_read_dops },
9946 { MKTAG('d','m','l','p'), mov_read_dmlp },
9947 { MKTAG('S','m','D','m'), mov_read_smdm },
9948 { MKTAG('C','o','L','L'), mov_read_coll },
9949 { MKTAG('v','p','c','C'), mov_read_vpcc },
9950 { MKTAG('m','d','c','v'), mov_read_mdcv },
9951 { MKTAG('c','l','l','i'), mov_read_clli },
9952 { MKTAG('d','v','c','C'), mov_read_dvcc_dvvc },
9953 { MKTAG('d','v','v','C'), mov_read_dvcc_dvvc },
9954 { MKTAG('d','v','w','C'), mov_read_dvcc_dvvc },
9955 { MKTAG('h','v','c','E'), mov_read_hvce },
9956 { MKTAG('k','i','n','d'), mov_read_kind },
9957 { MKTAG('S','A','3','D'), mov_read_SA3D }, /* ambisonic audio box */
9958 { MKTAG('S','A','N','D'), mov_read_SAND }, /* non diegetic audio box */
9959 { MKTAG('i','l','o','c'), mov_read_iloc },
9960 { MKTAG('p','c','m','C'), mov_read_pcmc }, /* PCM configuration box */
9961 { MKTAG('p','i','t','m'), mov_read_pitm },
9962 { MKTAG('e','v','c','C'), mov_read_glbl },
9963 { MKTAG('i','d','a','t'), mov_read_idat },
9964 { MKTAG('i','m','i','r'), mov_read_imir },
9965 { MKTAG('i','r','e','f'), mov_read_iref },
9966 { MKTAG('i','s','p','e'), mov_read_ispe },
9967 { MKTAG('i','r','o','t'), mov_read_irot },
9968 { MKTAG('i','p','r','p'), mov_read_iprp },
9969 { MKTAG('i','i','n','f'), mov_read_iinf },
9970 { MKTAG('a','m','v','e'), mov_read_amve }, /* ambient viewing environment box */
9971 { MKTAG('l','h','v','C'), mov_read_lhvc },
9972 { MKTAG('l','v','c','C'), mov_read_glbl },
9973 { MKTAG('a','p','v','C'), mov_read_glbl },
9974 #if CONFIG_IAMFDEC
9975 { MKTAG('i','a','c','b'), mov_read_iacb },
9976 #endif
9977 { MKTAG('s','r','a','t'), mov_read_srat },
9978 { 0, NULL }
9979 };
9980 
9982 {
9983  int64_t total_size = 0;
9984  MOVAtom a;
9985  int i;
9986 
9987  if (c->atom_depth > 10) {
9988  av_log(c->fc, AV_LOG_ERROR, "Atoms too deeply nested\n");
9989  return AVERROR_INVALIDDATA;
9990  }
9991  c->atom_depth ++;
9992 
9993  if (atom.size < 0)
9994  atom.size = INT64_MAX;
9995  while (total_size <= atom.size - 8) {
9996  int (*parse)(MOVContext*, AVIOContext*, MOVAtom) = NULL;
9997  a.size = avio_rb32(pb);
9998  a.type = avio_rl32(pb);
9999  if (avio_feof(pb))
10000  break;
10001  if (((a.type == MKTAG('f','r','e','e') && c->moov_retry) ||
10002  a.type == MKTAG('h','o','o','v')) &&
10003  a.size >= 8 &&
10004  c->fc->strict_std_compliance < FF_COMPLIANCE_STRICT) {
10005  uint32_t type;
10006  avio_skip(pb, 4);
10007  type = avio_rl32(pb);
10008  if (avio_feof(pb))
10009  break;
10010  avio_seek(pb, -8, SEEK_CUR);
10011  if (type == MKTAG('m','v','h','d') ||
10012  type == MKTAG('c','m','o','v')) {
10013  av_log(c->fc, AV_LOG_ERROR, "Detected moov in a free or hoov atom.\n");
10014  a.type = MKTAG('m','o','o','v');
10015  }
10016  }
10017  if (atom.type != MKTAG('r','o','o','t') &&
10018  atom.type != MKTAG('m','o','o','v')) {
10019  if (a.type == MKTAG('t','r','a','k') ||
10020  a.type == MKTAG('m','d','a','t')) {
10021  av_log(c->fc, AV_LOG_ERROR, "Broken file, trak/mdat not at top-level\n");
10022  avio_skip(pb, -8);
10023  c->atom_depth --;
10024  return 0;
10025  }
10026  }
10027  total_size += 8;
10028  if (a.size == 1 && total_size + 8 <= atom.size) { /* 64 bit extended size */
10029  a.size = avio_rb64(pb) - 8;
10030  total_size += 8;
10031  }
10032  av_log(c->fc, AV_LOG_TRACE, "type:'%s' parent:'%s' sz: %"PRId64" %"PRId64" %"PRId64"\n",
10033  av_fourcc2str(a.type), av_fourcc2str(atom.type), a.size, total_size, atom.size);
10034  if (a.size == 0) {
10035  a.size = atom.size - total_size + 8;
10036  }
10037  if (a.size < 0)
10038  break;
10039  a.size -= 8;
10040  if (a.size < 0)
10041  break;
10042  a.size = FFMIN(a.size, atom.size - total_size);
10043 
10044  for (i = 0; mov_default_parse_table[i].type; i++)
10045  if (mov_default_parse_table[i].type == a.type) {
10047  break;
10048  }
10049 
10050  // container is user data
10051  if (!parse && (atom.type == MKTAG('u','d','t','a') ||
10052  atom.type == MKTAG('i','l','s','t')))
10054 
10055  // Supports parsing the QuickTime Metadata Keys.
10056  // https://developer.apple.com/library/mac/documentation/QuickTime/QTFF/Metadata/Metadata.html
10057  if (!parse && c->found_hdlr_mdta &&
10058  atom.type == MKTAG('m','e','t','a') &&
10059  a.type == MKTAG('k','e','y','s') &&
10060  c->meta_keys_count == 0) {
10061  parse = mov_read_keys;
10062  }
10063 
10064  if (!parse) { /* skip leaf atoms data */
10065  avio_skip(pb, a.size);
10066  } else {
10067  int64_t start_pos = avio_tell(pb);
10068  int64_t left;
10069  int err = parse(c, pb, a);
10070  if (err < 0) {
10071  c->atom_depth --;
10072  return err;
10073  }
10074  if (c->found_moov && c->found_mdat && a.size <= INT64_MAX - start_pos &&
10075  ((!(pb->seekable & AVIO_SEEKABLE_NORMAL) || c->fc->flags & AVFMT_FLAG_IGNIDX || c->frag_index.complete) ||
10076  start_pos + a.size == avio_size(pb))) {
10077  if (!(pb->seekable & AVIO_SEEKABLE_NORMAL) || c->fc->flags & AVFMT_FLAG_IGNIDX || c->frag_index.complete)
10078  c->next_root_atom = start_pos + a.size;
10079  c->atom_depth --;
10080  return 0;
10081  }
10082  left = a.size - avio_tell(pb) + start_pos;
10083  if (left > 0) /* skip garbage at atom end */
10084  avio_skip(pb, left);
10085  else if (left < 0) {
10086  av_log(c->fc, AV_LOG_WARNING,
10087  "overread end of atom '%s' by %"PRId64" bytes\n",
10088  av_fourcc2str(a.type), -left);
10089  avio_seek(pb, left, SEEK_CUR);
10090  }
10091  }
10092 
10093  total_size += a.size;
10094  }
10095 
10096  if (total_size < atom.size && atom.size < 0x7ffff)
10097  avio_skip(pb, atom.size - total_size);
10098 
10099  c->atom_depth --;
10100  return 0;
10101 }
10102 
10103 static int mov_probe(const AVProbeData *p)
10104 {
10105  int64_t offset;
10106  uint32_t tag;
10107  int score = 0;
10108  int moov_offset = -1;
10109 
10110  /* check file header */
10111  offset = 0;
10112  for (;;) {
10113  int64_t size;
10114  int minsize = 8;
10115  /* ignore invalid offset */
10116  if ((offset + 8ULL) > (unsigned int)p->buf_size)
10117  break;
10118  size = AV_RB32(p->buf + offset);
10119  if (size == 1 && offset + 16 <= (unsigned int)p->buf_size) {
10120  size = AV_RB64(p->buf+offset + 8);
10121  minsize = 16;
10122  } else if (size == 0) {
10123  size = p->buf_size - offset;
10124  }
10125  if (size < minsize) {
10126  offset += 4;
10127  continue;
10128  }
10129  tag = AV_RL32(p->buf + offset + 4);
10130  switch(tag) {
10131  /* check for obvious tags */
10132  case MKTAG('m','o','o','v'):
10133  moov_offset = offset + 4;
10135  case MKTAG('m','d','a','t'):
10136  case MKTAG('p','n','o','t'): /* detect movs with preview pics like ew.mov and april.mov */
10137  case MKTAG('u','d','t','a'): /* Packet Video PVAuthor adds this and a lot of more junk */
10138  case MKTAG('f','t','y','p'):
10139  if (tag == MKTAG('f','t','y','p') &&
10140  ( AV_RL32(p->buf + offset + 8) == MKTAG('j','p','2',' ')
10141  || AV_RL32(p->buf + offset + 8) == MKTAG('j','p','x',' ')
10142  || AV_RL32(p->buf + offset + 8) == MKTAG('j','x','l',' ')
10143  )) {
10144  score = FFMAX(score, 5);
10145  } else {
10146  score = AVPROBE_SCORE_MAX;
10147  }
10148  break;
10149  /* those are more common words, so rate then a bit less */
10150  case MKTAG('e','d','i','w'): /* xdcam files have reverted first tags */
10151  case MKTAG('w','i','d','e'):
10152  case MKTAG('f','r','e','e'):
10153  case MKTAG('j','u','n','k'):
10154  case MKTAG('p','i','c','t'):
10155  score = FFMAX(score, AVPROBE_SCORE_MAX - 5);
10156  break;
10157  case MKTAG(0x82,0x82,0x7f,0x7d):
10158  score = FFMAX(score, AVPROBE_SCORE_EXTENSION - 5);
10159  break;
10160  case MKTAG('s','k','i','p'):
10161  case MKTAG('u','u','i','d'):
10162  case MKTAG('p','r','f','l'):
10163  /* if we only find those cause probedata is too small at least rate them */
10164  score = FFMAX(score, AVPROBE_SCORE_EXTENSION);
10165  break;
10166  }
10167  if (size > INT64_MAX - offset)
10168  break;
10169  offset += size;
10170  }
10171  if (score > AVPROBE_SCORE_MAX - 50 && moov_offset != -1) {
10172  /* moov atom in the header - we should make sure that this is not a
10173  * MOV-packed MPEG-PS */
10174  offset = moov_offset;
10175 
10176  while (offset < (p->buf_size - 16)) { /* Sufficient space */
10177  /* We found an actual hdlr atom */
10178  if (AV_RL32(p->buf + offset ) == MKTAG('h','d','l','r') &&
10179  AV_RL32(p->buf + offset + 8) == MKTAG('m','h','l','r') &&
10180  AV_RL32(p->buf + offset + 12) == MKTAG('M','P','E','G')) {
10181  av_log(NULL, AV_LOG_WARNING, "Found media data tag MPEG indicating this is a MOV-packed MPEG-PS.\n");
10182  /* We found a media handler reference atom describing an
10183  * MPEG-PS-in-MOV, return a
10184  * low score to force expanding the probe window until
10185  * mpegps_probe finds what it needs */
10186  return 5;
10187  } else {
10188  /* Keep looking */
10189  offset += 2;
10190  }
10191  }
10192  }
10193 
10194  return score;
10195 }
10196 
10197 // must be done after parsing all trak because there's no order requirement
10199 {
10200  MOVContext *mov = s->priv_data;
10201  MOVStreamContext *sc;
10202  int64_t cur_pos;
10203  int i, j;
10204  int chapter_track;
10205 
10206  for (j = 0; j < mov->nb_chapter_tracks; j++) {
10207  AVStream *st = NULL;
10208  FFStream *sti = NULL;
10209  chapter_track = mov->chapter_tracks[j];
10210  for (i = 0; i < s->nb_streams; i++) {
10211  sc = mov->fc->streams[i]->priv_data;
10212  if (sc->id == chapter_track) {
10213  st = s->streams[i];
10214  break;
10215  }
10216  }
10217  if (!st) {
10218  av_log(s, AV_LOG_ERROR, "Referenced QT chapter track not found\n");
10219  continue;
10220  }
10221  sti = ffstream(st);
10222 
10223  sc = st->priv_data;
10224  cur_pos = avio_tell(sc->pb);
10225 
10226  if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
10228  if (!st->attached_pic.data && sti->nb_index_entries) {
10229  // Retrieve the first frame, if possible
10230  AVIndexEntry *sample = &sti->index_entries[0];
10231  if (avio_seek(sc->pb, sample->pos, SEEK_SET) != sample->pos) {
10232  av_log(s, AV_LOG_ERROR, "Failed to retrieve first frame\n");
10233  goto finish;
10234  }
10235 
10236  if (ff_add_attached_pic(s, st, sc->pb, NULL, sample->size) < 0)
10237  goto finish;
10238  }
10239  } else {
10242  st->discard = AVDISCARD_ALL;
10243  for (int i = 0; i < sti->nb_index_entries; i++) {
10244  AVIndexEntry *sample = &sti->index_entries[i];
10245  int64_t end = i+1 < sti->nb_index_entries ? sti->index_entries[i+1].timestamp : st->duration;
10246  uint8_t *title;
10247  uint16_t ch;
10248  int len, title_len;
10249 
10250  if (end < sample->timestamp) {
10251  av_log(s, AV_LOG_WARNING, "ignoring stream duration which is shorter than chapters\n");
10252  end = AV_NOPTS_VALUE;
10253  }
10254 
10255  if (avio_seek(sc->pb, sample->pos, SEEK_SET) != sample->pos) {
10256  av_log(s, AV_LOG_ERROR, "Chapter %d not found in file\n", i);
10257  goto finish;
10258  }
10259 
10260  // the first two bytes are the length of the title
10261  len = avio_rb16(sc->pb);
10262  if (len > sample->size-2)
10263  continue;
10264  title_len = 2*len + 1;
10265  if (!(title = av_mallocz(title_len)))
10266  goto finish;
10267 
10268  // The samples could theoretically be in any encoding if there's an encd
10269  // atom following, but in practice are only utf-8 or utf-16, distinguished
10270  // instead by the presence of a BOM
10271  if (!len) {
10272  title[0] = 0;
10273  } else {
10274  ch = avio_rb16(sc->pb);
10275  if (ch == 0xfeff)
10276  avio_get_str16be(sc->pb, len, title, title_len);
10277  else if (ch == 0xfffe)
10278  avio_get_str16le(sc->pb, len, title, title_len);
10279  else {
10280  AV_WB16(title, ch);
10281  if (len == 1 || len == 2)
10282  title[len] = 0;
10283  else
10284  avio_get_str(sc->pb, INT_MAX, title + 2, len - 1);
10285  }
10286  }
10287 
10288  avpriv_new_chapter(s, i, st->time_base, sample->timestamp, end, title);
10289  av_freep(&title);
10290  }
10291  }
10292 finish:
10293  avio_seek(sc->pb, cur_pos, SEEK_SET);
10294  }
10295 }
10296 
10298  int64_t value, int flags)
10299 {
10300  AVTimecode tc;
10301  char buf[AV_TIMECODE_STR_SIZE];
10302  AVRational rate = st->avg_frame_rate;
10303  int ret = av_timecode_init(&tc, rate, flags, 0, s);
10304  if (ret < 0)
10305  return ret;
10306  av_dict_set(&st->metadata, "timecode",
10307  av_timecode_make_string(&tc, buf, value), 0);
10308  return 0;
10309 }
10310 
10312 {
10313  MOVStreamContext *sc = st->priv_data;
10314  FFStream *const sti = ffstream(st);
10315  char buf[AV_TIMECODE_STR_SIZE];
10316  int64_t cur_pos = avio_tell(sc->pb);
10317  int hh, mm, ss, ff, drop;
10318 
10319  if (!sti->nb_index_entries)
10320  return -1;
10321 
10322  avio_seek(sc->pb, sti->index_entries->pos, SEEK_SET);
10323  avio_skip(s->pb, 13);
10324  hh = avio_r8(s->pb);
10325  mm = avio_r8(s->pb);
10326  ss = avio_r8(s->pb);
10327  drop = avio_r8(s->pb);
10328  ff = avio_r8(s->pb);
10329  snprintf(buf, AV_TIMECODE_STR_SIZE, "%02d:%02d:%02d%c%02d",
10330  hh, mm, ss, drop ? ';' : ':', ff);
10331  av_dict_set(&st->metadata, "timecode", buf, 0);
10332 
10333  avio_seek(sc->pb, cur_pos, SEEK_SET);
10334  return 0;
10335 }
10336 
10338 {
10339  MOVStreamContext *sc = st->priv_data;
10340  FFStream *const sti = ffstream(st);
10341  int flags = 0;
10342  int64_t cur_pos = avio_tell(sc->pb);
10343  int64_t value;
10344  AVRational tc_rate = st->avg_frame_rate;
10345  int tmcd_nb_frames = sc->tmcd_nb_frames;
10346  int rounded_tc_rate;
10347 
10348  if (!sti->nb_index_entries)
10349  return -1;
10350 
10351  if (!tc_rate.num || !tc_rate.den || !tmcd_nb_frames)
10352  return -1;
10353 
10354  avio_seek(sc->pb, sti->index_entries->pos, SEEK_SET);
10355  value = avio_rb32(s->pb);
10356 
10357  if (sc->tmcd_flags & 0x0001) flags |= AV_TIMECODE_FLAG_DROPFRAME;
10358  if (sc->tmcd_flags & 0x0002) flags |= AV_TIMECODE_FLAG_24HOURSMAX;
10359  if (sc->tmcd_flags & 0x0004) flags |= AV_TIMECODE_FLAG_ALLOWNEGATIVE;
10360 
10361  /* Assume Counter flag is set to 1 in tmcd track (even though it is likely
10362  * not the case) and thus assume "frame number format" instead of QT one.
10363  * No sample with tmcd track can be found with a QT timecode at the moment,
10364  * despite what the tmcd track "suggests" (Counter flag set to 0 means QT
10365  * format). */
10366 
10367  /* 60 fps content have tmcd_nb_frames set to 30 but tc_rate set to 60, so
10368  * we multiply the frame number with the quotient.
10369  * See tickets #9492, #9710. */
10370  rounded_tc_rate = (tc_rate.num + tc_rate.den / 2LL) / tc_rate.den;
10371  /* Work around files where tmcd_nb_frames is rounded down from frame rate
10372  * instead of up. See ticket #5978. */
10373  if (tmcd_nb_frames == tc_rate.num / tc_rate.den &&
10374  s->strict_std_compliance < FF_COMPLIANCE_STRICT)
10375  tmcd_nb_frames = rounded_tc_rate;
10376  value = av_rescale(value, rounded_tc_rate, tmcd_nb_frames);
10377 
10379 
10380  avio_seek(sc->pb, cur_pos, SEEK_SET);
10381  return 0;
10382 }
10383 
10385  int i;
10386  if (!index || !*index) return;
10387  for (i = 0; i < (*index)->nb_encrypted_samples; i++) {
10388  av_encryption_info_free((*index)->encrypted_samples[i]);
10389  }
10390  av_freep(&(*index)->encrypted_samples);
10391  av_freep(&(*index)->auxiliary_info_sizes);
10392  av_freep(&(*index)->auxiliary_offsets);
10393  av_freep(index);
10394 }
10395 
10397 {
10398  MOVStreamContext *sc = st->priv_data;
10399 
10400  if (!sc || --sc->refcount) {
10401  st->priv_data = NULL;
10402  return;
10403  }
10404 
10405  av_freep(&sc->tts_data);
10406  for (int i = 0; i < sc->drefs_count; i++) {
10407  av_freep(&sc->drefs[i].path);
10408  av_freep(&sc->drefs[i].dir);
10409  }
10410  av_freep(&sc->drefs);
10411 
10412  sc->drefs_count = 0;
10413 
10414  if (!sc->pb_is_copied)
10415  ff_format_io_close(s, &sc->pb);
10416 
10417  sc->pb = NULL;
10418  av_freep(&sc->chunk_offsets);
10419  av_freep(&sc->stsc_data);
10420  av_freep(&sc->sample_sizes);
10421  av_freep(&sc->keyframes);
10422  av_freep(&sc->ctts_data);
10423  av_freep(&sc->stts_data);
10424  av_freep(&sc->sdtp_data);
10425  av_freep(&sc->stps_data);
10426  av_freep(&sc->elst_data);
10427  av_freep(&sc->rap_group);
10428  av_freep(&sc->sync_group);
10429  av_freep(&sc->sgpd_sync);
10430  av_freep(&sc->sample_offsets);
10431  av_freep(&sc->open_key_samples);
10432  av_freep(&sc->display_matrix);
10433  av_freep(&sc->index_ranges);
10434  for (int i = 0; i < sc->nb_tref_tags; i++)
10435  av_freep(&sc->tref_tags[i].id);
10436  av_freep(&sc->tref_tags);
10437 
10438  if (sc->extradata)
10439  for (int i = 0; i < sc->stsd_count; i++)
10440  av_free(sc->extradata[i]);
10441  av_freep(&sc->extradata);
10442  av_freep(&sc->extradata_size);
10443 
10447 
10448  av_freep(&sc->stereo3d);
10449  av_freep(&sc->spherical);
10450  av_freep(&sc->mastering);
10451  av_freep(&sc->coll);
10452  av_freep(&sc->ambient);
10453 
10454 #if CONFIG_IAMFDEC
10455  if (sc->iamf)
10457 #endif
10458  av_freep(&sc->iamf);
10459 }
10460 
10462 {
10463  MOVContext *mov = s->priv_data;
10464  int i, j;
10465 
10466  for (i = 0; i < s->nb_streams; i++) {
10467  AVStream *st = s->streams[i];
10468 
10470  }
10471 
10472  av_freep(&mov->dv_demux);
10474  mov->dv_fctx = NULL;
10475 
10476  if (mov->meta_keys) {
10477  for (i = 1; i < mov->meta_keys_count; i++) {
10478  av_freep(&mov->meta_keys[i]);
10479  }
10480  av_freep(&mov->meta_keys);
10481  }
10482 
10483  av_freep(&mov->trex_data);
10484  av_freep(&mov->bitrates);
10485 
10486  for (i = 0; i < mov->frag_index.nb_items; i++) {
10488  for (j = 0; j < mov->frag_index.item[i].nb_stream_info; j++) {
10489  mov_free_encryption_index(&frag[j].encryption_index);
10490  }
10492  }
10493  av_freep(&mov->frag_index.item);
10494 
10495  av_freep(&mov->aes_decrypt);
10496  av_freep(&mov->chapter_tracks);
10497  for (i = 0; i < mov->nb_heif_item; i++) {
10498  if (!mov->heif_item[i])
10499  continue;
10500  av_freep(&mov->heif_item[i]->name);
10501  av_freep(&mov->heif_item[i]->iref_list);
10502  av_freep(&mov->heif_item[i]->icc_profile);
10503  av_freep(&mov->heif_item[i]);
10504  }
10505  av_freep(&mov->heif_item);
10506  for (i = 0; i < mov->nb_heif_grid; i++) {
10507  av_freep(&mov->heif_grid[i].tile_id_list);
10510  }
10511  av_freep(&mov->heif_grid);
10512 
10513  return 0;
10514 }
10515 
10516 static int tmcd_is_referenced(AVFormatContext *s, int tmcd_id)
10517 {
10518  int i;
10519 
10520  for (i = 0; i < s->nb_streams; i++) {
10521  AVStream *st = s->streams[i];
10522  MOVStreamContext *sc = st->priv_data;
10523  MovTref *tag = mov_find_tref_tag(sc, MKTAG('t','m','c','d'));
10524 
10525  if (!tag)
10526  continue;
10527  if (mov_find_tref_id(tag, tmcd_id))
10528  return 1;
10529  }
10530  return 0;
10531 }
10532 
10533 /* look for a tmcd track not referenced by any video track, and export it globally */
10535 {
10536  int i;
10537 
10538  for (i = 0; i < s->nb_streams; i++) {
10539  AVStream *st = s->streams[i];
10540 
10541  if (st->codecpar->codec_tag == MKTAG('t','m','c','d') &&
10542  !tmcd_is_referenced(s, st->id)) {
10543  AVDictionaryEntry *tcr = av_dict_get(st->metadata, "timecode", NULL, 0);
10544  if (tcr) {
10545  av_dict_set(&s->metadata, "timecode", tcr->value, 0);
10546  break;
10547  }
10548  }
10549  }
10550 }
10551 
10552 static int read_tfra(MOVContext *mov, AVIOContext *f)
10553 {
10554  int version, fieldlength, i, j;
10555  int64_t pos = avio_tell(f);
10556  uint32_t size = avio_rb32(f);
10557  unsigned track_id, item_count;
10558 
10559  if (avio_rb32(f) != MKBETAG('t', 'f', 'r', 'a')) {
10560  return 1;
10561  }
10562  av_log(mov->fc, AV_LOG_VERBOSE, "found tfra\n");
10563 
10564  version = avio_r8(f);
10565  avio_rb24(f);
10566  track_id = avio_rb32(f);
10567  fieldlength = avio_rb32(f);
10568  item_count = avio_rb32(f);
10569  for (i = 0; i < item_count; i++) {
10570  int64_t time, offset;
10571  int index;
10572  MOVFragmentStreamInfo * frag_stream_info;
10573 
10574  if (avio_feof(f)) {
10575  return AVERROR_INVALIDDATA;
10576  }
10577 
10578  if (version == 1) {
10579  time = avio_rb64(f);
10580  offset = avio_rb64(f);
10581  } else {
10582  time = avio_rb32(f);
10583  offset = avio_rb32(f);
10584  }
10585 
10586  // The first sample of each stream in a fragment is always a random
10587  // access sample. So it's entry in the tfra can be used as the
10588  // initial PTS of the fragment.
10589  index = update_frag_index(mov, offset);
10590  frag_stream_info = get_frag_stream_info(&mov->frag_index, index, track_id);
10591  if (frag_stream_info &&
10592  frag_stream_info->first_tfra_pts == AV_NOPTS_VALUE)
10593  frag_stream_info->first_tfra_pts = time;
10594 
10595  for (j = 0; j < ((fieldlength >> 4) & 3) + 1; j++)
10596  avio_r8(f);
10597  for (j = 0; j < ((fieldlength >> 2) & 3) + 1; j++)
10598  avio_r8(f);
10599  for (j = 0; j < ((fieldlength >> 0) & 3) + 1; j++)
10600  avio_r8(f);
10601  }
10602 
10603  avio_seek(f, pos + size, SEEK_SET);
10604  return 0;
10605 }
10606 
10608 {
10609  int64_t stream_size = avio_size(f);
10610  int64_t original_pos = avio_tell(f);
10611  int64_t seek_ret;
10612  int ret = -1;
10613  if ((seek_ret = avio_seek(f, stream_size - 4, SEEK_SET)) < 0) {
10614  ret = seek_ret;
10615  goto fail;
10616  }
10617  c->mfra_size = avio_rb32(f);
10618  c->have_read_mfra_size = 1;
10619  if (!c->mfra_size || c->mfra_size > stream_size) {
10620  av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (unreasonable size)\n");
10621  goto fail;
10622  }
10623  if ((seek_ret = avio_seek(f, -((int64_t) c->mfra_size), SEEK_CUR)) < 0) {
10624  ret = seek_ret;
10625  goto fail;
10626  }
10627  if (avio_rb32(f) != c->mfra_size) {
10628  av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (size mismatch)\n");
10629  goto fail;
10630  }
10631  if (avio_rb32(f) != MKBETAG('m', 'f', 'r', 'a')) {
10632  av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (tag mismatch)\n");
10633  goto fail;
10634  }
10635  av_log(c->fc, AV_LOG_VERBOSE, "stream has mfra\n");
10636  do {
10637  ret = read_tfra(c, f);
10638  if (ret < 0)
10639  goto fail;
10640  } while (!ret);
10641  ret = 0;
10642  c->frag_index.complete = 1;
10643 fail:
10644  seek_ret = avio_seek(f, original_pos, SEEK_SET);
10645  if (seek_ret < 0) {
10646  av_log(c->fc, AV_LOG_ERROR,
10647  "failed to seek back after looking for mfra\n");
10648  ret = seek_ret;
10649  }
10650  return ret;
10651 }
10652 
10653 static int set_icc_profile_from_item(AVPacketSideData **coded_side_data, int *nb_coded_side_data,
10654  const HEIFItem *item)
10655 {
10656  AVPacketSideData *sd = av_packet_side_data_new(coded_side_data, nb_coded_side_data,
10658  item->icc_profile_size, 0);
10659  if (!sd)
10660  return AVERROR(ENOMEM);
10661 
10662  memcpy(sd->data, item->icc_profile, item->icc_profile_size);
10663 
10664  return 0;
10665 }
10666 
10667 static int set_display_matrix_from_item(AVPacketSideData **coded_side_data, int *nb_coded_side_data,
10668  const HEIFItem *item)
10669 {
10670  int32_t *matrix;
10671  AVPacketSideData *sd = av_packet_side_data_new(coded_side_data,
10672  nb_coded_side_data,
10674  9 * sizeof(*matrix), 0);
10675  if (!sd)
10676  return AVERROR(ENOMEM);
10677 
10678  matrix = (int32_t*)sd->data;
10679  /* rotation is in the counter-clockwise direction whereas
10680  * av_display_rotation_set() expects its argument to be
10681  * oriented clockwise, so we need to negate it. */
10683  av_display_matrix_flip(matrix, item->hflip, item->vflip);
10684 
10685  return 0;
10686 }
10687 
10688 static int read_image_grid(AVFormatContext *s, const HEIFGrid *grid,
10689  AVStreamGroupTileGrid *tile_grid)
10690 {
10691  MOVContext *c = s->priv_data;
10692  const HEIFItem *item = grid->item;
10693  int64_t coded_width = 0, coded_height = 0;
10694  int64_t offset = 0, pos = avio_tell(s->pb);
10695  int64_t x = 0, y = 0;
10696  int i = 0;
10697  int tile_rows, tile_cols;
10698  int flags, size;
10699 
10700  if (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL)) {
10701  av_log(c->fc, AV_LOG_INFO, "grid box with non seekable input\n");
10702  return AVERROR_PATCHWELCOME;
10703  }
10704  if (item->is_idat_relative) {
10705  if (!c->idat_offset) {
10706  av_log(c->fc, AV_LOG_ERROR, "missing idat box required by the image grid\n");
10707  return AVERROR_INVALIDDATA;
10708  }
10709  offset = c->idat_offset;
10710  }
10711 
10712  if (offset > INT64_MAX - item->extent_offset)
10713  return AVERROR_INVALIDDATA;
10714 
10715  avio_seek(s->pb, item->extent_offset + offset, SEEK_SET);
10716 
10717  avio_r8(s->pb); /* version */
10718  flags = avio_r8(s->pb);
10719 
10720  tile_rows = avio_r8(s->pb) + 1;
10721  tile_cols = avio_r8(s->pb) + 1;
10722  /* actual width and height of output image */
10723  tile_grid->width = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
10724  tile_grid->height = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
10725 
10726  av_log(c->fc, AV_LOG_TRACE, "grid: grid_rows %d grid_cols %d output_width %d output_height %d\n",
10727  tile_rows, tile_cols, tile_grid->width, tile_grid->height);
10728 
10729  avio_seek(s->pb, pos, SEEK_SET);
10730 
10731  size = tile_rows * tile_cols;
10732  tile_grid->nb_tiles = grid->nb_tiles;
10733 
10734  if (tile_grid->nb_tiles != size)
10735  return AVERROR_INVALIDDATA;
10736 
10737  for (int i = 0; i < tile_cols; i++)
10738  coded_width += grid->tile_item_list[i]->width;
10739  for (int i = 0; i < size; i += tile_cols)
10740  coded_height += grid->tile_item_list[i]->height;
10741 
10742  if (coded_width > INT_MAX || coded_height > INT_MAX)
10743  return AVERROR_INVALIDDATA;
10744 
10745  tile_grid->coded_width = coded_width;
10746  tile_grid->coded_height = coded_height;
10747 
10748  tile_grid->offsets = av_calloc(tile_grid->nb_tiles, sizeof(*tile_grid->offsets));
10749  if (!tile_grid->offsets)
10750  return AVERROR(ENOMEM);
10751 
10752  while (y < tile_grid->coded_height) {
10753  int left_col = i;
10754 
10755  while (x < tile_grid->coded_width) {
10756  if (i == tile_grid->nb_tiles)
10757  return AVERROR_INVALIDDATA;
10758 
10759  tile_grid->offsets[i].idx = grid->tile_idx_list[i];
10760  tile_grid->offsets[i].horizontal = x;
10761  tile_grid->offsets[i].vertical = y;
10762 
10763  x += grid->tile_item_list[i++]->width;
10764  }
10765 
10766  if (x > tile_grid->coded_width) {
10767  av_log(c->fc, AV_LOG_ERROR, "Non uniform HEIF tiles\n");
10768  return AVERROR_INVALIDDATA;
10769  }
10770 
10771  x = 0;
10772  y += grid->tile_item_list[left_col]->height;
10773  }
10774 
10775  if (y > tile_grid->coded_height || i != tile_grid->nb_tiles) {
10776  av_log(c->fc, AV_LOG_ERROR, "Non uniform HEIF tiles\n");
10777  return AVERROR_INVALIDDATA;
10778  }
10779 
10780  return 0;
10781 }
10782 
10783 static int read_image_iovl(AVFormatContext *s, const HEIFGrid *grid,
10784  AVStreamGroupTileGrid *tile_grid)
10785 {
10786  MOVContext *c = s->priv_data;
10787  const HEIFItem *item = grid->item;
10788  uint16_t canvas_fill_value[4];
10789  int64_t offset = 0, pos = avio_tell(s->pb);
10790  int ret = 0, flags;
10791 
10792  if (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL)) {
10793  av_log(c->fc, AV_LOG_INFO, "iovl box with non seekable input\n");
10794  return AVERROR_PATCHWELCOME;
10795  }
10796  if (item->is_idat_relative) {
10797  if (!c->idat_offset) {
10798  av_log(c->fc, AV_LOG_ERROR, "missing idat box required by the image overlay\n");
10799  return AVERROR_INVALIDDATA;
10800  }
10801  offset = c->idat_offset;
10802  }
10803 
10804  if (offset > INT64_MAX - item->extent_offset)
10805  return AVERROR_INVALIDDATA;
10806 
10807  avio_seek(s->pb, item->extent_offset + offset, SEEK_SET);
10808 
10809  avio_r8(s->pb); /* version */
10810  flags = avio_r8(s->pb);
10811 
10812  for (int i = 0; i < 4; i++)
10813  canvas_fill_value[i] = avio_rb16(s->pb);
10814  av_log(c->fc, AV_LOG_TRACE, "iovl: canvas_fill_value { %u, %u, %u, %u }\n",
10815  canvas_fill_value[0], canvas_fill_value[1],
10816  canvas_fill_value[2], canvas_fill_value[3]);
10817  for (int i = 0; i < 4; i++)
10818  tile_grid->background[i] = canvas_fill_value[i];
10819 
10820  /* actual width and height of output image */
10821  tile_grid->width =
10822  tile_grid->coded_width = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
10823  tile_grid->height =
10824  tile_grid->coded_height = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
10825 
10826  av_log(c->fc, AV_LOG_TRACE, "iovl: output_width %d, output_height %d\n",
10827  tile_grid->width, tile_grid->height);
10828 
10829  tile_grid->nb_tiles = grid->nb_tiles;
10830  tile_grid->offsets = av_malloc_array(tile_grid->nb_tiles, sizeof(*tile_grid->offsets));
10831  if (!tile_grid->offsets) {
10832  ret = AVERROR(ENOMEM);
10833  goto fail;
10834  }
10835 
10836  for (int i = 0; i < tile_grid->nb_tiles; i++) {
10837  tile_grid->offsets[i].idx = grid->tile_idx_list[i];
10838  tile_grid->offsets[i].horizontal = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
10839  tile_grid->offsets[i].vertical = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
10840  av_log(c->fc, AV_LOG_TRACE, "iovl: stream_idx[%d] %u, "
10841  "horizontal_offset[%d] %d, vertical_offset[%d] %d\n",
10842  i, tile_grid->offsets[i].idx,
10843  i, tile_grid->offsets[i].horizontal, i, tile_grid->offsets[i].vertical);
10844  }
10845 
10846 fail:
10847  avio_seek(s->pb, pos, SEEK_SET);
10848 
10849  return ret;
10850 }
10851 
10853  AVPacketSideData **coded_side_data, int *nb_coded_side_data,
10854  const HEIFItem *ref)
10855 {
10856  MOVContext *c = s->priv_data;
10857  AVPacketSideData *sd;
10858  AVExifMetadata ifd = { 0 };
10859  AVBufferRef *buf;
10860  int64_t offset = 0, pos = avio_tell(s->pb);
10861  unsigned orientation_id = av_exif_get_tag_id("Orientation");
10862  int err;
10863 
10864  if (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL)) {
10865  av_log(c->fc, AV_LOG_WARNING, "Exif metadata with non seekable input\n");
10866  return AVERROR_PATCHWELCOME;
10867  }
10868  if (ref->is_idat_relative) {
10869  if (!c->idat_offset) {
10870  av_log(c->fc, AV_LOG_ERROR, "missing idat box required by the Exif metadata\n");
10871  return AVERROR_INVALIDDATA;
10872  }
10873  offset = c->idat_offset;
10874  }
10875 
10876  buf = av_buffer_alloc(ref->extent_length);
10877  if (!buf)
10878  return AVERROR(ENOMEM);
10879 
10880  if (offset > INT64_MAX - ref->extent_offset) {
10881  err = AVERROR(ENOMEM);
10882  goto fail;
10883  }
10884 
10885  avio_seek(s->pb, ref->extent_offset + offset, SEEK_SET);
10886  err = avio_read(s->pb, buf->data, ref->extent_length);
10887  if (err != ref->extent_length) {
10888  if (err > 0)
10889  err = AVERROR_INVALIDDATA;
10890  goto fail;
10891  }
10892 
10893  // HEIF spec states that Exif metadata is informative. The irot item property is
10894  // the normative source of rotation information. So we remove any Orientation tag
10895  // present in the Exif buffer.
10896  err = av_exif_parse_buffer(s, buf->data, ref->extent_length, &ifd, AV_EXIF_T_OFF);
10897  if (err < 0) {
10898  av_log(s, AV_LOG_ERROR, "Unable to parse Exif metadata\n");
10899  goto fail;
10900  }
10901 
10902  err = av_exif_remove_entry(s, &ifd, orientation_id, 0);
10903  if (err < 0)
10904  goto fail;
10905  else if (!err)
10906  goto finish;
10907 
10908  av_buffer_unref(&buf);
10909  err = av_exif_write(s, &ifd, &buf, AV_EXIF_T_OFF);
10910  if (err < 0)
10911  goto fail;
10912 
10913 finish:
10914  offset = AV_RB32(buf->data) + 4;
10915  if (offset >= buf->size) {
10916  err = AVERROR_INVALIDDATA;
10917  goto fail;
10918  }
10919  sd = av_packet_side_data_new(coded_side_data, nb_coded_side_data,
10920  AV_PKT_DATA_EXIF, buf->size - offset, 0);
10921  if (!sd) {
10922  err = AVERROR(ENOMEM);
10923  goto fail;
10924  }
10925  memcpy(sd->data, buf->data + offset, buf->size - offset);
10926 
10927  err = 0;
10928 fail:
10929  av_buffer_unref(&buf);
10930  av_exif_free(&ifd);
10931  avio_seek(s->pb, pos, SEEK_SET);
10932 
10933  return err;
10934 }
10935 
10937 {
10938  MOVContext *mov = s->priv_data;
10939 
10940  for (int i = 0; i < mov->nb_heif_grid; i++) {
10942  AVStreamGroupTileGrid *tile_grid;
10943  const HEIFGrid *grid = &mov->heif_grid[i];
10944  int err, loop = 1;
10945 
10946  if (!stg)
10947  return AVERROR(ENOMEM);
10948 
10949  stg->id = grid->item->item_id;
10950  tile_grid = stg->params.tile_grid;
10951 
10952  for (int j = 0; j < grid->nb_tiles; j++) {
10953  int tile_id = grid->tile_id_list[j];
10954  int k;
10955 
10956  for (k = 0; k < mov->nb_heif_item; k++) {
10957  HEIFItem *item = mov->heif_item[k];
10958  AVStream *st;
10959 
10960  if (!item || item->item_id != tile_id)
10961  continue;
10962  st = item->st;
10963  if (!st) {
10964  av_log(s, AV_LOG_WARNING, "HEIF item id %d from grid id %d doesn't "
10965  "reference a stream\n",
10966  tile_id, grid->item->item_id);
10967  ff_remove_stream_group(s, stg);
10968  loop = 0;
10969  break;
10970  }
10971 
10972  grid->tile_item_list[j] = item;
10973  grid->tile_idx_list[j] = stg->nb_streams;
10974 
10975  err = avformat_stream_group_add_stream(stg, st);
10976  if (err < 0) {
10977  int l;
10978  if (err != AVERROR(EEXIST))
10979  return err;
10980 
10981  for (l = 0; l < stg->nb_streams; l++)
10982  if (stg->streams[l]->index == st->index)
10983  break;
10984  av_assert0(l < stg->nb_streams);
10985  grid->tile_idx_list[j] = l;
10986  }
10987 
10988  if (item->item_id != mov->primary_item_id)
10990  break;
10991  }
10992 
10993  if (k == mov->nb_heif_item) {
10994  av_assert0(loop);
10995  av_log(s, AV_LOG_WARNING, "HEIF item id %d referenced by grid id %d doesn't "
10996  "exist\n",
10997  tile_id, grid->item->item_id);
10998  ff_remove_stream_group(s, stg);
10999  loop = 0;
11000  }
11001  if (!loop)
11002  break;
11003  }
11004 
11005  if (!loop)
11006  continue;
11007 
11008  switch (grid->item->type) {
11009  case MKTAG('g','r','i','d'):
11010  err = read_image_grid(s, grid, tile_grid);
11011  break;
11012  case MKTAG('i','o','v','l'):
11013  err = read_image_iovl(s, grid, tile_grid);
11014  break;
11015  default:
11016  av_assert0(0);
11017  }
11018  if (err < 0)
11019  return err;
11020 
11021  for (int j = 0; j < grid->item->nb_iref_list; j++) {
11022  HEIFItem *ref = get_heif_item(mov, grid->item->iref_list[j].item_id);
11023 
11024  av_assert0(ref);
11025  switch(ref->type) {
11026  case MKTAG('E','x','i','f'):
11027  err = mov_parse_exif_item(s, &tile_grid->coded_side_data,
11028  &tile_grid->nb_coded_side_data, ref);
11029  if (err < 0 && (s->error_recognition & AV_EF_EXPLODE))
11030  return err;
11031  break;
11032  default:
11033  break;
11034  }
11035  }
11036 
11037  /* rotation */
11038  if (grid->item->rotation || grid->item->hflip || grid->item->vflip) {
11040  &tile_grid->nb_coded_side_data, grid->item);
11041  if (err < 0)
11042  return err;
11043  }
11044 
11045  /* ICC profile */
11046  if (grid->item->icc_profile_size) {
11047  err = set_icc_profile_from_item(&tile_grid->coded_side_data,
11048  &tile_grid->nb_coded_side_data, grid->item);
11049  if (err < 0)
11050  return err;
11051  }
11052 
11053  if (grid->item->name)
11054  av_dict_set(&stg->metadata, "title", grid->item->name, 0);
11055  if (grid->item->item_id == mov->primary_item_id)
11057  }
11058 
11059  return 0;
11060 }
11061 
11063 {
11064  MOVContext *mov = s->priv_data;
11065  int err;
11066 
11067  for (int i = 0; i < mov->nb_heif_item; i++) {
11068  HEIFItem *item = mov->heif_item[i];
11069  MOVStreamContext *sc;
11070  AVStream *st;
11071  int64_t offset = 0;
11072 
11073  if (!item)
11074  continue;
11075  if (!item->st) {
11076  continue;
11077  }
11078  if (item->is_idat_relative) {
11079  if (!mov->idat_offset) {
11080  av_log(s, AV_LOG_ERROR, "Missing idat box for item %d\n", item->item_id);
11081  return AVERROR_INVALIDDATA;
11082  }
11083  offset = mov->idat_offset;
11084  }
11085 
11086  st = item->st;
11087  sc = st->priv_data;
11088  st->codecpar->width = item->width;
11089  st->codecpar->height = item->height;
11090 
11091  sc->sample_size = sc->stsz_sample_size = item->extent_length;
11092  sc->sample_count = 1;
11093 
11094  err = sanity_checks(s, sc, st->index);
11095  if (err)
11096  return AVERROR_INVALIDDATA;
11097 
11098  if (offset > INT64_MAX - item->extent_offset)
11099  return AVERROR_INVALIDDATA;
11100 
11101  sc->chunk_offsets[0] = item->extent_offset + offset;
11102 
11103  if (item->item_id == mov->primary_item_id)
11105 
11106  for (int j = 0; j < item->nb_iref_list; j++) {
11107  HEIFItem *ref = get_heif_item(mov, item->iref_list[j].item_id);
11108 
11109  av_assert0(ref);
11110  switch(ref->type) {
11111  case MKTAG('E','x','i','f'):
11114  if (err < 0 && (s->error_recognition & AV_EF_EXPLODE))
11115  return err;
11116  break;
11117  default:
11118  break;
11119  }
11120  }
11121 
11122  if (item->rotation || item->hflip || item->vflip) {
11124  &st->codecpar->nb_coded_side_data, item);
11125  if (err < 0)
11126  return err;
11127  }
11128 
11129  mov_build_index(mov, st);
11130  }
11131 
11132  if (mov->nb_heif_grid) {
11133  err = mov_parse_tiles(s);
11134  if (err < 0)
11135  return err;
11136  }
11137 
11138  return 0;
11139 }
11140 
11142 {
11143  int err;
11144 
11145  for (int i = 0; i < s->nb_streams; i++) {
11146  AVStreamGroup *stg;
11147  const AVDictionaryEntry *tcr;
11148  AVStream *st = s->streams[i];
11149 
11150  if (st->codecpar->codec_tag != MKTAG('t','m','c','d'))
11151  continue;
11152 
11154  if (!stg)
11155  return AVERROR(ENOMEM);
11156 
11157  stg->id = st->id;
11158  tcr = av_dict_get(st->metadata, "timecode", NULL, 0);
11159 
11160  for (int j = 0; j < s->nb_streams; j++) {
11161  AVStream *st2 = s->streams[j];
11162  MOVStreamContext *sc2 = st2->priv_data;
11163  MovTref *tag = mov_find_tref_tag(sc2, MKTAG('t','m','c','d'));
11164 
11165  if (!tag)
11166  continue;
11167 
11168  for (int k = 0; k < tag->nb_id; k++) {
11169  if (tag->id[k] != st->id)
11170  continue;
11171 
11172  err = avformat_stream_group_add_stream(stg, st2);
11173  if (err < 0)
11174  return err;
11175 
11176  if (tcr)
11177  av_dict_set(&st2->metadata, "timecode", tcr->value, AV_DICT_DONT_OVERWRITE);
11178  }
11179  }
11180 
11181  if (!stg->nb_streams) {
11182  ff_remove_stream_group(s, stg);
11183  continue;
11184  }
11185 
11186  err = avformat_stream_group_add_stream(stg, st);
11187  if (err < 0)
11188  return err;
11189 
11190  stg->params.tref->metadata_index = stg->nb_streams - 1;
11191  }
11193 
11194  return 0;
11195 }
11196 
11198  uint32_t *tref_id, int nb_tref_id, int first_index)
11199 {
11200  if (!nb_tref_id)
11201  return NULL;
11202 
11203  for (int i = first_index; i < s->nb_streams; i++)
11204  for (int j = 0; j < nb_tref_id; j++)
11205  if (s->streams[i]->index != st->index &&
11206  s->streams[i]->id == tref_id[j])
11207  return s->streams[i];
11208 
11209  return NULL;
11210 }
11211 
11213 {
11214  int err;
11215 
11216  // Don't try to add a group if there's only one track
11217  if (s->nb_streams <= 1)
11218  return 0;
11219 
11220  for (int i = 0; i < s->nb_streams; i++) {
11221  AVStreamGroup *stg;
11222  AVStream *st = s->streams[i];
11223  AVStream *st_ref;
11224  MOVStreamContext *sc = st->priv_data;
11225  MovTref *tag = mov_find_tref_tag(sc, MKTAG('c','d','s','c'));
11226 
11227  if (!tag)
11228  continue;
11229 
11230  st_ref = mov_find_reference_track(s, st, tag->id, tag->nb_id, 0);
11231  if (!st_ref) {
11232  int loglevel = (s->error_recognition & AV_EF_EXPLODE) ? AV_LOG_ERROR : AV_LOG_WARNING;
11233  av_log(s, loglevel, "Failed to find referenced stream\n");
11234  if (s->error_recognition & AV_EF_EXPLODE)
11235  return AVERROR_INVALIDDATA;
11236  continue;
11237  }
11238 
11240  if (!stg)
11241  return AVERROR(ENOMEM);
11242 
11243  stg->id = st->id;
11244 
11245  err = avformat_stream_group_add_stream(stg, st_ref);
11246  if (err < 0)
11247  return err;
11248 
11249  err = avformat_stream_group_add_stream(stg, st);
11250  if (err < 0)
11251  return err;
11252 
11253  stg->params.tref->metadata_index = stg->nb_streams - 1;
11254  }
11255 
11256  return 0;
11257 }
11258 
11260 {
11261  int err;
11262 
11263  // Don't try to add a group if there's only one track
11264  if (s->nb_streams <= 1)
11265  return 0;
11266 
11267  for (int i = 0; i < s->nb_streams; i++) {
11268  AVStreamGroup *stg;
11269  AVStream *st = s->streams[i];
11270  AVStream *st_base;
11271  MOVStreamContext *sc = st->priv_data;
11272  MovTref *tag = mov_find_tref_tag(sc, MKTAG('s','b','a','s'));
11273  int j = 0;
11274 
11275  /* Find an enhancement stream. */
11276  if (st->codecpar->codec_id != AV_CODEC_ID_LCEVC || !tag)
11277  continue;
11278 
11280  if (!stg)
11281  return AVERROR(ENOMEM);
11282 
11283  stg->id = st->id;
11284  stg->params.layered_video->width = st->codecpar->width;
11285  stg->params.layered_video->height = st->codecpar->height;
11286 
11287  while (st_base = mov_find_reference_track(s, st, tag->id, tag->nb_id, j)) {
11288  err = avformat_stream_group_add_stream(stg, st_base);
11289  if (err < 0)
11290  return err;
11291 
11292  j = st_base->index + 1;
11293  }
11294  if (!j) {
11295  int loglevel = (s->error_recognition & AV_EF_EXPLODE) ? AV_LOG_ERROR : AV_LOG_WARNING;
11296  av_log(s, loglevel, "Failed to find base stream for LCEVC stream\n");
11297  ff_remove_stream_group(s, stg);
11298  if (s->error_recognition & AV_EF_EXPLODE)
11299  return AVERROR_INVALIDDATA;
11300  continue;
11301  }
11302 
11303  err = avformat_stream_group_add_stream(stg, st);
11304  if (err < 0)
11305  return err;
11306 
11307  stg->params.layered_video->el_index = stg->nb_streams - 1;
11308  }
11309 
11310  return 0;
11311 }
11312 
11314 {
11315  int err;
11316 
11317  if (s->nb_streams <= 1)
11318  return 0;
11319 
11320  /* Identify legacy dual-track Dolby Vision profile 7 carriage per Annex
11321  * C of "Dolby Vision Streams Within the ISO Base Media File Format",
11322  * v2.7.1. The 'vdep' track reference type is shared with depth video
11323  * and multi-view dependencies. The spec-mandated DV-specific sample
11324  * entry combined with the dvcC configuration record disambiguates
11325  * those uses. */
11326  for (int i = 0; i < s->nb_streams; i++) {
11327  AVStreamGroup *stg;
11328  AVStream *st = s->streams[i];
11329  AVStream *st_base;
11330  MOVStreamContext *sc = st->priv_data;
11331  MovTref *tag = mov_find_tref_tag(sc, MKTAG('v','d','e','p'));
11332  const AVPacketSideData *sd;
11334 
11335  if (st->codecpar->codec_id != AV_CODEC_ID_HEVC || !tag)
11336  continue;
11337 
11338  if (st->codecpar->codec_tag != MKTAG('d','v','h','e') &&
11339  st->codecpar->codec_tag != MKTAG('d','v','h','1'))
11340  continue;
11341 
11345  if (!sd)
11346  continue;
11347  dovi = (const AVDOVIDecoderConfigurationRecord *)sd->data;
11348 
11349  /* EL track of a dual-track stream: rpu_present_flag = 1,
11350  * el_present_flag = 1, bl_present_flag = 0, dv_profile = 7. */
11351  if (dovi->dv_profile != 7 || !dovi->rpu_present_flag ||
11352  !dovi->el_present_flag || dovi->bl_present_flag)
11353  continue;
11354 
11355  st_base = mov_find_reference_track(s, st, tag->id, tag->nb_id, 0);
11356  if (!st_base) {
11357  int loglevel = (s->error_recognition & AV_EF_EXPLODE) ? AV_LOG_ERROR : AV_LOG_WARNING;
11358  av_log(s, loglevel, "Failed to find base layer for Dolby Vision EL stream\n");
11359  if (s->error_recognition & AV_EF_EXPLODE)
11360  return AVERROR_INVALIDDATA;
11361  continue;
11362  }
11363 
11365  if (!stg)
11366  return AVERROR(ENOMEM);
11367 
11368  stg->id = st->id;
11369 
11370  err = avformat_stream_group_add_stream(stg, st_base);
11371  if (err < 0)
11372  return err;
11373 
11374  err = avformat_stream_group_add_stream(stg, st);
11375  if (err < 0)
11376  return err;
11377 
11378  stg->params.layered_video->el_index = stg->nb_streams - 1;
11379  stg->params.layered_video->width = st_base->codecpar->width;
11380  stg->params.layered_video->height = st_base->codecpar->height;
11381  }
11382 
11383  return 0;
11384 }
11385 
11387 {
11388  int highest_id = 0, lowest_iamf_id = INT_MAX;
11389 
11390  for (int i = 0; i < s->nb_streams; i++) {
11391  const AVStream *st = s->streams[i];
11392  const MOVStreamContext *sc = st->priv_data;
11393  if (!sc->iamf)
11394  highest_id = FFMAX(highest_id, st->id);
11395  }
11396 
11397  for (int i = 0; i < s->nb_stream_groups; i++) {
11398  AVStreamGroup *stg = s->stream_groups[i];
11400  continue;
11401  for (int j = 0; j < stg->nb_streams; j++) {
11402  AVStream *st = stg->streams[j];
11403  lowest_iamf_id = FFMIN(lowest_iamf_id, st->id);
11404  }
11405  }
11406 
11407  if (highest_id < lowest_iamf_id)
11408  return;
11409 
11410  highest_id += !lowest_iamf_id;
11411  for (int i = 0; highest_id > 1 && i < s->nb_stream_groups; i++) {
11412  AVStreamGroup *stg = s->stream_groups[i];
11414  continue;
11415  for (int j = 0; j < stg->nb_streams; j++) {
11416  AVStream *st = stg->streams[j];
11417  MOVStreamContext *sc = st->priv_data;
11418  st->id += highest_id;
11419  sc->iamf_stream_offset = highest_id;
11420  }
11421  }
11422 }
11423 
11425 {
11426  MOVContext *mov = s->priv_data;
11427  AVIOContext *pb = s->pb;
11428  int j, err;
11429  MOVAtom atom = { AV_RL32("root") };
11430  int i;
11431 
11432  mov->fc = s;
11433  mov->trak_index = -1;
11434  mov->primary_item_id = -1;
11435  mov->cur_item_id = -1;
11436  /* .mov and .mp4 aren't streamable anyway (only progressive download if moov is before mdat) */
11437  if (pb->seekable & AVIO_SEEKABLE_NORMAL)
11438  atom.size = avio_size(pb);
11439  else
11440  atom.size = INT64_MAX;
11441 
11442  /* check MOV header */
11443  do {
11444  if (mov->moov_retry)
11445  avio_seek(pb, 0, SEEK_SET);
11446  if ((err = mov_read_default(mov, pb, atom)) < 0) {
11447  av_log(s, AV_LOG_ERROR, "error reading header\n");
11448  return err;
11449  }
11450  } while ((pb->seekable & AVIO_SEEKABLE_NORMAL) &&
11451  !mov->found_moov && (!mov->found_iloc || !mov->found_iinf) && !mov->moov_retry++);
11452  if (!mov->found_moov && !mov->found_iloc && !mov->found_iinf) {
11453  av_log(s, AV_LOG_ERROR, "moov atom not found\n");
11454  return AVERROR_INVALIDDATA;
11455  }
11456  av_log(mov->fc, AV_LOG_TRACE, "on_parse_exit_offset=%"PRId64"\n", avio_tell(pb));
11457 
11458  if (mov->found_iloc && mov->found_iinf) {
11459  err = mov_parse_heif_items(s);
11460  if (err < 0)
11461  return err;
11462  }
11463  // prevent iloc and iinf boxes from being parsed while reading packets.
11464  // this is needed because an iinf box may have been parsed but ignored
11465  // for having old infe boxes which create no streams.
11466  mov->found_iloc = mov->found_iinf = 1;
11467 
11468  if (pb->seekable & AVIO_SEEKABLE_NORMAL) {
11469  if (mov->nb_chapter_tracks > 0 && !mov->ignore_chapters)
11471  for (i = 0; i < s->nb_streams; i++)
11472  if (s->streams[i]->codecpar->codec_tag == AV_RL32("tmcd")) {
11473  mov_read_timecode_track(s, s->streams[i]);
11474  } else if (s->streams[i]->codecpar->codec_tag == AV_RL32("rtmd")) {
11475  mov_read_rtmd_track(s, s->streams[i]);
11476  }
11477  }
11478 
11479  /* Create metadata stream groups. */
11480  err = mov_parse_cdsc_streams(s);
11481  if (err < 0)
11482  return err;
11483 
11484  /* copy timecode metadata from tmcd tracks to the related video streams */
11485  err = mov_parse_tmcd_streams(s);
11486  if (err < 0)
11487  return err;
11488 
11489  /* Create LCEVC stream groups. */
11490  err = mov_parse_lcevc_streams(s);
11491  if (err < 0)
11492  return err;
11493 
11494  /* Create Dolby Vision Profile 7 stream groups. */
11495  err = mov_parse_dovi_streams(s);
11496  if (err < 0)
11497  return err;
11498 
11499  for (i = 0; i < s->nb_streams; i++) {
11500  AVStream *st = s->streams[i];
11501  FFStream *const sti = ffstream(st);
11502  MOVStreamContext *sc = st->priv_data;
11503  uint32_t dvdsub_clut[FF_DVDCLUT_CLUT_LEN] = {0};
11504  fix_timescale(mov, sc);
11505 
11506  /* Set the primary extradata based on the first Sample if it doesn't reference the first stsd entry. */
11507  if (sc->stsc_count && sc->extradata_size && !sc->iamf &&
11508  sc->stsc_data[0].id > 1 && sc->stsc_data[0].id <= sc->stsd_count) {
11509  sc->last_stsd_index = sc->stsc_data[0].id - 1;
11510  av_freep(&st->codecpar->extradata);
11512  if (sc->extradata_size[sc->last_stsd_index]) {
11514  if (!st->codecpar->extradata)
11515  return AVERROR(ENOMEM);
11516  memcpy(st->codecpar->extradata, sc->extradata[sc->last_stsd_index], sc->extradata_size[sc->last_stsd_index]);
11517  }
11518  }
11519 
11520  if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
11521  st->codecpar->codec_id == AV_CODEC_ID_AAC) {
11523  }
11524  if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && sc->nb_frames_for_fps > 0 && sc->duration_for_fps > 0)
11526  sc->time_scale*(int64_t)sc->nb_frames_for_fps, sc->duration_for_fps, INT_MAX);
11528  if (st->codecpar->width <= 0 || st->codecpar->height <= 0) {
11529  st->codecpar->width = sc->width;
11530  st->codecpar->height = sc->height;
11531  }
11534 
11535  for (j = 0; j < FF_DVDCLUT_CLUT_LEN; j++)
11536  dvdsub_clut[j] = AV_RB32(st->codecpar->extradata + j * 4);
11537 
11538  err = ff_dvdclut_yuv_to_rgb(dvdsub_clut, FF_DVDCLUT_CLUT_SIZE);
11539  if (err < 0)
11540  return err;
11541 
11542  av_freep(&st->codecpar->extradata);
11543  st->codecpar->extradata_size = 0;
11544 
11546  st->codecpar);
11547  if (err < 0)
11548  return err;
11549  }
11550  }
11551  if (mov->handbrake_version &&
11552  mov->handbrake_version <= 1000000*0 + 1000*10 + 2 && // 0.10.2
11553  st->codecpar->codec_id == AV_CODEC_ID_MP3) {
11554  av_log(s, AV_LOG_VERBOSE, "Forcing full parsing for mp3 stream\n");
11556  }
11557  }
11558 
11559  if (mov->trex_data || mov->use_mfra_for > 0) {
11560  for (i = 0; i < s->nb_streams; i++) {
11561  AVStream *st = s->streams[i];
11562  MOVStreamContext *sc = st->priv_data;
11563  if (sc->duration_for_fps > 0) {
11564  /* Akin to sc->data_size * 8 * sc->time_scale / sc->duration_for_fps but accounting for overflows. */
11566  if (st->codecpar->bit_rate == INT64_MIN) {
11567  av_log(s, AV_LOG_WARNING, "Overflow during bit rate calculation %"PRId64" * 8 * %d\n",
11568  sc->data_size, sc->time_scale);
11569  st->codecpar->bit_rate = 0;
11570  if (s->error_recognition & AV_EF_EXPLODE)
11571  return AVERROR_INVALIDDATA;
11572  }
11573  }
11574  }
11575  }
11576 
11577  for (i = 0; i < mov->bitrates_count && i < s->nb_streams; i++) {
11578  if (mov->bitrates[i]) {
11579  s->streams[i]->codecpar->bit_rate = mov->bitrates[i];
11580  }
11581  }
11582 
11584 
11585  for (i = 0; i < s->nb_streams; i++) {
11586  AVStream *st = s->streams[i];
11587  MOVStreamContext *sc = st->priv_data;
11588 
11589  switch (st->codecpar->codec_type) {
11590  case AVMEDIA_TYPE_AUDIO:
11591  err = ff_replaygain_export(st, s->metadata);
11592  if (err < 0)
11593  return err;
11594  break;
11595  case AVMEDIA_TYPE_VIDEO:
11596  if (sc->display_matrix) {
11599  (uint8_t*)sc->display_matrix, sizeof(int32_t) * 9, 0))
11600  return AVERROR(ENOMEM);
11601 
11602  sc->display_matrix = NULL;
11603  }
11604  if (sc->stereo3d) {
11607  (uint8_t *)sc->stereo3d, sc->stereo3d_size, 0))
11608  return AVERROR(ENOMEM);
11609 
11610  sc->stereo3d = NULL;
11611  }
11612  if (sc->spherical) {
11615  (uint8_t *)sc->spherical, sc->spherical_size, 0))
11616  return AVERROR(ENOMEM);
11617 
11618  sc->spherical = NULL;
11619  }
11620  if (sc->mastering) {
11623  (uint8_t *)sc->mastering, sc->mastering_size, 0))
11624  return AVERROR(ENOMEM);
11625 
11626  sc->mastering = NULL;
11627  }
11628  if (sc->coll) {
11631  (uint8_t *)sc->coll, sc->coll_size, 0))
11632  return AVERROR(ENOMEM);
11633 
11634  sc->coll = NULL;
11635  }
11636  if (sc->ambient) {
11639  (uint8_t *) sc->ambient, sc->ambient_size, 0))
11640  return AVERROR(ENOMEM);
11641 
11642  sc->ambient = NULL;
11643  }
11644  break;
11645  }
11646  }
11647 
11648  fix_stream_ids(s);
11649 
11651 
11652  for (i = 0; i < mov->frag_index.nb_items; i++)
11653  if (mov->frag_index.item[i].moof_offset <= mov->fragment.moof_offset)
11654  mov->frag_index.item[i].headers_read = 1;
11655 
11656  return 0;
11657 }
11658 
11660 {
11662  int64_t best_dts = INT64_MAX;
11663  int i;
11664  MOVContext *mov = s->priv_data;
11665  int no_interleave = !mov->interleaved_read || !(s->pb->seekable & AVIO_SEEKABLE_NORMAL);
11666  for (i = 0; i < s->nb_streams; i++) {
11667  AVStream *avst = s->streams[i];
11668  FFStream *const avsti = ffstream(avst);
11669  MOVStreamContext *msc = avst->priv_data;
11670  if (msc->pb && msc->current_sample < avsti->nb_index_entries) {
11671  AVIndexEntry *current_sample = &avsti->index_entries[msc->current_sample];
11672  int64_t dts = av_rescale(current_sample->timestamp, AV_TIME_BASE, msc->time_scale);
11673  uint64_t dtsdiff = best_dts > dts ? best_dts - (uint64_t)dts : ((uint64_t)dts - best_dts);
11674  av_log(s, AV_LOG_TRACE, "stream %d, sample %d, dts %"PRId64"\n", i, msc->current_sample, dts);
11675  if (!sample || (no_interleave && current_sample->pos < sample->pos) ||
11676  ((s->pb->seekable & AVIO_SEEKABLE_NORMAL) &&
11677  ((msc->pb != s->pb && dts < best_dts) || (msc->pb == s->pb && dts != AV_NOPTS_VALUE &&
11678  ((dtsdiff <= AV_TIME_BASE && current_sample->pos < sample->pos) ||
11679  (dtsdiff > AV_TIME_BASE && dts < best_dts && mov->interleaved_read)))))) {
11680  sample = current_sample;
11681  best_dts = dts;
11682  *st = avst;
11683  }
11684  }
11685  }
11686  return sample;
11687 }
11688 
11689 static int should_retry(AVIOContext *pb, int error_code) {
11690  if (error_code == AVERROR_EOF || avio_feof(pb))
11691  return 0;
11692 
11693  return 1;
11694 }
11695 
11696 static int mov_switch_root(AVFormatContext *s, int64_t target, int index)
11697 {
11698  int ret;
11699  MOVContext *mov = s->priv_data;
11700 
11701  if (index >= 0 && index < mov->frag_index.nb_items)
11702  target = mov->frag_index.item[index].moof_offset;
11703  if (target >= 0 && avio_seek(s->pb, target, SEEK_SET) != target) {
11704  av_log(mov->fc, AV_LOG_ERROR, "root atom offset 0x%"PRIx64": partial file\n", target);
11705  return AVERROR_INVALIDDATA;
11706  }
11707 
11708  mov->next_root_atom = 0;
11709  if ((index < 0 && target >= 0) || index >= mov->frag_index.nb_items)
11710  index = search_frag_moof_offset(&mov->frag_index, target);
11711  if (index >= 0 && index < mov->frag_index.nb_items &&
11712  mov->frag_index.item[index].moof_offset == target) {
11713  if (index + 1 < mov->frag_index.nb_items)
11714  mov->next_root_atom = mov->frag_index.item[index + 1].moof_offset;
11715  if (mov->frag_index.item[index].headers_read)
11716  return 0;
11717  mov->frag_index.item[index].headers_read = 1;
11718  }
11719 
11720  mov->found_mdat = 0;
11721 
11722  ret = mov_read_default(mov, s->pb, (MOVAtom){ AV_RL32("root"), INT64_MAX });
11723  if (ret < 0)
11724  return ret;
11725  if (avio_feof(s->pb))
11726  return AVERROR_EOF;
11727  av_log(s, AV_LOG_TRACE, "read fragments, offset 0x%"PRIx64"\n", avio_tell(s->pb));
11728 
11729  return 1;
11730 }
11731 
11733 {
11734  MOVStreamContext *sc = st->priv_data;
11735  uint8_t *side, *extradata;
11736  int extradata_size;
11737 
11738  /* Save the current index. */
11739  sc->last_stsd_index = sc->stsc_data[sc->stsc_index].id - 1;
11740 
11741  /* Notify the decoder that extradata changed. */
11742  extradata_size = sc->extradata_size[sc->last_stsd_index];
11743  extradata = sc->extradata[sc->last_stsd_index];
11744  if (st->discard != AVDISCARD_ALL && extradata_size > 0 && extradata) {
11747  extradata_size);
11748  if (!side)
11749  return AVERROR(ENOMEM);
11750  memcpy(side, extradata, extradata_size);
11751  }
11752 
11753  return 0;
11754 }
11755 
11756 static int get_eia608_packet(AVIOContext *pb, AVPacket *pkt, int src_size)
11757 {
11758  /* We can't make assumptions about the structure of the payload,
11759  because it may include multiple cdat and cdt2 samples. */
11760  const uint32_t cdat = AV_RB32("cdat");
11761  const uint32_t cdt2 = AV_RB32("cdt2");
11762  int ret, out_size = 0;
11763 
11764  /* a valid payload must have size, 4cc, and at least 1 byte pair: */
11765  if (src_size < 10)
11766  return AVERROR_INVALIDDATA;
11767 
11768  /* avoid an int overflow: */
11769  if ((src_size - 8) / 2 >= INT_MAX / 3)
11770  return AVERROR_INVALIDDATA;
11771 
11772  ret = av_new_packet(pkt, ((src_size - 8) / 2) * 3);
11773  if (ret < 0)
11774  return ret;
11775 
11776  /* parse and re-format the c608 payload in one pass. */
11777  while (src_size >= 10) {
11778  const uint32_t atom_size = avio_rb32(pb);
11779  const uint32_t atom_type = avio_rb32(pb);
11780  const uint32_t data_size = atom_size - 8;
11781  const uint8_t cc_field =
11782  atom_type == cdat ? 1 :
11783  atom_type == cdt2 ? 2 :
11784  0;
11785 
11786  /* account for bytes consumed for atom size and type. */
11787  src_size -= 8;
11788 
11789  /* make sure the data size stays within the buffer boundaries. */
11790  if (data_size < 2 || data_size > src_size) {
11792  break;
11793  }
11794 
11795  /* make sure the data size is consistent with N byte pairs. */
11796  if (data_size % 2 != 0) {
11798  break;
11799  }
11800 
11801  if (!cc_field) {
11802  /* neither cdat or cdt2 ... skip it */
11803  avio_skip(pb, data_size);
11804  src_size -= data_size;
11805  continue;
11806  }
11807 
11808  for (uint32_t i = 0; i < data_size; i += 2) {
11809  pkt->data[out_size] = (0x1F << 3) | (1 << 2) | (cc_field - 1);
11810  pkt->data[out_size + 1] = avio_r8(pb);
11811  pkt->data[out_size + 2] = avio_r8(pb);
11812  out_size += 3;
11813  src_size -= 2;
11814  }
11815  }
11816 
11817  if (src_size > 0)
11818  /* skip any remaining unread portion of the input payload */
11819  avio_skip(pb, src_size);
11820 
11822  return ret;
11823 }
11824 
11826  int64_t current_index, AVPacket *pkt)
11827 {
11828  MOVContext *mov = s->priv_data;
11829  MOVStreamContext *sc = st->priv_data;
11830 
11831  pkt->stream_index = sc->ffindex;
11832  pkt->dts = sample->timestamp;
11833  if (sample->flags & AVINDEX_DISCARD_FRAME) {
11835  }
11836  if (sc->stts_count && sc->tts_index < sc->tts_count)
11837  pkt->duration = sc->tts_data[sc->tts_index].duration;
11838  if (sc->ctts_count && sc->tts_index < sc->tts_count) {
11840  } else {
11841  if (pkt->duration == 0) {
11842  int64_t next_dts = (sc->current_sample < ffstream(st)->nb_index_entries) ?
11844  if (next_dts >= pkt->dts)
11845  pkt->duration = next_dts - pkt->dts;
11846  }
11847  pkt->pts = pkt->dts;
11848  }
11849 
11850  if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO && !mov->fragment.found_tfhd &&
11852  int64_t pts = av_rescale_q(pkt->pts, st->time_base, (AVRational){ 1, st->codecpar->sample_rate });
11853  int64_t total = av_rescale_q(st->duration, st->time_base, (AVRational){ 1, st->codecpar->sample_rate });
11855 
11856  if (st->duration < pkt->pts) {
11857  duration = 0;
11858  } else
11859  duration = FFMIN(duration, (uint64_t)st->duration - pkt->pts);
11860 
11861  duration = av_rescale_q(duration, st->time_base, (AVRational){ 1, st->codecpar->sample_rate });
11862 
11863  if (!ffstream(st)->first_discard_sample)
11865  if (!ffstream(st)->last_discard_sample)
11866  ffstream(st)->last_discard_sample = total;
11867  }
11868 
11869  if (sc->tts_data && sc->tts_index < sc->tts_count) {
11870  /* update tts context */
11871  sc->tts_sample++;
11872  if (sc->tts_index < sc->tts_count &&
11873  sc->tts_data[sc->tts_index].count == sc->tts_sample) {
11874  sc->tts_index++;
11875  sc->tts_sample = 0;
11876  }
11877  }
11878 
11879  if (sc->sdtp_data && sc->current_sample <= sc->sdtp_count) {
11880  uint8_t sample_flags = sc->sdtp_data[sc->current_sample - 1];
11881  uint8_t sample_is_depended_on = (sample_flags >> 2) & 0x3;
11882  pkt->flags |= sample_is_depended_on == MOV_SAMPLE_DEPENDENCY_NO ? AV_PKT_FLAG_DISPOSABLE : 0;
11883  }
11884  pkt->flags |= sample->flags & AVINDEX_KEYFRAME ? AV_PKT_FLAG_KEY : 0;
11885  pkt->pos = sample->pos;
11886 
11887  /* Multiple stsd handling. */
11888  if (sc->stsc_data) {
11889  if (sc->stsc_data[sc->stsc_index].id > 0 &&
11890  sc->stsc_data[sc->stsc_index].id - 1 < sc->stsd_count &&
11891  sc->stsc_data[sc->stsc_index].id - 1 != sc->last_stsd_index) {
11892  int ret = mov_change_extradata(st, pkt);
11893  if (ret < 0)
11894  return ret;
11895  }
11896 
11897  /* Update the stsc index for the next sample */
11898  sc->stsc_sample++;
11899  if (mov_stsc_index_valid(sc->stsc_index, sc->stsc_count) &&
11900  mov_get_stsc_samples(sc, sc->stsc_index) == sc->stsc_sample) {
11901  sc->stsc_index++;
11902  sc->stsc_sample = 0;
11903  }
11904  }
11905 
11906  return 0;
11907 }
11908 
11910 {
11911  MOVContext *mov = s->priv_data;
11912  MOVStreamContext *sc;
11914  AVStream *st = NULL;
11915  FFStream *avsti = NULL;
11916  int64_t current_index;
11917  int ret;
11918  int i;
11919  mov->fc = s;
11920  retry:
11921  if (s->pb->pos == 0) {
11922 
11923  // Discard current fragment index
11924  if (mov->frag_index.allocated_size > 0) {
11925  for(int i = 0; i < mov->frag_index.nb_items; i++) {
11927  }
11928  av_freep(&mov->frag_index.item);
11929  mov->frag_index.nb_items = 0;
11930  mov->frag_index.allocated_size = 0;
11931  mov->frag_index.current = -1;
11932  mov->frag_index.complete = 0;
11933  }
11934 
11935  for (i = 0; i < s->nb_streams; i++) {
11936  AVStream *avst = s->streams[i];
11937  MOVStreamContext *msc = avst->priv_data;
11938 
11939  // Clear current sample
11940  mov_current_sample_set(msc, 0);
11941  msc->tts_index = 0;
11942 
11943  // Discard current index entries
11944  avsti = ffstream(avst);
11945  if (avsti->index_entries_allocated_size > 0) {
11946  av_freep(&avsti->index_entries);
11947  avsti->index_entries_allocated_size = 0;
11948  avsti->nb_index_entries = 0;
11949  }
11950  }
11951 
11952  if ((ret = mov_switch_root(s, -1, -1)) < 0)
11953  return ret;
11954  }
11955  sample = mov_find_next_sample(s, &st);
11956  if (!sample || (mov->next_root_atom && sample->pos > mov->next_root_atom)) {
11957  if (!mov->next_root_atom)
11958  return AVERROR_EOF;
11959  if ((ret = mov_switch_root(s, mov->next_root_atom, -1)) < 0)
11960  return ret;
11961  goto retry;
11962  }
11963  sc = st->priv_data;
11964  /* must be done just before reading, to avoid infinite loop on sample */
11965  current_index = sc->current_index;
11967 
11968  if (mov->next_root_atom) {
11969  sample->pos = FFMIN(sample->pos, mov->next_root_atom);
11970  sample->size = FFMIN(sample->size, (mov->next_root_atom - sample->pos));
11971  }
11972 
11973  if (st->discard != AVDISCARD_ALL || sc->iamf) {
11974  int64_t ret64 = avio_seek(sc->pb, sample->pos, SEEK_SET);
11975  if (ret64 != sample->pos) {
11976  av_log(mov->fc, AV_LOG_ERROR, "stream %d, offset 0x%"PRIx64": partial file\n",
11977  sc->ffindex, sample->pos);
11978  if (should_retry(sc->pb, ret64)) {
11980  } else if (ret64 < 0) {
11981  return (int)ret64;
11982  }
11983  return AVERROR_INVALIDDATA;
11984  }
11985 
11986  if (st->discard == AVDISCARD_NONKEY && !(sample->flags & AVINDEX_KEYFRAME)) {
11987  av_log(mov->fc, AV_LOG_DEBUG, "Nonkey frame from stream %d discarded due to AVDISCARD_NONKEY\n", sc->ffindex);
11988  goto retry;
11989  }
11990 
11991  if (st->codecpar->codec_id == AV_CODEC_ID_EIA_608 && sample->size > 8)
11992  ret = get_eia608_packet(sc->pb, pkt, sample->size);
11993 #if CONFIG_IAMFDEC
11994  else if (sc->iamf) {
11995  int64_t pts, dts, pos, duration;
11996  int flags, size = sample->size;
11997  ret = mov_finalize_packet(s, st, sample, current_index, pkt);
11998  pts = pkt->pts; dts = pkt->dts;
11999  pos = pkt->pos; flags = pkt->flags;
12000  duration = pkt->duration;
12001  while (!ret && size > 0) {
12002  ret = ff_iamf_read_packet(s, sc->iamf, sc->pb, size, sc->iamf_stream_offset, pkt);
12003  if (ret < 0) {
12004  if (should_retry(sc->pb, ret))
12006  return ret;
12007  }
12008  size -= ret;
12009 
12010  if (pkt->flags & AV_PKT_FLAG_DISCARD) {
12012  ret = 0;
12013  continue;
12014  }
12015  pkt->pts = pts; pkt->dts = dts;
12016  pkt->pos = pos; pkt->flags |= flags;
12017  pkt->duration = duration;
12018  ret = ff_buffer_packet(s, pkt);
12019  }
12020  if (!ret)
12021  return FFERROR_REDO;
12022  }
12023 #endif
12024  else if (st->codecpar->codec_id == AV_CODEC_ID_APV && sample->size > 4) {
12025  uint32_t au_size = avio_rb32(sc->pb);
12026  int explode = !!(mov->fc->error_recognition & AV_EF_EXPLODE);
12027  if (au_size > sample->size - 4) {
12028  av_log(s, explode ? AV_LOG_ERROR : AV_LOG_WARNING,
12029  "APV au_size %u exceeds sample body %d\n",
12030  au_size, sample->size - 4);
12031  if (explode)
12032  return AVERROR_INVALIDDATA;
12033  au_size = sample->size - 4;
12034  }
12035  ret = av_get_packet(sc->pb, pkt, au_size);
12036  } else
12037  ret = av_get_packet(sc->pb, pkt, sample->size);
12038  if (ret < 0) {
12039  if (should_retry(sc->pb, ret)) {
12041  }
12042  return ret;
12043  }
12044 #if CONFIG_DV_DEMUXER
12045  if (mov->dv_demux && sc->dv_audio_container) {
12048  if (ret < 0)
12049  return ret;
12051  if (ret < 0)
12052  return ret;
12053  }
12054 #endif
12055  if (sc->has_palette) {
12056  uint8_t *pal;
12057 
12059  if (!pal) {
12060  av_log(mov->fc, AV_LOG_ERROR, "Cannot append palette to packet\n");
12061  } else {
12062  memcpy(pal, sc->palette, AVPALETTE_SIZE);
12063  sc->has_palette = 0;
12064  }
12065  }
12066  if (st->codecpar->codec_id == AV_CODEC_ID_MP3 && !ffstream(st)->need_parsing && pkt->size > 4) {
12067  if (ff_mpa_check_header(AV_RB32(pkt->data)) < 0)
12069  }
12070  }
12071 
12072  ret = mov_finalize_packet(s, st, sample, current_index, pkt);
12073  if (ret < 0)
12074  return ret;
12075 
12076  if (st->discard == AVDISCARD_ALL)
12077  goto retry;
12078 
12079  if (mov->aax_mode)
12080  aax_filter(pkt->data, pkt->size, mov);
12081 
12082  ret = cenc_filter(mov, st, sc, pkt, current_index);
12083  if (ret < 0) {
12084  return ret;
12085  }
12086 
12087  return 0;
12088 }
12089 
12091 {
12092  MOVContext *mov = s->priv_data;
12093  int index;
12094 
12095  if (!mov->frag_index.complete)
12096  return 0;
12097 
12098  index = search_frag_timestamp(s, &mov->frag_index, st, timestamp);
12099  if (index < 0)
12100  index = 0;
12101  if (!mov->frag_index.item[index].headers_read)
12102  return mov_switch_root(s, -1, index);
12103  if (index + 1 < mov->frag_index.nb_items)
12104  mov->next_root_atom = mov->frag_index.item[index + 1].moof_offset;
12105 
12106  return 0;
12107 }
12108 
12109 static int is_open_key_sample(const MOVStreamContext *sc, int sample)
12110 {
12111  // TODO: a bisect search would scale much better
12112  for (int i = 0; i < sc->open_key_samples_count; i++) {
12113  const int oks = sc->open_key_samples[i];
12114  if (oks == sample)
12115  return 1;
12116  if (oks > sample) /* list is monotically increasing so we can stop early */
12117  break;
12118  }
12119  return 0;
12120 }
12121 
12122 /*
12123  * Some key sample may be key frames but not IDR frames, so a random access to
12124  * them may not be allowed.
12125  */
12126 static int can_seek_to_key_sample(AVStream *st, int sample, int64_t requested_pts)
12127 {
12128  MOVStreamContext *sc = st->priv_data;
12129  FFStream *const sti = ffstream(st);
12130  int64_t key_sample_dts, key_sample_pts;
12131 
12132  if (st->codecpar->codec_id != AV_CODEC_ID_HEVC)
12133  return 1;
12134 
12135  if (sample >= sc->sample_offsets_count)
12136  return 1;
12137 
12138  av_assert0(sample >= 0);
12139  key_sample_dts = sti->index_entries[sample].timestamp;
12140  key_sample_pts = key_sample_dts + sc->sample_offsets[sample] + sc->dts_shift;
12141 
12142  /*
12143  * If the sample needs to be presented before an open key sample, they may
12144  * not be decodable properly, even though they come after in decoding
12145  * order.
12146  */
12147  if (is_open_key_sample(sc, sample) && key_sample_pts > requested_pts)
12148  return 0;
12149 
12150  return 1;
12151 }
12152 
12153 static int mov_seek_stream(AVFormatContext *s, AVStream *st, int64_t timestamp, int flags)
12154 {
12155  MOVStreamContext *sc = st->priv_data;
12156  FFStream *const sti = ffstream(st);
12157  int sample, time_sample, ret, requested_sample;
12158  int64_t next_ts;
12159  unsigned int i;
12160 
12161  // Here we consider timestamp to be PTS, hence try to offset it so that we
12162  // can search over the DTS timeline.
12163  timestamp -= (sc->min_corrected_pts + sc->dts_shift);
12164 
12165  ret = mov_seek_fragment(s, st, timestamp);
12166  if (ret < 0)
12167  return ret;
12168 
12169  for (;;) {
12170  sample = av_index_search_timestamp(st, timestamp, flags);
12171  av_log(s, AV_LOG_TRACE, "stream %d, timestamp %"PRId64", sample %d\n", st->index, timestamp, sample);
12172  if (sample < 0 && sti->nb_index_entries && timestamp < sti->index_entries[0].timestamp)
12173  sample = 0;
12174  if (sample < 0) /* not sure what to do */
12175  return AVERROR_INVALIDDATA;
12176 
12177  if (!sample || can_seek_to_key_sample(st, sample, timestamp))
12178  break;
12179 
12180  next_ts = timestamp - FFMAX(sc->min_sample_duration, 1);
12181  requested_sample = av_index_search_timestamp(st, next_ts, flags);
12182  if (requested_sample < 0)
12183  return AVERROR_INVALIDDATA;
12184 
12185  // If we've reached a different sample trying to find a good pts to
12186  // seek to, give up searching because we'll end up seeking back to
12187  // sample 0 on every seek.
12188  if (sample != requested_sample && !can_seek_to_key_sample(st, requested_sample, next_ts))
12189  break;
12190 
12191  timestamp = next_ts;
12192  }
12193 
12195  av_log(s, AV_LOG_TRACE, "stream %d, found sample %d\n", st->index, sc->current_sample);
12196  /* adjust time to sample index */
12197  if (sc->tts_data) {
12198  time_sample = 0;
12199  for (i = 0; i < sc->tts_count; i++) {
12200  int next = time_sample + sc->tts_data[i].count;
12201  if (next > sc->current_sample) {
12202  sc->tts_index = i;
12203  sc->tts_sample = sc->current_sample - time_sample;
12204  break;
12205  }
12206  time_sample = next;
12207  }
12208  }
12209 
12210  /* adjust stsd index */
12211  if (sc->chunk_count) {
12212  time_sample = 0;
12213  for (i = 0; i < sc->stsc_count; i++) {
12214  int64_t next = time_sample + mov_get_stsc_samples(sc, i);
12215  if (next > sc->current_sample) {
12216  sc->stsc_index = i;
12217  sc->stsc_sample = sc->current_sample - time_sample;
12218  break;
12219  }
12220  av_assert0(next == (int)next);
12221  time_sample = next;
12222  }
12223  }
12224 
12225  return sample;
12226 }
12227 
12229 {
12230  FFStream *const sti = ffstream(st);
12231  int64_t first_ts = sti->index_entries[0].timestamp;
12233  int64_t off;
12234 
12236  return 0;
12237 
12238  /* compute skip samples according to stream initial_padding, seek ts and first ts */
12239  off = av_rescale_q(ts - first_ts, st->time_base,
12240  (AVRational){1, st->codecpar->sample_rate});
12241  return FFMAX(st->codecpar->initial_padding - off, 0);
12242 }
12243 
12244 static int mov_read_seek(AVFormatContext *s, int stream_index, int64_t sample_time, int flags)
12245 {
12246  MOVContext *mc = s->priv_data;
12247  AVStream *st;
12248  FFStream *sti;
12249  int sample;
12250  int i;
12251 
12252  if (stream_index >= s->nb_streams)
12253  return AVERROR_INVALIDDATA;
12254 
12255  st = s->streams[stream_index];
12256  sti = ffstream(st);
12257  sample = mov_seek_stream(s, st, sample_time, flags);
12258  if (sample < 0)
12259  return sample;
12260 
12261  if (mc->seek_individually) {
12262  /* adjust seek timestamp to found sample timestamp */
12263  int64_t seek_timestamp = sti->index_entries[sample].timestamp;
12265 
12266  for (i = 0; i < s->nb_streams; i++) {
12267  AVStream *const st = s->streams[i];
12268  FFStream *const sti = ffstream(st);
12269  int64_t timestamp;
12270 
12271  if (stream_index == i)
12272  continue;
12273 
12274  timestamp = av_rescale_q(seek_timestamp, s->streams[stream_index]->time_base, st->time_base);
12275  sample = mov_seek_stream(s, st, timestamp, flags);
12276  if (sample >= 0)
12278  }
12279  } else {
12280  for (i = 0; i < s->nb_streams; i++) {
12281  MOVStreamContext *sc;
12282  st = s->streams[i];
12283  sc = st->priv_data;
12284  mov_current_sample_set(sc, 0);
12285  }
12286  while (1) {
12287  MOVStreamContext *sc;
12289  if (!entry)
12290  return AVERROR_INVALIDDATA;
12291  sc = st->priv_data;
12292  if (sc->ffindex == stream_index && sc->current_sample == sample)
12293  break;
12295  }
12296  }
12297  return 0;
12298 }
12299 
12300 #define OFFSET(x) offsetof(MOVContext, x)
12301 #define FLAGS AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM
12302 static const AVOption mov_options[] = {
12303  {"use_absolute_path",
12304  "allow using absolute path when opening alias, this is a possible security issue",
12305  OFFSET(use_absolute_path), AV_OPT_TYPE_BOOL, {.i64 = 0},
12306  0, 1, FLAGS},
12307  {"seek_streams_individually",
12308  "Seek each stream individually to the closest point",
12309  OFFSET(seek_individually), AV_OPT_TYPE_BOOL, { .i64 = 1 },
12310  0, 1, FLAGS},
12311  {"ignore_editlist", "Ignore the edit list atom.", OFFSET(ignore_editlist), AV_OPT_TYPE_BOOL, {.i64 = 0},
12312  0, 1, FLAGS},
12313  {"advanced_editlist",
12314  "Modify the AVIndex according to the editlists. Use this option to decode in the order specified by the edits.",
12315  OFFSET(advanced_editlist), AV_OPT_TYPE_BOOL, {.i64 = 1},
12316  0, 1, FLAGS},
12317  {"ignore_chapters", "", OFFSET(ignore_chapters), AV_OPT_TYPE_BOOL, {.i64 = 0},
12318  0, 1, FLAGS},
12319  {"use_mfra_for",
12320  "use mfra for fragment timestamps",
12321  OFFSET(use_mfra_for), AV_OPT_TYPE_INT, {.i64 = FF_MOV_FLAG_MFRA_AUTO},
12323  .unit = "use_mfra_for"},
12324  {"auto", "auto", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_AUTO}, 0, 0,
12325  FLAGS, .unit = "use_mfra_for" },
12326  {"dts", "dts", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_DTS}, 0, 0,
12327  FLAGS, .unit = "use_mfra_for" },
12328  {"pts", "pts", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_PTS}, 0, 0,
12329  FLAGS, .unit = "use_mfra_for" },
12330  {"use_tfdt", "use tfdt for fragment timestamps", OFFSET(use_tfdt), AV_OPT_TYPE_BOOL, {.i64 = 1},
12331  0, 1, FLAGS},
12332  { "export_all", "Export unrecognized metadata entries", OFFSET(export_all),
12333  AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = FLAGS },
12334  { "export_xmp", "Export full XMP metadata", OFFSET(export_xmp),
12335  AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = FLAGS },
12336  { "activation_bytes", "Secret bytes for Audible AAX files", OFFSET(activation_bytes),
12338  { "audible_key", "AES-128 Key for Audible AAXC files", OFFSET(audible_key),
12340  { "audible_iv", "AES-128 IV for Audible AAXC files", OFFSET(audible_iv),
12342  { "audible_fixed_key", // extracted from libAAX_SDK.so and AAXSDKWin.dll files!
12343  "Fixed key used for handling Audible AAX files", OFFSET(audible_fixed_key),
12344  AV_OPT_TYPE_BINARY, {.str="77214d4b196a87cd520045fd20a51d67"},
12345  .flags = AV_OPT_FLAG_DECODING_PARAM },
12346  { "decryption_key", "The default media decryption key (hex)", OFFSET(decryption_default_key), AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM },
12347  { "decryption_keys", "The media decryption keys by KID (hex)", OFFSET(decryption_keys), AV_OPT_TYPE_DICT, .flags = AV_OPT_FLAG_DECODING_PARAM },
12348  { "enable_drefs", "Enable external track support.", OFFSET(enable_drefs), AV_OPT_TYPE_BOOL,
12349  {.i64 = 0}, 0, 1, FLAGS },
12350  { "max_stts_delta", "treat offsets above this value as invalid", OFFSET(max_stts_delta), AV_OPT_TYPE_INT, {.i64 = UINT_MAX-48000*10 }, 0, UINT_MAX, .flags = AV_OPT_FLAG_DECODING_PARAM },
12351  { "interleaved_read", "Interleave packets from multiple tracks at demuxer level", OFFSET(interleaved_read), AV_OPT_TYPE_BOOL, {.i64 = 1 }, 0, 1, .flags = AV_OPT_FLAG_DECODING_PARAM },
12352 
12353  { NULL },
12354 };
12355 
12356 static const AVClass mov_class = {
12357  .class_name = "mov,mp4,m4a,3gp,3g2,mj2",
12358  .item_name = av_default_item_name,
12359  .option = mov_options,
12360  .version = LIBAVUTIL_VERSION_INT,
12361 };
12362 
12364  .p.name = "mov,mp4,m4a,3gp,3g2,mj2",
12365  .p.long_name = NULL_IF_CONFIG_SMALL("QuickTime / MOV"),
12366  .p.priv_class = &mov_class,
12367  .p.extensions = "mov,mp4,m4a,3gp,3g2,mj2,psp,m4v,m4b,ism,ismv,isma,f4v,avif,heic,heif",
12369  .priv_data_size = sizeof(MOVContext),
12370  .flags_internal = FF_INFMT_FLAG_INIT_CLEANUP,
12371  .read_probe = mov_probe,
12376 };
HEIFItemRef::item_id
int item_id
Definition: isom.h:295
avpriv_new_chapter
AVChapter * avpriv_new_chapter(AVFormatContext *s, int64_t id, AVRational time_base, int64_t start, int64_t end, const char *title)
Add a new chapter.
Definition: demux_utils.c:43
MOVStreamContext::ctts_allocated_size
unsigned int ctts_allocated_size
Definition: isom.h:197
item_name
item_name
Definition: libkvazaar.c:311
AV_CODEC_ID_PCM_S16LE
@ AV_CODEC_ID_PCM_S16LE
Definition: codec_id.h:330
AV_EXIF_T_OFF
@ AV_EXIF_T_OFF
The first four bytes point to the actual start, then it's AV_EXIF_TIFF_HEADER.
Definition: exif.h:68
mov_finalize_stsd_entry
static int mov_finalize_stsd_entry(MOVContext *c, AVStream *st)
Definition: mov.c:3328
mov_read_chpl
static int mov_read_chpl(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:614
AVMasteringDisplayMetadata::has_primaries
int has_primaries
Flag indicating whether the display primaries (and white point) are set.
Definition: mastering_display_metadata.h:62
mov_read_frma
static int mov_read_frma(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:7721
mov_read_meta
static int mov_read_meta(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5813
AV_CODEC_ID_EIA_608
@ AV_CODEC_ID_EIA_608
Definition: codec_id.h:575
AV_PKT_DATA_DISPLAYMATRIX
@ AV_PKT_DATA_DISPLAYMATRIX
This side data contains a 3x3 transformation matrix describing an affine transformation that needs to...
Definition: packet.h:105
av_packet_unref
void av_packet_unref(AVPacket *pkt)
Wipe the packet.
Definition: packet.c:434
MOVContext::found_iloc
int found_iloc
'iloc' atom has been found
Definition: isom.h:331
AV_CODEC_ID_MACE6
@ AV_CODEC_ID_MACE6
Definition: codec_id.h:462
MOVFragmentStreamInfo::first_tfra_pts
int64_t first_tfra_pts
Definition: isom.h:148
ff_rfps_add_frame
int ff_rfps_add_frame(AVFormatContext *ic, AVStream *st, int64_t ts)
add frame for rfps calculation.
Definition: demux.c:2336
read_image_iovl
static int read_image_iovl(AVFormatContext *s, const HEIFGrid *grid, AVStreamGroupTileGrid *tile_grid)
Definition: mov.c:10783
AV_PRIMARY_EYE_RIGHT
@ AV_PRIMARY_EYE_RIGHT
Right eye.
Definition: stereo3d.h:188
mov_read_irot
static int mov_read_irot(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:9698
AVMEDIA_TYPE_SUBTITLE
@ AVMEDIA_TYPE_SUBTITLE
Definition: avutil.h:203
AVIAMFSubmix::elements
AVIAMFSubmixElement ** elements
Array of submix elements.
Definition: iamf.h:568
skip_bits_long
static void skip_bits_long(GetBitContext *s, int n)
Skips the specified number of bits.
Definition: get_bits.h:280
AV_LOG_WARNING
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:216
AV_BPRINT_SIZE_UNLIMITED
#define AV_BPRINT_SIZE_UNLIMITED
MOV_TFHD_DEFAULT_FLAGS
#define MOV_TFHD_DEFAULT_FLAGS
Definition: isom.h:412
PUT_UTF8
#define PUT_UTF8(val, tmp, PUT_BYTE)
Definition: common.h:530
AV_TIMECODE_STR_SIZE
#define AV_TIMECODE_STR_SIZE
Definition: timecode.h:33
av_aes_init
int av_aes_init(AVAES *a, const uint8_t *key, int key_bits, int decrypt)
Initialize an AVAES context.
Definition: aes.c:231
AV_CODEC_ID_PCM_F32BE
@ AV_CODEC_ID_PCM_F32BE
Definition: codec_id.h:350
FFStream::skip_samples
int skip_samples
Number of samples to skip at the start of the frame decoded from the next packet.
Definition: internal.h:208
MOVStreamContext::audio_cid
int16_t audio_cid
stsd audio compression id
Definition: isom.h:227
AVMasteringDisplayMetadata::max_luminance
AVRational max_luminance
Max luminance of mastering display (cd/m^2).
Definition: mastering_display_metadata.h:57
AVSphericalProjection
AVSphericalProjection
Projection of the video surface(s) on a sphere.
Definition: spherical.h:47
AV_CODEC_ID_ADPCM_MS
@ AV_CODEC_ID_ADPCM_MS
Definition: codec_id.h:375
AVCodecParameters::extradata
uint8_t * extradata
Extra binary data needed for initializing the decoder, codec-dependent.
Definition: codec_par.h:71
mov_read_dops
static int mov_read_dops(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:8849
can_seek_to_key_sample
static int can_seek_to_key_sample(AVStream *st, int sample, int64_t requested_pts)
Definition: mov.c:12126
name
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf default minimum maximum flags name is the option name
Definition: writing_filters.txt:88
AV_CODEC_ID_ADPCM_IMA_QT
@ AV_CODEC_ID_ADPCM_IMA_QT
Definition: codec_id.h:369
entry
#define entry
Definition: aom_film_grain_template.c:66
AVFMT_NO_BYTE_SEEK
#define AVFMT_NO_BYTE_SEEK
Format does not allow seeking by bytes.
Definition: avformat.h:506
AV_EF_EXPLODE
#define AV_EF_EXPLODE
abort decoding on minor error detection
Definition: defs.h:51
AVStreamGroup::id
int64_t id
Group type-specific group ID.
Definition: avformat.h:1178
AV_CODEC_ID_AC3
@ AV_CODEC_ID_AC3
Definition: codec_id.h:455
HEIFItem::name
char * name
Definition: isom.h:302
AV_STEREO3D_VIEW_LEFT
@ AV_STEREO3D_VIEW_LEFT
Frame contains only the left view.
Definition: stereo3d.h:158
MOVStreamContext::sync_group
MOVSbgp * sync_group
Definition: isom.h:247
MOVStreamContext::height
int height
tkhd height
Definition: isom.h:234
MOVContext::moov_retry
int moov_retry
Definition: isom.h:359
MOV_TRUN_SAMPLE_FLAGS
#define MOV_TRUN_SAMPLE_FLAGS
Definition: isom.h:420
AV_PKT_DATA_AMBIENT_VIEWING_ENVIRONMENT
@ AV_PKT_DATA_AMBIENT_VIEWING_ENVIRONMENT
Ambient viewing environment metadata, as defined by H.274.
Definition: packet.h:327
MOVContext::nb_chapter_tracks
unsigned int nb_chapter_tracks
Definition: isom.h:347
mix
static int mix(int c0, int c1)
Definition: 4xm.c:717
MOVStreamContext::last_stsd_index
int last_stsd_index
Definition: isom.h:262
ff_ac3_channel_layout_tab
const uint16_t ff_ac3_channel_layout_tab[8]
Map audio coding mode (acmod) to channel layout mask.
Definition: ac3_channel_layout_tab.h:31
r
const char * r
Definition: vf_curves.c:127
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
flag
int flag
Definition: cpu.c:40
get_heif_item
static HEIFItem * get_heif_item(MOVContext *c, unsigned id)
Get the requested item.
Definition: mov.c:195
MOV_TKHD_FLAG_ENABLED
#define MOV_TKHD_FLAG_ENABLED
Definition: isom.h:433
AV_CH_TOP_SIDE_LEFT
#define AV_CH_TOP_SIDE_LEFT
Definition: channel_layout.h:200
AVCodecParameters::codec_type
enum AVMediaType codec_type
General type of the encoded data.
Definition: codec_par.h:53
AVStreamGroup::tile_grid
struct AVStreamGroupTileGrid * tile_grid
Definition: avformat.h:1194
AVFMT_SHOW_IDS
#define AVFMT_SHOW_IDS
Show format stream IDs numbers.
Definition: avformat.h:496
AVSphericalMapping::projection
enum AVSphericalProjection projection
Projection type.
Definition: spherical.h:104
AV_WL32
#define AV_WL32(p, v)
Definition: intreadwrite.h:422
av_exif_parse_buffer
int av_exif_parse_buffer(void *logctx, const uint8_t *buf, size_t size, AVExifMetadata *ifd, enum AVExifHeaderMode header_mode)
Decodes the EXIF data provided in the buffer and writes it into the struct *ifd.
Definition: exif.c:882
AV_STREAM_GROUP_PARAMS_LCEVC
@ AV_STREAM_GROUP_PARAMS_LCEVC
Definition: avformat.h:1151
MOVStreamContext::extradata
uint8_t ** extradata
extradata array (and size) for multiple stsd
Definition: isom.h:260
mov_class
static const AVClass mov_class
Definition: mov.c:12356
AVSphericalMapping::bound_bottom
uint32_t bound_bottom
Distance from the bottom edge.
Definition: spherical.h:188
MOVStreamContext::open_key_samples
int * open_key_samples
Definition: isom.h:252
AVUUID
uint8_t AVUUID[AV_UUID_LEN]
Definition: uuid.h:60
MovTref
Definition: isom.h:94
mov_parse_tmcd_streams
static int mov_parse_tmcd_streams(AVFormatContext *s)
Definition: mov.c:11141
AV_CH_TOP_FRONT_CENTER
#define AV_CH_TOP_FRONT_CENTER
Definition: channel_layout.h:188
out
static FILE * out
Definition: movenc.c:55
MOVFragmentStreamInfo
Definition: isom.h:145
AV_CHANNEL_LAYOUT_STEREO
#define AV_CHANNEL_LAYOUT_STEREO
Definition: channel_layout.h:395
AVFieldOrder
AVFieldOrder
Definition: defs.h:211
mov_read_targa_y216
static int mov_read_targa_y216(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2415
mov_read_chnl
static int mov_read_chnl(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1317
mov_read_moof
static int mov_read_moof(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1945
av_bprint_init
void av_bprint_init(AVBPrint *buf, unsigned size_init, unsigned size_max)
Definition: bprint.c:69
ctype
#define ctype
Definition: afir_template.c:46
AV_PKT_DATA_FRAME_CROPPING
@ AV_PKT_DATA_FRAME_CROPPING
The number of pixels to discard from the top/bottom/left/right border of the decoded frame to obtain ...
Definition: packet.h:340
av_exif_write
int av_exif_write(void *logctx, const AVExifMetadata *ifd, AVBufferRef **buffer, enum AVExifHeaderMode header_mode)
Allocates a buffer using av_malloc of an appropriate size and writes the EXIF data represented by ifd...
Definition: exif.c:753
AVCodecParameters
This struct describes the properties of an encoded stream.
Definition: codec_par.h:49
AV_CH_LOW_FREQUENCY_2
#define AV_CH_LOW_FREQUENCY_2
Definition: channel_layout.h:199
HEIFItem::icc_profile
uint8_t * icc_profile
Definition: isom.h:313
AVFMT_FLAG_IGNIDX
#define AVFMT_FLAG_IGNIDX
Ignore index.
Definition: avformat.h:1486
AVExifMetadata
Definition: exif.h:75
sanity_checks
static int sanity_checks(void *log_obj, MOVStreamContext *sc, int index)
Definition: mov.c:5429
av_stristr
char * av_stristr(const char *s1, const char *s2)
Locate the first case-independent occurrence in the string haystack of the string needle.
Definition: avstring.c:58
AVCodecParameters::color_space
enum AVColorSpace color_space
Definition: codec_par.h:192
avformat_new_stream
AVStream * avformat_new_stream(AVFormatContext *s, const struct AVCodec *c)
Add a new stream to a media file.
ff_replaygain_export
int ff_replaygain_export(AVStream *st, AVDictionary *metadata)
Parse replaygain tags and export them as per-stream side data.
Definition: replaygain.c:94
tmcd_is_referenced
static int tmcd_is_referenced(AVFormatContext *s, int tmcd_id)
Definition: mov.c:10516
HEIFItem::hflip
int hflip
Definition: isom.h:309
AV_PKT_DATA_NEW_EXTRADATA
@ AV_PKT_DATA_NEW_EXTRADATA
The AV_PKT_DATA_NEW_EXTRADATA is used to notify the codec or the format that the extradata buffer was...
Definition: packet.h:56
IAMFAudioElement::nb_substreams
unsigned int nb_substreams
Definition: iamf.h:99
AVStream::priv_data
void * priv_data
Definition: avformat.h:791
AVERROR_EOF
#define AVERROR_EOF
End of file.
Definition: error.h:57
AVBufferRef::data
uint8_t * data
The data buffer.
Definition: buffer.h:90
AV_DISPOSITION_ATTACHED_PIC
#define AV_DISPOSITION_ATTACHED_PIC
The stream is stored in the file as an attached picture/"cover art" (e.g.
Definition: avformat.h:692
AVStream::discard
enum AVDiscard discard
Selects which packets can be discarded at will and do not need to be demuxed.
Definition: avformat.h:837
AV_FIELD_PROGRESSIVE
@ AV_FIELD_PROGRESSIVE
Definition: defs.h:213
mov_options
static const AVOption mov_options[]
Definition: mov.c:12302
mov_codec_id
static int mov_codec_id(AVStream *st, uint32_t format)
Definition: mov.c:2884
AV_PKT_DATA_MASTERING_DISPLAY_METADATA
@ AV_PKT_DATA_MASTERING_DISPLAY_METADATA
Mastering display metadata (based on SMPTE-2086:2014).
Definition: packet.h:219
MOVStreamContext::sample_offsets
int32_t * sample_offsets
Definition: isom.h:250
av_int2double
static av_always_inline double av_int2double(uint64_t i)
Reinterpret a 64-bit integer as a double.
Definition: intfloat.h:60
mov_read_iloc
static int mov_read_iloc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:9273
matrix
Definition: vc1dsp.c:43
AVMasteringDisplayMetadata::display_primaries
AVRational display_primaries[3][2]
CIE 1931 xy chromaticity coords of color primaries (r, g, b order).
Definition: mastering_display_metadata.h:42
AV_PKT_FLAG_DISCARD
#define AV_PKT_FLAG_DISCARD
Flag is used to discard packets which are required to maintain valid decoder state but are not requir...
Definition: packet.h:657
AVMasteringDisplayMetadata::has_luminance
int has_luminance
Flag indicating whether the luminance (min_ and max_) have been set.
Definition: mastering_display_metadata.h:67
get_bits_long
static unsigned int get_bits_long(GetBitContext *s, int n)
Read 0-32 bits.
Definition: get_bits.h:424
int64_t
long long int64_t
Definition: coverity.c:34
output
filter_frame For filters that do not use the this method is called when a frame is pushed to the filter s input It can be called at any time except in a reentrant way If the input frame is enough to produce output
Definition: filter_design.txt:226
mov_read_alac
static int mov_read_alac(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2387
MOVStreamContext::cenc
struct MOVStreamContext::@492 cenc
test_same_origin
static int test_same_origin(const char *src, const char *ref)
Definition: mov.c:5272
cbcs_scheme_decrypt
static int cbcs_scheme_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
Definition: mov.c:8666
MOVFragment::base_data_offset
uint64_t base_data_offset
Definition: isom.h:110
MOVStreamContext
Definition: isom.h:179
AVChannelLayout::map
AVChannelCustom * map
This member must be used when the channel order is AV_CHANNEL_ORDER_CUSTOM.
Definition: channel_layout.h:370
MOVStreamContext::stsc_data
MOVStsc * stsc_data
Definition: isom.h:200
ff_buffer_packet
int ff_buffer_packet(AVFormatContext *s, AVPacket *pkt)
Definition: demux.c:622
IS_MATRIX_IDENT
#define IS_MATRIX_IDENT(matrix)
Definition: mov.c:5831
AV_PROFILE_DTS_EXPRESS
#define AV_PROFILE_DTS_EXPRESS
Definition: defs.h:92
AVStreamGroup::disposition
int disposition
Stream group disposition - a combination of AV_DISPOSITION_* flags.
Definition: avformat.h:1244
AV_DISPOSITION_DEFAULT
#define AV_DISPOSITION_DEFAULT
The stream should be chosen by default among other streams of the same type, unless the user has expl...
Definition: avformat.h:639
mov_update_dts_shift
static void mov_update_dts_shift(MOVStreamContext *sc, int duration, void *logctx)
Definition: mov.c:3964
MOVStreamContext::spherical
AVSphericalMapping * spherical
Definition: isom.h:269
mask
int mask
Definition: mediacodecdec_common.c:154
AVChannelLayout::u
union AVChannelLayout::@529 u
Details about which channels are present in this layout.
out_size
static int out_size
Definition: movenc.c:56
AV_CH_TOP_FRONT_RIGHT
#define AV_CH_TOP_FRONT_RIGHT
Definition: channel_layout.h:189
AV_CODEC_ID_MPEG4
@ AV_CODEC_ID_MPEG4
Definition: codec_id.h:62
AVContentLightMetadata::MaxCLL
unsigned MaxCLL
Max content light level (cd/m^2).
Definition: mastering_display_metadata.h:111
avio_get_str16be
int avio_get_str16be(AVIOContext *pb, int maxlen, char *buf, int buflen)
MOVEncryptionIndex
Definition: isom.h:132
av_encryption_init_info_free
void av_encryption_init_info_free(AVEncryptionInitInfo *info)
Frees the given encryption init info object.
Definition: encryption_info.c:216
FFStream::first_discard_sample
int64_t first_discard_sample
If not 0, the first audio sample that should be discarded from the stream.
Definition: internal.h:225
mov_read_avss
static int mov_read_avss(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2392
AV_RB32A
#define AV_RB32A(p)
Definition: intreadwrite.h:575
MOVContext::primary_item_id
int primary_item_id
Definition: isom.h:384
mode
Definition: swscale.c:71
MOVContext::found_moov
int found_moov
'moov' atom has been found
Definition: isom.h:330
ff_iamf_read_packet
int ff_iamf_read_packet(AVFormatContext *s, IAMFDemuxContext *c, AVIOContext *pb, int max_size, int stream_id_offset, AVPacket *pkt)
Definition: iamf_reader.c:308
mov_read_custom
static int mov_read_custom(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5654
pixdesc.h
cleanup
static av_cold void cleanup(FlashSV2Context *s)
Definition: flashsv2enc.c:130
AVFormatContext::streams
AVStream ** streams
A list of all streams in the file.
Definition: avformat.h:1401
HEIFGrid::nb_tiles
int nb_tiles
Definition: isom.h:322
ID3v1_GENRE_MAX
#define ID3v1_GENRE_MAX
Definition: id3v1.h:29
MOVSbgp
Definition: isom.h:127
MOVCtts
Definition: isom.h:68
AVPacketSideData
This structure stores auxiliary information for decoding, presenting, or otherwise processing the cod...
Definition: packet.h:424
mov_read_extradata
static int mov_read_extradata(MOVContext *c, AVIOContext *pb, MOVAtom atom, enum AVCodecID codec_id)
Definition: mov.c:2361
AVCOL_RANGE_JPEG
@ AVCOL_RANGE_JPEG
Full range content.
Definition: pixfmt.h:783
mpegaudiodecheader.h
MOVStreamContext::rap_group_count
unsigned int rap_group_count
Definition: isom.h:244
av_display_matrix_flip
void av_display_matrix_flip(int32_t matrix[9], int hflip, int vflip)
Flip the input matrix horizontally and/or vertically.
Definition: display.c:66
mov_read_iref_cdsc
static int mov_read_iref_cdsc(MOVContext *c, AVIOContext *pb, uint32_t type, int version, uint32_t size)
Definition: mov.c:9581
av_sha_init
av_cold int av_sha_init(AVSHA *ctx, int bits)
Initialize SHA-1 or SHA-2 hashing.
Definition: sha.c:274
HEIFItem::type
int type
Definition: isom.h:311
mov_read_mvhd
static int mov_read_mvhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2047
mov_read_idat
static int mov_read_idat(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:9267
AVPacket::data
uint8_t * data
Definition: packet.h:603
MOVContext::found_mdat
int found_mdat
'mdat' atom has been found
Definition: isom.h:333
MOVStreamContext::drefs_count
unsigned drefs_count
Definition: isom.h:228
AVEncryptionInfo::crypt_byte_block
uint32_t crypt_byte_block
Only used for pattern encryption.
Definition: encryption_info.h:51
AV_PKT_DATA_ENCRYPTION_INIT_INFO
@ AV_PKT_DATA_ENCRYPTION_INIT_INFO
This side data is encryption initialization data.
Definition: packet.h:246
mov_read_avid
static int mov_read_avid(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2407
AVAmbientViewingEnvironment::ambient_light_x
AVRational ambient_light_x
Normalized x chromaticity coordinate of the environmental ambient light in the nominal viewing enviro...
Definition: ambient_viewing_environment.h:47
AVCodecParameters::seek_preroll
int seek_preroll
Number of audio samples to skip after a discontinuity.
Definition: codec_par.h:256
av_dynarray2_add
void * av_dynarray2_add(void **tab_ptr, int *nb_ptr, size_t elem_size, const uint8_t *elem_data)
Add an element of size elem_size to a dynamic array.
Definition: mem.c:341
AVOption
AVOption.
Definition: opt.h:428
MOVContext::trex_data
MOVTrackExt * trex_data
Definition: isom.h:342
mov_read_stps
static int mov_read_stps(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:3617
MOVContext::bitrates
int * bitrates
bitrates read before streams creation
Definition: isom.h:357
b
#define b
Definition: input.c:43
AVCOL_TRC_UNSPECIFIED
@ AVCOL_TRC_UNSPECIFIED
Definition: pixfmt.h:675
MOVContext::interleaved_read
int interleaved_read
Definition: isom.h:391
mov_read_tkhd
static int mov_read_tkhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5839
MOVElst::rate
float rate
Definition: isom.h:82
AVStream::avg_frame_rate
AVRational avg_frame_rate
Average framerate.
Definition: avformat.h:855
table
static const uint16_t table[]
Definition: prosumer.c:203
spherical.h
current
static struct @601 current
mov_read_colr
static int mov_read_colr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2201
data
const char data[16]
Definition: mxf.c:149
set_last_stream_little_endian
static void set_last_stream_little_endian(AVFormatContext *fc)
Definition: mov.c:2086
mov_read_strf
static int mov_read_strf(MOVContext *c, AVIOContext *pb, MOVAtom atom)
An strf atom is a BITMAPINFOHEADER struct.
Definition: mov.c:2797
AV_CODEC_ID_ALAC
@ AV_CODEC_ID_ALAC
Definition: codec_id.h:468
HEIFItem::st
AVStream * st
Definition: isom.h:299
FF_COMPLIANCE_STRICT
#define FF_COMPLIANCE_STRICT
Strictly conform to all the things in the spec no matter what consequences.
Definition: defs.h:59
AV_DICT_APPEND
#define AV_DICT_APPEND
If the entry already exists, append to it.
Definition: dict.h:82
AVIOContext::error
int error
contains the error code or 0 if no error happened
Definition: avio.h:239
AV_CODEC_ID_AMR_NB
@ AV_CODEC_ID_AMR_NB
Definition: codec_id.h:433
av_iamf_mix_presentation_free
void av_iamf_mix_presentation_free(AVIAMFMixPresentation **pmix_presentation)
Free an AVIAMFMixPresentation and all its contents.
Definition: iamf.c:536
AVStreamGroupTREF::metadata_index
unsigned int metadata_index
Index of the metadata stream in the AVStreamGroup.
Definition: avformat.h:1143
mov_parse_auxiliary_info
static int mov_parse_auxiliary_info(MOVContext *c, MOVStreamContext *sc, AVIOContext *pb, MOVEncryptionIndex *encryption_index)
Definition: mov.c:7929
mov_seek_stream
static int mov_seek_stream(AVFormatContext *s, AVStream *st, int64_t timestamp, int flags)
Definition: mov.c:12153
mov_read_saio
static int mov_read_saio(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:8075
mov_get_stsc_samples
static int64_t mov_get_stsc_samples(MOVStreamContext *sc, unsigned int index)
Definition: mov.c:3602
AV_LOG_VERBOSE
#define AV_LOG_VERBOSE
Detailed information.
Definition: log.h:226
ff_codec_wav_tags
const AVCodecTag ff_codec_wav_tags[]
Definition: riff.c:525
get_edit_list_entry
static int get_edit_list_entry(MOVContext *mov, const MOVStreamContext *msc, unsigned int edit_list_index, int64_t *edit_list_media_time, int64_t *edit_list_duration, int64_t global_timescale)
Get ith edit list entry (media time, duration).
Definition: mov.c:4173
MOVFragmentIndexItem::moof_offset
int64_t moof_offset
Definition: isom.h:159
MOVStreamContext::spherical_size
size_t spherical_size
Definition: isom.h:270
mov_change_extradata
static int mov_change_extradata(AVStream *st, AVPacket *pkt)
Definition: mov.c:11732
nb_streams
static unsigned int nb_streams
Definition: ffprobe.c:352
HEIFItemRef
Definition: isom.h:293
AV_CH_TOP_FRONT_LEFT
#define AV_CH_TOP_FRONT_LEFT
Definition: channel_layout.h:187
MP4TrackKindMapping::scheme_uri
const char * scheme_uri
Definition: isom.h:493
AVINDEX_DISCARD_FRAME
#define AVINDEX_DISCARD_FRAME
Definition: avformat.h:629
av_display_rotation_set
void av_display_rotation_set(int32_t matrix[9], double angle)
Initialize a transformation matrix describing a pure clockwise rotation by the specified angle (in de...
Definition: display.c:51
AVPacket::duration
int64_t duration
Duration of this packet in AVStream->time_base units, 0 if unknown.
Definition: packet.h:621
AVStreamGroup::tref
struct AVStreamGroupTREF * tref
Definition: avformat.h:1203
AVCodecParameters::codec_tag
uint32_t codec_tag
Additional information about the codec (corresponds to the AVI FOURCC).
Definition: codec_par.h:61
fixed_key
static const uint8_t fixed_key[]
Definition: aes_ctr.c:45
AV_SPHERICAL_EQUIRECTANGULAR_TILE
@ AV_SPHERICAL_EQUIRECTANGULAR_TILE
Video represents a portion of a sphere mapped on a flat surface using equirectangular projection.
Definition: spherical.h:68
AVStereo3D::baseline
uint32_t baseline
The distance between the centres of the lenses of the camera system, in micrometers.
Definition: stereo3d.h:228
MOVDref::dir
char * dir
Definition: isom.h:88
mov_current_sample_set
static void mov_current_sample_set(MOVStreamContext *sc, int current_sample)
Definition: mov.c:4477
mathematics.h
AVDictionary
Definition: dict.c:32
ffio_init_read_context
void ffio_init_read_context(FFIOContext *s, const uint8_t *buffer, int buffer_size)
Wrap a buffer in an AVIOContext for reading.
Definition: aviobuf.c:99
AV_PKT_FLAG_DISPOSABLE
#define AV_PKT_FLAG_DISPOSABLE
Flag is used to indicate packets that contain frames that can be discarded by the decoder.
Definition: packet.h:669
AVChannelLayout::order
enum AVChannelOrder order
Channel order used in this layout.
Definition: channel_layout.h:324
FFMAX
#define FFMAX(a, b)
Definition: macros.h:47
MOVAtom
Definition: isom.h:100
AVStreamGroupTileGrid::vertical
int vertical
Offset in pixels from the top edge of the canvas where the tile should be placed.
Definition: avformat.h:1022
iamf_parse.h
mov_read_moov
static int mov_read_moov(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1695
av_sub_q
AVRational av_sub_q(AVRational b, AVRational c)
Subtract one rational from another.
Definition: rational.c:101
cffstream
static const av_always_inline FFStream * cffstream(const AVStream *st)
Definition: internal.h:363
mov_read_esds
static int mov_read_esds(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:863
MOVStreamContext::sample_count
unsigned int sample_count
Definition: isom.h:211
MOVFragmentIndex::allocated_size
int allocated_size
Definition: isom.h:167
MOVTrackExt::flags
unsigned flags
Definition: isom.h:124
AVChannelLayout::nb_channels
int nb_channels
Number of channels in this layout.
Definition: channel_layout.h:329
key
const char * key
Definition: ffmpeg_mux_init.c:2971
HEIFItem::height
int height
Definition: isom.h:307
AV_SPHERICAL_EQUIRECTANGULAR
@ AV_SPHERICAL_EQUIRECTANGULAR
Video represents a sphere mapped on a flat surface using equirectangular projection.
Definition: spherical.h:52
intfloat.h
id3v1.h
MOVStreamContext::ctts_data
MOVCtts * ctts_data
Definition: isom.h:198
ff_dvdclut_yuv_to_rgb
int ff_dvdclut_yuv_to_rgb(uint32_t *clut, const size_t clut_size)
Definition: dvdclut.c:50
AV_CODEC_ID_R10K
@ AV_CODEC_ID_R10K
Definition: codec_id.h:195
av_encryption_init_info_get_side_data
AVEncryptionInitInfo * av_encryption_init_info_get_side_data(const uint8_t *side_data, size_t side_data_size)
Creates a copy of the AVEncryptionInitInfo that is contained in the given side data.
Definition: encryption_info.c:231
AV_CODEC_ID_ITUT_T35
@ AV_CODEC_ID_ITUT_T35
Definition: codec_id.h:610
AV_STEREO3D_VIEW_RIGHT
@ AV_STEREO3D_VIEW_RIGHT
Frame contains only the right view.
Definition: stereo3d.h:163
MOVContext::advanced_editlist_autodisabled
int advanced_editlist_autodisabled
Definition: isom.h:351
avio_size
int64_t avio_size(AVIOContext *s)
Get the filesize.
Definition: aviobuf.c:326
av_strlcatf
size_t av_strlcatf(char *dst, size_t size, const char *fmt,...)
Definition: avstring.c:103
mov_read_stco
static int mov_read_stco(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2819
AV_CH_WIDE_LEFT
#define AV_CH_WIDE_LEFT
Definition: channel_layout.h:195
AV_STEREO3D_VIEW_UNSPEC
@ AV_STEREO3D_VIEW_UNSPEC
Content is unspecified.
Definition: stereo3d.h:168
mov_read_vexu
static int mov_read_vexu(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:7440
FFIOContext
Definition: avio_internal.h:28
AV_PKT_FLAG_KEY
#define AV_PKT_FLAG_KEY
The packet contains a keyframe.
Definition: packet.h:650
init_get_bits
static int init_get_bits(GetBitContext *s, const uint8_t *buffer, int bit_size)
Initialize GetBitContext.
Definition: get_bits.h:517
MOVStreamContext::aes_ctr
struct AVAESCTR * aes_ctr
Definition: isom.h:282
cenc_filter
static int cenc_filter(MOVContext *mov, AVStream *st, MOVStreamContext *sc, AVPacket *pkt, int current_index)
Definition: mov.c:8779
mov_read_sdtp
static int mov_read_sdtp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:3926
mov_read_jp2h
static int mov_read_jp2h(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2397
AV_STEREO3D_UNSPEC
@ AV_STEREO3D_UNSPEC
Video is stereoscopic but the packing is unspecified.
Definition: stereo3d.h:143
AVIndexEntry
Definition: avformat.h:620
AV_WB64
#define AV_WB64(p, v)
Definition: intreadwrite.h:429
MOVStreamContext::dv_audio_container
int dv_audio_container
Definition: isom.h:225
AV_CODEC_ID_AMR_WB
@ AV_CODEC_ID_AMR_WB
Definition: codec_id.h:434
mov_read_tfhd
static int mov_read_tfhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5944
AV_CODEC_ID_BIN_DATA
@ AV_CODEC_ID_BIN_DATA
Definition: codec_id.h:606
OPUS_SEEK_PREROLL_MS
#define OPUS_SEEK_PREROLL_MS
Definition: oggparseopus.c:36
AV_CODEC_ID_H261
@ AV_CODEC_ID_H261
Definition: codec_id.h:53
IAMFMixPresentation::cmix
const AVIAMFMixPresentation * cmix
Definition: iamf.h:108
MOVContext::decryption_default_key
uint8_t * decryption_default_key
Definition: isom.h:377
mov_read_wide
static int mov_read_wide(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6524
AVINDEX_KEYFRAME
#define AVINDEX_KEYFRAME
Definition: avformat.h:628
AV_FIELD_BT
@ AV_FIELD_BT
Bottom coded first, top displayed first.
Definition: defs.h:217
AV_CH_WIDE_RIGHT
#define AV_CH_WIDE_RIGHT
Definition: channel_layout.h:196
AV_CH_TOP_BACK_LEFT
#define AV_CH_TOP_BACK_LEFT
Definition: channel_layout.h:190
MOVStreamContext::stsd_count
int stsd_count
Definition: isom.h:263
ff_mov_lang_to_iso639
int ff_mov_lang_to_iso639(unsigned code, char to[4])
Definition: isom.c:261
ff_generate_avci_extradata
int ff_generate_avci_extradata(AVStream *st)
Generate standard extradata for AVC-Intra based on width/height and field order.
Definition: demux_utils.c:205
ff_get_extradata
int ff_get_extradata(void *logctx, AVCodecParameters *par, AVIOContext *pb, int size)
Allocate extradata with additional AV_INPUT_BUFFER_PADDING_SIZE at end which is always set to 0 and f...
Definition: demux_utils.c:340
mov_add_tref_id
static int mov_add_tref_id(MovTref *tag, uint32_t id)
Definition: mov.c:2659
AV_PKT_DATA_DOVI_CONF
@ AV_PKT_DATA_DOVI_CONF
DOVI configuration ref: dolby-vision-bitstreams-within-the-iso-base-media-file-format-v2....
Definition: packet.h:280
AVStereo3D::horizontal_field_of_view
AVRational horizontal_field_of_view
Horizontal field of view, in degrees.
Definition: stereo3d.h:239
skip_bits
static void skip_bits(GetBitContext *s, int n)
Definition: get_bits.h:383
AVCodecParameters::color_primaries
enum AVColorPrimaries color_primaries
Definition: codec_par.h:190
AVEncryptionInfo::scheme
uint32_t scheme
The fourcc encryption scheme, in big-endian byte order.
Definition: encryption_info.h:45
MOVStreamContext::stsc_count
unsigned int stsc_count
Definition: isom.h:199
MOVStreamContext::has_palette
int has_palette
Definition: isom.h:239
AVPROBE_SCORE_MAX
#define AVPROBE_SCORE_MAX
maximum score
Definition: avformat.h:483
AV_STEREO3D_SIDEBYSIDE
@ AV_STEREO3D_SIDEBYSIDE
Views are next to each other.
Definition: stereo3d.h:64
MOVIndexRange::start
int64_t start
Definition: isom.h:175
AVPacketSideData::size
size_t size
Definition: packet.h:426
get_bits
static unsigned int get_bits(GetBitContext *s, int n)
Read 1-25 bits.
Definition: get_bits.h:337
ff_remove_stream
void ff_remove_stream(AVFormatContext *s, AVStream *st)
Remove a stream from its AVFormatContext and free it.
Definition: avformat.c:120
OFFSET
#define OFFSET(x)
Definition: mov.c:12300
HEIFGrid::tile_item_list
HEIFItem ** tile_item_list
Definition: isom.h:319
set_icc_profile_from_item
static int set_icc_profile_from_item(AVPacketSideData **coded_side_data, int *nb_coded_side_data, const HEIFItem *item)
Definition: mov.c:10653
AV_CH_TOP_BACK_CENTER
#define AV_CH_TOP_BACK_CENTER
Definition: channel_layout.h:191
AV_FIELD_TT
@ AV_FIELD_TT
Top coded_first, top displayed first.
Definition: defs.h:214
AV_STEREO3D_VIEW_PACKED
@ AV_STEREO3D_VIEW_PACKED
Frame contains two packed views.
Definition: stereo3d.h:153
AV_SPHERICAL_PARAMETRIC_IMMERSIVE
@ AV_SPHERICAL_PARAMETRIC_IMMERSIVE
Parametric Immersive projection (Apple).
Definition: spherical.h:90
MOVStreamContext::nb_frames_for_fps
int nb_frames_for_fps
Definition: isom.h:256
avpriv_dv_produce_packet
int avpriv_dv_produce_packet(DVDemuxContext *c, AVPacket *pkt, uint8_t *buf, int buf_size, int64_t pos)
Definition: dv.c:738
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: avformat.c:829
FF_DVDCLUT_CLUT_LEN
#define FF_DVDCLUT_CLUT_LEN
Definition: dvdclut.h:28
AVEncryptionInfo::skip_byte_block
uint32_t skip_byte_block
Only used for pattern encryption.
Definition: encryption_info.h:57
finish
static void finish(void)
Definition: movenc.c:374
av_realloc
#define av_realloc(p, s)
Definition: ops_static.c:46
aax_filter
static int aax_filter(uint8_t *input, int size, MOVContext *c)
Definition: mov.c:1633
AV_OPT_TYPE_BINARY
@ AV_OPT_TYPE_BINARY
Underlying C type is a uint8_t* that is either NULL or points to an array allocated with the av_mallo...
Definition: opt.h:285
av_color_space_name
const char * av_color_space_name(enum AVColorSpace space)
Definition: pixdesc.c:3860
av_packet_add_side_data
int av_packet_add_side_data(AVPacket *pkt, enum AVPacketSideDataType type, uint8_t *data, size_t size)
Wrap an existing array as a packet side data.
Definition: packet.c:197
MOVStreamContext::mastering
AVMasteringDisplayMetadata * mastering
Definition: isom.h:271
AV_CODEC_ID_SPEEX
@ AV_CODEC_ID_SPEEX
Definition: codec_id.h:487
AV_FOURCC_MAX_STRING_SIZE
#define AV_FOURCC_MAX_STRING_SIZE
Definition: avutil.h:321
AV_PKT_DATA_PALETTE
@ AV_PKT_DATA_PALETTE
An AV_PKT_DATA_PALETTE side data packet contains exactly AVPALETTE_SIZE bytes worth of palette.
Definition: packet.h:47
mov_find_tref_id
static int mov_find_tref_id(const MovTref *tag, uint32_t id)
Definition: mov.c:2650
ffstream
static av_always_inline FFStream * ffstream(AVStream *st)
Definition: internal.h:358
MOVFragmentIndexItem::current
int current
Definition: isom.h:161
mov_add_tref_tag
static MovTref * mov_add_tref_tag(MOVStreamContext *sc, uint32_t name)
Definition: mov.c:2685
AVFMT_SEEK_TO_PTS
#define AVFMT_SEEK_TO_PTS
Seeking is based on PTS.
Definition: avformat.h:520
AV_CODEC_ID_PCM_S16BE
@ AV_CODEC_ID_PCM_S16BE
Definition: codec_id.h:331
mov_read_mdhd
static int mov_read_mdhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2001
mov_read_ctts
static int mov_read_ctts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:3975
MOVTrackExt
Definition: isom.h:119
MOV_FRAG_SAMPLE_FLAG_IS_NON_SYNC
#define MOV_FRAG_SAMPLE_FLAG_IS_NON_SYNC
Definition: isom.h:424
mov_read_aclr
static int mov_read_aclr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2474
AVSEEK_FLAG_ANY
#define AVSEEK_FLAG_ANY
seek to any frame, even non-keyframes
Definition: avformat.h:2603
av_int2float
static av_always_inline float av_int2float(uint32_t i)
Reinterpret a 32-bit integer as a float.
Definition: intfloat.h:40
MOVFragment::found_tfhd
int found_tfhd
Definition: isom.h:108
AVStreamGroupTileGrid
AVStreamGroupTileGrid holds information on how to combine several independent images on a single canv...
Definition: avformat.h:973
FF_DVDCLUT_CLUT_SIZE
#define FF_DVDCLUT_CLUT_SIZE
Definition: dvdclut.h:29
AV_STEREO3D_2D
@ AV_STEREO3D_2D
Video is not stereoscopic (and metadata has to be there).
Definition: stereo3d.h:52
read_seek
static int read_seek(AVFormatContext *ctx, int stream_index, int64_t timestamp, int flags)
Definition: libcdio.c:151
HEIFItem::item_id
int item_id
Definition: isom.h:303
av_shrink_packet
void av_shrink_packet(AVPacket *pkt, int size)
Reduce packet size, correctly zeroing padding.
Definition: packet.c:113
timecode.h
get_current_frag_stream_info
static MOVFragmentStreamInfo * get_current_frag_stream_info(MOVFragmentIndex *frag_index)
Definition: mov.c:1752
GetBitContext
Definition: get_bits.h:109
AV_CH_BACK_LEFT
#define AV_CH_BACK_LEFT
Definition: channel_layout.h:179
MOVStreamContext::mastering_size
size_t mastering_size
Definition: isom.h:272
AVStreamGroupTileGrid::coded_width
int coded_width
Width of the canvas.
Definition: avformat.h:988
av_iamf_audio_element_free
void av_iamf_audio_element_free(AVIAMFAudioElement **paudio_element)
Free an AVIAMFAudioElement and all its contents.
Definition: iamf.c:338
FFStream::index_entries_allocated_size
unsigned int index_entries_allocated_size
Definition: internal.h:187
read_close
static av_cold int read_close(AVFormatContext *ctx)
Definition: libcdio.c:143
mov_read_amve
static int mov_read_amve(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6900
mov_read_enda
static int mov_read_enda(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2115
mov_read_chap
static int mov_read_chap(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5991
MOVParseTableEntry
Definition: mov.c:83
avio_tell
static av_always_inline int64_t avio_tell(AVIOContext *s)
ftell() equivalent for AVIOContext.
Definition: avio.h:494
av_exif_free
void av_exif_free(AVExifMetadata *ifd)
Frees all resources associated with the given EXIF metadata struct.
Definition: exif.c:659
MOV_TRUN_SAMPLE_DURATION
#define MOV_TRUN_SAMPLE_DURATION
Definition: isom.h:418
val
static double val(void *priv, double ch)
Definition: aeval.c:77
set_display_matrix_from_item
static int set_display_matrix_from_item(AVPacketSideData **coded_side_data, int *nb_coded_side_data, const HEIFItem *item)
Definition: mov.c:10667
type
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf type
Definition: writing_filters.txt:86
MOVContext
Definition: isom.h:325
AV_DISPOSITION_TIMED_THUMBNAILS
#define AV_DISPOSITION_TIMED_THUMBNAILS
The stream is sparse, and contains thumbnail images, often corresponding to chapter markers.
Definition: avformat.h:697
AVStreamGroupTileGrid::coded_height
int coded_height
Width of the canvas.
Definition: avformat.h:994
pts
static int64_t pts
Definition: transcode_aac.c:649
MOVStreamContext::v_spacing
int v_spacing
pasp vSpacing
Definition: isom.h:236
AVEncryptionInfo::iv
uint8_t * iv
The initialization vector.
Definition: encryption_info.h:71
AV_CODEC_ID_MP3
@ AV_CODEC_ID_MP3
preferred ID for decoding MPEG audio layer 1, 2 or 3
Definition: codec_id.h:453
AVStream::duration
int64_t duration
Decoding: duration of the stream, in stream time base.
Definition: avformat.h:825
AVAmbientViewingEnvironment::ambient_illuminance
AVRational ambient_illuminance
Environmental illuminance of the ambient viewing environment in lux.
Definition: ambient_viewing_environment.h:40
ss
#define ss(width, name, subs,...)
Definition: cbs_vp9.c:202
MOVStreamContext::width
int width
tkhd width
Definition: isom.h:233
MOVContext::meta_keys
char ** meta_keys
Definition: isom.h:336
get_key_from_kid
static int get_key_from_kid(uint8_t *out, int len, MOVContext *c, AVEncryptionInfo *sample)
Definition: mov.c:8433
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
MOVStreamContext::extradata_size
int * extradata_size
Definition: isom.h:261
AVIAMFAudioElement::audio_element_type
enum AVIAMFAudioElementType audio_element_type
Audio element type as defined in section 3.6 of IAMF.
Definition: iamf.h:391
loop
static int loop
Definition: ffplay.c:337
AV_STREAM_GROUP_PARAMS_DOLBY_VISION
@ AV_STREAM_GROUP_PARAMS_DOLBY_VISION
Definition: avformat.h:1153
ff_data_to_hex
char * ff_data_to_hex(char *buf, const uint8_t *src, int size, int lowercase)
Write hexadecimal string corresponding to given binary data.
Definition: utils.c:464
update_frag_index
static int update_frag_index(MOVContext *c, int64_t offset)
Definition: mov.c:1869
AV_CODEC_ID_PRORES_RAW
@ AV_CODEC_ID_PRORES_RAW
Definition: codec_id.h:324
AVRational::num
int num
Numerator.
Definition: rational.h:59
av_clip64
#define av_clip64
Definition: common.h:103
MOVStreamContext::keyframes
int * keyframes
Definition: isom.h:215
av_unused
#define av_unused
Definition: attributes.h:164
MOVEncryptionIndex::auxiliary_info_sample_count
size_t auxiliary_info_sample_count
Definition: isom.h:139
AV_FIELD_TB
@ AV_FIELD_TB
Top coded first, bottom displayed first.
Definition: defs.h:216
mov_read_pack
static int mov_read_pack(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6972
AVStream::attached_pic
AVPacket attached_pic
For streams with AV_DISPOSITION_ATTACHED_PIC disposition, this packet will contain the attached pictu...
Definition: avformat.h:864
MOVStsc::id
int id
Definition: isom.h:76
mov_read_saiz
static int mov_read_saiz(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:7991
MOV_FRAG_SAMPLE_FLAG_DEPENDS_YES
#define MOV_FRAG_SAMPLE_FLAG_DEPENDS_YES
Definition: isom.h:431
mov_merge_tts_data
static int mov_merge_tts_data(MOVContext *mov, AVStream *st, int flags)
Definition: mov.c:4893
MOVContext::idat_offset
int64_t idat_offset
Definition: isom.h:390
MOV_TRUN_DATA_OFFSET
#define MOV_TRUN_DATA_OFFSET
Definition: isom.h:416
av_encryption_info_clone
AVEncryptionInfo * av_encryption_info_clone(const AVEncryptionInfo *info)
Allocates an AVEncryptionInfo structure with a copy of the given data.
Definition: encryption_info.c:65
av_ambient_viewing_environment_alloc
AVAmbientViewingEnvironment * av_ambient_viewing_environment_alloc(size_t *size)
Allocate an AVAmbientViewingEnvironment structure.
Definition: ambient_viewing_environment.c:31
AV_DICT_DONT_STRDUP_VAL
#define AV_DICT_DONT_STRDUP_VAL
Take ownership of a value that's been allocated with av_malloc() or another memory allocation functio...
Definition: dict.h:79
IAMFAudioElement::element
AVIAMFAudioElement * element
element backs celement iff the AVIAMFAudioElement is owned by this structure.
Definition: iamf.h:95
MOVStreamContext::elst_data
MOVElst * elst_data
Definition: isom.h:205
mov_read_ares
static int mov_read_ares(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2429
mov_read_adrm
static int mov_read_adrm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1507
av_get_bits_per_sample
int av_get_bits_per_sample(enum AVCodecID codec_id)
Return codec bits per sample.
Definition: utils.c:556
AVCodecParameters::color_trc
enum AVColorTransferCharacteristic color_trc
Definition: codec_par.h:191
IAMFContext::audio_elements
IAMFAudioElement ** audio_elements
Definition: iamf.h:131
MOVFragmentIndex::complete
int complete
Definition: isom.h:168
AV_CODEC_ID_PCM_S8
@ AV_CODEC_ID_PCM_S8
Definition: codec_id.h:334
avassert.h
avio_rb32
unsigned int avio_rb32(AVIOContext *s)
Definition: aviobuf.c:764
AV_LOG_TRACE
#define AV_LOG_TRACE
Extremely verbose debugging, useful for libav* development.
Definition: log.h:236
MOVStreamContext::stsc_sample
int stsc_sample
Definition: isom.h:202
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:210
AV_CODEC_ID_MACE3
@ AV_CODEC_ID_MACE3
Definition: codec_id.h:461
FF_ARRAY_ELEMS
#define FF_ARRAY_ELEMS(a)
Definition: sinewin_tablegen.c:29
AV_PROFILE_UNKNOWN
#define AV_PROFILE_UNKNOWN
Definition: defs.h:65
MOVTrackExt::track_id
unsigned track_id
Definition: isom.h:120
mov_free_encryption_index
static void mov_free_encryption_index(MOVEncryptionIndex **index)
Definition: mov.c:10384
AV_CH_LOW_FREQUENCY
#define AV_CH_LOW_FREQUENCY
Definition: channel_layout.h:178
MOVEncryptionIndex::auxiliary_offsets
uint64_t * auxiliary_offsets
Absolute seek position.
Definition: isom.h:141
read_packet
static int read_packet(void *opaque, uint8_t *buf, int buf_size)
Definition: avio_read_callback.c:42
AV_FIELD_UNKNOWN
@ AV_FIELD_UNKNOWN
Definition: defs.h:212
MOVStreamContext::dts_shift
int dts_shift
dts shift when ctts is negative
Definition: isom.h:237
av_timecode_init
int av_timecode_init(AVTimecode *tc, AVRational rate, int flags, int frame_start, void *log_ctx)
Init a timecode struct with the passed parameters.
Definition: timecode.c:201
AVCodecParameters::frame_size
int frame_size
Audio frame size, if known.
Definition: codec_par.h:227
mov_read_srat
static int mov_read_srat(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1092
avio_get_str16le
int avio_get_str16le(AVIOContext *pb, int maxlen, char *buf, int buflen)
Read a UTF-16 string from pb and convert it to UTF-8.
mov_metadata_track_or_disc_number
static int mov_metadata_track_or_disc_number(MOVContext *c, AVIOContext *pb, unsigned len, const char *key)
Definition: mov.c:92
av_dict_get
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
AES_CTR_KEY_SIZE
#define AES_CTR_KEY_SIZE
Definition: aes_ctr.h:35
MOVStreamContext::stsd_version
int stsd_version
Definition: isom.h:264
mov_parse_exif_item
static int mov_parse_exif_item(AVFormatContext *s, AVPacketSideData **coded_side_data, int *nb_coded_side_data, const HEIFItem *ref)
Definition: mov.c:10852
flags
#define flags(name, subs,...)
Definition: cbs_av1.c:504
AV_STREAM_GROUP_PARAMS_IAMF_MIX_PRESENTATION
@ AV_STREAM_GROUP_PARAMS_IAMF_MIX_PRESENTATION
Definition: avformat.h:1149
ff_add_attached_pic
int ff_add_attached_pic(AVFormatContext *s, AVStream *st, AVIOContext *pb, AVBufferRef **buf, int size)
Add an attached pic to an AVStream.
Definition: demux_utils.c:107
add_tts_entry
static int add_tts_entry(MOVTimeToSample **tts_data, unsigned int *tts_count, unsigned int *allocated_size, int count, int offset, unsigned int duration)
Definition: mov.c:4368
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:495
FF_MOV_FLAG_MFRA_PTS
#define FF_MOV_FLAG_MFRA_PTS
Definition: isom.h:466
MOV_MERGE_STTS
#define MOV_MERGE_STTS
Definition: mov.c:4887
MOVStreamContext::iamf_stream_offset
int iamf_stream_offset
Definition: isom.h:290
ff_mov_read_esds
int ff_mov_read_esds(AVFormatContext *fc, AVIOContext *pb)
Definition: mov_esds.c:23
stereo3d.h
AVMasteringDisplayMetadata::white_point
AVRational white_point[2]
CIE 1931 xy chromaticity coords of white point.
Definition: mastering_display_metadata.h:47
intreadwrite.h
mov_read_coll
static int mov_read_coll(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6834
MOVFragmentStreamInfo::encryption_index
MOVEncryptionIndex * encryption_index
Definition: isom.h:154
mov_read_trak
static int mov_read_trak(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5448
IAMFSubStream::audio_substream_id
unsigned int audio_substream_id
Definition: iamf.h:83
MOVContext::fc
AVFormatContext * fc
Definition: isom.h:327
MOV_TFHD_DEFAULT_BASE_IS_MOOF
#define MOV_TFHD_DEFAULT_BASE_IS_MOOF
Definition: isom.h:414
av_new_packet
int av_new_packet(AVPacket *pkt, int size)
Allocate the payload of a packet and initialize its fields with default values.
Definition: packet.c:98
AV_CODEC_ID_BMP
@ AV_CODEC_ID_BMP
Definition: codec_id.h:128
AV_CODEC_ID_EVC
@ AV_CODEC_ID_EVC
Definition: codec_id.h:316
IAMFLayer::substream_count
unsigned int substream_count
Definition: iamf.h:78
MOV_TFHD_DEFAULT_DURATION
#define MOV_TFHD_DEFAULT_DURATION
Definition: isom.h:410
ALAC_EXTRADATA_SIZE
#define ALAC_EXTRADATA_SIZE
DRM_BLOB_SIZE
#define DRM_BLOB_SIZE
Definition: mov.c:1505
MOVStreamContext::sample_offsets_count
int sample_offsets_count
Definition: isom.h:251
MOVCtts::count
unsigned int count
Definition: isom.h:69
MOVStreamContext::drefs
MOVDref * drefs
Definition: isom.h:229
av_realloc_array
void * av_realloc_array(void *ptr, size_t nmemb, size_t size)
Definition: mem.c:217
AVInputFormat::name
const char * name
A comma separated list of short names for the format.
Definition: avformat.h:570
MOVContext::aes_decrypt
struct AVAES * aes_decrypt
Definition: isom.h:376
AVSphericalMapping::bound_top
uint32_t bound_top
Distance from the top edge.
Definition: spherical.h:186
AVMEDIA_TYPE_AUDIO
@ AVMEDIA_TYPE_AUDIO
Definition: avutil.h:201
AV_CODEC_ID_VP9
@ AV_CODEC_ID_VP9
Definition: codec_id.h:217
MOVFragmentIndex::nb_items
int nb_items
Definition: isom.h:170
AVCodecParameters::width
int width
The width of the video frame in pixels.
Definition: codec_par.h:143
MOVTimeToSample
Definition: isom.h:57
AV_CHANNEL_ORDER_UNSPEC
@ AV_CHANNEL_ORDER_UNSPEC
Only the channel count is specified, without any further information about the channel order.
Definition: channel_layout.h:119
AV_CODEC_ID_MP2
@ AV_CODEC_ID_MP2
Definition: codec_id.h:452
HEIFGrid::tile_idx_list
unsigned * tile_idx_list
Definition: isom.h:321
MOV_TRUN_FIRST_SAMPLE_FLAGS
#define MOV_TRUN_FIRST_SAMPLE_FLAGS
Definition: isom.h:417
av_q2d
static double av_q2d(AVRational a)
Convert an AVRational to a double.
Definition: rational.h:104
AVIndexEntry::size
int size
Definition: avformat.h:631
av_channel_layout_from_mask
int av_channel_layout_from_mask(AVChannelLayout *channel_layout, uint64_t mask)
Initialize a native channel layout from a bitmask indicating which channels are present.
Definition: channel_layout.c:253
MOVStreamContext::keyframe_absent
int keyframe_absent
Definition: isom.h:213
info
MIPS optimizations info
Definition: mips.txt:2
MOVStts::duration
unsigned int duration
Definition: isom.h:65
fc
#define fc(width, name, range_min, range_max)
Definition: cbs_av1.c:494
MOVStreamContext::coll_size
size_t coll_size
Definition: isom.h:274
tile_rows
int tile_rows
Definition: h265_levels.c:217
mov_estimate_video_delay
static void mov_estimate_video_delay(MOVContext *c, AVStream *st)
Definition: mov.c:4397
AVIndexEntry::timestamp
int64_t timestamp
Timestamp in AVStream.time_base units, preferably the time from which on correctly decoded frames are...
Definition: avformat.h:622
av_assert0
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:42
MOVStreamContext::min_corrected_pts
int64_t min_corrected_pts
minimum Composition time shown by the edits excluding empty edits.
Definition: isom.h:218
ffio_read_leb
unsigned int ffio_read_leb(AVIOContext *s)
Read a unsigned integer coded as a variable number of up to eight little-endian bytes,...
Definition: aviobuf.c:930
tile_cols
int tile_cols
Definition: av1_levels.c:73
MOVStreamContext::sdtp_count
unsigned int sdtp_count
Definition: isom.h:194
dvdclut.h
MOVStreamContext::nb_tref_tags
int nb_tref_tags
Definition: isom.h:231
mov_read_lhvc
static int mov_read_lhvc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:8984
AV_LOG_DEBUG
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:231
AV_CH_TOP_SIDE_RIGHT
#define AV_CH_TOP_SIDE_RIGHT
Definition: channel_layout.h:201
AVPacketSideData::data
uint8_t * data
Definition: packet.h:425
AVDOVIDecoderConfigurationRecord::dv_profile
uint8_t dv_profile
Definition: dovi_meta.h:58
ctx
static AVFormatContext * ctx
Definition: movenc.c:49
hevc.h
get_bits.h
limits.h
mov_read_sidx
static int mov_read_sidx(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6385
AV_PKT_DATA_STEREO3D
@ AV_PKT_DATA_STEREO3D
This side data should be associated with a video stream and contains Stereoscopic 3D information in f...
Definition: packet.h:111
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:142
ff_iamfdec_read_descriptors
int ff_iamfdec_read_descriptors(IAMFContext *c, AVIOContext *pb, int max_size, void *log_ctx)
Definition: iamf_parse.c:1237
FFStream::display_aspect_ratio
AVRational display_aspect_ratio
display aspect ratio (0 if unknown)
Definition: internal.h:296
IAMFContext::nb_mix_presentations
int nb_mix_presentations
Definition: iamf.h:134
mov_find_next_sample
static AVIndexEntry * mov_find_next_sample(AVFormatContext *s, AVStream **st)
Definition: mov.c:11659
ff_mov_read_chnl
int ff_mov_read_chnl(AVFormatContext *s, AVIOContext *pb, AVStream *st, int version)
Read 'chnl' tag from the input stream.
Definition: mov_chan.c:768
AV_CODEC_ID_TARGA_Y216
@ AV_CODEC_ID_TARGA_Y216
Definition: codec_id.h:253
AVStreamGroupTileGrid::offsets
struct AVStreamGroupTileGrid::@460 * offsets
An nb_tiles sized array of offsets in pixels from the topleft edge of the canvas, indicating where ea...
AVIndexEntry::min_distance
int min_distance
Minimum distance between this and the previous keyframe, used to avoid unneeded searching.
Definition: avformat.h:632
mov_read_dvcc_dvvc
static int mov_read_dvcc_dvvc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:8937
MOVParseTableEntry::parse
int(* parse)(MOVContext *ctx, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:85
codec_id
enum AVCodecID codec_id
Definition: vaapi_decode.c:410
MOVStreamContext::tref_tags
MovTref * tref_tags
Definition: isom.h:232
AV_CODEC_ID_SVQ3
@ AV_CODEC_ID_SVQ3
Definition: codec_id.h:73
AVCodecParameters::nb_coded_side_data
int nb_coded_side_data
Amount of entries in coded_side_data.
Definition: codec_par.h:88
MOVStreamContext::sdtp_data
uint8_t * sdtp_data
Definition: isom.h:195
color_range
color_range
Definition: vf_selectivecolor.c:43
AVMEDIA_TYPE_DATA
@ AVMEDIA_TYPE_DATA
Opaque data information usually continuous.
Definition: avutil.h:202
mov_read_udta_string
static int mov_read_udta_string(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:346
av_mallocz
#define av_mallocz(s)
Definition: tableprint_vlc.h:31
mov_read_stss
static int mov_read_stss(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:3658
mov_read_ddts
static int mov_read_ddts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1236
mov_read_uuid
static int mov_read_uuid(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:7594
AVCOL_PRI_UNSPECIFIED
@ AVCOL_PRI_UNSPECIFIED
Definition: pixfmt.h:645
MOVTrackExt::duration
unsigned duration
Definition: isom.h:122
AV_CODEC_ID_H264
@ AV_CODEC_ID_H264
Definition: codec_id.h:77
AVStreamGroup::layered_video
struct AVStreamGroupLayeredVideo * layered_video
Definition: avformat.h:1195
av_content_light_metadata_alloc
AVContentLightMetadata * av_content_light_metadata_alloc(size_t *size)
Allocate an AVContentLightMetadata structure and set its fields to default values.
Definition: mastering_display_metadata.c:73
tmp
static uint8_t tmp[40]
Definition: aes_ctr.c:52
av_sha_final
void av_sha_final(AVSHA *ctx, uint8_t *digest)
Finish hashing and output digest value.
Definition: sha.c:347
MOVStreamContext::current_sample
int current_sample
Definition: isom.h:219
MOVFragmentStreamInfo::sidx_pts
int64_t sidx_pts
Definition: isom.h:147
MAX_REORDER_DELAY
#define MAX_REORDER_DELAY
Definition: mov.c:4396
MOVFragmentIndex::current
int current
Definition: isom.h:169
MOVEncryptionIndex::encrypted_samples
AVEncryptionInfo ** encrypted_samples
Definition: isom.h:136
mov_read_close
static int mov_read_close(AVFormatContext *s)
Definition: mov.c:10461
ff_hex_to_data
int ff_hex_to_data(uint8_t *data, const char *p)
Parse a string of hexadecimal strings.
Definition: utils.c:485
MOVAtom::size
int64_t size
Definition: isom.h:102
MOVStreamContext::refcount
int refcount
Definition: isom.h:181
AVStereo3D::flags
int flags
Additional information about the frame packing.
Definition: stereo3d.h:212
ff_mov_get_lpcm_codec_id
static enum AVCodecID ff_mov_get_lpcm_codec_id(int bps, int flags)
Compute codec id for 'lpcm' tag.
Definition: isom.h:472
AV_CODEC_ID_PNG
@ AV_CODEC_ID_PNG
Definition: codec_id.h:111
AV_CODEC_ID_AVUI
@ AV_CODEC_ID_AVUI
Definition: codec_id.h:252
if
if(ret)
Definition: filter_design.txt:179
mov_read_cmov
static int mov_read_cmov(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6544
FF_INFMT_FLAG_INIT_CLEANUP
#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
mov_read_sample_encryption_info
static int mov_read_sample_encryption_info(MOVContext *c, AVIOContext *pb, MOVStreamContext *sc, AVEncryptionInfo **sample, int use_subsamples)
Definition: mov.c:7819
FFStream::need_parsing
enum AVStreamParseType need_parsing
Definition: internal.h:314
MOVStreamContext::keyframe_count
unsigned int keyframe_count
Definition: isom.h:214
mov_read_SAND
static int mov_read_SAND(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:9214
IAMFAudioElement::audio_element_id
unsigned int audio_element_id
Definition: iamf.h:96
AVDISCARD_ALL
@ AVDISCARD_ALL
discard all
Definition: defs.h:232
AVFormatContext
Format I/O context.
Definition: avformat.h:1333
av_realloc_f
#define av_realloc_f(p, o, n)
Definition: tableprint_vlc.h:33
mov_read_stts
static int mov_read_stts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:3806
MOVStreamContext::index_ranges
MOVIndexRange * index_ranges
Definition: isom.h:221
fail
#define fail
Definition: test.h:478
DDTS_SIZE
#define DDTS_SIZE
internal.h
MOVTrackExt::stsd_id
unsigned stsd_id
Definition: isom.h:121
find_prev_closest_index
static int find_prev_closest_index(AVStream *st, AVIndexEntry *e_old, int nb_old, MOVTimeToSample *tts_data, int64_t tts_count, int64_t timestamp_pts, int flag, int64_t *index, int64_t *tts_index, int64_t *tts_sample)
Find the closest previous frame to the timestamp_pts, in e_old index entries.
Definition: mov.c:4219
set_frag_stream
static void set_frag_stream(MOVFragmentIndex *frag_index, int id)
Definition: mov.c:1732
mov_read_free
static int mov_read_free(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:7699
mov_realloc_extradata
static int mov_realloc_extradata(AVCodecParameters *par, MOVAtom atom)
Definition: mov.c:2324
AVStream::codecpar
AVCodecParameters * codecpar
Codec parameters associated with this stream.
Definition: avformat.h:789
LIBAVUTIL_VERSION_INT
#define LIBAVUTIL_VERSION_INT
Definition: version.h:85
av_exif_get_tag_id
int32_t av_exif_get_tag_id(const char *name)
Retrieves the tag ID associated with the provided tag string name.
Definition: exif.c:244
AV_PKT_DATA_EXIF
@ AV_PKT_DATA_EXIF
Extensible image file format metadata.
Definition: packet.h:369
AVSEEK_FLAG_BACKWARD
#define AVSEEK_FLAG_BACKWARD
Definition: avformat.h:2601
mov_dts_stream_construction_to_profile
static int mov_dts_stream_construction_to_profile(unsigned int sc)
Definition: mov.c:1175
aes.h
AVClass
Describe the class of an AVClass context structure.
Definition: log.h:76
MOVStreamContext::tts_sample
int tts_sample
Definition: isom.h:208
avpriv_dv_get_packet
int avpriv_dv_get_packet(DVDemuxContext *c, AVPacket *pkt)
Definition: dv.c:733
MOVContext::ignore_editlist
int ignore_editlist
Definition: isom.h:349
result
and forward the result(frame or status change) to the corresponding input. If nothing is possible
fabs
static __device__ float fabs(float a)
Definition: cuda_runtime.h:182
metadata
Stream codec metadata
Definition: ogg-flac-chained-meta.txt:2
AV_CH_TOP_CENTER
#define AV_CH_TOP_CENTER
Definition: channel_layout.h:186
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:805
NULL
#define NULL
Definition: coverity.c:32
sha.h
truehd_layout
static uint64_t truehd_layout(int chanmap)
Definition: mlp_parse.h:105
MOVDref
Definition: isom.h:85
AVERROR_PATCHWELCOME
#define AVERROR_PATCHWELCOME
Not yet implemented in FFmpeg, patches welcome.
Definition: error.h:64
format
New swscale design to change SwsGraph is what coordinates multiple passes These can include cascaded scaling error diffusion and so on Or we could have separate passes for the vertical and horizontal scaling In between each SwsPass lies a fully allocated image buffer Graph passes may have different levels of e g we can have a single threaded error diffusion pass following a multi threaded scaling pass SwsGraph is internally recreated whenever the image format
Definition: swscale-v2.txt:14
av_buffer_unref
void av_buffer_unref(AVBufferRef **buf)
Free a given reference and automatically free the buffer if there are no more references to it.
Definition: buffer.c:139
AV_CODEC_ID_AV1
@ AV_CODEC_ID_AV1
Definition: codec_id.h:275
MOVStreamContext::ctts_count
unsigned int ctts_count
Definition: isom.h:196
AVEncryptionInitInfo
This describes info used to initialize an encryption key system.
Definition: encryption_info.h:88
isom.h
MP4TrackKindValueMapping::disposition
int disposition
Definition: isom.h:488
mov_read_ftyp
static int mov_read_ftyp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1647
AV_WB16
#define AV_WB16(p, v)
Definition: intreadwrite.h:401
MOVContext::nb_heif_grid
int nb_heif_grid
Definition: isom.h:389
read_image_grid
static int read_image_grid(AVFormatContext *s, const HEIFGrid *grid, AVStreamGroupTileGrid *tile_grid)
Definition: mov.c:10688
MOVElst
Definition: isom.h:79
av_aes_ctr_alloc
struct AVAESCTR * av_aes_ctr_alloc(void)
Allocate an AVAESCTR context.
Definition: aes_ctr.c:41
flac_parse_block_header
static av_always_inline void flac_parse_block_header(const uint8_t *block_header, int *last, int *type, int *size)
Parse the metadata block parameters from the header.
Definition: flac.h:63
AVStreamGroupTileGrid::coded_side_data
AVPacketSideData * coded_side_data
Additional data associated with the grid.
Definition: avformat.h:1076
AVRational
Rational number (pair of numerator and denominator).
Definition: rational.h:58
AV_PRIMARY_EYE_LEFT
@ AV_PRIMARY_EYE_LEFT
Left eye.
Definition: stereo3d.h:183
mov_read_sgpd
static int mov_read_sgpd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:4056
AV_CHANNEL_LAYOUT_RETYPE_FLAG_CANONICAL
#define AV_CHANNEL_LAYOUT_RETYPE_FLAG_CANONICAL
The specified retype target order is ignored and the simplest possible (canonical) order is used for ...
Definition: channel_layout.h:721
mov_probe
static int mov_probe(const AVProbeData *p)
Definition: mov.c:10103
AVPALETTE_SIZE
#define AVPALETTE_SIZE
Definition: pixfmt.h:32
AV_OPT_TYPE_DICT
@ AV_OPT_TYPE_DICT
Underlying C type is AVDictionary*.
Definition: opt.h:289
MOVDref::nlvl_to
int16_t nlvl_to
Definition: isom.h:91
get_eia608_packet
static int get_eia608_packet(AVIOContext *pb, AVPacket *pkt, int src_size)
Definition: mov.c:11756
av_fallthrough
#define av_fallthrough
Definition: attributes.h:67
AV_CODEC_ID_DVD_SUBTITLE
@ AV_CODEC_ID_DVD_SUBTITLE
Definition: codec_id.h:565
AVIndexEntry::flags
int flags
Definition: avformat.h:630
MOVStreamContext::time_offset
int64_t time_offset
time offset of the edit list entries
Definition: isom.h:217
mov_read_smdm
static int mov_read_smdm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6743
av_default_item_name
const char * av_default_item_name(void *ptr)
Return the context name.
Definition: log.c:242
AVStereo3D::horizontal_disparity_adjustment
AVRational horizontal_disparity_adjustment
Relative shift of the left and right images, which changes the zero parallax plane.
Definition: stereo3d.h:234
avio_rb64
uint64_t avio_rb64(AVIOContext *s)
Definition: aviobuf.c:911
av_aes_crypt
void av_aes_crypt(AVAES *a, uint8_t *dst, const uint8_t *src, int count, uint8_t *iv, int decrypt)
Encrypt or decrypt a buffer using a previously initialized context.
Definition: aes.c:171
MOVStreamContext::current_index_range
MOVIndexRange * current_index_range
Definition: isom.h:222
mov_open_dref
static int mov_open_dref(MOVContext *c, AVIOContext **pb, const char *src, MOVDref *ref)
Definition: mov.c:5301
FFStream::nb_index_entries
int nb_index_entries
Definition: internal.h:186
AVProbeData
This structure contains the data a format has to probe a file.
Definition: avformat.h:471
av_aes_alloc
struct AVAES * av_aes_alloc(void)
Allocate an AVAES context.
Definition: aes.c:37
TAG_IS_AVCI
#define TAG_IS_AVCI(tag)
Definition: isom.h:442
IAMFSubStream
Definition: iamf.h:82
IAMFAudioElement::layers
IAMFLayer * layers
Definition: iamf.h:103
mov_read_schm
static int mov_read_schm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:8291
AVStream::metadata
AVDictionary * metadata
Definition: avformat.h:846
FLAC_STREAMINFO_SIZE
#define FLAC_STREAMINFO_SIZE
Definition: flac.h:32
av_color_primaries_name
const char * av_color_primaries_name(enum AVColorPrimaries primaries)
Definition: pixdesc.c:3794
FF_MOV_FLAG_MFRA_DTS
#define FF_MOV_FLAG_MFRA_DTS
Definition: isom.h:465
MOV_SAMPLE_DEPENDENCY_NO
#define MOV_SAMPLE_DEPENDENCY_NO
Definition: isom.h:440
AV_DICT_DONT_OVERWRITE
#define AV_DICT_DONT_OVERWRITE
Don't overwrite existing entries.
Definition: dict.h:81
ff_codec_movvideo_tags
const AVCodecTag ff_codec_movvideo_tags[]
Definition: isom_tags.c:29
attributes.h
MOVStreamContext::tts_index
int tts_index
Definition: isom.h:207
AV_DISPOSITION_MULTILAYER
#define AV_DISPOSITION_MULTILAYER
The video stream contains multiple layers, e.g.
Definition: avformat.h:736
MOVFragmentStreamInfo::index_base
int index_base
Definition: isom.h:152
MOVStreamContext::rap_group
MOVSbgp * rap_group
Definition: isom.h:245
AV_CODEC_ID_QDM2
@ AV_CODEC_ID_QDM2
Definition: codec_id.h:471
mov_read_ilst
static int mov_read_ilst(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5599
MOVTimeToSample::duration
unsigned int duration
Definition: isom.h:59
AV_CH_FRONT_CENTER
#define AV_CH_FRONT_CENTER
Definition: channel_layout.h:177
AVCodecParameters::ch_layout
AVChannelLayout ch_layout
The channel layout and number of channels.
Definition: codec_par.h:207
get_frag_stream_info_from_pkt
static MOVFragmentStreamInfo * get_frag_stream_info_from_pkt(MOVFragmentIndex *frag_index, AVPacket *pkt, int id)
Definition: mov.c:8754
get_sgpd_sync_index
static uint32_t get_sgpd_sync_index(const MOVStreamContext *sc, int nal_unit_type)
Definition: mov.c:4815
mov_read_fiel
static int mov_read_fiel(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2290
parse
static int parse(AVCodecParserContext *s, AVCodecContext *avctx, const uint8_t **poutbuf, int *poutbuf_size, const uint8_t *buf, int buf_size)
Definition: apv_parser.c:92
AV_CH_FRONT_LEFT_OF_CENTER
#define AV_CH_FRONT_LEFT_OF_CENTER
Definition: channel_layout.h:181
MOV_MP4_TTML_TAG
#define MOV_MP4_TTML_TAG
Definition: isom.h:483
AV_PKT_DATA_CONTENT_LIGHT_LEVEL
@ AV_PKT_DATA_CONTENT_LIGHT_LEVEL
Content light level (based on CTA-861.3).
Definition: packet.h:232
av_encryption_info_add_side_data
uint8_t * av_encryption_info_add_side_data(const AVEncryptionInfo *info, size_t *size)
Allocates and initializes side data that holds a copy of the given encryption info.
Definition: encryption_info.c:127
MOV_TFHD_BASE_DATA_OFFSET
#define MOV_TFHD_BASE_DATA_OFFSET
Definition: isom.h:408
MOVFragmentStreamInfo::stsd_id
int stsd_id
Definition: isom.h:155
av_exif_remove_entry
int av_exif_remove_entry(void *logctx, AVExifMetadata *ifd, uint16_t id, int flags)
Remove an entry from the provided EXIF metadata struct.
Definition: exif.c:1272
MOVStreamContext::open_key_samples_count
int open_key_samples_count
Definition: isom.h:253
HEIFItem
Definition: isom.h:298
ff_codec_movaudio_tags
const AVCodecTag ff_codec_movaudio_tags[]
Definition: isom_tags.c:306
ff_codec_movdata_tags
const AVCodecTag ff_codec_movdata_tags[]
Definition: isom.c:82
mov_read_wfex
static int mov_read_wfex(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1351
av_stereo3d_alloc_size
AVStereo3D * av_stereo3d_alloc_size(size_t *size)
Allocate an AVStereo3D structure and set its fields to default values.
Definition: stereo3d.c:39
index
int index
Definition: gxfenc.c:90
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
AVPROBE_SCORE_EXTENSION
#define AVPROBE_SCORE_EXTENSION
score for file extension
Definition: avformat.h:481
MOVSbgp::count
unsigned int count
Definition: isom.h:128
AVCodecParameters::sample_rate
int sample_rate
The number of audio samples per second.
Definition: codec_par.h:213
mov_parse_stsd_subtitle
static void mov_parse_stsd_subtitle(MOVContext *c, AVIOContext *pb, AVStream *st, MOVStreamContext *sc, int64_t size)
Definition: mov.c:3109
cid
uint16_t cid
Definition: mxfenc.c:2335
mov_skip_multiple_stsd
static int mov_skip_multiple_stsd(MOVContext *c, AVIOContext *pb, int codec_tag, int format, int64_t size)
Definition: mov.c:3302
MOVStts
Definition: isom.h:63
AVAudioServiceType
AVAudioServiceType
Definition: defs.h:235
AV_CODEC_ID_MPEG1VIDEO
@ AV_CODEC_ID_MPEG1VIDEO
Definition: codec_id.h:51
AV_CODEC_ID_GSM
@ AV_CODEC_ID_GSM
as in Berlin toast format
Definition: codec_id.h:470
AVStream::nb_frames
int64_t nb_frames
number of frames in this stream if known or 0
Definition: avformat.h:827
AVCodecID
AVCodecID
Identify the syntax and semantics of the bitstream.
Definition: codec_id.h:47
av_packet_side_data_get
const AVPacketSideData * av_packet_side_data_get(const AVPacketSideData *sd, int nb_sd, enum AVPacketSideDataType type)
Get side information from a side data array.
Definition: packet.c:570
AVIAMFSubmixElement::audio_element_id
unsigned int audio_element_id
The id of the Audio Element this submix element references.
Definition: iamf.h:455
AV_CODEC_ID_EAC3
@ AV_CODEC_ID_EAC3
Definition: codec_id.h:492
should_retry
static int should_retry(AVIOContext *pb, int error_code)
Definition: mov.c:11689
avformat_stream_group_add_stream
int avformat_stream_group_add_stream(AVStreamGroup *stg, AVStream *st)
Add an already allocated stream to a stream group.
Definition: options.c:557
AV_PKT_DATA_SPHERICAL
@ AV_PKT_DATA_SPHERICAL
This side data should be associated with a video stream and corresponds to the AVSphericalMapping str...
Definition: packet.h:225
AVCodecParameters::extradata_size
int extradata_size
Size of the extradata content in bytes.
Definition: codec_par.h:75
AVIAMFSubmix
Submix layout as defined in section 3.7 of IAMF.
Definition: iamf.h:559
AV_WB32
#define AV_WB32(p, v)
Definition: intreadwrite.h:415
mov_read_pasp
static int mov_read_pasp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1475
MOVContext::dv_demux
DVDemuxContext * dv_demux
Definition: isom.h:338
AV_CODEC_ID_AAC
@ AV_CODEC_ID_AAC
Definition: codec_id.h:454
AVStereo3D::primary_eye
enum AVStereo3DPrimaryEye primary_eye
Which eye is the primary eye when rendering in 2D.
Definition: stereo3d.h:222
ff_dlog
#define ff_dlog(a,...)
Definition: tableprint_vlc.h:28
color_primaries
static const AVColorPrimariesDesc color_primaries[AVCOL_PRI_NB]
Definition: csp.c:76
mov_read_SA3D
static int mov_read_SA3D(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:9124
mov_read_elst
static int mov_read_elst(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6597
MOVEncryptionIndex::auxiliary_info_default_size
uint8_t auxiliary_info_default_size
Definition: isom.h:140
AV_STREAM_GROUP_PARAMS_TILE_GRID
@ AV_STREAM_GROUP_PARAMS_TILE_GRID
Definition: avformat.h:1150
IAMFAudioElement
Definition: iamf.h:89
AV_UUID_LEN
#define AV_UUID_LEN
Definition: uuid.h:57
av_sat_sub64
#define av_sat_sub64
Definition: common.h:142
mov_read_header
static int mov_read_header(AVFormatContext *s)
Definition: mov.c:11424
AV_CODEC_ID_QCELP
@ AV_CODEC_ID_QCELP
Definition: codec_id.h:476
mov_read_vdep
static int mov_read_vdep(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2765
AV_SPHERICAL_HALF_EQUIRECTANGULAR
@ AV_SPHERICAL_HALF_EQUIRECTANGULAR
Video frame displays as a 180 degree equirectangular projection.
Definition: spherical.h:73
AV_PROFILE_DTS_HD_HRA
#define AV_PROFILE_DTS_HD_HRA
Definition: defs.h:90
cbc1_scheme_decrypt
static int cbc1_scheme_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
Definition: mov.c:8529
avio_rl32
unsigned int avio_rl32(AVIOContext *s)
Definition: aviobuf.c:733
AVDISCARD_NONKEY
@ AVDISCARD_NONKEY
discard all frames except keyframes
Definition: defs.h:231
MOVFragment::flags
unsigned flags
Definition: isom.h:116
f
f
Definition: af_crystalizer.c:122
AVIOContext
Bytestream IO Context.
Definition: avio.h:160
AV_CODEC_ID_PCM_S24LE
@ AV_CODEC_ID_PCM_S24LE
Definition: codec_id.h:342
mov_read_wave
static int mov_read_wave(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2522
AV_SPHERICAL_CUBEMAP
@ AV_SPHERICAL_CUBEMAP
Video frame is split into 6 faces of a cube, and arranged on a 3x2 layout.
Definition: spherical.h:61
avio_rb24
unsigned int avio_rb24(AVIOContext *s)
Definition: aviobuf.c:757
ff_mpa_check_header
static int ff_mpa_check_header(uint32_t header)
Definition: mpegaudiodecheader.h:62
MOVStreamContext::aes_ctx
struct AVAES * aes_ctx
Definition: isom.h:283
cens_scheme_decrypt
static int cens_scheme_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
Definition: mov.c:8595
MOVContext::handbrake_version
int handbrake_version
Definition: isom.h:345
mov_free_stream_context
static void mov_free_stream_context(AVFormatContext *s, AVStream *st)
Definition: mov.c:10396
AVPacket::size
int size
Definition: packet.h:604
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:88
AV_STREAM_GROUP_PARAMS_TREF
@ AV_STREAM_GROUP_PARAMS_TREF
Definition: avformat.h:1152
ff_codec_get_id
enum AVCodecID ff_codec_get_id(const AVCodecTag *tags, unsigned int tag)
Definition: utils.c:143
avformat_alloc_context
AVFormatContext * avformat_alloc_context(void)
Allocate an AVFormatContext.
Definition: options.c:164
MOVFragmentIndexItem
Definition: isom.h:158
get_current_encryption_info
static int get_current_encryption_info(MOVContext *c, MOVEncryptionIndex **encryption_index, MOVStreamContext **sc)
Gets the current encryption info and associated current stream context.
Definition: mov.c:7768
AVIOContext::seekable
int seekable
A combination of AVIO_SEEKABLE_ flags or 0 when the stream is not seekable.
Definition: avio.h:261
av_aes_ctr_init
int av_aes_ctr_init(struct AVAESCTR *a, const uint8_t *key)
Initialize an AVAESCTR context.
Definition: aes_ctr.c:74
height
#define height
Definition: dsp.h:89
qtpalette.h
av_bprint_finalize
int av_bprint_finalize(AVBPrint *buf, char **ret_str)
Finalize a print buffer.
Definition: bprint.c:235
AVChannelLayout
An AVChannelLayout holds information about the channel layout of audio data.
Definition: channel_layout.h:319
FFStream
Definition: internal.h:128
mov_read_dref
static int mov_read_dref(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:653
mov_current_sample_dec
static void mov_current_sample_dec(MOVStreamContext *sc)
Definition: mov.c:4465
AVSphericalMapping::bound_right
uint32_t bound_right
Distance from the right edge.
Definition: spherical.h:187
MOVStsc::first
int first
Definition: isom.h:74
dst
uint8_t ptrdiff_t const uint8_t ptrdiff_t int intptr_t intptr_t int int16_t * dst
Definition: dsp.h:87
FFStream::last_discard_sample
int64_t last_discard_sample
The sample after last sample that is intended to be discarded after first_discard_sample.
Definition: internal.h:232
av_bswap32
#define av_bswap32
Definition: bswap.h:47
i
#define i(width, name, range_min, range_max)
Definition: cbs_h264.c:63
MOVStreamContext::stsz_sample_size
unsigned int stsz_sample_size
always contains sample size from stsz atom
Definition: isom.h:210
FF_MOV_FLAG_MFRA_AUTO
#define FF_MOV_FLAG_MFRA_AUTO
Definition: isom.h:464
ff_dict_set_timestamp
int ff_dict_set_timestamp(AVDictionary **dict, const char *key, int64_t timestamp)
Set a dictionary value to an ISO-8601 compliant timestamp string.
Definition: utils.c:616
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:122
for
for(k=2;k<=8;++k)
Definition: h264pred_template.c:424
MOVStreamContext::sgpd_sync
uint8_t * sgpd_sync
Definition: isom.h:248
start_time
static int64_t start_time
Definition: ffplay.c:328
uuid.h
ff_dvdclut_palette_extradata_cat
int ff_dvdclut_palette_extradata_cat(const uint32_t *clut, const size_t clut_size, AVCodecParameters *par)
Definition: dvdclut.c:28
mov_read_trun
static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6077
MOVStreamContext::stereo3d_size
size_t stereo3d_size
Definition: isom.h:268
avio_get_str
int avio_get_str(AVIOContext *pb, int maxlen, char *buf, int buflen)
Read a string from pb into buf.
Definition: aviobuf.c:869
mov_read_iprp
static int mov_read_iprp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:9737
av_sha_update
void av_sha_update(struct AVSHA *ctx, const uint8_t *data, size_t len)
Update hash value.
Definition: sha.c:315
sample
#define sample
Definition: flacdsp_template.c:44
hypot
static av_const double hypot(double x, double y)
Definition: libm.h:368
AV_CODEC_ID_H263
@ AV_CODEC_ID_H263
Definition: codec_id.h:54
MOV_TFHD_STSD_ID
#define MOV_TFHD_STSD_ID
Definition: isom.h:409
size
int size
Definition: twinvq_data.h:10344
mov_read_chan
static int mov_read_chan(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1298
AV_PROFILE_DTS_ES
#define AV_PROFILE_DTS_ES
Definition: defs.h:88
av_make_q
static AVRational av_make_q(int num, int den)
Create an AVRational.
Definition: rational.h:71
mov_read_stsc
static int mov_read_stsc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:3516
AV_WL32A
#define AV_WL32A(p, v)
Definition: intreadwrite.h:571
av_reallocp
int av_reallocp(void *ptr, size_t size)
Allocate, reallocate, or free a block of memory through a pointer to a pointer.
Definition: mem.c:188
ff_get_qtpalette
int ff_get_qtpalette(int codec_id, AVIOContext *pb, uint32_t *palette)
Retrieve the palette (or "color table" in QuickTime terms), either from the video sample description,...
Definition: qtpalette.c:323
AV_NOPTS_VALUE
#define AV_NOPTS_VALUE
Undefined timestamp value.
Definition: avutil.h:247
MKBETAG
#define MKBETAG(a, b, c, d)
Definition: macros.h:56
AV_CODEC_ID_QDMC
@ AV_CODEC_ID_QDMC
Definition: codec_id.h:502
av_fourcc_make_string
char * av_fourcc_make_string(char *buf, uint32_t fourcc)
Fill the provided buffer with a string containing a FourCC (four-character code) representation.
Definition: utils.c:54
AV_RB32
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_WL16 uint64_t_TMPL AV_WB64 unsigned int_TMPL AV_RB32
Definition: bytestream.h:96
avpriv_report_missing_feature
void avpriv_report_missing_feature(void *avc, const char *msg,...) av_printf_format(2
Log a generic warning message about a missing feature.
av_aes_ctr_set_full_iv
void av_aes_ctr_set_full_iv(struct AVAESCTR *a, const uint8_t *iv)
Forcefully change the "full" 16-byte iv, including the counter.
Definition: aes_ctr.c:53
AVStreamGroup::iamf_audio_element
struct AVIAMFAudioElement * iamf_audio_element
Definition: avformat.h:1192
AVCodecParameters::profile
int profile
Codec-specific bitstream restrictions that the stream conforms to.
Definition: codec_par.h:135
av_malloc
#define av_malloc(s)
Definition: ops_static.c:44
MOVStreamContext::coll
AVContentLightMetadata * coll
Definition: isom.h:273
aes_ctr.h
ff_format_io_close
int ff_format_io_close(AVFormatContext *s, AVIOContext **pb)
Definition: avformat.c:956
mov_parse_heif_items
static int mov_parse_heif_items(AVFormatContext *s)
Definition: mov.c:11062
HEIFItem::is_idat_relative
int is_idat_relative
Definition: isom.h:312
IAMFContext
Definition: iamf.h:128
add_index_entry
static int64_t add_index_entry(AVStream *st, int64_t pos, int64_t timestamp, int size, int distance, int flags)
Add index entry with the given values, to the end of ffstream(st)->index_entries.
Definition: mov.c:4315
MOVDref::path
char * path
Definition: isom.h:87
mov_current_sample_inc
static void mov_current_sample_inc(MOVStreamContext *sc)
Definition: mov.c:4453
AVStream::sample_aspect_ratio
AVRational sample_aspect_ratio
sample aspect ratio (0 if unknown)
Definition: avformat.h:844
FFInputFormat::p
AVInputFormat p
The public AVInputFormat.
Definition: demux.h:70
dovi_isom.h
AVPacket::dts
int64_t dts
Decompression timestamp in AVStream->time_base units; the time at which the packet is decompressed.
Definition: packet.h:602
mov_read_vexu_proj
static int mov_read_vexu_proj(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:7190
fix_timescale
static void fix_timescale(MOVContext *c, MOVStreamContext *sc)
Definition: mov.c:5373
avio_r8
int avio_r8(AVIOContext *s)
Definition: aviobuf.c:606
IAMFAudioElement::substreams
IAMFSubStream * substreams
Definition: iamf.h:98
AVSphericalMapping::padding
uint32_t padding
Number of pixels to pad from the edge of each cube face.
Definition: spherical.h:200
a
The reader does not expect b to be semantically here and if the code is changed by maybe adding a a division or other the signedness will almost certainly be mistaken To avoid this confusion a new type was SUINT is the C unsigned type but it holds a signed int to use the same example SUINT a
Definition: undefined.txt:41
av_channel_layout_retype
int av_channel_layout_retype(AVChannelLayout *channel_layout, enum AVChannelOrder order, int flags)
Change the AVChannelOrder of a channel layout.
Definition: channel_layout.c:887
mov_parse_dovi_streams
static int mov_parse_dovi_streams(AVFormatContext *s)
Definition: mov.c:11313
av_reallocp_array
int av_reallocp_array(void *ptr, size_t nmemb, size_t size)
Allocate, reallocate an array through a pointer to a pointer.
Definition: mem.c:225
AVIAMFAudioElement
Information on how to combine one or more audio streams, as defined in section 3.6 of IAMF.
Definition: iamf.h:359
AV_PRIMARY_EYE_NONE
@ AV_PRIMARY_EYE_NONE
Neither eye.
Definition: stereo3d.h:178
mov_read_default
static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:9981
AV_PROFILE_DTS
#define AV_PROFILE_DTS
Definition: defs.h:87
AV_TIMECODE_FLAG_24HOURSMAX
@ AV_TIMECODE_FLAG_24HOURSMAX
timecode wraps after 24 hours
Definition: timecode.h:37
mov_find_reference_track
static AVStream * mov_find_reference_track(AVFormatContext *s, AVStream *st, uint32_t *tref_id, int nb_tref_id, int first_index)
Definition: mov.c:11197
MOV_MP4_FPCM_TAG
#define MOV_MP4_FPCM_TAG
Definition: isom.h:484
ffio_ensure_seekback
int ffio_ensure_seekback(AVIOContext *s, int64_t buf_size)
Ensures that the requested seekback buffer size will be available.
Definition: aviobuf.c:1026
AVStreamGroupTileGrid::nb_tiles
unsigned int nb_tiles
Amount of tiles in the grid.
Definition: avformat.h:981
av_packet_side_data_add
AVPacketSideData * av_packet_side_data_add(AVPacketSideData **psd, int *pnb_sd, enum AVPacketSideDataType type, void *data, size_t size, int flags)
Wrap existing data as packet side data.
Definition: packet.c:613
mov_read_packet
static int mov_read_packet(AVFormatContext *s, AVPacket *pkt)
Definition: mov.c:11909
mov_read_infe
static int mov_read_infe(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:9367
offset
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf offset
Definition: writing_filters.txt:86
AV_CODEC_ID_LCEVC
@ AV_CODEC_ID_LCEVC
Definition: codec_id.h:608
AV_CH_TOP_BACK_RIGHT
#define AV_CH_TOP_BACK_RIGHT
Definition: channel_layout.h:192
MOVEncryptionIndex::auxiliary_offsets_count
size_t auxiliary_offsets_count
Definition: isom.h:142
HEIFItem::vflip
int vflip
Definition: isom.h:310
AVPacket::flags
int flags
A combination of AV_PKT_FLAG values.
Definition: packet.h:609
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:233
av_encryption_info_free
void av_encryption_info_free(AVEncryptionInfo *info)
Frees the given encryption info object.
Definition: encryption_info.c:82
read_header
static int read_header(FFV1Context *f, RangeCoder *c)
Definition: ffv1dec.c:574
av_strstart
int av_strstart(const char *str, const char *pfx, const char **ptr)
Return non-zero if pfx is a prefix of str.
Definition: avstring.c:36
AV_CH_FRONT_RIGHT_OF_CENTER
#define AV_CH_FRONT_RIGHT_OF_CENTER
Definition: channel_layout.h:182
AVSubsampleEncryptionInfo
This file is part of FFmpeg.
Definition: encryption_info.h:25
av_buffer_alloc
AVBufferRef * av_buffer_alloc(size_t size)
Allocate an AVBuffer of the given size using av_malloc().
Definition: buffer.c:77
MOVFragmentIndexItem::stream_info
MOVFragmentStreamInfo * stream_info
Definition: isom.h:163
version
version
Definition: libkvazaar.c:313
AV_STREAM_GROUP_PARAMS_IAMF_AUDIO_ELEMENT
@ AV_STREAM_GROUP_PARAMS_IAMF_AUDIO_ELEMENT
Definition: avformat.h:1148
AVEncryptionInitInfo::next
struct AVEncryptionInitInfo * next
An optional pointer to the next initialization info in the list.
Definition: encryption_info.h:122
AV_STEREO3D_FLAG_INVERT
#define AV_STEREO3D_FLAG_INVERT
Inverted views, Right/Bottom represents the left view.
Definition: stereo3d.h:194
AVStreamGroup::streams
AVStream ** streams
A list of streams in the group.
Definition: avformat.h:1234
ff_rfps_calculate
void ff_rfps_calculate(AVFormatContext *ic)
Definition: demux.c:2397
input
and forward the test the status of outputs and forward it to the corresponding return FFERROR_NOT_READY If the filters stores internally one or a few frame for some input
Definition: filter_design.txt:172
MOV_MP4_IPCM_TAG
#define MOV_MP4_IPCM_TAG
Definition: isom.h:485
mov_read_clli
static int mov_read_clli(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6871
MOVStreamContext::chunk_offsets
int64_t * chunk_offsets
Definition: isom.h:187
MovTref::id
uint32_t * id
trackID of the referenced track
Definition: isom.h:97
AVStreamGroup::iamf_mix_presentation
struct AVIAMFMixPresentation * iamf_mix_presentation
Definition: avformat.h:1193
AVBufferRef::size
size_t size
Size of data in bytes.
Definition: buffer.h:94
MOVFragmentIndex::item
MOVFragmentIndexItem * item
Definition: isom.h:171
AV_LOG_INFO
#define AV_LOG_INFO
Standard information.
Definition: log.h:221
MOVStreamContext::iamf
struct IAMFDemuxContext * iamf
Definition: isom.h:289
FFERROR_REDO
#define FFERROR_REDO
Returned by demuxers to indicate that data was consumed but discarded (ignored streams or junk data).
Definition: demux.h:224
av_encryption_init_info_alloc
AVEncryptionInitInfo * av_encryption_init_info_alloc(uint32_t system_id_size, uint32_t num_key_ids, uint32_t key_id_size, uint32_t data_size)
Allocates an AVEncryptionInitInfo structure and sub-pointers to hold the given sizes.
Definition: encryption_info.c:178
av_channel_layout_custom_init
int av_channel_layout_custom_init(AVChannelLayout *channel_layout, int nb_channels)
Initialize a custom channel layout with the specified number of channels.
Definition: channel_layout.c:233
av_aes_ctr_free
void av_aes_ctr_free(struct AVAESCTR *a)
Release an AVAESCTR context.
Definition: aes_ctr.c:84
AVFormatContext::error_recognition
int error_recognition
Error recognition; higher values will detect more errors but may misdetect some more or less valid pa...
Definition: avformat.h:1592
av_mastering_display_metadata_alloc_size
AVMasteringDisplayMetadata * av_mastering_display_metadata_alloc_size(size_t *size)
Allocate an AVMasteringDisplayMetadata structure and set its fields to default values.
Definition: mastering_display_metadata.c:44
mov_read_dfla
static int mov_read_dfla(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:8393
AV_RB16A
#define AV_RB16A(p)
Definition: intreadwrite.h:561
AVSHA::count
uint64_t count
number of bytes in buffer
Definition: sha.c:37
AV_SPHERICAL_RECTILINEAR
@ AV_SPHERICAL_RECTILINEAR
Video frame displays on a flat, rectangular 2D surface.
Definition: spherical.h:78
mov_default_parse_table
static const MOVParseTableEntry mov_default_parse_table[]
Definition: mov.c:9848
layout
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 layout
Definition: filter_design.txt:18
MOVDref::nlvl_from
int16_t nlvl_from
Definition: isom.h:91
AVStreamGroupTileGrid::nb_coded_side_data
int nb_coded_side_data
Amount of entries in coded_side_data.
Definition: avformat.h:1081
mov_metadata_creation_time
static void mov_metadata_creation_time(MOVContext *c, AVIOContext *pb, AVDictionary **metadata, int version)
Definition: mov.c:1971
mov_metadata_hmmt
static int mov_metadata_hmmt(MOVContext *c, AVIOContext *pb, unsigned len)
Definition: mov.c:325
AV_CODEC_ID_MJPEG
@ AV_CODEC_ID_MJPEG
Definition: codec_id.h:57
MOVFragmentStreamInfo::next_trun_dts
int64_t next_trun_dts
Definition: isom.h:150
MOVStreamContext::stsc_index
unsigned int stsc_index
Definition: isom.h:201
av_sha_alloc
struct AVSHA * av_sha_alloc(void)
Allocate an AVSHA context.
Definition: sha.c:46
mov_read_tenc
static int mov_read_tenc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:8322
av_uuid_equal
static int av_uuid_equal(const AVUUID uu1, const AVUUID uu2)
Compares two UUIDs for equality.
Definition: uuid.h:119
mov_stsc_index_valid
static int mov_stsc_index_valid(unsigned int index, unsigned int count)
Definition: mov.c:3596
mov_finalize_packet
static int mov_finalize_packet(AVFormatContext *s, AVStream *st, AVIndexEntry *sample, int64_t current_index, AVPacket *pkt)
Definition: mov.c:11825
MOVIndexRange
Definition: isom.h:174
mov_read_seek
static int mov_read_seek(AVFormatContext *s, int stream_index, int64_t sample_time, int flags)
Definition: mov.c:12244
bprint.h
MOVContext::advanced_editlist
int advanced_editlist
Definition: isom.h:350
MOVStreamContext::time_scale
int time_scale
Definition: isom.h:216
mlp_parse.h
mac_to_unicode
static const uint32_t mac_to_unicode[128]
Definition: mov.c:151
AVStreamGroupTileGrid::width
int width
Width of the final image for presentation.
Definition: avformat.h:1058
MOVStreamContext::bytes_per_frame
unsigned int bytes_per_frame
Definition: isom.h:223
AVSphericalMapping::roll
int32_t roll
Rotation around the forward vector [-180, 180].
Definition: spherical.h:146
IAMFContext::nb_audio_elements
int nb_audio_elements
Definition: iamf.h:132
MOVIndexRange::end
int64_t end
Definition: isom.h:176
AV_CODEC_ID_NONE
@ AV_CODEC_ID_NONE
Definition: codec_id.h:48
AVPacket::pts
int64_t pts
Presentation timestamp in AVStream->time_base units; the time at which the decompressed packet will b...
Definition: packet.h:596
code
and forward the test the status of outputs and forward it to the corresponding return FFERROR_NOT_READY If the filters stores internally one or a few frame for some it can consider them to be part of the FIFO and delay acknowledging a status change accordingly Example code
Definition: filter_design.txt:178
avio_internal.h
MOVCtts::offset
int offset
Definition: isom.h:70
AV_CH_SIDE_SURROUND_RIGHT
#define AV_CH_SIDE_SURROUND_RIGHT
Definition: channel_layout.h:206
mov_read_trex
static int mov_read_trex(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6012
search_frag_timestamp
static int search_frag_timestamp(AVFormatContext *s, MOVFragmentIndex *frag_index, AVStream *st, int64_t timestamp)
Definition: mov.c:1844
HEIFItem::width
int width
Definition: isom.h:306
FLAGS
#define FLAGS
Definition: mov.c:12301
MOVStreamContext::stereo3d
AVStereo3D * stereo3d
Definition: isom.h:267
mov_fix_index
static void mov_fix_index(MOVContext *mov, AVStream *st)
Fix ffstream(st)->index_entries, so that it contains only the entries (and the entries which are need...
Definition: mov.c:4505
ff_isom_parse_dvcc_dvvc
int ff_isom_parse_dvcc_dvvc(void *logctx, AVStream *st, const uint8_t *buf_ptr, uint64_t size)
Definition: dovi_isom.c:32
mov_read_pssh
static int mov_read_pssh(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:8170
MOVDref::volume
char volume[28]
Definition: isom.h:89
mov_read_stsd
static int mov_read_stsd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:3450
internal.h
AV_SPHERICAL_FISHEYE
@ AV_SPHERICAL_FISHEYE
Fisheye projection (Apple).
Definition: spherical.h:84
AVCodecParameters::height
int height
The height of the video frame in pixels.
Definition: codec_par.h:150
AV_TIME_BASE
#define AV_TIME_BASE
Internal time base represented as integer.
Definition: avutil.h:253
MOVStreamContext::stps_count
unsigned int stps_count
Definition: isom.h:203
AVCodecParameters::block_align
int block_align
The number of bytes per coded audio frame, required by some formats.
Definition: codec_par.h:221
AV_CODEC_ID_TTML
@ AV_CODEC_ID_TTML
Definition: codec_id.h:589
rb_size
static int rb_size(AVIOContext *pb, int64_t *value, int size)
Definition: mov.c:9240
AVStereo3DPrimaryEye
AVStereo3DPrimaryEye
List of possible primary eyes.
Definition: stereo3d.h:174
av_malloc_array
#define av_malloc_array(a, b)
Definition: tableprint_vlc.h:32
AV_CODEC_ID_CAVS
@ AV_CODEC_ID_CAVS
Definition: codec_id.h:137
display.h
ff_mov_read_stsd_entries
int ff_mov_read_stsd_entries(MOVContext *c, AVIOContext *pb, int entries)
Definition: mov.c:3349
AV_FIELD_BB
@ AV_FIELD_BB
Bottom coded first, bottom displayed first.
Definition: defs.h:215
AV_PKT_DATA_ICC_PROFILE
@ AV_PKT_DATA_ICC_PROFILE
ICC profile data consisting of an opaque octet buffer following the format described by ISO 15076-1.
Definition: packet.h:271
AV_STEREO3D_TOPBOTTOM
@ AV_STEREO3D_TOPBOTTOM
Views are on top of each other.
Definition: stereo3d.h:76
MOVFragment::duration
unsigned duration
Definition: isom.h:114
AVIAMFMixPresentation
Information on how to render and mix one or more AVIAMFAudioElement to generate the final audio outpu...
Definition: iamf.h:616
ff_id3v1_genre_str
const char *const ff_id3v1_genre_str[ID3v1_GENRE_MAX+1]
ID3v1 genres.
Definition: id3v1.c:26
MOVStreamContext::sample_sizes
unsigned int * sample_sizes
Definition: isom.h:212
s
uint8_t s
Definition: llvidencdsp.c:39
MOVContext::frag_index
MOVFragmentIndex frag_index
Definition: isom.h:363
mov_read_vpcc
static int mov_read_vpcc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6699
AV_CODEC_ID_PCM_F64BE
@ AV_CODEC_ID_PCM_F64BE
Definition: codec_id.h:352
AVStreamGroupLayeredVideo::width
int width
Width of the final stream for presentation.
Definition: avformat.h:1114
AV_CODEC_ID_HEVC
@ AV_CODEC_ID_HEVC
Definition: codec_id.h:223
AV_CH_BACK_CENTER
#define AV_CH_BACK_CENTER
Definition: channel_layout.h:183
value
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf default value
Definition: writing_filters.txt:86
av_url_split
void av_url_split(char *proto, int proto_size, char *authorization, int authorization_size, char *hostname, int hostname_size, int *port_ptr, char *path, int path_size, const char *url)
Split a URL string into components.
Definition: utils.c:361
MOVStreamContext::dref_id
int dref_id
Definition: isom.h:230
FFMIN
#define FFMIN(a, b)
Definition: macros.h:49
av_d2q
AVRational av_d2q(double d, int max)
Convert a double precision floating point number to a rational.
Definition: rational.c:110
fix_frag_index_entries
static void fix_frag_index_entries(MOVFragmentIndex *frag_index, int index, int id, int entries)
Definition: mov.c:1930
mov_finalize_stsd_codec
static int mov_finalize_stsd_codec(MOVContext *c, AVIOContext *pb, AVStream *st, MOVStreamContext *sc)
Definition: mov.c:3198
AV_CH_FRONT_LEFT
#define AV_CH_FRONT_LEFT
Definition: channel_layout.h:175
AV_CODEC_ID_PCM_S32BE
@ AV_CODEC_ID_PCM_S32BE
Definition: codec_id.h:339
mov_read_mdcv
static int mov_read_mdcv(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6790
AV_TIMECODE_FLAG_ALLOWNEGATIVE
@ AV_TIMECODE_FLAG_ALLOWNEGATIVE
negative time values are allowed
Definition: timecode.h:38
mov_read_mdat
static int mov_read_mdat(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1497
AV_CODEC_ID_VC1
@ AV_CODEC_ID_VC1
Definition: codec_id.h:120
demux.h
AV_DISPOSITION_DEPENDENT
#define AV_DISPOSITION_DEPENDENT
The stream is intended to be mixed with another stream before presentation.
Definition: avformat.h:727
MOVStreamContext::pb
AVIOContext * pb
Definition: isom.h:180
mov_read_keys
static int mov_read_keys(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5608
AVCodecParameters::color_range
enum AVColorRange color_range
Additional colorspace characteristics.
Definition: codec_par.h:189
AV_CH_SIDE_RIGHT
#define AV_CH_SIDE_RIGHT
Definition: channel_layout.h:185
len
int len
Definition: vorbis_enc_data.h:426
AV_CODEC_ID_JPEG2000
@ AV_CODEC_ID_JPEG2000
Definition: codec_id.h:138
exif.h
MOVFragment::size
unsigned size
Definition: isom.h:115
MOV_TFHD_DEFAULT_SIZE
#define MOV_TFHD_DEFAULT_SIZE
Definition: isom.h:411
MOVTimeToSample::count
unsigned int count
Definition: isom.h:58
profile
int profile
Definition: mxfenc.c:2299
ff_get_wav_header
int ff_get_wav_header(AVFormatContext *s, AVIOContext *pb, AVCodecParameters *par, int size, int big_endian)
Definition: riffdec.c:141
AVCOL_SPC_UNSPECIFIED
@ AVCOL_SPC_UNSPECIFIED
Definition: pixfmt.h:709
fix_stream_ids
static void fix_stream_ids(AVFormatContext *s)
Definition: mov.c:11386
av_rescale
int64_t av_rescale(int64_t a, int64_t b, int64_t c)
Rescale a 64-bit integer with rounding to nearest.
Definition: mathematics.c:129
mov_build_index
static void mov_build_index(MOVContext *mov, AVStream *st)
Definition: mov.c:4956
AVCodecParameters::coded_side_data
AVPacketSideData * coded_side_data
Additional data associated with the entire stream.
Definition: codec_par.h:83
mov_read_svq3
static int mov_read_svq3(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2517
mov_find_tref_tag
static MovTref * mov_find_tref_tag(const MOVStreamContext *sc, uint32_t name)
Definition: mov.c:2674
AVSHA
hash context
Definition: sha.c:35
AVCOL_RANGE_MPEG
@ AVCOL_RANGE_MPEG
Narrow or limited range content.
Definition: pixfmt.h:766
av_calloc
void * av_calloc(size_t nmemb, size_t size)
Definition: mem.c:264
MOVFragmentStreamInfo::tfdt_dts
int64_t tfdt_dts
Definition: isom.h:149
AV_IAMF_AUDIO_ELEMENT_TYPE_SCENE
@ AV_IAMF_AUDIO_ELEMENT_TYPE_SCENE
Definition: iamf.h:349
AVCodecParameters::field_order
enum AVFieldOrder field_order
The order of the fields in interlaced video.
Definition: codec_par.h:182
av_get_packet
int av_get_packet(AVIOContext *s, AVPacket *pkt, int size)
Allocate and read the payload of a packet and initialize its fields with default values.
Definition: utils.c:98
mov_read_iinf
static int mov_read_iinf(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:9444
ff_read_string_to_bprint_overwrite
int64_t ff_read_string_to_bprint_overwrite(AVIOContext *s, struct AVBPrint *bp, int64_t max_len)
Read a whole null-terminated string of text from AVIOContext to an AVBPrint buffer overwriting its co...
Definition: aviobuf.c:863
AVStreamGroupTileGrid::horizontal
int horizontal
Offset in pixels from the left edge of the canvas where the tile should be placed.
Definition: avformat.h:1017
get_stream_info_time
static int64_t get_stream_info_time(MOVFragmentStreamInfo *frag_stream_info)
Definition: mov.c:1792
MP4TrackKindValueMapping
Definition: isom.h:487
fix_index_entry_timestamps
static void fix_index_entry_timestamps(AVStream *st, int end_index, int64_t end_ts, int64_t *frame_duration_buffer, int frame_duration_buffer_size)
Rewrite timestamps of index entries in the range [end_index - frame_duration_buffer_size,...
Definition: mov.c:4356
AV_WB8
#define AV_WB8(p, d)
Definition: intreadwrite.h:392
MOVStreamContext::chunk_count
unsigned int chunk_count
Definition: isom.h:186
av_cmp_q
static int av_cmp_q(AVRational a, AVRational b)
Compare two rationals.
Definition: rational.h:89
MOVStreamContext::data_size
int64_t data_size
Definition: isom.h:240
AV_TIMECODE_FLAG_DROPFRAME
@ AV_TIMECODE_FLAG_DROPFRAME
timecode is drop frame
Definition: timecode.h:36
language
Undefined Behavior In the C language
Definition: undefined.txt:3
MOVStreamContext::ambient
AVAmbientViewingEnvironment * ambient
Definition: isom.h:275
AVCodecParameters::avcodec_parameters_copy
int avcodec_parameters_copy(AVCodecParameters *dst, const AVCodecParameters *src)
Copy the contents of src to dst.
Definition: codec_par.c:107
mov_read_tmcd
static int mov_read_tmcd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6671
AV_PROFILE_DTS_96_24
#define AV_PROFILE_DTS_96_24
Definition: defs.h:89
mov_chan.h
AVStream::disposition
int disposition
Stream disposition - a combination of AV_DISPOSITION_* flags.
Definition: avformat.h:835
MOVStreamContext::ambient_size
size_t ambient_size
Definition: isom.h:276
tag
uint32_t tag
Definition: movenc.c:2073
AVStream::id
int id
Format-specific stream ID.
Definition: avformat.h:778
ret
ret
Definition: filter_design.txt:187
AVStream
Stream structure.
Definition: avformat.h:766
AV_CODEC_ID_APV
@ AV_CODEC_ID_APV
Definition: codec_id.h:323
AV_LOG_FATAL
#define AV_LOG_FATAL
Something went wrong and recovery is not possible.
Definition: log.h:204
HEIFItem::extent_length
int64_t extent_length
Definition: isom.h:304
MOVEncryptionIndex::nb_encrypted_samples
unsigned int nb_encrypted_samples
Definition: isom.h:135
mov_read_senc
static int mov_read_senc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:7873
avio_seek
int64_t avio_seek(AVIOContext *s, int64_t offset, int whence)
fseek() equivalent for AVIOContext.
Definition: aviobuf.c:236
AVStreamGroupLayeredVideo::height
int height
Height of the final image for presentation.
Definition: avformat.h:1118
FFSWAP
#define FFSWAP(type, a, b)
Definition: macros.h:52
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:81
AVEncryptionInfo::key_id
uint8_t * key_id
The ID of the key used to encrypt the packet.
Definition: encryption_info.h:63
av_strlcat
size_t av_strlcat(char *dst, const char *src, size_t size)
Append the string src to the string dst, but to a total length of no more than size - 1 bytes,...
Definition: avstring.c:95
MOVStreamContext::stts_data
MOVStts * stts_data
Definition: isom.h:193
AVSphericalMapping::pitch
int32_t pitch
Rotation around the right vector [-90, 90].
Definition: spherical.h:145
AVStreamGroup::metadata
AVDictionary * metadata
Metadata that applies to the whole group.
Definition: avformat.h:1214
avio_rb16
unsigned int avio_rb16(AVIOContext *s)
Definition: aviobuf.c:749
AVStereo3D::type
enum AVStereo3DType type
How views are packed within the video.
Definition: stereo3d.h:207
MOVSbgp::index
unsigned int index
Definition: isom.h:129
HEIFItem::icc_profile_size
size_t icc_profile_size
Definition: isom.h:314
MOVContext::chapter_tracks
int * chapter_tracks
Definition: isom.h:346
cdt2
static const int16_t cdt2[8]
Definition: truemotion1data.h:43
AVSTREAM_PARSE_HEADERS
@ AVSTREAM_PARSE_HEADERS
Only parse headers, do not repack.
Definition: avformat.h:612
pos
unsigned int pos
Definition: spdifenc.c:414
avformat.h
dovi_meta.h
MOVFragment::implicit_offset
uint64_t implicit_offset
Definition: isom.h:112
dict.h
av_packet_side_data_new
AVPacketSideData * av_packet_side_data_new(AVPacketSideData **psd, int *pnb_sd, enum AVPacketSideDataType type, size_t size, int flags)
Allocate a new packet side data.
Definition: packet.c:620
AV_AUDIO_SERVICE_TYPE_KARAOKE
@ AV_AUDIO_SERVICE_TYPE_KARAOKE
Definition: defs.h:244
mov_read_dmlp
static int mov_read_dmlp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:8902
AV_INPUT_BUFFER_PADDING_SIZE
#define AV_INPUT_BUFFER_PADDING_SIZE
Definition: defs.h:40
MOVStreamContext::pseudo_stream_id
int pseudo_stream_id
-1 means demux all ids
Definition: isom.h:226
MOVContext::time_scale
int time_scale
Definition: isom.h:328
id
enum AVCodecID id
Definition: dts2pts.c:607
mov_read_tfdt
static int mov_read_tfdt(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6038
left
Tag MUST be and< 10hcoeff half pel interpolation filter coefficients, hcoeff[0] are the 2 middle coefficients[1] are the next outer ones and so on, resulting in a filter like:...eff[2], hcoeff[1], hcoeff[0], hcoeff[0], hcoeff[1], hcoeff[2] ... the sign of the coefficients is not explicitly stored but alternates after each coeff and coeff[0] is positive, so ...,+,-,+,-,+,+,-,+,-,+,... hcoeff[0] is not explicitly stored but found by subtracting the sum of all stored coefficients with signs from 32 hcoeff[0]=32 - hcoeff[1] - hcoeff[2] - ... a good choice for hcoeff and htaps is htaps=6 hcoeff={40,-10, 2} an alternative which requires more computations at both encoder and decoder side and may or may not be better is htaps=8 hcoeff={42,-14, 6,-2}ref_frames minimum of the number of available reference frames and max_ref_frames for example the first frame after a key frame always has ref_frames=1spatial_decomposition_type wavelet type 0 is a 9/7 symmetric compact integer wavelet 1 is a 5/3 symmetric compact integer wavelet others are reserved stored as delta from last, last is reset to 0 if always_reset||keyframeqlog quality(logarithmic quantizer scale) stored as delta from last, last is reset to 0 if always_reset||keyframemv_scale stored as delta from last, last is reset to 0 if always_reset||keyframe FIXME check that everything works fine if this changes between framesqbias dequantization bias stored as delta from last, last is reset to 0 if always_reset||keyframeblock_max_depth maximum depth of the block tree stored as delta from last, last is reset to 0 if always_reset||keyframequant_table quantization tableHighlevel bitstream structure:==============================--------------------------------------------|Header|--------------------------------------------|------------------------------------|||Block0||||split?||||yes no||||......... intra?||||:Block01 :yes no||||:Block02 :....... ..........||||:Block03 ::y DC ::ref index:||||:Block04 ::cb DC ::motion x :||||......... :cr DC ::motion y :||||....... ..........|||------------------------------------||------------------------------------|||Block1|||...|--------------------------------------------|------------ ------------ ------------|||Y subbands||Cb subbands||Cr subbands||||--- ---||--- ---||--- ---|||||LL0||HL0||||LL0||HL0||||LL0||HL0|||||--- ---||--- ---||--- ---||||--- ---||--- ---||--- ---|||||LH0||HH0||||LH0||HH0||||LH0||HH0|||||--- ---||--- ---||--- ---||||--- ---||--- ---||--- ---|||||HL1||LH1||||HL1||LH1||||HL1||LH1|||||--- ---||--- ---||--- ---||||--- ---||--- ---||--- ---|||||HH1||HL2||||HH1||HL2||||HH1||HL2|||||...||...||...|||------------ ------------ ------------|--------------------------------------------Decoding process:=================------------|||Subbands|------------||||------------|Intra DC||||LL0 subband prediction ------------|\ Dequantization ------------------- \||Reference frames|\ IDWT|------- -------|Motion \|||Frame 0||Frame 1||Compensation . OBMC v -------|------- -------|--------------. \------> Frame n output Frame Frame<----------------------------------/|...|------------------- Range Coder:============Binary Range Coder:------------------- The implemented range coder is an adapted version based upon "Range encoding: an algorithm for removing redundancy from a digitised message." by G. N. N. Martin. The symbols encoded by the Snow range coder are bits(0|1). The associated probabilities are not fix but change depending on the symbol mix seen so far. bit seen|new state ---------+----------------------------------------------- 0|256 - state_transition_table[256 - old_state];1|state_transition_table[old_state];state_transition_table={ 0, 0, 0, 0, 0, 0, 0, 0, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 190, 191, 192, 194, 194, 195, 196, 197, 198, 199, 200, 201, 202, 202, 204, 205, 206, 207, 208, 209, 209, 210, 211, 212, 213, 215, 215, 216, 217, 218, 219, 220, 220, 222, 223, 224, 225, 226, 227, 227, 229, 229, 230, 231, 232, 234, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 248, 0, 0, 0, 0, 0, 0, 0};FIXME Range Coding of integers:------------------------- FIXME Neighboring Blocks:===================left and top are set to the respective blocks unless they are outside of the image in which case they are set to the Null block top-left is set to the top left block unless it is outside of the image in which case it is set to the left block if this block has no larger parent block or it is at the left side of its parent block and the top right block is not outside of the image then the top right block is used for top-right else the top-left block is used Null block y, cb, cr are 128 level, ref, mx and my are 0 Motion Vector Prediction:=========================1. the motion vectors of all the neighboring blocks are scaled to compensate for the difference of reference frames scaled_mv=(mv *(256 *(current_reference+1)/(mv.reference+1))+128)> the median of the scaled left
Definition: snow.txt:386
av_sat_add64
#define av_sat_add64
Definition: common.h:139
heif_add_stream
static int heif_add_stream(MOVContext *c, HEIFItem *item)
Definition: mov.c:5754
search_frag_moof_offset
static int search_frag_moof_offset(MOVFragmentIndex *frag_index, int64_t offset)
Definition: mov.c:1768
MOVFragment
Definition: isom.h:107
AV_DICT_MATCH_CASE
#define AV_DICT_MATCH_CASE
Only get an entry with exact-case key match.
Definition: dict.h:74
AV_RL32
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_RL32
Definition: bytestream.h:92
U
#define U(x)
Definition: vpx_arith.h:37
mov_switch_root
static int mov_switch_root(AVFormatContext *s, int64_t target, int index)
Definition: mov.c:11696
FLAC_METADATA_TYPE_STREAMINFO
@ FLAC_METADATA_TYPE_STREAMINFO
Definition: flac.h:46
MOVContext::use_mfra_for
int use_mfra_for
Definition: isom.h:360
AVEncryptionInfo
This describes encryption info for a packet.
Definition: encryption_info.h:43
MOVStreamContext::encryption_index
MOVEncryptionIndex * encryption_index
Definition: isom.h:286
MIN_DATA_ENTRY_BOX_SIZE
#define MIN_DATA_ENTRY_BOX_SIZE
Definition: mov.c:652
AVStreamGroup
Definition: avformat.h:1159
av_get_media_type_string
const char * av_get_media_type_string(enum AVMediaType media_type)
Return a string describing the media_type enum, NULL if media_type is unknown.
Definition: utils.c:28
IAMFMixPresentation
Definition: iamf.h:107
AVStream::index
int index
stream index in AVFormatContext
Definition: avformat.h:772
avpriv_dv_init_demux
DVDemuxContext * avpriv_dv_init_demux(AVFormatContext *s)
Definition: dv.c:728
mov_seek_fragment
static int mov_seek_fragment(AVFormatContext *s, AVStream *st, int64_t timestamp)
Definition: mov.c:12090
AV_PROFILE_DTS_HD_MA
#define AV_PROFILE_DTS_HD_MA
Definition: defs.h:91
ff_configure_buffers_for_index
void ff_configure_buffers_for_index(AVFormatContext *s, int64_t time_tolerance)
Definition: seek.c:175
mov_parse_stsd_video
static void mov_parse_stsd_video(MOVContext *c, AVIOContext *pb, AVStream *st, MOVStreamContext *sc)
Definition: mov.c:2924
ff_codec_bmp_tags
const AVCodecTag ff_codec_bmp_tags[]
Definition: riff.c:36
MOVStreamContext::h_spacing
int h_spacing
pasp hSpacing
Definition: isom.h:235
mov_read_dec3
static int mov_read_dec3(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1126
get_frag_time
static int64_t get_frag_time(AVFormatContext *s, AVStream *dst_st, MOVFragmentIndex *frag_index, int index)
Definition: mov.c:1802
MOVStreamContext::sample_size
unsigned int sample_size
may contain value calculated from stsd or value from stsz atom
Definition: isom.h:209
HEVC_NAL_CRA_NUT
@ HEVC_NAL_CRA_NUT
Definition: hevc.h:50
AVStreamGroup::nb_streams
unsigned int nb_streams
Number of elements in AVStreamGroup.streams.
Definition: avformat.h:1221
mlp_samplerate
static int mlp_samplerate(int in)
Definition: mlp_parse.h:87
channel_layout.h
MOVStreamContext::duration_for_fps
int64_t duration_for_fps
Definition: isom.h:257
ISOM_DVCC_DVVC_SIZE
#define ISOM_DVCC_DVVC_SIZE
Definition: dovi_isom.h:29
mov_read_sbgp
static int mov_read_sbgp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:4112
MOVFragment::moof_offset
uint64_t moof_offset
Definition: isom.h:111
AVIO_SEEKABLE_NORMAL
#define AVIO_SEEKABLE_NORMAL
Seeking works like for a local file.
Definition: avio.h:41
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: packet.c:231
buffer
the frame and frame reference mechanism is intended to as much as expensive copies of that data while still allowing the filters to produce correct results The data is stored in buffers represented by AVFrame structures Several references can point to the same frame buffer
Definition: filter_design.txt:49
mov_read_glbl
static int mov_read_glbl(MOVContext *c, AVIOContext *pb, MOVAtom atom)
This function reads atom content and puts data in extradata without tag nor size unlike mov_read_extr...
Definition: mov.c:2579
AVRational::den
int den
Denominator.
Definition: rational.h:60
mode
mode
Definition: ebur128.h:83
mov_parse_uuid_spherical
static int mov_parse_uuid_spherical(MOVStreamContext *sc, AVIOContext *pb, size_t len)
Definition: mov.c:7531
MOVTrackExt::size
unsigned size
Definition: isom.h:123
AVDOVIDecoderConfigurationRecord::bl_present_flag
uint8_t bl_present_flag
Definition: dovi_meta.h:62
ff_remove_stream_group
void ff_remove_stream_group(AVFormatContext *s, AVStreamGroup *stg)
Remove a stream group from its AVFormatContext and free it.
Definition: avformat.c:128
AV_OPT_TYPE_INT
@ AV_OPT_TYPE_INT
Underlying C type is int.
Definition: opt.h:258
MOVContext::dv_fctx
AVFormatContext * dv_fctx
Definition: isom.h:339
av_channel_layout_uninit
void av_channel_layout_uninit(AVChannelLayout *channel_layout)
Free any allocated data in the channel layout and reset the channel count to 0.
Definition: channel_layout.c:443
AV_CODEC_ID_DVAUDIO
@ AV_CODEC_ID_DVAUDIO
Definition: codec_id.h:458
avformat_free_context
void avformat_free_context(AVFormatContext *s)
Free an AVFormatContext and all its streams.
Definition: avformat.c:148
MOVContext::aax_mode
unsigned int aax_mode
'aax' file has been detected
Definition: isom.h:365
mov_read_sv3d
static int mov_read_sv3d(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:7053
avio_read
int avio_read(AVIOContext *s, unsigned char *buf, int size)
Read size bytes from AVIOContext into buf.
Definition: aviobuf.c:615
mov_aaxc_crypto
static int mov_aaxc_crypto(MOVContext *c)
Definition: mov.c:1608
mov_get_skip_samples
static int64_t mov_get_skip_samples(AVStream *st, int sample)
Definition: mov.c:12228
MOVFragmentIndex
Definition: isom.h:166
AV_RB8
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_WL16 uint64_t_TMPL AV_WB64 unsigned int_TMPL AV_WB32 unsigned int_TMPL AV_WB24 unsigned int_TMPL AV_WB16 unsigned int_TMPL AV_RB8
Definition: bytestream.h:99
ref
static int ref[MAX_W *MAX_W]
Definition: jpeg2000dwt.c:117
mov_read_cdsc
static int mov_read_cdsc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2702
AVStream::r_frame_rate
AVRational r_frame_rate
Real base framerate of the stream.
Definition: avformat.h:900
MOVStreamContext::tts_count
unsigned int tts_count
Definition: isom.h:188
MOVStreamContext::track_end
int64_t track_end
used for dts generation in fragmented movie files
Definition: isom.h:243
MOVStreamContext::sgpd_sync_count
uint32_t sgpd_sync_count
Definition: isom.h:249
MOVContext::fragment
MOVFragment fragment
current fragment in moof atom
Definition: isom.h:341
AVDOVIDecoderConfigurationRecord::rpu_present_flag
uint8_t rpu_present_flag
Definition: dovi_meta.h:60
AVIndexEntry::pos
int64_t pos
Definition: avformat.h:621
AVIOContext::eof_reached
int eof_reached
true if was unable to read due to error or eof
Definition: avio.h:238
mov_metadata_int8_bypass_padding
static int mov_metadata_int8_bypass_padding(MOVContext *c, AVIOContext *pb, unsigned len, const char *key)
Definition: mov.c:112
AVDOVIDecoderConfigurationRecord::el_present_flag
uint8_t el_present_flag
Definition: dovi_meta.h:61
MOVDref::type
uint32_t type
Definition: isom.h:86
samples
Filter the word “frame” indicates either a video frame or a group of audio samples
Definition: filter_design.txt:8
mean
static float mean(const float *input, int size)
Definition: vf_nnedi.c:861
mov_read_covr
static int mov_read_covr(MOVContext *c, AVIOContext *pb, int type, int len)
Definition: mov.c:232
MOVParseTableEntry::type
uint32_t type
Definition: mov.c:84
Windows::Graphics::DirectX::Direct3D11::p
IDirect3DDxgiInterfaceAccess _COM_Outptr_ void ** p
Definition: vsrc_gfxcapture_winrt.hpp:53
AVMasteringDisplayMetadata::min_luminance
AVRational min_luminance
Min luminance of mastering display (cd/m^2).
Definition: mastering_display_metadata.h:52
MOVStreamContext::per_sample_iv_size
unsigned int per_sample_iv_size
Definition: isom.h:284
ff_codec_movsubtitle_tags
const AVCodecTag ff_codec_movsubtitle_tags[]
Definition: isom.c:75
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:605
MOVFragmentIndexItem::nb_stream_info
int nb_stream_info
Definition: isom.h:162
avio_skip
int64_t avio_skip(AVIOContext *s, int64_t offset)
Skip given number of bytes forward.
Definition: aviobuf.c:321
export_orphan_timecode
static void export_orphan_timecode(AVFormatContext *s)
Definition: mov.c:10534
mov_read_sbas
static int mov_read_sbas(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2733
MOVStreamContext::has_sidx
int has_sidx
Definition: isom.h:280
AV_CH_FRONT_RIGHT
#define AV_CH_FRONT_RIGHT
Definition: channel_layout.h:176
av_aes_ctr_crypt
void av_aes_ctr_crypt(struct AVAESCTR *a, uint8_t *dst, const uint8_t *src, int count)
Process a buffer using a previously initialized context.
Definition: aes_ctr.c:102
mov_metadata_gnre
static int mov_metadata_gnre(MOVContext *c, AVIOContext *pb, unsigned len, const char *key)
Definition: mov.c:135
AV_PKT_DATA_ENCRYPTION_INFO
@ AV_PKT_DATA_ENCRYPTION_INFO
This side data contains encryption info for how to decrypt the packet.
Definition: packet.h:252
MOV_MERGE_CTTS
#define MOV_MERGE_CTTS
Definition: mov.c:4886
FFStream::index_entries
AVIndexEntry * index_entries
Only used if the format does not support seeking natively.
Definition: internal.h:184
av_dict_set_int
int av_dict_set_int(AVDictionary **pm, const char *key, int64_t value, int flags)
Convenience wrapper for av_dict_set() that converts the value to a string and stores it.
Definition: dict.c:177
mov_read_dpxe
static int mov_read_dpxe(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2402
AVIAMFSubmix::nb_elements
unsigned int nb_elements
Number of elements in the submix.
Definition: iamf.h:575
MOVFragmentStreamInfo::id
int id
Definition: isom.h:146
AVIO_FLAG_READ
#define AVIO_FLAG_READ
read-only
Definition: avio.h:617
AV_PKT_DATA_AUDIO_SERVICE_TYPE
@ AV_PKT_DATA_AUDIO_SERVICE_TYPE
This side data should be associated with an audio stream and corresponds to enum AVAudioServiceType.
Definition: packet.h:117
av_spherical_alloc
AVSphericalMapping * av_spherical_alloc(size_t *size)
Allocate a AVSphericalVideo structure and initialize its fields to default values.
Definition: spherical.c:26
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:355
mov_read_rtmd_track
static int mov_read_rtmd_track(AVFormatContext *s, AVStream *st)
Definition: mov.c:10311
AVMEDIA_TYPE_VIDEO
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:200
read_probe
static int read_probe(const AVProbeData *p)
Definition: cdg.c:30
MOVStreamContext::pb_is_copied
int pb_is_copied
Definition: isom.h:182
AV_CODEC_ID_PCM_S32LE
@ AV_CODEC_ID_PCM_S32LE
Definition: codec_id.h:338
AVCodecParameters::bits_per_coded_sample
int bits_per_coded_sample
The number of bits per sample in the codedwords.
Definition: codec_par.h:113
mov_parse_tiles
static int mov_parse_tiles(AVFormatContext *s)
Definition: mov.c:10936
mem.h
AVStreamGroup::type
enum AVStreamGroupParamsType type
Group type.
Definition: avformat.h:1186
MOVElst::time
int64_t time
Definition: isom.h:81
AVBufferRef
A reference to a data buffer.
Definition: buffer.h:82
HEIFGrid
Definition: isom.h:317
mov_read_iref_dimg
static int mov_read_iref_dimg(MOVContext *c, AVIOContext *pb, int version)
Definition: mov.c:9498
mov_read_pcmc
static int mov_read_pcmc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2124
build_open_gop_key_points
static int build_open_gop_key_points(AVStream *st)
Definition: mov.c:4823
mov_parse_stsd_audio
static void mov_parse_stsd_audio(MOVContext *c, AVIOContext *pb, AVStream *st, MOVStreamContext *sc)
Definition: mov.c:2988
IAMFContext::mix_presentations
IAMFMixPresentation ** mix_presentations
Definition: iamf.h:133
AV_CODEC_ID_PCM_U8
@ AV_CODEC_ID_PCM_U8
Definition: codec_id.h:335
MOVContext::trak_index
int trak_index
Index of the current 'trak'.
Definition: isom.h:335
mov_read_timecode_track
static int mov_read_timecode_track(AVFormatContext *s, AVStream *st)
Definition: mov.c:10337
HEIFGrid::item
HEIFItem * item
Definition: isom.h:318
AVSphericalMapping::bound_left
uint32_t bound_left
Distance from the left edge.
Definition: spherical.h:185
mov_read_mac_string
static int mov_read_mac_string(MOVContext *c, AVIOContext *pb, int len, char *dst, int dstlen)
Definition: mov.c:170
MOVEncryptionIndex::auxiliary_info_sizes
uint8_t * auxiliary_info_sizes
Definition: isom.h:138
MOVFragment::stsd_id
unsigned stsd_id
Definition: isom.h:113
AVCodecParameters::video_delay
int video_delay
Number of delayed frames.
Definition: codec_par.h:200
HEIFGrid::tile_id_list
int16_t * tile_id_list
Definition: isom.h:320
avpriv_request_sample
#define avpriv_request_sample(...)
Definition: tableprint_vlc.h:37
MOVStreamContext::tts_data
MOVTimeToSample * tts_data
Definition: isom.h:190
map
const VDPAUPixFmtMap * map
Definition: hwcontext_vdpau.c:71
avformat_stream_group_create
AVStreamGroup * avformat_stream_group_create(AVFormatContext *s, enum AVStreamGroupParamsType type, AVDictionary **options)
Add a new empty stream group to a media file.
Definition: options.c:469
AV_CHANNEL_LAYOUT_MONO
#define AV_CHANNEL_LAYOUT_MONO
Definition: channel_layout.h:394
AV_CODEC_ID_PCM_F64LE
@ AV_CODEC_ID_PCM_F64LE
Definition: codec_id.h:353
AVStreamGroupTileGrid::height
int height
Height of the final image for presentation.
Definition: avformat.h:1068
AVStereo3D::view
enum AVStereo3DView view
Determines which views are packed.
Definition: stereo3d.h:217
read_tfra
static int read_tfra(MOVContext *mov, AVIOContext *f)
Definition: mov.c:10552
av_free
#define av_free(p)
Definition: tableprint_vlc.h:34
AVDictionaryEntry
Definition: dict.h:90
mov_read_hvce
static int mov_read_hvce(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:8957
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:57
AV_PKT_DATA_HEVC_CONF
@ AV_PKT_DATA_HEVC_CONF
Dolby Vision enhancement-layer HEVC decoder configuration.
Definition: packet.h:384
AVStereo3DView
AVStereo3DView
List of possible view types.
Definition: stereo3d.h:149
AV_CH_SIDE_SURROUND_LEFT
#define AV_CH_SIDE_SURROUND_LEFT
Definition: channel_layout.h:205
AVPacket
This structure stores compressed data.
Definition: packet.h:580
AVContentLightMetadata::MaxFALL
unsigned MaxFALL
Max average light level per frame (cd/m^2).
Definition: mastering_display_metadata.h:116
mov_parse_lcevc_streams
static int mov_parse_lcevc_streams(AVFormatContext *s)
Definition: mov.c:11259
mov_read_hfov
static int mov_read_hfov(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:7502
AV_OPT_TYPE_BOOL
@ AV_OPT_TYPE_BOOL
Underlying C type is int.
Definition: opt.h:326
MOVStreamContext::stps_data
unsigned * stps_data
partial sync sample for mpeg-2 open gop
Definition: isom.h:204
AV_CODEC_ID_ADPCM_IMA_WAV
@ AV_CODEC_ID_ADPCM_IMA_WAV
Definition: codec_id.h:370
MOVContext::nb_heif_item
int nb_heif_item
Definition: isom.h:387
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:35
av_dict_set
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
riff.h
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:247
av_encryption_info_alloc
AVEncryptionInfo * av_encryption_info_alloc(uint32_t subsample_count, uint32_t key_id_size, uint32_t iv_size)
Allocates an AVEncryptionInfo structure and sub-pointers to hold the given number of subsamples.
Definition: encryption_info.c:41
AVPacket::pos
int64_t pos
byte position in stream, -1 if unknown
Definition: packet.h:623
FFInputFormat
Definition: demux.h:66
MOVContext::decryption_keys
AVDictionary * decryption_keys
Definition: isom.h:392
mov_metadata_loci
static int mov_metadata_loci(MOVContext *c, AVIOContext *pb, unsigned len)
Definition: mov.c:275
mov_read_eyes
static int mov_read_eyes(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:7263
AV_CODEC_ID_ILBC
@ AV_CODEC_ID_ILBC
Definition: codec_id.h:511
AV_CHAN_AMBISONIC_BASE
@ AV_CHAN_AMBISONIC_BASE
Range of channels between AV_CHAN_AMBISONIC_BASE and AV_CHAN_AMBISONIC_END represent Ambisonic compon...
Definition: channel_layout.h:108
MOV_TRUN_SAMPLE_SIZE
#define MOV_TRUN_SAMPLE_SIZE
Definition: isom.h:419
MOVStreamContext::tmcd_flags
uint32_t tmcd_flags
tmcd track flags
Definition: isom.h:241
int32_t
int32_t
Definition: audioconvert.c:56
HEIFItem::rotation
int rotation
Definition: isom.h:308
MOVAtom::type
uint32_t type
Definition: isom.h:101
distance
static float distance(float x, float y, int band)
Definition: nellymoserenc.c:231
AVSTREAM_PARSE_FULL
@ AVSTREAM_PARSE_FULL
full parsing and repack
Definition: avformat.h:611
parse_timecode_in_framenum_format
static int parse_timecode_in_framenum_format(AVFormatContext *s, AVStream *st, int64_t value, int flags)
Definition: mov.c:10297
MOVStreamContext::tmcd_nb_frames
uint8_t tmcd_nb_frames
tmcd number of frames per tick / second
Definition: isom.h:242
AVIAMFSubmixElement
Submix element as defined in section 3.7 of IAMF.
Definition: iamf.h:449
replaygain.h
MOVFragmentIndexItem::headers_read
int headers_read
Definition: isom.h:160
AV_CODEC_ID_VP8
@ AV_CODEC_ID_VP8
Definition: codec_id.h:190
AVERROR_BUG
#define AVERROR_BUG
Internal bug, also see AVERROR_BUG2.
Definition: error.h:52
mov_parse_cdsc_streams
static int mov_parse_cdsc_streams(AVFormatContext *s)
Definition: mov.c:11212
MP4TrackKindValueMapping::value
const char * value
Definition: isom.h:489
AVStereo3DType
AVStereo3DType
List of possible 3D Types.
Definition: stereo3d.h:48
MOVDref::filename
char filename[64]
Definition: isom.h:90
MOVStsc::count
int count
Definition: isom.h:75
AV_CODEC_ID_PCM_F32LE
@ AV_CODEC_ID_PCM_F32LE
Definition: codec_id.h:351
ff_mov_demuxer
const FFInputFormat ff_mov_demuxer
Definition: mov.c:12363
AVCodecParameters::bit_rate
int64_t bit_rate
The average bitrate of the encoded data (in bits per second).
Definition: codec_par.h:99
MOVStts::count
unsigned int count
Definition: isom.h:64
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
MOVStreamContext::display_matrix
int32_t * display_matrix
Definition: isom.h:266
MOVContext::heif_grid
HEIFGrid * heif_grid
Definition: isom.h:388
MOVStreamContext::min_sample_duration
uint32_t min_sample_duration
Definition: isom.h:254
MOVStreamContext::current_index
int64_t current_index
Definition: isom.h:220
AVERROR_INVALIDDATA
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:61
ff_mov_track_kind_table
const struct MP4TrackKindMapping ff_mov_track_kind_table[]
Definition: isom.c:465
AV_CH_BACK_RIGHT
#define AV_CH_BACK_RIGHT
Definition: channel_layout.h:180
get_curr_st
static AVStream * get_curr_st(MOVContext *c)
Get the current stream in the parsing process.
Definition: mov.c:214
mov_dts_channel_layout_to_mask
static uint64_t mov_dts_channel_layout_to_mask(unsigned int code)
Definition: mov.c:1208
MOVStreamContext::stts_allocated_size
unsigned int stts_allocated_size
Definition: isom.h:192
MOVFragmentStreamInfo::index_entry
int index_entry
Definition: isom.h:153
cenc_decrypt
static int cenc_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
Definition: mov.c:8738
AVStreamGroup::params
union AVStreamGroup::@461 params
Group type-specific parameters.
MOVStreamContext::format
uint32_t format
Definition: isom.h:278
MKTAG
#define MKTAG(a, b, c, d)
Definition: macros.h:55
ffio_read_size
int ffio_read_size(AVIOContext *s, unsigned char *buf, int size)
Read size bytes from AVIOContext into buf.
Definition: aviobuf.c:665
MOVStreamContext::sync_group_count
unsigned int sync_group_count
Definition: isom.h:246
MOVContext::bitrates_count
int bitrates_count
Definition: isom.h:358
AV_CODEC_ID_VORBIS
@ AV_CODEC_ID_VORBIS
Definition: codec_id.h:457
AVDictionaryEntry::value
char * value
Definition: dict.h:92
AVStream::start_time
int64_t start_time
Decoding: pts of the first frame of the stream in presentation order, in stream time base.
Definition: avformat.h:815
MOVStreamContext::id
int id
AVStream id.
Definition: isom.h:183
MOVStreamContext::samples_per_frame
unsigned int samples_per_frame
Definition: isom.h:224
MOVStreamContext::tts_allocated_size
unsigned int tts_allocated_size
Definition: isom.h:189
pkt
static AVPacket * pkt
Definition: demux_decode.c:55
MOVElst::duration
int64_t duration
Definition: isom.h:80
ac3tab.h
avstring.h
mov_read_ispe
static int mov_read_ispe(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:9670
width
#define width
Definition: dsp.h:89
AVAmbientViewingEnvironment::ambient_light_y
AVRational ambient_light_y
Normalized y chromaticity coordinate of the environmental ambient light in the nominal viewing enviro...
Definition: ambient_viewing_environment.h:54
mov_read_iref
static int mov_read_iref(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:9625
IAMFMixPresentation::mix
AVIAMFMixPresentation * mix
mix backs cmix iff the AVIAMFMixPresentation is owned by this structure.
Definition: iamf.h:113
mov_read_clap
static int mov_read_clap(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1366
mov_read_mfra
static int mov_read_mfra(MOVContext *c, AVIOContext *f)
Definition: mov.c:10607
AV_CODEC_ID_FLV1
@ AV_CODEC_ID_FLV1
Definition: codec_id.h:71
mov_metadata_int8_no_padding
static int mov_metadata_int8_no_padding(MOVContext *c, AVIOContext *pb, unsigned len, const char *key)
Definition: mov.c:126
flac.h
AVStreamGroupTileGrid::idx
unsigned int idx
Index of the stream in the group this tile references.
Definition: avformat.h:1012
AVTimecode
Definition: timecode.h:41
get_frag_stream_info
static MOVFragmentStreamInfo * get_frag_stream_info(MOVFragmentIndex *frag_index, int index, int id)
Definition: mov.c:1713
IAMFDemuxContext::iamf
IAMFContext iamf
Definition: iamf_reader.h:33
IAMFSubStream::codecpar
AVCodecParameters * codecpar
Definition: iamf.h:86
mov_read_kind
static int mov_read_kind(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:9035
MOVContext::heif_item
HEIFItem ** heif_item
Definition: isom.h:386
MOVStreamContext::stts_count
unsigned int stts_count
Definition: isom.h:191
AVStreamGroupLayeredVideo::el_index
unsigned int el_index
Index of the enhancement layer stream in AVStreamGroup.
Definition: avformat.h:1102
MOV_TRUN_SAMPLE_CTS
#define MOV_TRUN_SAMPLE_CTS
Definition: isom.h:421
HEIFItem::iref_list
HEIFItemRef * iref_list
Definition: isom.h:300
AV_OPT_TYPE_CONST
@ AV_OPT_TYPE_CONST
Special option type for declaring named constants.
Definition: opt.h:298
MOV_ISMV_TTML_TAG
#define MOV_ISMV_TTML_TAG
Definition: isom.h:482
snprintf
#define snprintf
Definition: snprintf.h:34
IAMFMixPresentation::mix_presentation_id
unsigned int mix_presentation_id
Definition: iamf.h:114
AVCodecParameters::initial_padding
int initial_padding
Number of padding audio samples at the start.
Definition: codec_par.h:239
AV_CODEC_ID_PCM_S24BE
@ AV_CODEC_ID_PCM_S24BE
Definition: codec_id.h:343
mov_read_st3d
static int mov_read_st3d(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6925
mov_read_imir
static int mov_read_imir(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:9718
is_open_key_sample
static int is_open_key_sample(const MOVStreamContext *sc, int sample)
Definition: mov.c:12109
mov_read_dvc1
static int mov_read_dvc1(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2625
MOVStreamContext::elst_count
unsigned int elst_count
Definition: isom.h:206
av_color_transfer_name
const char * av_color_transfer_name(enum AVColorTransferCharacteristic transfer)
Definition: pixdesc.c:3827
AVChannelCustom::id
enum AVChannel id
Definition: channel_layout.h:284
mov_read_atom_into_extradata
static int64_t mov_read_atom_into_extradata(MOVContext *c, AVIOContext *pb, MOVAtom atom, AVCodecParameters *par, uint8_t *buf)
Definition: mov.c:2339
AV_WL16A
#define AV_WL16A(p, v)
Definition: intreadwrite.h:557
AV_RB64
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_WL16 uint64_t_TMPL AV_RB64
Definition: bytestream.h:95
AVSphericalMapping::yaw
int32_t yaw
Rotation around the up vector [-180, 180].
Definition: spherical.h:144
src
#define src
Definition: vp8dsp.c:248
mov_read_chapters
static void mov_read_chapters(AVFormatContext *s)
Definition: mov.c:10198
AV_CODEC_ID_DNXHD
@ AV_CODEC_ID_DNXHD
Definition: codec_id.h:149
channel
channel
Definition: ebur128.h:39
MOVStreamContext::default_encrypted_sample
AVEncryptionInfo * default_encrypted_sample
Definition: isom.h:285
duration
static int64_t duration
Definition: ffplay.c:329
MOVContext::cur_item_id
int cur_item_id
Definition: isom.h:385
av_timecode_make_string
char * av_timecode_make_string(const AVTimecode *tc, char *buf, int framenum_arg)
Load timecode string in buf.
Definition: timecode.c:104
AVFMT_EVENT_FLAG_METADATA_UPDATED
#define AVFMT_EVENT_FLAG_METADATA_UPDATED
Definition: avformat.h:1712
AV_DICT_DONT_STRDUP_KEY
#define AV_DICT_DONT_STRDUP_KEY
Take ownership of a key that's been allocated with av_malloc() or another memory allocation function.
Definition: dict.h:77
MOVContext::next_root_atom
int64_t next_root_atom
offset of the next root atom
Definition: isom.h:354
MOVContext::found_iinf
int found_iinf
'iinf' atom has been found
Definition: isom.h:332
MOVContext::meta_keys_count
unsigned meta_keys_count
Definition: isom.h:337
iamf_reader.h
AVStreamGroupTileGrid::background
uint8_t background[4]
The pixel value per channel in RGBA format used if no pixel of any tile is located at a particular pi...
Definition: avformat.h:1032
MOVStreamContext::palette
uint32_t palette[256]
Definition: isom.h:238
cenc_scheme_decrypt
static int cenc_scheme_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
Definition: mov.c:8470
MOVFragment::track_id
unsigned track_id
Definition: isom.h:109
mov_read_hdlr
static int mov_read_hdlr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:797
mov_parse_stsd_data
static int mov_parse_stsd_data(MOVContext *c, AVIOContext *pb, AVStream *st, MOVStreamContext *sc, int64_t size)
Definition: mov.c:3125
AV_CH_SIDE_LEFT
#define AV_CH_SIDE_LEFT
Definition: channel_layout.h:184
ff_iamf_read_deinit
void ff_iamf_read_deinit(IAMFDemuxContext *c)
Definition: iamf_reader.c:371
AV_CODEC_ID_PRORES
@ AV_CODEC_ID_PRORES
Definition: codec_id.h:198
AV_RB16
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_WL16 uint64_t_TMPL AV_WB64 unsigned int_TMPL AV_WB32 unsigned int_TMPL AV_WB24 unsigned int_TMPL AV_RB16
Definition: bytestream.h:98
av_encryption_init_info_add_side_data
uint8_t * av_encryption_init_info_add_side_data(const AVEncryptionInitInfo *info, size_t *side_data_size)
Allocates and initializes side data that holds a copy of the given encryption init info.
Definition: encryption_info.c:292
av_fourcc2str
#define av_fourcc2str(fourcc)
Definition: avutil.h:323
ff_mov_read_chan
int ff_mov_read_chan(AVFormatContext *s, AVIOContext *pb, AVStream *st, int64_t size)
Read 'chan' tag from the input stream.
Definition: mov_chan.c:550
av_index_search_timestamp
int av_index_search_timestamp(AVStream *st, int64_t timestamp, int flags)
Get the index for a specific timestamp.
Definition: seek.c:245
mov_read_pitm
static int mov_read_pitm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:9259
MOVContext::ignore_chapters
int ignore_chapters
Definition: isom.h:352
MOVTimeToSample::offset
int offset
Definition: isom.h:60
mov_read_dac3
static int mov_read_dac3(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:868
MP4TrackKindMapping
Definition: isom.h:492
ff_alloc_extradata
int ff_alloc_extradata(AVCodecParameters *par, int size)
Allocate extradata with additional AV_INPUT_BUFFER_PADDING_SIZE at end which is always set to 0.
Definition: utils.c:237
AVDOVIDecoderConfigurationRecord
Definition: dovi_meta.h:55
HEIFItem::nb_iref_list
int nb_iref_list
Definition: isom.h:301
AV_DISPOSITION_NON_DIEGETIC
#define AV_DISPOSITION_NON_DIEGETIC
The stream is intended to be mixed with a spatial audio track.
Definition: avformat.h:704
avio_feof
int avio_feof(AVIOContext *s)
Similar to feof() but also returns nonzero on read errors.
Definition: aviobuf.c:349
mc
#define mc
Definition: vf_colormatrix.c:100
MOVStreamContext::ffindex
int ffindex
AVStream index.
Definition: isom.h:184
HEIFItem::extent_offset
int64_t extent_offset
Definition: isom.h:305
mov_read_stsz
static int mov_read_stsz(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:3713