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;
2992  case AV_CODEC_ID_APV:
2993  case AV_CODEC_ID_EVC:
2994  case AV_CODEC_ID_AV1:
2995  /* field_order detection of H264 requires parsing */
2996  case AV_CODEC_ID_H264:
2998  break;
2999  default:
3000  break;
3001  }
3002  return 0;
3003 }
3004 
3006  int codec_tag, int format,
3007  int64_t size)
3008 {
3009  if (codec_tag &&
3010  (codec_tag != format &&
3011  // AVID 1:1 samples with differing data format and codec tag exist
3012  (codec_tag != AV_RL32("AV1x") || format != AV_RL32("AVup")) &&
3013  // prores is allowed to have differing data format and codec tag
3014  codec_tag != AV_RL32("apcn") && codec_tag != AV_RL32("apch") &&
3015  // so is dv (sigh)
3016  codec_tag != AV_RL32("dvpp") && codec_tag != AV_RL32("dvcp") &&
3017  (c->fc->video_codec_id ? ff_codec_get_id(ff_codec_movvideo_tags, format) != c->fc->video_codec_id
3018  : codec_tag != MKTAG('j','p','e','g')))) {
3019  /* Multiple fourcc, we skip JPEG. This is not correct, we should
3020  * export it as a separate AVStream but this needs a few changes
3021  * in the MOV demuxer, patch welcome. */
3022 
3023  av_log(c->fc, AV_LOG_WARNING, "multiple fourcc not supported\n");
3024  avio_skip(pb, size);
3025  return 1;
3026  }
3027 
3028  return 0;
3029 }
3030 
3032 {
3033  AVStream *st;
3034  MOVStreamContext *sc;
3035  int pseudo_stream_id;
3036 
3037  av_assert0 (c->fc->nb_streams >= 1);
3038  st = c->fc->streams[c->fc->nb_streams-1];
3039  sc = st->priv_data;
3040 
3041  for (pseudo_stream_id = 0;
3042  pseudo_stream_id < entries && !pb->eof_reached;
3043  pseudo_stream_id++) {
3044  //Parsing Sample description table
3045  enum AVCodecID id;
3046  int ret, dref_id = 1;
3047  MOVAtom a = { AV_RL32("stsd") };
3048  int64_t start_pos = avio_tell(pb);
3049  int64_t size = avio_rb32(pb); /* size */
3050  uint32_t format = avio_rl32(pb); /* data format */
3051 
3052  if (size >= 16) {
3053  avio_rb32(pb); /* reserved */
3054  avio_rb16(pb); /* reserved */
3055  dref_id = avio_rb16(pb);
3056  } else if (size <= 7) {
3057  av_log(c->fc, AV_LOG_ERROR,
3058  "invalid size %"PRId64" in stsd\n", size);
3059  return AVERROR_INVALIDDATA;
3060  }
3061 
3063  size - (avio_tell(pb) - start_pos))) {
3064  sc->stsd_count++;
3065  continue;
3066  }
3067 
3068  sc->pseudo_stream_id = st->codecpar->codec_tag ? -1 : pseudo_stream_id;
3069  sc->dref_id= dref_id;
3070  sc->format = format;
3071 
3072  id = mov_codec_id(st, format);
3073 
3074  av_log(c->fc, AV_LOG_TRACE,
3075  "size=%"PRId64" 4CC=%s codec_type=%d\n", size,
3077 
3078  st->codecpar->codec_id = id;
3080  mov_parse_stsd_video(c, pb, st, sc);
3081  } else if (st->codecpar->codec_type==AVMEDIA_TYPE_AUDIO) {
3082  mov_parse_stsd_audio(c, pb, st, sc);
3083  if (st->codecpar->sample_rate < 0) {
3084  av_log(c->fc, AV_LOG_ERROR, "Invalid sample rate %d\n", st->codecpar->sample_rate);
3085  return AVERROR_INVALIDDATA;
3086  }
3087  if (st->codecpar->ch_layout.nb_channels < 0) {
3088  av_log(c->fc, AV_LOG_ERROR, "Invalid channels %d\n", st->codecpar->ch_layout.nb_channels);
3089  return AVERROR_INVALIDDATA;
3090  }
3091  } else if (st->codecpar->codec_type==AVMEDIA_TYPE_SUBTITLE){
3092  mov_parse_stsd_subtitle(c, pb, st, sc,
3093  size - (avio_tell(pb) - start_pos));
3094  } else {
3095  ret = mov_parse_stsd_data(c, pb, st, sc,
3096  size - (avio_tell(pb) - start_pos));
3097  if (ret < 0)
3098  return ret;
3099  }
3100  /* this will read extra atoms at the end (wave, alac, damr, avcC, hvcC, SMI ...) */
3101  a.size = size - (avio_tell(pb) - start_pos);
3102  if (a.size > 8) {
3103  if ((ret = mov_read_default(c, pb, a)) < 0)
3104  return ret;
3105  } else if (a.size > 0)
3106  avio_skip(pb, a.size);
3107 
3108  if (sc->extradata && st->codecpar->extradata) {
3109  int extra_size = st->codecpar->extradata_size;
3110 
3111  /* Move the current stream extradata to the stream context one. */
3112  sc->extradata_size[pseudo_stream_id] = extra_size;
3113  sc->extradata[pseudo_stream_id] = st->codecpar->extradata;
3114  st->codecpar->extradata = NULL;
3115  st->codecpar->extradata_size = 0;
3116  }
3117  sc->stsd_count++;
3118  }
3119 
3120  if (pb->eof_reached) {
3121  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSD atom\n");
3122  return AVERROR_EOF;
3123  }
3124 
3125  return 0;
3126 }
3127 
3129 {
3130  AVStream *st;
3131  MOVStreamContext *sc;
3132  int ret, entries;
3133 
3134  if (c->fc->nb_streams < 1)
3135  return 0;
3136  st = c->fc->streams[c->fc->nb_streams - 1];
3137  sc = st->priv_data;
3138 
3139  sc->stsd_version = avio_r8(pb);
3140  avio_rb24(pb); /* flags */
3141  entries = avio_rb32(pb);
3142 
3143  /* Each entry contains a size (4 bytes) and format (4 bytes). */
3144  if (entries <= 0 || entries > atom.size / 8 || entries > 1024) {
3145  av_log(c->fc, AV_LOG_ERROR, "invalid STSD entries %d\n", entries);
3146  return AVERROR_INVALIDDATA;
3147  }
3148 
3149  if (sc->extradata) {
3150  av_log(c->fc, AV_LOG_ERROR,
3151  "Duplicate stsd found in this track.\n");
3152  return AVERROR_INVALIDDATA;
3153  }
3154 
3155  /* Prepare space for hosting multiple extradata. */
3156  sc->extradata = av_calloc(entries, sizeof(*sc->extradata));
3157  if (!sc->extradata)
3158  return AVERROR(ENOMEM);
3159 
3160  sc->extradata_size = av_calloc(entries, sizeof(*sc->extradata_size));
3161  if (!sc->extradata_size) {
3162  ret = AVERROR(ENOMEM);
3163  goto fail;
3164  }
3165 
3166  ret = ff_mov_read_stsd_entries(c, pb, entries);
3167  if (ret < 0)
3168  goto fail;
3169 
3170  /* Restore back the primary extradata. */
3171  av_freep(&st->codecpar->extradata);
3172  st->codecpar->extradata_size = sc->extradata_size[0];
3173  if (sc->extradata_size[0]) {
3175  if (!st->codecpar->extradata)
3176  return AVERROR(ENOMEM);
3177  memcpy(st->codecpar->extradata, sc->extradata[0], sc->extradata_size[0]);
3178  }
3179 
3180  return mov_finalize_stsd_codec(c, pb, st, sc);
3181 fail:
3182  if (sc->extradata) {
3183  int j;
3184  for (j = 0; j < sc->stsd_count; j++)
3185  av_freep(&sc->extradata[j]);
3186  }
3187 
3188  av_freep(&sc->extradata);
3189  av_freep(&sc->extradata_size);
3190  return ret;
3191 }
3192 
3194 {
3195  AVStream *st;
3196  MOVStreamContext *sc;
3197  unsigned int i, entries;
3198 
3199  if (c->trak_index < 0) {
3200  av_log(c->fc, AV_LOG_WARNING, "STSC outside TRAK\n");
3201  return 0;
3202  }
3203 
3204  if (c->fc->nb_streams < 1)
3205  return 0;
3206  st = c->fc->streams[c->fc->nb_streams-1];
3207  sc = st->priv_data;
3208 
3209  avio_r8(pb); /* version */
3210  avio_rb24(pb); /* flags */
3211 
3212  entries = avio_rb32(pb);
3213  if ((uint64_t)entries * 12 + 4 > atom.size)
3214  return AVERROR_INVALIDDATA;
3215 
3216  av_log(c->fc, AV_LOG_TRACE, "track[%u].stsc.entries = %u\n", c->fc->nb_streams - 1, entries);
3217 
3218  if (!entries)
3219  return 0;
3220  if (sc->stsc_data) {
3221  av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicated STSC atom\n");
3222  return 0;
3223  }
3224  av_free(sc->stsc_data);
3225  sc->stsc_count = 0;
3226  sc->stsc_data = av_malloc_array(entries, sizeof(*sc->stsc_data));
3227  if (!sc->stsc_data)
3228  return AVERROR(ENOMEM);
3229 
3230  for (i = 0; i < entries && !pb->eof_reached; i++) {
3231  sc->stsc_data[i].first = avio_rb32(pb);
3232  sc->stsc_data[i].count = avio_rb32(pb);
3233  sc->stsc_data[i].id = avio_rb32(pb);
3234  }
3235 
3236  sc->stsc_count = i;
3237  for (i = sc->stsc_count - 1; i < UINT_MAX; i--) {
3238  int64_t first_min = i + 1;
3239  if ((i+1 < sc->stsc_count && sc->stsc_data[i].first >= sc->stsc_data[i+1].first) ||
3240  (i > 0 && sc->stsc_data[i].first <= sc->stsc_data[i-1].first) ||
3241  sc->stsc_data[i].first < first_min ||
3242  sc->stsc_data[i].count < 1 ||
3243  sc->stsc_data[i].id < 1) {
3244  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);
3245  if (i+1 >= sc->stsc_count) {
3246  if (sc->stsc_data[i].count == 0 && i > 0) {
3247  sc->stsc_count --;
3248  continue;
3249  }
3250  sc->stsc_data[i].first = FFMAX(sc->stsc_data[i].first, first_min);
3251  if (i > 0 && sc->stsc_data[i].first <= sc->stsc_data[i-1].first)
3252  sc->stsc_data[i].first = FFMIN(sc->stsc_data[i-1].first + 1LL, INT_MAX);
3253  sc->stsc_data[i].count = FFMAX(sc->stsc_data[i].count, 1);
3254  sc->stsc_data[i].id = FFMAX(sc->stsc_data[i].id, 1);
3255  continue;
3256  }
3257  av_assert0(sc->stsc_data[i+1].first >= 2);
3258  // We replace this entry by the next valid
3259  sc->stsc_data[i].first = sc->stsc_data[i+1].first - 1;
3260  sc->stsc_data[i].count = sc->stsc_data[i+1].count;
3261  sc->stsc_data[i].id = sc->stsc_data[i+1].id;
3262  }
3263  }
3264 
3265  if (pb->eof_reached) {
3266  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSC atom\n");
3267  return AVERROR_EOF;
3268  }
3269 
3270  return 0;
3271 }
3272 
3273 static inline int mov_stsc_index_valid(unsigned int index, unsigned int count)
3274 {
3275  return index < count - 1;
3276 }
3277 
3278 /* Compute the samples value for the stsc entry at the given index. */
3279 static inline int64_t mov_get_stsc_samples(MOVStreamContext *sc, unsigned int index)
3280 {
3281  int chunk_count;
3282 
3284  chunk_count = sc->stsc_data[index + 1].first - sc->stsc_data[index].first;
3285  else {
3286  // Validation for stsc / stco happens earlier in mov_read_stsc + mov_read_trak.
3288  chunk_count = sc->chunk_count - (sc->stsc_data[index].first - 1);
3289  }
3290 
3291  return sc->stsc_data[index].count * (int64_t)chunk_count;
3292 }
3293 
3295 {
3296  AVStream *st;
3297  MOVStreamContext *sc;
3298  unsigned i, entries;
3299 
3300  if (c->trak_index < 0) {
3301  av_log(c->fc, AV_LOG_WARNING, "STPS outside TRAK\n");
3302  return 0;
3303  }
3304 
3305  if (c->fc->nb_streams < 1)
3306  return 0;
3307  st = c->fc->streams[c->fc->nb_streams-1];
3308  sc = st->priv_data;
3309 
3310  avio_rb32(pb); // version + flags
3311 
3312  entries = avio_rb32(pb);
3313  if (sc->stps_data)
3314  av_log(c->fc, AV_LOG_WARNING, "Duplicated STPS atom\n");
3315  av_free(sc->stps_data);
3316  sc->stps_count = 0;
3317  sc->stps_data = av_malloc_array(entries, sizeof(*sc->stps_data));
3318  if (!sc->stps_data)
3319  return AVERROR(ENOMEM);
3320 
3321  for (i = 0; i < entries && !pb->eof_reached; i++) {
3322  sc->stps_data[i] = avio_rb32(pb);
3323  }
3324 
3325  sc->stps_count = i;
3326 
3327  if (pb->eof_reached) {
3328  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STPS atom\n");
3329  return AVERROR_EOF;
3330  }
3331 
3332  return 0;
3333 }
3334 
3336 {
3337  AVStream *st;
3338  FFStream *sti;
3339  MOVStreamContext *sc;
3340  unsigned int i, entries;
3341 
3342  if (c->trak_index < 0) {
3343  av_log(c->fc, AV_LOG_WARNING, "STSS outside TRAK\n");
3344  return 0;
3345  }
3346 
3347  if (c->fc->nb_streams < 1)
3348  return 0;
3349  st = c->fc->streams[c->fc->nb_streams-1];
3350  sti = ffstream(st);
3351  sc = st->priv_data;
3352 
3353  avio_r8(pb); /* version */
3354  avio_rb24(pb); /* flags */
3355 
3356  entries = avio_rb32(pb);
3357 
3358  av_log(c->fc, AV_LOG_TRACE, "keyframe_count = %u\n", entries);
3359 
3360  if (!entries) {
3361  sc->keyframe_absent = 1;
3362  if (!sti->need_parsing && st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
3364  return 0;
3365  }
3366  if (sc->keyframes)
3367  av_log(c->fc, AV_LOG_WARNING, "Duplicated STSS atom\n");
3368  if (entries >= UINT_MAX / sizeof(int))
3369  return AVERROR_INVALIDDATA;
3370  av_freep(&sc->keyframes);
3371  sc->keyframe_count = 0;
3372  sc->keyframes = av_malloc_array(entries, sizeof(*sc->keyframes));
3373  if (!sc->keyframes)
3374  return AVERROR(ENOMEM);
3375 
3376  for (i = 0; i < entries && !pb->eof_reached; i++) {
3377  sc->keyframes[i] = avio_rb32(pb);
3378  }
3379 
3380  sc->keyframe_count = i;
3381 
3382  if (pb->eof_reached) {
3383  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSS atom\n");
3384  return AVERROR_EOF;
3385  }
3386 
3387  return 0;
3388 }
3389 
3391 {
3392  AVStream *st;
3393  MOVStreamContext *sc;
3394  unsigned int i, entries, sample_size, field_size, num_bytes;
3395  GetBitContext gb;
3396  unsigned char* buf;
3397  int ret;
3398 
3399  if (c->trak_index < 0) {
3400  av_log(c->fc, AV_LOG_WARNING, "STSZ outside TRAK\n");
3401  return 0;
3402  }
3403 
3404  if (c->fc->nb_streams < 1)
3405  return 0;
3406  st = c->fc->streams[c->fc->nb_streams-1];
3407  sc = st->priv_data;
3408 
3409  avio_r8(pb); /* version */
3410  avio_rb24(pb); /* flags */
3411 
3412  if (atom.type == MKTAG('s','t','s','z')) {
3413  sample_size = avio_rb32(pb);
3414  if (!sc->sample_size) /* do not overwrite value computed in stsd */
3415  sc->sample_size = sample_size;
3416  sc->stsz_sample_size = sample_size;
3417  field_size = 32;
3418  } else {
3419  sample_size = 0;
3420  avio_rb24(pb); /* reserved */
3421  field_size = avio_r8(pb);
3422  }
3423  entries = avio_rb32(pb);
3424 
3425  av_log(c->fc, AV_LOG_TRACE, "sample_size = %u sample_count = %u\n", sc->sample_size, entries);
3426 
3427  sc->sample_count = entries;
3428  if (sample_size)
3429  return 0;
3430 
3431  if (field_size != 4 && field_size != 8 && field_size != 16 && field_size != 32) {
3432  av_log(c->fc, AV_LOG_ERROR, "Invalid sample field size %u\n", field_size);
3433  return AVERROR_INVALIDDATA;
3434  }
3435 
3436  if (!entries)
3437  return 0;
3438  if (entries >= (INT_MAX - 4 - 8 * AV_INPUT_BUFFER_PADDING_SIZE) / field_size)
3439  return AVERROR_INVALIDDATA;
3440  if (sc->sample_sizes)
3441  av_log(c->fc, AV_LOG_WARNING, "Duplicated STSZ atom\n");
3442  av_free(sc->sample_sizes);
3443  sc->sample_count = 0;
3444  sc->sample_sizes = av_malloc_array(entries, sizeof(*sc->sample_sizes));
3445  if (!sc->sample_sizes)
3446  return AVERROR(ENOMEM);
3447 
3448  num_bytes = (entries*field_size+4)>>3;
3449 
3450  buf = av_malloc(num_bytes+AV_INPUT_BUFFER_PADDING_SIZE);
3451  if (!buf) {
3452  av_freep(&sc->sample_sizes);
3453  return AVERROR(ENOMEM);
3454  }
3455 
3456  ret = ffio_read_size(pb, buf, num_bytes);
3457  if (ret < 0) {
3458  av_freep(&sc->sample_sizes);
3459  av_free(buf);
3460  av_log(c->fc, AV_LOG_WARNING, "STSZ atom truncated\n");
3461  return 0;
3462  }
3463 
3464  init_get_bits(&gb, buf, 8*num_bytes);
3465 
3466  for (i = 0; i < entries; i++) {
3467  sc->sample_sizes[i] = get_bits_long(&gb, field_size);
3468  if (sc->sample_sizes[i] > INT64_MAX - sc->data_size) {
3469  av_free(buf);
3470  av_log(c->fc, AV_LOG_ERROR, "Sample size overflow in STSZ\n");
3471  return AVERROR_INVALIDDATA;
3472  }
3473  sc->data_size += sc->sample_sizes[i];
3474  }
3475 
3476  sc->sample_count = i;
3477 
3478  av_free(buf);
3479 
3480  return 0;
3481 }
3482 
3484 {
3485  AVStream *st;
3486  MOVStreamContext *sc;
3487  unsigned int i, entries;
3488  int64_t duration = 0;
3489  int64_t total_sample_count = 0;
3490  int64_t current_dts = 0;
3491  int64_t corrected_dts = 0;
3492 
3493  if (c->trak_index < 0) {
3494  av_log(c->fc, AV_LOG_WARNING, "STTS outside TRAK\n");
3495  return 0;
3496  }
3497 
3498  if (c->fc->nb_streams < 1)
3499  return 0;
3500  st = c->fc->streams[c->fc->nb_streams-1];
3501  sc = st->priv_data;
3502 
3503  avio_r8(pb); /* version */
3504  avio_rb24(pb); /* flags */
3505  entries = avio_rb32(pb);
3506 
3507  av_log(c->fc, AV_LOG_TRACE, "track[%u].stts.entries = %u\n",
3508  c->fc->nb_streams-1, entries);
3509 
3510  if (sc->stts_data)
3511  av_log(c->fc, AV_LOG_WARNING, "Duplicated STTS atom\n");
3512  av_freep(&sc->stts_data);
3513  sc->stts_count = 0;
3514  if (entries >= INT_MAX / sizeof(*sc->stts_data))
3515  return AVERROR(ENOMEM);
3516 
3517  for (i = 0; i < entries && !pb->eof_reached; i++) {
3518  unsigned int sample_duration;
3519  unsigned int sample_count;
3520  unsigned int min_entries = FFMIN(FFMAX(i + 1, 1024 * 1024), entries);
3521  MOVStts *stts_data = av_fast_realloc(sc->stts_data, &sc->stts_allocated_size,
3522  min_entries * sizeof(*sc->stts_data));
3523  if (!stts_data) {
3524  av_freep(&sc->stts_data);
3525  sc->stts_count = 0;
3526  return AVERROR(ENOMEM);
3527  }
3528  sc->stts_count = min_entries;
3529  sc->stts_data = stts_data;
3530 
3531  sample_count = avio_rb32(pb);
3532  sample_duration = avio_rb32(pb);
3533 
3534  sc->stts_data[i].count= sample_count;
3535  sc->stts_data[i].duration= sample_duration;
3536 
3537  av_log(c->fc, AV_LOG_TRACE, "sample_count=%u, sample_duration=%u\n",
3538  sample_count, sample_duration);
3539 
3540  /* STTS sample offsets are uint32 but some files store it as int32
3541  * with negative values used to correct DTS delays.
3542  There may be abnormally large values as well. */
3543  if (sample_duration > c->max_stts_delta) {
3544  // assume high delta is a correction if negative when cast as int32
3545  int32_t delta_magnitude = (int32_t)sample_duration;
3546  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",
3547  sample_duration, i, sample_count, st->index);
3548  sc->stts_data[i].duration = 1;
3549  corrected_dts = av_sat_add64(corrected_dts, (delta_magnitude < 0 ? (int64_t)delta_magnitude : 1) * sample_count);
3550  } else {
3551  corrected_dts += sample_duration * (uint64_t)sample_count;
3552  }
3553 
3554  current_dts += sc->stts_data[i].duration * (uint64_t)sample_count;
3555 
3556  if (current_dts > corrected_dts) {
3557  int64_t drift = av_sat_sub64(current_dts, corrected_dts) / FFMAX(sample_count, 1);
3558  uint32_t correction = (sc->stts_data[i].duration > drift) ? drift : sc->stts_data[i].duration - 1;
3559  current_dts -= correction * (uint64_t)sample_count;
3560  sc->stts_data[i].duration -= correction;
3561  }
3562 
3563  duration+=(int64_t)sc->stts_data[i].duration*(uint64_t)sc->stts_data[i].count;
3564  total_sample_count+=sc->stts_data[i].count;
3565  }
3566 
3567  sc->stts_count = i;
3568 
3569  if (duration > 0 &&
3570  duration <= INT64_MAX - sc->duration_for_fps &&
3571  total_sample_count <= INT_MAX - sc->nb_frames_for_fps) {
3572  sc->duration_for_fps += duration;
3573  sc->nb_frames_for_fps += total_sample_count;
3574  }
3575 
3576  if (pb->eof_reached) {
3577  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STTS atom\n");
3578  return AVERROR_EOF;
3579  }
3580 
3581  st->nb_frames= total_sample_count;
3582  if (duration)
3583  st->duration= FFMIN(st->duration, duration);
3584 
3585  // All samples have zero duration. They have higher chance be chose by
3586  // mov_find_next_sample, which leads to seek again and again.
3587  //
3588  // It's AVERROR_INVALIDDATA actually, but such files exist in the wild.
3589  // So only mark data stream as discarded for safety.
3590  if (!duration && sc->stts_count &&
3592  av_log(c->fc, AV_LOG_WARNING,
3593  "All samples in data stream index:id [%d:%d] have zero "
3594  "duration, stream set to be discarded by default. Override "
3595  "using AVStream->discard or -discard for ffmpeg command.\n",
3596  st->index, sc->id);
3597  st->discard = AVDISCARD_ALL;
3598  }
3599  sc->track_end = duration;
3600  return 0;
3601 }
3602 
3604 {
3605  AVStream *st;
3606  MOVStreamContext *sc;
3607  int64_t i, entries;
3608 
3609  if (c->fc->nb_streams < 1)
3610  return 0;
3611  st = c->fc->streams[c->fc->nb_streams - 1];
3612  sc = st->priv_data;
3613 
3614  avio_r8(pb); /* version */
3615  avio_rb24(pb); /* flags */
3616  entries = atom.size - 4;
3617 
3618  av_log(c->fc, AV_LOG_TRACE, "track[%u].sdtp.entries = %" PRId64 "\n",
3619  c->fc->nb_streams - 1, entries);
3620 
3621  if (sc->sdtp_data)
3622  av_log(c->fc, AV_LOG_WARNING, "Duplicated SDTP atom\n");
3623  av_freep(&sc->sdtp_data);
3624  sc->sdtp_count = 0;
3625 
3626  sc->sdtp_data = av_malloc(entries);
3627  if (!sc->sdtp_data)
3628  return AVERROR(ENOMEM);
3629 
3630  for (i = 0; i < entries && !pb->eof_reached; i++)
3631  sc->sdtp_data[i] = avio_r8(pb);
3632  sc->sdtp_count = i;
3633 
3634  return 0;
3635 }
3636 
3637 static void mov_update_dts_shift(MOVStreamContext *sc, int duration, void *logctx)
3638 {
3639  if (duration < 0) {
3640  if (duration == INT_MIN) {
3641  av_log(logctx, AV_LOG_WARNING, "mov_update_dts_shift(): dts_shift set to %d\n", INT_MAX);
3642  duration++;
3643  }
3644  sc->dts_shift = FFMAX(sc->dts_shift, -duration);
3645  }
3646 }
3647 
3649 {
3650  AVStream *st;
3651  MOVStreamContext *sc;
3652  unsigned int i, entries, ctts_count = 0;
3653 
3654  if (c->trak_index < 0) {
3655  av_log(c->fc, AV_LOG_WARNING, "CTTS outside TRAK\n");
3656  return 0;
3657  }
3658 
3659  if (c->fc->nb_streams < 1)
3660  return 0;
3661  st = c->fc->streams[c->fc->nb_streams-1];
3662  sc = st->priv_data;
3663 
3664  avio_r8(pb); /* version */
3665  avio_rb24(pb); /* flags */
3666  entries = avio_rb32(pb);
3667 
3668  av_log(c->fc, AV_LOG_TRACE, "track[%u].ctts.entries = %u\n", c->fc->nb_streams - 1, entries);
3669 
3670  if (!entries)
3671  return 0;
3672  if (entries >= UINT_MAX / sizeof(*sc->ctts_data))
3673  return AVERROR_INVALIDDATA;
3674  av_freep(&sc->ctts_data);
3675  sc->ctts_data = av_fast_realloc(NULL, &sc->ctts_allocated_size, entries * sizeof(*sc->ctts_data));
3676  if (!sc->ctts_data)
3677  return AVERROR(ENOMEM);
3678 
3679  for (i = 0; i < entries && !pb->eof_reached; i++) {
3680  MOVCtts *ctts_data;
3681  const size_t min_size_needed = (ctts_count + 1) * sizeof(MOVCtts);
3682  const size_t requested_size =
3683  min_size_needed > sc->ctts_allocated_size ?
3684  FFMAX(min_size_needed, 2 * sc->ctts_allocated_size) :
3685  min_size_needed;
3686  int count = avio_rb32(pb);
3687  int duration = avio_rb32(pb);
3688 
3689  if (count <= 0) {
3690  av_log(c->fc, AV_LOG_TRACE,
3691  "ignoring CTTS entry with count=%d duration=%d\n",
3692  count, duration);
3693  continue;
3694  }
3695 
3696  if (ctts_count >= UINT_MAX / sizeof(MOVCtts) - 1)
3697  return AVERROR(ENOMEM);
3698 
3699  ctts_data = av_fast_realloc(sc->ctts_data, &sc->ctts_allocated_size, requested_size);
3700 
3701  if (!ctts_data)
3702  return AVERROR(ENOMEM);
3703 
3704  sc->ctts_data = ctts_data;
3705 
3706  ctts_data[ctts_count].count = count;
3707  ctts_data[ctts_count].offset = duration;
3708  ctts_count++;
3709 
3710  av_log(c->fc, AV_LOG_TRACE, "count=%d, duration=%d\n",
3711  count, duration);
3712 
3713  if (i+2<entries)
3714  mov_update_dts_shift(sc, duration, c->fc);
3715  }
3716 
3717  sc->ctts_count = ctts_count;
3718 
3719  if (pb->eof_reached) {
3720  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted CTTS atom\n");
3721  return AVERROR_EOF;
3722  }
3723 
3724  av_log(c->fc, AV_LOG_TRACE, "dts shift %d\n", sc->dts_shift);
3725 
3726  return 0;
3727 }
3728 
3730 {
3731  AVStream *st;
3732  MOVStreamContext *sc;
3733  uint8_t version;
3734  uint32_t grouping_type;
3735  uint32_t default_length;
3736  av_unused uint32_t default_group_description_index;
3737  uint32_t entry_count;
3738 
3739  if (c->fc->nb_streams < 1)
3740  return 0;
3741  st = c->fc->streams[c->fc->nb_streams - 1];
3742  sc = st->priv_data;
3743 
3744  version = avio_r8(pb); /* version */
3745  avio_rb24(pb); /* flags */
3746  grouping_type = avio_rl32(pb);
3747 
3748  /*
3749  * This function only supports "sync" boxes, but the code is able to parse
3750  * other boxes (such as "tscl", "tsas" and "stsa")
3751  */
3752  if (grouping_type != MKTAG('s','y','n','c'))
3753  return 0;
3754 
3755  default_length = version >= 1 ? avio_rb32(pb) : 0;
3756  default_group_description_index = version >= 2 ? avio_rb32(pb) : 0;
3757  entry_count = avio_rb32(pb);
3758 
3759  av_freep(&sc->sgpd_sync);
3760  sc->sgpd_sync_count = entry_count;
3761  sc->sgpd_sync = av_calloc(entry_count, sizeof(*sc->sgpd_sync));
3762  if (!sc->sgpd_sync)
3763  return AVERROR(ENOMEM);
3764 
3765  for (uint32_t i = 0; i < entry_count && !pb->eof_reached; i++) {
3766  uint32_t description_length = default_length;
3767  if (version >= 1 && default_length == 0)
3768  description_length = avio_rb32(pb);
3769  if (grouping_type == MKTAG('s','y','n','c')) {
3770  const uint8_t nal_unit_type = avio_r8(pb) & 0x3f;
3771  sc->sgpd_sync[i] = nal_unit_type;
3772  description_length -= 1;
3773  }
3774  avio_skip(pb, description_length);
3775  }
3776 
3777  if (pb->eof_reached) {
3778  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted SGPD atom\n");
3779  return AVERROR_EOF;
3780  }
3781 
3782  return 0;
3783 }
3784 
3786 {
3787  AVStream *st;
3788  MOVStreamContext *sc;
3789  unsigned int i, entries;
3790  uint8_t version;
3791  uint32_t grouping_type;
3792  MOVSbgp *table, **tablep;
3793  int *table_count;
3794 
3795  if (c->fc->nb_streams < 1)
3796  return 0;
3797  st = c->fc->streams[c->fc->nb_streams-1];
3798  sc = st->priv_data;
3799 
3800  version = avio_r8(pb); /* version */
3801  avio_rb24(pb); /* flags */
3802  grouping_type = avio_rl32(pb);
3803 
3804  if (grouping_type == MKTAG('r','a','p',' ')) {
3805  tablep = &sc->rap_group;
3806  table_count = &sc->rap_group_count;
3807  } else if (grouping_type == MKTAG('s','y','n','c')) {
3808  tablep = &sc->sync_group;
3809  table_count = &sc->sync_group_count;
3810  } else {
3811  return 0;
3812  }
3813 
3814  if (version == 1)
3815  avio_rb32(pb); /* grouping_type_parameter */
3816 
3817  entries = avio_rb32(pb);
3818  if (!entries)
3819  return 0;
3820  if (*tablep)
3821  av_log(c->fc, AV_LOG_WARNING, "Duplicated SBGP %s atom\n", av_fourcc2str(grouping_type));
3822  av_freep(tablep);
3823  table = av_malloc_array(entries, sizeof(*table));
3824  if (!table)
3825  return AVERROR(ENOMEM);
3826  *tablep = table;
3827 
3828  for (i = 0; i < entries && !pb->eof_reached; i++) {
3829  table[i].count = avio_rb32(pb); /* sample_count */
3830  table[i].index = avio_rb32(pb); /* group_description_index */
3831  }
3832 
3833  *table_count = i;
3834 
3835  if (pb->eof_reached) {
3836  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted SBGP atom\n");
3837  return AVERROR_EOF;
3838  }
3839 
3840  return 0;
3841 }
3842 
3843 /**
3844  * Get ith edit list entry (media time, duration).
3845  */
3847  const MOVStreamContext *msc,
3848  unsigned int edit_list_index,
3849  int64_t *edit_list_media_time,
3850  int64_t *edit_list_duration,
3851  int64_t global_timescale)
3852 {
3853  if (edit_list_index == msc->elst_count) {
3854  return 0;
3855  }
3856  *edit_list_media_time = msc->elst_data[edit_list_index].time;
3857  *edit_list_duration = msc->elst_data[edit_list_index].duration;
3858 
3859  /* duration is in global timescale units;convert to msc timescale */
3860  if (global_timescale == 0) {
3861  avpriv_request_sample(mov->fc, "Support for mvhd.timescale = 0 with editlists");
3862  return 0;
3863  }
3864  *edit_list_duration = av_rescale(*edit_list_duration, msc->time_scale,
3865  global_timescale);
3866 
3867  if (*edit_list_duration + (uint64_t)*edit_list_media_time > INT64_MAX)
3868  *edit_list_duration = 0;
3869 
3870  return 1;
3871 }
3872 
3873 /**
3874  * Find the closest previous frame to the timestamp_pts, in e_old index
3875  * entries. Searching for just any frame / just key frames can be controlled by
3876  * last argument 'flag'.
3877  * Note that if ctts_data is not NULL, we will always search for a key frame
3878  * irrespective of the value of 'flag'. If we don't find any keyframe, we will
3879  * return the first frame of the video.
3880  *
3881  * Here the timestamp_pts is considered to be a presentation timestamp and
3882  * the timestamp of index entries are considered to be decoding timestamps.
3883  *
3884  * Returns 0 if successful in finding a frame, else returns -1.
3885  * Places the found index corresponding output arg.
3886  *
3887  * If ctts_old is not NULL, then refines the searched entry by searching
3888  * backwards from the found timestamp, to find the frame with correct PTS.
3889  *
3890  * Places the found ctts_index and ctts_sample in corresponding output args.
3891  */
3893  AVIndexEntry *e_old,
3894  int nb_old,
3895  MOVTimeToSample *tts_data,
3896  int64_t tts_count,
3897  int64_t timestamp_pts,
3898  int flag,
3899  int64_t* index,
3900  int64_t* tts_index,
3901  int64_t* tts_sample)
3902 {
3903  MOVStreamContext *msc = st->priv_data;
3904  FFStream *const sti = ffstream(st);
3905  AVIndexEntry *e_keep = sti->index_entries;
3906  int nb_keep = sti->nb_index_entries;
3907  int64_t i = 0;
3908 
3909  av_assert0(index);
3910 
3911  // If dts_shift > 0, then all the index timestamps will have to be offset by
3912  // at least dts_shift amount to obtain PTS.
3913  // Hence we decrement the searched timestamp_pts by dts_shift to find the closest index element.
3914  if (msc->dts_shift > 0) {
3915  timestamp_pts -= msc->dts_shift;
3916  }
3917 
3918  sti->index_entries = e_old;
3919  sti->nb_index_entries = nb_old;
3920  *index = av_index_search_timestamp(st, timestamp_pts, flag | AVSEEK_FLAG_BACKWARD);
3921 
3922  // Keep going backwards in the index entries until the timestamp is the same.
3923  if (*index >= 0) {
3924  for (i = *index; i > 0 && e_old[i].timestamp == e_old[i - 1].timestamp;
3925  i--) {
3926  if ((flag & AVSEEK_FLAG_ANY) ||
3927  (e_old[i - 1].flags & AVINDEX_KEYFRAME)) {
3928  *index = i - 1;
3929  }
3930  }
3931  }
3932 
3933  // If we have CTTS then refine the search, by searching backwards over PTS
3934  // computed by adding corresponding CTTS durations to index timestamps.
3935  if (msc->ctts_count && *index >= 0) {
3936  av_assert0(tts_index);
3937  av_assert0(tts_sample);
3938  // Find out the ctts_index for the found frame.
3939  *tts_index = 0;
3940  *tts_sample = 0;
3941  for (int64_t index_tts_count = 0; index_tts_count < *index; index_tts_count++) {
3942  if (*tts_index < tts_count) {
3943  (*tts_sample)++;
3944  if (tts_data[*tts_index].count == *tts_sample) {
3945  (*tts_index)++;
3946  *tts_sample = 0;
3947  }
3948  }
3949  }
3950 
3951  while (*index >= 0 && (*tts_index) >= 0 && (*tts_index) < tts_count) {
3952  // Find a "key frame" with PTS <= timestamp_pts (So that we can decode B-frames correctly).
3953  // No need to add dts_shift to the timestamp here becase timestamp_pts has already been
3954  // compensated by dts_shift above.
3955  if ((e_old[*index].timestamp + tts_data[*tts_index].offset) <= timestamp_pts &&
3956  (e_old[*index].flags & AVINDEX_KEYFRAME)) {
3957  break;
3958  }
3959 
3960  (*index)--;
3961  if (*tts_sample == 0) {
3962  (*tts_index)--;
3963  if (*tts_index >= 0)
3964  *tts_sample = tts_data[*tts_index].count - 1;
3965  } else {
3966  (*tts_sample)--;
3967  }
3968  }
3969  }
3970 
3971  /* restore AVStream state*/
3972  sti->index_entries = e_keep;
3973  sti->nb_index_entries = nb_keep;
3974  return *index >= 0 ? 0 : -1;
3975 }
3976 
3977 /**
3978  * Add index entry with the given values, to the end of ffstream(st)->index_entries.
3979  * Returns the new size ffstream(st)->index_entries if successful, else returns -1.
3980  *
3981  * This function is similar to ff_add_index_entry in libavformat/utils.c
3982  * except that here we are always unconditionally adding an index entry to
3983  * the end, instead of searching the entries list and skipping the add if
3984  * there is an existing entry with the same timestamp.
3985  * This is needed because the mov_fix_index calls this func with the same
3986  * unincremented timestamp for successive discarded frames.
3987  */
3989  int size, int distance, int flags)
3990 {
3991  FFStream *const sti = ffstream(st);
3992  AVIndexEntry *entries, *ie;
3993  int64_t index = -1;
3994  const size_t min_size_needed = (sti->nb_index_entries + 1) * sizeof(AVIndexEntry);
3995 
3996  // Double the allocation each time, to lower memory fragmentation.
3997  // Another difference from ff_add_index_entry function.
3998  const size_t requested_size =
3999  min_size_needed > sti->index_entries_allocated_size ?
4000  FFMAX(min_size_needed, 2 * sti->index_entries_allocated_size) :
4001  min_size_needed;
4002 
4003  if (sti->nb_index_entries + 1U >= UINT_MAX / sizeof(AVIndexEntry))
4004  return -1;
4005 
4006  entries = av_fast_realloc(sti->index_entries,
4008  requested_size);
4009  if (!entries)
4010  return -1;
4011 
4012  sti->index_entries = entries;
4013 
4014  index = sti->nb_index_entries++;
4015  ie= &entries[index];
4016 
4017  ie->pos = pos;
4018  ie->timestamp = timestamp;
4019  ie->min_distance= distance;
4020  ie->size= size;
4021  ie->flags = flags;
4022  return index;
4023 }
4024 
4025 /**
4026  * Rewrite timestamps of index entries in the range [end_index - frame_duration_buffer_size, end_index)
4027  * by subtracting end_ts successively by the amounts given in frame_duration_buffer.
4028  */
4029 static void fix_index_entry_timestamps(AVStream* st, int end_index, int64_t end_ts,
4030  int64_t* frame_duration_buffer,
4031  int frame_duration_buffer_size) {
4032  FFStream *const sti = ffstream(st);
4033  int i = 0;
4034  av_assert0(end_index >= 0 && end_index <= sti->nb_index_entries);
4035  for (i = 0; i < frame_duration_buffer_size; i++) {
4036  end_ts -= frame_duration_buffer[frame_duration_buffer_size - 1 - i];
4037  sti->index_entries[end_index - 1 - i].timestamp = end_ts;
4038  }
4039 }
4040 
4041 static int add_tts_entry(MOVTimeToSample **tts_data, unsigned int *tts_count, unsigned int *allocated_size,
4042  int count, int offset, unsigned int duration)
4043 {
4044  MOVTimeToSample *tts_buf_new;
4045  const size_t min_size_needed = (*tts_count + 1) * sizeof(MOVTimeToSample);
4046  const size_t requested_size =
4047  min_size_needed > *allocated_size ?
4048  FFMAX(min_size_needed, 2 * (*allocated_size)) :
4049  min_size_needed;
4050 
4051  if ((unsigned)(*tts_count) >= UINT_MAX / sizeof(MOVTimeToSample) - 1)
4052  return -1;
4053 
4054  tts_buf_new = av_fast_realloc(*tts_data, allocated_size, requested_size);
4055 
4056  if (!tts_buf_new)
4057  return -1;
4058 
4059  *tts_data = tts_buf_new;
4060 
4061  tts_buf_new[*tts_count].count = count;
4062  tts_buf_new[*tts_count].offset = offset;
4063  tts_buf_new[*tts_count].duration = duration;
4064 
4065  *tts_count = (*tts_count) + 1;
4066  return 0;
4067 }
4068 
4069 #define MAX_REORDER_DELAY 16
4071 {
4072  MOVStreamContext *msc = st->priv_data;
4073  FFStream *const sti = ffstream(st);
4074  int ctts_ind = 0;
4075  int ctts_sample = 0;
4076  int64_t pts_buf[MAX_REORDER_DELAY + 1]; // Circular buffer to sort pts.
4077  int buf_start = 0;
4078  int j, r, num_swaps;
4079 
4080  for (j = 0; j < MAX_REORDER_DELAY + 1; j++)
4081  pts_buf[j] = INT64_MIN;
4082 
4083  if (st->codecpar->video_delay <= 0 && msc->ctts_count &&
4085  st->codecpar->video_delay = 0;
4086  for (int ind = 0; ind < sti->nb_index_entries && ctts_ind < msc->tts_count; ++ind) {
4087  // Point j to the last elem of the buffer and insert the current pts there.
4088  j = buf_start;
4089  buf_start = (buf_start + 1);
4090  if (buf_start == MAX_REORDER_DELAY + 1)
4091  buf_start = 0;
4092 
4093  pts_buf[j] = sti->index_entries[ind].timestamp + msc->tts_data[ctts_ind].offset;
4094 
4095  // The timestamps that are already in the sorted buffer, and are greater than the
4096  // current pts, are exactly the timestamps that need to be buffered to output PTS
4097  // in correct sorted order.
4098  // Hence the video delay (which is the buffer size used to sort DTS and output PTS),
4099  // can be computed as the maximum no. of swaps any particular timestamp needs to
4100  // go through, to keep this buffer in sorted order.
4101  num_swaps = 0;
4102  while (j != buf_start) {
4103  r = j - 1;
4104  if (r < 0) r = MAX_REORDER_DELAY;
4105  if (pts_buf[j] < pts_buf[r]) {
4106  FFSWAP(int64_t, pts_buf[j], pts_buf[r]);
4107  ++num_swaps;
4108  } else {
4109  break;
4110  }
4111  j = r;
4112  }
4113  st->codecpar->video_delay = FFMAX(st->codecpar->video_delay, num_swaps);
4114 
4115  ctts_sample++;
4116  if (ctts_sample == msc->tts_data[ctts_ind].count) {
4117  ctts_ind++;
4118  ctts_sample = 0;
4119  }
4120  }
4121  av_log(c->fc, AV_LOG_DEBUG, "Setting codecpar->delay to %d for stream st: %d\n",
4122  st->codecpar->video_delay, st->index);
4123  }
4124 }
4125 
4127 {
4128  sc->current_sample++;
4129  sc->current_index++;
4130  if (sc->index_ranges &&
4131  sc->current_index >= sc->current_index_range->end &&
4132  sc->current_index_range->end) {
4133  sc->current_index_range++;
4135  }
4136 }
4137 
4139 {
4140  sc->current_sample--;
4141  sc->current_index--;
4142  if (sc->index_ranges &&
4144  sc->current_index_range > sc->index_ranges) {
4145  sc->current_index_range--;
4146  sc->current_index = sc->current_index_range->end - 1;
4147  }
4148 }
4149 
4150 static void mov_current_sample_set(MOVStreamContext *sc, int current_sample)
4151 {
4152  int64_t range_size;
4153 
4154  sc->current_sample = current_sample;
4155  sc->current_index = current_sample;
4156  if (!sc->index_ranges) {
4157  return;
4158  }
4159 
4160  for (sc->current_index_range = sc->index_ranges;
4161  sc->current_index_range->end;
4162  sc->current_index_range++) {
4163  range_size = sc->current_index_range->end - sc->current_index_range->start;
4164  if (range_size > current_sample) {
4165  sc->current_index = sc->current_index_range->start + current_sample;
4166  break;
4167  }
4168  current_sample -= range_size;
4169  }
4170 }
4171 
4172 /**
4173  * Fix ffstream(st)->index_entries, so that it contains only the entries (and the entries
4174  * which are needed to decode them) that fall in the edit list time ranges.
4175  * Also fixes the timestamps of the index entries to match the timeline
4176  * specified the edit lists.
4177  */
4178 static void mov_fix_index(MOVContext *mov, AVStream *st)
4179 {
4180  MOVStreamContext *msc = st->priv_data;
4181  FFStream *const sti = ffstream(st);
4182  AVIndexEntry *e_old = sti->index_entries;
4183  int nb_old = sti->nb_index_entries;
4184  const AVIndexEntry *e_old_end = e_old + nb_old;
4185  const AVIndexEntry *current = NULL;
4186  MOVTimeToSample *tts_data_old = msc->tts_data;
4187  int64_t tts_index_old = 0;
4188  int64_t tts_sample_old = 0;
4189  int64_t tts_count_old = msc->tts_count;
4190  int64_t edit_list_media_time = 0;
4191  int64_t edit_list_duration = 0;
4192  int64_t frame_duration = 0;
4193  int64_t edit_list_dts_counter = 0;
4194  int64_t edit_list_dts_entry_end = 0;
4195  int64_t edit_list_start_tts_sample = 0;
4196  int64_t curr_cts;
4197  int64_t curr_ctts = 0;
4198  int64_t empty_edits_sum_duration = 0;
4199  int64_t edit_list_index = 0;
4200  int64_t index;
4201  int flags;
4202  int64_t start_dts = 0;
4203  int64_t edit_list_start_encountered = 0;
4204  int64_t search_timestamp = 0;
4205  int64_t* frame_duration_buffer = NULL;
4206  int num_discarded_begin = 0;
4207  int first_non_zero_audio_edit = -1;
4208  int packet_skip_samples = 0;
4209  MOVIndexRange *current_index_range = NULL;
4210  int found_keyframe_after_edit = 0;
4211  int found_non_empty_edit = 0;
4212 
4213  if (!msc->elst_data || msc->elst_count <= 0 || nb_old <= 0) {
4214  return;
4215  }
4216 
4217  // allocate the index ranges array
4218  msc->index_ranges = av_malloc_array(msc->elst_count + 1,
4219  sizeof(msc->index_ranges[0]));
4220  if (!msc->index_ranges) {
4221  av_log(mov->fc, AV_LOG_ERROR, "Cannot allocate index ranges buffer\n");
4222  return;
4223  }
4224  msc->current_index_range = msc->index_ranges;
4225 
4226  // Clean AVStream from traces of old index
4227  sti->index_entries = NULL;
4229  sti->nb_index_entries = 0;
4230 
4231  // Clean time to sample fields of MOVStreamContext
4232  msc->tts_data = NULL;
4233  msc->tts_count = 0;
4234  msc->tts_index = 0;
4235  msc->tts_sample = 0;
4236  msc->tts_allocated_size = 0;
4237 
4238  // Reinitialize min_corrected_pts so that it can be computed again.
4239  msc->min_corrected_pts = -1;
4240 
4241  // If the dts_shift is positive (in case of negative ctts values in mov),
4242  // then negate the DTS by dts_shift
4243  if (msc->dts_shift > 0) {
4244  edit_list_dts_entry_end -= msc->dts_shift;
4245  av_log(mov->fc, AV_LOG_DEBUG, "Shifting DTS by %d because of negative CTTS.\n", msc->dts_shift);
4246  }
4247 
4248  start_dts = edit_list_dts_entry_end;
4249 
4250  while (get_edit_list_entry(mov, msc, edit_list_index, &edit_list_media_time,
4251  &edit_list_duration, mov->time_scale)) {
4252  av_log(mov->fc, AV_LOG_DEBUG, "Processing st: %d, edit list %"PRId64" - media time: %"PRId64", duration: %"PRId64"\n",
4253  st->index, edit_list_index, edit_list_media_time, edit_list_duration);
4254  edit_list_index++;
4255  edit_list_dts_counter = edit_list_dts_entry_end;
4256  edit_list_dts_entry_end += edit_list_duration;
4257  num_discarded_begin = 0;
4258  if (!found_non_empty_edit && edit_list_media_time == -1) {
4259  empty_edits_sum_duration += edit_list_duration;
4260  continue;
4261  }
4262  found_non_empty_edit = 1;
4263 
4264  // If we encounter a non-negative edit list reset the skip_samples/start_pad fields and set them
4265  // according to the edit list below.
4266  if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
4267  if (first_non_zero_audio_edit < 0) {
4268  first_non_zero_audio_edit = 1;
4269  } else {
4270  first_non_zero_audio_edit = 0;
4271  }
4272 
4273  if (first_non_zero_audio_edit > 0)
4274  sti->skip_samples = msc->start_pad = 0;
4275  }
4276 
4277  // While reordering frame index according to edit list we must handle properly
4278  // the scenario when edit list entry starts from none key frame.
4279  // We find closest previous key frame and preserve it and consequent frames in index.
4280  // All frames which are outside edit list entry time boundaries will be dropped after decoding.
4281  search_timestamp = edit_list_media_time;
4282  if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
4283  // Audio decoders like AAC need need a decoder delay samples previous to the current sample,
4284  // to correctly decode this frame. Hence for audio we seek to a frame 1 sec. before the
4285  // edit_list_media_time to cover the decoder delay.
4286  search_timestamp = FFMAX(search_timestamp - msc->time_scale, e_old[0].timestamp);
4287  }
4288 
4289  if (find_prev_closest_index(st, e_old, nb_old, tts_data_old, tts_count_old, search_timestamp, 0,
4290  &index, &tts_index_old, &tts_sample_old) < 0) {
4291  av_log(mov->fc, AV_LOG_WARNING,
4292  "st: %d edit list: %"PRId64" Missing key frame while searching for timestamp: %"PRId64"\n",
4293  st->index, edit_list_index, search_timestamp);
4294  if (find_prev_closest_index(st, e_old, nb_old, tts_data_old, tts_count_old, search_timestamp, AVSEEK_FLAG_ANY,
4295  &index, &tts_index_old, &tts_sample_old) < 0) {
4296  av_log(mov->fc, AV_LOG_WARNING,
4297  "st: %d edit list %"PRId64" Cannot find an index entry before timestamp: %"PRId64".\n",
4298  st->index, edit_list_index, search_timestamp);
4299  index = 0;
4300  tts_index_old = 0;
4301  tts_sample_old = 0;
4302  }
4303  }
4304  current = e_old + index;
4305  edit_list_start_tts_sample = tts_sample_old;
4306 
4307  // Iterate over index and arrange it according to edit list
4308  edit_list_start_encountered = 0;
4309  found_keyframe_after_edit = 0;
4310  for (; current < e_old_end; current++, index++) {
4311  // check if frame outside edit list mark it for discard
4312  frame_duration = (current + 1 < e_old_end) ?
4313  ((current + 1)->timestamp - current->timestamp) : edit_list_duration;
4314 
4315  flags = current->flags;
4316 
4317  // frames (pts) before or after edit list
4318  curr_cts = current->timestamp + msc->dts_shift;
4319  curr_ctts = 0;
4320 
4321  if (tts_data_old && tts_index_old < tts_count_old) {
4322  curr_ctts = tts_data_old[tts_index_old].offset;
4323  av_log(mov->fc, AV_LOG_TRACE, "stts: %"PRId64" ctts: %"PRId64", tts_index: %"PRId64", tts_count: %"PRId64"\n",
4324  curr_cts, curr_ctts, tts_index_old, tts_count_old);
4325  curr_cts += curr_ctts;
4326  tts_sample_old++;
4327  if (tts_sample_old == tts_data_old[tts_index_old].count) {
4328  if (add_tts_entry(&msc->tts_data, &msc->tts_count,
4329  &msc->tts_allocated_size,
4330  tts_data_old[tts_index_old].count - edit_list_start_tts_sample,
4331  tts_data_old[tts_index_old].offset, tts_data_old[tts_index_old].duration) == -1) {
4332  av_log(mov->fc, AV_LOG_ERROR, "Cannot add Time To Sample entry %"PRId64" - {%"PRId64", %d}\n",
4333  tts_index_old,
4334  tts_data_old[tts_index_old].count - edit_list_start_tts_sample,
4335  tts_data_old[tts_index_old].offset);
4336  break;
4337  }
4338  tts_index_old++;
4339  tts_sample_old = 0;
4340  edit_list_start_tts_sample = 0;
4341  }
4342  }
4343 
4344  if (curr_cts < edit_list_media_time || curr_cts >= (edit_list_duration + edit_list_media_time)) {
4346  curr_cts < edit_list_media_time && curr_cts + frame_duration > edit_list_media_time &&
4347  first_non_zero_audio_edit > 0) {
4348  packet_skip_samples = edit_list_media_time - curr_cts;
4349  sti->skip_samples += packet_skip_samples;
4350 
4351  // Shift the index entry timestamp by packet_skip_samples to be correct.
4352  edit_list_dts_counter -= packet_skip_samples;
4353  if (edit_list_start_encountered == 0) {
4354  edit_list_start_encountered = 1;
4355  // Make timestamps strictly monotonically increasing for audio, by rewriting timestamps for
4356  // discarded packets.
4357  if (frame_duration_buffer) {
4358  fix_index_entry_timestamps(st, sti->nb_index_entries, edit_list_dts_counter,
4359  frame_duration_buffer, num_discarded_begin);
4360  av_freep(&frame_duration_buffer);
4361  }
4362  }
4363 
4364  av_log(mov->fc, AV_LOG_DEBUG, "skip %d audio samples from curr_cts: %"PRId64"\n", packet_skip_samples, curr_cts);
4365  } else {
4367  av_log(mov->fc, AV_LOG_DEBUG, "drop a frame at curr_cts: %"PRId64" @ %"PRId64"\n", curr_cts, index);
4368 
4369  if (edit_list_start_encountered == 0) {
4370  num_discarded_begin++;
4371  frame_duration_buffer = av_realloc(frame_duration_buffer,
4372  num_discarded_begin * sizeof(int64_t));
4373  if (!frame_duration_buffer) {
4374  av_log(mov->fc, AV_LOG_ERROR, "Cannot reallocate frame duration buffer\n");
4375  break;
4376  }
4377  frame_duration_buffer[num_discarded_begin - 1] = frame_duration;
4378 
4379  // Increment skip_samples for the first non-zero audio edit list
4380  if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
4381  first_non_zero_audio_edit > 0 && st->codecpar->codec_id != AV_CODEC_ID_VORBIS) {
4382  sti->skip_samples += frame_duration;
4383  }
4384  }
4385  }
4386  } else {
4387  if (msc->min_corrected_pts < 0) {
4388  msc->min_corrected_pts = edit_list_dts_counter + curr_ctts + msc->dts_shift;
4389  } else {
4390  msc->min_corrected_pts = FFMIN(msc->min_corrected_pts, edit_list_dts_counter + curr_ctts + msc->dts_shift);
4391  }
4392  if (edit_list_start_encountered == 0) {
4393  edit_list_start_encountered = 1;
4394  // Make timestamps strictly monotonically increasing by rewriting timestamps for
4395  // discarded packets.
4396  if (frame_duration_buffer) {
4397  fix_index_entry_timestamps(st, sti->nb_index_entries, edit_list_dts_counter,
4398  frame_duration_buffer, num_discarded_begin);
4399  av_freep(&frame_duration_buffer);
4400  }
4401  }
4402  }
4403 
4404  if (add_index_entry(st, current->pos, edit_list_dts_counter, current->size,
4405  current->min_distance, flags) == -1) {
4406  av_log(mov->fc, AV_LOG_ERROR, "Cannot add index entry\n");
4407  break;
4408  }
4409 
4410  // Update the index ranges array
4411  if (!current_index_range || index != current_index_range->end) {
4412  current_index_range = current_index_range ? current_index_range + 1
4413  : msc->index_ranges;
4414  current_index_range->start = index;
4415  }
4416  current_index_range->end = index + 1;
4417 
4418  // Only start incrementing DTS in frame_duration amounts, when we encounter a frame in edit list.
4419  if (edit_list_start_encountered > 0) {
4420  edit_list_dts_counter = edit_list_dts_counter + frame_duration;
4421  }
4422 
4423  // Break when found first key frame after edit entry completion
4424  if ((curr_cts + frame_duration >= (edit_list_duration + edit_list_media_time)) &&
4426  if (msc->ctts_count) {
4427  // If we have CTTS and this is the first keyframe after edit elist,
4428  // wait for one more, because there might be trailing B-frames after this I-frame
4429  // that do belong to the edit.
4430  if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO && found_keyframe_after_edit == 0) {
4431  found_keyframe_after_edit = 1;
4432  continue;
4433  }
4434  if (tts_sample_old != 0) {
4435  if (add_tts_entry(&msc->tts_data, &msc->tts_count,
4436  &msc->tts_allocated_size,
4437  tts_sample_old - edit_list_start_tts_sample,
4438  tts_data_old[tts_index_old].offset, tts_data_old[tts_index_old].duration) == -1) {
4439  av_log(mov->fc, AV_LOG_ERROR, "Cannot add Time To Sample entry %"PRId64" - {%"PRId64", %d}\n",
4440  tts_index_old, tts_sample_old - edit_list_start_tts_sample,
4441  tts_data_old[tts_index_old].offset);
4442  break;
4443  }
4444  }
4445  }
4446  break;
4447  }
4448  }
4449  }
4450  // If there are empty edits, then msc->min_corrected_pts might be positive
4451  // intentionally. So we subtract the sum duration of emtpy edits here.
4452  msc->min_corrected_pts -= empty_edits_sum_duration;
4453 
4454  // If the minimum pts turns out to be greater than zero after fixing the index, then we subtract the
4455  // dts by that amount to make the first pts zero.
4456  if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
4457  if (msc->min_corrected_pts > 0) {
4458  av_log(mov->fc, AV_LOG_DEBUG, "Offset DTS by %"PRId64" to make first pts zero.\n", msc->min_corrected_pts);
4459  for (int i = 0; i < sti->nb_index_entries; ++i)
4461  }
4462  }
4463  // Start time should be equal to zero or the duration of any empty edits.
4464  st->start_time = empty_edits_sum_duration;
4465 
4466  // Update av stream length, if it ends up shorter than the track's media duration
4467  st->duration = FFMIN(st->duration, edit_list_dts_entry_end - start_dts);
4468  msc->start_pad = sti->skip_samples;
4469 
4470  // Free the old index and the old CTTS structures
4471  av_free(e_old);
4472  av_free(tts_data_old);
4473  av_freep(&frame_duration_buffer);
4474 
4475  // Null terminate the index ranges array
4476  current_index_range = current_index_range ? current_index_range + 1
4477  : msc->index_ranges;
4478  current_index_range->start = 0;
4479  current_index_range->end = 0;
4480  msc->current_index = msc->index_ranges[0].start;
4481 }
4482 
4483 static uint32_t get_sgpd_sync_index(const MOVStreamContext *sc, int nal_unit_type)
4484 {
4485  for (uint32_t i = 0; i < sc->sgpd_sync_count; i++)
4486  if (sc->sgpd_sync[i] == nal_unit_type)
4487  return i + 1;
4488  return 0;
4489 }
4490 
4492 {
4493  int k;
4494  int sample_id = 0;
4495  uint32_t cra_index;
4496  MOVStreamContext *sc = st->priv_data;
4497 
4498  if (st->codecpar->codec_id != AV_CODEC_ID_HEVC || !sc->sync_group_count)
4499  return 0;
4500 
4501  /* Build an unrolled index of the samples */
4502  sc->sample_offsets_count = 0;
4503  for (uint32_t i = 0; i < sc->ctts_count; i++) {
4504  if (sc->ctts_data[i].count > INT_MAX - sc->sample_offsets_count)
4505  return AVERROR(ENOMEM);
4506  sc->sample_offsets_count += sc->ctts_data[i].count;
4507  }
4508  av_freep(&sc->sample_offsets);
4510  if (!sc->sample_offsets)
4511  return AVERROR(ENOMEM);
4512  k = 0;
4513  for (uint32_t i = 0; i < sc->ctts_count; i++)
4514  for (int j = 0; j < sc->ctts_data[i].count; j++)
4515  sc->sample_offsets[k++] = sc->ctts_data[i].offset;
4516 
4517  /* The following HEVC NAL type reveal the use of open GOP sync points
4518  * (TODO: BLA types may also be concerned) */
4519  cra_index = get_sgpd_sync_index(sc, HEVC_NAL_CRA_NUT); /* Clean Random Access */
4520  if (!cra_index)
4521  return 0;
4522 
4523  /* Build a list of open-GOP key samples */
4524  sc->open_key_samples_count = 0;
4525  for (uint32_t i = 0; i < sc->sync_group_count; i++)
4526  if (sc->sync_group[i].index == cra_index) {
4527  if (sc->sync_group[i].count > INT_MAX - sc->open_key_samples_count)
4528  return AVERROR(ENOMEM);
4530  }
4531  av_freep(&sc->open_key_samples);
4533  if (!sc->open_key_samples)
4534  return AVERROR(ENOMEM);
4535  k = 0;
4536  for (uint32_t i = 0; i < sc->sync_group_count; i++) {
4537  const MOVSbgp *sg = &sc->sync_group[i];
4538  if (sg->index == cra_index)
4539  for (uint32_t j = 0; j < sg->count; j++)
4540  sc->open_key_samples[k++] = sample_id;
4541  if (sg->count > INT_MAX - sample_id)
4542  return AVERROR_PATCHWELCOME;
4543  sample_id += sg->count;
4544  }
4545 
4546  /* Identify the minimal time step between samples */
4547  sc->min_sample_duration = UINT_MAX;
4548  for (uint32_t i = 0; i < sc->stts_count; i++)
4550 
4551  return 0;
4552 }
4553 
4554 #define MOV_MERGE_CTTS 1
4555 #define MOV_MERGE_STTS 2
4556 /*
4557  * Merge stts and ctts arrays into a new combined array.
4558  * stts_count and ctts_count may be left untouched as they will be
4559  * used to check for the presence of either of them.
4560  */
4561 static int mov_merge_tts_data(MOVContext *mov, AVStream *st, int flags)
4562 {
4563  MOVStreamContext *sc = st->priv_data;
4564  int ctts = sc->ctts_data && (flags & MOV_MERGE_CTTS);
4565  int stts = sc->stts_data && (flags & MOV_MERGE_STTS);
4566  int idx = 0;
4567 
4568  if (!sc->ctts_data && !sc->stts_data)
4569  return 0;
4570  // Expand time to sample entries such that we have a 1-1 mapping with samples
4571  if (!sc->sample_count || sc->sample_count >= UINT_MAX / sizeof(*sc->tts_data))
4572  return -1;
4573 
4574  if (ctts) {
4576  sc->sample_count * sizeof(*sc->tts_data));
4577  if (!sc->tts_data)
4578  return -1;
4579 
4580  memset(sc->tts_data, 0, sc->tts_allocated_size);
4581 
4582  for (int i = 0; i < sc->ctts_count &&
4583  idx < sc->sample_count; i++)
4584  for (int j = 0; j < sc->ctts_data[i].count &&
4585  idx < sc->sample_count; j++) {
4586  sc->tts_data[idx].offset = sc->ctts_data[i].offset;
4587  sc->tts_data[idx++].count = 1;
4588  }
4589 
4590  sc->tts_count = idx;
4591  } else
4592  sc->ctts_count = 0;
4593  av_freep(&sc->ctts_data);
4594  sc->ctts_allocated_size = 0;
4595 
4596  idx = 0;
4597  if (stts) {
4599  sc->sample_count * sizeof(*sc->tts_data));
4600  if (!tts_data)
4601  return -1;
4602 
4603  if (!sc->tts_data)
4604  memset(tts_data, 0, sc->tts_allocated_size);
4605  sc->tts_data = tts_data;
4606 
4607  for (int i = 0; i < sc->stts_count &&
4608  idx < sc->sample_count; i++)
4609  for (int j = 0; j < sc->stts_data[i].count &&
4610  idx < sc->sample_count; j++) {
4611  sc->tts_data[idx].duration = sc->stts_data[i].duration;
4612  sc->tts_data[idx++].count = 1;
4613  }
4614 
4615  sc->tts_count = FFMAX(sc->tts_count, idx);
4616  } else
4617  sc->stts_count = 0;
4618  av_freep(&sc->stts_data);
4619  sc->stts_allocated_size = 0;
4620 
4621  return 0;
4622 }
4623 
4624 static void mov_build_index(MOVContext *mov, AVStream *st)
4625 {
4626  MOVStreamContext *sc = st->priv_data;
4627  FFStream *const sti = ffstream(st);
4628  int64_t current_offset;
4629  int64_t current_dts = 0;
4630  unsigned int stts_index = 0;
4631  unsigned int stsc_index = 0;
4632  unsigned int stss_index = 0;
4633  unsigned int stps_index = 0;
4634  unsigned int i, j;
4635  uint64_t stream_size = 0;
4636 
4637  int ret = build_open_gop_key_points(st);
4638  if (ret < 0)
4639  return;
4640 
4641  if (sc->elst_count) {
4642  int i, edit_start_index = 0, multiple_edits = 0;
4643  int64_t empty_duration = 0; // empty duration of the first edit list entry
4644  int64_t start_time = 0; // start time of the media
4645 
4646  for (i = 0; i < sc->elst_count; i++) {
4647  const MOVElst *e = &sc->elst_data[i];
4648  if (i == 0 && e->time == -1) {
4649  /* if empty, the first entry is the start time of the stream
4650  * relative to the presentation itself */
4651  empty_duration = e->duration;
4652  edit_start_index = 1;
4653  } else if (i == edit_start_index && e->time >= 0) {
4654  start_time = e->time;
4655  } else {
4656  multiple_edits = 1;
4657  }
4658  }
4659 
4660  if (multiple_edits && !mov->advanced_editlist) {
4662  av_log(mov->fc, AV_LOG_WARNING, "multiple edit list entries, "
4663  "not supported in fragmented MP4 files\n");
4664  else
4665  av_log(mov->fc, AV_LOG_WARNING, "multiple edit list entries, "
4666  "Use -advanced_editlist to correctly decode otherwise "
4667  "a/v desync might occur\n");
4668  }
4669 
4670  /* adjust first dts according to edit list */
4671  if ((empty_duration || start_time) && mov->time_scale > 0) {
4672  if (empty_duration)
4673  empty_duration = av_rescale(empty_duration, sc->time_scale, mov->time_scale);
4674 
4675  if (av_sat_sub64(start_time, empty_duration) != start_time - (uint64_t)empty_duration)
4676  av_log(mov->fc, AV_LOG_WARNING, "start_time - empty_duration is not representable\n");
4677 
4678  sc->time_offset = start_time - (uint64_t)empty_duration;
4680  if (!mov->advanced_editlist)
4681  current_dts = -sc->time_offset;
4682  }
4683 
4684  if (!multiple_edits && !mov->advanced_editlist &&
4686  sc->start_pad = start_time;
4687  }
4688 
4689  /* only use old uncompressed audio chunk demuxing when stts specifies it */
4690  if (!(st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
4691  sc->stts_count == 1 && sc->stts_data && sc->stts_data[0].duration == 1)) {
4692  unsigned int current_sample = 0;
4693  unsigned int stts_sample = 0;
4694  unsigned int sample_size;
4695  unsigned int distance = 0;
4696  unsigned int rap_group_index = 0;
4697  unsigned int rap_group_sample = 0;
4698  int rap_group_present = sc->rap_group_count && sc->rap_group;
4699  int key_off = (sc->keyframe_count && sc->keyframes[0] > 0) || (sc->stps_count && sc->stps_data[0] > 0);
4700 
4701  current_dts -= sc->dts_shift;
4702 
4703  if (!sc->sample_count || sti->nb_index_entries || sc->tts_count)
4704  return;
4705  if (sc->sample_count >= UINT_MAX / sizeof(*sti->index_entries) - sti->nb_index_entries)
4706  return;
4707  if (av_reallocp_array(&sti->index_entries,
4708  sti->nb_index_entries + sc->sample_count,
4709  sizeof(*sti->index_entries)) < 0) {
4710  sti->nb_index_entries = 0;
4711  return;
4712  }
4713  sti->index_entries_allocated_size = (sti->nb_index_entries + sc->sample_count) * sizeof(*sti->index_entries);
4714 
4716  if (ret < 0)
4717  return;
4718 
4719  for (i = 0; i < sc->chunk_count; i++) {
4720  int64_t next_offset = i+1 < sc->chunk_count ? sc->chunk_offsets[i+1] : INT64_MAX;
4721  current_offset = sc->chunk_offsets[i];
4722  while (mov_stsc_index_valid(stsc_index, sc->stsc_count) &&
4723  i + 1 == sc->stsc_data[stsc_index + 1].first)
4724  stsc_index++;
4725 
4726  if (next_offset > current_offset && sc->sample_size>0 && sc->sample_size < sc->stsz_sample_size &&
4727  sc->stsc_data[stsc_index].count * (int64_t)sc->stsz_sample_size > next_offset - current_offset) {
4728  av_log(mov->fc, AV_LOG_WARNING, "STSZ sample size %d invalid (too large), ignoring\n", sc->stsz_sample_size);
4729  sc->stsz_sample_size = sc->sample_size;
4730  }
4731  if (sc->stsz_sample_size>0 && sc->stsz_sample_size < sc->sample_size) {
4732  av_log(mov->fc, AV_LOG_WARNING, "STSZ sample size %d invalid (too small), ignoring\n", sc->stsz_sample_size);
4733  sc->stsz_sample_size = sc->sample_size;
4734  }
4735 
4736  for (j = 0; j < sc->stsc_data[stsc_index].count; j++) {
4737  int keyframe = 0;
4738  if (current_sample >= sc->sample_count) {
4739  av_log(mov->fc, AV_LOG_ERROR, "wrong sample count\n");
4740  return;
4741  }
4742 
4743  if (!sc->keyframe_absent && (!sc->keyframe_count || current_sample+key_off == sc->keyframes[stss_index])) {
4744  keyframe = 1;
4745  if (stss_index + 1 < sc->keyframe_count)
4746  stss_index++;
4747  } else if (sc->stps_count && current_sample+key_off == sc->stps_data[stps_index]) {
4748  keyframe = 1;
4749  if (stps_index + 1 < sc->stps_count)
4750  stps_index++;
4751  }
4752  if (rap_group_present && rap_group_index < sc->rap_group_count) {
4753  if (sc->rap_group[rap_group_index].index > 0)
4754  keyframe = 1;
4755  if (++rap_group_sample == sc->rap_group[rap_group_index].count) {
4756  rap_group_sample = 0;
4757  rap_group_index++;
4758  }
4759  }
4760  if (sc->keyframe_absent
4761  && !sc->stps_count
4762  && !rap_group_present
4763  && (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO || (i==0 && j==0)))
4764  keyframe = 1;
4765  if (keyframe)
4766  distance = 0;
4767  sample_size = sc->stsz_sample_size > 0 ? sc->stsz_sample_size : sc->sample_sizes[current_sample];
4768  if (current_offset > INT64_MAX - sample_size) {
4769  av_log(mov->fc, AV_LOG_ERROR, "Current offset %"PRId64" or sample size %u is too large\n",
4770  current_offset,
4771  sample_size);
4772  return;
4773  }
4774 
4775  if (sc->pseudo_stream_id == -1 ||
4776  sc->stsc_data[stsc_index].id - 1 == sc->pseudo_stream_id) {
4777  AVIndexEntry *e;
4778  if (sample_size > 0x3FFFFFFF) {
4779  av_log(mov->fc, AV_LOG_ERROR, "Sample size %u is too large\n", sample_size);
4780  return;
4781  }
4782  e = &sti->index_entries[sti->nb_index_entries++];
4783  e->pos = current_offset;
4784  e->timestamp = current_dts;
4785  e->size = sample_size;
4786  e->min_distance = distance;
4787  e->flags = keyframe ? AVINDEX_KEYFRAME : 0;
4788  av_log(mov->fc, AV_LOG_TRACE, "AVIndex stream %d, sample %u, offset %"PRIx64", dts %"PRId64", "
4789  "size %u, distance %u, keyframe %d\n", st->index, current_sample,
4790  current_offset, current_dts, sample_size, distance, keyframe);
4791  if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && sti->nb_index_entries < 100)
4792  ff_rfps_add_frame(mov->fc, st, current_dts);
4793  }
4794 
4795  current_offset += sample_size;
4796  stream_size += sample_size;
4797 
4798  current_dts += sc->tts_data[stts_index].duration;
4799 
4800  distance++;
4801  stts_sample++;
4802  current_sample++;
4803  if (stts_index + 1 < sc->tts_count && stts_sample == sc->tts_data[stts_index].count) {
4804  stts_sample = 0;
4805  stts_index++;
4806  }
4807  }
4808  }
4809  if (st->duration > 0)
4810  st->codecpar->bit_rate = stream_size*8*sc->time_scale/st->duration;
4811  } else {
4812  unsigned chunk_samples, total = 0;
4813 
4814  if (!sc->chunk_count || sc->tts_count)
4815  return;
4816 
4818  if (ret < 0)
4819  return;
4820 
4821  // compute total chunk count
4822  for (i = 0; i < sc->stsc_count; i++) {
4823  unsigned count, chunk_count;
4824 
4825  chunk_samples = sc->stsc_data[i].count;
4826  if (i != sc->stsc_count - 1 &&
4827  sc->samples_per_frame && chunk_samples % sc->samples_per_frame) {
4828  av_log(mov->fc, AV_LOG_ERROR, "error unaligned chunk\n");
4829  return;
4830  }
4831 
4832  if (sc->samples_per_frame >= 160) { // gsm
4833  count = chunk_samples / sc->samples_per_frame;
4834  } else if (sc->samples_per_frame > 1) {
4835  unsigned samples = (1024/sc->samples_per_frame)*sc->samples_per_frame;
4836  count = (chunk_samples+samples-1) / samples;
4837  } else {
4838  count = (chunk_samples+1023) / 1024;
4839  }
4840 
4841  if (mov_stsc_index_valid(i, sc->stsc_count))
4842  chunk_count = sc->stsc_data[i+1].first - sc->stsc_data[i].first;
4843  else
4844  chunk_count = sc->chunk_count - (sc->stsc_data[i].first - 1);
4845  total += chunk_count * count;
4846  }
4847 
4848  av_log(mov->fc, AV_LOG_TRACE, "chunk count %u\n", total);
4849  if (total >= UINT_MAX / sizeof(*sti->index_entries) - sti->nb_index_entries)
4850  return;
4851  if (av_reallocp_array(&sti->index_entries,
4852  sti->nb_index_entries + total,
4853  sizeof(*sti->index_entries)) < 0) {
4854  sti->nb_index_entries = 0;
4855  return;
4856  }
4857  sti->index_entries_allocated_size = (sti->nb_index_entries + total) * sizeof(*sti->index_entries);
4858 
4859  // populate index
4860  for (i = 0; i < sc->chunk_count; i++) {
4861  current_offset = sc->chunk_offsets[i];
4862  if (mov_stsc_index_valid(stsc_index, sc->stsc_count) &&
4863  i + 1 == sc->stsc_data[stsc_index + 1].first)
4864  stsc_index++;
4865  chunk_samples = sc->stsc_data[stsc_index].count;
4866 
4867  while (chunk_samples > 0) {
4868  AVIndexEntry *e;
4869  unsigned size, samples;
4870 
4871  if (sc->samples_per_frame > 1 && !sc->bytes_per_frame) {
4873  "Zero bytes per frame, but %d samples per frame",
4874  sc->samples_per_frame);
4875  return;
4876  }
4877 
4878  if (sc->samples_per_frame >= 160) { // gsm
4879  samples = sc->samples_per_frame;
4880  size = sc->bytes_per_frame;
4881  } else {
4882  if (sc->samples_per_frame > 1) {
4883  samples = FFMIN((1024 / sc->samples_per_frame)*
4884  sc->samples_per_frame, chunk_samples);
4886  } else {
4887  samples = FFMIN(1024, chunk_samples);
4888  size = samples * sc->sample_size;
4889  }
4890  }
4891 
4892  if (sti->nb_index_entries >= total) {
4893  av_log(mov->fc, AV_LOG_ERROR, "wrong chunk count %u\n", total);
4894  return;
4895  }
4896  if (size > 0x3FFFFFFF) {
4897  av_log(mov->fc, AV_LOG_ERROR, "Sample size %u is too large\n", size);
4898  return;
4899  }
4900  e = &sti->index_entries[sti->nb_index_entries++];
4901  e->pos = current_offset;
4902  e->timestamp = current_dts;
4903  e->size = size;
4904  e->min_distance = 0;
4905  e->flags = AVINDEX_KEYFRAME;
4906  av_log(mov->fc, AV_LOG_TRACE, "AVIndex stream %d, chunk %u, offset %"PRIx64", dts %"PRId64", "
4907  "size %u, duration %u\n", st->index, i, current_offset, current_dts,
4908  size, samples);
4909 
4910  current_offset += size;
4911  current_dts += samples;
4912  chunk_samples -= samples;
4913  }
4914  }
4915  }
4916 
4917  if (!mov->ignore_editlist && mov->advanced_editlist) {
4918  // Fix index according to edit lists.
4919  mov_fix_index(mov, st);
4920  }
4921 
4922  // Update start time of the stream.
4924  st->start_time = sti->index_entries[0].timestamp + sc->dts_shift;
4925  if (sc->tts_data) {
4926  st->start_time += sc->tts_data[0].offset;
4927  }
4928  }
4929 
4930  mov_estimate_video_delay(mov, st);
4931 }
4932 
4933 static int test_same_origin(const char *src, const char *ref) {
4934  char src_proto[64];
4935  char ref_proto[64];
4936  char src_auth[256];
4937  char ref_auth[256];
4938  char src_host[256];
4939  char ref_host[256];
4940  int src_port=-1;
4941  int ref_port=-1;
4942 
4943  av_url_split(src_proto, sizeof(src_proto), src_auth, sizeof(src_auth), src_host, sizeof(src_host), &src_port, NULL, 0, src);
4944  av_url_split(ref_proto, sizeof(ref_proto), ref_auth, sizeof(ref_auth), ref_host, sizeof(ref_host), &ref_port, NULL, 0, ref);
4945 
4946  if (strlen(src) == 0) {
4947  return -1;
4948  } else if (strlen(src_auth) + 1 >= sizeof(src_auth) ||
4949  strlen(ref_auth) + 1 >= sizeof(ref_auth) ||
4950  strlen(src_host) + 1 >= sizeof(src_host) ||
4951  strlen(ref_host) + 1 >= sizeof(ref_host)) {
4952  return 0;
4953  } else if (strcmp(src_proto, ref_proto) ||
4954  strcmp(src_auth, ref_auth) ||
4955  strcmp(src_host, ref_host) ||
4956  src_port != ref_port) {
4957  return 0;
4958  } else
4959  return 1;
4960 }
4961 
4962 static int mov_open_dref(MOVContext *c, AVIOContext **pb, const char *src, MOVDref *ref)
4963 {
4964  /* try relative path, we do not try the absolute because it can leak information about our
4965  system to an attacker */
4966  if (ref->nlvl_to > 0 && ref->nlvl_from > 0) {
4967  char filename[1025];
4968  const char *src_path;
4969  int i, l;
4970 
4971  /* find a source dir */
4972  src_path = strrchr(src, '/');
4973  if (src_path)
4974  src_path++;
4975  else
4976  src_path = src;
4977 
4978  /* find a next level down to target */
4979  for (i = 0, l = strlen(ref->path) - 1; l >= 0; l--)
4980  if (ref->path[l] == '/') {
4981  if (i == ref->nlvl_to - 1)
4982  break;
4983  else
4984  i++;
4985  }
4986 
4987  /* compose filename if next level down to target was found */
4988  if (i == ref->nlvl_to - 1 && src_path - src < sizeof(filename)) {
4989  memcpy(filename, src, src_path - src);
4990  filename[src_path - src] = 0;
4991 
4992  for (i = 1; i < ref->nlvl_from; i++)
4993  av_strlcat(filename, "../", sizeof(filename));
4994 
4995  av_strlcat(filename, ref->path + l + 1, sizeof(filename));
4996  if (!c->use_absolute_path) {
4997  int same_origin = test_same_origin(src, filename);
4998 
4999  if (!same_origin) {
5000  av_log(c->fc, AV_LOG_ERROR,
5001  "Reference with mismatching origin, %s not tried for security reasons, "
5002  "set demuxer option use_absolute_path to allow it anyway\n",
5003  ref->path);
5004  return AVERROR(ENOENT);
5005  }
5006 
5007  if (strstr(ref->path + l + 1, "..") ||
5008  strstr(ref->path + l + 1, ":") ||
5009  (ref->nlvl_from > 1 && same_origin < 0) ||
5010  (filename[0] == '/' && src_path == src))
5011  return AVERROR(ENOENT);
5012  }
5013 
5014  if (strlen(filename) + 1 == sizeof(filename))
5015  return AVERROR(ENOENT);
5016  if (!c->fc->io_open(c->fc, pb, filename, AVIO_FLAG_READ, NULL))
5017  return 0;
5018  }
5019  } else if (c->use_absolute_path) {
5020  av_log(c->fc, AV_LOG_WARNING, "Using absolute path on user request, "
5021  "this is a possible security issue\n");
5022  if (!c->fc->io_open(c->fc, pb, ref->path, AVIO_FLAG_READ, NULL))
5023  return 0;
5024  } else {
5025  av_log(c->fc, AV_LOG_ERROR,
5026  "Absolute path %s not tried for security reasons, "
5027  "set demuxer option use_absolute_path to allow absolute paths\n",
5028  ref->path);
5029  }
5030 
5031  return AVERROR(ENOENT);
5032 }
5033 
5035 {
5036  if (sc->time_scale <= 0) {
5037  av_log(c->fc, AV_LOG_WARNING, "stream %d, timescale not set\n", sc->ffindex);
5038  sc->time_scale = c->time_scale;
5039  if (sc->time_scale <= 0)
5040  sc->time_scale = 1;
5041  }
5042 }
5043 
5044 #if CONFIG_IAMFDEC
5045 static int mov_update_iamf_streams(MOVContext *c, const AVStream *st)
5046 {
5047  const MOVStreamContext *sc = st->priv_data;
5048  const IAMFContext *iamf = &sc->iamf->iamf;
5049 
5050  for (int i = 0; i < iamf->nb_audio_elements; i++) {
5051  const AVStreamGroup *stg = NULL;
5052 
5053  for (int j = 0; j < c->fc->nb_stream_groups; j++)
5054  if (c->fc->stream_groups[j]->id == iamf->audio_elements[i]->audio_element_id)
5055  stg = c->fc->stream_groups[j];
5056  av_assert0(stg);
5057 
5058  for (int j = 0; j < stg->nb_streams; j++) {
5059  const FFStream *sti = cffstream(st);
5060  AVStream *out = stg->streams[j];
5061  FFStream *out_sti = ffstream(stg->streams[j]);
5062 
5063  out->codecpar->bit_rate = 0;
5064 
5065  if (out == st)
5066  continue;
5067 
5068  out->time_base = st->time_base;
5069  out->start_time = st->start_time;
5070  out->duration = st->duration;
5071  out->nb_frames = st->nb_frames;
5072  out->discard = st->discard;
5073 
5074  av_assert0(!out_sti->index_entries);
5076  if (!out_sti->index_entries)
5077  return AVERROR(ENOMEM);
5078 
5080  out_sti->nb_index_entries = sti->nb_index_entries;
5081  out_sti->skip_samples = sti->skip_samples;
5082  memcpy(out_sti->index_entries, sti->index_entries, sti->index_entries_allocated_size);
5083  }
5084  }
5085 
5086  return 0;
5087 }
5088 #endif
5089 
5090 static int sanity_checks(void *log_obj, MOVStreamContext *sc, int index)
5091 {
5092  if ((sc->chunk_count && (!sc->stts_count || !sc->stsc_count ||
5093  (!sc->sample_size && !sc->sample_count))) ||
5094  (!sc->chunk_count && sc->sample_count)) {
5095  av_log(log_obj, AV_LOG_ERROR, "stream %d, missing mandatory atoms, broken header\n",
5096  index);
5097  return 1;
5098  }
5099 
5100  if (sc->stsc_count && sc->stsc_data[ sc->stsc_count - 1 ].first > sc->chunk_count) {
5101  av_log(log_obj, AV_LOG_ERROR, "stream %d, contradictionary STSC and STCO\n",
5102  index);
5103  return 2;
5104  }
5105  return 0;
5106 }
5107 
5109 {
5110  AVStream *st;
5111  MOVStreamContext *sc;
5112  int ret;
5113 
5114  st = avformat_new_stream(c->fc, NULL);
5115  if (!st) return AVERROR(ENOMEM);
5116  st->id = -1;
5117  sc = av_mallocz(sizeof(MOVStreamContext));
5118  if (!sc) return AVERROR(ENOMEM);
5119 
5120  st->priv_data = sc;
5122  sc->ffindex = st->index;
5123  c->trak_index = st->index;
5124  sc->tref_flags = 0;
5125  sc->tref_id = -1;
5126  sc->refcount = 1;
5127 
5128  if ((ret = mov_read_default(c, pb, atom)) < 0)
5129  return ret;
5130 
5131  c->trak_index = -1;
5132 
5133  // Here stsc refers to a chunk not described in stco. This is technically invalid,
5134  // but we can overlook it (clearing stsc) whenever stts_count == 0 (indicating no samples).
5135  if (!sc->chunk_count && !sc->stts_count && sc->stsc_count) {
5136  sc->stsc_count = 0;
5137  av_freep(&sc->stsc_data);
5138  }
5139 
5140  ret = sanity_checks(c->fc, sc, st->index);
5141  if (ret)
5142  return ret > 1 ? AVERROR_INVALIDDATA : 0;
5143 
5144  fix_timescale(c, sc);
5145 
5146  avpriv_set_pts_info(st, 64, 1, sc->time_scale);
5147 
5148  /*
5149  * Advanced edit list support does not work with fragemented MP4s, which
5150  * have stsc, stsz, stco, and stts with zero entries in the moov atom.
5151  * In these files, trun atoms may be streamed in.
5152  */
5153  if (!sc->stts_count && c->advanced_editlist) {
5154 
5155  av_log(c->fc, AV_LOG_VERBOSE, "advanced_editlist does not work with fragmented "
5156  "MP4. disabling.\n");
5157  c->advanced_editlist = 0;
5158  c->advanced_editlist_autodisabled = 1;
5159  }
5160 
5161  mov_build_index(c, st);
5162 
5163 #if CONFIG_IAMFDEC
5164  if (sc->iamf) {
5165  ret = mov_update_iamf_streams(c, st);
5166  if (ret < 0)
5167  return ret;
5168  }
5169 #endif
5170 
5171  if (sc->dref_id-1 < sc->drefs_count && sc->drefs[sc->dref_id-1].path) {
5172  MOVDref *dref = &sc->drefs[sc->dref_id - 1];
5173  if (c->enable_drefs) {
5174  if (mov_open_dref(c, &sc->pb, c->fc->url, dref) < 0)
5175  av_log(c->fc, AV_LOG_ERROR,
5176  "stream %d, error opening alias: path='%s', dir='%s', "
5177  "filename='%s', volume='%s', nlvl_from=%d, nlvl_to=%d\n",
5178  st->index, dref->path, dref->dir, dref->filename,
5179  dref->volume, dref->nlvl_from, dref->nlvl_to);
5180  } else {
5181  av_log(c->fc, AV_LOG_WARNING,
5182  "Skipped opening external track: "
5183  "stream %d, alias: path='%s', dir='%s', "
5184  "filename='%s', volume='%s', nlvl_from=%d, nlvl_to=%d."
5185  "Set enable_drefs to allow this.\n",
5186  st->index, dref->path, dref->dir, dref->filename,
5187  dref->volume, dref->nlvl_from, dref->nlvl_to);
5188  }
5189  } else {
5190  sc->pb = c->fc->pb;
5191  sc->pb_is_copied = 1;
5192  }
5193 
5194  if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
5195  int stts_constant = sc->stts_count && sc->tts_count;
5196  if (sc->h_spacing && sc->v_spacing)
5198  sc->h_spacing, sc->v_spacing, INT_MAX);
5199  if (!st->sample_aspect_ratio.num && st->codecpar->width && st->codecpar->height &&
5200  sc->height && sc->width &&
5201  (st->codecpar->width != sc->width || st->codecpar->height != sc->height)) {
5203  (int64_t)st->codecpar->height * sc->width,
5204  (int64_t)st->codecpar->width * sc->height, INT_MAX);
5205  }
5206 
5207 #if FF_API_R_FRAME_RATE
5208  for (unsigned int i = 1; sc->stts_count && i + 1 < sc->tts_count; i++) {
5209  if (sc->tts_data[i].duration == sc->tts_data[0].duration)
5210  continue;
5211  stts_constant = 0;
5212  }
5213  if (stts_constant)
5215  sc->time_scale, sc->tts_data[0].duration, INT_MAX);
5216 #endif
5217  }
5218 
5219  // done for ai5q, ai52, ai55, ai1q, ai12 and ai15.
5220  if (!st->codecpar->extradata_size && st->codecpar->codec_id == AV_CODEC_ID_H264 &&
5221  TAG_IS_AVCI(st->codecpar->codec_tag)) {
5223  if (ret < 0)
5224  return ret;
5225  }
5226 
5227  switch (st->codecpar->codec_id) {
5228  case AV_CODEC_ID_H261:
5229  case AV_CODEC_ID_H263:
5230  case AV_CODEC_ID_MPEG4:
5231  st->codecpar->width = 0; /* let decoder init width/height */
5232  st->codecpar->height= 0;
5233  break;
5234  default:
5235  break;
5236  }
5237 
5238  // If the duration of the mp3 packets is not constant, then they could need a parser
5239  if (st->codecpar->codec_id == AV_CODEC_ID_MP3
5240  && sc->time_scale == st->codecpar->sample_rate) {
5241  int stts_constant = 1;
5242  for (int i = 1; sc->stts_count && i < sc->tts_count; i++) {
5243  if (sc->tts_data[i].duration == sc->tts_data[0].duration)
5244  continue;
5245  stts_constant = 0;
5246  }
5247  if (!stts_constant)
5249  }
5250  /* Do not need those anymore. */
5251  av_freep(&sc->chunk_offsets);
5252  av_freep(&sc->sample_sizes);
5253  av_freep(&sc->keyframes);
5254  av_freep(&sc->stps_data);
5255  av_freep(&sc->elst_data);
5256  av_freep(&sc->rap_group);
5257  av_freep(&sc->sync_group);
5258  av_freep(&sc->sgpd_sync);
5259 
5260  return 0;
5261 }
5262 
5264 {
5265  int ret;
5266  c->itunes_metadata = 1;
5267  ret = mov_read_default(c, pb, atom);
5268  c->itunes_metadata = 0;
5269  return ret;
5270 }
5271 
5273 {
5274  uint32_t count;
5275  uint32_t i;
5276 
5277  if (atom.size < 8)
5278  return 0;
5279 
5280  avio_skip(pb, 4);
5281  count = avio_rb32(pb);
5282  atom.size -= 8;
5283  if (count >= UINT_MAX / sizeof(*c->meta_keys)) {
5284  av_log(c->fc, AV_LOG_ERROR,
5285  "The 'keys' atom with the invalid key count: %"PRIu32"\n", count);
5286  return AVERROR_INVALIDDATA;
5287  }
5288 
5289  c->meta_keys_count = count + 1;
5290  c->meta_keys = av_mallocz(c->meta_keys_count * sizeof(*c->meta_keys));
5291  if (!c->meta_keys)
5292  return AVERROR(ENOMEM);
5293 
5294  for (i = 1; i <= count; ++i) {
5295  uint32_t key_size = avio_rb32(pb);
5296  uint32_t type = avio_rl32(pb);
5297  if (key_size < 8 || key_size > atom.size) {
5298  av_log(c->fc, AV_LOG_ERROR,
5299  "The key# %"PRIu32" in meta has invalid size:"
5300  "%"PRIu32"\n", i, key_size);
5301  return AVERROR_INVALIDDATA;
5302  }
5303  atom.size -= key_size;
5304  key_size -= 8;
5305  if (type != MKTAG('m','d','t','a')) {
5306  avio_skip(pb, key_size);
5307  continue;
5308  }
5309  c->meta_keys[i] = av_mallocz(key_size + 1);
5310  if (!c->meta_keys[i])
5311  return AVERROR(ENOMEM);
5312  avio_read(pb, c->meta_keys[i], key_size);
5313  }
5314 
5315  return 0;
5316 }
5317 
5319 {
5320  int64_t end = av_sat_add64(avio_tell(pb), atom.size);
5321  uint8_t *key = NULL, *val = NULL, *mean = NULL;
5322  int i;
5323  int ret = 0;
5324  AVStream *st;
5325  MOVStreamContext *sc;
5326 
5327  if (c->fc->nb_streams < 1)
5328  return 0;
5329  st = c->fc->streams[c->fc->nb_streams-1];
5330  sc = st->priv_data;
5331 
5332  for (i = 0; i < 3; i++) {
5333  uint8_t **p;
5334  uint32_t len, tag;
5335 
5336  if (end - avio_tell(pb) <= 12)
5337  break;
5338 
5339  len = avio_rb32(pb);
5340  tag = avio_rl32(pb);
5341  avio_skip(pb, 4); // flags
5342 
5343  if (len < 12 || len - 12 > end - avio_tell(pb))
5344  break;
5345  len -= 12;
5346 
5347  if (tag == MKTAG('m', 'e', 'a', 'n'))
5348  p = &mean;
5349  else if (tag == MKTAG('n', 'a', 'm', 'e'))
5350  p = &key;
5351  else if (tag == MKTAG('d', 'a', 't', 'a') && len > 4) {
5352  avio_skip(pb, 4);
5353  len -= 4;
5354  p = &val;
5355  } else
5356  break;
5357 
5358  if (*p)
5359  break;
5360 
5361  *p = av_malloc(len + 1);
5362  if (!*p) {
5363  ret = AVERROR(ENOMEM);
5364  break;
5365  }
5366  ret = ffio_read_size(pb, *p, len);
5367  if (ret < 0) {
5368  av_freep(p);
5369  break;
5370  }
5371  (*p)[len] = 0;
5372  }
5373 
5374  if (mean && key && val) {
5375  if (strcmp(key, "iTunSMPB") == 0) {
5376  int priming, remainder, samples;
5377  if(sscanf(val, "%*X %X %X %X", &priming, &remainder, &samples) == 3){
5378  if(priming>0 && priming<16384)
5379  sc->start_pad = priming;
5380  }
5381  }
5382  if (strcmp(key, "cdec") != 0) {
5383  av_dict_set(&c->fc->metadata, key, val,
5385  key = val = NULL;
5386  }
5387  } else {
5388  av_log(c->fc, AV_LOG_VERBOSE,
5389  "Unhandled or malformed custom metadata of size %"PRId64"\n", atom.size);
5390  }
5391 
5392  avio_seek(pb, end, SEEK_SET);
5393  av_freep(&key);
5394  av_freep(&val);
5395  av_freep(&mean);
5396  return ret;
5397 }
5398 
5400 {
5401  MOVStreamContext *sc;
5402  AVStream *st;
5403 
5404  st = avformat_new_stream(c->fc, NULL);
5405  if (!st)
5406  return AVERROR(ENOMEM);
5407  sc = av_mallocz(sizeof(MOVStreamContext));
5408  if (!sc)
5409  return AVERROR(ENOMEM);
5410 
5411  item->st = st;
5412  st->id = item->item_id;
5413  st->priv_data = sc;
5415  st->codecpar->codec_id = mov_codec_id(st, item->type);
5416  sc->id = st->id;
5417  sc->ffindex = st->index;
5418  st->avg_frame_rate.num = st->avg_frame_rate.den = 1;
5419  st->time_base.num = st->time_base.den = 1;
5420  st->nb_frames = 1;
5421  sc->time_scale = 1;
5422  sc->pb = c->fc->pb;
5423  sc->pb_is_copied = 1;
5424  sc->refcount = 1;
5425 
5426  if (item->name)
5427  av_dict_set(&st->metadata, "title", item->name, 0);
5428 
5429  // Populate the necessary fields used by mov_build_index.
5430  sc->stsc_count = 1;
5431  sc->stsc_data = av_malloc_array(1, sizeof(*sc->stsc_data));
5432  if (!sc->stsc_data)
5433  return AVERROR(ENOMEM);
5434  sc->stsc_data[0].first = 1;
5435  sc->stsc_data[0].count = 1;
5436  sc->stsc_data[0].id = 1;
5437  sc->chunk_offsets = av_malloc_array(1, sizeof(*sc->chunk_offsets));
5438  if (!sc->chunk_offsets)
5439  return AVERROR(ENOMEM);
5440  sc->chunk_count = 1;
5441  sc->sample_sizes = av_malloc_array(1, sizeof(*sc->sample_sizes));
5442  if (!sc->sample_sizes)
5443  return AVERROR(ENOMEM);
5444  sc->sample_count = 1;
5445  sc->stts_data = av_malloc_array(1, sizeof(*sc->stts_data));
5446  if (!sc->stts_data)
5447  return AVERROR(ENOMEM);
5448  sc->stts_count = 1;
5449  sc->stts_data[0].count = 1;
5450  // Not used for still images. But needed by mov_build_index.
5451  sc->stts_data[0].duration = 0;
5452 
5453  return 0;
5454 }
5455 
5457 {
5458  while (atom.size > 8) {
5459  uint32_t tag;
5460  if (avio_feof(pb))
5461  return AVERROR_EOF;
5462  tag = avio_rl32(pb);
5463  atom.size -= 4;
5464  if (tag == MKTAG('h','d','l','r')) {
5465  avio_seek(pb, -8, SEEK_CUR);
5466  atom.size += 8;
5467  return mov_read_default(c, pb, atom);
5468  }
5469  }
5470  return 0;
5471 }
5472 
5473 // return 1 when matrix is identity, 0 otherwise
5474 #define IS_MATRIX_IDENT(matrix) \
5475  ( (matrix)[0][0] == (1 << 16) && \
5476  (matrix)[1][1] == (1 << 16) && \
5477  (matrix)[2][2] == (1 << 30) && \
5478  !(matrix)[0][1] && !(matrix)[0][2] && \
5479  !(matrix)[1][0] && !(matrix)[1][2] && \
5480  !(matrix)[2][0] && !(matrix)[2][1])
5481 
5483 {
5484  int i, j, e;
5485  int width;
5486  int height;
5487  int display_matrix[3][3];
5488  int res_display_matrix[3][3] = { { 0 } };
5489  AVStream *st;
5490  MOVStreamContext *sc;
5491  int version;
5492  int flags;
5493 
5494  if (c->fc->nb_streams < 1)
5495  return 0;
5496  st = c->fc->streams[c->fc->nb_streams-1];
5497  sc = st->priv_data;
5498 
5499  // Each stream (trak) should have exactly 1 tkhd. This catches bad files and
5500  // avoids corrupting AVStreams mapped to an earlier tkhd.
5501  if (st->id != -1)
5502  return AVERROR_INVALIDDATA;
5503 
5504  version = avio_r8(pb);
5505  flags = avio_rb24(pb);
5507 
5508  if (version == 1) {
5509  avio_rb64(pb);
5510  avio_rb64(pb);
5511  } else {
5512  avio_rb32(pb); /* creation time */
5513  avio_rb32(pb); /* modification time */
5514  }
5515  st->id = (int)avio_rb32(pb); /* track id (NOT 0 !)*/
5516  sc->id = st->id;
5517  avio_rb32(pb); /* reserved */
5518 
5519  /* highlevel (considering edits) duration in movie timebase */
5520  (version == 1) ? avio_rb64(pb) : avio_rb32(pb);
5521  avio_rb32(pb); /* reserved */
5522  avio_rb32(pb); /* reserved */
5523 
5524  avio_rb16(pb); /* layer */
5525  avio_rb16(pb); /* alternate group */
5526  avio_rb16(pb); /* volume */
5527  avio_rb16(pb); /* reserved */
5528 
5529  //read in the display matrix (outlined in ISO 14496-12, Section 6.2.2)
5530  // they're kept in fixed point format through all calculations
5531  // save u,v,z to store the whole matrix in the AV_PKT_DATA_DISPLAYMATRIX
5532  // side data, but the scale factor is not needed to calculate aspect ratio
5533  for (i = 0; i < 3; i++) {
5534  display_matrix[i][0] = avio_rb32(pb); // 16.16 fixed point
5535  display_matrix[i][1] = avio_rb32(pb); // 16.16 fixed point
5536  display_matrix[i][2] = avio_rb32(pb); // 2.30 fixed point
5537  }
5538 
5539  width = avio_rb32(pb); // 16.16 fixed point track width
5540  height = avio_rb32(pb); // 16.16 fixed point track height
5541  sc->width = width >> 16;
5542  sc->height = height >> 16;
5543 
5544  // apply the moov display matrix (after the tkhd one)
5545  for (i = 0; i < 3; i++) {
5546  const int sh[3] = { 16, 16, 30 };
5547  for (j = 0; j < 3; j++) {
5548  for (e = 0; e < 3; e++) {
5549  res_display_matrix[i][j] +=
5550  ((int64_t) display_matrix[i][e] *
5551  c->movie_display_matrix[e][j]) >> sh[e];
5552  }
5553  }
5554  }
5555 
5556  // save the matrix when it is not the default identity
5557  if (!IS_MATRIX_IDENT(res_display_matrix)) {
5558  av_freep(&sc->display_matrix);
5559  sc->display_matrix = av_malloc(sizeof(int32_t) * 9);
5560  if (!sc->display_matrix)
5561  return AVERROR(ENOMEM);
5562 
5563  for (i = 0; i < 3; i++)
5564  for (j = 0; j < 3; j++)
5565  sc->display_matrix[i * 3 + j] = res_display_matrix[i][j];
5566  }
5567 
5568  // transform the display width/height according to the matrix
5569  // to keep the same scale, use [width height 1<<16]
5570  if (width && height && sc->display_matrix) {
5571  double disp_transform[2];
5572 
5573  for (i = 0; i < 2; i++)
5574  disp_transform[i] = hypot(sc->display_matrix[0 + i],
5575  sc->display_matrix[3 + i]);
5576 
5577  if (disp_transform[0] > 1 && disp_transform[1] > 1 &&
5578  disp_transform[0] < (1<<24) && disp_transform[1] < (1<<24) &&
5579  fabs((disp_transform[0] / disp_transform[1]) - 1.0) > 0.01)
5581  disp_transform[0] / disp_transform[1],
5582  INT_MAX);
5583  }
5584  return 0;
5585 }
5586 
5588 {
5589  MOVFragment *frag = &c->fragment;
5590  MOVTrackExt *trex = NULL;
5591  int flags, track_id, i;
5592  MOVFragmentStreamInfo * frag_stream_info;
5593 
5594  avio_r8(pb); /* version */
5595  flags = avio_rb24(pb);
5596 
5597  track_id = avio_rb32(pb);
5598  if (!track_id)
5599  return AVERROR_INVALIDDATA;
5600  for (i = 0; i < c->trex_count; i++)
5601  if (c->trex_data[i].track_id == track_id) {
5602  trex = &c->trex_data[i];
5603  break;
5604  }
5605  if (!trex) {
5606  av_log(c->fc, AV_LOG_WARNING, "could not find corresponding trex (id %u)\n", track_id);
5607  return 0;
5608  }
5609  c->fragment.found_tfhd = 1;
5610  frag->track_id = track_id;
5611  set_frag_stream(&c->frag_index, track_id);
5612 
5615  frag->moof_offset : frag->implicit_offset;
5616  frag->stsd_id = flags & MOV_TFHD_STSD_ID ? avio_rb32(pb) : trex->stsd_id;
5617 
5619  avio_rb32(pb) : trex->duration;
5620  frag->size = flags & MOV_TFHD_DEFAULT_SIZE ?
5621  avio_rb32(pb) : trex->size;
5622  frag->flags = flags & MOV_TFHD_DEFAULT_FLAGS ?
5623  avio_rb32(pb) : trex->flags;
5624  av_log(c->fc, AV_LOG_TRACE, "frag flags 0x%x\n", frag->flags);
5625 
5626  frag_stream_info = get_current_frag_stream_info(&c->frag_index);
5627  if (frag_stream_info) {
5628  frag_stream_info->next_trun_dts = AV_NOPTS_VALUE;
5629  frag_stream_info->stsd_id = frag->stsd_id;
5630  }
5631  return 0;
5632 }
5633 
5635 {
5636  unsigned i, num;
5637  void *new_tracks;
5638 
5639  num = atom.size / 4;
5640  if (!(new_tracks = av_malloc_array(num, sizeof(int))))
5641  return AVERROR(ENOMEM);
5642 
5643  av_free(c->chapter_tracks);
5644  c->chapter_tracks = new_tracks;
5645  c->nb_chapter_tracks = num;
5646 
5647  for (i = 0; i < num && !pb->eof_reached; i++)
5648  c->chapter_tracks[i] = avio_rb32(pb);
5649 
5650  c->nb_chapter_tracks = i;
5651 
5652  return 0;
5653 }
5654 
5656 {
5657  MOVTrackExt *trex;
5658  int err;
5659 
5660  if ((uint64_t)c->trex_count+1 >= UINT_MAX / sizeof(*c->trex_data))
5661  return AVERROR_INVALIDDATA;
5662  if ((err = av_reallocp_array(&c->trex_data, c->trex_count + 1,
5663  sizeof(*c->trex_data))) < 0) {
5664  c->trex_count = 0;
5665  return err;
5666  }
5667 
5668  c->fc->duration = AV_NOPTS_VALUE; // the duration from mvhd is not representing the whole file when fragments are used.
5669 
5670  trex = &c->trex_data[c->trex_count++];
5671  avio_r8(pb); /* version */
5672  avio_rb24(pb); /* flags */
5673  trex->track_id = avio_rb32(pb);
5674  trex->stsd_id = avio_rb32(pb);
5675  trex->duration = avio_rb32(pb);
5676  trex->size = avio_rb32(pb);
5677  trex->flags = avio_rb32(pb);
5678  return 0;
5679 }
5680 
5682 {
5683  MOVFragment *frag = &c->fragment;
5684  AVStream *st = NULL;
5685  MOVStreamContext *sc;
5686  int version, i;
5687  MOVFragmentStreamInfo * frag_stream_info;
5688  int64_t base_media_decode_time;
5689 
5690  for (i = 0; i < c->fc->nb_streams; i++) {
5691  sc = c->fc->streams[i]->priv_data;
5692  if (sc->id == frag->track_id) {
5693  st = c->fc->streams[i];
5694  break;
5695  }
5696  }
5697  if (!st) {
5698  av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %u\n", frag->track_id);
5699  return 0;
5700  }
5701  sc = st->priv_data;
5702  if (sc->pseudo_stream_id + 1 != frag->stsd_id && sc->pseudo_stream_id != -1)
5703  return 0;
5704  version = avio_r8(pb);
5705  avio_rb24(pb); /* flags */
5706  if (version) {
5707  base_media_decode_time = avio_rb64(pb);
5708  } else {
5709  base_media_decode_time = avio_rb32(pb);
5710  }
5711 
5712  frag_stream_info = get_current_frag_stream_info(&c->frag_index);
5713  if (frag_stream_info)
5714  frag_stream_info->tfdt_dts = base_media_decode_time;
5715  sc->track_end = base_media_decode_time;
5716 
5717  return 0;
5718 }
5719 
5721 {
5722  MOVFragment *frag = &c->fragment;
5723  AVStream *st = NULL;
5724  FFStream *sti = NULL;
5725  MOVStreamContext *sc;
5726  MOVTimeToSample *tts_data;
5727  uint64_t offset;
5728  int64_t dts, pts = AV_NOPTS_VALUE;
5729  int data_offset = 0;
5730  unsigned entries, first_sample_flags = frag->flags;
5731  int flags, distance, i;
5732  int64_t prev_dts = AV_NOPTS_VALUE;
5733  int next_frag_index = -1, index_entry_pos;
5734  size_t requested_size;
5735  size_t old_allocated_size;
5736  AVIndexEntry *new_entries;
5737  MOVFragmentStreamInfo * frag_stream_info;
5738 
5739  if (!frag->found_tfhd) {
5740  av_log(c->fc, AV_LOG_ERROR, "trun track id unknown, no tfhd was found\n");
5741  return AVERROR_INVALIDDATA;
5742  }
5743 
5744  for (i = 0; i < c->fc->nb_streams; i++) {
5745  sc = c->fc->streams[i]->priv_data;
5746  if (sc->id == frag->track_id) {
5747  st = c->fc->streams[i];
5748  sti = ffstream(st);
5749  break;
5750  }
5751  }
5752  if (!st) {
5753  av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %u\n", frag->track_id);
5754  return 0;
5755  }
5756  sc = st->priv_data;
5757  if (sc->pseudo_stream_id+1 != frag->stsd_id && sc->pseudo_stream_id != -1)
5758  return 0;
5759 
5760  // Find the next frag_index index that has a valid index_entry for
5761  // the current track_id.
5762  //
5763  // A valid index_entry means the trun for the fragment was read
5764  // and it's samples are in index_entries at the given position.
5765  // New index entries will be inserted before the index_entry found.
5766  index_entry_pos = sti->nb_index_entries;
5767  for (i = c->frag_index.current + 1; i < c->frag_index.nb_items; i++) {
5768  frag_stream_info = get_frag_stream_info(&c->frag_index, i, frag->track_id);
5769  if (frag_stream_info && frag_stream_info->index_entry >= 0) {
5770  next_frag_index = i;
5771  index_entry_pos = frag_stream_info->index_entry;
5772  break;
5773  }
5774  }
5775  av_assert0(index_entry_pos <= sti->nb_index_entries);
5776 
5777  avio_r8(pb); /* version */
5778  flags = avio_rb24(pb);
5779  entries = avio_rb32(pb);
5780  av_log(c->fc, AV_LOG_TRACE, "flags 0x%x entries %u\n", flags, entries);
5781 
5782  if ((uint64_t)entries+sc->tts_count >= UINT_MAX/sizeof(*sc->tts_data))
5783  return AVERROR_INVALIDDATA;
5784  if (flags & MOV_TRUN_DATA_OFFSET) data_offset = avio_rb32(pb);
5785  if (flags & MOV_TRUN_FIRST_SAMPLE_FLAGS) first_sample_flags = avio_rb32(pb);
5786 
5787  frag_stream_info = get_current_frag_stream_info(&c->frag_index);
5788  if (frag_stream_info) {
5789  if (frag_stream_info->next_trun_dts != AV_NOPTS_VALUE) {
5790  dts = frag_stream_info->next_trun_dts - sc->time_offset;
5791  } else if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE &&
5792  c->use_mfra_for == FF_MOV_FLAG_MFRA_PTS) {
5793  pts = frag_stream_info->first_tfra_pts;
5794  av_log(c->fc, AV_LOG_DEBUG, "found mfra time %"PRId64
5795  ", using it for pts\n", pts);
5796  } else if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE &&
5797  c->use_mfra_for == FF_MOV_FLAG_MFRA_DTS) {
5798  dts = frag_stream_info->first_tfra_pts;
5799  av_log(c->fc, AV_LOG_DEBUG, "found mfra time %"PRId64
5800  ", using it for dts\n", pts);
5801  } else {
5802  int has_tfdt = frag_stream_info->tfdt_dts != AV_NOPTS_VALUE;
5803  int has_sidx = frag_stream_info->sidx_pts != AV_NOPTS_VALUE;
5804  int fallback_tfdt = !c->use_tfdt && !has_sidx && has_tfdt;
5805  int fallback_sidx = c->use_tfdt && !has_tfdt && has_sidx;
5806 
5807  if (fallback_sidx) {
5808  av_log(c->fc, AV_LOG_DEBUG, "use_tfdt set but no tfdt found, using sidx instead\n");
5809  }
5810  if (fallback_tfdt) {
5811  av_log(c->fc, AV_LOG_DEBUG, "use_tfdt not set but no sidx found, using tfdt instead\n");
5812  }
5813 
5814  if (has_tfdt && c->use_tfdt || fallback_tfdt) {
5815  dts = frag_stream_info->tfdt_dts - sc->time_offset;
5816  av_log(c->fc, AV_LOG_DEBUG, "found tfdt time %"PRId64
5817  ", using it for dts\n", dts);
5818  } else if (has_sidx && !c->use_tfdt || fallback_sidx) {
5819  // FIXME: sidx earliest_presentation_time is *PTS*, s.b.
5820  // pts = frag_stream_info->sidx_pts;
5821  dts = frag_stream_info->sidx_pts - sc->time_offset;
5822  av_log(c->fc, AV_LOG_DEBUG, "found sidx time %"PRId64
5823  ", using it for dts\n", frag_stream_info->sidx_pts);
5824  } else {
5825  dts = sc->track_end - sc->time_offset;
5826  av_log(c->fc, AV_LOG_DEBUG, "found track end time %"PRId64
5827  ", using it for dts\n", dts);
5828  }
5829  }
5830  } else {
5831  dts = sc->track_end - sc->time_offset;
5832  av_log(c->fc, AV_LOG_DEBUG, "found track end time %"PRId64
5833  ", using it for dts\n", dts);
5834  }
5835  offset = frag->base_data_offset + data_offset;
5836  distance = 0;
5837  av_log(c->fc, AV_LOG_TRACE, "first sample flags 0x%x\n", first_sample_flags);
5838 
5839  // realloc space for new index entries
5840  if ((uint64_t)sti->nb_index_entries + entries >= UINT_MAX / sizeof(AVIndexEntry)) {
5841  entries = UINT_MAX / sizeof(AVIndexEntry) - sti->nb_index_entries;
5842  av_log(c->fc, AV_LOG_ERROR, "Failed to add index entry\n");
5843  }
5844  if (entries == 0)
5845  return 0;
5846 
5847  requested_size = (sti->nb_index_entries + entries) * sizeof(AVIndexEntry);
5848  new_entries = av_fast_realloc(sti->index_entries,
5850  requested_size);
5851  if (!new_entries)
5852  return AVERROR(ENOMEM);
5853  sti->index_entries= new_entries;
5854 
5855  requested_size = (sti->nb_index_entries + entries) * sizeof(*sc->tts_data);
5856  old_allocated_size = sc->tts_allocated_size;
5857  tts_data = av_fast_realloc(sc->tts_data, &sc->tts_allocated_size,
5858  requested_size);
5859  if (!tts_data)
5860  return AVERROR(ENOMEM);
5861  sc->tts_data = tts_data;
5862 
5863  // In case there were samples without time to sample entries, ensure they get
5864  // zero valued entries. This ensures clips which mix boxes with and
5865  // without time to sample entries don't pickup uninitialized data.
5866  memset((uint8_t*)(sc->tts_data) + old_allocated_size, 0,
5867  sc->tts_allocated_size - old_allocated_size);
5868 
5869  if (index_entry_pos < sti->nb_index_entries) {
5870  // Make hole in index_entries and tts_data for new samples
5871  memmove(sti->index_entries + index_entry_pos + entries,
5872  sti->index_entries + index_entry_pos,
5873  sizeof(*sti->index_entries) *
5874  (sti->nb_index_entries - index_entry_pos));
5875  memmove(sc->tts_data + index_entry_pos + entries,
5876  sc->tts_data + index_entry_pos,
5877  sizeof(*sc->tts_data) * (sc->tts_count - index_entry_pos));
5878  if (index_entry_pos < sc->current_sample) {
5879  sc->current_sample += entries;
5880  }
5881  }
5882 
5883  sti->nb_index_entries += entries;
5884  sc->tts_count = sti->nb_index_entries;
5885  sc->stts_count = sti->nb_index_entries;
5886  if (flags & MOV_TRUN_SAMPLE_CTS)
5887  sc->ctts_count = sti->nb_index_entries;
5888 
5889  // Record the index_entry position in frag_index of this fragment
5890  if (frag_stream_info) {
5891  frag_stream_info->index_entry = index_entry_pos;
5892  if (frag_stream_info->index_base < 0)
5893  frag_stream_info->index_base = index_entry_pos;
5894  }
5895 
5896  if (index_entry_pos > 0)
5897  prev_dts = sti->index_entries[index_entry_pos-1].timestamp;
5898 
5899  for (i = 0; i < entries && !pb->eof_reached; i++) {
5900  unsigned sample_size = frag->size;
5901  int sample_flags = i ? frag->flags : first_sample_flags;
5902  unsigned sample_duration = frag->duration;
5903  unsigned ctts_duration = 0;
5904  int keyframe = 0;
5905  int index_entry_flags = 0;
5906 
5907  if (flags & MOV_TRUN_SAMPLE_DURATION) sample_duration = avio_rb32(pb);
5908  if (flags & MOV_TRUN_SAMPLE_SIZE) sample_size = avio_rb32(pb);
5909  if (flags & MOV_TRUN_SAMPLE_FLAGS) sample_flags = avio_rb32(pb);
5910  if (flags & MOV_TRUN_SAMPLE_CTS) ctts_duration = avio_rb32(pb);
5911 
5912  mov_update_dts_shift(sc, ctts_duration, c->fc);
5913  if (pts != AV_NOPTS_VALUE) {
5914  dts = pts - sc->dts_shift;
5915  if (flags & MOV_TRUN_SAMPLE_CTS) {
5916  dts -= ctts_duration;
5917  } else {
5918  dts -= sc->time_offset;
5919  }
5920  av_log(c->fc, AV_LOG_DEBUG,
5921  "pts %"PRId64" calculated dts %"PRId64
5922  " sc->dts_shift %d ctts.duration %d"
5923  " sc->time_offset %"PRId64
5924  " flags & MOV_TRUN_SAMPLE_CTS %d\n",
5925  pts, dts,
5926  sc->dts_shift, ctts_duration,
5928  pts = AV_NOPTS_VALUE;
5929  }
5930 
5931  keyframe =
5932  !(sample_flags & (MOV_FRAG_SAMPLE_FLAG_IS_NON_SYNC |
5934  if (keyframe) {
5935  distance = 0;
5936  index_entry_flags |= AVINDEX_KEYFRAME;
5937  }
5938  // Fragments can overlap in time. Discard overlapping frames after
5939  // decoding.
5940  if (prev_dts >= dts)
5941  index_entry_flags |= AVINDEX_DISCARD_FRAME;
5942 
5943  sti->index_entries[index_entry_pos].pos = offset;
5944  sti->index_entries[index_entry_pos].timestamp = dts;
5945  sti->index_entries[index_entry_pos].size = sample_size;
5946  sti->index_entries[index_entry_pos].min_distance = distance;
5947  sti->index_entries[index_entry_pos].flags = index_entry_flags;
5948 
5949  sc->tts_data[index_entry_pos].count = 1;
5950  sc->tts_data[index_entry_pos].offset = ctts_duration;
5951  sc->tts_data[index_entry_pos].duration = sample_duration;
5952  index_entry_pos++;
5953 
5954  av_log(c->fc, AV_LOG_TRACE, "AVIndex stream %d, sample %d, offset %"PRIx64", dts %"PRId64", "
5955  "size %u, distance %d, keyframe %d\n", st->index,
5956  index_entry_pos, offset, dts, sample_size, distance, keyframe);
5957  distance++;
5958  if (av_sat_add64(dts, sample_duration) != dts + (uint64_t)sample_duration)
5959  return AVERROR_INVALIDDATA;
5960  if (!sample_size)
5961  return AVERROR_INVALIDDATA;
5962  dts += sample_duration;
5963  offset += sample_size;
5964  sc->data_size += sample_size;
5965 
5966  if (sample_duration <= INT64_MAX - sc->duration_for_fps &&
5967  1 <= INT_MAX - sc->nb_frames_for_fps
5968  ) {
5969  sc->duration_for_fps += sample_duration;
5970  sc->nb_frames_for_fps ++;
5971  }
5972  }
5973  if (frag_stream_info)
5974  frag_stream_info->next_trun_dts = dts + sc->time_offset;
5975  if (i < entries) {
5976  // EOF found before reading all entries. Fix the hole this would
5977  // leave in index_entries and tts_data
5978  int gap = entries - i;
5979  memmove(sti->index_entries + index_entry_pos,
5980  sti->index_entries + index_entry_pos + gap,
5981  sizeof(*sti->index_entries) *
5982  (sti->nb_index_entries - (index_entry_pos + gap)));
5983  memmove(sc->tts_data + index_entry_pos,
5984  sc->tts_data + index_entry_pos + gap,
5985  sizeof(*sc->tts_data) *
5986  (sc->tts_count - (index_entry_pos + gap)));
5987 
5988  sti->nb_index_entries -= gap;
5989  sc->tts_count -= gap;
5990  if (index_entry_pos < sc->current_sample) {
5991  sc->current_sample -= gap;
5992  }
5993  entries = i;
5994  }
5995 
5996  // The end of this new fragment may overlap in time with the start
5997  // of the next fragment in index_entries. Mark the samples in the next
5998  // fragment that overlap with AVINDEX_DISCARD_FRAME
5999  prev_dts = AV_NOPTS_VALUE;
6000  if (index_entry_pos > 0)
6001  prev_dts = sti->index_entries[index_entry_pos-1].timestamp;
6002  for (int i = index_entry_pos; i < sti->nb_index_entries; i++) {
6003  if (prev_dts < sti->index_entries[i].timestamp)
6004  break;
6006  }
6007 
6008  // If a hole was created to insert the new index_entries into,
6009  // the index_entry recorded for all subsequent moof must
6010  // be incremented by the number of entries inserted.
6011  fix_frag_index_entries(&c->frag_index, next_frag_index,
6012  frag->track_id, entries);
6013 
6014  if (pb->eof_reached) {
6015  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted TRUN atom\n");
6016  return AVERROR_EOF;
6017  }
6018 
6019  frag->implicit_offset = offset;
6020 
6021  sc->track_end = dts + sc->time_offset;
6022  if (st->duration < sc->track_end)
6023  st->duration = sc->track_end;
6024 
6025  return 0;
6026 }
6027 
6029 {
6030  int64_t stream_size = avio_size(pb);
6031  int64_t offset = av_sat_add64(avio_tell(pb), atom.size), pts, timestamp;
6032  uint8_t version, is_complete;
6033  int64_t offadd;
6034  unsigned i, j, track_id, item_count;
6035  AVStream *st = NULL;
6036  AVStream *ref_st = NULL;
6037  MOVStreamContext *sc, *ref_sc = NULL;
6038  AVRational timescale;
6039 
6040  version = avio_r8(pb);
6041  if (version > 1) {
6042  avpriv_request_sample(c->fc, "sidx version %u", version);
6043  return 0;
6044  }
6045 
6046  avio_rb24(pb); // flags
6047 
6048  track_id = avio_rb32(pb); // Reference ID
6049  for (i = 0; i < c->fc->nb_streams; i++) {
6050  sc = c->fc->streams[i]->priv_data;
6051  if (sc->id == track_id) {
6052  st = c->fc->streams[i];
6053  break;
6054  }
6055  }
6056  if (!st) {
6057  av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %d\n", track_id);
6058  return 0;
6059  }
6060 
6061  sc = st->priv_data;
6062 
6063  timescale = av_make_q(1, avio_rb32(pb));
6064 
6065  if (timescale.den <= 0) {
6066  av_log(c->fc, AV_LOG_ERROR, "Invalid sidx timescale 1/%d\n", timescale.den);
6067  return AVERROR_INVALIDDATA;
6068  }
6069 
6070  if (version == 0) {
6071  pts = avio_rb32(pb);
6072  offadd= avio_rb32(pb);
6073  } else {
6074  pts = avio_rb64(pb);
6075  offadd= avio_rb64(pb);
6076  }
6077  if (av_sat_add64(offset, offadd) != offset + (uint64_t)offadd)
6078  return AVERROR_INVALIDDATA;
6079 
6080  offset += (uint64_t)offadd;
6081 
6082  avio_rb16(pb); // reserved
6083 
6084  item_count = avio_rb16(pb);
6085  if (item_count == 0)
6086  return AVERROR_INVALIDDATA;
6087 
6088  for (i = 0; i < item_count; i++) {
6089  int index;
6090  MOVFragmentStreamInfo * frag_stream_info;
6091  uint32_t size = avio_rb32(pb);
6092  uint32_t duration = avio_rb32(pb);
6093  if (size & 0x80000000) {
6094  avpriv_request_sample(c->fc, "sidx reference_type 1");
6095  return AVERROR_PATCHWELCOME;
6096  }
6097  avio_rb32(pb); // sap_flags
6098  timestamp = av_rescale_q(pts, timescale, st->time_base);
6099 
6101  frag_stream_info = get_frag_stream_info(&c->frag_index, index, track_id);
6102  if (frag_stream_info)
6103  frag_stream_info->sidx_pts = timestamp;
6104 
6105  if (av_sat_add64(offset, size) != offset + (uint64_t)size ||
6106  av_sat_add64(pts, duration) != pts + (uint64_t)duration
6107  )
6108  return AVERROR_INVALIDDATA;
6109  offset += size;
6110  pts += duration;
6111  }
6112 
6113  st->duration = sc->track_end = pts;
6114 
6115  sc->has_sidx = 1;
6116 
6117  // See if the remaining bytes are just an mfra which we can ignore.
6118  is_complete = offset == stream_size;
6119  if (!is_complete && (pb->seekable & AVIO_SEEKABLE_NORMAL) && stream_size > 0 ) {
6120  int64_t ret;
6121  int64_t original_pos = avio_tell(pb);
6122  if (!c->have_read_mfra_size) {
6123  if ((ret = avio_seek(pb, stream_size - 4, SEEK_SET)) < 0)
6124  return ret;
6125  c->mfra_size = avio_rb32(pb);
6126  c->have_read_mfra_size = 1;
6127  if ((ret = avio_seek(pb, original_pos, SEEK_SET)) < 0)
6128  return ret;
6129  }
6130  if (offset == stream_size - c->mfra_size)
6131  is_complete = 1;
6132  }
6133 
6134  if (is_complete) {
6135  // Find first entry in fragment index that came from an sidx.
6136  // This will pretty much always be the first entry.
6137  for (i = 0; i < c->frag_index.nb_items; i++) {
6138  MOVFragmentIndexItem * item = &c->frag_index.item[i];
6139  for (j = 0; ref_st == NULL && j < item->nb_stream_info; j++) {
6140  MOVFragmentStreamInfo * si;
6141  si = &item->stream_info[j];
6142  if (si->sidx_pts != AV_NOPTS_VALUE) {
6143  ref_st = c->fc->streams[j];
6144  ref_sc = ref_st->priv_data;
6145  break;
6146  }
6147  }
6148  }
6149  if (ref_st) for (i = 0; i < c->fc->nb_streams; i++) {
6150  st = c->fc->streams[i];
6151  sc = st->priv_data;
6152  if (!sc->has_sidx) {
6153  st->duration = sc->track_end = av_rescale(ref_st->duration, sc->time_scale, ref_sc->time_scale);
6154  }
6155  }
6156 
6157  c->frag_index.complete = 1;
6158  }
6159 
6160  return 0;
6161 }
6162 
6163 /* this atom should be null (from specs), but some buggy files put the 'moov' atom inside it... */
6164 /* like the files created with Adobe Premiere 5.0, for samples see */
6165 /* http://graphics.tudelft.nl/~wouter/publications/soundtests/ */
6167 {
6168  int err;
6169 
6170  if (atom.size < 8)
6171  return 0; /* continue */
6172  if (avio_rb32(pb) != 0) { /* 0 sized mdat atom... use the 'wide' atom size */
6173  avio_skip(pb, atom.size - 4);
6174  return 0;
6175  }
6176  atom.type = avio_rl32(pb);
6177  atom.size -= 8;
6178  if (atom.type != MKTAG('m','d','a','t')) {
6179  avio_skip(pb, atom.size);
6180  return 0;
6181  }
6182  err = mov_read_mdat(c, pb, atom);
6183  return err;
6184 }
6185 
6187 {
6188 #if CONFIG_ZLIB
6189  FFIOContext ctx;
6190  uint8_t *cmov_data;
6191  uint8_t *moov_data; /* uncompressed data */
6192  long cmov_len, moov_len;
6193  int ret = -1;
6194 
6195  avio_rb32(pb); /* dcom atom */
6196  if (avio_rl32(pb) != MKTAG('d','c','o','m'))
6197  return AVERROR_INVALIDDATA;
6198  if (avio_rl32(pb) != MKTAG('z','l','i','b')) {
6199  av_log(c->fc, AV_LOG_ERROR, "unknown compression for cmov atom !\n");
6200  return AVERROR_INVALIDDATA;
6201  }
6202  avio_rb32(pb); /* cmvd atom */
6203  if (avio_rl32(pb) != MKTAG('c','m','v','d'))
6204  return AVERROR_INVALIDDATA;
6205  moov_len = avio_rb32(pb); /* uncompressed size */
6206  cmov_len = atom.size - 6 * 4;
6207 
6208  cmov_data = av_malloc(cmov_len);
6209  if (!cmov_data)
6210  return AVERROR(ENOMEM);
6211  moov_data = av_malloc(moov_len);
6212  if (!moov_data) {
6213  av_free(cmov_data);
6214  return AVERROR(ENOMEM);
6215  }
6216  ret = ffio_read_size(pb, cmov_data, cmov_len);
6217  if (ret < 0)
6218  goto free_and_return;
6219 
6221  if (uncompress (moov_data, (uLongf *) &moov_len, (const Bytef *)cmov_data, cmov_len) != Z_OK)
6222  goto free_and_return;
6223  ffio_init_read_context(&ctx, moov_data, moov_len);
6224  ctx.pub.seekable = AVIO_SEEKABLE_NORMAL;
6225  atom.type = MKTAG('m','o','o','v');
6226  atom.size = moov_len;
6227  ret = mov_read_default(c, &ctx.pub, atom);
6228 free_and_return:
6229  av_free(moov_data);
6230  av_free(cmov_data);
6231  return ret;
6232 #else
6233  av_log(c->fc, AV_LOG_ERROR, "this file requires zlib support compiled in\n");
6234  return AVERROR(ENOSYS);
6235 #endif
6236 }
6237 
6238 /* edit list atom */
6240 {
6241  MOVStreamContext *sc;
6242  int i, edit_count, version;
6243  int64_t elst_entry_size;
6244 
6245  if (c->fc->nb_streams < 1 || c->ignore_editlist)
6246  return 0;
6247  sc = c->fc->streams[c->fc->nb_streams-1]->priv_data;
6248 
6249  version = avio_r8(pb); /* version */
6250  avio_rb24(pb); /* flags */
6251  edit_count = avio_rb32(pb); /* entries */
6252  atom.size -= 8;
6253 
6254  elst_entry_size = version == 1 ? 20 : 12;
6255  if (atom.size != edit_count * elst_entry_size) {
6256  if (c->fc->strict_std_compliance >= FF_COMPLIANCE_STRICT) {
6257  av_log(c->fc, AV_LOG_ERROR, "Invalid edit list entry_count: %d for elst atom of size: %"PRId64" bytes.\n",
6258  edit_count, atom.size + 8);
6259  return AVERROR_INVALIDDATA;
6260  } else {
6261  edit_count = atom.size / elst_entry_size;
6262  if (edit_count * elst_entry_size != atom.size) {
6263  av_log(c->fc, AV_LOG_WARNING, "ELST atom of %"PRId64" bytes, bigger than %d entries.\n", atom.size, edit_count);
6264  }
6265  }
6266  }
6267 
6268  if (!edit_count)
6269  return 0;
6270  if (sc->elst_data)
6271  av_log(c->fc, AV_LOG_WARNING, "Duplicated ELST atom\n");
6272  av_free(sc->elst_data);
6273  sc->elst_count = 0;
6274  sc->elst_data = av_malloc_array(edit_count, sizeof(*sc->elst_data));
6275  if (!sc->elst_data)
6276  return AVERROR(ENOMEM);
6277 
6278  av_log(c->fc, AV_LOG_TRACE, "track[%u].edit_count = %i\n", c->fc->nb_streams - 1, edit_count);
6279  for (i = 0; i < edit_count && atom.size > 0 && !pb->eof_reached; i++) {
6280  MOVElst *e = &sc->elst_data[i];
6281 
6282  if (version == 1) {
6283  e->duration = avio_rb64(pb);
6284  e->time = avio_rb64(pb);
6285  atom.size -= 16;
6286  } else {
6287  e->duration = avio_rb32(pb); /* segment duration */
6288  e->time = (int32_t)avio_rb32(pb); /* media time */
6289  atom.size -= 8;
6290  }
6291  e->rate = avio_rb32(pb) / 65536.0;
6292  atom.size -= 4;
6293  av_log(c->fc, AV_LOG_TRACE, "duration=%"PRId64" time=%"PRId64" rate=%f\n",
6294  e->duration, e->time, e->rate);
6295 
6296  if (e->time < 0 && e->time != -1 &&
6297  c->fc->strict_std_compliance >= FF_COMPLIANCE_STRICT) {
6298  av_log(c->fc, AV_LOG_ERROR, "Track %d, edit %d: Invalid edit list media time=%"PRId64"\n",
6299  c->fc->nb_streams-1, i, e->time);
6300  return AVERROR_INVALIDDATA;
6301  }
6302  if (e->duration < 0) {
6303  av_log(c->fc, AV_LOG_ERROR, "Track %d, edit %d: Invalid edit list duration=%"PRId64"\n",
6304  c->fc->nb_streams-1, i, e->duration);
6305  return AVERROR_INVALIDDATA;
6306  }
6307  }
6308  sc->elst_count = i;
6309 
6310  return 0;
6311 }
6312 
6314 {
6315  MOVStreamContext *sc;
6316 
6317  if (c->fc->nb_streams < 1)
6318  return AVERROR_INVALIDDATA;
6319  sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
6320  sc->timecode_track = avio_rb32(pb);
6321  return 0;
6322 }
6323 
6325 {
6326  AVStream *st;
6327  int version, color_range, color_primaries, color_trc, color_space;
6328 
6329  if (c->fc->nb_streams < 1)
6330  return 0;
6331  st = c->fc->streams[c->fc->nb_streams - 1];
6332 
6333  if (atom.size < 5) {
6334  av_log(c->fc, AV_LOG_ERROR, "Empty VP Codec Configuration box\n");
6335  return AVERROR_INVALIDDATA;
6336  }
6337 
6338  version = avio_r8(pb);
6339  if (version != 1) {
6340  av_log(c->fc, AV_LOG_WARNING, "Unsupported VP Codec Configuration box version %d\n", version);
6341  return 0;
6342  }
6343  avio_skip(pb, 3); /* flags */
6344 
6345  avio_skip(pb, 2); /* profile + level */
6346  color_range = avio_r8(pb); /* bitDepth, chromaSubsampling, videoFullRangeFlag */
6347  color_primaries = avio_r8(pb);
6348  color_trc = avio_r8(pb);
6349  color_space = avio_r8(pb);
6350  if (avio_rb16(pb)) /* codecIntializationDataSize */
6351  return AVERROR_INVALIDDATA;
6352 
6355  if (!av_color_transfer_name(color_trc))
6356  color_trc = AVCOL_TRC_UNSPECIFIED;
6357  if (!av_color_space_name(color_space))
6358  color_space = AVCOL_SPC_UNSPECIFIED;
6359 
6362  st->codecpar->color_trc = color_trc;
6363  st->codecpar->color_space = color_space;
6364 
6365  return 0;
6366 }
6367 
6369 {
6370  MOVStreamContext *sc;
6371  int i, version;
6372 
6373  if (c->fc->nb_streams < 1)
6374  return AVERROR_INVALIDDATA;
6375 
6376  sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
6377 
6378  if (atom.size < 5) {
6379  av_log(c->fc, AV_LOG_ERROR, "Empty Mastering Display Metadata box\n");
6380  return AVERROR_INVALIDDATA;
6381  }
6382 
6383  version = avio_r8(pb);
6384  if (version) {
6385  av_log(c->fc, AV_LOG_WARNING, "Unsupported Mastering Display Metadata box version %d\n", version);
6386  return 0;
6387  }
6388  if (sc->mastering) {
6389  av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicate Mastering Display Metadata\n");
6390  return 0;
6391  }
6392 
6393  avio_skip(pb, 3); /* flags */
6394 
6396  if (!sc->mastering)
6397  return AVERROR(ENOMEM);
6398 
6399  for (i = 0; i < 3; i++) {
6400  sc->mastering->display_primaries[i][0] = av_make_q(avio_rb16(pb), 1 << 16);
6401  sc->mastering->display_primaries[i][1] = av_make_q(avio_rb16(pb), 1 << 16);
6402  }
6403  sc->mastering->white_point[0] = av_make_q(avio_rb16(pb), 1 << 16);
6404  sc->mastering->white_point[1] = av_make_q(avio_rb16(pb), 1 << 16);
6405 
6406  sc->mastering->max_luminance = av_make_q(avio_rb32(pb), 1 << 8);
6407  sc->mastering->min_luminance = av_make_q(avio_rb32(pb), 1 << 14);
6408 
6409  sc->mastering->has_primaries = 1;
6410  sc->mastering->has_luminance = 1;
6411 
6412  return 0;
6413 }
6414 
6416 {
6417  MOVStreamContext *sc;
6418  const int mapping[3] = {1, 2, 0};
6419  const int chroma_den = 50000;
6420  const int luma_den = 10000;
6421  int i;
6422 
6423  if (c->fc->nb_streams < 1)
6424  return AVERROR_INVALIDDATA;
6425 
6426  sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
6427 
6428  if (atom.size < 24) {
6429  av_log(c->fc, AV_LOG_ERROR, "Invalid Mastering Display Color Volume box\n");
6430  return AVERROR_INVALIDDATA;
6431  }
6432 
6433  if (sc->mastering) {
6434  av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicate Mastering Display Color Volume\n");
6435  return 0;
6436  }
6437 
6439  if (!sc->mastering)
6440  return AVERROR(ENOMEM);
6441 
6442  for (i = 0; i < 3; i++) {
6443  const int j = mapping[i];
6444  sc->mastering->display_primaries[j][0] = av_make_q(avio_rb16(pb), chroma_den);
6445  sc->mastering->display_primaries[j][1] = av_make_q(avio_rb16(pb), chroma_den);
6446  }
6447  sc->mastering->white_point[0] = av_make_q(avio_rb16(pb), chroma_den);
6448  sc->mastering->white_point[1] = av_make_q(avio_rb16(pb), chroma_den);
6449 
6450  sc->mastering->max_luminance = av_make_q(avio_rb32(pb), luma_den);
6451  sc->mastering->min_luminance = av_make_q(avio_rb32(pb), luma_den);
6452 
6453  sc->mastering->has_luminance = 1;
6454  sc->mastering->has_primaries = 1;
6455 
6456  return 0;
6457 }
6458 
6460 {
6461  MOVStreamContext *sc;
6462  int version;
6463 
6464  if (c->fc->nb_streams < 1)
6465  return AVERROR_INVALIDDATA;
6466 
6467  sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
6468 
6469  if (atom.size < 5) {
6470  av_log(c->fc, AV_LOG_ERROR, "Empty Content Light Level box\n");
6471  return AVERROR_INVALIDDATA;
6472  }
6473 
6474  version = avio_r8(pb);
6475  if (version) {
6476  av_log(c->fc, AV_LOG_WARNING, "Unsupported Content Light Level box version %d\n", version);
6477  return 0;
6478  }
6479  avio_skip(pb, 3); /* flags */
6480 
6481  if (sc->coll){
6482  av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicate COLL\n");
6483  return 0;
6484  }
6485 
6487  if (!sc->coll)
6488  return AVERROR(ENOMEM);
6489 
6490  sc->coll->MaxCLL = avio_rb16(pb);
6491  sc->coll->MaxFALL = avio_rb16(pb);
6492 
6493  return 0;
6494 }
6495 
6497 {
6498  MOVStreamContext *sc;
6499 
6500  if (c->fc->nb_streams < 1)
6501  return AVERROR_INVALIDDATA;
6502 
6503  sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
6504 
6505  if (atom.size < 4) {
6506  av_log(c->fc, AV_LOG_ERROR, "Empty Content Light Level Info box\n");
6507  return AVERROR_INVALIDDATA;
6508  }
6509 
6510  if (sc->coll){
6511  av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicate CLLI/COLL\n");
6512  return 0;
6513  }
6514 
6516  if (!sc->coll)
6517  return AVERROR(ENOMEM);
6518 
6519  sc->coll->MaxCLL = avio_rb16(pb);
6520  sc->coll->MaxFALL = avio_rb16(pb);
6521 
6522  return 0;
6523 }
6524 
6526 {
6527  MOVStreamContext *sc;
6528  const int illuminance_den = 10000;
6529  const int ambient_den = 50000;
6530  if (c->fc->nb_streams < 1)
6531  return AVERROR_INVALIDDATA;
6532  sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
6533  if (atom.size < 6) {
6534  av_log(c->fc, AV_LOG_ERROR, "Empty Ambient Viewing Environment Info box\n");
6535  return AVERROR_INVALIDDATA;
6536  }
6537  if (sc->ambient){
6538  av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicate AMVE\n");
6539  return 0;
6540  }
6542  if (!sc->ambient)
6543  return AVERROR(ENOMEM);
6544  sc->ambient->ambient_illuminance = av_make_q(avio_rb32(pb), illuminance_den);
6545  sc->ambient->ambient_light_x = av_make_q(avio_rb16(pb), ambient_den);
6546  sc->ambient->ambient_light_y = av_make_q(avio_rb16(pb), ambient_den);
6547  return 0;
6548 }
6549 
6551 {
6552  AVStream *st;
6553  MOVStreamContext *sc;
6554  enum AVStereo3DType type;
6555  int mode;
6556 
6557  if (c->fc->nb_streams < 1)
6558  return 0;
6559 
6560  st = c->fc->streams[c->fc->nb_streams - 1];
6561  sc = st->priv_data;
6562 
6563  if (atom.size < 5) {
6564  av_log(c->fc, AV_LOG_ERROR, "Empty stereoscopic video box\n");
6565  return AVERROR_INVALIDDATA;
6566  }
6567 
6568  if (sc->stereo3d)
6569  return AVERROR_INVALIDDATA;
6570 
6571  avio_skip(pb, 4); /* version + flags */
6572 
6573  mode = avio_r8(pb);
6574  switch (mode) {
6575  case 0:
6576  type = AV_STEREO3D_2D;
6577  break;
6578  case 1:
6580  break;
6581  case 2:
6583  break;
6584  default:
6585  av_log(c->fc, AV_LOG_WARNING, "Unknown st3d mode value %d\n", mode);
6586  return 0;
6587  }
6588 
6590  if (!sc->stereo3d)
6591  return AVERROR(ENOMEM);
6592 
6593  sc->stereo3d->type = type;
6594  return 0;
6595 }
6596 
6598 {
6599  AVStream *st;
6600  MOVStreamContext *sc;
6601  int size = 0;
6602  int64_t remaining;
6603  uint32_t tag = 0;
6605 
6606  if (c->fc->nb_streams < 1)
6607  return 0;
6608 
6609  st = c->fc->streams[c->fc->nb_streams - 1];
6610  sc = st->priv_data;
6611 
6612  remaining = atom.size;
6613  while (remaining > 0) {
6614  size = avio_rb32(pb);
6615  if (size < 8 || size > remaining ) {
6616  av_log(c->fc, AV_LOG_ERROR, "Invalid child size in pack box\n");
6617  return AVERROR_INVALIDDATA;
6618  }
6619 
6620  tag = avio_rl32(pb);
6621  switch (tag) {
6622  case MKTAG('p','k','i','n'): {
6623  if (size != 16) {
6624  av_log(c->fc, AV_LOG_ERROR, "Invalid size of pkin box: %d\n", size);
6625  return AVERROR_INVALIDDATA;
6626  }
6627  avio_skip(pb, 1); // version
6628  avio_skip(pb, 3); // flags
6629 
6630  tag = avio_rl32(pb);
6631  switch (tag) {
6632  case MKTAG('s','i','d','e'):
6634  break;
6635  case MKTAG('o','v','e','r'):
6637  break;
6638  case 0:
6639  // This means value will be set in another layer
6640  break;
6641  default:
6642  av_log(c->fc, AV_LOG_WARNING, "Unknown tag in pkin: 0x%08X\n", tag);
6643  avio_skip(pb, size - 8);
6644  break;
6645  }
6646 
6647  break;
6648  }
6649  default:
6650  av_log(c->fc, AV_LOG_WARNING, "Unknown tag in pack: 0x%08X\n", tag);
6651  avio_skip(pb, size - 8);
6652  break;
6653  }
6654  remaining -= size;
6655  }
6656 
6657  if (remaining != 0) {
6658  av_log(c->fc, AV_LOG_ERROR, "Broken pack box\n");
6659  return AVERROR_INVALIDDATA;
6660  }
6661 
6662  if (type == AV_STEREO3D_2D)
6663  return 0;
6664 
6665  if (!sc->stereo3d) {
6667  if (!sc->stereo3d)
6668  return AVERROR(ENOMEM);
6669  }
6670 
6671  sc->stereo3d->type = type;
6672 
6673  return 0;
6674 }
6675 
6677 {
6678  AVStream *st;
6679  MOVStreamContext *sc;
6680  int size, version, layout;
6681  int32_t yaw, pitch, roll;
6682  uint32_t l = 0, t = 0, r = 0, b = 0;
6683  uint32_t tag, padding = 0;
6684  enum AVSphericalProjection projection;
6685 
6686  if (c->fc->nb_streams < 1)
6687  return 0;
6688 
6689  st = c->fc->streams[c->fc->nb_streams - 1];
6690  sc = st->priv_data;
6691 
6692  if (atom.size < 8) {
6693  av_log(c->fc, AV_LOG_ERROR, "Empty spherical video box\n");
6694  return AVERROR_INVALIDDATA;
6695  }
6696 
6697  size = avio_rb32(pb);
6698  if (size <= 12 || size > atom.size)
6699  return AVERROR_INVALIDDATA;
6700 
6701  tag = avio_rl32(pb);
6702  if (tag != MKTAG('s','v','h','d')) {
6703  av_log(c->fc, AV_LOG_ERROR, "Missing spherical video header\n");
6704  return 0;
6705  }
6706  version = avio_r8(pb);
6707  if (version != 0) {
6708  av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
6709  version);
6710  return 0;
6711  }
6712  avio_skip(pb, 3); /* flags */
6713  avio_skip(pb, size - 12); /* metadata_source */
6714 
6715  size = avio_rb32(pb);
6716  if (size > atom.size)
6717  return AVERROR_INVALIDDATA;
6718 
6719  tag = avio_rl32(pb);
6720  if (tag != MKTAG('p','r','o','j')) {
6721  av_log(c->fc, AV_LOG_ERROR, "Missing projection box\n");
6722  return 0;
6723  }
6724 
6725  size = avio_rb32(pb);
6726  if (size > atom.size)
6727  return AVERROR_INVALIDDATA;
6728 
6729  tag = avio_rl32(pb);
6730  if (tag != MKTAG('p','r','h','d')) {
6731  av_log(c->fc, AV_LOG_ERROR, "Missing projection header box\n");
6732  return 0;
6733  }
6734  version = avio_r8(pb);
6735  if (version != 0) {
6736  av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
6737  version);
6738  return 0;
6739  }
6740  avio_skip(pb, 3); /* flags */
6741 
6742  /* 16.16 fixed point */
6743  yaw = avio_rb32(pb);
6744  pitch = avio_rb32(pb);
6745  roll = avio_rb32(pb);
6746 
6747  size = avio_rb32(pb);
6748  if (size > atom.size)
6749  return AVERROR_INVALIDDATA;
6750 
6751  tag = avio_rl32(pb);
6752  version = avio_r8(pb);
6753  if (version != 0) {
6754  av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
6755  version);
6756  return 0;
6757  }
6758  avio_skip(pb, 3); /* flags */
6759  switch (tag) {
6760  case MKTAG('c','b','m','p'):
6761  layout = avio_rb32(pb);
6762  if (layout) {
6763  av_log(c->fc, AV_LOG_WARNING,
6764  "Unsupported cubemap layout %d\n", layout);
6765  return 0;
6766  }
6767  projection = AV_SPHERICAL_CUBEMAP;
6768  padding = avio_rb32(pb);
6769  break;
6770  case MKTAG('e','q','u','i'):
6771  t = avio_rb32(pb);
6772  b = avio_rb32(pb);
6773  l = avio_rb32(pb);
6774  r = avio_rb32(pb);
6775 
6776  if (b >= UINT_MAX - t || r >= UINT_MAX - l) {
6777  av_log(c->fc, AV_LOG_ERROR,
6778  "Invalid bounding rectangle coordinates "
6779  "%"PRIu32",%"PRIu32",%"PRIu32",%"PRIu32"\n", l, t, r, b);
6780  return AVERROR_INVALIDDATA;
6781  }
6782 
6783  if (l || t || r || b)
6784  projection = AV_SPHERICAL_EQUIRECTANGULAR_TILE;
6785  else
6786  projection = AV_SPHERICAL_EQUIRECTANGULAR;
6787  break;
6788  default:
6789  av_log(c->fc, AV_LOG_ERROR, "Unknown projection type: %s\n", av_fourcc2str(tag));
6790  return 0;
6791  }
6792 
6794  if (!sc->spherical)
6795  return AVERROR(ENOMEM);
6796 
6797  sc->spherical->projection = projection;
6798 
6799  sc->spherical->yaw = yaw;
6800  sc->spherical->pitch = pitch;
6801  sc->spherical->roll = roll;
6802 
6803  sc->spherical->padding = padding;
6804 
6805  sc->spherical->bound_left = l;
6806  sc->spherical->bound_top = t;
6807  sc->spherical->bound_right = r;
6808  sc->spherical->bound_bottom = b;
6809 
6810  return 0;
6811 }
6812 
6814 {
6815  AVStream *st;
6816  MOVStreamContext *sc;
6817  int size;
6818  uint32_t tag;
6819  enum AVSphericalProjection projection;
6820 
6821  if (c->fc->nb_streams < 1)
6822  return 0;
6823 
6824  st = c->fc->streams[c->fc->nb_streams - 1];
6825  sc = st->priv_data;
6826 
6827  if (atom.size != 16) {
6828  av_log(c->fc, AV_LOG_ERROR, "Invalid size for proj box: %"PRIu64"\n", atom.size);
6829  return AVERROR_INVALIDDATA;
6830  }
6831 
6832  size = avio_rb32(pb);
6833  if (size != 16) {
6834  av_log(c->fc, AV_LOG_ERROR, "Invalid size for prji box: %d\n", size);
6835  return AVERROR_INVALIDDATA;
6836  }
6837 
6838  tag = avio_rl32(pb);
6839  if (tag != MKTAG('p','r','j','i')) {
6840  av_log(c->fc, AV_LOG_ERROR, "Invalid child box of proj box: 0x%08X\n", tag);
6841  return AVERROR_INVALIDDATA;
6842  }
6843 
6844  avio_skip(pb, 1); // version
6845  avio_skip(pb, 3); // flags
6846 
6847  tag = avio_rl32(pb);
6848  switch (tag) {
6849  case MKTAG('r','e','c','t'):
6850  projection = AV_SPHERICAL_RECTILINEAR;
6851  break;
6852  case MKTAG('e','q','u','i'):
6853  projection = AV_SPHERICAL_EQUIRECTANGULAR;
6854  break;
6855  case MKTAG('h','e','q','u'):
6856  projection = AV_SPHERICAL_HALF_EQUIRECTANGULAR;
6857  break;
6858  case MKTAG('f','i','s','h'):
6859  projection = AV_SPHERICAL_FISHEYE;
6860  break;
6861  case MKTAG('p','r','i','m'):
6862  projection = AV_SPHERICAL_PARAMETRIC_IMMERSIVE;
6863  break;
6864  default:
6865  av_log(c->fc, AV_LOG_ERROR, "Invalid projection type in prji box: 0x%08X\n", tag);
6866  return AVERROR_INVALIDDATA;
6867  }
6868 
6870  if (!sc->spherical)
6871  return AVERROR(ENOMEM);
6872 
6873  sc->spherical->projection = projection;
6874 
6875  return 0;
6876 }
6877 
6879 {
6880  AVStream *st;
6881  MOVStreamContext *sc;
6882  int size, flags = 0;
6883  int64_t remaining;
6884  uint32_t tag, baseline = 0;
6887  enum AVStereo3DPrimaryEye primary_eye = AV_PRIMARY_EYE_NONE;
6888  AVRational horizontal_disparity_adjustment = { 0, 1 };
6889 
6890  if (c->fc->nb_streams < 1)
6891  return 0;
6892 
6893  st = c->fc->streams[c->fc->nb_streams - 1];
6894  sc = st->priv_data;
6895 
6896  remaining = atom.size;
6897  while (remaining > 0) {
6898  size = avio_rb32(pb);
6899  if (size < 8 || size > remaining ) {
6900  av_log(c->fc, AV_LOG_ERROR, "Invalid child size in eyes box\n");
6901  return AVERROR_INVALIDDATA;
6902  }
6903 
6904  tag = avio_rl32(pb);
6905  switch (tag) {
6906  case MKTAG('s','t','r','i'): {
6907  int has_right, has_left;
6908  uint8_t tmp;
6909  if (size != 13) {
6910  av_log(c->fc, AV_LOG_ERROR, "Invalid size of stri box: %d\n", size);
6911  return AVERROR_INVALIDDATA;
6912  }
6913  avio_skip(pb, 1); // version
6914  avio_skip(pb, 3); // flags
6915 
6916  tmp = avio_r8(pb);
6917 
6918  // eye_views_reversed
6919  if (tmp & 8) {
6921  }
6922  // has_additional_views
6923  if (tmp & 4) {
6924  // skip...
6925  }
6926 
6927  has_right = tmp & 2; // has_right_eye_view
6928  has_left = tmp & 1; // has_left_eye_view
6929 
6930  if (has_left && has_right)
6931  view = AV_STEREO3D_VIEW_PACKED;
6932  else if (has_left)
6933  view = AV_STEREO3D_VIEW_LEFT;
6934  else if (has_right)
6935  view = AV_STEREO3D_VIEW_RIGHT;
6936  if (has_left || has_right)
6938 
6939  break;
6940  }
6941  case MKTAG('h','e','r','o'): {
6942  int tmp;
6943  if (size != 13) {
6944  av_log(c->fc, AV_LOG_ERROR, "Invalid size of hero box: %d\n", size);
6945  return AVERROR_INVALIDDATA;
6946  }
6947  avio_skip(pb, 1); // version
6948  avio_skip(pb, 3); // flags
6949 
6950  tmp = avio_r8(pb);
6951  if (tmp == 0)
6952  primary_eye = AV_PRIMARY_EYE_NONE;
6953  else if (tmp == 1)
6954  primary_eye = AV_PRIMARY_EYE_LEFT;
6955  else if (tmp == 2)
6956  primary_eye = AV_PRIMARY_EYE_RIGHT;
6957  else
6958  av_log(c->fc, AV_LOG_WARNING, "Unknown hero eye type: %d\n", tmp);
6959 
6960  break;
6961  }
6962  case MKTAG('c','a','m','s'): {
6963  uint32_t subtag;
6964  int subsize;
6965  if (size != 24) {
6966  av_log(c->fc, AV_LOG_ERROR, "Invalid size of cams box: %d\n", size);
6967  return AVERROR_INVALIDDATA;
6968  }
6969 
6970  subsize = avio_rb32(pb);
6971  if (subsize != 16) {
6972  av_log(c->fc, AV_LOG_ERROR, "Invalid size of blin box: %d\n", size);
6973  return AVERROR_INVALIDDATA;
6974  }
6975 
6976  subtag = avio_rl32(pb);
6977  if (subtag != MKTAG('b','l','i','n')) {
6978  av_log(c->fc, AV_LOG_ERROR, "Expected blin box, got 0x%08X\n", subtag);
6979  return AVERROR_INVALIDDATA;
6980  }
6981 
6982  avio_skip(pb, 1); // version
6983  avio_skip(pb, 3); // flags
6984 
6985  baseline = avio_rb32(pb);
6986 
6987  break;
6988  }
6989  case MKTAG('c','m','f','y'): {
6990  uint32_t subtag;
6991  int subsize;
6992  int32_t adjustment;
6993  if (size != 24) {
6994  av_log(c->fc, AV_LOG_ERROR, "Invalid size of cmfy box: %d\n", size);
6995  return AVERROR_INVALIDDATA;
6996  }
6997 
6998  subsize = avio_rb32(pb);
6999  if (subsize != 16) {
7000  av_log(c->fc, AV_LOG_ERROR, "Invalid size of dadj box: %d\n", size);
7001  return AVERROR_INVALIDDATA;
7002  }
7003 
7004  subtag = avio_rl32(pb);
7005  if (subtag != MKTAG('d','a','d','j')) {
7006  av_log(c->fc, AV_LOG_ERROR, "Expected dadj box, got 0x%08X\n", subtag);
7007  return AVERROR_INVALIDDATA;
7008  }
7009 
7010  avio_skip(pb, 1); // version
7011  avio_skip(pb, 3); // flags
7012 
7013  adjustment = (int32_t) avio_rb32(pb);
7014 
7015  horizontal_disparity_adjustment.num = (int) adjustment;
7016  horizontal_disparity_adjustment.den = 10000;
7017 
7018  break;
7019  }
7020  default:
7021  av_log(c->fc, AV_LOG_WARNING, "Unknown tag in eyes: 0x%08X\n", tag);
7022  avio_skip(pb, size - 8);
7023  break;
7024  }
7025  remaining -= size;
7026  }
7027 
7028  if (remaining != 0) {
7029  av_log(c->fc, AV_LOG_ERROR, "Broken eyes box\n");
7030  return AVERROR_INVALIDDATA;
7031  }
7032 
7033  if (type == AV_STEREO3D_2D)
7034  return 0;
7035 
7036  if (!sc->stereo3d) {
7038  if (!sc->stereo3d)
7039  return AVERROR(ENOMEM);
7040  }
7041 
7042  sc->stereo3d->flags = flags;
7043  sc->stereo3d->type = type;
7044  sc->stereo3d->view = view;
7045  sc->stereo3d->primary_eye = primary_eye;
7046  sc->stereo3d->baseline = baseline;
7047  sc->stereo3d->horizontal_disparity_adjustment = horizontal_disparity_adjustment;
7048 
7049  return 0;
7050 }
7051 
7053 {
7054  int size;
7055  int64_t remaining;
7056  uint32_t tag;
7057 
7058  if (c->fc->nb_streams < 1)
7059  return 0;
7060 
7061  if (atom.size < 8) {
7062  av_log(c->fc, AV_LOG_ERROR, "Empty video extension usage box\n");
7063  return AVERROR_INVALIDDATA;
7064  }
7065 
7066  remaining = atom.size;
7067  while (remaining > 0) {
7068  size = avio_rb32(pb);
7069  if (size < 8 || size > remaining ) {
7070  av_log(c->fc, AV_LOG_ERROR, "Invalid child size in vexu box\n");
7071  return AVERROR_INVALIDDATA;
7072  }
7073 
7074  tag = avio_rl32(pb);
7075  switch (tag) {
7076  case MKTAG('p','r','o','j'): {
7077  MOVAtom proj = { tag, size - 8 };
7078  int ret = mov_read_vexu_proj(c, pb, proj);
7079  if (ret < 0)
7080  return ret;
7081  break;
7082  }
7083  case MKTAG('e','y','e','s'): {
7084  MOVAtom eyes = { tag, size - 8 };
7085  int ret = mov_read_eyes(c, pb, eyes);
7086  if (ret < 0)
7087  return ret;
7088  break;
7089  }
7090  case MKTAG('p','a','c','k'): {
7091  MOVAtom pack = { tag, size - 8 };
7092  int ret = mov_read_pack(c, pb, pack);
7093  if (ret < 0)
7094  return ret;
7095  break;
7096  }
7097  default:
7098  av_log(c->fc, AV_LOG_WARNING, "Unknown tag in vexu: 0x%08X\n", tag);
7099  avio_skip(pb, size - 8);
7100  break;
7101  }
7102  remaining -= size;
7103  }
7104 
7105  if (remaining != 0) {
7106  av_log(c->fc, AV_LOG_ERROR, "Broken vexu box\n");
7107  return AVERROR_INVALIDDATA;
7108  }
7109 
7110  return 0;
7111 }
7112 
7114 {
7115  AVStream *st;
7116  MOVStreamContext *sc;
7117 
7118  if (c->fc->nb_streams < 1)
7119  return 0;
7120 
7121  st = c->fc->streams[c->fc->nb_streams - 1];
7122  sc = st->priv_data;
7123 
7124  if (atom.size != 4) {
7125  av_log(c->fc, AV_LOG_ERROR, "Invalid size of hfov box: %"PRIu64"\n", atom.size);
7126  return AVERROR_INVALIDDATA;
7127  }
7128 
7129 
7130  if (!sc->stereo3d) {
7132  if (!sc->stereo3d)
7133  return AVERROR(ENOMEM);
7134  }
7135 
7137  sc->stereo3d->horizontal_field_of_view.den = 1000; // thousands of a degree
7138 
7139  return 0;
7140 }
7141 
7143 {
7144  int ret = 0;
7145  uint8_t *buffer = av_malloc(len + 1);
7146  const char *val;
7147 
7148  if (!buffer)
7149  return AVERROR(ENOMEM);
7150  buffer[len] = '\0';
7151 
7152  ret = ffio_read_size(pb, buffer, len);
7153  if (ret < 0)
7154  goto out;
7155 
7156  /* Check for mandatory keys and values, try to support XML as best-effort */
7157  if (!sc->spherical &&
7158  av_stristr(buffer, "<GSpherical:StitchingSoftware>") &&
7159  (val = av_stristr(buffer, "<GSpherical:Spherical>")) &&
7160  av_stristr(val, "true") &&
7161  (val = av_stristr(buffer, "<GSpherical:Stitched>")) &&
7162  av_stristr(val, "true") &&
7163  (val = av_stristr(buffer, "<GSpherical:ProjectionType>")) &&
7164  av_stristr(val, "equirectangular")) {
7166  if (!sc->spherical)
7167  goto out;
7168 
7170 
7171  if (av_stristr(buffer, "<GSpherical:StereoMode>") && !sc->stereo3d) {
7172  enum AVStereo3DType mode;
7173 
7174  if (av_stristr(buffer, "left-right"))
7176  else if (av_stristr(buffer, "top-bottom"))
7178  else
7179  mode = AV_STEREO3D_2D;
7180 
7182  if (!sc->stereo3d)
7183  goto out;
7184 
7185  sc->stereo3d->type = mode;
7186  }
7187 
7188  /* orientation */
7189  val = av_stristr(buffer, "<GSpherical:InitialViewHeadingDegrees>");
7190  if (val)
7191  sc->spherical->yaw = strtol(val, NULL, 10) * (1 << 16);
7192  val = av_stristr(buffer, "<GSpherical:InitialViewPitchDegrees>");
7193  if (val)
7194  sc->spherical->pitch = strtol(val, NULL, 10) * (1 << 16);
7195  val = av_stristr(buffer, "<GSpherical:InitialViewRollDegrees>");
7196  if (val)
7197  sc->spherical->roll = strtol(val, NULL, 10) * (1 << 16);
7198  }
7199 
7200 out:
7201  av_free(buffer);
7202  return ret;
7203 }
7204 
7206 {
7207  AVStream *st;
7208  MOVStreamContext *sc;
7209  int64_t ret;
7210  AVUUID uuid;
7211  static const AVUUID uuid_isml_manifest = {
7212  0xa5, 0xd4, 0x0b, 0x30, 0xe8, 0x14, 0x11, 0xdd,
7213  0xba, 0x2f, 0x08, 0x00, 0x20, 0x0c, 0x9a, 0x66
7214  };
7215  static const AVUUID uuid_xmp = {
7216  0xbe, 0x7a, 0xcf, 0xcb, 0x97, 0xa9, 0x42, 0xe8,
7217  0x9c, 0x71, 0x99, 0x94, 0x91, 0xe3, 0xaf, 0xac
7218  };
7219  static const AVUUID uuid_spherical = {
7220  0xff, 0xcc, 0x82, 0x63, 0xf8, 0x55, 0x4a, 0x93,
7221  0x88, 0x14, 0x58, 0x7a, 0x02, 0x52, 0x1f, 0xdd,
7222  };
7223 
7224  if (atom.size < AV_UUID_LEN || atom.size >= FFMIN(INT_MAX, SIZE_MAX))
7225  return AVERROR_INVALIDDATA;
7226 
7227  if (c->fc->nb_streams < 1)
7228  return 0;
7229  st = c->fc->streams[c->fc->nb_streams - 1];
7230  sc = st->priv_data;
7231 
7232  ret = ffio_read_size(pb, uuid, AV_UUID_LEN);
7233  if (ret < 0)
7234  return ret;
7235  if (av_uuid_equal(uuid, uuid_isml_manifest)) {
7236  uint8_t *buffer, *ptr;
7237  char *endptr;
7238  size_t len = atom.size - AV_UUID_LEN;
7239 
7240  if (len < 4) {
7241  return AVERROR_INVALIDDATA;
7242  }
7243  ret = avio_skip(pb, 4); // zeroes
7244  len -= 4;
7245 
7246  buffer = av_mallocz(len + 1);
7247  if (!buffer) {
7248  return AVERROR(ENOMEM);
7249  }
7250  ret = ffio_read_size(pb, buffer, len);
7251  if (ret < 0) {
7252  av_free(buffer);
7253  return ret;
7254  }
7255 
7256  ptr = buffer;
7257  while ((ptr = av_stristr(ptr, "systemBitrate=\""))) {
7258  ptr += sizeof("systemBitrate=\"") - 1;
7259  c->bitrates_count++;
7260  c->bitrates = av_realloc_f(c->bitrates, c->bitrates_count, sizeof(*c->bitrates));
7261  if (!c->bitrates) {
7262  c->bitrates_count = 0;
7263  av_free(buffer);
7264  return AVERROR(ENOMEM);
7265  }
7266  errno = 0;
7267  ret = strtol(ptr, &endptr, 10);
7268  if (ret < 0 || errno || *endptr != '"') {
7269  c->bitrates[c->bitrates_count - 1] = 0;
7270  } else {
7271  c->bitrates[c->bitrates_count - 1] = ret;
7272  }
7273  }
7274 
7275  av_free(buffer);
7276  } else if (av_uuid_equal(uuid, uuid_xmp)) {
7277  uint8_t *buffer;
7278  size_t len = atom.size - AV_UUID_LEN;
7279  if (c->export_xmp) {
7280  buffer = av_mallocz(len + 1);
7281  if (!buffer) {
7282  return AVERROR(ENOMEM);
7283  }
7284  ret = ffio_read_size(pb, buffer, len);
7285  if (ret < 0) {
7286  av_free(buffer);
7287  return ret;
7288  }
7289  buffer[len] = '\0';
7290  av_dict_set(&c->fc->metadata, "xmp",
7292  } else {
7293  // skip all uuid atom, which makes it fast for long uuid-xmp file
7294  ret = avio_skip(pb, len);
7295  if (ret < 0)
7296  return ret;
7297  }
7298  } else if (av_uuid_equal(uuid, uuid_spherical)) {
7299  size_t len = atom.size - AV_UUID_LEN;
7300  ret = mov_parse_uuid_spherical(sc, pb, len);
7301  if (ret < 0)
7302  return ret;
7303  if (!sc->spherical)
7304  av_log(c->fc, AV_LOG_WARNING, "Invalid spherical metadata found\n");
7305  }
7306 
7307  return 0;
7308 }
7309 
7311 {
7312  int ret;
7313  uint8_t content[16];
7314 
7315  if (atom.size < 8)
7316  return 0;
7317 
7318  ret = ffio_read_size(pb, content, FFMIN(sizeof(content), atom.size));
7319  if (ret < 0)
7320  return ret;
7321 
7322  if ( !c->found_moov
7323  && !c->found_mdat
7324  && !memcmp(content, "Anevia\x1A\x1A", 8)
7325  && c->use_mfra_for == FF_MOV_FLAG_MFRA_AUTO) {
7326  c->use_mfra_for = FF_MOV_FLAG_MFRA_PTS;
7327  }
7328 
7329  return 0;
7330 }
7331 
7333 {
7334  uint32_t format = avio_rl32(pb);
7335  MOVStreamContext *sc;
7336  enum AVCodecID id;
7337  AVStream *st;
7338 
7339  if (c->fc->nb_streams < 1)
7340  return 0;
7341  st = c->fc->streams[c->fc->nb_streams - 1];
7342  sc = st->priv_data;
7343 
7344  switch (sc->format)
7345  {
7346  case MKTAG('e','n','c','v'): // encrypted video
7347  case MKTAG('e','n','c','a'): // encrypted audio
7348  id = mov_codec_id(st, format);
7349  if (st->codecpar->codec_id != AV_CODEC_ID_NONE &&
7350  st->codecpar->codec_id != id) {
7351  av_log(c->fc, AV_LOG_WARNING,
7352  "ignoring 'frma' atom of '%.4s', stream has codec id %d\n",
7353  (char*)&format, st->codecpar->codec_id);
7354  break;
7355  }
7356 
7357  st->codecpar->codec_id = id;
7358  sc->format = format;
7359  break;
7360 
7361  default:
7362  if (format != sc->format) {
7363  av_log(c->fc, AV_LOG_WARNING,
7364  "ignoring 'frma' atom of '%.4s', stream format is '%.4s'\n",
7365  (char*)&format, (char*)&sc->format);
7366  }
7367  break;
7368  }
7369 
7370  return 0;
7371 }
7372 
7373 /**
7374  * Gets the current encryption info and associated current stream context. If
7375  * we are parsing a track fragment, this will return the specific encryption
7376  * info for this fragment; otherwise this will return the global encryption
7377  * info for the current stream.
7378  */
7380 {
7381  MOVFragmentStreamInfo *frag_stream_info;
7382  AVStream *st;
7383  int i;
7384 
7385  frag_stream_info = get_current_frag_stream_info(&c->frag_index);
7386  if (frag_stream_info) {
7387  for (i = 0; i < c->fc->nb_streams; i++) {
7388  *sc = c->fc->streams[i]->priv_data;
7389  if ((*sc)->id == frag_stream_info->id) {
7390  st = c->fc->streams[i];
7391  break;
7392  }
7393  }
7394  if (i == c->fc->nb_streams)
7395  return 0;
7396  *sc = st->priv_data;
7397 
7398  if (!frag_stream_info->encryption_index) {
7399  // If this stream isn't encrypted, don't create the index.
7400  if (!(*sc)->cenc.default_encrypted_sample)
7401  return 0;
7402  frag_stream_info->encryption_index = av_mallocz(sizeof(*frag_stream_info->encryption_index));
7403  if (!frag_stream_info->encryption_index)
7404  return AVERROR(ENOMEM);
7405  }
7406  *encryption_index = frag_stream_info->encryption_index;
7407  return 1;
7408  } else {
7409  // No current track fragment, using stream level encryption info.
7410 
7411  if (c->fc->nb_streams < 1)
7412  return 0;
7413  st = c->fc->streams[c->fc->nb_streams - 1];
7414  *sc = st->priv_data;
7415 
7416  if (!(*sc)->cenc.encryption_index) {
7417  // If this stream isn't encrypted, don't create the index.
7418  if (!(*sc)->cenc.default_encrypted_sample)
7419  return 0;
7420  (*sc)->cenc.encryption_index = av_mallocz(sizeof(*frag_stream_info->encryption_index));
7421  if (!(*sc)->cenc.encryption_index)
7422  return AVERROR(ENOMEM);
7423  }
7424 
7425  *encryption_index = (*sc)->cenc.encryption_index;
7426  return 1;
7427  }
7428 }
7429 
7431 {
7432  int i, ret;
7433  unsigned int subsample_count;
7434  AVSubsampleEncryptionInfo *subsamples;
7435 
7436  if (!sc->cenc.default_encrypted_sample) {
7437  av_log(c->fc, AV_LOG_ERROR, "Missing schm or tenc\n");
7438  return AVERROR_INVALIDDATA;
7439  }
7440 
7441  if (sc->cenc.per_sample_iv_size || use_subsamples) {
7443  if (!*sample)
7444  return AVERROR(ENOMEM);
7445  } else
7446  *sample = NULL;
7447 
7448  if (sc->cenc.per_sample_iv_size != 0) {
7449  if ((ret = ffio_read_size(pb, (*sample)->iv, sc->cenc.per_sample_iv_size)) < 0) {
7450  av_log(c->fc, AV_LOG_ERROR, "failed to read the initialization vector\n");
7452  *sample = NULL;
7453  return ret;
7454  }
7455  }
7456 
7457  if (use_subsamples) {
7458  subsample_count = avio_rb16(pb);
7459  av_free((*sample)->subsamples);
7460  (*sample)->subsamples = av_calloc(subsample_count, sizeof(*subsamples));
7461  if (!(*sample)->subsamples) {
7463  *sample = NULL;
7464  return AVERROR(ENOMEM);
7465  }
7466 
7467  for (i = 0; i < subsample_count && !pb->eof_reached; i++) {
7468  (*sample)->subsamples[i].bytes_of_clear_data = avio_rb16(pb);
7469  (*sample)->subsamples[i].bytes_of_protected_data = avio_rb32(pb);
7470  }
7471 
7472  if (pb->eof_reached) {
7473  av_log(c->fc, AV_LOG_ERROR, "hit EOF while reading sub-sample encryption info\n");
7475  *sample = NULL;
7476  return AVERROR_INVALIDDATA;
7477  }
7478  (*sample)->subsample_count = subsample_count;
7479  }
7480 
7481  return 0;
7482 }
7483 
7485 {
7486  AVEncryptionInfo **encrypted_samples;
7487  MOVEncryptionIndex *encryption_index;
7488  MOVStreamContext *sc;
7489  int use_subsamples, ret;
7490  unsigned int sample_count, i, alloc_size = 0;
7491 
7492  ret = get_current_encryption_info(c, &encryption_index, &sc);
7493  if (ret != 1)
7494  return ret;
7495 
7496  if (encryption_index->nb_encrypted_samples) {
7497  // This can happen if we have both saio/saiz and senc atoms.
7498  av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in senc\n");
7499  return 0;
7500  }
7501 
7502  avio_r8(pb); /* version */
7503  use_subsamples = avio_rb24(pb) & 0x02; /* flags */
7504 
7505  sample_count = avio_rb32(pb);
7506  if (sample_count >= INT_MAX / sizeof(*encrypted_samples))
7507  return AVERROR(ENOMEM);
7508 
7509  for (i = 0; i < sample_count; i++) {
7510  unsigned int min_samples = FFMIN(FFMAX(i + 1, 1024 * 1024), sample_count);
7511  encrypted_samples = av_fast_realloc(encryption_index->encrypted_samples, &alloc_size,
7512  min_samples * sizeof(*encrypted_samples));
7513  if (encrypted_samples) {
7514  encryption_index->encrypted_samples = encrypted_samples;
7515 
7517  c, pb, sc, &encryption_index->encrypted_samples[i], use_subsamples);
7518  } else {
7519  ret = AVERROR(ENOMEM);
7520  }
7521  if (pb->eof_reached) {
7522  av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading senc\n");
7523  if (ret >= 0)
7524  av_encryption_info_free(encryption_index->encrypted_samples[i]);
7526  }
7527 
7528  if (ret < 0) {
7529  for (; i > 0; i--)
7530  av_encryption_info_free(encryption_index->encrypted_samples[i - 1]);
7531  av_freep(&encryption_index->encrypted_samples);
7532  return ret;
7533  }
7534  }
7535  encryption_index->nb_encrypted_samples = sample_count;
7536 
7537  return 0;
7538 }
7539 
7541 {
7542  AVEncryptionInfo **sample, **encrypted_samples;
7543  int64_t prev_pos;
7544  size_t sample_count, sample_info_size, i;
7545  int ret = 0;
7546  unsigned int alloc_size = 0;
7547 
7548  if (encryption_index->nb_encrypted_samples)
7549  return 0;
7550  sample_count = encryption_index->auxiliary_info_sample_count;
7551  if (encryption_index->auxiliary_offsets_count != 1) {
7552  av_log(c->fc, AV_LOG_ERROR, "Multiple auxiliary info chunks are not supported\n");
7553  return AVERROR_PATCHWELCOME;
7554  }
7555  if (sample_count >= INT_MAX / sizeof(*encrypted_samples))
7556  return AVERROR(ENOMEM);
7557 
7558  prev_pos = avio_tell(pb);
7559  if (!(pb->seekable & AVIO_SEEKABLE_NORMAL) ||
7560  avio_seek(pb, encryption_index->auxiliary_offsets[0], SEEK_SET) != encryption_index->auxiliary_offsets[0]) {
7561  av_log(c->fc, AV_LOG_INFO, "Failed to seek for auxiliary info, will only parse senc atoms for encryption info\n");
7562  goto finish;
7563  }
7564 
7565  for (i = 0; i < sample_count && !pb->eof_reached; i++) {
7566  unsigned int min_samples = FFMIN(FFMAX(i + 1, 1024 * 1024), sample_count);
7567  encrypted_samples = av_fast_realloc(encryption_index->encrypted_samples, &alloc_size,
7568  min_samples * sizeof(*encrypted_samples));
7569  if (!encrypted_samples) {
7570  ret = AVERROR(ENOMEM);
7571  goto finish;
7572  }
7573  encryption_index->encrypted_samples = encrypted_samples;
7574 
7575  sample = &encryption_index->encrypted_samples[i];
7576  sample_info_size = encryption_index->auxiliary_info_default_size
7577  ? encryption_index->auxiliary_info_default_size
7578  : encryption_index->auxiliary_info_sizes[i];
7579 
7580  ret = mov_read_sample_encryption_info(c, pb, sc, sample, sample_info_size > sc->cenc.per_sample_iv_size);
7581  if (ret < 0)
7582  goto finish;
7583  }
7584  if (pb->eof_reached) {
7585  av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading auxiliary info\n");
7587  } else {
7588  encryption_index->nb_encrypted_samples = sample_count;
7589  }
7590 
7591 finish:
7592  avio_seek(pb, prev_pos, SEEK_SET);
7593  if (ret < 0) {
7594  for (; i > 0; i--) {
7595  av_encryption_info_free(encryption_index->encrypted_samples[i - 1]);
7596  }
7597  av_freep(&encryption_index->encrypted_samples);
7598  }
7599  return ret;
7600 }
7601 
7603 {
7604  MOVEncryptionIndex *encryption_index;
7605  MOVStreamContext *sc;
7606  int ret;
7607  unsigned int sample_count, aux_info_type, aux_info_param;
7608 
7609  ret = get_current_encryption_info(c, &encryption_index, &sc);
7610  if (ret != 1)
7611  return ret;
7612 
7613  if (encryption_index->nb_encrypted_samples) {
7614  // This can happen if we have both saio/saiz and senc atoms.
7615  av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in saiz\n");
7616  return 0;
7617  }
7618 
7619  if (encryption_index->auxiliary_info_sample_count) {
7620  av_log(c->fc, AV_LOG_ERROR, "Duplicate saiz atom\n");
7621  return AVERROR_INVALIDDATA;
7622  }
7623 
7624  avio_r8(pb); /* version */
7625  if (avio_rb24(pb) & 0x01) { /* flags */
7626  aux_info_type = avio_rb32(pb);
7627  aux_info_param = avio_rb32(pb);
7628  if (sc->cenc.default_encrypted_sample) {
7629  if (aux_info_type != sc->cenc.default_encrypted_sample->scheme) {
7630  av_log(c->fc, AV_LOG_DEBUG, "Ignoring saiz box with non-zero aux_info_type\n");
7631  return 0;
7632  }
7633  if (aux_info_param != 0) {
7634  av_log(c->fc, AV_LOG_DEBUG, "Ignoring saiz box with non-zero aux_info_type_parameter\n");
7635  return 0;
7636  }
7637  } else {
7638  // Didn't see 'schm' or 'tenc', so this isn't encrypted.
7639  if ((aux_info_type == MKBETAG('c','e','n','c') ||
7640  aux_info_type == MKBETAG('c','e','n','s') ||
7641  aux_info_type == MKBETAG('c','b','c','1') ||
7642  aux_info_type == MKBETAG('c','b','c','s')) &&
7643  aux_info_param == 0) {
7644  av_log(c->fc, AV_LOG_ERROR, "Saw encrypted saiz without schm/tenc\n");
7645  return AVERROR_INVALIDDATA;
7646  } else {
7647  return 0;
7648  }
7649  }
7650  } else if (!sc->cenc.default_encrypted_sample) {
7651  // Didn't see 'schm' or 'tenc', so this isn't encrypted.
7652  return 0;
7653  }
7654 
7655  encryption_index->auxiliary_info_default_size = avio_r8(pb);
7656  sample_count = avio_rb32(pb);
7657 
7658  if (encryption_index->auxiliary_info_default_size == 0) {
7659  if (sample_count == 0)
7660  return AVERROR_INVALIDDATA;
7661 
7662  encryption_index->auxiliary_info_sizes = av_malloc(sample_count);
7663  if (!encryption_index->auxiliary_info_sizes)
7664  return AVERROR(ENOMEM);
7665 
7666  ret = avio_read(pb, encryption_index->auxiliary_info_sizes, sample_count);
7667  if (ret != sample_count) {
7668  av_freep(&encryption_index->auxiliary_info_sizes);
7669 
7670  if (ret >= 0)
7672  av_log(c->fc, AV_LOG_ERROR, "Failed to read the auxiliary info, %s\n",
7673  av_err2str(ret));
7674  return ret;
7675  }
7676  }
7677  encryption_index->auxiliary_info_sample_count = sample_count;
7678 
7679  if (encryption_index->auxiliary_offsets_count) {
7680  return mov_parse_auxiliary_info(c, sc, pb, encryption_index);
7681  }
7682 
7683  return 0;
7684 }
7685 
7687 {
7688  uint64_t *auxiliary_offsets;
7689  MOVEncryptionIndex *encryption_index;
7690  MOVStreamContext *sc;
7691  int i, ret;
7692  unsigned int version, entry_count, aux_info_type, aux_info_param;
7693  unsigned int alloc_size = 0;
7694 
7695  ret = get_current_encryption_info(c, &encryption_index, &sc);
7696  if (ret != 1)
7697  return ret;
7698 
7699  if (encryption_index->nb_encrypted_samples) {
7700  // This can happen if we have both saio/saiz and senc atoms.
7701  av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in saio\n");
7702  return 0;
7703  }
7704 
7705  if (encryption_index->auxiliary_offsets_count) {
7706  av_log(c->fc, AV_LOG_ERROR, "Duplicate saio atom\n");
7707  return AVERROR_INVALIDDATA;
7708  }
7709 
7710  version = avio_r8(pb); /* version */
7711  if (avio_rb24(pb) & 0x01) { /* flags */
7712  aux_info_type = avio_rb32(pb);
7713  aux_info_param = avio_rb32(pb);
7714  if (sc->cenc.default_encrypted_sample) {
7715  if (aux_info_type != sc->cenc.default_encrypted_sample->scheme) {
7716  av_log(c->fc, AV_LOG_DEBUG, "Ignoring saio box with non-zero aux_info_type\n");
7717  return 0;
7718  }
7719  if (aux_info_param != 0) {
7720  av_log(c->fc, AV_LOG_DEBUG, "Ignoring saio box with non-zero aux_info_type_parameter\n");
7721  return 0;
7722  }
7723  } else {
7724  // Didn't see 'schm' or 'tenc', so this isn't encrypted.
7725  if ((aux_info_type == MKBETAG('c','e','n','c') ||
7726  aux_info_type == MKBETAG('c','e','n','s') ||
7727  aux_info_type == MKBETAG('c','b','c','1') ||
7728  aux_info_type == MKBETAG('c','b','c','s')) &&
7729  aux_info_param == 0) {
7730  av_log(c->fc, AV_LOG_ERROR, "Saw encrypted saio without schm/tenc\n");
7731  return AVERROR_INVALIDDATA;
7732  } else {
7733  return 0;
7734  }
7735  }
7736  } else if (!sc->cenc.default_encrypted_sample) {
7737  // Didn't see 'schm' or 'tenc', so this isn't encrypted.
7738  return 0;
7739  }
7740 
7741  entry_count = avio_rb32(pb);
7742  if (entry_count >= INT_MAX / sizeof(*auxiliary_offsets))
7743  return AVERROR(ENOMEM);
7744 
7745  for (i = 0; i < entry_count && !pb->eof_reached; i++) {
7746  unsigned int min_offsets = FFMIN(FFMAX(i + 1, 1024), entry_count);
7747  auxiliary_offsets = av_fast_realloc(
7748  encryption_index->auxiliary_offsets, &alloc_size,
7749  min_offsets * sizeof(*auxiliary_offsets));
7750  if (!auxiliary_offsets) {
7751  av_freep(&encryption_index->auxiliary_offsets);
7752  return AVERROR(ENOMEM);
7753  }
7754  encryption_index->auxiliary_offsets = auxiliary_offsets;
7755 
7756  if (version == 0) {
7757  encryption_index->auxiliary_offsets[i] = avio_rb32(pb);
7758  } else {
7759  encryption_index->auxiliary_offsets[i] = avio_rb64(pb);
7760  }
7761  if (c->frag_index.current >= 0) {
7762  encryption_index->auxiliary_offsets[i] += c->fragment.base_data_offset;
7763  }
7764  }
7765 
7766  if (pb->eof_reached) {
7767  av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading saio\n");
7768  av_freep(&encryption_index->auxiliary_offsets);
7769  return AVERROR_INVALIDDATA;
7770  }
7771 
7772  encryption_index->auxiliary_offsets_count = entry_count;
7773 
7774  if (encryption_index->auxiliary_info_sample_count) {
7775  return mov_parse_auxiliary_info(c, sc, pb, encryption_index);
7776  }
7777 
7778  return 0;
7779 }
7780 
7782 {
7783  AVEncryptionInitInfo *info, *old_init_info;
7784  uint8_t **key_ids;
7785  AVStream *st;
7786  const AVPacketSideData *old_side_data;
7787  uint8_t *side_data, *extra_data;
7788  size_t side_data_size;
7789  int ret = 0;
7790  unsigned int version, kid_count, extra_data_size, alloc_size = 0;
7791 
7792  if (c->fc->nb_streams < 1)
7793  return 0;
7794  st = c->fc->streams[c->fc->nb_streams-1];
7795 
7796  version = avio_r8(pb); /* version */
7797  avio_rb24(pb); /* flags */
7798 
7799  info = av_encryption_init_info_alloc(/* system_id_size */ 16, /* num_key_ids */ 0,
7800  /* key_id_size */ 16, /* data_size */ 0);
7801  if (!info)
7802  return AVERROR(ENOMEM);
7803 
7804  if ((ret = ffio_read_size(pb, info->system_id, 16)) < 0) {
7805  av_log(c->fc, AV_LOG_ERROR, "Failed to read the system id\n");
7806  goto finish;
7807  }
7808 
7809  if (version > 0) {
7810  kid_count = avio_rb32(pb);
7811  if (kid_count >= INT_MAX / sizeof(*key_ids)) {
7812  ret = AVERROR(ENOMEM);
7813  goto finish;
7814  }
7815 
7816  for (unsigned int i = 0; i < kid_count && !pb->eof_reached; i++) {
7817  unsigned int min_kid_count = FFMIN(FFMAX(i + 1, 1024), kid_count);
7818  key_ids = av_fast_realloc(info->key_ids, &alloc_size,
7819  min_kid_count * sizeof(*key_ids));
7820  if (!key_ids) {
7821  ret = AVERROR(ENOMEM);
7822  goto finish;
7823  }
7824  info->key_ids = key_ids;
7825 
7826  info->key_ids[i] = av_mallocz(16);
7827  if (!info->key_ids[i]) {
7828  ret = AVERROR(ENOMEM);
7829  goto finish;
7830  }
7831  info->num_key_ids = i + 1;
7832 
7833  if ((ret = ffio_read_size(pb, info->key_ids[i], 16)) < 0) {
7834  av_log(c->fc, AV_LOG_ERROR, "Failed to read the key id\n");
7835  goto finish;
7836  }
7837  }
7838 
7839  if (pb->eof_reached) {
7840  av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading pssh\n");
7842  goto finish;
7843  }
7844  }
7845 
7846  extra_data_size = avio_rb32(pb);
7847  extra_data = av_malloc(extra_data_size);
7848  if (!extra_data) {
7849  ret = AVERROR(ENOMEM);
7850  goto finish;
7851  }
7852  ret = avio_read(pb, extra_data, extra_data_size);
7853  if (ret != extra_data_size) {
7854  av_free(extra_data);
7855 
7856  if (ret >= 0)
7858  goto finish;
7859  }
7860 
7861  av_freep(&info->data); // malloc(0) may still allocate something.
7862  info->data = extra_data;
7863  info->data_size = extra_data_size;
7864 
7865  // If there is existing initialization data, append to the list.
7868  if (old_side_data) {
7869  old_init_info = av_encryption_init_info_get_side_data(old_side_data->data, old_side_data->size);
7870  if (old_init_info) {
7871  // Append to the end of the list.
7872  for (AVEncryptionInitInfo *cur = old_init_info;; cur = cur->next) {
7873  if (!cur->next) {
7874  cur->next = info;
7875  break;
7876  }
7877  }
7878  info = old_init_info;
7879  } else {
7880  // Assume existing side-data will be valid, so the only error we could get is OOM.
7881  ret = AVERROR(ENOMEM);
7882  goto finish;
7883  }
7884  }
7885 
7886  side_data = av_encryption_init_info_add_side_data(info, &side_data_size);
7887  if (!side_data) {
7888  ret = AVERROR(ENOMEM);
7889  goto finish;
7890  }
7894  side_data, side_data_size, 0))
7895  av_free(side_data);
7896 
7897 finish:
7899  return ret;
7900 }
7901 
7903 {
7904  AVStream *st;
7905  MOVStreamContext *sc;
7906 
7907  if (c->fc->nb_streams < 1)
7908  return 0;
7909  st = c->fc->streams[c->fc->nb_streams-1];
7910  sc = st->priv_data;
7911 
7912  if (sc->pseudo_stream_id != 0) {
7913  av_log(c->fc, AV_LOG_ERROR, "schm boxes are only supported in first sample descriptor\n");
7914  return AVERROR_PATCHWELCOME;
7915  }
7916 
7917  if (atom.size < 8)
7918  return AVERROR_INVALIDDATA;
7919 
7920  avio_rb32(pb); /* version and flags */
7921 
7922  if (!sc->cenc.default_encrypted_sample) {
7924  if (!sc->cenc.default_encrypted_sample) {
7925  return AVERROR(ENOMEM);
7926  }
7927  }
7928 
7930  return 0;
7931 }
7932 
7934 {
7935  AVStream *st;
7936  MOVStreamContext *sc;
7937  unsigned int version, pattern, is_protected, iv_size;
7938 
7939  if (c->fc->nb_streams < 1)
7940  return 0;
7941  st = c->fc->streams[c->fc->nb_streams-1];
7942  sc = st->priv_data;
7943 
7944  if (sc->pseudo_stream_id != 0) {
7945  av_log(c->fc, AV_LOG_ERROR, "tenc atom are only supported in first sample descriptor\n");
7946  return AVERROR_PATCHWELCOME;
7947  }
7948 
7949  if (!sc->cenc.default_encrypted_sample) {
7951  if (!sc->cenc.default_encrypted_sample) {
7952  return AVERROR(ENOMEM);
7953  }
7954  }
7955 
7956  if (atom.size < 20)
7957  return AVERROR_INVALIDDATA;
7958 
7959  version = avio_r8(pb); /* version */
7960  avio_rb24(pb); /* flags */
7961 
7962  avio_r8(pb); /* reserved */
7963  pattern = avio_r8(pb);
7964 
7965  if (version > 0) {
7966  sc->cenc.default_encrypted_sample->crypt_byte_block = pattern >> 4;
7967  sc->cenc.default_encrypted_sample->skip_byte_block = pattern & 0xf;
7968  }
7969 
7970  is_protected = avio_r8(pb);
7971  if (is_protected && !sc->cenc.encryption_index) {
7972  // The whole stream should be by-default encrypted.
7974  if (!sc->cenc.encryption_index)
7975  return AVERROR(ENOMEM);
7976  }
7977  sc->cenc.per_sample_iv_size = avio_r8(pb);
7978  if (sc->cenc.per_sample_iv_size != 0 && sc->cenc.per_sample_iv_size != 8 &&
7979  sc->cenc.per_sample_iv_size != 16) {
7980  av_log(c->fc, AV_LOG_ERROR, "invalid per-sample IV size value\n");
7981  return AVERROR_INVALIDDATA;
7982  }
7983  if (avio_read(pb, sc->cenc.default_encrypted_sample->key_id, 16) != 16) {
7984  av_log(c->fc, AV_LOG_ERROR, "failed to read the default key ID\n");
7985  return AVERROR_INVALIDDATA;
7986  }
7987 
7988  if (is_protected && !sc->cenc.per_sample_iv_size) {
7989  iv_size = avio_r8(pb);
7990  if (iv_size != 8 && iv_size != 16) {
7991  av_log(c->fc, AV_LOG_ERROR, "invalid default_constant_IV_size in tenc atom\n");
7992  return AVERROR_INVALIDDATA;
7993  }
7994 
7995  if (avio_read(pb, sc->cenc.default_encrypted_sample->iv, iv_size) != iv_size) {
7996  av_log(c->fc, AV_LOG_ERROR, "failed to read the default IV\n");
7997  return AVERROR_INVALIDDATA;
7998  }
7999  }
8000 
8001  return 0;
8002 }
8003 
8005 {
8006  AVStream *st;
8007  int last, type, size, ret;
8008  uint8_t buf[4];
8009 
8010  if (c->fc->nb_streams < 1)
8011  return 0;
8012  st = c->fc->streams[c->fc->nb_streams-1];
8013 
8014  if ((uint64_t)atom.size > (1<<30) || atom.size < 42)
8015  return AVERROR_INVALIDDATA;
8016 
8017  /* Check FlacSpecificBox version. */
8018  if (avio_r8(pb) != 0)
8019  return AVERROR_INVALIDDATA;
8020 
8021  avio_rb24(pb); /* Flags */
8022 
8023  if (avio_read(pb, buf, sizeof(buf)) != sizeof(buf)) {
8024  av_log(c->fc, AV_LOG_ERROR, "failed to read FLAC metadata block header\n");
8025  return pb->error < 0 ? pb->error : AVERROR_INVALIDDATA;
8026  }
8027  flac_parse_block_header(buf, &last, &type, &size);
8028 
8030  av_log(c->fc, AV_LOG_ERROR, "STREAMINFO must be first FLACMetadataBlock\n");
8031  return AVERROR_INVALIDDATA;
8032  }
8033 
8034  ret = ff_get_extradata(c->fc, st->codecpar, pb, size);
8035  if (ret < 0)
8036  return ret;
8037 
8038  if (!last)
8039  av_log(c->fc, AV_LOG_WARNING, "non-STREAMINFO FLACMetadataBlock(s) ignored\n");
8040 
8041  return 0;
8042 }
8043 
8045 {
8046  int i, ret;
8047  int bytes_of_protected_data;
8048 
8049  if (!sc->cenc.aes_ctr) {
8050  /* initialize the cipher */
8051  sc->cenc.aes_ctr = av_aes_ctr_alloc();
8052  if (!sc->cenc.aes_ctr) {
8053  return AVERROR(ENOMEM);
8054  }
8055 
8056  ret = av_aes_ctr_init(sc->cenc.aes_ctr, c->decryption_key);
8057  if (ret < 0) {
8058  return ret;
8059  }
8060  }
8061 
8063 
8064  if (!sample->subsample_count) {
8065  /* decrypt the whole packet */
8067  return 0;
8068  }
8069 
8070  for (i = 0; i < sample->subsample_count; i++) {
8071  if (sample->subsamples[i].bytes_of_clear_data + sample->subsamples[i].bytes_of_protected_data > size) {
8072  av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n");
8073  return AVERROR_INVALIDDATA;
8074  }
8075 
8076  /* skip the clear bytes */
8077  input += sample->subsamples[i].bytes_of_clear_data;
8078  size -= sample->subsamples[i].bytes_of_clear_data;
8079 
8080  /* decrypt the encrypted bytes */
8081 
8082  bytes_of_protected_data = sample->subsamples[i].bytes_of_protected_data;
8083  av_aes_ctr_crypt(sc->cenc.aes_ctr, input, input, bytes_of_protected_data);
8084 
8085  input += bytes_of_protected_data;
8086  size -= bytes_of_protected_data;
8087  }
8088 
8089  if (size > 0) {
8090  av_log(c->fc, AV_LOG_ERROR, "leftover packet bytes after subsample processing\n");
8091  return AVERROR_INVALIDDATA;
8092  }
8093 
8094  return 0;
8095 }
8096 
8098 {
8099  int i, ret;
8100  int num_of_encrypted_blocks;
8101  uint8_t iv[16];
8102 
8103  if (!sc->cenc.aes_ctx) {
8104  /* initialize the cipher */
8105  sc->cenc.aes_ctx = av_aes_alloc();
8106  if (!sc->cenc.aes_ctx) {
8107  return AVERROR(ENOMEM);
8108  }
8109 
8110  ret = av_aes_init(sc->cenc.aes_ctx, c->decryption_key, 16 * 8, 1);
8111  if (ret < 0) {
8112  return ret;
8113  }
8114  }
8115 
8116  memcpy(iv, sample->iv, 16);
8117 
8118  /* whole-block full sample encryption */
8119  if (!sample->subsample_count) {
8120  /* decrypt the whole packet */
8121  av_aes_crypt(sc->cenc.aes_ctx, input, input, size/16, iv, 1);
8122  return 0;
8123  }
8124 
8125  for (i = 0; i < sample->subsample_count; i++) {
8126  if (sample->subsamples[i].bytes_of_clear_data + sample->subsamples[i].bytes_of_protected_data > size) {
8127  av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n");
8128  return AVERROR_INVALIDDATA;
8129  }
8130 
8131  if (sample->subsamples[i].bytes_of_protected_data % 16) {
8132  av_log(c->fc, AV_LOG_ERROR, "subsample BytesOfProtectedData is not a multiple of 16\n");
8133  return AVERROR_INVALIDDATA;
8134  }
8135 
8136  /* skip the clear bytes */
8137  input += sample->subsamples[i].bytes_of_clear_data;
8138  size -= sample->subsamples[i].bytes_of_clear_data;
8139 
8140  /* decrypt the encrypted bytes */
8141  num_of_encrypted_blocks = sample->subsamples[i].bytes_of_protected_data/16;
8142  if (num_of_encrypted_blocks > 0) {
8143  av_aes_crypt(sc->cenc.aes_ctx, input, input, num_of_encrypted_blocks, iv, 1);
8144  }
8145  input += sample->subsamples[i].bytes_of_protected_data;
8146  size -= sample->subsamples[i].bytes_of_protected_data;
8147  }
8148 
8149  if (size > 0) {
8150  av_log(c->fc, AV_LOG_ERROR, "leftover packet bytes after subsample processing\n");
8151  return AVERROR_INVALIDDATA;
8152  }
8153 
8154  return 0;
8155 }
8156 
8158 {
8159  int i, ret, rem_bytes;
8160  uint8_t *data;
8161 
8162  if (!sc->cenc.aes_ctr) {
8163  /* initialize the cipher */
8164  sc->cenc.aes_ctr = av_aes_ctr_alloc();
8165  if (!sc->cenc.aes_ctr) {
8166  return AVERROR(ENOMEM);
8167  }
8168 
8169  ret = av_aes_ctr_init(sc->cenc.aes_ctr, c->decryption_key);
8170  if (ret < 0) {
8171  return ret;
8172  }
8173  }
8174 
8176 
8177  /* whole-block full sample encryption */
8178  if (!sample->subsample_count) {
8179  /* decrypt the whole packet */
8181  return 0;
8182  } else if (!sample->crypt_byte_block && !sample->skip_byte_block) {
8183  av_log(c->fc, AV_LOG_ERROR, "pattern encryption is not present in 'cens' scheme\n");
8184  return AVERROR_INVALIDDATA;
8185  }
8186 
8187  for (i = 0; i < sample->subsample_count; i++) {
8188  if (sample->subsamples[i].bytes_of_clear_data + sample->subsamples[i].bytes_of_protected_data > size) {
8189  av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n");
8190  return AVERROR_INVALIDDATA;
8191  }
8192 
8193  /* skip the clear bytes */
8194  input += sample->subsamples[i].bytes_of_clear_data;
8195  size -= sample->subsamples[i].bytes_of_clear_data;
8196 
8197  /* decrypt the encrypted bytes */
8198  data = input;
8199  rem_bytes = sample->subsamples[i].bytes_of_protected_data;
8200  while (rem_bytes > 0) {
8201  if (rem_bytes < 16*sample->crypt_byte_block) {
8202  break;
8203  }
8204  av_aes_ctr_crypt(sc->cenc.aes_ctr, data, data, 16*sample->crypt_byte_block);
8205  data += 16*sample->crypt_byte_block;
8206  rem_bytes -= 16*sample->crypt_byte_block;
8207  data += FFMIN(16*sample->skip_byte_block, rem_bytes);
8208  rem_bytes -= FFMIN(16*sample->skip_byte_block, rem_bytes);
8209  }
8210  input += sample->subsamples[i].bytes_of_protected_data;
8211  size -= sample->subsamples[i].bytes_of_protected_data;
8212  }
8213 
8214  if (size > 0) {
8215  av_log(c->fc, AV_LOG_ERROR, "leftover packet bytes after subsample processing\n");
8216  return AVERROR_INVALIDDATA;
8217  }
8218 
8219  return 0;
8220 }
8221 
8223 {
8224  int i, ret, rem_bytes;
8225  uint8_t iv[16];
8226  uint8_t *data;
8227 
8228  if (!sc->cenc.aes_ctx) {
8229  /* initialize the cipher */
8230  sc->cenc.aes_ctx = av_aes_alloc();
8231  if (!sc->cenc.aes_ctx) {
8232  return AVERROR(ENOMEM);
8233  }
8234 
8235  ret = av_aes_init(sc->cenc.aes_ctx, c->decryption_key, 16 * 8, 1);
8236  if (ret < 0) {
8237  return ret;
8238  }
8239  }
8240 
8241  /* whole-block full sample encryption */
8242  if (!sample->subsample_count) {
8243  /* decrypt the whole packet */
8244  memcpy(iv, sample->iv, 16);
8245  av_aes_crypt(sc->cenc.aes_ctx, input, input, size/16, iv, 1);
8246  return 0;
8247  } else if (!sample->crypt_byte_block && !sample->skip_byte_block) {
8248  av_log(c->fc, AV_LOG_ERROR, "pattern encryption is not present in 'cbcs' scheme\n");
8249  return AVERROR_INVALIDDATA;
8250  }
8251 
8252  for (i = 0; i < sample->subsample_count; i++) {
8253  if (sample->subsamples[i].bytes_of_clear_data + sample->subsamples[i].bytes_of_protected_data > size) {
8254  av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n");
8255  return AVERROR_INVALIDDATA;
8256  }
8257 
8258  /* skip the clear bytes */
8259  input += sample->subsamples[i].bytes_of_clear_data;
8260  size -= sample->subsamples[i].bytes_of_clear_data;
8261 
8262  /* decrypt the encrypted bytes */
8263  memcpy(iv, sample->iv, 16);
8264  data = input;
8265  rem_bytes = sample->subsamples[i].bytes_of_protected_data;
8266  while (rem_bytes > 0) {
8267  if (rem_bytes < 16*sample->crypt_byte_block) {
8268  break;
8269  }
8270  av_aes_crypt(sc->cenc.aes_ctx, data, data, sample->crypt_byte_block, iv, 1);
8271  data += 16*sample->crypt_byte_block;
8272  rem_bytes -= 16*sample->crypt_byte_block;
8273  data += FFMIN(16*sample->skip_byte_block, rem_bytes);
8274  rem_bytes -= FFMIN(16*sample->skip_byte_block, rem_bytes);
8275  }
8276  input += sample->subsamples[i].bytes_of_protected_data;
8277  size -= sample->subsamples[i].bytes_of_protected_data;
8278  }
8279 
8280  if (size > 0) {
8281  av_log(c->fc, AV_LOG_ERROR, "leftover packet bytes after subsample processing\n");
8282  return AVERROR_INVALIDDATA;
8283  }
8284 
8285  return 0;
8286 }
8287 
8289 {
8290  if (sample->scheme == MKBETAG('c','e','n','c') && !sample->crypt_byte_block && !sample->skip_byte_block) {
8291  return cenc_scheme_decrypt(c, sc, sample, input, size);
8292  } else if (sample->scheme == MKBETAG('c','b','c','1') && !sample->crypt_byte_block && !sample->skip_byte_block) {
8293  return cbc1_scheme_decrypt(c, sc, sample, input, size);
8294  } else if (sample->scheme == MKBETAG('c','e','n','s')) {
8295  return cens_scheme_decrypt(c, sc, sample, input, size);
8296  } else if (sample->scheme == MKBETAG('c','b','c','s')) {
8297  return cbcs_scheme_decrypt(c, sc, sample, input, size);
8298  } else {
8299  av_log(c->fc, AV_LOG_ERROR, "invalid encryption scheme\n");
8300  return AVERROR_INVALIDDATA;
8301  }
8302 }
8303 
8305 {
8306  int current = frag_index->current;
8307 
8308  if (!frag_index->nb_items)
8309  return NULL;
8310 
8311  // Check frag_index->current is the right one for pkt. It can out of sync.
8312  if (current >= 0 && current < frag_index->nb_items) {
8313  if (frag_index->item[current].moof_offset < pkt->pos &&
8314  (current + 1 == frag_index->nb_items ||
8315  frag_index->item[current + 1].moof_offset > pkt->pos))
8316  return get_frag_stream_info(frag_index, current, id);
8317  }
8318 
8319 
8320  for (int i = 0; i < frag_index->nb_items; i++) {
8321  if (frag_index->item[i].moof_offset > pkt->pos)
8322  break;
8323  current = i;
8324  }
8325  frag_index->current = current;
8326  return get_frag_stream_info(frag_index, current, id);
8327 }
8328 
8329 static int cenc_filter(MOVContext *mov, AVStream* st, MOVStreamContext *sc, AVPacket *pkt, int current_index)
8330 {
8331  MOVFragmentStreamInfo *frag_stream_info;
8332  MOVEncryptionIndex *encryption_index;
8333  AVEncryptionInfo *encrypted_sample;
8334  int encrypted_index, ret;
8335 
8336  frag_stream_info = get_frag_stream_info_from_pkt(&mov->frag_index, pkt, sc->id);
8337  encrypted_index = current_index;
8338  encryption_index = NULL;
8339  if (frag_stream_info) {
8340  // Note this only supports encryption info in the first sample descriptor.
8341  if (frag_stream_info->stsd_id == 1) {
8342  if (frag_stream_info->encryption_index) {
8343  encrypted_index = current_index - frag_stream_info->index_base;
8344  encryption_index = frag_stream_info->encryption_index;
8345  } else {
8346  encryption_index = sc->cenc.encryption_index;
8347  }
8348  }
8349  } else {
8350  encryption_index = sc->cenc.encryption_index;
8351  }
8352 
8353  if (encryption_index) {
8354  if (encryption_index->auxiliary_info_sample_count &&
8355  !encryption_index->nb_encrypted_samples) {
8356  av_log(mov->fc, AV_LOG_ERROR, "saiz atom found without saio\n");
8357  return AVERROR_INVALIDDATA;
8358  }
8359  if (encryption_index->auxiliary_offsets_count &&
8360  !encryption_index->nb_encrypted_samples) {
8361  av_log(mov->fc, AV_LOG_ERROR, "saio atom found without saiz\n");
8362  return AVERROR_INVALIDDATA;
8363  }
8364 
8365  encrypted_sample = NULL;
8366  if (!encryption_index->nb_encrypted_samples) {
8367  // Full-sample encryption with default settings.
8368  encrypted_sample = sc->cenc.default_encrypted_sample;
8369  } else if (encrypted_index >= 0 && encrypted_index < encryption_index->nb_encrypted_samples) {
8370  // Per-sample setting override.
8371  encrypted_sample = encryption_index->encrypted_samples[encrypted_index];
8372  if (!encrypted_sample) {
8373  encrypted_sample = sc->cenc.default_encrypted_sample;
8374  }
8375  }
8376 
8377  if (!encrypted_sample) {
8378  av_log(mov->fc, AV_LOG_ERROR, "Incorrect number of samples in encryption info\n");
8379  return AVERROR_INVALIDDATA;
8380  }
8381 
8382  if (mov->decryption_key) {
8383  return cenc_decrypt(mov, sc, encrypted_sample, pkt->data, pkt->size);
8384  } else {
8385  size_t size;
8386  uint8_t *side_data = av_encryption_info_add_side_data(encrypted_sample, &size);
8387  if (!side_data)
8388  return AVERROR(ENOMEM);
8390  if (ret < 0)
8391  av_free(side_data);
8392  return ret;
8393  }
8394  }
8395 
8396  return 0;
8397 }
8398 
8400 {
8401  const int OPUS_SEEK_PREROLL_MS = 80;
8402  int ret;
8403  AVStream *st;
8404  size_t size;
8405  uint16_t pre_skip;
8406 
8407  if (c->fc->nb_streams < 1)
8408  return 0;
8409  st = c->fc->streams[c->fc->nb_streams-1];
8410 
8411  if ((uint64_t)atom.size > (1<<30) || atom.size < 11)
8412  return AVERROR_INVALIDDATA;
8413 
8414  /* Check OpusSpecificBox version. */
8415  if (avio_r8(pb) != 0) {
8416  av_log(c->fc, AV_LOG_ERROR, "unsupported OpusSpecificBox version\n");
8417  return AVERROR_INVALIDDATA;
8418  }
8419 
8420  /* OpusSpecificBox size plus magic for Ogg OpusHead header. */
8421  size = atom.size + 8;
8422 
8423  if ((ret = ff_alloc_extradata(st->codecpar, size)) < 0)
8424  return ret;
8425 
8426  AV_WL32A(st->codecpar->extradata, MKTAG('O','p','u','s'));
8427  AV_WL32A(st->codecpar->extradata + 4, MKTAG('H','e','a','d'));
8428  AV_WB8(st->codecpar->extradata + 8, 1); /* OpusHead version */
8429  avio_read(pb, st->codecpar->extradata + 9, size - 9);
8430 
8431  /* OpusSpecificBox is stored in big-endian, but OpusHead is
8432  little-endian; aside from the preceeding magic and version they're
8433  otherwise currently identical. Data after output gain at offset 16
8434  doesn't need to be bytewapped. */
8435  pre_skip = AV_RB16A(st->codecpar->extradata + 10);
8436  AV_WL16A(st->codecpar->extradata + 10, pre_skip);
8437  AV_WL32A(st->codecpar->extradata + 12, AV_RB32A(st->codecpar->extradata + 12));
8438  AV_WL16A(st->codecpar->extradata + 16, AV_RB16A(st->codecpar->extradata + 16));
8439 
8440  st->codecpar->initial_padding = pre_skip;
8442  (AVRational){1, 1000},
8443  (AVRational){1, 48000});
8444 
8445  return 0;
8446 }
8447 
8449 {
8450  AVStream *st;
8451  unsigned format_info;
8452  int channel_assignment, channel_assignment1, channel_assignment2;
8453  int ratebits;
8454  uint64_t chmask;
8455 
8456  if (c->fc->nb_streams < 1)
8457  return 0;
8458  st = c->fc->streams[c->fc->nb_streams-1];
8459 
8460  if (atom.size < 10)
8461  return AVERROR_INVALIDDATA;
8462 
8463  format_info = avio_rb32(pb);
8464 
8465  ratebits = (format_info >> 28) & 0xF;
8466  channel_assignment1 = (format_info >> 15) & 0x1F;
8467  channel_assignment2 = format_info & 0x1FFF;
8468  if (channel_assignment2)
8469  channel_assignment = channel_assignment2;
8470  else
8471  channel_assignment = channel_assignment1;
8472 
8473  st->codecpar->frame_size = 40 << (ratebits & 0x7);
8474  st->codecpar->sample_rate = mlp_samplerate(ratebits);
8475 
8477  chmask = truehd_layout(channel_assignment);
8479 
8480  return 0;
8481 }
8482 
8484 {
8485  AVStream *st;
8486  uint8_t buf[ISOM_DVCC_DVVC_SIZE];
8487  int ret;
8488  int64_t read_size = atom.size;
8489 
8490  if (c->fc->nb_streams < 1)
8491  return 0;
8492  st = c->fc->streams[c->fc->nb_streams-1];
8493 
8494  // At most 24 bytes
8495  read_size = FFMIN(read_size, ISOM_DVCC_DVVC_SIZE);
8496 
8497  if ((ret = ffio_read_size(pb, buf, read_size)) < 0)
8498  return ret;
8499 
8500  return ff_isom_parse_dvcc_dvvc(c->fc, st, buf, read_size);
8501 }
8502 
8504 {
8505  AVStream *st;
8506  uint8_t *buf;
8507  int ret, old_size, num_arrays;
8508 
8509  if (c->fc->nb_streams < 1)
8510  return 0;
8511  st = c->fc->streams[c->fc->nb_streams-1];
8512 
8513  if (!st->codecpar->extradata_size)
8514  // TODO: handle lhvC when present before hvcC
8515  return 0;
8516 
8517  if (atom.size < 6 || st->codecpar->extradata_size < 23)
8518  return AVERROR_INVALIDDATA;
8519 
8521  if (!buf)
8522  return AVERROR(ENOMEM);
8523  memset(buf + atom.size, 0, AV_INPUT_BUFFER_PADDING_SIZE);
8524 
8525  ret = ffio_read_size(pb, buf, atom.size);
8526  if (ret < 0) {
8527  av_free(buf);
8528  av_log(c->fc, AV_LOG_WARNING, "lhvC atom truncated\n");
8529  return 0;
8530  }
8531 
8532  num_arrays = buf[5];
8533  old_size = st->codecpar->extradata_size;
8534  atom.size -= 8 /* account for mov_realloc_extradata offseting */
8535  + 6 /* lhvC bytes before the arrays*/;
8536 
8537  ret = mov_realloc_extradata(st->codecpar, atom);
8538  if (ret < 0) {
8539  av_free(buf);
8540  return ret;
8541  }
8542 
8543  st->codecpar->extradata[22] += num_arrays;
8544  memcpy(st->codecpar->extradata + old_size, buf + 6, atom.size + 8);
8545 
8547 
8548  av_free(buf);
8549  return 0;
8550 }
8551 
8553 {
8554  AVFormatContext *ctx = c->fc;
8555  AVStream *st = NULL;
8556  AVBPrint scheme_buf, value_buf;
8557  int64_t scheme_str_len = 0, value_str_len = 0;
8558  int version, flags, ret = AVERROR_BUG;
8559  int64_t size = atom.size;
8560 
8561  if (atom.size < 6)
8562  // 4 bytes for version + flags, 2x 1 byte for null
8563  return AVERROR_INVALIDDATA;
8564 
8565  if (c->fc->nb_streams < 1)
8566  return 0;
8567  st = c->fc->streams[c->fc->nb_streams-1];
8568 
8569  version = avio_r8(pb);
8570  flags = avio_rb24(pb);
8571  size -= 4;
8572 
8573  if (version != 0 || flags != 0) {
8575  "Unsupported 'kind' box with version %d, flags: %x",
8576  version, flags);
8577  return AVERROR_INVALIDDATA;
8578  }
8579 
8580  av_bprint_init(&scheme_buf, 0, AV_BPRINT_SIZE_UNLIMITED);
8581  av_bprint_init(&value_buf, 0, AV_BPRINT_SIZE_UNLIMITED);
8582 
8583  if ((scheme_str_len = ff_read_string_to_bprint_overwrite(pb, &scheme_buf,
8584  size)) < 0) {
8585  ret = scheme_str_len;
8586  goto cleanup;
8587  }
8588 
8589  if (scheme_str_len + 1 >= size) {
8590  // we need to have another string, even if nullptr.
8591  // we check with + 1 since we expect that if size was not hit,
8592  // an additional null was read.
8594  goto cleanup;
8595  }
8596 
8597  size -= scheme_str_len + 1;
8598 
8599  if ((value_str_len = ff_read_string_to_bprint_overwrite(pb, &value_buf,
8600  size)) < 0) {
8601  ret = value_str_len;
8602  goto cleanup;
8603  }
8604 
8605  if (value_str_len == size) {
8606  // in case of no trailing null, box is not valid.
8608  goto cleanup;
8609  }
8610 
8612  "%s stream %d KindBox(scheme: %s, value: %s)\n",
8614  st->index,
8615  scheme_buf.str, value_buf.str);
8616 
8617  for (int i = 0; ff_mov_track_kind_table[i].scheme_uri; i++) {
8619  if (!av_strstart(scheme_buf.str, map.scheme_uri, NULL))
8620  continue;
8621 
8622  for (int j = 0; map.value_maps[j].disposition; j++) {
8623  const struct MP4TrackKindValueMapping value_map = map.value_maps[j];
8624  if (!av_strstart(value_buf.str, value_map.value, NULL))
8625  continue;
8626 
8627  st->disposition |= value_map.disposition;
8628  }
8629  }
8630 
8631  ret = 0;
8632 
8633 cleanup:
8634 
8635  av_bprint_finalize(&scheme_buf, NULL);
8636  av_bprint_finalize(&value_buf, NULL);
8637 
8638  return ret;
8639 }
8640 
8642 {
8643  AVStream *st;
8644  AVChannelLayout ch_layout = { 0 };
8645  int ret, i, version, type;
8646  int ambisonic_order, channel_order, normalization, channel_count;
8647  int ambi_channels, non_diegetic_channels;
8648 
8649  if (c->fc->nb_streams < 1)
8650  return 0;
8651 
8652  st = c->fc->streams[c->fc->nb_streams - 1];
8653 
8654  if (atom.size < 16) {
8655  av_log(c->fc, AV_LOG_ERROR, "SA3D audio box too small\n");
8656  return AVERROR_INVALIDDATA;
8657  }
8658 
8659  version = avio_r8(pb);
8660  if (version) {
8661  av_log(c->fc, AV_LOG_WARNING, "Unsupported SA3D box version %d\n", version);
8662  return 0;
8663  }
8664 
8665  type = avio_r8(pb);
8666  if (type & 0x7f) {
8667  av_log(c->fc, AV_LOG_WARNING,
8668  "Unsupported ambisonic type %d\n", type & 0x7f);
8669  return 0;
8670  }
8671  non_diegetic_channels = (type >> 7) * 2; // head_locked_stereo
8672 
8673  ambisonic_order = avio_rb32(pb);
8674 
8675  channel_order = avio_r8(pb);
8676  if (channel_order) {
8677  av_log(c->fc, AV_LOG_WARNING,
8678  "Unsupported channel_order %d\n", channel_order);
8679  return 0;
8680  }
8681 
8682  normalization = avio_r8(pb);
8683  if (normalization) {
8684  av_log(c->fc, AV_LOG_WARNING,
8685  "Unsupported normalization %d\n", normalization);
8686  return 0;
8687  }
8688 
8689  channel_count = avio_rb32(pb);
8690  if (ambisonic_order < 0 || ambisonic_order > 31 ||
8691  channel_count != ((ambisonic_order + 1LL) * (ambisonic_order + 1LL) +
8692  non_diegetic_channels)) {
8693  av_log(c->fc, AV_LOG_ERROR,
8694  "Invalid number of channels (%d / %d)\n",
8695  channel_count, ambisonic_order);
8696  return 0;
8697  }
8698  ambi_channels = channel_count - non_diegetic_channels;
8699 
8700  ret = av_channel_layout_custom_init(&ch_layout, channel_count);
8701  if (ret < 0)
8702  return 0;
8703 
8704  for (i = 0; i < channel_count; i++) {
8705  unsigned channel = avio_rb32(pb);
8706 
8707  if (channel >= channel_count) {
8708  av_log(c->fc, AV_LOG_ERROR, "Invalid channel index (%d / %d)\n",
8709  channel, ambisonic_order);
8710  av_channel_layout_uninit(&ch_layout);
8711  return 0;
8712  }
8713  if (channel >= ambi_channels)
8714  ch_layout.u.map[i].id = channel - ambi_channels;
8715  else
8716  ch_layout.u.map[i].id = AV_CHAN_AMBISONIC_BASE + channel;
8717  }
8718 
8720  if (ret < 0) {
8721  av_channel_layout_uninit(&ch_layout);
8722  return 0;
8723  }
8724 
8726  st->codecpar->ch_layout = ch_layout;
8727 
8728  return 0;
8729 }
8730 
8732 {
8733  AVStream *st;
8734  int version;
8735 
8736  if (c->fc->nb_streams < 1)
8737  return 0;
8738 
8739  st = c->fc->streams[c->fc->nb_streams - 1];
8740 
8741  if (atom.size < 5) {
8742  av_log(c->fc, AV_LOG_ERROR, "Empty SAND audio box\n");
8743  return AVERROR_INVALIDDATA;
8744  }
8745 
8746  version = avio_r8(pb);
8747  if (version) {
8748  av_log(c->fc, AV_LOG_WARNING, "Unsupported SAND box version %d\n", version);
8749  return 0;
8750  }
8751 
8753 
8754  return 0;
8755 }
8756 
8757 static int rb_size(AVIOContext *pb, int64_t *value, int size)
8758 {
8759  if (size == 0)
8760  *value = 0;
8761  else if (size == 1)
8762  *value = avio_r8(pb);
8763  else if (size == 2)
8764  *value = avio_rb16(pb);
8765  else if (size == 4)
8766  *value = avio_rb32(pb);
8767  else if (size == 8) {
8768  *value = avio_rb64(pb);
8769  if (*value < 0)
8770  return -1;
8771  } else
8772  return -1;
8773  return size;
8774 }
8775 
8777 {
8778  avio_rb32(pb); // version & flags.
8779  c->primary_item_id = avio_rb16(pb);
8780  av_log(c->fc, AV_LOG_TRACE, "pitm: primary_item_id %d\n", c->primary_item_id);
8781  return atom.size;
8782 }
8783 
8785 {
8786  c->idat_offset = avio_tell(pb);
8787  return 0;
8788 }
8789 
8791 {
8792  HEIFItem **heif_item;
8793  int version, offset_size, length_size, base_offset_size, index_size;
8794  int item_count, extent_count;
8795  int64_t base_offset, extent_offset, extent_length;
8796  uint8_t value;
8797 
8798  if (c->found_iloc) {
8799  av_log(c->fc, AV_LOG_INFO, "Duplicate iloc box found\n");
8800  return 0;
8801  }
8802 
8803  version = avio_r8(pb);
8804  avio_rb24(pb); // flags.
8805 
8806  value = avio_r8(pb);
8807  offset_size = (value >> 4) & 0xF;
8808  length_size = value & 0xF;
8809  value = avio_r8(pb);
8810  base_offset_size = (value >> 4) & 0xF;
8811  index_size = !version ? 0 : (value & 0xF);
8812  if (index_size) {
8813  avpriv_report_missing_feature(c->fc, "iloc: index_size != 0");
8814  return AVERROR_PATCHWELCOME;
8815  }
8816  item_count = (version < 2) ? avio_rb16(pb) : avio_rb32(pb);
8817 
8818  heif_item = av_realloc_array(c->heif_item, FFMAX(item_count, c->nb_heif_item), sizeof(*c->heif_item));
8819  if (!heif_item)
8820  return AVERROR(ENOMEM);
8821  c->heif_item = heif_item;
8822  if (item_count > c->nb_heif_item)
8823  memset(&c->heif_item[c->nb_heif_item], 0,
8824  sizeof(*c->heif_item) * (item_count - c->nb_heif_item));
8825  c->nb_heif_item = FFMAX(c->nb_heif_item, item_count);
8826 
8827  av_log(c->fc, AV_LOG_TRACE, "iloc: item_count %d\n", item_count);
8828  for (int i = 0; i < item_count; i++) {
8829  HEIFItem *item = NULL;
8830  int item_id = (version < 2) ? avio_rb16(pb) : avio_rb32(pb);
8831  int offset_type = (version > 0) ? avio_rb16(pb) & 0xf : 0;
8832 
8833  if (avio_feof(pb))
8834  return AVERROR_INVALIDDATA;
8835  if (offset_type > 1) {
8836  avpriv_report_missing_feature(c->fc, "iloc offset type %d", offset_type);
8837  return AVERROR_PATCHWELCOME;
8838  }
8839 
8840  avio_rb16(pb); // data_reference_index.
8841  if (rb_size(pb, &base_offset, base_offset_size) < 0)
8842  return AVERROR_INVALIDDATA;
8843  extent_count = avio_rb16(pb);
8844  if (extent_count > 1) {
8845  // For still AVIF images, we only support one extent item.
8846  avpriv_report_missing_feature(c->fc, "iloc: extent_count > 1");
8847  return AVERROR_PATCHWELCOME;
8848  }
8849 
8850  if (rb_size(pb, &extent_offset, offset_size) < 0 ||
8851  rb_size(pb, &extent_length, length_size) < 0 ||
8852  base_offset > INT64_MAX - extent_offset)
8853  return AVERROR_INVALIDDATA;
8854 
8855  for (int j = 0; j < c->nb_heif_item; j++) {
8856  item = c->heif_item[j];
8857  if (!item)
8858  item = c->heif_item[j] = av_mallocz(sizeof(*item));
8859  else if (item->item_id != item_id)
8860  continue;
8861  break;
8862  }
8863  if (!item)
8864  return AVERROR(ENOMEM);
8865 
8866  item->item_id = item_id;
8867 
8868  if (offset_type == 1)
8869  item->is_idat_relative = 1;
8870  item->extent_length = extent_length;
8871  item->extent_offset = base_offset + extent_offset;
8872  av_log(c->fc, AV_LOG_TRACE, "iloc: item_idx %d, item->item_id %d, offset_type %d, "
8873  "extent_offset %"PRId64", extent_length %"PRId64"\n",
8874  i, item->item_id, offset_type, item->extent_offset, item->extent_length);
8875  }
8876 
8877  c->found_iloc = 1;
8878  return atom.size;
8879 }
8880 
8882 {
8883  HEIFItem *item = NULL;
8884  AVBPrint item_name;
8885  int64_t size = atom.size;
8886  uint32_t item_type;
8887  int item_id;
8888  int version, ret;
8889 
8890  version = avio_r8(pb);
8891  avio_rb24(pb); // flags.
8892  size -= 4;
8893  if (size < 0)
8894  return AVERROR_INVALIDDATA;
8895 
8896  if (version < 2) {
8897  avpriv_report_missing_feature(c->fc, "infe version < 2");
8898  avio_skip(pb, size);
8899  return 1;
8900  }
8901 
8902  item_id = version > 2 ? avio_rb32(pb) : avio_rb16(pb);
8903  avio_rb16(pb); // item_protection_index
8904  item_type = avio_rl32(pb);
8905  size -= 8;
8906  if (size < 1)
8907  return AVERROR_INVALIDDATA;
8908 
8911  if (ret < 0) {
8913  return ret;
8914  }
8915 
8916  av_log(c->fc, AV_LOG_TRACE, "infe: item_id %d, item_type %s, item_name %s\n",
8917  item_id, av_fourcc2str(item_type), item_name.str);
8918 
8919  size -= ret + 1;
8920  if (size > 0)
8921  avio_skip(pb, size);
8922 
8923  for (int i = 0; i < c->nb_heif_item; i++) {
8924  item = c->heif_item[i];
8925  if (!item)
8926  item = c->heif_item[i] = av_mallocz(sizeof(*item));
8927  else if (item->item_id != item_id)
8928  continue;
8929  break;
8930  }
8931  if (!item)
8932  return AVERROR(ENOMEM);
8933 
8934  if (ret)
8935  av_bprint_finalize(&item_name, &item->name);
8936  item->item_id = item_id;
8937  item->type = item_type;
8938 
8939  switch (item_type) {
8940  case MKTAG('a','v','0','1'):
8941  case MKTAG('j','p','e','g'):
8942  case MKTAG('h','v','c','1'):
8943  ret = heif_add_stream(c, item);
8944  if (ret < 0)
8945  return ret;
8946  break;
8947  }
8948 
8949  return 0;
8950 }
8951 
8953 {
8954  HEIFItem **heif_item;
8955  int entry_count;
8956  int version, got_stream = 0, ret, i;
8957 
8958  if (c->found_iinf) {
8959  av_log(c->fc, AV_LOG_WARNING, "Duplicate iinf box found\n");
8960  return 0;
8961  }
8962 
8963  version = avio_r8(pb);
8964  avio_rb24(pb); // flags.
8965  entry_count = version ? avio_rb32(pb) : avio_rb16(pb);
8966 
8967  heif_item = av_realloc_array(c->heif_item, FFMAX(entry_count, c->nb_heif_item), sizeof(*c->heif_item));
8968  if (!heif_item)
8969  return AVERROR(ENOMEM);
8970  c->heif_item = heif_item;
8971  if (entry_count > c->nb_heif_item)
8972  memset(&c->heif_item[c->nb_heif_item], 0,
8973  sizeof(*c->heif_item) * (entry_count - c->nb_heif_item));
8974  c->nb_heif_item = FFMAX(c->nb_heif_item, entry_count);
8975 
8976  for (i = 0; i < entry_count; i++) {
8977  MOVAtom infe;
8978 
8979  infe.size = avio_rb32(pb) - 8;
8980  infe.type = avio_rl32(pb);
8981  if (avio_feof(pb)) {
8983  goto fail;
8984  }
8985  ret = mov_read_infe(c, pb, infe);
8986  if (ret < 0)
8987  goto fail;
8988  if (!ret)
8989  got_stream = 1;
8990  }
8991 
8992  c->found_iinf = got_stream;
8993  return 0;
8994 fail:
8995  for (; i >= 0; i--) {
8996  HEIFItem *item = c->heif_item[i];
8997 
8998  if (!item)
8999  continue;
9000 
9001  av_freep(&item->name);
9002  if (!item->st)
9003  continue;
9004 
9005  mov_free_stream_context(c->fc, item->st);
9006  ff_remove_stream(c->fc, item->st);
9007  item->st = NULL;
9008  }
9009  return ret;
9010 }
9011 
9013 {
9014  HEIFItem *item = NULL;
9015  HEIFGrid *grid;
9016  int entries, i;
9017  int from_item_id = version ? avio_rb32(pb) : avio_rb16(pb);
9018 
9019  for (int i = 0; i < c->nb_heif_grid; i++) {
9020  if (c->heif_grid[i].item->item_id == from_item_id) {
9021  av_log(c->fc, AV_LOG_ERROR, "More than one 'dimg' box "
9022  "referencing the same Derived Image item\n");
9023  return AVERROR_INVALIDDATA;
9024  }
9025  }
9026  for (int i = 0; i < c->nb_heif_item; i++) {
9027  if (!c->heif_item[i] || c->heif_item[i]->item_id != from_item_id)
9028  continue;
9029  item = c->heif_item[i];
9030 
9031  switch (item->type) {
9032  case MKTAG('g','r','i','d'):
9033  case MKTAG('i','o','v','l'):
9034  break;
9035  default:
9036  avpriv_report_missing_feature(c->fc, "Derived Image item of type %s",
9037  av_fourcc2str(item->type));
9038  return 0;
9039  }
9040  break;
9041  }
9042  if (!item) {
9043  av_log(c->fc, AV_LOG_ERROR, "Missing grid information\n");
9044  return AVERROR_INVALIDDATA;
9045  }
9046 
9047  grid = av_realloc_array(c->heif_grid, c->nb_heif_grid + 1U,
9048  sizeof(*c->heif_grid));
9049  if (!grid)
9050  return AVERROR(ENOMEM);
9051  c->heif_grid = grid;
9052  grid = &grid[c->nb_heif_grid++];
9053 
9054  entries = avio_rb16(pb);
9055  grid->tile_id_list = av_malloc_array(entries, sizeof(*grid->tile_id_list));
9056  grid->tile_idx_list = av_calloc(entries, sizeof(*grid->tile_idx_list));
9057  grid->tile_item_list = av_calloc(entries, sizeof(*grid->tile_item_list));
9058  if (!grid->tile_id_list || !grid->tile_item_list || !grid->tile_idx_list)
9059  return AVERROR(ENOMEM);
9060  /* 'to' item ids */
9061  for (i = 0; i < entries; i++)
9062  grid->tile_id_list[i] = version ? avio_rb32(pb) : avio_rb16(pb);
9063  grid->nb_tiles = entries;
9064  grid->item = item;
9065 
9066  av_log(c->fc, AV_LOG_TRACE, "dimg: from_item_id %d, entries %d\n",
9067  from_item_id, entries);
9068 
9069  return 0;
9070 }
9071 
9073 {
9074  int *thmb_item_id;
9075  int entries;
9076  int to_item_id, from_item_id = version ? avio_rb32(pb) : avio_rb16(pb);
9077 
9078  entries = avio_rb16(pb);
9079  if (entries > 1) {
9080  avpriv_request_sample(c->fc, "thmb in iref referencing several items");
9081  return AVERROR_PATCHWELCOME;
9082  }
9083  /* 'to' item ids */
9084  to_item_id = version ? avio_rb32(pb) : avio_rb16(pb);
9085 
9086  if (to_item_id != c->primary_item_id)
9087  return 0;
9088 
9089  /* Put thumnbail IDs into an array */
9090  thmb_item_id = av_dynarray2_add((void **)&c->thmb_item_id, &c->nb_thmb_item,
9091  sizeof(*c->thmb_item_id),
9092  (const void *)&from_item_id);
9093  if (!thmb_item_id)
9094  return AVERROR(ENOMEM);
9095 
9096  av_log(c->fc, AV_LOG_TRACE, "thmb: from_item_id %d, entries %d, nb_thmb: %d\n",
9097  from_item_id, entries, c->nb_thmb_item);
9098 
9099  return 0;
9100 }
9101 
9103 {
9104  int version = avio_r8(pb);
9105  avio_rb24(pb); // flags
9106  atom.size -= 4;
9107 
9108  if (version > 1) {
9109  av_log(c->fc, AV_LOG_WARNING, "Unknown iref box version %d\n", version);
9110  return 0;
9111  }
9112 
9113  while (atom.size) {
9114  uint32_t type, size = avio_rb32(pb);
9115  int64_t next = avio_tell(pb);
9116 
9117  if (size < 14 || next < 0 || next > INT64_MAX - size)
9118  return AVERROR_INVALIDDATA;
9119 
9120  next += size - 4;
9121  type = avio_rl32(pb);
9122  switch (type) {
9123  case MKTAG('d','i','m','g'):
9125  break;
9126  case MKTAG('t','h','m','b'):
9128  break;
9129  default:
9130  av_log(c->fc, AV_LOG_DEBUG, "Unknown iref type %s size %"PRIu32"\n",
9131  av_fourcc2str(type), size);
9132  }
9133 
9134  atom.size -= size;
9135  avio_seek(pb, next, SEEK_SET);
9136  }
9137  return 0;
9138 }
9139 
9141 {
9142  HEIFItem *item;
9143  uint32_t width, height;
9144 
9145  avio_r8(pb); /* version */
9146  avio_rb24(pb); /* flags */
9147  width = avio_rb32(pb);
9148  height = avio_rb32(pb);
9149 
9150  av_log(c->fc, AV_LOG_TRACE, "ispe: item_id %d, width %u, height %u\n",
9151  c->cur_item_id, width, height);
9152 
9153  item = heif_cur_item(c);
9154  if (item) {
9155  item->width = width;
9156  item->height = height;
9157  }
9158 
9159  return 0;
9160 }
9161 
9163 {
9164  HEIFItem *item;
9165  int angle;
9166 
9167  angle = avio_r8(pb) & 0x3;
9168 
9169  av_log(c->fc, AV_LOG_TRACE, "irot: item_id %d, angle %u\n",
9170  c->cur_item_id, angle);
9171 
9172  item = heif_cur_item(c);
9173  if (item) {
9174  // angle * 90 specifies the angle (in anti-clockwise direction)
9175  // in units of degrees.
9176  item->rotation = angle * 90;
9177  }
9178 
9179  return 0;
9180 }
9181 
9183 {
9184  HEIFItem *item;
9185  int axis;
9186 
9187  axis = avio_r8(pb) & 0x1;
9188 
9189  av_log(c->fc, AV_LOG_TRACE, "imir: item_id %d, axis %u\n",
9190  c->cur_item_id, axis);
9191 
9192  item = heif_cur_item(c);
9193  if (item) {
9194  item->hflip = axis;
9195  item->vflip = !axis;
9196  }
9197 
9198  return 0;
9199 }
9200 
9202 {
9203  typedef struct MOVAtoms {
9204  FFIOContext b;
9205  uint32_t type;
9206  int64_t size;
9207  uint8_t *data;
9208  } MOVAtoms;
9209  MOVAtoms *atoms = NULL;
9210  MOVAtom a;
9211  unsigned count;
9212  int nb_atoms = 0;
9213  int version, flags;
9214  int ret;
9215 
9216  a.size = avio_rb32(pb);
9217  a.type = avio_rl32(pb);
9218 
9219  if (a.size < 8 || a.type != MKTAG('i','p','c','o'))
9220  return AVERROR_INVALIDDATA;
9221 
9222  a.size -= 8;
9223  while (a.size >= 8) {
9224  MOVAtoms *ref = av_dynarray2_add((void**)&atoms, &nb_atoms, sizeof(MOVAtoms), NULL);
9225  if (!ref) {
9226  ret = AVERROR(ENOMEM);
9227  goto fail;
9228  }
9229  ref->data = NULL;
9230  ref->size = avio_rb32(pb);
9231  ref->type = avio_rl32(pb);
9232  if (ref->size > a.size || ref->size < 8)
9233  break;
9234  ref->data = av_malloc(ref->size);
9235  if (!ref->data) {
9237  goto fail;
9238  }
9239  av_log(c->fc, AV_LOG_TRACE, "ipco: index %d, box type %s\n", nb_atoms, av_fourcc2str(ref->type));
9240  avio_seek(pb, -8, SEEK_CUR);
9241  if (avio_read(pb, ref->data, ref->size) != ref->size) {
9243  goto fail;
9244  }
9245  ffio_init_read_context(&ref->b, ref->data, ref->size);
9246  a.size -= ref->size;
9247  }
9248 
9249  if (a.size) {
9251  goto fail;
9252  }
9253 
9254  a.size = avio_rb32(pb);
9255  a.type = avio_rl32(pb);
9256 
9257  if (a.size < 8 || a.type != MKTAG('i','p','m','a')) {
9259  goto fail;
9260  }
9261 
9262  version = avio_r8(pb);
9263  flags = avio_rb24(pb);
9264  count = avio_rb32(pb);
9265 
9266  for (int i = 0; i < count; i++) {
9267  int item_id = version ? avio_rb32(pb) : avio_rb16(pb);
9268  int assoc_count = avio_r8(pb);
9269 
9270  if (avio_feof(pb)) {
9272  goto fail;
9273  }
9274 
9275  for (int j = 0; j < assoc_count; j++) {
9276  MOVAtoms *ref;
9277  int index = avio_r8(pb) & 0x7f;
9278  if (flags & 1) {
9279  index <<= 8;
9280  index |= avio_r8(pb);
9281  }
9282  if (index > nb_atoms || index <= 0) {
9284  goto fail;
9285  }
9286  ref = &atoms[--index];
9287 
9288  av_log(c->fc, AV_LOG_TRACE, "ipma: property_index %d, item_id %d, item_type %s\n",
9289  index + 1, item_id, av_fourcc2str(ref->type));
9290 
9291  c->cur_item_id = item_id;
9292 
9293  ret = mov_read_default(c, &ref->b.pub,
9294  (MOVAtom) { .size = ref->size,
9295  .type = MKTAG('i','p','c','o') });
9296  if (ret < 0)
9297  goto fail;
9298  ffio_init_read_context(&ref->b, ref->data, ref->size);
9299  }
9300  }
9301 
9302  ret = 0;
9303 fail:
9304  c->cur_item_id = -1;
9305  for (int i = 0; i < nb_atoms; i++)
9306  av_free(atoms[i].data);
9307  av_free(atoms);
9308 
9309  return ret;
9310 }
9311 
9313 { MKTAG('A','C','L','R'), mov_read_aclr },
9314 { MKTAG('A','P','R','G'), mov_read_avid },
9315 { MKTAG('A','A','L','P'), mov_read_avid },
9316 { MKTAG('A','R','E','S'), mov_read_ares },
9317 { MKTAG('a','v','s','s'), mov_read_avss },
9318 { MKTAG('a','v','1','C'), mov_read_glbl },
9319 { MKTAG('c','h','p','l'), mov_read_chpl },
9320 { MKTAG('c','o','6','4'), mov_read_stco },
9321 { MKTAG('c','o','l','r'), mov_read_colr },
9322 { MKTAG('c','t','t','s'), mov_read_ctts }, /* composition time to sample */
9323 { MKTAG('d','i','n','f'), mov_read_default },
9324 { MKTAG('D','p','x','E'), mov_read_dpxe },
9325 { MKTAG('d','r','e','f'), mov_read_dref },
9326 { MKTAG('e','d','t','s'), mov_read_default },
9327 { MKTAG('e','l','s','t'), mov_read_elst },
9328 { MKTAG('e','n','d','a'), mov_read_enda },
9329 { MKTAG('f','i','e','l'), mov_read_fiel },
9330 { MKTAG('a','d','r','m'), mov_read_adrm },
9331 { MKTAG('f','t','y','p'), mov_read_ftyp },
9332 { MKTAG('g','l','b','l'), mov_read_glbl },
9333 { MKTAG('h','d','l','r'), mov_read_hdlr },
9334 { MKTAG('i','l','s','t'), mov_read_ilst },
9335 { MKTAG('j','p','2','h'), mov_read_jp2h },
9336 { MKTAG('m','d','a','t'), mov_read_mdat },
9337 { MKTAG('m','d','h','d'), mov_read_mdhd },
9338 { MKTAG('m','d','i','a'), mov_read_default },
9339 { MKTAG('m','e','t','a'), mov_read_meta },
9340 { MKTAG('m','i','n','f'), mov_read_default },
9341 { MKTAG('m','o','o','f'), mov_read_moof },
9342 { MKTAG('m','o','o','v'), mov_read_moov },
9343 { MKTAG('m','v','e','x'), mov_read_default },
9344 { MKTAG('m','v','h','d'), mov_read_mvhd },
9345 { MKTAG('S','M','I',' '), mov_read_svq3 },
9346 { MKTAG('a','l','a','c'), mov_read_alac }, /* alac specific atom */
9347 { MKTAG('a','v','c','C'), mov_read_glbl },
9348 { MKTAG('p','a','s','p'), mov_read_pasp },
9349 { MKTAG('c','l','a','p'), mov_read_clap },
9350 { MKTAG('s','b','a','s'), mov_read_sbas },
9351 { MKTAG('s','i','d','x'), mov_read_sidx },
9352 { MKTAG('s','t','b','l'), mov_read_default },
9353 { MKTAG('s','t','c','o'), mov_read_stco },
9354 { MKTAG('s','t','p','s'), mov_read_stps },
9355 { MKTAG('s','t','r','f'), mov_read_strf },
9356 { MKTAG('s','t','s','c'), mov_read_stsc },
9357 { MKTAG('s','t','s','d'), mov_read_stsd }, /* sample description */
9358 { MKTAG('s','t','s','s'), mov_read_stss }, /* sync sample */
9359 { MKTAG('s','t','s','z'), mov_read_stsz }, /* sample size */
9360 { MKTAG('s','t','t','s'), mov_read_stts },
9361 { MKTAG('s','t','z','2'), mov_read_stsz }, /* compact sample size */
9362 { MKTAG('s','d','t','p'), mov_read_sdtp }, /* independent and disposable samples */
9363 { MKTAG('t','k','h','d'), mov_read_tkhd }, /* track header */
9364 { MKTAG('t','f','d','t'), mov_read_tfdt },
9365 { MKTAG('t','f','h','d'), mov_read_tfhd }, /* track fragment header */
9366 { MKTAG('t','r','a','k'), mov_read_trak },
9367 { MKTAG('t','r','a','f'), mov_read_default },
9368 { MKTAG('t','r','e','f'), mov_read_default },
9369 { MKTAG('t','m','c','d'), mov_read_tmcd },
9370 { MKTAG('c','h','a','p'), mov_read_chap },
9371 { MKTAG('t','r','e','x'), mov_read_trex },
9372 { MKTAG('t','r','u','n'), mov_read_trun },
9373 { MKTAG('u','d','t','a'), mov_read_default },
9374 { MKTAG('w','a','v','e'), mov_read_wave },
9375 { MKTAG('e','s','d','s'), mov_read_esds },
9376 { MKTAG('d','a','c','3'), mov_read_dac3 }, /* AC-3 info */
9377 { MKTAG('d','e','c','3'), mov_read_dec3 }, /* EAC-3 info */
9378 { MKTAG('d','d','t','s'), mov_read_ddts }, /* DTS audio descriptor */
9379 { MKTAG('w','i','d','e'), mov_read_wide }, /* place holder */
9380 { MKTAG('w','f','e','x'), mov_read_wfex },
9381 { MKTAG('c','m','o','v'), mov_read_cmov },
9382 { MKTAG('c','h','a','n'), mov_read_chan }, /* channel layout from quicktime */
9383 { MKTAG('c','h','n','l'), mov_read_chnl }, /* channel layout from ISO-14496-12 */
9384 { MKTAG('d','v','c','1'), mov_read_dvc1 },
9385 { MKTAG('s','g','p','d'), mov_read_sgpd },
9386 { MKTAG('s','b','g','p'), mov_read_sbgp },
9387 { MKTAG('h','v','c','C'), mov_read_glbl },
9388 { MKTAG('v','v','c','C'), mov_read_glbl },
9389 { MKTAG('u','u','i','d'), mov_read_uuid },
9390 { MKTAG('C','i','n', 0x8e), mov_read_targa_y216 },
9391 { MKTAG('f','r','e','e'), mov_read_free },
9392 { MKTAG('-','-','-','-'), mov_read_custom },
9393 { MKTAG('s','i','n','f'), mov_read_default },
9394 { MKTAG('f','r','m','a'), mov_read_frma },
9395 { MKTAG('s','e','n','c'), mov_read_senc },
9396 { MKTAG('s','a','i','z'), mov_read_saiz },
9397 { MKTAG('s','a','i','o'), mov_read_saio },
9398 { MKTAG('p','s','s','h'), mov_read_pssh },
9399 { MKTAG('s','c','h','m'), mov_read_schm },
9400 { MKTAG('s','c','h','i'), mov_read_default },
9401 { MKTAG('t','e','n','c'), mov_read_tenc },
9402 { MKTAG('d','f','L','a'), mov_read_dfla },
9403 { MKTAG('s','t','3','d'), mov_read_st3d }, /* stereoscopic 3D video box */
9404 { MKTAG('s','v','3','d'), mov_read_sv3d }, /* spherical video box */
9405 { MKTAG('v','e','x','u'), mov_read_vexu }, /* video extension usage */
9406 { MKTAG('h','f','o','v'), mov_read_hfov },
9407 { MKTAG('d','O','p','s'), mov_read_dops },
9408 { MKTAG('d','m','l','p'), mov_read_dmlp },
9409 { MKTAG('S','m','D','m'), mov_read_smdm },
9410 { MKTAG('C','o','L','L'), mov_read_coll },
9411 { MKTAG('v','p','c','C'), mov_read_vpcc },
9412 { MKTAG('m','d','c','v'), mov_read_mdcv },
9413 { MKTAG('c','l','l','i'), mov_read_clli },
9414 { MKTAG('d','v','c','C'), mov_read_dvcc_dvvc },
9415 { MKTAG('d','v','v','C'), mov_read_dvcc_dvvc },
9416 { MKTAG('d','v','w','C'), mov_read_dvcc_dvvc },
9417 { MKTAG('k','i','n','d'), mov_read_kind },
9418 { MKTAG('S','A','3','D'), mov_read_SA3D }, /* ambisonic audio box */
9419 { MKTAG('S','A','N','D'), mov_read_SAND }, /* non diegetic audio box */
9420 { MKTAG('i','l','o','c'), mov_read_iloc },
9421 { MKTAG('p','c','m','C'), mov_read_pcmc }, /* PCM configuration box */
9422 { MKTAG('p','i','t','m'), mov_read_pitm },
9423 { MKTAG('e','v','c','C'), mov_read_glbl },
9424 { MKTAG('i','d','a','t'), mov_read_idat },
9425 { MKTAG('i','m','i','r'), mov_read_imir },
9426 { MKTAG('i','r','e','f'), mov_read_iref },
9427 { MKTAG('i','s','p','e'), mov_read_ispe },
9428 { MKTAG('i','r','o','t'), mov_read_irot },
9429 { MKTAG('i','p','r','p'), mov_read_iprp },
9430 { MKTAG('i','i','n','f'), mov_read_iinf },
9431 { MKTAG('a','m','v','e'), mov_read_amve }, /* ambient viewing environment box */
9432 { MKTAG('l','h','v','C'), mov_read_lhvc },
9433 { MKTAG('l','v','c','C'), mov_read_glbl },
9434 { MKTAG('a','p','v','C'), mov_read_glbl },
9435 #if CONFIG_IAMFDEC
9436 { MKTAG('i','a','c','b'), mov_read_iacb },
9437 #endif
9438 { 0, NULL }
9439 };
9440 
9442 {
9443  int64_t total_size = 0;
9444  MOVAtom a;
9445  int i;
9446 
9447  if (c->atom_depth > 10) {
9448  av_log(c->fc, AV_LOG_ERROR, "Atoms too deeply nested\n");
9449  return AVERROR_INVALIDDATA;
9450  }
9451  c->atom_depth ++;
9452 
9453  if (atom.size < 0)
9454  atom.size = INT64_MAX;
9455  while (total_size <= atom.size - 8) {
9456  int (*parse)(MOVContext*, AVIOContext*, MOVAtom) = NULL;
9457  a.size = avio_rb32(pb);
9458  a.type = avio_rl32(pb);
9459  if (avio_feof(pb))
9460  break;
9461  if (((a.type == MKTAG('f','r','e','e') && c->moov_retry) ||
9462  a.type == MKTAG('h','o','o','v')) &&
9463  a.size >= 8 &&
9464  c->fc->strict_std_compliance < FF_COMPLIANCE_STRICT) {
9465  uint32_t type;
9466  avio_skip(pb, 4);
9467  type = avio_rl32(pb);
9468  if (avio_feof(pb))
9469  break;
9470  avio_seek(pb, -8, SEEK_CUR);
9471  if (type == MKTAG('m','v','h','d') ||
9472  type == MKTAG('c','m','o','v')) {
9473  av_log(c->fc, AV_LOG_ERROR, "Detected moov in a free or hoov atom.\n");
9474  a.type = MKTAG('m','o','o','v');
9475  }
9476  }
9477  if (atom.type != MKTAG('r','o','o','t') &&
9478  atom.type != MKTAG('m','o','o','v')) {
9479  if (a.type == MKTAG('t','r','a','k') ||
9480  a.type == MKTAG('m','d','a','t')) {
9481  av_log(c->fc, AV_LOG_ERROR, "Broken file, trak/mdat not at top-level\n");
9482  avio_skip(pb, -8);
9483  c->atom_depth --;
9484  return 0;
9485  }
9486  }
9487  total_size += 8;
9488  if (a.size == 1 && total_size + 8 <= atom.size) { /* 64 bit extended size */
9489  a.size = avio_rb64(pb) - 8;
9490  total_size += 8;
9491  }
9492  av_log(c->fc, AV_LOG_TRACE, "type:'%s' parent:'%s' sz: %"PRId64" %"PRId64" %"PRId64"\n",
9493  av_fourcc2str(a.type), av_fourcc2str(atom.type), a.size, total_size, atom.size);
9494  if (a.size == 0) {
9495  a.size = atom.size - total_size + 8;
9496  }
9497  if (a.size < 0)
9498  break;
9499  a.size -= 8;
9500  if (a.size < 0)
9501  break;
9502  a.size = FFMIN(a.size, atom.size - total_size);
9503 
9504  for (i = 0; mov_default_parse_table[i].type; i++)
9505  if (mov_default_parse_table[i].type == a.type) {
9507  break;
9508  }
9509 
9510  // container is user data
9511  if (!parse && (atom.type == MKTAG('u','d','t','a') ||
9512  atom.type == MKTAG('i','l','s','t')))
9514 
9515  // Supports parsing the QuickTime Metadata Keys.
9516  // https://developer.apple.com/library/mac/documentation/QuickTime/QTFF/Metadata/Metadata.html
9517  if (!parse && c->found_hdlr_mdta &&
9518  atom.type == MKTAG('m','e','t','a') &&
9519  a.type == MKTAG('k','e','y','s') &&
9520  c->meta_keys_count == 0) {
9521  parse = mov_read_keys;
9522  }
9523 
9524  if (!parse) { /* skip leaf atoms data */
9525  avio_skip(pb, a.size);
9526  } else {
9527  int64_t start_pos = avio_tell(pb);
9528  int64_t left;
9529  int err = parse(c, pb, a);
9530  if (err < 0) {
9531  c->atom_depth --;
9532  return err;
9533  }
9534  if (c->found_moov && c->found_mdat && a.size <= INT64_MAX - start_pos &&
9535  ((!(pb->seekable & AVIO_SEEKABLE_NORMAL) || c->fc->flags & AVFMT_FLAG_IGNIDX || c->frag_index.complete) ||
9536  start_pos + a.size == avio_size(pb))) {
9537  if (!(pb->seekable & AVIO_SEEKABLE_NORMAL) || c->fc->flags & AVFMT_FLAG_IGNIDX || c->frag_index.complete)
9538  c->next_root_atom = start_pos + a.size;
9539  c->atom_depth --;
9540  return 0;
9541  }
9542  left = a.size - avio_tell(pb) + start_pos;
9543  if (left > 0) /* skip garbage at atom end */
9544  avio_skip(pb, left);
9545  else if (left < 0) {
9546  av_log(c->fc, AV_LOG_WARNING,
9547  "overread end of atom '%s' by %"PRId64" bytes\n",
9548  av_fourcc2str(a.type), -left);
9549  avio_seek(pb, left, SEEK_CUR);
9550  }
9551  }
9552 
9553  total_size += a.size;
9554  }
9555 
9556  if (total_size < atom.size && atom.size < 0x7ffff)
9557  avio_skip(pb, atom.size - total_size);
9558 
9559  c->atom_depth --;
9560  return 0;
9561 }
9562 
9563 static int mov_probe(const AVProbeData *p)
9564 {
9565  int64_t offset;
9566  uint32_t tag;
9567  int score = 0;
9568  int moov_offset = -1;
9569 
9570  /* check file header */
9571  offset = 0;
9572  for (;;) {
9573  int64_t size;
9574  int minsize = 8;
9575  /* ignore invalid offset */
9576  if ((offset + 8ULL) > (unsigned int)p->buf_size)
9577  break;
9578  size = AV_RB32(p->buf + offset);
9579  if (size == 1 && offset + 16 <= (unsigned int)p->buf_size) {
9580  size = AV_RB64(p->buf+offset + 8);
9581  minsize = 16;
9582  } else if (size == 0) {
9583  size = p->buf_size - offset;
9584  }
9585  if (size < minsize) {
9586  offset += 4;
9587  continue;
9588  }
9589  tag = AV_RL32(p->buf + offset + 4);
9590  switch(tag) {
9591  /* check for obvious tags */
9592  case MKTAG('m','o','o','v'):
9593  moov_offset = offset + 4;
9594  case MKTAG('m','d','a','t'):
9595  case MKTAG('p','n','o','t'): /* detect movs with preview pics like ew.mov and april.mov */
9596  case MKTAG('u','d','t','a'): /* Packet Video PVAuthor adds this and a lot of more junk */
9597  case MKTAG('f','t','y','p'):
9598  if (tag == MKTAG('f','t','y','p') &&
9599  ( AV_RL32(p->buf + offset + 8) == MKTAG('j','p','2',' ')
9600  || AV_RL32(p->buf + offset + 8) == MKTAG('j','p','x',' ')
9601  || AV_RL32(p->buf + offset + 8) == MKTAG('j','x','l',' ')
9602  )) {
9603  score = FFMAX(score, 5);
9604  } else {
9605  score = AVPROBE_SCORE_MAX;
9606  }
9607  break;
9608  /* those are more common words, so rate then a bit less */
9609  case MKTAG('e','d','i','w'): /* xdcam files have reverted first tags */
9610  case MKTAG('w','i','d','e'):
9611  case MKTAG('f','r','e','e'):
9612  case MKTAG('j','u','n','k'):
9613  case MKTAG('p','i','c','t'):
9614  score = FFMAX(score, AVPROBE_SCORE_MAX - 5);
9615  break;
9616  case MKTAG(0x82,0x82,0x7f,0x7d):
9617  score = FFMAX(score, AVPROBE_SCORE_EXTENSION - 5);
9618  break;
9619  case MKTAG('s','k','i','p'):
9620  case MKTAG('u','u','i','d'):
9621  case MKTAG('p','r','f','l'):
9622  /* if we only find those cause probedata is too small at least rate them */
9623  score = FFMAX(score, AVPROBE_SCORE_EXTENSION);
9624  break;
9625  }
9626  if (size > INT64_MAX - offset)
9627  break;
9628  offset += size;
9629  }
9630  if (score > AVPROBE_SCORE_MAX - 50 && moov_offset != -1) {
9631  /* moov atom in the header - we should make sure that this is not a
9632  * MOV-packed MPEG-PS */
9633  offset = moov_offset;
9634 
9635  while (offset < (p->buf_size - 16)) { /* Sufficient space */
9636  /* We found an actual hdlr atom */
9637  if (AV_RL32(p->buf + offset ) == MKTAG('h','d','l','r') &&
9638  AV_RL32(p->buf + offset + 8) == MKTAG('m','h','l','r') &&
9639  AV_RL32(p->buf + offset + 12) == MKTAG('M','P','E','G')) {
9640  av_log(NULL, AV_LOG_WARNING, "Found media data tag MPEG indicating this is a MOV-packed MPEG-PS.\n");
9641  /* We found a media handler reference atom describing an
9642  * MPEG-PS-in-MOV, return a
9643  * low score to force expanding the probe window until
9644  * mpegps_probe finds what it needs */
9645  return 5;
9646  } else {
9647  /* Keep looking */
9648  offset += 2;
9649  }
9650  }
9651  }
9652 
9653  return score;
9654 }
9655 
9656 // must be done after parsing all trak because there's no order requirement
9658 {
9659  MOVContext *mov = s->priv_data;
9660  MOVStreamContext *sc;
9661  int64_t cur_pos;
9662  int i, j;
9663  int chapter_track;
9664 
9665  for (j = 0; j < mov->nb_chapter_tracks; j++) {
9666  AVStream *st = NULL;
9667  FFStream *sti = NULL;
9668  chapter_track = mov->chapter_tracks[j];
9669  for (i = 0; i < s->nb_streams; i++) {
9670  sc = mov->fc->streams[i]->priv_data;
9671  if (sc->id == chapter_track) {
9672  st = s->streams[i];
9673  break;
9674  }
9675  }
9676  if (!st) {
9677  av_log(s, AV_LOG_ERROR, "Referenced QT chapter track not found\n");
9678  continue;
9679  }
9680  sti = ffstream(st);
9681 
9682  sc = st->priv_data;
9683  cur_pos = avio_tell(sc->pb);
9684 
9685  if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
9687  if (!st->attached_pic.data && sti->nb_index_entries) {
9688  // Retrieve the first frame, if possible
9689  AVIndexEntry *sample = &sti->index_entries[0];
9690  if (avio_seek(sc->pb, sample->pos, SEEK_SET) != sample->pos) {
9691  av_log(s, AV_LOG_ERROR, "Failed to retrieve first frame\n");
9692  goto finish;
9693  }
9694 
9695  if (ff_add_attached_pic(s, st, sc->pb, NULL, sample->size) < 0)
9696  goto finish;
9697  }
9698  } else {
9701  st->discard = AVDISCARD_ALL;
9702  for (int i = 0; i < sti->nb_index_entries; i++) {
9703  AVIndexEntry *sample = &sti->index_entries[i];
9704  int64_t end = i+1 < sti->nb_index_entries ? sti->index_entries[i+1].timestamp : st->duration;
9705  uint8_t *title;
9706  uint16_t ch;
9707  int len, title_len;
9708 
9709  if (end < sample->timestamp) {
9710  av_log(s, AV_LOG_WARNING, "ignoring stream duration which is shorter than chapters\n");
9711  end = AV_NOPTS_VALUE;
9712  }
9713 
9714  if (avio_seek(sc->pb, sample->pos, SEEK_SET) != sample->pos) {
9715  av_log(s, AV_LOG_ERROR, "Chapter %d not found in file\n", i);
9716  goto finish;
9717  }
9718 
9719  // the first two bytes are the length of the title
9720  len = avio_rb16(sc->pb);
9721  if (len > sample->size-2)
9722  continue;
9723  title_len = 2*len + 1;
9724  if (!(title = av_mallocz(title_len)))
9725  goto finish;
9726 
9727  // The samples could theoretically be in any encoding if there's an encd
9728  // atom following, but in practice are only utf-8 or utf-16, distinguished
9729  // instead by the presence of a BOM
9730  if (!len) {
9731  title[0] = 0;
9732  } else {
9733  ch = avio_rb16(sc->pb);
9734  if (ch == 0xfeff)
9735  avio_get_str16be(sc->pb, len, title, title_len);
9736  else if (ch == 0xfffe)
9737  avio_get_str16le(sc->pb, len, title, title_len);
9738  else {
9739  AV_WB16(title, ch);
9740  if (len == 1 || len == 2)
9741  title[len] = 0;
9742  else
9743  avio_get_str(sc->pb, INT_MAX, title + 2, len - 1);
9744  }
9745  }
9746 
9747  avpriv_new_chapter(s, i, st->time_base, sample->timestamp, end, title);
9748  av_freep(&title);
9749  }
9750  }
9751 finish:
9752  avio_seek(sc->pb, cur_pos, SEEK_SET);
9753  }
9754 }
9755 
9757  int64_t value, int flags)
9758 {
9759  AVTimecode tc;
9760  char buf[AV_TIMECODE_STR_SIZE];
9761  AVRational rate = st->avg_frame_rate;
9762  int ret = av_timecode_init(&tc, rate, flags, 0, s);
9763  if (ret < 0)
9764  return ret;
9765  av_dict_set(&st->metadata, "timecode",
9766  av_timecode_make_string(&tc, buf, value), 0);
9767  return 0;
9768 }
9769 
9771 {
9772  MOVStreamContext *sc = st->priv_data;
9773  FFStream *const sti = ffstream(st);
9774  char buf[AV_TIMECODE_STR_SIZE];
9775  int64_t cur_pos = avio_tell(sc->pb);
9776  int hh, mm, ss, ff, drop;
9777 
9778  if (!sti->nb_index_entries)
9779  return -1;
9780 
9781  avio_seek(sc->pb, sti->index_entries->pos, SEEK_SET);
9782  avio_skip(s->pb, 13);
9783  hh = avio_r8(s->pb);
9784  mm = avio_r8(s->pb);
9785  ss = avio_r8(s->pb);
9786  drop = avio_r8(s->pb);
9787  ff = avio_r8(s->pb);
9788  snprintf(buf, AV_TIMECODE_STR_SIZE, "%02d:%02d:%02d%c%02d",
9789  hh, mm, ss, drop ? ';' : ':', ff);
9790  av_dict_set(&st->metadata, "timecode", buf, 0);
9791 
9792  avio_seek(sc->pb, cur_pos, SEEK_SET);
9793  return 0;
9794 }
9795 
9797 {
9798  MOVStreamContext *sc = st->priv_data;
9799  FFStream *const sti = ffstream(st);
9800  int flags = 0;
9801  int64_t cur_pos = avio_tell(sc->pb);
9802  int64_t value;
9803  AVRational tc_rate = st->avg_frame_rate;
9804  int tmcd_nb_frames = sc->tmcd_nb_frames;
9805  int rounded_tc_rate;
9806 
9807  if (!sti->nb_index_entries)
9808  return -1;
9809 
9810  if (!tc_rate.num || !tc_rate.den || !tmcd_nb_frames)
9811  return -1;
9812 
9813  avio_seek(sc->pb, sti->index_entries->pos, SEEK_SET);
9814  value = avio_rb32(s->pb);
9815 
9816  if (sc->tmcd_flags & 0x0001) flags |= AV_TIMECODE_FLAG_DROPFRAME;
9817  if (sc->tmcd_flags & 0x0002) flags |= AV_TIMECODE_FLAG_24HOURSMAX;
9818  if (sc->tmcd_flags & 0x0004) flags |= AV_TIMECODE_FLAG_ALLOWNEGATIVE;
9819 
9820  /* Assume Counter flag is set to 1 in tmcd track (even though it is likely
9821  * not the case) and thus assume "frame number format" instead of QT one.
9822  * No sample with tmcd track can be found with a QT timecode at the moment,
9823  * despite what the tmcd track "suggests" (Counter flag set to 0 means QT
9824  * format). */
9825 
9826  /* 60 fps content have tmcd_nb_frames set to 30 but tc_rate set to 60, so
9827  * we multiply the frame number with the quotient.
9828  * See tickets #9492, #9710. */
9829  rounded_tc_rate = (tc_rate.num + tc_rate.den / 2LL) / tc_rate.den;
9830  /* Work around files where tmcd_nb_frames is rounded down from frame rate
9831  * instead of up. See ticket #5978. */
9832  if (tmcd_nb_frames == tc_rate.num / tc_rate.den &&
9833  s->strict_std_compliance < FF_COMPLIANCE_STRICT)
9834  tmcd_nb_frames = rounded_tc_rate;
9835  value = av_rescale(value, rounded_tc_rate, tmcd_nb_frames);
9836 
9838 
9839  avio_seek(sc->pb, cur_pos, SEEK_SET);
9840  return 0;
9841 }
9842 
9844  int i;
9845  if (!index || !*index) return;
9846  for (i = 0; i < (*index)->nb_encrypted_samples; i++) {
9847  av_encryption_info_free((*index)->encrypted_samples[i]);
9848  }
9849  av_freep(&(*index)->encrypted_samples);
9850  av_freep(&(*index)->auxiliary_info_sizes);
9851  av_freep(&(*index)->auxiliary_offsets);
9852  av_freep(index);
9853 }
9854 
9856 {
9857  MOVStreamContext *sc = st->priv_data;
9858 
9859  if (!sc || --sc->refcount) {
9860  st->priv_data = NULL;
9861  return;
9862  }
9863 
9864  av_freep(&sc->tts_data);
9865  for (int i = 0; i < sc->drefs_count; i++) {
9866  av_freep(&sc->drefs[i].path);
9867  av_freep(&sc->drefs[i].dir);
9868  }
9869  av_freep(&sc->drefs);
9870 
9871  sc->drefs_count = 0;
9872 
9873  if (!sc->pb_is_copied)
9874  ff_format_io_close(s, &sc->pb);
9875 
9876  sc->pb = NULL;
9877  av_freep(&sc->chunk_offsets);
9878  av_freep(&sc->stsc_data);
9879  av_freep(&sc->sample_sizes);
9880  av_freep(&sc->keyframes);
9881  av_freep(&sc->ctts_data);
9882  av_freep(&sc->stts_data);
9883  av_freep(&sc->sdtp_data);
9884  av_freep(&sc->stps_data);
9885  av_freep(&sc->elst_data);
9886  av_freep(&sc->rap_group);
9887  av_freep(&sc->sync_group);
9888  av_freep(&sc->sgpd_sync);
9889  av_freep(&sc->sample_offsets);
9890  av_freep(&sc->open_key_samples);
9891  av_freep(&sc->display_matrix);
9892  av_freep(&sc->index_ranges);
9893 
9894  if (sc->extradata)
9895  for (int i = 0; i < sc->stsd_count; i++)
9896  av_free(sc->extradata[i]);
9897  av_freep(&sc->extradata);
9898  av_freep(&sc->extradata_size);
9899 
9903 
9904  av_freep(&sc->stereo3d);
9905  av_freep(&sc->spherical);
9906  av_freep(&sc->mastering);
9907  av_freep(&sc->coll);
9908  av_freep(&sc->ambient);
9909 
9910 #if CONFIG_IAMFDEC
9911  if (sc->iamf)
9913 #endif
9914  av_freep(&sc->iamf);
9915 }
9916 
9918 {
9919  MOVContext *mov = s->priv_data;
9920  int i, j;
9921 
9922  for (i = 0; i < s->nb_streams; i++) {
9923  AVStream *st = s->streams[i];
9924 
9926  }
9927 
9928  av_freep(&mov->dv_demux);
9930  mov->dv_fctx = NULL;
9931 
9932  if (mov->meta_keys) {
9933  for (i = 1; i < mov->meta_keys_count; i++) {
9934  av_freep(&mov->meta_keys[i]);
9935  }
9936  av_freep(&mov->meta_keys);
9937  }
9938 
9939  av_freep(&mov->trex_data);
9940  av_freep(&mov->bitrates);
9941 
9942  for (i = 0; i < mov->frag_index.nb_items; i++) {
9944  for (j = 0; j < mov->frag_index.item[i].nb_stream_info; j++) {
9945  mov_free_encryption_index(&frag[j].encryption_index);
9946  }
9948  }
9949  av_freep(&mov->frag_index.item);
9950 
9951  av_freep(&mov->aes_decrypt);
9952  av_freep(&mov->chapter_tracks);
9953  for (i = 0; i < mov->nb_heif_item; i++) {
9954  if (!mov->heif_item[i])
9955  continue;
9956  av_freep(&mov->heif_item[i]->name);
9957  av_freep(&mov->heif_item[i]->icc_profile);
9958  av_freep(&mov->heif_item[i]);
9959  }
9960  av_freep(&mov->heif_item);
9961  for (i = 0; i < mov->nb_heif_grid; i++) {
9962  av_freep(&mov->heif_grid[i].tile_id_list);
9965  }
9966  av_freep(&mov->heif_grid);
9967  av_freep(&mov->thmb_item_id);
9968 
9969  return 0;
9970 }
9971 
9972 static int tmcd_is_referenced(AVFormatContext *s, int tmcd_id)
9973 {
9974  int i;
9975 
9976  for (i = 0; i < s->nb_streams; i++) {
9977  AVStream *st = s->streams[i];
9978  MOVStreamContext *sc = st->priv_data;
9979 
9980  if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO &&
9981  sc->timecode_track == tmcd_id)
9982  return 1;
9983  }
9984  return 0;
9985 }
9986 
9987 /* look for a tmcd track not referenced by any video track, and export it globally */
9989 {
9990  int i;
9991 
9992  for (i = 0; i < s->nb_streams; i++) {
9993  AVStream *st = s->streams[i];
9994 
9995  if (st->codecpar->codec_tag == MKTAG('t','m','c','d') &&
9996  !tmcd_is_referenced(s, i + 1)) {
9997  AVDictionaryEntry *tcr = av_dict_get(st->metadata, "timecode", NULL, 0);
9998  if (tcr) {
9999  av_dict_set(&s->metadata, "timecode", tcr->value, 0);
10000  break;
10001  }
10002  }
10003  }
10004 }
10005 
10006 static int read_tfra(MOVContext *mov, AVIOContext *f)
10007 {
10008  int version, fieldlength, i, j;
10009  int64_t pos = avio_tell(f);
10010  uint32_t size = avio_rb32(f);
10011  unsigned track_id, item_count;
10012 
10013  if (avio_rb32(f) != MKBETAG('t', 'f', 'r', 'a')) {
10014  return 1;
10015  }
10016  av_log(mov->fc, AV_LOG_VERBOSE, "found tfra\n");
10017 
10018  version = avio_r8(f);
10019  avio_rb24(f);
10020  track_id = avio_rb32(f);
10021  fieldlength = avio_rb32(f);
10022  item_count = avio_rb32(f);
10023  for (i = 0; i < item_count; i++) {
10024  int64_t time, offset;
10025  int index;
10026  MOVFragmentStreamInfo * frag_stream_info;
10027 
10028  if (avio_feof(f)) {
10029  return AVERROR_INVALIDDATA;
10030  }
10031 
10032  if (version == 1) {
10033  time = avio_rb64(f);
10034  offset = avio_rb64(f);
10035  } else {
10036  time = avio_rb32(f);
10037  offset = avio_rb32(f);
10038  }
10039 
10040  // The first sample of each stream in a fragment is always a random
10041  // access sample. So it's entry in the tfra can be used as the
10042  // initial PTS of the fragment.
10043  index = update_frag_index(mov, offset);
10044  frag_stream_info = get_frag_stream_info(&mov->frag_index, index, track_id);
10045  if (frag_stream_info &&
10046  frag_stream_info->first_tfra_pts == AV_NOPTS_VALUE)
10047  frag_stream_info->first_tfra_pts = time;
10048 
10049  for (j = 0; j < ((fieldlength >> 4) & 3) + 1; j++)
10050  avio_r8(f);
10051  for (j = 0; j < ((fieldlength >> 2) & 3) + 1; j++)
10052  avio_r8(f);
10053  for (j = 0; j < ((fieldlength >> 0) & 3) + 1; j++)
10054  avio_r8(f);
10055  }
10056 
10057  avio_seek(f, pos + size, SEEK_SET);
10058  return 0;
10059 }
10060 
10062 {
10063  int64_t stream_size = avio_size(f);
10064  int64_t original_pos = avio_tell(f);
10065  int64_t seek_ret;
10066  int ret = -1;
10067  if ((seek_ret = avio_seek(f, stream_size - 4, SEEK_SET)) < 0) {
10068  ret = seek_ret;
10069  goto fail;
10070  }
10071  c->mfra_size = avio_rb32(f);
10072  c->have_read_mfra_size = 1;
10073  if (!c->mfra_size || c->mfra_size > stream_size) {
10074  av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (unreasonable size)\n");
10075  goto fail;
10076  }
10077  if ((seek_ret = avio_seek(f, -((int64_t) c->mfra_size), SEEK_CUR)) < 0) {
10078  ret = seek_ret;
10079  goto fail;
10080  }
10081  if (avio_rb32(f) != c->mfra_size) {
10082  av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (size mismatch)\n");
10083  goto fail;
10084  }
10085  if (avio_rb32(f) != MKBETAG('m', 'f', 'r', 'a')) {
10086  av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (tag mismatch)\n");
10087  goto fail;
10088  }
10089  av_log(c->fc, AV_LOG_VERBOSE, "stream has mfra\n");
10090  do {
10091  ret = read_tfra(c, f);
10092  if (ret < 0)
10093  goto fail;
10094  } while (!ret);
10095  ret = 0;
10096  c->frag_index.complete = 1;
10097 fail:
10098  seek_ret = avio_seek(f, original_pos, SEEK_SET);
10099  if (seek_ret < 0) {
10100  av_log(c->fc, AV_LOG_ERROR,
10101  "failed to seek back after looking for mfra\n");
10102  ret = seek_ret;
10103  }
10104  return ret;
10105 }
10106 
10107 static int set_icc_profile_from_item(AVPacketSideData **coded_side_data, int *nb_coded_side_data,
10108  const HEIFItem *item)
10109 {
10110  AVPacketSideData *sd = av_packet_side_data_new(coded_side_data, nb_coded_side_data,
10112  item->icc_profile_size, 0);
10113  if (!sd)
10114  return AVERROR(ENOMEM);
10115 
10116  memcpy(sd->data, item->icc_profile, item->icc_profile_size);
10117 
10118  return 0;
10119 }
10120 
10121 static int set_display_matrix_from_item(AVPacketSideData **coded_side_data, int *nb_coded_side_data,
10122  const HEIFItem *item)
10123 {
10124  int32_t *matrix;
10125  AVPacketSideData *sd = av_packet_side_data_new(coded_side_data,
10126  nb_coded_side_data,
10128  9 * sizeof(*matrix), 0);
10129  if (!sd)
10130  return AVERROR(ENOMEM);
10131 
10132  matrix = (int32_t*)sd->data;
10133  /* rotation is in the counter-clockwise direction whereas
10134  * av_display_rotation_set() expects its argument to be
10135  * oriented clockwise, so we need to negate it. */
10137  av_display_matrix_flip(matrix, item->hflip, item->vflip);
10138 
10139  return 0;
10140 }
10141 
10142 static int read_image_grid(AVFormatContext *s, const HEIFGrid *grid,
10143  AVStreamGroupTileGrid *tile_grid)
10144 {
10145  MOVContext *c = s->priv_data;
10146  const HEIFItem *item = grid->item;
10147  int64_t offset = 0, pos = avio_tell(s->pb);
10148  int x = 0, y = 0, i = 0;
10149  int tile_rows, tile_cols;
10150  int flags, size;
10151 
10152  if (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL)) {
10153  av_log(c->fc, AV_LOG_INFO, "grid box with non seekable input\n");
10154  return AVERROR_PATCHWELCOME;
10155  }
10156  if (item->is_idat_relative) {
10157  if (!c->idat_offset) {
10158  av_log(c->fc, AV_LOG_ERROR, "missing idat box required by the image grid\n");
10159  return AVERROR_INVALIDDATA;
10160  }
10161  offset = c->idat_offset;
10162  }
10163 
10164  avio_seek(s->pb, item->extent_offset + offset, SEEK_SET);
10165 
10166  avio_r8(s->pb); /* version */
10167  flags = avio_r8(s->pb);
10168 
10169  tile_rows = avio_r8(s->pb) + 1;
10170  tile_cols = avio_r8(s->pb) + 1;
10171  /* actual width and height of output image */
10172  tile_grid->width = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
10173  tile_grid->height = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
10174 
10175  /* ICC profile */
10176  if (item->icc_profile_size) {
10177  int ret = set_icc_profile_from_item(&tile_grid->coded_side_data,
10178  &tile_grid->nb_coded_side_data, item);
10179  if (ret < 0)
10180  return ret;
10181  }
10182  /* rotation */
10183  if (item->rotation || item->hflip || item->vflip) {
10185  &tile_grid->nb_coded_side_data, item);
10186  if (ret < 0)
10187  return ret;
10188  }
10189 
10190  av_log(c->fc, AV_LOG_TRACE, "grid: grid_rows %d grid_cols %d output_width %d output_height %d\n",
10191  tile_rows, tile_cols, tile_grid->width, tile_grid->height);
10192 
10193  avio_seek(s->pb, pos, SEEK_SET);
10194 
10195  size = tile_rows * tile_cols;
10196  tile_grid->nb_tiles = grid->nb_tiles;
10197 
10198  if (tile_grid->nb_tiles != size)
10199  return AVERROR_INVALIDDATA;
10200 
10201  for (int i = 0; i < tile_cols; i++)
10202  tile_grid->coded_width += grid->tile_item_list[i]->width;
10203  for (int i = 0; i < size; i += tile_cols)
10204  tile_grid->coded_height += grid->tile_item_list[i]->height;
10205 
10206  tile_grid->offsets = av_calloc(tile_grid->nb_tiles, sizeof(*tile_grid->offsets));
10207  if (!tile_grid->offsets)
10208  return AVERROR(ENOMEM);
10209 
10210  while (y < tile_grid->coded_height) {
10211  int left_col = i;
10212 
10213  while (x < tile_grid->coded_width) {
10214  if (i == tile_grid->nb_tiles)
10215  return AVERROR_INVALIDDATA;
10216 
10217  tile_grid->offsets[i].idx = grid->tile_idx_list[i];
10218  tile_grid->offsets[i].horizontal = x;
10219  tile_grid->offsets[i].vertical = y;
10220 
10221  x += grid->tile_item_list[i++]->width;
10222  }
10223 
10224  if (x > tile_grid->coded_width) {
10225  av_log(c->fc, AV_LOG_ERROR, "Non uniform HEIF tiles\n");
10226  return AVERROR_INVALIDDATA;
10227  }
10228 
10229  x = 0;
10230  y += grid->tile_item_list[left_col]->height;
10231  }
10232 
10233  if (y > tile_grid->coded_height || i != tile_grid->nb_tiles) {
10234  av_log(c->fc, AV_LOG_ERROR, "Non uniform HEIF tiles\n");
10235  return AVERROR_INVALIDDATA;
10236  }
10237 
10238  return 0;
10239 }
10240 
10241 static int read_image_iovl(AVFormatContext *s, const HEIFGrid *grid,
10242  AVStreamGroupTileGrid *tile_grid)
10243 {
10244  MOVContext *c = s->priv_data;
10245  const HEIFItem *item = grid->item;
10246  uint16_t canvas_fill_value[4];
10247  int64_t offset = 0, pos = avio_tell(s->pb);
10248  int ret = 0, flags;
10249 
10250  if (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL)) {
10251  av_log(c->fc, AV_LOG_INFO, "iovl box with non seekable input\n");
10252  return AVERROR_PATCHWELCOME;
10253  }
10254  if (item->is_idat_relative) {
10255  if (!c->idat_offset) {
10256  av_log(c->fc, AV_LOG_ERROR, "missing idat box required by the image overlay\n");
10257  return AVERROR_INVALIDDATA;
10258  }
10259  offset = c->idat_offset;
10260  }
10261 
10262  avio_seek(s->pb, item->extent_offset + offset, SEEK_SET);
10263 
10264  avio_r8(s->pb); /* version */
10265  flags = avio_r8(s->pb);
10266 
10267  for (int i = 0; i < 4; i++)
10268  canvas_fill_value[i] = avio_rb16(s->pb);
10269  av_log(c->fc, AV_LOG_TRACE, "iovl: canvas_fill_value { %u, %u, %u, %u }\n",
10270  canvas_fill_value[0], canvas_fill_value[1],
10271  canvas_fill_value[2], canvas_fill_value[3]);
10272  for (int i = 0; i < 4; i++)
10273  tile_grid->background[i] = canvas_fill_value[i];
10274 
10275  /* actual width and height of output image */
10276  tile_grid->width =
10277  tile_grid->coded_width = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
10278  tile_grid->height =
10279  tile_grid->coded_height = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
10280 
10281  /* rotation */
10282  if (item->rotation || item->hflip || item->vflip) {
10284  &tile_grid->nb_coded_side_data, item);
10285  if (ret < 0)
10286  return ret;
10287  }
10288 
10289  /* ICC profile */
10290  if (item->icc_profile_size) {
10291  int ret = set_icc_profile_from_item(&tile_grid->coded_side_data,
10292  &tile_grid->nb_coded_side_data, item);
10293  if (ret < 0)
10294  return ret;
10295  }
10296 
10297  av_log(c->fc, AV_LOG_TRACE, "iovl: output_width %d, output_height %d\n",
10298  tile_grid->width, tile_grid->height);
10299 
10300  tile_grid->nb_tiles = grid->nb_tiles;
10301  tile_grid->offsets = av_malloc_array(tile_grid->nb_tiles, sizeof(*tile_grid->offsets));
10302  if (!tile_grid->offsets) {
10303  ret = AVERROR(ENOMEM);
10304  goto fail;
10305  }
10306 
10307  for (int i = 0; i < tile_grid->nb_tiles; i++) {
10308  tile_grid->offsets[i].idx = grid->tile_idx_list[i];
10309  tile_grid->offsets[i].horizontal = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
10310  tile_grid->offsets[i].vertical = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
10311  av_log(c->fc, AV_LOG_TRACE, "iovl: stream_idx[%d] %u, "
10312  "horizontal_offset[%d] %d, vertical_offset[%d] %d\n",
10313  i, tile_grid->offsets[i].idx,
10314  i, tile_grid->offsets[i].horizontal, i, tile_grid->offsets[i].vertical);
10315  }
10316 
10317 fail:
10318  avio_seek(s->pb, pos, SEEK_SET);
10319 
10320  return ret;
10321 }
10322 
10324 {
10325  MOVContext *mov = s->priv_data;
10326 
10327  for (int i = 0; i < mov->nb_heif_grid; i++) {
10329  AVStreamGroupTileGrid *tile_grid;
10330  const HEIFGrid *grid = &mov->heif_grid[i];
10331  int err, loop = 1;
10332 
10333  if (!stg)
10334  return AVERROR(ENOMEM);
10335 
10336  stg->id = grid->item->item_id;
10337  tile_grid = stg->params.tile_grid;
10338 
10339  for (int j = 0; j < grid->nb_tiles; j++) {
10340  int tile_id = grid->tile_id_list[j];
10341  int k;
10342 
10343  for (k = 0; k < mov->nb_heif_item; k++) {
10344  HEIFItem *item = mov->heif_item[k];
10345  AVStream *st;
10346 
10347  if (!item || item->item_id != tile_id)
10348  continue;
10349  st = item->st;
10350  if (!st) {
10351  av_log(s, AV_LOG_WARNING, "HEIF item id %d from grid id %d doesn't "
10352  "reference a stream\n",
10353  tile_id, grid->item->item_id);
10354  ff_remove_stream_group(s, stg);
10355  loop = 0;
10356  break;
10357  }
10358 
10359  grid->tile_item_list[j] = item;
10360  grid->tile_idx_list[j] = stg->nb_streams;
10361 
10362  err = avformat_stream_group_add_stream(stg, st);
10363  if (err < 0) {
10364  int l;
10365  if (err != AVERROR(EEXIST))
10366  return err;
10367 
10368  for (l = 0; l < stg->nb_streams; l++)
10369  if (stg->streams[l]->index == st->index)
10370  break;
10371  av_assert0(l < stg->nb_streams);
10372  grid->tile_idx_list[j] = l;
10373  }
10374 
10375  if (item->item_id != mov->primary_item_id)
10377  break;
10378  }
10379 
10380  if (k == mov->nb_heif_item) {
10381  av_assert0(loop);
10382  av_log(s, AV_LOG_WARNING, "HEIF item id %d referenced by grid id %d doesn't "
10383  "exist\n",
10384  tile_id, grid->item->item_id);
10385  ff_remove_stream_group(s, stg);
10386  loop = 0;
10387  }
10388  if (!loop)
10389  break;
10390  }
10391 
10392  if (!loop)
10393  continue;
10394 
10395  switch (grid->item->type) {
10396  case MKTAG('g','r','i','d'):
10397  err = read_image_grid(s, grid, tile_grid);
10398  break;
10399  case MKTAG('i','o','v','l'):
10400  err = read_image_iovl(s, grid, tile_grid);
10401  break;
10402  default:
10403  av_assert0(0);
10404  }
10405  if (err < 0)
10406  return err;
10407 
10408 
10409  if (grid->item->name)
10410  av_dict_set(&stg->metadata, "title", grid->item->name, 0);
10411  if (grid->item->item_id == mov->primary_item_id)
10413  }
10414 
10415  return 0;
10416 }
10417 
10419 {
10420  MOVContext *mov = s->priv_data;
10421  int err;
10422 
10423  for (int i = 0; i < mov->nb_heif_item; i++) {
10424  HEIFItem *item = mov->heif_item[i];
10425  MOVStreamContext *sc;
10426  AVStream *st;
10427  int64_t offset = 0;
10428 
10429  if (!item)
10430  continue;
10431  if (!item->st) {
10432  for (int j = 0; j < mov->nb_thmb_item; j++) {
10433  if (item->item_id == mov->thmb_item_id[j]) {
10434  av_log(s, AV_LOG_ERROR, "HEIF thumbnail ID %d doesn't reference a stream\n",
10435  item->item_id);
10436  return AVERROR_INVALIDDATA;
10437  }
10438  }
10439  continue;
10440  }
10441  if (item->is_idat_relative) {
10442  if (!mov->idat_offset) {
10443  av_log(s, AV_LOG_ERROR, "Missing idat box for item %d\n", item->item_id);
10444  return AVERROR_INVALIDDATA;
10445  }
10446  offset = mov->idat_offset;
10447  }
10448 
10449  st = item->st;
10450  sc = st->priv_data;
10451  st->codecpar->width = item->width;
10452  st->codecpar->height = item->height;
10453 
10454  err = sanity_checks(s, sc, item->item_id);
10455  if (err || !sc->sample_count)
10456  return AVERROR_INVALIDDATA;
10457 
10458  sc->sample_sizes[0] = item->extent_length;
10459  sc->chunk_offsets[0] = item->extent_offset + offset;
10460 
10461  if (item->item_id == mov->primary_item_id)
10463 
10464  if (item->rotation || item->hflip || item->vflip) {
10466  &st->codecpar->nb_coded_side_data, item);
10467  if (err < 0)
10468  return err;
10469  }
10470 
10471  mov_build_index(mov, st);
10472  }
10473 
10474  if (mov->nb_heif_grid) {
10475  err = mov_parse_tiles(s);
10476  if (err < 0)
10477  return err;
10478  }
10479 
10480  return 0;
10481 }
10482 
10484  int first_index)
10485 {
10486  MOVStreamContext *sc = st->priv_data;
10487 
10488  if (sc->tref_id < 0)
10489  return NULL;
10490 
10491  for (int i = first_index; i < s->nb_streams; i++)
10492  if (s->streams[i]->id == sc->tref_id)
10493  return s->streams[i];
10494 
10495  return NULL;
10496 }
10497 
10499 {
10500  int err;
10501 
10502  for (int i = 0; i < s->nb_streams; i++) {
10503  AVStreamGroup *stg;
10504  AVStream *st = s->streams[i];
10505  AVStream *st_base;
10506  MOVStreamContext *sc = st->priv_data;
10507  int j = 0;
10508 
10509  /* Find an enhancement stream. */
10510  if (st->codecpar->codec_id != AV_CODEC_ID_LCEVC ||
10512  continue;
10513 
10515 
10517  if (!stg)
10518  return AVERROR(ENOMEM);
10519 
10520  stg->id = st->id;
10521  stg->params.lcevc->width = st->codecpar->width;
10522  stg->params.lcevc->height = st->codecpar->height;
10523  st->codecpar->width = 0;
10524  st->codecpar->height = 0;
10525 
10526  while (st_base = mov_find_reference_track(s, st, j)) {
10527  err = avformat_stream_group_add_stream(stg, st_base);
10528  if (err < 0)
10529  return err;
10530 
10531  j = st_base->index + 1;
10532  }
10533  if (!j) {
10534  av_log(s, AV_LOG_ERROR, "Failed to find base stream for enhancement stream\n");
10535  return AVERROR_INVALIDDATA;
10536  }
10537 
10538  err = avformat_stream_group_add_stream(stg, st);
10539  if (err < 0)
10540  return err;
10541 
10542  stg->params.lcevc->lcevc_index = stg->nb_streams - 1;
10543  }
10544 
10545  return 0;
10546 }
10547 
10549 {
10550  int highest_id = 0;
10551 
10552  for (int i = 0; i < s->nb_streams; i++) {
10553  const AVStream *st = s->streams[i];
10554  const MOVStreamContext *sc = st->priv_data;
10555  if (!sc->iamf)
10556  highest_id = FFMAX(highest_id, st->id);
10557  }
10558  highest_id += !highest_id;
10559  for (int i = 0; highest_id > 1 && i < s->nb_stream_groups; i++) {
10560  AVStreamGroup *stg = s->stream_groups[i];
10562  continue;
10563  for (int j = 0; j < stg->nb_streams; j++) {
10564  AVStream *st = stg->streams[j];
10565  MOVStreamContext *sc = st->priv_data;
10566  st->id += highest_id;
10567  sc->iamf_stream_offset = highest_id;
10568  }
10569  }
10570 }
10571 
10573 {
10574  MOVContext *mov = s->priv_data;
10575  AVIOContext *pb = s->pb;
10576  int j, err;
10577  MOVAtom atom = { AV_RL32("root") };
10578  int i;
10579 
10580  if (mov->decryption_key_len != 0 && mov->decryption_key_len != AES_CTR_KEY_SIZE) {
10581  av_log(s, AV_LOG_ERROR, "Invalid decryption key len %d expected %d\n",
10583  return AVERROR(EINVAL);
10584  }
10585 
10586  mov->fc = s;
10587  mov->trak_index = -1;
10588  mov->thmb_item_id = NULL;
10589  mov->primary_item_id = -1;
10590  mov->cur_item_id = -1;
10591  /* .mov and .mp4 aren't streamable anyway (only progressive download if moov is before mdat) */
10592  if (pb->seekable & AVIO_SEEKABLE_NORMAL)
10593  atom.size = avio_size(pb);
10594  else
10595  atom.size = INT64_MAX;
10596 
10597  /* check MOV header */
10598  do {
10599  if (mov->moov_retry)
10600  avio_seek(pb, 0, SEEK_SET);
10601  if ((err = mov_read_default(mov, pb, atom)) < 0) {
10602  av_log(s, AV_LOG_ERROR, "error reading header\n");
10603  return err;
10604  }
10605  } while ((pb->seekable & AVIO_SEEKABLE_NORMAL) &&
10606  !mov->found_moov && (!mov->found_iloc || !mov->found_iinf) && !mov->moov_retry++);
10607  if (!mov->found_moov && !mov->found_iloc && !mov->found_iinf) {
10608  av_log(s, AV_LOG_ERROR, "moov atom not found\n");
10609  return AVERROR_INVALIDDATA;
10610  }
10611  av_log(mov->fc, AV_LOG_TRACE, "on_parse_exit_offset=%"PRId64"\n", avio_tell(pb));
10612 
10613  if (mov->found_iloc && mov->found_iinf) {
10614  err = mov_parse_heif_items(s);
10615  if (err < 0)
10616  return err;
10617  }
10618  // prevent iloc and iinf boxes from being parsed while reading packets.
10619  // this is needed because an iinf box may have been parsed but ignored
10620  // for having old infe boxes which create no streams.
10621  mov->found_iloc = mov->found_iinf = 1;
10622 
10623  if (pb->seekable & AVIO_SEEKABLE_NORMAL) {
10624  if (mov->nb_chapter_tracks > 0 && !mov->ignore_chapters)
10626  for (i = 0; i < s->nb_streams; i++)
10627  if (s->streams[i]->codecpar->codec_tag == AV_RL32("tmcd")) {
10628  mov_read_timecode_track(s, s->streams[i]);
10629  } else if (s->streams[i]->codecpar->codec_tag == AV_RL32("rtmd")) {
10630  mov_read_rtmd_track(s, s->streams[i]);
10631  }
10632  }
10633 
10634  /* copy timecode metadata from tmcd tracks to the related video streams */
10635  for (i = 0; i < s->nb_streams; i++) {
10636  AVStream *st = s->streams[i];
10637  MOVStreamContext *sc = st->priv_data;
10638  if (sc->timecode_track > 0) {
10639  AVDictionaryEntry *tcr;
10640  int tmcd_st_id = -1;
10641 
10642  for (j = 0; j < s->nb_streams; j++) {
10643  MOVStreamContext *sc2 = s->streams[j]->priv_data;
10644  if (sc2->id == sc->timecode_track)
10645  tmcd_st_id = j;
10646  }
10647 
10648  if (tmcd_st_id < 0 || tmcd_st_id == i)
10649  continue;
10650  tcr = av_dict_get(s->streams[tmcd_st_id]->metadata, "timecode", NULL, 0);
10651  if (tcr)
10652  av_dict_set(&st->metadata, "timecode", tcr->value, 0);
10653  }
10654  }
10656 
10657  /* Create LCEVC stream groups. */
10658  err = mov_parse_lcevc_streams(s);
10659  if (err < 0)
10660  return err;
10661 
10662  for (i = 0; i < s->nb_streams; i++) {
10663  AVStream *st = s->streams[i];
10664  FFStream *const sti = ffstream(st);
10665  MOVStreamContext *sc = st->priv_data;
10666  uint32_t dvdsub_clut[FF_DVDCLUT_CLUT_LEN] = {0};
10667  fix_timescale(mov, sc);
10668 
10669  /* Set the primary extradata based on the first Sample. */
10670  if (sc->stsc_count && sc->extradata_size && !sc->iamf &&
10671  sc->stsc_data[0].id > 0 && sc->stsc_data[0].id <= sc->stsd_count) {
10672  sc->last_stsd_index = sc->stsc_data[0].id - 1;
10673  av_freep(&st->codecpar->extradata);
10675  if (sc->extradata_size[sc->last_stsd_index]) {
10677  if (!st->codecpar->extradata)
10678  return AVERROR(ENOMEM);
10679  memcpy(st->codecpar->extradata, sc->extradata[sc->last_stsd_index], sc->extradata_size[sc->last_stsd_index]);
10680  }
10681  }
10682 
10683  if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
10684  st->codecpar->codec_id == AV_CODEC_ID_AAC) {
10685  sti->skip_samples = sc->start_pad;
10686  }
10687  if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && sc->nb_frames_for_fps > 0 && sc->duration_for_fps > 0)
10689  sc->time_scale*(int64_t)sc->nb_frames_for_fps, sc->duration_for_fps, INT_MAX);
10691  if (st->codecpar->width <= 0 || st->codecpar->height <= 0) {
10692  st->codecpar->width = sc->width;
10693  st->codecpar->height = sc->height;
10694  }
10697 
10698  for (j = 0; j < FF_DVDCLUT_CLUT_LEN; j++)
10699  dvdsub_clut[j] = AV_RB32(st->codecpar->extradata + j * 4);
10700 
10701  err = ff_dvdclut_yuv_to_rgb(dvdsub_clut, FF_DVDCLUT_CLUT_SIZE);
10702  if (err < 0)
10703  return err;
10704 
10705  av_freep(&st->codecpar->extradata);
10706  st->codecpar->extradata_size = 0;
10707 
10709  st->codecpar);
10710  if (err < 0)
10711  return err;
10712  }
10713  }
10714  if (mov->handbrake_version &&
10715  mov->handbrake_version <= 1000000*0 + 1000*10 + 2 && // 0.10.2
10716  st->codecpar->codec_id == AV_CODEC_ID_MP3) {
10717  av_log(s, AV_LOG_VERBOSE, "Forcing full parsing for mp3 stream\n");
10719  }
10720  }
10721 
10722  if (mov->trex_data || mov->use_mfra_for > 0) {
10723  for (i = 0; i < s->nb_streams; i++) {
10724  AVStream *st = s->streams[i];
10725  MOVStreamContext *sc = st->priv_data;
10726  if (sc->duration_for_fps > 0) {
10727  /* Akin to sc->data_size * 8 * sc->time_scale / sc->duration_for_fps but accounting for overflows. */
10729  if (st->codecpar->bit_rate == INT64_MIN) {
10730  av_log(s, AV_LOG_WARNING, "Overflow during bit rate calculation %"PRId64" * 8 * %d\n",
10731  sc->data_size, sc->time_scale);
10732  st->codecpar->bit_rate = 0;
10733  if (s->error_recognition & AV_EF_EXPLODE)
10734  return AVERROR_INVALIDDATA;
10735  }
10736  }
10737  }
10738  }
10739 
10740  for (i = 0; i < mov->bitrates_count && i < s->nb_streams; i++) {
10741  if (mov->bitrates[i]) {
10742  s->streams[i]->codecpar->bit_rate = mov->bitrates[i];
10743  }
10744  }
10745 
10747 
10748  for (i = 0; i < s->nb_streams; i++) {
10749  AVStream *st = s->streams[i];
10750  MOVStreamContext *sc = st->priv_data;
10751 
10752  switch (st->codecpar->codec_type) {
10753  case AVMEDIA_TYPE_AUDIO:
10754  err = ff_replaygain_export(st, s->metadata);
10755  if (err < 0)
10756  return err;
10757  break;
10758  case AVMEDIA_TYPE_VIDEO:
10759  if (sc->display_matrix) {
10762  (uint8_t*)sc->display_matrix, sizeof(int32_t) * 9, 0))
10763  return AVERROR(ENOMEM);
10764 
10765  sc->display_matrix = NULL;
10766  }
10767  if (sc->stereo3d) {
10770  (uint8_t *)sc->stereo3d, sc->stereo3d_size, 0))
10771  return AVERROR(ENOMEM);
10772 
10773  sc->stereo3d = NULL;
10774  }
10775  if (sc->spherical) {
10778  (uint8_t *)sc->spherical, sc->spherical_size, 0))
10779  return AVERROR(ENOMEM);
10780 
10781  sc->spherical = NULL;
10782  }
10783  if (sc->mastering) {
10786  (uint8_t *)sc->mastering, sc->mastering_size, 0))
10787  return AVERROR(ENOMEM);
10788 
10789  sc->mastering = NULL;
10790  }
10791  if (sc->coll) {
10794  (uint8_t *)sc->coll, sc->coll_size, 0))
10795  return AVERROR(ENOMEM);
10796 
10797  sc->coll = NULL;
10798  }
10799  if (sc->ambient) {
10802  (uint8_t *) sc->ambient, sc->ambient_size, 0))
10803  return AVERROR(ENOMEM);
10804 
10805  sc->ambient = NULL;
10806  }
10807  break;
10808  }
10809  }
10810 
10811  fix_stream_ids(s);
10812 
10814 
10815  for (i = 0; i < mov->frag_index.nb_items; i++)
10816  if (mov->frag_index.item[i].moof_offset <= mov->fragment.moof_offset)
10817  mov->frag_index.item[i].headers_read = 1;
10818 
10819  return 0;
10820 }
10821 
10823 {
10825  int64_t best_dts = INT64_MAX;
10826  int i;
10827  MOVContext *mov = s->priv_data;
10828  int no_interleave = !mov->interleaved_read || !(s->pb->seekable & AVIO_SEEKABLE_NORMAL);
10829  for (i = 0; i < s->nb_streams; i++) {
10830  AVStream *avst = s->streams[i];
10831  FFStream *const avsti = ffstream(avst);
10832  MOVStreamContext *msc = avst->priv_data;
10833  if (msc->pb && msc->current_sample < avsti->nb_index_entries) {
10834  AVIndexEntry *current_sample = &avsti->index_entries[msc->current_sample];
10835  int64_t dts = av_rescale(current_sample->timestamp, AV_TIME_BASE, msc->time_scale);
10836  uint64_t dtsdiff = best_dts > dts ? best_dts - (uint64_t)dts : ((uint64_t)dts - best_dts);
10837  av_log(s, AV_LOG_TRACE, "stream %d, sample %d, dts %"PRId64"\n", i, msc->current_sample, dts);
10838  if (!sample || (no_interleave && current_sample->pos < sample->pos) ||
10839  ((s->pb->seekable & AVIO_SEEKABLE_NORMAL) &&
10840  ((msc->pb != s->pb && dts < best_dts) || (msc->pb == s->pb && dts != AV_NOPTS_VALUE &&
10841  ((dtsdiff <= AV_TIME_BASE && current_sample->pos < sample->pos) ||
10842  (dtsdiff > AV_TIME_BASE && dts < best_dts && mov->interleaved_read)))))) {
10843  sample = current_sample;
10844  best_dts = dts;
10845  *st = avst;
10846  }
10847  }
10848  }
10849  return sample;
10850 }
10851 
10852 static int should_retry(AVIOContext *pb, int error_code) {
10853  if (error_code == AVERROR_EOF || avio_feof(pb))
10854  return 0;
10855 
10856  return 1;
10857 }
10858 
10859 static int mov_switch_root(AVFormatContext *s, int64_t target, int index)
10860 {
10861  int ret;
10862  MOVContext *mov = s->priv_data;
10863 
10864  if (index >= 0 && index < mov->frag_index.nb_items)
10865  target = mov->frag_index.item[index].moof_offset;
10866  if (target >= 0 && avio_seek(s->pb, target, SEEK_SET) != target) {
10867  av_log(mov->fc, AV_LOG_ERROR, "root atom offset 0x%"PRIx64": partial file\n", target);
10868  return AVERROR_INVALIDDATA;
10869  }
10870 
10871  mov->next_root_atom = 0;
10872  if ((index < 0 && target >= 0) || index >= mov->frag_index.nb_items)
10873  index = search_frag_moof_offset(&mov->frag_index, target);
10874  if (index >= 0 && index < mov->frag_index.nb_items &&
10875  mov->frag_index.item[index].moof_offset == target) {
10876  if (index + 1 < mov->frag_index.nb_items)
10877  mov->next_root_atom = mov->frag_index.item[index + 1].moof_offset;
10878  if (mov->frag_index.item[index].headers_read)
10879  return 0;
10880  mov->frag_index.item[index].headers_read = 1;
10881  }
10882 
10883  mov->found_mdat = 0;
10884 
10885  ret = mov_read_default(mov, s->pb, (MOVAtom){ AV_RL32("root"), INT64_MAX });
10886  if (ret < 0)
10887  return ret;
10888  if (avio_feof(s->pb))
10889  return AVERROR_EOF;
10890  av_log(s, AV_LOG_TRACE, "read fragments, offset 0x%"PRIx64"\n", avio_tell(s->pb));
10891 
10892  return 1;
10893 }
10894 
10896 {
10897  MOVStreamContext *sc = st->priv_data;
10898  uint8_t *side, *extradata;
10899  int extradata_size;
10900 
10901  /* Save the current index. */
10902  sc->last_stsd_index = sc->stsc_data[sc->stsc_index].id - 1;
10903 
10904  /* Notify the decoder that extradata changed. */
10905  extradata_size = sc->extradata_size[sc->last_stsd_index];
10906  extradata = sc->extradata[sc->last_stsd_index];
10907  if (st->discard != AVDISCARD_ALL && extradata_size > 0 && extradata) {
10910  extradata_size);
10911  if (!side)
10912  return AVERROR(ENOMEM);
10913  memcpy(side, extradata, extradata_size);
10914  }
10915 
10916  return 0;
10917 }
10918 
10919 static int get_eia608_packet(AVIOContext *pb, AVPacket *pkt, int src_size)
10920 {
10921  /* We can't make assumptions about the structure of the payload,
10922  because it may include multiple cdat and cdt2 samples. */
10923  const uint32_t cdat = AV_RB32("cdat");
10924  const uint32_t cdt2 = AV_RB32("cdt2");
10925  int ret, out_size = 0;
10926 
10927  /* a valid payload must have size, 4cc, and at least 1 byte pair: */
10928  if (src_size < 10)
10929  return AVERROR_INVALIDDATA;
10930 
10931  /* avoid an int overflow: */
10932  if ((src_size - 8) / 2 >= INT_MAX / 3)
10933  return AVERROR_INVALIDDATA;
10934 
10935  ret = av_new_packet(pkt, ((src_size - 8) / 2) * 3);
10936  if (ret < 0)
10937  return ret;
10938 
10939  /* parse and re-format the c608 payload in one pass. */
10940  while (src_size >= 10) {
10941  const uint32_t atom_size = avio_rb32(pb);
10942  const uint32_t atom_type = avio_rb32(pb);
10943  const uint32_t data_size = atom_size - 8;
10944  const uint8_t cc_field =
10945  atom_type == cdat ? 1 :
10946  atom_type == cdt2 ? 2 :
10947  0;
10948 
10949  /* account for bytes consumed for atom size and type. */
10950  src_size -= 8;
10951 
10952  /* make sure the data size stays within the buffer boundaries. */
10953  if (data_size < 2 || data_size > src_size) {
10955  break;
10956  }
10957 
10958  /* make sure the data size is consistent with N byte pairs. */
10959  if (data_size % 2 != 0) {
10961  break;
10962  }
10963 
10964  if (!cc_field) {
10965  /* neither cdat or cdt2 ... skip it */
10966  avio_skip(pb, data_size);
10967  src_size -= data_size;
10968  continue;
10969  }
10970 
10971  for (uint32_t i = 0; i < data_size; i += 2) {
10972  pkt->data[out_size] = (0x1F << 3) | (1 << 2) | (cc_field - 1);
10973  pkt->data[out_size + 1] = avio_r8(pb);
10974  pkt->data[out_size + 2] = avio_r8(pb);
10975  out_size += 3;
10976  src_size -= 2;
10977  }
10978  }
10979 
10980  if (src_size > 0)
10981  /* skip any remaining unread portion of the input payload */
10982  avio_skip(pb, src_size);
10983 
10985  return ret;
10986 }
10987 
10989  int64_t current_index, AVPacket *pkt)
10990 {
10991  MOVStreamContext *sc = st->priv_data;
10992 
10993  pkt->stream_index = sc->ffindex;
10994  pkt->dts = sample->timestamp;
10995  if (sample->flags & AVINDEX_DISCARD_FRAME) {
10997  }
10998  if (sc->stts_count && sc->tts_index < sc->tts_count)
10999  pkt->duration = sc->tts_data[sc->tts_index].duration;
11000  if (sc->ctts_count && sc->tts_index < sc->tts_count) {
11002  } else {
11003  if (pkt->duration == 0) {
11004  int64_t next_dts = (sc->current_sample < ffstream(st)->nb_index_entries) ?
11006  if (next_dts >= pkt->dts)
11007  pkt->duration = next_dts - pkt->dts;
11008  }
11009  pkt->pts = pkt->dts;
11010  }
11011 
11012  if (sc->tts_data && sc->tts_index < sc->tts_count) {
11013  /* update tts context */
11014  sc->tts_sample++;
11015  if (sc->tts_index < sc->tts_count &&
11016  sc->tts_data[sc->tts_index].count == sc->tts_sample) {
11017  sc->tts_index++;
11018  sc->tts_sample = 0;
11019  }
11020  }
11021 
11022  if (sc->sdtp_data && sc->current_sample <= sc->sdtp_count) {
11023  uint8_t sample_flags = sc->sdtp_data[sc->current_sample - 1];
11024  uint8_t sample_is_depended_on = (sample_flags >> 2) & 0x3;
11025  pkt->flags |= sample_is_depended_on == MOV_SAMPLE_DEPENDENCY_NO ? AV_PKT_FLAG_DISPOSABLE : 0;
11026  }
11027  pkt->flags |= sample->flags & AVINDEX_KEYFRAME ? AV_PKT_FLAG_KEY : 0;
11028  pkt->pos = sample->pos;
11029 
11030  /* Multiple stsd handling. */
11031  if (sc->stsc_data) {
11032  if (sc->stsc_data[sc->stsc_index].id > 0 &&
11033  sc->stsc_data[sc->stsc_index].id - 1 < sc->stsd_count &&
11034  sc->stsc_data[sc->stsc_index].id - 1 != sc->last_stsd_index) {
11035  int ret = mov_change_extradata(st, pkt);
11036  if (ret < 0)
11037  return ret;
11038  }
11039 
11040  /* Update the stsc index for the next sample */
11041  sc->stsc_sample++;
11042  if (mov_stsc_index_valid(sc->stsc_index, sc->stsc_count) &&
11043  mov_get_stsc_samples(sc, sc->stsc_index) == sc->stsc_sample) {
11044  sc->stsc_index++;
11045  sc->stsc_sample = 0;
11046  }
11047  }
11048 
11049  return 0;
11050 }
11051 
11053 {
11054  MOVContext *mov = s->priv_data;
11055  MOVStreamContext *sc;
11057  AVStream *st = NULL;
11058  FFStream *avsti = NULL;
11059  int64_t current_index;
11060  int ret;
11061  int i;
11062  mov->fc = s;
11063  retry:
11064  if (s->pb->pos == 0) {
11065 
11066  // Discard current fragment index
11067  if (mov->frag_index.allocated_size > 0) {
11068  for(int i = 0; i < mov->frag_index.nb_items; i++) {
11070  }
11071  av_freep(&mov->frag_index.item);
11072  mov->frag_index.nb_items = 0;
11073  mov->frag_index.allocated_size = 0;
11074  mov->frag_index.current = -1;
11075  mov->frag_index.complete = 0;
11076  }
11077 
11078  for (i = 0; i < s->nb_streams; i++) {
11079  AVStream *avst = s->streams[i];
11080  MOVStreamContext *msc = avst->priv_data;
11081 
11082  // Clear current sample
11083  mov_current_sample_set(msc, 0);
11084  msc->tts_index = 0;
11085 
11086  // Discard current index entries
11087  avsti = ffstream(avst);
11088  if (avsti->index_entries_allocated_size > 0) {
11089  av_freep(&avsti->index_entries);
11090  avsti->index_entries_allocated_size = 0;
11091  avsti->nb_index_entries = 0;
11092  }
11093  }
11094 
11095  if ((ret = mov_switch_root(s, -1, -1)) < 0)
11096  return ret;
11097  }
11098  sample = mov_find_next_sample(s, &st);
11099  if (!sample || (mov->next_root_atom && sample->pos > mov->next_root_atom)) {
11100  if (!mov->next_root_atom)
11101  return AVERROR_EOF;
11102  if ((ret = mov_switch_root(s, mov->next_root_atom, -1)) < 0)
11103  return ret;
11104  goto retry;
11105  }
11106  sc = st->priv_data;
11107  /* must be done just before reading, to avoid infinite loop on sample */
11108  current_index = sc->current_index;
11110 
11111  if (mov->next_root_atom) {
11112  sample->pos = FFMIN(sample->pos, mov->next_root_atom);
11113  sample->size = FFMIN(sample->size, (mov->next_root_atom - sample->pos));
11114  }
11115 
11116  if (st->discard != AVDISCARD_ALL) {
11117  int64_t ret64 = avio_seek(sc->pb, sample->pos, SEEK_SET);
11118  if (ret64 != sample->pos) {
11119  av_log(mov->fc, AV_LOG_ERROR, "stream %d, offset 0x%"PRIx64": partial file\n",
11120  sc->ffindex, sample->pos);
11121  if (should_retry(sc->pb, ret64)) {
11123  } else if (ret64 < 0) {
11124  return (int)ret64;
11125  }
11126  return AVERROR_INVALIDDATA;
11127  }
11128 
11129  if (st->discard == AVDISCARD_NONKEY && !(sample->flags & AVINDEX_KEYFRAME)) {
11130  av_log(mov->fc, AV_LOG_DEBUG, "Nonkey frame from stream %d discarded due to AVDISCARD_NONKEY\n", sc->ffindex);
11131  goto retry;
11132  }
11133 
11134  if (st->codecpar->codec_id == AV_CODEC_ID_EIA_608 && sample->size > 8)
11135  ret = get_eia608_packet(sc->pb, pkt, sample->size);
11136 #if CONFIG_IAMFDEC
11137  else if (sc->iamf) {
11138  int64_t pts, dts, pos, duration;
11139  int flags, size = sample->size;
11140  ret = mov_finalize_packet(s, st, sample, current_index, pkt);
11141  pts = pkt->pts; dts = pkt->dts;
11142  pos = pkt->pos; flags = pkt->flags;
11143  duration = pkt->duration;
11144  while (!ret && size > 0) {
11145  ret = ff_iamf_read_packet(s, sc->iamf, sc->pb, size, sc->iamf_stream_offset, pkt);
11146  if (ret < 0) {
11147  if (should_retry(sc->pb, ret))
11149  return ret;
11150  }
11151  size -= ret;
11152  pkt->pts = pts; pkt->dts = dts;
11153  pkt->pos = pos; pkt->flags |= flags;
11154  pkt->duration = duration;
11155  ret = ff_buffer_packet(s, pkt);
11156  }
11157  if (!ret)
11158  return FFERROR_REDO;
11159  }
11160 #endif
11161  else if (st->codecpar->codec_id == AV_CODEC_ID_APV && sample->size > 4) {
11162  const uint32_t au_size = avio_rb32(sc->pb);
11163  ret = av_get_packet(sc->pb, pkt, au_size);
11164  } else
11165  ret = av_get_packet(sc->pb, pkt, sample->size);
11166  if (ret < 0) {
11167  if (should_retry(sc->pb, ret)) {
11169  }
11170  return ret;
11171  }
11172 #if CONFIG_DV_DEMUXER
11173  if (mov->dv_demux && sc->dv_audio_container) {
11176  if (ret < 0)
11177  return ret;
11179  if (ret < 0)
11180  return ret;
11181  }
11182 #endif
11183  if (sc->has_palette) {
11184  uint8_t *pal;
11185 
11187  if (!pal) {
11188  av_log(mov->fc, AV_LOG_ERROR, "Cannot append palette to packet\n");
11189  } else {
11190  memcpy(pal, sc->palette, AVPALETTE_SIZE);
11191  sc->has_palette = 0;
11192  }
11193  }
11194  if (st->codecpar->codec_id == AV_CODEC_ID_MP3 && !ffstream(st)->need_parsing && pkt->size > 4) {
11195  if (ff_mpa_check_header(AV_RB32(pkt->data)) < 0)
11197  }
11198  }
11199 
11200  ret = mov_finalize_packet(s, st, sample, current_index, pkt);
11201  if (ret < 0)
11202  return ret;
11203 
11204  if (st->discard == AVDISCARD_ALL)
11205  goto retry;
11206 
11207  if (mov->aax_mode)
11208  aax_filter(pkt->data, pkt->size, mov);
11209 
11210  ret = cenc_filter(mov, st, sc, pkt, current_index);
11211  if (ret < 0) {
11212  return ret;
11213  }
11214 
11215  return 0;
11216 }
11217 
11219 {
11220  MOVContext *mov = s->priv_data;
11221  int index;
11222 
11223  if (!mov->frag_index.complete)
11224  return 0;
11225 
11226  index = search_frag_timestamp(s, &mov->frag_index, st, timestamp);
11227  if (index < 0)
11228  index = 0;
11229  if (!mov->frag_index.item[index].headers_read)
11230  return mov_switch_root(s, -1, index);
11231  if (index + 1 < mov->frag_index.nb_items)
11232  mov->next_root_atom = mov->frag_index.item[index + 1].moof_offset;
11233 
11234  return 0;
11235 }
11236 
11237 static int is_open_key_sample(const MOVStreamContext *sc, int sample)
11238 {
11239  // TODO: a bisect search would scale much better
11240  for (int i = 0; i < sc->open_key_samples_count; i++) {
11241  const int oks = sc->open_key_samples[i];
11242  if (oks == sample)
11243  return 1;
11244  if (oks > sample) /* list is monotically increasing so we can stop early */
11245  break;
11246  }
11247  return 0;
11248 }
11249 
11250 /*
11251  * Some key sample may be key frames but not IDR frames, so a random access to
11252  * them may not be allowed.
11253  */
11254 static int can_seek_to_key_sample(AVStream *st, int sample, int64_t requested_pts)
11255 {
11256  MOVStreamContext *sc = st->priv_data;
11257  FFStream *const sti = ffstream(st);
11258  int64_t key_sample_dts, key_sample_pts;
11259 
11260  if (st->codecpar->codec_id != AV_CODEC_ID_HEVC)
11261  return 1;
11262 
11263  if (sample >= sc->sample_offsets_count)
11264  return 1;
11265 
11266  key_sample_dts = sti->index_entries[sample].timestamp;
11267  key_sample_pts = key_sample_dts + sc->sample_offsets[sample] + sc->dts_shift;
11268 
11269  /*
11270  * If the sample needs to be presented before an open key sample, they may
11271  * not be decodable properly, even though they come after in decoding
11272  * order.
11273  */
11274  if (is_open_key_sample(sc, sample) && key_sample_pts > requested_pts)
11275  return 0;
11276 
11277  return 1;
11278 }
11279 
11280 static int mov_seek_stream(AVFormatContext *s, AVStream *st, int64_t timestamp, int flags)
11281 {
11282  MOVStreamContext *sc = st->priv_data;
11283  FFStream *const sti = ffstream(st);
11284  int sample, time_sample, ret, next_ts, requested_sample;
11285  unsigned int i;
11286 
11287  // Here we consider timestamp to be PTS, hence try to offset it so that we
11288  // can search over the DTS timeline.
11289  timestamp -= (sc->min_corrected_pts + sc->dts_shift);
11290 
11291  ret = mov_seek_fragment(s, st, timestamp);
11292  if (ret < 0)
11293  return ret;
11294 
11295  for (;;) {
11296  sample = av_index_search_timestamp(st, timestamp, flags);
11297  av_log(s, AV_LOG_TRACE, "stream %d, timestamp %"PRId64", sample %d\n", st->index, timestamp, sample);
11298  if (sample < 0 && sti->nb_index_entries && timestamp < sti->index_entries[0].timestamp)
11299  sample = 0;
11300  if (sample < 0) /* not sure what to do */
11301  return AVERROR_INVALIDDATA;
11302 
11303  if (!sample || can_seek_to_key_sample(st, sample, timestamp))
11304  break;
11305 
11306  next_ts = timestamp - FFMAX(sc->min_sample_duration, 1);
11307  requested_sample = av_index_search_timestamp(st, next_ts, flags);
11308 
11309  // If we've reached a different sample trying to find a good pts to
11310  // seek to, give up searching because we'll end up seeking back to
11311  // sample 0 on every seek.
11312  if (sample != requested_sample && !can_seek_to_key_sample(st, requested_sample, next_ts))
11313  break;
11314 
11315  timestamp = next_ts;
11316  }
11317 
11319  av_log(s, AV_LOG_TRACE, "stream %d, found sample %d\n", st->index, sc->current_sample);
11320  /* adjust time to sample index */
11321  if (sc->tts_data) {
11322  time_sample = 0;
11323  for (i = 0; i < sc->tts_count; i++) {
11324  int next = time_sample + sc->tts_data[i].count;
11325  if (next > sc->current_sample) {
11326  sc->tts_index = i;
11327  sc->tts_sample = sc->current_sample - time_sample;
11328  break;
11329  }
11330  time_sample = next;
11331  }
11332  }
11333 
11334  /* adjust stsd index */
11335  if (sc->chunk_count) {
11336  time_sample = 0;
11337  for (i = 0; i < sc->stsc_count; i++) {
11338  int64_t next = time_sample + mov_get_stsc_samples(sc, i);
11339  if (next > sc->current_sample) {
11340  sc->stsc_index = i;
11341  sc->stsc_sample = sc->current_sample - time_sample;
11342  break;
11343  }
11344  av_assert0(next == (int)next);
11345  time_sample = next;
11346  }
11347  }
11348 
11349  return sample;
11350 }
11351 
11353 {
11354  MOVStreamContext *sc = st->priv_data;
11355  FFStream *const sti = ffstream(st);
11356  int64_t first_ts = sti->index_entries[0].timestamp;
11358  int64_t off;
11359 
11361  return 0;
11362 
11363  /* compute skip samples according to stream start_pad, seek ts and first ts */
11364  off = av_rescale_q(ts - first_ts, st->time_base,
11365  (AVRational){1, st->codecpar->sample_rate});
11366  return FFMAX(sc->start_pad - off, 0);
11367 }
11368 
11369 static int mov_read_seek(AVFormatContext *s, int stream_index, int64_t sample_time, int flags)
11370 {
11371  MOVContext *mc = s->priv_data;
11372  AVStream *st;
11373  FFStream *sti;
11374  int sample;
11375  int i;
11376 
11377  if (stream_index >= s->nb_streams)
11378  return AVERROR_INVALIDDATA;
11379 
11380  st = s->streams[stream_index];
11381  sti = ffstream(st);
11382  sample = mov_seek_stream(s, st, sample_time, flags);
11383  if (sample < 0)
11384  return sample;
11385 
11386  if (mc->seek_individually) {
11387  /* adjust seek timestamp to found sample timestamp */
11388  int64_t seek_timestamp = sti->index_entries[sample].timestamp;
11390 
11391  for (i = 0; i < s->nb_streams; i++) {
11392  AVStream *const st = s->streams[i];
11393  FFStream *const sti = ffstream(st);
11394  int64_t timestamp;
11395 
11396  if (stream_index == i)
11397  continue;
11398 
11399  timestamp = av_rescale_q(seek_timestamp, s->streams[stream_index]->time_base, st->time_base);
11400  sample = mov_seek_stream(s, st, timestamp, flags);
11401  if (sample >= 0)
11403  }
11404  } else {
11405  for (i = 0; i < s->nb_streams; i++) {
11406  MOVStreamContext *sc;
11407  st = s->streams[i];
11408  sc = st->priv_data;
11409  mov_current_sample_set(sc, 0);
11410  }
11411  while (1) {
11412  MOVStreamContext *sc;
11414  if (!entry)
11415  return AVERROR_INVALIDDATA;
11416  sc = st->priv_data;
11417  if (sc->ffindex == stream_index && sc->current_sample == sample)
11418  break;
11420  }
11421  }
11422  return 0;
11423 }
11424 
11425 #define OFFSET(x) offsetof(MOVContext, x)
11426 #define FLAGS AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM
11427 static const AVOption mov_options[] = {
11428  {"use_absolute_path",
11429  "allow using absolute path when opening alias, this is a possible security issue",
11430  OFFSET(use_absolute_path), AV_OPT_TYPE_BOOL, {.i64 = 0},
11431  0, 1, FLAGS},
11432  {"seek_streams_individually",
11433  "Seek each stream individually to the closest point",
11434  OFFSET(seek_individually), AV_OPT_TYPE_BOOL, { .i64 = 1 },
11435  0, 1, FLAGS},
11436  {"ignore_editlist", "Ignore the edit list atom.", OFFSET(ignore_editlist), AV_OPT_TYPE_BOOL, {.i64 = 0},
11437  0, 1, FLAGS},
11438  {"advanced_editlist",
11439  "Modify the AVIndex according to the editlists. Use this option to decode in the order specified by the edits.",
11440  OFFSET(advanced_editlist), AV_OPT_TYPE_BOOL, {.i64 = 1},
11441  0, 1, FLAGS},
11442  {"ignore_chapters", "", OFFSET(ignore_chapters), AV_OPT_TYPE_BOOL, {.i64 = 0},
11443  0, 1, FLAGS},
11444  {"use_mfra_for",
11445  "use mfra for fragment timestamps",
11446  OFFSET(use_mfra_for), AV_OPT_TYPE_INT, {.i64 = FF_MOV_FLAG_MFRA_AUTO},
11448  .unit = "use_mfra_for"},
11449  {"auto", "auto", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_AUTO}, 0, 0,
11450  FLAGS, .unit = "use_mfra_for" },
11451  {"dts", "dts", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_DTS}, 0, 0,
11452  FLAGS, .unit = "use_mfra_for" },
11453  {"pts", "pts", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_PTS}, 0, 0,
11454  FLAGS, .unit = "use_mfra_for" },
11455  {"use_tfdt", "use tfdt for fragment timestamps", OFFSET(use_tfdt), AV_OPT_TYPE_BOOL, {.i64 = 1},
11456  0, 1, FLAGS},
11457  { "export_all", "Export unrecognized metadata entries", OFFSET(export_all),
11458  AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = FLAGS },
11459  { "export_xmp", "Export full XMP metadata", OFFSET(export_xmp),
11460  AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = FLAGS },
11461  { "activation_bytes", "Secret bytes for Audible AAX files", OFFSET(activation_bytes),
11463  { "audible_key", "AES-128 Key for Audible AAXC files", OFFSET(audible_key),
11465  { "audible_iv", "AES-128 IV for Audible AAXC files", OFFSET(audible_iv),
11467  { "audible_fixed_key", // extracted from libAAX_SDK.so and AAXSDKWin.dll files!
11468  "Fixed key used for handling Audible AAX files", OFFSET(audible_fixed_key),
11469  AV_OPT_TYPE_BINARY, {.str="77214d4b196a87cd520045fd20a51d67"},
11470  .flags = AV_OPT_FLAG_DECODING_PARAM },
11471  { "decryption_key", "The media decryption key (hex)", OFFSET(decryption_key), AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM },
11472  { "enable_drefs", "Enable external track support.", OFFSET(enable_drefs), AV_OPT_TYPE_BOOL,
11473  {.i64 = 0}, 0, 1, FLAGS },
11474  { "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 },
11475  { "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 },
11476 
11477  { NULL },
11478 };
11479 
11480 static const AVClass mov_class = {
11481  .class_name = "mov,mp4,m4a,3gp,3g2,mj2",
11482  .item_name = av_default_item_name,
11483  .option = mov_options,
11484  .version = LIBAVUTIL_VERSION_INT,
11485 };
11486 
11488  .p.name = "mov,mp4,m4a,3gp,3g2,mj2",
11489  .p.long_name = NULL_IF_CONFIG_SMALL("QuickTime / MOV"),
11490  .p.priv_class = &mov_class,
11491  .p.extensions = "mov,mp4,m4a,3gp,3g2,mj2,psp,m4b,ism,ismv,isma,f4v,avif,heic,heif",
11493  .priv_data_size = sizeof(MOVContext),
11494  .flags_internal = FF_INFMT_FLAG_INIT_CLEANUP,
11495  .read_probe = mov_probe,
11500 };
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:336
flags
const SwsFlags flags[]
Definition: swscale.c:61
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:7332
mov_read_meta
static int mov_read_meta(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5456
AV_CODEC_ID_EIA_608
@ AV_CODEC_ID_EIA_608
Definition: codec_id.h:571
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:460
MOVFragmentStreamInfo::first_tfra_pts
int64_t first_tfra_pts
Definition: isom.h:142
AVStreamGroup::params
union AVStreamGroup::@404 params
Group type-specific parameters.
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:10241
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:9162
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:356
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:381
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:8399
can_seek_to_key_sample
static int can_seek_to_key_sample(AVStream *st, int sample, int64_t requested_pts)
Definition: mov.c:11254
AV_CODEC_ID_ADPCM_IMA_QT
@ AV_CODEC_ID_ADPCM_IMA_QT
Definition: codec_id.h:375
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:453
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:11480
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:208
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:5090
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:9972
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:210
mov_options
static const AVOption mov_options[]
Definition: mov.c:11427
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:8790
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:4933
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:8222
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:5474
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:3637
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:5318
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:8784
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:3294
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:5482
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:466
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
AV_CODEC_ID_AMR_NB
@ AV_CODEC_ID_AMR_NB
Definition: codec_id.h:431
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:7540
mov_seek_stream
static int mov_seek_stream(AVFormatContext *s, AVStream *st, int64_t timestamp, int flags)
Definition: mov.c:11280
mov_read_saio
static int mov_read_saio(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:7686
mov_get_stsc_samples
static int64_t mov_get_stsc_samples(MOVStreamContext *sc, unsigned int index)
Definition: mov.c:3279
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:3846
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:10895
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:4150
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:7052
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:8329
mov_read_sdtp
static int mov_read_sdtp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:3603
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:432
mov_read_tfhd
static int mov_read_tfhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5587
AV_CODEC_ID_BIN_DATA
@ AV_CODEC_ID_BIN_DATA
Definition: codec_id.h:602
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:6166
AVINDEX_KEYFRAME
#define AVINDEX_KEYFRAME
Definition: avformat.h:606
AV_FIELD_BT
@ AV_FIELD_BT
Bottom coded first, top displayed first.
Definition: defs.h:214
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:11425
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:10107
AV_FIELD_TT
@ AV_FIELD_TT
Top coded_first, top displayed first.
Definition: defs.h:211
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:485
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:337
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:3648
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:6525
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:5634
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:10121
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:451
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
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:213
mov_read_pack
static int mov_read_pack(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6597
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:7602
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:4561
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:340
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:459
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:9843
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:209
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:4041
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:4555
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:6459
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:5108
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:450
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:4070
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:8503
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:6028
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:10822
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:8483
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:3335
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:7205
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:4069
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:9917
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:6186
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:7430
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:8731
IAMFAudioElement::audio_element_id
unsigned int audio_element_id
Definition: iamf.h:96
AVDISCARD_ALL
@ AVDISCARD_ALL
discard all
Definition: defs.h:229
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:3483
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:3892
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:7310
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:10142
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:3729
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:9563
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:10919
AV_CODEC_ID_DVD_SUBTITLE
@ AV_CODEC_ID_DVD_SUBTITLE
Definition: codec_id.h:561
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:6368
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:4962
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:7902
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:9072
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:469
mov_read_ilst
static int mov_read_ilst(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5263
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:8304
get_sgpd_sync_index
static uint32_t get_sgpd_sync_index(const MOVStreamContext *sc, int nal_unit_type)
Definition: mov.c:4483
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:307
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:2312
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:3005
MOVStts
Definition: isom.h:63
AVAudioServiceType
AVAudioServiceType
Definition: defs.h:232
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:468
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:490
should_retry
static int should_retry(AVIOContext *pb, int error_code)
Definition: mov.c:10852
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:452
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:8641
mov_read_elst
static int mov_read_elst(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6239
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:10572
AV_CODEC_ID_QCELP
@ AV_CODEC_ID_QCELP
Definition: codec_id.h:474
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:8097
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:228
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:348
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:8157
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:9855
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:7379
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:4138
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:5720
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:9201
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:3193
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:500
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:10418
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:3988
MOVDref::path
char * path
Definition: isom.h:87
mov_current_sample_inc
static void mov_current_sample_inc(MOVStreamContext *sc)
Definition: mov.c:4126
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:6813
fix_timescale
static void fix_timescale(MOVContext *c, MOVStreamContext *sc)
Definition: mov.c:5034
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:9441
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:11052
mov_read_infe
static int mov_read_infe(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:8881
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:604
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:10483
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:6496
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:8004
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:9312
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:7933
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:3273
mov_finalize_packet
static int mov_finalize_packet(AVFormatContext *s, AVStream *st, AVIndexEntry *sample, int64_t current_index, AVPacket *pkt)
Definition: mov.c:10988
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:11369
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:5655
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:11426
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:4178
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:7781
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:3128
internal.h
AV_SPHERICAL_FISHEYE
@ AV_SPHERICAL_FISHEYE
Fisheye projection (Apple).
Definition: spherical.h:84
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:585
rb_size
static int rb_size(AVIOContext *pb, int64_t *value, int size)
Definition: mov.c:8757
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:3031
AV_FIELD_BB
@ AV_FIELD_BB
Bottom coded first, bottom displayed first.
Definition: defs.h:212
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:6324
AV_CODEC_ID_PCM_F64BE
@ AV_CODEC_ID_PCM_F64BE
Definition: codec_id.h:358
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:345
mov_read_mdcv
static int mov_read_mdcv(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6415
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:5272
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:10548
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:4624
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:8952
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:4029
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
AVStreamGroupTileGrid::offsets
struct AVStreamGroupTileGrid::@403 * offsets
An nb_tiles sized array of offsets in pixels from the topleft edge of the canvas, indicating where ea...
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:6313
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:7484
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:241
mov_read_dmlp
static int mov_read_dmlp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:8448
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:5681
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:5399
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:10859
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:11218
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:3785
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
MOVStreamContext::cenc
struct MOVStreamContext::@435 cenc
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:7142
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:456
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:6676
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:11352
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:9988
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:4554
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
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:9770
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:344
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:10323
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:9012
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:4491
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:341
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:9796
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:359
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:10006
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:10498
mov_read_hfov
static int mov_read_hfov(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:7113
AV_OPT_TYPE_BOOL
@ AV_OPT_TYPE_BOOL
Underlying C type is int.
Definition: opt.h:327
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:376
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:6878
AV_CODEC_ID_ILBC
@ AV_CODEC_ID_ILBC
Definition: codec_id.h:509
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:9756
MOVStreamContext::tmcd_nb_frames
uint8_t tmcd_nb_frames
tmcd number of frames per tick / second
Definition: isom.h:237
AVChannelLayout::u
union AVChannelLayout::@471 u
Details about which channels are present in this layout.
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:357
ff_mov_demuxer
const FFInputFormat ff_mov_demuxer
Definition: mov.c:11487
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:8288
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:455
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:9140
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:9102
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:10061
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:8552
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:349
mov_read_st3d
static int mov_read_st3d(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6550
mov_read_imir
static int mov_read_imir(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:9182
is_open_key_sample
static int is_open_key_sample(const MOVStreamContext *sc, int sample)
Definition: mov.c:11237
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:9657
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:8044
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:8776
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:3390