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/internal.h"
36 #include "libavutil/intreadwrite.h"
37 #include "libavutil/intfloat.h"
38 #include "libavutil/mathematics.h"
39 #include "libavutil/avassert.h"
40 #include "libavutil/avstring.h"
41 #include "libavutil/dict.h"
42 #include "libavutil/display.h"
43 #include "libavutil/mem.h"
44 #include "libavutil/opt.h"
45 #include "libavutil/aes.h"
46 #include "libavutil/aes_ctr.h"
47 #include "libavutil/pixdesc.h"
48 #include "libavutil/sha.h"
49 #include "libavutil/spherical.h"
50 #include "libavutil/stereo3d.h"
51 #include "libavutil/timecode.h"
52 #include "libavutil/uuid.h"
53 #include "libavcodec/ac3tab.h"
54 #include "libavcodec/flac.h"
55 #include "libavcodec/hevc/hevc.h"
57 #include "libavcodec/mlp_parse.h"
58 #include "avformat.h"
59 #include "internal.h"
60 #include "avio_internal.h"
61 #include "demux.h"
62 #include "dvdclut.h"
63 #include "iamf_parse.h"
64 #include "iamf_reader.h"
65 #include "dovi_isom.h"
66 #include "riff.h"
67 #include "isom.h"
68 #include "libavcodec/get_bits.h"
69 #include "id3v1.h"
70 #include "mov_chan.h"
71 #include "replaygain.h"
72 
73 #if CONFIG_ZLIB
74 #include <zlib.h>
75 #endif
76 
77 #include "qtpalette.h"
78 
79 /* those functions parse an atom */
80 /* links atom IDs to parse functions */
81 typedef struct MOVParseTableEntry {
82  uint32_t type;
83  int (*parse)(MOVContext *ctx, AVIOContext *pb, MOVAtom atom);
85 
86 static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom);
87 static int mov_read_mfra(MOVContext *c, AVIOContext *f);
89 
91  unsigned len, const char *key)
92 {
93  char buf[16];
94 
95  short current, total = 0;
96  avio_rb16(pb); // unknown
97  current = avio_rb16(pb);
98  if (len >= 6)
99  total = avio_rb16(pb);
100  if (!total)
101  snprintf(buf, sizeof(buf), "%d", current);
102  else
103  snprintf(buf, sizeof(buf), "%d/%d", current, total);
104  c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
105  av_dict_set(&c->fc->metadata, key, buf, 0);
106 
107  return 0;
108 }
109 
111  unsigned len, const char *key)
112 {
113  /* bypass padding bytes */
114  avio_r8(pb);
115  avio_r8(pb);
116  avio_r8(pb);
117 
118  c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
119  av_dict_set_int(&c->fc->metadata, key, avio_r8(pb), 0);
120 
121  return 0;
122 }
123 
125  unsigned len, const char *key)
126 {
127  c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
128  av_dict_set_int(&c->fc->metadata, key, avio_r8(pb), 0);
129 
130  return 0;
131 }
132 
134  unsigned len, const char *key)
135 {
136  short genre;
137 
138  avio_r8(pb); // unknown
139 
140  genre = avio_r8(pb);
141  if (genre < 1 || genre > ID3v1_GENRE_MAX)
142  return 0;
143  c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
144  av_dict_set(&c->fc->metadata, key, ff_id3v1_genre_str[genre-1], 0);
145 
146  return 0;
147 }
148 
149 static const uint32_t mac_to_unicode[128] = {
150  0x00C4,0x00C5,0x00C7,0x00C9,0x00D1,0x00D6,0x00DC,0x00E1,
151  0x00E0,0x00E2,0x00E4,0x00E3,0x00E5,0x00E7,0x00E9,0x00E8,
152  0x00EA,0x00EB,0x00ED,0x00EC,0x00EE,0x00EF,0x00F1,0x00F3,
153  0x00F2,0x00F4,0x00F6,0x00F5,0x00FA,0x00F9,0x00FB,0x00FC,
154  0x2020,0x00B0,0x00A2,0x00A3,0x00A7,0x2022,0x00B6,0x00DF,
155  0x00AE,0x00A9,0x2122,0x00B4,0x00A8,0x2260,0x00C6,0x00D8,
156  0x221E,0x00B1,0x2264,0x2265,0x00A5,0x00B5,0x2202,0x2211,
157  0x220F,0x03C0,0x222B,0x00AA,0x00BA,0x03A9,0x00E6,0x00F8,
158  0x00BF,0x00A1,0x00AC,0x221A,0x0192,0x2248,0x2206,0x00AB,
159  0x00BB,0x2026,0x00A0,0x00C0,0x00C3,0x00D5,0x0152,0x0153,
160  0x2013,0x2014,0x201C,0x201D,0x2018,0x2019,0x00F7,0x25CA,
161  0x00FF,0x0178,0x2044,0x20AC,0x2039,0x203A,0xFB01,0xFB02,
162  0x2021,0x00B7,0x201A,0x201E,0x2030,0x00C2,0x00CA,0x00C1,
163  0x00CB,0x00C8,0x00CD,0x00CE,0x00CF,0x00CC,0x00D3,0x00D4,
164  0xF8FF,0x00D2,0x00DA,0x00DB,0x00D9,0x0131,0x02C6,0x02DC,
165  0x00AF,0x02D8,0x02D9,0x02DA,0x00B8,0x02DD,0x02DB,0x02C7,
166 };
167 
169  char *dst, int dstlen)
170 {
171  char *p = dst;
172  char *end = dst+dstlen-1;
173  int i;
174 
175  for (i = 0; i < len; i++) {
176  uint8_t t, c = avio_r8(pb);
177 
178  if (p >= end)
179  continue;
180 
181  if (c < 0x80)
182  *p++ = c;
183  else if (p < end)
184  PUT_UTF8(mac_to_unicode[c-0x80], t, if (p < end) *p++ = t;);
185  }
186  *p = 0;
187  return p - dst;
188 }
189 
190 /**
191  * Get the current item in the parsing process.
192  */
194 {
195  HEIFItem *item = NULL;
196 
197  for (int i = 0; i < c->nb_heif_item; i++) {
198  if (!c->heif_item[i] || c->heif_item[i]->item_id != c->cur_item_id)
199  continue;
200 
201  item = c->heif_item[i];
202  break;
203  }
204 
205  return item;
206 }
207 
208 /**
209  * Get the current stream in the parsing process. This can either be the
210  * latest stream added to the context, or the stream referenced by an item.
211  */
213 {
214  AVStream *st = NULL;
215  HEIFItem *item;
216 
217  if (c->fc->nb_streams < 1)
218  return NULL;
219 
220  if (c->cur_item_id == -1)
221  return c->fc->streams[c->fc->nb_streams-1];
222 
223  item = heif_cur_item(c);
224  if (item)
225  st = item->st;
226 
227  return st;
228 }
229 
230 static int mov_read_covr(MOVContext *c, AVIOContext *pb, int type, int len)
231 {
232  AVStream *st;
233  MOVStreamContext *sc;
234  enum AVCodecID id;
235  int ret;
236 
237  switch (type) {
238  case 0xd: id = AV_CODEC_ID_MJPEG; break;
239  case 0xe: id = AV_CODEC_ID_PNG; break;
240  case 0x1b: id = AV_CODEC_ID_BMP; break;
241  default:
242  av_log(c->fc, AV_LOG_WARNING, "Unknown cover type: 0x%x.\n", type);
243  avio_skip(pb, len);
244  return 0;
245  }
246 
247  sc = av_mallocz(sizeof(*sc));
248  if (!sc)
249  return AVERROR(ENOMEM);
250  ret = ff_add_attached_pic(c->fc, NULL, pb, NULL, len);
251  if (ret < 0) {
252  av_free(sc);
253  return ret;
254  }
255  st = c->fc->streams[c->fc->nb_streams - 1];
256  st->priv_data = sc;
257  sc->id = st->id;
258  sc->refcount = 1;
259 
260  if (st->attached_pic.size >= 8 && id != AV_CODEC_ID_BMP) {
261  if (AV_RB64(st->attached_pic.data) == 0x89504e470d0a1a0a) {
262  id = AV_CODEC_ID_PNG;
263  } else {
264  id = AV_CODEC_ID_MJPEG;
265  }
266  }
267  st->codecpar->codec_id = id;
268 
269  return 0;
270 }
271 
272 // 3GPP TS 26.244
273 static int mov_metadata_loci(MOVContext *c, AVIOContext *pb, unsigned len)
274 {
275  char language[4] = { 0 };
276  char buf[200], place[100];
277  uint16_t langcode = 0;
278  double longitude, latitude, altitude;
279  const char *key = "location";
280 
281  if (len < 4 + 2 + 1 + 1 + 4 + 4 + 4) {
282  av_log(c->fc, AV_LOG_ERROR, "loci too short\n");
283  return AVERROR_INVALIDDATA;
284  }
285 
286  avio_skip(pb, 4); // version+flags
287  langcode = avio_rb16(pb);
288  ff_mov_lang_to_iso639(langcode, language);
289  len -= 6;
290 
291  len -= avio_get_str(pb, len, place, sizeof(place));
292  if (len < 1) {
293  av_log(c->fc, AV_LOG_ERROR, "place name too long\n");
294  return AVERROR_INVALIDDATA;
295  }
296  avio_skip(pb, 1); // role
297  len -= 1;
298 
299  if (len < 12) {
300  av_log(c->fc, AV_LOG_ERROR,
301  "loci too short (%u bytes left, need at least %d)\n", len, 12);
302  return AVERROR_INVALIDDATA;
303  }
304  longitude = ((int32_t) avio_rb32(pb)) / (float) (1 << 16);
305  latitude = ((int32_t) avio_rb32(pb)) / (float) (1 << 16);
306  altitude = ((int32_t) avio_rb32(pb)) / (float) (1 << 16);
307 
308  // Try to output in the same format as the ?xyz field
309  snprintf(buf, sizeof(buf), "%+08.4f%+09.4f", latitude, longitude);
310  if (altitude)
311  av_strlcatf(buf, sizeof(buf), "%+f", altitude);
312  av_strlcatf(buf, sizeof(buf), "/%s", place);
313 
314  if (*language && strcmp(language, "und")) {
315  char key2[16];
316  snprintf(key2, sizeof(key2), "%s-%s", key, language);
317  av_dict_set(&c->fc->metadata, key2, buf, 0);
318  }
319  c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
320  return av_dict_set(&c->fc->metadata, key, buf, 0);
321 }
322 
323 static int mov_metadata_hmmt(MOVContext *c, AVIOContext *pb, unsigned len)
324 {
325  int i, n_hmmt;
326 
327  if (len < 2)
328  return 0;
329  if (c->ignore_chapters)
330  return 0;
331 
332  n_hmmt = avio_rb32(pb);
333  if (n_hmmt > len / 4)
334  return AVERROR_INVALIDDATA;
335  for (i = 0; i < n_hmmt && !pb->eof_reached; i++) {
336  int moment_time = avio_rb32(pb);
337  avpriv_new_chapter(c->fc, i, av_make_q(1, 1000), moment_time, AV_NOPTS_VALUE, NULL);
338  }
339  if (avio_feof(pb))
340  return AVERROR_INVALIDDATA;
341  return 0;
342 }
343 
345 {
346  char tmp_key[AV_FOURCC_MAX_STRING_SIZE] = {0};
347  char key2[32], language[4] = {0};
348  char *str = NULL;
349  const char *key = NULL;
350  uint16_t langcode = 0;
351  uint32_t data_type = 0, str_size_alloc;
352  uint64_t str_size;
353  int (*parse)(MOVContext*, AVIOContext*, unsigned, const char*) = NULL;
354  int raw = 0;
355  int num = 0;
357 
358  if (c->trak_index >= 0 && c->trak_index < c->fc->nb_streams)
359  metadata = &c->fc->streams[c->trak_index]->metadata;
360  else
361  metadata = &c->fc->metadata;
362 
363  switch (atom.type) {
364  case MKTAG( '@','P','R','M'): key = "premiere_version"; raw = 1; break;
365  case MKTAG( '@','P','R','Q'): key = "quicktime_version"; raw = 1; break;
366  case MKTAG( 'X','M','P','_'):
367  if (c->export_xmp) { key = "xmp"; raw = 1; } break;
368  case MKTAG( 'a','A','R','T'): key = "album_artist"; break;
369  case MKTAG( 'a','k','I','D'): key = "account_type";
371  case MKTAG( 'a','p','I','D'): key = "account_id"; break;
372  case MKTAG( 'c','a','t','g'): key = "category"; break;
373  case MKTAG( 'c','p','i','l'): key = "compilation";
375  case MKTAG( 'c','p','r','t'): key = "copyright"; break;
376  case MKTAG( 'd','e','s','c'): key = "description"; break;
377  case MKTAG( 'd','i','s','k'): key = "disc";
379  case MKTAG( 'e','g','i','d'): key = "episode_uid";
381  case MKTAG( 'F','I','R','M'): key = "firmware"; raw = 1; break;
382  case MKTAG( 'g','n','r','e'): key = "genre";
383  parse = mov_metadata_gnre; break;
384  case MKTAG( 'h','d','v','d'): key = "hd_video";
386  case MKTAG( 'H','M','M','T'):
387  return mov_metadata_hmmt(c, pb, atom.size);
388  case MKTAG( 'k','e','y','w'): key = "keywords"; break;
389  case MKTAG( 'l','d','e','s'): key = "synopsis"; break;
390  case MKTAG( 'l','o','c','i'):
391  return mov_metadata_loci(c, pb, atom.size);
392  case MKTAG( 'm','a','n','u'): key = "make"; break;
393  case MKTAG( 'm','o','d','l'): key = "model"; break;
394  case MKTAG( 'p','c','s','t'): key = "podcast";
396  case MKTAG( 'p','g','a','p'): key = "gapless_playback";
398  case MKTAG( 'p','u','r','d'): key = "purchase_date"; break;
399  case MKTAG( 'r','t','n','g'): key = "rating";
401  case MKTAG( 's','o','a','a'): key = "sort_album_artist"; break;
402  case MKTAG( 's','o','a','l'): key = "sort_album"; break;
403  case MKTAG( 's','o','a','r'): key = "sort_artist"; break;
404  case MKTAG( 's','o','c','o'): key = "sort_composer"; break;
405  case MKTAG( 's','o','n','m'): key = "sort_name"; break;
406  case MKTAG( 's','o','s','n'): key = "sort_show"; break;
407  case MKTAG( 's','t','i','k'): key = "media_type";
409  case MKTAG( 't','r','k','n'): key = "track";
411  case MKTAG( 't','v','e','n'): key = "episode_id"; break;
412  case MKTAG( 't','v','e','s'): key = "episode_sort";
414  case MKTAG( 't','v','n','n'): key = "network"; break;
415  case MKTAG( 't','v','s','h'): key = "show"; break;
416  case MKTAG( 't','v','s','n'): key = "season_number";
418  case MKTAG(0xa9,'A','R','T'): key = "artist"; break;
419  case MKTAG(0xa9,'P','R','D'): key = "producer"; break;
420  case MKTAG(0xa9,'a','l','b'): key = "album"; break;
421  case MKTAG(0xa9,'a','u','t'): key = "artist"; break;
422  case MKTAG(0xa9,'c','h','p'): key = "chapter"; break;
423  case MKTAG(0xa9,'c','m','t'): key = "comment"; break;
424  case MKTAG(0xa9,'c','o','m'): key = "composer"; break;
425  case MKTAG(0xa9,'c','p','y'): key = "copyright"; break;
426  case MKTAG(0xa9,'d','a','y'): key = "date"; break;
427  case MKTAG(0xa9,'d','i','r'): key = "director"; break;
428  case MKTAG(0xa9,'d','i','s'): key = "disclaimer"; break;
429  case MKTAG(0xa9,'e','d','1'): key = "edit_date"; break;
430  case MKTAG(0xa9,'e','n','c'): key = "encoder"; break;
431  case MKTAG(0xa9,'f','m','t'): key = "original_format"; break;
432  case MKTAG(0xa9,'g','e','n'): key = "genre"; break;
433  case MKTAG(0xa9,'g','r','p'): key = "grouping"; break;
434  case MKTAG(0xa9,'h','s','t'): key = "host_computer"; break;
435  case MKTAG(0xa9,'i','n','f'): key = "comment"; break;
436  case MKTAG(0xa9,'l','y','r'): key = "lyrics"; break;
437  case MKTAG(0xa9,'m','a','k'): key = "make"; break;
438  case MKTAG(0xa9,'m','o','d'): key = "model"; break;
439  case MKTAG(0xa9,'n','a','m'): key = "title"; break;
440  case MKTAG(0xa9,'o','p','e'): key = "original_artist"; break;
441  case MKTAG(0xa9,'p','r','d'): key = "producer"; break;
442  case MKTAG(0xa9,'p','r','f'): key = "performers"; break;
443  case MKTAG(0xa9,'r','e','q'): key = "playback_requirements"; break;
444  case MKTAG(0xa9,'s','r','c'): key = "original_source"; break;
445  case MKTAG(0xa9,'s','t','3'): key = "subtitle"; break;
446  case MKTAG(0xa9,'s','w','r'): key = "encoder"; break;
447  case MKTAG(0xa9,'t','o','o'): key = "encoder"; break;
448  case MKTAG(0xa9,'t','r','k'): key = "track"; break;
449  case MKTAG(0xa9,'u','r','l'): key = "URL"; break;
450  case MKTAG(0xa9,'w','r','n'): key = "warning"; break;
451  case MKTAG(0xa9,'w','r','t'): key = "composer"; break;
452  case MKTAG(0xa9,'x','y','z'): key = "location"; break;
453  }
454 retry:
455  if (c->itunes_metadata && atom.size > 8) {
456  int data_size = avio_rb32(pb);
457  int tag = avio_rl32(pb);
458  if (tag == MKTAG('d','a','t','a') && data_size <= atom.size && data_size >= 16) {
459  data_type = avio_rb32(pb); // type
460  avio_rb32(pb); // unknown
461  str_size = data_size - 16;
462  atom.size -= 16;
463 
464  if (!key && c->found_hdlr_mdta && c->meta_keys) {
465  uint32_t index = av_bswap32(atom.type); // BE number has been read as LE
466  if (index < c->meta_keys_count && index > 0) {
467  key = c->meta_keys[index];
468  } else if (atom.type != MKTAG('c', 'o', 'v', 'r')) {
469  av_log(c->fc, AV_LOG_WARNING,
470  "The index of 'data' is out of range: %"PRId32" < 1 or >= %d.\n",
471  index, c->meta_keys_count);
472  }
473  }
474  if (atom.type == MKTAG('c', 'o', 'v', 'r') ||
475  (key && !strcmp(key, "com.apple.quicktime.artwork"))) {
476  int ret = mov_read_covr(c, pb, data_type, str_size);
477  if (ret < 0) {
478  av_log(c->fc, AV_LOG_ERROR, "Error parsing cover art.\n");
479  return ret;
480  }
481  atom.size -= str_size;
482  if (atom.size > 8)
483  goto retry;
484  return ret;
485  }
486  } else return 0;
487  } else if (atom.size > 4 && (key || c->export_all) && !c->itunes_metadata && !raw) {
488  str_size = avio_rb16(pb); // string length
489  if (str_size > atom.size) {
490  raw = 1;
491  avio_seek(pb, -2, SEEK_CUR);
492  av_log(c->fc, AV_LOG_WARNING, "UDTA parsing failed retrying raw\n");
493  goto retry;
494  }
495  langcode = avio_rb16(pb);
496  ff_mov_lang_to_iso639(langcode, language);
497  atom.size -= 4;
498  } else
499  str_size = atom.size;
500 
501  if (c->export_all && !key) {
502  key = av_fourcc_make_string(tmp_key, atom.type);
503  }
504 
505  if (!key)
506  return 0;
507  if (atom.size < 0 || str_size >= INT_MAX/2)
508  return AVERROR_INVALIDDATA;
509 
510  // Allocates enough space if data_type is a int32 or float32 number, otherwise
511  // worst-case requirement for output string in case of utf8 coded input
512  num = (data_type >= 21 && data_type <= 23);
513  str_size_alloc = (num ? 512 : (raw ? str_size : str_size * 2)) + 1;
514  str = av_mallocz(str_size_alloc);
515  if (!str)
516  return AVERROR(ENOMEM);
517 
518  if (parse)
519  parse(c, pb, str_size, key);
520  else {
521  if (!raw && (data_type == 3 || (data_type == 0 && (langcode < 0x400 || langcode == 0x7fff)))) { // MAC Encoded
522  mov_read_mac_string(c, pb, str_size, str, str_size_alloc);
523  } else if (data_type == 21) { // BE signed integer, variable size
524  int val = 0;
525  if (str_size == 1)
526  val = (int8_t)avio_r8(pb);
527  else if (str_size == 2)
528  val = (int16_t)avio_rb16(pb);
529  else if (str_size == 3)
530  val = ((int32_t)(avio_rb24(pb)<<8))>>8;
531  else if (str_size == 4)
532  val = (int32_t)avio_rb32(pb);
533  if (snprintf(str, str_size_alloc, "%d", val) >= str_size_alloc) {
534  av_log(c->fc, AV_LOG_ERROR,
535  "Failed to store the number (%d) in string.\n", val);
536  av_free(str);
537  return AVERROR_INVALIDDATA;
538  }
539  } else if (data_type == 22) { // BE unsigned integer, variable size
540  unsigned int val = 0;
541  if (str_size == 1)
542  val = avio_r8(pb);
543  else if (str_size == 2)
544  val = avio_rb16(pb);
545  else if (str_size == 3)
546  val = avio_rb24(pb);
547  else if (str_size == 4)
548  val = avio_rb32(pb);
549  if (snprintf(str, str_size_alloc, "%u", val) >= str_size_alloc) {
550  av_log(c->fc, AV_LOG_ERROR,
551  "Failed to store the number (%u) in string.\n", val);
552  av_free(str);
553  return AVERROR_INVALIDDATA;
554  }
555  } else if (data_type == 23 && str_size >= 4) { // BE float32
556  float val = av_int2float(avio_rb32(pb));
557  if (snprintf(str, str_size_alloc, "%f", val) >= str_size_alloc) {
558  av_log(c->fc, AV_LOG_ERROR,
559  "Failed to store the float32 number (%f) in string.\n", val);
560  av_free(str);
561  return AVERROR_INVALIDDATA;
562  }
563  } else if (data_type > 1 && data_type != 4) {
564  // data_type can be 0 if not set at all above. data_type 1 means
565  // UTF8 and 4 means "UTF8 sort". For any other type (UTF16 or e.g.
566  // a picture), don't return it blindly in a string that is supposed
567  // to be UTF8 text.
568  av_log(c->fc, AV_LOG_WARNING, "Skipping unhandled metadata %s of type %d\n", key, data_type);
569  av_free(str);
570  return 0;
571  } else {
572  int ret = ffio_read_size(pb, str, str_size);
573  if (ret < 0) {
574  av_free(str);
575  return ret;
576  }
577  str[str_size] = 0;
578  }
579  c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
580  av_dict_set(metadata, key, str, 0);
581  if (*language && strcmp(language, "und")) {
582  snprintf(key2, sizeof(key2), "%s-%s", key, language);
583  av_dict_set(metadata, key2, str, 0);
584  }
585  if (!strcmp(key, "encoder")) {
586  int major, minor, micro;
587  if (sscanf(str, "HandBrake %d.%d.%d", &major, &minor, &micro) == 3) {
588  c->handbrake_version = 1000000*major + 1000*minor + micro;
589  }
590  }
591  }
592 
593  av_freep(&str);
594  return 0;
595 }
596 
598 {
599  int64_t start;
600  int i, nb_chapters, str_len, version;
601  char str[256+1];
602  int ret;
603 
604  if (c->ignore_chapters)
605  return 0;
606 
607  if ((atom.size -= 5) < 0)
608  return 0;
609 
610  version = avio_r8(pb);
611  avio_rb24(pb);
612  if (version)
613  avio_rb32(pb); // ???
614  nb_chapters = avio_r8(pb);
615 
616  for (i = 0; i < nb_chapters; i++) {
617  if (atom.size < 9)
618  return 0;
619 
620  start = avio_rb64(pb);
621  str_len = avio_r8(pb);
622 
623  if ((atom.size -= 9+str_len) < 0)
624  return 0;
625 
626  ret = ffio_read_size(pb, str, str_len);
627  if (ret < 0)
628  return ret;
629  str[str_len] = 0;
630  avpriv_new_chapter(c->fc, i, (AVRational){1,10000000}, start, AV_NOPTS_VALUE, str);
631  }
632  return 0;
633 }
634 
635 #define MIN_DATA_ENTRY_BOX_SIZE 12
637 {
638  AVStream *st;
639  MOVStreamContext *sc;
640  int entries, i, j;
641 
642  if (c->fc->nb_streams < 1)
643  return 0;
644  st = c->fc->streams[c->fc->nb_streams-1];
645  sc = st->priv_data;
646 
647  avio_rb32(pb); // version + flags
648  entries = avio_rb32(pb);
649  if (!entries ||
650  entries > (atom.size - 1) / MIN_DATA_ENTRY_BOX_SIZE + 1 ||
651  entries >= UINT_MAX / sizeof(*sc->drefs))
652  return AVERROR_INVALIDDATA;
653 
654  for (i = 0; i < sc->drefs_count; i++) {
655  MOVDref *dref = &sc->drefs[i];
656  av_freep(&dref->path);
657  av_freep(&dref->dir);
658  }
659  av_free(sc->drefs);
660  sc->drefs_count = 0;
661  sc->drefs = av_mallocz(entries * sizeof(*sc->drefs));
662  if (!sc->drefs)
663  return AVERROR(ENOMEM);
664  sc->drefs_count = entries;
665 
666  for (i = 0; i < entries; i++) {
667  MOVDref *dref = &sc->drefs[i];
668  uint32_t size = avio_rb32(pb);
669  int64_t next = avio_tell(pb);
670 
671  if (size < 12 || next < 0 || next > INT64_MAX - size)
672  return AVERROR_INVALIDDATA;
673 
674  next += size - 4;
675 
676  dref->type = avio_rl32(pb);
677  avio_rb32(pb); // version + flags
678 
679  if (dref->type == MKTAG('a','l','i','s') && size > 150) {
680  /* macintosh alias record */
681  uint16_t volume_len, len;
682  int16_t type;
683  int ret;
684 
685  avio_skip(pb, 10);
686 
687  volume_len = avio_r8(pb);
688  volume_len = FFMIN(volume_len, 27);
689  ret = ffio_read_size(pb, dref->volume, 27);
690  if (ret < 0)
691  return ret;
692  dref->volume[volume_len] = 0;
693  av_log(c->fc, AV_LOG_DEBUG, "volume %s, len %d\n", dref->volume, volume_len);
694 
695  avio_skip(pb, 12);
696 
697  len = avio_r8(pb);
698  len = FFMIN(len, 63);
699  ret = ffio_read_size(pb, dref->filename, 63);
700  if (ret < 0)
701  return ret;
702  dref->filename[len] = 0;
703  av_log(c->fc, AV_LOG_DEBUG, "filename %s, len %d\n", dref->filename, len);
704 
705  avio_skip(pb, 16);
706 
707  /* read next level up_from_alias/down_to_target */
708  dref->nlvl_from = avio_rb16(pb);
709  dref->nlvl_to = avio_rb16(pb);
710  av_log(c->fc, AV_LOG_DEBUG, "nlvl from %d, nlvl to %d\n",
711  dref->nlvl_from, dref->nlvl_to);
712 
713  avio_skip(pb, 16);
714 
715  for (type = 0; type != -1 && avio_tell(pb) < next; ) {
716  if (avio_feof(pb))
717  return AVERROR_EOF;
718  type = avio_rb16(pb);
719  len = avio_rb16(pb);
720  av_log(c->fc, AV_LOG_DEBUG, "type %d, len %d\n", type, len);
721  if (len&1)
722  len += 1;
723  if (type == 2) { // absolute path
724  av_free(dref->path);
725  dref->path = av_mallocz(len+1);
726  if (!dref->path)
727  return AVERROR(ENOMEM);
728 
729  ret = ffio_read_size(pb, dref->path, len);
730  if (ret < 0) {
731  av_freep(&dref->path);
732  return ret;
733  }
734  if (len > volume_len && !strncmp(dref->path, dref->volume, volume_len)) {
735  len -= volume_len;
736  memmove(dref->path, dref->path+volume_len, len);
737  dref->path[len] = 0;
738  }
739  // trim string of any ending zeros
740  for (j = len - 1; j >= 0; j--) {
741  if (dref->path[j] == 0)
742  len--;
743  else
744  break;
745  }
746  for (j = 0; j < len; j++)
747  if (dref->path[j] == ':' || dref->path[j] == 0)
748  dref->path[j] = '/';
749  av_log(c->fc, AV_LOG_DEBUG, "path %s\n", dref->path);
750  } else if (type == 0) { // directory name
751  av_free(dref->dir);
752  dref->dir = av_malloc(len+1);
753  if (!dref->dir)
754  return AVERROR(ENOMEM);
755 
756  ret = ffio_read_size(pb, dref->dir, len);
757  if (ret < 0) {
758  av_freep(&dref->dir);
759  return ret;
760  }
761  dref->dir[len] = 0;
762  for (j = 0; j < len; j++)
763  if (dref->dir[j] == ':')
764  dref->dir[j] = '/';
765  av_log(c->fc, AV_LOG_DEBUG, "dir %s\n", dref->dir);
766  } else
767  avio_skip(pb, len);
768  }
769  } else {
770  av_log(c->fc, AV_LOG_DEBUG, "Unknown dref type 0x%08"PRIx32" size %"PRIu32"\n",
771  dref->type, size);
772  entries--;
773  i--;
774  }
775  avio_seek(pb, next, SEEK_SET);
776  }
777  return 0;
778 }
779 
781 {
782  AVStream *st;
783  uint32_t type;
784  uint32_t ctype;
785  int64_t title_size;
786  char *title_str;
787  int ret;
788 
789  avio_r8(pb); /* version */
790  avio_rb24(pb); /* flags */
791 
792  /* component type */
793  ctype = avio_rl32(pb);
794  type = avio_rl32(pb); /* component subtype */
795 
796  av_log(c->fc, AV_LOG_TRACE, "ctype=%s\n", av_fourcc2str(ctype));
797  av_log(c->fc, AV_LOG_TRACE, "stype=%s\n", av_fourcc2str(type));
798 
799  if (c->trak_index < 0) { // meta not inside a trak
800  if (type == MKTAG('m','d','t','a')) {
801  c->found_hdlr_mdta = 1;
802  }
803  return 0;
804  }
805 
806  st = c->fc->streams[c->fc->nb_streams-1];
807 
808  if (type == MKTAG('v','i','d','e'))
810  else if (type == MKTAG('s','o','u','n'))
812  else if (type == MKTAG('m','1','a',' '))
814  else if ((type == MKTAG('s','u','b','p')) || (type == MKTAG('c','l','c','p')))
816 
817  avio_rb32(pb); /* component manufacture */
818  avio_rb32(pb); /* component flags */
819  avio_rb32(pb); /* component flags mask */
820 
821  title_size = atom.size - 24;
822  if (title_size > 0) {
823  if (title_size > FFMIN(INT_MAX, SIZE_MAX-1))
824  return AVERROR_INVALIDDATA;
825  title_str = av_malloc(title_size + 1); /* Add null terminator */
826  if (!title_str)
827  return AVERROR(ENOMEM);
828 
829  ret = ffio_read_size(pb, title_str, title_size);
830  if (ret < 0) {
831  av_freep(&title_str);
832  return ret;
833  }
834  title_str[title_size] = 0;
835  if (title_str[0]) {
836  int off = (!c->isom && title_str[0] == title_size - 1);
837  // flag added so as to not set stream handler name if already set from mdia->hdlr
838  av_dict_set(&st->metadata, "handler_name", title_str + off, AV_DICT_DONT_OVERWRITE);
839  }
840  av_freep(&title_str);
841  }
842 
843  return 0;
844 }
845 
847 {
848  return ff_mov_read_esds(c->fc, pb);
849 }
850 
852 {
853  AVStream *st;
854  AVPacketSideData *sd;
855  enum AVAudioServiceType *ast;
856  int ac3info, acmod, lfeon, bsmod;
857  uint64_t mask;
858 
859  if (c->fc->nb_streams < 1)
860  return 0;
861  st = c->fc->streams[c->fc->nb_streams-1];
862 
866  sizeof(*ast), 0);
867  if (!sd)
868  return AVERROR(ENOMEM);
869 
870  ast = (enum AVAudioServiceType*)sd->data;
871  ac3info = avio_rb24(pb);
872  bsmod = (ac3info >> 14) & 0x7;
873  acmod = (ac3info >> 11) & 0x7;
874  lfeon = (ac3info >> 10) & 0x1;
875 
877  if (lfeon)
881 
882  *ast = bsmod;
883  if (st->codecpar->ch_layout.nb_channels > 1 && bsmod == 0x7)
885 
886  return 0;
887 }
888 
889 #if CONFIG_IAMFDEC
890 static int mov_read_iacb(MOVContext *c, AVIOContext *pb, MOVAtom atom)
891 {
892  AVStream *st;
893  MOVStreamContext *sc;
894  FFIOContext b;
895  AVIOContext *descriptor_pb;
897  IAMFContext *iamf;
899  unsigned descriptors_size;
900  int nb_frames, disposition;
901  int version, ret;
902 
903  if (atom.size < 5)
904  return AVERROR_INVALIDDATA;
905 
906  if (c->fc->nb_streams < 1)
907  return 0;
908 
909  version = avio_r8(pb);
910  if (version != 1) {
911  av_log(c->fc, AV_LOG_ERROR, "%s configurationVersion %d",
912  version < 1 ? "invalid" : "unsupported", version);
913  return AVERROR_INVALIDDATA;
914  }
915 
916  descriptors_size = ffio_read_leb(pb);
917  if (!descriptors_size || descriptors_size > INT_MAX)
918  return AVERROR_INVALIDDATA;
919 
920  st = c->fc->streams[c->fc->nb_streams - 1];
921  sc = st->priv_data;
922 
923  if (st->codecpar->extradata) {
924  av_log(c->fc, AV_LOG_WARNING, "ignoring iacb\n");
925  return 0;
926  }
927 
928  sc->iamf = av_mallocz(sizeof(*sc->iamf));
929  if (!sc->iamf)
930  return AVERROR(ENOMEM);
931  iamf = &sc->iamf->iamf;
932 
933  st->codecpar->extradata = av_malloc(descriptors_size);
934  if (!st->codecpar->extradata)
935  return AVERROR(ENOMEM);
936  st->codecpar->extradata_size = descriptors_size;
937 
938  ret = avio_read(pb, st->codecpar->extradata, descriptors_size);
939  if (ret != descriptors_size)
940  return ret < 0 ? ret : AVERROR_INVALIDDATA;
941 
942  ffio_init_read_context(&b, st->codecpar->extradata, descriptors_size);
943  descriptor_pb = &b.pub;
944 
945  ret = ff_iamfdec_read_descriptors(iamf, descriptor_pb, descriptors_size, c->fc);
946  if (ret < 0)
947  return ret;
948 
949  metadata = st->metadata;
950  st->metadata = NULL;
951  start_time = st->start_time;
952  nb_frames = st->nb_frames;
953  duration = st->duration;
954  disposition = st->disposition;
955 
956  for (int i = 0; i < iamf->nb_audio_elements; i++) {
957  IAMFAudioElement *audio_element = iamf->audio_elements[i];
958  const AVIAMFAudioElement *element;
959  AVStreamGroup *stg =
961 
962  if (!stg) {
963  ret = AVERROR(ENOMEM);
964  goto fail;
965  }
966 
968  stg->id = audio_element->audio_element_id;
969  /* Transfer ownership */
970  element = stg->params.iamf_audio_element = audio_element->element;
971  audio_element->element = NULL;
972 
973  for (int j = 0; j < audio_element->nb_substreams; j++) {
974  IAMFSubStream *substream = &audio_element->substreams[j];
975  AVStream *stream;
976 
977  if (!i && !j) {
978  if (audio_element->layers[0].substream_count != 1)
979  disposition &= ~AV_DISPOSITION_DEFAULT;
980  stream = st;
981  } else
982  stream = avformat_new_stream(c->fc, NULL);
983  if (!stream) {
984  ret = AVERROR(ENOMEM);
985  goto fail;
986  }
987 
988  stream->start_time = start_time;
989  stream->nb_frames = nb_frames;
990  stream->duration = duration;
991  stream->disposition = disposition;
992  if (stream != st) {
993  stream->priv_data = sc;
994  sc->refcount++;
995  }
996 
999  if (i || j) {
1001  if (audio_element->layers[0].substream_count == 1)
1002  stream->disposition &= ~AV_DISPOSITION_DEFAULT;
1003  }
1004 
1005  ret = avcodec_parameters_copy(stream->codecpar, substream->codecpar);
1006  if (ret < 0)
1007  goto fail;
1008 
1009  stream->id = substream->audio_substream_id;
1010 
1011  avpriv_set_pts_info(st, 64, 1, sc->time_scale);
1012 
1013  ret = avformat_stream_group_add_stream(stg, stream);
1014  if (ret < 0)
1015  goto fail;
1016  }
1017 
1018  ret = av_dict_copy(&stg->metadata, metadata, 0);
1019  if (ret < 0)
1020  goto fail;
1021  }
1022 
1023  for (int i = 0; i < iamf->nb_mix_presentations; i++) {
1024  IAMFMixPresentation *mix_presentation = iamf->mix_presentations[i];
1025  const AVIAMFMixPresentation *mix = mix_presentation->cmix;
1026  AVStreamGroup *stg =
1028 
1029  if (!stg) {
1030  ret = AVERROR(ENOMEM);
1031  goto fail;
1032  }
1033 
1035  stg->id = mix_presentation->mix_presentation_id;
1036  /* Transfer ownership */
1037  stg->params.iamf_mix_presentation = mix_presentation->mix;
1038  mix_presentation->mix = NULL;
1039 
1040  for (int j = 0; j < mix->nb_submixes; j++) {
1041  const AVIAMFSubmix *submix = mix->submixes[j];
1042 
1043  for (int k = 0; k < submix->nb_elements; k++) {
1044  const AVIAMFSubmixElement *submix_element = submix->elements[k];
1045  const AVStreamGroup *audio_element = NULL;
1046 
1047  for (int l = 0; l < c->fc->nb_stream_groups; l++)
1048  if (c->fc->stream_groups[l]->type == AV_STREAM_GROUP_PARAMS_IAMF_AUDIO_ELEMENT &&
1049  c->fc->stream_groups[l]->id == submix_element->audio_element_id) {
1050  audio_element = c->fc->stream_groups[l];
1051  break;
1052  }
1053  av_assert0(audio_element);
1054 
1055  for (int l = 0; l < audio_element->nb_streams; l++) {
1056  ret = avformat_stream_group_add_stream(stg, audio_element->streams[l]);
1057  if (ret < 0 && ret != AVERROR(EEXIST))
1058  goto fail;
1059  }
1060  }
1061  }
1062 
1063  ret = av_dict_copy(&stg->metadata, metadata, 0);
1064  if (ret < 0)
1065  goto fail;
1066  }
1067 
1068  ret = 0;
1069 fail:
1071 
1072  return ret;
1073 }
1074 #endif
1075 
1077 {
1078  AVStream *st;
1079  AVPacketSideData *sd;
1080  enum AVAudioServiceType *ast;
1081  int eac3info, acmod, lfeon, bsmod;
1082  uint64_t mask;
1083 
1084  if (c->fc->nb_streams < 1)
1085  return 0;
1086  st = c->fc->streams[c->fc->nb_streams-1];
1087 
1091  sizeof(*ast), 0);
1092  if (!sd)
1093  return AVERROR(ENOMEM);
1094 
1095  ast = (enum AVAudioServiceType*)sd->data;
1096 
1097  /* No need to parse fields for additional independent substreams and its
1098  * associated dependent substreams since libavcodec's E-AC-3 decoder
1099  * does not support them yet. */
1100  avio_rb16(pb); /* data_rate and num_ind_sub */
1101  eac3info = avio_rb24(pb);
1102  bsmod = (eac3info >> 12) & 0x1f;
1103  acmod = (eac3info >> 9) & 0x7;
1104  lfeon = (eac3info >> 8) & 0x1;
1105 
1107  if (lfeon)
1111 
1112  *ast = bsmod;
1113  if (st->codecpar->ch_layout.nb_channels > 1 && bsmod == 0x7)
1115 
1116  return 0;
1117 }
1118 
1120 {
1121 #define DDTS_SIZE 20
1122  uint8_t buf[DDTS_SIZE + AV_INPUT_BUFFER_PADDING_SIZE];
1123  AVStream *st = NULL;
1124  uint32_t frame_duration_code = 0;
1125  uint32_t channel_layout_code = 0;
1126  GetBitContext gb;
1127  int ret;
1128 
1129  if ((ret = ffio_read_size(pb, buf, DDTS_SIZE)) < 0)
1130  return ret;
1131 
1132  init_get_bits(&gb, buf, 8 * DDTS_SIZE);
1133 
1134  if (c->fc->nb_streams < 1) {
1135  return 0;
1136  }
1137  st = c->fc->streams[c->fc->nb_streams-1];
1138 
1139  st->codecpar->sample_rate = get_bits_long(&gb, 32);
1140  if (st->codecpar->sample_rate <= 0) {
1141  av_log(c->fc, AV_LOG_ERROR, "Invalid sample rate %d\n", st->codecpar->sample_rate);
1142  return AVERROR_INVALIDDATA;
1143  }
1144  skip_bits_long(&gb, 32); /* max bitrate */
1145  st->codecpar->bit_rate = get_bits_long(&gb, 32);
1146  st->codecpar->bits_per_coded_sample = get_bits(&gb, 8);
1147  frame_duration_code = get_bits(&gb, 2);
1148  skip_bits(&gb, 30); /* various fields */
1149  channel_layout_code = get_bits(&gb, 16);
1150 
1151  st->codecpar->frame_size =
1152  (frame_duration_code == 0) ? 512 :
1153  (frame_duration_code == 1) ? 1024 :
1154  (frame_duration_code == 2) ? 2048 :
1155  (frame_duration_code == 3) ? 4096 : 0;
1156 
1157  if (channel_layout_code > 0xff) {
1158  av_log(c->fc, AV_LOG_WARNING, "Unsupported DTS audio channel layout\n");
1159  }
1162  ((channel_layout_code & 0x1) ? AV_CH_FRONT_CENTER : 0) |
1163  ((channel_layout_code & 0x2) ? AV_CH_FRONT_LEFT : 0) |
1164  ((channel_layout_code & 0x2) ? AV_CH_FRONT_RIGHT : 0) |
1165  ((channel_layout_code & 0x4) ? AV_CH_SIDE_LEFT : 0) |
1166  ((channel_layout_code & 0x4) ? AV_CH_SIDE_RIGHT : 0) |
1167  ((channel_layout_code & 0x8) ? AV_CH_LOW_FREQUENCY : 0));
1168 
1169  return 0;
1170 }
1171 
1173 {
1174  AVStream *st;
1175 
1176  if (c->fc->nb_streams < 1)
1177  return 0;
1178  st = c->fc->streams[c->fc->nb_streams-1];
1179 
1180  if (atom.size < 16)
1181  return 0;
1182 
1183  /* skip version and flags */
1184  avio_skip(pb, 4);
1185 
1186  ff_mov_read_chan(c->fc, pb, st, atom.size - 4);
1187 
1188  return 0;
1189 }
1190 
1192 {
1193  int64_t end = av_sat_add64(avio_tell(pb), atom.size);
1194  int version, flags;
1195  int ret;
1196  AVStream *st;
1197 
1198  if (c->fc->nb_streams < 1)
1199  return 0;
1200  st = c->fc->streams[c->fc->nb_streams-1];
1201 
1202  version = avio_r8(pb);
1203  flags = avio_rb24(pb);
1204  if (version != 0 || flags != 0) {
1205  av_log(c->fc, AV_LOG_ERROR,
1206  "Unsupported 'chnl' box with version %d, flags: %#x",
1207  version, flags);
1208  return AVERROR_INVALIDDATA;
1209  }
1210 
1211  ret = ff_mov_read_chnl(c->fc, pb, st);
1212  if (ret < 0)
1213  return ret;
1214 
1215  if (avio_tell(pb) != end) {
1216  av_log(c->fc, AV_LOG_WARNING, "skip %" PRId64 " bytes of unknown data inside chnl\n",
1217  end - avio_tell(pb));
1218  avio_seek(pb, end, SEEK_SET);
1219  }
1220  return ret;
1221 }
1222 
1224 {
1225  AVStream *st;
1226  int ret;
1227 
1228  if (c->fc->nb_streams < 1)
1229  return 0;
1230  st = c->fc->streams[c->fc->nb_streams-1];
1231 
1232  if ((ret = ff_get_wav_header(c->fc, pb, st->codecpar, atom.size, 0)) < 0)
1233  av_log(c->fc, AV_LOG_WARNING, "get_wav_header failed\n");
1234 
1235  return ret;
1236 }
1237 
1239 {
1240  AVStream *st;
1241  HEIFItem *item;
1242  AVPacketSideData *sd;
1243  int width, height, err = 0;
1244  AVRational aperture_width, aperture_height, horiz_off, vert_off;
1245  AVRational pc_x, pc_y;
1246  uint64_t top, bottom, left, right;
1247 
1248  item = heif_cur_item(c);
1249  st = get_curr_st(c);
1250  if (!st)
1251  return 0;
1252 
1253  width = st->codecpar->width;
1254  height = st->codecpar->height;
1255  if ((!width || !height) && item) {
1256  width = item->width;
1257  height = item->height;
1258  }
1259  if (!width || !height) {
1260  err = AVERROR_INVALIDDATA;
1261  goto fail;
1262  }
1263 
1264  aperture_width.num = avio_rb32(pb);
1265  aperture_width.den = avio_rb32(pb);
1266  aperture_height.num = avio_rb32(pb);
1267  aperture_height.den = avio_rb32(pb);
1268 
1269  horiz_off.num = avio_rb32(pb);
1270  horiz_off.den = avio_rb32(pb);
1271  vert_off.num = avio_rb32(pb);
1272  vert_off.den = avio_rb32(pb);
1273 
1274  if (aperture_width.num < 0 || aperture_width.den < 0 ||
1275  aperture_height.num < 0 || aperture_height.den < 0 ||
1276  horiz_off.den < 0 || vert_off.den < 0) {
1277  err = AVERROR_INVALIDDATA;
1278  goto fail;
1279  }
1280  if ((av_cmp_q((AVRational) { width, 1 }, aperture_width) < 0) ||
1281  (av_cmp_q((AVRational) { height, 1 }, aperture_height) < 0)) {
1282  err = AVERROR_INVALIDDATA;
1283  goto fail;
1284  }
1285  av_log(c->fc, AV_LOG_TRACE, "clap: apertureWidth %d/%d, apertureHeight %d/%d "
1286  "horizOff %d/%d vertOff %d/%d\n",
1287  aperture_width.num, aperture_width.den, aperture_height.num, aperture_height.den,
1288  horiz_off.num, horiz_off.den, vert_off.num, vert_off.den);
1289 
1290  pc_x = av_mul_q((AVRational) { width - 1, 1 }, (AVRational) { 1, 2 });
1291  pc_x = av_add_q(pc_x, horiz_off);
1292  pc_y = av_mul_q((AVRational) { height - 1, 1 }, (AVRational) { 1, 2 });
1293  pc_y = av_add_q(pc_y, vert_off);
1294 
1295  aperture_width = av_sub_q(aperture_width, (AVRational) { 1, 1 });
1296  aperture_width = av_mul_q(aperture_width, (AVRational) { 1, 2 });
1297  aperture_height = av_sub_q(aperture_height, (AVRational) { 1, 1 });
1298  aperture_height = av_mul_q(aperture_height, (AVRational) { 1, 2 });
1299 
1300  left = av_q2d(av_sub_q(pc_x, aperture_width));
1301  right = av_q2d(av_add_q(pc_x, aperture_width));
1302  top = av_q2d(av_sub_q(pc_y, aperture_height));
1303  bottom = av_q2d(av_add_q(pc_y, aperture_height));
1304 
1305  if (bottom > (height - 1) ||
1306  right > (width - 1)) {
1307  err = AVERROR_INVALIDDATA;
1308  goto fail;
1309  }
1310 
1311  bottom = height - 1 - bottom;
1312  right = width - 1 - right;
1313 
1314  if (!(left | right | top | bottom))
1315  return 0;
1316 
1317  if ((left + right) >= width ||
1318  (top + bottom) >= height) {
1319  err = AVERROR_INVALIDDATA;
1320  goto fail;
1321  }
1322 
1326  sizeof(uint32_t) * 4, 0);
1327  if (!sd)
1328  return AVERROR(ENOMEM);
1329 
1330  AV_WL32A(sd->data, top);
1331  AV_WL32A(sd->data + 4, bottom);
1332  AV_WL32A(sd->data + 8, left);
1333  AV_WL32A(sd->data + 12, right);
1334 
1335 fail:
1336  if (err < 0) {
1337  int explode = !!(c->fc->error_recognition & AV_EF_EXPLODE);
1338  av_log(c->fc, explode ? AV_LOG_ERROR : AV_LOG_WARNING, "Invalid clap box\n");
1339  if (!explode)
1340  err = 0;
1341  }
1342 
1343  return err;
1344 }
1345 
1346 /* This atom overrides any previously set aspect ratio */
1348 {
1349  const int num = avio_rb32(pb);
1350  const int den = avio_rb32(pb);
1351  AVStream *st;
1352  MOVStreamContext *sc;
1353 
1354  if (c->fc->nb_streams < 1)
1355  return 0;
1356  st = c->fc->streams[c->fc->nb_streams-1];
1357  sc = st->priv_data;
1358 
1359  av_log(c->fc, AV_LOG_TRACE, "pasp: hSpacing %d, vSpacing %d\n", num, den);
1360 
1361  if (den != 0) {
1362  sc->h_spacing = num;
1363  sc->v_spacing = den;
1364  }
1365  return 0;
1366 }
1367 
1368 /* this atom contains actual media data */
1370 {
1371  if (atom.size == 0) /* wrong one (MP4) */
1372  return 0;
1373  c->found_mdat=1;
1374  return 0; /* now go for moov */
1375 }
1376 
1377 #define DRM_BLOB_SIZE 56
1378 
1380 {
1381  uint8_t intermediate_key[20];
1382  uint8_t intermediate_iv[20];
1383  uint8_t input[64];
1384  uint8_t output[64];
1385  uint8_t file_checksum[20];
1386  uint8_t calculated_checksum[20];
1387  char checksum_string[2 * sizeof(file_checksum) + 1];
1388  struct AVSHA *sha;
1389  int i;
1390  int ret = 0;
1391  uint8_t *activation_bytes = c->activation_bytes;
1392  uint8_t *fixed_key = c->audible_fixed_key;
1393 
1394  c->aax_mode = 1;
1395 
1396  sha = av_sha_alloc();
1397  if (!sha)
1398  return AVERROR(ENOMEM);
1399  av_free(c->aes_decrypt);
1400  c->aes_decrypt = av_aes_alloc();
1401  if (!c->aes_decrypt) {
1402  ret = AVERROR(ENOMEM);
1403  goto fail;
1404  }
1405 
1406  /* drm blob processing */
1407  avio_read(pb, output, 8); // go to offset 8, absolute position 0x251
1409  avio_read(pb, output, 4); // go to offset 4, absolute position 0x28d
1410  ret = ffio_read_size(pb, file_checksum, 20);
1411  if (ret < 0)
1412  goto fail;
1413 
1414  // required by external tools
1415  ff_data_to_hex(checksum_string, file_checksum, sizeof(file_checksum), 1);
1416  av_log(c->fc, AV_LOG_INFO, "[aax] file checksum == %s\n", checksum_string);
1417 
1418  /* verify activation data */
1419  if (!activation_bytes) {
1420  av_log(c->fc, AV_LOG_WARNING, "[aax] activation_bytes option is missing!\n");
1421  ret = 0; /* allow ffprobe to continue working on .aax files */
1422  goto fail;
1423  }
1424  if (c->activation_bytes_size != 4) {
1425  av_log(c->fc, AV_LOG_FATAL, "[aax] activation_bytes value needs to be 4 bytes!\n");
1426  ret = AVERROR(EINVAL);
1427  goto fail;
1428  }
1429 
1430  /* verify fixed key */
1431  if (c->audible_fixed_key_size != 16) {
1432  av_log(c->fc, AV_LOG_FATAL, "[aax] audible_fixed_key value needs to be 16 bytes!\n");
1433  ret = AVERROR(EINVAL);
1434  goto fail;
1435  }
1436 
1437  /* AAX (and AAX+) key derivation */
1438  av_sha_init(sha, 160);
1439  av_sha_update(sha, fixed_key, 16);
1440  av_sha_update(sha, activation_bytes, 4);
1441  av_sha_final(sha, intermediate_key);
1442  av_sha_init(sha, 160);
1443  av_sha_update(sha, fixed_key, 16);
1444  av_sha_update(sha, intermediate_key, 20);
1445  av_sha_update(sha, activation_bytes, 4);
1446  av_sha_final(sha, intermediate_iv);
1447  av_sha_init(sha, 160);
1448  av_sha_update(sha, intermediate_key, 16);
1449  av_sha_update(sha, intermediate_iv, 16);
1450  av_sha_final(sha, calculated_checksum);
1451  if (memcmp(calculated_checksum, file_checksum, 20)) { // critical error
1452  av_log(c->fc, AV_LOG_ERROR, "[aax] mismatch in checksums!\n");
1454  goto fail;
1455  }
1456  av_aes_init(c->aes_decrypt, intermediate_key, 128, 1);
1457  av_aes_crypt(c->aes_decrypt, output, input, DRM_BLOB_SIZE >> 4, intermediate_iv, 1);
1458  for (i = 0; i < 4; i++) {
1459  // file data (in output) is stored in big-endian mode
1460  if (activation_bytes[i] != output[3 - i]) { // critical error
1461  av_log(c->fc, AV_LOG_ERROR, "[aax] error in drm blob decryption!\n");
1463  goto fail;
1464  }
1465  }
1466  memcpy(c->file_key, output + 8, 16);
1467  memcpy(input, output + 26, 16);
1468  av_sha_init(sha, 160);
1469  av_sha_update(sha, input, 16);
1470  av_sha_update(sha, c->file_key, 16);
1471  av_sha_update(sha, fixed_key, 16);
1472  av_sha_final(sha, c->file_iv);
1473 
1474 fail:
1475  av_free(sha);
1476 
1477  return ret;
1478 }
1479 
1481 {
1482  if (c->audible_key_size != 16) {
1483  av_log(c->fc, AV_LOG_FATAL, "[aaxc] audible_key value needs to be 16 bytes!\n");
1484  return AVERROR(EINVAL);
1485  }
1486 
1487  if (c->audible_iv_size != 16) {
1488  av_log(c->fc, AV_LOG_FATAL, "[aaxc] audible_iv value needs to be 16 bytes!\n");
1489  return AVERROR(EINVAL);
1490  }
1491 
1492  c->aes_decrypt = av_aes_alloc();
1493  if (!c->aes_decrypt) {
1494  return AVERROR(ENOMEM);
1495  }
1496 
1497  memcpy(c->file_key, c->audible_key, 16);
1498  memcpy(c->file_iv, c->audible_iv, 16);
1499  c->aax_mode = 1;
1500 
1501  return 0;
1502 }
1503 
1504 // Audible AAX (and AAX+) bytestream decryption
1505 static int aax_filter(uint8_t *input, int size, MOVContext *c)
1506 {
1507  int blocks = 0;
1508  unsigned char iv[16];
1509 
1510  memcpy(iv, c->file_iv, 16); // iv is overwritten
1511  blocks = size >> 4; // trailing bytes are not encrypted!
1512  av_aes_init(c->aes_decrypt, c->file_key, 128, 1);
1513  av_aes_crypt(c->aes_decrypt, input, input, blocks, iv, 1);
1514 
1515  return 0;
1516 }
1517 
1518 /* read major brand, minor version and compatible brands and store them as metadata */
1520 {
1521  uint32_t minor_ver;
1522  int comp_brand_size;
1523  char* comp_brands_str;
1524  uint8_t type[5] = {0};
1525  int ret = ffio_read_size(pb, type, 4);
1526  if (ret < 0)
1527  return ret;
1528  if (c->fc->nb_streams) {
1529  if (c->fc->strict_std_compliance >= FF_COMPLIANCE_STRICT)
1530  return AVERROR_INVALIDDATA;
1531  av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate FTYP\n");
1532  return 0;
1533  }
1534 
1535  if (strcmp(type, "qt "))
1536  c->isom = 1;
1537  av_log(c->fc, AV_LOG_DEBUG, "ISO: File Type Major Brand: %.4s\n",(char *)&type);
1538  av_dict_set(&c->fc->metadata, "major_brand", type, 0);
1539  minor_ver = avio_rb32(pb); /* minor version */
1540  av_dict_set_int(&c->fc->metadata, "minor_version", minor_ver, 0);
1541 
1542  comp_brand_size = atom.size - 8;
1543  if (comp_brand_size < 0 || comp_brand_size == INT_MAX)
1544  return AVERROR_INVALIDDATA;
1545  comp_brands_str = av_malloc(comp_brand_size + 1); /* Add null terminator */
1546  if (!comp_brands_str)
1547  return AVERROR(ENOMEM);
1548 
1549  ret = ffio_read_size(pb, comp_brands_str, comp_brand_size);
1550  if (ret < 0) {
1551  av_freep(&comp_brands_str);
1552  return ret;
1553  }
1554  comp_brands_str[comp_brand_size] = 0;
1555  av_dict_set(&c->fc->metadata, "compatible_brands",
1556  comp_brands_str, AV_DICT_DONT_STRDUP_VAL);
1557 
1558  // Logic for handling Audible's .aaxc files
1559  if (!strcmp(type, "aaxc")) {
1560  mov_aaxc_crypto(c);
1561  }
1562 
1563  return 0;
1564 }
1565 
1566 /* this atom should contain all header atoms */
1568 {
1569  int ret;
1570 
1571  if (c->found_moov) {
1572  av_log(c->fc, AV_LOG_WARNING, "Found duplicated MOOV Atom. Skipped it\n");
1573  avio_skip(pb, atom.size);
1574  return 0;
1575  }
1576 
1577  if ((ret = mov_read_default(c, pb, atom)) < 0)
1578  return ret;
1579  /* we parsed the 'moov' atom, we can terminate the parsing as soon as we find the 'mdat' */
1580  /* so we don't parse the whole file if over a network */
1581  c->found_moov=1;
1582  return 0; /* now go for mdat */
1583 }
1584 
1586  MOVFragmentIndex *frag_index,
1587  int index,
1588  int id)
1589 {
1590  int i;
1591  MOVFragmentIndexItem * item;
1592 
1593  if (index < 0 || index >= frag_index->nb_items)
1594  return NULL;
1595  item = &frag_index->item[index];
1596  for (i = 0; i < item->nb_stream_info; i++)
1597  if (item->stream_info[i].id == id)
1598  return &item->stream_info[i];
1599 
1600  // This shouldn't happen
1601  return NULL;
1602 }
1603 
1604 static void set_frag_stream(MOVFragmentIndex *frag_index, int id)
1605 {
1606  int i;
1607  MOVFragmentIndexItem * item;
1608 
1609  if (frag_index->current < 0 ||
1610  frag_index->current >= frag_index->nb_items)
1611  return;
1612 
1613  item = &frag_index->item[frag_index->current];
1614  for (i = 0; i < item->nb_stream_info; i++)
1615  if (item->stream_info[i].id == id) {
1616  item->current = i;
1617  return;
1618  }
1619 
1620  // id not found. This shouldn't happen.
1621  item->current = -1;
1622 }
1623 
1625  MOVFragmentIndex *frag_index)
1626 {
1627  MOVFragmentIndexItem *item;
1628  if (frag_index->current < 0 ||
1629  frag_index->current >= frag_index->nb_items)
1630  return NULL;
1631 
1632  item = &frag_index->item[frag_index->current];
1633  if (item->current >= 0 && item->current < item->nb_stream_info)
1634  return &item->stream_info[item->current];
1635 
1636  // This shouldn't happen
1637  return NULL;
1638 }
1639 
1641 {
1642  int a, b, m;
1643  int64_t moof_offset;
1644 
1645  // Optimize for appending new entries
1646  if (!frag_index->nb_items ||
1647  frag_index->item[frag_index->nb_items - 1].moof_offset < offset)
1648  return frag_index->nb_items;
1649 
1650  a = -1;
1651  b = frag_index->nb_items;
1652 
1653  while (b - a > 1) {
1654  m = (a + b) >> 1;
1655  moof_offset = frag_index->item[m].moof_offset;
1656  if (moof_offset >= offset)
1657  b = m;
1658  if (moof_offset <= offset)
1659  a = m;
1660  }
1661  return b;
1662 }
1663 
1665 {
1666  av_assert0(frag_stream_info);
1667  if (frag_stream_info->sidx_pts != AV_NOPTS_VALUE)
1668  return frag_stream_info->sidx_pts;
1669  if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE)
1670  return frag_stream_info->first_tfra_pts;
1671  return frag_stream_info->tfdt_dts;
1672 }
1673 
1675  MOVFragmentIndex *frag_index, int index)
1676 {
1677  MOVFragmentStreamInfo * frag_stream_info;
1678  MOVStreamContext *sc = dst_st->priv_data;
1679  int64_t timestamp;
1680  int i, j;
1681 
1682  // If the stream is referenced by any sidx, limit the search
1683  // to fragments that referenced this stream in the sidx
1684  if (sc->has_sidx) {
1685  frag_stream_info = get_frag_stream_info(frag_index, index, sc->id);
1686  if (!frag_stream_info)
1687  return AV_NOPTS_VALUE;
1688  if (frag_stream_info->sidx_pts != AV_NOPTS_VALUE)
1689  return frag_stream_info->sidx_pts;
1690  if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE)
1691  return frag_stream_info->first_tfra_pts;
1692  return frag_stream_info->sidx_pts;
1693  }
1694 
1695  for (i = 0; i < frag_index->item[index].nb_stream_info; i++) {
1696  AVStream *frag_stream = NULL;
1697  frag_stream_info = &frag_index->item[index].stream_info[i];
1698  for (j = 0; j < s->nb_streams; j++) {
1699  MOVStreamContext *sc2 = s->streams[j]->priv_data;
1700  if (sc2->id == frag_stream_info->id)
1701  frag_stream = s->streams[j];
1702  }
1703  if (!frag_stream) {
1704  av_log(s, AV_LOG_WARNING, "No stream matching sidx ID found.\n");
1705  continue;
1706  }
1707  timestamp = get_stream_info_time(frag_stream_info);
1708  if (timestamp != AV_NOPTS_VALUE)
1709  return av_rescale_q(timestamp, frag_stream->time_base, dst_st->time_base);
1710  }
1711  return AV_NOPTS_VALUE;
1712 }
1713 
1715  AVStream *st, int64_t timestamp)
1716 {
1717  int a, b, m, m0;
1718  int64_t frag_time;
1719 
1720  a = -1;
1721  b = frag_index->nb_items;
1722 
1723  while (b - a > 1) {
1724  m0 = m = (a + b) >> 1;
1725 
1726  while (m < b &&
1727  (frag_time = get_frag_time(s, st, frag_index, m)) == AV_NOPTS_VALUE)
1728  m++;
1729 
1730  if (m < b && frag_time <= timestamp)
1731  a = m;
1732  else
1733  b = m0;
1734  }
1735 
1736  return a;
1737 }
1738 
1740 {
1741  int index, i;
1742  MOVFragmentIndexItem * item;
1743  MOVFragmentStreamInfo * frag_stream_info;
1744 
1745  // If moof_offset already exists in frag_index, return index to it
1746  index = search_frag_moof_offset(&c->frag_index, offset);
1747  if (index < c->frag_index.nb_items &&
1748  c->frag_index.item[index].moof_offset == offset)
1749  return index;
1750 
1751  // offset is not yet in frag index.
1752  // Insert new item at index (sorted by moof offset)
1753  item = av_fast_realloc(c->frag_index.item,
1754  &c->frag_index.allocated_size,
1755  (c->frag_index.nb_items + 1) *
1756  sizeof(*c->frag_index.item));
1757  if (!item)
1758  return -1;
1759  c->frag_index.item = item;
1760 
1761  frag_stream_info = av_realloc_array(NULL, c->fc->nb_streams,
1762  sizeof(*item->stream_info));
1763  if (!frag_stream_info)
1764  return -1;
1765 
1766  for (i = 0; i < c->fc->nb_streams; i++) {
1767  // Avoid building frag index if streams lack track id.
1768  MOVStreamContext *sc = c->fc->streams[i]->priv_data;
1769  if (sc->id < 0) {
1770  av_free(frag_stream_info);
1771  return AVERROR_INVALIDDATA;
1772  }
1773 
1774  frag_stream_info[i].id = sc->id;
1775  frag_stream_info[i].sidx_pts = AV_NOPTS_VALUE;
1776  frag_stream_info[i].tfdt_dts = AV_NOPTS_VALUE;
1777  frag_stream_info[i].next_trun_dts = AV_NOPTS_VALUE;
1778  frag_stream_info[i].first_tfra_pts = AV_NOPTS_VALUE;
1779  frag_stream_info[i].index_base = -1;
1780  frag_stream_info[i].index_entry = -1;
1781  frag_stream_info[i].encryption_index = NULL;
1782  frag_stream_info[i].stsd_id = -1;
1783  }
1784 
1785  if (index < c->frag_index.nb_items)
1786  memmove(c->frag_index.item + index + 1, c->frag_index.item + index,
1787  (c->frag_index.nb_items - index) * sizeof(*c->frag_index.item));
1788 
1789  item = &c->frag_index.item[index];
1790  item->headers_read = 0;
1791  item->current = 0;
1792  item->nb_stream_info = c->fc->nb_streams;
1793  item->moof_offset = offset;
1794  item->stream_info = frag_stream_info;
1795  c->frag_index.nb_items++;
1796 
1797  return index;
1798 }
1799 
1800 static void fix_frag_index_entries(MOVFragmentIndex *frag_index, int index,
1801  int id, int entries)
1802 {
1803  int i;
1804  MOVFragmentStreamInfo * frag_stream_info;
1805 
1806  if (index < 0)
1807  return;
1808  for (i = index; i < frag_index->nb_items; i++) {
1809  frag_stream_info = get_frag_stream_info(frag_index, i, id);
1810  if (frag_stream_info && frag_stream_info->index_entry >= 0)
1811  frag_stream_info->index_entry += entries;
1812  }
1813 }
1814 
1816 {
1817  // Set by mov_read_tfhd(). mov_read_trun() will reject files missing tfhd.
1818  c->fragment.found_tfhd = 0;
1819 
1820  if (!c->has_looked_for_mfra && c->use_mfra_for > 0) {
1821  c->has_looked_for_mfra = 1;
1822  if (pb->seekable & AVIO_SEEKABLE_NORMAL) {
1823  int ret;
1824  av_log(c->fc, AV_LOG_VERBOSE, "stream has moof boxes, will look "
1825  "for a mfra\n");
1826  if ((ret = mov_read_mfra(c, pb)) < 0) {
1827  av_log(c->fc, AV_LOG_VERBOSE, "found a moof box but failed to "
1828  "read the mfra (may be a live ismv)\n");
1829  }
1830  } else {
1831  av_log(c->fc, AV_LOG_VERBOSE, "found a moof box but stream is not "
1832  "seekable, can not look for mfra\n");
1833  }
1834  }
1835  c->fragment.moof_offset = c->fragment.implicit_offset = avio_tell(pb) - 8;
1836  av_log(c->fc, AV_LOG_TRACE, "moof offset %"PRIx64"\n", c->fragment.moof_offset);
1837  c->frag_index.current = update_frag_index(c, c->fragment.moof_offset);
1838  return mov_read_default(c, pb, atom);
1839 }
1840 
1842 {
1843  int64_t time;
1844  if (version == 1) {
1845  time = avio_rb64(pb);
1846  avio_rb64(pb);
1847  if (time < 0) {
1848  av_log(c->fc, AV_LOG_DEBUG, "creation_time is negative\n");
1849  return;
1850  }
1851  } else {
1852  time = avio_rb32(pb);
1853  avio_rb32(pb); /* modification time */
1854  if (time > 0 && time < 2082844800) {
1855  av_log(c->fc, AV_LOG_WARNING, "Detected creation time before 1970, parsing as unix timestamp.\n");
1856  time += 2082844800;
1857  }
1858  }
1859  if (time) {
1860  time -= 2082844800; /* seconds between 1904-01-01 and Epoch */
1861 
1862  if ((int64_t)(time * 1000000ULL) / 1000000 != time) {
1863  av_log(c->fc, AV_LOG_DEBUG, "creation_time is not representable\n");
1864  return;
1865  }
1866 
1867  ff_dict_set_timestamp(metadata, "creation_time", time * 1000000);
1868  }
1869 }
1870 
1872 {
1873  AVStream *st;
1874  MOVStreamContext *sc;
1875  int version;
1876  char language[4] = {0};
1877  unsigned lang;
1878 
1879  if (c->fc->nb_streams < 1)
1880  return 0;
1881  st = c->fc->streams[c->fc->nb_streams-1];
1882  sc = st->priv_data;
1883 
1884  if (sc->time_scale) {
1885  av_log(c->fc, AV_LOG_ERROR, "Multiple mdhd?\n");
1886  return AVERROR_INVALIDDATA;
1887  }
1888 
1889  version = avio_r8(pb);
1890  if (version > 1) {
1891  avpriv_request_sample(c->fc, "Version %d", version);
1892  return AVERROR_PATCHWELCOME;
1893  }
1894  avio_rb24(pb); /* flags */
1896 
1897  sc->time_scale = avio_rb32(pb);
1898  if (sc->time_scale <= 0) {
1899  av_log(c->fc, AV_LOG_ERROR, "Invalid mdhd time scale %d, defaulting to 1\n", sc->time_scale);
1900  sc->time_scale = 1;
1901  }
1902  st->duration = (version == 1) ? avio_rb64(pb) : avio_rb32(pb); /* duration */
1903 
1904  if ((version == 1 && st->duration == UINT64_MAX) ||
1905  (version != 1 && st->duration == UINT32_MAX)) {
1906  st->duration = 0;
1907  }
1908 
1909  lang = avio_rb16(pb); /* language */
1910  if (ff_mov_lang_to_iso639(lang, language))
1911  av_dict_set(&st->metadata, "language", language, 0);
1912  avio_rb16(pb); /* quality */
1913 
1914  return 0;
1915 }
1916 
1918 {
1919  int i;
1920  int version = avio_r8(pb); /* version */
1921  avio_rb24(pb); /* flags */
1922 
1923  mov_metadata_creation_time(c, pb, &c->fc->metadata, version);
1924  c->time_scale = avio_rb32(pb); /* time scale */
1925  if (c->time_scale <= 0) {
1926  av_log(c->fc, AV_LOG_ERROR, "Invalid mvhd time scale %d, defaulting to 1\n", c->time_scale);
1927  c->time_scale = 1;
1928  }
1929  av_log(c->fc, AV_LOG_TRACE, "time scale = %i\n", c->time_scale);
1930 
1931  c->duration = (version == 1) ? avio_rb64(pb) : avio_rb32(pb); /* duration */
1932  avio_rb32(pb); /* preferred scale */
1933 
1934  avio_rb16(pb); /* preferred volume */
1935 
1936  avio_skip(pb, 10); /* reserved */
1937 
1938  /* movie display matrix, store it in main context and use it later on */
1939  for (i = 0; i < 3; i++) {
1940  c->movie_display_matrix[i][0] = avio_rb32(pb); // 16.16 fixed point
1941  c->movie_display_matrix[i][1] = avio_rb32(pb); // 16.16 fixed point
1942  c->movie_display_matrix[i][2] = avio_rb32(pb); // 2.30 fixed point
1943  }
1944 
1945  avio_rb32(pb); /* preview time */
1946  avio_rb32(pb); /* preview duration */
1947  avio_rb32(pb); /* poster time */
1948  avio_rb32(pb); /* selection time */
1949  avio_rb32(pb); /* selection duration */
1950  avio_rb32(pb); /* current time */
1951  avio_rb32(pb); /* next track ID */
1952 
1953  return 0;
1954 }
1955 
1957 {
1958  AVStream *st;
1959 
1960  if (fc->nb_streams < 1)
1961  return;
1962  st = fc->streams[fc->nb_streams-1];
1963 
1964  switch (st->codecpar->codec_id) {
1965  case AV_CODEC_ID_PCM_S16BE:
1967  break;
1968  case AV_CODEC_ID_PCM_S24BE:
1970  break;
1971  case AV_CODEC_ID_PCM_S32BE:
1973  break;
1974  case AV_CODEC_ID_PCM_F32BE:
1976  break;
1977  case AV_CODEC_ID_PCM_F64BE:
1979  break;
1980  default:
1981  break;
1982  }
1983 }
1984 
1986 {
1987  int little_endian = avio_rb16(pb) & 0xFF;
1988  av_log(c->fc, AV_LOG_TRACE, "enda %d\n", little_endian);
1989  if (little_endian == 1)
1991  return 0;
1992 }
1993 
1995 {
1996  int format_flags;
1997  int version, flags;
1998  int pcm_sample_size;
1999  AVFormatContext *fc = c->fc;
2000  AVStream *st;
2001  MOVStreamContext *sc;
2002 
2003  if (atom.size < 6) {
2004  av_log(c->fc, AV_LOG_ERROR, "Empty pcmC box\n");
2005  return AVERROR_INVALIDDATA;
2006  }
2007 
2008  version = avio_r8(pb);
2009  flags = avio_rb24(pb);
2010 
2011  if (version != 0 || flags != 0) {
2012  av_log(c->fc, AV_LOG_ERROR,
2013  "Unsupported 'pcmC' box with version %d, flags: %x",
2014  version, flags);
2015  return AVERROR_INVALIDDATA;
2016  }
2017 
2018  format_flags = avio_r8(pb);
2019  pcm_sample_size = avio_r8(pb);
2020 
2021  if (fc->nb_streams < 1)
2022  return AVERROR_INVALIDDATA;
2023 
2024  st = fc->streams[fc->nb_streams - 1];
2025  sc = st->priv_data;
2026 
2027  if (sc->format == MOV_MP4_FPCM_TAG) {
2028  switch (pcm_sample_size) {
2029  case 32:
2031  break;
2032  case 64:
2034  break;
2035  default:
2036  av_log(fc, AV_LOG_ERROR, "invalid pcm_sample_size %d for %s\n",
2037  pcm_sample_size,
2038  av_fourcc2str(sc->format));
2039  return AVERROR_INVALIDDATA;
2040  }
2041  } else if (sc->format == MOV_MP4_IPCM_TAG) {
2042  switch (pcm_sample_size) {
2043  case 16:
2045  break;
2046  case 24:
2048  break;
2049  case 32:
2051  break;
2052  default:
2053  av_log(fc, AV_LOG_ERROR, "invalid pcm_sample_size %d for %s\n",
2054  pcm_sample_size,
2055  av_fourcc2str(sc->format));
2056  return AVERROR_INVALIDDATA;
2057  }
2058  } else {
2059  av_log(fc, AV_LOG_ERROR, "'pcmC' with invalid sample entry '%s'\n",
2060  av_fourcc2str(sc->format));
2061  return AVERROR_INVALIDDATA;
2062  }
2063 
2064  if (format_flags & 1) // indicates little-endian format. If not present, big-endian format is used
2067 
2068  return 0;
2069 }
2070 
2072 {
2073  AVStream *st;
2074  HEIFItem *item = NULL;
2075  char color_parameter_type[5] = { 0 };
2076  uint16_t color_primaries, color_trc, color_matrix;
2077  int ret;
2078 
2079  st = get_curr_st(c);
2080  if (!st) {
2081  item = heif_cur_item(c);
2082  if (!item)
2083  return 0;
2084  }
2085 
2086  ret = ffio_read_size(pb, color_parameter_type, 4);
2087  if (ret < 0)
2088  return ret;
2089  if (strncmp(color_parameter_type, "nclx", 4) &&
2090  strncmp(color_parameter_type, "nclc", 4) &&
2091  strncmp(color_parameter_type, "prof", 4)) {
2092  av_log(c->fc, AV_LOG_WARNING, "unsupported color_parameter_type %s\n",
2093  color_parameter_type);
2094  return 0;
2095  }
2096 
2097  if (!strncmp(color_parameter_type, "prof", 4)) {
2098  AVPacketSideData *sd;
2099  uint8_t *icc_profile;
2100  if (st) {
2104  atom.size - 4, 0);
2105  if (!sd)
2106  return AVERROR(ENOMEM);
2107  icc_profile = sd->data;
2108  } else {
2109  av_freep(&item->icc_profile);
2110  icc_profile = item->icc_profile = av_malloc(atom.size - 4);
2111  if (!icc_profile) {
2112  item->icc_profile_size = 0;
2113  return AVERROR(ENOMEM);
2114  }
2115  item->icc_profile_size = atom.size - 4;
2116  }
2117  ret = ffio_read_size(pb, icc_profile, atom.size - 4);
2118  if (ret < 0)
2119  return ret;
2120  } else if (st) {
2121  color_primaries = avio_rb16(pb);
2122  color_trc = avio_rb16(pb);
2123  color_matrix = avio_rb16(pb);
2124 
2125  av_log(c->fc, AV_LOG_TRACE,
2126  "%s: pri %d trc %d matrix %d",
2127  color_parameter_type, color_primaries, color_trc, color_matrix);
2128 
2129  if (!strncmp(color_parameter_type, "nclx", 4)) {
2130  uint8_t color_range = avio_r8(pb) >> 7;
2131  av_log(c->fc, AV_LOG_TRACE, " full %"PRIu8"", color_range);
2132  if (color_range)
2134  else
2136  }
2137 
2140  if (!av_color_transfer_name(color_trc))
2141  color_trc = AVCOL_TRC_UNSPECIFIED;
2142  if (!av_color_space_name(color_matrix))
2143  color_matrix = AVCOL_SPC_UNSPECIFIED;
2144 
2146  st->codecpar->color_trc = color_trc;
2147  st->codecpar->color_space = color_matrix;
2148  av_log(c->fc, AV_LOG_TRACE, "\n");
2149  }
2150  return 0;
2151 }
2152 
2154 {
2155  AVStream *st;
2156  unsigned mov_field_order;
2157  enum AVFieldOrder decoded_field_order = AV_FIELD_UNKNOWN;
2158 
2159  if (c->fc->nb_streams < 1) // will happen with jp2 files
2160  return 0;
2161  st = c->fc->streams[c->fc->nb_streams-1];
2162  if (atom.size < 2)
2163  return AVERROR_INVALIDDATA;
2164  mov_field_order = avio_rb16(pb);
2165  if ((mov_field_order & 0xFF00) == 0x0100)
2166  decoded_field_order = AV_FIELD_PROGRESSIVE;
2167  else if ((mov_field_order & 0xFF00) == 0x0200) {
2168  switch (mov_field_order & 0xFF) {
2169  case 0x01: decoded_field_order = AV_FIELD_TT;
2170  break;
2171  case 0x06: decoded_field_order = AV_FIELD_BB;
2172  break;
2173  case 0x09: decoded_field_order = AV_FIELD_TB;
2174  break;
2175  case 0x0E: decoded_field_order = AV_FIELD_BT;
2176  break;
2177  }
2178  }
2179  if (decoded_field_order == AV_FIELD_UNKNOWN && mov_field_order) {
2180  av_log(c->fc, AV_LOG_ERROR, "Unknown MOV field order 0x%04x\n", mov_field_order);
2181  }
2182  st->codecpar->field_order = decoded_field_order;
2183 
2184  return 0;
2185 }
2186 
2188 {
2189  int err = 0;
2190  uint64_t size = (uint64_t)par->extradata_size + atom.size + 8 + AV_INPUT_BUFFER_PADDING_SIZE;
2191  if (size > INT_MAX || (uint64_t)atom.size > INT_MAX)
2192  return AVERROR_INVALIDDATA;
2193  if ((err = av_reallocp(&par->extradata, size)) < 0) {
2194  par->extradata_size = 0;
2195  return err;
2196  }
2198  return 0;
2199 }
2200 
2201 /* Read a whole atom into the extradata return the size of the atom read, possibly truncated if != atom.size */
2203  AVCodecParameters *par, uint8_t *buf)
2204 {
2205  int64_t result = atom.size;
2206  int err;
2207 
2208  AV_WB32(buf , atom.size + 8);
2209  AV_WL32(buf + 4, atom.type);
2210  err = ffio_read_size(pb, buf + 8, atom.size);
2211  if (err < 0) {
2212  par->extradata_size -= atom.size;
2213  return err;
2214  } else if (err < atom.size) {
2215  av_log(c->fc, AV_LOG_WARNING, "truncated extradata\n");
2216  par->extradata_size -= atom.size - err;
2217  result = err;
2218  }
2219  memset(buf + 8 + err, 0, AV_INPUT_BUFFER_PADDING_SIZE);
2220  return result;
2221 }
2222 
2223 /* FIXME modify QDM2/SVQ3/H.264 decoders to take full atom as extradata */
2225  enum AVCodecID codec_id)
2226 {
2227  AVStream *st;
2228  uint64_t original_size;
2229  int err;
2230 
2231  if (c->fc->nb_streams < 1) // will happen with jp2 files
2232  return 0;
2233  st = c->fc->streams[c->fc->nb_streams-1];
2234 
2235  if (st->codecpar->codec_id != codec_id)
2236  return 0; /* unexpected codec_id - don't mess with extradata */
2237 
2238  original_size = st->codecpar->extradata_size;
2239  err = mov_realloc_extradata(st->codecpar, atom);
2240  if (err)
2241  return err;
2242 
2243  err = mov_read_atom_into_extradata(c, pb, atom, st->codecpar, st->codecpar->extradata + original_size);
2244  if (err < 0)
2245  return err;
2246  return 0; // Note: this is the original behavior to ignore truncation.
2247 }
2248 
2249 /* wrapper functions for reading ALAC/AVS/MJPEG/MJPEG2000 extradata atoms only for those codecs */
2251 {
2252  return mov_read_extradata(c, pb, atom, AV_CODEC_ID_ALAC);
2253 }
2254 
2256 {
2257  return mov_read_extradata(c, pb, atom, AV_CODEC_ID_CAVS);
2258 }
2259 
2261 {
2262  return mov_read_extradata(c, pb, atom, AV_CODEC_ID_JPEG2000);
2263 }
2264 
2266 {
2267  return mov_read_extradata(c, pb, atom, AV_CODEC_ID_R10K);
2268 }
2269 
2271 {
2272  int ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_AVUI);
2273  if (!ret)
2274  ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_DNXHD);
2275  return ret;
2276 }
2277 
2279 {
2280  int ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_TARGA_Y216);
2281 
2282  if (!ret && c->fc->nb_streams >= 1) {
2283  AVCodecParameters *par = c->fc->streams[c->fc->nb_streams-1]->codecpar;
2284  if (par->extradata_size >= 40) {
2285  par->height = AV_RB16(&par->extradata[36]);
2286  par->width = AV_RB16(&par->extradata[38]);
2287  }
2288  }
2289  return ret;
2290 }
2291 
2293 {
2294  if (c->fc->nb_streams >= 1) {
2295  AVStream *const st = c->fc->streams[c->fc->nb_streams - 1];
2296  FFStream *const sti = ffstream(st);
2297  AVCodecParameters *par = st->codecpar;
2298 
2299  if (par->codec_tag == MKTAG('A', 'V', 'i', 'n') &&
2300  par->codec_id == AV_CODEC_ID_H264 &&
2301  atom.size > 11) {
2302  int cid;
2303  avio_skip(pb, 10);
2304  cid = avio_rb16(pb);
2305  /* For AVID AVCI50, force width of 1440 to be able to select the correct SPS and PPS */
2306  if (cid == 0xd4d || cid == 0xd4e)
2307  par->width = 1440;
2308  return 0;
2309  } else if ((par->codec_tag == MKTAG('A', 'V', 'd', '1') ||
2310  par->codec_tag == MKTAG('A', 'V', 'j', '2') ||
2311  par->codec_tag == MKTAG('A', 'V', 'd', 'n')) &&
2312  atom.size >= 24) {
2313  int num, den;
2314  avio_skip(pb, 12);
2315  num = avio_rb32(pb);
2316  den = avio_rb32(pb);
2317  if (num <= 0 || den <= 0)
2318  return 0;
2319  switch (avio_rb32(pb)) {
2320  case 2:
2321  if (den >= INT_MAX / 2)
2322  return 0;
2323  den *= 2;
2324  case 1:
2325  sti->display_aspect_ratio = (AVRational){ num, den };
2326  default:
2327  return 0;
2328  }
2329  }
2330  }
2331 
2332  return mov_read_avid(c, pb, atom);
2333 }
2334 
2336 {
2337  int ret = 0;
2338  int length = 0;
2339  uint64_t original_size;
2340  if (c->fc->nb_streams >= 1) {
2341  AVCodecParameters *par = c->fc->streams[c->fc->nb_streams-1]->codecpar;
2342  if (par->codec_id == AV_CODEC_ID_H264)
2343  return 0;
2344  if (atom.size == 16) {
2345  original_size = par->extradata_size;
2346  ret = mov_realloc_extradata(par, atom);
2347  if (!ret) {
2348  length = mov_read_atom_into_extradata(c, pb, atom, par, par->extradata + original_size);
2349  if (length == atom.size) {
2350  const uint8_t range_value = par->extradata[original_size + 19];
2351  switch (range_value) {
2352  case 1:
2354  break;
2355  case 2:
2357  break;
2358  default:
2359  av_log(c->fc, AV_LOG_WARNING, "ignored unknown aclr value (%d)\n", range_value);
2360  break;
2361  }
2362  ff_dlog(c->fc, "color_range: %d\n", par->color_range);
2363  } else {
2364  /* For some reason the whole atom was not added to the extradata */
2365  av_log(c->fc, AV_LOG_ERROR, "aclr not decoded - incomplete atom\n");
2366  }
2367  } else {
2368  av_log(c->fc, AV_LOG_ERROR, "aclr not decoded - unable to add atom to extradata\n");
2369  }
2370  } else {
2371  av_log(c->fc, AV_LOG_WARNING, "aclr not decoded - unexpected size %"PRId64"\n", atom.size);
2372  }
2373  }
2374 
2375  return ret;
2376 }
2377 
2379 {
2380  return mov_read_extradata(c, pb, atom, AV_CODEC_ID_SVQ3);
2381 }
2382 
2384 {
2385  AVStream *st;
2386  int ret;
2387 
2388  if (c->fc->nb_streams < 1)
2389  return 0;
2390  st = c->fc->streams[c->fc->nb_streams-1];
2391 
2392  if ((uint64_t)atom.size > (1<<30))
2393  return AVERROR_INVALIDDATA;
2394 
2395  if (st->codecpar->codec_id == AV_CODEC_ID_QDM2 ||
2398  // pass all frma atom to codec, needed at least for QDMC and QDM2
2399  ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size);
2400  if (ret < 0)
2401  return ret;
2402  } else if (atom.size > 8) { /* to read frma, esds atoms */
2403  if (st->codecpar->codec_id == AV_CODEC_ID_ALAC && atom.size >= 24) {
2404  uint64_t buffer;
2405  ret = ffio_ensure_seekback(pb, 8);
2406  if (ret < 0)
2407  return ret;
2408  buffer = avio_rb64(pb);
2409  atom.size -= 8;
2410  if ( (buffer & 0xFFFFFFFF) == MKBETAG('f','r','m','a')
2411  && buffer >> 32 <= atom.size
2412  && buffer >> 32 >= 8) {
2413  avio_skip(pb, -8);
2414  atom.size += 8;
2415  } else if (!st->codecpar->extradata_size) {
2416 #define ALAC_EXTRADATA_SIZE 36
2418  if (!st->codecpar->extradata)
2419  return AVERROR(ENOMEM);
2422  AV_WB32(st->codecpar->extradata + 4, MKTAG('a','l','a','c'));
2423  AV_WB64(st->codecpar->extradata + 12, buffer);
2424  avio_read(pb, st->codecpar->extradata + 20, 16);
2425  avio_skip(pb, atom.size - 24);
2426  return 0;
2427  }
2428  }
2429  if ((ret = mov_read_default(c, pb, atom)) < 0)
2430  return ret;
2431  } else
2432  avio_skip(pb, atom.size);
2433  return 0;
2434 }
2435 
2436 /**
2437  * This function reads atom content and puts data in extradata without tag
2438  * nor size unlike mov_read_extradata.
2439  */
2441 {
2442  AVStream *st;
2443  int ret;
2444 
2445  st = get_curr_st(c);
2446  if (!st)
2447  return 0;
2448 
2449  if ((uint64_t)atom.size > (1<<30))
2450  return AVERROR_INVALIDDATA;
2451 
2452  if (atom.type == MKTAG('v','v','c','C')) {
2453  avio_skip(pb, 4);
2454  atom.size -= 4;
2455  }
2456 
2457  if (atom.size >= 10) {
2458  // Broken files created by legacy versions of libavformat will
2459  // wrap a whole fiel atom inside of a glbl atom.
2460  unsigned size = avio_rb32(pb);
2461  unsigned type = avio_rl32(pb);
2462  if (avio_feof(pb))
2463  return AVERROR_INVALIDDATA;
2464  avio_seek(pb, -8, SEEK_CUR);
2465  if (type == MKTAG('f','i','e','l') && size == atom.size)
2466  return mov_read_default(c, pb, atom);
2467  }
2468  if (st->codecpar->extradata_size > 1 && st->codecpar->extradata) {
2469  av_log(c->fc, AV_LOG_WARNING, "ignoring multiple glbl\n");
2470  return 0;
2471  }
2472  ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size);
2473  if (ret < 0)
2474  return ret;
2475  if (atom.type == MKTAG('h','v','c','C') && st->codecpar->codec_tag == MKTAG('d','v','h','1'))
2476  /* HEVC-based Dolby Vision derived from hvc1.
2477  Happens to match with an identifier
2478  previously utilized for DV. Thus, if we have
2479  the hvcC extradata box available as specified,
2480  set codec to HEVC */
2482 
2483  return 0;
2484 }
2485 
2487 {
2488  AVStream *st;
2489  uint8_t profile_level;
2490  int ret;
2491 
2492  if (c->fc->nb_streams < 1)
2493  return 0;
2494  st = c->fc->streams[c->fc->nb_streams-1];
2495 
2496  if (atom.size >= (1<<28) || atom.size < 7)
2497  return AVERROR_INVALIDDATA;
2498 
2499  profile_level = avio_r8(pb);
2500  if ((profile_level & 0xf0) != 0xc0)
2501  return 0;
2502 
2503  avio_seek(pb, 6, SEEK_CUR);
2504  ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size - 7);
2505  if (ret < 0)
2506  return ret;
2507 
2508  return 0;
2509 }
2510 
2512 {
2513  AVStream* st;
2514  MOVStreamContext* sc;
2515 
2516  if (c->fc->nb_streams < 1)
2517  return 0;
2518 
2519  /* For SBAS this should be fine - though beware if someone implements a
2520  * tref atom processor that doesn't drop down to default then this may
2521  * be lost. */
2522  if (atom.size > 4) {
2523  av_log(c->fc, AV_LOG_ERROR, "Only a single tref of type sbas is supported\n");
2524  return AVERROR_PATCHWELCOME;
2525  }
2526 
2527  st = c->fc->streams[c->fc->nb_streams - 1];
2528  sc = st->priv_data;
2529  sc->tref_id = avio_rb32(pb);
2531 
2532  return 0;
2533 }
2534 
2535 /**
2536  * An strf atom is a BITMAPINFOHEADER struct. This struct is 40 bytes itself,
2537  * but can have extradata appended at the end after the 40 bytes belonging
2538  * to the struct.
2539  */
2541 {
2542  AVStream *st;
2543  int ret;
2544 
2545  if (c->fc->nb_streams < 1)
2546  return 0;
2547  if (atom.size <= 40)
2548  return 0;
2549  st = c->fc->streams[c->fc->nb_streams-1];
2550 
2551  if ((uint64_t)atom.size > (1<<30))
2552  return AVERROR_INVALIDDATA;
2553 
2554  avio_skip(pb, 40);
2555  ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size - 40);
2556  if (ret < 0)
2557  return ret;
2558 
2559  return 0;
2560 }
2561 
2563 {
2564  AVStream *st;
2565  MOVStreamContext *sc;
2566  unsigned int i, entries;
2567 
2568  if (c->trak_index < 0) {
2569  av_log(c->fc, AV_LOG_WARNING, "STCO outside TRAK\n");
2570  return 0;
2571  }
2572  if (c->fc->nb_streams < 1)
2573  return 0;
2574  st = c->fc->streams[c->fc->nb_streams-1];
2575  sc = st->priv_data;
2576 
2577  avio_r8(pb); /* version */
2578  avio_rb24(pb); /* flags */
2579 
2580  // Clamp allocation size for `chunk_offsets` -- don't throw an error for an
2581  // invalid count since the EOF path doesn't throw either.
2582  entries = avio_rb32(pb);
2583  entries =
2584  FFMIN(entries,
2585  FFMAX(0, (atom.size - 8) /
2586  (atom.type == MKTAG('s', 't', 'c', 'o') ? 4 : 8)));
2587 
2588  if (!entries)
2589  return 0;
2590 
2591  if (sc->chunk_offsets) {
2592  av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicated STCO atom\n");
2593  return 0;
2594  }
2595 
2596  av_free(sc->chunk_offsets);
2597  sc->chunk_count = 0;
2598  sc->chunk_offsets = av_malloc_array(entries, sizeof(*sc->chunk_offsets));
2599  if (!sc->chunk_offsets)
2600  return AVERROR(ENOMEM);
2601  sc->chunk_count = entries;
2602 
2603  if (atom.type == MKTAG('s','t','c','o'))
2604  for (i = 0; i < entries && !pb->eof_reached; i++)
2605  sc->chunk_offsets[i] = avio_rb32(pb);
2606  else if (atom.type == MKTAG('c','o','6','4'))
2607  for (i = 0; i < entries && !pb->eof_reached; i++) {
2608  sc->chunk_offsets[i] = avio_rb64(pb);
2609  if (sc->chunk_offsets[i] < 0) {
2610  av_log(c->fc, AV_LOG_WARNING, "Impossible chunk_offset\n");
2611  sc->chunk_offsets[i] = 0;
2612  }
2613  }
2614  else
2615  return AVERROR_INVALIDDATA;
2616 
2617  sc->chunk_count = i;
2618 
2619  if (pb->eof_reached) {
2620  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STCO atom\n");
2621  return AVERROR_EOF;
2622  }
2623 
2624  return 0;
2625 }
2626 
2627 static int mov_codec_id(AVStream *st, uint32_t format)
2628 {
2630 
2631  if (id <= 0 &&
2632  ((format & 0xFFFF) == 'm' + ('s' << 8) ||
2633  (format & 0xFFFF) == 'T' + ('S' << 8)))
2635 
2636  if (st->codecpar->codec_type != AVMEDIA_TYPE_VIDEO && id > 0) {
2638  } else if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO &&
2639  /* skip old ASF MPEG-4 tag */
2640  format && format != MKTAG('m','p','4','s')) {
2642  if (id <= 0)
2644  if (id > 0)
2646  else if (st->codecpar->codec_type == AVMEDIA_TYPE_DATA ||
2648  st->codecpar->codec_id == AV_CODEC_ID_NONE)) {
2650  if (id <= 0) {
2652  AV_CODEC_ID_TTML : id;
2653  }
2654 
2655  if (id > 0)
2657  else
2659  }
2660  }
2661 
2662  st->codecpar->codec_tag = format;
2663 
2664  return id;
2665 }
2666 
2668  AVStream *st, MOVStreamContext *sc)
2669 {
2670  uint8_t codec_name[32] = { 0 };
2671  int64_t stsd_start;
2672  unsigned int len;
2673  uint32_t id = 0;
2674 
2675  /* The first 16 bytes of the video sample description are already
2676  * read in ff_mov_read_stsd_entries() */
2677  stsd_start = avio_tell(pb) - 16;
2678 
2679  avio_rb16(pb); /* version */
2680  avio_rb16(pb); /* revision level */
2681  id = avio_rl32(pb); /* vendor */
2682  av_dict_set(&st->metadata, "vendor_id", av_fourcc2str(id), 0);
2683  avio_rb32(pb); /* temporal quality */
2684  avio_rb32(pb); /* spatial quality */
2685 
2686  st->codecpar->width = avio_rb16(pb); /* width */
2687  st->codecpar->height = avio_rb16(pb); /* height */
2688 
2689  avio_rb32(pb); /* horiz resolution */
2690  avio_rb32(pb); /* vert resolution */
2691  avio_rb32(pb); /* data size, always 0 */
2692  avio_rb16(pb); /* frames per samples */
2693 
2694  len = avio_r8(pb); /* codec name, pascal string */
2695  if (len > 31)
2696  len = 31;
2697  mov_read_mac_string(c, pb, len, codec_name, sizeof(codec_name));
2698  if (len < 31)
2699  avio_skip(pb, 31 - len);
2700 
2701  if (codec_name[0])
2702  av_dict_set(&st->metadata, "encoder", codec_name, 0);
2703 
2704  /* codec_tag YV12 triggers an UV swap in rawdec.c */
2705  if (!strncmp(codec_name, "Planar Y'CbCr 8-bit 4:2:0", 25)) {
2706  st->codecpar->codec_tag = MKTAG('I', '4', '2', '0');
2707  st->codecpar->width &= ~1;
2708  st->codecpar->height &= ~1;
2709  }
2710  /* Flash Media Server uses tag H.263 with Sorenson Spark */
2711  if (st->codecpar->codec_tag == MKTAG('H','2','6','3') &&
2712  !strncmp(codec_name, "Sorenson H263", 13))
2714 
2715  st->codecpar->bits_per_coded_sample = avio_rb16(pb); /* depth */
2716 
2717  avio_seek(pb, stsd_start, SEEK_SET);
2718 
2719  if (ff_get_qtpalette(st->codecpar->codec_id, pb, sc->palette)) {
2720  st->codecpar->bits_per_coded_sample &= 0x1F;
2721  sc->has_palette = 1;
2722  }
2723 }
2724 
2726  AVStream *st, MOVStreamContext *sc)
2727 {
2728  int bits_per_sample, flags;
2729  uint16_t version = avio_rb16(pb);
2730  uint32_t id = 0;
2731  AVDictionaryEntry *compatible_brands = av_dict_get(c->fc->metadata, "compatible_brands", NULL, AV_DICT_MATCH_CASE);
2732  int channel_count;
2733 
2734  avio_rb16(pb); /* revision level */
2735  id = avio_rl32(pb); /* vendor */
2736  av_dict_set(&st->metadata, "vendor_id", av_fourcc2str(id), 0);
2737 
2738  channel_count = avio_rb16(pb);
2739 
2741  st->codecpar->ch_layout.nb_channels = channel_count;
2742  st->codecpar->bits_per_coded_sample = avio_rb16(pb); /* sample size */
2743  av_log(c->fc, AV_LOG_TRACE, "audio channels %d\n", channel_count);
2744 
2745  sc->audio_cid = avio_rb16(pb);
2746  avio_rb16(pb); /* packet size = 0 */
2747 
2748  st->codecpar->sample_rate = ((avio_rb32(pb) >> 16));
2749 
2750  // Read QT version 1 fields. In version 0 these do not exist.
2751  av_log(c->fc, AV_LOG_TRACE, "version =%d, isom =%d\n", version, c->isom);
2752  if (!c->isom ||
2753  (compatible_brands && strstr(compatible_brands->value, "qt ")) ||
2754  (sc->stsd_version == 0 && version > 0)) {
2755  if (version == 1) {
2756  sc->samples_per_frame = avio_rb32(pb);
2757  avio_rb32(pb); /* bytes per packet */
2758  sc->bytes_per_frame = avio_rb32(pb);
2759  avio_rb32(pb); /* bytes per sample */
2760  } else if (version == 2) {
2761  avio_rb32(pb); /* sizeof struct only */
2763  channel_count = avio_rb32(pb);
2765  st->codecpar->ch_layout.nb_channels = channel_count;
2766  avio_rb32(pb); /* always 0x7F000000 */
2768 
2769  flags = avio_rb32(pb); /* lpcm format specific flag */
2770  sc->bytes_per_frame = avio_rb32(pb);
2771  sc->samples_per_frame = avio_rb32(pb);
2772  if (st->codecpar->codec_tag == MKTAG('l','p','c','m'))
2773  st->codecpar->codec_id =
2775  flags);
2776  }
2777  if (version == 0 || (version == 1 && sc->audio_cid != -2)) {
2778  /* can't correctly handle variable sized packet as audio unit */
2779  switch (st->codecpar->codec_id) {
2780  case AV_CODEC_ID_MP2:
2781  case AV_CODEC_ID_MP3:
2783  break;
2784  }
2785  }
2786  }
2787 
2788  if (sc->format == 0) {
2789  if (st->codecpar->bits_per_coded_sample == 8)
2790  st->codecpar->codec_id = mov_codec_id(st, MKTAG('r','a','w',' '));
2791  else if (st->codecpar->bits_per_coded_sample == 16)
2792  st->codecpar->codec_id = mov_codec_id(st, MKTAG('t','w','o','s'));
2793  }
2794 
2795  switch (st->codecpar->codec_id) {
2796  case AV_CODEC_ID_PCM_S8:
2797  case AV_CODEC_ID_PCM_U8:
2798  if (st->codecpar->bits_per_coded_sample == 16)
2800  break;
2801  case AV_CODEC_ID_PCM_S16LE:
2802  case AV_CODEC_ID_PCM_S16BE:
2803  if (st->codecpar->bits_per_coded_sample == 8)
2805  else if (st->codecpar->bits_per_coded_sample == 24)
2806  st->codecpar->codec_id =
2809  else if (st->codecpar->bits_per_coded_sample == 32)
2810  st->codecpar->codec_id =
2813  break;
2814  /* set values for old format before stsd version 1 appeared */
2815  case AV_CODEC_ID_MACE3:
2816  sc->samples_per_frame = 6;
2818  break;
2819  case AV_CODEC_ID_MACE6:
2820  sc->samples_per_frame = 6;
2822  break;
2824  sc->samples_per_frame = 64;
2826  break;
2827  case AV_CODEC_ID_GSM:
2828  sc->samples_per_frame = 160;
2829  sc->bytes_per_frame = 33;
2830  break;
2831  default:
2832  break;
2833  }
2834 
2835  bits_per_sample = av_get_bits_per_sample(st->codecpar->codec_id);
2836  if (bits_per_sample && (bits_per_sample >> 3) * (uint64_t)st->codecpar->ch_layout.nb_channels <= INT_MAX) {
2837  st->codecpar->bits_per_coded_sample = bits_per_sample;
2838  sc->sample_size = (bits_per_sample >> 3) * st->codecpar->ch_layout.nb_channels;
2839  }
2840 }
2841 
2843  AVStream *st, MOVStreamContext *sc,
2844  int64_t size)
2845 {
2846  // ttxt stsd contains display flags, justification, background
2847  // color, fonts, and default styles, so fake an atom to read it
2848  MOVAtom fake_atom = { .size = size };
2849  // mp4s contains a regular esds atom, dfxp ISMV TTML has no content
2850  // in extradata unlike stpp MP4 TTML.
2851  if (st->codecpar->codec_tag != AV_RL32("mp4s") &&
2853  mov_read_glbl(c, pb, fake_atom);
2854  st->codecpar->width = sc->width;
2855  st->codecpar->height = sc->height;
2856 }
2857 
2859  AVStream *st, MOVStreamContext *sc,
2860  int64_t size)
2861 {
2862  int ret;
2863 
2864  if (st->codecpar->codec_tag == MKTAG('t','m','c','d')) {
2865  if ((int)size != size)
2866  return AVERROR(ENOMEM);
2867 
2868  ret = ff_get_extradata(c->fc, st->codecpar, pb, size);
2869  if (ret < 0)
2870  return ret;
2871  if (size > 16) {
2872  MOVStreamContext *tmcd_ctx = st->priv_data;
2873  int val;
2874  val = AV_RB32(st->codecpar->extradata + 4);
2875  tmcd_ctx->tmcd_flags = val;
2876  st->avg_frame_rate.num = AV_RB32(st->codecpar->extradata + 8); /* timescale */
2877  st->avg_frame_rate.den = AV_RB32(st->codecpar->extradata + 12); /* frameDuration */
2878  tmcd_ctx->tmcd_nb_frames = st->codecpar->extradata[16]; /* number of frames */
2879  if (size > 30) {
2880  uint32_t len = AV_RB32(st->codecpar->extradata + 18); /* name atom length */
2881  uint32_t format = AV_RB32(st->codecpar->extradata + 22);
2882  if (format == AV_RB32("name") && (int64_t)size >= (int64_t)len + 18) {
2883  uint16_t str_size = AV_RB16(st->codecpar->extradata + 26); /* string length */
2884  if (str_size > 0 && size >= (int)str_size + 30 &&
2885  st->codecpar->extradata[30] /* Don't add empty string */) {
2886  char *reel_name = av_malloc(str_size + 1);
2887  if (!reel_name)
2888  return AVERROR(ENOMEM);
2889  memcpy(reel_name, st->codecpar->extradata + 30, str_size);
2890  reel_name[str_size] = 0; /* Add null terminator */
2891  av_dict_set(&st->metadata, "reel_name", reel_name,
2893  }
2894  }
2895  }
2896  }
2897  } else {
2898  /* other codec type, just skip (rtp, mp4s ...) */
2899  avio_skip(pb, size);
2900  }
2901  return 0;
2902 }
2903 
2905  AVStream *st, MOVStreamContext *sc)
2906 {
2907  FFStream *const sti = ffstream(st);
2908 
2909  if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
2910  !st->codecpar->sample_rate && sc->time_scale > 1)
2911  st->codecpar->sample_rate = sc->time_scale;
2912 
2913  /* special codec parameters handling */
2914  switch (st->codecpar->codec_id) {
2915 #if CONFIG_DV_DEMUXER
2916  case AV_CODEC_ID_DVAUDIO:
2917  if (c->dv_fctx) {
2918  avpriv_request_sample(c->fc, "multiple DV audio streams");
2919  return AVERROR(ENOSYS);
2920  }
2921 
2922  c->dv_fctx = avformat_alloc_context();
2923  if (!c->dv_fctx) {
2924  av_log(c->fc, AV_LOG_ERROR, "dv demux context alloc error\n");
2925  return AVERROR(ENOMEM);
2926  }
2927  c->dv_demux = avpriv_dv_init_demux(c->dv_fctx);
2928  if (!c->dv_demux) {
2929  av_log(c->fc, AV_LOG_ERROR, "dv demux context init error\n");
2930  return AVERROR(ENOMEM);
2931  }
2932  sc->dv_audio_container = 1;
2934  break;
2935 #endif
2936  /* no ifdef since parameters are always those */
2937  case AV_CODEC_ID_QCELP:
2940  // force sample rate for qcelp when not stored in mov
2941  if (st->codecpar->codec_tag != MKTAG('Q','c','l','p'))
2942  st->codecpar->sample_rate = 8000;
2943  // FIXME: Why is the following needed for some files?
2944  sc->samples_per_frame = 160;
2945  if (!sc->bytes_per_frame)
2946  sc->bytes_per_frame = 35;
2947  break;
2948  case AV_CODEC_ID_AMR_NB:
2951  /* force sample rate for amr, stsd in 3gp does not store sample rate */
2952  st->codecpar->sample_rate = 8000;
2953  break;
2954  case AV_CODEC_ID_AMR_WB:
2957  st->codecpar->sample_rate = 16000;
2958  break;
2959  case AV_CODEC_ID_MP2:
2960  case AV_CODEC_ID_MP3:
2961  /* force type after stsd for m1a hdlr */
2963  break;
2964  case AV_CODEC_ID_GSM:
2965  case AV_CODEC_ID_ADPCM_MS:
2967  case AV_CODEC_ID_ILBC:
2968  case AV_CODEC_ID_MACE3:
2969  case AV_CODEC_ID_MACE6:
2970  case AV_CODEC_ID_QDM2:
2972  break;
2973  case AV_CODEC_ID_ALAC:
2974  if (st->codecpar->extradata_size == 36) {
2975  int channel_count = AV_RB8(st->codecpar->extradata + 21);
2976  if (st->codecpar->ch_layout.nb_channels != channel_count) {
2979  st->codecpar->ch_layout.nb_channels = channel_count;
2980  }
2981  st->codecpar->sample_rate = AV_RB32(st->codecpar->extradata + 32);
2982  }
2983  break;
2984  case AV_CODEC_ID_AC3:
2985  case AV_CODEC_ID_EAC3:
2987  case AV_CODEC_ID_VC1:
2988  case AV_CODEC_ID_VP8:
2989  case AV_CODEC_ID_VP9:
2991  break;
2993  case AV_CODEC_ID_APV:
2994  case AV_CODEC_ID_EVC:
2995  case AV_CODEC_ID_AV1:
2996  /* field_order detection of H264 requires parsing */
2997  case AV_CODEC_ID_H264:
2999  break;
3000  default:
3001  break;
3002  }
3003  return 0;
3004 }
3005 
3007  int codec_tag, int format,
3008  int64_t size)
3009 {
3010  if (codec_tag &&
3011  (codec_tag != format &&
3012  // AVID 1:1 samples with differing data format and codec tag exist
3013  (codec_tag != AV_RL32("AV1x") || format != AV_RL32("AVup")) &&
3014  // prores is allowed to have differing data format and codec tag
3015  codec_tag != AV_RL32("apcn") && codec_tag != AV_RL32("apch") &&
3016  // so is dv (sigh)
3017  codec_tag != AV_RL32("dvpp") && codec_tag != AV_RL32("dvcp") &&
3018  (c->fc->video_codec_id ? ff_codec_get_id(ff_codec_movvideo_tags, format) != c->fc->video_codec_id
3019  : codec_tag != MKTAG('j','p','e','g')))) {
3020  /* Multiple fourcc, we skip JPEG. This is not correct, we should
3021  * export it as a separate AVStream but this needs a few changes
3022  * in the MOV demuxer, patch welcome. */
3023 
3024  av_log(c->fc, AV_LOG_WARNING, "multiple fourcc not supported\n");
3025  avio_skip(pb, size);
3026  return 1;
3027  }
3028 
3029  return 0;
3030 }
3031 
3033 {
3034  int ret;
3035 
3036  /* special codec parameters handling */
3037  switch (st->codecpar->codec_id) {
3038  case AV_CODEC_ID_H264:
3039  // done for ai5q, ai52, ai55, ai1q, ai12 and ai15.
3040  if (!st->codecpar->extradata_size && TAG_IS_AVCI(st->codecpar->codec_tag)) {
3042  if (ret < 0)
3043  return ret;
3044  }
3045  break;
3046  default:
3047  break;
3048  }
3049 
3050  return 0;
3051 }
3052 
3054 {
3055  AVStream *st;
3056  MOVStreamContext *sc;
3057  int pseudo_stream_id;
3058 
3059  av_assert0 (c->fc->nb_streams >= 1);
3060  st = c->fc->streams[c->fc->nb_streams-1];
3061  sc = st->priv_data;
3062 
3063  for (pseudo_stream_id = 0;
3064  pseudo_stream_id < entries && !pb->eof_reached;
3065  pseudo_stream_id++) {
3066  //Parsing Sample description table
3067  enum AVCodecID id;
3068  int ret, dref_id = 1;
3069  MOVAtom a = { AV_RL32("stsd") };
3070  int64_t start_pos = avio_tell(pb);
3071  int64_t size = avio_rb32(pb); /* size */
3072  uint32_t format = avio_rl32(pb); /* data format */
3073 
3074  if (size >= 16) {
3075  avio_rb32(pb); /* reserved */
3076  avio_rb16(pb); /* reserved */
3077  dref_id = avio_rb16(pb);
3078  } else if (size <= 7) {
3079  av_log(c->fc, AV_LOG_ERROR,
3080  "invalid size %"PRId64" in stsd\n", size);
3081  return AVERROR_INVALIDDATA;
3082  }
3083 
3085  size - (avio_tell(pb) - start_pos))) {
3086  sc->stsd_count++;
3087  continue;
3088  }
3089 
3090  sc->pseudo_stream_id = st->codecpar->codec_tag ? -1 : pseudo_stream_id;
3091  sc->dref_id= dref_id;
3092  sc->format = format;
3093 
3094  id = mov_codec_id(st, format);
3095 
3096  av_log(c->fc, AV_LOG_TRACE,
3097  "size=%"PRId64" 4CC=%s codec_type=%d\n", size,
3099 
3100  st->codecpar->codec_id = id;
3102  mov_parse_stsd_video(c, pb, st, sc);
3103  } else if (st->codecpar->codec_type==AVMEDIA_TYPE_AUDIO) {
3104  mov_parse_stsd_audio(c, pb, st, sc);
3105  if (st->codecpar->sample_rate < 0) {
3106  av_log(c->fc, AV_LOG_ERROR, "Invalid sample rate %d\n", st->codecpar->sample_rate);
3107  return AVERROR_INVALIDDATA;
3108  }
3109  if (st->codecpar->ch_layout.nb_channels < 0) {
3110  av_log(c->fc, AV_LOG_ERROR, "Invalid channels %d\n", st->codecpar->ch_layout.nb_channels);
3111  return AVERROR_INVALIDDATA;
3112  }
3113  } else if (st->codecpar->codec_type==AVMEDIA_TYPE_SUBTITLE){
3114  mov_parse_stsd_subtitle(c, pb, st, sc,
3115  size - (avio_tell(pb) - start_pos));
3116  } else {
3117  ret = mov_parse_stsd_data(c, pb, st, sc,
3118  size - (avio_tell(pb) - start_pos));
3119  if (ret < 0)
3120  return ret;
3121  }
3122  /* this will read extra atoms at the end (wave, alac, damr, avcC, hvcC, SMI ...) */
3123  a.size = size - (avio_tell(pb) - start_pos);
3124  if (a.size > 8) {
3125  if ((ret = mov_read_default(c, pb, a)) < 0)
3126  return ret;
3127  } else if (a.size > 0)
3128  avio_skip(pb, a.size);
3129 
3130  ret = mov_finalize_stsd_entry(c, st);
3131  if (ret < 0)
3132  return ret;
3133 
3134  if (sc->extradata && st->codecpar->extradata) {
3135  int extra_size = st->codecpar->extradata_size;
3136 
3137  /* Move the current stream extradata to the stream context one. */
3138  sc->extradata_size[pseudo_stream_id] = extra_size;
3139  sc->extradata[pseudo_stream_id] = st->codecpar->extradata;
3140  st->codecpar->extradata = NULL;
3141  st->codecpar->extradata_size = 0;
3142  }
3143  sc->stsd_count++;
3144  }
3145 
3146  if (pb->eof_reached) {
3147  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSD atom\n");
3148  return AVERROR_EOF;
3149  }
3150 
3151  return 0;
3152 }
3153 
3155 {
3156  AVStream *st;
3157  MOVStreamContext *sc;
3158  int ret, entries;
3159 
3160  if (c->fc->nb_streams < 1)
3161  return 0;
3162  st = c->fc->streams[c->fc->nb_streams - 1];
3163  sc = st->priv_data;
3164 
3165  sc->stsd_version = avio_r8(pb);
3166  avio_rb24(pb); /* flags */
3167  entries = avio_rb32(pb);
3168 
3169  /* Each entry contains a size (4 bytes) and format (4 bytes). */
3170  if (entries <= 0 || entries > atom.size / 8 || entries > 1024) {
3171  av_log(c->fc, AV_LOG_ERROR, "invalid STSD entries %d\n", entries);
3172  return AVERROR_INVALIDDATA;
3173  }
3174 
3175  if (sc->extradata) {
3176  av_log(c->fc, AV_LOG_ERROR,
3177  "Duplicate stsd found in this track.\n");
3178  return AVERROR_INVALIDDATA;
3179  }
3180 
3181  /* Prepare space for hosting multiple extradata. */
3182  sc->extradata = av_calloc(entries, sizeof(*sc->extradata));
3183  if (!sc->extradata)
3184  return AVERROR(ENOMEM);
3185 
3186  sc->extradata_size = av_calloc(entries, sizeof(*sc->extradata_size));
3187  if (!sc->extradata_size) {
3188  ret = AVERROR(ENOMEM);
3189  goto fail;
3190  }
3191 
3192  ret = ff_mov_read_stsd_entries(c, pb, entries);
3193  if (ret < 0)
3194  goto fail;
3195 
3196  /* Restore back the primary extradata. */
3197  av_freep(&st->codecpar->extradata);
3198  st->codecpar->extradata_size = sc->extradata_size[0];
3199  if (sc->extradata_size[0]) {
3201  if (!st->codecpar->extradata)
3202  return AVERROR(ENOMEM);
3203  memcpy(st->codecpar->extradata, sc->extradata[0], sc->extradata_size[0]);
3204  }
3205 
3206  return mov_finalize_stsd_codec(c, pb, st, sc);
3207 fail:
3208  if (sc->extradata) {
3209  int j;
3210  for (j = 0; j < sc->stsd_count; j++)
3211  av_freep(&sc->extradata[j]);
3212  }
3213 
3214  av_freep(&sc->extradata);
3215  av_freep(&sc->extradata_size);
3216  return ret;
3217 }
3218 
3220 {
3221  AVStream *st;
3222  MOVStreamContext *sc;
3223  unsigned int i, entries;
3224 
3225  if (c->trak_index < 0) {
3226  av_log(c->fc, AV_LOG_WARNING, "STSC outside TRAK\n");
3227  return 0;
3228  }
3229 
3230  if (c->fc->nb_streams < 1)
3231  return 0;
3232  st = c->fc->streams[c->fc->nb_streams-1];
3233  sc = st->priv_data;
3234 
3235  avio_r8(pb); /* version */
3236  avio_rb24(pb); /* flags */
3237 
3238  entries = avio_rb32(pb);
3239  if ((uint64_t)entries * 12 + 4 > atom.size)
3240  return AVERROR_INVALIDDATA;
3241 
3242  av_log(c->fc, AV_LOG_TRACE, "track[%u].stsc.entries = %u\n", c->fc->nb_streams - 1, entries);
3243 
3244  if (!entries)
3245  return 0;
3246  if (sc->stsc_data) {
3247  av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicated STSC atom\n");
3248  return 0;
3249  }
3250  av_free(sc->stsc_data);
3251  sc->stsc_count = 0;
3252  sc->stsc_data = av_malloc_array(entries, sizeof(*sc->stsc_data));
3253  if (!sc->stsc_data)
3254  return AVERROR(ENOMEM);
3255 
3256  for (i = 0; i < entries && !pb->eof_reached; i++) {
3257  sc->stsc_data[i].first = avio_rb32(pb);
3258  sc->stsc_data[i].count = avio_rb32(pb);
3259  sc->stsc_data[i].id = avio_rb32(pb);
3260  }
3261 
3262  sc->stsc_count = i;
3263  for (i = sc->stsc_count - 1; i < UINT_MAX; i--) {
3264  int64_t first_min = i + 1;
3265  if ((i+1 < sc->stsc_count && sc->stsc_data[i].first >= sc->stsc_data[i+1].first) ||
3266  (i > 0 && sc->stsc_data[i].first <= sc->stsc_data[i-1].first) ||
3267  sc->stsc_data[i].first < first_min ||
3268  sc->stsc_data[i].count < 1 ||
3269  sc->stsc_data[i].id < 1) {
3270  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);
3271  if (i+1 >= sc->stsc_count) {
3272  if (sc->stsc_data[i].count == 0 && i > 0) {
3273  sc->stsc_count --;
3274  continue;
3275  }
3276  sc->stsc_data[i].first = FFMAX(sc->stsc_data[i].first, first_min);
3277  if (i > 0 && sc->stsc_data[i].first <= sc->stsc_data[i-1].first)
3278  sc->stsc_data[i].first = FFMIN(sc->stsc_data[i-1].first + 1LL, INT_MAX);
3279  sc->stsc_data[i].count = FFMAX(sc->stsc_data[i].count, 1);
3280  sc->stsc_data[i].id = FFMAX(sc->stsc_data[i].id, 1);
3281  continue;
3282  }
3283  av_assert0(sc->stsc_data[i+1].first >= 2);
3284  // We replace this entry by the next valid
3285  sc->stsc_data[i].first = sc->stsc_data[i+1].first - 1;
3286  sc->stsc_data[i].count = sc->stsc_data[i+1].count;
3287  sc->stsc_data[i].id = sc->stsc_data[i+1].id;
3288  }
3289  }
3290 
3291  if (pb->eof_reached) {
3292  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSC atom\n");
3293  return AVERROR_EOF;
3294  }
3295 
3296  return 0;
3297 }
3298 
3299 static inline int mov_stsc_index_valid(unsigned int index, unsigned int count)
3300 {
3301  return index < count - 1;
3302 }
3303 
3304 /* Compute the samples value for the stsc entry at the given index. */
3305 static inline int64_t mov_get_stsc_samples(MOVStreamContext *sc, unsigned int index)
3306 {
3307  int chunk_count;
3308 
3310  chunk_count = sc->stsc_data[index + 1].first - sc->stsc_data[index].first;
3311  else {
3312  // Validation for stsc / stco happens earlier in mov_read_stsc + mov_read_trak.
3314  chunk_count = sc->chunk_count - (sc->stsc_data[index].first - 1);
3315  }
3316 
3317  return sc->stsc_data[index].count * (int64_t)chunk_count;
3318 }
3319 
3321 {
3322  AVStream *st;
3323  MOVStreamContext *sc;
3324  unsigned i, entries;
3325 
3326  if (c->trak_index < 0) {
3327  av_log(c->fc, AV_LOG_WARNING, "STPS outside TRAK\n");
3328  return 0;
3329  }
3330 
3331  if (c->fc->nb_streams < 1)
3332  return 0;
3333  st = c->fc->streams[c->fc->nb_streams-1];
3334  sc = st->priv_data;
3335 
3336  avio_rb32(pb); // version + flags
3337 
3338  entries = avio_rb32(pb);
3339  if (sc->stps_data)
3340  av_log(c->fc, AV_LOG_WARNING, "Duplicated STPS atom\n");
3341  av_free(sc->stps_data);
3342  sc->stps_count = 0;
3343  sc->stps_data = av_malloc_array(entries, sizeof(*sc->stps_data));
3344  if (!sc->stps_data)
3345  return AVERROR(ENOMEM);
3346 
3347  for (i = 0; i < entries && !pb->eof_reached; i++) {
3348  sc->stps_data[i] = avio_rb32(pb);
3349  }
3350 
3351  sc->stps_count = i;
3352 
3353  if (pb->eof_reached) {
3354  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STPS atom\n");
3355  return AVERROR_EOF;
3356  }
3357 
3358  return 0;
3359 }
3360 
3362 {
3363  AVStream *st;
3364  FFStream *sti;
3365  MOVStreamContext *sc;
3366  unsigned int i, entries;
3367 
3368  if (c->trak_index < 0) {
3369  av_log(c->fc, AV_LOG_WARNING, "STSS outside TRAK\n");
3370  return 0;
3371  }
3372 
3373  if (c->fc->nb_streams < 1)
3374  return 0;
3375  st = c->fc->streams[c->fc->nb_streams-1];
3376  sti = ffstream(st);
3377  sc = st->priv_data;
3378 
3379  avio_r8(pb); /* version */
3380  avio_rb24(pb); /* flags */
3381 
3382  entries = avio_rb32(pb);
3383 
3384  av_log(c->fc, AV_LOG_TRACE, "keyframe_count = %u\n", entries);
3385 
3386  if (!entries) {
3387  sc->keyframe_absent = 1;
3388  if (!sti->need_parsing && st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
3390  return 0;
3391  }
3392  if (sc->keyframes)
3393  av_log(c->fc, AV_LOG_WARNING, "Duplicated STSS atom\n");
3394  if (entries >= UINT_MAX / sizeof(int))
3395  return AVERROR_INVALIDDATA;
3396  av_freep(&sc->keyframes);
3397  sc->keyframe_count = 0;
3398  sc->keyframes = av_malloc_array(entries, sizeof(*sc->keyframes));
3399  if (!sc->keyframes)
3400  return AVERROR(ENOMEM);
3401 
3402  for (i = 0; i < entries && !pb->eof_reached; i++) {
3403  sc->keyframes[i] = avio_rb32(pb);
3404  }
3405 
3406  sc->keyframe_count = i;
3407 
3408  if (pb->eof_reached) {
3409  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSS atom\n");
3410  return AVERROR_EOF;
3411  }
3412 
3413  return 0;
3414 }
3415 
3417 {
3418  AVStream *st;
3419  MOVStreamContext *sc;
3420  unsigned int i, entries, sample_size, field_size, num_bytes;
3421  GetBitContext gb;
3422  unsigned char* buf;
3423  int ret;
3424 
3425  if (c->trak_index < 0) {
3426  av_log(c->fc, AV_LOG_WARNING, "STSZ outside TRAK\n");
3427  return 0;
3428  }
3429 
3430  if (c->fc->nb_streams < 1)
3431  return 0;
3432  st = c->fc->streams[c->fc->nb_streams-1];
3433  sc = st->priv_data;
3434 
3435  avio_r8(pb); /* version */
3436  avio_rb24(pb); /* flags */
3437 
3438  if (atom.type == MKTAG('s','t','s','z')) {
3439  sample_size = avio_rb32(pb);
3440  if (!sc->sample_size) /* do not overwrite value computed in stsd */
3441  sc->sample_size = sample_size;
3442  sc->stsz_sample_size = sample_size;
3443  field_size = 32;
3444  } else {
3445  sample_size = 0;
3446  avio_rb24(pb); /* reserved */
3447  field_size = avio_r8(pb);
3448  }
3449  entries = avio_rb32(pb);
3450 
3451  av_log(c->fc, AV_LOG_TRACE, "sample_size = %u sample_count = %u\n", sc->sample_size, entries);
3452 
3453  sc->sample_count = entries;
3454  if (sample_size)
3455  return 0;
3456 
3457  if (field_size != 4 && field_size != 8 && field_size != 16 && field_size != 32) {
3458  av_log(c->fc, AV_LOG_ERROR, "Invalid sample field size %u\n", field_size);
3459  return AVERROR_INVALIDDATA;
3460  }
3461 
3462  if (!entries)
3463  return 0;
3464  if (entries >= (INT_MAX - 4 - 8 * AV_INPUT_BUFFER_PADDING_SIZE) / field_size)
3465  return AVERROR_INVALIDDATA;
3466  if (sc->sample_sizes)
3467  av_log(c->fc, AV_LOG_WARNING, "Duplicated STSZ atom\n");
3468  av_free(sc->sample_sizes);
3469  sc->sample_count = 0;
3470  sc->sample_sizes = av_malloc_array(entries, sizeof(*sc->sample_sizes));
3471  if (!sc->sample_sizes)
3472  return AVERROR(ENOMEM);
3473 
3474  num_bytes = (entries*field_size+4)>>3;
3475 
3476  buf = av_malloc(num_bytes+AV_INPUT_BUFFER_PADDING_SIZE);
3477  if (!buf) {
3478  av_freep(&sc->sample_sizes);
3479  return AVERROR(ENOMEM);
3480  }
3481 
3482  ret = ffio_read_size(pb, buf, num_bytes);
3483  if (ret < 0) {
3484  av_freep(&sc->sample_sizes);
3485  av_free(buf);
3486  av_log(c->fc, AV_LOG_WARNING, "STSZ atom truncated\n");
3487  return 0;
3488  }
3489 
3490  init_get_bits(&gb, buf, 8*num_bytes);
3491 
3492  for (i = 0; i < entries; i++) {
3493  sc->sample_sizes[i] = get_bits_long(&gb, field_size);
3494  if (sc->sample_sizes[i] > INT64_MAX - sc->data_size) {
3495  av_free(buf);
3496  av_log(c->fc, AV_LOG_ERROR, "Sample size overflow in STSZ\n");
3497  return AVERROR_INVALIDDATA;
3498  }
3499  sc->data_size += sc->sample_sizes[i];
3500  }
3501 
3502  sc->sample_count = i;
3503 
3504  av_free(buf);
3505 
3506  return 0;
3507 }
3508 
3510 {
3511  AVStream *st;
3512  MOVStreamContext *sc;
3513  unsigned int i, entries;
3514  int64_t duration = 0;
3515  int64_t total_sample_count = 0;
3516  int64_t current_dts = 0;
3517  int64_t corrected_dts = 0;
3518 
3519  if (c->trak_index < 0) {
3520  av_log(c->fc, AV_LOG_WARNING, "STTS outside TRAK\n");
3521  return 0;
3522  }
3523 
3524  if (c->fc->nb_streams < 1)
3525  return 0;
3526  st = c->fc->streams[c->fc->nb_streams-1];
3527  sc = st->priv_data;
3528 
3529  avio_r8(pb); /* version */
3530  avio_rb24(pb); /* flags */
3531  entries = avio_rb32(pb);
3532 
3533  av_log(c->fc, AV_LOG_TRACE, "track[%u].stts.entries = %u\n",
3534  c->fc->nb_streams-1, entries);
3535 
3536  if (sc->stts_data)
3537  av_log(c->fc, AV_LOG_WARNING, "Duplicated STTS atom\n");
3538  av_freep(&sc->stts_data);
3539  sc->stts_count = 0;
3540  if (entries >= INT_MAX / sizeof(*sc->stts_data))
3541  return AVERROR(ENOMEM);
3542 
3543  for (i = 0; i < entries && !pb->eof_reached; i++) {
3544  unsigned int sample_duration;
3545  unsigned int sample_count;
3546  unsigned int min_entries = FFMIN(FFMAX(i + 1, 1024 * 1024), entries);
3547  MOVStts *stts_data = av_fast_realloc(sc->stts_data, &sc->stts_allocated_size,
3548  min_entries * sizeof(*sc->stts_data));
3549  if (!stts_data) {
3550  av_freep(&sc->stts_data);
3551  sc->stts_count = 0;
3552  return AVERROR(ENOMEM);
3553  }
3554  sc->stts_count = min_entries;
3555  sc->stts_data = stts_data;
3556 
3557  sample_count = avio_rb32(pb);
3558  sample_duration = avio_rb32(pb);
3559 
3560  sc->stts_data[i].count= sample_count;
3561  sc->stts_data[i].duration= sample_duration;
3562 
3563  av_log(c->fc, AV_LOG_TRACE, "sample_count=%u, sample_duration=%u\n",
3564  sample_count, sample_duration);
3565 
3566  /* STTS sample offsets are uint32 but some files store it as int32
3567  * with negative values used to correct DTS delays.
3568  There may be abnormally large values as well. */
3569  if (sample_duration > c->max_stts_delta) {
3570  // assume high delta is a correction if negative when cast as int32
3571  int32_t delta_magnitude = (int32_t)sample_duration;
3572  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",
3573  sample_duration, i, sample_count, st->index);
3574  sc->stts_data[i].duration = 1;
3575  corrected_dts = av_sat_add64(corrected_dts, (delta_magnitude < 0 ? (int64_t)delta_magnitude : 1) * sample_count);
3576  } else {
3577  corrected_dts += sample_duration * (uint64_t)sample_count;
3578  }
3579 
3580  current_dts += sc->stts_data[i].duration * (uint64_t)sample_count;
3581 
3582  if (current_dts > corrected_dts) {
3583  int64_t drift = av_sat_sub64(current_dts, corrected_dts) / FFMAX(sample_count, 1);
3584  uint32_t correction = (sc->stts_data[i].duration > drift) ? drift : sc->stts_data[i].duration - 1;
3585  current_dts -= correction * (uint64_t)sample_count;
3586  sc->stts_data[i].duration -= correction;
3587  }
3588 
3589  duration+=(int64_t)sc->stts_data[i].duration*(uint64_t)sc->stts_data[i].count;
3590  total_sample_count+=sc->stts_data[i].count;
3591  }
3592 
3593  sc->stts_count = i;
3594 
3595  if (duration > 0 &&
3596  duration <= INT64_MAX - sc->duration_for_fps &&
3597  total_sample_count <= INT_MAX - sc->nb_frames_for_fps) {
3598  sc->duration_for_fps += duration;
3599  sc->nb_frames_for_fps += total_sample_count;
3600  }
3601 
3602  if (pb->eof_reached) {
3603  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STTS atom\n");
3604  return AVERROR_EOF;
3605  }
3606 
3607  st->nb_frames= total_sample_count;
3608  if (duration)
3609  st->duration= FFMIN(st->duration, duration);
3610 
3611  // All samples have zero duration. They have higher chance be chose by
3612  // mov_find_next_sample, which leads to seek again and again.
3613  //
3614  // It's AVERROR_INVALIDDATA actually, but such files exist in the wild.
3615  // So only mark data stream as discarded for safety.
3616  if (!duration && sc->stts_count &&
3618  av_log(c->fc, AV_LOG_WARNING,
3619  "All samples in data stream index:id [%d:%d] have zero "
3620  "duration, stream set to be discarded by default. Override "
3621  "using AVStream->discard or -discard for ffmpeg command.\n",
3622  st->index, sc->id);
3623  st->discard = AVDISCARD_ALL;
3624  }
3625  sc->track_end = duration;
3626  return 0;
3627 }
3628 
3630 {
3631  AVStream *st;
3632  MOVStreamContext *sc;
3633  int64_t i, entries;
3634 
3635  if (c->fc->nb_streams < 1)
3636  return 0;
3637  st = c->fc->streams[c->fc->nb_streams - 1];
3638  sc = st->priv_data;
3639 
3640  avio_r8(pb); /* version */
3641  avio_rb24(pb); /* flags */
3642  entries = atom.size - 4;
3643 
3644  av_log(c->fc, AV_LOG_TRACE, "track[%u].sdtp.entries = %" PRId64 "\n",
3645  c->fc->nb_streams - 1, entries);
3646 
3647  if (sc->sdtp_data)
3648  av_log(c->fc, AV_LOG_WARNING, "Duplicated SDTP atom\n");
3649  av_freep(&sc->sdtp_data);
3650  sc->sdtp_count = 0;
3651 
3652  sc->sdtp_data = av_malloc(entries);
3653  if (!sc->sdtp_data)
3654  return AVERROR(ENOMEM);
3655 
3656  for (i = 0; i < entries && !pb->eof_reached; i++)
3657  sc->sdtp_data[i] = avio_r8(pb);
3658  sc->sdtp_count = i;
3659 
3660  return 0;
3661 }
3662 
3663 static void mov_update_dts_shift(MOVStreamContext *sc, int duration, void *logctx)
3664 {
3665  if (duration < 0) {
3666  if (duration == INT_MIN) {
3667  av_log(logctx, AV_LOG_WARNING, "mov_update_dts_shift(): dts_shift set to %d\n", INT_MAX);
3668  duration++;
3669  }
3670  sc->dts_shift = FFMAX(sc->dts_shift, -duration);
3671  }
3672 }
3673 
3675 {
3676  AVStream *st;
3677  MOVStreamContext *sc;
3678  unsigned int i, entries, ctts_count = 0;
3679 
3680  if (c->trak_index < 0) {
3681  av_log(c->fc, AV_LOG_WARNING, "CTTS outside TRAK\n");
3682  return 0;
3683  }
3684 
3685  if (c->fc->nb_streams < 1)
3686  return 0;
3687  st = c->fc->streams[c->fc->nb_streams-1];
3688  sc = st->priv_data;
3689 
3690  avio_r8(pb); /* version */
3691  avio_rb24(pb); /* flags */
3692  entries = avio_rb32(pb);
3693 
3694  av_log(c->fc, AV_LOG_TRACE, "track[%u].ctts.entries = %u\n", c->fc->nb_streams - 1, entries);
3695 
3696  if (!entries)
3697  return 0;
3698  if (entries >= UINT_MAX / sizeof(*sc->ctts_data))
3699  return AVERROR_INVALIDDATA;
3700  av_freep(&sc->ctts_data);
3701  sc->ctts_data = av_fast_realloc(NULL, &sc->ctts_allocated_size, entries * sizeof(*sc->ctts_data));
3702  if (!sc->ctts_data)
3703  return AVERROR(ENOMEM);
3704 
3705  for (i = 0; i < entries && !pb->eof_reached; i++) {
3706  MOVCtts *ctts_data;
3707  const size_t min_size_needed = (ctts_count + 1) * sizeof(MOVCtts);
3708  const size_t requested_size =
3709  min_size_needed > sc->ctts_allocated_size ?
3710  FFMAX(min_size_needed, 2 * sc->ctts_allocated_size) :
3711  min_size_needed;
3712  int count = avio_rb32(pb);
3713  int duration = avio_rb32(pb);
3714 
3715  if (count <= 0) {
3716  av_log(c->fc, AV_LOG_TRACE,
3717  "ignoring CTTS entry with count=%d duration=%d\n",
3718  count, duration);
3719  continue;
3720  }
3721 
3722  if (ctts_count >= UINT_MAX / sizeof(MOVCtts) - 1)
3723  return AVERROR(ENOMEM);
3724 
3725  ctts_data = av_fast_realloc(sc->ctts_data, &sc->ctts_allocated_size, requested_size);
3726 
3727  if (!ctts_data)
3728  return AVERROR(ENOMEM);
3729 
3730  sc->ctts_data = ctts_data;
3731 
3732  ctts_data[ctts_count].count = count;
3733  ctts_data[ctts_count].offset = duration;
3734  ctts_count++;
3735 
3736  av_log(c->fc, AV_LOG_TRACE, "count=%d, duration=%d\n",
3737  count, duration);
3738 
3739  if (i+2<entries)
3740  mov_update_dts_shift(sc, duration, c->fc);
3741  }
3742 
3743  sc->ctts_count = ctts_count;
3744 
3745  if (pb->eof_reached) {
3746  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted CTTS atom\n");
3747  return AVERROR_EOF;
3748  }
3749 
3750  av_log(c->fc, AV_LOG_TRACE, "dts shift %d\n", sc->dts_shift);
3751 
3752  return 0;
3753 }
3754 
3756 {
3757  AVStream *st;
3758  MOVStreamContext *sc;
3759  uint8_t version;
3760  uint32_t grouping_type;
3761  uint32_t default_length;
3762  av_unused uint32_t default_group_description_index;
3763  uint32_t entry_count;
3764 
3765  if (c->fc->nb_streams < 1)
3766  return 0;
3767  st = c->fc->streams[c->fc->nb_streams - 1];
3768  sc = st->priv_data;
3769 
3770  version = avio_r8(pb); /* version */
3771  avio_rb24(pb); /* flags */
3772  grouping_type = avio_rl32(pb);
3773 
3774  /*
3775  * This function only supports "sync" boxes, but the code is able to parse
3776  * other boxes (such as "tscl", "tsas" and "stsa")
3777  */
3778  if (grouping_type != MKTAG('s','y','n','c'))
3779  return 0;
3780 
3781  default_length = version >= 1 ? avio_rb32(pb) : 0;
3782  default_group_description_index = version >= 2 ? avio_rb32(pb) : 0;
3783  entry_count = avio_rb32(pb);
3784 
3785  av_freep(&sc->sgpd_sync);
3786  sc->sgpd_sync_count = entry_count;
3787  sc->sgpd_sync = av_calloc(entry_count, sizeof(*sc->sgpd_sync));
3788  if (!sc->sgpd_sync)
3789  return AVERROR(ENOMEM);
3790 
3791  for (uint32_t i = 0; i < entry_count && !pb->eof_reached; i++) {
3792  uint32_t description_length = default_length;
3793  if (version >= 1 && default_length == 0)
3794  description_length = avio_rb32(pb);
3795  if (grouping_type == MKTAG('s','y','n','c')) {
3796  const uint8_t nal_unit_type = avio_r8(pb) & 0x3f;
3797  sc->sgpd_sync[i] = nal_unit_type;
3798  description_length -= 1;
3799  }
3800  avio_skip(pb, description_length);
3801  }
3802 
3803  if (pb->eof_reached) {
3804  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted SGPD atom\n");
3805  return AVERROR_EOF;
3806  }
3807 
3808  return 0;
3809 }
3810 
3812 {
3813  AVStream *st;
3814  MOVStreamContext *sc;
3815  unsigned int i, entries;
3816  uint8_t version;
3817  uint32_t grouping_type;
3818  MOVSbgp *table, **tablep;
3819  int *table_count;
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  version = avio_r8(pb); /* version */
3827  avio_rb24(pb); /* flags */
3828  grouping_type = avio_rl32(pb);
3829 
3830  if (grouping_type == MKTAG('r','a','p',' ')) {
3831  tablep = &sc->rap_group;
3832  table_count = &sc->rap_group_count;
3833  } else if (grouping_type == MKTAG('s','y','n','c')) {
3834  tablep = &sc->sync_group;
3835  table_count = &sc->sync_group_count;
3836  } else {
3837  return 0;
3838  }
3839 
3840  if (version == 1)
3841  avio_rb32(pb); /* grouping_type_parameter */
3842 
3843  entries = avio_rb32(pb);
3844  if (!entries)
3845  return 0;
3846  if (*tablep)
3847  av_log(c->fc, AV_LOG_WARNING, "Duplicated SBGP %s atom\n", av_fourcc2str(grouping_type));
3848  av_freep(tablep);
3849  table = av_malloc_array(entries, sizeof(*table));
3850  if (!table)
3851  return AVERROR(ENOMEM);
3852  *tablep = table;
3853 
3854  for (i = 0; i < entries && !pb->eof_reached; i++) {
3855  table[i].count = avio_rb32(pb); /* sample_count */
3856  table[i].index = avio_rb32(pb); /* group_description_index */
3857  }
3858 
3859  *table_count = i;
3860 
3861  if (pb->eof_reached) {
3862  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted SBGP atom\n");
3863  return AVERROR_EOF;
3864  }
3865 
3866  return 0;
3867 }
3868 
3869 /**
3870  * Get ith edit list entry (media time, duration).
3871  */
3873  const MOVStreamContext *msc,
3874  unsigned int edit_list_index,
3875  int64_t *edit_list_media_time,
3876  int64_t *edit_list_duration,
3877  int64_t global_timescale)
3878 {
3879  if (edit_list_index == msc->elst_count) {
3880  return 0;
3881  }
3882  *edit_list_media_time = msc->elst_data[edit_list_index].time;
3883  *edit_list_duration = msc->elst_data[edit_list_index].duration;
3884 
3885  /* duration is in global timescale units;convert to msc timescale */
3886  if (global_timescale == 0) {
3887  avpriv_request_sample(mov->fc, "Support for mvhd.timescale = 0 with editlists");
3888  return 0;
3889  }
3890  *edit_list_duration = av_rescale(*edit_list_duration, msc->time_scale,
3891  global_timescale);
3892 
3893  if (*edit_list_duration + (uint64_t)*edit_list_media_time > INT64_MAX)
3894  *edit_list_duration = 0;
3895 
3896  return 1;
3897 }
3898 
3899 /**
3900  * Find the closest previous frame to the timestamp_pts, in e_old index
3901  * entries. Searching for just any frame / just key frames can be controlled by
3902  * last argument 'flag'.
3903  * Note that if ctts_data is not NULL, we will always search for a key frame
3904  * irrespective of the value of 'flag'. If we don't find any keyframe, we will
3905  * return the first frame of the video.
3906  *
3907  * Here the timestamp_pts is considered to be a presentation timestamp and
3908  * the timestamp of index entries are considered to be decoding timestamps.
3909  *
3910  * Returns 0 if successful in finding a frame, else returns -1.
3911  * Places the found index corresponding output arg.
3912  *
3913  * If ctts_old is not NULL, then refines the searched entry by searching
3914  * backwards from the found timestamp, to find the frame with correct PTS.
3915  *
3916  * Places the found ctts_index and ctts_sample in corresponding output args.
3917  */
3919  AVIndexEntry *e_old,
3920  int nb_old,
3921  MOVTimeToSample *tts_data,
3922  int64_t tts_count,
3923  int64_t timestamp_pts,
3924  int flag,
3925  int64_t* index,
3926  int64_t* tts_index,
3927  int64_t* tts_sample)
3928 {
3929  MOVStreamContext *msc = st->priv_data;
3930  FFStream *const sti = ffstream(st);
3931  AVIndexEntry *e_keep = sti->index_entries;
3932  int nb_keep = sti->nb_index_entries;
3933  int64_t i = 0;
3934 
3935  av_assert0(index);
3936 
3937  // If dts_shift > 0, then all the index timestamps will have to be offset by
3938  // at least dts_shift amount to obtain PTS.
3939  // Hence we decrement the searched timestamp_pts by dts_shift to find the closest index element.
3940  if (msc->dts_shift > 0) {
3941  timestamp_pts -= msc->dts_shift;
3942  }
3943 
3944  sti->index_entries = e_old;
3945  sti->nb_index_entries = nb_old;
3946  *index = av_index_search_timestamp(st, timestamp_pts, flag | AVSEEK_FLAG_BACKWARD);
3947 
3948  // Keep going backwards in the index entries until the timestamp is the same.
3949  if (*index >= 0) {
3950  for (i = *index; i > 0 && e_old[i].timestamp == e_old[i - 1].timestamp;
3951  i--) {
3952  if ((flag & AVSEEK_FLAG_ANY) ||
3953  (e_old[i - 1].flags & AVINDEX_KEYFRAME)) {
3954  *index = i - 1;
3955  }
3956  }
3957  }
3958 
3959  // If we have CTTS then refine the search, by searching backwards over PTS
3960  // computed by adding corresponding CTTS durations to index timestamps.
3961  if (msc->ctts_count && *index >= 0) {
3962  av_assert0(tts_index);
3963  av_assert0(tts_sample);
3964  // Find out the ctts_index for the found frame.
3965  *tts_index = 0;
3966  *tts_sample = 0;
3967  for (int64_t index_tts_count = 0; index_tts_count < *index; index_tts_count++) {
3968  if (*tts_index < tts_count) {
3969  (*tts_sample)++;
3970  if (tts_data[*tts_index].count == *tts_sample) {
3971  (*tts_index)++;
3972  *tts_sample = 0;
3973  }
3974  }
3975  }
3976 
3977  while (*index >= 0 && (*tts_index) >= 0 && (*tts_index) < tts_count) {
3978  // Find a "key frame" with PTS <= timestamp_pts (So that we can decode B-frames correctly).
3979  // No need to add dts_shift to the timestamp here because timestamp_pts has already been
3980  // compensated by dts_shift above.
3981  if ((e_old[*index].timestamp + tts_data[*tts_index].offset) <= timestamp_pts &&
3982  (e_old[*index].flags & AVINDEX_KEYFRAME)) {
3983  break;
3984  }
3985 
3986  (*index)--;
3987  if (*tts_sample == 0) {
3988  (*tts_index)--;
3989  if (*tts_index >= 0)
3990  *tts_sample = tts_data[*tts_index].count - 1;
3991  } else {
3992  (*tts_sample)--;
3993  }
3994  }
3995  }
3996 
3997  /* restore AVStream state*/
3998  sti->index_entries = e_keep;
3999  sti->nb_index_entries = nb_keep;
4000  return *index >= 0 ? 0 : -1;
4001 }
4002 
4003 /**
4004  * Add index entry with the given values, to the end of ffstream(st)->index_entries.
4005  * Returns the new size ffstream(st)->index_entries if successful, else returns -1.
4006  *
4007  * This function is similar to ff_add_index_entry in libavformat/utils.c
4008  * except that here we are always unconditionally adding an index entry to
4009  * the end, instead of searching the entries list and skipping the add if
4010  * there is an existing entry with the same timestamp.
4011  * This is needed because the mov_fix_index calls this func with the same
4012  * unincremented timestamp for successive discarded frames.
4013  */
4015  int size, int distance, int flags)
4016 {
4017  FFStream *const sti = ffstream(st);
4018  AVIndexEntry *entries, *ie;
4019  int64_t index = -1;
4020  const size_t min_size_needed = (sti->nb_index_entries + 1) * sizeof(AVIndexEntry);
4021 
4022  // Double the allocation each time, to lower memory fragmentation.
4023  // Another difference from ff_add_index_entry function.
4024  const size_t requested_size =
4025  min_size_needed > sti->index_entries_allocated_size ?
4026  FFMAX(min_size_needed, 2 * sti->index_entries_allocated_size) :
4027  min_size_needed;
4028 
4029  if (sti->nb_index_entries + 1U >= UINT_MAX / sizeof(AVIndexEntry))
4030  return -1;
4031 
4032  entries = av_fast_realloc(sti->index_entries,
4034  requested_size);
4035  if (!entries)
4036  return -1;
4037 
4038  sti->index_entries = entries;
4039 
4040  index = sti->nb_index_entries++;
4041  ie= &entries[index];
4042 
4043  ie->pos = pos;
4044  ie->timestamp = timestamp;
4045  ie->min_distance= distance;
4046  ie->size= size;
4047  ie->flags = flags;
4048  return index;
4049 }
4050 
4051 /**
4052  * Rewrite timestamps of index entries in the range [end_index - frame_duration_buffer_size, end_index)
4053  * by subtracting end_ts successively by the amounts given in frame_duration_buffer.
4054  */
4055 static void fix_index_entry_timestamps(AVStream* st, int end_index, int64_t end_ts,
4056  int64_t* frame_duration_buffer,
4057  int frame_duration_buffer_size) {
4058  FFStream *const sti = ffstream(st);
4059  int i = 0;
4060  av_assert0(end_index >= 0 && end_index <= sti->nb_index_entries);
4061  for (i = 0; i < frame_duration_buffer_size; i++) {
4062  end_ts -= frame_duration_buffer[frame_duration_buffer_size - 1 - i];
4063  sti->index_entries[end_index - 1 - i].timestamp = end_ts;
4064  }
4065 }
4066 
4067 static int add_tts_entry(MOVTimeToSample **tts_data, unsigned int *tts_count, unsigned int *allocated_size,
4068  int count, int offset, unsigned int duration)
4069 {
4070  MOVTimeToSample *tts_buf_new;
4071  const size_t min_size_needed = (*tts_count + 1) * sizeof(MOVTimeToSample);
4072  const size_t requested_size =
4073  min_size_needed > *allocated_size ?
4074  FFMAX(min_size_needed, 2 * (*allocated_size)) :
4075  min_size_needed;
4076 
4077  if ((unsigned)(*tts_count) >= UINT_MAX / sizeof(MOVTimeToSample) - 1)
4078  return -1;
4079 
4080  tts_buf_new = av_fast_realloc(*tts_data, allocated_size, requested_size);
4081 
4082  if (!tts_buf_new)
4083  return -1;
4084 
4085  *tts_data = tts_buf_new;
4086 
4087  tts_buf_new[*tts_count].count = count;
4088  tts_buf_new[*tts_count].offset = offset;
4089  tts_buf_new[*tts_count].duration = duration;
4090 
4091  *tts_count = (*tts_count) + 1;
4092  return 0;
4093 }
4094 
4095 #define MAX_REORDER_DELAY 16
4097 {
4098  MOVStreamContext *msc = st->priv_data;
4099  FFStream *const sti = ffstream(st);
4100  int ctts_ind = 0;
4101  int ctts_sample = 0;
4102  int64_t pts_buf[MAX_REORDER_DELAY + 1]; // Circular buffer to sort pts.
4103  int buf_start = 0;
4104  int j, r, num_swaps;
4105 
4106  for (j = 0; j < MAX_REORDER_DELAY + 1; j++)
4107  pts_buf[j] = INT64_MIN;
4108 
4109  if (st->codecpar->video_delay <= 0 && msc->ctts_count &&
4111  st->codecpar->video_delay = 0;
4112  for (int ind = 0; ind < sti->nb_index_entries && ctts_ind < msc->tts_count; ++ind) {
4113  // Point j to the last elem of the buffer and insert the current pts there.
4114  j = buf_start;
4115  buf_start = (buf_start + 1);
4116  if (buf_start == MAX_REORDER_DELAY + 1)
4117  buf_start = 0;
4118 
4119  pts_buf[j] = sti->index_entries[ind].timestamp + msc->tts_data[ctts_ind].offset;
4120 
4121  // The timestamps that are already in the sorted buffer, and are greater than the
4122  // current pts, are exactly the timestamps that need to be buffered to output PTS
4123  // in correct sorted order.
4124  // Hence the video delay (which is the buffer size used to sort DTS and output PTS),
4125  // can be computed as the maximum no. of swaps any particular timestamp needs to
4126  // go through, to keep this buffer in sorted order.
4127  num_swaps = 0;
4128  while (j != buf_start) {
4129  r = j - 1;
4130  if (r < 0) r = MAX_REORDER_DELAY;
4131  if (pts_buf[j] < pts_buf[r]) {
4132  FFSWAP(int64_t, pts_buf[j], pts_buf[r]);
4133  ++num_swaps;
4134  } else {
4135  break;
4136  }
4137  j = r;
4138  }
4139  st->codecpar->video_delay = FFMAX(st->codecpar->video_delay, num_swaps);
4140 
4141  ctts_sample++;
4142  if (ctts_sample == msc->tts_data[ctts_ind].count) {
4143  ctts_ind++;
4144  ctts_sample = 0;
4145  }
4146  }
4147  av_log(c->fc, AV_LOG_DEBUG, "Setting codecpar->delay to %d for stream st: %d\n",
4148  st->codecpar->video_delay, st->index);
4149  }
4150 }
4151 
4153 {
4154  sc->current_sample++;
4155  sc->current_index++;
4156  if (sc->index_ranges &&
4157  sc->current_index >= sc->current_index_range->end &&
4158  sc->current_index_range->end) {
4159  sc->current_index_range++;
4161  }
4162 }
4163 
4165 {
4166  sc->current_sample--;
4167  sc->current_index--;
4168  if (sc->index_ranges &&
4170  sc->current_index_range > sc->index_ranges) {
4171  sc->current_index_range--;
4172  sc->current_index = sc->current_index_range->end - 1;
4173  }
4174 }
4175 
4176 static void mov_current_sample_set(MOVStreamContext *sc, int current_sample)
4177 {
4178  int64_t range_size;
4179 
4180  sc->current_sample = current_sample;
4181  sc->current_index = current_sample;
4182  if (!sc->index_ranges) {
4183  return;
4184  }
4185 
4186  for (sc->current_index_range = sc->index_ranges;
4187  sc->current_index_range->end;
4188  sc->current_index_range++) {
4189  range_size = sc->current_index_range->end - sc->current_index_range->start;
4190  if (range_size > current_sample) {
4191  sc->current_index = sc->current_index_range->start + current_sample;
4192  break;
4193  }
4194  current_sample -= range_size;
4195  }
4196 }
4197 
4198 /**
4199  * Fix ffstream(st)->index_entries, so that it contains only the entries (and the entries
4200  * which are needed to decode them) that fall in the edit list time ranges.
4201  * Also fixes the timestamps of the index entries to match the timeline
4202  * specified the edit lists.
4203  */
4204 static void mov_fix_index(MOVContext *mov, AVStream *st)
4205 {
4206  MOVStreamContext *msc = st->priv_data;
4207  FFStream *const sti = ffstream(st);
4208  AVIndexEntry *e_old = sti->index_entries;
4209  int nb_old = sti->nb_index_entries;
4210  const AVIndexEntry *e_old_end = e_old + nb_old;
4211  const AVIndexEntry *current = NULL;
4212  MOVTimeToSample *tts_data_old = msc->tts_data;
4213  int64_t tts_index_old = 0;
4214  int64_t tts_sample_old = 0;
4215  int64_t tts_count_old = msc->tts_count;
4216  int64_t edit_list_media_time = 0;
4217  int64_t edit_list_duration = 0;
4218  int64_t frame_duration = 0;
4219  int64_t edit_list_dts_counter = 0;
4220  int64_t edit_list_dts_entry_end = 0;
4221  int64_t edit_list_start_tts_sample = 0;
4222  int64_t curr_cts;
4223  int64_t curr_ctts = 0;
4224  int64_t empty_edits_sum_duration = 0;
4225  int64_t edit_list_index = 0;
4226  int64_t index;
4227  int flags;
4228  int64_t start_dts = 0;
4229  int64_t edit_list_start_encountered = 0;
4230  int64_t search_timestamp = 0;
4231  int64_t* frame_duration_buffer = NULL;
4232  int num_discarded_begin = 0;
4233  int first_non_zero_audio_edit = -1;
4234  int packet_skip_samples = 0;
4235  MOVIndexRange *current_index_range = NULL;
4236  int found_keyframe_after_edit = 0;
4237  int found_non_empty_edit = 0;
4238 
4239  if (!msc->elst_data || msc->elst_count <= 0 || nb_old <= 0) {
4240  return;
4241  }
4242 
4243  // allocate the index ranges array
4244  msc->index_ranges = av_malloc_array(msc->elst_count + 1,
4245  sizeof(msc->index_ranges[0]));
4246  if (!msc->index_ranges) {
4247  av_log(mov->fc, AV_LOG_ERROR, "Cannot allocate index ranges buffer\n");
4248  return;
4249  }
4250  msc->current_index_range = msc->index_ranges;
4251 
4252  // Clean AVStream from traces of old index
4253  sti->index_entries = NULL;
4255  sti->nb_index_entries = 0;
4256 
4257  // Clean time to sample fields of MOVStreamContext
4258  msc->tts_data = NULL;
4259  msc->tts_count = 0;
4260  msc->tts_index = 0;
4261  msc->tts_sample = 0;
4262  msc->tts_allocated_size = 0;
4263 
4264  // Reinitialize min_corrected_pts so that it can be computed again.
4265  msc->min_corrected_pts = -1;
4266 
4267  // If the dts_shift is positive (in case of negative ctts values in mov),
4268  // then negate the DTS by dts_shift
4269  if (msc->dts_shift > 0) {
4270  edit_list_dts_entry_end -= msc->dts_shift;
4271  av_log(mov->fc, AV_LOG_DEBUG, "Shifting DTS by %d because of negative CTTS.\n", msc->dts_shift);
4272  }
4273 
4274  start_dts = edit_list_dts_entry_end;
4275 
4276  while (get_edit_list_entry(mov, msc, edit_list_index, &edit_list_media_time,
4277  &edit_list_duration, mov->time_scale)) {
4278  av_log(mov->fc, AV_LOG_DEBUG, "Processing st: %d, edit list %"PRId64" - media time: %"PRId64", duration: %"PRId64"\n",
4279  st->index, edit_list_index, edit_list_media_time, edit_list_duration);
4280  edit_list_index++;
4281  edit_list_dts_counter = edit_list_dts_entry_end;
4282  edit_list_dts_entry_end += edit_list_duration;
4283  num_discarded_begin = 0;
4284  if (!found_non_empty_edit && edit_list_media_time == -1) {
4285  empty_edits_sum_duration += edit_list_duration;
4286  continue;
4287  }
4288  found_non_empty_edit = 1;
4289 
4290  // If we encounter a non-negative edit list reset the skip_samples/start_pad fields and set them
4291  // according to the edit list below.
4292  if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
4293  if (first_non_zero_audio_edit < 0) {
4294  first_non_zero_audio_edit = 1;
4295  } else {
4296  first_non_zero_audio_edit = 0;
4297  }
4298 
4299  if (first_non_zero_audio_edit > 0)
4300  sti->skip_samples = msc->start_pad = 0;
4301  }
4302 
4303  // While reordering frame index according to edit list we must handle properly
4304  // the scenario when edit list entry starts from none key frame.
4305  // We find closest previous key frame and preserve it and consequent frames in index.
4306  // All frames which are outside edit list entry time boundaries will be dropped after decoding.
4307  search_timestamp = edit_list_media_time;
4308  if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
4309  // Audio decoders like AAC need need a decoder delay samples previous to the current sample,
4310  // to correctly decode this frame. Hence for audio we seek to a frame 1 sec. before the
4311  // edit_list_media_time to cover the decoder delay.
4312  search_timestamp = FFMAX(search_timestamp - msc->time_scale, e_old[0].timestamp);
4313  }
4314 
4315  if (find_prev_closest_index(st, e_old, nb_old, tts_data_old, tts_count_old, search_timestamp, 0,
4316  &index, &tts_index_old, &tts_sample_old) < 0) {
4317  av_log(mov->fc, AV_LOG_WARNING,
4318  "st: %d edit list: %"PRId64" Missing key frame while searching for timestamp: %"PRId64"\n",
4319  st->index, edit_list_index, search_timestamp);
4320  if (find_prev_closest_index(st, e_old, nb_old, tts_data_old, tts_count_old, search_timestamp, AVSEEK_FLAG_ANY,
4321  &index, &tts_index_old, &tts_sample_old) < 0) {
4322  av_log(mov->fc, AV_LOG_WARNING,
4323  "st: %d edit list %"PRId64" Cannot find an index entry before timestamp: %"PRId64".\n",
4324  st->index, edit_list_index, search_timestamp);
4325  index = 0;
4326  tts_index_old = 0;
4327  tts_sample_old = 0;
4328  }
4329  }
4330  current = e_old + index;
4331  edit_list_start_tts_sample = tts_sample_old;
4332 
4333  // Iterate over index and arrange it according to edit list
4334  edit_list_start_encountered = 0;
4335  found_keyframe_after_edit = 0;
4336  for (; current < e_old_end; current++, index++) {
4337  // check if frame outside edit list mark it for discard
4338  frame_duration = (current + 1 < e_old_end) ?
4339  ((current + 1)->timestamp - current->timestamp) : edit_list_duration;
4340 
4341  flags = current->flags;
4342 
4343  // frames (pts) before or after edit list
4344  curr_cts = current->timestamp + msc->dts_shift;
4345  curr_ctts = 0;
4346 
4347  if (tts_data_old && tts_index_old < tts_count_old) {
4348  curr_ctts = tts_data_old[tts_index_old].offset;
4349  av_log(mov->fc, AV_LOG_TRACE, "stts: %"PRId64" ctts: %"PRId64", tts_index: %"PRId64", tts_count: %"PRId64"\n",
4350  curr_cts, curr_ctts, tts_index_old, tts_count_old);
4351  curr_cts += curr_ctts;
4352  tts_sample_old++;
4353  if (tts_sample_old == tts_data_old[tts_index_old].count) {
4354  if (add_tts_entry(&msc->tts_data, &msc->tts_count,
4355  &msc->tts_allocated_size,
4356  tts_data_old[tts_index_old].count - edit_list_start_tts_sample,
4357  tts_data_old[tts_index_old].offset, tts_data_old[tts_index_old].duration) == -1) {
4358  av_log(mov->fc, AV_LOG_ERROR, "Cannot add Time To Sample entry %"PRId64" - {%"PRId64", %d}\n",
4359  tts_index_old,
4360  tts_data_old[tts_index_old].count - edit_list_start_tts_sample,
4361  tts_data_old[tts_index_old].offset);
4362  break;
4363  }
4364  tts_index_old++;
4365  tts_sample_old = 0;
4366  edit_list_start_tts_sample = 0;
4367  }
4368  }
4369 
4370  if (curr_cts < edit_list_media_time || curr_cts >= (edit_list_duration + edit_list_media_time)) {
4372  curr_cts < edit_list_media_time && curr_cts + frame_duration > edit_list_media_time &&
4373  first_non_zero_audio_edit > 0) {
4374  packet_skip_samples = edit_list_media_time - curr_cts;
4375  sti->skip_samples += packet_skip_samples;
4376 
4377  // Shift the index entry timestamp by packet_skip_samples to be correct.
4378  edit_list_dts_counter -= packet_skip_samples;
4379  if (edit_list_start_encountered == 0) {
4380  edit_list_start_encountered = 1;
4381  // Make timestamps strictly monotonically increasing for audio, by rewriting timestamps for
4382  // discarded packets.
4383  if (frame_duration_buffer) {
4384  fix_index_entry_timestamps(st, sti->nb_index_entries, edit_list_dts_counter,
4385  frame_duration_buffer, num_discarded_begin);
4386  av_freep(&frame_duration_buffer);
4387  }
4388  }
4389 
4390  av_log(mov->fc, AV_LOG_DEBUG, "skip %d audio samples from curr_cts: %"PRId64"\n", packet_skip_samples, curr_cts);
4391  } else {
4393  av_log(mov->fc, AV_LOG_DEBUG, "drop a frame at curr_cts: %"PRId64" @ %"PRId64"\n", curr_cts, index);
4394 
4395  if (edit_list_start_encountered == 0) {
4396  num_discarded_begin++;
4397  frame_duration_buffer = av_realloc(frame_duration_buffer,
4398  num_discarded_begin * sizeof(int64_t));
4399  if (!frame_duration_buffer) {
4400  av_log(mov->fc, AV_LOG_ERROR, "Cannot reallocate frame duration buffer\n");
4401  break;
4402  }
4403  frame_duration_buffer[num_discarded_begin - 1] = frame_duration;
4404 
4405  // Increment skip_samples for the first non-zero audio edit list
4406  if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
4407  first_non_zero_audio_edit > 0 && st->codecpar->codec_id != AV_CODEC_ID_VORBIS) {
4408  sti->skip_samples += frame_duration;
4409  }
4410  }
4411  }
4412  } else {
4413  if (msc->min_corrected_pts < 0) {
4414  msc->min_corrected_pts = edit_list_dts_counter + curr_ctts + msc->dts_shift;
4415  } else {
4416  msc->min_corrected_pts = FFMIN(msc->min_corrected_pts, edit_list_dts_counter + curr_ctts + msc->dts_shift);
4417  }
4418  if (edit_list_start_encountered == 0) {
4419  edit_list_start_encountered = 1;
4420  // Make timestamps strictly monotonically increasing by rewriting timestamps for
4421  // discarded packets.
4422  if (frame_duration_buffer) {
4423  fix_index_entry_timestamps(st, sti->nb_index_entries, edit_list_dts_counter,
4424  frame_duration_buffer, num_discarded_begin);
4425  av_freep(&frame_duration_buffer);
4426  }
4427  }
4428  }
4429 
4430  if (add_index_entry(st, current->pos, edit_list_dts_counter, current->size,
4431  current->min_distance, flags) == -1) {
4432  av_log(mov->fc, AV_LOG_ERROR, "Cannot add index entry\n");
4433  break;
4434  }
4435 
4436  // Update the index ranges array
4437  if (!current_index_range || index != current_index_range->end) {
4438  current_index_range = current_index_range ? current_index_range + 1
4439  : msc->index_ranges;
4440  current_index_range->start = index;
4441  }
4442  current_index_range->end = index + 1;
4443 
4444  // Only start incrementing DTS in frame_duration amounts, when we encounter a frame in edit list.
4445  if (edit_list_start_encountered > 0) {
4446  edit_list_dts_counter = edit_list_dts_counter + frame_duration;
4447  }
4448 
4449  // Break when found first key frame after edit entry completion
4450  if ((curr_cts + frame_duration >= (edit_list_duration + edit_list_media_time)) &&
4452  if (msc->ctts_count) {
4453  // If we have CTTS and this is the first keyframe after edit elist,
4454  // wait for one more, because there might be trailing B-frames after this I-frame
4455  // that do belong to the edit.
4456  if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO && found_keyframe_after_edit == 0) {
4457  found_keyframe_after_edit = 1;
4458  continue;
4459  }
4460  if (tts_sample_old != 0) {
4461  if (add_tts_entry(&msc->tts_data, &msc->tts_count,
4462  &msc->tts_allocated_size,
4463  tts_sample_old - edit_list_start_tts_sample,
4464  tts_data_old[tts_index_old].offset, tts_data_old[tts_index_old].duration) == -1) {
4465  av_log(mov->fc, AV_LOG_ERROR, "Cannot add Time To Sample entry %"PRId64" - {%"PRId64", %d}\n",
4466  tts_index_old, tts_sample_old - edit_list_start_tts_sample,
4467  tts_data_old[tts_index_old].offset);
4468  break;
4469  }
4470  }
4471  }
4472  break;
4473  }
4474  }
4475  }
4476  // If there are empty edits, then msc->min_corrected_pts might be positive
4477  // intentionally. So we subtract the sum duration of empty edits here.
4478  msc->min_corrected_pts -= empty_edits_sum_duration;
4479 
4480  // If the minimum pts turns out to be greater than zero after fixing the index, then we subtract the
4481  // dts by that amount to make the first pts zero.
4482  if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
4483  if (msc->min_corrected_pts > 0) {
4484  av_log(mov->fc, AV_LOG_DEBUG, "Offset DTS by %"PRId64" to make first pts zero.\n", msc->min_corrected_pts);
4485  for (int i = 0; i < sti->nb_index_entries; ++i)
4487  }
4488  }
4489  // Start time should be equal to zero or the duration of any empty edits.
4490  st->start_time = empty_edits_sum_duration;
4491 
4492  // Update av stream length, if it ends up shorter than the track's media duration
4493  st->duration = FFMIN(st->duration, edit_list_dts_entry_end - start_dts);
4494  msc->start_pad = sti->skip_samples;
4495 
4496  // Free the old index and the old CTTS structures
4497  av_free(e_old);
4498  av_free(tts_data_old);
4499  av_freep(&frame_duration_buffer);
4500 
4501  // Null terminate the index ranges array
4502  current_index_range = current_index_range ? current_index_range + 1
4503  : msc->index_ranges;
4504  current_index_range->start = 0;
4505  current_index_range->end = 0;
4506  msc->current_index = msc->index_ranges[0].start;
4507 }
4508 
4509 static uint32_t get_sgpd_sync_index(const MOVStreamContext *sc, int nal_unit_type)
4510 {
4511  for (uint32_t i = 0; i < sc->sgpd_sync_count; i++)
4512  if (sc->sgpd_sync[i] == nal_unit_type)
4513  return i + 1;
4514  return 0;
4515 }
4516 
4518 {
4519  int k;
4520  int sample_id = 0;
4521  uint32_t cra_index;
4522  MOVStreamContext *sc = st->priv_data;
4523 
4524  if (st->codecpar->codec_id != AV_CODEC_ID_HEVC || !sc->sync_group_count)
4525  return 0;
4526 
4527  /* Build an unrolled index of the samples */
4528  sc->sample_offsets_count = 0;
4529  for (uint32_t i = 0; i < sc->ctts_count; i++) {
4530  if (sc->ctts_data[i].count > INT_MAX - sc->sample_offsets_count)
4531  return AVERROR(ENOMEM);
4532  sc->sample_offsets_count += sc->ctts_data[i].count;
4533  }
4534  av_freep(&sc->sample_offsets);
4536  if (!sc->sample_offsets)
4537  return AVERROR(ENOMEM);
4538  k = 0;
4539  for (uint32_t i = 0; i < sc->ctts_count; i++)
4540  for (int j = 0; j < sc->ctts_data[i].count; j++)
4541  sc->sample_offsets[k++] = sc->ctts_data[i].offset;
4542 
4543  /* The following HEVC NAL type reveal the use of open GOP sync points
4544  * (TODO: BLA types may also be concerned) */
4545  cra_index = get_sgpd_sync_index(sc, HEVC_NAL_CRA_NUT); /* Clean Random Access */
4546  if (!cra_index)
4547  return 0;
4548 
4549  /* Build a list of open-GOP key samples */
4550  sc->open_key_samples_count = 0;
4551  for (uint32_t i = 0; i < sc->sync_group_count; i++)
4552  if (sc->sync_group[i].index == cra_index) {
4553  if (sc->sync_group[i].count > INT_MAX - sc->open_key_samples_count)
4554  return AVERROR(ENOMEM);
4556  }
4557  av_freep(&sc->open_key_samples);
4559  if (!sc->open_key_samples)
4560  return AVERROR(ENOMEM);
4561  k = 0;
4562  for (uint32_t i = 0; i < sc->sync_group_count; i++) {
4563  const MOVSbgp *sg = &sc->sync_group[i];
4564  if (sg->index == cra_index)
4565  for (uint32_t j = 0; j < sg->count; j++)
4566  sc->open_key_samples[k++] = sample_id;
4567  if (sg->count > INT_MAX - sample_id)
4568  return AVERROR_PATCHWELCOME;
4569  sample_id += sg->count;
4570  }
4571 
4572  /* Identify the minimal time step between samples */
4573  sc->min_sample_duration = UINT_MAX;
4574  for (uint32_t i = 0; i < sc->stts_count; i++)
4576 
4577  return 0;
4578 }
4579 
4580 #define MOV_MERGE_CTTS 1
4581 #define MOV_MERGE_STTS 2
4582 /*
4583  * Merge stts and ctts arrays into a new combined array.
4584  * stts_count and ctts_count may be left untouched as they will be
4585  * used to check for the presence of either of them.
4586  */
4587 static int mov_merge_tts_data(MOVContext *mov, AVStream *st, int flags)
4588 {
4589  MOVStreamContext *sc = st->priv_data;
4590  int ctts = sc->ctts_data && (flags & MOV_MERGE_CTTS);
4591  int stts = sc->stts_data && (flags & MOV_MERGE_STTS);
4592  int idx = 0;
4593 
4594  if (!sc->ctts_data && !sc->stts_data)
4595  return 0;
4596  // Expand time to sample entries such that we have a 1-1 mapping with samples
4597  if (!sc->sample_count || sc->sample_count >= UINT_MAX / sizeof(*sc->tts_data))
4598  return -1;
4599 
4600  if (ctts) {
4602  sc->sample_count * sizeof(*sc->tts_data));
4603  if (!sc->tts_data)
4604  return -1;
4605 
4606  memset(sc->tts_data, 0, sc->tts_allocated_size);
4607 
4608  for (int i = 0; i < sc->ctts_count &&
4609  idx < sc->sample_count; i++)
4610  for (int j = 0; j < sc->ctts_data[i].count &&
4611  idx < sc->sample_count; j++) {
4612  sc->tts_data[idx].offset = sc->ctts_data[i].offset;
4613  sc->tts_data[idx++].count = 1;
4614  }
4615 
4616  sc->tts_count = idx;
4617  } else
4618  sc->ctts_count = 0;
4619  av_freep(&sc->ctts_data);
4620  sc->ctts_allocated_size = 0;
4621 
4622  idx = 0;
4623  if (stts) {
4625  sc->sample_count * sizeof(*sc->tts_data));
4626  if (!tts_data)
4627  return -1;
4628 
4629  if (!sc->tts_data)
4630  memset(tts_data, 0, sc->tts_allocated_size);
4631  sc->tts_data = tts_data;
4632 
4633  for (int i = 0; i < sc->stts_count &&
4634  idx < sc->sample_count; i++)
4635  for (int j = 0; j < sc->stts_data[i].count &&
4636  idx < sc->sample_count; j++) {
4637  sc->tts_data[idx].duration = sc->stts_data[i].duration;
4638  sc->tts_data[idx++].count = 1;
4639  }
4640 
4641  sc->tts_count = FFMAX(sc->tts_count, idx);
4642  } else
4643  sc->stts_count = 0;
4644  av_freep(&sc->stts_data);
4645  sc->stts_allocated_size = 0;
4646 
4647  return 0;
4648 }
4649 
4650 static void mov_build_index(MOVContext *mov, AVStream *st)
4651 {
4652  MOVStreamContext *sc = st->priv_data;
4653  FFStream *const sti = ffstream(st);
4654  int64_t current_offset;
4655  int64_t current_dts = 0;
4656  unsigned int stts_index = 0;
4657  unsigned int stsc_index = 0;
4658  unsigned int stss_index = 0;
4659  unsigned int stps_index = 0;
4660  unsigned int i, j;
4661  uint64_t stream_size = 0;
4662 
4663  int ret = build_open_gop_key_points(st);
4664  if (ret < 0)
4665  return;
4666 
4667  if (sc->elst_count) {
4668  int i, edit_start_index = 0, multiple_edits = 0;
4669  int64_t empty_duration = 0; // empty duration of the first edit list entry
4670  int64_t start_time = 0; // start time of the media
4671 
4672  for (i = 0; i < sc->elst_count; i++) {
4673  const MOVElst *e = &sc->elst_data[i];
4674  if (i == 0 && e->time == -1) {
4675  /* if empty, the first entry is the start time of the stream
4676  * relative to the presentation itself */
4677  empty_duration = e->duration;
4678  edit_start_index = 1;
4679  } else if (i == edit_start_index && e->time >= 0) {
4680  start_time = e->time;
4681  } else {
4682  multiple_edits = 1;
4683  }
4684  }
4685 
4686  if (multiple_edits && !mov->advanced_editlist) {
4688  av_log(mov->fc, AV_LOG_WARNING, "multiple edit list entries, "
4689  "not supported in fragmented MP4 files\n");
4690  else
4691  av_log(mov->fc, AV_LOG_WARNING, "multiple edit list entries, "
4692  "Use -advanced_editlist to correctly decode otherwise "
4693  "a/v desync might occur\n");
4694  }
4695 
4696  /* adjust first dts according to edit list */
4697  if ((empty_duration || start_time) && mov->time_scale > 0) {
4698  if (empty_duration)
4699  empty_duration = av_rescale(empty_duration, sc->time_scale, mov->time_scale);
4700 
4701  if (av_sat_sub64(start_time, empty_duration) != start_time - (uint64_t)empty_duration)
4702  av_log(mov->fc, AV_LOG_WARNING, "start_time - empty_duration is not representable\n");
4703 
4704  sc->time_offset = start_time - (uint64_t)empty_duration;
4706  if (!mov->advanced_editlist)
4707  current_dts = -sc->time_offset;
4708  }
4709 
4710  if (!multiple_edits && !mov->advanced_editlist &&
4712  sc->start_pad = start_time;
4713  }
4714 
4715  /* only use old uncompressed audio chunk demuxing when stts specifies it */
4716  if (!(st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
4717  sc->stts_count == 1 && sc->stts_data && sc->stts_data[0].duration == 1)) {
4718  unsigned int current_sample = 0;
4719  unsigned int stts_sample = 0;
4720  unsigned int sample_size;
4721  unsigned int distance = 0;
4722  unsigned int rap_group_index = 0;
4723  unsigned int rap_group_sample = 0;
4724  int rap_group_present = sc->rap_group_count && sc->rap_group;
4725  int key_off = (sc->keyframe_count && sc->keyframes[0] > 0) || (sc->stps_count && sc->stps_data[0] > 0);
4726 
4727  current_dts -= sc->dts_shift;
4728 
4729  if (!sc->sample_count || sti->nb_index_entries || sc->tts_count)
4730  return;
4731  if (sc->sample_count >= UINT_MAX / sizeof(*sti->index_entries) - sti->nb_index_entries)
4732  return;
4733  if (av_reallocp_array(&sti->index_entries,
4734  sti->nb_index_entries + sc->sample_count,
4735  sizeof(*sti->index_entries)) < 0) {
4736  sti->nb_index_entries = 0;
4737  return;
4738  }
4739  sti->index_entries_allocated_size = (sti->nb_index_entries + sc->sample_count) * sizeof(*sti->index_entries);
4740 
4742  if (ret < 0)
4743  return;
4744 
4745  for (i = 0; i < sc->chunk_count; i++) {
4746  int64_t next_offset = i+1 < sc->chunk_count ? sc->chunk_offsets[i+1] : INT64_MAX;
4747  current_offset = sc->chunk_offsets[i];
4748  while (mov_stsc_index_valid(stsc_index, sc->stsc_count) &&
4749  i + 1 == sc->stsc_data[stsc_index + 1].first)
4750  stsc_index++;
4751 
4752  if (next_offset > current_offset && sc->sample_size>0 && sc->sample_size < sc->stsz_sample_size &&
4753  sc->stsc_data[stsc_index].count * (int64_t)sc->stsz_sample_size > next_offset - current_offset) {
4754  av_log(mov->fc, AV_LOG_WARNING, "STSZ sample size %d invalid (too large), ignoring\n", sc->stsz_sample_size);
4755  sc->stsz_sample_size = sc->sample_size;
4756  }
4757  if (sc->stsz_sample_size>0 && sc->stsz_sample_size < sc->sample_size) {
4758  av_log(mov->fc, AV_LOG_WARNING, "STSZ sample size %d invalid (too small), ignoring\n", sc->stsz_sample_size);
4759  sc->stsz_sample_size = sc->sample_size;
4760  }
4761 
4762  for (j = 0; j < sc->stsc_data[stsc_index].count; j++) {
4763  int keyframe = 0;
4764  if (current_sample >= sc->sample_count) {
4765  av_log(mov->fc, AV_LOG_ERROR, "wrong sample count\n");
4766  return;
4767  }
4768 
4769  if (!sc->keyframe_absent && (!sc->keyframe_count || current_sample+key_off == sc->keyframes[stss_index])) {
4770  keyframe = 1;
4771  if (stss_index + 1 < sc->keyframe_count)
4772  stss_index++;
4773  } else if (sc->stps_count && current_sample+key_off == sc->stps_data[stps_index]) {
4774  keyframe = 1;
4775  if (stps_index + 1 < sc->stps_count)
4776  stps_index++;
4777  }
4778  if (rap_group_present && rap_group_index < sc->rap_group_count) {
4779  if (sc->rap_group[rap_group_index].index > 0)
4780  keyframe = 1;
4781  if (++rap_group_sample == sc->rap_group[rap_group_index].count) {
4782  rap_group_sample = 0;
4783  rap_group_index++;
4784  }
4785  }
4786  if (sc->keyframe_absent
4787  && !sc->stps_count
4788  && !rap_group_present
4789  && (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO || (i==0 && j==0)))
4790  keyframe = 1;
4791  if (keyframe)
4792  distance = 0;
4793  sample_size = sc->stsz_sample_size > 0 ? sc->stsz_sample_size : sc->sample_sizes[current_sample];
4794  if (current_offset > INT64_MAX - sample_size) {
4795  av_log(mov->fc, AV_LOG_ERROR, "Current offset %"PRId64" or sample size %u is too large\n",
4796  current_offset,
4797  sample_size);
4798  return;
4799  }
4800 
4801  if (sc->pseudo_stream_id == -1 ||
4802  sc->stsc_data[stsc_index].id - 1 == sc->pseudo_stream_id) {
4803  AVIndexEntry *e;
4804  if (sample_size > 0x3FFFFFFF) {
4805  av_log(mov->fc, AV_LOG_ERROR, "Sample size %u is too large\n", sample_size);
4806  return;
4807  }
4808  e = &sti->index_entries[sti->nb_index_entries++];
4809  e->pos = current_offset;
4810  e->timestamp = current_dts;
4811  e->size = sample_size;
4812  e->min_distance = distance;
4813  e->flags = keyframe ? AVINDEX_KEYFRAME : 0;
4814  av_log(mov->fc, AV_LOG_TRACE, "AVIndex stream %d, sample %u, offset %"PRIx64", dts %"PRId64", "
4815  "size %u, distance %u, keyframe %d\n", st->index, current_sample,
4816  current_offset, current_dts, sample_size, distance, keyframe);
4817  if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && sti->nb_index_entries < 100)
4818  ff_rfps_add_frame(mov->fc, st, current_dts);
4819  }
4820 
4821  current_offset += sample_size;
4822  stream_size += sample_size;
4823 
4824  current_dts += sc->tts_data[stts_index].duration;
4825 
4826  distance++;
4827  stts_sample++;
4828  current_sample++;
4829  if (stts_index + 1 < sc->tts_count && stts_sample == sc->tts_data[stts_index].count) {
4830  stts_sample = 0;
4831  stts_index++;
4832  }
4833  }
4834  }
4835  if (st->duration > 0)
4836  st->codecpar->bit_rate = stream_size*8*sc->time_scale/st->duration;
4837  } else {
4838  unsigned chunk_samples, total = 0;
4839 
4840  if (!sc->chunk_count || sc->tts_count)
4841  return;
4842 
4844  if (ret < 0)
4845  return;
4846 
4847  // compute total chunk count
4848  for (i = 0; i < sc->stsc_count; i++) {
4849  unsigned count, chunk_count;
4850 
4851  chunk_samples = sc->stsc_data[i].count;
4852  if (i != sc->stsc_count - 1 &&
4853  sc->samples_per_frame && chunk_samples % sc->samples_per_frame) {
4854  av_log(mov->fc, AV_LOG_ERROR, "error unaligned chunk\n");
4855  return;
4856  }
4857 
4858  if (sc->samples_per_frame >= 160) { // gsm
4859  count = chunk_samples / sc->samples_per_frame;
4860  } else if (sc->samples_per_frame > 1) {
4861  unsigned samples = (1024/sc->samples_per_frame)*sc->samples_per_frame;
4862  count = (chunk_samples+samples-1) / samples;
4863  } else {
4864  count = (chunk_samples+1023) / 1024;
4865  }
4866 
4867  if (mov_stsc_index_valid(i, sc->stsc_count))
4868  chunk_count = sc->stsc_data[i+1].first - sc->stsc_data[i].first;
4869  else
4870  chunk_count = sc->chunk_count - (sc->stsc_data[i].first - 1);
4871  total += chunk_count * count;
4872  }
4873 
4874  av_log(mov->fc, AV_LOG_TRACE, "chunk count %u\n", total);
4875  if (total >= UINT_MAX / sizeof(*sti->index_entries) - sti->nb_index_entries)
4876  return;
4877  if (av_reallocp_array(&sti->index_entries,
4878  sti->nb_index_entries + total,
4879  sizeof(*sti->index_entries)) < 0) {
4880  sti->nb_index_entries = 0;
4881  return;
4882  }
4883  sti->index_entries_allocated_size = (sti->nb_index_entries + total) * sizeof(*sti->index_entries);
4884 
4885  // populate index
4886  for (i = 0; i < sc->chunk_count; i++) {
4887  current_offset = sc->chunk_offsets[i];
4888  if (mov_stsc_index_valid(stsc_index, sc->stsc_count) &&
4889  i + 1 == sc->stsc_data[stsc_index + 1].first)
4890  stsc_index++;
4891  chunk_samples = sc->stsc_data[stsc_index].count;
4892 
4893  while (chunk_samples > 0) {
4894  AVIndexEntry *e;
4895  unsigned size, samples;
4896 
4897  if (sc->samples_per_frame > 1 && !sc->bytes_per_frame) {
4899  "Zero bytes per frame, but %d samples per frame",
4900  sc->samples_per_frame);
4901  return;
4902  }
4903 
4904  if (sc->samples_per_frame >= 160) { // gsm
4905  samples = sc->samples_per_frame;
4906  size = sc->bytes_per_frame;
4907  } else {
4908  if (sc->samples_per_frame > 1) {
4909  samples = FFMIN((1024 / sc->samples_per_frame)*
4910  sc->samples_per_frame, chunk_samples);
4912  } else {
4913  samples = FFMIN(1024, chunk_samples);
4914  size = samples * sc->sample_size;
4915  }
4916  }
4917 
4918  if (sti->nb_index_entries >= total) {
4919  av_log(mov->fc, AV_LOG_ERROR, "wrong chunk count %u\n", total);
4920  return;
4921  }
4922  if (size > 0x3FFFFFFF) {
4923  av_log(mov->fc, AV_LOG_ERROR, "Sample size %u is too large\n", size);
4924  return;
4925  }
4926  e = &sti->index_entries[sti->nb_index_entries++];
4927  e->pos = current_offset;
4928  e->timestamp = current_dts;
4929  e->size = size;
4930  e->min_distance = 0;
4931  e->flags = AVINDEX_KEYFRAME;
4932  av_log(mov->fc, AV_LOG_TRACE, "AVIndex stream %d, chunk %u, offset %"PRIx64", dts %"PRId64", "
4933  "size %u, duration %u\n", st->index, i, current_offset, current_dts,
4934  size, samples);
4935 
4936  current_offset += size;
4937  current_dts += samples;
4938  chunk_samples -= samples;
4939  }
4940  }
4941  }
4942 
4943  if (!mov->ignore_editlist && mov->advanced_editlist) {
4944  // Fix index according to edit lists.
4945  mov_fix_index(mov, st);
4946  }
4947 
4948  // Update start time of the stream.
4950  st->start_time = sti->index_entries[0].timestamp + sc->dts_shift;
4951  if (sc->tts_data) {
4952  st->start_time += sc->tts_data[0].offset;
4953  }
4954  }
4955 
4956  mov_estimate_video_delay(mov, st);
4957 }
4958 
4959 static int test_same_origin(const char *src, const char *ref) {
4960  char src_proto[64];
4961  char ref_proto[64];
4962  char src_auth[256];
4963  char ref_auth[256];
4964  char src_host[256];
4965  char ref_host[256];
4966  int src_port=-1;
4967  int ref_port=-1;
4968 
4969  av_url_split(src_proto, sizeof(src_proto), src_auth, sizeof(src_auth), src_host, sizeof(src_host), &src_port, NULL, 0, src);
4970  av_url_split(ref_proto, sizeof(ref_proto), ref_auth, sizeof(ref_auth), ref_host, sizeof(ref_host), &ref_port, NULL, 0, ref);
4971 
4972  if (strlen(src) == 0) {
4973  return -1;
4974  } else if (strlen(src_auth) + 1 >= sizeof(src_auth) ||
4975  strlen(ref_auth) + 1 >= sizeof(ref_auth) ||
4976  strlen(src_host) + 1 >= sizeof(src_host) ||
4977  strlen(ref_host) + 1 >= sizeof(ref_host)) {
4978  return 0;
4979  } else if (strcmp(src_proto, ref_proto) ||
4980  strcmp(src_auth, ref_auth) ||
4981  strcmp(src_host, ref_host) ||
4982  src_port != ref_port) {
4983  return 0;
4984  } else
4985  return 1;
4986 }
4987 
4988 static int mov_open_dref(MOVContext *c, AVIOContext **pb, const char *src, MOVDref *ref)
4989 {
4990  /* try relative path, we do not try the absolute because it can leak information about our
4991  system to an attacker */
4992  if (ref->nlvl_to > 0 && ref->nlvl_from > 0) {
4993  char filename[1025];
4994  const char *src_path;
4995  int i, l;
4996 
4997  /* find a source dir */
4998  src_path = strrchr(src, '/');
4999  if (src_path)
5000  src_path++;
5001  else
5002  src_path = src;
5003 
5004  /* find a next level down to target */
5005  for (i = 0, l = strlen(ref->path) - 1; l >= 0; l--)
5006  if (ref->path[l] == '/') {
5007  if (i == ref->nlvl_to - 1)
5008  break;
5009  else
5010  i++;
5011  }
5012 
5013  /* compose filename if next level down to target was found */
5014  if (i == ref->nlvl_to - 1 && src_path - src < sizeof(filename)) {
5015  memcpy(filename, src, src_path - src);
5016  filename[src_path - src] = 0;
5017 
5018  for (i = 1; i < ref->nlvl_from; i++)
5019  av_strlcat(filename, "../", sizeof(filename));
5020 
5021  av_strlcat(filename, ref->path + l + 1, sizeof(filename));
5022  if (!c->use_absolute_path) {
5023  int same_origin = test_same_origin(src, filename);
5024 
5025  if (!same_origin) {
5026  av_log(c->fc, AV_LOG_ERROR,
5027  "Reference with mismatching origin, %s not tried for security reasons, "
5028  "set demuxer option use_absolute_path to allow it anyway\n",
5029  ref->path);
5030  return AVERROR(ENOENT);
5031  }
5032 
5033  if (strstr(ref->path + l + 1, "..") ||
5034  strstr(ref->path + l + 1, ":") ||
5035  (ref->nlvl_from > 1 && same_origin < 0) ||
5036  (filename[0] == '/' && src_path == src))
5037  return AVERROR(ENOENT);
5038  }
5039 
5040  if (strlen(filename) + 1 == sizeof(filename))
5041  return AVERROR(ENOENT);
5042  if (!c->fc->io_open(c->fc, pb, filename, AVIO_FLAG_READ, NULL))
5043  return 0;
5044  }
5045  } else if (c->use_absolute_path) {
5046  av_log(c->fc, AV_LOG_WARNING, "Using absolute path on user request, "
5047  "this is a possible security issue\n");
5048  if (!c->fc->io_open(c->fc, pb, ref->path, AVIO_FLAG_READ, NULL))
5049  return 0;
5050  } else {
5051  av_log(c->fc, AV_LOG_ERROR,
5052  "Absolute path %s not tried for security reasons, "
5053  "set demuxer option use_absolute_path to allow absolute paths\n",
5054  ref->path);
5055  }
5056 
5057  return AVERROR(ENOENT);
5058 }
5059 
5061 {
5062  if (sc->time_scale <= 0) {
5063  av_log(c->fc, AV_LOG_WARNING, "stream %d, timescale not set\n", sc->ffindex);
5064  sc->time_scale = c->time_scale;
5065  if (sc->time_scale <= 0)
5066  sc->time_scale = 1;
5067  }
5068 }
5069 
5070 #if CONFIG_IAMFDEC
5071 static int mov_update_iamf_streams(MOVContext *c, const AVStream *st)
5072 {
5073  const MOVStreamContext *sc = st->priv_data;
5074  const IAMFContext *iamf = &sc->iamf->iamf;
5075 
5076  for (int i = 0; i < iamf->nb_audio_elements; i++) {
5077  const AVStreamGroup *stg = NULL;
5078 
5079  for (int j = 0; j < c->fc->nb_stream_groups; j++)
5080  if (c->fc->stream_groups[j]->id == iamf->audio_elements[i]->audio_element_id)
5081  stg = c->fc->stream_groups[j];
5082  av_assert0(stg);
5083 
5084  for (int j = 0; j < stg->nb_streams; j++) {
5085  const FFStream *sti = cffstream(st);
5086  AVStream *out = stg->streams[j];
5087  FFStream *out_sti = ffstream(stg->streams[j]);
5088 
5089  out->codecpar->bit_rate = 0;
5090 
5091  if (out == st)
5092  continue;
5093 
5094  out->time_base = st->time_base;
5095  out->start_time = st->start_time;
5096  out->duration = st->duration;
5097  out->nb_frames = st->nb_frames;
5098  out->discard = st->discard;
5099 
5100  av_assert0(!out_sti->index_entries);
5102  if (!out_sti->index_entries)
5103  return AVERROR(ENOMEM);
5104 
5106  out_sti->nb_index_entries = sti->nb_index_entries;
5107  out_sti->skip_samples = sti->skip_samples;
5108  memcpy(out_sti->index_entries, sti->index_entries, sti->index_entries_allocated_size);
5109  }
5110  }
5111 
5112  return 0;
5113 }
5114 #endif
5115 
5116 static int sanity_checks(void *log_obj, MOVStreamContext *sc, int index)
5117 {
5118  if ((sc->chunk_count && (!sc->stts_count || !sc->stsc_count ||
5119  (!sc->sample_size && !sc->sample_count))) ||
5120  (!sc->chunk_count && sc->sample_count)) {
5121  av_log(log_obj, AV_LOG_ERROR, "stream %d, missing mandatory atoms, broken header\n",
5122  index);
5123  return 1;
5124  }
5125 
5126  if (sc->stsc_count && sc->stsc_data[ sc->stsc_count - 1 ].first > sc->chunk_count) {
5127  av_log(log_obj, AV_LOG_ERROR, "stream %d, contradictionary STSC and STCO\n",
5128  index);
5129  return 2;
5130  }
5131  return 0;
5132 }
5133 
5135 {
5136  AVStream *st;
5137  MOVStreamContext *sc;
5138  int ret;
5139 
5140  st = avformat_new_stream(c->fc, NULL);
5141  if (!st) return AVERROR(ENOMEM);
5142  st->id = -1;
5143  sc = av_mallocz(sizeof(MOVStreamContext));
5144  if (!sc) return AVERROR(ENOMEM);
5145 
5146  st->priv_data = sc;
5148  sc->ffindex = st->index;
5149  c->trak_index = st->index;
5150  sc->tref_flags = 0;
5151  sc->tref_id = -1;
5152  sc->refcount = 1;
5153 
5154  if ((ret = mov_read_default(c, pb, atom)) < 0)
5155  return ret;
5156 
5157  c->trak_index = -1;
5158 
5159  // Here stsc refers to a chunk not described in stco. This is technically invalid,
5160  // but we can overlook it (clearing stsc) whenever stts_count == 0 (indicating no samples).
5161  if (!sc->chunk_count && !sc->stts_count && sc->stsc_count) {
5162  sc->stsc_count = 0;
5163  av_freep(&sc->stsc_data);
5164  }
5165 
5166  ret = sanity_checks(c->fc, sc, st->index);
5167  if (ret)
5168  return ret > 1 ? AVERROR_INVALIDDATA : 0;
5169 
5170  fix_timescale(c, sc);
5171 
5172  avpriv_set_pts_info(st, 64, 1, sc->time_scale);
5173 
5174  /*
5175  * Advanced edit list support does not work with fragemented MP4s, which
5176  * have stsc, stsz, stco, and stts with zero entries in the moov atom.
5177  * In these files, trun atoms may be streamed in.
5178  */
5179  if (!sc->stts_count && c->advanced_editlist) {
5180 
5181  av_log(c->fc, AV_LOG_VERBOSE, "advanced_editlist does not work with fragmented "
5182  "MP4. disabling.\n");
5183  c->advanced_editlist = 0;
5184  c->advanced_editlist_autodisabled = 1;
5185  }
5186 
5187  mov_build_index(c, st);
5188 
5189 #if CONFIG_IAMFDEC
5190  if (sc->iamf) {
5191  ret = mov_update_iamf_streams(c, st);
5192  if (ret < 0)
5193  return ret;
5194  }
5195 #endif
5196 
5197  if (sc->dref_id-1 < sc->drefs_count && sc->drefs[sc->dref_id-1].path) {
5198  MOVDref *dref = &sc->drefs[sc->dref_id - 1];
5199  if (c->enable_drefs) {
5200  if (mov_open_dref(c, &sc->pb, c->fc->url, dref) < 0)
5201  av_log(c->fc, AV_LOG_ERROR,
5202  "stream %d, error opening alias: path='%s', dir='%s', "
5203  "filename='%s', volume='%s', nlvl_from=%d, nlvl_to=%d\n",
5204  st->index, dref->path, dref->dir, dref->filename,
5205  dref->volume, dref->nlvl_from, dref->nlvl_to);
5206  } else {
5207  av_log(c->fc, AV_LOG_WARNING,
5208  "Skipped opening external track: "
5209  "stream %d, alias: path='%s', dir='%s', "
5210  "filename='%s', volume='%s', nlvl_from=%d, nlvl_to=%d."
5211  "Set enable_drefs to allow this.\n",
5212  st->index, dref->path, dref->dir, dref->filename,
5213  dref->volume, dref->nlvl_from, dref->nlvl_to);
5214  }
5215  } else {
5216  sc->pb = c->fc->pb;
5217  sc->pb_is_copied = 1;
5218  }
5219 
5220  if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
5221  int stts_constant = sc->stts_count && sc->tts_count;
5222  if (sc->h_spacing && sc->v_spacing)
5224  sc->h_spacing, sc->v_spacing, INT_MAX);
5225  if (!st->sample_aspect_ratio.num && st->codecpar->width && st->codecpar->height &&
5226  sc->height && sc->width &&
5227  (st->codecpar->width != sc->width || st->codecpar->height != sc->height)) {
5229  (int64_t)st->codecpar->height * sc->width,
5230  (int64_t)st->codecpar->width * sc->height, INT_MAX);
5231  }
5232 
5233 #if FF_API_R_FRAME_RATE
5234  for (unsigned int i = 1; sc->stts_count && i + 1 < sc->tts_count; i++) {
5235  if (sc->tts_data[i].duration == sc->tts_data[0].duration)
5236  continue;
5237  stts_constant = 0;
5238  }
5239  if (stts_constant)
5241  sc->time_scale, sc->tts_data[0].duration, INT_MAX);
5242 #endif
5243  }
5244 
5245  switch (st->codecpar->codec_id) {
5246  case AV_CODEC_ID_H261:
5247  case AV_CODEC_ID_H263:
5248  case AV_CODEC_ID_MPEG4:
5249  st->codecpar->width = 0; /* let decoder init width/height */
5250  st->codecpar->height= 0;
5251  break;
5252  default:
5253  break;
5254  }
5255 
5256  // If the duration of the mp3 packets is not constant, then they could need a parser
5257  if (st->codecpar->codec_id == AV_CODEC_ID_MP3
5258  && sc->time_scale == st->codecpar->sample_rate) {
5259  int stts_constant = 1;
5260  for (int i = 1; sc->stts_count && i < sc->tts_count; i++) {
5261  if (sc->tts_data[i].duration == sc->tts_data[0].duration)
5262  continue;
5263  stts_constant = 0;
5264  }
5265  if (!stts_constant)
5267  }
5268  /* Do not need those anymore. */
5269  av_freep(&sc->chunk_offsets);
5270  av_freep(&sc->sample_sizes);
5271  av_freep(&sc->keyframes);
5272  av_freep(&sc->stps_data);
5273  av_freep(&sc->elst_data);
5274  av_freep(&sc->rap_group);
5275  av_freep(&sc->sync_group);
5276  av_freep(&sc->sgpd_sync);
5277 
5278  return 0;
5279 }
5280 
5282 {
5283  int ret;
5284  c->itunes_metadata = 1;
5285  ret = mov_read_default(c, pb, atom);
5286  c->itunes_metadata = 0;
5287  return ret;
5288 }
5289 
5291 {
5292  uint32_t count;
5293  uint32_t i;
5294 
5295  if (atom.size < 8)
5296  return 0;
5297 
5298  avio_skip(pb, 4);
5299  count = avio_rb32(pb);
5300  atom.size -= 8;
5301  if (count >= UINT_MAX / sizeof(*c->meta_keys)) {
5302  av_log(c->fc, AV_LOG_ERROR,
5303  "The 'keys' atom with the invalid key count: %"PRIu32"\n", count);
5304  return AVERROR_INVALIDDATA;
5305  }
5306 
5307  c->meta_keys_count = count + 1;
5308  c->meta_keys = av_mallocz(c->meta_keys_count * sizeof(*c->meta_keys));
5309  if (!c->meta_keys)
5310  return AVERROR(ENOMEM);
5311 
5312  for (i = 1; i <= count; ++i) {
5313  uint32_t key_size = avio_rb32(pb);
5314  uint32_t type = avio_rl32(pb);
5315  if (key_size < 8 || key_size > atom.size) {
5316  av_log(c->fc, AV_LOG_ERROR,
5317  "The key# %"PRIu32" in meta has invalid size:"
5318  "%"PRIu32"\n", i, key_size);
5319  return AVERROR_INVALIDDATA;
5320  }
5321  atom.size -= key_size;
5322  key_size -= 8;
5323  if (type != MKTAG('m','d','t','a')) {
5324  avio_skip(pb, key_size);
5325  continue;
5326  }
5327  c->meta_keys[i] = av_mallocz(key_size + 1);
5328  if (!c->meta_keys[i])
5329  return AVERROR(ENOMEM);
5330  avio_read(pb, c->meta_keys[i], key_size);
5331  }
5332 
5333  return 0;
5334 }
5335 
5337 {
5338  int64_t end = av_sat_add64(avio_tell(pb), atom.size);
5339  uint8_t *key = NULL, *val = NULL, *mean = NULL;
5340  int i;
5341  int ret = 0;
5342  AVStream *st;
5343  MOVStreamContext *sc;
5344 
5345  if (c->fc->nb_streams < 1)
5346  return 0;
5347  st = c->fc->streams[c->fc->nb_streams-1];
5348  sc = st->priv_data;
5349 
5350  for (i = 0; i < 3; i++) {
5351  uint8_t **p;
5352  uint32_t len, tag;
5353 
5354  if (end - avio_tell(pb) <= 12)
5355  break;
5356 
5357  len = avio_rb32(pb);
5358  tag = avio_rl32(pb);
5359  avio_skip(pb, 4); // flags
5360 
5361  if (len < 12 || len - 12 > end - avio_tell(pb))
5362  break;
5363  len -= 12;
5364 
5365  if (tag == MKTAG('m', 'e', 'a', 'n'))
5366  p = &mean;
5367  else if (tag == MKTAG('n', 'a', 'm', 'e'))
5368  p = &key;
5369  else if (tag == MKTAG('d', 'a', 't', 'a') && len > 4) {
5370  avio_skip(pb, 4);
5371  len -= 4;
5372  p = &val;
5373  } else
5374  break;
5375 
5376  if (*p)
5377  break;
5378 
5379  *p = av_malloc(len + 1);
5380  if (!*p) {
5381  ret = AVERROR(ENOMEM);
5382  break;
5383  }
5384  ret = ffio_read_size(pb, *p, len);
5385  if (ret < 0) {
5386  av_freep(p);
5387  break;
5388  }
5389  (*p)[len] = 0;
5390  }
5391 
5392  if (mean && key && val) {
5393  if (strcmp(key, "iTunSMPB") == 0) {
5394  int priming, remainder, samples;
5395  if(sscanf(val, "%*X %X %X %X", &priming, &remainder, &samples) == 3){
5396  if(priming>0 && priming<16384)
5397  sc->start_pad = priming;
5398  }
5399  }
5400  if (strcmp(key, "cdec") != 0) {
5401  av_dict_set(&c->fc->metadata, key, val,
5403  key = val = NULL;
5404  }
5405  } else {
5406  av_log(c->fc, AV_LOG_VERBOSE,
5407  "Unhandled or malformed custom metadata of size %"PRId64"\n", atom.size);
5408  }
5409 
5410  avio_seek(pb, end, SEEK_SET);
5411  av_freep(&key);
5412  av_freep(&val);
5413  av_freep(&mean);
5414  return ret;
5415 }
5416 
5418 {
5419  MOVStreamContext *sc;
5420  AVStream *st;
5421 
5422  st = avformat_new_stream(c->fc, NULL);
5423  if (!st)
5424  return AVERROR(ENOMEM);
5425  sc = av_mallocz(sizeof(MOVStreamContext));
5426  if (!sc)
5427  goto fail;
5428 
5429  item->st = st;
5430  st->id = item->item_id;
5431  st->priv_data = sc;
5433  st->codecpar->codec_id = mov_codec_id(st, item->type);
5434  sc->id = st->id;
5435  sc->ffindex = st->index;
5436  st->avg_frame_rate.num = st->avg_frame_rate.den = 1;
5437  st->time_base.num = st->time_base.den = 1;
5438  st->nb_frames = 1;
5439  sc->time_scale = 1;
5440  sc->pb = c->fc->pb;
5441  sc->pb_is_copied = 1;
5442  sc->refcount = 1;
5443 
5444  if (item->name)
5445  av_dict_set(&st->metadata, "title", item->name, 0);
5446 
5447  // Populate the necessary fields used by mov_build_index.
5448  sc->stsc_data = av_malloc_array(1, sizeof(*sc->stsc_data));
5449  if (!sc->stsc_data)
5450  goto fail;
5451  sc->stsc_count = 1;
5452  sc->stsc_data[0].first = 1;
5453  sc->stsc_data[0].count = 1;
5454  sc->stsc_data[0].id = 1;
5455  sc->chunk_offsets = av_malloc_array(1, sizeof(*sc->chunk_offsets));
5456  if (!sc->chunk_offsets)
5457  goto fail;
5458  sc->chunk_count = 1;
5459  sc->stts_data = av_malloc_array(1, sizeof(*sc->stts_data));
5460  if (!sc->stts_data)
5461  goto fail;
5462  sc->stts_count = 1;
5463  sc->stts_data[0].count = 1;
5464  // Not used for still images. But needed by mov_build_index.
5465  sc->stts_data[0].duration = 0;
5466 
5467  return 0;
5468 fail:
5469  mov_free_stream_context(c->fc, st);
5470  ff_remove_stream(c->fc, st);
5471  item->st = NULL;
5472 
5473  return AVERROR(ENOMEM);
5474 }
5475 
5477 {
5478  while (atom.size > 8) {
5479  uint32_t tag;
5480  if (avio_feof(pb))
5481  return AVERROR_EOF;
5482  tag = avio_rl32(pb);
5483  atom.size -= 4;
5484  if (tag == MKTAG('h','d','l','r')) {
5485  avio_seek(pb, -8, SEEK_CUR);
5486  atom.size += 8;
5487  return mov_read_default(c, pb, atom);
5488  }
5489  }
5490  return 0;
5491 }
5492 
5493 // return 1 when matrix is identity, 0 otherwise
5494 #define IS_MATRIX_IDENT(matrix) \
5495  ( (matrix)[0][0] == (1 << 16) && \
5496  (matrix)[1][1] == (1 << 16) && \
5497  (matrix)[2][2] == (1 << 30) && \
5498  !(matrix)[0][1] && !(matrix)[0][2] && \
5499  !(matrix)[1][0] && !(matrix)[1][2] && \
5500  !(matrix)[2][0] && !(matrix)[2][1])
5501 
5503 {
5504  int i, j, e;
5505  int width;
5506  int height;
5507  int display_matrix[3][3];
5508  int res_display_matrix[3][3] = { { 0 } };
5509  AVStream *st;
5510  MOVStreamContext *sc;
5511  int version;
5512  int flags;
5513 
5514  if (c->fc->nb_streams < 1)
5515  return 0;
5516  st = c->fc->streams[c->fc->nb_streams-1];
5517  sc = st->priv_data;
5518 
5519  // Each stream (trak) should have exactly 1 tkhd. This catches bad files and
5520  // avoids corrupting AVStreams mapped to an earlier tkhd.
5521  if (st->id != -1)
5522  return AVERROR_INVALIDDATA;
5523 
5524  version = avio_r8(pb);
5525  flags = avio_rb24(pb);
5527 
5528  if (version == 1) {
5529  avio_rb64(pb);
5530  avio_rb64(pb);
5531  } else {
5532  avio_rb32(pb); /* creation time */
5533  avio_rb32(pb); /* modification time */
5534  }
5535  st->id = (int)avio_rb32(pb); /* track id (NOT 0 !)*/
5536  sc->id = st->id;
5537  avio_rb32(pb); /* reserved */
5538 
5539  /* highlevel (considering edits) duration in movie timebase */
5540  (version == 1) ? avio_rb64(pb) : avio_rb32(pb);
5541  avio_rb32(pb); /* reserved */
5542  avio_rb32(pb); /* reserved */
5543 
5544  avio_rb16(pb); /* layer */
5545  avio_rb16(pb); /* alternate group */
5546  avio_rb16(pb); /* volume */
5547  avio_rb16(pb); /* reserved */
5548 
5549  //read in the display matrix (outlined in ISO 14496-12, Section 6.2.2)
5550  // they're kept in fixed point format through all calculations
5551  // save u,v,z to store the whole matrix in the AV_PKT_DATA_DISPLAYMATRIX
5552  // side data, but the scale factor is not needed to calculate aspect ratio
5553  for (i = 0; i < 3; i++) {
5554  display_matrix[i][0] = avio_rb32(pb); // 16.16 fixed point
5555  display_matrix[i][1] = avio_rb32(pb); // 16.16 fixed point
5556  display_matrix[i][2] = avio_rb32(pb); // 2.30 fixed point
5557  }
5558 
5559  width = avio_rb32(pb); // 16.16 fixed point track width
5560  height = avio_rb32(pb); // 16.16 fixed point track height
5561  sc->width = width >> 16;
5562  sc->height = height >> 16;
5563 
5564  // apply the moov display matrix (after the tkhd one)
5565  for (i = 0; i < 3; i++) {
5566  const int sh[3] = { 16, 16, 30 };
5567  for (j = 0; j < 3; j++) {
5568  for (e = 0; e < 3; e++) {
5569  res_display_matrix[i][j] +=
5570  ((int64_t) display_matrix[i][e] *
5571  c->movie_display_matrix[e][j]) >> sh[e];
5572  }
5573  }
5574  }
5575 
5576  // save the matrix when it is not the default identity
5577  if (!IS_MATRIX_IDENT(res_display_matrix)) {
5578  av_freep(&sc->display_matrix);
5579  sc->display_matrix = av_malloc(sizeof(int32_t) * 9);
5580  if (!sc->display_matrix)
5581  return AVERROR(ENOMEM);
5582 
5583  for (i = 0; i < 3; i++)
5584  for (j = 0; j < 3; j++)
5585  sc->display_matrix[i * 3 + j] = res_display_matrix[i][j];
5586  }
5587 
5588  // transform the display width/height according to the matrix
5589  // to keep the same scale, use [width height 1<<16]
5590  if (width && height && sc->display_matrix) {
5591  double disp_transform[2];
5592 
5593  for (i = 0; i < 2; i++)
5594  disp_transform[i] = hypot(sc->display_matrix[0 + i],
5595  sc->display_matrix[3 + i]);
5596 
5597  if (disp_transform[0] > 1 && disp_transform[1] > 1 &&
5598  disp_transform[0] < (1<<24) && disp_transform[1] < (1<<24) &&
5599  fabs((disp_transform[0] / disp_transform[1]) - 1.0) > 0.01)
5601  disp_transform[0] / disp_transform[1],
5602  INT_MAX);
5603  }
5604  return 0;
5605 }
5606 
5608 {
5609  MOVFragment *frag = &c->fragment;
5610  MOVTrackExt *trex = NULL;
5611  int flags, track_id, i;
5612  MOVFragmentStreamInfo * frag_stream_info;
5613 
5614  avio_r8(pb); /* version */
5615  flags = avio_rb24(pb);
5616 
5617  track_id = avio_rb32(pb);
5618  if (!track_id)
5619  return AVERROR_INVALIDDATA;
5620  for (i = 0; i < c->trex_count; i++)
5621  if (c->trex_data[i].track_id == track_id) {
5622  trex = &c->trex_data[i];
5623  break;
5624  }
5625  if (!trex) {
5626  av_log(c->fc, AV_LOG_WARNING, "could not find corresponding trex (id %u)\n", track_id);
5627  return 0;
5628  }
5629  c->fragment.found_tfhd = 1;
5630  frag->track_id = track_id;
5631  set_frag_stream(&c->frag_index, track_id);
5632 
5635  frag->moof_offset : frag->implicit_offset;
5636  frag->stsd_id = flags & MOV_TFHD_STSD_ID ? avio_rb32(pb) : trex->stsd_id;
5637 
5639  avio_rb32(pb) : trex->duration;
5640  frag->size = flags & MOV_TFHD_DEFAULT_SIZE ?
5641  avio_rb32(pb) : trex->size;
5642  frag->flags = flags & MOV_TFHD_DEFAULT_FLAGS ?
5643  avio_rb32(pb) : trex->flags;
5644  av_log(c->fc, AV_LOG_TRACE, "frag flags 0x%x\n", frag->flags);
5645 
5646  frag_stream_info = get_current_frag_stream_info(&c->frag_index);
5647  if (frag_stream_info) {
5648  frag_stream_info->next_trun_dts = AV_NOPTS_VALUE;
5649  frag_stream_info->stsd_id = frag->stsd_id;
5650  }
5651  return 0;
5652 }
5653 
5655 {
5656  unsigned i, num;
5657  void *new_tracks;
5658 
5659  num = atom.size / 4;
5660  if (!(new_tracks = av_malloc_array(num, sizeof(int))))
5661  return AVERROR(ENOMEM);
5662 
5663  av_free(c->chapter_tracks);
5664  c->chapter_tracks = new_tracks;
5665  c->nb_chapter_tracks = num;
5666 
5667  for (i = 0; i < num && !pb->eof_reached; i++)
5668  c->chapter_tracks[i] = avio_rb32(pb);
5669 
5670  c->nb_chapter_tracks = i;
5671 
5672  return 0;
5673 }
5674 
5676 {
5677  MOVTrackExt *trex;
5678  int err;
5679 
5680  if ((uint64_t)c->trex_count+1 >= UINT_MAX / sizeof(*c->trex_data))
5681  return AVERROR_INVALIDDATA;
5682  if ((err = av_reallocp_array(&c->trex_data, c->trex_count + 1,
5683  sizeof(*c->trex_data))) < 0) {
5684  c->trex_count = 0;
5685  return err;
5686  }
5687 
5688  c->fc->duration = AV_NOPTS_VALUE; // the duration from mvhd is not representing the whole file when fragments are used.
5689 
5690  trex = &c->trex_data[c->trex_count++];
5691  avio_r8(pb); /* version */
5692  avio_rb24(pb); /* flags */
5693  trex->track_id = avio_rb32(pb);
5694  trex->stsd_id = avio_rb32(pb);
5695  trex->duration = avio_rb32(pb);
5696  trex->size = avio_rb32(pb);
5697  trex->flags = avio_rb32(pb);
5698  return 0;
5699 }
5700 
5702 {
5703  MOVFragment *frag = &c->fragment;
5704  AVStream *st = NULL;
5705  MOVStreamContext *sc;
5706  int version, i;
5707  MOVFragmentStreamInfo * frag_stream_info;
5708  int64_t base_media_decode_time;
5709 
5710  for (i = 0; i < c->fc->nb_streams; i++) {
5711  sc = c->fc->streams[i]->priv_data;
5712  if (sc->id == frag->track_id) {
5713  st = c->fc->streams[i];
5714  break;
5715  }
5716  }
5717  if (!st) {
5718  av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %u\n", frag->track_id);
5719  return 0;
5720  }
5721  sc = st->priv_data;
5722  if (sc->pseudo_stream_id + 1 != frag->stsd_id && sc->pseudo_stream_id != -1)
5723  return 0;
5724  version = avio_r8(pb);
5725  avio_rb24(pb); /* flags */
5726  if (version) {
5727  base_media_decode_time = avio_rb64(pb);
5728  } else {
5729  base_media_decode_time = avio_rb32(pb);
5730  }
5731 
5732  frag_stream_info = get_current_frag_stream_info(&c->frag_index);
5733  if (frag_stream_info)
5734  frag_stream_info->tfdt_dts = base_media_decode_time;
5735  sc->track_end = base_media_decode_time;
5736 
5737  return 0;
5738 }
5739 
5741 {
5742  MOVFragment *frag = &c->fragment;
5743  AVStream *st = NULL;
5744  FFStream *sti = NULL;
5745  MOVStreamContext *sc;
5746  MOVTimeToSample *tts_data;
5747  uint64_t offset;
5748  int64_t dts, pts = AV_NOPTS_VALUE;
5749  int data_offset = 0;
5750  unsigned entries, first_sample_flags = frag->flags;
5751  int flags, distance, i;
5752  int64_t prev_dts = AV_NOPTS_VALUE;
5753  int next_frag_index = -1, index_entry_pos;
5754  size_t requested_size;
5755  size_t old_allocated_size;
5756  AVIndexEntry *new_entries;
5757  MOVFragmentStreamInfo * frag_stream_info;
5758 
5759  if (!frag->found_tfhd) {
5760  av_log(c->fc, AV_LOG_ERROR, "trun track id unknown, no tfhd was found\n");
5761  return AVERROR_INVALIDDATA;
5762  }
5763 
5764  for (i = 0; i < c->fc->nb_streams; i++) {
5765  sc = c->fc->streams[i]->priv_data;
5766  if (sc->id == frag->track_id) {
5767  st = c->fc->streams[i];
5768  sti = ffstream(st);
5769  break;
5770  }
5771  }
5772  if (!st) {
5773  av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %u\n", frag->track_id);
5774  return 0;
5775  }
5776  sc = st->priv_data;
5777  if (sc->pseudo_stream_id+1 != frag->stsd_id && sc->pseudo_stream_id != -1)
5778  return 0;
5779 
5780  // Find the next frag_index index that has a valid index_entry for
5781  // the current track_id.
5782  //
5783  // A valid index_entry means the trun for the fragment was read
5784  // and it's samples are in index_entries at the given position.
5785  // New index entries will be inserted before the index_entry found.
5786  index_entry_pos = sti->nb_index_entries;
5787  for (i = c->frag_index.current + 1; i < c->frag_index.nb_items; i++) {
5788  frag_stream_info = get_frag_stream_info(&c->frag_index, i, frag->track_id);
5789  if (frag_stream_info && frag_stream_info->index_entry >= 0) {
5790  next_frag_index = i;
5791  index_entry_pos = frag_stream_info->index_entry;
5792  break;
5793  }
5794  }
5795  av_assert0(index_entry_pos <= sti->nb_index_entries);
5796 
5797  avio_r8(pb); /* version */
5798  flags = avio_rb24(pb);
5799  entries = avio_rb32(pb);
5800  av_log(c->fc, AV_LOG_TRACE, "flags 0x%x entries %u\n", flags, entries);
5801 
5802  if ((uint64_t)entries+sc->tts_count >= UINT_MAX/sizeof(*sc->tts_data))
5803  return AVERROR_INVALIDDATA;
5804  if (flags & MOV_TRUN_DATA_OFFSET) data_offset = avio_rb32(pb);
5805  if (flags & MOV_TRUN_FIRST_SAMPLE_FLAGS) first_sample_flags = avio_rb32(pb);
5806 
5807  frag_stream_info = get_current_frag_stream_info(&c->frag_index);
5808  if (frag_stream_info) {
5809  if (frag_stream_info->next_trun_dts != AV_NOPTS_VALUE) {
5810  dts = frag_stream_info->next_trun_dts - sc->time_offset;
5811  } else if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE &&
5812  c->use_mfra_for == FF_MOV_FLAG_MFRA_PTS) {
5813  pts = frag_stream_info->first_tfra_pts;
5814  av_log(c->fc, AV_LOG_DEBUG, "found mfra time %"PRId64
5815  ", using it for pts\n", pts);
5816  } else if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE &&
5817  c->use_mfra_for == FF_MOV_FLAG_MFRA_DTS) {
5818  dts = frag_stream_info->first_tfra_pts;
5819  av_log(c->fc, AV_LOG_DEBUG, "found mfra time %"PRId64
5820  ", using it for dts\n", pts);
5821  } else {
5822  int has_tfdt = frag_stream_info->tfdt_dts != AV_NOPTS_VALUE;
5823  int has_sidx = frag_stream_info->sidx_pts != AV_NOPTS_VALUE;
5824  int fallback_tfdt = !c->use_tfdt && !has_sidx && has_tfdt;
5825  int fallback_sidx = c->use_tfdt && !has_tfdt && has_sidx;
5826 
5827  if (fallback_sidx) {
5828  av_log(c->fc, AV_LOG_DEBUG, "use_tfdt set but no tfdt found, using sidx instead\n");
5829  }
5830  if (fallback_tfdt) {
5831  av_log(c->fc, AV_LOG_DEBUG, "use_tfdt not set but no sidx found, using tfdt instead\n");
5832  }
5833 
5834  if (has_tfdt && c->use_tfdt || fallback_tfdt) {
5835  dts = frag_stream_info->tfdt_dts - sc->time_offset;
5836  av_log(c->fc, AV_LOG_DEBUG, "found tfdt time %"PRId64
5837  ", using it for dts\n", dts);
5838  } else if (has_sidx && !c->use_tfdt || fallback_sidx) {
5839  // FIXME: sidx earliest_presentation_time is *PTS*, s.b.
5840  // pts = frag_stream_info->sidx_pts;
5841  dts = frag_stream_info->sidx_pts - sc->time_offset;
5842  av_log(c->fc, AV_LOG_DEBUG, "found sidx time %"PRId64
5843  ", using it for dts\n", frag_stream_info->sidx_pts);
5844  } else {
5845  dts = sc->track_end - sc->time_offset;
5846  av_log(c->fc, AV_LOG_DEBUG, "found track end time %"PRId64
5847  ", using it for dts\n", dts);
5848  }
5849  }
5850  } else {
5851  dts = sc->track_end - sc->time_offset;
5852  av_log(c->fc, AV_LOG_DEBUG, "found track end time %"PRId64
5853  ", using it for dts\n", dts);
5854  }
5855  offset = frag->base_data_offset + data_offset;
5856  distance = 0;
5857  av_log(c->fc, AV_LOG_TRACE, "first sample flags 0x%x\n", first_sample_flags);
5858 
5859  // realloc space for new index entries
5860  if ((uint64_t)sti->nb_index_entries + entries >= UINT_MAX / sizeof(AVIndexEntry)) {
5861  entries = UINT_MAX / sizeof(AVIndexEntry) - sti->nb_index_entries;
5862  av_log(c->fc, AV_LOG_ERROR, "Failed to add index entry\n");
5863  }
5864  if (entries == 0)
5865  return 0;
5866 
5867  requested_size = (sti->nb_index_entries + entries) * sizeof(AVIndexEntry);
5868  new_entries = av_fast_realloc(sti->index_entries,
5870  requested_size);
5871  if (!new_entries)
5872  return AVERROR(ENOMEM);
5873  sti->index_entries= new_entries;
5874 
5875  requested_size = (sti->nb_index_entries + entries) * sizeof(*sc->tts_data);
5876  old_allocated_size = sc->tts_allocated_size;
5877  tts_data = av_fast_realloc(sc->tts_data, &sc->tts_allocated_size,
5878  requested_size);
5879  if (!tts_data)
5880  return AVERROR(ENOMEM);
5881  sc->tts_data = tts_data;
5882 
5883  // In case there were samples without time to sample entries, ensure they get
5884  // zero valued entries. This ensures clips which mix boxes with and
5885  // without time to sample entries don't pickup uninitialized data.
5886  memset((uint8_t*)(sc->tts_data) + old_allocated_size, 0,
5887  sc->tts_allocated_size - old_allocated_size);
5888 
5889  if (index_entry_pos < sti->nb_index_entries) {
5890  // Make hole in index_entries and tts_data for new samples
5891  memmove(sti->index_entries + index_entry_pos + entries,
5892  sti->index_entries + index_entry_pos,
5893  sizeof(*sti->index_entries) *
5894  (sti->nb_index_entries - index_entry_pos));
5895  memmove(sc->tts_data + index_entry_pos + entries,
5896  sc->tts_data + index_entry_pos,
5897  sizeof(*sc->tts_data) * (sc->tts_count - index_entry_pos));
5898  if (index_entry_pos < sc->current_sample) {
5899  sc->current_sample += entries;
5900  }
5901  }
5902 
5903  sti->nb_index_entries += entries;
5904  sc->tts_count = sti->nb_index_entries;
5905  sc->stts_count = sti->nb_index_entries;
5906  if (flags & MOV_TRUN_SAMPLE_CTS)
5907  sc->ctts_count = sti->nb_index_entries;
5908 
5909  // Record the index_entry position in frag_index of this fragment
5910  if (frag_stream_info) {
5911  frag_stream_info->index_entry = index_entry_pos;
5912  if (frag_stream_info->index_base < 0)
5913  frag_stream_info->index_base = index_entry_pos;
5914  }
5915 
5916  if (index_entry_pos > 0)
5917  prev_dts = sti->index_entries[index_entry_pos-1].timestamp;
5918 
5919  for (i = 0; i < entries && !pb->eof_reached; i++) {
5920  unsigned sample_size = frag->size;
5921  int sample_flags = i ? frag->flags : first_sample_flags;
5922  unsigned sample_duration = frag->duration;
5923  unsigned ctts_duration = 0;
5924  int keyframe = 0;
5925  int index_entry_flags = 0;
5926 
5927  if (flags & MOV_TRUN_SAMPLE_DURATION) sample_duration = avio_rb32(pb);
5928  if (flags & MOV_TRUN_SAMPLE_SIZE) sample_size = avio_rb32(pb);
5929  if (flags & MOV_TRUN_SAMPLE_FLAGS) sample_flags = avio_rb32(pb);
5930  if (flags & MOV_TRUN_SAMPLE_CTS) ctts_duration = avio_rb32(pb);
5931 
5932  mov_update_dts_shift(sc, ctts_duration, c->fc);
5933  if (pts != AV_NOPTS_VALUE) {
5934  dts = pts - sc->dts_shift;
5935  if (flags & MOV_TRUN_SAMPLE_CTS) {
5936  dts -= ctts_duration;
5937  } else {
5938  dts -= sc->time_offset;
5939  }
5940  av_log(c->fc, AV_LOG_DEBUG,
5941  "pts %"PRId64" calculated dts %"PRId64
5942  " sc->dts_shift %d ctts.duration %d"
5943  " sc->time_offset %"PRId64
5944  " flags & MOV_TRUN_SAMPLE_CTS %d\n",
5945  pts, dts,
5946  sc->dts_shift, ctts_duration,
5948  pts = AV_NOPTS_VALUE;
5949  }
5950 
5951  keyframe =
5952  !(sample_flags & (MOV_FRAG_SAMPLE_FLAG_IS_NON_SYNC |
5954  if (keyframe) {
5955  distance = 0;
5956  index_entry_flags |= AVINDEX_KEYFRAME;
5957  }
5958  // Fragments can overlap in time. Discard overlapping frames after
5959  // decoding.
5960  if (prev_dts >= dts)
5961  index_entry_flags |= AVINDEX_DISCARD_FRAME;
5962 
5963  sti->index_entries[index_entry_pos].pos = offset;
5964  sti->index_entries[index_entry_pos].timestamp = dts;
5965  sti->index_entries[index_entry_pos].size = sample_size;
5966  sti->index_entries[index_entry_pos].min_distance = distance;
5967  sti->index_entries[index_entry_pos].flags = index_entry_flags;
5968 
5969  sc->tts_data[index_entry_pos].count = 1;
5970  sc->tts_data[index_entry_pos].offset = ctts_duration;
5971  sc->tts_data[index_entry_pos].duration = sample_duration;
5972  index_entry_pos++;
5973 
5974  av_log(c->fc, AV_LOG_TRACE, "AVIndex stream %d, sample %d, offset %"PRIx64", dts %"PRId64", "
5975  "size %u, distance %d, keyframe %d\n", st->index,
5976  index_entry_pos, offset, dts, sample_size, distance, keyframe);
5977  distance++;
5978  if (av_sat_add64(dts, sample_duration) != dts + (uint64_t)sample_duration)
5979  return AVERROR_INVALIDDATA;
5980  if (!sample_size)
5981  return AVERROR_INVALIDDATA;
5982  dts += sample_duration;
5983  offset += sample_size;
5984  sc->data_size += sample_size;
5985 
5986  if (sample_duration <= INT64_MAX - sc->duration_for_fps &&
5987  1 <= INT_MAX - sc->nb_frames_for_fps
5988  ) {
5989  sc->duration_for_fps += sample_duration;
5990  sc->nb_frames_for_fps ++;
5991  }
5992  }
5993  if (frag_stream_info)
5994  frag_stream_info->next_trun_dts = dts + sc->time_offset;
5995  if (i < entries) {
5996  // EOF found before reading all entries. Fix the hole this would
5997  // leave in index_entries and tts_data
5998  int gap = entries - i;
5999  memmove(sti->index_entries + index_entry_pos,
6000  sti->index_entries + index_entry_pos + gap,
6001  sizeof(*sti->index_entries) *
6002  (sti->nb_index_entries - (index_entry_pos + gap)));
6003  memmove(sc->tts_data + index_entry_pos,
6004  sc->tts_data + index_entry_pos + gap,
6005  sizeof(*sc->tts_data) *
6006  (sc->tts_count - (index_entry_pos + gap)));
6007 
6008  sti->nb_index_entries -= gap;
6009  sc->tts_count -= gap;
6010  if (index_entry_pos < sc->current_sample) {
6011  sc->current_sample -= gap;
6012  }
6013  entries = i;
6014  }
6015 
6016  // The end of this new fragment may overlap in time with the start
6017  // of the next fragment in index_entries. Mark the samples in the next
6018  // fragment that overlap with AVINDEX_DISCARD_FRAME
6019  prev_dts = AV_NOPTS_VALUE;
6020  if (index_entry_pos > 0)
6021  prev_dts = sti->index_entries[index_entry_pos-1].timestamp;
6022  for (int i = index_entry_pos; i < sti->nb_index_entries; i++) {
6023  if (prev_dts < sti->index_entries[i].timestamp)
6024  break;
6026  }
6027 
6028  // If a hole was created to insert the new index_entries into,
6029  // the index_entry recorded for all subsequent moof must
6030  // be incremented by the number of entries inserted.
6031  fix_frag_index_entries(&c->frag_index, next_frag_index,
6032  frag->track_id, entries);
6033 
6034  if (pb->eof_reached) {
6035  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted TRUN atom\n");
6036  return AVERROR_EOF;
6037  }
6038 
6039  frag->implicit_offset = offset;
6040 
6041  sc->track_end = dts + sc->time_offset;
6042  if (st->duration < sc->track_end)
6043  st->duration = sc->track_end;
6044 
6045  return 0;
6046 }
6047 
6049 {
6050  int64_t stream_size = avio_size(pb);
6051  int64_t offset = av_sat_add64(avio_tell(pb), atom.size), pts, timestamp;
6052  uint8_t version, is_complete;
6053  int64_t offadd;
6054  unsigned i, j, track_id, item_count;
6055  AVStream *st = NULL;
6056  AVStream *ref_st = NULL;
6057  MOVStreamContext *sc, *ref_sc = NULL;
6058  AVRational timescale;
6059 
6060  version = avio_r8(pb);
6061  if (version > 1) {
6062  avpriv_request_sample(c->fc, "sidx version %u", version);
6063  return 0;
6064  }
6065 
6066  avio_rb24(pb); // flags
6067 
6068  track_id = avio_rb32(pb); // Reference ID
6069  for (i = 0; i < c->fc->nb_streams; i++) {
6070  sc = c->fc->streams[i]->priv_data;
6071  if (sc->id == track_id) {
6072  st = c->fc->streams[i];
6073  break;
6074  }
6075  }
6076  if (!st) {
6077  av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %d\n", track_id);
6078  return 0;
6079  }
6080 
6081  sc = st->priv_data;
6082 
6083  timescale = av_make_q(1, avio_rb32(pb));
6084 
6085  if (timescale.den <= 0) {
6086  av_log(c->fc, AV_LOG_ERROR, "Invalid sidx timescale 1/%d\n", timescale.den);
6087  return AVERROR_INVALIDDATA;
6088  }
6089 
6090  if (version == 0) {
6091  pts = avio_rb32(pb);
6092  offadd= avio_rb32(pb);
6093  } else {
6094  pts = avio_rb64(pb);
6095  offadd= avio_rb64(pb);
6096  }
6097  if (av_sat_add64(offset, offadd) != offset + (uint64_t)offadd)
6098  return AVERROR_INVALIDDATA;
6099 
6100  offset += (uint64_t)offadd;
6101 
6102  avio_rb16(pb); // reserved
6103 
6104  item_count = avio_rb16(pb);
6105  if (item_count == 0)
6106  return AVERROR_INVALIDDATA;
6107 
6108  for (i = 0; i < item_count; i++) {
6109  int index;
6110  MOVFragmentStreamInfo * frag_stream_info;
6111  uint32_t size = avio_rb32(pb);
6112  uint32_t duration = avio_rb32(pb);
6113  if (size & 0x80000000) {
6114  avpriv_request_sample(c->fc, "sidx reference_type 1");
6115  return AVERROR_PATCHWELCOME;
6116  }
6117  avio_rb32(pb); // sap_flags
6118  timestamp = av_rescale_q(pts, timescale, st->time_base);
6119 
6121  frag_stream_info = get_frag_stream_info(&c->frag_index, index, track_id);
6122  if (frag_stream_info)
6123  frag_stream_info->sidx_pts = timestamp;
6124 
6125  if (av_sat_add64(offset, size) != offset + (uint64_t)size ||
6126  av_sat_add64(pts, duration) != pts + (uint64_t)duration
6127  )
6128  return AVERROR_INVALIDDATA;
6129  offset += size;
6130  pts += duration;
6131  }
6132 
6133  st->duration = sc->track_end = pts;
6134 
6135  sc->has_sidx = 1;
6136 
6137  // See if the remaining bytes are just an mfra which we can ignore.
6138  is_complete = offset == stream_size;
6139  if (!is_complete && (pb->seekable & AVIO_SEEKABLE_NORMAL) && stream_size > 0 ) {
6140  int64_t ret;
6141  int64_t original_pos = avio_tell(pb);
6142  if (!c->have_read_mfra_size) {
6143  if ((ret = avio_seek(pb, stream_size - 4, SEEK_SET)) < 0)
6144  return ret;
6145  c->mfra_size = avio_rb32(pb);
6146  c->have_read_mfra_size = 1;
6147  if ((ret = avio_seek(pb, original_pos, SEEK_SET)) < 0)
6148  return ret;
6149  }
6150  if (offset == stream_size - c->mfra_size)
6151  is_complete = 1;
6152  }
6153 
6154  if (is_complete) {
6155  // Find first entry in fragment index that came from an sidx.
6156  // This will pretty much always be the first entry.
6157  for (i = 0; i < c->frag_index.nb_items; i++) {
6158  MOVFragmentIndexItem * item = &c->frag_index.item[i];
6159  for (j = 0; ref_st == NULL && j < item->nb_stream_info; j++) {
6160  MOVFragmentStreamInfo * si;
6161  si = &item->stream_info[j];
6162  if (si->sidx_pts != AV_NOPTS_VALUE) {
6163  ref_st = c->fc->streams[j];
6164  ref_sc = ref_st->priv_data;
6165  break;
6166  }
6167  }
6168  }
6169  if (ref_st) for (i = 0; i < c->fc->nb_streams; i++) {
6170  st = c->fc->streams[i];
6171  sc = st->priv_data;
6172  if (!sc->has_sidx) {
6173  st->duration = sc->track_end = av_rescale(ref_st->duration, sc->time_scale, ref_sc->time_scale);
6174  }
6175  }
6176 
6177  c->frag_index.complete = 1;
6178  }
6179 
6180  return 0;
6181 }
6182 
6183 /* this atom should be null (from specs), but some buggy files put the 'moov' atom inside it... */
6184 /* like the files created with Adobe Premiere 5.0, for samples see */
6185 /* http://graphics.tudelft.nl/~wouter/publications/soundtests/ */
6187 {
6188  int err;
6189 
6190  if (atom.size < 8)
6191  return 0; /* continue */
6192  if (avio_rb32(pb) != 0) { /* 0 sized mdat atom... use the 'wide' atom size */
6193  avio_skip(pb, atom.size - 4);
6194  return 0;
6195  }
6196  atom.type = avio_rl32(pb);
6197  atom.size -= 8;
6198  if (atom.type != MKTAG('m','d','a','t')) {
6199  avio_skip(pb, atom.size);
6200  return 0;
6201  }
6202  err = mov_read_mdat(c, pb, atom);
6203  return err;
6204 }
6205 
6207 {
6208 #if CONFIG_ZLIB
6209  FFIOContext ctx;
6210  uint8_t *cmov_data;
6211  uint8_t *moov_data; /* uncompressed data */
6212  long cmov_len, moov_len;
6213  int ret = -1;
6214 
6215  avio_rb32(pb); /* dcom atom */
6216  if (avio_rl32(pb) != MKTAG('d','c','o','m'))
6217  return AVERROR_INVALIDDATA;
6218  if (avio_rl32(pb) != MKTAG('z','l','i','b')) {
6219  av_log(c->fc, AV_LOG_ERROR, "unknown compression for cmov atom !\n");
6220  return AVERROR_INVALIDDATA;
6221  }
6222  avio_rb32(pb); /* cmvd atom */
6223  if (avio_rl32(pb) != MKTAG('c','m','v','d'))
6224  return AVERROR_INVALIDDATA;
6225  moov_len = avio_rb32(pb); /* uncompressed size */
6226  cmov_len = atom.size - 6 * 4;
6227 
6228  cmov_data = av_malloc(cmov_len);
6229  if (!cmov_data)
6230  return AVERROR(ENOMEM);
6231  moov_data = av_malloc(moov_len);
6232  if (!moov_data) {
6233  av_free(cmov_data);
6234  return AVERROR(ENOMEM);
6235  }
6236  ret = ffio_read_size(pb, cmov_data, cmov_len);
6237  if (ret < 0)
6238  goto free_and_return;
6239 
6241  if (uncompress (moov_data, (uLongf *) &moov_len, (const Bytef *)cmov_data, cmov_len) != Z_OK)
6242  goto free_and_return;
6243  ffio_init_read_context(&ctx, moov_data, moov_len);
6244  ctx.pub.seekable = AVIO_SEEKABLE_NORMAL;
6245  atom.type = MKTAG('m','o','o','v');
6246  atom.size = moov_len;
6247  ret = mov_read_default(c, &ctx.pub, atom);
6248 free_and_return:
6249  av_free(moov_data);
6250  av_free(cmov_data);
6251  return ret;
6252 #else
6253  av_log(c->fc, AV_LOG_ERROR, "this file requires zlib support compiled in\n");
6254  return AVERROR(ENOSYS);
6255 #endif
6256 }
6257 
6258 /* edit list atom */
6260 {
6261  MOVStreamContext *sc;
6262  int i, edit_count, version;
6263  int64_t elst_entry_size;
6264 
6265  if (c->fc->nb_streams < 1 || c->ignore_editlist)
6266  return 0;
6267  sc = c->fc->streams[c->fc->nb_streams-1]->priv_data;
6268 
6269  version = avio_r8(pb); /* version */
6270  avio_rb24(pb); /* flags */
6271  edit_count = avio_rb32(pb); /* entries */
6272  atom.size -= 8;
6273 
6274  elst_entry_size = version == 1 ? 20 : 12;
6275  if (atom.size != edit_count * elst_entry_size) {
6276  if (c->fc->strict_std_compliance >= FF_COMPLIANCE_STRICT) {
6277  av_log(c->fc, AV_LOG_ERROR, "Invalid edit list entry_count: %d for elst atom of size: %"PRId64" bytes.\n",
6278  edit_count, atom.size + 8);
6279  return AVERROR_INVALIDDATA;
6280  } else {
6281  edit_count = atom.size / elst_entry_size;
6282  if (edit_count * elst_entry_size != atom.size) {
6283  av_log(c->fc, AV_LOG_WARNING, "ELST atom of %"PRId64" bytes, bigger than %d entries.\n", atom.size, edit_count);
6284  }
6285  }
6286  }
6287 
6288  if (!edit_count)
6289  return 0;
6290  if (sc->elst_data)
6291  av_log(c->fc, AV_LOG_WARNING, "Duplicated ELST atom\n");
6292  av_free(sc->elst_data);
6293  sc->elst_count = 0;
6294  sc->elst_data = av_malloc_array(edit_count, sizeof(*sc->elst_data));
6295  if (!sc->elst_data)
6296  return AVERROR(ENOMEM);
6297 
6298  av_log(c->fc, AV_LOG_TRACE, "track[%u].edit_count = %i\n", c->fc->nb_streams - 1, edit_count);
6299  for (i = 0; i < edit_count && atom.size > 0 && !pb->eof_reached; i++) {
6300  MOVElst *e = &sc->elst_data[i];
6301 
6302  if (version == 1) {
6303  e->duration = avio_rb64(pb);
6304  e->time = avio_rb64(pb);
6305  atom.size -= 16;
6306  } else {
6307  e->duration = avio_rb32(pb); /* segment duration */
6308  e->time = (int32_t)avio_rb32(pb); /* media time */
6309  atom.size -= 8;
6310  }
6311  e->rate = avio_rb32(pb) / 65536.0;
6312  atom.size -= 4;
6313  av_log(c->fc, AV_LOG_TRACE, "duration=%"PRId64" time=%"PRId64" rate=%f\n",
6314  e->duration, e->time, e->rate);
6315 
6316  if (e->time < 0 && e->time != -1 &&
6317  c->fc->strict_std_compliance >= FF_COMPLIANCE_STRICT) {
6318  av_log(c->fc, AV_LOG_ERROR, "Track %d, edit %d: Invalid edit list media time=%"PRId64"\n",
6319  c->fc->nb_streams-1, i, e->time);
6320  return AVERROR_INVALIDDATA;
6321  }
6322  if (e->duration < 0) {
6323  av_log(c->fc, AV_LOG_ERROR, "Track %d, edit %d: Invalid edit list duration=%"PRId64"\n",
6324  c->fc->nb_streams-1, i, e->duration);
6325  return AVERROR_INVALIDDATA;
6326  }
6327  }
6328  sc->elst_count = i;
6329 
6330  return 0;
6331 }
6332 
6334 {
6335  MOVStreamContext *sc;
6336 
6337  if (c->fc->nb_streams < 1)
6338  return AVERROR_INVALIDDATA;
6339  sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
6340  sc->timecode_track = avio_rb32(pb);
6341  return 0;
6342 }
6343 
6345 {
6346  AVStream *st;
6347  int version, color_range, color_primaries, color_trc, color_space;
6348 
6349  if (c->fc->nb_streams < 1)
6350  return 0;
6351  st = c->fc->streams[c->fc->nb_streams - 1];
6352 
6353  if (atom.size < 5) {
6354  av_log(c->fc, AV_LOG_ERROR, "Empty VP Codec Configuration box\n");
6355  return AVERROR_INVALIDDATA;
6356  }
6357 
6358  version = avio_r8(pb);
6359  if (version != 1) {
6360  av_log(c->fc, AV_LOG_WARNING, "Unsupported VP Codec Configuration box version %d\n", version);
6361  return 0;
6362  }
6363  avio_skip(pb, 3); /* flags */
6364 
6365  avio_skip(pb, 2); /* profile + level */
6366  color_range = avio_r8(pb); /* bitDepth, chromaSubsampling, videoFullRangeFlag */
6367  color_primaries = avio_r8(pb);
6368  color_trc = avio_r8(pb);
6369  color_space = avio_r8(pb);
6370  if (avio_rb16(pb)) /* codecIntializationDataSize */
6371  return AVERROR_INVALIDDATA;
6372 
6375  if (!av_color_transfer_name(color_trc))
6376  color_trc = AVCOL_TRC_UNSPECIFIED;
6377  if (!av_color_space_name(color_space))
6378  color_space = AVCOL_SPC_UNSPECIFIED;
6379 
6382  st->codecpar->color_trc = color_trc;
6383  st->codecpar->color_space = color_space;
6384 
6385  return 0;
6386 }
6387 
6389 {
6390  MOVStreamContext *sc;
6391  int i, version;
6392 
6393  if (c->fc->nb_streams < 1)
6394  return AVERROR_INVALIDDATA;
6395 
6396  sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
6397 
6398  if (atom.size < 5) {
6399  av_log(c->fc, AV_LOG_ERROR, "Empty Mastering Display Metadata box\n");
6400  return AVERROR_INVALIDDATA;
6401  }
6402 
6403  version = avio_r8(pb);
6404  if (version) {
6405  av_log(c->fc, AV_LOG_WARNING, "Unsupported Mastering Display Metadata box version %d\n", version);
6406  return 0;
6407  }
6408  if (sc->mastering) {
6409  av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicate Mastering Display Metadata\n");
6410  return 0;
6411  }
6412 
6413  avio_skip(pb, 3); /* flags */
6414 
6416  if (!sc->mastering)
6417  return AVERROR(ENOMEM);
6418 
6419  for (i = 0; i < 3; i++) {
6420  sc->mastering->display_primaries[i][0] = av_make_q(avio_rb16(pb), 1 << 16);
6421  sc->mastering->display_primaries[i][1] = av_make_q(avio_rb16(pb), 1 << 16);
6422  }
6423  sc->mastering->white_point[0] = av_make_q(avio_rb16(pb), 1 << 16);
6424  sc->mastering->white_point[1] = av_make_q(avio_rb16(pb), 1 << 16);
6425 
6426  sc->mastering->max_luminance = av_make_q(avio_rb32(pb), 1 << 8);
6427  sc->mastering->min_luminance = av_make_q(avio_rb32(pb), 1 << 14);
6428 
6429  sc->mastering->has_primaries = 1;
6430  sc->mastering->has_luminance = 1;
6431 
6432  return 0;
6433 }
6434 
6436 {
6437  MOVStreamContext *sc;
6438  const int mapping[3] = {1, 2, 0};
6439  const int chroma_den = 50000;
6440  const int luma_den = 10000;
6441  int i;
6442 
6443  if (c->fc->nb_streams < 1)
6444  return AVERROR_INVALIDDATA;
6445 
6446  sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
6447 
6448  if (atom.size < 24) {
6449  av_log(c->fc, AV_LOG_ERROR, "Invalid Mastering Display Color Volume box\n");
6450  return AVERROR_INVALIDDATA;
6451  }
6452 
6453  if (sc->mastering) {
6454  av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicate Mastering Display Color Volume\n");
6455  return 0;
6456  }
6457 
6459  if (!sc->mastering)
6460  return AVERROR(ENOMEM);
6461 
6462  for (i = 0; i < 3; i++) {
6463  const int j = mapping[i];
6464  sc->mastering->display_primaries[j][0] = av_make_q(avio_rb16(pb), chroma_den);
6465  sc->mastering->display_primaries[j][1] = av_make_q(avio_rb16(pb), chroma_den);
6466  }
6467  sc->mastering->white_point[0] = av_make_q(avio_rb16(pb), chroma_den);
6468  sc->mastering->white_point[1] = av_make_q(avio_rb16(pb), chroma_den);
6469 
6470  sc->mastering->max_luminance = av_make_q(avio_rb32(pb), luma_den);
6471  sc->mastering->min_luminance = av_make_q(avio_rb32(pb), luma_den);
6472 
6473  sc->mastering->has_luminance = 1;
6474  sc->mastering->has_primaries = 1;
6475 
6476  return 0;
6477 }
6478 
6480 {
6481  MOVStreamContext *sc;
6482  int version;
6483 
6484  if (c->fc->nb_streams < 1)
6485  return AVERROR_INVALIDDATA;
6486 
6487  sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
6488 
6489  if (atom.size < 5) {
6490  av_log(c->fc, AV_LOG_ERROR, "Empty Content Light Level box\n");
6491  return AVERROR_INVALIDDATA;
6492  }
6493 
6494  version = avio_r8(pb);
6495  if (version) {
6496  av_log(c->fc, AV_LOG_WARNING, "Unsupported Content Light Level box version %d\n", version);
6497  return 0;
6498  }
6499  avio_skip(pb, 3); /* flags */
6500 
6501  if (sc->coll){
6502  av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicate COLL\n");
6503  return 0;
6504  }
6505 
6507  if (!sc->coll)
6508  return AVERROR(ENOMEM);
6509 
6510  sc->coll->MaxCLL = avio_rb16(pb);
6511  sc->coll->MaxFALL = avio_rb16(pb);
6512 
6513  return 0;
6514 }
6515 
6517 {
6518  MOVStreamContext *sc;
6519 
6520  if (c->fc->nb_streams < 1)
6521  return AVERROR_INVALIDDATA;
6522 
6523  sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
6524 
6525  if (atom.size < 4) {
6526  av_log(c->fc, AV_LOG_ERROR, "Empty Content Light Level Info box\n");
6527  return AVERROR_INVALIDDATA;
6528  }
6529 
6530  if (sc->coll){
6531  av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicate CLLI/COLL\n");
6532  return 0;
6533  }
6534 
6536  if (!sc->coll)
6537  return AVERROR(ENOMEM);
6538 
6539  sc->coll->MaxCLL = avio_rb16(pb);
6540  sc->coll->MaxFALL = avio_rb16(pb);
6541 
6542  return 0;
6543 }
6544 
6546 {
6547  MOVStreamContext *sc;
6548  const int illuminance_den = 10000;
6549  const int ambient_den = 50000;
6550  if (c->fc->nb_streams < 1)
6551  return AVERROR_INVALIDDATA;
6552  sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
6553  if (atom.size < 6) {
6554  av_log(c->fc, AV_LOG_ERROR, "Empty Ambient Viewing Environment Info box\n");
6555  return AVERROR_INVALIDDATA;
6556  }
6557  if (sc->ambient){
6558  av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicate AMVE\n");
6559  return 0;
6560  }
6562  if (!sc->ambient)
6563  return AVERROR(ENOMEM);
6564  sc->ambient->ambient_illuminance = av_make_q(avio_rb32(pb), illuminance_den);
6565  sc->ambient->ambient_light_x = av_make_q(avio_rb16(pb), ambient_den);
6566  sc->ambient->ambient_light_y = av_make_q(avio_rb16(pb), ambient_den);
6567  return 0;
6568 }
6569 
6571 {
6572  AVStream *st;
6573  MOVStreamContext *sc;
6574  enum AVStereo3DType type;
6575  int mode;
6576 
6577  if (c->fc->nb_streams < 1)
6578  return 0;
6579 
6580  st = c->fc->streams[c->fc->nb_streams - 1];
6581  sc = st->priv_data;
6582 
6583  if (atom.size < 5) {
6584  av_log(c->fc, AV_LOG_ERROR, "Empty stereoscopic video box\n");
6585  return AVERROR_INVALIDDATA;
6586  }
6587 
6588  if (sc->stereo3d)
6589  return AVERROR_INVALIDDATA;
6590 
6591  avio_skip(pb, 4); /* version + flags */
6592 
6593  mode = avio_r8(pb);
6594  switch (mode) {
6595  case 0:
6596  type = AV_STEREO3D_2D;
6597  break;
6598  case 1:
6600  break;
6601  case 2:
6603  break;
6604  default:
6605  av_log(c->fc, AV_LOG_WARNING, "Unknown st3d mode value %d\n", mode);
6606  return 0;
6607  }
6608 
6610  if (!sc->stereo3d)
6611  return AVERROR(ENOMEM);
6612 
6613  sc->stereo3d->type = type;
6614  return 0;
6615 }
6616 
6618 {
6619  AVStream *st;
6620  MOVStreamContext *sc;
6621  int size = 0;
6622  int64_t remaining;
6623  uint32_t tag = 0;
6625 
6626  if (c->fc->nb_streams < 1)
6627  return 0;
6628 
6629  st = c->fc->streams[c->fc->nb_streams - 1];
6630  sc = st->priv_data;
6631 
6632  remaining = atom.size;
6633  while (remaining > 0) {
6634  size = avio_rb32(pb);
6635  if (size < 8 || size > remaining ) {
6636  av_log(c->fc, AV_LOG_ERROR, "Invalid child size in pack box\n");
6637  return AVERROR_INVALIDDATA;
6638  }
6639 
6640  tag = avio_rl32(pb);
6641  switch (tag) {
6642  case MKTAG('p','k','i','n'): {
6643  if (size != 16) {
6644  av_log(c->fc, AV_LOG_ERROR, "Invalid size of pkin box: %d\n", size);
6645  return AVERROR_INVALIDDATA;
6646  }
6647  avio_skip(pb, 1); // version
6648  avio_skip(pb, 3); // flags
6649 
6650  tag = avio_rl32(pb);
6651  switch (tag) {
6652  case MKTAG('s','i','d','e'):
6654  break;
6655  case MKTAG('o','v','e','r'):
6657  break;
6658  case 0:
6659  // This means value will be set in another layer
6660  break;
6661  default:
6662  av_log(c->fc, AV_LOG_WARNING, "Unknown tag in pkin: 0x%08X\n", tag);
6663  avio_skip(pb, size - 8);
6664  break;
6665  }
6666 
6667  break;
6668  }
6669  default:
6670  av_log(c->fc, AV_LOG_WARNING, "Unknown tag in pack: 0x%08X\n", tag);
6671  avio_skip(pb, size - 8);
6672  break;
6673  }
6674  remaining -= size;
6675  }
6676 
6677  if (remaining != 0) {
6678  av_log(c->fc, AV_LOG_ERROR, "Broken pack box\n");
6679  return AVERROR_INVALIDDATA;
6680  }
6681 
6682  if (type == AV_STEREO3D_2D)
6683  return 0;
6684 
6685  if (!sc->stereo3d) {
6687  if (!sc->stereo3d)
6688  return AVERROR(ENOMEM);
6689  }
6690 
6691  sc->stereo3d->type = type;
6692 
6693  return 0;
6694 }
6695 
6697 {
6698  AVStream *st;
6699  MOVStreamContext *sc;
6700  int size, version, layout;
6701  int32_t yaw, pitch, roll;
6702  uint32_t l = 0, t = 0, r = 0, b = 0;
6703  uint32_t tag, padding = 0;
6704  enum AVSphericalProjection projection;
6705 
6706  if (c->fc->nb_streams < 1)
6707  return 0;
6708 
6709  st = c->fc->streams[c->fc->nb_streams - 1];
6710  sc = st->priv_data;
6711 
6712  if (atom.size < 8) {
6713  av_log(c->fc, AV_LOG_ERROR, "Empty spherical video box\n");
6714  return AVERROR_INVALIDDATA;
6715  }
6716 
6717  size = avio_rb32(pb);
6718  if (size <= 12 || size > atom.size)
6719  return AVERROR_INVALIDDATA;
6720 
6721  tag = avio_rl32(pb);
6722  if (tag != MKTAG('s','v','h','d')) {
6723  av_log(c->fc, AV_LOG_ERROR, "Missing spherical video header\n");
6724  return 0;
6725  }
6726  version = avio_r8(pb);
6727  if (version != 0) {
6728  av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
6729  version);
6730  return 0;
6731  }
6732  avio_skip(pb, 3); /* flags */
6733  avio_skip(pb, size - 12); /* metadata_source */
6734 
6735  size = avio_rb32(pb);
6736  if (size > atom.size)
6737  return AVERROR_INVALIDDATA;
6738 
6739  tag = avio_rl32(pb);
6740  if (tag != MKTAG('p','r','o','j')) {
6741  av_log(c->fc, AV_LOG_ERROR, "Missing projection box\n");
6742  return 0;
6743  }
6744 
6745  size = avio_rb32(pb);
6746  if (size > atom.size)
6747  return AVERROR_INVALIDDATA;
6748 
6749  tag = avio_rl32(pb);
6750  if (tag != MKTAG('p','r','h','d')) {
6751  av_log(c->fc, AV_LOG_ERROR, "Missing projection header box\n");
6752  return 0;
6753  }
6754  version = avio_r8(pb);
6755  if (version != 0) {
6756  av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
6757  version);
6758  return 0;
6759  }
6760  avio_skip(pb, 3); /* flags */
6761 
6762  /* 16.16 fixed point */
6763  yaw = avio_rb32(pb);
6764  pitch = avio_rb32(pb);
6765  roll = avio_rb32(pb);
6766 
6767  size = avio_rb32(pb);
6768  if (size > atom.size)
6769  return AVERROR_INVALIDDATA;
6770 
6771  tag = avio_rl32(pb);
6772  version = avio_r8(pb);
6773  if (version != 0) {
6774  av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
6775  version);
6776  return 0;
6777  }
6778  avio_skip(pb, 3); /* flags */
6779  switch (tag) {
6780  case MKTAG('c','b','m','p'):
6781  layout = avio_rb32(pb);
6782  if (layout) {
6783  av_log(c->fc, AV_LOG_WARNING,
6784  "Unsupported cubemap layout %d\n", layout);
6785  return 0;
6786  }
6787  projection = AV_SPHERICAL_CUBEMAP;
6788  padding = avio_rb32(pb);
6789  break;
6790  case MKTAG('e','q','u','i'):
6791  t = avio_rb32(pb);
6792  b = avio_rb32(pb);
6793  l = avio_rb32(pb);
6794  r = avio_rb32(pb);
6795 
6796  if (b >= UINT_MAX - t || r >= UINT_MAX - l) {
6797  av_log(c->fc, AV_LOG_ERROR,
6798  "Invalid bounding rectangle coordinates "
6799  "%"PRIu32",%"PRIu32",%"PRIu32",%"PRIu32"\n", l, t, r, b);
6800  return AVERROR_INVALIDDATA;
6801  }
6802 
6803  if (l || t || r || b)
6804  projection = AV_SPHERICAL_EQUIRECTANGULAR_TILE;
6805  else
6806  projection = AV_SPHERICAL_EQUIRECTANGULAR;
6807  break;
6808  default:
6809  av_log(c->fc, AV_LOG_ERROR, "Unknown projection type: %s\n", av_fourcc2str(tag));
6810  return 0;
6811  }
6812 
6814  if (!sc->spherical)
6815  return AVERROR(ENOMEM);
6816 
6817  sc->spherical->projection = projection;
6818 
6819  sc->spherical->yaw = yaw;
6820  sc->spherical->pitch = pitch;
6821  sc->spherical->roll = roll;
6822 
6823  sc->spherical->padding = padding;
6824 
6825  sc->spherical->bound_left = l;
6826  sc->spherical->bound_top = t;
6827  sc->spherical->bound_right = r;
6828  sc->spherical->bound_bottom = b;
6829 
6830  return 0;
6831 }
6832 
6834 {
6835  AVStream *st;
6836  MOVStreamContext *sc;
6837  int size;
6838  uint32_t tag;
6839  enum AVSphericalProjection projection;
6840 
6841  if (c->fc->nb_streams < 1)
6842  return 0;
6843 
6844  st = c->fc->streams[c->fc->nb_streams - 1];
6845  sc = st->priv_data;
6846 
6847  if (atom.size != 16) {
6848  av_log(c->fc, AV_LOG_ERROR, "Invalid size for proj box: %"PRIu64"\n", atom.size);
6849  return AVERROR_INVALIDDATA;
6850  }
6851 
6852  size = avio_rb32(pb);
6853  if (size != 16) {
6854  av_log(c->fc, AV_LOG_ERROR, "Invalid size for prji box: %d\n", size);
6855  return AVERROR_INVALIDDATA;
6856  }
6857 
6858  tag = avio_rl32(pb);
6859  if (tag != MKTAG('p','r','j','i')) {
6860  av_log(c->fc, AV_LOG_ERROR, "Invalid child box of proj box: 0x%08X\n", tag);
6861  return AVERROR_INVALIDDATA;
6862  }
6863 
6864  avio_skip(pb, 1); // version
6865  avio_skip(pb, 3); // flags
6866 
6867  tag = avio_rl32(pb);
6868  switch (tag) {
6869  case MKTAG('r','e','c','t'):
6870  projection = AV_SPHERICAL_RECTILINEAR;
6871  break;
6872  case MKTAG('e','q','u','i'):
6873  projection = AV_SPHERICAL_EQUIRECTANGULAR;
6874  break;
6875  case MKTAG('h','e','q','u'):
6876  projection = AV_SPHERICAL_HALF_EQUIRECTANGULAR;
6877  break;
6878  case MKTAG('f','i','s','h'):
6879  projection = AV_SPHERICAL_FISHEYE;
6880  break;
6881  case MKTAG('p','r','i','m'):
6882  projection = AV_SPHERICAL_PARAMETRIC_IMMERSIVE;
6883  break;
6884  default:
6885  av_log(c->fc, AV_LOG_ERROR, "Invalid projection type in prji box: 0x%08X\n", tag);
6886  return AVERROR_INVALIDDATA;
6887  }
6888 
6890  if (!sc->spherical)
6891  return AVERROR(ENOMEM);
6892 
6893  sc->spherical->projection = projection;
6894 
6895  return 0;
6896 }
6897 
6899 {
6900  AVStream *st;
6901  MOVStreamContext *sc;
6902  int size, flags = 0;
6903  int64_t remaining;
6904  uint32_t tag, baseline = 0;
6907  enum AVStereo3DPrimaryEye primary_eye = AV_PRIMARY_EYE_NONE;
6908  AVRational horizontal_disparity_adjustment = { 0, 1 };
6909 
6910  if (c->fc->nb_streams < 1)
6911  return 0;
6912 
6913  st = c->fc->streams[c->fc->nb_streams - 1];
6914  sc = st->priv_data;
6915 
6916  remaining = atom.size;
6917  while (remaining > 0) {
6918  size = avio_rb32(pb);
6919  if (size < 8 || size > remaining ) {
6920  av_log(c->fc, AV_LOG_ERROR, "Invalid child size in eyes box\n");
6921  return AVERROR_INVALIDDATA;
6922  }
6923 
6924  tag = avio_rl32(pb);
6925  switch (tag) {
6926  case MKTAG('s','t','r','i'): {
6927  int has_right, has_left;
6928  uint8_t tmp;
6929  if (size != 13) {
6930  av_log(c->fc, AV_LOG_ERROR, "Invalid size of stri box: %d\n", size);
6931  return AVERROR_INVALIDDATA;
6932  }
6933  avio_skip(pb, 1); // version
6934  avio_skip(pb, 3); // flags
6935 
6936  tmp = avio_r8(pb);
6937 
6938  // eye_views_reversed
6939  if (tmp & 8) {
6941  }
6942  // has_additional_views
6943  if (tmp & 4) {
6944  // skip...
6945  }
6946 
6947  has_right = tmp & 2; // has_right_eye_view
6948  has_left = tmp & 1; // has_left_eye_view
6949 
6950  if (has_left && has_right)
6951  view = AV_STEREO3D_VIEW_PACKED;
6952  else if (has_left)
6953  view = AV_STEREO3D_VIEW_LEFT;
6954  else if (has_right)
6955  view = AV_STEREO3D_VIEW_RIGHT;
6956  if (has_left || has_right)
6958 
6959  break;
6960  }
6961  case MKTAG('h','e','r','o'): {
6962  int tmp;
6963  if (size != 13) {
6964  av_log(c->fc, AV_LOG_ERROR, "Invalid size of hero box: %d\n", size);
6965  return AVERROR_INVALIDDATA;
6966  }
6967  avio_skip(pb, 1); // version
6968  avio_skip(pb, 3); // flags
6969 
6970  tmp = avio_r8(pb);
6971  if (tmp == 0)
6972  primary_eye = AV_PRIMARY_EYE_NONE;
6973  else if (tmp == 1)
6974  primary_eye = AV_PRIMARY_EYE_LEFT;
6975  else if (tmp == 2)
6976  primary_eye = AV_PRIMARY_EYE_RIGHT;
6977  else
6978  av_log(c->fc, AV_LOG_WARNING, "Unknown hero eye type: %d\n", tmp);
6979 
6980  break;
6981  }
6982  case MKTAG('c','a','m','s'): {
6983  uint32_t subtag;
6984  int subsize;
6985  if (size != 24) {
6986  av_log(c->fc, AV_LOG_ERROR, "Invalid size of cams box: %d\n", size);
6987  return AVERROR_INVALIDDATA;
6988  }
6989 
6990  subsize = avio_rb32(pb);
6991  if (subsize != 16) {
6992  av_log(c->fc, AV_LOG_ERROR, "Invalid size of blin box: %d\n", size);
6993  return AVERROR_INVALIDDATA;
6994  }
6995 
6996  subtag = avio_rl32(pb);
6997  if (subtag != MKTAG('b','l','i','n')) {
6998  av_log(c->fc, AV_LOG_ERROR, "Expected blin box, got 0x%08X\n", subtag);
6999  return AVERROR_INVALIDDATA;
7000  }
7001 
7002  avio_skip(pb, 1); // version
7003  avio_skip(pb, 3); // flags
7004 
7005  baseline = avio_rb32(pb);
7006 
7007  break;
7008  }
7009  case MKTAG('c','m','f','y'): {
7010  uint32_t subtag;
7011  int subsize;
7012  int32_t adjustment;
7013  if (size != 24) {
7014  av_log(c->fc, AV_LOG_ERROR, "Invalid size of cmfy box: %d\n", size);
7015  return AVERROR_INVALIDDATA;
7016  }
7017 
7018  subsize = avio_rb32(pb);
7019  if (subsize != 16) {
7020  av_log(c->fc, AV_LOG_ERROR, "Invalid size of dadj box: %d\n", size);
7021  return AVERROR_INVALIDDATA;
7022  }
7023 
7024  subtag = avio_rl32(pb);
7025  if (subtag != MKTAG('d','a','d','j')) {
7026  av_log(c->fc, AV_LOG_ERROR, "Expected dadj box, got 0x%08X\n", subtag);
7027  return AVERROR_INVALIDDATA;
7028  }
7029 
7030  avio_skip(pb, 1); // version
7031  avio_skip(pb, 3); // flags
7032 
7033  adjustment = (int32_t) avio_rb32(pb);
7034 
7035  horizontal_disparity_adjustment.num = (int) adjustment;
7036  horizontal_disparity_adjustment.den = 10000;
7037 
7038  break;
7039  }
7040  default:
7041  av_log(c->fc, AV_LOG_WARNING, "Unknown tag in eyes: 0x%08X\n", tag);
7042  avio_skip(pb, size - 8);
7043  break;
7044  }
7045  remaining -= size;
7046  }
7047 
7048  if (remaining != 0) {
7049  av_log(c->fc, AV_LOG_ERROR, "Broken eyes box\n");
7050  return AVERROR_INVALIDDATA;
7051  }
7052 
7053  if (type == AV_STEREO3D_2D)
7054  return 0;
7055 
7056  if (!sc->stereo3d) {
7058  if (!sc->stereo3d)
7059  return AVERROR(ENOMEM);
7060  }
7061 
7062  sc->stereo3d->flags = flags;
7063  sc->stereo3d->type = type;
7064  sc->stereo3d->view = view;
7065  sc->stereo3d->primary_eye = primary_eye;
7066  sc->stereo3d->baseline = baseline;
7067  sc->stereo3d->horizontal_disparity_adjustment = horizontal_disparity_adjustment;
7068 
7069  return 0;
7070 }
7071 
7073 {
7074  int size;
7075  int64_t remaining;
7076  uint32_t tag;
7077 
7078  if (c->fc->nb_streams < 1)
7079  return 0;
7080 
7081  if (atom.size < 8) {
7082  av_log(c->fc, AV_LOG_ERROR, "Empty video extension usage box\n");
7083  return AVERROR_INVALIDDATA;
7084  }
7085 
7086  remaining = atom.size;
7087  while (remaining > 0) {
7088  size = avio_rb32(pb);
7089  if (size < 8 || size > remaining ) {
7090  av_log(c->fc, AV_LOG_ERROR, "Invalid child size in vexu box\n");
7091  return AVERROR_INVALIDDATA;
7092  }
7093 
7094  tag = avio_rl32(pb);
7095  switch (tag) {
7096  case MKTAG('p','r','o','j'): {
7097  MOVAtom proj = { tag, size - 8 };
7098  int ret = mov_read_vexu_proj(c, pb, proj);
7099  if (ret < 0)
7100  return ret;
7101  break;
7102  }
7103  case MKTAG('e','y','e','s'): {
7104  MOVAtom eyes = { tag, size - 8 };
7105  int ret = mov_read_eyes(c, pb, eyes);
7106  if (ret < 0)
7107  return ret;
7108  break;
7109  }
7110  case MKTAG('p','a','c','k'): {
7111  MOVAtom pack = { tag, size - 8 };
7112  int ret = mov_read_pack(c, pb, pack);
7113  if (ret < 0)
7114  return ret;
7115  break;
7116  }
7117  default:
7118  av_log(c->fc, AV_LOG_WARNING, "Unknown tag in vexu: 0x%08X\n", tag);
7119  avio_skip(pb, size - 8);
7120  break;
7121  }
7122  remaining -= size;
7123  }
7124 
7125  if (remaining != 0) {
7126  av_log(c->fc, AV_LOG_ERROR, "Broken vexu box\n");
7127  return AVERROR_INVALIDDATA;
7128  }
7129 
7130  return 0;
7131 }
7132 
7134 {
7135  AVStream *st;
7136  MOVStreamContext *sc;
7137 
7138  if (c->fc->nb_streams < 1)
7139  return 0;
7140 
7141  st = c->fc->streams[c->fc->nb_streams - 1];
7142  sc = st->priv_data;
7143 
7144  if (atom.size != 4) {
7145  av_log(c->fc, AV_LOG_ERROR, "Invalid size of hfov box: %"PRIu64"\n", atom.size);
7146  return AVERROR_INVALIDDATA;
7147  }
7148 
7149 
7150  if (!sc->stereo3d) {
7152  if (!sc->stereo3d)
7153  return AVERROR(ENOMEM);
7154  }
7155 
7157  sc->stereo3d->horizontal_field_of_view.den = 1000; // thousands of a degree
7158 
7159  return 0;
7160 }
7161 
7163 {
7164  int ret = 0;
7165  uint8_t *buffer = av_malloc(len + 1);
7166  const char *val;
7167 
7168  if (!buffer)
7169  return AVERROR(ENOMEM);
7170  buffer[len] = '\0';
7171 
7172  ret = ffio_read_size(pb, buffer, len);
7173  if (ret < 0)
7174  goto out;
7175 
7176  /* Check for mandatory keys and values, try to support XML as best-effort */
7177  if (!sc->spherical &&
7178  av_stristr(buffer, "<GSpherical:StitchingSoftware>") &&
7179  (val = av_stristr(buffer, "<GSpherical:Spherical>")) &&
7180  av_stristr(val, "true") &&
7181  (val = av_stristr(buffer, "<GSpherical:Stitched>")) &&
7182  av_stristr(val, "true") &&
7183  (val = av_stristr(buffer, "<GSpherical:ProjectionType>")) &&
7184  av_stristr(val, "equirectangular")) {
7186  if (!sc->spherical)
7187  goto out;
7188 
7190 
7191  if (av_stristr(buffer, "<GSpherical:StereoMode>") && !sc->stereo3d) {
7192  enum AVStereo3DType mode;
7193 
7194  if (av_stristr(buffer, "left-right"))
7196  else if (av_stristr(buffer, "top-bottom"))
7198  else
7199  mode = AV_STEREO3D_2D;
7200 
7202  if (!sc->stereo3d)
7203  goto out;
7204 
7205  sc->stereo3d->type = mode;
7206  }
7207 
7208  /* orientation */
7209  val = av_stristr(buffer, "<GSpherical:InitialViewHeadingDegrees>");
7210  if (val)
7211  sc->spherical->yaw = strtol(val, NULL, 10) * (1 << 16);
7212  val = av_stristr(buffer, "<GSpherical:InitialViewPitchDegrees>");
7213  if (val)
7214  sc->spherical->pitch = strtol(val, NULL, 10) * (1 << 16);
7215  val = av_stristr(buffer, "<GSpherical:InitialViewRollDegrees>");
7216  if (val)
7217  sc->spherical->roll = strtol(val, NULL, 10) * (1 << 16);
7218  }
7219 
7220 out:
7221  av_free(buffer);
7222  return ret;
7223 }
7224 
7226 {
7227  AVStream *st;
7228  MOVStreamContext *sc;
7229  int64_t ret;
7230  AVUUID uuid;
7231  static const AVUUID uuid_isml_manifest = {
7232  0xa5, 0xd4, 0x0b, 0x30, 0xe8, 0x14, 0x11, 0xdd,
7233  0xba, 0x2f, 0x08, 0x00, 0x20, 0x0c, 0x9a, 0x66
7234  };
7235  static const AVUUID uuid_xmp = {
7236  0xbe, 0x7a, 0xcf, 0xcb, 0x97, 0xa9, 0x42, 0xe8,
7237  0x9c, 0x71, 0x99, 0x94, 0x91, 0xe3, 0xaf, 0xac
7238  };
7239  static const AVUUID uuid_spherical = {
7240  0xff, 0xcc, 0x82, 0x63, 0xf8, 0x55, 0x4a, 0x93,
7241  0x88, 0x14, 0x58, 0x7a, 0x02, 0x52, 0x1f, 0xdd,
7242  };
7243 
7244  if (atom.size < AV_UUID_LEN || atom.size >= FFMIN(INT_MAX, SIZE_MAX))
7245  return AVERROR_INVALIDDATA;
7246 
7247  if (c->fc->nb_streams < 1)
7248  return 0;
7249  st = c->fc->streams[c->fc->nb_streams - 1];
7250  sc = st->priv_data;
7251 
7252  ret = ffio_read_size(pb, uuid, AV_UUID_LEN);
7253  if (ret < 0)
7254  return ret;
7255  if (av_uuid_equal(uuid, uuid_isml_manifest)) {
7256  uint8_t *buffer, *ptr;
7257  char *endptr;
7258  size_t len = atom.size - AV_UUID_LEN;
7259 
7260  if (len < 4) {
7261  return AVERROR_INVALIDDATA;
7262  }
7263  ret = avio_skip(pb, 4); // zeroes
7264  len -= 4;
7265 
7266  buffer = av_mallocz(len + 1);
7267  if (!buffer) {
7268  return AVERROR(ENOMEM);
7269  }
7270  ret = ffio_read_size(pb, buffer, len);
7271  if (ret < 0) {
7272  av_free(buffer);
7273  return ret;
7274  }
7275 
7276  ptr = buffer;
7277  while ((ptr = av_stristr(ptr, "systemBitrate=\""))) {
7278  ptr += sizeof("systemBitrate=\"") - 1;
7279  c->bitrates_count++;
7280  c->bitrates = av_realloc_f(c->bitrates, c->bitrates_count, sizeof(*c->bitrates));
7281  if (!c->bitrates) {
7282  c->bitrates_count = 0;
7283  av_free(buffer);
7284  return AVERROR(ENOMEM);
7285  }
7286  errno = 0;
7287  ret = strtol(ptr, &endptr, 10);
7288  if (ret < 0 || errno || *endptr != '"') {
7289  c->bitrates[c->bitrates_count - 1] = 0;
7290  } else {
7291  c->bitrates[c->bitrates_count - 1] = ret;
7292  }
7293  }
7294 
7295  av_free(buffer);
7296  } else if (av_uuid_equal(uuid, uuid_xmp)) {
7297  uint8_t *buffer;
7298  size_t len = atom.size - AV_UUID_LEN;
7299  if (c->export_xmp) {
7300  buffer = av_mallocz(len + 1);
7301  if (!buffer) {
7302  return AVERROR(ENOMEM);
7303  }
7304  ret = ffio_read_size(pb, buffer, len);
7305  if (ret < 0) {
7306  av_free(buffer);
7307  return ret;
7308  }
7309  buffer[len] = '\0';
7310  av_dict_set(&c->fc->metadata, "xmp",
7312  } else {
7313  // skip all uuid atom, which makes it fast for long uuid-xmp file
7314  ret = avio_skip(pb, len);
7315  if (ret < 0)
7316  return ret;
7317  }
7318  } else if (av_uuid_equal(uuid, uuid_spherical)) {
7319  size_t len = atom.size - AV_UUID_LEN;
7320  ret = mov_parse_uuid_spherical(sc, pb, len);
7321  if (ret < 0)
7322  return ret;
7323  if (!sc->spherical)
7324  av_log(c->fc, AV_LOG_WARNING, "Invalid spherical metadata found\n");
7325  }
7326 
7327  return 0;
7328 }
7329 
7331 {
7332  int ret;
7333  uint8_t content[16];
7334 
7335  if (atom.size < 8)
7336  return 0;
7337 
7338  ret = ffio_read_size(pb, content, FFMIN(sizeof(content), atom.size));
7339  if (ret < 0)
7340  return ret;
7341 
7342  if ( !c->found_moov
7343  && !c->found_mdat
7344  && !memcmp(content, "Anevia\x1A\x1A", 8)
7345  && c->use_mfra_for == FF_MOV_FLAG_MFRA_AUTO) {
7346  c->use_mfra_for = FF_MOV_FLAG_MFRA_PTS;
7347  }
7348 
7349  return 0;
7350 }
7351 
7353 {
7354  uint32_t format = avio_rl32(pb);
7355  MOVStreamContext *sc;
7356  enum AVCodecID id;
7357  AVStream *st;
7358 
7359  if (c->fc->nb_streams < 1)
7360  return 0;
7361  st = c->fc->streams[c->fc->nb_streams - 1];
7362  sc = st->priv_data;
7363 
7364  switch (sc->format)
7365  {
7366  case MKTAG('e','n','c','v'): // encrypted video
7367  case MKTAG('e','n','c','a'): // encrypted audio
7368  id = mov_codec_id(st, format);
7369  if (st->codecpar->codec_id != AV_CODEC_ID_NONE &&
7370  st->codecpar->codec_id != id) {
7371  av_log(c->fc, AV_LOG_WARNING,
7372  "ignoring 'frma' atom of '%.4s', stream has codec id %d\n",
7373  (char*)&format, st->codecpar->codec_id);
7374  break;
7375  }
7376 
7377  st->codecpar->codec_id = id;
7378  sc->format = format;
7379  break;
7380 
7381  default:
7382  if (format != sc->format) {
7383  av_log(c->fc, AV_LOG_WARNING,
7384  "ignoring 'frma' atom of '%.4s', stream format is '%.4s'\n",
7385  (char*)&format, (char*)&sc->format);
7386  }
7387  break;
7388  }
7389 
7390  return 0;
7391 }
7392 
7393 /**
7394  * Gets the current encryption info and associated current stream context. If
7395  * we are parsing a track fragment, this will return the specific encryption
7396  * info for this fragment; otherwise this will return the global encryption
7397  * info for the current stream.
7398  */
7400 {
7401  MOVFragmentStreamInfo *frag_stream_info;
7402  AVStream *st;
7403  int i;
7404 
7405  frag_stream_info = get_current_frag_stream_info(&c->frag_index);
7406  if (frag_stream_info) {
7407  for (i = 0; i < c->fc->nb_streams; i++) {
7408  *sc = c->fc->streams[i]->priv_data;
7409  if ((*sc)->id == frag_stream_info->id) {
7410  st = c->fc->streams[i];
7411  break;
7412  }
7413  }
7414  if (i == c->fc->nb_streams)
7415  return 0;
7416  *sc = st->priv_data;
7417 
7418  if (!frag_stream_info->encryption_index) {
7419  // If this stream isn't encrypted, don't create the index.
7420  if (!(*sc)->cenc.default_encrypted_sample)
7421  return 0;
7422  frag_stream_info->encryption_index = av_mallocz(sizeof(*frag_stream_info->encryption_index));
7423  if (!frag_stream_info->encryption_index)
7424  return AVERROR(ENOMEM);
7425  }
7426  *encryption_index = frag_stream_info->encryption_index;
7427  return 1;
7428  } else {
7429  // No current track fragment, using stream level encryption info.
7430 
7431  if (c->fc->nb_streams < 1)
7432  return 0;
7433  st = c->fc->streams[c->fc->nb_streams - 1];
7434  *sc = st->priv_data;
7435 
7436  if (!(*sc)->cenc.encryption_index) {
7437  // If this stream isn't encrypted, don't create the index.
7438  if (!(*sc)->cenc.default_encrypted_sample)
7439  return 0;
7440  (*sc)->cenc.encryption_index = av_mallocz(sizeof(*frag_stream_info->encryption_index));
7441  if (!(*sc)->cenc.encryption_index)
7442  return AVERROR(ENOMEM);
7443  }
7444 
7445  *encryption_index = (*sc)->cenc.encryption_index;
7446  return 1;
7447  }
7448 }
7449 
7451 {
7452  int i, ret;
7453  unsigned int subsample_count;
7454  AVSubsampleEncryptionInfo *subsamples;
7455 
7456  if (!sc->cenc.default_encrypted_sample) {
7457  av_log(c->fc, AV_LOG_ERROR, "Missing schm or tenc\n");
7458  return AVERROR_INVALIDDATA;
7459  }
7460 
7461  if (sc->cenc.per_sample_iv_size || use_subsamples) {
7463  if (!*sample)
7464  return AVERROR(ENOMEM);
7465  } else
7466  *sample = NULL;
7467 
7468  if (sc->cenc.per_sample_iv_size != 0) {
7469  if ((ret = ffio_read_size(pb, (*sample)->iv, sc->cenc.per_sample_iv_size)) < 0) {
7470  av_log(c->fc, AV_LOG_ERROR, "failed to read the initialization vector\n");
7472  *sample = NULL;
7473  return ret;
7474  }
7475  }
7476 
7477  if (use_subsamples) {
7478  subsample_count = avio_rb16(pb);
7479  av_free((*sample)->subsamples);
7480  (*sample)->subsamples = av_calloc(subsample_count, sizeof(*subsamples));
7481  if (!(*sample)->subsamples) {
7483  *sample = NULL;
7484  return AVERROR(ENOMEM);
7485  }
7486 
7487  for (i = 0; i < subsample_count && !pb->eof_reached; i++) {
7488  (*sample)->subsamples[i].bytes_of_clear_data = avio_rb16(pb);
7489  (*sample)->subsamples[i].bytes_of_protected_data = avio_rb32(pb);
7490  }
7491 
7492  if (pb->eof_reached) {
7493  av_log(c->fc, AV_LOG_ERROR, "hit EOF while reading sub-sample encryption info\n");
7495  *sample = NULL;
7496  return AVERROR_INVALIDDATA;
7497  }
7498  (*sample)->subsample_count = subsample_count;
7499  }
7500 
7501  return 0;
7502 }
7503 
7505 {
7506  AVEncryptionInfo **encrypted_samples;
7507  MOVEncryptionIndex *encryption_index;
7508  MOVStreamContext *sc;
7509  int use_subsamples, ret;
7510  unsigned int sample_count, i, alloc_size = 0;
7511 
7512  ret = get_current_encryption_info(c, &encryption_index, &sc);
7513  if (ret != 1)
7514  return ret;
7515 
7516  if (encryption_index->nb_encrypted_samples) {
7517  // This can happen if we have both saio/saiz and senc atoms.
7518  av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in senc\n");
7519  return 0;
7520  }
7521 
7522  avio_r8(pb); /* version */
7523  use_subsamples = avio_rb24(pb) & 0x02; /* flags */
7524 
7525  sample_count = avio_rb32(pb);
7526  if (sample_count >= INT_MAX / sizeof(*encrypted_samples))
7527  return AVERROR(ENOMEM);
7528 
7529  for (i = 0; i < sample_count; i++) {
7530  unsigned int min_samples = FFMIN(FFMAX(i + 1, 1024 * 1024), sample_count);
7531  encrypted_samples = av_fast_realloc(encryption_index->encrypted_samples, &alloc_size,
7532  min_samples * sizeof(*encrypted_samples));
7533  if (encrypted_samples) {
7534  encryption_index->encrypted_samples = encrypted_samples;
7535 
7537  c, pb, sc, &encryption_index->encrypted_samples[i], use_subsamples);
7538  } else {
7539  ret = AVERROR(ENOMEM);
7540  }
7541  if (pb->eof_reached) {
7542  av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading senc\n");
7543  if (ret >= 0)
7544  av_encryption_info_free(encryption_index->encrypted_samples[i]);
7546  }
7547 
7548  if (ret < 0) {
7549  for (; i > 0; i--)
7550  av_encryption_info_free(encryption_index->encrypted_samples[i - 1]);
7551  av_freep(&encryption_index->encrypted_samples);
7552  return ret;
7553  }
7554  }
7555  encryption_index->nb_encrypted_samples = sample_count;
7556 
7557  return 0;
7558 }
7559 
7561 {
7562  AVEncryptionInfo **sample, **encrypted_samples;
7563  int64_t prev_pos;
7564  size_t sample_count, sample_info_size, i;
7565  int ret = 0;
7566  unsigned int alloc_size = 0;
7567 
7568  if (encryption_index->nb_encrypted_samples)
7569  return 0;
7570  sample_count = encryption_index->auxiliary_info_sample_count;
7571  if (encryption_index->auxiliary_offsets_count != 1) {
7572  av_log(c->fc, AV_LOG_ERROR, "Multiple auxiliary info chunks are not supported\n");
7573  return AVERROR_PATCHWELCOME;
7574  }
7575  if (sample_count >= INT_MAX / sizeof(*encrypted_samples))
7576  return AVERROR(ENOMEM);
7577 
7578  prev_pos = avio_tell(pb);
7579  if (!(pb->seekable & AVIO_SEEKABLE_NORMAL) ||
7580  avio_seek(pb, encryption_index->auxiliary_offsets[0], SEEK_SET) != encryption_index->auxiliary_offsets[0]) {
7581  av_log(c->fc, AV_LOG_INFO, "Failed to seek for auxiliary info, will only parse senc atoms for encryption info\n");
7582  goto finish;
7583  }
7584 
7585  for (i = 0; i < sample_count && !pb->eof_reached; i++) {
7586  unsigned int min_samples = FFMIN(FFMAX(i + 1, 1024 * 1024), sample_count);
7587  encrypted_samples = av_fast_realloc(encryption_index->encrypted_samples, &alloc_size,
7588  min_samples * sizeof(*encrypted_samples));
7589  if (!encrypted_samples) {
7590  ret = AVERROR(ENOMEM);
7591  goto finish;
7592  }
7593  encryption_index->encrypted_samples = encrypted_samples;
7594 
7595  sample = &encryption_index->encrypted_samples[i];
7596  sample_info_size = encryption_index->auxiliary_info_default_size
7597  ? encryption_index->auxiliary_info_default_size
7598  : encryption_index->auxiliary_info_sizes[i];
7599 
7600  ret = mov_read_sample_encryption_info(c, pb, sc, sample, sample_info_size > sc->cenc.per_sample_iv_size);
7601  if (ret < 0)
7602  goto finish;
7603  }
7604  if (pb->eof_reached) {
7605  av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading auxiliary info\n");
7607  } else {
7608  encryption_index->nb_encrypted_samples = sample_count;
7609  }
7610 
7611 finish:
7612  avio_seek(pb, prev_pos, SEEK_SET);
7613  if (ret < 0) {
7614  for (; i > 0; i--) {
7615  av_encryption_info_free(encryption_index->encrypted_samples[i - 1]);
7616  }
7617  av_freep(&encryption_index->encrypted_samples);
7618  }
7619  return ret;
7620 }
7621 
7623 {
7624  MOVEncryptionIndex *encryption_index;
7625  MOVStreamContext *sc;
7626  int ret;
7627  unsigned int sample_count, aux_info_type, aux_info_param;
7628 
7629  ret = get_current_encryption_info(c, &encryption_index, &sc);
7630  if (ret != 1)
7631  return ret;
7632 
7633  if (encryption_index->nb_encrypted_samples) {
7634  // This can happen if we have both saio/saiz and senc atoms.
7635  av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in saiz\n");
7636  return 0;
7637  }
7638 
7639  if (encryption_index->auxiliary_info_sample_count) {
7640  av_log(c->fc, AV_LOG_ERROR, "Duplicate saiz atom\n");
7641  return AVERROR_INVALIDDATA;
7642  }
7643 
7644  avio_r8(pb); /* version */
7645  if (avio_rb24(pb) & 0x01) { /* flags */
7646  aux_info_type = avio_rb32(pb);
7647  aux_info_param = avio_rb32(pb);
7648  if (sc->cenc.default_encrypted_sample) {
7649  if (aux_info_type != sc->cenc.default_encrypted_sample->scheme) {
7650  av_log(c->fc, AV_LOG_DEBUG, "Ignoring saiz box with non-zero aux_info_type\n");
7651  return 0;
7652  }
7653  if (aux_info_param != 0) {
7654  av_log(c->fc, AV_LOG_DEBUG, "Ignoring saiz box with non-zero aux_info_type_parameter\n");
7655  return 0;
7656  }
7657  } else {
7658  // Didn't see 'schm' or 'tenc', so this isn't encrypted.
7659  if ((aux_info_type == MKBETAG('c','e','n','c') ||
7660  aux_info_type == MKBETAG('c','e','n','s') ||
7661  aux_info_type == MKBETAG('c','b','c','1') ||
7662  aux_info_type == MKBETAG('c','b','c','s')) &&
7663  aux_info_param == 0) {
7664  av_log(c->fc, AV_LOG_ERROR, "Saw encrypted saiz without schm/tenc\n");
7665  return AVERROR_INVALIDDATA;
7666  } else {
7667  return 0;
7668  }
7669  }
7670  } else if (!sc->cenc.default_encrypted_sample) {
7671  // Didn't see 'schm' or 'tenc', so this isn't encrypted.
7672  return 0;
7673  }
7674 
7675  encryption_index->auxiliary_info_default_size = avio_r8(pb);
7676  sample_count = avio_rb32(pb);
7677 
7678  if (encryption_index->auxiliary_info_default_size == 0) {
7679  if (sample_count == 0)
7680  return AVERROR_INVALIDDATA;
7681 
7682  encryption_index->auxiliary_info_sizes = av_malloc(sample_count);
7683  if (!encryption_index->auxiliary_info_sizes)
7684  return AVERROR(ENOMEM);
7685 
7686  ret = avio_read(pb, encryption_index->auxiliary_info_sizes, sample_count);
7687  if (ret != sample_count) {
7688  av_freep(&encryption_index->auxiliary_info_sizes);
7689 
7690  if (ret >= 0)
7692  av_log(c->fc, AV_LOG_ERROR, "Failed to read the auxiliary info, %s\n",
7693  av_err2str(ret));
7694  return ret;
7695  }
7696  }
7697  encryption_index->auxiliary_info_sample_count = sample_count;
7698 
7699  if (encryption_index->auxiliary_offsets_count) {
7700  return mov_parse_auxiliary_info(c, sc, pb, encryption_index);
7701  }
7702 
7703  return 0;
7704 }
7705 
7707 {
7708  uint64_t *auxiliary_offsets;
7709  MOVEncryptionIndex *encryption_index;
7710  MOVStreamContext *sc;
7711  int i, ret;
7712  unsigned int version, entry_count, aux_info_type, aux_info_param;
7713  unsigned int alloc_size = 0;
7714 
7715  ret = get_current_encryption_info(c, &encryption_index, &sc);
7716  if (ret != 1)
7717  return ret;
7718 
7719  if (encryption_index->nb_encrypted_samples) {
7720  // This can happen if we have both saio/saiz and senc atoms.
7721  av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in saio\n");
7722  return 0;
7723  }
7724 
7725  if (encryption_index->auxiliary_offsets_count) {
7726  av_log(c->fc, AV_LOG_ERROR, "Duplicate saio atom\n");
7727  return AVERROR_INVALIDDATA;
7728  }
7729 
7730  version = avio_r8(pb); /* version */
7731  if (avio_rb24(pb) & 0x01) { /* flags */
7732  aux_info_type = avio_rb32(pb);
7733  aux_info_param = avio_rb32(pb);
7734  if (sc->cenc.default_encrypted_sample) {
7735  if (aux_info_type != sc->cenc.default_encrypted_sample->scheme) {
7736  av_log(c->fc, AV_LOG_DEBUG, "Ignoring saio box with non-zero aux_info_type\n");
7737  return 0;
7738  }
7739  if (aux_info_param != 0) {
7740  av_log(c->fc, AV_LOG_DEBUG, "Ignoring saio box with non-zero aux_info_type_parameter\n");
7741  return 0;
7742  }
7743  } else {
7744  // Didn't see 'schm' or 'tenc', so this isn't encrypted.
7745  if ((aux_info_type == MKBETAG('c','e','n','c') ||
7746  aux_info_type == MKBETAG('c','e','n','s') ||
7747  aux_info_type == MKBETAG('c','b','c','1') ||
7748  aux_info_type == MKBETAG('c','b','c','s')) &&
7749  aux_info_param == 0) {
7750  av_log(c->fc, AV_LOG_ERROR, "Saw encrypted saio without schm/tenc\n");
7751  return AVERROR_INVALIDDATA;
7752  } else {
7753  return 0;
7754  }
7755  }
7756  } else if (!sc->cenc.default_encrypted_sample) {
7757  // Didn't see 'schm' or 'tenc', so this isn't encrypted.
7758  return 0;
7759  }
7760 
7761  entry_count = avio_rb32(pb);
7762  if (entry_count >= INT_MAX / sizeof(*auxiliary_offsets))
7763  return AVERROR(ENOMEM);
7764 
7765  for (i = 0; i < entry_count && !pb->eof_reached; i++) {
7766  unsigned int min_offsets = FFMIN(FFMAX(i + 1, 1024), entry_count);
7767  auxiliary_offsets = av_fast_realloc(
7768  encryption_index->auxiliary_offsets, &alloc_size,
7769  min_offsets * sizeof(*auxiliary_offsets));
7770  if (!auxiliary_offsets) {
7771  av_freep(&encryption_index->auxiliary_offsets);
7772  return AVERROR(ENOMEM);
7773  }
7774  encryption_index->auxiliary_offsets = auxiliary_offsets;
7775 
7776  if (version == 0) {
7777  encryption_index->auxiliary_offsets[i] = avio_rb32(pb);
7778  } else {
7779  encryption_index->auxiliary_offsets[i] = avio_rb64(pb);
7780  }
7781  if (c->frag_index.current >= 0) {
7782  encryption_index->auxiliary_offsets[i] += c->fragment.base_data_offset;
7783  }
7784  }
7785 
7786  if (pb->eof_reached) {
7787  av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading saio\n");
7788  av_freep(&encryption_index->auxiliary_offsets);
7789  return AVERROR_INVALIDDATA;
7790  }
7791 
7792  encryption_index->auxiliary_offsets_count = entry_count;
7793 
7794  if (encryption_index->auxiliary_info_sample_count) {
7795  return mov_parse_auxiliary_info(c, sc, pb, encryption_index);
7796  }
7797 
7798  return 0;
7799 }
7800 
7802 {
7803  AVEncryptionInitInfo *info, *old_init_info;
7804  uint8_t **key_ids;
7805  AVStream *st;
7806  const AVPacketSideData *old_side_data;
7807  uint8_t *side_data, *extra_data;
7808  size_t side_data_size;
7809  int ret = 0;
7810  unsigned int version, kid_count, extra_data_size, alloc_size = 0;
7811 
7812  if (c->fc->nb_streams < 1)
7813  return 0;
7814  st = c->fc->streams[c->fc->nb_streams-1];
7815 
7816  version = avio_r8(pb); /* version */
7817  avio_rb24(pb); /* flags */
7818 
7819  info = av_encryption_init_info_alloc(/* system_id_size */ 16, /* num_key_ids */ 0,
7820  /* key_id_size */ 16, /* data_size */ 0);
7821  if (!info)
7822  return AVERROR(ENOMEM);
7823 
7824  if ((ret = ffio_read_size(pb, info->system_id, 16)) < 0) {
7825  av_log(c->fc, AV_LOG_ERROR, "Failed to read the system id\n");
7826  goto finish;
7827  }
7828 
7829  if (version > 0) {
7830  kid_count = avio_rb32(pb);
7831  if (kid_count >= INT_MAX / sizeof(*key_ids)) {
7832  ret = AVERROR(ENOMEM);
7833  goto finish;
7834  }
7835 
7836  for (unsigned int i = 0; i < kid_count && !pb->eof_reached; i++) {
7837  unsigned int min_kid_count = FFMIN(FFMAX(i + 1, 1024), kid_count);
7838  key_ids = av_fast_realloc(info->key_ids, &alloc_size,
7839  min_kid_count * sizeof(*key_ids));
7840  if (!key_ids) {
7841  ret = AVERROR(ENOMEM);
7842  goto finish;
7843  }
7844  info->key_ids = key_ids;
7845 
7846  info->key_ids[i] = av_mallocz(16);
7847  if (!info->key_ids[i]) {
7848  ret = AVERROR(ENOMEM);
7849  goto finish;
7850  }
7851  info->num_key_ids = i + 1;
7852 
7853  if ((ret = ffio_read_size(pb, info->key_ids[i], 16)) < 0) {
7854  av_log(c->fc, AV_LOG_ERROR, "Failed to read the key id\n");
7855  goto finish;
7856  }
7857  }
7858 
7859  if (pb->eof_reached) {
7860  av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading pssh\n");
7862  goto finish;
7863  }
7864  }
7865 
7866  extra_data_size = avio_rb32(pb);
7867  extra_data = av_malloc(extra_data_size);
7868  if (!extra_data) {
7869  ret = AVERROR(ENOMEM);
7870  goto finish;
7871  }
7872  ret = avio_read(pb, extra_data, extra_data_size);
7873  if (ret != extra_data_size) {
7874  av_free(extra_data);
7875 
7876  if (ret >= 0)
7878  goto finish;
7879  }
7880 
7881  av_freep(&info->data); // malloc(0) may still allocate something.
7882  info->data = extra_data;
7883  info->data_size = extra_data_size;
7884 
7885  // If there is existing initialization data, append to the list.
7888  if (old_side_data) {
7889  old_init_info = av_encryption_init_info_get_side_data(old_side_data->data, old_side_data->size);
7890  if (old_init_info) {
7891  // Append to the end of the list.
7892  for (AVEncryptionInitInfo *cur = old_init_info;; cur = cur->next) {
7893  if (!cur->next) {
7894  cur->next = info;
7895  break;
7896  }
7897  }
7898  info = old_init_info;
7899  } else {
7900  // Assume existing side-data will be valid, so the only error we could get is OOM.
7901  ret = AVERROR(ENOMEM);
7902  goto finish;
7903  }
7904  }
7905 
7906  side_data = av_encryption_init_info_add_side_data(info, &side_data_size);
7907  if (!side_data) {
7908  ret = AVERROR(ENOMEM);
7909  goto finish;
7910  }
7914  side_data, side_data_size, 0))
7915  av_free(side_data);
7916 
7917 finish:
7919  return ret;
7920 }
7921 
7923 {
7924  AVStream *st;
7925  MOVStreamContext *sc;
7926 
7927  if (c->fc->nb_streams < 1)
7928  return 0;
7929  st = c->fc->streams[c->fc->nb_streams-1];
7930  sc = st->priv_data;
7931 
7932  if (sc->pseudo_stream_id != 0) {
7933  av_log(c->fc, AV_LOG_ERROR, "schm boxes are only supported in first sample descriptor\n");
7934  return AVERROR_PATCHWELCOME;
7935  }
7936 
7937  if (atom.size < 8)
7938  return AVERROR_INVALIDDATA;
7939 
7940  avio_rb32(pb); /* version and flags */
7941 
7942  if (!sc->cenc.default_encrypted_sample) {
7944  if (!sc->cenc.default_encrypted_sample) {
7945  return AVERROR(ENOMEM);
7946  }
7947  }
7948 
7950  return 0;
7951 }
7952 
7954 {
7955  AVStream *st;
7956  MOVStreamContext *sc;
7957  unsigned int version, pattern, is_protected, iv_size;
7958 
7959  if (c->fc->nb_streams < 1)
7960  return 0;
7961  st = c->fc->streams[c->fc->nb_streams-1];
7962  sc = st->priv_data;
7963 
7964  if (sc->pseudo_stream_id != 0) {
7965  av_log(c->fc, AV_LOG_ERROR, "tenc atom are only supported in first sample descriptor\n");
7966  return AVERROR_PATCHWELCOME;
7967  }
7968 
7969  if (!sc->cenc.default_encrypted_sample) {
7971  if (!sc->cenc.default_encrypted_sample) {
7972  return AVERROR(ENOMEM);
7973  }
7974  }
7975 
7976  if (atom.size < 20)
7977  return AVERROR_INVALIDDATA;
7978 
7979  version = avio_r8(pb); /* version */
7980  avio_rb24(pb); /* flags */
7981 
7982  avio_r8(pb); /* reserved */
7983  pattern = avio_r8(pb);
7984 
7985  if (version > 0) {
7986  sc->cenc.default_encrypted_sample->crypt_byte_block = pattern >> 4;
7987  sc->cenc.default_encrypted_sample->skip_byte_block = pattern & 0xf;
7988  }
7989 
7990  is_protected = avio_r8(pb);
7991  if (is_protected && !sc->cenc.encryption_index) {
7992  // The whole stream should be by-default encrypted.
7994  if (!sc->cenc.encryption_index)
7995  return AVERROR(ENOMEM);
7996  }
7997  sc->cenc.per_sample_iv_size = avio_r8(pb);
7998  if (sc->cenc.per_sample_iv_size != 0 && sc->cenc.per_sample_iv_size != 8 &&
7999  sc->cenc.per_sample_iv_size != 16) {
8000  av_log(c->fc, AV_LOG_ERROR, "invalid per-sample IV size value\n");
8001  return AVERROR_INVALIDDATA;
8002  }
8003  if (avio_read(pb, sc->cenc.default_encrypted_sample->key_id, 16) != 16) {
8004  av_log(c->fc, AV_LOG_ERROR, "failed to read the default key ID\n");
8005  return AVERROR_INVALIDDATA;
8006  }
8007 
8008  if (is_protected && !sc->cenc.per_sample_iv_size) {
8009  iv_size = avio_r8(pb);
8010  if (iv_size != 8 && iv_size != 16) {
8011  av_log(c->fc, AV_LOG_ERROR, "invalid default_constant_IV_size in tenc atom\n");
8012  return AVERROR_INVALIDDATA;
8013  }
8014 
8015  if (avio_read(pb, sc->cenc.default_encrypted_sample->iv, iv_size) != iv_size) {
8016  av_log(c->fc, AV_LOG_ERROR, "failed to read the default IV\n");
8017  return AVERROR_INVALIDDATA;
8018  }
8019  }
8020 
8021  return 0;
8022 }
8023 
8025 {
8026  AVStream *st;
8027  int last, type, size, ret;
8028  uint8_t buf[4];
8029 
8030  if (c->fc->nb_streams < 1)
8031  return 0;
8032  st = c->fc->streams[c->fc->nb_streams-1];
8033 
8034  if ((uint64_t)atom.size > (1<<30) || atom.size < 42)
8035  return AVERROR_INVALIDDATA;
8036 
8037  /* Check FlacSpecificBox version. */
8038  if (avio_r8(pb) != 0)
8039  return AVERROR_INVALIDDATA;
8040 
8041  avio_rb24(pb); /* Flags */
8042 
8043  if (avio_read(pb, buf, sizeof(buf)) != sizeof(buf)) {
8044  av_log(c->fc, AV_LOG_ERROR, "failed to read FLAC metadata block header\n");
8045  return pb->error < 0 ? pb->error : AVERROR_INVALIDDATA;
8046  }
8047  flac_parse_block_header(buf, &last, &type, &size);
8048 
8050  av_log(c->fc, AV_LOG_ERROR, "STREAMINFO must be first FLACMetadataBlock\n");
8051  return AVERROR_INVALIDDATA;
8052  }
8053 
8054  ret = ff_get_extradata(c->fc, st->codecpar, pb, size);
8055  if (ret < 0)
8056  return ret;
8057 
8058  if (!last)
8059  av_log(c->fc, AV_LOG_WARNING, "non-STREAMINFO FLACMetadataBlock(s) ignored\n");
8060 
8061  return 0;
8062 }
8063 
8065 {
8066  int i, ret;
8067  int bytes_of_protected_data;
8068 
8069  if (!sc->cenc.aes_ctr) {
8070  /* initialize the cipher */
8071  sc->cenc.aes_ctr = av_aes_ctr_alloc();
8072  if (!sc->cenc.aes_ctr) {
8073  return AVERROR(ENOMEM);
8074  }
8075 
8076  ret = av_aes_ctr_init(sc->cenc.aes_ctr, c->decryption_key);
8077  if (ret < 0) {
8078  return ret;
8079  }
8080  }
8081 
8083 
8084  if (!sample->subsample_count) {
8085  /* decrypt the whole packet */
8087  return 0;
8088  }
8089 
8090  for (i = 0; i < sample->subsample_count; i++) {
8091  if (sample->subsamples[i].bytes_of_clear_data + sample->subsamples[i].bytes_of_protected_data > size) {
8092  av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n");
8093  return AVERROR_INVALIDDATA;
8094  }
8095 
8096  /* skip the clear bytes */
8097  input += sample->subsamples[i].bytes_of_clear_data;
8098  size -= sample->subsamples[i].bytes_of_clear_data;
8099 
8100  /* decrypt the encrypted bytes */
8101 
8102  bytes_of_protected_data = sample->subsamples[i].bytes_of_protected_data;
8103  av_aes_ctr_crypt(sc->cenc.aes_ctr, input, input, bytes_of_protected_data);
8104 
8105  input += bytes_of_protected_data;
8106  size -= bytes_of_protected_data;
8107  }
8108 
8109  if (size > 0) {
8110  av_log(c->fc, AV_LOG_ERROR, "leftover packet bytes after subsample processing\n");
8111  return AVERROR_INVALIDDATA;
8112  }
8113 
8114  return 0;
8115 }
8116 
8118 {
8119  int i, ret;
8120  int num_of_encrypted_blocks;
8121  uint8_t iv[16];
8122 
8123  if (!sc->cenc.aes_ctx) {
8124  /* initialize the cipher */
8125  sc->cenc.aes_ctx = av_aes_alloc();
8126  if (!sc->cenc.aes_ctx) {
8127  return AVERROR(ENOMEM);
8128  }
8129 
8130  ret = av_aes_init(sc->cenc.aes_ctx, c->decryption_key, 16 * 8, 1);
8131  if (ret < 0) {
8132  return ret;
8133  }
8134  }
8135 
8136  memcpy(iv, sample->iv, 16);
8137 
8138  /* whole-block full sample encryption */
8139  if (!sample->subsample_count) {
8140  /* decrypt the whole packet */
8141  av_aes_crypt(sc->cenc.aes_ctx, input, input, size/16, iv, 1);
8142  return 0;
8143  }
8144 
8145  for (i = 0; i < sample->subsample_count; i++) {
8146  if (sample->subsamples[i].bytes_of_clear_data + sample->subsamples[i].bytes_of_protected_data > size) {
8147  av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n");
8148  return AVERROR_INVALIDDATA;
8149  }
8150 
8151  if (sample->subsamples[i].bytes_of_protected_data % 16) {
8152  av_log(c->fc, AV_LOG_ERROR, "subsample BytesOfProtectedData is not a multiple of 16\n");
8153  return AVERROR_INVALIDDATA;
8154  }
8155 
8156  /* skip the clear bytes */
8157  input += sample->subsamples[i].bytes_of_clear_data;
8158  size -= sample->subsamples[i].bytes_of_clear_data;
8159 
8160  /* decrypt the encrypted bytes */
8161  num_of_encrypted_blocks = sample->subsamples[i].bytes_of_protected_data/16;
8162  if (num_of_encrypted_blocks > 0) {
8163  av_aes_crypt(sc->cenc.aes_ctx, input, input, num_of_encrypted_blocks, iv, 1);
8164  }
8165  input += sample->subsamples[i].bytes_of_protected_data;
8166  size -= sample->subsamples[i].bytes_of_protected_data;
8167  }
8168 
8169  if (size > 0) {
8170  av_log(c->fc, AV_LOG_ERROR, "leftover packet bytes after subsample processing\n");
8171  return AVERROR_INVALIDDATA;
8172  }
8173 
8174  return 0;
8175 }
8176 
8178 {
8179  int i, ret, rem_bytes;
8180  uint8_t *data;
8181 
8182  if (!sc->cenc.aes_ctr) {
8183  /* initialize the cipher */
8184  sc->cenc.aes_ctr = av_aes_ctr_alloc();
8185  if (!sc->cenc.aes_ctr) {
8186  return AVERROR(ENOMEM);
8187  }
8188 
8189  ret = av_aes_ctr_init(sc->cenc.aes_ctr, c->decryption_key);
8190  if (ret < 0) {
8191  return ret;
8192  }
8193  }
8194 
8196 
8197  /* whole-block full sample encryption */
8198  if (!sample->subsample_count) {
8199  /* decrypt the whole packet */
8201  return 0;
8202  } else if (!sample->crypt_byte_block && !sample->skip_byte_block) {
8203  av_log(c->fc, AV_LOG_ERROR, "pattern encryption is not present in 'cens' scheme\n");
8204  return AVERROR_INVALIDDATA;
8205  }
8206 
8207  for (i = 0; i < sample->subsample_count; i++) {
8208  if (sample->subsamples[i].bytes_of_clear_data + sample->subsamples[i].bytes_of_protected_data > size) {
8209  av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n");
8210  return AVERROR_INVALIDDATA;
8211  }
8212 
8213  /* skip the clear bytes */
8214  input += sample->subsamples[i].bytes_of_clear_data;
8215  size -= sample->subsamples[i].bytes_of_clear_data;
8216 
8217  /* decrypt the encrypted bytes */
8218  data = input;
8219  rem_bytes = sample->subsamples[i].bytes_of_protected_data;
8220  while (rem_bytes > 0) {
8221  if (rem_bytes < 16*sample->crypt_byte_block) {
8222  break;
8223  }
8224  av_aes_ctr_crypt(sc->cenc.aes_ctr, data, data, 16*sample->crypt_byte_block);
8225  data += 16*sample->crypt_byte_block;
8226  rem_bytes -= 16*sample->crypt_byte_block;
8227  data += FFMIN(16*sample->skip_byte_block, rem_bytes);
8228  rem_bytes -= FFMIN(16*sample->skip_byte_block, rem_bytes);
8229  }
8230  input += sample->subsamples[i].bytes_of_protected_data;
8231  size -= sample->subsamples[i].bytes_of_protected_data;
8232  }
8233 
8234  if (size > 0) {
8235  av_log(c->fc, AV_LOG_ERROR, "leftover packet bytes after subsample processing\n");
8236  return AVERROR_INVALIDDATA;
8237  }
8238 
8239  return 0;
8240 }
8241 
8243 {
8244  int i, ret, rem_bytes;
8245  uint8_t iv[16];
8246  uint8_t *data;
8247 
8248  if (!sc->cenc.aes_ctx) {
8249  /* initialize the cipher */
8250  sc->cenc.aes_ctx = av_aes_alloc();
8251  if (!sc->cenc.aes_ctx) {
8252  return AVERROR(ENOMEM);
8253  }
8254 
8255  ret = av_aes_init(sc->cenc.aes_ctx, c->decryption_key, 16 * 8, 1);
8256  if (ret < 0) {
8257  return ret;
8258  }
8259  }
8260 
8261  /* whole-block full sample encryption */
8262  if (!sample->subsample_count) {
8263  /* decrypt the whole packet */
8264  memcpy(iv, sample->iv, 16);
8265  av_aes_crypt(sc->cenc.aes_ctx, input, input, size/16, iv, 1);
8266  return 0;
8267  } else if (!sample->crypt_byte_block && !sample->skip_byte_block) {
8268  av_log(c->fc, AV_LOG_ERROR, "pattern encryption is not present in 'cbcs' scheme\n");
8269  return AVERROR_INVALIDDATA;
8270  }
8271 
8272  for (i = 0; i < sample->subsample_count; i++) {
8273  if (sample->subsamples[i].bytes_of_clear_data + sample->subsamples[i].bytes_of_protected_data > size) {
8274  av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n");
8275  return AVERROR_INVALIDDATA;
8276  }
8277 
8278  /* skip the clear bytes */
8279  input += sample->subsamples[i].bytes_of_clear_data;
8280  size -= sample->subsamples[i].bytes_of_clear_data;
8281 
8282  /* decrypt the encrypted bytes */
8283  memcpy(iv, sample->iv, 16);
8284  data = input;
8285  rem_bytes = sample->subsamples[i].bytes_of_protected_data;
8286  while (rem_bytes > 0) {
8287  if (rem_bytes < 16*sample->crypt_byte_block) {
8288  break;
8289  }
8290  av_aes_crypt(sc->cenc.aes_ctx, data, data, sample->crypt_byte_block, iv, 1);
8291  data += 16*sample->crypt_byte_block;
8292  rem_bytes -= 16*sample->crypt_byte_block;
8293  data += FFMIN(16*sample->skip_byte_block, rem_bytes);
8294  rem_bytes -= FFMIN(16*sample->skip_byte_block, rem_bytes);
8295  }
8296  input += sample->subsamples[i].bytes_of_protected_data;
8297  size -= sample->subsamples[i].bytes_of_protected_data;
8298  }
8299 
8300  if (size > 0) {
8301  av_log(c->fc, AV_LOG_ERROR, "leftover packet bytes after subsample processing\n");
8302  return AVERROR_INVALIDDATA;
8303  }
8304 
8305  return 0;
8306 }
8307 
8309 {
8310  if (sample->scheme == MKBETAG('c','e','n','c') && !sample->crypt_byte_block && !sample->skip_byte_block) {
8311  return cenc_scheme_decrypt(c, sc, sample, input, size);
8312  } else if (sample->scheme == MKBETAG('c','b','c','1') && !sample->crypt_byte_block && !sample->skip_byte_block) {
8313  return cbc1_scheme_decrypt(c, sc, sample, input, size);
8314  } else if (sample->scheme == MKBETAG('c','e','n','s')) {
8315  return cens_scheme_decrypt(c, sc, sample, input, size);
8316  } else if (sample->scheme == MKBETAG('c','b','c','s')) {
8317  return cbcs_scheme_decrypt(c, sc, sample, input, size);
8318  } else {
8319  av_log(c->fc, AV_LOG_ERROR, "invalid encryption scheme\n");
8320  return AVERROR_INVALIDDATA;
8321  }
8322 }
8323 
8325 {
8326  int current = frag_index->current;
8327 
8328  if (!frag_index->nb_items)
8329  return NULL;
8330 
8331  // Check frag_index->current is the right one for pkt. It can out of sync.
8332  if (current >= 0 && current < frag_index->nb_items) {
8333  if (frag_index->item[current].moof_offset < pkt->pos &&
8334  (current + 1 == frag_index->nb_items ||
8335  frag_index->item[current + 1].moof_offset > pkt->pos))
8336  return get_frag_stream_info(frag_index, current, id);
8337  }
8338 
8339 
8340  for (int i = 0; i < frag_index->nb_items; i++) {
8341  if (frag_index->item[i].moof_offset > pkt->pos)
8342  break;
8343  current = i;
8344  }
8345  frag_index->current = current;
8346  return get_frag_stream_info(frag_index, current, id);
8347 }
8348 
8349 static int cenc_filter(MOVContext *mov, AVStream* st, MOVStreamContext *sc, AVPacket *pkt, int current_index)
8350 {
8351  MOVFragmentStreamInfo *frag_stream_info;
8352  MOVEncryptionIndex *encryption_index;
8353  AVEncryptionInfo *encrypted_sample;
8354  int encrypted_index, ret;
8355 
8356  frag_stream_info = get_frag_stream_info_from_pkt(&mov->frag_index, pkt, sc->id);
8357  encrypted_index = current_index;
8358  encryption_index = NULL;
8359  if (frag_stream_info) {
8360  // Note this only supports encryption info in the first sample descriptor.
8361  if (frag_stream_info->stsd_id == 1) {
8362  if (frag_stream_info->encryption_index) {
8363  encrypted_index = current_index - frag_stream_info->index_base;
8364  encryption_index = frag_stream_info->encryption_index;
8365  } else {
8366  encryption_index = sc->cenc.encryption_index;
8367  }
8368  }
8369  } else {
8370  encryption_index = sc->cenc.encryption_index;
8371  }
8372 
8373  if (encryption_index) {
8374  if (encryption_index->auxiliary_info_sample_count &&
8375  !encryption_index->nb_encrypted_samples) {
8376  av_log(mov->fc, AV_LOG_ERROR, "saiz atom found without saio\n");
8377  return AVERROR_INVALIDDATA;
8378  }
8379  if (encryption_index->auxiliary_offsets_count &&
8380  !encryption_index->nb_encrypted_samples) {
8381  av_log(mov->fc, AV_LOG_ERROR, "saio atom found without saiz\n");
8382  return AVERROR_INVALIDDATA;
8383  }
8384 
8385  encrypted_sample = NULL;
8386  if (!encryption_index->nb_encrypted_samples) {
8387  // Full-sample encryption with default settings.
8388  encrypted_sample = sc->cenc.default_encrypted_sample;
8389  } else if (encrypted_index >= 0 && encrypted_index < encryption_index->nb_encrypted_samples) {
8390  // Per-sample setting override.
8391  encrypted_sample = encryption_index->encrypted_samples[encrypted_index];
8392  if (!encrypted_sample) {
8393  encrypted_sample = sc->cenc.default_encrypted_sample;
8394  }
8395  }
8396 
8397  if (!encrypted_sample) {
8398  av_log(mov->fc, AV_LOG_ERROR, "Incorrect number of samples in encryption info\n");
8399  return AVERROR_INVALIDDATA;
8400  }
8401 
8402  if (mov->decryption_key) {
8403  return cenc_decrypt(mov, sc, encrypted_sample, pkt->data, pkt->size);
8404  } else {
8405  size_t size;
8406  uint8_t *side_data = av_encryption_info_add_side_data(encrypted_sample, &size);
8407  if (!side_data)
8408  return AVERROR(ENOMEM);
8410  if (ret < 0)
8411  av_free(side_data);
8412  return ret;
8413  }
8414  }
8415 
8416  return 0;
8417 }
8418 
8420 {
8421  const int OPUS_SEEK_PREROLL_MS = 80;
8422  int ret;
8423  AVStream *st;
8424  size_t size;
8425  uint16_t pre_skip;
8426 
8427  if (c->fc->nb_streams < 1)
8428  return 0;
8429  st = c->fc->streams[c->fc->nb_streams-1];
8430 
8431  if ((uint64_t)atom.size > (1<<30) || atom.size < 11)
8432  return AVERROR_INVALIDDATA;
8433 
8434  /* Check OpusSpecificBox version. */
8435  if (avio_r8(pb) != 0) {
8436  av_log(c->fc, AV_LOG_ERROR, "unsupported OpusSpecificBox version\n");
8437  return AVERROR_INVALIDDATA;
8438  }
8439 
8440  /* OpusSpecificBox size plus magic for Ogg OpusHead header. */
8441  size = atom.size + 8;
8442 
8443  if ((ret = ff_alloc_extradata(st->codecpar, size)) < 0)
8444  return ret;
8445 
8446  AV_WL32A(st->codecpar->extradata, MKTAG('O','p','u','s'));
8447  AV_WL32A(st->codecpar->extradata + 4, MKTAG('H','e','a','d'));
8448  AV_WB8(st->codecpar->extradata + 8, 1); /* OpusHead version */
8449  avio_read(pb, st->codecpar->extradata + 9, size - 9);
8450 
8451  /* OpusSpecificBox is stored in big-endian, but OpusHead is
8452  little-endian; aside from the preceding magic and version they're
8453  otherwise currently identical. Data after output gain at offset 16
8454  doesn't need to be bytewapped. */
8455  pre_skip = AV_RB16A(st->codecpar->extradata + 10);
8456  AV_WL16A(st->codecpar->extradata + 10, pre_skip);
8457  AV_WL32A(st->codecpar->extradata + 12, AV_RB32A(st->codecpar->extradata + 12));
8458  AV_WL16A(st->codecpar->extradata + 16, AV_RB16A(st->codecpar->extradata + 16));
8459 
8460  st->codecpar->initial_padding = pre_skip;
8462  (AVRational){1, 1000},
8463  (AVRational){1, 48000});
8464 
8465  return 0;
8466 }
8467 
8469 {
8470  AVStream *st;
8471  unsigned format_info;
8472  int channel_assignment, channel_assignment1, channel_assignment2;
8473  int ratebits;
8474  uint64_t chmask;
8475 
8476  if (c->fc->nb_streams < 1)
8477  return 0;
8478  st = c->fc->streams[c->fc->nb_streams-1];
8479 
8480  if (atom.size < 10)
8481  return AVERROR_INVALIDDATA;
8482 
8483  format_info = avio_rb32(pb);
8484 
8485  ratebits = (format_info >> 28) & 0xF;
8486  channel_assignment1 = (format_info >> 15) & 0x1F;
8487  channel_assignment2 = format_info & 0x1FFF;
8488  if (channel_assignment2)
8489  channel_assignment = channel_assignment2;
8490  else
8491  channel_assignment = channel_assignment1;
8492 
8493  st->codecpar->frame_size = 40 << (ratebits & 0x7);
8494  st->codecpar->sample_rate = mlp_samplerate(ratebits);
8495 
8497  chmask = truehd_layout(channel_assignment);
8499 
8500  return 0;
8501 }
8502 
8504 {
8505  AVStream *st;
8506  uint8_t buf[ISOM_DVCC_DVVC_SIZE];
8507  int ret;
8508  int64_t read_size = atom.size;
8509 
8510  if (c->fc->nb_streams < 1)
8511  return 0;
8512  st = c->fc->streams[c->fc->nb_streams-1];
8513 
8514  // At most 24 bytes
8515  read_size = FFMIN(read_size, ISOM_DVCC_DVVC_SIZE);
8516 
8517  if ((ret = ffio_read_size(pb, buf, read_size)) < 0)
8518  return ret;
8519 
8520  return ff_isom_parse_dvcc_dvvc(c->fc, st, buf, read_size);
8521 }
8522 
8524 {
8525  AVStream *st;
8526  uint8_t *buf;
8527  int ret, old_size, num_arrays;
8528 
8529  if (c->fc->nb_streams < 1)
8530  return 0;
8531  st = c->fc->streams[c->fc->nb_streams-1];
8532 
8533  if (!st->codecpar->extradata_size)
8534  // TODO: handle lhvC when present before hvcC
8535  return 0;
8536 
8537  if (atom.size < 6 || st->codecpar->extradata_size < 23)
8538  return AVERROR_INVALIDDATA;
8539 
8541  if (!buf)
8542  return AVERROR(ENOMEM);
8543  memset(buf + atom.size, 0, AV_INPUT_BUFFER_PADDING_SIZE);
8544 
8545  ret = ffio_read_size(pb, buf, atom.size);
8546  if (ret < 0) {
8547  av_free(buf);
8548  av_log(c->fc, AV_LOG_WARNING, "lhvC atom truncated\n");
8549  return 0;
8550  }
8551 
8552  num_arrays = buf[5];
8553  old_size = st->codecpar->extradata_size;
8554  atom.size -= 8 /* account for mov_realloc_extradata offsetting */
8555  + 6 /* lhvC bytes before the arrays*/;
8556 
8557  ret = mov_realloc_extradata(st->codecpar, atom);
8558  if (ret < 0) {
8559  av_free(buf);
8560  return ret;
8561  }
8562 
8563  st->codecpar->extradata[22] += num_arrays;
8564  memcpy(st->codecpar->extradata + old_size, buf + 6, atom.size + 8);
8565 
8567 
8568  av_free(buf);
8569  return 0;
8570 }
8571 
8573 {
8574  AVFormatContext *ctx = c->fc;
8575  AVStream *st = NULL;
8576  AVBPrint scheme_buf, value_buf;
8577  int64_t scheme_str_len = 0, value_str_len = 0;
8578  int version, flags, ret = AVERROR_BUG;
8579  int64_t size = atom.size;
8580 
8581  if (atom.size < 6)
8582  // 4 bytes for version + flags, 2x 1 byte for null
8583  return AVERROR_INVALIDDATA;
8584 
8585  if (c->fc->nb_streams < 1)
8586  return 0;
8587  st = c->fc->streams[c->fc->nb_streams-1];
8588 
8589  version = avio_r8(pb);
8590  flags = avio_rb24(pb);
8591  size -= 4;
8592 
8593  if (version != 0 || flags != 0) {
8595  "Unsupported 'kind' box with version %d, flags: %x",
8596  version, flags);
8597  return AVERROR_INVALIDDATA;
8598  }
8599 
8600  av_bprint_init(&scheme_buf, 0, AV_BPRINT_SIZE_UNLIMITED);
8601  av_bprint_init(&value_buf, 0, AV_BPRINT_SIZE_UNLIMITED);
8602 
8603  if ((scheme_str_len = ff_read_string_to_bprint_overwrite(pb, &scheme_buf,
8604  size)) < 0) {
8605  ret = scheme_str_len;
8606  goto cleanup;
8607  }
8608 
8609  if (scheme_str_len + 1 >= size) {
8610  // we need to have another string, even if nullptr.
8611  // we check with + 1 since we expect that if size was not hit,
8612  // an additional null was read.
8614  goto cleanup;
8615  }
8616 
8617  size -= scheme_str_len + 1;
8618 
8619  if ((value_str_len = ff_read_string_to_bprint_overwrite(pb, &value_buf,
8620  size)) < 0) {
8621  ret = value_str_len;
8622  goto cleanup;
8623  }
8624 
8625  if (value_str_len == size) {
8626  // in case of no trailing null, box is not valid.
8628  goto cleanup;
8629  }
8630 
8632  "%s stream %d KindBox(scheme: %s, value: %s)\n",
8634  st->index,
8635  scheme_buf.str, value_buf.str);
8636 
8637  for (int i = 0; ff_mov_track_kind_table[i].scheme_uri; i++) {
8639  if (!av_strstart(scheme_buf.str, map.scheme_uri, NULL))
8640  continue;
8641 
8642  for (int j = 0; map.value_maps[j].disposition; j++) {
8643  const struct MP4TrackKindValueMapping value_map = map.value_maps[j];
8644  if (!av_strstart(value_buf.str, value_map.value, NULL))
8645  continue;
8646 
8647  st->disposition |= value_map.disposition;
8648  }
8649  }
8650 
8651  ret = 0;
8652 
8653 cleanup:
8654 
8655  av_bprint_finalize(&scheme_buf, NULL);
8656  av_bprint_finalize(&value_buf, NULL);
8657 
8658  return ret;
8659 }
8660 
8662 {
8663  AVStream *st;
8664  AVChannelLayout ch_layout = { 0 };
8665  int ret, i, version, type;
8666  int ambisonic_order, channel_order, normalization, channel_count;
8667  int ambi_channels, non_diegetic_channels;
8668 
8669  if (c->fc->nb_streams < 1)
8670  return 0;
8671 
8672  st = c->fc->streams[c->fc->nb_streams - 1];
8673 
8674  if (atom.size < 16) {
8675  av_log(c->fc, AV_LOG_ERROR, "SA3D audio box too small\n");
8676  return AVERROR_INVALIDDATA;
8677  }
8678 
8679  version = avio_r8(pb);
8680  if (version) {
8681  av_log(c->fc, AV_LOG_WARNING, "Unsupported SA3D box version %d\n", version);
8682  return 0;
8683  }
8684 
8685  type = avio_r8(pb);
8686  if (type & 0x7f) {
8687  av_log(c->fc, AV_LOG_WARNING,
8688  "Unsupported ambisonic type %d\n", type & 0x7f);
8689  return 0;
8690  }
8691  non_diegetic_channels = (type >> 7) * 2; // head_locked_stereo
8692 
8693  ambisonic_order = avio_rb32(pb);
8694 
8695  channel_order = avio_r8(pb);
8696  if (channel_order) {
8697  av_log(c->fc, AV_LOG_WARNING,
8698  "Unsupported channel_order %d\n", channel_order);
8699  return 0;
8700  }
8701 
8702  normalization = avio_r8(pb);
8703  if (normalization) {
8704  av_log(c->fc, AV_LOG_WARNING,
8705  "Unsupported normalization %d\n", normalization);
8706  return 0;
8707  }
8708 
8709  channel_count = avio_rb32(pb);
8710  if (ambisonic_order < 0 || ambisonic_order > 31 ||
8711  channel_count != ((ambisonic_order + 1LL) * (ambisonic_order + 1LL) +
8712  non_diegetic_channels)) {
8713  av_log(c->fc, AV_LOG_ERROR,
8714  "Invalid number of channels (%d / %d)\n",
8715  channel_count, ambisonic_order);
8716  return 0;
8717  }
8718  ambi_channels = channel_count - non_diegetic_channels;
8719 
8720  ret = av_channel_layout_custom_init(&ch_layout, channel_count);
8721  if (ret < 0)
8722  return 0;
8723 
8724  for (i = 0; i < channel_count; i++) {
8725  unsigned channel = avio_rb32(pb);
8726 
8727  if (channel >= channel_count) {
8728  av_log(c->fc, AV_LOG_ERROR, "Invalid channel index (%d / %d)\n",
8729  channel, ambisonic_order);
8730  av_channel_layout_uninit(&ch_layout);
8731  return 0;
8732  }
8733  if (channel >= ambi_channels)
8734  ch_layout.u.map[i].id = channel - ambi_channels;
8735  else
8736  ch_layout.u.map[i].id = AV_CHAN_AMBISONIC_BASE + channel;
8737  }
8738 
8740  if (ret < 0) {
8741  av_channel_layout_uninit(&ch_layout);
8742  return 0;
8743  }
8744 
8746  st->codecpar->ch_layout = ch_layout;
8747 
8748  return 0;
8749 }
8750 
8752 {
8753  AVStream *st;
8754  int version;
8755 
8756  if (c->fc->nb_streams < 1)
8757  return 0;
8758 
8759  st = c->fc->streams[c->fc->nb_streams - 1];
8760 
8761  if (atom.size < 5) {
8762  av_log(c->fc, AV_LOG_ERROR, "Empty SAND audio box\n");
8763  return AVERROR_INVALIDDATA;
8764  }
8765 
8766  version = avio_r8(pb);
8767  if (version) {
8768  av_log(c->fc, AV_LOG_WARNING, "Unsupported SAND box version %d\n", version);
8769  return 0;
8770  }
8771 
8773 
8774  return 0;
8775 }
8776 
8777 static int rb_size(AVIOContext *pb, int64_t *value, int size)
8778 {
8779  if (size == 0)
8780  *value = 0;
8781  else if (size == 1)
8782  *value = avio_r8(pb);
8783  else if (size == 2)
8784  *value = avio_rb16(pb);
8785  else if (size == 4)
8786  *value = avio_rb32(pb);
8787  else if (size == 8) {
8788  *value = avio_rb64(pb);
8789  if (*value < 0)
8790  return -1;
8791  } else
8792  return -1;
8793  return size;
8794 }
8795 
8797 {
8798  avio_rb32(pb); // version & flags.
8799  c->primary_item_id = avio_rb16(pb);
8800  av_log(c->fc, AV_LOG_TRACE, "pitm: primary_item_id %d\n", c->primary_item_id);
8801  return atom.size;
8802 }
8803 
8805 {
8806  c->idat_offset = avio_tell(pb);
8807  return 0;
8808 }
8809 
8811 {
8812  HEIFItem **heif_item;
8813  int version, offset_size, length_size, base_offset_size, index_size;
8814  int item_count, extent_count;
8815  int64_t base_offset, extent_offset, extent_length;
8816  uint8_t value;
8817 
8818  if (c->found_iloc) {
8819  av_log(c->fc, AV_LOG_INFO, "Duplicate iloc box found\n");
8820  return 0;
8821  }
8822 
8823  version = avio_r8(pb);
8824  avio_rb24(pb); // flags.
8825 
8826  value = avio_r8(pb);
8827  offset_size = (value >> 4) & 0xF;
8828  length_size = value & 0xF;
8829  value = avio_r8(pb);
8830  base_offset_size = (value >> 4) & 0xF;
8831  index_size = !version ? 0 : (value & 0xF);
8832  if (index_size) {
8833  avpriv_report_missing_feature(c->fc, "iloc: index_size != 0");
8834  return AVERROR_PATCHWELCOME;
8835  }
8836  item_count = (version < 2) ? avio_rb16(pb) : avio_rb32(pb);
8837 
8838  heif_item = av_realloc_array(c->heif_item, FFMAX(item_count, c->nb_heif_item), sizeof(*c->heif_item));
8839  if (!heif_item)
8840  return AVERROR(ENOMEM);
8841  c->heif_item = heif_item;
8842  if (item_count > c->nb_heif_item)
8843  memset(&c->heif_item[c->nb_heif_item], 0,
8844  sizeof(*c->heif_item) * (item_count - c->nb_heif_item));
8845  c->nb_heif_item = FFMAX(c->nb_heif_item, item_count);
8846 
8847  av_log(c->fc, AV_LOG_TRACE, "iloc: item_count %d\n", item_count);
8848  for (int i = 0; i < item_count; i++) {
8849  HEIFItem *item = NULL;
8850  int item_id = (version < 2) ? avio_rb16(pb) : avio_rb32(pb);
8851  int offset_type = (version > 0) ? avio_rb16(pb) & 0xf : 0;
8852 
8853  if (avio_feof(pb))
8854  return AVERROR_INVALIDDATA;
8855  if (offset_type > 1) {
8856  avpriv_report_missing_feature(c->fc, "iloc offset type %d", offset_type);
8857  return AVERROR_PATCHWELCOME;
8858  }
8859 
8860  avio_rb16(pb); // data_reference_index.
8861  if (rb_size(pb, &base_offset, base_offset_size) < 0)
8862  return AVERROR_INVALIDDATA;
8863  extent_count = avio_rb16(pb);
8864  if (extent_count > 1) {
8865  // For still AVIF images, we only support one extent item.
8866  avpriv_report_missing_feature(c->fc, "iloc: extent_count > 1");
8867  return AVERROR_PATCHWELCOME;
8868  }
8869 
8870  if (rb_size(pb, &extent_offset, offset_size) < 0 ||
8871  rb_size(pb, &extent_length, length_size) < 0 ||
8872  base_offset > INT64_MAX - extent_offset)
8873  return AVERROR_INVALIDDATA;
8874 
8875  for (int j = 0; j < c->nb_heif_item; j++) {
8876  item = c->heif_item[j];
8877  if (!item)
8878  item = c->heif_item[j] = av_mallocz(sizeof(*item));
8879  else if (item->item_id != item_id)
8880  continue;
8881  break;
8882  }
8883  if (!item)
8884  return AVERROR(ENOMEM);
8885 
8886  item->item_id = item_id;
8887 
8888  if (offset_type == 1)
8889  item->is_idat_relative = 1;
8890  item->extent_length = extent_length;
8891  item->extent_offset = base_offset + extent_offset;
8892  av_log(c->fc, AV_LOG_TRACE, "iloc: item_idx %d, item->item_id %d, offset_type %d, "
8893  "extent_offset %"PRId64", extent_length %"PRId64"\n",
8894  i, item->item_id, offset_type, item->extent_offset, item->extent_length);
8895  }
8896 
8897  c->found_iloc = 1;
8898  return atom.size;
8899 }
8900 
8902 {
8903  HEIFItem *item = NULL;
8904  AVBPrint item_name;
8905  int64_t size = atom.size;
8906  uint32_t item_type;
8907  int item_id;
8908  int version, ret;
8909 
8910  version = avio_r8(pb);
8911  avio_rb24(pb); // flags.
8912  size -= 4;
8913  if (size < 0)
8914  return AVERROR_INVALIDDATA;
8915 
8916  if (version < 2) {
8917  avpriv_report_missing_feature(c->fc, "infe version < 2");
8918  avio_skip(pb, size);
8919  return 1;
8920  }
8921 
8922  item_id = version > 2 ? avio_rb32(pb) : avio_rb16(pb);
8923  avio_rb16(pb); // item_protection_index
8924  item_type = avio_rl32(pb);
8925  size -= 8;
8926  if (size < 1)
8927  return AVERROR_INVALIDDATA;
8928 
8931  if (ret < 0) {
8933  return ret;
8934  }
8935 
8936  av_log(c->fc, AV_LOG_TRACE, "infe: item_id %d, item_type %s, item_name %s\n",
8937  item_id, av_fourcc2str(item_type), item_name.str);
8938 
8939  size -= ret + 1;
8940  if (size > 0)
8941  avio_skip(pb, size);
8942 
8943  for (int i = 0; i < c->nb_heif_item; i++) {
8944  item = c->heif_item[i];
8945  if (!item)
8946  item = c->heif_item[i] = av_mallocz(sizeof(*item));
8947  else if (item->item_id != item_id)
8948  continue;
8949  break;
8950  }
8951  if (!item) {
8953  return AVERROR(ENOMEM);
8954  }
8955 
8956  av_freep(&item->name);
8957  av_bprint_finalize(&item_name, ret ? &item->name : NULL);
8958  item->item_id = item_id;
8959  item->type = item_type;
8960 
8961  switch (item_type) {
8962  case MKTAG('a','v','0','1'):
8963  case MKTAG('j','p','e','g'):
8964  case MKTAG('h','v','c','1'):
8965  ret = heif_add_stream(c, item);
8966  if (ret < 0)
8967  return ret;
8968  break;
8969  }
8970 
8971  return 0;
8972 }
8973 
8975 {
8976  HEIFItem **heif_item;
8977  int entry_count;
8978  int version, got_stream = 0, ret, i;
8979 
8980  if (c->found_iinf) {
8981  av_log(c->fc, AV_LOG_WARNING, "Duplicate iinf box found\n");
8982  return 0;
8983  }
8984 
8985  version = avio_r8(pb);
8986  avio_rb24(pb); // flags.
8987  entry_count = version ? avio_rb32(pb) : avio_rb16(pb);
8988 
8989  heif_item = av_realloc_array(c->heif_item, FFMAX(entry_count, c->nb_heif_item), sizeof(*c->heif_item));
8990  if (!heif_item)
8991  return AVERROR(ENOMEM);
8992  c->heif_item = heif_item;
8993  if (entry_count > c->nb_heif_item)
8994  memset(&c->heif_item[c->nb_heif_item], 0,
8995  sizeof(*c->heif_item) * (entry_count - c->nb_heif_item));
8996  c->nb_heif_item = FFMAX(c->nb_heif_item, entry_count);
8997 
8998  for (i = 0; i < entry_count; i++) {
8999  MOVAtom infe;
9000 
9001  infe.size = avio_rb32(pb) - 8;
9002  infe.type = avio_rl32(pb);
9003  if (avio_feof(pb)) {
9005  goto fail;
9006  }
9007  ret = mov_read_infe(c, pb, infe);
9008  if (ret < 0)
9009  goto fail;
9010  if (!ret)
9011  got_stream = 1;
9012  }
9013 
9014  c->found_iinf = got_stream;
9015  return 0;
9016 fail:
9017  for (; i >= 0; i--) {
9018  HEIFItem *item = c->heif_item[i];
9019 
9020  if (!item)
9021  continue;
9022 
9023  av_freep(&item->name);
9024  }
9025  return ret;
9026 }
9027 
9029 {
9030  HEIFItem *item = NULL;
9031  HEIFGrid *grid;
9032  int entries, i;
9033  int from_item_id = version ? avio_rb32(pb) : avio_rb16(pb);
9034 
9035  for (int i = 0; i < c->nb_heif_grid; i++) {
9036  if (c->heif_grid[i].item->item_id == from_item_id) {
9037  av_log(c->fc, AV_LOG_ERROR, "More than one 'dimg' box "
9038  "referencing the same Derived Image item\n");
9039  return AVERROR_INVALIDDATA;
9040  }
9041  }
9042  for (int i = 0; i < c->nb_heif_item; i++) {
9043  if (!c->heif_item[i] || c->heif_item[i]->item_id != from_item_id)
9044  continue;
9045  item = c->heif_item[i];
9046 
9047  switch (item->type) {
9048  case MKTAG('g','r','i','d'):
9049  case MKTAG('i','o','v','l'):
9050  break;
9051  default:
9052  avpriv_report_missing_feature(c->fc, "Derived Image item of type %s",
9053  av_fourcc2str(item->type));
9054  return 0;
9055  }
9056  break;
9057  }
9058  if (!item) {
9059  av_log(c->fc, AV_LOG_ERROR, "Missing grid information\n");
9060  return AVERROR_INVALIDDATA;
9061  }
9062 
9063  grid = av_realloc_array(c->heif_grid, c->nb_heif_grid + 1U,
9064  sizeof(*c->heif_grid));
9065  if (!grid)
9066  return AVERROR(ENOMEM);
9067  c->heif_grid = grid;
9068  grid = &grid[c->nb_heif_grid++];
9069 
9070  entries = avio_rb16(pb);
9071  grid->tile_id_list = av_malloc_array(entries, sizeof(*grid->tile_id_list));
9072  grid->tile_idx_list = av_calloc(entries, sizeof(*grid->tile_idx_list));
9073  grid->tile_item_list = av_calloc(entries, sizeof(*grid->tile_item_list));
9074  if (!grid->tile_id_list || !grid->tile_item_list || !grid->tile_idx_list)
9075  return AVERROR(ENOMEM);
9076  /* 'to' item ids */
9077  for (i = 0; i < entries; i++)
9078  grid->tile_id_list[i] = version ? avio_rb32(pb) : avio_rb16(pb);
9079  grid->nb_tiles = entries;
9080  grid->item = item;
9081 
9082  av_log(c->fc, AV_LOG_TRACE, "dimg: from_item_id %d, entries %d\n",
9083  from_item_id, entries);
9084 
9085  return 0;
9086 }
9087 
9089 {
9090  int *thmb_item_id;
9091  int entries;
9092  int to_item_id, from_item_id = version ? avio_rb32(pb) : avio_rb16(pb);
9093 
9094  entries = avio_rb16(pb);
9095  if (entries > 1) {
9096  avpriv_request_sample(c->fc, "thmb in iref referencing several items");
9097  return AVERROR_PATCHWELCOME;
9098  }
9099  /* 'to' item ids */
9100  to_item_id = version ? avio_rb32(pb) : avio_rb16(pb);
9101 
9102  if (to_item_id != c->primary_item_id)
9103  return 0;
9104 
9105  /* Put thumnbail IDs into an array */
9106  thmb_item_id = av_dynarray2_add((void **)&c->thmb_item_id, &c->nb_thmb_item,
9107  sizeof(*c->thmb_item_id),
9108  (const void *)&from_item_id);
9109  if (!thmb_item_id)
9110  return AVERROR(ENOMEM);
9111 
9112  av_log(c->fc, AV_LOG_TRACE, "thmb: from_item_id %d, entries %d, nb_thmb: %d\n",
9113  from_item_id, entries, c->nb_thmb_item);
9114 
9115  return 0;
9116 }
9117 
9119 {
9120  int version = avio_r8(pb);
9121  avio_rb24(pb); // flags
9122  atom.size -= 4;
9123 
9124  if (version > 1) {
9125  av_log(c->fc, AV_LOG_WARNING, "Unknown iref box version %d\n", version);
9126  return 0;
9127  }
9128 
9129  while (atom.size) {
9130  uint32_t type, size = avio_rb32(pb);
9131  int64_t next = avio_tell(pb);
9132 
9133  if (size < 14 || next < 0 || next > INT64_MAX - size)
9134  return AVERROR_INVALIDDATA;
9135 
9136  next += size - 4;
9137  type = avio_rl32(pb);
9138  switch (type) {
9139  case MKTAG('d','i','m','g'):
9141  break;
9142  case MKTAG('t','h','m','b'):
9144  break;
9145  default:
9146  av_log(c->fc, AV_LOG_DEBUG, "Unknown iref type %s size %"PRIu32"\n",
9147  av_fourcc2str(type), size);
9148  }
9149 
9150  atom.size -= size;
9151  avio_seek(pb, next, SEEK_SET);
9152  }
9153  return 0;
9154 }
9155 
9157 {
9158  HEIFItem *item;
9159  uint32_t width, height;
9160 
9161  avio_r8(pb); /* version */
9162  avio_rb24(pb); /* flags */
9163  width = avio_rb32(pb);
9164  height = avio_rb32(pb);
9165 
9166  av_log(c->fc, AV_LOG_TRACE, "ispe: item_id %d, width %u, height %u\n",
9167  c->cur_item_id, width, height);
9168 
9169  item = heif_cur_item(c);
9170  if (item) {
9171  item->width = width;
9172  item->height = height;
9173  }
9174 
9175  return 0;
9176 }
9177 
9179 {
9180  HEIFItem *item;
9181  int angle;
9182 
9183  angle = avio_r8(pb) & 0x3;
9184 
9185  av_log(c->fc, AV_LOG_TRACE, "irot: item_id %d, angle %u\n",
9186  c->cur_item_id, angle);
9187 
9188  item = heif_cur_item(c);
9189  if (item) {
9190  // angle * 90 specifies the angle (in anti-clockwise direction)
9191  // in units of degrees.
9192  item->rotation = angle * 90;
9193  }
9194 
9195  return 0;
9196 }
9197 
9199 {
9200  HEIFItem *item;
9201  int axis;
9202 
9203  axis = avio_r8(pb) & 0x1;
9204 
9205  av_log(c->fc, AV_LOG_TRACE, "imir: item_id %d, axis %u\n",
9206  c->cur_item_id, axis);
9207 
9208  item = heif_cur_item(c);
9209  if (item) {
9210  item->hflip = axis;
9211  item->vflip = !axis;
9212  }
9213 
9214  return 0;
9215 }
9216 
9218 {
9219  typedef struct MOVAtoms {
9220  FFIOContext b;
9221  uint32_t type;
9222  int64_t size;
9223  uint8_t *data;
9224  } MOVAtoms;
9225  MOVAtoms *atoms = NULL;
9226  MOVAtom a;
9227  unsigned count;
9228  int nb_atoms = 0;
9229  int version, flags;
9230  int ret;
9231 
9232  a.size = avio_rb32(pb);
9233  a.type = avio_rl32(pb);
9234 
9235  if (a.size < 8 || a.type != MKTAG('i','p','c','o'))
9236  return AVERROR_INVALIDDATA;
9237 
9238  a.size -= 8;
9239  while (a.size >= 8) {
9240  MOVAtoms *ref = av_dynarray2_add((void**)&atoms, &nb_atoms, sizeof(MOVAtoms), NULL);
9241  if (!ref) {
9242  ret = AVERROR(ENOMEM);
9243  goto fail;
9244  }
9245  ref->data = NULL;
9246  ref->size = avio_rb32(pb);
9247  ref->type = avio_rl32(pb);
9248  if (ref->size > a.size || ref->size < 8)
9249  break;
9250  ref->data = av_malloc(ref->size);
9251  if (!ref->data) {
9253  goto fail;
9254  }
9255  av_log(c->fc, AV_LOG_TRACE, "ipco: index %d, box type %s\n", nb_atoms, av_fourcc2str(ref->type));
9256  avio_seek(pb, -8, SEEK_CUR);
9257  if (avio_read(pb, ref->data, ref->size) != ref->size) {
9259  goto fail;
9260  }
9261  ffio_init_read_context(&ref->b, ref->data, ref->size);
9262  a.size -= ref->size;
9263  }
9264 
9265  if (a.size) {
9267  goto fail;
9268  }
9269 
9270  a.size = avio_rb32(pb);
9271  a.type = avio_rl32(pb);
9272 
9273  if (a.size < 8 || a.type != MKTAG('i','p','m','a')) {
9275  goto fail;
9276  }
9277 
9278  version = avio_r8(pb);
9279  flags = avio_rb24(pb);
9280  count = avio_rb32(pb);
9281 
9282  for (int i = 0; i < count; i++) {
9283  int item_id = version ? avio_rb32(pb) : avio_rb16(pb);
9284  int assoc_count = avio_r8(pb);
9285 
9286  if (avio_feof(pb)) {
9288  goto fail;
9289  }
9290 
9291  for (int j = 0; j < assoc_count; j++) {
9292  MOVAtoms *ref;
9293  int index = avio_r8(pb) & 0x7f;
9294  if (flags & 1) {
9295  index <<= 8;
9296  index |= avio_r8(pb);
9297  }
9298  if (index > nb_atoms || index <= 0) {
9300  goto fail;
9301  }
9302  ref = &atoms[--index];
9303 
9304  av_log(c->fc, AV_LOG_TRACE, "ipma: property_index %d, item_id %d, item_type %s\n",
9305  index + 1, item_id, av_fourcc2str(ref->type));
9306 
9307  c->cur_item_id = item_id;
9308 
9309  ret = mov_read_default(c, &ref->b.pub,
9310  (MOVAtom) { .size = ref->size,
9311  .type = MKTAG('i','p','c','o') });
9312  if (ret < 0)
9313  goto fail;
9314  ffio_init_read_context(&ref->b, ref->data, ref->size);
9315  }
9316  }
9317 
9318  ret = 0;
9319 fail:
9320  c->cur_item_id = -1;
9321  for (int i = 0; i < nb_atoms; i++)
9322  av_free(atoms[i].data);
9323  av_free(atoms);
9324 
9325  return ret;
9326 }
9327 
9329 { MKTAG('A','C','L','R'), mov_read_aclr },
9330 { MKTAG('A','P','R','G'), mov_read_avid },
9331 { MKTAG('A','A','L','P'), mov_read_avid },
9332 { MKTAG('A','R','E','S'), mov_read_ares },
9333 { MKTAG('a','v','s','s'), mov_read_avss },
9334 { MKTAG('a','v','1','C'), mov_read_glbl },
9335 { MKTAG('c','h','p','l'), mov_read_chpl },
9336 { MKTAG('c','o','6','4'), mov_read_stco },
9337 { MKTAG('c','o','l','r'), mov_read_colr },
9338 { MKTAG('c','t','t','s'), mov_read_ctts }, /* composition time to sample */
9339 { MKTAG('d','i','n','f'), mov_read_default },
9340 { MKTAG('D','p','x','E'), mov_read_dpxe },
9341 { MKTAG('d','r','e','f'), mov_read_dref },
9342 { MKTAG('e','d','t','s'), mov_read_default },
9343 { MKTAG('e','l','s','t'), mov_read_elst },
9344 { MKTAG('e','n','d','a'), mov_read_enda },
9345 { MKTAG('f','i','e','l'), mov_read_fiel },
9346 { MKTAG('a','d','r','m'), mov_read_adrm },
9347 { MKTAG('f','t','y','p'), mov_read_ftyp },
9348 { MKTAG('g','l','b','l'), mov_read_glbl },
9349 { MKTAG('h','d','l','r'), mov_read_hdlr },
9350 { MKTAG('i','l','s','t'), mov_read_ilst },
9351 { MKTAG('j','p','2','h'), mov_read_jp2h },
9352 { MKTAG('m','d','a','t'), mov_read_mdat },
9353 { MKTAG('m','d','h','d'), mov_read_mdhd },
9354 { MKTAG('m','d','i','a'), mov_read_default },
9355 { MKTAG('m','e','t','a'), mov_read_meta },
9356 { MKTAG('m','i','n','f'), mov_read_default },
9357 { MKTAG('m','o','o','f'), mov_read_moof },
9358 { MKTAG('m','o','o','v'), mov_read_moov },
9359 { MKTAG('m','v','e','x'), mov_read_default },
9360 { MKTAG('m','v','h','d'), mov_read_mvhd },
9361 { MKTAG('S','M','I',' '), mov_read_svq3 },
9362 { MKTAG('a','l','a','c'), mov_read_alac }, /* alac specific atom */
9363 { MKTAG('a','v','c','C'), mov_read_glbl },
9364 { MKTAG('p','a','s','p'), mov_read_pasp },
9365 { MKTAG('c','l','a','p'), mov_read_clap },
9366 { MKTAG('s','b','a','s'), mov_read_sbas },
9367 { MKTAG('s','i','d','x'), mov_read_sidx },
9368 { MKTAG('s','t','b','l'), mov_read_default },
9369 { MKTAG('s','t','c','o'), mov_read_stco },
9370 { MKTAG('s','t','p','s'), mov_read_stps },
9371 { MKTAG('s','t','r','f'), mov_read_strf },
9372 { MKTAG('s','t','s','c'), mov_read_stsc },
9373 { MKTAG('s','t','s','d'), mov_read_stsd }, /* sample description */
9374 { MKTAG('s','t','s','s'), mov_read_stss }, /* sync sample */
9375 { MKTAG('s','t','s','z'), mov_read_stsz }, /* sample size */
9376 { MKTAG('s','t','t','s'), mov_read_stts },
9377 { MKTAG('s','t','z','2'), mov_read_stsz }, /* compact sample size */
9378 { MKTAG('s','d','t','p'), mov_read_sdtp }, /* independent and disposable samples */
9379 { MKTAG('t','k','h','d'), mov_read_tkhd }, /* track header */
9380 { MKTAG('t','f','d','t'), mov_read_tfdt },
9381 { MKTAG('t','f','h','d'), mov_read_tfhd }, /* track fragment header */
9382 { MKTAG('t','r','a','k'), mov_read_trak },
9383 { MKTAG('t','r','a','f'), mov_read_default },
9384 { MKTAG('t','r','e','f'), mov_read_default },
9385 { MKTAG('t','m','c','d'), mov_read_tmcd },
9386 { MKTAG('c','h','a','p'), mov_read_chap },
9387 { MKTAG('t','r','e','x'), mov_read_trex },
9388 { MKTAG('t','r','u','n'), mov_read_trun },
9389 { MKTAG('u','d','t','a'), mov_read_default },
9390 { MKTAG('w','a','v','e'), mov_read_wave },
9391 { MKTAG('e','s','d','s'), mov_read_esds },
9392 { MKTAG('d','a','c','3'), mov_read_dac3 }, /* AC-3 info */
9393 { MKTAG('d','e','c','3'), mov_read_dec3 }, /* EAC-3 info */
9394 { MKTAG('d','d','t','s'), mov_read_ddts }, /* DTS audio descriptor */
9395 { MKTAG('w','i','d','e'), mov_read_wide }, /* place holder */
9396 { MKTAG('w','f','e','x'), mov_read_wfex },
9397 { MKTAG('c','m','o','v'), mov_read_cmov },
9398 { MKTAG('c','h','a','n'), mov_read_chan }, /* channel layout from quicktime */
9399 { MKTAG('c','h','n','l'), mov_read_chnl }, /* channel layout from ISO-14496-12 */
9400 { MKTAG('d','v','c','1'), mov_read_dvc1 },
9401 { MKTAG('s','g','p','d'), mov_read_sgpd },
9402 { MKTAG('s','b','g','p'), mov_read_sbgp },
9403 { MKTAG('h','v','c','C'), mov_read_glbl },
9404 { MKTAG('v','v','c','C'), mov_read_glbl },
9405 { MKTAG('u','u','i','d'), mov_read_uuid },
9406 { MKTAG('C','i','n', 0x8e), mov_read_targa_y216 },
9407 { MKTAG('f','r','e','e'), mov_read_free },
9408 { MKTAG('-','-','-','-'), mov_read_custom },
9409 { MKTAG('s','i','n','f'), mov_read_default },
9410 { MKTAG('f','r','m','a'), mov_read_frma },
9411 { MKTAG('s','e','n','c'), mov_read_senc },
9412 { MKTAG('s','a','i','z'), mov_read_saiz },
9413 { MKTAG('s','a','i','o'), mov_read_saio },
9414 { MKTAG('p','s','s','h'), mov_read_pssh },
9415 { MKTAG('s','c','h','m'), mov_read_schm },
9416 { MKTAG('s','c','h','i'), mov_read_default },
9417 { MKTAG('t','e','n','c'), mov_read_tenc },
9418 { MKTAG('d','f','L','a'), mov_read_dfla },
9419 { MKTAG('s','t','3','d'), mov_read_st3d }, /* stereoscopic 3D video box */
9420 { MKTAG('s','v','3','d'), mov_read_sv3d }, /* spherical video box */
9421 { MKTAG('v','e','x','u'), mov_read_vexu }, /* video extension usage */
9422 { MKTAG('h','f','o','v'), mov_read_hfov },
9423 { MKTAG('d','O','p','s'), mov_read_dops },
9424 { MKTAG('d','m','l','p'), mov_read_dmlp },
9425 { MKTAG('S','m','D','m'), mov_read_smdm },
9426 { MKTAG('C','o','L','L'), mov_read_coll },
9427 { MKTAG('v','p','c','C'), mov_read_vpcc },
9428 { MKTAG('m','d','c','v'), mov_read_mdcv },
9429 { MKTAG('c','l','l','i'), mov_read_clli },
9430 { MKTAG('d','v','c','C'), mov_read_dvcc_dvvc },
9431 { MKTAG('d','v','v','C'), mov_read_dvcc_dvvc },
9432 { MKTAG('d','v','w','C'), mov_read_dvcc_dvvc },
9433 { MKTAG('k','i','n','d'), mov_read_kind },
9434 { MKTAG('S','A','3','D'), mov_read_SA3D }, /* ambisonic audio box */
9435 { MKTAG('S','A','N','D'), mov_read_SAND }, /* non diegetic audio box */
9436 { MKTAG('i','l','o','c'), mov_read_iloc },
9437 { MKTAG('p','c','m','C'), mov_read_pcmc }, /* PCM configuration box */
9438 { MKTAG('p','i','t','m'), mov_read_pitm },
9439 { MKTAG('e','v','c','C'), mov_read_glbl },
9440 { MKTAG('i','d','a','t'), mov_read_idat },
9441 { MKTAG('i','m','i','r'), mov_read_imir },
9442 { MKTAG('i','r','e','f'), mov_read_iref },
9443 { MKTAG('i','s','p','e'), mov_read_ispe },
9444 { MKTAG('i','r','o','t'), mov_read_irot },
9445 { MKTAG('i','p','r','p'), mov_read_iprp },
9446 { MKTAG('i','i','n','f'), mov_read_iinf },
9447 { MKTAG('a','m','v','e'), mov_read_amve }, /* ambient viewing environment box */
9448 { MKTAG('l','h','v','C'), mov_read_lhvc },
9449 { MKTAG('l','v','c','C'), mov_read_glbl },
9450 { MKTAG('a','p','v','C'), mov_read_glbl },
9451 #if CONFIG_IAMFDEC
9452 { MKTAG('i','a','c','b'), mov_read_iacb },
9453 #endif
9454 { 0, NULL }
9455 };
9456 
9458 {
9459  int64_t total_size = 0;
9460  MOVAtom a;
9461  int i;
9462 
9463  if (c->atom_depth > 10) {
9464  av_log(c->fc, AV_LOG_ERROR, "Atoms too deeply nested\n");
9465  return AVERROR_INVALIDDATA;
9466  }
9467  c->atom_depth ++;
9468 
9469  if (atom.size < 0)
9470  atom.size = INT64_MAX;
9471  while (total_size <= atom.size - 8) {
9472  int (*parse)(MOVContext*, AVIOContext*, MOVAtom) = NULL;
9473  a.size = avio_rb32(pb);
9474  a.type = avio_rl32(pb);
9475  if (avio_feof(pb))
9476  break;
9477  if (((a.type == MKTAG('f','r','e','e') && c->moov_retry) ||
9478  a.type == MKTAG('h','o','o','v')) &&
9479  a.size >= 8 &&
9480  c->fc->strict_std_compliance < FF_COMPLIANCE_STRICT) {
9481  uint32_t type;
9482  avio_skip(pb, 4);
9483  type = avio_rl32(pb);
9484  if (avio_feof(pb))
9485  break;
9486  avio_seek(pb, -8, SEEK_CUR);
9487  if (type == MKTAG('m','v','h','d') ||
9488  type == MKTAG('c','m','o','v')) {
9489  av_log(c->fc, AV_LOG_ERROR, "Detected moov in a free or hoov atom.\n");
9490  a.type = MKTAG('m','o','o','v');
9491  }
9492  }
9493  if (atom.type != MKTAG('r','o','o','t') &&
9494  atom.type != MKTAG('m','o','o','v')) {
9495  if (a.type == MKTAG('t','r','a','k') ||
9496  a.type == MKTAG('m','d','a','t')) {
9497  av_log(c->fc, AV_LOG_ERROR, "Broken file, trak/mdat not at top-level\n");
9498  avio_skip(pb, -8);
9499  c->atom_depth --;
9500  return 0;
9501  }
9502  }
9503  total_size += 8;
9504  if (a.size == 1 && total_size + 8 <= atom.size) { /* 64 bit extended size */
9505  a.size = avio_rb64(pb) - 8;
9506  total_size += 8;
9507  }
9508  av_log(c->fc, AV_LOG_TRACE, "type:'%s' parent:'%s' sz: %"PRId64" %"PRId64" %"PRId64"\n",
9509  av_fourcc2str(a.type), av_fourcc2str(atom.type), a.size, total_size, atom.size);
9510  if (a.size == 0) {
9511  a.size = atom.size - total_size + 8;
9512  }
9513  if (a.size < 0)
9514  break;
9515  a.size -= 8;
9516  if (a.size < 0)
9517  break;
9518  a.size = FFMIN(a.size, atom.size - total_size);
9519 
9520  for (i = 0; mov_default_parse_table[i].type; i++)
9521  if (mov_default_parse_table[i].type == a.type) {
9523  break;
9524  }
9525 
9526  // container is user data
9527  if (!parse && (atom.type == MKTAG('u','d','t','a') ||
9528  atom.type == MKTAG('i','l','s','t')))
9530 
9531  // Supports parsing the QuickTime Metadata Keys.
9532  // https://developer.apple.com/library/mac/documentation/QuickTime/QTFF/Metadata/Metadata.html
9533  if (!parse && c->found_hdlr_mdta &&
9534  atom.type == MKTAG('m','e','t','a') &&
9535  a.type == MKTAG('k','e','y','s') &&
9536  c->meta_keys_count == 0) {
9537  parse = mov_read_keys;
9538  }
9539 
9540  if (!parse) { /* skip leaf atoms data */
9541  avio_skip(pb, a.size);
9542  } else {
9543  int64_t start_pos = avio_tell(pb);
9544  int64_t left;
9545  int err = parse(c, pb, a);
9546  if (err < 0) {
9547  c->atom_depth --;
9548  return err;
9549  }
9550  if (c->found_moov && c->found_mdat && a.size <= INT64_MAX - start_pos &&
9551  ((!(pb->seekable & AVIO_SEEKABLE_NORMAL) || c->fc->flags & AVFMT_FLAG_IGNIDX || c->frag_index.complete) ||
9552  start_pos + a.size == avio_size(pb))) {
9553  if (!(pb->seekable & AVIO_SEEKABLE_NORMAL) || c->fc->flags & AVFMT_FLAG_IGNIDX || c->frag_index.complete)
9554  c->next_root_atom = start_pos + a.size;
9555  c->atom_depth --;
9556  return 0;
9557  }
9558  left = a.size - avio_tell(pb) + start_pos;
9559  if (left > 0) /* skip garbage at atom end */
9560  avio_skip(pb, left);
9561  else if (left < 0) {
9562  av_log(c->fc, AV_LOG_WARNING,
9563  "overread end of atom '%s' by %"PRId64" bytes\n",
9564  av_fourcc2str(a.type), -left);
9565  avio_seek(pb, left, SEEK_CUR);
9566  }
9567  }
9568 
9569  total_size += a.size;
9570  }
9571 
9572  if (total_size < atom.size && atom.size < 0x7ffff)
9573  avio_skip(pb, atom.size - total_size);
9574 
9575  c->atom_depth --;
9576  return 0;
9577 }
9578 
9579 static int mov_probe(const AVProbeData *p)
9580 {
9581  int64_t offset;
9582  uint32_t tag;
9583  int score = 0;
9584  int moov_offset = -1;
9585 
9586  /* check file header */
9587  offset = 0;
9588  for (;;) {
9589  int64_t size;
9590  int minsize = 8;
9591  /* ignore invalid offset */
9592  if ((offset + 8ULL) > (unsigned int)p->buf_size)
9593  break;
9594  size = AV_RB32(p->buf + offset);
9595  if (size == 1 && offset + 16 <= (unsigned int)p->buf_size) {
9596  size = AV_RB64(p->buf+offset + 8);
9597  minsize = 16;
9598  } else if (size == 0) {
9599  size = p->buf_size - offset;
9600  }
9601  if (size < minsize) {
9602  offset += 4;
9603  continue;
9604  }
9605  tag = AV_RL32(p->buf + offset + 4);
9606  switch(tag) {
9607  /* check for obvious tags */
9608  case MKTAG('m','o','o','v'):
9609  moov_offset = offset + 4;
9610  case MKTAG('m','d','a','t'):
9611  case MKTAG('p','n','o','t'): /* detect movs with preview pics like ew.mov and april.mov */
9612  case MKTAG('u','d','t','a'): /* Packet Video PVAuthor adds this and a lot of more junk */
9613  case MKTAG('f','t','y','p'):
9614  if (tag == MKTAG('f','t','y','p') &&
9615  ( AV_RL32(p->buf + offset + 8) == MKTAG('j','p','2',' ')
9616  || AV_RL32(p->buf + offset + 8) == MKTAG('j','p','x',' ')
9617  || AV_RL32(p->buf + offset + 8) == MKTAG('j','x','l',' ')
9618  )) {
9619  score = FFMAX(score, 5);
9620  } else {
9621  score = AVPROBE_SCORE_MAX;
9622  }
9623  break;
9624  /* those are more common words, so rate then a bit less */
9625  case MKTAG('e','d','i','w'): /* xdcam files have reverted first tags */
9626  case MKTAG('w','i','d','e'):
9627  case MKTAG('f','r','e','e'):
9628  case MKTAG('j','u','n','k'):
9629  case MKTAG('p','i','c','t'):
9630  score = FFMAX(score, AVPROBE_SCORE_MAX - 5);
9631  break;
9632  case MKTAG(0x82,0x82,0x7f,0x7d):
9633  score = FFMAX(score, AVPROBE_SCORE_EXTENSION - 5);
9634  break;
9635  case MKTAG('s','k','i','p'):
9636  case MKTAG('u','u','i','d'):
9637  case MKTAG('p','r','f','l'):
9638  /* if we only find those cause probedata is too small at least rate them */
9639  score = FFMAX(score, AVPROBE_SCORE_EXTENSION);
9640  break;
9641  }
9642  if (size > INT64_MAX - offset)
9643  break;
9644  offset += size;
9645  }
9646  if (score > AVPROBE_SCORE_MAX - 50 && moov_offset != -1) {
9647  /* moov atom in the header - we should make sure that this is not a
9648  * MOV-packed MPEG-PS */
9649  offset = moov_offset;
9650 
9651  while (offset < (p->buf_size - 16)) { /* Sufficient space */
9652  /* We found an actual hdlr atom */
9653  if (AV_RL32(p->buf + offset ) == MKTAG('h','d','l','r') &&
9654  AV_RL32(p->buf + offset + 8) == MKTAG('m','h','l','r') &&
9655  AV_RL32(p->buf + offset + 12) == MKTAG('M','P','E','G')) {
9656  av_log(NULL, AV_LOG_WARNING, "Found media data tag MPEG indicating this is a MOV-packed MPEG-PS.\n");
9657  /* We found a media handler reference atom describing an
9658  * MPEG-PS-in-MOV, return a
9659  * low score to force expanding the probe window until
9660  * mpegps_probe finds what it needs */
9661  return 5;
9662  } else {
9663  /* Keep looking */
9664  offset += 2;
9665  }
9666  }
9667  }
9668 
9669  return score;
9670 }
9671 
9672 // must be done after parsing all trak because there's no order requirement
9674 {
9675  MOVContext *mov = s->priv_data;
9676  MOVStreamContext *sc;
9677  int64_t cur_pos;
9678  int i, j;
9679  int chapter_track;
9680 
9681  for (j = 0; j < mov->nb_chapter_tracks; j++) {
9682  AVStream *st = NULL;
9683  FFStream *sti = NULL;
9684  chapter_track = mov->chapter_tracks[j];
9685  for (i = 0; i < s->nb_streams; i++) {
9686  sc = mov->fc->streams[i]->priv_data;
9687  if (sc->id == chapter_track) {
9688  st = s->streams[i];
9689  break;
9690  }
9691  }
9692  if (!st) {
9693  av_log(s, AV_LOG_ERROR, "Referenced QT chapter track not found\n");
9694  continue;
9695  }
9696  sti = ffstream(st);
9697 
9698  sc = st->priv_data;
9699  cur_pos = avio_tell(sc->pb);
9700 
9701  if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
9703  if (!st->attached_pic.data && sti->nb_index_entries) {
9704  // Retrieve the first frame, if possible
9705  AVIndexEntry *sample = &sti->index_entries[0];
9706  if (avio_seek(sc->pb, sample->pos, SEEK_SET) != sample->pos) {
9707  av_log(s, AV_LOG_ERROR, "Failed to retrieve first frame\n");
9708  goto finish;
9709  }
9710 
9711  if (ff_add_attached_pic(s, st, sc->pb, NULL, sample->size) < 0)
9712  goto finish;
9713  }
9714  } else {
9717  st->discard = AVDISCARD_ALL;
9718  for (int i = 0; i < sti->nb_index_entries; i++) {
9719  AVIndexEntry *sample = &sti->index_entries[i];
9720  int64_t end = i+1 < sti->nb_index_entries ? sti->index_entries[i+1].timestamp : st->duration;
9721  uint8_t *title;
9722  uint16_t ch;
9723  int len, title_len;
9724 
9725  if (end < sample->timestamp) {
9726  av_log(s, AV_LOG_WARNING, "ignoring stream duration which is shorter than chapters\n");
9727  end = AV_NOPTS_VALUE;
9728  }
9729 
9730  if (avio_seek(sc->pb, sample->pos, SEEK_SET) != sample->pos) {
9731  av_log(s, AV_LOG_ERROR, "Chapter %d not found in file\n", i);
9732  goto finish;
9733  }
9734 
9735  // the first two bytes are the length of the title
9736  len = avio_rb16(sc->pb);
9737  if (len > sample->size-2)
9738  continue;
9739  title_len = 2*len + 1;
9740  if (!(title = av_mallocz(title_len)))
9741  goto finish;
9742 
9743  // The samples could theoretically be in any encoding if there's an encd
9744  // atom following, but in practice are only utf-8 or utf-16, distinguished
9745  // instead by the presence of a BOM
9746  if (!len) {
9747  title[0] = 0;
9748  } else {
9749  ch = avio_rb16(sc->pb);
9750  if (ch == 0xfeff)
9751  avio_get_str16be(sc->pb, len, title, title_len);
9752  else if (ch == 0xfffe)
9753  avio_get_str16le(sc->pb, len, title, title_len);
9754  else {
9755  AV_WB16(title, ch);
9756  if (len == 1 || len == 2)
9757  title[len] = 0;
9758  else
9759  avio_get_str(sc->pb, INT_MAX, title + 2, len - 1);
9760  }
9761  }
9762 
9763  avpriv_new_chapter(s, i, st->time_base, sample->timestamp, end, title);
9764  av_freep(&title);
9765  }
9766  }
9767 finish:
9768  avio_seek(sc->pb, cur_pos, SEEK_SET);
9769  }
9770 }
9771 
9773  int64_t value, int flags)
9774 {
9775  AVTimecode tc;
9776  char buf[AV_TIMECODE_STR_SIZE];
9777  AVRational rate = st->avg_frame_rate;
9778  int ret = av_timecode_init(&tc, rate, flags, 0, s);
9779  if (ret < 0)
9780  return ret;
9781  av_dict_set(&st->metadata, "timecode",
9782  av_timecode_make_string(&tc, buf, value), 0);
9783  return 0;
9784 }
9785 
9787 {
9788  MOVStreamContext *sc = st->priv_data;
9789  FFStream *const sti = ffstream(st);
9790  char buf[AV_TIMECODE_STR_SIZE];
9791  int64_t cur_pos = avio_tell(sc->pb);
9792  int hh, mm, ss, ff, drop;
9793 
9794  if (!sti->nb_index_entries)
9795  return -1;
9796 
9797  avio_seek(sc->pb, sti->index_entries->pos, SEEK_SET);
9798  avio_skip(s->pb, 13);
9799  hh = avio_r8(s->pb);
9800  mm = avio_r8(s->pb);
9801  ss = avio_r8(s->pb);
9802  drop = avio_r8(s->pb);
9803  ff = avio_r8(s->pb);
9804  snprintf(buf, AV_TIMECODE_STR_SIZE, "%02d:%02d:%02d%c%02d",
9805  hh, mm, ss, drop ? ';' : ':', ff);
9806  av_dict_set(&st->metadata, "timecode", buf, 0);
9807 
9808  avio_seek(sc->pb, cur_pos, SEEK_SET);
9809  return 0;
9810 }
9811 
9813 {
9814  MOVStreamContext *sc = st->priv_data;
9815  FFStream *const sti = ffstream(st);
9816  int flags = 0;
9817  int64_t cur_pos = avio_tell(sc->pb);
9818  int64_t value;
9819  AVRational tc_rate = st->avg_frame_rate;
9820  int tmcd_nb_frames = sc->tmcd_nb_frames;
9821  int rounded_tc_rate;
9822 
9823  if (!sti->nb_index_entries)
9824  return -1;
9825 
9826  if (!tc_rate.num || !tc_rate.den || !tmcd_nb_frames)
9827  return -1;
9828 
9829  avio_seek(sc->pb, sti->index_entries->pos, SEEK_SET);
9830  value = avio_rb32(s->pb);
9831 
9832  if (sc->tmcd_flags & 0x0001) flags |= AV_TIMECODE_FLAG_DROPFRAME;
9833  if (sc->tmcd_flags & 0x0002) flags |= AV_TIMECODE_FLAG_24HOURSMAX;
9834  if (sc->tmcd_flags & 0x0004) flags |= AV_TIMECODE_FLAG_ALLOWNEGATIVE;
9835 
9836  /* Assume Counter flag is set to 1 in tmcd track (even though it is likely
9837  * not the case) and thus assume "frame number format" instead of QT one.
9838  * No sample with tmcd track can be found with a QT timecode at the moment,
9839  * despite what the tmcd track "suggests" (Counter flag set to 0 means QT
9840  * format). */
9841 
9842  /* 60 fps content have tmcd_nb_frames set to 30 but tc_rate set to 60, so
9843  * we multiply the frame number with the quotient.
9844  * See tickets #9492, #9710. */
9845  rounded_tc_rate = (tc_rate.num + tc_rate.den / 2LL) / tc_rate.den;
9846  /* Work around files where tmcd_nb_frames is rounded down from frame rate
9847  * instead of up. See ticket #5978. */
9848  if (tmcd_nb_frames == tc_rate.num / tc_rate.den &&
9849  s->strict_std_compliance < FF_COMPLIANCE_STRICT)
9850  tmcd_nb_frames = rounded_tc_rate;
9851  value = av_rescale(value, rounded_tc_rate, tmcd_nb_frames);
9852 
9854 
9855  avio_seek(sc->pb, cur_pos, SEEK_SET);
9856  return 0;
9857 }
9858 
9860  int i;
9861  if (!index || !*index) return;
9862  for (i = 0; i < (*index)->nb_encrypted_samples; i++) {
9863  av_encryption_info_free((*index)->encrypted_samples[i]);
9864  }
9865  av_freep(&(*index)->encrypted_samples);
9866  av_freep(&(*index)->auxiliary_info_sizes);
9867  av_freep(&(*index)->auxiliary_offsets);
9868  av_freep(index);
9869 }
9870 
9872 {
9873  MOVStreamContext *sc = st->priv_data;
9874 
9875  if (!sc || --sc->refcount) {
9876  st->priv_data = NULL;
9877  return;
9878  }
9879 
9880  av_freep(&sc->tts_data);
9881  for (int i = 0; i < sc->drefs_count; i++) {
9882  av_freep(&sc->drefs[i].path);
9883  av_freep(&sc->drefs[i].dir);
9884  }
9885  av_freep(&sc->drefs);
9886 
9887  sc->drefs_count = 0;
9888 
9889  if (!sc->pb_is_copied)
9890  ff_format_io_close(s, &sc->pb);
9891 
9892  sc->pb = NULL;
9893  av_freep(&sc->chunk_offsets);
9894  av_freep(&sc->stsc_data);
9895  av_freep(&sc->sample_sizes);
9896  av_freep(&sc->keyframes);
9897  av_freep(&sc->ctts_data);
9898  av_freep(&sc->stts_data);
9899  av_freep(&sc->sdtp_data);
9900  av_freep(&sc->stps_data);
9901  av_freep(&sc->elst_data);
9902  av_freep(&sc->rap_group);
9903  av_freep(&sc->sync_group);
9904  av_freep(&sc->sgpd_sync);
9905  av_freep(&sc->sample_offsets);
9906  av_freep(&sc->open_key_samples);
9907  av_freep(&sc->display_matrix);
9908  av_freep(&sc->index_ranges);
9909 
9910  if (sc->extradata)
9911  for (int i = 0; i < sc->stsd_count; i++)
9912  av_free(sc->extradata[i]);
9913  av_freep(&sc->extradata);
9914  av_freep(&sc->extradata_size);
9915 
9919 
9920  av_freep(&sc->stereo3d);
9921  av_freep(&sc->spherical);
9922  av_freep(&sc->mastering);
9923  av_freep(&sc->coll);
9924  av_freep(&sc->ambient);
9925 
9926 #if CONFIG_IAMFDEC
9927  if (sc->iamf)
9929 #endif
9930  av_freep(&sc->iamf);
9931 }
9932 
9934 {
9935  MOVContext *mov = s->priv_data;
9936  int i, j;
9937 
9938  for (i = 0; i < s->nb_streams; i++) {
9939  AVStream *st = s->streams[i];
9940 
9942  }
9943 
9944  av_freep(&mov->dv_demux);
9946  mov->dv_fctx = NULL;
9947 
9948  if (mov->meta_keys) {
9949  for (i = 1; i < mov->meta_keys_count; i++) {
9950  av_freep(&mov->meta_keys[i]);
9951  }
9952  av_freep(&mov->meta_keys);
9953  }
9954 
9955  av_freep(&mov->trex_data);
9956  av_freep(&mov->bitrates);
9957 
9958  for (i = 0; i < mov->frag_index.nb_items; i++) {
9960  for (j = 0; j < mov->frag_index.item[i].nb_stream_info; j++) {
9961  mov_free_encryption_index(&frag[j].encryption_index);
9962  }
9964  }
9965  av_freep(&mov->frag_index.item);
9966 
9967  av_freep(&mov->aes_decrypt);
9968  av_freep(&mov->chapter_tracks);
9969  for (i = 0; i < mov->nb_heif_item; i++) {
9970  if (!mov->heif_item[i])
9971  continue;
9972  av_freep(&mov->heif_item[i]->name);
9973  av_freep(&mov->heif_item[i]->icc_profile);
9974  av_freep(&mov->heif_item[i]);
9975  }
9976  av_freep(&mov->heif_item);
9977  for (i = 0; i < mov->nb_heif_grid; i++) {
9978  av_freep(&mov->heif_grid[i].tile_id_list);
9981  }
9982  av_freep(&mov->heif_grid);
9983  av_freep(&mov->thmb_item_id);
9984 
9985  return 0;
9986 }
9987 
9988 static int tmcd_is_referenced(AVFormatContext *s, int tmcd_id)
9989 {
9990  int i;
9991 
9992  for (i = 0; i < s->nb_streams; i++) {
9993  AVStream *st = s->streams[i];
9994  MOVStreamContext *sc = st->priv_data;
9995 
9996  if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO &&
9997  sc->timecode_track == tmcd_id)
9998  return 1;
9999  }
10000  return 0;
10001 }
10002 
10003 /* look for a tmcd track not referenced by any video track, and export it globally */
10005 {
10006  int i;
10007 
10008  for (i = 0; i < s->nb_streams; i++) {
10009  AVStream *st = s->streams[i];
10010 
10011  if (st->codecpar->codec_tag == MKTAG('t','m','c','d') &&
10012  !tmcd_is_referenced(s, i + 1)) {
10013  AVDictionaryEntry *tcr = av_dict_get(st->metadata, "timecode", NULL, 0);
10014  if (tcr) {
10015  av_dict_set(&s->metadata, "timecode", tcr->value, 0);
10016  break;
10017  }
10018  }
10019  }
10020 }
10021 
10022 static int read_tfra(MOVContext *mov, AVIOContext *f)
10023 {
10024  int version, fieldlength, i, j;
10025  int64_t pos = avio_tell(f);
10026  uint32_t size = avio_rb32(f);
10027  unsigned track_id, item_count;
10028 
10029  if (avio_rb32(f) != MKBETAG('t', 'f', 'r', 'a')) {
10030  return 1;
10031  }
10032  av_log(mov->fc, AV_LOG_VERBOSE, "found tfra\n");
10033 
10034  version = avio_r8(f);
10035  avio_rb24(f);
10036  track_id = avio_rb32(f);
10037  fieldlength = avio_rb32(f);
10038  item_count = avio_rb32(f);
10039  for (i = 0; i < item_count; i++) {
10040  int64_t time, offset;
10041  int index;
10042  MOVFragmentStreamInfo * frag_stream_info;
10043 
10044  if (avio_feof(f)) {
10045  return AVERROR_INVALIDDATA;
10046  }
10047 
10048  if (version == 1) {
10049  time = avio_rb64(f);
10050  offset = avio_rb64(f);
10051  } else {
10052  time = avio_rb32(f);
10053  offset = avio_rb32(f);
10054  }
10055 
10056  // The first sample of each stream in a fragment is always a random
10057  // access sample. So it's entry in the tfra can be used as the
10058  // initial PTS of the fragment.
10059  index = update_frag_index(mov, offset);
10060  frag_stream_info = get_frag_stream_info(&mov->frag_index, index, track_id);
10061  if (frag_stream_info &&
10062  frag_stream_info->first_tfra_pts == AV_NOPTS_VALUE)
10063  frag_stream_info->first_tfra_pts = time;
10064 
10065  for (j = 0; j < ((fieldlength >> 4) & 3) + 1; j++)
10066  avio_r8(f);
10067  for (j = 0; j < ((fieldlength >> 2) & 3) + 1; j++)
10068  avio_r8(f);
10069  for (j = 0; j < ((fieldlength >> 0) & 3) + 1; j++)
10070  avio_r8(f);
10071  }
10072 
10073  avio_seek(f, pos + size, SEEK_SET);
10074  return 0;
10075 }
10076 
10078 {
10079  int64_t stream_size = avio_size(f);
10080  int64_t original_pos = avio_tell(f);
10081  int64_t seek_ret;
10082  int ret = -1;
10083  if ((seek_ret = avio_seek(f, stream_size - 4, SEEK_SET)) < 0) {
10084  ret = seek_ret;
10085  goto fail;
10086  }
10087  c->mfra_size = avio_rb32(f);
10088  c->have_read_mfra_size = 1;
10089  if (!c->mfra_size || c->mfra_size > stream_size) {
10090  av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (unreasonable size)\n");
10091  goto fail;
10092  }
10093  if ((seek_ret = avio_seek(f, -((int64_t) c->mfra_size), SEEK_CUR)) < 0) {
10094  ret = seek_ret;
10095  goto fail;
10096  }
10097  if (avio_rb32(f) != c->mfra_size) {
10098  av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (size mismatch)\n");
10099  goto fail;
10100  }
10101  if (avio_rb32(f) != MKBETAG('m', 'f', 'r', 'a')) {
10102  av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (tag mismatch)\n");
10103  goto fail;
10104  }
10105  av_log(c->fc, AV_LOG_VERBOSE, "stream has mfra\n");
10106  do {
10107  ret = read_tfra(c, f);
10108  if (ret < 0)
10109  goto fail;
10110  } while (!ret);
10111  ret = 0;
10112  c->frag_index.complete = 1;
10113 fail:
10114  seek_ret = avio_seek(f, original_pos, SEEK_SET);
10115  if (seek_ret < 0) {
10116  av_log(c->fc, AV_LOG_ERROR,
10117  "failed to seek back after looking for mfra\n");
10118  ret = seek_ret;
10119  }
10120  return ret;
10121 }
10122 
10123 static int set_icc_profile_from_item(AVPacketSideData **coded_side_data, int *nb_coded_side_data,
10124  const HEIFItem *item)
10125 {
10126  AVPacketSideData *sd = av_packet_side_data_new(coded_side_data, nb_coded_side_data,
10128  item->icc_profile_size, 0);
10129  if (!sd)
10130  return AVERROR(ENOMEM);
10131 
10132  memcpy(sd->data, item->icc_profile, item->icc_profile_size);
10133 
10134  return 0;
10135 }
10136 
10137 static int set_display_matrix_from_item(AVPacketSideData **coded_side_data, int *nb_coded_side_data,
10138  const HEIFItem *item)
10139 {
10140  int32_t *matrix;
10141  AVPacketSideData *sd = av_packet_side_data_new(coded_side_data,
10142  nb_coded_side_data,
10144  9 * sizeof(*matrix), 0);
10145  if (!sd)
10146  return AVERROR(ENOMEM);
10147 
10148  matrix = (int32_t*)sd->data;
10149  /* rotation is in the counter-clockwise direction whereas
10150  * av_display_rotation_set() expects its argument to be
10151  * oriented clockwise, so we need to negate it. */
10153  av_display_matrix_flip(matrix, item->hflip, item->vflip);
10154 
10155  return 0;
10156 }
10157 
10158 static int read_image_grid(AVFormatContext *s, const HEIFGrid *grid,
10159  AVStreamGroupTileGrid *tile_grid)
10160 {
10161  MOVContext *c = s->priv_data;
10162  const HEIFItem *item = grid->item;
10163  int64_t offset = 0, pos = avio_tell(s->pb);
10164  int x = 0, y = 0, i = 0;
10165  int tile_rows, tile_cols;
10166  int flags, size;
10167 
10168  if (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL)) {
10169  av_log(c->fc, AV_LOG_INFO, "grid box with non seekable input\n");
10170  return AVERROR_PATCHWELCOME;
10171  }
10172  if (item->is_idat_relative) {
10173  if (!c->idat_offset) {
10174  av_log(c->fc, AV_LOG_ERROR, "missing idat box required by the image grid\n");
10175  return AVERROR_INVALIDDATA;
10176  }
10177  offset = c->idat_offset;
10178  }
10179 
10180  avio_seek(s->pb, item->extent_offset + offset, SEEK_SET);
10181 
10182  avio_r8(s->pb); /* version */
10183  flags = avio_r8(s->pb);
10184 
10185  tile_rows = avio_r8(s->pb) + 1;
10186  tile_cols = avio_r8(s->pb) + 1;
10187  /* actual width and height of output image */
10188  tile_grid->width = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
10189  tile_grid->height = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
10190 
10191  /* ICC profile */
10192  if (item->icc_profile_size) {
10193  int ret = set_icc_profile_from_item(&tile_grid->coded_side_data,
10194  &tile_grid->nb_coded_side_data, item);
10195  if (ret < 0)
10196  return ret;
10197  }
10198  /* rotation */
10199  if (item->rotation || item->hflip || item->vflip) {
10201  &tile_grid->nb_coded_side_data, item);
10202  if (ret < 0)
10203  return ret;
10204  }
10205 
10206  av_log(c->fc, AV_LOG_TRACE, "grid: grid_rows %d grid_cols %d output_width %d output_height %d\n",
10207  tile_rows, tile_cols, tile_grid->width, tile_grid->height);
10208 
10209  avio_seek(s->pb, pos, SEEK_SET);
10210 
10211  size = tile_rows * tile_cols;
10212  tile_grid->nb_tiles = grid->nb_tiles;
10213 
10214  if (tile_grid->nb_tiles != size)
10215  return AVERROR_INVALIDDATA;
10216 
10217  for (int i = 0; i < tile_cols; i++)
10218  tile_grid->coded_width += grid->tile_item_list[i]->width;
10219  for (int i = 0; i < size; i += tile_cols)
10220  tile_grid->coded_height += grid->tile_item_list[i]->height;
10221 
10222  tile_grid->offsets = av_calloc(tile_grid->nb_tiles, sizeof(*tile_grid->offsets));
10223  if (!tile_grid->offsets)
10224  return AVERROR(ENOMEM);
10225 
10226  while (y < tile_grid->coded_height) {
10227  int left_col = i;
10228 
10229  while (x < tile_grid->coded_width) {
10230  if (i == tile_grid->nb_tiles)
10231  return AVERROR_INVALIDDATA;
10232 
10233  tile_grid->offsets[i].idx = grid->tile_idx_list[i];
10234  tile_grid->offsets[i].horizontal = x;
10235  tile_grid->offsets[i].vertical = y;
10236 
10237  x += grid->tile_item_list[i++]->width;
10238  }
10239 
10240  if (x > tile_grid->coded_width) {
10241  av_log(c->fc, AV_LOG_ERROR, "Non uniform HEIF tiles\n");
10242  return AVERROR_INVALIDDATA;
10243  }
10244 
10245  x = 0;
10246  y += grid->tile_item_list[left_col]->height;
10247  }
10248 
10249  if (y > tile_grid->coded_height || i != tile_grid->nb_tiles) {
10250  av_log(c->fc, AV_LOG_ERROR, "Non uniform HEIF tiles\n");
10251  return AVERROR_INVALIDDATA;
10252  }
10253 
10254  return 0;
10255 }
10256 
10257 static int read_image_iovl(AVFormatContext *s, const HEIFGrid *grid,
10258  AVStreamGroupTileGrid *tile_grid)
10259 {
10260  MOVContext *c = s->priv_data;
10261  const HEIFItem *item = grid->item;
10262  uint16_t canvas_fill_value[4];
10263  int64_t offset = 0, pos = avio_tell(s->pb);
10264  int ret = 0, flags;
10265 
10266  if (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL)) {
10267  av_log(c->fc, AV_LOG_INFO, "iovl box with non seekable input\n");
10268  return AVERROR_PATCHWELCOME;
10269  }
10270  if (item->is_idat_relative) {
10271  if (!c->idat_offset) {
10272  av_log(c->fc, AV_LOG_ERROR, "missing idat box required by the image overlay\n");
10273  return AVERROR_INVALIDDATA;
10274  }
10275  offset = c->idat_offset;
10276  }
10277 
10278  avio_seek(s->pb, item->extent_offset + offset, SEEK_SET);
10279 
10280  avio_r8(s->pb); /* version */
10281  flags = avio_r8(s->pb);
10282 
10283  for (int i = 0; i < 4; i++)
10284  canvas_fill_value[i] = avio_rb16(s->pb);
10285  av_log(c->fc, AV_LOG_TRACE, "iovl: canvas_fill_value { %u, %u, %u, %u }\n",
10286  canvas_fill_value[0], canvas_fill_value[1],
10287  canvas_fill_value[2], canvas_fill_value[3]);
10288  for (int i = 0; i < 4; i++)
10289  tile_grid->background[i] = canvas_fill_value[i];
10290 
10291  /* actual width and height of output image */
10292  tile_grid->width =
10293  tile_grid->coded_width = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
10294  tile_grid->height =
10295  tile_grid->coded_height = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
10296 
10297  /* rotation */
10298  if (item->rotation || item->hflip || item->vflip) {
10300  &tile_grid->nb_coded_side_data, item);
10301  if (ret < 0)
10302  return ret;
10303  }
10304 
10305  /* ICC profile */
10306  if (item->icc_profile_size) {
10307  int ret = set_icc_profile_from_item(&tile_grid->coded_side_data,
10308  &tile_grid->nb_coded_side_data, item);
10309  if (ret < 0)
10310  return ret;
10311  }
10312 
10313  av_log(c->fc, AV_LOG_TRACE, "iovl: output_width %d, output_height %d\n",
10314  tile_grid->width, tile_grid->height);
10315 
10316  tile_grid->nb_tiles = grid->nb_tiles;
10317  tile_grid->offsets = av_malloc_array(tile_grid->nb_tiles, sizeof(*tile_grid->offsets));
10318  if (!tile_grid->offsets) {
10319  ret = AVERROR(ENOMEM);
10320  goto fail;
10321  }
10322 
10323  for (int i = 0; i < tile_grid->nb_tiles; i++) {
10324  tile_grid->offsets[i].idx = grid->tile_idx_list[i];
10325  tile_grid->offsets[i].horizontal = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
10326  tile_grid->offsets[i].vertical = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
10327  av_log(c->fc, AV_LOG_TRACE, "iovl: stream_idx[%d] %u, "
10328  "horizontal_offset[%d] %d, vertical_offset[%d] %d\n",
10329  i, tile_grid->offsets[i].idx,
10330  i, tile_grid->offsets[i].horizontal, i, tile_grid->offsets[i].vertical);
10331  }
10332 
10333 fail:
10334  avio_seek(s->pb, pos, SEEK_SET);
10335 
10336  return ret;
10337 }
10338 
10340 {
10341  MOVContext *mov = s->priv_data;
10342 
10343  for (int i = 0; i < mov->nb_heif_grid; i++) {
10345  AVStreamGroupTileGrid *tile_grid;
10346  const HEIFGrid *grid = &mov->heif_grid[i];
10347  int err, loop = 1;
10348 
10349  if (!stg)
10350  return AVERROR(ENOMEM);
10351 
10352  stg->id = grid->item->item_id;
10353  tile_grid = stg->params.tile_grid;
10354 
10355  for (int j = 0; j < grid->nb_tiles; j++) {
10356  int tile_id = grid->tile_id_list[j];
10357  int k;
10358 
10359  for (k = 0; k < mov->nb_heif_item; k++) {
10360  HEIFItem *item = mov->heif_item[k];
10361  AVStream *st;
10362 
10363  if (!item || item->item_id != tile_id)
10364  continue;
10365  st = item->st;
10366  if (!st) {
10367  av_log(s, AV_LOG_WARNING, "HEIF item id %d from grid id %d doesn't "
10368  "reference a stream\n",
10369  tile_id, grid->item->item_id);
10370  ff_remove_stream_group(s, stg);
10371  loop = 0;
10372  break;
10373  }
10374 
10375  grid->tile_item_list[j] = item;
10376  grid->tile_idx_list[j] = stg->nb_streams;
10377 
10378  err = avformat_stream_group_add_stream(stg, st);
10379  if (err < 0) {
10380  int l;
10381  if (err != AVERROR(EEXIST))
10382  return err;
10383 
10384  for (l = 0; l < stg->nb_streams; l++)
10385  if (stg->streams[l]->index == st->index)
10386  break;
10387  av_assert0(l < stg->nb_streams);
10388  grid->tile_idx_list[j] = l;
10389  }
10390 
10391  if (item->item_id != mov->primary_item_id)
10393  break;
10394  }
10395 
10396  if (k == mov->nb_heif_item) {
10397  av_assert0(loop);
10398  av_log(s, AV_LOG_WARNING, "HEIF item id %d referenced by grid id %d doesn't "
10399  "exist\n",
10400  tile_id, grid->item->item_id);
10401  ff_remove_stream_group(s, stg);
10402  loop = 0;
10403  }
10404  if (!loop)
10405  break;
10406  }
10407 
10408  if (!loop)
10409  continue;
10410 
10411  switch (grid->item->type) {
10412  case MKTAG('g','r','i','d'):
10413  err = read_image_grid(s, grid, tile_grid);
10414  break;
10415  case MKTAG('i','o','v','l'):
10416  err = read_image_iovl(s, grid, tile_grid);
10417  break;
10418  default:
10419  av_assert0(0);
10420  }
10421  if (err < 0)
10422  return err;
10423 
10424 
10425  if (grid->item->name)
10426  av_dict_set(&stg->metadata, "title", grid->item->name, 0);
10427  if (grid->item->item_id == mov->primary_item_id)
10429  }
10430 
10431  return 0;
10432 }
10433 
10435 {
10436  MOVContext *mov = s->priv_data;
10437  int err;
10438 
10439  for (int i = 0; i < mov->nb_heif_item; i++) {
10440  HEIFItem *item = mov->heif_item[i];
10441  MOVStreamContext *sc;
10442  AVStream *st;
10443  int64_t offset = 0;
10444 
10445  if (!item)
10446  continue;
10447  if (!item->st) {
10448  for (int j = 0; j < mov->nb_thmb_item; j++) {
10449  if (item->item_id == mov->thmb_item_id[j]) {
10450  av_log(s, AV_LOG_ERROR, "HEIF thumbnail ID %d doesn't reference a stream\n",
10451  item->item_id);
10452  return AVERROR_INVALIDDATA;
10453  }
10454  }
10455  continue;
10456  }
10457  if (item->is_idat_relative) {
10458  if (!mov->idat_offset) {
10459  av_log(s, AV_LOG_ERROR, "Missing idat box for item %d\n", item->item_id);
10460  return AVERROR_INVALIDDATA;
10461  }
10462  offset = mov->idat_offset;
10463  }
10464 
10465  st = item->st;
10466  sc = st->priv_data;
10467  st->codecpar->width = item->width;
10468  st->codecpar->height = item->height;
10469 
10470  sc->sample_size = sc->stsz_sample_size = item->extent_length;
10471  sc->sample_count = 1;
10472 
10473  err = sanity_checks(s, sc, item->item_id);
10474  if (err)
10475  return AVERROR_INVALIDDATA;
10476 
10477  sc->chunk_offsets[0] = item->extent_offset + offset;
10478 
10479  if (item->item_id == mov->primary_item_id)
10481 
10482  if (item->rotation || item->hflip || item->vflip) {
10484  &st->codecpar->nb_coded_side_data, item);
10485  if (err < 0)
10486  return err;
10487  }
10488 
10489  mov_build_index(mov, st);
10490  }
10491 
10492  if (mov->nb_heif_grid) {
10493  err = mov_parse_tiles(s);
10494  if (err < 0)
10495  return err;
10496  }
10497 
10498  return 0;
10499 }
10500 
10502  int first_index)
10503 {
10504  MOVStreamContext *sc = st->priv_data;
10505 
10506  if (sc->tref_id < 0)
10507  return NULL;
10508 
10509  for (int i = first_index; i < s->nb_streams; i++)
10510  if (s->streams[i]->id == sc->tref_id)
10511  return s->streams[i];
10512 
10513  return NULL;
10514 }
10515 
10517 {
10518  int err;
10519 
10520  for (int i = 0; i < s->nb_streams; i++) {
10521  AVStreamGroup *stg;
10522  AVStream *st = s->streams[i];
10523  AVStream *st_base;
10524  MOVStreamContext *sc = st->priv_data;
10525  int j = 0;
10526 
10527  /* Find an enhancement stream. */
10528  if (st->codecpar->codec_id != AV_CODEC_ID_LCEVC ||
10530  continue;
10531 
10533 
10535  if (!stg)
10536  return AVERROR(ENOMEM);
10537 
10538  stg->id = st->id;
10539  stg->params.lcevc->width = st->codecpar->width;
10540  stg->params.lcevc->height = st->codecpar->height;
10541  st->codecpar->width = 0;
10542  st->codecpar->height = 0;
10543 
10544  while (st_base = mov_find_reference_track(s, st, j)) {
10545  err = avformat_stream_group_add_stream(stg, st_base);
10546  if (err < 0)
10547  return err;
10548 
10549  j = st_base->index + 1;
10550  }
10551  if (!j) {
10552  av_log(s, AV_LOG_ERROR, "Failed to find base stream for enhancement stream\n");
10553  return AVERROR_INVALIDDATA;
10554  }
10555 
10556  err = avformat_stream_group_add_stream(stg, st);
10557  if (err < 0)
10558  return err;
10559 
10560  stg->params.lcevc->lcevc_index = stg->nb_streams - 1;
10561  }
10562 
10563  return 0;
10564 }
10565 
10567 {
10568  int highest_id = 0;
10569 
10570  for (int i = 0; i < s->nb_streams; i++) {
10571  const AVStream *st = s->streams[i];
10572  const MOVStreamContext *sc = st->priv_data;
10573  if (!sc->iamf)
10574  highest_id = FFMAX(highest_id, st->id);
10575  }
10576  highest_id += !highest_id;
10577  for (int i = 0; highest_id > 1 && i < s->nb_stream_groups; i++) {
10578  AVStreamGroup *stg = s->stream_groups[i];
10580  continue;
10581  for (int j = 0; j < stg->nb_streams; j++) {
10582  AVStream *st = stg->streams[j];
10583  MOVStreamContext *sc = st->priv_data;
10584  st->id += highest_id;
10585  sc->iamf_stream_offset = highest_id;
10586  }
10587  }
10588 }
10589 
10591 {
10592  MOVContext *mov = s->priv_data;
10593  AVIOContext *pb = s->pb;
10594  int j, err;
10595  MOVAtom atom = { AV_RL32("root") };
10596  int i;
10597 
10598  if (mov->decryption_key_len != 0 && mov->decryption_key_len != AES_CTR_KEY_SIZE) {
10599  av_log(s, AV_LOG_ERROR, "Invalid decryption key len %d expected %d\n",
10601  return AVERROR(EINVAL);
10602  }
10603 
10604  mov->fc = s;
10605  mov->trak_index = -1;
10606  mov->thmb_item_id = NULL;
10607  mov->primary_item_id = -1;
10608  mov->cur_item_id = -1;
10609  /* .mov and .mp4 aren't streamable anyway (only progressive download if moov is before mdat) */
10610  if (pb->seekable & AVIO_SEEKABLE_NORMAL)
10611  atom.size = avio_size(pb);
10612  else
10613  atom.size = INT64_MAX;
10614 
10615  /* check MOV header */
10616  do {
10617  if (mov->moov_retry)
10618  avio_seek(pb, 0, SEEK_SET);
10619  if ((err = mov_read_default(mov, pb, atom)) < 0) {
10620  av_log(s, AV_LOG_ERROR, "error reading header\n");
10621  return err;
10622  }
10623  } while ((pb->seekable & AVIO_SEEKABLE_NORMAL) &&
10624  !mov->found_moov && (!mov->found_iloc || !mov->found_iinf) && !mov->moov_retry++);
10625  if (!mov->found_moov && !mov->found_iloc && !mov->found_iinf) {
10626  av_log(s, AV_LOG_ERROR, "moov atom not found\n");
10627  return AVERROR_INVALIDDATA;
10628  }
10629  av_log(mov->fc, AV_LOG_TRACE, "on_parse_exit_offset=%"PRId64"\n", avio_tell(pb));
10630 
10631  if (mov->found_iloc && mov->found_iinf) {
10632  err = mov_parse_heif_items(s);
10633  if (err < 0)
10634  return err;
10635  }
10636  // prevent iloc and iinf boxes from being parsed while reading packets.
10637  // this is needed because an iinf box may have been parsed but ignored
10638  // for having old infe boxes which create no streams.
10639  mov->found_iloc = mov->found_iinf = 1;
10640 
10641  if (pb->seekable & AVIO_SEEKABLE_NORMAL) {
10642  if (mov->nb_chapter_tracks > 0 && !mov->ignore_chapters)
10644  for (i = 0; i < s->nb_streams; i++)
10645  if (s->streams[i]->codecpar->codec_tag == AV_RL32("tmcd")) {
10646  mov_read_timecode_track(s, s->streams[i]);
10647  } else if (s->streams[i]->codecpar->codec_tag == AV_RL32("rtmd")) {
10648  mov_read_rtmd_track(s, s->streams[i]);
10649  }
10650  }
10651 
10652  /* copy timecode metadata from tmcd tracks to the related video streams */
10653  for (i = 0; i < s->nb_streams; i++) {
10654  AVStream *st = s->streams[i];
10655  MOVStreamContext *sc = st->priv_data;
10656  if (sc->timecode_track > 0) {
10657  AVDictionaryEntry *tcr;
10658  int tmcd_st_id = -1;
10659 
10660  for (j = 0; j < s->nb_streams; j++) {
10661  MOVStreamContext *sc2 = s->streams[j]->priv_data;
10662  if (sc2->id == sc->timecode_track)
10663  tmcd_st_id = j;
10664  }
10665 
10666  if (tmcd_st_id < 0 || tmcd_st_id == i)
10667  continue;
10668  tcr = av_dict_get(s->streams[tmcd_st_id]->metadata, "timecode", NULL, 0);
10669  if (tcr)
10670  av_dict_set(&st->metadata, "timecode", tcr->value, 0);
10671  }
10672  }
10674 
10675  /* Create LCEVC stream groups. */
10676  err = mov_parse_lcevc_streams(s);
10677  if (err < 0)
10678  return err;
10679 
10680  for (i = 0; i < s->nb_streams; i++) {
10681  AVStream *st = s->streams[i];
10682  FFStream *const sti = ffstream(st);
10683  MOVStreamContext *sc = st->priv_data;
10684  uint32_t dvdsub_clut[FF_DVDCLUT_CLUT_LEN] = {0};
10685  fix_timescale(mov, sc);
10686 
10687  /* Set the primary extradata based on the first Sample if it doesn't reference the first stsd entry. */
10688  if (sc->stsc_count && sc->extradata_size && !sc->iamf &&
10689  sc->stsc_data[0].id > 1 && sc->stsc_data[0].id <= sc->stsd_count) {
10690  sc->last_stsd_index = sc->stsc_data[0].id - 1;
10691  av_freep(&st->codecpar->extradata);
10693  if (sc->extradata_size[sc->last_stsd_index]) {
10695  if (!st->codecpar->extradata)
10696  return AVERROR(ENOMEM);
10697  memcpy(st->codecpar->extradata, sc->extradata[sc->last_stsd_index], sc->extradata_size[sc->last_stsd_index]);
10698  }
10699  }
10700 
10701  if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
10702  st->codecpar->codec_id == AV_CODEC_ID_AAC) {
10703  sti->skip_samples = sc->start_pad;
10704  }
10705  if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && sc->nb_frames_for_fps > 0 && sc->duration_for_fps > 0)
10707  sc->time_scale*(int64_t)sc->nb_frames_for_fps, sc->duration_for_fps, INT_MAX);
10709  if (st->codecpar->width <= 0 || st->codecpar->height <= 0) {
10710  st->codecpar->width = sc->width;
10711  st->codecpar->height = sc->height;
10712  }
10715 
10716  for (j = 0; j < FF_DVDCLUT_CLUT_LEN; j++)
10717  dvdsub_clut[j] = AV_RB32(st->codecpar->extradata + j * 4);
10718 
10719  err = ff_dvdclut_yuv_to_rgb(dvdsub_clut, FF_DVDCLUT_CLUT_SIZE);
10720  if (err < 0)
10721  return err;
10722 
10723  av_freep(&st->codecpar->extradata);
10724  st->codecpar->extradata_size = 0;
10725 
10727  st->codecpar);
10728  if (err < 0)
10729  return err;
10730  }
10731  }
10732  if (mov->handbrake_version &&
10733  mov->handbrake_version <= 1000000*0 + 1000*10 + 2 && // 0.10.2
10734  st->codecpar->codec_id == AV_CODEC_ID_MP3) {
10735  av_log(s, AV_LOG_VERBOSE, "Forcing full parsing for mp3 stream\n");
10737  }
10738  }
10739 
10740  if (mov->trex_data || mov->use_mfra_for > 0) {
10741  for (i = 0; i < s->nb_streams; i++) {
10742  AVStream *st = s->streams[i];
10743  MOVStreamContext *sc = st->priv_data;
10744  if (sc->duration_for_fps > 0) {
10745  /* Akin to sc->data_size * 8 * sc->time_scale / sc->duration_for_fps but accounting for overflows. */
10747  if (st->codecpar->bit_rate == INT64_MIN) {
10748  av_log(s, AV_LOG_WARNING, "Overflow during bit rate calculation %"PRId64" * 8 * %d\n",
10749  sc->data_size, sc->time_scale);
10750  st->codecpar->bit_rate = 0;
10751  if (s->error_recognition & AV_EF_EXPLODE)
10752  return AVERROR_INVALIDDATA;
10753  }
10754  }
10755  }
10756  }
10757 
10758  for (i = 0; i < mov->bitrates_count && i < s->nb_streams; i++) {
10759  if (mov->bitrates[i]) {
10760  s->streams[i]->codecpar->bit_rate = mov->bitrates[i];
10761  }
10762  }
10763 
10765 
10766  for (i = 0; i < s->nb_streams; i++) {
10767  AVStream *st = s->streams[i];
10768  MOVStreamContext *sc = st->priv_data;
10769 
10770  switch (st->codecpar->codec_type) {
10771  case AVMEDIA_TYPE_AUDIO:
10772  err = ff_replaygain_export(st, s->metadata);
10773  if (err < 0)
10774  return err;
10775  break;
10776  case AVMEDIA_TYPE_VIDEO:
10777  if (sc->display_matrix) {
10780  (uint8_t*)sc->display_matrix, sizeof(int32_t) * 9, 0))
10781  return AVERROR(ENOMEM);
10782 
10783  sc->display_matrix = NULL;
10784  }
10785  if (sc->stereo3d) {
10788  (uint8_t *)sc->stereo3d, sc->stereo3d_size, 0))
10789  return AVERROR(ENOMEM);
10790 
10791  sc->stereo3d = NULL;
10792  }
10793  if (sc->spherical) {
10796  (uint8_t *)sc->spherical, sc->spherical_size, 0))
10797  return AVERROR(ENOMEM);
10798 
10799  sc->spherical = NULL;
10800  }
10801  if (sc->mastering) {
10804  (uint8_t *)sc->mastering, sc->mastering_size, 0))
10805  return AVERROR(ENOMEM);
10806 
10807  sc->mastering = NULL;
10808  }
10809  if (sc->coll) {
10812  (uint8_t *)sc->coll, sc->coll_size, 0))
10813  return AVERROR(ENOMEM);
10814 
10815  sc->coll = NULL;
10816  }
10817  if (sc->ambient) {
10820  (uint8_t *) sc->ambient, sc->ambient_size, 0))
10821  return AVERROR(ENOMEM);
10822 
10823  sc->ambient = NULL;
10824  }
10825  break;
10826  }
10827  }
10828 
10829  fix_stream_ids(s);
10830 
10832 
10833  for (i = 0; i < mov->frag_index.nb_items; i++)
10834  if (mov->frag_index.item[i].moof_offset <= mov->fragment.moof_offset)
10835  mov->frag_index.item[i].headers_read = 1;
10836 
10837  return 0;
10838 }
10839 
10841 {
10843  int64_t best_dts = INT64_MAX;
10844  int i;
10845  MOVContext *mov = s->priv_data;
10846  int no_interleave = !mov->interleaved_read || !(s->pb->seekable & AVIO_SEEKABLE_NORMAL);
10847  for (i = 0; i < s->nb_streams; i++) {
10848  AVStream *avst = s->streams[i];
10849  FFStream *const avsti = ffstream(avst);
10850  MOVStreamContext *msc = avst->priv_data;
10851  if (msc->pb && msc->current_sample < avsti->nb_index_entries) {
10852  AVIndexEntry *current_sample = &avsti->index_entries[msc->current_sample];
10853  int64_t dts = av_rescale(current_sample->timestamp, AV_TIME_BASE, msc->time_scale);
10854  uint64_t dtsdiff = best_dts > dts ? best_dts - (uint64_t)dts : ((uint64_t)dts - best_dts);
10855  av_log(s, AV_LOG_TRACE, "stream %d, sample %d, dts %"PRId64"\n", i, msc->current_sample, dts);
10856  if (!sample || (no_interleave && current_sample->pos < sample->pos) ||
10857  ((s->pb->seekable & AVIO_SEEKABLE_NORMAL) &&
10858  ((msc->pb != s->pb && dts < best_dts) || (msc->pb == s->pb && dts != AV_NOPTS_VALUE &&
10859  ((dtsdiff <= AV_TIME_BASE && current_sample->pos < sample->pos) ||
10860  (dtsdiff > AV_TIME_BASE && dts < best_dts && mov->interleaved_read)))))) {
10861  sample = current_sample;
10862  best_dts = dts;
10863  *st = avst;
10864  }
10865  }
10866  }
10867  return sample;
10868 }
10869 
10870 static int should_retry(AVIOContext *pb, int error_code) {
10871  if (error_code == AVERROR_EOF || avio_feof(pb))
10872  return 0;
10873 
10874  return 1;
10875 }
10876 
10877 static int mov_switch_root(AVFormatContext *s, int64_t target, int index)
10878 {
10879  int ret;
10880  MOVContext *mov = s->priv_data;
10881 
10882  if (index >= 0 && index < mov->frag_index.nb_items)
10883  target = mov->frag_index.item[index].moof_offset;
10884  if (target >= 0 && avio_seek(s->pb, target, SEEK_SET) != target) {
10885  av_log(mov->fc, AV_LOG_ERROR, "root atom offset 0x%"PRIx64": partial file\n", target);
10886  return AVERROR_INVALIDDATA;
10887  }
10888 
10889  mov->next_root_atom = 0;
10890  if ((index < 0 && target >= 0) || index >= mov->frag_index.nb_items)
10891  index = search_frag_moof_offset(&mov->frag_index, target);
10892  if (index >= 0 && index < mov->frag_index.nb_items &&
10893  mov->frag_index.item[index].moof_offset == target) {
10894  if (index + 1 < mov->frag_index.nb_items)
10895  mov->next_root_atom = mov->frag_index.item[index + 1].moof_offset;
10896  if (mov->frag_index.item[index].headers_read)
10897  return 0;
10898  mov->frag_index.item[index].headers_read = 1;
10899  }
10900 
10901  mov->found_mdat = 0;
10902 
10903  ret = mov_read_default(mov, s->pb, (MOVAtom){ AV_RL32("root"), INT64_MAX });
10904  if (ret < 0)
10905  return ret;
10906  if (avio_feof(s->pb))
10907  return AVERROR_EOF;
10908  av_log(s, AV_LOG_TRACE, "read fragments, offset 0x%"PRIx64"\n", avio_tell(s->pb));
10909 
10910  return 1;
10911 }
10912 
10914 {
10915  MOVStreamContext *sc = st->priv_data;
10916  uint8_t *side, *extradata;
10917  int extradata_size;
10918 
10919  /* Save the current index. */
10920  sc->last_stsd_index = sc->stsc_data[sc->stsc_index].id - 1;
10921 
10922  /* Notify the decoder that extradata changed. */
10923  extradata_size = sc->extradata_size[sc->last_stsd_index];
10924  extradata = sc->extradata[sc->last_stsd_index];
10925  if (st->discard != AVDISCARD_ALL && extradata_size > 0 && extradata) {
10928  extradata_size);
10929  if (!side)
10930  return AVERROR(ENOMEM);
10931  memcpy(side, extradata, extradata_size);
10932  }
10933 
10934  return 0;
10935 }
10936 
10937 static int get_eia608_packet(AVIOContext *pb, AVPacket *pkt, int src_size)
10938 {
10939  /* We can't make assumptions about the structure of the payload,
10940  because it may include multiple cdat and cdt2 samples. */
10941  const uint32_t cdat = AV_RB32("cdat");
10942  const uint32_t cdt2 = AV_RB32("cdt2");
10943  int ret, out_size = 0;
10944 
10945  /* a valid payload must have size, 4cc, and at least 1 byte pair: */
10946  if (src_size < 10)
10947  return AVERROR_INVALIDDATA;
10948 
10949  /* avoid an int overflow: */
10950  if ((src_size - 8) / 2 >= INT_MAX / 3)
10951  return AVERROR_INVALIDDATA;
10952 
10953  ret = av_new_packet(pkt, ((src_size - 8) / 2) * 3);
10954  if (ret < 0)
10955  return ret;
10956 
10957  /* parse and re-format the c608 payload in one pass. */
10958  while (src_size >= 10) {
10959  const uint32_t atom_size = avio_rb32(pb);
10960  const uint32_t atom_type = avio_rb32(pb);
10961  const uint32_t data_size = atom_size - 8;
10962  const uint8_t cc_field =
10963  atom_type == cdat ? 1 :
10964  atom_type == cdt2 ? 2 :
10965  0;
10966 
10967  /* account for bytes consumed for atom size and type. */
10968  src_size -= 8;
10969 
10970  /* make sure the data size stays within the buffer boundaries. */
10971  if (data_size < 2 || data_size > src_size) {
10973  break;
10974  }
10975 
10976  /* make sure the data size is consistent with N byte pairs. */
10977  if (data_size % 2 != 0) {
10979  break;
10980  }
10981 
10982  if (!cc_field) {
10983  /* neither cdat or cdt2 ... skip it */
10984  avio_skip(pb, data_size);
10985  src_size -= data_size;
10986  continue;
10987  }
10988 
10989  for (uint32_t i = 0; i < data_size; i += 2) {
10990  pkt->data[out_size] = (0x1F << 3) | (1 << 2) | (cc_field - 1);
10991  pkt->data[out_size + 1] = avio_r8(pb);
10992  pkt->data[out_size + 2] = avio_r8(pb);
10993  out_size += 3;
10994  src_size -= 2;
10995  }
10996  }
10997 
10998  if (src_size > 0)
10999  /* skip any remaining unread portion of the input payload */
11000  avio_skip(pb, src_size);
11001 
11003  return ret;
11004 }
11005 
11007  int64_t current_index, AVPacket *pkt)
11008 {
11009  MOVStreamContext *sc = st->priv_data;
11010 
11011  pkt->stream_index = sc->ffindex;
11012  pkt->dts = sample->timestamp;
11013  if (sample->flags & AVINDEX_DISCARD_FRAME) {
11015  }
11016  if (sc->stts_count && sc->tts_index < sc->tts_count)
11017  pkt->duration = sc->tts_data[sc->tts_index].duration;
11018  if (sc->ctts_count && sc->tts_index < sc->tts_count) {
11020  } else {
11021  if (pkt->duration == 0) {
11022  int64_t next_dts = (sc->current_sample < ffstream(st)->nb_index_entries) ?
11024  if (next_dts >= pkt->dts)
11025  pkt->duration = next_dts - pkt->dts;
11026  }
11027  pkt->pts = pkt->dts;
11028  }
11029 
11030  if (sc->tts_data && sc->tts_index < sc->tts_count) {
11031  /* update tts context */
11032  sc->tts_sample++;
11033  if (sc->tts_index < sc->tts_count &&
11034  sc->tts_data[sc->tts_index].count == sc->tts_sample) {
11035  sc->tts_index++;
11036  sc->tts_sample = 0;
11037  }
11038  }
11039 
11040  if (sc->sdtp_data && sc->current_sample <= sc->sdtp_count) {
11041  uint8_t sample_flags = sc->sdtp_data[sc->current_sample - 1];
11042  uint8_t sample_is_depended_on = (sample_flags >> 2) & 0x3;
11043  pkt->flags |= sample_is_depended_on == MOV_SAMPLE_DEPENDENCY_NO ? AV_PKT_FLAG_DISPOSABLE : 0;
11044  }
11045  pkt->flags |= sample->flags & AVINDEX_KEYFRAME ? AV_PKT_FLAG_KEY : 0;
11046  pkt->pos = sample->pos;
11047 
11048  /* Multiple stsd handling. */
11049  if (sc->stsc_data) {
11050  if (sc->stsc_data[sc->stsc_index].id > 0 &&
11051  sc->stsc_data[sc->stsc_index].id - 1 < sc->stsd_count &&
11052  sc->stsc_data[sc->stsc_index].id - 1 != sc->last_stsd_index) {
11053  int ret = mov_change_extradata(st, pkt);
11054  if (ret < 0)
11055  return ret;
11056  }
11057 
11058  /* Update the stsc index for the next sample */
11059  sc->stsc_sample++;
11060  if (mov_stsc_index_valid(sc->stsc_index, sc->stsc_count) &&
11061  mov_get_stsc_samples(sc, sc->stsc_index) == sc->stsc_sample) {
11062  sc->stsc_index++;
11063  sc->stsc_sample = 0;
11064  }
11065  }
11066 
11067  return 0;
11068 }
11069 
11071 {
11072  MOVContext *mov = s->priv_data;
11073  MOVStreamContext *sc;
11075  AVStream *st = NULL;
11076  FFStream *avsti = NULL;
11077  int64_t current_index;
11078  int ret;
11079  int i;
11080  mov->fc = s;
11081  retry:
11082  if (s->pb->pos == 0) {
11083 
11084  // Discard current fragment index
11085  if (mov->frag_index.allocated_size > 0) {
11086  for(int i = 0; i < mov->frag_index.nb_items; i++) {
11088  }
11089  av_freep(&mov->frag_index.item);
11090  mov->frag_index.nb_items = 0;
11091  mov->frag_index.allocated_size = 0;
11092  mov->frag_index.current = -1;
11093  mov->frag_index.complete = 0;
11094  }
11095 
11096  for (i = 0; i < s->nb_streams; i++) {
11097  AVStream *avst = s->streams[i];
11098  MOVStreamContext *msc = avst->priv_data;
11099 
11100  // Clear current sample
11101  mov_current_sample_set(msc, 0);
11102  msc->tts_index = 0;
11103 
11104  // Discard current index entries
11105  avsti = ffstream(avst);
11106  if (avsti->index_entries_allocated_size > 0) {
11107  av_freep(&avsti->index_entries);
11108  avsti->index_entries_allocated_size = 0;
11109  avsti->nb_index_entries = 0;
11110  }
11111  }
11112 
11113  if ((ret = mov_switch_root(s, -1, -1)) < 0)
11114  return ret;
11115  }
11116  sample = mov_find_next_sample(s, &st);
11117  if (!sample || (mov->next_root_atom && sample->pos > mov->next_root_atom)) {
11118  if (!mov->next_root_atom)
11119  return AVERROR_EOF;
11120  if ((ret = mov_switch_root(s, mov->next_root_atom, -1)) < 0)
11121  return ret;
11122  goto retry;
11123  }
11124  sc = st->priv_data;
11125  /* must be done just before reading, to avoid infinite loop on sample */
11126  current_index = sc->current_index;
11128 
11129  if (mov->next_root_atom) {
11130  sample->pos = FFMIN(sample->pos, mov->next_root_atom);
11131  sample->size = FFMIN(sample->size, (mov->next_root_atom - sample->pos));
11132  }
11133 
11134  if (st->discard != AVDISCARD_ALL) {
11135  int64_t ret64 = avio_seek(sc->pb, sample->pos, SEEK_SET);
11136  if (ret64 != sample->pos) {
11137  av_log(mov->fc, AV_LOG_ERROR, "stream %d, offset 0x%"PRIx64": partial file\n",
11138  sc->ffindex, sample->pos);
11139  if (should_retry(sc->pb, ret64)) {
11141  } else if (ret64 < 0) {
11142  return (int)ret64;
11143  }
11144  return AVERROR_INVALIDDATA;
11145  }
11146 
11147  if (st->discard == AVDISCARD_NONKEY && !(sample->flags & AVINDEX_KEYFRAME)) {
11148  av_log(mov->fc, AV_LOG_DEBUG, "Nonkey frame from stream %d discarded due to AVDISCARD_NONKEY\n", sc->ffindex);
11149  goto retry;
11150  }
11151 
11152  if (st->codecpar->codec_id == AV_CODEC_ID_EIA_608 && sample->size > 8)
11153  ret = get_eia608_packet(sc->pb, pkt, sample->size);
11154 #if CONFIG_IAMFDEC
11155  else if (sc->iamf) {
11156  int64_t pts, dts, pos, duration;
11157  int flags, size = sample->size;
11158  ret = mov_finalize_packet(s, st, sample, current_index, pkt);
11159  pts = pkt->pts; dts = pkt->dts;
11160  pos = pkt->pos; flags = pkt->flags;
11161  duration = pkt->duration;
11162  while (!ret && size > 0) {
11163  ret = ff_iamf_read_packet(s, sc->iamf, sc->pb, size, sc->iamf_stream_offset, pkt);
11164  if (ret < 0) {
11165  if (should_retry(sc->pb, ret))
11167  return ret;
11168  }
11169  size -= ret;
11170  pkt->pts = pts; pkt->dts = dts;
11171  pkt->pos = pos; pkt->flags |= flags;
11172  pkt->duration = duration;
11173  ret = ff_buffer_packet(s, pkt);
11174  }
11175  if (!ret)
11176  return FFERROR_REDO;
11177  }
11178 #endif
11179  else if (st->codecpar->codec_id == AV_CODEC_ID_APV && sample->size > 4) {
11180  const uint32_t au_size = avio_rb32(sc->pb);
11181  ret = av_get_packet(sc->pb, pkt, au_size);
11182  } else
11183  ret = av_get_packet(sc->pb, pkt, sample->size);
11184  if (ret < 0) {
11185  if (should_retry(sc->pb, ret)) {
11187  }
11188  return ret;
11189  }
11190 #if CONFIG_DV_DEMUXER
11191  if (mov->dv_demux && sc->dv_audio_container) {
11194  if (ret < 0)
11195  return ret;
11197  if (ret < 0)
11198  return ret;
11199  }
11200 #endif
11201  if (sc->has_palette) {
11202  uint8_t *pal;
11203 
11205  if (!pal) {
11206  av_log(mov->fc, AV_LOG_ERROR, "Cannot append palette to packet\n");
11207  } else {
11208  memcpy(pal, sc->palette, AVPALETTE_SIZE);
11209  sc->has_palette = 0;
11210  }
11211  }
11212  if (st->codecpar->codec_id == AV_CODEC_ID_MP3 && !ffstream(st)->need_parsing && pkt->size > 4) {
11213  if (ff_mpa_check_header(AV_RB32(pkt->data)) < 0)
11215  }
11216  }
11217 
11218  ret = mov_finalize_packet(s, st, sample, current_index, pkt);
11219  if (ret < 0)
11220  return ret;
11221 
11222  if (st->discard == AVDISCARD_ALL)
11223  goto retry;
11224 
11225  if (mov->aax_mode)
11226  aax_filter(pkt->data, pkt->size, mov);
11227 
11228  ret = cenc_filter(mov, st, sc, pkt, current_index);
11229  if (ret < 0) {
11230  return ret;
11231  }
11232 
11233  return 0;
11234 }
11235 
11237 {
11238  MOVContext *mov = s->priv_data;
11239  int index;
11240 
11241  if (!mov->frag_index.complete)
11242  return 0;
11243 
11244  index = search_frag_timestamp(s, &mov->frag_index, st, timestamp);
11245  if (index < 0)
11246  index = 0;
11247  if (!mov->frag_index.item[index].headers_read)
11248  return mov_switch_root(s, -1, index);
11249  if (index + 1 < mov->frag_index.nb_items)
11250  mov->next_root_atom = mov->frag_index.item[index + 1].moof_offset;
11251 
11252  return 0;
11253 }
11254 
11255 static int is_open_key_sample(const MOVStreamContext *sc, int sample)
11256 {
11257  // TODO: a bisect search would scale much better
11258  for (int i = 0; i < sc->open_key_samples_count; i++) {
11259  const int oks = sc->open_key_samples[i];
11260  if (oks == sample)
11261  return 1;
11262  if (oks > sample) /* list is monotically increasing so we can stop early */
11263  break;
11264  }
11265  return 0;
11266 }
11267 
11268 /*
11269  * Some key sample may be key frames but not IDR frames, so a random access to
11270  * them may not be allowed.
11271  */
11272 static int can_seek_to_key_sample(AVStream *st, int sample, int64_t requested_pts)
11273 {
11274  MOVStreamContext *sc = st->priv_data;
11275  FFStream *const sti = ffstream(st);
11276  int64_t key_sample_dts, key_sample_pts;
11277 
11278  if (st->codecpar->codec_id != AV_CODEC_ID_HEVC)
11279  return 1;
11280 
11281  if (sample >= sc->sample_offsets_count)
11282  return 1;
11283 
11284  key_sample_dts = sti->index_entries[sample].timestamp;
11285  key_sample_pts = key_sample_dts + sc->sample_offsets[sample] + sc->dts_shift;
11286 
11287  /*
11288  * If the sample needs to be presented before an open key sample, they may
11289  * not be decodable properly, even though they come after in decoding
11290  * order.
11291  */
11292  if (is_open_key_sample(sc, sample) && key_sample_pts > requested_pts)
11293  return 0;
11294 
11295  return 1;
11296 }
11297 
11298 static int mov_seek_stream(AVFormatContext *s, AVStream *st, int64_t timestamp, int flags)
11299 {
11300  MOVStreamContext *sc = st->priv_data;
11301  FFStream *const sti = ffstream(st);
11302  int sample, time_sample, ret, next_ts, requested_sample;
11303  unsigned int i;
11304 
11305  // Here we consider timestamp to be PTS, hence try to offset it so that we
11306  // can search over the DTS timeline.
11307  timestamp -= (sc->min_corrected_pts + sc->dts_shift);
11308 
11309  ret = mov_seek_fragment(s, st, timestamp);
11310  if (ret < 0)
11311  return ret;
11312 
11313  for (;;) {
11314  sample = av_index_search_timestamp(st, timestamp, flags);
11315  av_log(s, AV_LOG_TRACE, "stream %d, timestamp %"PRId64", sample %d\n", st->index, timestamp, sample);
11316  if (sample < 0 && sti->nb_index_entries && timestamp < sti->index_entries[0].timestamp)
11317  sample = 0;
11318  if (sample < 0) /* not sure what to do */
11319  return AVERROR_INVALIDDATA;
11320 
11321  if (!sample || can_seek_to_key_sample(st, sample, timestamp))
11322  break;
11323 
11324  next_ts = timestamp - FFMAX(sc->min_sample_duration, 1);
11325  requested_sample = av_index_search_timestamp(st, next_ts, flags);
11326 
11327  // If we've reached a different sample trying to find a good pts to
11328  // seek to, give up searching because we'll end up seeking back to
11329  // sample 0 on every seek.
11330  if (sample != requested_sample && !can_seek_to_key_sample(st, requested_sample, next_ts))
11331  break;
11332 
11333  timestamp = next_ts;
11334  }
11335 
11337  av_log(s, AV_LOG_TRACE, "stream %d, found sample %d\n", st->index, sc->current_sample);
11338  /* adjust time to sample index */
11339  if (sc->tts_data) {
11340  time_sample = 0;
11341  for (i = 0; i < sc->tts_count; i++) {
11342  int next = time_sample + sc->tts_data[i].count;
11343  if (next > sc->current_sample) {
11344  sc->tts_index = i;
11345  sc->tts_sample = sc->current_sample - time_sample;
11346  break;
11347  }
11348  time_sample = next;
11349  }
11350  }
11351 
11352  /* adjust stsd index */
11353  if (sc->chunk_count) {
11354  time_sample = 0;
11355  for (i = 0; i < sc->stsc_count; i++) {
11356  int64_t next = time_sample + mov_get_stsc_samples(sc, i);
11357  if (next > sc->current_sample) {
11358  sc->stsc_index = i;
11359  sc->stsc_sample = sc->current_sample - time_sample;
11360  break;
11361  }
11362  av_assert0(next == (int)next);
11363  time_sample = next;
11364  }
11365  }
11366 
11367  return sample;
11368 }
11369 
11371 {
11372  MOVStreamContext *sc = st->priv_data;
11373  FFStream *const sti = ffstream(st);
11374  int64_t first_ts = sti->index_entries[0].timestamp;
11376  int64_t off;
11377 
11379  return 0;
11380 
11381  /* compute skip samples according to stream start_pad, seek ts and first ts */
11382  off = av_rescale_q(ts - first_ts, st->time_base,
11383  (AVRational){1, st->codecpar->sample_rate});
11384  return FFMAX(sc->start_pad - off, 0);
11385 }
11386 
11387 static int mov_read_seek(AVFormatContext *s, int stream_index, int64_t sample_time, int flags)
11388 {
11389  MOVContext *mc = s->priv_data;
11390  AVStream *st;
11391  FFStream *sti;
11392  int sample;
11393  int i;
11394 
11395  if (stream_index >= s->nb_streams)
11396  return AVERROR_INVALIDDATA;
11397 
11398  st = s->streams[stream_index];
11399  sti = ffstream(st);
11400  sample = mov_seek_stream(s, st, sample_time, flags);
11401  if (sample < 0)
11402  return sample;
11403 
11404  if (mc->seek_individually) {
11405  /* adjust seek timestamp to found sample timestamp */
11406  int64_t seek_timestamp = sti->index_entries[sample].timestamp;
11408 
11409  for (i = 0; i < s->nb_streams; i++) {
11410  AVStream *const st = s->streams[i];
11411  FFStream *const sti = ffstream(st);
11412  int64_t timestamp;
11413 
11414  if (stream_index == i)
11415  continue;
11416 
11417  timestamp = av_rescale_q(seek_timestamp, s->streams[stream_index]->time_base, st->time_base);
11418  sample = mov_seek_stream(s, st, timestamp, flags);
11419  if (sample >= 0)
11421  }
11422  } else {
11423  for (i = 0; i < s->nb_streams; i++) {
11424  MOVStreamContext *sc;
11425  st = s->streams[i];
11426  sc = st->priv_data;
11427  mov_current_sample_set(sc, 0);
11428  }
11429  while (1) {
11430  MOVStreamContext *sc;
11432  if (!entry)
11433  return AVERROR_INVALIDDATA;
11434  sc = st->priv_data;
11435  if (sc->ffindex == stream_index && sc->current_sample == sample)
11436  break;
11438  }
11439  }
11440  return 0;
11441 }
11442 
11443 #define OFFSET(x) offsetof(MOVContext, x)
11444 #define FLAGS AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM
11445 static const AVOption mov_options[] = {
11446  {"use_absolute_path",
11447  "allow using absolute path when opening alias, this is a possible security issue",
11448  OFFSET(use_absolute_path), AV_OPT_TYPE_BOOL, {.i64 = 0},
11449  0, 1, FLAGS},
11450  {"seek_streams_individually",
11451  "Seek each stream individually to the closest point",
11452  OFFSET(seek_individually), AV_OPT_TYPE_BOOL, { .i64 = 1 },
11453  0, 1, FLAGS},
11454  {"ignore_editlist", "Ignore the edit list atom.", OFFSET(ignore_editlist), AV_OPT_TYPE_BOOL, {.i64 = 0},
11455  0, 1, FLAGS},
11456  {"advanced_editlist",
11457  "Modify the AVIndex according to the editlists. Use this option to decode in the order specified by the edits.",
11458  OFFSET(advanced_editlist), AV_OPT_TYPE_BOOL, {.i64 = 1},
11459  0, 1, FLAGS},
11460  {"ignore_chapters", "", OFFSET(ignore_chapters), AV_OPT_TYPE_BOOL, {.i64 = 0},
11461  0, 1, FLAGS},
11462  {"use_mfra_for",
11463  "use mfra for fragment timestamps",
11464  OFFSET(use_mfra_for), AV_OPT_TYPE_INT, {.i64 = FF_MOV_FLAG_MFRA_AUTO},
11466  .unit = "use_mfra_for"},
11467  {"auto", "auto", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_AUTO}, 0, 0,
11468  FLAGS, .unit = "use_mfra_for" },
11469  {"dts", "dts", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_DTS}, 0, 0,
11470  FLAGS, .unit = "use_mfra_for" },
11471  {"pts", "pts", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_PTS}, 0, 0,
11472  FLAGS, .unit = "use_mfra_for" },
11473  {"use_tfdt", "use tfdt for fragment timestamps", OFFSET(use_tfdt), AV_OPT_TYPE_BOOL, {.i64 = 1},
11474  0, 1, FLAGS},
11475  { "export_all", "Export unrecognized metadata entries", OFFSET(export_all),
11476  AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = FLAGS },
11477  { "export_xmp", "Export full XMP metadata", OFFSET(export_xmp),
11478  AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = FLAGS },
11479  { "activation_bytes", "Secret bytes for Audible AAX files", OFFSET(activation_bytes),
11481  { "audible_key", "AES-128 Key for Audible AAXC files", OFFSET(audible_key),
11483  { "audible_iv", "AES-128 IV for Audible AAXC files", OFFSET(audible_iv),
11485  { "audible_fixed_key", // extracted from libAAX_SDK.so and AAXSDKWin.dll files!
11486  "Fixed key used for handling Audible AAX files", OFFSET(audible_fixed_key),
11487  AV_OPT_TYPE_BINARY, {.str="77214d4b196a87cd520045fd20a51d67"},
11488  .flags = AV_OPT_FLAG_DECODING_PARAM },
11489  { "decryption_key", "The media decryption key (hex)", OFFSET(decryption_key), AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM },
11490  { "enable_drefs", "Enable external track support.", OFFSET(enable_drefs), AV_OPT_TYPE_BOOL,
11491  {.i64 = 0}, 0, 1, FLAGS },
11492  { "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 },
11493  { "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 },
11494 
11495  { NULL },
11496 };
11497 
11498 static const AVClass mov_class = {
11499  .class_name = "mov,mp4,m4a,3gp,3g2,mj2",
11500  .item_name = av_default_item_name,
11501  .option = mov_options,
11502  .version = LIBAVUTIL_VERSION_INT,
11503 };
11504 
11506  .p.name = "mov,mp4,m4a,3gp,3g2,mj2",
11507  .p.long_name = NULL_IF_CONFIG_SMALL("QuickTime / MOV"),
11508  .p.priv_class = &mov_class,
11509  .p.extensions = "mov,mp4,m4a,3gp,3g2,mj2,psp,m4b,ism,ismv,isma,f4v,avif,heic,heif",
11511  .priv_data_size = sizeof(MOVContext),
11512  .flags_internal = FF_INFMT_FLAG_INIT_CLEANUP,
11513  .read_probe = mov_probe,
11518 };
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:191
item_name
item_name
Definition: libkvazaar.c:313
AV_CODEC_ID_PCM_S16LE
@ AV_CODEC_ID_PCM_S16LE
Definition: codec_id.h:337
flags
const SwsFlags flags[]
Definition: swscale.c:61
mov_finalize_stsd_entry
static int mov_finalize_stsd_entry(MOVContext *c, AVStream *st)
Definition: mov.c:3032
mov_read_chpl
static int mov_read_chpl(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:597
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:7352
mov_read_meta
static int mov_read_meta(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5476
AV_CODEC_ID_EIA_608
@ AV_CODEC_ID_EIA_608
Definition: codec_id.h:572
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:432
MOVContext::found_iloc
int found_iloc
'iloc' atom has been found
Definition: isom.h:320
AV_CODEC_ID_MACE6
@ AV_CODEC_ID_MACE6
Definition: codec_id.h:461
MOVFragmentStreamInfo::first_tfra_pts
int64_t first_tfra_pts
Definition: isom.h:142
ff_rfps_add_frame
int ff_rfps_add_frame(AVFormatContext *ic, AVStream *st, int64_t ts)
add frame for rfps calculation.
Definition: demux.c:2282
read_image_iovl
static int read_image_iovl(AVFormatContext *s, const HEIFGrid *grid, AVStreamGroupTileGrid *tile_grid)
Definition: mov.c:10257
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:9178
AVMEDIA_TYPE_SUBTITLE
@ AVMEDIA_TYPE_SUBTITLE
Definition: avutil.h:203
AVIAMFSubmix::elements
AVIAMFSubmixElement ** elements
Array of submix elements.
Definition: iamf.h:565
skip_bits_long
static void skip_bits_long(GetBitContext *s, int n)
Skips the specified number of bits.
Definition: get_bits.h:276
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:401
PUT_UTF8
#define PUT_UTF8(val, tmp, PUT_BYTE)
Definition: common.h:541
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:357
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:221
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:382
AVCodecParameters::extradata
uint8_t * extradata
Extra binary data needed for initializing the decoder, codec-dependent.
Definition: codec_par.h:69
mov_read_dops
static int mov_read_dops(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:8419
can_seek_to_key_sample
static int can_seek_to_key_sample(AVStream *st, int sample, int64_t requested_pts)
Definition: mov.c:11272
AV_CODEC_ID_ADPCM_IMA_QT
@ AV_CODEC_ID_ADPCM_IMA_QT
Definition: codec_id.h:376
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:486
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:1117
AV_CODEC_ID_AC3
@ AV_CODEC_ID_AC3
Definition: codec_id.h:454
HEIFItem::name
char * name
Definition: isom.h:291
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:243
MOVStreamContext::height
int height
tkhd height
Definition: isom.h:229
MOVContext::moov_retry
int moov_retry
Definition: isom.h:348
MOV_TRUN_SAMPLE_FLAGS
#define MOV_TRUN_SAMPLE_FLAGS
Definition: isom.h:409
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:336
mix
static int mix(int c0, int c1)
Definition: 4xm.c:717
MOVStreamContext::last_stsd_index
int last_stsd_index
Definition: isom.h:258
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
MOV_TKHD_FLAG_ENABLED
#define MOV_TKHD_FLAG_ENABLED
Definition: isom.h:422
AVCodecParameters::codec_type
enum AVMediaType codec_type
General type of the encoded data.
Definition: codec_par.h:51
AVStreamGroup::tile_grid
struct AVStreamGroupTileGrid * tile_grid
Definition: avformat.h:1133
AVFMT_SHOW_IDS
#define AVFMT_SHOW_IDS
Show format stream IDs numbers.
Definition: avformat.h:476
AVSphericalMapping::projection
enum AVSphericalProjection projection
Projection type.
Definition: spherical.h:104
AV_WL32
#define AV_WL32(p, v)
Definition: intreadwrite.h:422
AV_STREAM_GROUP_PARAMS_LCEVC
@ AV_STREAM_GROUP_PARAMS_LCEVC
Definition: avformat.h:1092
MOVStreamContext::extradata
uint8_t ** extradata
extradata array (and size) for multiple stsd
Definition: isom.h:256
mov_class
static const AVClass mov_class
Definition: mov.c:11498
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:248
AVUUID
uint8_t AVUUID[AV_UUID_LEN]
Definition: uuid.h:60
out
FILE * out
Definition: movenc.c:55
MOVFragmentStreamInfo
Definition: isom.h:139
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:2278
mov_read_chnl
static int mov_read_chnl(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1191
mov_read_moof
static int mov_read_moof(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1815
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
AVCodecParameters
This struct describes the properties of an encoded stream.
Definition: codec_par.h:47
HEIFItem::icc_profile
uint8_t * icc_profile
Definition: isom.h:302
AVFMT_FLAG_IGNIDX
#define AVFMT_FLAG_IGNIDX
Ignore index.
Definition: avformat.h:1417
sanity_checks
static int sanity_checks(void *log_obj, MOVStreamContext *sc, int index)
Definition: mov.c:5116
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:169
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:9988
HEIFItem::hflip
int hflip
Definition: isom.h:298
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:769
AVERROR_EOF
#define AVERROR_EOF
End of file.
Definition: error.h:57
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:670
AVStream::discard
enum AVDiscard discard
Selects which packets can be discarded at will and do not need to be demuxed.
Definition: avformat.h:815
AV_FIELD_PROGRESSIVE
@ AV_FIELD_PROGRESSIVE
Definition: defs.h:213
mov_options
static const AVOption mov_options[]
Definition: mov.c:11445
mov_codec_id
static int mov_codec_id(AVStream *st, uint32_t format)
Definition: mov.c:2627
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:246
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:8810
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:614
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:419
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:2250
test_same_origin
static int test_same_origin(const char *src, const char *ref)
Definition: mov.c:4959
metadata
Stream codec metadata
Definition: ogg-flac-chained-meta.txt:2
cbcs_scheme_decrypt
static int cbcs_scheme_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
Definition: mov.c:8242
MOVFragment::base_data_offset
uint64_t base_data_offset
Definition: isom.h:104
MOVStreamContext
Definition: isom.h:173
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:194
ff_buffer_packet
int ff_buffer_packet(AVFormatContext *s, AVPacket *pkt)
Definition: demux.c:612
IS_MATRIX_IDENT
#define IS_MATRIX_IDENT(matrix)
Definition: mov.c:5494
AVStreamGroup::disposition
int disposition
Stream group disposition - a combination of AV_DISPOSITION_* flags.
Definition: avformat.h:1175
av_unused
#define av_unused
Definition: attributes.h:131
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:617
mov_update_dts_shift
static void mov_update_dts_shift(MOVStreamContext *sc, int duration, void *logctx)
Definition: mov.c:3663
MOVStreamContext::spherical
AVSphericalMapping * spherical
Definition: isom.h:265
mask
int mask
Definition: mediacodecdec_common.c:154
out_size
int out_size
Definition: movenc.c:56
AV_CODEC_ID_MPEG4
@ AV_CODEC_ID_MPEG4
Definition: codec_id.h:64
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:126
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
mov_read_avss
static int mov_read_avss(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2255
AV_RB32A
#define AV_RB32A(p)
Definition: intreadwrite.h:575
MOVContext::primary_item_id
int primary_item_id
Definition: isom.h:373
mode
Definition: swscale.c:56
MOVContext::found_moov
int found_moov
'moov' atom has been found
Definition: isom.h:319
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:279
mov_read_custom
static int mov_read_custom(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5336
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:1332
HEIFGrid::nb_tiles
int nb_tiles
Definition: isom.h:311
ID3v1_GENRE_MAX
#define ID3v1_GENRE_MAX
Definition: id3v1.h:29
MOVSbgp
Definition: isom.h:121
MOVCtts
Definition: isom.h:68
AVPacketSideData
This structure stores auxiliary information for decoding, presenting, or otherwise processing the cod...
Definition: packet.h:403
mov_read_extradata
static int mov_read_extradata(MOVContext *c, AVIOContext *pb, MOVAtom atom, enum AVCodecID codec_id)
Definition: mov.c:2224
AVCOL_RANGE_JPEG
@ AVCOL_RANGE_JPEG
Full range content.
Definition: pixfmt.h:767
mpegaudiodecheader.h
MOVStreamContext::rap_group_count
unsigned int rap_group_count
Definition: isom.h:240
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
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:300
mov_read_mvhd
static int mov_read_mvhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1917
mov_read_idat
static int mov_read_idat(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:8804
AVPacket::data
uint8_t * data
Definition: packet.h:552
MOVContext::found_mdat
int found_mdat
'mdat' atom has been found
Definition: isom.h:322
MOVStreamContext::drefs_count
unsigned drefs_count
Definition: isom.h:222
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:2270
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
Audio only.
Definition: codec_par.h:214
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:343
AVOption
AVOption.
Definition: opt.h:429
MOVContext::trex_data
MOVTrackExt * trex_data
Definition: isom.h:331
mov_read_stps
static int mov_read_stps(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:3320
MOVContext::bitrates
int * bitrates
bitrates read before streams creation
Definition: isom.h:346
b
#define b
Definition: input.c:42
AVCOL_TRC_UNSPECIFIED
@ AVCOL_TRC_UNSPECIFIED
Definition: pixfmt.h:664
MOVContext::interleaved_read
int interleaved_read
Definition: isom.h:382
mov_read_tkhd
static int mov_read_tkhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5502
MOVElst::rate
float rate
Definition: isom.h:82
AVStream::avg_frame_rate
AVRational avg_frame_rate
Average framerate.
Definition: avformat.h:833
table
static const uint16_t table[]
Definition: prosumer.c:203
spherical.h
mov_read_colr
static int mov_read_colr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2071
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:1956
mov_read_strf
static int mov_read_strf(MOVContext *c, AVIOContext *pb, MOVAtom atom)
An strf atom is a BITMAPINFOHEADER struct.
Definition: mov.c:2540
AV_CODEC_ID_ALAC
@ AV_CODEC_ID_ALAC
Definition: codec_id.h:467
HEIFItem::st
AVStream * st
Definition: isom.h:290
FF_COMPLIANCE_STRICT
#define FF_COMPLIANCE_STRICT
Strictly conform to all the things in the spec no matter what consequences.
Definition: defs.h:59
AVIOContext::error
int error
contains the error code or 0 if no error happened
Definition: avio.h:239
MOVStreamContext::cenc
struct MOVStreamContext::@436 cenc
AV_CODEC_ID_AMR_NB
@ AV_CODEC_ID_AMR_NB
Definition: codec_id.h:432
av_iamf_mix_presentation_free
void av_iamf_mix_presentation_free(AVIAMFMixPresentation **pmix_presentation)
Free an AVIAMFMixPresentation and all its contents.
Definition: iamf.c:534
mov_parse_auxiliary_info
static int mov_parse_auxiliary_info(MOVContext *c, MOVStreamContext *sc, AVIOContext *pb, MOVEncryptionIndex *encryption_index)
Definition: mov.c:7560
mov_seek_stream
static int mov_seek_stream(AVFormatContext *s, AVStream *st, int64_t timestamp, int flags)
Definition: mov.c:11298
mov_read_saio
static int mov_read_saio(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:7706
mov_get_stsc_samples
static int64_t mov_get_stsc_samples(MOVStreamContext *sc, unsigned int index)
Definition: mov.c:3305
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:530
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:3872
MOVFragmentIndexItem::moof_offset
int64_t moof_offset
Definition: isom.h:153
MOVStreamContext::spherical_size
size_t spherical_size
Definition: isom.h:266
mov_change_extradata
static int mov_change_extradata(AVStream *st, AVPacket *pkt)
Definition: mov.c:10913
MOVStreamContext::tref_id
int tref_id
Definition: isom.h:226
MP4TrackKindMapping::scheme_uri
const char * scheme_uri
Definition: isom.h:484
AVINDEX_DISCARD_FRAME
#define AVINDEX_DISCARD_FRAME
Definition: avformat.h:607
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:570
AVCodecParameters::codec_tag
uint32_t codec_tag
Additional information about the codec (corresponds to the AVI FOURCC).
Definition: codec_par.h:59
fixed_key
static const uint8_t fixed_key[]
Definition: aes_ctr.c:40
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:4176
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:626
AVProbeData::buf_size
int buf_size
Size of buf except extra allocated bytes.
Definition: avformat.h:454
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:94
AVStreamGroupTileGrid::vertical
int vertical
Offset in pixels from the top edge of the canvas where the tile should be placed.
Definition: avformat.h:1000
iamf_parse.h
mov_read_moov
static int mov_read_moov(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1567
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:352
mov_read_esds
static int mov_read_esds(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:846
MOVStreamContext::sample_count
unsigned int sample_count
Definition: isom.h:205
MOVFragmentIndex::allocated_size
int allocated_size
Definition: isom.h:161
MOVTrackExt::flags
unsigned flags
Definition: isom.h:118
AVChannelLayout::nb_channels
int nb_channels
Number of channels in this layout.
Definition: channel_layout.h:329
HEIFItem::height
int height
Definition: isom.h:296
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:192
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:197
heif_cur_item
static HEIFItem * heif_cur_item(MOVContext *c)
Get the current item in the parsing process.
Definition: mov.c:193
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_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:340
avio_size
int64_t avio_size(AVIOContext *s)
Get the filesize.
Definition: aviobuf.c:323
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:2562
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:7072
FFIOContext
Definition: avio_internal.h:28
AV_PKT_FLAG_KEY
#define AV_PKT_FLAG_KEY
The packet contains a keyframe.
Definition: packet.h:607
init_get_bits
static int init_get_bits(GetBitContext *s, const uint8_t *buffer, int bit_size)
Initialize GetBitContext.
Definition: get_bits.h:512
MOVStreamContext::aes_ctr
struct AVAESCTR * aes_ctr
Definition: isom.h:278
cenc_filter
static int cenc_filter(MOVContext *mov, AVStream *st, MOVStreamContext *sc, AVPacket *pkt, int current_index)
Definition: mov.c:8349
mov_read_sdtp
static int mov_read_sdtp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:3629
mov_read_jp2h
static int mov_read_jp2h(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2260
AV_STEREO3D_UNSPEC
@ AV_STEREO3D_UNSPEC
Video is stereoscopic but the packing is unspecified.
Definition: stereo3d.h:143
AVIndexEntry
Definition: avformat.h:598
AV_WB64
#define AV_WB64(p, v)
Definition: intreadwrite.h:429
MOVStreamContext::dv_audio_container
int dv_audio_container
Definition: isom.h:219
AV_CODEC_ID_AMR_WB
@ AV_CODEC_ID_AMR_WB
Definition: codec_id.h:433
mov_read_tfhd
static int mov_read_tfhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5607
AV_CODEC_ID_BIN_DATA
@ AV_CODEC_ID_BIN_DATA
Definition: codec_id.h:603
av_malloc
#define av_malloc(s)
Definition: tableprint_vlc.h:31
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:55
IAMFMixPresentation::cmix
const AVIAMFMixPresentation * cmix
Definition: iamf.h:108
mov_read_wide
static int mov_read_wide(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6186
AVINDEX_KEYFRAME
#define AVINDEX_KEYFRAME
Definition: avformat.h:606
AV_FIELD_BT
@ AV_FIELD_BT
Bottom coded first, top displayed first.
Definition: defs.h:217
MOVStreamContext::stsd_count
int stsd_count
Definition: isom.h:259
ff_mov_lang_to_iso639
int ff_mov_lang_to_iso639(unsigned code, char to[4])
Definition: isom.c:260
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:191
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:326
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:379
AVCodecParameters::color_primaries
enum AVColorPrimaries color_primaries
Definition: codec_par.h:167
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:193
MOVStreamContext::has_palette
int has_palette
Definition: isom.h:234
AVPROBE_SCORE_MAX
#define AVPROBE_SCORE_MAX
maximum score
Definition: avformat.h:463
AV_STEREO3D_SIDEBYSIDE
@ AV_STEREO3D_SIDEBYSIDE
Views are next to each other.
Definition: stereo3d.h:64
MOVIndexRange::start
int64_t start
Definition: isom.h:169
AVPacketSideData::size
size_t size
Definition: packet.h:405
get_bits
static unsigned int get_bits(GetBitContext *s, int n)
Read 1-25 bits.
Definition: get_bits.h:333
ff_remove_stream
void ff_remove_stream(AVFormatContext *s, AVStream *st)
Remove a stream from its AVFormatContext and free it.
Definition: avformat.c:113
OFFSET
#define OFFSET(x)
Definition: mov.c:11443
HEIFGrid::tile_item_list
HEIFItem ** tile_item_list
Definition: isom.h:308
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:10123
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:252
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:736
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:777
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
aax_filter
static int aax_filter(uint8_t *input, int size, MOVContext *c)
Definition: mov.c:1505
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:286
av_color_space_name
const char * av_color_space_name(enum AVColorSpace space)
Definition: pixdesc.c:3817
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:198
MOVStreamContext::mastering
AVMasteringDisplayMetadata * mastering
Definition: isom.h:267
AV_CODEC_ID_SPEEX
@ AV_CODEC_ID_SPEEX
Definition: codec_id.h:486
AV_FOURCC_MAX_STRING_SIZE
#define AV_FOURCC_MAX_STRING_SIZE
Definition: avutil.h:345
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
ffstream
static av_always_inline FFStream * ffstream(AVStream *st)
Definition: internal.h:347
MOVFragmentIndexItem::current
int current
Definition: isom.h:155
AVFMT_SEEK_TO_PTS
#define AVFMT_SEEK_TO_PTS
Seeking is based on PTS.
Definition: avformat.h:499
AV_CODEC_ID_PCM_S16BE
@ AV_CODEC_ID_PCM_S16BE
Definition: codec_id.h:338
mov_read_mdhd
static int mov_read_mdhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1871
mov_read_ctts
static int mov_read_ctts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:3674
MOVTrackExt
Definition: isom.h:113
MOV_FRAG_SAMPLE_FLAG_IS_NON_SYNC
#define MOV_FRAG_SAMPLE_FLAG_IS_NON_SYNC
Definition: isom.h:413
fail
#define fail()
Definition: checkasm.h:199
mov_read_aclr
static int mov_read_aclr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2335
AVSEEK_FLAG_ANY
#define AVSEEK_FLAG_ANY
seek to any frame, even non-keyframes
Definition: avformat.h:2376
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:102
AVStreamGroupTileGrid
AVStreamGroupTileGrid holds information on how to combine several independent images on a single canv...
Definition: avformat.h:951
MOVContext::decryption_key
uint8_t * decryption_key
Definition: isom.h:366
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:292
av_shrink_packet
void av_shrink_packet(AVPacket *pkt, int size)
Reduce packet size, correctly zeroing padding.
Definition: packet.c:114
timecode.h
get_current_frag_stream_info
static MOVFragmentStreamInfo * get_current_frag_stream_info(MOVFragmentIndex *frag_index)
Definition: mov.c:1624
GetBitContext
Definition: get_bits.h:109
MOVStreamContext::mastering_size
size_t mastering_size
Definition: isom.h:268
AVStreamGroupTileGrid::coded_width
int coded_width
Width of the canvas.
Definition: avformat.h:966
av_iamf_audio_element_free
void av_iamf_audio_element_free(AVIAMFAudioElement **paudio_element)
Free an AVIAMFAudioElement and all its contents.
Definition: iamf.c:336
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:6545
mov_read_enda
static int mov_read_enda(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1985
mov_read_chap
static int mov_read_chap(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5654
MOVParseTableEntry
Definition: mov.c:81
avio_tell
static av_always_inline int64_t avio_tell(AVIOContext *s)
ftell() equivalent for AVIOContext.
Definition: avio.h:494
MOV_TRUN_SAMPLE_DURATION
#define MOV_TRUN_SAMPLE_DURATION
Definition: isom.h:407
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:10137
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:314
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:675
AVStreamGroupTileGrid::coded_height
int coded_height
Width of the canvas.
Definition: avformat.h:972
pts
static int64_t pts
Definition: transcode_aac.c:644
MOVStreamContext::v_spacing
int v_spacing
pasp vSpacing
Definition: isom.h:231
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:452
AVStream::duration
int64_t duration
Decoding: duration of the stream, in stream time base.
Definition: avformat.h:803
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:228
MOVContext::meta_keys
char ** meta_keys
Definition: isom.h:325
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:257
AVIAMFAudioElement::audio_element_type
enum AVIAMFAudioElementType audio_element_type
Audio element type as defined in section 3.6 of IAMF.
Definition: iamf.h:388
loop
static int loop
Definition: ffplay.c:335
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:451
update_frag_index
static int update_frag_index(MOVContext *c, int64_t offset)
Definition: mov.c:1739
AV_CODEC_ID_PRORES_RAW
@ AV_CODEC_ID_PRORES_RAW
Definition: codec_id.h:333
AVRational::num
int num
Numerator.
Definition: rational.h:59
MOVStreamContext::keyframes
int * keyframes
Definition: isom.h:209
MOVEncryptionIndex::auxiliary_info_sample_count
size_t auxiliary_info_sample_count
Definition: isom.h:133
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:6617
AVStream::attached_pic
AVPacket attached_pic
For streams with AV_DISPOSITION_ATTACHED_PIC disposition, this packet will contain the attached pictu...
Definition: avformat.h:842
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:7622
MOV_FRAG_SAMPLE_FLAG_DEPENDS_YES
#define MOV_FRAG_SAMPLE_FLAG_DEPENDS_YES
Definition: isom.h:420
mov_merge_tts_data
static int mov_merge_tts_data(MOVContext *mov, AVStream *st, int flags)
Definition: mov.c:4587
MOVContext::idat_offset
int64_t idat_offset
Definition: isom.h:381
MOV_TRUN_DATA_OFFSET
#define MOV_TRUN_DATA_OFFSET
Definition: isom.h:405
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:199
mov_read_ares
static int mov_read_ares(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2292
mov_read_adrm
static int mov_read_adrm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1379
av_get_bits_per_sample
int av_get_bits_per_sample(enum AVCodecID codec_id)
Return codec bits per sample.
Definition: utils.c:547
AVCodecParameters::color_trc
enum AVColorTransferCharacteristic color_trc
Definition: codec_par.h:168
IAMFContext::audio_elements
IAMFAudioElement ** audio_elements
Definition: iamf.h:131
MOVFragmentIndex::complete
int complete
Definition: isom.h:162
AV_CODEC_ID_PCM_S8
@ AV_CODEC_ID_PCM_S8
Definition: codec_id.h:341
avassert.h
avio_rb32
unsigned int avio_rb32(AVIOContext *s)
Definition: aviobuf.c:761
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:196
pkt
AVPacket * pkt
Definition: movenc.c:60
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:460
MOVTrackExt::track_id
unsigned track_id
Definition: isom.h:114
mov_free_encryption_index
static void mov_free_encryption_index(MOVEncryptionIndex **index)
Definition: mov.c:9859
AV_CH_LOW_FREQUENCY
#define AV_CH_LOW_FREQUENCY
Definition: channel_layout.h:178
duration
int64_t duration
Definition: movenc.c:65
MOVEncryptionIndex::auxiliary_offsets
uint64_t * auxiliary_offsets
Absolute seek position.
Definition: isom.h:135
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:232
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 only.
Definition: codec_par.h:195
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:90
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:260
AV_STREAM_GROUP_PARAMS_IAMF_MIX_PRESENTATION
@ AV_STREAM_GROUP_PARAMS_IAMF_MIX_PRESENTATION
Definition: avformat.h:1090
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:4067
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:497
FF_MOV_FLAG_MFRA_PTS
#define FF_MOV_FLAG_MFRA_PTS
Definition: isom.h:457
MOV_MERGE_STTS
#define MOV_MERGE_STTS
Definition: mov.c:4581
MOVStreamContext::iamf_stream_offset
int iamf_stream_offset
Definition: isom.h:286
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:6479
s
#define s(width, name)
Definition: cbs_vp9.c:198
MOVFragmentStreamInfo::encryption_index
MOVEncryptionIndex * encryption_index
Definition: isom.h:148
mov_read_trak
static int mov_read_trak(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5134
IAMFSubStream::audio_substream_id
unsigned int audio_substream_id
Definition: iamf.h:83
MOVContext::fc
AVFormatContext * fc
Definition: isom.h:316
MOV_TFHD_DEFAULT_BASE_IS_MOOF
#define MOV_TFHD_DEFAULT_BASE_IS_MOOF
Definition: isom.h:403
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:99
AV_CODEC_ID_BMP
@ AV_CODEC_ID_BMP
Definition: codec_id.h:130
AV_CODEC_ID_EVC
@ AV_CODEC_ID_EVC
Definition: codec_id.h:325
IAMFLayer::substream_count
unsigned int substream_count
Definition: iamf.h:78
MOV_TFHD_DEFAULT_DURATION
#define MOV_TFHD_DEFAULT_DURATION
Definition: isom.h:399
ALAC_EXTRADATA_SIZE
#define ALAC_EXTRADATA_SIZE
DRM_BLOB_SIZE
#define DRM_BLOB_SIZE
Definition: mov.c:1377
MOVStreamContext::sample_offsets_count
int sample_offsets_count
Definition: isom.h:247
MOVCtts::count
unsigned int count
Definition: isom.h:69
MOVStreamContext::drefs
MOVDref * drefs
Definition: isom.h:223
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:549
MOVContext::aes_decrypt
struct AVAES * aes_decrypt
Definition: isom.h:365
AVProbeData::buf
unsigned char * buf
Buffer must have AVPROBE_PADDING_SIZE of extra allocated bytes filled with zero.
Definition: avformat.h:453
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:222
MOVFragmentIndex::nb_items
int nb_items
Definition: isom.h:164
AVCodecParameters::width
int width
Video only.
Definition: codec_par.h:134
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:451
HEIFGrid::tile_idx_list
unsigned * tile_idx_list
Definition: isom.h:310
MOV_TRUN_FIRST_SAMPLE_FLAGS
#define MOV_TRUN_FIRST_SAMPLE_FLAGS
Definition: isom.h:406
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:609
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:252
MOVStreamContext::keyframe_absent
int keyframe_absent
Definition: isom.h:207
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:493
MOVStreamContext::coll_size
size_t coll_size
Definition: isom.h:270
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:4096
AVIndexEntry::timestamp
int64_t timestamp
Timestamp in AVStream.time_base units, preferably the time from which on correctly decoded frames are...
Definition: avformat.h:600
av_assert0
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:41
MOVStreamContext::min_corrected_pts
int64_t min_corrected_pts
minimum Composition time shown by the edits excluding empty edits.
Definition: isom.h:212
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:927
tile_cols
int tile_cols
Definition: av1_levels.c:73
MOVStreamContext::sdtp_count
unsigned int sdtp_count
Definition: isom.h:188
dvdclut.h
mov_read_lhvc
static int mov_read_lhvc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:8523
AV_LOG_DEBUG
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:231
AVPacketSideData::data
uint8_t * data
Definition: packet.h:404
ctx
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:6048
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
nb_streams
static int nb_streams
Definition: ffprobe.c:334
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:1165
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:10840
AV_CODEC_ID_TARGA_Y216
@ AV_CODEC_ID_TARGA_Y216
Definition: codec_id.h:258
AVIndexEntry::min_distance
int min_distance
Minimum distance between this and the previous keyframe, used to avoid unneeded searching.
Definition: avformat.h:610
mov_read_dvcc_dvvc
static int mov_read_dvcc_dvvc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:8503
MOVParseTableEntry::parse
int(* parse)(MOVContext *ctx, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:83
codec_id
enum AVCodecID codec_id
Definition: vaapi_decode.c:410
AV_CODEC_ID_SVQ3
@ AV_CODEC_ID_SVQ3
Definition: codec_id.h:75
key
const char * key
Definition: hwcontext_opencl.c:189
AVCodecParameters::nb_coded_side_data
int nb_coded_side_data
Amount of entries in coded_side_data.
Definition: codec_par.h:86
MOVStreamContext::sdtp_data
uint8_t * sdtp_data
Definition: isom.h:189
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:344
mov_read_stss
static int mov_read_stss(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:3361
mov_read_ddts
static int mov_read_ddts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1119
mov_read_uuid
static int mov_read_uuid(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:7225
AVCOL_PRI_UNSPECIFIED
@ AVCOL_PRI_UNSPECIFIED
Definition: pixfmt.h:639
MOVTrackExt::duration
unsigned duration
Definition: isom.h:116
AV_CODEC_ID_H264
@ AV_CODEC_ID_H264
Definition: codec_id.h:79
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:72
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:213
MOVFragmentStreamInfo::sidx_pts
int64_t sidx_pts
Definition: isom.h:141
MAX_REORDER_DELAY
#define MAX_REORDER_DELAY
Definition: mov.c:4095
MOVFragmentIndex::current
int current
Definition: isom.h:163
MOVEncryptionIndex::encrypted_samples
AVEncryptionInfo ** encrypted_samples
Definition: isom.h:130
mov_read_close
static int mov_read_close(AVFormatContext *s)
Definition: mov.c:9933
MOVAtom::size
int64_t size
Definition: isom.h:96
MOVStreamContext::refcount
int refcount
Definition: isom.h:175
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:463
AV_CODEC_ID_PNG
@ AV_CODEC_ID_PNG
Definition: codec_id.h:113
AV_CODEC_ID_AVUI
@ AV_CODEC_ID_AVUI
Definition: codec_id.h:257
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:6206
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:7450
FFStream::need_parsing
enum AVStreamParseType need_parsing
Definition: internal.h:314
MOVStreamContext::keyframe_count
unsigned int keyframe_count
Definition: isom.h:208
mov_read_SAND
static int mov_read_SAND(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:8751
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:1264
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:3509
MOVStreamContext::index_ranges
MOVIndexRange * index_ranges
Definition: isom.h:215
DDTS_SIZE
#define DDTS_SIZE
internal.h
MOVTrackExt::stsd_id
unsigned stsd_id
Definition: isom.h:115
AVStreamGroupLCEVC::height
int height
Height of the final image for presentation.
Definition: avformat.h:1084
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:3918
set_frag_stream
static void set_frag_stream(MOVFragmentIndex *frag_index, int id)
Definition: mov.c:1604
mov_read_free
static int mov_read_free(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:7330
mov_realloc_extradata
static int mov_realloc_extradata(AVCodecParameters *par, MOVAtom atom)
Definition: mov.c:2187
AVStream::codecpar
AVCodecParameters * codecpar
Codec parameters associated with this stream.
Definition: avformat.h:767
LIBAVUTIL_VERSION_INT
#define LIBAVUTIL_VERSION_INT
Definition: version.h:85
AVSEEK_FLAG_BACKWARD
#define AVSEEK_FLAG_BACKWARD
Definition: avformat.h:2374
aes.h
AVClass
Describe the class of an AVClass context structure.
Definition: log.h:76
MOVStreamContext::tts_sample
int tts_sample
Definition: isom.h:202
avpriv_dv_get_packet
int avpriv_dv_get_packet(DVDemuxContext *c, AVPacket *pkt)
Definition: dv.c:731
MOVContext::ignore_editlist
int ignore_editlist
Definition: isom.h:338
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
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:783
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_CODEC_ID_AV1
@ AV_CODEC_ID_AV1
Definition: codec_id.h:284
MOVStreamContext::ctts_count
unsigned int ctts_count
Definition: isom.h:190
AVEncryptionInitInfo
This describes info used to initialize an encryption key system.
Definition: encryption_info.h:88
isom.h
tmp
static uint8_t tmp[20]
Definition: aes_ctr.c:47
MP4TrackKindValueMapping::disposition
int disposition
Definition: isom.h:479
mov_read_ftyp
static int mov_read_ftyp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1519
AV_WB16
#define AV_WB16(p, v)
Definition: intreadwrite.h:401
MOVContext::nb_heif_grid
int nb_heif_grid
Definition: isom.h:378
read_image_grid
static int read_image_grid(AVFormatContext *s, const HEIFGrid *grid, AVStreamGroupTileGrid *tile_grid)
Definition: mov.c:10158
MOVElst
Definition: isom.h:79
av_aes_ctr_alloc
struct AVAESCTR * av_aes_ctr_alloc(void)
Allocate an AVAESCTR context.
Definition: aes_ctr.c:40
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:1054
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:3755
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:9579
AVPALETTE_SIZE
#define AVPALETTE_SIZE
Definition: pixfmt.h:32
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:10937
AV_CODEC_ID_DVD_SUBTITLE
@ AV_CODEC_ID_DVD_SUBTITLE
Definition: codec_id.h:562
AVIndexEntry::flags
int flags
Definition: avformat.h:608
MOVStreamContext::time_offset
int64_t time_offset
time offset of the edit list entries
Definition: isom.h:211
mov_read_smdm
static int mov_read_smdm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6388
av_default_item_name
const char * av_default_item_name(void *ptr)
Return the context name.
Definition: log.c:240
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:908
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:216
mov_open_dref
static int mov_open_dref(MOVContext *c, AVIOContext **pb, const char *src, MOVDref *ref)
Definition: mov.c:4988
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:451
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:433
IAMFSubStream
Definition: iamf.h:82
MOVStreamContext::timecode_track
int timecode_track
Definition: isom.h:227
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:7922
AVStream::metadata
AVDictionary * metadata
Definition: avformat.h:824
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:3775
FF_MOV_FLAG_MFRA_DTS
#define FF_MOV_FLAG_MFRA_DTS
Definition: isom.h:456
MOV_SAMPLE_DEPENDENCY_NO
#define MOV_SAMPLE_DEPENDENCY_NO
Definition: isom.h:429
mov_read_iref_thmb
static int mov_read_iref_thmb(MOVContext *c, AVIOContext *pb, int version)
Definition: mov.c:9088
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
MOVStreamContext::tts_index
int tts_index
Definition: isom.h:201
AV_DISPOSITION_MULTILAYER
#define AV_DISPOSITION_MULTILAYER
The video stream contains multiple layers, e.g.
Definition: avformat.h:714
MOVFragmentStreamInfo::index_base
int index_base
Definition: isom.h:146
MOVStreamContext::rap_group
MOVSbgp * rap_group
Definition: isom.h:241
AV_CODEC_ID_QDM2
@ AV_CODEC_ID_QDM2
Definition: codec_id.h:470
mov_read_ilst
static int mov_read_ilst(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5281
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
Audio only.
Definition: codec_par.h:180
get_frag_stream_info_from_pkt
static MOVFragmentStreamInfo * get_frag_stream_info_from_pkt(MOVFragmentIndex *frag_index, AVPacket *pkt, int id)
Definition: mov.c:8324
get_sgpd_sync_index
static uint32_t get_sgpd_sync_index(const MOVStreamContext *sc, int nal_unit_type)
Definition: mov.c:4509
mov_read_fiel
static int mov_read_fiel(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2153
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:45
MOV_MP4_TTML_TAG
#define MOV_MP4_TTML_TAG
Definition: isom.h:474
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:397
MOVFragmentStreamInfo::stsd_id
int stsd_id
Definition: isom.h:149
MOVStreamContext::open_key_samples_count
int open_key_samples_count
Definition: isom.h:249
HEIFItem
Definition: isom.h:289
ff_codec_movaudio_tags
const AVCodecTag ff_codec_movaudio_tags[]
Definition: isom_tags.c:311
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:1223
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:40
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:461
MOVSbgp::count
unsigned int count
Definition: isom.h:122
AVCodecParameters::sample_rate
int sample_rate
Audio only.
Definition: codec_par.h:184
mov_parse_stsd_subtitle
static void mov_parse_stsd_subtitle(MOVContext *c, AVIOContext *pb, AVStream *st, MOVStreamContext *sc, int64_t size)
Definition: mov.c:2842
cid
uint16_t cid
Definition: mxfenc.c:2314
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:3006
MOVStts
Definition: isom.h:63
AVAudioServiceType
AVAudioServiceType
Definition: defs.h:235
AV_CODEC_ID_MPEG1VIDEO
@ AV_CODEC_ID_MPEG1VIDEO
Definition: codec_id.h:53
AV_CODEC_ID_GSM
@ AV_CODEC_ID_GSM
as in Berlin toast format
Definition: codec_id.h:469
AVStream::nb_frames
int64_t nb_frames
number of frames in this stream if known or 0
Definition: avformat.h:805
AVCodecID
AVCodecID
Identify the syntax and semantics of the bitstream.
Definition: codec_id.h:49
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:659
AVIAMFSubmixElement::audio_element_id
unsigned int audio_element_id
The id of the Audio Element this submix element references.
Definition: iamf.h:452
AV_CODEC_ID_EAC3
@ AV_CODEC_ID_EAC3
Definition: codec_id.h:491
should_retry
static int should_retry(AVIOContext *pb, int error_code)
Definition: mov.c:10870
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:513
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:73
AVIAMFSubmix
Submix layout as defined in section 3.7 of IAMF.
Definition: iamf.h:556
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:1347
MOVContext::dv_demux
DVDemuxContext * dv_demux
Definition: isom.h:327
AV_CODEC_ID_AAC
@ AV_CODEC_ID_AAC
Definition: codec_id.h:453
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:8661
mov_read_elst
static int mov_read_elst(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6259
MOVEncryptionIndex::auxiliary_info_default_size
uint8_t auxiliary_info_default_size
Definition: isom.h:134
AV_STREAM_GROUP_PARAMS_TILE_GRID
@ AV_STREAM_GROUP_PARAMS_TILE_GRID
Definition: avformat.h:1091
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:10590
AV_CODEC_ID_QCELP
@ AV_CODEC_ID_QCELP
Definition: codec_id.h:475
AV_SPHERICAL_HALF_EQUIRECTANGULAR
@ AV_SPHERICAL_HALF_EQUIRECTANGULAR
Video frame displays as a 180 degree equirectangular projection.
Definition: spherical.h:73
cbc1_scheme_decrypt
static int cbc1_scheme_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
Definition: mov.c:8117
avio_rl32
unsigned int avio_rl32(AVIOContext *s)
Definition: aviobuf.c:730
MOVStreamContext::tref_flags
unsigned tref_flags
Definition: isom.h:225
AVDISCARD_NONKEY
@ AVDISCARD_NONKEY
discard all frames except keyframes
Definition: defs.h:231
MOVFragment::flags
unsigned flags
Definition: isom.h:110
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:349
mov_read_wave
static int mov_read_wave(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2383
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:754
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:279
MOV_TREF_FLAG_ENHANCEMENT
#define MOV_TREF_FLAG_ENHANCEMENT
Definition: isom.h:431
cens_scheme_decrypt
static int cens_scheme_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
Definition: mov.c:8177
MOVContext::handbrake_version
int handbrake_version
Definition: isom.h:334
mov_free_stream_context
static void mov_free_stream_context(AVFormatContext *s, AVStream *st)
Definition: mov.c:9871
AVPacket::size
int size
Definition: packet.h:553
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:94
ff_codec_get_id
enum AVCodecID ff_codec_get_id(const AVCodecTag *tags, unsigned int tag)
Definition: utils.c:136
avformat_alloc_context
AVFormatContext * avformat_alloc_context(void)
Allocate an AVFormatContext.
Definition: options.c:162
MOVFragmentIndexItem
Definition: isom.h:152
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:7399
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:71
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:240
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:636
mov_current_sample_dec
static void mov_current_sample_dec(MOVStreamContext *sc)
Definition: mov.c:4164
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
av_bswap32
#define av_bswap32
Definition: bswap.h:47
MOVStreamContext::stsz_sample_size
unsigned int stsz_sample_size
always contains sample size from stsz atom
Definition: isom.h:204
FF_MOV_FLAG_MFRA_AUTO
#define FF_MOV_FLAG_MFRA_AUTO
Definition: isom.h:455
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:603
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:244
start_time
static int64_t start_time
Definition: ffplay.c:326
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:5740
MOVStreamContext::stereo3d_size
size_t stereo3d_size
Definition: isom.h:264
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:866
mov_read_iprp
static int mov_read_iprp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:9217
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:56
MOV_TFHD_STSD_ID
#define MOV_TFHD_STSD_ID
Definition: isom.h:398
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:1172
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:3219
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:501
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:75
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:51
AVStreamGroup::iamf_audio_element
struct AVIAMFAudioElement * iamf_audio_element
Definition: avformat.h:1131
MOVStreamContext::coll
AVContentLightMetadata * coll
Definition: isom.h:269
aes_ctr.h
ff_format_io_close
int ff_format_io_close(AVFormatContext *s, AVIOContext **pb)
Definition: avformat.c:868
mov_parse_heif_items
static int mov_parse_heif_items(AVFormatContext *s)
Definition: mov.c:10434
HEIFItem::is_idat_relative
int is_idat_relative
Definition: isom.h:301
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:4014
MOVDref::path
char * path
Definition: isom.h:87
mov_current_sample_inc
static void mov_current_sample_inc(MOVStreamContext *sc)
Definition: mov.c:4152
AVStream::sample_aspect_ratio
AVRational sample_aspect_ratio
sample aspect ratio (0 if unknown)
Definition: avformat.h:822
FFInputFormat::p
AVInputFormat p
The public AVInputFormat.
Definition: demux.h:46
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:551
mov_read_vexu_proj
static int mov_read_vexu_proj(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6833
fix_timescale
static void fix_timescale(MOVContext *c, MOVStreamContext *sc)
Definition: mov.c:5060
avio_r8
int avio_r8(AVIOContext *s)
Definition: aviobuf.c:603
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:885
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:356
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:9457
AV_TIMECODE_FLAG_24HOURSMAX
@ AV_TIMECODE_FLAG_24HOURSMAX
timecode wraps after 24 hours
Definition: timecode.h:37
MOV_MP4_FPCM_TAG
#define MOV_MP4_FPCM_TAG
Definition: isom.h:475
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:1023
AVStreamGroupTileGrid::nb_tiles
unsigned int nb_tiles
Amount of tiles in the grid.
Definition: avformat.h:959
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:702
mov_read_packet
static int mov_read_packet(AVFormatContext *s, AVPacket *pkt)
Definition: mov.c:11070
mov_read_infe
static int mov_read_infe(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:8901
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
AVStreamGroupLCEVC::lcevc_index
unsigned int lcevc_index
Index of the LCEVC data stream in AVStreamGroup.
Definition: avformat.h:1076
AVStreamGroup::lcevc
struct AVStreamGroupLCEVC * lcevc
Definition: avformat.h:1134
attributes.h
AV_CODEC_ID_LCEVC
@ AV_CODEC_ID_LCEVC
Definition: codec_id.h:605
MOVEncryptionIndex::auxiliary_offsets_count
size_t auxiliary_offsets_count
Definition: isom.h:136
HEIFItem::vflip
int vflip
Definition: isom.h:299
AVPacket::flags
int flags
A combination of AV_PKT_FLAG values.
Definition: packet.h:558
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:498
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
mov_find_reference_track
static AVStream * mov_find_reference_track(AVFormatContext *s, AVStream *st, int first_index)
Definition: mov.c:10501
AVSubsampleEncryptionInfo
This file is part of FFmpeg.
Definition: encryption_info.h:25
MOVFragmentIndexItem::stream_info
MOVFragmentStreamInfo * stream_info
Definition: isom.h:157
version
version
Definition: libkvazaar.c:315
AV_STREAM_GROUP_PARAMS_IAMF_AUDIO_ELEMENT
@ AV_STREAM_GROUP_PARAMS_IAMF_AUDIO_ELEMENT
Definition: avformat.h:1089
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:1165
ff_rfps_calculate
void ff_rfps_calculate(AVFormatContext *ic)
Definition: demux.c:2343
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:476
mov_read_clli
static int mov_read_clli(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6516
MOVStreamContext::chunk_offsets
int64_t * chunk_offsets
Definition: isom.h:181
AVStreamGroup::iamf_mix_presentation
struct AVIAMFMixPresentation * iamf_mix_presentation
Definition: avformat.h:1132
MOVFragmentIndex::item
MOVFragmentIndexItem * item
Definition: isom.h:165
AV_LOG_INFO
#define AV_LOG_INFO
Standard information.
Definition: log.h:221
MOVStreamContext::iamf
struct IAMFDemuxContext * iamf
Definition: isom.h:285
FFERROR_REDO
#define FFERROR_REDO
Returned by demuxers to indicate that data was consumed but discarded (ignored streams or junk data).
Definition: demux.h:176
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:232
MOVContext::decryption_key_len
int decryption_key_len
Definition: isom.h:367
av_aes_ctr_free
void av_aes_ctr_free(struct AVAESCTR *a)
Release an AVAESCTR context.
Definition: aes_ctr.c:80
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:8024
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:9328
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:1059
mov_metadata_creation_time
static void mov_metadata_creation_time(MOVContext *c, AVIOContext *pb, AVDictionary **metadata, int version)
Definition: mov.c:1841
mov_metadata_hmmt
static int mov_metadata_hmmt(MOVContext *c, AVIOContext *pb, unsigned len)
Definition: mov.c:323
AV_CODEC_ID_MJPEG
@ AV_CODEC_ID_MJPEG
Definition: codec_id.h:59
MOVFragmentStreamInfo::next_trun_dts
int64_t next_trun_dts
Definition: isom.h:144
MOVStreamContext::stsc_index
unsigned int stsc_index
Definition: isom.h:195
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:7953
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:3299
mov_finalize_packet
static int mov_finalize_packet(AVFormatContext *s, AVStream *st, AVIndexEntry *sample, int64_t current_index, AVPacket *pkt)
Definition: mov.c:11006
MOVIndexRange
Definition: isom.h:168
mov_read_seek
static int mov_read_seek(AVFormatContext *s, int stream_index, int64_t sample_time, int flags)
Definition: mov.c:11387
bprint.h
MOVContext::advanced_editlist
int advanced_editlist
Definition: isom.h:339
MOVStreamContext::time_scale
int time_scale
Definition: isom.h:210
mlp_parse.h
mac_to_unicode
static const uint32_t mac_to_unicode[128]
Definition: mov.c:149
AVStreamGroupTileGrid::width
int width
Width of the final image for presentation.
Definition: avformat.h:1036
MOVStreamContext::bytes_per_frame
unsigned int bytes_per_frame
Definition: isom.h:217
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:170
AV_CODEC_ID_NONE
@ AV_CODEC_ID_NONE
Definition: codec_id.h:50
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:256
AVPacket::pts
int64_t pts
Presentation timestamp in AVStream->time_base units; the time at which the decompressed packet will b...
Definition: packet.h:545
avio_internal.h
MOVCtts::offset
int offset
Definition: isom.h:70
mov_read_trex
static int mov_read_trex(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5675
search_frag_timestamp
static int search_frag_timestamp(AVFormatContext *s, MOVFragmentIndex *frag_index, AVStream *st, int64_t timestamp)
Definition: mov.c:1714
HEIFItem::width
int width
Definition: isom.h:295
FLAGS
#define FLAGS
Definition: mov.c:11444
MOVStreamContext::stereo3d
AVStereo3D * stereo3d
Definition: isom.h:263
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:4204
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:7801
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:3154
internal.h
AV_SPHERICAL_FISHEYE
@ AV_SPHERICAL_FISHEYE
Fisheye projection (Apple).
Definition: spherical.h:84
AVStreamGroup::params
union AVStreamGroup::@405 params
Group type-specific parameters.
AVCodecParameters::height
int height
Definition: codec_par.h:135
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:197
AVCodecParameters::block_align
int block_align
Audio only.
Definition: codec_par.h:191
AV_CODEC_ID_TTML
@ AV_CODEC_ID_TTML
Definition: codec_id.h:586
rb_size
static int rb_size(AVIOContext *pb, int64_t *value, int size)
Definition: mov.c:8777
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:139
display.h
ff_mov_read_stsd_entries
int ff_mov_read_stsd_entries(MOVContext *c, AVIOContext *pb, int entries)
Definition: mov.c:3053
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:108
AVIAMFMixPresentation
Information on how to render and mix one or more AVIAMFAudioElement to generate the final audio outpu...
Definition: iamf.h:613
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:206
MOVContext::frag_index
MOVFragmentIndex frag_index
Definition: isom.h:352
mov_read_vpcc
static int mov_read_vpcc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6344
AV_CODEC_ID_PCM_F64BE
@ AV_CODEC_ID_PCM_F64BE
Definition: codec_id.h:359
AV_CODEC_ID_HEVC
@ AV_CODEC_ID_HEVC
Definition: codec_id.h:228
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:354
MOVStreamContext::dref_id
int dref_id
Definition: isom.h:224
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:106
fix_frag_index_entries
static void fix_frag_index_entries(MOVFragmentIndex *frag_index, int index, int id, int entries)
Definition: mov.c:1800
mov_finalize_stsd_codec
static int mov_finalize_stsd_codec(MOVContext *c, AVIOContext *pb, AVStream *st, MOVStreamContext *sc)
Definition: mov.c:2904
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:346
mov_read_mdcv
static int mov_read_mdcv(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6435
av_mallocz
void * av_mallocz(size_t size)
Allocate a memory block with alignment suitable for all memory accesses (including vectors if availab...
Definition: mem.c:256
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:1369
AV_CODEC_ID_VC1
@ AV_CODEC_ID_VC1
Definition: codec_id.h:122
demux.h
AV_DISPOSITION_DEPENDENT
#define AV_DISPOSITION_DEPENDENT
The stream is intended to be mixed with another stream before presentation.
Definition: avformat.h:705
MOVStreamContext::pb
AVIOContext * pb
Definition: isom.h:174
mov_read_keys
static int mov_read_keys(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5290
AVCodecParameters::color_range
enum AVColorRange color_range
Video only.
Definition: codec_par.h:166
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:140
MOVFragment::size
unsigned size
Definition: isom.h:109
MOV_TFHD_DEFAULT_SIZE
#define MOV_TFHD_DEFAULT_SIZE
Definition: isom.h:400
MOVTimeToSample::count
unsigned int count
Definition: isom.h:58
ff_get_wav_header
int ff_get_wav_header(AVFormatContext *s, AVIOContext *pb, AVCodecParameters *par, int size, int big_endian)
Definition: riffdec.c:95
AVCOL_SPC_UNSPECIFIED
@ AVCOL_SPC_UNSPECIFIED
Definition: pixfmt.h:693
fix_stream_ids
static void fix_stream_ids(AVFormatContext *s)
Definition: mov.c:10566
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:4650
AVCodecParameters::coded_side_data
AVPacketSideData * coded_side_data
Additional data associated with the entire stream.
Definition: codec_par.h:81
mov_read_svq3
static int mov_read_svq3(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2378
AVSHA
hash context
Definition: sha.c:35
AVCOL_RANGE_MPEG
@ AVCOL_RANGE_MPEG
Narrow or limited range content.
Definition: pixfmt.h:750
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:143
AV_IAMF_AUDIO_ELEMENT_TYPE_SCENE
@ AV_IAMF_AUDIO_ELEMENT_TYPE_SCENE
Definition: iamf.h:346
AVCodecParameters::field_order
enum AVFieldOrder field_order
Video only.
Definition: codec_par.h:161
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:94
mov_read_iinf
static int mov_read_iinf(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:8974
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:860
AVStreamGroupTileGrid::horizontal
int horizontal
Offset in pixels from the left edge of the canvas where the tile should be placed.
Definition: avformat.h:995
get_stream_info_time
static int64_t get_stream_info_time(MOVFragmentStreamInfo *frag_stream_info)
Definition: mov.c:1664
MP4TrackKindValueMapping
Definition: isom.h:478
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:4055
AV_WB8
#define AV_WB8(p, d)
Definition: intreadwrite.h:392
MOVStreamContext::chunk_count
unsigned int chunk_count
Definition: isom.h:180
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:235
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:271
mov_read_tmcd
static int mov_read_tmcd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6333
mov_chan.h
AVStream::disposition
int disposition
Stream disposition - a combination of AV_DISPOSITION_* flags.
Definition: avformat.h:813
MOVStreamContext::ambient_size
size_t ambient_size
Definition: isom.h:272
tag
uint32_t tag
Definition: movenc.c:1957
AVStream::id
int id
Format-specific stream ID.
Definition: avformat.h:756
ret
ret
Definition: filter_design.txt:187
AVStream
Stream structure.
Definition: avformat.h:744
AV_CODEC_ID_APV
@ AV_CODEC_ID_APV
Definition: codec_id.h:332
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:293
MOVEncryptionIndex::nb_encrypted_samples
unsigned int nb_encrypted_samples
Definition: isom.h:129
mov_read_senc
static int mov_read_senc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:7504
avio_seek
int64_t avio_seek(AVIOContext *s, int64_t offset, int whence)
fseek() equivalent for AVIOContext.
Definition: aviobuf.c:231
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:187
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:1145
avio_rb16
unsigned int avio_rb16(AVIOContext *s)
Definition: aviobuf.c:746
AVStereo3D::type
enum AVStereo3DType type
How views are packed within the video.
Definition: stereo3d.h:207
MOVSbgp::index
unsigned int index
Definition: isom.h:123
HEIFItem::icc_profile_size
size_t icc_profile_size
Definition: isom.h:303
MOVContext::chapter_tracks
int * chapter_tracks
Definition: isom.h:335
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:590
pos
unsigned int pos
Definition: spdifenc.c:414
avformat.h
MOVFragment::implicit_offset
uint64_t implicit_offset
Definition: isom.h:106
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:709
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:8468
flag
#define flag(name)
Definition: cbs_av1.c:495
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:220
MOVContext::time_scale
int time_scale
Definition: isom.h:317
id
enum AVCodecID id
Definition: dts2pts.c:367
mov_read_tfdt
static int mov_read_tfdt(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5701
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:5417
search_frag_moof_offset
static int search_frag_moof_offset(MOVFragmentIndex *frag_index, int64_t offset)
Definition: mov.c:1640
MOVFragment
Definition: isom.h:101
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:10877
MOVContext::use_mfra_for
int use_mfra_for
Definition: isom.h:349
AVEncryptionInfo
This describes encryption info for a packet.
Definition: encryption_info.h:43
MOVStreamContext::encryption_index
MOVEncryptionIndex * encryption_index
Definition: isom.h:282
MIN_DATA_ENTRY_BOX_SIZE
#define MIN_DATA_ENTRY_BOX_SIZE
Definition: mov.c:635
AVStreamGroup
Definition: avformat.h:1098
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:750
avpriv_dv_init_demux
DVDemuxContext * avpriv_dv_init_demux(AVFormatContext *s)
Definition: dv.c:726
mov_seek_fragment
static int mov_seek_fragment(AVFormatContext *s, AVStream *st, int64_t timestamp)
Definition: mov.c:11236
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:2667
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:230
mov_read_dec3
static int mov_read_dec3(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1076
get_frag_time
static int64_t get_frag_time(AVFormatContext *s, AVStream *dst_st, MOVFragmentIndex *frag_index, int index)
Definition: mov.c:1674
MOVStreamContext::sample_size
unsigned int sample_size
may contain value calculated from stsd or value from stsz atom
Definition: isom.h:203
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:1152
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:253
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:3811
MOVFragment::moof_offset
uint64_t moof_offset
Definition: isom.h:105
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:232
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:2440
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:7162
MOVTrackExt::size
unsigned size
Definition: isom.h:117
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:121
AV_OPT_TYPE_INT
@ AV_OPT_TYPE_INT
Underlying C type is int.
Definition: opt.h:259
MOVContext::dv_fctx
AVFormatContext * dv_fctx
Definition: isom.h:328
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:442
AV_CODEC_ID_DVAUDIO
@ AV_CODEC_ID_DVAUDIO
Definition: codec_id.h:457
avformat_free_context
void avformat_free_context(AVFormatContext *s)
Free an AVFormatContext and all its streams.
Definition: avformat.c:141
MOVContext::aax_mode
unsigned int aax_mode
'aax' file has been detected
Definition: isom.h:354
mov_read_sv3d
static int mov_read_sv3d(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6696
avio_read
int avio_read(AVIOContext *s, unsigned char *buf, int size)
Read size bytes from AVIOContext into buf.
Definition: aviobuf.c:612
mov_aaxc_crypto
static int mov_aaxc_crypto(MOVContext *c)
Definition: mov.c:1480
mov_get_skip_samples
static int64_t mov_get_skip_samples(AVStream *st, int sample)
Definition: mov.c:11370
MOVFragmentIndex
Definition: isom.h:160
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
AVStream::r_frame_rate
AVRational r_frame_rate
Real base framerate of the stream.
Definition: avformat.h:878
MOVStreamContext::tts_count
unsigned int tts_count
Definition: isom.h:182
MOVStreamContext::track_end
int64_t track_end
used for dts generation in fragmented movie files
Definition: isom.h:238
MOVStreamContext::sgpd_sync_count
uint32_t sgpd_sync_count
Definition: isom.h:245
MOVContext::fragment
MOVFragment fragment
current fragment in moof atom
Definition: isom.h:330
AVIndexEntry::pos
int64_t pos
Definition: avformat.h:599
AVIOContext::eof_reached
int eof_reached
true if was unable to read due to error or eof
Definition: avio.h:238
MOVContext::thmb_item_id
int * thmb_item_id
Definition: isom.h:379
mov_metadata_int8_bypass_padding
static int mov_metadata_int8_bypass_padding(MOVContext *c, AVIOContext *pb, unsigned len, const char *key)
Definition: mov.c:110
AVStreamGroupLCEVC::width
int width
Width of the final stream for presentation.
Definition: avformat.h:1080
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:230
MOVParseTableEntry::type
uint32_t type
Definition: mov.c:82
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:280
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:554
MOVFragmentIndexItem::nb_stream_info
int nb_stream_info
Definition: isom.h:156
avio_skip
int64_t avio_skip(AVIOContext *s, int64_t offset)
Skip given number of bytes forward.
Definition: aviobuf.c:318
export_orphan_timecode
static void export_orphan_timecode(AVFormatContext *s)
Definition: mov.c:10004
mov_read_sbas
static int mov_read_sbas(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2511
MOVStreamContext::has_sidx
int has_sidx
Definition: isom.h:276
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:97
mov_metadata_gnre
static int mov_metadata_gnre(MOVContext *c, AVIOContext *pb, unsigned len, const char *key)
Definition: mov.c:133
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:4580
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:2265
AVIAMFSubmix::nb_elements
unsigned int nb_elements
Number of elements in the submix.
Definition: iamf.h:572
AVStreamGroupTileGrid::offsets
struct AVStreamGroupTileGrid::@404 * offsets
An nb_tiles sized array of offsets in pixels from the topleft edge of the canvas, indicating where ea...
MOVFragmentStreamInfo::id
int id
Definition: isom.h:140
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:356
mov_read_rtmd_track
static int mov_read_rtmd_track(AVFormatContext *s, AVStream *st)
Definition: mov.c:9786
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:176
AV_CODEC_ID_PCM_S32LE
@ AV_CODEC_ID_PCM_S32LE
Definition: codec_id.h:345
AVCodecParameters::bits_per_coded_sample
int bits_per_coded_sample
The number of bits per sample in the codedwords.
Definition: codec_par.h:110
mov_parse_tiles
static int mov_parse_tiles(AVFormatContext *s)
Definition: mov.c:10339
mem.h
AVStreamGroup::type
enum AVStreamGroupParamsType type
Group type.
Definition: avformat.h:1125
MOVElst::time
int64_t time
Definition: isom.h:81
HEIFGrid
Definition: isom.h:306
mov_read_iref_dimg
static int mov_read_iref_dimg(MOVContext *c, AVIOContext *pb, int version)
Definition: mov.c:9028
mov_read_pcmc
static int mov_read_pcmc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1994
build_open_gop_key_points
static int build_open_gop_key_points(AVStream *st)
Definition: mov.c:4517
mov_parse_stsd_audio
static void mov_parse_stsd_audio(MOVContext *c, AVIOContext *pb, AVStream *st, MOVStreamContext *sc)
Definition: mov.c:2725
IAMFContext::mix_presentations
IAMFMixPresentation ** mix_presentations
Definition: iamf.h:133
AV_CODEC_ID_PCM_U8
@ AV_CODEC_ID_PCM_U8
Definition: codec_id.h:342
MOVContext::trak_index
int trak_index
Index of the current 'trak'.
Definition: isom.h:324
mov_read_timecode_track
static int mov_read_timecode_track(AVFormatContext *s, AVStream *st)
Definition: mov.c:9812
HEIFGrid::item
HEIFItem * item
Definition: isom.h:307
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:168
MOVEncryptionIndex::auxiliary_info_sizes
uint8_t * auxiliary_info_sizes
Definition: isom.h:132
MOVFragment::stsd_id
unsigned stsd_id
Definition: isom.h:107
AVCodecParameters::video_delay
int video_delay
Video only.
Definition: codec_par.h:175
HEIFGrid::tile_id_list
int16_t * tile_id_list
Definition: isom.h:309
avpriv_request_sample
#define avpriv_request_sample(...)
Definition: tableprint_vlc.h:37
MOVStreamContext::tts_data
MOVTimeToSample * tts_data
Definition: isom.h:184
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:433
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:360
AVStreamGroupTileGrid::height
int height
Height of the final image for presentation.
Definition: avformat.h:1046
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:10022
av_free
#define av_free(p)
Definition: tableprint_vlc.h:34
AVDictionaryEntry
Definition: dict.h:90
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:55
AVStereo3DView
AVStereo3DView
List of possible view types.
Definition: stereo3d.h:149
AVPacket
This structure stores compressed data.
Definition: packet.h:529
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:10516
mov_read_hfov
static int mov_read_hfov(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:7133
AV_OPT_TYPE_BOOL
@ AV_OPT_TYPE_BOOL
Underlying C type is int.
Definition: opt.h:327
AVChannelLayout::u
union AVChannelLayout::@472 u
Details about which channels are present in this layout.
MOVStreamContext::stps_data
unsigned * stps_data
partial sync sample for mpeg-2 open gop
Definition: isom.h:198
AV_CODEC_ID_ADPCM_IMA_WAV
@ AV_CODEC_ID_ADPCM_IMA_WAV
Definition: codec_id.h:377
MOVContext::nb_heif_item
int nb_heif_item
Definition: isom.h:376
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:572
FFInputFormat
Definition: demux.h:42
mov_metadata_loci
static int mov_metadata_loci(MOVContext *c, AVIOContext *pb, unsigned len)
Definition: mov.c:273
mov_read_eyes
static int mov_read_eyes(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6898
AV_CODEC_ID_ILBC
@ AV_CODEC_ID_ILBC
Definition: codec_id.h:510
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:408
MOVStreamContext::tmcd_flags
uint32_t tmcd_flags
tmcd track flags
Definition: isom.h:236
int32_t
int32_t
Definition: audioconvert.c:56
HEIFItem::rotation
int rotation
Definition: isom.h:297
MOVAtom::type
uint32_t type
Definition: isom.h:95
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:589
parse_timecode_in_framenum_format
static int parse_timecode_in_framenum_format(AVFormatContext *s, AVStream *st, int64_t value, int flags)
Definition: mov.c:9772
MOVStreamContext::tmcd_nb_frames
uint8_t tmcd_nb_frames
tmcd number of frames per tick / second
Definition: isom.h:237
AVIAMFSubmixElement
Submix element as defined in section 3.7 of IAMF.
Definition: iamf.h:446
replaygain.h
MOVFragmentIndexItem::headers_read
int headers_read
Definition: isom.h:154
AV_CODEC_ID_VP8
@ AV_CODEC_ID_VP8
Definition: codec_id.h:192
AVERROR_BUG
#define AVERROR_BUG
Internal bug, also see AVERROR_BUG2.
Definition: error.h:52
MOVStreamContext::start_pad
int start_pad
amount of samples to skip due to enc-dec delay
Definition: isom.h:239
MP4TrackKindValueMapping::value
const char * value
Definition: isom.h:480
AVStereo3DType
AVStereo3DType
List of possible 3D Types.
Definition: stereo3d.h:48
MOVDref::filename
char filename[64]
Definition: isom.h:90
ff_mov_read_chnl
int ff_mov_read_chnl(AVFormatContext *s, AVIOContext *pb, AVStream *st)
Read 'chnl' tag from the input stream.
Definition: mov_chan.c:729
MOVStsc::count
int count
Definition: isom.h:75
AV_CODEC_ID_PCM_F32LE
@ AV_CODEC_ID_PCM_F32LE
Definition: codec_id.h:358
ff_mov_demuxer
const FFInputFormat ff_mov_demuxer
Definition: mov.c:11505
AVCodecParameters::bit_rate
int64_t bit_rate
The average bitrate of the encoded data (in bits per second).
Definition: codec_par.h:97
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:262
MOVContext::heif_grid
HEIFGrid * heif_grid
Definition: isom.h:377
MOVStreamContext::min_sample_duration
uint32_t min_sample_duration
Definition: isom.h:250
MOVStreamContext::current_index
int64_t current_index
Definition: isom.h:214
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:451
get_curr_st
static AVStream * get_curr_st(MOVContext *c)
Get the current stream in the parsing process.
Definition: mov.c:212
MOVStreamContext::stts_allocated_size
unsigned int stts_allocated_size
Definition: isom.h:186
MOVFragmentStreamInfo::index_entry
int index_entry
Definition: isom.h:147
cenc_decrypt
static int cenc_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
Definition: mov.c:8308
MOVStreamContext::format
uint32_t format
Definition: isom.h:274
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:662
MOVStreamContext::sync_group_count
unsigned int sync_group_count
Definition: isom.h:242
MOVContext::bitrates_count
int bitrates_count
Definition: isom.h:347
AV_CODEC_ID_VORBIS
@ AV_CODEC_ID_VORBIS
Definition: codec_id.h:456
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:793
MOVStreamContext::id
int id
AVStream id.
Definition: isom.h:177
MOVStreamContext::samples_per_frame
unsigned int samples_per_frame
Definition: isom.h:218
MOVStreamContext::tts_allocated_size
unsigned int tts_allocated_size
Definition: isom.h:183
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:9156
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:9118
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:1238
mov_read_mfra
static int mov_read_mfra(MOVContext *c, AVIOContext *f)
Definition: mov.c:10077
AV_CODEC_ID_FLV1
@ AV_CODEC_ID_FLV1
Definition: codec_id.h:73
mov_metadata_int8_no_padding
static int mov_metadata_int8_no_padding(MOVContext *c, AVIOContext *pb, unsigned len, const char *key)
Definition: mov.c:124
flac.h
AVStreamGroupTileGrid::idx
unsigned int idx
Index of the stream in the group this tile references.
Definition: avformat.h:990
MOVContext::nb_thmb_item
int nb_thmb_item
Definition: isom.h:380
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:1585
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:8572
MOVContext::heif_item
HEIFItem ** heif_item
Definition: isom.h:375
MOVStreamContext::stts_count
unsigned int stts_count
Definition: isom.h:185
MOV_TRUN_SAMPLE_CTS
#define MOV_TRUN_SAMPLE_CTS
Definition: isom.h:410
AV_OPT_TYPE_CONST
@ AV_OPT_TYPE_CONST
Special option type for declaring named constants.
Definition: opt.h:299
MOV_ISMV_TTML_TAG
#define MOV_ISMV_TTML_TAG
Definition: isom.h:473
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
Audio only.
Definition: codec_par.h:203
AV_CODEC_ID_PCM_S24BE
@ AV_CODEC_ID_PCM_S24BE
Definition: codec_id.h:350
mov_read_st3d
static int mov_read_st3d(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6570
mov_read_imir
static int mov_read_imir(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:9198
is_open_key_sample
static int is_open_key_sample(const MOVStreamContext *sc, int sample)
Definition: mov.c:11255
mov_read_dvc1
static int mov_read_dvc1(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2486
MOVStreamContext::elst_count
unsigned int elst_count
Definition: isom.h:200
av_color_transfer_name
const char * av_color_transfer_name(enum AVColorTransferCharacteristic transfer)
Definition: pixdesc.c:3796
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:2202
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:9673
AV_CODEC_ID_DNXHD
@ AV_CODEC_ID_DNXHD
Definition: codec_id.h:151
channel
channel
Definition: ebur128.h:39
MOVStreamContext::default_encrypted_sample
AVEncryptionInfo * default_encrypted_sample
Definition: isom.h:281
MOVContext::cur_item_id
int cur_item_id
Definition: isom.h:374
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:1638
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:343
MOVContext::found_iinf
int found_iinf
'iinf' atom has been found
Definition: isom.h:321
MOVContext::meta_keys_count
unsigned meta_keys_count
Definition: isom.h:326
avcodec_parameters_copy
int avcodec_parameters_copy(AVCodecParameters *dst, const AVCodecParameters *src)
Copy the contents of src to dst.
Definition: codec_par.c:106
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:1010
MOVStreamContext::palette
uint32_t palette[256]
Definition: isom.h:233
cenc_scheme_decrypt
static int cenc_scheme_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
Definition: mov.c:8064
MOVFragment::track_id
unsigned track_id
Definition: isom.h:103
mov_read_hdlr
static int mov_read_hdlr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:780
mov_parse_stsd_data
static int mov_parse_stsd_data(MOVContext *c, AVIOContext *pb, AVStream *st, MOVStreamContext *sc, int64_t size)
Definition: mov.c:2858
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:342
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_realloc
void * av_realloc(void *ptr, size_t size)
Allocate, reallocate, or free a block of memory.
Definition: mem.c:155
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:347
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:524
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:8796
FLAC_METADATA_TYPE_STREAMINFO
@ FLAC_METADATA_TYPE_STREAMINFO
Definition: flac.h:46
MOVContext::ignore_chapters
int ignore_chapters
Definition: isom.h:341
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:851
MP4TrackKindMapping
Definition: isom.h:483
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:230
AV_DISPOSITION_NON_DIEGETIC
#define AV_DISPOSITION_NON_DIEGETIC
The stream is intended to be mixed with a spatial audio track.
Definition: avformat.h:682
avio_feof
int avio_feof(AVIOContext *s)
Similar to feof() but also returns nonzero on read errors.
Definition: aviobuf.c:346
mc
#define mc
Definition: vf_colormatrix.c:100
MOVStreamContext::ffindex
int ffindex
AVStream index.
Definition: isom.h:178
HEIFItem::extent_offset
int64_t extent_offset
Definition: isom.h:294
mov_read_stsz
static int mov_read_stsz(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:3416