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