FFmpeg
mov.c
Go to the documentation of this file.
1 /*
2  * MOV demuxer
3  * Copyright (c) 2001 Fabrice Bellard
4  * Copyright (c) 2009 Baptiste Coudurier <baptiste dot coudurier at gmail dot com>
5  *
6  * first version by Francois Revol <revol@free.fr>
7  * seek function by Gael Chardon <gael.dev@4now.net>
8  *
9  * This file is part of FFmpeg.
10  *
11  * FFmpeg is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU Lesser General Public
13  * License as published by the Free Software Foundation; either
14  * version 2.1 of the License, or (at your option) any later version.
15  *
16  * FFmpeg is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19  * Lesser General Public License for more details.
20  *
21  * You should have received a copy of the GNU Lesser General Public
22  * License along with FFmpeg; if not, write to the Free Software
23  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
24  */
25 
26 #include "config_components.h"
27 
28 #include <inttypes.h>
29 #include <limits.h>
30 #include <stdint.h>
31 
32 #include "libavutil/attributes.h"
33 #include "libavutil/bprint.h"
35 #include "libavutil/dovi_meta.h"
36 #include "libavutil/internal.h"
37 #include "libavutil/intreadwrite.h"
38 #include "libavutil/intfloat.h"
39 #include "libavutil/mathematics.h"
40 #include "libavutil/avassert.h"
41 #include "libavutil/avstring.h"
42 #include "libavutil/dict.h"
43 #include "libavutil/display.h"
44 #include "libavutil/mem.h"
45 #include "libavutil/opt.h"
46 #include "libavutil/aes.h"
47 #include "libavutil/aes_ctr.h"
48 #include "libavutil/pixdesc.h"
49 #include "libavutil/sha.h"
50 #include "libavutil/spherical.h"
51 #include "libavutil/stereo3d.h"
52 #include "libavutil/timecode.h"
53 #include "libavutil/uuid.h"
54 #include "libavcodec/ac3tab.h"
55 #include "libavcodec/exif.h"
56 #include "libavcodec/flac.h"
57 #include "libavcodec/hevc/hevc.h"
59 #include "libavcodec/mlp_parse.h"
60 #include "avformat.h"
61 #include "internal.h"
62 #include "avio_internal.h"
63 #include "demux.h"
64 #include "dvdclut.h"
65 #include "iamf_parse.h"
66 #include "iamf_reader.h"
67 #include "dovi_isom.h"
68 #include "riff.h"
69 #include "isom.h"
70 #include "libavcodec/get_bits.h"
71 #include "id3v1.h"
72 #include "mov_chan.h"
73 #include "replaygain.h"
74 
75 #if CONFIG_ZLIB
76 #include <zlib.h>
77 #endif
78 
79 #include "qtpalette.h"
80 
81 /* those functions parse an atom */
82 /* links atom IDs to parse functions */
83 typedef struct MOVParseTableEntry {
84  uint32_t type;
85  int (*parse)(MOVContext *ctx, AVIOContext *pb, MOVAtom atom);
87 
88 static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom);
89 static int mov_read_mfra(MOVContext *c, AVIOContext *f);
91 
93  unsigned len, const char *key)
94 {
95  char buf[16];
96 
97  short current, total = 0;
98  avio_rb16(pb); // unknown
99  current = avio_rb16(pb);
100  if (len >= 6)
101  total = avio_rb16(pb);
102  if (!total)
103  snprintf(buf, sizeof(buf), "%d", current);
104  else
105  snprintf(buf, sizeof(buf), "%d/%d", current, total);
106  c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
107  av_dict_set(&c->fc->metadata, key, buf, 0);
108 
109  return 0;
110 }
111 
113  unsigned len, const char *key)
114 {
115  /* bypass padding bytes */
116  avio_r8(pb);
117  avio_r8(pb);
118  avio_r8(pb);
119 
120  c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
121  av_dict_set_int(&c->fc->metadata, key, avio_r8(pb), 0);
122 
123  return 0;
124 }
125 
127  unsigned len, const char *key)
128 {
129  c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
130  av_dict_set_int(&c->fc->metadata, key, avio_r8(pb), 0);
131 
132  return 0;
133 }
134 
136  unsigned len, const char *key)
137 {
138  short genre;
139 
140  avio_r8(pb); // unknown
141 
142  genre = avio_r8(pb);
143  if (genre < 1 || genre > ID3v1_GENRE_MAX)
144  return 0;
145  c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
146  av_dict_set(&c->fc->metadata, key, ff_id3v1_genre_str[genre-1], 0);
147 
148  return 0;
149 }
150 
151 static const uint32_t mac_to_unicode[128] = {
152  0x00C4,0x00C5,0x00C7,0x00C9,0x00D1,0x00D6,0x00DC,0x00E1,
153  0x00E0,0x00E2,0x00E4,0x00E3,0x00E5,0x00E7,0x00E9,0x00E8,
154  0x00EA,0x00EB,0x00ED,0x00EC,0x00EE,0x00EF,0x00F1,0x00F3,
155  0x00F2,0x00F4,0x00F6,0x00F5,0x00FA,0x00F9,0x00FB,0x00FC,
156  0x2020,0x00B0,0x00A2,0x00A3,0x00A7,0x2022,0x00B6,0x00DF,
157  0x00AE,0x00A9,0x2122,0x00B4,0x00A8,0x2260,0x00C6,0x00D8,
158  0x221E,0x00B1,0x2264,0x2265,0x00A5,0x00B5,0x2202,0x2211,
159  0x220F,0x03C0,0x222B,0x00AA,0x00BA,0x03A9,0x00E6,0x00F8,
160  0x00BF,0x00A1,0x00AC,0x221A,0x0192,0x2248,0x2206,0x00AB,
161  0x00BB,0x2026,0x00A0,0x00C0,0x00C3,0x00D5,0x0152,0x0153,
162  0x2013,0x2014,0x201C,0x201D,0x2018,0x2019,0x00F7,0x25CA,
163  0x00FF,0x0178,0x2044,0x20AC,0x2039,0x203A,0xFB01,0xFB02,
164  0x2021,0x00B7,0x201A,0x201E,0x2030,0x00C2,0x00CA,0x00C1,
165  0x00CB,0x00C8,0x00CD,0x00CE,0x00CF,0x00CC,0x00D3,0x00D4,
166  0xF8FF,0x00D2,0x00DA,0x00DB,0x00D9,0x0131,0x02C6,0x02DC,
167  0x00AF,0x02D8,0x02D9,0x02DA,0x00B8,0x02DD,0x02DB,0x02C7,
168 };
169 
171  char *dst, int dstlen)
172 {
173  char *p = dst;
174  char *end = dst+dstlen-1;
175  int i;
176 
177  for (i = 0; i < len; i++) {
178  uint8_t t, c = avio_r8(pb);
179 
180  if (p >= end)
181  continue;
182 
183  if (c < 0x80)
184  *p++ = c;
185  else if (p < end)
186  PUT_UTF8(mac_to_unicode[c-0x80], t, if (p < end) *p++ = t;);
187  }
188  *p = 0;
189  return p - dst;
190 }
191 
192 /**
193  * Get the requested item.
194  */
195 static HEIFItem *get_heif_item(MOVContext *c, unsigned id)
196 {
197  HEIFItem *item = NULL;
198 
199  for (int i = 0; i < c->nb_heif_item; i++) {
200  if (!c->heif_item[i] || c->heif_item[i]->item_id != id)
201  continue;
202 
203  item = c->heif_item[i];
204  break;
205  }
206 
207  return item;
208 }
209 
210 /**
211  * Get the current stream in the parsing process. This can either be the
212  * latest stream added to the context, or the stream referenced by an item.
213  */
215 {
216  AVStream *st = NULL;
217  HEIFItem *item;
218 
219  if (c->fc->nb_streams < 1)
220  return NULL;
221 
222  if (c->cur_item_id == -1)
223  return c->fc->streams[c->fc->nb_streams-1];
224 
225  item = get_heif_item(c, c->cur_item_id);
226  if (item)
227  st = item->st;
228 
229  return st;
230 }
231 
232 static int mov_read_covr(MOVContext *c, AVIOContext *pb, int type, int len)
233 {
234  AVStream *st;
235  MOVStreamContext *sc;
236  enum AVCodecID id;
237  int ret;
238 
239  switch (type) {
240  case 0xd: id = AV_CODEC_ID_MJPEG; break;
241  case 0xe: id = AV_CODEC_ID_PNG; break;
242  case 0x1b: id = AV_CODEC_ID_BMP; break;
243  default:
244  av_log(c->fc, AV_LOG_WARNING, "Unknown cover type: 0x%x.\n", type);
245  avio_skip(pb, len);
246  return 0;
247  }
248 
249  sc = av_mallocz(sizeof(*sc));
250  if (!sc)
251  return AVERROR(ENOMEM);
252  ret = ff_add_attached_pic(c->fc, NULL, pb, NULL, len);
253  if (ret < 0) {
254  av_free(sc);
255  return ret;
256  }
257  st = c->fc->streams[c->fc->nb_streams - 1];
258  st->priv_data = sc;
259  sc->id = st->id;
260  sc->refcount = 1;
261 
262  if (st->attached_pic.size >= 8 && id != AV_CODEC_ID_BMP) {
263  if (AV_RB64(st->attached_pic.data) == 0x89504e470d0a1a0a) {
264  id = AV_CODEC_ID_PNG;
265  } else {
266  id = AV_CODEC_ID_MJPEG;
267  }
268  }
269  st->codecpar->codec_id = id;
270 
271  return 0;
272 }
273 
274 // 3GPP TS 26.244
275 static int mov_metadata_loci(MOVContext *c, AVIOContext *pb, unsigned len)
276 {
277  char language[4] = { 0 };
278  char buf[200], place[100];
279  uint16_t langcode = 0;
280  double longitude, latitude, altitude;
281  const char *key = "location";
282 
283  if (len < 4 + 2 + 1 + 1 + 4 + 4 + 4) {
284  av_log(c->fc, AV_LOG_ERROR, "loci too short\n");
285  return AVERROR_INVALIDDATA;
286  }
287 
288  avio_skip(pb, 4); // version+flags
289  langcode = avio_rb16(pb);
290  ff_mov_lang_to_iso639(langcode, language);
291  len -= 6;
292 
293  len -= avio_get_str(pb, len, place, sizeof(place));
294  if (len < 1) {
295  av_log(c->fc, AV_LOG_ERROR, "place name too long\n");
296  return AVERROR_INVALIDDATA;
297  }
298  avio_skip(pb, 1); // role
299  len -= 1;
300 
301  if (len < 12) {
302  av_log(c->fc, AV_LOG_ERROR,
303  "loci too short (%u bytes left, need at least %d)\n", len, 12);
304  return AVERROR_INVALIDDATA;
305  }
306  longitude = ((int32_t) avio_rb32(pb)) / (float) (1 << 16);
307  latitude = ((int32_t) avio_rb32(pb)) / (float) (1 << 16);
308  altitude = ((int32_t) avio_rb32(pb)) / (float) (1 << 16);
309 
310  // Try to output in the same format as the ?xyz field
311  snprintf(buf, sizeof(buf), "%+08.4f%+09.4f", latitude, longitude);
312  if (altitude)
313  av_strlcatf(buf, sizeof(buf), "%+f", altitude);
314  av_strlcatf(buf, sizeof(buf), "/%s", place);
315 
316  if (*language && strcmp(language, "und")) {
317  char key2[16];
318  snprintf(key2, sizeof(key2), "%s-%s", key, language);
319  av_dict_set(&c->fc->metadata, key2, buf, 0);
320  }
321  c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
322  return av_dict_set(&c->fc->metadata, key, buf, 0);
323 }
324 
325 static int mov_metadata_hmmt(MOVContext *c, AVIOContext *pb, unsigned len)
326 {
327  int i, n_hmmt;
328 
329  if (len < 2)
330  return 0;
331  if (c->ignore_chapters)
332  return 0;
333 
334  n_hmmt = avio_rb32(pb);
335  if (n_hmmt > len / 4)
336  return AVERROR_INVALIDDATA;
337  for (i = 0; i < n_hmmt && !pb->eof_reached; i++) {
338  int moment_time = avio_rb32(pb);
339  avpriv_new_chapter(c->fc, i, av_make_q(1, 1000), moment_time, AV_NOPTS_VALUE, NULL);
340  }
341  if (avio_feof(pb))
342  return AVERROR_INVALIDDATA;
343  return 0;
344 }
345 
347 {
348  char tmp_key[AV_FOURCC_MAX_STRING_SIZE] = {0};
349  char key2[32], language[4] = {0};
350  char *str = NULL;
351  const char *key = NULL;
352  uint16_t langcode = 0;
353  uint32_t data_type = 0, str_size_alloc;
354  uint64_t str_size;
355  int (*parse)(MOVContext*, AVIOContext*, unsigned, const char*) = NULL;
356  int raw = 0;
357  int num = 0;
359 
360  if (c->trak_index >= 0 && c->trak_index < c->fc->nb_streams)
361  metadata = &c->fc->streams[c->trak_index]->metadata;
362  else
363  metadata = &c->fc->metadata;
364 
365  switch (atom.type) {
366  case MKTAG( '@','P','R','M'): key = "premiere_version"; raw = 1; break;
367  case MKTAG( '@','P','R','Q'): key = "quicktime_version"; raw = 1; break;
368  case MKTAG( 'X','M','P','_'):
369  if (c->export_xmp) { key = "xmp"; raw = 1; } break;
370  case MKTAG( 'a','A','R','T'): key = "album_artist"; break;
371  case MKTAG( 'a','k','I','D'): key = "account_type";
373  case MKTAG( 'a','p','I','D'): key = "account_id"; break;
374  case MKTAG( 'c','a','t','g'): key = "category"; break;
375  case MKTAG( 'c','p','i','l'): key = "compilation";
377  case MKTAG( 'c','p','r','t'): key = "copyright"; break;
378  case MKTAG( 'd','e','s','c'): key = "description"; break;
379  case MKTAG( 'd','i','s','k'): key = "disc";
381  case MKTAG( 'e','g','i','d'): key = "episode_uid";
383  case MKTAG( 'F','I','R','M'): key = "firmware"; raw = 1; break;
384  case MKTAG( 'g','n','r','e'): key = "genre";
385  parse = mov_metadata_gnre; break;
386  case MKTAG( 'h','d','v','d'): key = "hd_video";
388  case MKTAG( 'H','M','M','T'):
389  return mov_metadata_hmmt(c, pb, atom.size);
390  case MKTAG( 'k','e','y','w'): key = "keywords"; break;
391  case MKTAG( 'l','d','e','s'): key = "synopsis"; break;
392  case MKTAG( 'l','o','c','i'):
393  return mov_metadata_loci(c, pb, atom.size);
394  case MKTAG( 'm','a','n','u'): key = "make"; break;
395  case MKTAG( 'm','o','d','l'): key = "model"; break;
396  case MKTAG( 'n','a','m','e'): key = "name"; break;
397  case MKTAG( 'p','c','s','t'): key = "podcast";
399  case MKTAG( 'p','g','a','p'): key = "gapless_playback";
401  case MKTAG( 'p','u','r','d'): key = "purchase_date"; break;
402  case MKTAG( 'r','t','n','g'): key = "rating";
404  case MKTAG( 's','o','a','a'): key = "sort_album_artist"; break;
405  case MKTAG( 's','o','a','l'): key = "sort_album"; break;
406  case MKTAG( 's','o','a','r'): key = "sort_artist"; break;
407  case MKTAG( 's','o','c','o'): key = "sort_composer"; break;
408  case MKTAG( 's','o','n','m'): key = "sort_name"; break;
409  case MKTAG( 's','o','s','n'): key = "sort_show"; break;
410  case MKTAG( 's','t','i','k'): key = "media_type";
412  case MKTAG( 't','r','k','n'): key = "track";
414  case MKTAG( 't','v','e','n'): key = "episode_id"; break;
415  case MKTAG( 't','v','e','s'): key = "episode_sort";
417  case MKTAG( 't','v','n','n'): key = "network"; break;
418  case MKTAG( 't','v','s','h'): key = "show"; break;
419  case MKTAG( 't','v','s','n'): key = "season_number";
421  case MKTAG(0xa9,'A','R','T'): key = "artist"; break;
422  case MKTAG(0xa9,'P','R','D'): key = "producer"; break;
423  case MKTAG(0xa9,'a','l','b'): key = "album"; break;
424  case MKTAG(0xa9,'a','u','t'): key = "artist"; break;
425  case MKTAG(0xa9,'c','h','p'): key = "chapter"; break;
426  case MKTAG(0xa9,'c','m','t'): key = "comment"; break;
427  case MKTAG(0xa9,'c','o','m'): key = "composer"; break;
428  case MKTAG(0xa9,'c','p','y'): key = "copyright"; break;
429  case MKTAG(0xa9,'d','a','y'): key = "date"; break;
430  case MKTAG(0xa9,'d','i','r'): key = "director"; break;
431  case MKTAG(0xa9,'d','i','s'): key = "disclaimer"; break;
432  case MKTAG(0xa9,'e','d','1'): key = "edit_date"; break;
433  case MKTAG(0xa9,'e','n','c'): key = "encoder"; break;
434  case MKTAG(0xa9,'f','m','t'): key = "original_format"; break;
435  case MKTAG(0xa9,'g','e','n'): key = "genre"; break;
436  case MKTAG(0xa9,'g','r','p'): key = "grouping"; break;
437  case MKTAG(0xa9,'h','s','t'): key = "host_computer"; break;
438  case MKTAG(0xa9,'i','n','f'): key = "comment"; break;
439  case MKTAG(0xa9,'l','y','r'): key = "lyrics"; break;
440  case MKTAG(0xa9,'m','a','k'): key = "make"; break;
441  case MKTAG(0xa9,'m','o','d'): key = "model"; break;
442  case MKTAG(0xa9,'n','a','m'): key = "title"; break;
443  case MKTAG(0xa9,'o','p','e'): key = "original_artist"; break;
444  case MKTAG(0xa9,'p','r','d'): key = "producer"; break;
445  case MKTAG(0xa9,'p','r','f'): key = "performers"; break;
446  case MKTAG(0xa9,'r','e','q'): key = "playback_requirements"; break;
447  case MKTAG(0xa9,'s','r','c'): key = "original_source"; break;
448  case MKTAG(0xa9,'s','t','3'): key = "subtitle"; break;
449  case MKTAG(0xa9,'s','w','r'): key = "encoder"; break;
450  case MKTAG(0xa9,'t','o','o'): key = "encoder"; break;
451  case MKTAG(0xa9,'t','r','k'): key = "track"; break;
452  case MKTAG(0xa9,'u','r','l'): key = "URL"; break;
453  case MKTAG(0xa9,'w','r','n'): key = "warning"; break;
454  case MKTAG(0xa9,'w','r','t'): key = "composer"; break;
455  case MKTAG(0xa9,'x','y','z'): key = "location"; break;
456  }
457 retry:
458  if (c->itunes_metadata && atom.size > 8) {
459  int data_size = avio_rb32(pb);
460  int tag = avio_rl32(pb);
461  if (tag == MKTAG('d','a','t','a') && data_size <= atom.size && data_size >= 16) {
462  data_type = avio_rb32(pb); // type
463  avio_rb32(pb); // unknown
464  str_size = data_size - 16;
465  atom.size -= 16;
466 
467  if (!key && c->found_hdlr_mdta && c->meta_keys) {
468  uint32_t index = av_bswap32(atom.type); // BE number has been read as LE
469  if (index < c->meta_keys_count && index > 0) {
470  key = c->meta_keys[index];
471  } else if (atom.type != MKTAG('c', 'o', 'v', 'r')) {
472  av_log(c->fc, AV_LOG_WARNING,
473  "The index of 'data' is out of range: %"PRId32" < 1 or >= %d.\n",
474  index, c->meta_keys_count);
475  }
476  }
477  if (atom.type == MKTAG('c', 'o', 'v', 'r') ||
478  (key && !strcmp(key, "com.apple.quicktime.artwork"))) {
479  int ret = mov_read_covr(c, pb, data_type, str_size);
480  if (ret < 0) {
481  av_log(c->fc, AV_LOG_ERROR, "Error parsing cover art.\n");
482  return ret;
483  }
484  atom.size -= str_size;
485  if (atom.size > 8)
486  goto retry;
487  return ret;
488  }
489  } else return 0;
490  } else if (atom.size > 4 && (key || c->export_all) && !c->itunes_metadata && !raw) {
491  str_size = avio_rb16(pb); // string length
492  if (str_size > atom.size) {
493  raw = 1;
494  avio_seek(pb, -2, SEEK_CUR);
495  av_log(c->fc, AV_LOG_WARNING, "UDTA parsing failed retrying raw\n");
496  goto retry;
497  }
498  langcode = avio_rb16(pb);
499  ff_mov_lang_to_iso639(langcode, language);
500  atom.size -= 4;
501  } else
502  str_size = atom.size;
503 
504  if (c->export_all && !key) {
505  key = av_fourcc_make_string(tmp_key, atom.type);
506  }
507 
508  if (!key)
509  return 0;
510  if (atom.size < 0 || str_size >= INT_MAX/2)
511  return AVERROR_INVALIDDATA;
512 
513  // Allocates enough space if data_type is a int32 or float32 number, otherwise
514  // worst-case requirement for output string in case of utf8 coded input
515  num = (data_type >= 21 && data_type <= 23);
516  str_size_alloc = (num ? 512 : (raw ? str_size : str_size * 2)) + 1;
517  str = av_mallocz(str_size_alloc);
518  if (!str)
519  return AVERROR(ENOMEM);
520 
521  if (parse)
522  parse(c, pb, str_size, key);
523  else {
524  if (!raw && (data_type == 3 || (data_type == 0 && (langcode < 0x400 || langcode == 0x7fff)))) { // MAC Encoded
525  mov_read_mac_string(c, pb, str_size, str, str_size_alloc);
526  } else if (data_type == 21) { // BE signed integer, variable size
527  int val = 0;
528  if (str_size == 1)
529  val = (int8_t)avio_r8(pb);
530  else if (str_size == 2)
531  val = (int16_t)avio_rb16(pb);
532  else if (str_size == 3)
533  val = ((int32_t)(avio_rb24(pb)<<8))>>8;
534  else if (str_size == 4)
535  val = (int32_t)avio_rb32(pb);
536  if (snprintf(str, str_size_alloc, "%d", val) >= str_size_alloc) {
537  av_log(c->fc, AV_LOG_ERROR,
538  "Failed to store the number (%d) in string.\n", val);
539  av_free(str);
540  return AVERROR_INVALIDDATA;
541  }
542  } else if (data_type == 22) { // BE unsigned integer, variable size
543  unsigned int val = 0;
544  if (str_size == 1)
545  val = avio_r8(pb);
546  else if (str_size == 2)
547  val = avio_rb16(pb);
548  else if (str_size == 3)
549  val = avio_rb24(pb);
550  else if (str_size == 4)
551  val = avio_rb32(pb);
552  if (snprintf(str, str_size_alloc, "%u", val) >= str_size_alloc) {
553  av_log(c->fc, AV_LOG_ERROR,
554  "Failed to store the number (%u) in string.\n", val);
555  av_free(str);
556  return AVERROR_INVALIDDATA;
557  }
558  } else if (data_type == 23 && str_size >= 4) { // BE float32
559  float val = av_int2float(avio_rb32(pb));
560  if (snprintf(str, str_size_alloc, "%f", val) >= str_size_alloc) {
561  av_log(c->fc, AV_LOG_ERROR,
562  "Failed to store the float32 number (%f) in string.\n", val);
563  av_free(str);
564  return AVERROR_INVALIDDATA;
565  }
566  } else if (data_type > 1 && data_type != 4) {
567  // data_type can be 0 if not set at all above. data_type 1 means
568  // UTF8 and 4 means "UTF8 sort". For any other type (UTF16 or e.g.
569  // a picture), don't return it blindly in a string that is supposed
570  // to be UTF8 text.
571  av_log(c->fc, AV_LOG_WARNING, "Skipping unhandled metadata %s of type %"PRIu32"\n", key, data_type);
572  av_free(str);
573  return 0;
574  } else {
575  int ret = ffio_read_size(pb, str, str_size);
576  if (ret < 0) {
577  av_free(str);
578  return ret;
579  }
580  str[str_size] = 0;
581  }
582  c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
583  if (c->itunes_metadata && av_dict_get(*metadata, key, NULL, 0))
585  av_dict_set(metadata, key, str, c->itunes_metadata ? AV_DICT_APPEND : 0);
586  if (*language && strcmp(language, "und")) {
587  snprintf(key2, sizeof(key2), "%s-%s", key, language);
588  av_dict_set(metadata, key2, str, 0);
589  }
590  if (!strcmp(key, "encoder")) {
591  int major, minor, micro;
592  if (sscanf(str, "HandBrake %d.%d.%d", &major, &minor, &micro) == 3) {
593  c->handbrake_version = 1000000*major + 1000*minor + micro;
594  }
595  }
596 
597  atom.size -= str_size;
598  av_freep(&str);
599 
600  // Read remaining data atoms for multi-valued iTunes tags (e.g. multiple
601  // artists stored as multiple data atoms within one tag atom), consistent
602  // with the existing covr path.
603  // Note: multiple sibling tag atoms with the same key (e.g. three separate
604  // ©ART atoms under ilst) are handled by the AV_DICT_APPEND logic above,
605  // since mov_read_udta_string() is called once per tag atom.
606  if (c->itunes_metadata && atom.size > 8)
607  goto retry;
608  }
609 
610  av_freep(&str);
611  return 0;
612 }
613 
615 {
616  int64_t start;
617  int i, nb_chapters, str_len, version;
618  char str[256+1];
619  int ret;
620 
621  if (c->ignore_chapters)
622  return 0;
623 
624  if ((atom.size -= 5) < 0)
625  return 0;
626 
627  version = avio_r8(pb);
628  avio_rb24(pb);
629  if (version)
630  avio_rb32(pb); // ???
631  nb_chapters = avio_r8(pb);
632 
633  for (i = 0; i < nb_chapters; i++) {
634  if (atom.size < 9)
635  return 0;
636 
637  start = avio_rb64(pb);
638  str_len = avio_r8(pb);
639 
640  if ((atom.size -= 9+str_len) < 0)
641  return 0;
642 
643  ret = ffio_read_size(pb, str, str_len);
644  if (ret < 0)
645  return ret;
646  str[str_len] = 0;
647  avpriv_new_chapter(c->fc, i, (AVRational){1,10000000}, start, AV_NOPTS_VALUE, str);
648  }
649  return 0;
650 }
651 
652 #define MIN_DATA_ENTRY_BOX_SIZE 12
654 {
655  AVStream *st;
656  MOVStreamContext *sc;
657  int entries, i, j;
658 
659  if (c->fc->nb_streams < 1)
660  return 0;
661  st = c->fc->streams[c->fc->nb_streams-1];
662  sc = st->priv_data;
663 
664  avio_rb32(pb); // version + flags
665  entries = avio_rb32(pb);
666  if (!entries ||
667  entries > (atom.size - 1) / MIN_DATA_ENTRY_BOX_SIZE + 1 ||
668  entries >= UINT_MAX / sizeof(*sc->drefs))
669  return AVERROR_INVALIDDATA;
670 
671  for (i = 0; i < sc->drefs_count; i++) {
672  MOVDref *dref = &sc->drefs[i];
673  av_freep(&dref->path);
674  av_freep(&dref->dir);
675  }
676  av_free(sc->drefs);
677  sc->drefs_count = 0;
678  sc->drefs = av_mallocz(entries * sizeof(*sc->drefs));
679  if (!sc->drefs)
680  return AVERROR(ENOMEM);
681  sc->drefs_count = entries;
682 
683  for (i = 0; i < entries; i++) {
684  MOVDref *dref = &sc->drefs[i];
685  uint32_t size = avio_rb32(pb);
686  int64_t next = avio_tell(pb);
687 
688  if (size < 12 || next < 0 || next > INT64_MAX - size)
689  return AVERROR_INVALIDDATA;
690 
691  next += size - 4;
692 
693  dref->type = avio_rl32(pb);
694  avio_rb32(pb); // version + flags
695 
696  if (dref->type == MKTAG('a','l','i','s') && size > 150) {
697  /* macintosh alias record */
698  uint16_t volume_len, len;
699  int16_t type;
700  int ret;
701 
702  avio_skip(pb, 10);
703 
704  volume_len = avio_r8(pb);
705  volume_len = FFMIN(volume_len, 27);
706  ret = ffio_read_size(pb, dref->volume, 27);
707  if (ret < 0)
708  return ret;
709  dref->volume[volume_len] = 0;
710  av_log(c->fc, AV_LOG_DEBUG, "volume %s, len %d\n", dref->volume, volume_len);
711 
712  avio_skip(pb, 12);
713 
714  len = avio_r8(pb);
715  len = FFMIN(len, 63);
716  ret = ffio_read_size(pb, dref->filename, 63);
717  if (ret < 0)
718  return ret;
719  dref->filename[len] = 0;
720  av_log(c->fc, AV_LOG_DEBUG, "filename %s, len %d\n", dref->filename, len);
721 
722  avio_skip(pb, 16);
723 
724  /* read next level up_from_alias/down_to_target */
725  dref->nlvl_from = avio_rb16(pb);
726  dref->nlvl_to = avio_rb16(pb);
727  av_log(c->fc, AV_LOG_DEBUG, "nlvl from %d, nlvl to %d\n",
728  dref->nlvl_from, dref->nlvl_to);
729 
730  avio_skip(pb, 16);
731 
732  for (type = 0; type != -1 && avio_tell(pb) < next; ) {
733  if (avio_feof(pb))
734  return AVERROR_EOF;
735  type = avio_rb16(pb);
736  len = avio_rb16(pb);
737  av_log(c->fc, AV_LOG_DEBUG, "type %d, len %d\n", type, len);
738  if (len&1)
739  len += 1;
740  if (type == 2) { // absolute path
741  av_free(dref->path);
742  dref->path = av_mallocz(len+1);
743  if (!dref->path)
744  return AVERROR(ENOMEM);
745 
746  ret = ffio_read_size(pb, dref->path, len);
747  if (ret < 0) {
748  av_freep(&dref->path);
749  return ret;
750  }
751  if (len > volume_len && !strncmp(dref->path, dref->volume, volume_len)) {
752  len -= volume_len;
753  memmove(dref->path, dref->path+volume_len, len);
754  dref->path[len] = 0;
755  }
756  // trim string of any ending zeros
757  for (j = len - 1; j >= 0; j--) {
758  if (dref->path[j] == 0)
759  len--;
760  else
761  break;
762  }
763  for (j = 0; j < len; j++)
764  if (dref->path[j] == ':' || dref->path[j] == 0)
765  dref->path[j] = '/';
766  av_log(c->fc, AV_LOG_DEBUG, "path %s\n", dref->path);
767  } else if (type == 0) { // directory name
768  av_free(dref->dir);
769  dref->dir = av_malloc(len+1);
770  if (!dref->dir)
771  return AVERROR(ENOMEM);
772 
773  ret = ffio_read_size(pb, dref->dir, len);
774  if (ret < 0) {
775  av_freep(&dref->dir);
776  return ret;
777  }
778  dref->dir[len] = 0;
779  for (j = 0; j < len; j++)
780  if (dref->dir[j] == ':')
781  dref->dir[j] = '/';
782  av_log(c->fc, AV_LOG_DEBUG, "dir %s\n", dref->dir);
783  } else
784  avio_skip(pb, len);
785  }
786  } else {
787  av_log(c->fc, AV_LOG_DEBUG, "Unknown dref type 0x%08"PRIx32" size %"PRIu32"\n",
788  dref->type, size);
789  entries--;
790  i--;
791  }
792  avio_seek(pb, next, SEEK_SET);
793  }
794  return 0;
795 }
796 
798 {
799  AVStream *st;
800  uint32_t type;
801  uint32_t ctype;
802  int64_t title_size;
803  char *title_str;
804  int ret;
805 
806  avio_r8(pb); /* version */
807  avio_rb24(pb); /* flags */
808 
809  /* component type */
810  ctype = avio_rl32(pb);
811  type = avio_rl32(pb); /* component subtype */
812 
813  av_log(c->fc, AV_LOG_TRACE, "ctype=%s\n", av_fourcc2str(ctype));
814  av_log(c->fc, AV_LOG_TRACE, "stype=%s\n", av_fourcc2str(type));
815 
816  if (c->trak_index < 0) { // meta not inside a trak
817  if (type == MKTAG('m','d','t','a')) {
818  c->found_hdlr_mdta = 1;
819  }
820  return 0;
821  }
822 
823  st = c->fc->streams[c->fc->nb_streams-1];
824 
825  if (type == MKTAG('v','i','d','e'))
827  else if (type == MKTAG('s','o','u','n'))
829  else if (type == MKTAG('m','1','a',' '))
831  else if ((type == MKTAG('s','u','b','p')) || (type == MKTAG('c','l','c','p')))
833 
834  avio_rb32(pb); /* component manufacture */
835  avio_rb32(pb); /* component flags */
836  avio_rb32(pb); /* component flags mask */
837 
838  title_size = atom.size - 24;
839  if (title_size > 0) {
840  if (title_size > FFMIN(INT_MAX, SIZE_MAX-1))
841  return AVERROR_INVALIDDATA;
842  title_str = av_malloc(title_size + 1); /* Add null terminator */
843  if (!title_str)
844  return AVERROR(ENOMEM);
845 
846  ret = ffio_read_size(pb, title_str, title_size);
847  if (ret < 0) {
848  av_freep(&title_str);
849  return ret;
850  }
851  title_str[title_size] = 0;
852  if (title_str[0]) {
853  int off = (!c->isom && title_str[0] == title_size - 1);
854  // flag added so as to not set stream handler name if already set from mdia->hdlr
855  av_dict_set(&st->metadata, "handler_name", title_str + off, AV_DICT_DONT_OVERWRITE);
856  }
857  av_freep(&title_str);
858  }
859 
860  return 0;
861 }
862 
864 {
865  return ff_mov_read_esds(c->fc, pb);
866 }
867 
869 {
870  AVStream *st;
871  AVPacketSideData *sd;
872  enum AVAudioServiceType *ast;
873  int ac3info, acmod, lfeon, bsmod;
874  uint64_t mask;
875 
876  if (c->fc->nb_streams < 1)
877  return 0;
878  st = c->fc->streams[c->fc->nb_streams-1];
879 
883  sizeof(*ast), 0);
884  if (!sd)
885  return AVERROR(ENOMEM);
886 
887  ast = (enum AVAudioServiceType*)sd->data;
888  ac3info = avio_rb24(pb);
889  bsmod = (ac3info >> 14) & 0x7;
890  acmod = (ac3info >> 11) & 0x7;
891  lfeon = (ac3info >> 10) & 0x1;
892 
894  if (lfeon)
898 
899  *ast = bsmod;
900  if (st->codecpar->ch_layout.nb_channels > 1 && bsmod == 0x7)
902 
903  return 0;
904 }
905 
906 #if CONFIG_IAMFDEC
907 static int mov_read_iacb(MOVContext *c, AVIOContext *pb, MOVAtom atom)
908 {
909  AVStream *st;
910  MOVStreamContext *sc;
911  FFIOContext b;
912  AVIOContext *descriptor_pb;
914  IAMFContext *iamf;
916  unsigned descriptors_size;
917  int nb_frames, disposition;
918  int version, ret;
919 
920  if (atom.size < 5)
921  return AVERROR_INVALIDDATA;
922 
923  if (c->fc->nb_streams < 1)
924  return 0;
925 
926  version = avio_r8(pb);
927  if (version != 1) {
928  av_log(c->fc, AV_LOG_ERROR, "%s configurationVersion %d",
929  version < 1 ? "invalid" : "unsupported", version);
930  return AVERROR_INVALIDDATA;
931  }
932 
933  descriptors_size = ffio_read_leb(pb);
934  if (!descriptors_size || descriptors_size > INT_MAX)
935  return AVERROR_INVALIDDATA;
936 
937  st = c->fc->streams[c->fc->nb_streams - 1];
938  sc = st->priv_data;
939 
940  if (st->codecpar->extradata) {
941  av_log(c->fc, AV_LOG_WARNING, "ignoring iacb\n");
942  return 0;
943  }
944 
945  sc->iamf = av_mallocz(sizeof(*sc->iamf));
946  if (!sc->iamf)
947  return AVERROR(ENOMEM);
948  iamf = &sc->iamf->iamf;
949 
950  ret = ff_alloc_extradata(st->codecpar, descriptors_size);
951  if (ret < 0)
952  return ret;
953 
954  ret = avio_read(pb, st->codecpar->extradata, descriptors_size);
955  if (ret != descriptors_size)
956  return ret < 0 ? ret : AVERROR_INVALIDDATA;
957 
958  ffio_init_read_context(&b, st->codecpar->extradata, descriptors_size);
959  descriptor_pb = &b.pub;
960 
961  ret = ff_iamfdec_read_descriptors(iamf, descriptor_pb, descriptors_size, c->fc);
962  if (ret < 0)
963  return ret;
964 
965  metadata = st->metadata;
966  st->metadata = NULL;
967  start_time = st->start_time;
968  nb_frames = st->nb_frames;
969  duration = st->duration;
970  disposition = st->disposition;
971 
972  for (int i = 0; i < iamf->nb_audio_elements; i++) {
973  IAMFAudioElement *audio_element = iamf->audio_elements[i];
974  const AVIAMFAudioElement *element;
975  AVStreamGroup *stg =
977 
978  if (!stg) {
979  ret = AVERROR(ENOMEM);
980  goto fail;
981  }
982 
984  stg->id = audio_element->audio_element_id;
985  /* Transfer ownership */
986  element = stg->params.iamf_audio_element = audio_element->element;
987  audio_element->element = NULL;
988 
989  for (int j = 0; j < audio_element->nb_substreams; j++) {
990  IAMFSubStream *substream = &audio_element->substreams[j];
991  AVStream *stream;
992 
993  if (!i && !j) {
994  if (audio_element->layers[0].substream_count != 1)
995  disposition &= ~AV_DISPOSITION_DEFAULT;
996  stream = st;
997  } else
998  stream = avformat_new_stream(c->fc, NULL);
999  if (!stream) {
1000  ret = AVERROR(ENOMEM);
1001  goto fail;
1002  }
1003 
1004  stream->start_time = start_time;
1005  stream->nb_frames = nb_frames;
1006  stream->duration = duration;
1007  stream->disposition = disposition;
1008  if (stream != st) {
1009  stream->priv_data = sc;
1010  sc->refcount++;
1011  }
1012 
1015  if (i || j) {
1017  if (audio_element->layers[0].substream_count == 1)
1018  stream->disposition &= ~AV_DISPOSITION_DEFAULT;
1019  }
1020 
1021  ret = avcodec_parameters_copy(stream->codecpar, substream->codecpar);
1022  if (ret < 0)
1023  goto fail;
1024 
1025  stream->id = substream->audio_substream_id;
1026 
1027  avpriv_set_pts_info(st, 64, 1, sc->time_scale);
1028 
1029  ret = avformat_stream_group_add_stream(stg, stream);
1030  if (ret < 0)
1031  goto fail;
1032  }
1033 
1034  ret = av_dict_copy(&stg->metadata, metadata, 0);
1035  if (ret < 0)
1036  goto fail;
1037  }
1038 
1039  for (int i = 0; i < iamf->nb_mix_presentations; i++) {
1040  IAMFMixPresentation *mix_presentation = iamf->mix_presentations[i];
1041  const AVIAMFMixPresentation *mix = mix_presentation->cmix;
1042  AVStreamGroup *stg =
1044 
1045  if (!stg) {
1046  ret = AVERROR(ENOMEM);
1047  goto fail;
1048  }
1049 
1051  stg->id = mix_presentation->mix_presentation_id;
1052  /* Transfer ownership */
1053  stg->params.iamf_mix_presentation = mix_presentation->mix;
1054  mix_presentation->mix = NULL;
1055 
1056  for (int j = 0; j < mix->nb_submixes; j++) {
1057  const AVIAMFSubmix *submix = mix->submixes[j];
1058 
1059  for (int k = 0; k < submix->nb_elements; k++) {
1060  const AVIAMFSubmixElement *submix_element = submix->elements[k];
1061  const AVStreamGroup *audio_element = NULL;
1062 
1063  for (int l = 0; l < c->fc->nb_stream_groups; l++)
1064  if (c->fc->stream_groups[l]->type == AV_STREAM_GROUP_PARAMS_IAMF_AUDIO_ELEMENT &&
1065  c->fc->stream_groups[l]->id == submix_element->audio_element_id) {
1066  audio_element = c->fc->stream_groups[l];
1067  break;
1068  }
1069  av_assert0(audio_element);
1070 
1071  for (int l = 0; l < audio_element->nb_streams; l++) {
1072  ret = avformat_stream_group_add_stream(stg, audio_element->streams[l]);
1073  if (ret < 0 && ret != AVERROR(EEXIST))
1074  goto fail;
1075  }
1076  }
1077  }
1078 
1079  ret = av_dict_copy(&stg->metadata, metadata, 0);
1080  if (ret < 0)
1081  goto fail;
1082  }
1083 
1084  ret = 0;
1085 fail:
1087 
1088  return ret;
1089 }
1090 #endif
1091 
1093 {
1094  AVStream *st;
1095  int32_t sample_rate;
1096 
1097  if (atom.size < 8 || c->fc->nb_streams < 1)
1098  return 0;
1099 
1100  st = c->fc->streams[c->fc->nb_streams-1];
1101  if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO) {
1102  av_log(c->fc, AV_LOG_WARNING, "'srat' within non-audio sample entry, skip\n");
1103  return 0;
1104  }
1105 
1106  if (!c->isom) {
1107  av_log(c->fc, AV_LOG_WARNING, "'srat' within non-isom, skip\n");
1108  return 0;
1109  }
1110 
1111  avio_skip(pb, 4); // version+flags
1112  sample_rate = avio_rb32(pb);
1113  if (sample_rate > 0) {
1114  av_log(c->fc, AV_LOG_DEBUG,
1115  "overwrite sample rate from %d to %d by 'srat'\n",
1116  st->codecpar->sample_rate, sample_rate);
1117  st->codecpar->sample_rate = sample_rate;
1118  } else {
1119  av_log(c->fc, AV_LOG_WARNING,
1120  "ignore invalid sample rate %d in 'srat'\n", sample_rate);
1121  }
1122 
1123  return 0;
1124 }
1125 
1127 {
1128  AVStream *st;
1129  AVPacketSideData *sd;
1130  enum AVAudioServiceType *ast;
1131  int eac3info, acmod, lfeon, bsmod;
1132  uint64_t mask;
1133 
1134  if (c->fc->nb_streams < 1)
1135  return 0;
1136  st = c->fc->streams[c->fc->nb_streams-1];
1137 
1141  sizeof(*ast), 0);
1142  if (!sd)
1143  return AVERROR(ENOMEM);
1144 
1145  ast = (enum AVAudioServiceType*)sd->data;
1146 
1147  /* No need to parse fields for additional independent substreams and its
1148  * associated dependent substreams since libavcodec's E-AC-3 decoder
1149  * does not support them yet. */
1150  avio_rb16(pb); /* data_rate and num_ind_sub */
1151  eac3info = avio_rb24(pb);
1152  bsmod = (eac3info >> 12) & 0x1f;
1153  acmod = (eac3info >> 9) & 0x7;
1154  lfeon = (eac3info >> 8) & 0x1;
1155 
1157  if (lfeon)
1161 
1162  *ast = bsmod;
1163  if (st->codecpar->ch_layout.nb_channels > 1 && bsmod == 0x7)
1165 
1166  return 0;
1167 }
1168 
1170 {
1171 #define DDTS_SIZE 20
1172  uint8_t buf[DDTS_SIZE + AV_INPUT_BUFFER_PADDING_SIZE];
1173  AVStream *st = NULL;
1174  uint32_t frame_duration_code = 0;
1175  uint32_t channel_layout_code = 0;
1176  GetBitContext gb;
1177  int ret;
1178 
1179  if ((ret = ffio_read_size(pb, buf, DDTS_SIZE)) < 0)
1180  return ret;
1181 
1182  init_get_bits(&gb, buf, 8 * DDTS_SIZE);
1183 
1184  if (c->fc->nb_streams < 1) {
1185  return 0;
1186  }
1187  st = c->fc->streams[c->fc->nb_streams-1];
1188 
1189  st->codecpar->sample_rate = get_bits_long(&gb, 32);
1190  if (st->codecpar->sample_rate <= 0) {
1191  av_log(c->fc, AV_LOG_ERROR, "Invalid sample rate %d\n", st->codecpar->sample_rate);
1192  return AVERROR_INVALIDDATA;
1193  }
1194  skip_bits_long(&gb, 32); /* max bitrate */
1195  st->codecpar->bit_rate = get_bits_long(&gb, 32);
1196  st->codecpar->bits_per_coded_sample = get_bits(&gb, 8);
1197  frame_duration_code = get_bits(&gb, 2);
1198  skip_bits(&gb, 30); /* various fields */
1199  channel_layout_code = get_bits(&gb, 16);
1200 
1201  st->codecpar->frame_size =
1202  (frame_duration_code == 0) ? 512 :
1203  (frame_duration_code == 1) ? 1024 :
1204  (frame_duration_code == 2) ? 2048 :
1205  (frame_duration_code == 3) ? 4096 : 0;
1206 
1207  if (channel_layout_code > 0xff) {
1208  av_log(c->fc, AV_LOG_WARNING, "Unsupported DTS audio channel layout\n");
1209  }
1212  ((channel_layout_code & 0x1) ? AV_CH_FRONT_CENTER : 0) |
1213  ((channel_layout_code & 0x2) ? AV_CH_FRONT_LEFT : 0) |
1214  ((channel_layout_code & 0x2) ? AV_CH_FRONT_RIGHT : 0) |
1215  ((channel_layout_code & 0x4) ? AV_CH_SIDE_LEFT : 0) |
1216  ((channel_layout_code & 0x4) ? AV_CH_SIDE_RIGHT : 0) |
1217  ((channel_layout_code & 0x8) ? AV_CH_LOW_FREQUENCY : 0));
1218 
1219  return 0;
1220 }
1221 
1223 {
1224  AVStream *st;
1225 
1226  if (c->fc->nb_streams < 1)
1227  return 0;
1228  st = c->fc->streams[c->fc->nb_streams-1];
1229 
1230  if (atom.size < 16)
1231  return 0;
1232 
1233  /* skip version and flags */
1234  avio_skip(pb, 4);
1235 
1236  ff_mov_read_chan(c->fc, pb, st, atom.size - 4);
1237 
1238  return 0;
1239 }
1240 
1242 {
1243  int64_t end = av_sat_add64(avio_tell(pb), atom.size);
1244  int version, flags;
1245  int ret;
1246  AVStream *st;
1247 
1248  if (c->fc->nb_streams < 1)
1249  return 0;
1250  st = c->fc->streams[c->fc->nb_streams-1];
1251 
1252  version = avio_r8(pb);
1253  flags = avio_rb24(pb);
1254  if (version > 1 || flags != 0) {
1255  av_log(c->fc, AV_LOG_WARNING,
1256  "Unsupported 'chnl' box with version %d, flags: %#x\n",
1257  version, flags);
1258  return 0;
1259  }
1260 
1261  ret = ff_mov_read_chnl(c->fc, pb, st, version);
1262  if (ret < 0) {
1263  avio_seek(pb, end, SEEK_SET);
1264  return 0;
1265  }
1266 
1267  if (avio_tell(pb) != end) {
1268  av_log(c->fc, AV_LOG_WARNING, "skip %" PRId64 " bytes of unknown data inside chnl\n",
1269  end - avio_tell(pb));
1270  avio_seek(pb, end, SEEK_SET);
1271  }
1272  return ret;
1273 }
1274 
1276 {
1277  AVStream *st;
1278  int ret;
1279 
1280  if (c->fc->nb_streams < 1)
1281  return 0;
1282  st = c->fc->streams[c->fc->nb_streams-1];
1283 
1284  if ((ret = ff_get_wav_header(c->fc, pb, st->codecpar, atom.size, 0)) < 0)
1285  av_log(c->fc, AV_LOG_WARNING, "get_wav_header failed\n");
1286 
1287  return ret;
1288 }
1289 
1291 {
1292  AVStream *st;
1293  HEIFItem *item;
1294  AVPacketSideData *sd;
1295  int width, height, err = 0;
1296  AVRational aperture_width, aperture_height, horiz_off, vert_off;
1297  AVRational pc_x, pc_y;
1298  uint64_t top, bottom, left, right;
1299 
1300  item = get_heif_item(c, c->cur_item_id);
1301  st = get_curr_st(c);
1302  if (!st)
1303  return 0;
1304 
1305  width = st->codecpar->width;
1306  height = st->codecpar->height;
1307  if ((!width || !height) && item) {
1308  width = item->width;
1309  height = item->height;
1310  }
1311  if (!width || !height) {
1312  err = AVERROR_INVALIDDATA;
1313  goto fail;
1314  }
1315 
1316  aperture_width.num = avio_rb32(pb);
1317  aperture_width.den = avio_rb32(pb);
1318  aperture_height.num = avio_rb32(pb);
1319  aperture_height.den = avio_rb32(pb);
1320 
1321  horiz_off.num = avio_rb32(pb);
1322  horiz_off.den = avio_rb32(pb);
1323  vert_off.num = avio_rb32(pb);
1324  vert_off.den = avio_rb32(pb);
1325 
1326  if (aperture_width.num < 0 || aperture_width.den < 0 ||
1327  aperture_height.num < 0 || aperture_height.den < 0 ||
1328  horiz_off.den < 0 || vert_off.den < 0) {
1329  err = AVERROR_INVALIDDATA;
1330  goto fail;
1331  }
1332  if ((av_cmp_q((AVRational) { width, 1 }, aperture_width) < 0) ||
1333  (av_cmp_q((AVRational) { height, 1 }, aperture_height) < 0)) {
1334  err = AVERROR_INVALIDDATA;
1335  goto fail;
1336  }
1337  av_log(c->fc, AV_LOG_TRACE, "clap: apertureWidth %d/%d, apertureHeight %d/%d "
1338  "horizOff %d/%d vertOff %d/%d\n",
1339  aperture_width.num, aperture_width.den, aperture_height.num, aperture_height.den,
1340  horiz_off.num, horiz_off.den, vert_off.num, vert_off.den);
1341 
1342  pc_x = av_mul_q((AVRational) { width - 1, 1 }, (AVRational) { 1, 2 });
1343  pc_x = av_add_q(pc_x, horiz_off);
1344  pc_y = av_mul_q((AVRational) { height - 1, 1 }, (AVRational) { 1, 2 });
1345  pc_y = av_add_q(pc_y, vert_off);
1346 
1347  aperture_width = av_sub_q(aperture_width, (AVRational) { 1, 1 });
1348  aperture_width = av_mul_q(aperture_width, (AVRational) { 1, 2 });
1349  aperture_height = av_sub_q(aperture_height, (AVRational) { 1, 1 });
1350  aperture_height = av_mul_q(aperture_height, (AVRational) { 1, 2 });
1351 
1352  left = av_q2d(av_sub_q(pc_x, aperture_width));
1353  right = av_q2d(av_add_q(pc_x, aperture_width));
1354  top = av_q2d(av_sub_q(pc_y, aperture_height));
1355  bottom = av_q2d(av_add_q(pc_y, aperture_height));
1356 
1357  if (bottom > (height - 1) ||
1358  right > (width - 1)) {
1359  err = AVERROR_INVALIDDATA;
1360  goto fail;
1361  }
1362 
1363  bottom = height - 1 - bottom;
1364  right = width - 1 - right;
1365 
1366  if (!(left | right | top | bottom))
1367  return 0;
1368 
1369  if ((left + right) >= width ||
1370  (top + bottom) >= height) {
1371  err = AVERROR_INVALIDDATA;
1372  goto fail;
1373  }
1374 
1378  sizeof(uint32_t) * 4, 0);
1379  if (!sd)
1380  return AVERROR(ENOMEM);
1381 
1382  AV_WL32A(sd->data, top);
1383  AV_WL32A(sd->data + 4, bottom);
1384  AV_WL32A(sd->data + 8, left);
1385  AV_WL32A(sd->data + 12, right);
1386 
1387 fail:
1388  if (err < 0) {
1389  int explode = !!(c->fc->error_recognition & AV_EF_EXPLODE);
1390  av_log(c->fc, explode ? AV_LOG_ERROR : AV_LOG_WARNING, "Invalid clap box\n");
1391  if (!explode)
1392  err = 0;
1393  }
1394 
1395  return err;
1396 }
1397 
1398 /* This atom overrides any previously set aspect ratio */
1400 {
1401  const int num = avio_rb32(pb);
1402  const int den = avio_rb32(pb);
1403  AVStream *st;
1404  MOVStreamContext *sc;
1405 
1406  if (c->fc->nb_streams < 1)
1407  return 0;
1408  st = c->fc->streams[c->fc->nb_streams-1];
1409  sc = st->priv_data;
1410 
1411  av_log(c->fc, AV_LOG_TRACE, "pasp: hSpacing %d, vSpacing %d\n", num, den);
1412 
1413  if (den != 0) {
1414  sc->h_spacing = num;
1415  sc->v_spacing = den;
1416  }
1417  return 0;
1418 }
1419 
1420 /* this atom contains actual media data */
1422 {
1423  if (atom.size == 0) /* wrong one (MP4) */
1424  return 0;
1425  c->found_mdat=1;
1426  return 0; /* now go for moov */
1427 }
1428 
1429 #define DRM_BLOB_SIZE 56
1430 
1432 {
1433  uint8_t intermediate_key[20];
1434  uint8_t intermediate_iv[20];
1435  uint8_t input[64];
1436  uint8_t output[64];
1437  uint8_t file_checksum[20];
1438  uint8_t calculated_checksum[20];
1439  char checksum_string[2 * sizeof(file_checksum) + 1];
1440  struct AVSHA *sha;
1441  int i;
1442  int ret = 0;
1443  uint8_t *activation_bytes = c->activation_bytes;
1444  uint8_t *fixed_key = c->audible_fixed_key;
1445 
1446  c->aax_mode = 1;
1447 
1448  sha = av_sha_alloc();
1449  if (!sha)
1450  return AVERROR(ENOMEM);
1451  av_free(c->aes_decrypt);
1452  c->aes_decrypt = av_aes_alloc();
1453  if (!c->aes_decrypt) {
1454  ret = AVERROR(ENOMEM);
1455  goto fail;
1456  }
1457 
1458  /* drm blob processing */
1459  avio_read(pb, output, 8); // go to offset 8, absolute position 0x251
1461  avio_read(pb, output, 4); // go to offset 4, absolute position 0x28d
1462  ret = ffio_read_size(pb, file_checksum, 20);
1463  if (ret < 0)
1464  goto fail;
1465 
1466  // required by external tools
1467  ff_data_to_hex(checksum_string, file_checksum, sizeof(file_checksum), 1);
1468  av_log(c->fc, AV_LOG_INFO, "[aax] file checksum == %s\n", checksum_string);
1469 
1470  /* verify activation data */
1471  if (!activation_bytes) {
1472  av_log(c->fc, AV_LOG_WARNING, "[aax] activation_bytes option is missing!\n");
1473  ret = 0; /* allow ffprobe to continue working on .aax files */
1474  goto fail;
1475  }
1476  if (c->activation_bytes_size != 4) {
1477  av_log(c->fc, AV_LOG_FATAL, "[aax] activation_bytes value needs to be 4 bytes!\n");
1478  ret = AVERROR(EINVAL);
1479  goto fail;
1480  }
1481 
1482  /* verify fixed key */
1483  if (c->audible_fixed_key_size != 16) {
1484  av_log(c->fc, AV_LOG_FATAL, "[aax] audible_fixed_key value needs to be 16 bytes!\n");
1485  ret = AVERROR(EINVAL);
1486  goto fail;
1487  }
1488 
1489  /* AAX (and AAX+) key derivation */
1490  av_sha_init(sha, 160);
1491  av_sha_update(sha, fixed_key, 16);
1492  av_sha_update(sha, activation_bytes, 4);
1493  av_sha_final(sha, intermediate_key);
1494  av_sha_init(sha, 160);
1495  av_sha_update(sha, fixed_key, 16);
1496  av_sha_update(sha, intermediate_key, 20);
1497  av_sha_update(sha, activation_bytes, 4);
1498  av_sha_final(sha, intermediate_iv);
1499  av_sha_init(sha, 160);
1500  av_sha_update(sha, intermediate_key, 16);
1501  av_sha_update(sha, intermediate_iv, 16);
1502  av_sha_final(sha, calculated_checksum);
1503  if (memcmp(calculated_checksum, file_checksum, 20)) { // critical error
1504  av_log(c->fc, AV_LOG_ERROR, "[aax] mismatch in checksums!\n");
1506  goto fail;
1507  }
1508  av_aes_init(c->aes_decrypt, intermediate_key, 128, 1);
1509  av_aes_crypt(c->aes_decrypt, output, input, DRM_BLOB_SIZE >> 4, intermediate_iv, 1);
1510  for (i = 0; i < 4; i++) {
1511  // file data (in output) is stored in big-endian mode
1512  if (activation_bytes[i] != output[3 - i]) { // critical error
1513  av_log(c->fc, AV_LOG_ERROR, "[aax] error in drm blob decryption!\n");
1515  goto fail;
1516  }
1517  }
1518  memcpy(c->file_key, output + 8, 16);
1519  memcpy(input, output + 26, 16);
1520  av_sha_init(sha, 160);
1521  av_sha_update(sha, input, 16);
1522  av_sha_update(sha, c->file_key, 16);
1523  av_sha_update(sha, fixed_key, 16);
1524  av_sha_final(sha, c->file_iv);
1525 
1526 fail:
1527  av_free(sha);
1528 
1529  return ret;
1530 }
1531 
1533 {
1534  if (c->audible_key_size != 16) {
1535  av_log(c->fc, AV_LOG_FATAL, "[aaxc] audible_key value needs to be 16 bytes!\n");
1536  return AVERROR(EINVAL);
1537  }
1538 
1539  if (c->audible_iv_size != 16) {
1540  av_log(c->fc, AV_LOG_FATAL, "[aaxc] audible_iv value needs to be 16 bytes!\n");
1541  return AVERROR(EINVAL);
1542  }
1543 
1544  c->aes_decrypt = av_aes_alloc();
1545  if (!c->aes_decrypt) {
1546  return AVERROR(ENOMEM);
1547  }
1548 
1549  memcpy(c->file_key, c->audible_key, 16);
1550  memcpy(c->file_iv, c->audible_iv, 16);
1551  c->aax_mode = 1;
1552 
1553  return 0;
1554 }
1555 
1556 // Audible AAX (and AAX+) bytestream decryption
1557 static int aax_filter(uint8_t *input, int size, MOVContext *c)
1558 {
1559  int blocks = 0;
1560  unsigned char iv[16];
1561 
1562  memcpy(iv, c->file_iv, 16); // iv is overwritten
1563  blocks = size >> 4; // trailing bytes are not encrypted!
1564  av_aes_init(c->aes_decrypt, c->file_key, 128, 1);
1565  av_aes_crypt(c->aes_decrypt, input, input, blocks, iv, 1);
1566 
1567  return 0;
1568 }
1569 
1570 /* read major brand, minor version and compatible brands and store them as metadata */
1572 {
1573  uint32_t minor_ver;
1574  int comp_brand_size;
1575  char* comp_brands_str;
1576  uint8_t type[5] = {0};
1577  int ret = ffio_read_size(pb, type, 4);
1578  if (ret < 0)
1579  return ret;
1580  if (c->fc->nb_streams) {
1581  if (c->fc->strict_std_compliance >= FF_COMPLIANCE_STRICT)
1582  return AVERROR_INVALIDDATA;
1583  av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate FTYP\n");
1584  return 0;
1585  }
1586 
1587  if (strcmp(type, "qt "))
1588  c->isom = 1;
1589  av_log(c->fc, AV_LOG_DEBUG, "ISO: File Type Major Brand: %.4s\n",(char *)&type);
1590  av_dict_set(&c->fc->metadata, "major_brand", type, 0);
1591  minor_ver = avio_rb32(pb); /* minor version */
1592  av_dict_set_int(&c->fc->metadata, "minor_version", minor_ver, 0);
1593 
1594  comp_brand_size = atom.size - 8;
1595  if (comp_brand_size < 0 || comp_brand_size == INT_MAX)
1596  return AVERROR_INVALIDDATA;
1597  comp_brands_str = av_malloc(comp_brand_size + 1); /* Add null terminator */
1598  if (!comp_brands_str)
1599  return AVERROR(ENOMEM);
1600 
1601  ret = ffio_read_size(pb, comp_brands_str, comp_brand_size);
1602  if (ret < 0) {
1603  av_freep(&comp_brands_str);
1604  return ret;
1605  }
1606  comp_brands_str[comp_brand_size] = 0;
1607  av_dict_set(&c->fc->metadata, "compatible_brands",
1608  comp_brands_str, AV_DICT_DONT_STRDUP_VAL);
1609 
1610  // Logic for handling Audible's .aaxc files
1611  if (!strcmp(type, "aaxc")) {
1612  mov_aaxc_crypto(c);
1613  }
1614 
1615  return 0;
1616 }
1617 
1618 /* this atom should contain all header atoms */
1620 {
1621  int ret;
1622 
1623  if (c->found_moov) {
1624  av_log(c->fc, AV_LOG_WARNING, "Found duplicated MOOV Atom. Skipped it\n");
1625  avio_skip(pb, atom.size);
1626  return 0;
1627  }
1628 
1629  if ((ret = mov_read_default(c, pb, atom)) < 0)
1630  return ret;
1631  /* we parsed the 'moov' atom, we can terminate the parsing as soon as we find the 'mdat' */
1632  /* so we don't parse the whole file if over a network */
1633  c->found_moov=1;
1634  return 0; /* now go for mdat */
1635 }
1636 
1638  MOVFragmentIndex *frag_index,
1639  int index,
1640  int id)
1641 {
1642  int i;
1643  MOVFragmentIndexItem * item;
1644 
1645  if (index < 0 || index >= frag_index->nb_items)
1646  return NULL;
1647  item = &frag_index->item[index];
1648  for (i = 0; i < item->nb_stream_info; i++)
1649  if (item->stream_info[i].id == id)
1650  return &item->stream_info[i];
1651 
1652  // This shouldn't happen
1653  return NULL;
1654 }
1655 
1656 static void set_frag_stream(MOVFragmentIndex *frag_index, int id)
1657 {
1658  int i;
1659  MOVFragmentIndexItem * item;
1660 
1661  if (frag_index->current < 0 ||
1662  frag_index->current >= frag_index->nb_items)
1663  return;
1664 
1665  item = &frag_index->item[frag_index->current];
1666  for (i = 0; i < item->nb_stream_info; i++)
1667  if (item->stream_info[i].id == id) {
1668  item->current = i;
1669  return;
1670  }
1671 
1672  // id not found. This shouldn't happen.
1673  item->current = -1;
1674 }
1675 
1677  MOVFragmentIndex *frag_index)
1678 {
1679  MOVFragmentIndexItem *item;
1680  if (frag_index->current < 0 ||
1681  frag_index->current >= frag_index->nb_items)
1682  return NULL;
1683 
1684  item = &frag_index->item[frag_index->current];
1685  if (item->current >= 0 && item->current < item->nb_stream_info)
1686  return &item->stream_info[item->current];
1687 
1688  // This shouldn't happen
1689  return NULL;
1690 }
1691 
1693 {
1694  int a, b, m;
1695  int64_t moof_offset;
1696 
1697  // Optimize for appending new entries
1698  if (!frag_index->nb_items ||
1699  frag_index->item[frag_index->nb_items - 1].moof_offset < offset)
1700  return frag_index->nb_items;
1701 
1702  a = -1;
1703  b = frag_index->nb_items;
1704 
1705  while (b - a > 1) {
1706  m = (a + b) >> 1;
1707  moof_offset = frag_index->item[m].moof_offset;
1708  if (moof_offset >= offset)
1709  b = m;
1710  if (moof_offset <= offset)
1711  a = m;
1712  }
1713  return b;
1714 }
1715 
1717 {
1718  av_assert0(frag_stream_info);
1719  if (frag_stream_info->sidx_pts != AV_NOPTS_VALUE)
1720  return frag_stream_info->sidx_pts;
1721  if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE)
1722  return frag_stream_info->first_tfra_pts;
1723  return frag_stream_info->tfdt_dts;
1724 }
1725 
1727  MOVFragmentIndex *frag_index, int index)
1728 {
1729  MOVFragmentStreamInfo * frag_stream_info;
1730  MOVStreamContext *sc = dst_st->priv_data;
1731  int64_t timestamp;
1732  int i, j;
1733 
1734  // If the stream is referenced by any sidx, limit the search
1735  // to fragments that referenced this stream in the sidx
1736  if (sc->has_sidx) {
1737  frag_stream_info = get_frag_stream_info(frag_index, index, sc->id);
1738  if (!frag_stream_info)
1739  return AV_NOPTS_VALUE;
1740  if (frag_stream_info->sidx_pts != AV_NOPTS_VALUE)
1741  return frag_stream_info->sidx_pts;
1742  if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE)
1743  return frag_stream_info->first_tfra_pts;
1744  return frag_stream_info->sidx_pts;
1745  }
1746 
1747  for (i = 0; i < frag_index->item[index].nb_stream_info; i++) {
1748  if (dst_st->id != frag_index->item[index].stream_info[i].id)
1749  continue;
1750  AVStream *frag_stream = NULL;
1751  frag_stream_info = &frag_index->item[index].stream_info[i];
1752  for (j = 0; j < s->nb_streams; j++) {
1753  MOVStreamContext *sc2 = s->streams[j]->priv_data;
1754  if (sc2->id == frag_stream_info->id)
1755  frag_stream = s->streams[j];
1756  }
1757  if (!frag_stream) {
1758  av_log(s, AV_LOG_WARNING, "No stream matching sidx ID found.\n");
1759  continue;
1760  }
1761  timestamp = get_stream_info_time(frag_stream_info);
1762  if (timestamp != AV_NOPTS_VALUE)
1763  return av_rescale_q(timestamp, frag_stream->time_base, dst_st->time_base);
1764  }
1765  return AV_NOPTS_VALUE;
1766 }
1767 
1769  AVStream *st, int64_t timestamp)
1770 {
1771  int a, b, m, m0;
1772  int64_t frag_time;
1773 
1774  a = -1;
1775  b = frag_index->nb_items;
1776 
1777  while (b - a > 1) {
1778  m0 = m = (a + b) >> 1;
1779 
1780  while (m < b &&
1781  (frag_time = get_frag_time(s, st, frag_index, m)) == AV_NOPTS_VALUE)
1782  m++;
1783 
1784  if (m < b && frag_time <= timestamp)
1785  a = m;
1786  else
1787  b = m0;
1788  }
1789 
1790  return a;
1791 }
1792 
1794 {
1795  int index, i;
1796  MOVFragmentIndexItem * item;
1797  MOVFragmentStreamInfo * frag_stream_info;
1798 
1799  // If moof_offset already exists in frag_index, return index to it
1800  index = search_frag_moof_offset(&c->frag_index, offset);
1801  if (index < c->frag_index.nb_items &&
1802  c->frag_index.item[index].moof_offset == offset)
1803  return index;
1804 
1805  // offset is not yet in frag index.
1806  // Insert new item at index (sorted by moof offset)
1807  item = av_fast_realloc(c->frag_index.item,
1808  &c->frag_index.allocated_size,
1809  (c->frag_index.nb_items + 1) *
1810  sizeof(*c->frag_index.item));
1811  if (!item)
1812  return -1;
1813  c->frag_index.item = item;
1814 
1815  frag_stream_info = av_realloc_array(NULL, c->fc->nb_streams,
1816  sizeof(*item->stream_info));
1817  if (!frag_stream_info)
1818  return -1;
1819 
1820  for (i = 0; i < c->fc->nb_streams; i++) {
1821  // Avoid building frag index if streams lack track id.
1822  MOVStreamContext *sc = c->fc->streams[i]->priv_data;
1823  if (sc->id < 0) {
1824  av_free(frag_stream_info);
1825  return AVERROR_INVALIDDATA;
1826  }
1827 
1828  frag_stream_info[i].id = sc->id;
1829  frag_stream_info[i].sidx_pts = AV_NOPTS_VALUE;
1830  frag_stream_info[i].tfdt_dts = AV_NOPTS_VALUE;
1831  frag_stream_info[i].next_trun_dts = AV_NOPTS_VALUE;
1832  frag_stream_info[i].first_tfra_pts = AV_NOPTS_VALUE;
1833  frag_stream_info[i].index_base = -1;
1834  frag_stream_info[i].index_entry = -1;
1835  frag_stream_info[i].encryption_index = NULL;
1836  frag_stream_info[i].stsd_id = -1;
1837  }
1838 
1839  if (index < c->frag_index.nb_items)
1840  memmove(c->frag_index.item + index + 1, c->frag_index.item + index,
1841  (c->frag_index.nb_items - index) * sizeof(*c->frag_index.item));
1842 
1843  item = &c->frag_index.item[index];
1844  item->headers_read = 0;
1845  item->current = 0;
1846  item->nb_stream_info = c->fc->nb_streams;
1847  item->moof_offset = offset;
1848  item->stream_info = frag_stream_info;
1849  c->frag_index.nb_items++;
1850 
1851  return index;
1852 }
1853 
1854 static void fix_frag_index_entries(MOVFragmentIndex *frag_index, int index,
1855  int id, int entries)
1856 {
1857  int i;
1858  MOVFragmentStreamInfo * frag_stream_info;
1859 
1860  if (index < 0)
1861  return;
1862  for (i = index; i < frag_index->nb_items; i++) {
1863  frag_stream_info = get_frag_stream_info(frag_index, i, id);
1864  if (frag_stream_info && frag_stream_info->index_entry >= 0)
1865  frag_stream_info->index_entry += entries;
1866  }
1867 }
1868 
1870 {
1871  // Set by mov_read_tfhd(). mov_read_trun() will reject files missing tfhd.
1872  c->fragment.found_tfhd = 0;
1873 
1874  if (!c->has_looked_for_mfra && c->use_mfra_for > 0) {
1875  c->has_looked_for_mfra = 1;
1876  if (pb->seekable & AVIO_SEEKABLE_NORMAL) {
1877  int ret;
1878  av_log(c->fc, AV_LOG_VERBOSE, "stream has moof boxes, will look "
1879  "for a mfra\n");
1880  if ((ret = mov_read_mfra(c, pb)) < 0) {
1881  av_log(c->fc, AV_LOG_VERBOSE, "found a moof box but failed to "
1882  "read the mfra (may be a live ismv)\n");
1883  }
1884  } else {
1885  av_log(c->fc, AV_LOG_VERBOSE, "found a moof box but stream is not "
1886  "seekable, can not look for mfra\n");
1887  }
1888  }
1889  c->fragment.moof_offset = c->fragment.implicit_offset = avio_tell(pb) - 8;
1890  av_log(c->fc, AV_LOG_TRACE, "moof offset %"PRIx64"\n", c->fragment.moof_offset);
1891  c->frag_index.current = update_frag_index(c, c->fragment.moof_offset);
1892  return mov_read_default(c, pb, atom);
1893 }
1894 
1896 {
1897  int64_t time;
1898  if (version == 1) {
1899  time = avio_rb64(pb);
1900  avio_rb64(pb);
1901  if (time < 0) {
1902  av_log(c->fc, AV_LOG_DEBUG, "creation_time is negative\n");
1903  return;
1904  }
1905  } else {
1906  time = avio_rb32(pb);
1907  avio_rb32(pb); /* modification time */
1908  if (time > 0 && time < 2082844800) {
1909  av_log(c->fc, AV_LOG_WARNING, "Detected creation time before 1970, parsing as unix timestamp.\n");
1910  time += 2082844800;
1911  }
1912  }
1913  if (time) {
1914  time -= 2082844800; /* seconds between 1904-01-01 and Epoch */
1915 
1916  if ((int64_t)(time * 1000000ULL) / 1000000 != time) {
1917  av_log(c->fc, AV_LOG_DEBUG, "creation_time is not representable\n");
1918  return;
1919  }
1920 
1921  ff_dict_set_timestamp(metadata, "creation_time", time * 1000000);
1922  }
1923 }
1924 
1926 {
1927  AVStream *st;
1928  MOVStreamContext *sc;
1929  int version;
1930  char language[4] = {0};
1931  unsigned lang;
1932 
1933  if (c->fc->nb_streams < 1)
1934  return 0;
1935  st = c->fc->streams[c->fc->nb_streams-1];
1936  sc = st->priv_data;
1937 
1938  if (sc->time_scale) {
1939  av_log(c->fc, AV_LOG_ERROR, "Multiple mdhd?\n");
1940  return AVERROR_INVALIDDATA;
1941  }
1942 
1943  version = avio_r8(pb);
1944  if (version > 1) {
1945  avpriv_request_sample(c->fc, "Version %d", version);
1946  return AVERROR_PATCHWELCOME;
1947  }
1948  avio_rb24(pb); /* flags */
1950 
1951  sc->time_scale = avio_rb32(pb);
1952  if (sc->time_scale <= 0) {
1953  av_log(c->fc, AV_LOG_ERROR, "Invalid mdhd time scale %d, defaulting to 1\n", sc->time_scale);
1954  sc->time_scale = 1;
1955  }
1956  st->duration = (version == 1) ? avio_rb64(pb) : avio_rb32(pb); /* duration */
1957 
1958  if ((version == 1 && st->duration == UINT64_MAX) ||
1959  (version != 1 && st->duration == UINT32_MAX)) {
1960  st->duration = 0;
1961  }
1962 
1963  lang = avio_rb16(pb); /* language */
1964  if (ff_mov_lang_to_iso639(lang, language))
1965  av_dict_set(&st->metadata, "language", language, 0);
1966  avio_rb16(pb); /* quality */
1967 
1968  return 0;
1969 }
1970 
1972 {
1973  int i;
1974  int version = avio_r8(pb); /* version */
1975  avio_rb24(pb); /* flags */
1976 
1977  mov_metadata_creation_time(c, pb, &c->fc->metadata, version);
1978  c->time_scale = avio_rb32(pb); /* time scale */
1979  if (c->time_scale <= 0) {
1980  av_log(c->fc, AV_LOG_ERROR, "Invalid mvhd time scale %d, defaulting to 1\n", c->time_scale);
1981  c->time_scale = 1;
1982  }
1983  av_log(c->fc, AV_LOG_TRACE, "time scale = %i\n", c->time_scale);
1984 
1985  c->duration = (version == 1) ? avio_rb64(pb) : avio_rb32(pb); /* duration */
1986  avio_rb32(pb); /* preferred scale */
1987 
1988  avio_rb16(pb); /* preferred volume */
1989 
1990  avio_skip(pb, 10); /* reserved */
1991 
1992  /* movie display matrix, store it in main context and use it later on */
1993  for (i = 0; i < 3; i++) {
1994  c->movie_display_matrix[i][0] = avio_rb32(pb); // 16.16 fixed point
1995  c->movie_display_matrix[i][1] = avio_rb32(pb); // 16.16 fixed point
1996  c->movie_display_matrix[i][2] = avio_rb32(pb); // 2.30 fixed point
1997  }
1998 
1999  avio_rb32(pb); /* preview time */
2000  avio_rb32(pb); /* preview duration */
2001  avio_rb32(pb); /* poster time */
2002  avio_rb32(pb); /* selection time */
2003  avio_rb32(pb); /* selection duration */
2004  avio_rb32(pb); /* current time */
2005  avio_rb32(pb); /* next track ID */
2006 
2007  return 0;
2008 }
2009 
2011 {
2012  AVStream *st;
2013 
2014  if (fc->nb_streams < 1)
2015  return;
2016  st = fc->streams[fc->nb_streams-1];
2017 
2018  switch (st->codecpar->codec_id) {
2019  case AV_CODEC_ID_PCM_S16BE:
2021  break;
2022  case AV_CODEC_ID_PCM_S24BE:
2024  break;
2025  case AV_CODEC_ID_PCM_S32BE:
2027  break;
2028  case AV_CODEC_ID_PCM_F32BE:
2030  break;
2031  case AV_CODEC_ID_PCM_F64BE:
2033  break;
2034  default:
2035  break;
2036  }
2037 }
2038 
2040 {
2041  int little_endian = avio_rb16(pb) & 0xFF;
2042  av_log(c->fc, AV_LOG_TRACE, "enda %d\n", little_endian);
2043  if (little_endian == 1)
2045  return 0;
2046 }
2047 
2049 {
2050  int format_flags;
2051  int version, flags;
2052  int pcm_sample_size;
2053  AVFormatContext *fc = c->fc;
2054  AVStream *st;
2055  MOVStreamContext *sc;
2056 
2057  if (atom.size < 6) {
2058  av_log(c->fc, AV_LOG_ERROR, "Empty pcmC box\n");
2059  return AVERROR_INVALIDDATA;
2060  }
2061 
2062  version = avio_r8(pb);
2063  flags = avio_rb24(pb);
2064 
2065  if (version != 0 || flags != 0) {
2066  av_log(c->fc, AV_LOG_ERROR,
2067  "Unsupported 'pcmC' box with version %d, flags: %x",
2068  version, flags);
2069  return AVERROR_INVALIDDATA;
2070  }
2071 
2072  format_flags = avio_r8(pb);
2073  pcm_sample_size = avio_r8(pb);
2074 
2075  if (fc->nb_streams < 1)
2076  return AVERROR_INVALIDDATA;
2077 
2078  st = fc->streams[fc->nb_streams - 1];
2079  sc = st->priv_data;
2080 
2081  if (sc->format == MOV_MP4_FPCM_TAG) {
2082  switch (pcm_sample_size) {
2083  case 32:
2085  break;
2086  case 64:
2088  break;
2089  default:
2090  av_log(fc, AV_LOG_ERROR, "invalid pcm_sample_size %d for %s\n",
2091  pcm_sample_size,
2092  av_fourcc2str(sc->format));
2093  return AVERROR_INVALIDDATA;
2094  }
2095  } else if (sc->format == MOV_MP4_IPCM_TAG) {
2096  switch (pcm_sample_size) {
2097  case 16:
2099  break;
2100  case 24:
2102  break;
2103  case 32:
2105  break;
2106  default:
2107  av_log(fc, AV_LOG_ERROR, "invalid pcm_sample_size %d for %s\n",
2108  pcm_sample_size,
2109  av_fourcc2str(sc->format));
2110  return AVERROR_INVALIDDATA;
2111  }
2112  } else {
2113  av_log(fc, AV_LOG_ERROR, "'pcmC' with invalid sample entry '%s'\n",
2114  av_fourcc2str(sc->format));
2115  return AVERROR_INVALIDDATA;
2116  }
2117 
2118  if (format_flags & 1) // indicates little-endian format. If not present, big-endian format is used
2121 
2122  return 0;
2123 }
2124 
2126 {
2127  AVStream *st;
2128  HEIFItem *item = NULL;
2129  char color_parameter_type[5] = { 0 };
2130  uint16_t color_primaries, color_trc, color_matrix;
2131  int ret;
2132 
2133  st = get_curr_st(c);
2134  if (!st) {
2135  item = get_heif_item(c, c->cur_item_id);
2136  if (!item)
2137  return 0;
2138  }
2139 
2140  ret = ffio_read_size(pb, color_parameter_type, 4);
2141  if (ret < 0)
2142  return ret;
2143  if (strncmp(color_parameter_type, "nclx", 4) &&
2144  strncmp(color_parameter_type, "nclc", 4) &&
2145  strncmp(color_parameter_type, "prof", 4)) {
2146  av_log(c->fc, AV_LOG_WARNING, "unsupported color_parameter_type %s\n",
2147  color_parameter_type);
2148  return 0;
2149  }
2150 
2151  if (!strncmp(color_parameter_type, "prof", 4)) {
2152  AVPacketSideData *sd;
2153  uint8_t *icc_profile;
2154  if (st) {
2158  atom.size - 4, 0);
2159  if (!sd)
2160  return AVERROR(ENOMEM);
2161  icc_profile = sd->data;
2162  } else {
2163  if (c->heif_icc_profile_items >= c->fc->max_streams) {
2164  av_log(c->fc, AV_LOG_WARNING,
2165  "HEIF ICC profile copies exceed cap %d; ignoring further items\n",
2166  c->fc->max_streams);
2167  return 0;
2168  }
2169  av_freep(&item->icc_profile);
2170  icc_profile = item->icc_profile = av_malloc(atom.size - 4);
2171  if (!icc_profile) {
2172  item->icc_profile_size = 0;
2173  return AVERROR(ENOMEM);
2174  }
2175  item->icc_profile_size = atom.size - 4;
2176  c->heif_icc_profile_items++;
2177  }
2178  ret = ffio_read_size(pb, icc_profile, atom.size - 4);
2179  if (ret < 0)
2180  return ret;
2181  } else if (st) {
2182  color_primaries = avio_rb16(pb);
2183  color_trc = avio_rb16(pb);
2184  color_matrix = avio_rb16(pb);
2185 
2186  av_log(c->fc, AV_LOG_TRACE,
2187  "%s: pri %d trc %d matrix %d",
2188  color_parameter_type, color_primaries, color_trc, color_matrix);
2189 
2190  if (!strncmp(color_parameter_type, "nclx", 4)) {
2191  uint8_t color_range = avio_r8(pb) >> 7;
2192  av_log(c->fc, AV_LOG_TRACE, " full %"PRIu8"", color_range);
2193  if (color_range)
2195  else
2197  }
2198 
2201  if (!av_color_transfer_name(color_trc))
2202  color_trc = AVCOL_TRC_UNSPECIFIED;
2203  if (!av_color_space_name(color_matrix))
2204  color_matrix = AVCOL_SPC_UNSPECIFIED;
2205 
2207  st->codecpar->color_trc = color_trc;
2208  st->codecpar->color_space = color_matrix;
2209  av_log(c->fc, AV_LOG_TRACE, "\n");
2210  }
2211  return 0;
2212 }
2213 
2215 {
2216  AVStream *st;
2217  unsigned mov_field_order;
2218  enum AVFieldOrder decoded_field_order = AV_FIELD_UNKNOWN;
2219 
2220  if (c->fc->nb_streams < 1) // will happen with jp2 files
2221  return 0;
2222  st = c->fc->streams[c->fc->nb_streams-1];
2223  if (atom.size < 2)
2224  return AVERROR_INVALIDDATA;
2225  mov_field_order = avio_rb16(pb);
2226  if ((mov_field_order & 0xFF00) == 0x0100)
2227  decoded_field_order = AV_FIELD_PROGRESSIVE;
2228  else if ((mov_field_order & 0xFF00) == 0x0200) {
2229  switch (mov_field_order & 0xFF) {
2230  case 0x01: decoded_field_order = AV_FIELD_TT;
2231  break;
2232  case 0x06: decoded_field_order = AV_FIELD_BB;
2233  break;
2234  case 0x09: decoded_field_order = AV_FIELD_TB;
2235  break;
2236  case 0x0E: decoded_field_order = AV_FIELD_BT;
2237  break;
2238  }
2239  }
2240  if (decoded_field_order == AV_FIELD_UNKNOWN && mov_field_order) {
2241  av_log(c->fc, AV_LOG_ERROR, "Unknown MOV field order 0x%04x\n", mov_field_order);
2242  }
2243  st->codecpar->field_order = decoded_field_order;
2244 
2245  return 0;
2246 }
2247 
2249 {
2250  int err = 0;
2251  uint64_t size = (uint64_t)par->extradata_size + atom.size + 8 + AV_INPUT_BUFFER_PADDING_SIZE;
2252  if (size > INT_MAX || (uint64_t)atom.size > INT_MAX)
2253  return AVERROR_INVALIDDATA;
2254  if ((err = av_reallocp(&par->extradata, size)) < 0) {
2255  par->extradata_size = 0;
2256  return err;
2257  }
2259  return 0;
2260 }
2261 
2262 /* Read a whole atom into the extradata return the size of the atom read, possibly truncated if != atom.size */
2264  AVCodecParameters *par, uint8_t *buf)
2265 {
2266  int64_t result = atom.size;
2267  int err;
2268 
2269  AV_WB32(buf , atom.size + 8);
2270  AV_WL32(buf + 4, atom.type);
2271  err = ffio_read_size(pb, buf + 8, atom.size);
2272  if (err < 0) {
2273  par->extradata_size -= atom.size;
2274  return err;
2275  } else if (err < atom.size) {
2276  av_log(c->fc, AV_LOG_WARNING, "truncated extradata\n");
2277  par->extradata_size -= atom.size - err;
2278  result = err;
2279  }
2280  memset(buf + 8 + err, 0, AV_INPUT_BUFFER_PADDING_SIZE);
2281  return result;
2282 }
2283 
2284 /* FIXME modify QDM2/SVQ3/H.264 decoders to take full atom as extradata */
2286  enum AVCodecID codec_id)
2287 {
2288  AVStream *st;
2289  uint64_t original_size;
2290  int err;
2291 
2292  if (c->fc->nb_streams < 1) // will happen with jp2 files
2293  return 0;
2294  st = c->fc->streams[c->fc->nb_streams-1];
2295 
2296  if (st->codecpar->codec_id != codec_id)
2297  return 0; /* unexpected codec_id - don't mess with extradata */
2298 
2299  original_size = st->codecpar->extradata_size;
2300  err = mov_realloc_extradata(st->codecpar, atom);
2301  if (err)
2302  return err;
2303 
2304  err = mov_read_atom_into_extradata(c, pb, atom, st->codecpar, st->codecpar->extradata + original_size);
2305  if (err < 0)
2306  return err;
2307  return 0; // Note: this is the original behavior to ignore truncation.
2308 }
2309 
2310 /* wrapper functions for reading ALAC/AVS/MJPEG/MJPEG2000 extradata atoms only for those codecs */
2312 {
2313  return mov_read_extradata(c, pb, atom, AV_CODEC_ID_ALAC);
2314 }
2315 
2317 {
2318  return mov_read_extradata(c, pb, atom, AV_CODEC_ID_CAVS);
2319 }
2320 
2322 {
2323  return mov_read_extradata(c, pb, atom, AV_CODEC_ID_JPEG2000);
2324 }
2325 
2327 {
2328  return mov_read_extradata(c, pb, atom, AV_CODEC_ID_R10K);
2329 }
2330 
2332 {
2333  int ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_AVUI);
2334  if (!ret)
2335  ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_DNXHD);
2336  return ret;
2337 }
2338 
2340 {
2341  int ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_TARGA_Y216);
2342 
2343  if (!ret && c->fc->nb_streams >= 1) {
2344  AVCodecParameters *par = c->fc->streams[c->fc->nb_streams-1]->codecpar;
2345  if (par->extradata_size >= 40) {
2346  par->height = AV_RB16(&par->extradata[36]);
2347  par->width = AV_RB16(&par->extradata[38]);
2348  }
2349  }
2350  return ret;
2351 }
2352 
2354 {
2355  if (c->fc->nb_streams >= 1) {
2356  AVStream *const st = c->fc->streams[c->fc->nb_streams - 1];
2357  FFStream *const sti = ffstream(st);
2358  AVCodecParameters *par = st->codecpar;
2359 
2360  if (par->codec_tag == MKTAG('A', 'V', 'i', 'n') &&
2361  par->codec_id == AV_CODEC_ID_H264 &&
2362  atom.size > 11) {
2363  int cid;
2364  avio_skip(pb, 10);
2365  cid = avio_rb16(pb);
2366  /* For AVID AVCI50, force width of 1440 to be able to select the correct SPS and PPS */
2367  if (cid == 0xd4d || cid == 0xd4e)
2368  par->width = 1440;
2369  return 0;
2370  } else if ((par->codec_tag == MKTAG('A', 'V', 'd', '1') ||
2371  par->codec_tag == MKTAG('A', 'V', 'j', '2') ||
2372  par->codec_tag == MKTAG('A', 'V', 'd', 'n')) &&
2373  atom.size >= 24) {
2374  int num, den;
2375  avio_skip(pb, 12);
2376  num = avio_rb32(pb);
2377  den = avio_rb32(pb);
2378  if (num <= 0 || den <= 0)
2379  return 0;
2380  switch (avio_rb32(pb)) {
2381  case 2:
2382  if (den >= INT_MAX / 2)
2383  return 0;
2384  den *= 2;
2386  case 1:
2387  sti->display_aspect_ratio = (AVRational){ num, den };
2389  default:
2390  return 0;
2391  }
2392  }
2393  }
2394 
2395  return mov_read_avid(c, pb, atom);
2396 }
2397 
2399 {
2400  int ret = 0;
2401  int length = 0;
2402  uint64_t original_size;
2403  if (c->fc->nb_streams >= 1) {
2404  AVCodecParameters *par = c->fc->streams[c->fc->nb_streams-1]->codecpar;
2405  if (par->codec_id == AV_CODEC_ID_H264)
2406  return 0;
2407  if (atom.size == 16) {
2408  original_size = par->extradata_size;
2409  ret = mov_realloc_extradata(par, atom);
2410  if (!ret) {
2411  length = mov_read_atom_into_extradata(c, pb, atom, par, par->extradata + original_size);
2412  if (length == atom.size) {
2413  const uint8_t range_value = par->extradata[original_size + 19];
2414  switch (range_value) {
2415  case 1:
2417  break;
2418  case 2:
2420  break;
2421  default:
2422  av_log(c->fc, AV_LOG_WARNING, "ignored unknown aclr value (%d)\n", range_value);
2423  break;
2424  }
2425  ff_dlog(c->fc, "color_range: %d\n", par->color_range);
2426  } else {
2427  /* For some reason the whole atom was not added to the extradata */
2428  av_log(c->fc, AV_LOG_ERROR, "aclr not decoded - incomplete atom\n");
2429  }
2430  } else {
2431  av_log(c->fc, AV_LOG_ERROR, "aclr not decoded - unable to add atom to extradata\n");
2432  }
2433  } else {
2434  av_log(c->fc, AV_LOG_WARNING, "aclr not decoded - unexpected size %"PRId64"\n", atom.size);
2435  }
2436  }
2437 
2438  return ret;
2439 }
2440 
2442 {
2443  return mov_read_extradata(c, pb, atom, AV_CODEC_ID_SVQ3);
2444 }
2445 
2447 {
2448  AVStream *st;
2449  int ret;
2450 
2451  if (c->fc->nb_streams < 1)
2452  return 0;
2453  st = c->fc->streams[c->fc->nb_streams-1];
2454 
2455  if ((uint64_t)atom.size > (1<<30))
2456  return AVERROR_INVALIDDATA;
2457 
2458  if (st->codecpar->codec_id == AV_CODEC_ID_QDM2 ||
2461  // pass all frma atom to codec, needed at least for QDMC and QDM2
2462  ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size);
2463  if (ret < 0)
2464  return ret;
2465  } else if (atom.size > 8) { /* to read frma, esds atoms */
2466  if (st->codecpar->codec_id == AV_CODEC_ID_ALAC && atom.size >= 24) {
2467  uint64_t buffer;
2468  ret = ffio_ensure_seekback(pb, 8);
2469  if (ret < 0)
2470  return ret;
2471  buffer = avio_rb64(pb);
2472  atom.size -= 8;
2473  if ( (buffer & 0xFFFFFFFF) == MKBETAG('f','r','m','a')
2474  && buffer >> 32 <= atom.size
2475  && buffer >> 32 >= 8) {
2476  avio_skip(pb, -8);
2477  atom.size += 8;
2478  } else if (!st->codecpar->extradata_size) {
2479 #define ALAC_EXTRADATA_SIZE 36
2481  if (!st->codecpar->extradata)
2482  return AVERROR(ENOMEM);
2485  AV_WB32(st->codecpar->extradata + 4, MKTAG('a','l','a','c'));
2486  AV_WB64(st->codecpar->extradata + 12, buffer);
2487  avio_read(pb, st->codecpar->extradata + 20, 16);
2488  avio_skip(pb, atom.size - 24);
2489  return 0;
2490  }
2491  }
2492  if ((ret = mov_read_default(c, pb, atom)) < 0)
2493  return ret;
2494  } else
2495  avio_skip(pb, atom.size);
2496  return 0;
2497 }
2498 
2499 /**
2500  * This function reads atom content and puts data in extradata without tag
2501  * nor size unlike mov_read_extradata.
2502  */
2504 {
2505  AVStream *st;
2506  int ret;
2507 
2508  st = get_curr_st(c);
2509  if (!st)
2510  return 0;
2511 
2512  if ((uint64_t)atom.size > (1<<30))
2513  return AVERROR_INVALIDDATA;
2514 
2515  if (atom.type == MKTAG('v','v','c','C')) {
2516  avio_skip(pb, 4);
2517  atom.size -= 4;
2518  }
2519 
2520  if (atom.size >= 10) {
2521  // Broken files created by legacy versions of libavformat will
2522  // wrap a whole fiel atom inside of a glbl atom.
2523  unsigned size = avio_rb32(pb);
2524  unsigned type = avio_rl32(pb);
2525  if (avio_feof(pb))
2526  return AVERROR_INVALIDDATA;
2527  avio_seek(pb, -8, SEEK_CUR);
2528  if (type == MKTAG('f','i','e','l') && size == atom.size)
2529  return mov_read_default(c, pb, atom);
2530  }
2531  if (st->codecpar->extradata_size > 1 && st->codecpar->extradata) {
2532  av_log(c->fc, AV_LOG_WARNING, "ignoring multiple glbl\n");
2533  return 0;
2534  }
2535  ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size);
2536  if (ret < 0)
2537  return ret;
2538  if (atom.type == MKTAG('h','v','c','C') && st->codecpar->codec_tag == MKTAG('d','v','h','1'))
2539  /* HEVC-based Dolby Vision derived from hvc1.
2540  Happens to match with an identifier
2541  previously utilized for DV. Thus, if we have
2542  the hvcC extradata box available as specified,
2543  set codec to HEVC */
2545 
2546  return 0;
2547 }
2548 
2550 {
2551  AVStream *st;
2552  uint8_t profile_level;
2553  int ret;
2554 
2555  if (c->fc->nb_streams < 1)
2556  return 0;
2557  st = c->fc->streams[c->fc->nb_streams-1];
2558 
2559  if (atom.size >= (1<<28) || atom.size < 7)
2560  return AVERROR_INVALIDDATA;
2561 
2562  profile_level = avio_r8(pb);
2563  if ((profile_level & 0xf0) != 0xc0)
2564  return 0;
2565 
2566  avio_seek(pb, 6, SEEK_CUR);
2567  ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size - 7);
2568  if (ret < 0)
2569  return ret;
2570 
2571  return 0;
2572 }
2573 
2574 static int mov_find_tref_id(const MovTref *tag, uint32_t id)
2575 {
2576  for (int i = 0; i < tag->nb_id; i++) {
2577  if (tag->id[i] == id)
2578  return 1;
2579  }
2580  return 0;
2581 }
2582 
2583 static int mov_add_tref_id(MovTref *tag, uint32_t id)
2584 {
2585  int ret = mov_find_tref_id(tag, id);
2586 
2587  if (!ret) {
2588  uint32_t *tmp = av_realloc_array(tag->id, tag->nb_id + 1, sizeof(*tag->id));
2589  if (!tmp)
2590  return AVERROR(ENOMEM);
2591  tag->id = tmp;
2592  tag->id[tag->nb_id++] = id;
2593  }
2594 
2595  return 0;
2596 }
2597 
2598 static MovTref *mov_find_tref_tag(const MOVStreamContext *sc, uint32_t name)
2599 {
2600  for (int i = 0; i < sc->nb_tref_tags; i++) {
2601  MovTref *entry = &sc->tref_tags[i];
2602 
2603  if (entry->name == name)
2604  return entry;
2605  }
2606  return NULL;
2607 }
2608 
2610 {
2612 
2613  if (!tag) {
2615  sizeof(*sc->tref_tags));
2616  if (!tmp)
2617  return NULL;
2618  sc->tref_tags = tmp;
2619  tag = &sc->tref_tags[sc->nb_tref_tags++];
2620  *tag = (MovTref){ .name = name };
2621  }
2622 
2623  return tag;
2624 }
2625 
2627 {
2628  AVStream* st;
2629  MOVStreamContext* sc;
2630 
2631  if (c->fc->nb_streams < 1)
2632  return 0;
2633 
2634  /* For SBAS this should be fine - though beware if someone implements a
2635  * tref atom processor that doesn't drop down to default then this may
2636  * be lost. */
2637  if (atom.size > 4) {
2638  av_log(c->fc, AV_LOG_ERROR, "Only a single tref of type sbas is supported\n");
2639  return AVERROR_PATCHWELCOME;
2640  }
2641  if (atom.size < 4)
2642  return AVERROR_INVALIDDATA;
2643 
2644  st = c->fc->streams[c->fc->nb_streams - 1];
2645  sc = st->priv_data;
2646 
2647  MovTref *tag = mov_add_tref_tag(sc, atom.type);
2648  if (!tag)
2649  return AVERROR(ENOMEM);
2650 
2651  int ret = mov_add_tref_id(tag, avio_rb32(pb));
2652  if (ret < 0)
2653  return ret;
2654 
2655  return 0;
2656 }
2657 
2659 {
2660  AVStream* st;
2661  MOVStreamContext* sc;
2662 
2663  if (c->fc->nb_streams < 1)
2664  return 0;
2665 
2666  if (atom.size > 4)
2667  av_log(c->fc, AV_LOG_WARNING, "More than one vdep reference is not supported.\n");
2668  if (atom.size < 4)
2669  return AVERROR_INVALIDDATA;
2670 
2671  st = c->fc->streams[c->fc->nb_streams - 1];
2672  sc = st->priv_data;
2673 
2674  MovTref *tag = mov_add_tref_tag(sc, atom.type);
2675  if (!tag)
2676  return AVERROR(ENOMEM);
2677 
2678  int ret = mov_add_tref_id(tag, avio_rb32(pb));
2679  if (ret < 0)
2680  return ret;
2681 
2682  return 0;
2683 }
2684 
2685 /**
2686  * An strf atom is a BITMAPINFOHEADER struct. This struct is 40 bytes itself,
2687  * but can have extradata appended at the end after the 40 bytes belonging
2688  * to the struct.
2689  */
2691 {
2692  AVStream *st;
2693  int ret;
2694 
2695  if (c->fc->nb_streams < 1)
2696  return 0;
2697  if (atom.size <= 40)
2698  return 0;
2699  st = c->fc->streams[c->fc->nb_streams-1];
2700 
2701  if ((uint64_t)atom.size > (1<<30))
2702  return AVERROR_INVALIDDATA;
2703 
2704  avio_skip(pb, 40);
2705  ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size - 40);
2706  if (ret < 0)
2707  return ret;
2708 
2709  return 0;
2710 }
2711 
2713 {
2714  AVStream *st;
2715  MOVStreamContext *sc;
2716  unsigned int i, entries;
2717 
2718  if (c->trak_index < 0) {
2719  av_log(c->fc, AV_LOG_WARNING, "STCO outside TRAK\n");
2720  return 0;
2721  }
2722  if (c->fc->nb_streams < 1)
2723  return 0;
2724  st = c->fc->streams[c->fc->nb_streams-1];
2725  sc = st->priv_data;
2726 
2727  avio_r8(pb); /* version */
2728  avio_rb24(pb); /* flags */
2729 
2730  // Clamp allocation size for `chunk_offsets` -- don't throw an error for an
2731  // invalid count since the EOF path doesn't throw either.
2732  entries = avio_rb32(pb);
2733  entries =
2734  FFMIN(entries,
2735  FFMAX(0, (atom.size - 8) /
2736  (atom.type == MKTAG('s', 't', 'c', 'o') ? 4 : 8)));
2737 
2738  if (!entries)
2739  return 0;
2740 
2741  if (sc->chunk_offsets) {
2742  av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicated STCO atom\n");
2743  return 0;
2744  }
2745 
2746  av_free(sc->chunk_offsets);
2747  sc->chunk_count = 0;
2748  sc->chunk_offsets = av_malloc_array(entries, sizeof(*sc->chunk_offsets));
2749  if (!sc->chunk_offsets)
2750  return AVERROR(ENOMEM);
2751  sc->chunk_count = entries;
2752 
2753  if (atom.type == MKTAG('s','t','c','o'))
2754  for (i = 0; i < entries && !pb->eof_reached; i++)
2755  sc->chunk_offsets[i] = avio_rb32(pb);
2756  else if (atom.type == MKTAG('c','o','6','4'))
2757  for (i = 0; i < entries && !pb->eof_reached; i++) {
2758  sc->chunk_offsets[i] = avio_rb64(pb);
2759  if (sc->chunk_offsets[i] < 0) {
2760  av_log(c->fc, AV_LOG_WARNING, "Impossible chunk_offset\n");
2761  sc->chunk_offsets[i] = 0;
2762  }
2763  }
2764  else
2765  return AVERROR_INVALIDDATA;
2766 
2767  sc->chunk_count = i;
2768 
2769  if (pb->eof_reached) {
2770  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STCO atom\n");
2771  return AVERROR_EOF;
2772  }
2773 
2774  return 0;
2775 }
2776 
2777 static int mov_codec_id(AVStream *st, uint32_t format)
2778 {
2780 
2781  if (id <= 0 &&
2782  ((format & 0xFFFF) == 'm' + ('s' << 8) ||
2783  (format & 0xFFFF) == 'T' + ('S' << 8)))
2785 
2786  if (st->codecpar->codec_type != AVMEDIA_TYPE_VIDEO && id > 0) {
2788  } else if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO &&
2789  /* skip old ASF MPEG-4 tag */
2790  format && format != MKTAG('m','p','4','s')) {
2792  if (id <= 0)
2794  if (id > 0)
2796  else if (st->codecpar->codec_type == AVMEDIA_TYPE_DATA ||
2798  st->codecpar->codec_id == AV_CODEC_ID_NONE)) {
2800  if (id <= 0) {
2802  AV_CODEC_ID_TTML : id;
2803  }
2804 
2805  if (id > 0)
2807  else
2809  }
2810  }
2811 
2812  st->codecpar->codec_tag = format;
2813 
2814  return id;
2815 }
2816 
2818  AVStream *st, MOVStreamContext *sc)
2819 {
2820  uint8_t codec_name[32] = { 0 };
2821  int64_t stsd_start;
2822  unsigned int len;
2823  uint32_t id = 0;
2824 
2825  /* The first 16 bytes of the video sample description are already
2826  * read in ff_mov_read_stsd_entries() */
2827  stsd_start = avio_tell(pb) - 16;
2828 
2829  if (c->isom) {
2830  avio_skip(pb, 2); /* pre_defined */
2831  avio_skip(pb, 2); /* reserved */
2832  avio_skip(pb, 12); /* pre_defined */
2833  } else {
2834  avio_rb16(pb); /* version */
2835  avio_rb16(pb); /* revision level */
2836  id = avio_rl32(pb); /* vendor */
2837  av_dict_set(&st->metadata, "vendor_id", av_fourcc2str(id), 0);
2838  avio_rb32(pb); /* temporal quality */
2839  avio_rb32(pb); /* spatial quality */
2840  }
2841 
2842  st->codecpar->width = avio_rb16(pb); /* width */
2843  st->codecpar->height = avio_rb16(pb); /* height */
2844 
2845  avio_rb32(pb); /* horiz resolution */
2846  avio_rb32(pb); /* vert resolution */
2847  avio_rb32(pb); /* data size, always 0 */
2848  avio_rb16(pb); /* frames per samples */
2849 
2850  len = avio_r8(pb); /* codec name, pascal string */
2851  if (len > 31)
2852  len = 31;
2853  mov_read_mac_string(c, pb, len, codec_name, sizeof(codec_name));
2854  if (len < 31)
2855  avio_skip(pb, 31 - len);
2856 
2857  if (codec_name[0])
2858  av_dict_set(&st->metadata, "encoder", codec_name, 0);
2859 
2860  /* codec_tag YV12 triggers an UV swap in rawdec.c */
2861  if (!strncmp(codec_name, "Planar Y'CbCr 8-bit 4:2:0", 25)) {
2862  st->codecpar->codec_tag = MKTAG('I', '4', '2', '0');
2863  st->codecpar->width &= ~1;
2864  st->codecpar->height &= ~1;
2865  }
2866  /* Flash Media Server uses tag H.263 with Sorenson Spark */
2867  if (st->codecpar->codec_tag == MKTAG('H','2','6','3') &&
2868  !strncmp(codec_name, "Sorenson H263", 13))
2870 
2871  st->codecpar->bits_per_coded_sample = avio_rb16(pb); /* depth */
2872 
2873  avio_seek(pb, stsd_start, SEEK_SET);
2874 
2875  if (ff_get_qtpalette(st->codecpar->codec_id, pb, sc->palette)) {
2876  st->codecpar->bits_per_coded_sample &= 0x1F;
2877  sc->has_palette = 1;
2878  }
2879 }
2880 
2882  AVStream *st, MOVStreamContext *sc)
2883 {
2884  int bits_per_sample, flags;
2885  uint16_t version = avio_rb16(pb);
2886  uint32_t id = 0;
2887  AVDictionaryEntry *compatible_brands = av_dict_get(c->fc->metadata, "compatible_brands", NULL, AV_DICT_MATCH_CASE);
2888  int channel_count;
2889 
2890  if (c->isom)
2891  avio_skip(pb, 6); /* reserved */
2892  else {
2893  avio_rb16(pb); /* revision level */
2894  id = avio_rl32(pb); /* vendor */
2895  av_dict_set(&st->metadata, "vendor_id", av_fourcc2str(id), 0);
2896  }
2897 
2898  channel_count = avio_rb16(pb);
2899 
2901  st->codecpar->ch_layout.nb_channels = channel_count;
2902  st->codecpar->bits_per_coded_sample = avio_rb16(pb); /* sample size */
2903  av_log(c->fc, AV_LOG_TRACE, "audio channels %d\n", channel_count);
2904 
2905  sc->audio_cid = avio_rb16(pb);
2906  avio_rb16(pb); /* packet size = 0 */
2907 
2908  st->codecpar->sample_rate = ((avio_rb32(pb) >> 16));
2909 
2910  // Read QT version 1 fields. In version 0 these do not exist.
2911  av_log(c->fc, AV_LOG_TRACE, "version =%d, isom =%d\n", version, c->isom);
2912  if (!c->isom ||
2913  (compatible_brands && strstr(compatible_brands->value, "qt ")) ||
2914  (sc->stsd_version == 0 && version > 0)) {
2915  if (version == 1) {
2916  sc->samples_per_frame = avio_rb32(pb);
2917  avio_rb32(pb); /* bytes per packet */
2918  sc->bytes_per_frame = avio_rb32(pb);
2919  avio_rb32(pb); /* bytes per sample */
2920  } else if (version == 2) {
2921  avio_rb32(pb); /* sizeof struct only */
2923  channel_count = avio_rb32(pb);
2925  st->codecpar->ch_layout.nb_channels = channel_count;
2926  avio_rb32(pb); /* always 0x7F000000 */
2928 
2929  flags = avio_rb32(pb); /* lpcm format specific flag */
2930  sc->bytes_per_frame = avio_rb32(pb);
2931  sc->samples_per_frame = avio_rb32(pb);
2932  if (st->codecpar->codec_tag == MKTAG('l','p','c','m'))
2933  st->codecpar->codec_id =
2935  flags);
2936  }
2937  if (version == 0 || (version == 1 && sc->audio_cid != -2)) {
2938  /* can't correctly handle variable sized packet as audio unit */
2939  switch (st->codecpar->codec_id) {
2940  case AV_CODEC_ID_MP2:
2941  case AV_CODEC_ID_MP3:
2943  break;
2944  }
2945  }
2946  }
2947 
2948  if (sc->format == 0) {
2949  if (st->codecpar->bits_per_coded_sample == 8)
2950  st->codecpar->codec_id = mov_codec_id(st, MKTAG('r','a','w',' '));
2951  else if (st->codecpar->bits_per_coded_sample == 16)
2952  st->codecpar->codec_id = mov_codec_id(st, MKTAG('t','w','o','s'));
2953  }
2954 
2955  switch (st->codecpar->codec_id) {
2956  case AV_CODEC_ID_PCM_S8:
2957  case AV_CODEC_ID_PCM_U8:
2958  if (st->codecpar->bits_per_coded_sample == 16)
2960  break;
2961  case AV_CODEC_ID_PCM_S16LE:
2962  case AV_CODEC_ID_PCM_S16BE:
2963  if (st->codecpar->bits_per_coded_sample == 8)
2965  else if (st->codecpar->bits_per_coded_sample == 24)
2966  st->codecpar->codec_id =
2969  else if (st->codecpar->bits_per_coded_sample == 32)
2970  st->codecpar->codec_id =
2973  break;
2974  /* set values for old format before stsd version 1 appeared */
2975  case AV_CODEC_ID_MACE3:
2976  sc->samples_per_frame = 6;
2978  break;
2979  case AV_CODEC_ID_MACE6:
2980  sc->samples_per_frame = 6;
2982  break;
2984  sc->samples_per_frame = 64;
2986  break;
2987  case AV_CODEC_ID_GSM:
2988  sc->samples_per_frame = 160;
2989  sc->bytes_per_frame = 33;
2990  break;
2991  default:
2992  break;
2993  }
2994 
2995  bits_per_sample = av_get_bits_per_sample(st->codecpar->codec_id);
2996  if (bits_per_sample && (bits_per_sample >> 3) * (uint64_t)st->codecpar->ch_layout.nb_channels <= INT_MAX) {
2997  st->codecpar->bits_per_coded_sample = bits_per_sample;
2998  sc->sample_size = (bits_per_sample >> 3) * st->codecpar->ch_layout.nb_channels;
2999  }
3000 }
3001 
3003  AVStream *st, MOVStreamContext *sc,
3004  int64_t size)
3005 {
3006  // ttxt stsd contains display flags, justification, background
3007  // color, fonts, and default styles, so fake an atom to read it
3008  MOVAtom fake_atom = { .size = size };
3009  // mp4s contains a regular esds atom, dfxp ISMV TTML has no content
3010  // in extradata unlike stpp MP4 TTML.
3011  if (st->codecpar->codec_tag != AV_RL32("mp4s") &&
3013  mov_read_glbl(c, pb, fake_atom);
3014  st->codecpar->width = sc->width;
3015  st->codecpar->height = sc->height;
3016 }
3017 
3019  AVStream *st, MOVStreamContext *sc,
3020  int64_t size)
3021 {
3022  int ret;
3023 
3024  if (st->codecpar->codec_tag == MKTAG('t','m','c','d')) {
3025  if ((int)size != size)
3026  return AVERROR(ENOMEM);
3027 
3028  ret = ff_get_extradata(c->fc, st->codecpar, pb, size);
3029  if (ret < 0)
3030  return ret;
3031  if (size > 16) {
3032  MOVStreamContext *tmcd_ctx = st->priv_data;
3033  int val;
3034  val = AV_RB32(st->codecpar->extradata + 4);
3035  tmcd_ctx->tmcd_flags = val;
3036  st->avg_frame_rate.num = AV_RB32(st->codecpar->extradata + 8); /* timescale */
3037  st->avg_frame_rate.den = AV_RB32(st->codecpar->extradata + 12); /* frameDuration */
3038  tmcd_ctx->tmcd_nb_frames = st->codecpar->extradata[16]; /* number of frames */
3039  if (size > 30) {
3040  uint32_t len = AV_RB32(st->codecpar->extradata + 18); /* name atom length */
3041  uint32_t format = AV_RB32(st->codecpar->extradata + 22);
3042  if (format == AV_RB32("name") && (int64_t)size >= (int64_t)len + 18) {
3043  uint16_t str_size = AV_RB16(st->codecpar->extradata + 26); /* string length */
3044  if (str_size > 0 && size >= (int)str_size + 30 &&
3045  st->codecpar->extradata[30] /* Don't add empty string */) {
3046  char *reel_name = av_malloc(str_size + 1);
3047  if (!reel_name)
3048  return AVERROR(ENOMEM);
3049  memcpy(reel_name, st->codecpar->extradata + 30, str_size);
3050  reel_name[str_size] = 0; /* Add null terminator */
3051  av_dict_set(&st->metadata, "reel_name", reel_name,
3053  }
3054  }
3055  }
3056  }
3057  } else {
3058  /* other codec type, just skip (rtp, mp4s ...) */
3059  avio_skip(pb, size);
3060  }
3061  return 0;
3062 }
3063 
3065  AVStream *st, MOVStreamContext *sc)
3066 {
3067  FFStream *const sti = ffstream(st);
3068 
3069  if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
3070  !st->codecpar->sample_rate && sc->time_scale > 1)
3071  st->codecpar->sample_rate = sc->time_scale;
3072 
3073  /* special codec parameters handling */
3074  switch (st->codecpar->codec_id) {
3075 #if CONFIG_DV_DEMUXER
3076  case AV_CODEC_ID_DVAUDIO:
3077  if (c->dv_fctx) {
3078  avpriv_request_sample(c->fc, "multiple DV audio streams");
3079  return AVERROR(ENOSYS);
3080  }
3081 
3082  c->dv_fctx = avformat_alloc_context();
3083  if (!c->dv_fctx) {
3084  av_log(c->fc, AV_LOG_ERROR, "dv demux context alloc error\n");
3085  return AVERROR(ENOMEM);
3086  }
3087  c->dv_demux = avpriv_dv_init_demux(c->dv_fctx);
3088  if (!c->dv_demux) {
3089  av_log(c->fc, AV_LOG_ERROR, "dv demux context init error\n");
3090  return AVERROR(ENOMEM);
3091  }
3092  sc->dv_audio_container = 1;
3094  break;
3095 #endif
3096  /* no ifdef since parameters are always those */
3097  case AV_CODEC_ID_QCELP:
3100  // force sample rate for qcelp when not stored in mov
3101  if (st->codecpar->codec_tag != MKTAG('Q','c','l','p'))
3102  st->codecpar->sample_rate = 8000;
3103  // FIXME: Why is the following needed for some files?
3104  sc->samples_per_frame = 160;
3105  if (!sc->bytes_per_frame)
3106  sc->bytes_per_frame = 35;
3107  break;
3108  case AV_CODEC_ID_AMR_NB:
3111  /* force sample rate for amr, stsd in 3gp does not store sample rate */
3112  st->codecpar->sample_rate = 8000;
3113  break;
3114  case AV_CODEC_ID_AMR_WB:
3117  st->codecpar->sample_rate = 16000;
3118  break;
3119  case AV_CODEC_ID_MP2:
3120  case AV_CODEC_ID_MP3:
3121  /* force type after stsd for m1a hdlr */
3123  break;
3124  case AV_CODEC_ID_GSM:
3125  case AV_CODEC_ID_ADPCM_MS:
3127  case AV_CODEC_ID_ILBC:
3128  case AV_CODEC_ID_MACE3:
3129  case AV_CODEC_ID_MACE6:
3130  case AV_CODEC_ID_QDM2:
3132  break;
3133  case AV_CODEC_ID_ALAC:
3134  if (st->codecpar->extradata_size == 36) {
3135  int channel_count = AV_RB8(st->codecpar->extradata + 21);
3136  if (st->codecpar->ch_layout.nb_channels != channel_count) {
3139  st->codecpar->ch_layout.nb_channels = channel_count;
3140  }
3141  st->codecpar->sample_rate = AV_RB32(st->codecpar->extradata + 32);
3142  }
3143  break;
3144  case AV_CODEC_ID_AC3:
3145  case AV_CODEC_ID_EAC3:
3147  case AV_CODEC_ID_VC1:
3148  case AV_CODEC_ID_VP8:
3149  case AV_CODEC_ID_VP9:
3151  break;
3153  case AV_CODEC_ID_PRORES:
3154  case AV_CODEC_ID_APV:
3155  case AV_CODEC_ID_EVC:
3156  case AV_CODEC_ID_LCEVC:
3157  case AV_CODEC_ID_AV1:
3158  /* field_order detection of H264 requires parsing */
3159  case AV_CODEC_ID_H264:
3161  break;
3162  default:
3163  break;
3164  }
3165  return 0;
3166 }
3167 
3169  int codec_tag, int format,
3170  int64_t size)
3171 {
3172  if (codec_tag &&
3173  (codec_tag != format &&
3174  // AVID 1:1 samples with differing data format and codec tag exist
3175  (codec_tag != AV_RL32("AV1x") || format != AV_RL32("AVup")) &&
3176  // prores is allowed to have differing data format and codec tag
3177  codec_tag != AV_RL32("apcn") && codec_tag != AV_RL32("apch") &&
3178  // so is dv (sigh)
3179  codec_tag != AV_RL32("dvpp") && codec_tag != AV_RL32("dvcp") &&
3180  (c->fc->video_codec_id ? ff_codec_get_id(ff_codec_movvideo_tags, format) != c->fc->video_codec_id
3181  : codec_tag != MKTAG('j','p','e','g')))) {
3182  /* Multiple fourcc, we skip JPEG. This is not correct, we should
3183  * export it as a separate AVStream but this needs a few changes
3184  * in the MOV demuxer, patch welcome. */
3185 
3186  av_log(c->fc, AV_LOG_WARNING, "multiple fourcc not supported\n");
3187  avio_skip(pb, size);
3188  return 1;
3189  }
3190 
3191  return 0;
3192 }
3193 
3195 {
3196  int ret;
3197 
3198  /* special codec parameters handling */
3199  switch (st->codecpar->codec_id) {
3200  case AV_CODEC_ID_H264:
3201  // done for ai5q, ai52, ai55, ai1q, ai12 and ai15.
3202  if (!st->codecpar->extradata_size && TAG_IS_AVCI(st->codecpar->codec_tag)) {
3204  if (ret < 0)
3205  return ret;
3206  }
3207  break;
3208  default:
3209  break;
3210  }
3211 
3212  return 0;
3213 }
3214 
3216 {
3217  AVStream *st;
3218  MOVStreamContext *sc;
3219  int pseudo_stream_id;
3220 
3221  av_assert0 (c->fc->nb_streams >= 1);
3222  st = c->fc->streams[c->fc->nb_streams-1];
3223  sc = st->priv_data;
3224 
3225  for (pseudo_stream_id = 0;
3226  pseudo_stream_id < entries && !pb->eof_reached;
3227  pseudo_stream_id++) {
3228  //Parsing Sample description table
3229  enum AVCodecID id;
3230  int ret, dref_id = 1;
3231  MOVAtom a = { AV_RL32("stsd") };
3232  int64_t start_pos = avio_tell(pb);
3233  int64_t size = avio_rb32(pb); /* size */
3234  uint32_t format = avio_rl32(pb); /* data format */
3235 
3236  if (size >= 16) {
3237  avio_rb32(pb); /* reserved */
3238  avio_rb16(pb); /* reserved */
3239  dref_id = avio_rb16(pb);
3240  } else if (size <= 7) {
3241  av_log(c->fc, AV_LOG_ERROR,
3242  "invalid size %"PRId64" in stsd\n", size);
3243  return AVERROR_INVALIDDATA;
3244  }
3245 
3247  size - (avio_tell(pb) - start_pos))) {
3248  sc->stsd_count++;
3249  continue;
3250  }
3251 
3252  sc->pseudo_stream_id = st->codecpar->codec_tag ? -1 : pseudo_stream_id;
3253  sc->dref_id= dref_id;
3254  sc->format = format;
3255 
3256  id = mov_codec_id(st, format);
3257 
3258  av_log(c->fc, AV_LOG_TRACE,
3259  "size=%"PRId64" 4CC=%s codec_type=%d\n", size,
3261 
3262  st->codecpar->codec_id = id;
3264  mov_parse_stsd_video(c, pb, st, sc);
3265  } else if (st->codecpar->codec_type==AVMEDIA_TYPE_AUDIO) {
3266  mov_parse_stsd_audio(c, pb, st, sc);
3267  if (st->codecpar->sample_rate < 0) {
3268  av_log(c->fc, AV_LOG_ERROR, "Invalid sample rate %d\n", st->codecpar->sample_rate);
3269  return AVERROR_INVALIDDATA;
3270  }
3271  if (st->codecpar->ch_layout.nb_channels < 0) {
3272  av_log(c->fc, AV_LOG_ERROR, "Invalid channels %d\n", st->codecpar->ch_layout.nb_channels);
3273  return AVERROR_INVALIDDATA;
3274  }
3275  } else if (st->codecpar->codec_type==AVMEDIA_TYPE_SUBTITLE){
3276  mov_parse_stsd_subtitle(c, pb, st, sc,
3277  size - (avio_tell(pb) - start_pos));
3278  } else {
3279  ret = mov_parse_stsd_data(c, pb, st, sc,
3280  size - (avio_tell(pb) - start_pos));
3281  if (ret < 0)
3282  return ret;
3283  }
3284  /* this will read extra atoms at the end (wave, alac, damr, avcC, hvcC, SMI ...) */
3285  a.size = size - (avio_tell(pb) - start_pos);
3286  if (a.size > 8) {
3287  if ((ret = mov_read_default(c, pb, a)) < 0)
3288  return ret;
3289  } else if (a.size > 0)
3290  avio_skip(pb, a.size);
3291 
3292  ret = mov_finalize_stsd_entry(c, st);
3293  if (ret < 0)
3294  return ret;
3295 
3296  if (sc->extradata && st->codecpar->extradata) {
3297  int extra_size = st->codecpar->extradata_size;
3298 
3299  /* Move the current stream extradata to the stream context one. */
3300  sc->extradata_size[pseudo_stream_id] = extra_size;
3301  sc->extradata[pseudo_stream_id] = st->codecpar->extradata;
3302  st->codecpar->extradata = NULL;
3303  st->codecpar->extradata_size = 0;
3304  }
3305  sc->stsd_count++;
3306  }
3307 
3308  if (pb->eof_reached) {
3309  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSD atom\n");
3310  return AVERROR_EOF;
3311  }
3312 
3313  return 0;
3314 }
3315 
3317 {
3318  AVStream *st;
3319  MOVStreamContext *sc;
3320  int ret, entries;
3321 
3322  if (c->fc->nb_streams < 1)
3323  return 0;
3324  st = c->fc->streams[c->fc->nb_streams - 1];
3325  sc = st->priv_data;
3326 
3327  if (sc->extradata) {
3328  av_log(c->fc, AV_LOG_ERROR,
3329  "Duplicate stsd found in this track.\n");
3330  return AVERROR_INVALIDDATA;
3331  }
3332 
3333  sc->stsd_version = avio_r8(pb);
3334  avio_rb24(pb); /* flags */
3335  entries = avio_rb32(pb);
3336 
3337  /* Each entry contains a size (4 bytes) and format (4 bytes). */
3338  if (entries <= 0 || entries > atom.size / 8 || entries > 1024) {
3339  av_log(c->fc, AV_LOG_ERROR, "invalid STSD entries %d\n", entries);
3340  return AVERROR_INVALIDDATA;
3341  }
3342 
3343  /* Prepare space for hosting multiple extradata. */
3344  sc->extradata = av_calloc(entries, sizeof(*sc->extradata));
3345  if (!sc->extradata)
3346  return AVERROR(ENOMEM);
3347 
3348  sc->extradata_size = av_calloc(entries, sizeof(*sc->extradata_size));
3349  if (!sc->extradata_size) {
3350  ret = AVERROR(ENOMEM);
3351  goto fail;
3352  }
3353 
3354  ret = ff_mov_read_stsd_entries(c, pb, entries);
3355  if (ret < 0)
3356  goto fail;
3357 
3358  /* Restore back the primary extradata. */
3359  av_freep(&st->codecpar->extradata);
3360  st->codecpar->extradata_size = sc->extradata_size[0];
3361  if (sc->extradata_size[0]) {
3363  if (!st->codecpar->extradata)
3364  return AVERROR(ENOMEM);
3365  memcpy(st->codecpar->extradata, sc->extradata[0], sc->extradata_size[0]);
3366  }
3367 
3368  return mov_finalize_stsd_codec(c, pb, st, sc);
3369 fail:
3370  if (sc->extradata) {
3371  int j;
3372  for (j = 0; j < sc->stsd_count; j++)
3373  av_freep(&sc->extradata[j]);
3374  }
3375 
3376  sc->stsd_count = 0;
3377  av_freep(&sc->extradata);
3378  av_freep(&sc->extradata_size);
3379  return ret;
3380 }
3381 
3383 {
3384  AVStream *st;
3385  MOVStreamContext *sc;
3386  unsigned int i, entries;
3387 
3388  if (c->trak_index < 0) {
3389  av_log(c->fc, AV_LOG_WARNING, "STSC outside TRAK\n");
3390  return 0;
3391  }
3392 
3393  if (c->fc->nb_streams < 1)
3394  return 0;
3395  st = c->fc->streams[c->fc->nb_streams-1];
3396  sc = st->priv_data;
3397 
3398  avio_r8(pb); /* version */
3399  avio_rb24(pb); /* flags */
3400 
3401  entries = avio_rb32(pb);
3402  if ((uint64_t)entries * 12 + 4 > atom.size)
3403  return AVERROR_INVALIDDATA;
3404 
3405  av_log(c->fc, AV_LOG_TRACE, "track[%u].stsc.entries = %u\n", c->fc->nb_streams - 1, entries);
3406 
3407  if (!entries)
3408  return 0;
3409  if (sc->stsc_data) {
3410  av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicated STSC atom\n");
3411  return 0;
3412  }
3413  av_free(sc->stsc_data);
3414  sc->stsc_count = 0;
3415  sc->stsc_data = av_malloc_array(entries, sizeof(*sc->stsc_data));
3416  if (!sc->stsc_data)
3417  return AVERROR(ENOMEM);
3418 
3419  for (i = 0; i < entries && !pb->eof_reached; i++) {
3420  sc->stsc_data[i].first = avio_rb32(pb);
3421  sc->stsc_data[i].count = avio_rb32(pb);
3422  sc->stsc_data[i].id = avio_rb32(pb);
3423  }
3424 
3425  sc->stsc_count = i;
3426  for (i = sc->stsc_count - 1; i < UINT_MAX; i--) {
3427  int64_t first_min = i + 1;
3428  if ((i+1 < sc->stsc_count && sc->stsc_data[i].first >= sc->stsc_data[i+1].first) ||
3429  (i > 0 && sc->stsc_data[i].first <= sc->stsc_data[i-1].first) ||
3430  sc->stsc_data[i].first < first_min ||
3431  sc->stsc_data[i].count < 1 ||
3432  sc->stsc_data[i].id < 1) {
3433  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);
3434  if (i+1 >= sc->stsc_count) {
3435  if (sc->stsc_data[i].count == 0 && i > 0) {
3436  sc->stsc_count --;
3437  continue;
3438  }
3439  sc->stsc_data[i].first = FFMAX(sc->stsc_data[i].first, first_min);
3440  if (i > 0 && sc->stsc_data[i].first <= sc->stsc_data[i-1].first)
3441  sc->stsc_data[i].first = FFMIN(sc->stsc_data[i-1].first + 1LL, INT_MAX);
3442  sc->stsc_data[i].count = FFMAX(sc->stsc_data[i].count, 1);
3443  sc->stsc_data[i].id = FFMAX(sc->stsc_data[i].id, 1);
3444  continue;
3445  }
3446  av_assert0(sc->stsc_data[i+1].first >= 2);
3447  // We replace this entry by the next valid
3448  sc->stsc_data[i].first = sc->stsc_data[i+1].first - 1;
3449  sc->stsc_data[i].count = sc->stsc_data[i+1].count;
3450  sc->stsc_data[i].id = sc->stsc_data[i+1].id;
3451  }
3452  }
3453 
3454  if (pb->eof_reached) {
3455  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSC atom\n");
3456  return AVERROR_EOF;
3457  }
3458 
3459  return 0;
3460 }
3461 
3462 static inline int mov_stsc_index_valid(unsigned int index, unsigned int count)
3463 {
3464  return index < count - 1;
3465 }
3466 
3467 /* Compute the samples value for the stsc entry at the given index. */
3468 static inline int64_t mov_get_stsc_samples(MOVStreamContext *sc, unsigned int index)
3469 {
3470  int chunk_count;
3471 
3473  chunk_count = sc->stsc_data[index + 1].first - sc->stsc_data[index].first;
3474  else {
3475  // Validation for stsc / stco happens earlier in mov_read_stsc + mov_read_trak.
3477  chunk_count = sc->chunk_count - (sc->stsc_data[index].first - 1);
3478  }
3479 
3480  return sc->stsc_data[index].count * (int64_t)chunk_count;
3481 }
3482 
3484 {
3485  AVStream *st;
3486  MOVStreamContext *sc;
3487  unsigned i, entries;
3488 
3489  if (c->trak_index < 0) {
3490  av_log(c->fc, AV_LOG_WARNING, "STPS outside TRAK\n");
3491  return 0;
3492  }
3493 
3494  if (c->fc->nb_streams < 1)
3495  return 0;
3496  st = c->fc->streams[c->fc->nb_streams-1];
3497  sc = st->priv_data;
3498 
3499  avio_rb32(pb); // version + flags
3500 
3501  entries = avio_rb32(pb);
3502  if (sc->stps_data)
3503  av_log(c->fc, AV_LOG_WARNING, "Duplicated STPS atom\n");
3504  av_free(sc->stps_data);
3505  sc->stps_count = 0;
3506  sc->stps_data = av_malloc_array(entries, sizeof(*sc->stps_data));
3507  if (!sc->stps_data)
3508  return AVERROR(ENOMEM);
3509 
3510  for (i = 0; i < entries && !pb->eof_reached; i++) {
3511  sc->stps_data[i] = avio_rb32(pb);
3512  }
3513 
3514  sc->stps_count = i;
3515 
3516  if (pb->eof_reached) {
3517  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STPS atom\n");
3518  return AVERROR_EOF;
3519  }
3520 
3521  return 0;
3522 }
3523 
3525 {
3526  AVStream *st;
3527  FFStream *sti;
3528  MOVStreamContext *sc;
3529  unsigned int i, entries;
3530 
3531  if (c->trak_index < 0) {
3532  av_log(c->fc, AV_LOG_WARNING, "STSS outside TRAK\n");
3533  return 0;
3534  }
3535 
3536  if (c->fc->nb_streams < 1)
3537  return 0;
3538  st = c->fc->streams[c->fc->nb_streams-1];
3539  sti = ffstream(st);
3540  sc = st->priv_data;
3541 
3542  avio_r8(pb); /* version */
3543  avio_rb24(pb); /* flags */
3544 
3545  entries = avio_rb32(pb);
3546 
3547  av_log(c->fc, AV_LOG_TRACE, "keyframe_count = %u\n", entries);
3548 
3549  if (!entries) {
3550  sc->keyframe_absent = 1;
3551  if (!sti->need_parsing && st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
3553  return 0;
3554  }
3555  if (sc->keyframes)
3556  av_log(c->fc, AV_LOG_WARNING, "Duplicated STSS atom\n");
3557  if (entries >= UINT_MAX / sizeof(int))
3558  return AVERROR_INVALIDDATA;
3559  av_freep(&sc->keyframes);
3560  sc->keyframe_count = 0;
3561  sc->keyframes = av_malloc_array(entries, sizeof(*sc->keyframes));
3562  if (!sc->keyframes)
3563  return AVERROR(ENOMEM);
3564 
3565  for (i = 0; i < entries && !pb->eof_reached; i++) {
3566  sc->keyframes[i] = avio_rb32(pb);
3567  }
3568 
3569  sc->keyframe_count = i;
3570 
3571  if (pb->eof_reached) {
3572  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSS atom\n");
3573  return AVERROR_EOF;
3574  }
3575 
3576  return 0;
3577 }
3578 
3580 {
3581  AVStream *st;
3582  MOVStreamContext *sc;
3583  unsigned int i, entries, sample_size, field_size, num_bytes;
3584  GetBitContext gb;
3585  unsigned char* buf;
3586  int ret;
3587 
3588  if (c->trak_index < 0) {
3589  av_log(c->fc, AV_LOG_WARNING, "STSZ outside TRAK\n");
3590  return 0;
3591  }
3592 
3593  if (c->fc->nb_streams < 1)
3594  return 0;
3595  st = c->fc->streams[c->fc->nb_streams-1];
3596  sc = st->priv_data;
3597 
3598  avio_r8(pb); /* version */
3599  avio_rb24(pb); /* flags */
3600 
3601  if (atom.type == MKTAG('s','t','s','z')) {
3602  sample_size = avio_rb32(pb);
3603  if (!sc->sample_size) /* do not overwrite value computed in stsd */
3604  sc->sample_size = sample_size;
3605  sc->stsz_sample_size = sample_size;
3606  field_size = 32;
3607  } else {
3608  sample_size = 0;
3609  avio_rb24(pb); /* reserved */
3610  field_size = avio_r8(pb);
3611  }
3612  entries = avio_rb32(pb);
3613 
3614  av_log(c->fc, AV_LOG_TRACE, "sample_size = %u sample_count = %u\n", sc->sample_size, entries);
3615 
3616  sc->sample_count = entries;
3617  if (sample_size)
3618  return 0;
3619 
3620  if (field_size != 4 && field_size != 8 && field_size != 16 && field_size != 32) {
3621  av_log(c->fc, AV_LOG_ERROR, "Invalid sample field size %u\n", field_size);
3622  return AVERROR_INVALIDDATA;
3623  }
3624 
3625  if (!entries)
3626  return 0;
3627  if (entries >= (INT_MAX - 4 - 8 * AV_INPUT_BUFFER_PADDING_SIZE) / field_size)
3628  return AVERROR_INVALIDDATA;
3629  if (sc->sample_sizes)
3630  av_log(c->fc, AV_LOG_WARNING, "Duplicated STSZ atom\n");
3631  av_free(sc->sample_sizes);
3632  sc->sample_count = 0;
3633  sc->sample_sizes = av_malloc_array(entries, sizeof(*sc->sample_sizes));
3634  if (!sc->sample_sizes)
3635  return AVERROR(ENOMEM);
3636 
3637  num_bytes = (entries*field_size+4)>>3;
3638 
3639  buf = av_malloc(num_bytes+AV_INPUT_BUFFER_PADDING_SIZE);
3640  if (!buf) {
3641  av_freep(&sc->sample_sizes);
3642  return AVERROR(ENOMEM);
3643  }
3644 
3645  ret = ffio_read_size(pb, buf, num_bytes);
3646  if (ret < 0) {
3647  av_freep(&sc->sample_sizes);
3648  av_free(buf);
3649  av_log(c->fc, AV_LOG_WARNING, "STSZ atom truncated\n");
3650  return 0;
3651  }
3652 
3653  init_get_bits(&gb, buf, 8*num_bytes);
3654 
3655  for (i = 0; i < entries; i++) {
3656  sc->sample_sizes[i] = get_bits_long(&gb, field_size);
3657  if (sc->sample_sizes[i] > INT64_MAX - sc->data_size) {
3658  av_free(buf);
3659  av_log(c->fc, AV_LOG_ERROR, "Sample size overflow in STSZ\n");
3660  return AVERROR_INVALIDDATA;
3661  }
3662  sc->data_size += sc->sample_sizes[i];
3663  }
3664 
3665  sc->sample_count = i;
3666 
3667  av_free(buf);
3668 
3669  return 0;
3670 }
3671 
3673 {
3674  AVStream *st;
3675  MOVStreamContext *sc;
3676  unsigned int i, entries;
3677  int64_t duration = 0;
3678  int64_t total_sample_count = 0;
3679  int64_t current_dts = 0;
3680  int64_t corrected_dts = 0;
3681 
3682  if (c->trak_index < 0) {
3683  av_log(c->fc, AV_LOG_WARNING, "STTS outside TRAK\n");
3684  return 0;
3685  }
3686 
3687  if (c->fc->nb_streams < 1)
3688  return 0;
3689  st = c->fc->streams[c->fc->nb_streams-1];
3690  sc = st->priv_data;
3691 
3692  avio_r8(pb); /* version */
3693  avio_rb24(pb); /* flags */
3694  entries = avio_rb32(pb);
3695 
3696  av_log(c->fc, AV_LOG_TRACE, "track[%u].stts.entries = %u\n",
3697  c->fc->nb_streams-1, entries);
3698 
3699  if (sc->stts_data)
3700  av_log(c->fc, AV_LOG_WARNING, "Duplicated STTS atom\n");
3701  av_freep(&sc->stts_data);
3702  sc->stts_count = 0;
3703  if (entries >= INT_MAX / sizeof(*sc->stts_data))
3704  return AVERROR(ENOMEM);
3705 
3706  for (i = 0; i < entries && !pb->eof_reached; i++) {
3707  unsigned int sample_duration;
3708  unsigned int sample_count;
3709  unsigned int min_entries = FFMIN(FFMAX(i + 1, 1024 * 1024), entries);
3710  MOVStts *stts_data = av_fast_realloc(sc->stts_data, &sc->stts_allocated_size,
3711  min_entries * sizeof(*sc->stts_data));
3712  if (!stts_data) {
3713  av_freep(&sc->stts_data);
3714  sc->stts_count = 0;
3715  return AVERROR(ENOMEM);
3716  }
3717  sc->stts_count = min_entries;
3718  sc->stts_data = stts_data;
3719 
3720  sample_count = avio_rb32(pb);
3721  sample_duration = avio_rb32(pb);
3722 
3723  sc->stts_data[i].count= sample_count;
3724  sc->stts_data[i].duration= sample_duration;
3725 
3726  av_log(c->fc, AV_LOG_TRACE, "sample_count=%u, sample_duration=%u\n",
3727  sample_count, sample_duration);
3728 
3729  /* STTS sample offsets are uint32 but some files store it as int32
3730  * with negative values used to correct DTS delays.
3731  There may be abnormally large values as well. */
3732  if (sample_duration > c->max_stts_delta) {
3733  // assume high delta is a correction if negative when cast as int32
3734  int32_t delta_magnitude = (int32_t)sample_duration;
3735  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",
3736  sample_duration, i, sample_count, st->index);
3737  sc->stts_data[i].duration = 1;
3738  corrected_dts = av_sat_add64(corrected_dts, (delta_magnitude < 0 ? (int64_t)delta_magnitude : 1) * sample_count);
3739  } else {
3740  corrected_dts += sample_duration * (uint64_t)sample_count;
3741  }
3742 
3743  current_dts += sc->stts_data[i].duration * (uint64_t)sample_count;
3744 
3745  if (current_dts > corrected_dts) {
3746  int64_t drift = av_sat_sub64(current_dts, corrected_dts) / FFMAX(sample_count, 1);
3747  uint32_t correction = (sc->stts_data[i].duration > drift) ? drift : sc->stts_data[i].duration - 1;
3748  current_dts -= correction * (uint64_t)sample_count;
3749  sc->stts_data[i].duration -= correction;
3750  }
3751 
3752  duration+=(int64_t)sc->stts_data[i].duration*(uint64_t)sc->stts_data[i].count;
3753  total_sample_count+=sc->stts_data[i].count;
3754  }
3755 
3756  sc->stts_count = i;
3757 
3758  if (duration > 0 &&
3759  duration <= INT64_MAX - sc->duration_for_fps &&
3760  total_sample_count <= INT_MAX - sc->nb_frames_for_fps) {
3761  sc->duration_for_fps += duration;
3762  sc->nb_frames_for_fps += total_sample_count;
3763  }
3764 
3765  if (pb->eof_reached) {
3766  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STTS atom\n");
3767  return AVERROR_EOF;
3768  }
3769 
3770  st->nb_frames= total_sample_count;
3771  if (duration)
3772  st->duration= FFMIN(st->duration, duration);
3773 
3774  // All samples have zero duration. They have higher chance be chose by
3775  // mov_find_next_sample, which leads to seek again and again.
3776  //
3777  // It's AVERROR_INVALIDDATA actually, but such files exist in the wild.
3778  // So only mark data stream as discarded for safety.
3779  if (!duration && sc->stts_count &&
3781  av_log(c->fc, AV_LOG_WARNING,
3782  "All samples in data stream index:id [%d:%d] have zero "
3783  "duration, stream set to be discarded by default. Override "
3784  "using AVStream->discard or -discard for ffmpeg command.\n",
3785  st->index, sc->id);
3786  st->discard = AVDISCARD_ALL;
3787  }
3788  sc->track_end = duration;
3789  return 0;
3790 }
3791 
3793 {
3794  AVStream *st;
3795  MOVStreamContext *sc;
3796  unsigned int i;
3797  int64_t entries;
3798 
3799  if (c->fc->nb_streams < 1)
3800  return 0;
3801  st = c->fc->streams[c->fc->nb_streams - 1];
3802  sc = st->priv_data;
3803 
3804  avio_r8(pb); /* version */
3805  avio_rb24(pb); /* flags */
3806  entries = atom.size - 4;
3807 
3808  av_log(c->fc, AV_LOG_TRACE, "track[%u].sdtp.entries = %" PRId64 "\n",
3809  c->fc->nb_streams - 1, entries);
3810 
3811  if (sc->sdtp_data)
3812  av_log(c->fc, AV_LOG_WARNING, "Duplicated SDTP atom\n");
3813  av_freep(&sc->sdtp_data);
3814  sc->sdtp_count = 0;
3815 
3816  if (entries < 0 || entries > UINT_MAX)
3817  return AVERROR(ERANGE);
3818 
3819  sc->sdtp_data = av_malloc(entries);
3820  if (!sc->sdtp_data)
3821  return AVERROR(ENOMEM);
3822 
3823  for (i = 0; i < entries && !pb->eof_reached; i++)
3824  sc->sdtp_data[i] = avio_r8(pb);
3825  sc->sdtp_count = i;
3826 
3827  return 0;
3828 }
3829 
3830 static void mov_update_dts_shift(MOVStreamContext *sc, int duration, void *logctx)
3831 {
3832  if (duration < 0) {
3833  if (duration == INT_MIN) {
3834  av_log(logctx, AV_LOG_WARNING, "mov_update_dts_shift(): dts_shift set to %d\n", INT_MAX);
3835  duration++;
3836  }
3837  sc->dts_shift = FFMAX(sc->dts_shift, -duration);
3838  }
3839 }
3840 
3842 {
3843  AVStream *st;
3844  MOVStreamContext *sc;
3845  unsigned int i, entries, ctts_count = 0;
3846 
3847  if (c->trak_index < 0) {
3848  av_log(c->fc, AV_LOG_WARNING, "CTTS outside TRAK\n");
3849  return 0;
3850  }
3851 
3852  if (c->fc->nb_streams < 1)
3853  return 0;
3854  st = c->fc->streams[c->fc->nb_streams-1];
3855  sc = st->priv_data;
3856 
3857  avio_r8(pb); /* version */
3858  avio_rb24(pb); /* flags */
3859  entries = avio_rb32(pb);
3860 
3861  av_log(c->fc, AV_LOG_TRACE, "track[%u].ctts.entries = %u\n", c->fc->nb_streams - 1, entries);
3862 
3863  if (!entries)
3864  return 0;
3865  if (entries >= UINT_MAX / sizeof(*sc->ctts_data))
3866  return AVERROR_INVALIDDATA;
3867  av_freep(&sc->ctts_data);
3868  sc->ctts_data = av_fast_realloc(NULL, &sc->ctts_allocated_size, entries * sizeof(*sc->ctts_data));
3869  if (!sc->ctts_data)
3870  return AVERROR(ENOMEM);
3871 
3872  for (i = 0; i < entries && !pb->eof_reached; i++) {
3873  MOVCtts *ctts_data;
3874  const size_t min_size_needed = (ctts_count + 1) * sizeof(MOVCtts);
3875  const size_t requested_size =
3876  min_size_needed > sc->ctts_allocated_size ?
3877  FFMAX(min_size_needed, 2 * sc->ctts_allocated_size) :
3878  min_size_needed;
3879  int count = avio_rb32(pb);
3880  int duration = avio_rb32(pb);
3881 
3882  if (count <= 0) {
3883  av_log(c->fc, AV_LOG_TRACE,
3884  "ignoring CTTS entry with count=%d duration=%d\n",
3885  count, duration);
3886  continue;
3887  }
3888 
3889  if (ctts_count >= UINT_MAX / sizeof(MOVCtts) - 1)
3890  return AVERROR(ENOMEM);
3891 
3892  ctts_data = av_fast_realloc(sc->ctts_data, &sc->ctts_allocated_size, requested_size);
3893 
3894  if (!ctts_data)
3895  return AVERROR(ENOMEM);
3896 
3897  sc->ctts_data = ctts_data;
3898 
3899  ctts_data[ctts_count].count = count;
3900  ctts_data[ctts_count].offset = duration;
3901  ctts_count++;
3902 
3903  av_log(c->fc, AV_LOG_TRACE, "count=%d, duration=%d\n",
3904  count, duration);
3905 
3906  if (i+2<entries)
3907  mov_update_dts_shift(sc, duration, c->fc);
3908  }
3909 
3910  sc->ctts_count = ctts_count;
3911 
3912  if (pb->eof_reached) {
3913  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted CTTS atom\n");
3914  return AVERROR_EOF;
3915  }
3916 
3917  av_log(c->fc, AV_LOG_TRACE, "dts shift %d\n", sc->dts_shift);
3918 
3919  return 0;
3920 }
3921 
3923 {
3924  AVStream *st;
3925  MOVStreamContext *sc;
3926  uint8_t version;
3927  uint32_t grouping_type;
3928  uint32_t default_length;
3929  av_unused uint32_t default_group_description_index;
3930  uint32_t entry_count;
3931 
3932  if (c->fc->nb_streams < 1)
3933  return 0;
3934  st = c->fc->streams[c->fc->nb_streams - 1];
3935  sc = st->priv_data;
3936 
3937  version = avio_r8(pb); /* version */
3938  avio_rb24(pb); /* flags */
3939  grouping_type = avio_rl32(pb);
3940 
3941  /*
3942  * This function only supports "sync" boxes, but the code is able to parse
3943  * other boxes (such as "tscl", "tsas" and "stsa")
3944  */
3945  if (grouping_type != MKTAG('s','y','n','c'))
3946  return 0;
3947 
3948  default_length = version >= 1 ? avio_rb32(pb) : 0;
3949  default_group_description_index = version >= 2 ? avio_rb32(pb) : 0;
3950  entry_count = avio_rb32(pb);
3951 
3952  if (entry_count > atom.size)
3953  return AVERROR_INVALIDDATA;
3954 
3955  av_freep(&sc->sgpd_sync);
3956  sc->sgpd_sync_count = entry_count;
3957  sc->sgpd_sync = av_calloc(entry_count, sizeof(*sc->sgpd_sync));
3958  if (!sc->sgpd_sync)
3959  return AVERROR(ENOMEM);
3960 
3961  for (uint32_t i = 0; i < entry_count && !pb->eof_reached; i++) {
3962  uint32_t description_length = default_length;
3963  if (version >= 1 && default_length == 0)
3964  description_length = avio_rb32(pb);
3965  if (grouping_type == MKTAG('s','y','n','c')) {
3966  const uint8_t nal_unit_type = avio_r8(pb) & 0x3f;
3967  sc->sgpd_sync[i] = nal_unit_type;
3968  description_length -= 1;
3969  }
3970  avio_skip(pb, description_length);
3971  }
3972 
3973  if (pb->eof_reached) {
3974  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted SGPD atom\n");
3975  return AVERROR_EOF;
3976  }
3977 
3978  return 0;
3979 }
3980 
3982 {
3983  AVStream *st;
3984  MOVStreamContext *sc;
3985  unsigned int i, entries;
3986  uint8_t version;
3987  uint32_t grouping_type;
3988  MOVSbgp *table, **tablep;
3989  int *table_count;
3990 
3991  if (c->fc->nb_streams < 1)
3992  return 0;
3993  st = c->fc->streams[c->fc->nb_streams-1];
3994  sc = st->priv_data;
3995 
3996  version = avio_r8(pb); /* version */
3997  avio_rb24(pb); /* flags */
3998  grouping_type = avio_rl32(pb);
3999 
4000  if (grouping_type == MKTAG('r','a','p',' ')) {
4001  tablep = &sc->rap_group;
4002  table_count = &sc->rap_group_count;
4003  } else if (grouping_type == MKTAG('s','y','n','c')) {
4004  tablep = &sc->sync_group;
4005  table_count = &sc->sync_group_count;
4006  } else {
4007  return 0;
4008  }
4009 
4010  if (version == 1)
4011  avio_rb32(pb); /* grouping_type_parameter */
4012 
4013  entries = avio_rb32(pb);
4014  if (!entries)
4015  return 0;
4016  if (*tablep)
4017  av_log(c->fc, AV_LOG_WARNING, "Duplicated SBGP %s atom\n", av_fourcc2str(grouping_type));
4018  av_freep(tablep);
4019  table = av_malloc_array(entries, sizeof(*table));
4020  if (!table)
4021  return AVERROR(ENOMEM);
4022  *tablep = table;
4023 
4024  for (i = 0; i < entries && !pb->eof_reached; i++) {
4025  table[i].count = avio_rb32(pb); /* sample_count */
4026  table[i].index = avio_rb32(pb); /* group_description_index */
4027  }
4028 
4029  *table_count = i;
4030 
4031  if (pb->eof_reached) {
4032  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted SBGP atom\n");
4033  return AVERROR_EOF;
4034  }
4035 
4036  return 0;
4037 }
4038 
4039 /**
4040  * Get ith edit list entry (media time, duration).
4041  */
4043  const MOVStreamContext *msc,
4044  unsigned int edit_list_index,
4045  int64_t *edit_list_media_time,
4046  int64_t *edit_list_duration,
4047  int64_t global_timescale)
4048 {
4049  if (edit_list_index == msc->elst_count) {
4050  return 0;
4051  }
4052  *edit_list_media_time = msc->elst_data[edit_list_index].time;
4053  *edit_list_duration = msc->elst_data[edit_list_index].duration;
4054 
4055  /* duration is in global timescale units;convert to msc timescale */
4056  if (global_timescale == 0) {
4057  avpriv_request_sample(mov->fc, "Support for mvhd.timescale = 0 with editlists");
4058  return 0;
4059  }
4060  *edit_list_duration = av_rescale(*edit_list_duration, msc->time_scale,
4061  global_timescale);
4062 
4063  if (*edit_list_duration + (uint64_t)*edit_list_media_time > INT64_MAX)
4064  *edit_list_duration = 0;
4065 
4066  return 1;
4067 }
4068 
4069 /**
4070  * Find the closest previous frame to the timestamp_pts, in e_old index
4071  * entries. Searching for just any frame / just key frames can be controlled by
4072  * last argument 'flag'.
4073  * Note that if ctts_data is not NULL, we will always search for a key frame
4074  * irrespective of the value of 'flag'. If we don't find any keyframe, we will
4075  * return the first frame of the video.
4076  *
4077  * Here the timestamp_pts is considered to be a presentation timestamp and
4078  * the timestamp of index entries are considered to be decoding timestamps.
4079  *
4080  * Returns 0 if successful in finding a frame, else returns -1.
4081  * Places the found index corresponding output arg.
4082  *
4083  * If ctts_old is not NULL, then refines the searched entry by searching
4084  * backwards from the found timestamp, to find the frame with correct PTS.
4085  *
4086  * Places the found ctts_index and ctts_sample in corresponding output args.
4087  */
4089  AVIndexEntry *e_old,
4090  int nb_old,
4091  MOVTimeToSample *tts_data,
4092  int64_t tts_count,
4093  int64_t timestamp_pts,
4094  int flag,
4095  int64_t* index,
4096  int64_t* tts_index,
4097  int64_t* tts_sample)
4098 {
4099  MOVStreamContext *msc = st->priv_data;
4100  FFStream *const sti = ffstream(st);
4101  AVIndexEntry *e_keep = sti->index_entries;
4102  int nb_keep = sti->nb_index_entries;
4103  int64_t i = 0;
4104 
4105  av_assert0(index);
4106 
4107  // If dts_shift > 0, then all the index timestamps will have to be offset by
4108  // at least dts_shift amount to obtain PTS.
4109  // Hence we decrement the searched timestamp_pts by dts_shift to find the closest index element.
4110  if (msc->dts_shift > 0) {
4111  timestamp_pts -= msc->dts_shift;
4112  }
4113 
4114  sti->index_entries = e_old;
4115  sti->nb_index_entries = nb_old;
4116  *index = av_index_search_timestamp(st, timestamp_pts, flag | AVSEEK_FLAG_BACKWARD);
4117 
4118  // Keep going backwards in the index entries until the timestamp is the same.
4119  if (*index >= 0) {
4120  for (i = *index; i > 0 && e_old[i].timestamp == e_old[i - 1].timestamp;
4121  i--) {
4122  if ((flag & AVSEEK_FLAG_ANY) ||
4123  (e_old[i - 1].flags & AVINDEX_KEYFRAME)) {
4124  *index = i - 1;
4125  }
4126  }
4127  }
4128 
4129  // If we have CTTS then refine the search, by searching backwards over PTS
4130  // computed by adding corresponding CTTS durations to index timestamps.
4131  if (msc->ctts_count && *index >= 0) {
4132  av_assert0(tts_index);
4133  av_assert0(tts_sample);
4134  // Find out the ctts_index for the found frame.
4135  *tts_index = 0;
4136  *tts_sample = 0;
4137  for (int64_t index_tts_count = 0; index_tts_count < *index; index_tts_count++) {
4138  if (*tts_index < tts_count) {
4139  (*tts_sample)++;
4140  if (tts_data[*tts_index].count == *tts_sample) {
4141  (*tts_index)++;
4142  *tts_sample = 0;
4143  }
4144  }
4145  }
4146 
4147  while (*index >= 0 && (*tts_index) >= 0 && (*tts_index) < tts_count) {
4148  // Find a "key frame" with PTS <= timestamp_pts (So that we can decode B-frames correctly).
4149  // No need to add dts_shift to the timestamp here because timestamp_pts has already been
4150  // compensated by dts_shift above.
4151  if ((e_old[*index].timestamp + tts_data[*tts_index].offset) <= timestamp_pts &&
4152  (e_old[*index].flags & AVINDEX_KEYFRAME)) {
4153  break;
4154  }
4155 
4156  (*index)--;
4157  if (*tts_sample == 0) {
4158  (*tts_index)--;
4159  if (*tts_index >= 0)
4160  *tts_sample = tts_data[*tts_index].count - 1;
4161  } else {
4162  (*tts_sample)--;
4163  }
4164  }
4165  }
4166 
4167  /* restore AVStream state*/
4168  sti->index_entries = e_keep;
4169  sti->nb_index_entries = nb_keep;
4170  return *index >= 0 ? 0 : -1;
4171 }
4172 
4173 /**
4174  * Add index entry with the given values, to the end of ffstream(st)->index_entries.
4175  * Returns the new size ffstream(st)->index_entries if successful, else returns -1.
4176  *
4177  * This function is similar to ff_add_index_entry in libavformat/utils.c
4178  * except that here we are always unconditionally adding an index entry to
4179  * the end, instead of searching the entries list and skipping the add if
4180  * there is an existing entry with the same timestamp.
4181  * This is needed because the mov_fix_index calls this func with the same
4182  * unincremented timestamp for successive discarded frames.
4183  */
4185  int size, int distance, int flags)
4186 {
4187  FFStream *const sti = ffstream(st);
4188  AVIndexEntry *entries, *ie;
4189  int64_t index = -1;
4190  const size_t min_size_needed = (sti->nb_index_entries + 1) * sizeof(AVIndexEntry);
4191 
4192  // Double the allocation each time, to lower memory fragmentation.
4193  // Another difference from ff_add_index_entry function.
4194  const size_t requested_size =
4195  min_size_needed > sti->index_entries_allocated_size ?
4196  FFMAX(min_size_needed, 2 * sti->index_entries_allocated_size) :
4197  min_size_needed;
4198 
4199  if (sti->nb_index_entries + 1U >= UINT_MAX / sizeof(AVIndexEntry))
4200  return -1;
4201 
4202  entries = av_fast_realloc(sti->index_entries,
4204  requested_size);
4205  if (!entries)
4206  return -1;
4207 
4208  sti->index_entries = entries;
4209 
4210  index = sti->nb_index_entries++;
4211  ie= &entries[index];
4212 
4213  ie->pos = pos;
4214  ie->timestamp = timestamp;
4215  ie->min_distance= distance;
4216  ie->size= size;
4217  ie->flags = flags;
4218  return index;
4219 }
4220 
4221 /**
4222  * Rewrite timestamps of index entries in the range [end_index - frame_duration_buffer_size, end_index)
4223  * by subtracting end_ts successively by the amounts given in frame_duration_buffer.
4224  */
4225 static void fix_index_entry_timestamps(AVStream* st, int end_index, int64_t end_ts,
4226  int64_t* frame_duration_buffer,
4227  int frame_duration_buffer_size) {
4228  FFStream *const sti = ffstream(st);
4229  int i = 0;
4230  av_assert0(end_index >= 0 && end_index <= sti->nb_index_entries);
4231  for (i = 0; i < frame_duration_buffer_size; i++) {
4232  end_ts -= frame_duration_buffer[frame_duration_buffer_size - 1 - i];
4233  sti->index_entries[end_index - 1 - i].timestamp = end_ts;
4234  }
4235 }
4236 
4237 static int add_tts_entry(MOVTimeToSample **tts_data, unsigned int *tts_count, unsigned int *allocated_size,
4238  int count, int offset, unsigned int duration)
4239 {
4240  MOVTimeToSample *tts_buf_new;
4241  const size_t min_size_needed = (*tts_count + 1) * sizeof(MOVTimeToSample);
4242  const size_t requested_size =
4243  min_size_needed > *allocated_size ?
4244  FFMAX(min_size_needed, 2 * (*allocated_size)) :
4245  min_size_needed;
4246 
4247  if ((unsigned)(*tts_count) >= UINT_MAX / sizeof(MOVTimeToSample) - 1)
4248  return -1;
4249 
4250  tts_buf_new = av_fast_realloc(*tts_data, allocated_size, requested_size);
4251 
4252  if (!tts_buf_new)
4253  return -1;
4254 
4255  *tts_data = tts_buf_new;
4256 
4257  tts_buf_new[*tts_count].count = count;
4258  tts_buf_new[*tts_count].offset = offset;
4259  tts_buf_new[*tts_count].duration = duration;
4260 
4261  *tts_count = (*tts_count) + 1;
4262  return 0;
4263 }
4264 
4265 #define MAX_REORDER_DELAY 16
4267 {
4268  MOVStreamContext *msc = st->priv_data;
4269  FFStream *const sti = ffstream(st);
4270  int ctts_ind = 0;
4271  int ctts_sample = 0;
4272  int64_t pts_buf[MAX_REORDER_DELAY + 1]; // Circular buffer to sort pts.
4273  int buf_start = 0;
4274  int j, r, num_swaps;
4275 
4276  for (j = 0; j < MAX_REORDER_DELAY + 1; j++)
4277  pts_buf[j] = INT64_MIN;
4278 
4279  if (st->codecpar->video_delay <= 0 && msc->ctts_count &&
4281  st->codecpar->video_delay = 0;
4282  for (int ind = 0; ind < sti->nb_index_entries && ctts_ind < msc->tts_count; ++ind) {
4283  // Point j to the last elem of the buffer and insert the current pts there.
4284  j = buf_start;
4285  buf_start = (buf_start + 1);
4286  if (buf_start == MAX_REORDER_DELAY + 1)
4287  buf_start = 0;
4288 
4289  pts_buf[j] = sti->index_entries[ind].timestamp + msc->tts_data[ctts_ind].offset;
4290 
4291  // The timestamps that are already in the sorted buffer, and are greater than the
4292  // current pts, are exactly the timestamps that need to be buffered to output PTS
4293  // in correct sorted order.
4294  // Hence the video delay (which is the buffer size used to sort DTS and output PTS),
4295  // can be computed as the maximum no. of swaps any particular timestamp needs to
4296  // go through, to keep this buffer in sorted order.
4297  num_swaps = 0;
4298  while (j != buf_start) {
4299  r = j - 1;
4300  if (r < 0) r = MAX_REORDER_DELAY;
4301  if (pts_buf[j] < pts_buf[r]) {
4302  FFSWAP(int64_t, pts_buf[j], pts_buf[r]);
4303  ++num_swaps;
4304  } else {
4305  break;
4306  }
4307  j = r;
4308  }
4309  st->codecpar->video_delay = FFMAX(st->codecpar->video_delay, num_swaps);
4310 
4311  ctts_sample++;
4312  if (ctts_sample == msc->tts_data[ctts_ind].count) {
4313  ctts_ind++;
4314  ctts_sample = 0;
4315  }
4316  }
4317  av_log(c->fc, AV_LOG_DEBUG, "Setting codecpar->delay to %d for stream st: %d\n",
4318  st->codecpar->video_delay, st->index);
4319  }
4320 }
4321 
4323 {
4324  sc->current_sample++;
4325  sc->current_index++;
4326  if (sc->index_ranges &&
4327  sc->current_index >= sc->current_index_range->end &&
4328  sc->current_index_range->end) {
4329  sc->current_index_range++;
4331  }
4332 }
4333 
4335 {
4336  sc->current_sample--;
4337  sc->current_index--;
4338  if (sc->index_ranges &&
4340  sc->current_index_range > sc->index_ranges) {
4341  sc->current_index_range--;
4342  sc->current_index = sc->current_index_range->end - 1;
4343  }
4344 }
4345 
4346 static void mov_current_sample_set(MOVStreamContext *sc, int current_sample)
4347 {
4348  int64_t range_size;
4349 
4350  sc->current_sample = current_sample;
4351  sc->current_index = current_sample;
4352  if (!sc->index_ranges) {
4353  return;
4354  }
4355 
4356  for (sc->current_index_range = sc->index_ranges;
4357  sc->current_index_range->end;
4358  sc->current_index_range++) {
4359  range_size = sc->current_index_range->end - sc->current_index_range->start;
4360  if (range_size > current_sample) {
4361  sc->current_index = sc->current_index_range->start + current_sample;
4362  break;
4363  }
4364  current_sample -= range_size;
4365  }
4366 }
4367 
4368 /**
4369  * Fix ffstream(st)->index_entries, so that it contains only the entries (and the entries
4370  * which are needed to decode them) that fall in the edit list time ranges.
4371  * Also fixes the timestamps of the index entries to match the timeline
4372  * specified the edit lists.
4373  */
4374 static void mov_fix_index(MOVContext *mov, AVStream *st)
4375 {
4376  MOVStreamContext *msc = st->priv_data;
4377  FFStream *const sti = ffstream(st);
4378  AVIndexEntry *e_old = sti->index_entries;
4379  int nb_old = sti->nb_index_entries;
4380  const AVIndexEntry *e_old_end = e_old + nb_old;
4381  const AVIndexEntry *current = NULL;
4382  MOVTimeToSample *tts_data_old = msc->tts_data;
4383  int64_t tts_index_old = 0;
4384  int64_t tts_sample_old = 0;
4385  int64_t tts_count_old = msc->tts_count;
4386  int64_t edit_list_media_time = 0;
4387  int64_t edit_list_duration = 0;
4388  int64_t frame_duration = 0;
4389  int64_t edit_list_dts_counter = 0;
4390  int64_t edit_list_dts_entry_end = 0;
4391  int64_t edit_list_start_tts_sample = 0;
4392  int64_t curr_cts;
4393  int64_t curr_ctts = 0;
4394  int64_t empty_edits_sum_duration = 0;
4395  int64_t edit_list_index = 0;
4396  int64_t index;
4397  int flags;
4398  int64_t start_dts = 0;
4399  int64_t edit_list_start_encountered = 0;
4400  int64_t search_timestamp = 0;
4401  int64_t* frame_duration_buffer = NULL;
4402  int num_discarded_begin = 0;
4403  int first_non_zero_audio_edit = -1;
4404  int packet_skip_samples = 0;
4405  MOVIndexRange *current_index_range = NULL;
4406  int found_keyframe_after_edit = 0;
4407  int found_non_empty_edit = 0;
4408 
4409  if (!msc->elst_data || msc->elst_count <= 0 || nb_old <= 0) {
4410  return;
4411  }
4412 
4413  // allocate the index ranges array
4414  msc->index_ranges = av_malloc_array(msc->elst_count + 1,
4415  sizeof(msc->index_ranges[0]));
4416  if (!msc->index_ranges) {
4417  av_log(mov->fc, AV_LOG_ERROR, "Cannot allocate index ranges buffer\n");
4418  return;
4419  }
4420  msc->current_index_range = msc->index_ranges;
4421 
4422  // Clean AVStream from traces of old index
4423  sti->index_entries = NULL;
4425  sti->nb_index_entries = 0;
4426 
4427  // Clean time to sample fields of MOVStreamContext
4428  msc->tts_data = NULL;
4429  msc->tts_count = 0;
4430  msc->tts_index = 0;
4431  msc->tts_sample = 0;
4432  msc->tts_allocated_size = 0;
4433 
4434  // Reinitialize min_corrected_pts so that it can be computed again.
4435  msc->min_corrected_pts = -1;
4436 
4437  // If the dts_shift is positive (in case of negative ctts values in mov),
4438  // then negate the DTS by dts_shift
4439  if (msc->dts_shift > 0) {
4440  edit_list_dts_entry_end -= msc->dts_shift;
4441  av_log(mov->fc, AV_LOG_DEBUG, "Shifting DTS by %d because of negative CTTS.\n", msc->dts_shift);
4442  }
4443 
4444  start_dts = edit_list_dts_entry_end;
4445 
4446  while (get_edit_list_entry(mov, msc, edit_list_index, &edit_list_media_time,
4447  &edit_list_duration, mov->time_scale)) {
4448  av_log(mov->fc, AV_LOG_DEBUG, "Processing st: %d, edit list %"PRId64" - media time: %"PRId64", duration: %"PRId64"\n",
4449  st->index, edit_list_index, edit_list_media_time, edit_list_duration);
4450  edit_list_index++;
4451  edit_list_dts_counter = edit_list_dts_entry_end;
4452  edit_list_dts_entry_end = av_sat_add64(edit_list_dts_entry_end, edit_list_duration);
4453  if (edit_list_dts_entry_end == INT64_MAX) {
4454  av_log(mov->fc, AV_LOG_ERROR, "Cannot calculate dts entry length with duration %"PRId64"\n",
4455  edit_list_duration);
4456  break;
4457  }
4458  num_discarded_begin = 0;
4459  if (!found_non_empty_edit && edit_list_media_time == -1) {
4460  empty_edits_sum_duration += edit_list_duration;
4461  continue;
4462  }
4463  found_non_empty_edit = 1;
4464 
4465  // If we encounter a non-negative edit list reset the skip_samples/initial_padding fields and set them
4466  // according to the edit list below.
4467  if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
4468  if (first_non_zero_audio_edit < 0) {
4469  first_non_zero_audio_edit = 1;
4470  } else {
4471  first_non_zero_audio_edit = 0;
4472  }
4473 
4474  if (first_non_zero_audio_edit > 0)
4475  sti->skip_samples = st->codecpar->initial_padding = 0;
4476  }
4477 
4478  // While reordering frame index according to edit list we must handle properly
4479  // the scenario when edit list entry starts from none key frame.
4480  // We find closest previous key frame and preserve it and consequent frames in index.
4481  // All frames which are outside edit list entry time boundaries will be dropped after decoding.
4482  search_timestamp = edit_list_media_time;
4483  if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
4484  // Audio decoders like AAC need need a decoder delay samples previous to the current sample,
4485  // to correctly decode this frame. Hence for audio we seek to a frame 1 sec. before the
4486  // edit_list_media_time to cover the decoder delay.
4487  search_timestamp = FFMAX(search_timestamp - msc->time_scale, e_old[0].timestamp);
4488  }
4489 
4490  if (find_prev_closest_index(st, e_old, nb_old, tts_data_old, tts_count_old, search_timestamp, 0,
4491  &index, &tts_index_old, &tts_sample_old) < 0) {
4492  av_log(mov->fc, AV_LOG_WARNING,
4493  "st: %d edit list: %"PRId64" Missing key frame while searching for timestamp: %"PRId64"\n",
4494  st->index, edit_list_index, search_timestamp);
4495  if (find_prev_closest_index(st, e_old, nb_old, tts_data_old, tts_count_old, search_timestamp, AVSEEK_FLAG_ANY,
4496  &index, &tts_index_old, &tts_sample_old) < 0) {
4497  av_log(mov->fc, AV_LOG_WARNING,
4498  "st: %d edit list %"PRId64" Cannot find an index entry before timestamp: %"PRId64".\n",
4499  st->index, edit_list_index, search_timestamp);
4500  index = 0;
4501  tts_index_old = 0;
4502  tts_sample_old = 0;
4503  }
4504  }
4505  current = e_old + index;
4506  edit_list_start_tts_sample = tts_sample_old;
4507 
4508  // Iterate over index and arrange it according to edit list
4509  edit_list_start_encountered = 0;
4510  found_keyframe_after_edit = 0;
4511  for (; current < e_old_end; current++, index++) {
4512  // check if frame outside edit list mark it for discard
4513  frame_duration = (current + 1 < e_old_end) ?
4514  ((current + 1)->timestamp - current->timestamp) : edit_list_duration;
4515 
4516  flags = current->flags;
4517 
4518  // frames (pts) before or after edit list
4519  curr_cts = current->timestamp + msc->dts_shift;
4520  curr_ctts = 0;
4521 
4522  if (tts_data_old && tts_index_old < tts_count_old) {
4523  curr_ctts = tts_data_old[tts_index_old].offset;
4524  av_log(mov->fc, AV_LOG_TRACE, "stts: %"PRId64" ctts: %"PRId64", tts_index: %"PRId64", tts_count: %"PRId64"\n",
4525  curr_cts, curr_ctts, tts_index_old, tts_count_old);
4526  curr_cts += curr_ctts;
4527  tts_sample_old++;
4528  if (tts_sample_old == tts_data_old[tts_index_old].count) {
4529  if (add_tts_entry(&msc->tts_data, &msc->tts_count,
4530  &msc->tts_allocated_size,
4531  tts_data_old[tts_index_old].count - edit_list_start_tts_sample,
4532  tts_data_old[tts_index_old].offset, tts_data_old[tts_index_old].duration) == -1) {
4533  av_log(mov->fc, AV_LOG_ERROR, "Cannot add Time To Sample entry %"PRId64" - {%"PRId64", %d}\n",
4534  tts_index_old,
4535  tts_data_old[tts_index_old].count - edit_list_start_tts_sample,
4536  tts_data_old[tts_index_old].offset);
4537  break;
4538  }
4539  tts_index_old++;
4540  tts_sample_old = 0;
4541  edit_list_start_tts_sample = 0;
4542  }
4543  }
4544 
4545  if (curr_cts < edit_list_media_time || curr_cts >= (edit_list_duration + edit_list_media_time)) {
4547  curr_cts < edit_list_media_time && curr_cts + frame_duration > edit_list_media_time &&
4548  first_non_zero_audio_edit > 0) {
4549  packet_skip_samples = edit_list_media_time - curr_cts;
4550  sti->skip_samples += packet_skip_samples;
4551 
4552  // Shift the index entry timestamp by packet_skip_samples to be correct.
4553  edit_list_dts_counter -= packet_skip_samples;
4554  if (edit_list_start_encountered == 0) {
4555  edit_list_start_encountered = 1;
4556  // Make timestamps strictly monotonically increasing for audio, by rewriting timestamps for
4557  // discarded packets.
4558  if (frame_duration_buffer) {
4559  fix_index_entry_timestamps(st, sti->nb_index_entries, edit_list_dts_counter,
4560  frame_duration_buffer, num_discarded_begin);
4561  av_freep(&frame_duration_buffer);
4562  }
4563  }
4564 
4565  av_log(mov->fc, AV_LOG_DEBUG, "skip %d audio samples from curr_cts: %"PRId64"\n", packet_skip_samples, curr_cts);
4566  } else {
4568  av_log(mov->fc, AV_LOG_DEBUG, "drop a frame at curr_cts: %"PRId64" @ %"PRId64"\n", curr_cts, index);
4569 
4570  if (edit_list_start_encountered == 0) {
4571  num_discarded_begin++;
4572  frame_duration_buffer = av_realloc(frame_duration_buffer,
4573  num_discarded_begin * sizeof(int64_t));
4574  if (!frame_duration_buffer) {
4575  av_log(mov->fc, AV_LOG_ERROR, "Cannot reallocate frame duration buffer\n");
4576  break;
4577  }
4578  frame_duration_buffer[num_discarded_begin - 1] = frame_duration;
4579 
4580  // Increment skip_samples for the first non-zero audio edit list
4581  if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
4582  first_non_zero_audio_edit > 0 && st->codecpar->codec_id != AV_CODEC_ID_VORBIS) {
4583  sti->skip_samples += frame_duration;
4584  }
4585  }
4586  }
4587  } else {
4588  if (msc->min_corrected_pts < 0) {
4589  msc->min_corrected_pts = edit_list_dts_counter + curr_ctts + msc->dts_shift;
4590  } else {
4591  msc->min_corrected_pts = FFMIN(msc->min_corrected_pts, edit_list_dts_counter + curr_ctts + msc->dts_shift);
4592  }
4593  if (edit_list_start_encountered == 0) {
4594  edit_list_start_encountered = 1;
4595  // Make timestamps strictly monotonically increasing by rewriting timestamps for
4596  // discarded packets.
4597  if (frame_duration_buffer) {
4598  fix_index_entry_timestamps(st, sti->nb_index_entries, edit_list_dts_counter,
4599  frame_duration_buffer, num_discarded_begin);
4600  av_freep(&frame_duration_buffer);
4601  }
4602  }
4603  }
4604 
4605  if (add_index_entry(st, current->pos, edit_list_dts_counter, current->size,
4606  current->min_distance, flags) == -1) {
4607  av_log(mov->fc, AV_LOG_ERROR, "Cannot add index entry\n");
4608  break;
4609  }
4610 
4611  // Update the index ranges array
4612  if (!current_index_range || index != current_index_range->end) {
4613  current_index_range = current_index_range ? current_index_range + 1
4614  : msc->index_ranges;
4615  current_index_range->start = index;
4616  }
4617  current_index_range->end = index + 1;
4618 
4619  // Only start incrementing DTS in frame_duration amounts, when we encounter a frame in edit list.
4620  if (edit_list_start_encountered > 0) {
4621  edit_list_dts_counter = edit_list_dts_counter + frame_duration;
4622  }
4623 
4624  // Break when found first key frame after edit entry completion
4625  if ((curr_cts + frame_duration >= (edit_list_duration + edit_list_media_time)) &&
4627  if (msc->ctts_count) {
4628  // If we have CTTS and this is the first keyframe after edit elist,
4629  // wait for one more, because there might be trailing B-frames after this I-frame
4630  // that do belong to the edit.
4631  if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO && found_keyframe_after_edit == 0) {
4632  found_keyframe_after_edit = 1;
4633  continue;
4634  }
4635  if (tts_sample_old != 0) {
4636  if (add_tts_entry(&msc->tts_data, &msc->tts_count,
4637  &msc->tts_allocated_size,
4638  tts_sample_old - edit_list_start_tts_sample,
4639  tts_data_old[tts_index_old].offset, tts_data_old[tts_index_old].duration) == -1) {
4640  av_log(mov->fc, AV_LOG_ERROR, "Cannot add Time To Sample entry %"PRId64" - {%"PRId64", %d}\n",
4641  tts_index_old, tts_sample_old - edit_list_start_tts_sample,
4642  tts_data_old[tts_index_old].offset);
4643  break;
4644  }
4645  }
4646  }
4647  break;
4648  }
4649  }
4650  }
4651  // If there are empty edits, then msc->min_corrected_pts might be positive
4652  // intentionally. So we subtract the sum duration of empty edits here.
4653  msc->min_corrected_pts -= empty_edits_sum_duration;
4654 
4655  // If the minimum pts turns out to be greater than zero after fixing the index, then we subtract the
4656  // dts by that amount to make the first pts zero.
4657  if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
4658  if (msc->min_corrected_pts > 0) {
4659  av_log(mov->fc, AV_LOG_DEBUG, "Offset DTS by %"PRId64" to make first pts zero.\n", msc->min_corrected_pts);
4660  for (int i = 0; i < sti->nb_index_entries; ++i)
4662  }
4663  }
4664  // Start time should be equal to zero or the duration of any empty edits.
4665  st->start_time = empty_edits_sum_duration;
4666 
4667  // Update av stream length, if it ends up shorter than the track's media duration
4668  st->duration = FFMIN(st->duration, edit_list_dts_entry_end - start_dts);
4670 
4671  // Free the old index and the old CTTS structures
4672  av_free(e_old);
4673  av_free(tts_data_old);
4674  av_freep(&frame_duration_buffer);
4675 
4676  // Null terminate the index ranges array
4677  current_index_range = current_index_range ? current_index_range + 1
4678  : msc->index_ranges;
4679  current_index_range->start = 0;
4680  current_index_range->end = 0;
4681  msc->current_index = msc->index_ranges[0].start;
4682 }
4683 
4684 static uint32_t get_sgpd_sync_index(const MOVStreamContext *sc, int nal_unit_type)
4685 {
4686  for (uint32_t i = 0; i < sc->sgpd_sync_count; i++)
4687  if (sc->sgpd_sync[i] == nal_unit_type)
4688  return i + 1;
4689  return 0;
4690 }
4691 
4693 {
4694  int k;
4695  int sample_id = 0;
4696  uint32_t cra_index;
4697  MOVStreamContext *sc = st->priv_data;
4698 
4699  if (st->codecpar->codec_id != AV_CODEC_ID_HEVC || !sc->sync_group_count)
4700  return 0;
4701 
4702  /* Build an unrolled index of the samples */
4703  sc->sample_offsets_count = 0;
4704  for (uint32_t i = 0; i < sc->ctts_count; i++) {
4705  if (sc->ctts_data[i].count > INT_MAX - sc->sample_offsets_count)
4706  return AVERROR(ENOMEM);
4707  sc->sample_offsets_count += sc->ctts_data[i].count;
4708  }
4709  av_freep(&sc->sample_offsets);
4711  if (!sc->sample_offsets)
4712  return AVERROR(ENOMEM);
4713  k = 0;
4714  for (uint32_t i = 0; i < sc->ctts_count; i++)
4715  for (int j = 0; j < sc->ctts_data[i].count; j++)
4716  sc->sample_offsets[k++] = sc->ctts_data[i].offset;
4717 
4718  /* The following HEVC NAL type reveal the use of open GOP sync points
4719  * (TODO: BLA types may also be concerned) */
4720  cra_index = get_sgpd_sync_index(sc, HEVC_NAL_CRA_NUT); /* Clean Random Access */
4721  if (!cra_index)
4722  return 0;
4723 
4724  /* Build a list of open-GOP key samples */
4725  sc->open_key_samples_count = 0;
4726  for (uint32_t i = 0; i < sc->sync_group_count; i++)
4727  if (sc->sync_group[i].index == cra_index) {
4728  if (sc->sync_group[i].count > INT_MAX - sc->open_key_samples_count)
4729  return AVERROR(ENOMEM);
4731  }
4732  av_freep(&sc->open_key_samples);
4734  if (!sc->open_key_samples)
4735  return AVERROR(ENOMEM);
4736  k = 0;
4737  for (uint32_t i = 0; i < sc->sync_group_count; i++) {
4738  const MOVSbgp *sg = &sc->sync_group[i];
4739  if (sg->index == cra_index)
4740  for (uint32_t j = 0; j < sg->count; j++)
4741  sc->open_key_samples[k++] = sample_id;
4742  if (sg->count > INT_MAX - sample_id)
4743  return AVERROR_PATCHWELCOME;
4744  sample_id += sg->count;
4745  }
4746 
4747  /* Identify the minimal time step between samples */
4748  sc->min_sample_duration = UINT_MAX;
4749  for (uint32_t i = 0; i < sc->stts_count; i++)
4751 
4752  return 0;
4753 }
4754 
4755 #define MOV_MERGE_CTTS 1
4756 #define MOV_MERGE_STTS 2
4757 /*
4758  * Merge stts and ctts arrays into a new combined array.
4759  * stts_count and ctts_count may be left untouched as they will be
4760  * used to check for the presence of either of them.
4761  */
4762 static int mov_merge_tts_data(MOVContext *mov, AVStream *st, int flags)
4763 {
4764  MOVStreamContext *sc = st->priv_data;
4765  int ctts = sc->ctts_data && (flags & MOV_MERGE_CTTS);
4766  int stts = sc->stts_data && (flags & MOV_MERGE_STTS);
4767  int idx = 0;
4768 
4769  if (!sc->ctts_data && !sc->stts_data)
4770  return 0;
4771  // Expand time to sample entries such that we have a 1-1 mapping with samples
4772  if (!sc->sample_count || sc->sample_count >= UINT_MAX / sizeof(*sc->tts_data))
4773  return -1;
4774 
4775  if (ctts) {
4777  sc->sample_count * sizeof(*sc->tts_data));
4778  if (!sc->tts_data)
4779  return -1;
4780 
4781  memset(sc->tts_data, 0, sc->tts_allocated_size);
4782 
4783  for (int i = 0; i < sc->ctts_count &&
4784  idx < sc->sample_count; i++)
4785  for (int j = 0; j < sc->ctts_data[i].count &&
4786  idx < sc->sample_count; j++) {
4787  sc->tts_data[idx].offset = sc->ctts_data[i].offset;
4788  sc->tts_data[idx++].count = 1;
4789  }
4790 
4791  sc->tts_count = idx;
4792  } else
4793  sc->ctts_count = 0;
4794  av_freep(&sc->ctts_data);
4795  sc->ctts_allocated_size = 0;
4796 
4797  idx = 0;
4798  if (stts) {
4800  sc->sample_count * sizeof(*sc->tts_data));
4801  if (!tts_data)
4802  return -1;
4803 
4804  if (!sc->tts_data)
4805  memset(tts_data, 0, sc->tts_allocated_size);
4806  sc->tts_data = tts_data;
4807 
4808  for (int i = 0; i < sc->stts_count &&
4809  idx < sc->sample_count; i++)
4810  for (int j = 0; j < sc->stts_data[i].count &&
4811  idx < sc->sample_count; j++) {
4812  sc->tts_data[idx].duration = sc->stts_data[i].duration;
4813  sc->tts_data[idx++].count = 1;
4814  }
4815 
4816  sc->tts_count = FFMAX(sc->tts_count, idx);
4817  } else
4818  sc->stts_count = 0;
4819  av_freep(&sc->stts_data);
4820  sc->stts_allocated_size = 0;
4821 
4822  return 0;
4823 }
4824 
4825 static void mov_build_index(MOVContext *mov, AVStream *st)
4826 {
4827  MOVStreamContext *sc = st->priv_data;
4828  FFStream *const sti = ffstream(st);
4829  int64_t current_offset;
4830  int64_t current_dts = 0;
4831  unsigned int stts_index = 0;
4832  unsigned int stsc_index = 0;
4833  unsigned int stss_index = 0;
4834  unsigned int stps_index = 0;
4835  unsigned int i, j;
4836  uint64_t stream_size = 0;
4837 
4838  int ret = build_open_gop_key_points(st);
4839  if (ret < 0)
4840  return;
4841 
4842  if (sc->elst_count) {
4843  int i, edit_start_index = 0, multiple_edits = 0;
4844  int64_t empty_duration = 0; // empty duration of the first edit list entry
4845  int64_t start_time = 0; // start time of the media
4846 
4847  for (i = 0; i < sc->elst_count; i++) {
4848  const MOVElst *e = &sc->elst_data[i];
4849  if (i == 0 && e->time == -1) {
4850  /* if empty, the first entry is the start time of the stream
4851  * relative to the presentation itself */
4852  empty_duration = e->duration;
4853  edit_start_index = 1;
4854  } else if (i == edit_start_index && e->time >= 0) {
4855  start_time = e->time;
4856  } else {
4857  multiple_edits = 1;
4858  }
4859  }
4860 
4861  if (multiple_edits && !mov->advanced_editlist) {
4863  av_log(mov->fc, AV_LOG_WARNING, "multiple edit list entries, "
4864  "not supported in fragmented MP4 files\n");
4865  else
4866  av_log(mov->fc, AV_LOG_WARNING, "multiple edit list entries, "
4867  "Use -advanced_editlist to correctly decode otherwise "
4868  "a/v desync might occur\n");
4869  }
4870 
4871  /* adjust first dts according to edit list */
4872  if ((empty_duration || start_time) && mov->time_scale > 0) {
4873  if (empty_duration)
4874  empty_duration = av_rescale(empty_duration, sc->time_scale, mov->time_scale);
4875 
4876  if (av_sat_sub64(start_time, empty_duration) != start_time - (uint64_t)empty_duration)
4877  av_log(mov->fc, AV_LOG_WARNING, "start_time - empty_duration is not representable\n");
4878 
4879  sc->time_offset = start_time - (uint64_t)empty_duration;
4881  if (!mov->advanced_editlist)
4882  current_dts = -av_clip64(sc->time_offset, -INT64_MAX, INT64_MAX);
4883  }
4884 
4885  if (!multiple_edits && !mov->advanced_editlist &&
4888  (AVRational){1, st->codecpar->sample_rate});
4889  }
4890 
4891  /* only use old uncompressed audio chunk demuxing when stts specifies it */
4892  if (!(st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
4893  sc->stts_count == 1 && sc->stts_data && sc->stts_data[0].duration == 1)) {
4894  unsigned int current_sample = 0;
4895  unsigned int stts_sample = 0;
4896  unsigned int sample_size;
4897  unsigned int distance = 0;
4898  unsigned int rap_group_index = 0;
4899  unsigned int rap_group_sample = 0;
4900  int rap_group_present = sc->rap_group_count && sc->rap_group;
4901  int key_off = (sc->keyframe_count && sc->keyframes[0] > 0) || (sc->stps_count && sc->stps_data[0] > 0);
4902 
4903  av_assert0(sc->dts_shift >= 0);
4904  if (current_dts < INT64_MIN + sc->dts_shift)
4905  return;
4906  current_dts -= sc->dts_shift;
4907  if (!sc->sample_count || sti->nb_index_entries || sc->tts_count)
4908  return;
4909  if (sc->sample_count >= UINT_MAX / sizeof(*sti->index_entries) - sti->nb_index_entries)
4910  return;
4911  if (av_reallocp_array(&sti->index_entries,
4912  sti->nb_index_entries + sc->sample_count,
4913  sizeof(*sti->index_entries)) < 0) {
4914  sti->nb_index_entries = 0;
4915  return;
4916  }
4917  sti->index_entries_allocated_size = (sti->nb_index_entries + sc->sample_count) * sizeof(*sti->index_entries);
4918 
4920  if (ret < 0)
4921  return;
4922 
4923  for (i = 0; i < sc->chunk_count; i++) {
4924  int64_t next_offset = i+1 < sc->chunk_count ? sc->chunk_offsets[i+1] : INT64_MAX;
4925  current_offset = sc->chunk_offsets[i];
4926  while (mov_stsc_index_valid(stsc_index, sc->stsc_count) &&
4927  i + 1 == sc->stsc_data[stsc_index + 1].first)
4928  stsc_index++;
4929 
4930  if (next_offset > current_offset && sc->sample_size>0 && sc->sample_size < sc->stsz_sample_size &&
4931  sc->stsc_data[stsc_index].count * (int64_t)sc->stsz_sample_size > next_offset - current_offset) {
4932  av_log(mov->fc, AV_LOG_WARNING, "STSZ sample size %d invalid (too large), ignoring\n", sc->stsz_sample_size);
4933  sc->stsz_sample_size = sc->sample_size;
4934  }
4935  if (sc->stsz_sample_size>0 && sc->stsz_sample_size < sc->sample_size) {
4936  av_log(mov->fc, AV_LOG_WARNING, "STSZ sample size %d invalid (too small), ignoring\n", sc->stsz_sample_size);
4937  sc->stsz_sample_size = sc->sample_size;
4938  }
4939 
4940  for (j = 0; j < sc->stsc_data[stsc_index].count; j++) {
4941  int keyframe = 0;
4942  if (current_sample >= sc->sample_count) {
4943  av_log(mov->fc, AV_LOG_ERROR, "wrong sample count\n");
4944  return;
4945  }
4946 
4947  if (!sc->keyframe_absent && (!sc->keyframe_count || current_sample+key_off == sc->keyframes[stss_index])) {
4948  keyframe = 1;
4949  if (stss_index + 1 < sc->keyframe_count)
4950  stss_index++;
4951  } else if (sc->stps_count && current_sample+key_off == sc->stps_data[stps_index]) {
4952  keyframe = 1;
4953  if (stps_index + 1 < sc->stps_count)
4954  stps_index++;
4955  }
4956  if (rap_group_present && rap_group_index < sc->rap_group_count) {
4957  if (sc->rap_group[rap_group_index].index > 0)
4958  keyframe = 1;
4959  if (++rap_group_sample == sc->rap_group[rap_group_index].count) {
4960  rap_group_sample = 0;
4961  rap_group_index++;
4962  }
4963  }
4964  if (sc->keyframe_absent
4965  && !sc->stps_count
4966  && !rap_group_present
4967  && (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO || (i==0 && j==0)))
4968  keyframe = 1;
4969  if (keyframe)
4970  distance = 0;
4971  sample_size = sc->stsz_sample_size > 0 ? sc->stsz_sample_size : sc->sample_sizes[current_sample];
4972  if (current_offset > INT64_MAX - sample_size) {
4973  av_log(mov->fc, AV_LOG_ERROR, "Current offset %"PRId64" or sample size %u is too large\n",
4974  current_offset,
4975  sample_size);
4976  return;
4977  }
4978 
4979  if (sc->pseudo_stream_id == -1 ||
4980  sc->stsc_data[stsc_index].id - 1 == sc->pseudo_stream_id) {
4981  AVIndexEntry *e;
4982  if (sample_size > 0x3FFFFFFF) {
4983  av_log(mov->fc, AV_LOG_ERROR, "Sample size %u is too large\n", sample_size);
4984  return;
4985  }
4986  e = &sti->index_entries[sti->nb_index_entries++];
4987  e->pos = current_offset;
4988  e->timestamp = current_dts;
4989  e->size = sample_size;
4990  e->min_distance = distance;
4991  e->flags = keyframe ? AVINDEX_KEYFRAME : 0;
4992  av_log(mov->fc, AV_LOG_TRACE, "AVIndex stream %d, sample %u, offset %"PRIx64", dts %"PRId64", "
4993  "size %u, distance %u, keyframe %d\n", st->index, current_sample,
4994  current_offset, current_dts, sample_size, distance, keyframe);
4995  if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && sti->nb_index_entries < 100)
4996  ff_rfps_add_frame(mov->fc, st, current_dts);
4997  }
4998 
4999  current_offset += sample_size;
5000  stream_size += sample_size;
5001 
5002  if (current_dts > INT64_MAX - sc->tts_data[stts_index].duration)
5003  return;
5004  current_dts += sc->tts_data[stts_index].duration;
5005 
5006  distance++;
5007  stts_sample++;
5008  current_sample++;
5009  if (stts_index + 1 < sc->tts_count && stts_sample == sc->tts_data[stts_index].count) {
5010  stts_sample = 0;
5011  stts_index++;
5012  }
5013  }
5014  }
5015  if (st->duration > 0)
5016  st->codecpar->bit_rate = stream_size*8*sc->time_scale/st->duration;
5017  } else {
5018  unsigned chunk_samples, total = 0;
5019 
5020  if (!sc->chunk_count || sc->tts_count)
5021  return;
5022 
5023  // compute total chunk count
5024  for (i = 0; i < sc->stsc_count; i++) {
5025  unsigned count, chunk_count;
5026 
5027  chunk_samples = sc->stsc_data[i].count;
5028  if (i != sc->stsc_count - 1 &&
5029  sc->samples_per_frame && chunk_samples % sc->samples_per_frame) {
5030  av_log(mov->fc, AV_LOG_ERROR, "error unaligned chunk\n");
5031  return;
5032  }
5033 
5034  if (sc->samples_per_frame >= 160) { // gsm
5035  count = chunk_samples / sc->samples_per_frame;
5036  } else if (sc->samples_per_frame > 1) {
5037  unsigned samples = (1024/sc->samples_per_frame)*sc->samples_per_frame;
5038  count = (chunk_samples+samples-1) / samples;
5039  } else {
5040  count = (chunk_samples+1023) / 1024;
5041  }
5042 
5043  if (mov_stsc_index_valid(i, sc->stsc_count))
5044  chunk_count = sc->stsc_data[i+1].first - sc->stsc_data[i].first;
5045  else
5046  chunk_count = sc->chunk_count - (sc->stsc_data[i].first - 1);
5047  total += chunk_count * count;
5048  }
5049 
5050  av_log(mov->fc, AV_LOG_TRACE, "chunk count %u\n", total);
5051  if (total >= UINT_MAX / sizeof(*sti->index_entries) - sti->nb_index_entries)
5052  return;
5053  if (av_reallocp_array(&sti->index_entries,
5054  sti->nb_index_entries + total,
5055  sizeof(*sti->index_entries)) < 0) {
5056  sti->nb_index_entries = 0;
5057  return;
5058  }
5059  sti->index_entries_allocated_size = (sti->nb_index_entries + total) * sizeof(*sti->index_entries);
5060 
5061  // populate index
5062  for (i = 0; i < sc->chunk_count; i++) {
5063  current_offset = sc->chunk_offsets[i];
5064  if (mov_stsc_index_valid(stsc_index, sc->stsc_count) &&
5065  i + 1 == sc->stsc_data[stsc_index + 1].first)
5066  stsc_index++;
5067  chunk_samples = sc->stsc_data[stsc_index].count;
5068 
5069  while (chunk_samples > 0) {
5070  AVIndexEntry *e;
5071  unsigned size, samples;
5072 
5073  if (sc->samples_per_frame > 1 && !sc->bytes_per_frame) {
5075  "Zero bytes per frame, but %d samples per frame",
5076  sc->samples_per_frame);
5077  return;
5078  }
5079 
5080  if (sc->samples_per_frame >= 160) { // gsm
5081  samples = sc->samples_per_frame;
5082  size = sc->bytes_per_frame;
5083  } else {
5084  if (sc->samples_per_frame > 1) {
5085  samples = FFMIN((1024 / sc->samples_per_frame)*
5086  sc->samples_per_frame, chunk_samples);
5088  } else {
5089  samples = FFMIN(1024, chunk_samples);
5090  size = samples * sc->sample_size;
5091  }
5092  }
5093 
5094  if (sti->nb_index_entries >= total) {
5095  av_log(mov->fc, AV_LOG_ERROR, "wrong chunk count %u\n", total);
5096  return;
5097  }
5098  if (size > 0x3FFFFFFF) {
5099  av_log(mov->fc, AV_LOG_ERROR, "Sample size %u is too large\n", size);
5100  return;
5101  }
5102  e = &sti->index_entries[sti->nb_index_entries++];
5103  e->pos = current_offset;
5104  e->timestamp = current_dts;
5105  e->size = size;
5106  e->min_distance = 0;
5107  e->flags = AVINDEX_KEYFRAME;
5108  av_log(mov->fc, AV_LOG_TRACE, "AVIndex stream %d, chunk %u, offset %"PRIx64", dts %"PRId64", "
5109  "size %u, duration %u\n", st->index, i, current_offset, current_dts,
5110  size, samples);
5111 
5112  current_offset += size;
5113  if (current_dts > INT64_MAX - samples)
5114  return;
5115  current_dts += samples;
5116  chunk_samples -= samples;
5117  }
5118  }
5119 
5121  if (ret < 0)
5122  return;
5123  }
5124 
5125  if (!mov->ignore_editlist && mov->advanced_editlist) {
5126  // Fix index according to edit lists.
5127  mov_fix_index(mov, st);
5128  }
5129 
5130  // Update start time of the stream.
5133  if (sc->tts_data) {
5134  st->start_time = av_sat_add64(st->start_time, sc->tts_data[0].offset);
5135  }
5136  }
5137 
5138  mov_estimate_video_delay(mov, st);
5139 }
5140 
5141 static int test_same_origin(const char *src, const char *ref) {
5142  char src_proto[64];
5143  char ref_proto[64];
5144  char src_auth[256];
5145  char ref_auth[256];
5146  char src_host[256];
5147  char ref_host[256];
5148  int src_port=-1;
5149  int ref_port=-1;
5150 
5151  av_url_split(src_proto, sizeof(src_proto), src_auth, sizeof(src_auth), src_host, sizeof(src_host), &src_port, NULL, 0, src);
5152  av_url_split(ref_proto, sizeof(ref_proto), ref_auth, sizeof(ref_auth), ref_host, sizeof(ref_host), &ref_port, NULL, 0, ref);
5153 
5154  if (strlen(src) == 0) {
5155  return -1;
5156  } else if (strlen(src_auth) + 1 >= sizeof(src_auth) ||
5157  strlen(ref_auth) + 1 >= sizeof(ref_auth) ||
5158  strlen(src_host) + 1 >= sizeof(src_host) ||
5159  strlen(ref_host) + 1 >= sizeof(ref_host)) {
5160  return 0;
5161  } else if (strcmp(src_proto, ref_proto) ||
5162  strcmp(src_auth, ref_auth) ||
5163  strcmp(src_host, ref_host) ||
5164  src_port != ref_port) {
5165  return 0;
5166  } else
5167  return 1;
5168 }
5169 
5170 static int mov_open_dref(MOVContext *c, AVIOContext **pb, const char *src, MOVDref *ref)
5171 {
5172  /* try relative path, we do not try the absolute because it can leak information about our
5173  system to an attacker */
5174  if (ref->nlvl_to > 0 && ref->nlvl_from > 0) {
5175  char filename[1025];
5176  const char *src_path;
5177  int i, l;
5178 
5179  /* find a source dir */
5180  src_path = strrchr(src, '/');
5181  if (src_path)
5182  src_path++;
5183  else
5184  src_path = src;
5185 
5186  /* find a next level down to target */
5187  for (i = 0, l = strlen(ref->path) - 1; l >= 0; l--)
5188  if (ref->path[l] == '/') {
5189  if (i == ref->nlvl_to - 1)
5190  break;
5191  else
5192  i++;
5193  }
5194 
5195  /* compose filename if next level down to target was found */
5196  if (i == ref->nlvl_to - 1 && src_path - src < sizeof(filename)) {
5197  memcpy(filename, src, src_path - src);
5198  filename[src_path - src] = 0;
5199 
5200  for (i = 1; i < ref->nlvl_from; i++)
5201  av_strlcat(filename, "../", sizeof(filename));
5202 
5203  av_strlcat(filename, ref->path + l + 1, sizeof(filename));
5204  if (!c->use_absolute_path) {
5205  int same_origin = test_same_origin(src, filename);
5206 
5207  if (!same_origin) {
5208  av_log(c->fc, AV_LOG_ERROR,
5209  "Reference with mismatching origin, %s not tried for security reasons, "
5210  "set demuxer option use_absolute_path to allow it anyway\n",
5211  ref->path);
5212  return AVERROR(ENOENT);
5213  }
5214 
5215  if (strstr(ref->path + l + 1, "..") ||
5216  strstr(ref->path + l + 1, ":") ||
5217  (ref->nlvl_from > 1 && same_origin < 0) ||
5218  (filename[0] == '/' && src_path == src))
5219  return AVERROR(ENOENT);
5220  }
5221 
5222  if (strlen(filename) + 1 == sizeof(filename))
5223  return AVERROR(ENOENT);
5224  if (!c->fc->io_open(c->fc, pb, filename, AVIO_FLAG_READ, NULL))
5225  return 0;
5226  }
5227  } else if (c->use_absolute_path) {
5228  av_log(c->fc, AV_LOG_WARNING, "Using absolute path on user request, "
5229  "this is a possible security issue\n");
5230  if (!c->fc->io_open(c->fc, pb, ref->path, AVIO_FLAG_READ, NULL))
5231  return 0;
5232  } else {
5233  av_log(c->fc, AV_LOG_ERROR,
5234  "Absolute path %s not tried for security reasons, "
5235  "set demuxer option use_absolute_path to allow absolute paths\n",
5236  ref->path);
5237  }
5238 
5239  return AVERROR(ENOENT);
5240 }
5241 
5243 {
5244  if (sc->time_scale <= 0) {
5245  av_log(c->fc, AV_LOG_WARNING, "stream %d, timescale not set\n", sc->ffindex);
5246  sc->time_scale = c->time_scale;
5247  if (sc->time_scale <= 0)
5248  sc->time_scale = 1;
5249  }
5250 }
5251 
5252 #if CONFIG_IAMFDEC
5253 static int mov_update_iamf_streams(MOVContext *c, const AVStream *st)
5254 {
5255  const MOVStreamContext *sc = st->priv_data;
5256  const IAMFContext *iamf = &sc->iamf->iamf;
5257 
5258  for (int i = 0; i < iamf->nb_audio_elements; i++) {
5259  const AVStreamGroup *stg = NULL;
5260 
5261  for (int j = 0; j < c->fc->nb_stream_groups; j++)
5262  if (c->fc->stream_groups[j]->id == iamf->audio_elements[i]->audio_element_id)
5263  stg = c->fc->stream_groups[j];
5264  av_assert0(stg);
5265 
5266  for (int j = 0; j < stg->nb_streams; j++) {
5267  const FFStream *sti = cffstream(st);
5268  AVStream *out = stg->streams[j];
5269  FFStream *out_sti = ffstream(stg->streams[j]);
5270 
5271  out->codecpar->bit_rate = 0;
5272 
5273  if (out == st)
5274  continue;
5275 
5276  out->time_base = st->time_base;
5277  out->start_time = st->start_time;
5278  out->duration = st->duration;
5279  out->nb_frames = st->nb_frames;
5280  out->discard = st->discard;
5281 
5282  av_assert0(!out_sti->index_entries);
5284  if (!out_sti->index_entries)
5285  return AVERROR(ENOMEM);
5286 
5288  out_sti->nb_index_entries = sti->nb_index_entries;
5289  out_sti->skip_samples = sti->skip_samples;
5290  memcpy(out_sti->index_entries, sti->index_entries, sti->index_entries_allocated_size);
5291  }
5292  }
5293 
5294  return 0;
5295 }
5296 #endif
5297 
5298 static int sanity_checks(void *log_obj, MOVStreamContext *sc, int index)
5299 {
5300  if ((sc->chunk_count && (!sc->stts_count || !sc->stsc_count ||
5301  (!sc->sample_size && !sc->sample_count))) ||
5302  (sc->sample_count && (!sc->chunk_count ||
5303  (!sc->sample_size && !sc->sample_sizes)))) {
5304  av_log(log_obj, AV_LOG_ERROR, "stream %d, missing mandatory atoms, broken header\n",
5305  index);
5306  return 1;
5307  }
5308 
5309  if (sc->stsc_count && sc->stsc_data[ sc->stsc_count - 1 ].first > sc->chunk_count) {
5310  av_log(log_obj, AV_LOG_ERROR, "stream %d, contradictionary STSC and STCO\n",
5311  index);
5312  return 2;
5313  }
5314  return 0;
5315 }
5316 
5318 {
5319  AVStream *st;
5320  MOVStreamContext *sc;
5321  int ret;
5322 
5323  st = avformat_new_stream(c->fc, NULL);
5324  if (!st) return AVERROR(ENOMEM);
5325  st->id = -1;
5326  sc = av_mallocz(sizeof(MOVStreamContext));
5327  if (!sc) return AVERROR(ENOMEM);
5328 
5329  st->priv_data = sc;
5331  sc->ffindex = st->index;
5332  c->trak_index = st->index;
5333  sc->refcount = 1;
5334 
5335  if ((ret = mov_read_default(c, pb, atom)) < 0)
5336  return ret;
5337 
5338  c->trak_index = -1;
5339 
5340  // Here stsc refers to a chunk not described in stco. This is technically invalid,
5341  // but we can overlook it (clearing stsc) whenever stts_count == 0 (indicating no samples).
5342  if (!sc->chunk_count && !sc->stts_count && sc->stsc_count) {
5343  sc->stsc_count = 0;
5344  av_freep(&sc->stsc_data);
5345  }
5346 
5347  ret = sanity_checks(c->fc, sc, st->index);
5348  if (ret)
5349  return ret > 1 ? AVERROR_INVALIDDATA : 0;
5350 
5351  fix_timescale(c, sc);
5352 
5353  avpriv_set_pts_info(st, 64, 1, sc->time_scale);
5354 
5355  /*
5356  * Advanced edit list support does not work with fragemented MP4s, which
5357  * have stsc, stsz, stco, and stts with zero entries in the moov atom.
5358  * In these files, trun atoms may be streamed in.
5359  */
5360  if (!sc->stts_count && c->advanced_editlist) {
5361 
5362  av_log(c->fc, AV_LOG_VERBOSE, "advanced_editlist does not work with fragmented "
5363  "MP4. disabling.\n");
5364  c->advanced_editlist = 0;
5365  c->advanced_editlist_autodisabled = 1;
5366  }
5367 
5368  mov_build_index(c, st);
5369 
5370 #if CONFIG_IAMFDEC
5371  if (sc->iamf) {
5372  ret = mov_update_iamf_streams(c, st);
5373  if (ret < 0)
5374  return ret;
5375  }
5376 #endif
5377 
5378  if (sc->dref_id-1 < sc->drefs_count && sc->drefs[sc->dref_id-1].path) {
5379  MOVDref *dref = &sc->drefs[sc->dref_id - 1];
5380  if (c->enable_drefs) {
5381  if (mov_open_dref(c, &sc->pb, c->fc->url, dref) < 0)
5382  av_log(c->fc, AV_LOG_ERROR,
5383  "stream %d, error opening alias: path='%s', dir='%s', "
5384  "filename='%s', volume='%s', nlvl_from=%d, nlvl_to=%d\n",
5385  st->index, dref->path, dref->dir, dref->filename,
5386  dref->volume, dref->nlvl_from, dref->nlvl_to);
5387  } else {
5388  av_log(c->fc, AV_LOG_WARNING,
5389  "Skipped opening external track: "
5390  "stream %d, alias: path='%s', dir='%s', "
5391  "filename='%s', volume='%s', nlvl_from=%d, nlvl_to=%d."
5392  "Set enable_drefs to allow this.\n",
5393  st->index, dref->path, dref->dir, dref->filename,
5394  dref->volume, dref->nlvl_from, dref->nlvl_to);
5395  }
5396  } else {
5397  sc->pb = c->fc->pb;
5398  sc->pb_is_copied = 1;
5399  }
5400 
5401  if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
5402  int stts_constant = sc->stts_count && sc->tts_count;
5403  if (sc->h_spacing && sc->v_spacing)
5405  sc->h_spacing, sc->v_spacing, INT_MAX);
5406  if (!st->sample_aspect_ratio.num && st->codecpar->width && st->codecpar->height &&
5407  sc->height && sc->width &&
5408  (st->codecpar->width != sc->width || st->codecpar->height != sc->height)) {
5410  (int64_t)st->codecpar->height * sc->width,
5411  (int64_t)st->codecpar->width * sc->height, INT_MAX);
5412  }
5413 
5414 #if FF_API_R_FRAME_RATE
5415  for (unsigned int i = 1; sc->stts_count && i + 1 < sc->tts_count; i++) {
5416  if (sc->tts_data[i].duration == sc->tts_data[0].duration)
5417  continue;
5418  stts_constant = 0;
5419  }
5420  if (stts_constant)
5422  sc->time_scale, sc->tts_data[0].duration, INT_MAX);
5423 #endif
5424  }
5425 
5426 #if CONFIG_H261_DECODER || CONFIG_H263_DECODER || CONFIG_MPEG4_DECODER
5427  switch (st->codecpar->codec_id) {
5428 #if CONFIG_H261_DECODER
5429  case AV_CODEC_ID_H261:
5430 #endif
5431 #if CONFIG_H263_DECODER
5432  case AV_CODEC_ID_H263:
5433 #endif
5434 #if CONFIG_MPEG4_DECODER
5435  case AV_CODEC_ID_MPEG4:
5436 #endif
5437  st->codecpar->width = 0; /* let decoder init width/height */
5438  st->codecpar->height= 0;
5439  break;
5440  }
5441 #endif
5442 
5443  // If the duration of the mp3 packets is not constant, then they could need a parser
5444  if (st->codecpar->codec_id == AV_CODEC_ID_MP3
5445  && sc->time_scale == st->codecpar->sample_rate) {
5446  int stts_constant = 1;
5447  for (int i = 1; sc->stts_count && i < sc->tts_count; i++) {
5448  if (sc->tts_data[i].duration == sc->tts_data[0].duration)
5449  continue;
5450  stts_constant = 0;
5451  }
5452  if (!stts_constant)
5454  }
5455  /* Do not need those anymore. */
5456  av_freep(&sc->chunk_offsets);
5457  av_freep(&sc->sample_sizes);
5458  av_freep(&sc->keyframes);
5459  av_freep(&sc->stps_data);
5460  av_freep(&sc->elst_data);
5461  av_freep(&sc->rap_group);
5462  av_freep(&sc->sync_group);
5463  av_freep(&sc->sgpd_sync);
5464 
5465  return 0;
5466 }
5467 
5469 {
5470  int ret;
5471  c->itunes_metadata = 1;
5472  ret = mov_read_default(c, pb, atom);
5473  c->itunes_metadata = 0;
5474  return ret;
5475 }
5476 
5478 {
5479  uint32_t count;
5480  uint32_t i;
5481 
5482  if (atom.size < 8)
5483  return 0;
5484 
5485  avio_skip(pb, 4);
5486  count = avio_rb32(pb);
5487  atom.size -= 8;
5488  if (count >= UINT_MAX / sizeof(*c->meta_keys)) {
5489  av_log(c->fc, AV_LOG_ERROR,
5490  "The 'keys' atom with the invalid key count: %"PRIu32"\n", count);
5491  return AVERROR_INVALIDDATA;
5492  }
5493 
5494  c->meta_keys_count = count + 1;
5495  c->meta_keys = av_mallocz(c->meta_keys_count * sizeof(*c->meta_keys));
5496  if (!c->meta_keys)
5497  return AVERROR(ENOMEM);
5498 
5499  for (i = 1; i <= count; ++i) {
5500  uint32_t key_size = avio_rb32(pb);
5501  uint32_t type = avio_rl32(pb);
5502  if (key_size < 8 || key_size > atom.size) {
5503  av_log(c->fc, AV_LOG_ERROR,
5504  "The key# %"PRIu32" in meta has invalid size:"
5505  "%"PRIu32"\n", i, key_size);
5506  return AVERROR_INVALIDDATA;
5507  }
5508  atom.size -= key_size;
5509  key_size -= 8;
5510  if (type != MKTAG('m','d','t','a')) {
5511  avio_skip(pb, key_size);
5512  continue;
5513  }
5514  c->meta_keys[i] = av_mallocz(key_size + 1);
5515  if (!c->meta_keys[i])
5516  return AVERROR(ENOMEM);
5517  avio_read(pb, c->meta_keys[i], key_size);
5518  }
5519 
5520  return 0;
5521 }
5522 
5524 {
5525  int64_t end = av_sat_add64(avio_tell(pb), atom.size);
5526  uint8_t *key = NULL, *val = NULL, *mean = NULL;
5527  int i;
5528  int ret = 0;
5529  AVStream *st;
5530 
5531  if (c->fc->nb_streams < 1)
5532  return 0;
5533  st = c->fc->streams[c->fc->nb_streams-1];
5534 
5535  for (i = 0; i < 3; i++) {
5536  uint8_t **p;
5537  uint32_t len, tag;
5538 
5539  if (end - avio_tell(pb) <= 12)
5540  break;
5541 
5542  len = avio_rb32(pb);
5543  tag = avio_rl32(pb);
5544  avio_skip(pb, 4); // flags
5545 
5546  if (len < 12 || len - 12 > end - avio_tell(pb))
5547  break;
5548  len -= 12;
5549 
5550  if (tag == MKTAG('m', 'e', 'a', 'n'))
5551  p = &mean;
5552  else if (tag == MKTAG('n', 'a', 'm', 'e'))
5553  p = &key;
5554  else if (tag == MKTAG('d', 'a', 't', 'a') && len > 4) {
5555  avio_skip(pb, 4);
5556  len -= 4;
5557  p = &val;
5558  } else
5559  break;
5560 
5561  if (*p)
5562  break;
5563 
5564  *p = av_malloc(len + 1);
5565  if (!*p) {
5566  ret = AVERROR(ENOMEM);
5567  break;
5568  }
5569  ret = ffio_read_size(pb, *p, len);
5570  if (ret < 0) {
5571  av_freep(p);
5572  break;
5573  }
5574  (*p)[len] = 0;
5575  }
5576 
5577  if (mean && key && val) {
5578  if (strcmp(key, "iTunSMPB") == 0) {
5579  int priming, remainder, samples;
5580  if(sscanf(val, "%*X %X %X %X", &priming, &remainder, &samples) == 3){
5581  if(priming>0 && priming<16384)
5582  st->codecpar->initial_padding = priming = av_rescale_q(priming, st->time_base,
5583  (AVRational){ 1, st->codecpar->sample_rate });
5584  if (remainder > 0) {
5586  (AVRational){ 1, st->codecpar->sample_rate });
5587  remainder = av_rescale_q(remainder, st->time_base,
5588  (AVRational){ 1, st->codecpar->sample_rate });
5590  (AVRational){ 1, st->codecpar->sample_rate });
5591  if (duration > remainder && duration > samples) {
5592  ffstream(st)->first_discard_sample = duration - remainder;
5594  }
5595  }
5596  av_log(c->fc, AV_LOG_DEBUG, "Parsed iTunSMPB: priming %d, remainder %d samples %d\n",
5597  priming, remainder, samples);
5598  }
5599  }
5600  if (strcmp(mean, "com.apple.iTunes") == 0 &&
5601  strcmp(key, "DISCSUBTITLE") == 0) {
5602  av_dict_set(&c->fc->metadata, "disc_subtitle", val,
5604  val = NULL;
5605  }
5606  if (strcmp(key, "cdec") != 0) {
5607  av_dict_set(&c->fc->metadata, key, val,
5609  key = val = NULL;
5610  }
5611  } else {
5612  av_log(c->fc, AV_LOG_VERBOSE,
5613  "Unhandled or malformed custom metadata of size %"PRId64"\n", atom.size);
5614  }
5615 
5616  avio_seek(pb, end, SEEK_SET);
5617  av_freep(&key);
5618  av_freep(&val);
5619  av_freep(&mean);
5620  return ret;
5621 }
5622 
5624 {
5625  MOVStreamContext *sc;
5626  AVStream *st;
5627 
5628  st = avformat_new_stream(c->fc, NULL);
5629  if (!st)
5630  return AVERROR(ENOMEM);
5631  sc = av_mallocz(sizeof(MOVStreamContext));
5632  if (!sc)
5633  goto fail;
5634 
5635  item->st = st;
5636  st->id = item->item_id;
5637  st->priv_data = sc;
5639  st->codecpar->codec_id = mov_codec_id(st, item->type);
5640  sc->id = st->id;
5641  sc->ffindex = st->index;
5642  st->avg_frame_rate.num = st->avg_frame_rate.den = 1;
5643  st->time_base.num = st->time_base.den = 1;
5644  st->nb_frames = 1;
5645  sc->time_scale = 1;
5646  sc->pb = c->fc->pb;
5647  sc->pb_is_copied = 1;
5648  sc->refcount = 1;
5649 
5650  if (item->name)
5651  av_dict_set(&st->metadata, "title", item->name, 0);
5652 
5653  // Populate the necessary fields used by mov_build_index.
5654  sc->stsc_data = av_malloc_array(1, sizeof(*sc->stsc_data));
5655  if (!sc->stsc_data)
5656  goto fail;
5657  sc->stsc_count = 1;
5658  sc->stsc_data[0].first = 1;
5659  sc->stsc_data[0].count = 1;
5660  sc->stsc_data[0].id = 1;
5661  sc->chunk_offsets = av_malloc_array(1, sizeof(*sc->chunk_offsets));
5662  if (!sc->chunk_offsets)
5663  goto fail;
5664  sc->chunk_count = 1;
5665  sc->stts_data = av_malloc_array(1, sizeof(*sc->stts_data));
5666  if (!sc->stts_data)
5667  goto fail;
5668  sc->stts_count = 1;
5669  sc->stts_data[0].count = 1;
5670  // Not used for still images. But needed by mov_build_index.
5671  sc->stts_data[0].duration = 0;
5672 
5673  return 0;
5674 fail:
5675  mov_free_stream_context(c->fc, st);
5676  ff_remove_stream(c->fc, st);
5677  item->st = NULL;
5678 
5679  return AVERROR(ENOMEM);
5680 }
5681 
5683 {
5684  while (atom.size > 8) {
5685  uint32_t tag;
5686  if (avio_feof(pb))
5687  return AVERROR_EOF;
5688  tag = avio_rl32(pb);
5689  atom.size -= 4;
5690  if (tag == MKTAG('h','d','l','r')) {
5691  avio_seek(pb, -8, SEEK_CUR);
5692  atom.size += 8;
5693  return mov_read_default(c, pb, atom);
5694  }
5695  }
5696  return 0;
5697 }
5698 
5699 // return 1 when matrix is identity, 0 otherwise
5700 #define IS_MATRIX_IDENT(matrix) \
5701  ( (matrix)[0][0] == (1 << 16) && \
5702  (matrix)[1][1] == (1 << 16) && \
5703  (matrix)[2][2] == (1 << 30) && \
5704  !(matrix)[0][1] && !(matrix)[0][2] && \
5705  !(matrix)[1][0] && !(matrix)[1][2] && \
5706  !(matrix)[2][0] && !(matrix)[2][1])
5707 
5709 {
5710  int i, j, e;
5711  int width;
5712  int height;
5713  int display_matrix[3][3];
5714  int res_display_matrix[3][3] = { { 0 } };
5715  AVStream *st;
5716  MOVStreamContext *sc;
5717  int version;
5718  int flags;
5719 
5720  if (c->fc->nb_streams < 1)
5721  return 0;
5722  st = c->fc->streams[c->fc->nb_streams-1];
5723  sc = st->priv_data;
5724 
5725  // Each stream (trak) should have exactly 1 tkhd. This catches bad files and
5726  // avoids corrupting AVStreams mapped to an earlier tkhd.
5727  if (st->id != -1)
5728  return AVERROR_INVALIDDATA;
5729 
5730  version = avio_r8(pb);
5731  flags = avio_rb24(pb);
5733 
5734  if (version == 1) {
5735  avio_rb64(pb);
5736  avio_rb64(pb);
5737  } else {
5738  avio_rb32(pb); /* creation time */
5739  avio_rb32(pb); /* modification time */
5740  }
5741  st->id = (int)avio_rb32(pb); /* track id (NOT 0 !)*/
5742  sc->id = st->id;
5743  avio_rb32(pb); /* reserved */
5744 
5745  /* highlevel (considering edits) duration in movie timebase */
5746  (version == 1) ? avio_rb64(pb) : avio_rb32(pb);
5747  avio_rb32(pb); /* reserved */
5748  avio_rb32(pb); /* reserved */
5749 
5750  avio_rb16(pb); /* layer */
5751  avio_rb16(pb); /* alternate group */
5752  avio_rb16(pb); /* volume */
5753  avio_rb16(pb); /* reserved */
5754 
5755  //read in the display matrix (outlined in ISO 14496-12, Section 6.2.2)
5756  // they're kept in fixed point format through all calculations
5757  // save u,v,z to store the whole matrix in the AV_PKT_DATA_DISPLAYMATRIX
5758  // side data, but the scale factor is not needed to calculate aspect ratio
5759  for (i = 0; i < 3; i++) {
5760  display_matrix[i][0] = avio_rb32(pb); // 16.16 fixed point
5761  display_matrix[i][1] = avio_rb32(pb); // 16.16 fixed point
5762  display_matrix[i][2] = avio_rb32(pb); // 2.30 fixed point
5763  }
5764 
5765  width = avio_rb32(pb); // 16.16 fixed point track width
5766  height = avio_rb32(pb); // 16.16 fixed point track height
5767  sc->width = width >> 16;
5768  sc->height = height >> 16;
5769 
5770  // apply the moov display matrix (after the tkhd one)
5771  for (i = 0; i < 3; i++) {
5772  const int sh[3] = { 16, 16, 30 };
5773  for (j = 0; j < 3; j++) {
5774  for (e = 0; e < 3; e++) {
5775  res_display_matrix[i][j] +=
5776  ((int64_t) display_matrix[i][e] *
5777  c->movie_display_matrix[e][j]) >> sh[e];
5778  }
5779  }
5780  }
5781 
5782  // save the matrix when it is not the default identity
5783  if (!IS_MATRIX_IDENT(res_display_matrix)) {
5784  av_freep(&sc->display_matrix);
5785  sc->display_matrix = av_malloc(sizeof(int32_t) * 9);
5786  if (!sc->display_matrix)
5787  return AVERROR(ENOMEM);
5788 
5789  for (i = 0; i < 3; i++)
5790  for (j = 0; j < 3; j++)
5791  sc->display_matrix[i * 3 + j] = res_display_matrix[i][j];
5792  }
5793 
5794  // transform the display width/height according to the matrix
5795  // to keep the same scale, use [width height 1<<16]
5796  if (width && height && sc->display_matrix) {
5797  double disp_transform[2];
5798 
5799  for (i = 0; i < 2; i++)
5800  disp_transform[i] = hypot(sc->display_matrix[0 + i],
5801  sc->display_matrix[3 + i]);
5802 
5803  if (disp_transform[0] > 1 && disp_transform[1] > 1 &&
5804  disp_transform[0] < (1<<24) && disp_transform[1] < (1<<24) &&
5805  fabs((disp_transform[0] / disp_transform[1]) - 1.0) > 0.01)
5807  disp_transform[0] / disp_transform[1],
5808  INT_MAX);
5809  }
5810  return 0;
5811 }
5812 
5814 {
5815  MOVFragment *frag = &c->fragment;
5816  MOVTrackExt *trex = NULL;
5817  int flags, track_id, i;
5818  MOVFragmentStreamInfo * frag_stream_info;
5819 
5820  avio_r8(pb); /* version */
5821  flags = avio_rb24(pb);
5822 
5823  track_id = avio_rb32(pb);
5824  if (!track_id)
5825  return AVERROR_INVALIDDATA;
5826  for (i = 0; i < c->trex_count; i++)
5827  if (c->trex_data[i].track_id == track_id) {
5828  trex = &c->trex_data[i];
5829  break;
5830  }
5831  if (!trex) {
5832  av_log(c->fc, AV_LOG_WARNING, "could not find corresponding trex (id %u)\n", track_id);
5833  return 0;
5834  }
5835  c->fragment.found_tfhd = 1;
5836  frag->track_id = track_id;
5837  set_frag_stream(&c->frag_index, track_id);
5838 
5841  frag->moof_offset : frag->implicit_offset;
5842  frag->stsd_id = flags & MOV_TFHD_STSD_ID ? avio_rb32(pb) : trex->stsd_id;
5843 
5845  avio_rb32(pb) : trex->duration;
5846  frag->size = flags & MOV_TFHD_DEFAULT_SIZE ?
5847  avio_rb32(pb) : trex->size;
5848  frag->flags = flags & MOV_TFHD_DEFAULT_FLAGS ?
5849  avio_rb32(pb) : trex->flags;
5850  av_log(c->fc, AV_LOG_TRACE, "frag flags 0x%x\n", frag->flags);
5851 
5852  frag_stream_info = get_current_frag_stream_info(&c->frag_index);
5853  if (frag_stream_info) {
5854  frag_stream_info->next_trun_dts = AV_NOPTS_VALUE;
5855  frag_stream_info->stsd_id = frag->stsd_id;
5856  }
5857  return 0;
5858 }
5859 
5861 {
5862  unsigned i, num;
5863  void *new_tracks;
5864 
5865  num = atom.size / 4;
5866  if (!(new_tracks = av_malloc_array(num, sizeof(int))))
5867  return AVERROR(ENOMEM);
5868 
5869  av_free(c->chapter_tracks);
5870  c->chapter_tracks = new_tracks;
5871  c->nb_chapter_tracks = num;
5872 
5873  for (i = 0; i < num && !pb->eof_reached; i++)
5874  c->chapter_tracks[i] = avio_rb32(pb);
5875 
5876  c->nb_chapter_tracks = i;
5877 
5878  return 0;
5879 }
5880 
5882 {
5883  MOVTrackExt *trex;
5884  int err;
5885 
5886  if ((uint64_t)c->trex_count+1 >= UINT_MAX / sizeof(*c->trex_data))
5887  return AVERROR_INVALIDDATA;
5888  if ((err = av_reallocp_array(&c->trex_data, c->trex_count + 1,
5889  sizeof(*c->trex_data))) < 0) {
5890  c->trex_count = 0;
5891  return err;
5892  }
5893 
5894  c->fc->duration = AV_NOPTS_VALUE; // the duration from mvhd is not representing the whole file when fragments are used.
5895 
5896  trex = &c->trex_data[c->trex_count++];
5897  avio_r8(pb); /* version */
5898  avio_rb24(pb); /* flags */
5899  trex->track_id = avio_rb32(pb);
5900  trex->stsd_id = avio_rb32(pb);
5901  trex->duration = avio_rb32(pb);
5902  trex->size = avio_rb32(pb);
5903  trex->flags = avio_rb32(pb);
5904  return 0;
5905 }
5906 
5908 {
5909  MOVFragment *frag = &c->fragment;
5910  AVStream *st = NULL;
5911  MOVStreamContext *sc;
5912  int version, i;
5913  MOVFragmentStreamInfo * frag_stream_info;
5914  int64_t base_media_decode_time;
5915 
5916  for (i = 0; i < c->fc->nb_streams; i++) {
5917  sc = c->fc->streams[i]->priv_data;
5918  if (sc->id == frag->track_id) {
5919  st = c->fc->streams[i];
5920  break;
5921  }
5922  }
5923  if (!st) {
5924  av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %u\n", frag->track_id);
5925  return 0;
5926  }
5927  sc = st->priv_data;
5928  if (sc->pseudo_stream_id + 1 != frag->stsd_id && sc->pseudo_stream_id != -1)
5929  return 0;
5930  version = avio_r8(pb);
5931  avio_rb24(pb); /* flags */
5932  if (version) {
5933  base_media_decode_time = avio_rb64(pb);
5934  } else {
5935  base_media_decode_time = avio_rb32(pb);
5936  }
5937 
5938  frag_stream_info = get_current_frag_stream_info(&c->frag_index);
5939  if (frag_stream_info)
5940  frag_stream_info->tfdt_dts = base_media_decode_time;
5941  sc->track_end = base_media_decode_time;
5942 
5943  return 0;
5944 }
5945 
5947 {
5948  MOVFragment *frag = &c->fragment;
5949  AVStream *st = NULL;
5950  FFStream *sti = NULL;
5951  MOVStreamContext *sc;
5952  MOVTimeToSample *tts_data;
5953  uint64_t offset;
5954  int64_t dts, pts = AV_NOPTS_VALUE;
5955  int data_offset = 0;
5956  unsigned entries, first_sample_flags = frag->flags;
5957  int flags, distance, i;
5958  int64_t prev_dts = AV_NOPTS_VALUE;
5959  int next_frag_index = -1, index_entry_pos;
5960  size_t requested_size;
5961  size_t old_allocated_size;
5962  AVIndexEntry *new_entries;
5963  MOVFragmentStreamInfo * frag_stream_info;
5964 
5965  if (!frag->found_tfhd) {
5966  av_log(c->fc, AV_LOG_ERROR, "trun track id unknown, no tfhd was found\n");
5967  return AVERROR_INVALIDDATA;
5968  }
5969 
5970  for (i = 0; i < c->fc->nb_streams; i++) {
5971  sc = c->fc->streams[i]->priv_data;
5972  if (sc->id == frag->track_id) {
5973  st = c->fc->streams[i];
5974  sti = ffstream(st);
5975  break;
5976  }
5977  }
5978  if (!st) {
5979  av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %u\n", frag->track_id);
5980  return 0;
5981  }
5982  sc = st->priv_data;
5983  if (sc->pseudo_stream_id+1 != frag->stsd_id && sc->pseudo_stream_id != -1)
5984  return 0;
5985 
5986  // Find the next frag_index index that has a valid index_entry for
5987  // the current track_id.
5988  //
5989  // A valid index_entry means the trun for the fragment was read
5990  // and it's samples are in index_entries at the given position.
5991  // New index entries will be inserted before the index_entry found.
5992  index_entry_pos = sti->nb_index_entries;
5993  for (i = c->frag_index.current + 1; i < c->frag_index.nb_items; i++) {
5994  frag_stream_info = get_frag_stream_info(&c->frag_index, i, frag->track_id);
5995  if (frag_stream_info && frag_stream_info->index_entry >= 0) {
5996  next_frag_index = i;
5997  index_entry_pos = frag_stream_info->index_entry;
5998  break;
5999  }
6000  }
6001  av_assert0(index_entry_pos <= sti->nb_index_entries);
6002 
6003  avio_r8(pb); /* version */
6004  flags = avio_rb24(pb);
6005  entries = avio_rb32(pb);
6006  av_log(c->fc, AV_LOG_TRACE, "flags 0x%x entries %u\n", flags, entries);
6007 
6008  if ((uint64_t)entries+sc->tts_count >= UINT_MAX/sizeof(*sc->tts_data))
6009  return AVERROR_INVALIDDATA;
6010  if (flags & MOV_TRUN_DATA_OFFSET) data_offset = avio_rb32(pb);
6011  if (flags & MOV_TRUN_FIRST_SAMPLE_FLAGS) first_sample_flags = avio_rb32(pb);
6012 
6013  int entry_size = !!(flags & MOV_TRUN_SAMPLE_DURATION) * 4
6014  + !!(flags & MOV_TRUN_SAMPLE_SIZE) * 4
6015  + !!(flags & MOV_TRUN_SAMPLE_FLAGS) * 4
6016  + !!(flags & MOV_TRUN_SAMPLE_CTS) * 4;
6017  int64_t sample_data_size = avio_size(sc->pb);
6018  int64_t max_entries = INT64_MAX;
6019 
6020  if (sample_data_size > 0)
6021  max_entries = sample_data_size - sti->nb_index_entries;
6022  if (entry_size) {
6023  int64_t size = sc->pb == pb ? sample_data_size : avio_size(pb);
6024  int64_t pos = avio_tell(pb);
6025  int64_t left = atom.size - 8 - !!(flags & MOV_TRUN_DATA_OFFSET) * 4
6026  - !!(flags & MOV_TRUN_FIRST_SAMPLE_FLAGS) * 4;
6027 
6028  if (pos >= 0 && size >= pos)
6029  left = FFMIN(left, size - pos);
6030  max_entries = FFMIN(max_entries, left / entry_size);
6031  }
6032  if (entries > max_entries) {
6033  av_log(c->fc, AV_LOG_ERROR, "trun sample count %u exceeds the %"PRId64" "
6034  "samples the input can hold\n", entries, max_entries);
6035  return AVERROR_INVALIDDATA;
6036  }
6037 
6038  frag_stream_info = get_current_frag_stream_info(&c->frag_index);
6039  if (frag_stream_info) {
6040  if (frag_stream_info->next_trun_dts != AV_NOPTS_VALUE) {
6041  dts = frag_stream_info->next_trun_dts - sc->time_offset;
6042  } else if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE &&
6043  c->use_mfra_for == FF_MOV_FLAG_MFRA_PTS) {
6044  pts = frag_stream_info->first_tfra_pts;
6045  av_log(c->fc, AV_LOG_DEBUG, "found mfra time %"PRId64
6046  ", using it for pts\n", pts);
6047  } else if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE &&
6048  c->use_mfra_for == FF_MOV_FLAG_MFRA_DTS) {
6049  dts = frag_stream_info->first_tfra_pts;
6050  av_log(c->fc, AV_LOG_DEBUG, "found mfra time %"PRId64
6051  ", using it for dts\n", pts);
6052  } else {
6053  int has_tfdt = frag_stream_info->tfdt_dts != AV_NOPTS_VALUE;
6054  int has_sidx = frag_stream_info->sidx_pts != AV_NOPTS_VALUE;
6055  int fallback_tfdt = !c->use_tfdt && !has_sidx && has_tfdt;
6056  int fallback_sidx = c->use_tfdt && !has_tfdt && has_sidx;
6057 
6058  if (fallback_sidx) {
6059  av_log(c->fc, AV_LOG_DEBUG, "use_tfdt set but no tfdt found, using sidx instead\n");
6060  }
6061  if (fallback_tfdt) {
6062  av_log(c->fc, AV_LOG_DEBUG, "use_tfdt not set but no sidx found, using tfdt instead\n");
6063  }
6064 
6065  if (has_tfdt && c->use_tfdt || fallback_tfdt) {
6066  dts = frag_stream_info->tfdt_dts - sc->time_offset;
6067  av_log(c->fc, AV_LOG_DEBUG, "found tfdt time %"PRId64
6068  ", using it for dts\n", dts);
6069  } else if (has_sidx && !c->use_tfdt || fallback_sidx) {
6070  // FIXME: sidx earliest_presentation_time is *PTS*, s.b.
6071  // pts = frag_stream_info->sidx_pts;
6072  dts = frag_stream_info->sidx_pts;
6073  av_log(c->fc, AV_LOG_DEBUG, "found sidx time %"PRId64
6074  ", using it for dts\n", frag_stream_info->sidx_pts);
6075  } else {
6076  dts = sc->track_end - sc->time_offset;
6077  av_log(c->fc, AV_LOG_DEBUG, "found track end time %"PRId64
6078  ", using it for dts\n", dts);
6079  }
6080  }
6081  } else {
6082  dts = sc->track_end - sc->time_offset;
6083  av_log(c->fc, AV_LOG_DEBUG, "found track end time %"PRId64
6084  ", using it for dts\n", dts);
6085  }
6086  offset = frag->base_data_offset + data_offset;
6087  distance = 0;
6088  av_log(c->fc, AV_LOG_TRACE, "first sample flags 0x%x\n", first_sample_flags);
6089 
6090  // realloc space for new index entries
6091  if ((uint64_t)sti->nb_index_entries + entries >= UINT_MAX / sizeof(AVIndexEntry)) {
6092  entries = UINT_MAX / sizeof(AVIndexEntry) - sti->nb_index_entries;
6093  av_log(c->fc, AV_LOG_ERROR, "Failed to add index entry\n");
6094  }
6095  if (entries == 0)
6096  return 0;
6097 
6098  requested_size = (sti->nb_index_entries + entries) * sizeof(AVIndexEntry);
6099  new_entries = av_fast_realloc(sti->index_entries,
6101  requested_size);
6102  if (!new_entries)
6103  return AVERROR(ENOMEM);
6104  sti->index_entries= new_entries;
6105 
6106  requested_size = (sti->nb_index_entries + entries) * sizeof(*sc->tts_data);
6107  old_allocated_size = sc->tts_allocated_size;
6108  tts_data = av_fast_realloc(sc->tts_data, &sc->tts_allocated_size,
6109  requested_size);
6110  if (!tts_data)
6111  return AVERROR(ENOMEM);
6112  sc->tts_data = tts_data;
6113 
6114  // In case there were samples without time to sample entries, ensure they get
6115  // zero valued entries. This ensures clips which mix boxes with and
6116  // without time to sample entries don't pickup uninitialized data.
6117  memset((uint8_t*)(sc->tts_data) + old_allocated_size, 0,
6118  sc->tts_allocated_size - old_allocated_size);
6119 
6120  if (index_entry_pos < sti->nb_index_entries) {
6121  // Make hole in index_entries and tts_data for new samples
6122  memmove(sti->index_entries + index_entry_pos + entries,
6123  sti->index_entries + index_entry_pos,
6124  sizeof(*sti->index_entries) *
6125  (sti->nb_index_entries - index_entry_pos));
6126  memmove(sc->tts_data + index_entry_pos + entries,
6127  sc->tts_data + index_entry_pos,
6128  sizeof(*sc->tts_data) * (sc->tts_count - index_entry_pos));
6129  if (index_entry_pos < sc->current_sample) {
6130  sc->current_sample += entries;
6131  }
6132  }
6133 
6134  sti->nb_index_entries += entries;
6135  sc->tts_count = sti->nb_index_entries;
6136  sc->stts_count = sti->nb_index_entries;
6137  if (flags & MOV_TRUN_SAMPLE_CTS)
6138  sc->ctts_count = sti->nb_index_entries;
6139 
6140  // Record the index_entry position in frag_index of this fragment
6141  if (frag_stream_info) {
6142  frag_stream_info->index_entry = index_entry_pos;
6143  if (frag_stream_info->index_base < 0)
6144  frag_stream_info->index_base = index_entry_pos;
6145  }
6146 
6147  if (index_entry_pos > 0)
6148  prev_dts = sti->index_entries[index_entry_pos-1].timestamp;
6149 
6150  for (i = 0; i < entries && !pb->eof_reached; i++) {
6151  unsigned sample_size = frag->size;
6152  int sample_flags = i ? frag->flags : first_sample_flags;
6153  unsigned sample_duration = frag->duration;
6154  unsigned ctts_duration = 0;
6155  int keyframe = 0;
6156  int index_entry_flags = 0;
6157 
6158  if (flags & MOV_TRUN_SAMPLE_DURATION) sample_duration = avio_rb32(pb);
6159  if (flags & MOV_TRUN_SAMPLE_SIZE) sample_size = avio_rb32(pb);
6160  if (flags & MOV_TRUN_SAMPLE_FLAGS) sample_flags = avio_rb32(pb);
6161  if (flags & MOV_TRUN_SAMPLE_CTS) ctts_duration = avio_rb32(pb);
6162 
6163  mov_update_dts_shift(sc, ctts_duration, c->fc);
6164  if (pts != AV_NOPTS_VALUE) {
6165  dts = pts - sc->dts_shift;
6166  if (flags & MOV_TRUN_SAMPLE_CTS) {
6167  dts -= ctts_duration;
6168  } else {
6169  dts -= sc->time_offset;
6170  }
6171  av_log(c->fc, AV_LOG_DEBUG,
6172  "pts %"PRId64" calculated dts %"PRId64
6173  " sc->dts_shift %d ctts.duration %d"
6174  " sc->time_offset %"PRId64
6175  " flags & MOV_TRUN_SAMPLE_CTS %d\n",
6176  pts, dts,
6177  sc->dts_shift, ctts_duration,
6179  pts = AV_NOPTS_VALUE;
6180  }
6181 
6182  keyframe =
6183  !(sample_flags & (MOV_FRAG_SAMPLE_FLAG_IS_NON_SYNC |
6185  if (keyframe) {
6186  distance = 0;
6187  index_entry_flags |= AVINDEX_KEYFRAME;
6188  }
6189  // Fragments can overlap in time. Discard overlapping frames after
6190  // decoding.
6191  if (prev_dts >= dts)
6192  index_entry_flags |= AVINDEX_DISCARD_FRAME;
6193 
6194  sti->index_entries[index_entry_pos].pos = offset;
6195  sti->index_entries[index_entry_pos].timestamp = dts;
6196  sti->index_entries[index_entry_pos].size = sample_size;
6197  sti->index_entries[index_entry_pos].min_distance = distance;
6198  sti->index_entries[index_entry_pos].flags = index_entry_flags;
6199 
6200  sc->tts_data[index_entry_pos].count = 1;
6201  sc->tts_data[index_entry_pos].offset = ctts_duration;
6202  sc->tts_data[index_entry_pos].duration = sample_duration;
6203  index_entry_pos++;
6204 
6205  av_log(c->fc, AV_LOG_TRACE, "AVIndex stream %d, sample %d, offset %"PRIx64", dts %"PRId64", "
6206  "size %u, distance %d, keyframe %d\n", st->index,
6207  index_entry_pos, offset, dts, sample_size, distance, keyframe);
6208  distance++;
6209  if (av_sat_add64(dts, sample_duration) != dts + (uint64_t)sample_duration)
6210  return AVERROR_INVALIDDATA;
6211  if (!sample_size)
6212  return AVERROR_INVALIDDATA;
6213  dts += sample_duration;
6214  offset += sample_size;
6215  sc->data_size += sample_size;
6216 
6217  if (sample_duration <= INT64_MAX - sc->duration_for_fps &&
6218  1 <= INT_MAX - sc->nb_frames_for_fps
6219  ) {
6220  sc->duration_for_fps += sample_duration;
6221  sc->nb_frames_for_fps ++;
6222  }
6223  }
6224  if (frag_stream_info)
6225  frag_stream_info->next_trun_dts = dts + sc->time_offset;
6226  if (i < entries) {
6227  // EOF found before reading all entries. Fix the hole this would
6228  // leave in index_entries and tts_data
6229  int gap = entries - i;
6230  memmove(sti->index_entries + index_entry_pos,
6231  sti->index_entries + index_entry_pos + gap,
6232  sizeof(*sti->index_entries) *
6233  (sti->nb_index_entries - (index_entry_pos + gap)));
6234  memmove(sc->tts_data + index_entry_pos,
6235  sc->tts_data + index_entry_pos + gap,
6236  sizeof(*sc->tts_data) *
6237  (sc->tts_count - (index_entry_pos + gap)));
6238 
6239  sti->nb_index_entries -= gap;
6240  sc->tts_count -= gap;
6241  if (index_entry_pos < sc->current_sample) {
6242  sc->current_sample -= gap;
6243  }
6244  entries = i;
6245  }
6246 
6247  // The end of this new fragment may overlap in time with the start
6248  // of the next fragment in index_entries. Mark the samples in the next
6249  // fragment that overlap with AVINDEX_DISCARD_FRAME
6250  prev_dts = AV_NOPTS_VALUE;
6251  if (index_entry_pos > 0)
6252  prev_dts = sti->index_entries[index_entry_pos-1].timestamp;
6253  for (int i = index_entry_pos; i < sti->nb_index_entries; i++) {
6254  if (prev_dts < sti->index_entries[i].timestamp)
6255  break;
6257  }
6258 
6259  // If a hole was created to insert the new index_entries into,
6260  // the index_entry recorded for all subsequent moof must
6261  // be incremented by the number of entries inserted.
6262  fix_frag_index_entries(&c->frag_index, next_frag_index,
6263  frag->track_id, entries);
6264 
6265  if (pb->eof_reached) {
6266  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted TRUN atom\n");
6267  return AVERROR_EOF;
6268  }
6269 
6270  frag->implicit_offset = offset;
6271 
6272  sc->track_end = dts + sc->time_offset;
6273  if (st->duration < sc->track_end)
6274  st->duration = sc->track_end;
6275 
6276  return 0;
6277 }
6278 
6280 {
6281  int64_t stream_size = avio_size(pb);
6282  int64_t offset = av_sat_add64(avio_tell(pb), atom.size), pts, timestamp;
6283  uint8_t version, is_complete;
6284  int64_t offadd;
6285  unsigned i, j, track_id, item_count;
6286  AVStream *st = NULL;
6287  AVStream *ref_st = NULL;
6288  MOVStreamContext *sc, *ref_sc = NULL;
6289  AVRational timescale;
6290 
6291  version = avio_r8(pb);
6292  if (version > 1) {
6293  avpriv_request_sample(c->fc, "sidx version %u", version);
6294  return 0;
6295  }
6296 
6297  avio_rb24(pb); // flags
6298 
6299  track_id = avio_rb32(pb); // Reference ID
6300  for (i = 0; i < c->fc->nb_streams; i++) {
6301  sc = c->fc->streams[i]->priv_data;
6302  if (sc->id == track_id) {
6303  st = c->fc->streams[i];
6304  break;
6305  }
6306  }
6307  if (!st) {
6308  av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %d\n", track_id);
6309  return 0;
6310  }
6311 
6312  sc = st->priv_data;
6313 
6314  timescale = av_make_q(1, avio_rb32(pb));
6315 
6316  if (timescale.den <= 0) {
6317  av_log(c->fc, AV_LOG_ERROR, "Invalid sidx timescale 1/%d\n", timescale.den);
6318  return AVERROR_INVALIDDATA;
6319  }
6320 
6321  if (version == 0) {
6322  pts = avio_rb32(pb);
6323  offadd= avio_rb32(pb);
6324  } else {
6325  pts = avio_rb64(pb);
6326  offadd= avio_rb64(pb);
6327  }
6328  if (av_sat_add64(offset, offadd) != offset + (uint64_t)offadd)
6329  return AVERROR_INVALIDDATA;
6330 
6331  offset += (uint64_t)offadd;
6332 
6333  avio_rb16(pb); // reserved
6334 
6335  item_count = avio_rb16(pb);
6336  if (item_count == 0)
6337  return AVERROR_INVALIDDATA;
6338 
6339  for (i = 0; i < item_count; i++) {
6340  int index;
6341  MOVFragmentStreamInfo * frag_stream_info;
6342  uint32_t size = avio_rb32(pb);
6343  uint32_t duration = avio_rb32(pb);
6344  if (size & 0x80000000) {
6345  avpriv_request_sample(c->fc, "sidx reference_type 1");
6346  return AVERROR_PATCHWELCOME;
6347  }
6348  avio_rb32(pb); // sap_flags
6349  timestamp = av_rescale_q(pts, timescale, st->time_base);
6350 
6352  frag_stream_info = get_frag_stream_info(&c->frag_index, index, track_id);
6353  if (frag_stream_info)
6354  frag_stream_info->sidx_pts = timestamp;
6355 
6356  if (av_sat_add64(offset, size) != offset + (uint64_t)size ||
6357  av_sat_add64(pts, duration) != pts + (uint64_t)duration
6358  )
6359  return AVERROR_INVALIDDATA;
6360  offset += size;
6361  pts += duration;
6362  }
6363 
6364  st->duration = sc->track_end = pts;
6365 
6366  sc->has_sidx = 1;
6367 
6368  // See if the remaining bytes are just an mfra which we can ignore.
6369  is_complete = offset == stream_size;
6370  if (!is_complete && (pb->seekable & AVIO_SEEKABLE_NORMAL) && stream_size > 0 ) {
6371  int64_t ret;
6372  int64_t original_pos = avio_tell(pb);
6373  if (!c->have_read_mfra_size) {
6374  if ((ret = avio_seek(pb, stream_size - 4, SEEK_SET)) < 0)
6375  return ret;
6376  c->mfra_size = avio_rb32(pb);
6377  c->have_read_mfra_size = 1;
6378  if ((ret = avio_seek(pb, original_pos, SEEK_SET)) < 0)
6379  return ret;
6380  }
6381  if (offset == stream_size - c->mfra_size)
6382  is_complete = 1;
6383  }
6384 
6385  if (is_complete) {
6386  // Find first entry in fragment index that came from an sidx.
6387  // This will pretty much always be the first entry.
6388  for (i = 0; i < c->frag_index.nb_items; i++) {
6389  MOVFragmentIndexItem * item = &c->frag_index.item[i];
6390  for (j = 0; ref_st == NULL && j < item->nb_stream_info; j++) {
6391  MOVFragmentStreamInfo * si;
6392  si = &item->stream_info[j];
6393  if (si->sidx_pts != AV_NOPTS_VALUE) {
6394  ref_st = c->fc->streams[j];
6395  ref_sc = ref_st->priv_data;
6396  break;
6397  }
6398  }
6399  }
6400  if (ref_st) for (i = 0; i < c->fc->nb_streams; i++) {
6401  st = c->fc->streams[i];
6402  sc = st->priv_data;
6403  if (!sc->has_sidx) {
6404  st->duration = sc->track_end = av_rescale(ref_st->duration, sc->time_scale, ref_sc->time_scale);
6405  }
6406  }
6407 
6408  if (offadd == 0)
6409  c->frag_index.complete = 1;
6410  }
6411 
6412  return 0;
6413 }
6414 
6415 /* this atom should be null (from specs), but some buggy files put the 'moov' atom inside it... */
6416 /* like the files created with Adobe Premiere 5.0, for samples see */
6417 /* http://graphics.tudelft.nl/~wouter/publications/soundtests/ */
6419 {
6420  int err;
6421 
6422  if (atom.size < 8)
6423  return 0; /* continue */
6424  if (avio_rb32(pb) != 0) { /* 0 sized mdat atom... use the 'wide' atom size */
6425  avio_skip(pb, atom.size - 4);
6426  return 0;
6427  }
6428  atom.type = avio_rl32(pb);
6429  atom.size -= 8;
6430  if (atom.type != MKTAG('m','d','a','t')) {
6431  avio_skip(pb, atom.size);
6432  return 0;
6433  }
6434  err = mov_read_mdat(c, pb, atom);
6435  return err;
6436 }
6437 
6439 {
6440 #if CONFIG_ZLIB
6441  FFIOContext ctx;
6442  uint8_t *cmov_data;
6443  uint8_t *moov_data; /* uncompressed data */
6444  long cmov_len, moov_len;
6445  int ret = -1;
6446 
6447  avio_rb32(pb); /* dcom atom */
6448  if (avio_rl32(pb) != MKTAG('d','c','o','m'))
6449  return AVERROR_INVALIDDATA;
6450  if (avio_rl32(pb) != MKTAG('z','l','i','b')) {
6451  av_log(c->fc, AV_LOG_ERROR, "unknown compression for cmov atom !\n");
6452  return AVERROR_INVALIDDATA;
6453  }
6454  avio_rb32(pb); /* cmvd atom */
6455  if (avio_rl32(pb) != MKTAG('c','m','v','d'))
6456  return AVERROR_INVALIDDATA;
6457  moov_len = avio_rb32(pb); /* uncompressed size */
6458  cmov_len = atom.size - 6 * 4;
6459 
6460  cmov_data = av_malloc(cmov_len);
6461  if (!cmov_data)
6462  return AVERROR(ENOMEM);
6463  moov_data = av_malloc(moov_len);
6464  if (!moov_data) {
6465  av_free(cmov_data);
6466  return AVERROR(ENOMEM);
6467  }
6468  ret = ffio_read_size(pb, cmov_data, cmov_len);
6469  if (ret < 0)
6470  goto free_and_return;
6471 
6473  if (uncompress (moov_data, (uLongf *) &moov_len, (const Bytef *)cmov_data, cmov_len) != Z_OK)
6474  goto free_and_return;
6475  ffio_init_read_context(&ctx, moov_data, moov_len);
6476  ctx.pub.seekable = AVIO_SEEKABLE_NORMAL;
6477  atom.type = MKTAG('m','o','o','v');
6478  atom.size = moov_len;
6479  ret = mov_read_default(c, &ctx.pub, atom);
6480 free_and_return:
6481  av_free(moov_data);
6482  av_free(cmov_data);
6483  return ret;
6484 #else
6485  av_log(c->fc, AV_LOG_ERROR, "this file requires zlib support compiled in\n");
6486  return AVERROR(ENOSYS);
6487 #endif
6488 }
6489 
6490 /* edit list atom */
6492 {
6493  MOVStreamContext *sc;
6494  int i, edit_count, version;
6495  int64_t elst_entry_size;
6496 
6497  if (c->fc->nb_streams < 1 || c->ignore_editlist)
6498  return 0;
6499  sc = c->fc->streams[c->fc->nb_streams-1]->priv_data;
6500 
6501  version = avio_r8(pb); /* version */
6502  avio_rb24(pb); /* flags */
6503  edit_count = avio_rb32(pb); /* entries */
6504  atom.size -= 8;
6505 
6506  elst_entry_size = version == 1 ? 20 : 12;
6507  if (atom.size != edit_count * elst_entry_size) {
6508  if (c->fc->strict_std_compliance >= FF_COMPLIANCE_STRICT) {
6509  av_log(c->fc, AV_LOG_ERROR, "Invalid edit list entry_count: %d for elst atom of size: %"PRId64" bytes.\n",
6510  edit_count, atom.size + 8);
6511  return AVERROR_INVALIDDATA;
6512  } else {
6513  edit_count = atom.size / elst_entry_size;
6514  if (edit_count * elst_entry_size != atom.size) {
6515  av_log(c->fc, AV_LOG_WARNING, "ELST atom of %"PRId64" bytes, bigger than %d entries.\n", atom.size, edit_count);
6516  }
6517  }
6518  }
6519 
6520  if (!edit_count)
6521  return 0;
6522  if (sc->elst_data)
6523  av_log(c->fc, AV_LOG_WARNING, "Duplicated ELST atom\n");
6524  av_free(sc->elst_data);
6525  sc->elst_count = 0;
6526  sc->elst_data = av_malloc_array(edit_count, sizeof(*sc->elst_data));
6527  if (!sc->elst_data)
6528  return AVERROR(ENOMEM);
6529 
6530  av_log(c->fc, AV_LOG_TRACE, "track[%u].edit_count = %i\n", c->fc->nb_streams - 1, edit_count);
6531  for (i = 0; i < edit_count && atom.size > 0 && !pb->eof_reached; i++) {
6532  MOVElst *e = &sc->elst_data[i];
6533 
6534  if (version == 1) {
6535  e->duration = avio_rb64(pb);
6536  e->time = avio_rb64(pb);
6537  atom.size -= 16;
6538  } else {
6539  e->duration = avio_rb32(pb); /* segment duration */
6540  e->time = (int32_t)avio_rb32(pb); /* media time */
6541  atom.size -= 8;
6542  }
6543  e->rate = avio_rb32(pb) / 65536.0;
6544  atom.size -= 4;
6545  av_log(c->fc, AV_LOG_TRACE, "duration=%"PRId64" time=%"PRId64" rate=%f\n",
6546  e->duration, e->time, e->rate);
6547 
6548  if (e->time < 0 && e->time != -1 &&
6549  c->fc->strict_std_compliance >= FF_COMPLIANCE_STRICT) {
6550  av_log(c->fc, AV_LOG_ERROR, "Track %d, edit %d: Invalid edit list media time=%"PRId64"\n",
6551  c->fc->nb_streams-1, i, e->time);
6552  return AVERROR_INVALIDDATA;
6553  }
6554  if (e->duration < 0) {
6555  av_log(c->fc, AV_LOG_ERROR, "Track %d, edit %d: Invalid edit list duration=%"PRId64"\n",
6556  c->fc->nb_streams-1, i, e->duration);
6557  return AVERROR_INVALIDDATA;
6558  }
6559  }
6560  sc->elst_count = i;
6561 
6562  return 0;
6563 }
6564 
6566 {
6567  MOVStreamContext *sc;
6568  int err;
6569 
6570  if (c->fc->nb_streams < 1)
6571  return AVERROR_INVALIDDATA;
6572  sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
6573 
6574  if (atom.size % sizeof(uint32_t))
6575  return AVERROR_INVALIDDATA;
6576 
6577  MovTref *tag = mov_add_tref_tag(sc, atom.type);
6578  if (!tag)
6579  return AVERROR(ENOMEM);
6580 
6581  int nb_timecode_track = atom.size >> 2;
6582  for (int i = 0; i < nb_timecode_track; i++) {
6583  if (avio_feof(pb))
6584  return AVERROR_INVALIDDATA;
6585  err = mov_add_tref_id(tag, avio_rb32(pb));
6586  if (err < 0)
6587  return err;
6588  }
6589 
6590  return 0;
6591 }
6592 
6594 {
6595  AVStream *st;
6596  int version, color_range, color_primaries, color_trc, color_space;
6597 
6598  if (c->fc->nb_streams < 1)
6599  return 0;
6600  st = c->fc->streams[c->fc->nb_streams - 1];
6601 
6602  if (atom.size < 5) {
6603  av_log(c->fc, AV_LOG_ERROR, "Empty VP Codec Configuration box\n");
6604  return AVERROR_INVALIDDATA;
6605  }
6606 
6607  version = avio_r8(pb);
6608  if (version != 1) {
6609  av_log(c->fc, AV_LOG_WARNING, "Unsupported VP Codec Configuration box version %d\n", version);
6610  return 0;
6611  }
6612  avio_skip(pb, 3); /* flags */
6613 
6614  avio_skip(pb, 2); /* profile + level */
6615  color_range = avio_r8(pb); /* bitDepth, chromaSubsampling, videoFullRangeFlag */
6616  color_primaries = avio_r8(pb);
6617  color_trc = avio_r8(pb);
6618  color_space = avio_r8(pb);
6619  if (avio_rb16(pb)) /* codecIntializationDataSize */
6620  return AVERROR_INVALIDDATA;
6621 
6624  if (!av_color_transfer_name(color_trc))
6625  color_trc = AVCOL_TRC_UNSPECIFIED;
6626  if (!av_color_space_name(color_space))
6627  color_space = AVCOL_SPC_UNSPECIFIED;
6628 
6631  st->codecpar->color_trc = color_trc;
6632  st->codecpar->color_space = color_space;
6633 
6634  return 0;
6635 }
6636 
6638 {
6639  MOVStreamContext *sc;
6640  int i, version;
6641 
6642  if (c->fc->nb_streams < 1)
6643  return AVERROR_INVALIDDATA;
6644 
6645  sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
6646 
6647  if (atom.size < 5) {
6648  av_log(c->fc, AV_LOG_ERROR, "Empty Mastering Display Metadata box\n");
6649  return AVERROR_INVALIDDATA;
6650  }
6651 
6652  version = avio_r8(pb);
6653  if (version) {
6654  av_log(c->fc, AV_LOG_WARNING, "Unsupported Mastering Display Metadata box version %d\n", version);
6655  return 0;
6656  }
6657  if (sc->mastering) {
6658  av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicate Mastering Display Metadata\n");
6659  return 0;
6660  }
6661 
6662  avio_skip(pb, 3); /* flags */
6663 
6665  if (!sc->mastering)
6666  return AVERROR(ENOMEM);
6667 
6668  for (i = 0; i < 3; i++) {
6669  sc->mastering->display_primaries[i][0] = av_make_q(avio_rb16(pb), 1 << 16);
6670  sc->mastering->display_primaries[i][1] = av_make_q(avio_rb16(pb), 1 << 16);
6671  }
6672  sc->mastering->white_point[0] = av_make_q(avio_rb16(pb), 1 << 16);
6673  sc->mastering->white_point[1] = av_make_q(avio_rb16(pb), 1 << 16);
6674 
6675  sc->mastering->max_luminance = av_make_q(avio_rb32(pb), 1 << 8);
6676  sc->mastering->min_luminance = av_make_q(avio_rb32(pb), 1 << 14);
6677 
6678  sc->mastering->has_primaries = 1;
6679  sc->mastering->has_luminance = 1;
6680 
6681  return 0;
6682 }
6683 
6685 {
6686  MOVStreamContext *sc;
6687  const int mapping[3] = {1, 2, 0};
6688  const int chroma_den = 50000;
6689  const int luma_den = 10000;
6690  int i;
6691 
6692  if (c->fc->nb_streams < 1)
6693  return AVERROR_INVALIDDATA;
6694 
6695  sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
6696 
6697  if (atom.size < 24) {
6698  av_log(c->fc, AV_LOG_ERROR, "Invalid Mastering Display Color Volume box\n");
6699  return AVERROR_INVALIDDATA;
6700  }
6701 
6702  if (sc->mastering) {
6703  av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicate Mastering Display Color Volume\n");
6704  return 0;
6705  }
6706 
6708  if (!sc->mastering)
6709  return AVERROR(ENOMEM);
6710 
6711  for (i = 0; i < 3; i++) {
6712  const int j = mapping[i];
6713  sc->mastering->display_primaries[j][0] = av_make_q(avio_rb16(pb), chroma_den);
6714  sc->mastering->display_primaries[j][1] = av_make_q(avio_rb16(pb), chroma_den);
6715  }
6716  sc->mastering->white_point[0] = av_make_q(avio_rb16(pb), chroma_den);
6717  sc->mastering->white_point[1] = av_make_q(avio_rb16(pb), chroma_den);
6718 
6719  sc->mastering->max_luminance = av_make_q(avio_rb32(pb), luma_den);
6720  sc->mastering->min_luminance = av_make_q(avio_rb32(pb), luma_den);
6721 
6722  sc->mastering->has_luminance = 1;
6723  sc->mastering->has_primaries = 1;
6724 
6725  return 0;
6726 }
6727 
6729 {
6730  MOVStreamContext *sc;
6731  int version;
6732 
6733  if (c->fc->nb_streams < 1)
6734  return AVERROR_INVALIDDATA;
6735 
6736  sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
6737 
6738  if (atom.size < 5) {
6739  av_log(c->fc, AV_LOG_ERROR, "Empty Content Light Level box\n");
6740  return AVERROR_INVALIDDATA;
6741  }
6742 
6743  version = avio_r8(pb);
6744  if (version) {
6745  av_log(c->fc, AV_LOG_WARNING, "Unsupported Content Light Level box version %d\n", version);
6746  return 0;
6747  }
6748  avio_skip(pb, 3); /* flags */
6749 
6750  if (sc->coll){
6751  av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicate COLL\n");
6752  return 0;
6753  }
6754 
6756  if (!sc->coll)
6757  return AVERROR(ENOMEM);
6758 
6759  sc->coll->MaxCLL = avio_rb16(pb);
6760  sc->coll->MaxFALL = avio_rb16(pb);
6761 
6762  return 0;
6763 }
6764 
6766 {
6767  MOVStreamContext *sc;
6768 
6769  if (c->fc->nb_streams < 1)
6770  return AVERROR_INVALIDDATA;
6771 
6772  sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
6773 
6774  if (atom.size < 4) {
6775  av_log(c->fc, AV_LOG_ERROR, "Empty Content Light Level Info box\n");
6776  return AVERROR_INVALIDDATA;
6777  }
6778 
6779  if (sc->coll){
6780  av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicate CLLI/COLL\n");
6781  return 0;
6782  }
6783 
6785  if (!sc->coll)
6786  return AVERROR(ENOMEM);
6787 
6788  sc->coll->MaxCLL = avio_rb16(pb);
6789  sc->coll->MaxFALL = avio_rb16(pb);
6790 
6791  return 0;
6792 }
6793 
6795 {
6796  MOVStreamContext *sc;
6797  const int illuminance_den = 10000;
6798  const int ambient_den = 50000;
6799  if (c->fc->nb_streams < 1)
6800  return AVERROR_INVALIDDATA;
6801  sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
6802  if (atom.size < 6) {
6803  av_log(c->fc, AV_LOG_ERROR, "Empty Ambient Viewing Environment Info box\n");
6804  return AVERROR_INVALIDDATA;
6805  }
6806  if (sc->ambient){
6807  av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicate AMVE\n");
6808  return 0;
6809  }
6811  if (!sc->ambient)
6812  return AVERROR(ENOMEM);
6813  sc->ambient->ambient_illuminance = av_make_q(avio_rb32(pb), illuminance_den);
6814  sc->ambient->ambient_light_x = av_make_q(avio_rb16(pb), ambient_den);
6815  sc->ambient->ambient_light_y = av_make_q(avio_rb16(pb), ambient_den);
6816  return 0;
6817 }
6818 
6820 {
6821  AVStream *st;
6822  MOVStreamContext *sc;
6823  enum AVStereo3DType type;
6824  int mode;
6825 
6826  if (c->fc->nb_streams < 1)
6827  return 0;
6828 
6829  st = c->fc->streams[c->fc->nb_streams - 1];
6830  sc = st->priv_data;
6831 
6832  if (atom.size < 5) {
6833  av_log(c->fc, AV_LOG_ERROR, "Empty stereoscopic video box\n");
6834  return AVERROR_INVALIDDATA;
6835  }
6836 
6837  if (sc->stereo3d)
6838  return AVERROR_INVALIDDATA;
6839 
6840  avio_skip(pb, 4); /* version + flags */
6841 
6842  mode = avio_r8(pb);
6843  switch (mode) {
6844  case 0:
6845  type = AV_STEREO3D_2D;
6846  break;
6847  case 1:
6849  break;
6850  case 2:
6852  break;
6853  default:
6854  av_log(c->fc, AV_LOG_WARNING, "Unknown st3d mode value %d\n", mode);
6855  return 0;
6856  }
6857 
6859  if (!sc->stereo3d)
6860  return AVERROR(ENOMEM);
6861 
6862  sc->stereo3d->type = type;
6863  return 0;
6864 }
6865 
6867 {
6868  AVStream *st;
6869  MOVStreamContext *sc;
6870  int size = 0;
6871  int64_t remaining;
6872  uint32_t tag = 0;
6874 
6875  if (c->fc->nb_streams < 1)
6876  return 0;
6877 
6878  st = c->fc->streams[c->fc->nb_streams - 1];
6879  sc = st->priv_data;
6880 
6881  remaining = atom.size;
6882  while (remaining > 0) {
6883  size = avio_rb32(pb);
6884  if (size < 8 || size > remaining ) {
6885  av_log(c->fc, AV_LOG_ERROR, "Invalid child size in pack box\n");
6886  return AVERROR_INVALIDDATA;
6887  }
6888 
6889  tag = avio_rl32(pb);
6890  switch (tag) {
6891  case MKTAG('p','k','i','n'): {
6892  if (size != 16) {
6893  av_log(c->fc, AV_LOG_ERROR, "Invalid size of pkin box: %d\n", size);
6894  return AVERROR_INVALIDDATA;
6895  }
6896  avio_skip(pb, 1); // version
6897  avio_skip(pb, 3); // flags
6898 
6899  tag = avio_rl32(pb);
6900  switch (tag) {
6901  case MKTAG('s','i','d','e'):
6903  break;
6904  case MKTAG('o','v','e','r'):
6906  break;
6907  case 0:
6908  // This means value will be set in another layer
6909  break;
6910  default:
6911  av_log(c->fc, AV_LOG_WARNING, "Unknown tag in pkin: %s\n",
6912  av_fourcc2str(tag));
6913  avio_skip(pb, size - 8);
6914  break;
6915  }
6916 
6917  break;
6918  }
6919  default:
6920  av_log(c->fc, AV_LOG_WARNING, "Unknown tag in pack: %s\n",
6921  av_fourcc2str(tag));
6922  avio_skip(pb, size - 8);
6923  break;
6924  }
6925  remaining -= size;
6926  }
6927 
6928  if (remaining != 0) {
6929  av_log(c->fc, AV_LOG_ERROR, "Broken pack box\n");
6930  return AVERROR_INVALIDDATA;
6931  }
6932 
6933  if (type == AV_STEREO3D_2D)
6934  return 0;
6935 
6936  if (!sc->stereo3d) {
6938  if (!sc->stereo3d)
6939  return AVERROR(ENOMEM);
6940  }
6941 
6942  sc->stereo3d->type = type;
6943 
6944  return 0;
6945 }
6946 
6948 {
6949  AVStream *st;
6950  MOVStreamContext *sc;
6951  int size, version, layout;
6952  int32_t yaw, pitch, roll;
6953  uint32_t l = 0, t = 0, r = 0, b = 0;
6954  uint32_t tag, padding = 0;
6955  enum AVSphericalProjection projection;
6956 
6957  if (c->fc->nb_streams < 1)
6958  return 0;
6959 
6960  st = c->fc->streams[c->fc->nb_streams - 1];
6961  sc = st->priv_data;
6962 
6963  if (atom.size < 8) {
6964  av_log(c->fc, AV_LOG_ERROR, "Empty spherical video box\n");
6965  return AVERROR_INVALIDDATA;
6966  }
6967 
6968  size = avio_rb32(pb);
6969  if (size <= 12 || size > atom.size)
6970  return AVERROR_INVALIDDATA;
6971 
6972  tag = avio_rl32(pb);
6973  if (tag != MKTAG('s','v','h','d')) {
6974  av_log(c->fc, AV_LOG_ERROR, "Missing spherical video header\n");
6975  return 0;
6976  }
6977  version = avio_r8(pb);
6978  if (version != 0) {
6979  av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
6980  version);
6981  return 0;
6982  }
6983  avio_skip(pb, 3); /* flags */
6984  avio_skip(pb, size - 12); /* metadata_source */
6985 
6986  size = avio_rb32(pb);
6987  if (size > atom.size)
6988  return AVERROR_INVALIDDATA;
6989 
6990  tag = avio_rl32(pb);
6991  if (tag != MKTAG('p','r','o','j')) {
6992  av_log(c->fc, AV_LOG_ERROR, "Missing projection box\n");
6993  return 0;
6994  }
6995 
6996  size = avio_rb32(pb);
6997  if (size > atom.size)
6998  return AVERROR_INVALIDDATA;
6999 
7000  tag = avio_rl32(pb);
7001  if (tag != MKTAG('p','r','h','d')) {
7002  av_log(c->fc, AV_LOG_ERROR, "Missing projection header box\n");
7003  return 0;
7004  }
7005  version = avio_r8(pb);
7006  if (version != 0) {
7007  av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
7008  version);
7009  return 0;
7010  }
7011  avio_skip(pb, 3); /* flags */
7012 
7013  /* 16.16 fixed point */
7014  yaw = avio_rb32(pb);
7015  pitch = avio_rb32(pb);
7016  roll = avio_rb32(pb);
7017 
7018  size = avio_rb32(pb);
7019  if (size > atom.size)
7020  return AVERROR_INVALIDDATA;
7021 
7022  tag = avio_rl32(pb);
7023  version = avio_r8(pb);
7024  if (version != 0) {
7025  av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
7026  version);
7027  return 0;
7028  }
7029  avio_skip(pb, 3); /* flags */
7030  switch (tag) {
7031  case MKTAG('c','b','m','p'):
7032  layout = avio_rb32(pb);
7033  if (layout) {
7034  av_log(c->fc, AV_LOG_WARNING,
7035  "Unsupported cubemap layout %d\n", layout);
7036  return 0;
7037  }
7038  projection = AV_SPHERICAL_CUBEMAP;
7039  padding = avio_rb32(pb);
7040  break;
7041  case MKTAG('e','q','u','i'):
7042  t = avio_rb32(pb);
7043  b = avio_rb32(pb);
7044  l = avio_rb32(pb);
7045  r = avio_rb32(pb);
7046 
7047  if (b >= UINT_MAX - t || r >= UINT_MAX - l) {
7048  av_log(c->fc, AV_LOG_ERROR,
7049  "Invalid bounding rectangle coordinates "
7050  "%"PRIu32",%"PRIu32",%"PRIu32",%"PRIu32"\n", l, t, r, b);
7051  return AVERROR_INVALIDDATA;
7052  }
7053 
7054  if (l || t || r || b)
7055  projection = AV_SPHERICAL_EQUIRECTANGULAR_TILE;
7056  else
7057  projection = AV_SPHERICAL_EQUIRECTANGULAR;
7058  break;
7059  default:
7060  av_log(c->fc, AV_LOG_ERROR, "Unknown projection type: %s\n", av_fourcc2str(tag));
7061  return 0;
7062  }
7063 
7065  if (!sc->spherical)
7066  return AVERROR(ENOMEM);
7067 
7068  sc->spherical->projection = projection;
7069 
7070  sc->spherical->yaw = yaw;
7071  sc->spherical->pitch = pitch;
7072  sc->spherical->roll = roll;
7073 
7074  sc->spherical->padding = padding;
7075 
7076  sc->spherical->bound_left = l;
7077  sc->spherical->bound_top = t;
7078  sc->spherical->bound_right = r;
7079  sc->spherical->bound_bottom = b;
7080 
7081  return 0;
7082 }
7083 
7085 {
7086  AVStream *st;
7087  MOVStreamContext *sc;
7088  int size;
7089  uint32_t tag;
7090  enum AVSphericalProjection projection;
7091 
7092  if (c->fc->nb_streams < 1)
7093  return 0;
7094 
7095  st = c->fc->streams[c->fc->nb_streams - 1];
7096  sc = st->priv_data;
7097 
7098  if (atom.size < 16) {
7099  av_log(c->fc, AV_LOG_ERROR, "Invalid size for proj box: %"PRIu64"\n", atom.size);
7100  return AVERROR_INVALIDDATA;
7101  }
7102 
7103  size = avio_rb32(pb);
7104  if (size < 16) {
7105  av_log(c->fc, AV_LOG_ERROR, "Invalid size for prji box: %d\n", size);
7106  return AVERROR_INVALIDDATA;
7107  } else if (size > 16) {
7108  av_log(c->fc, AV_LOG_WARNING, "Box has more bytes (%d) than prji box required (16) \n", size);
7109  }
7110 
7111  tag = avio_rl32(pb);
7112  if (tag != MKTAG('p','r','j','i')) {
7113  av_log(c->fc, AV_LOG_ERROR, "Invalid child box of proj box: %s\n",
7114  av_fourcc2str(tag));
7115  return AVERROR_INVALIDDATA;
7116  }
7117 
7118  // version and flags, only support (0, 0)
7119  unsigned n = avio_rl32(pb);
7120  if (n != 0) {
7121  av_log(c->fc, AV_LOG_ERROR, "prji version %u, flag %u are not supported\n",
7122  n & 0xFF, n >> 8);
7123  return AVERROR_PATCHWELCOME;
7124  }
7125 
7126  tag = avio_rl32(pb);
7127  switch (tag) {
7128  case MKTAG('r','e','c','t'):
7129  projection = AV_SPHERICAL_RECTILINEAR;
7130  break;
7131  case MKTAG('e','q','u','i'):
7132  projection = AV_SPHERICAL_EQUIRECTANGULAR;
7133  break;
7134  case MKTAG('h','e','q','u'):
7135  projection = AV_SPHERICAL_HALF_EQUIRECTANGULAR;
7136  break;
7137  case MKTAG('f','i','s','h'):
7138  projection = AV_SPHERICAL_FISHEYE;
7139  break;
7140  case MKTAG('p','r','i','m'):
7141  projection = AV_SPHERICAL_PARAMETRIC_IMMERSIVE;
7142  break;
7143  default:
7144  av_log(c->fc, AV_LOG_ERROR, "Invalid projection type in prji box: %s\n", av_fourcc2str(tag));
7145  return AVERROR_INVALIDDATA;
7146  }
7147 
7149  if (!sc->spherical)
7150  return AVERROR(ENOMEM);
7151 
7152  sc->spherical->projection = projection;
7153 
7154  return 0;
7155 }
7156 
7158 {
7159  AVStream *st;
7160  MOVStreamContext *sc;
7161  int size, flags = 0;
7162  int64_t remaining;
7163  uint32_t tag, baseline = 0;
7166  enum AVStereo3DPrimaryEye primary_eye = AV_PRIMARY_EYE_NONE;
7167  AVRational horizontal_disparity_adjustment = { 0, 1 };
7168 
7169  if (c->fc->nb_streams < 1)
7170  return 0;
7171 
7172  st = c->fc->streams[c->fc->nb_streams - 1];
7173  sc = st->priv_data;
7174 
7175  remaining = atom.size;
7176  while (remaining > 0) {
7177  size = avio_rb32(pb);
7178  if (size < 8 || size > remaining ) {
7179  av_log(c->fc, AV_LOG_ERROR, "Invalid child size in eyes box\n");
7180  return AVERROR_INVALIDDATA;
7181  }
7182 
7183  tag = avio_rl32(pb);
7184  switch (tag) {
7185  case MKTAG('s','t','r','i'): {
7186  int has_right, has_left;
7187  uint8_t tmp;
7188  if (size != 13) {
7189  av_log(c->fc, AV_LOG_ERROR, "Invalid size of stri box: %d\n", size);
7190  return AVERROR_INVALIDDATA;
7191  }
7192  avio_skip(pb, 1); // version
7193  avio_skip(pb, 3); // flags
7194 
7195  tmp = avio_r8(pb);
7196 
7197  // eye_views_reversed
7198  if (tmp & 8) {
7200  }
7201  // has_additional_views
7202  if (tmp & 4) {
7203  // skip...
7204  }
7205 
7206  has_right = tmp & 2; // has_right_eye_view
7207  has_left = tmp & 1; // has_left_eye_view
7208 
7209  if (has_left && has_right)
7210  view = AV_STEREO3D_VIEW_PACKED;
7211  else if (has_left)
7212  view = AV_STEREO3D_VIEW_LEFT;
7213  else if (has_right)
7214  view = AV_STEREO3D_VIEW_RIGHT;
7215  if (has_left || has_right)
7217 
7218  break;
7219  }
7220  case MKTAG('h','e','r','o'): {
7221  int tmp;
7222  if (size != 13) {
7223  av_log(c->fc, AV_LOG_ERROR, "Invalid size of hero box: %d\n", size);
7224  return AVERROR_INVALIDDATA;
7225  }
7226  avio_skip(pb, 1); // version
7227  avio_skip(pb, 3); // flags
7228 
7229  tmp = avio_r8(pb);
7230  if (tmp == 0)
7231  primary_eye = AV_PRIMARY_EYE_NONE;
7232  else if (tmp == 1)
7233  primary_eye = AV_PRIMARY_EYE_LEFT;
7234  else if (tmp == 2)
7235  primary_eye = AV_PRIMARY_EYE_RIGHT;
7236  else
7237  av_log(c->fc, AV_LOG_WARNING, "Unknown hero eye type: %d\n", tmp);
7238 
7239  break;
7240  }
7241  case MKTAG('c','a','m','s'): {
7242  uint32_t subtag;
7243  int subsize;
7244  if (size != 24) {
7245  av_log(c->fc, AV_LOG_ERROR, "Invalid size of cams box: %d\n", size);
7246  return AVERROR_INVALIDDATA;
7247  }
7248 
7249  subsize = avio_rb32(pb);
7250  if (subsize != 16) {
7251  av_log(c->fc, AV_LOG_ERROR, "Invalid size of blin box: %d\n", size);
7252  return AVERROR_INVALIDDATA;
7253  }
7254 
7255  subtag = avio_rl32(pb);
7256  if (subtag != MKTAG('b','l','i','n')) {
7257  av_log(c->fc, AV_LOG_ERROR, "Expected blin box, got %s\n",
7258  av_fourcc2str(subtag));
7259  return AVERROR_INVALIDDATA;
7260  }
7261 
7262  avio_skip(pb, 1); // version
7263  avio_skip(pb, 3); // flags
7264 
7265  baseline = avio_rb32(pb);
7266 
7267  break;
7268  }
7269  case MKTAG('c','m','f','y'): {
7270  uint32_t subtag;
7271  int subsize;
7272  int32_t adjustment;
7273  if (size != 24) {
7274  av_log(c->fc, AV_LOG_ERROR, "Invalid size of cmfy box: %d\n", size);
7275  return AVERROR_INVALIDDATA;
7276  }
7277 
7278  subsize = avio_rb32(pb);
7279  if (subsize != 16) {
7280  av_log(c->fc, AV_LOG_ERROR, "Invalid size of dadj box: %d\n", size);
7281  return AVERROR_INVALIDDATA;
7282  }
7283 
7284  subtag = avio_rl32(pb);
7285  if (subtag != MKTAG('d','a','d','j')) {
7286  av_log(c->fc, AV_LOG_ERROR, "Expected dadj box, got %s\n",
7287  av_fourcc2str(subtag));
7288  return AVERROR_INVALIDDATA;
7289  }
7290 
7291  avio_skip(pb, 1); // version
7292  avio_skip(pb, 3); // flags
7293 
7294  adjustment = (int32_t) avio_rb32(pb);
7295 
7296  horizontal_disparity_adjustment.num = (int) adjustment;
7297  horizontal_disparity_adjustment.den = 10000;
7298 
7299  break;
7300  }
7301  default:
7302  av_log(c->fc, AV_LOG_WARNING, "Unknown tag in eyes: %s\n",
7303  av_fourcc2str(tag));
7304  avio_skip(pb, size - 8);
7305  break;
7306  }
7307  remaining -= size;
7308  }
7309 
7310  if (remaining != 0) {
7311  av_log(c->fc, AV_LOG_ERROR, "Broken eyes box\n");
7312  return AVERROR_INVALIDDATA;
7313  }
7314 
7315  if (type == AV_STEREO3D_2D)
7316  return 0;
7317 
7318  if (!sc->stereo3d) {
7320  if (!sc->stereo3d)
7321  return AVERROR(ENOMEM);
7322  }
7323 
7324  sc->stereo3d->flags = flags;
7325  sc->stereo3d->type = type;
7326  sc->stereo3d->view = view;
7327  sc->stereo3d->primary_eye = primary_eye;
7328  sc->stereo3d->baseline = baseline;
7329  sc->stereo3d->horizontal_disparity_adjustment = horizontal_disparity_adjustment;
7330 
7331  return 0;
7332 }
7333 
7335 {
7336  int size;
7337  int64_t remaining;
7338  uint32_t tag;
7339 
7340  if (c->fc->nb_streams < 1)
7341  return 0;
7342 
7343  if (atom.size < 8) {
7344  av_log(c->fc, AV_LOG_ERROR, "Empty video extension usage box\n");
7345  return AVERROR_INVALIDDATA;
7346  }
7347 
7348  remaining = atom.size;
7349  while (remaining > 0) {
7350  size = avio_rb32(pb);
7351  if (size < 8 || size > remaining ) {
7352  av_log(c->fc, AV_LOG_ERROR, "Invalid child size in vexu box\n");
7353  return AVERROR_INVALIDDATA;
7354  }
7355 
7356  tag = avio_rl32(pb);
7357  switch (tag) {
7358  case MKTAG('p','r','o','j'): {
7359  MOVAtom proj = { tag, size - 8 };
7360  int ret = mov_read_vexu_proj(c, pb, proj);
7361  if (ret < 0)
7362  return ret;
7363  break;
7364  }
7365  case MKTAG('e','y','e','s'): {
7366  MOVAtom eyes = { tag, size - 8 };
7367  int ret = mov_read_eyes(c, pb, eyes);
7368  if (ret < 0)
7369  return ret;
7370  break;
7371  }
7372  case MKTAG('p','a','c','k'): {
7373  MOVAtom pack = { tag, size - 8 };
7374  int ret = mov_read_pack(c, pb, pack);
7375  if (ret < 0)
7376  return ret;
7377  break;
7378  }
7379  default:
7380  av_log(c->fc, AV_LOG_WARNING, "Unknown tag in vexu: %s\n",
7381  av_fourcc2str(tag));
7382  avio_skip(pb, size - 8);
7383  break;
7384  }
7385  remaining -= size;
7386  }
7387 
7388  if (remaining != 0) {
7389  av_log(c->fc, AV_LOG_ERROR, "Broken vexu box\n");
7390  return AVERROR_INVALIDDATA;
7391  }
7392 
7393  return 0;
7394 }
7395 
7397 {
7398  AVStream *st;
7399  MOVStreamContext *sc;
7400 
7401  if (c->fc->nb_streams < 1)
7402  return 0;
7403 
7404  st = c->fc->streams[c->fc->nb_streams - 1];
7405  sc = st->priv_data;
7406 
7407  if (atom.size != 4) {
7408  av_log(c->fc, AV_LOG_ERROR, "Invalid size of hfov box: %"PRIu64"\n", atom.size);
7409  return AVERROR_INVALIDDATA;
7410  }
7411 
7412 
7413  if (!sc->stereo3d) {
7415  if (!sc->stereo3d)
7416  return AVERROR(ENOMEM);
7417  }
7418 
7420  sc->stereo3d->horizontal_field_of_view.den = 1000; // thousands of a degree
7421 
7422  return 0;
7423 }
7424 
7426 {
7427  int ret = 0;
7428  uint8_t *buffer = av_malloc(len + 1);
7429  const char *val;
7430 
7431  if (!buffer)
7432  return AVERROR(ENOMEM);
7433  buffer[len] = '\0';
7434 
7435  ret = ffio_read_size(pb, buffer, len);
7436  if (ret < 0)
7437  goto out;
7438 
7439  /* Check for mandatory keys and values, try to support XML as best-effort */
7440  if (!sc->spherical &&
7441  av_stristr(buffer, "<GSpherical:StitchingSoftware>") &&
7442  (val = av_stristr(buffer, "<GSpherical:Spherical>")) &&
7443  av_stristr(val, "true") &&
7444  (val = av_stristr(buffer, "<GSpherical:Stitched>")) &&
7445  av_stristr(val, "true") &&
7446  (val = av_stristr(buffer, "<GSpherical:ProjectionType>")) &&
7447  av_stristr(val, "equirectangular")) {
7449  if (!sc->spherical)
7450  goto out;
7451 
7453 
7454  if (av_stristr(buffer, "<GSpherical:StereoMode>") && !sc->stereo3d) {
7455  enum AVStereo3DType mode;
7456 
7457  if (av_stristr(buffer, "left-right"))
7459  else if (av_stristr(buffer, "top-bottom"))
7461  else
7462  mode = AV_STEREO3D_2D;
7463 
7465  if (!sc->stereo3d)
7466  goto out;
7467 
7468  sc->stereo3d->type = mode;
7469  }
7470 
7471  /* orientation */
7472  val = av_stristr(buffer, "<GSpherical:InitialViewHeadingDegrees>");
7473  if (val)
7474  sc->spherical->yaw = strtol(val, NULL, 10) * (1 << 16);
7475  val = av_stristr(buffer, "<GSpherical:InitialViewPitchDegrees>");
7476  if (val)
7477  sc->spherical->pitch = strtol(val, NULL, 10) * (1 << 16);
7478  val = av_stristr(buffer, "<GSpherical:InitialViewRollDegrees>");
7479  if (val)
7480  sc->spherical->roll = strtol(val, NULL, 10) * (1 << 16);
7481  }
7482 
7483 out:
7484  av_free(buffer);
7485  return ret;
7486 }
7487 
7489 {
7490  AVStream *st;
7491  MOVStreamContext *sc;
7492  int64_t ret;
7493  AVUUID uuid;
7494  static const AVUUID uuid_isml_manifest = {
7495  0xa5, 0xd4, 0x0b, 0x30, 0xe8, 0x14, 0x11, 0xdd,
7496  0xba, 0x2f, 0x08, 0x00, 0x20, 0x0c, 0x9a, 0x66
7497  };
7498  static const AVUUID uuid_xmp = {
7499  0xbe, 0x7a, 0xcf, 0xcb, 0x97, 0xa9, 0x42, 0xe8,
7500  0x9c, 0x71, 0x99, 0x94, 0x91, 0xe3, 0xaf, 0xac
7501  };
7502  static const AVUUID uuid_spherical = {
7503  0xff, 0xcc, 0x82, 0x63, 0xf8, 0x55, 0x4a, 0x93,
7504  0x88, 0x14, 0x58, 0x7a, 0x02, 0x52, 0x1f, 0xdd,
7505  };
7506 
7507  if (atom.size < AV_UUID_LEN || atom.size >= FFMIN(INT_MAX, SIZE_MAX))
7508  return AVERROR_INVALIDDATA;
7509 
7510  if (c->fc->nb_streams < 1)
7511  return 0;
7512  st = c->fc->streams[c->fc->nb_streams - 1];
7513  sc = st->priv_data;
7514 
7515  ret = ffio_read_size(pb, uuid, AV_UUID_LEN);
7516  if (ret < 0)
7517  return ret;
7518  if (av_uuid_equal(uuid, uuid_isml_manifest)) {
7519  uint8_t *buffer, *ptr;
7520  char *endptr;
7521  size_t len = atom.size - AV_UUID_LEN;
7522 
7523  if (len < 4) {
7524  return AVERROR_INVALIDDATA;
7525  }
7526  ret = avio_skip(pb, 4); // zeroes
7527  len -= 4;
7528 
7529  buffer = av_mallocz(len + 1);
7530  if (!buffer) {
7531  return AVERROR(ENOMEM);
7532  }
7533  ret = ffio_read_size(pb, buffer, len);
7534  if (ret < 0) {
7535  av_free(buffer);
7536  return ret;
7537  }
7538 
7539  ptr = buffer;
7540  while ((ptr = av_stristr(ptr, "systemBitrate=\""))) {
7541  ptr += sizeof("systemBitrate=\"") - 1;
7542  c->bitrates_count++;
7543  c->bitrates = av_realloc_f(c->bitrates, c->bitrates_count, sizeof(*c->bitrates));
7544  if (!c->bitrates) {
7545  c->bitrates_count = 0;
7546  av_free(buffer);
7547  return AVERROR(ENOMEM);
7548  }
7549  errno = 0;
7550  ret = strtol(ptr, &endptr, 10);
7551  if (ret < 0 || errno || *endptr != '"') {
7552  c->bitrates[c->bitrates_count - 1] = 0;
7553  } else {
7554  c->bitrates[c->bitrates_count - 1] = ret;
7555  }
7556  }
7557 
7558  av_free(buffer);
7559  } else if (av_uuid_equal(uuid, uuid_xmp)) {
7560  uint8_t *buffer;
7561  size_t len = atom.size - AV_UUID_LEN;
7562  if (c->export_xmp) {
7563  buffer = av_mallocz(len + 1);
7564  if (!buffer) {
7565  return AVERROR(ENOMEM);
7566  }
7567  ret = ffio_read_size(pb, buffer, len);
7568  if (ret < 0) {
7569  av_free(buffer);
7570  return ret;
7571  }
7572  buffer[len] = '\0';
7573  av_dict_set(&c->fc->metadata, "xmp",
7575  } else {
7576  // skip all uuid atom, which makes it fast for long uuid-xmp file
7577  ret = avio_skip(pb, len);
7578  if (ret < 0)
7579  return ret;
7580  }
7581  } else if (av_uuid_equal(uuid, uuid_spherical)) {
7582  size_t len = atom.size - AV_UUID_LEN;
7583  ret = mov_parse_uuid_spherical(sc, pb, len);
7584  if (ret < 0)
7585  return ret;
7586  if (!sc->spherical)
7587  av_log(c->fc, AV_LOG_WARNING, "Invalid spherical metadata found\n");
7588  }
7589 
7590  return 0;
7591 }
7592 
7594 {
7595  int ret;
7596  uint8_t content[16];
7597 
7598  if (atom.size < 8)
7599  return 0;
7600 
7601  ret = ffio_read_size(pb, content, FFMIN(sizeof(content), atom.size));
7602  if (ret < 0)
7603  return ret;
7604 
7605  if ( !c->found_moov
7606  && !c->found_mdat
7607  && !memcmp(content, "Anevia\x1A\x1A", 8)
7608  && c->use_mfra_for == FF_MOV_FLAG_MFRA_AUTO) {
7609  c->use_mfra_for = FF_MOV_FLAG_MFRA_PTS;
7610  }
7611 
7612  return 0;
7613 }
7614 
7616 {
7617  uint32_t format = avio_rl32(pb);
7618  MOVStreamContext *sc;
7619  enum AVCodecID id;
7620  AVStream *st;
7621 
7622  if (c->fc->nb_streams < 1)
7623  return 0;
7624  st = c->fc->streams[c->fc->nb_streams - 1];
7625  sc = st->priv_data;
7626 
7627  switch (sc->format)
7628  {
7629  case MKTAG('e','n','c','v'): // encrypted video
7630  case MKTAG('e','n','c','a'): // encrypted audio
7631  id = mov_codec_id(st, format);
7632  if (st->codecpar->codec_id != AV_CODEC_ID_NONE &&
7633  st->codecpar->codec_id != id) {
7634  av_log(c->fc, AV_LOG_WARNING,
7635  "ignoring 'frma' atom of '%.4s', stream has codec id %d\n",
7636  (char*)&format, st->codecpar->codec_id);
7637  break;
7638  }
7639 
7640  st->codecpar->codec_id = id;
7641  sc->format = format;
7642  break;
7643 
7644  default:
7645  if (format != sc->format) {
7646  av_log(c->fc, AV_LOG_WARNING,
7647  "ignoring 'frma' atom of '%.4s', stream format is '%.4s'\n",
7648  (char*)&format, (char*)&sc->format);
7649  }
7650  break;
7651  }
7652 
7653  return 0;
7654 }
7655 
7656 /**
7657  * Gets the current encryption info and associated current stream context. If
7658  * we are parsing a track fragment, this will return the specific encryption
7659  * info for this fragment; otherwise this will return the global encryption
7660  * info for the current stream.
7661  */
7663 {
7664  MOVFragmentStreamInfo *frag_stream_info;
7665  AVStream *st;
7666  int i;
7667 
7668  frag_stream_info = get_current_frag_stream_info(&c->frag_index);
7669  if (frag_stream_info) {
7670  for (i = 0; i < c->fc->nb_streams; i++) {
7671  *sc = c->fc->streams[i]->priv_data;
7672  if ((*sc)->id == frag_stream_info->id) {
7673  st = c->fc->streams[i];
7674  break;
7675  }
7676  }
7677  if (i == c->fc->nb_streams)
7678  return 0;
7679  *sc = st->priv_data;
7680 
7681  if (!frag_stream_info->encryption_index) {
7682  // If this stream isn't encrypted, don't create the index.
7683  if (!(*sc)->cenc.default_encrypted_sample)
7684  return 0;
7685  frag_stream_info->encryption_index = av_mallocz(sizeof(*frag_stream_info->encryption_index));
7686  if (!frag_stream_info->encryption_index)
7687  return AVERROR(ENOMEM);
7688  }
7689  *encryption_index = frag_stream_info->encryption_index;
7690  return 1;
7691  } else {
7692  // No current track fragment, using stream level encryption info.
7693 
7694  if (c->fc->nb_streams < 1)
7695  return 0;
7696  st = c->fc->streams[c->fc->nb_streams - 1];
7697  *sc = st->priv_data;
7698 
7699  if (!(*sc)->cenc.encryption_index) {
7700  // If this stream isn't encrypted, don't create the index.
7701  if (!(*sc)->cenc.default_encrypted_sample)
7702  return 0;
7703  (*sc)->cenc.encryption_index = av_mallocz(sizeof(*frag_stream_info->encryption_index));
7704  if (!(*sc)->cenc.encryption_index)
7705  return AVERROR(ENOMEM);
7706  }
7707 
7708  *encryption_index = (*sc)->cenc.encryption_index;
7709  return 1;
7710  }
7711 }
7712 
7714 {
7715  int i, ret;
7716  unsigned int subsample_count;
7717  AVSubsampleEncryptionInfo *subsamples;
7718 
7719  if (!sc->cenc.default_encrypted_sample) {
7720  av_log(c->fc, AV_LOG_ERROR, "Missing schm or tenc\n");
7721  return AVERROR_INVALIDDATA;
7722  }
7723 
7724  if (sc->cenc.per_sample_iv_size || use_subsamples) {
7726  if (!*sample)
7727  return AVERROR(ENOMEM);
7728  } else
7729  *sample = NULL;
7730 
7731  if (sc->cenc.per_sample_iv_size != 0) {
7732  if ((ret = ffio_read_size(pb, (*sample)->iv, sc->cenc.per_sample_iv_size)) < 0) {
7733  av_log(c->fc, AV_LOG_ERROR, "failed to read the initialization vector\n");
7735  *sample = NULL;
7736  return ret;
7737  }
7738  }
7739 
7740  if (use_subsamples) {
7741  subsample_count = avio_rb16(pb);
7742  av_free((*sample)->subsamples);
7743  (*sample)->subsamples = av_calloc(subsample_count, sizeof(*subsamples));
7744  if (!(*sample)->subsamples) {
7746  *sample = NULL;
7747  return AVERROR(ENOMEM);
7748  }
7749 
7750  for (i = 0; i < subsample_count && !pb->eof_reached; i++) {
7751  (*sample)->subsamples[i].bytes_of_clear_data = avio_rb16(pb);
7752  (*sample)->subsamples[i].bytes_of_protected_data = avio_rb32(pb);
7753  }
7754 
7755  if (pb->eof_reached) {
7756  av_log(c->fc, AV_LOG_ERROR, "hit EOF while reading sub-sample encryption info\n");
7758  *sample = NULL;
7759  return AVERROR_INVALIDDATA;
7760  }
7761  (*sample)->subsample_count = subsample_count;
7762  }
7763 
7764  return 0;
7765 }
7766 
7768 {
7769  AVEncryptionInfo **encrypted_samples;
7770  MOVEncryptionIndex *encryption_index;
7771  MOVStreamContext *sc;
7772  int use_subsamples, ret;
7773  unsigned int sample_count, i, alloc_size = 0;
7774 
7775  ret = get_current_encryption_info(c, &encryption_index, &sc);
7776  if (ret != 1)
7777  return ret;
7778 
7779  if (encryption_index->nb_encrypted_samples) {
7780  // This can happen if we have both saio/saiz and senc atoms.
7781  av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in senc\n");
7782  return 0;
7783  }
7784 
7785  avio_r8(pb); /* version */
7786  use_subsamples = avio_rb24(pb) & 0x02; /* flags */
7787 
7788  sample_count = avio_rb32(pb);
7789  if (sample_count >= INT_MAX / sizeof(*encrypted_samples))
7790  return AVERROR(ENOMEM);
7791 
7792  for (i = 0; i < sample_count; i++) {
7793  unsigned int min_samples = FFMIN(FFMAX(i + 1, 1024 * 1024), sample_count);
7794  encrypted_samples = av_fast_realloc(encryption_index->encrypted_samples, &alloc_size,
7795  min_samples * sizeof(*encrypted_samples));
7796  if (encrypted_samples) {
7797  encryption_index->encrypted_samples = encrypted_samples;
7798 
7800  c, pb, sc, &encryption_index->encrypted_samples[i], use_subsamples);
7801  } else {
7802  ret = AVERROR(ENOMEM);
7803  }
7804  if (pb->eof_reached) {
7805  av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading senc\n");
7806  if (ret >= 0)
7807  av_encryption_info_free(encryption_index->encrypted_samples[i]);
7809  }
7810 
7811  if (ret < 0) {
7812  for (; i > 0; i--)
7813  av_encryption_info_free(encryption_index->encrypted_samples[i - 1]);
7814  av_freep(&encryption_index->encrypted_samples);
7815  return ret;
7816  }
7817  }
7818  encryption_index->nb_encrypted_samples = sample_count;
7819 
7820  return 0;
7821 }
7822 
7824 {
7825  AVEncryptionInfo **sample, **encrypted_samples;
7826  int64_t prev_pos;
7827  size_t sample_count, sample_info_size, i;
7828  int ret = 0;
7829  unsigned int alloc_size = 0;
7830 
7831  if (encryption_index->nb_encrypted_samples)
7832  return 0;
7833  sample_count = encryption_index->auxiliary_info_sample_count;
7834  if (encryption_index->auxiliary_offsets_count != 1) {
7835  av_log(c->fc, AV_LOG_ERROR, "Multiple auxiliary info chunks are not supported\n");
7836  return AVERROR_PATCHWELCOME;
7837  }
7838  if (sample_count >= INT_MAX / sizeof(*encrypted_samples))
7839  return AVERROR(ENOMEM);
7840 
7841  prev_pos = avio_tell(pb);
7842  if (!(pb->seekable & AVIO_SEEKABLE_NORMAL) ||
7843  avio_seek(pb, encryption_index->auxiliary_offsets[0], SEEK_SET) != encryption_index->auxiliary_offsets[0]) {
7844  av_log(c->fc, AV_LOG_INFO, "Failed to seek for auxiliary info, will only parse senc atoms for encryption info\n");
7845  goto finish;
7846  }
7847 
7848  for (i = 0; i < sample_count && !pb->eof_reached; i++) {
7849  unsigned int min_samples = FFMIN(FFMAX(i + 1, 1024 * 1024), sample_count);
7850  encrypted_samples = av_fast_realloc(encryption_index->encrypted_samples, &alloc_size,
7851  min_samples * sizeof(*encrypted_samples));
7852  if (!encrypted_samples) {
7853  ret = AVERROR(ENOMEM);
7854  goto finish;
7855  }
7856  encryption_index->encrypted_samples = encrypted_samples;
7857 
7858  sample = &encryption_index->encrypted_samples[i];
7859  sample_info_size = encryption_index->auxiliary_info_default_size
7860  ? encryption_index->auxiliary_info_default_size
7861  : encryption_index->auxiliary_info_sizes[i];
7862 
7863  ret = mov_read_sample_encryption_info(c, pb, sc, sample, sample_info_size > sc->cenc.per_sample_iv_size);
7864  if (ret < 0)
7865  goto finish;
7866  }
7867  if (pb->eof_reached) {
7868  av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading auxiliary info\n");
7870  } else {
7871  encryption_index->nb_encrypted_samples = sample_count;
7872  }
7873 
7874 finish:
7875  avio_seek(pb, prev_pos, SEEK_SET);
7876  if (ret < 0) {
7877  for (; i > 0; i--) {
7878  av_encryption_info_free(encryption_index->encrypted_samples[i - 1]);
7879  }
7880  av_freep(&encryption_index->encrypted_samples);
7881  }
7882  return ret;
7883 }
7884 
7886 {
7887  MOVEncryptionIndex *encryption_index;
7888  MOVStreamContext *sc;
7889  int ret;
7890  unsigned int sample_count, aux_info_type, aux_info_param;
7891 
7892  ret = get_current_encryption_info(c, &encryption_index, &sc);
7893  if (ret != 1)
7894  return ret;
7895 
7896  if (encryption_index->nb_encrypted_samples) {
7897  // This can happen if we have both saio/saiz and senc atoms.
7898  av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in saiz\n");
7899  return 0;
7900  }
7901 
7902  if (encryption_index->auxiliary_info_sample_count) {
7903  av_log(c->fc, AV_LOG_ERROR, "Duplicate saiz atom\n");
7904  return AVERROR_INVALIDDATA;
7905  }
7906 
7907  avio_r8(pb); /* version */
7908  if (avio_rb24(pb) & 0x01) { /* flags */
7909  aux_info_type = avio_rb32(pb);
7910  aux_info_param = avio_rb32(pb);
7911  if (sc->cenc.default_encrypted_sample) {
7912  if (aux_info_type != sc->cenc.default_encrypted_sample->scheme) {
7913  av_log(c->fc, AV_LOG_DEBUG, "Ignoring saiz box with non-zero aux_info_type\n");
7914  return 0;
7915  }
7916  if (aux_info_param != 0) {
7917  av_log(c->fc, AV_LOG_DEBUG, "Ignoring saiz box with non-zero aux_info_type_parameter\n");
7918  return 0;
7919  }
7920  } else {
7921  // Didn't see 'schm' or 'tenc', so this isn't encrypted.
7922  if ((aux_info_type == MKBETAG('c','e','n','c') ||
7923  aux_info_type == MKBETAG('c','e','n','s') ||
7924  aux_info_type == MKBETAG('c','b','c','1') ||
7925  aux_info_type == MKBETAG('c','b','c','s')) &&
7926  aux_info_param == 0) {
7927  av_log(c->fc, AV_LOG_ERROR, "Saw encrypted saiz without schm/tenc\n");
7928  return AVERROR_INVALIDDATA;
7929  } else {
7930  return 0;
7931  }
7932  }
7933  } else if (!sc->cenc.default_encrypted_sample) {
7934  // Didn't see 'schm' or 'tenc', so this isn't encrypted.
7935  return 0;
7936  }
7937 
7938  encryption_index->auxiliary_info_default_size = avio_r8(pb);
7939  sample_count = avio_rb32(pb);
7940 
7941  if (encryption_index->auxiliary_info_default_size == 0) {
7942  if (sample_count == 0)
7943  return AVERROR_INVALIDDATA;
7944 
7945  encryption_index->auxiliary_info_sizes = av_malloc(sample_count);
7946  if (!encryption_index->auxiliary_info_sizes)
7947  return AVERROR(ENOMEM);
7948 
7949  ret = avio_read(pb, encryption_index->auxiliary_info_sizes, sample_count);
7950  if (ret != sample_count) {
7951  av_freep(&encryption_index->auxiliary_info_sizes);
7952 
7953  if (ret >= 0)
7955  av_log(c->fc, AV_LOG_ERROR, "Failed to read the auxiliary info, %s\n",
7956  av_err2str(ret));
7957  return ret;
7958  }
7959  }
7960  encryption_index->auxiliary_info_sample_count = sample_count;
7961 
7962  if (encryption_index->auxiliary_offsets_count) {
7963  return mov_parse_auxiliary_info(c, sc, pb, encryption_index);
7964  }
7965 
7966  return 0;
7967 }
7968 
7970 {
7971  uint64_t *auxiliary_offsets;
7972  MOVEncryptionIndex *encryption_index;
7973  MOVStreamContext *sc;
7974  int i, ret;
7975  unsigned int version, entry_count, aux_info_type, aux_info_param;
7976  unsigned int alloc_size = 0;
7977 
7978  ret = get_current_encryption_info(c, &encryption_index, &sc);
7979  if (ret != 1)
7980  return ret;
7981 
7982  if (encryption_index->nb_encrypted_samples) {
7983  // This can happen if we have both saio/saiz and senc atoms.
7984  av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in saio\n");
7985  return 0;
7986  }
7987 
7988  if (encryption_index->auxiliary_offsets_count) {
7989  av_log(c->fc, AV_LOG_ERROR, "Duplicate saio atom\n");
7990  return AVERROR_INVALIDDATA;
7991  }
7992 
7993  version = avio_r8(pb); /* version */
7994  if (avio_rb24(pb) & 0x01) { /* flags */
7995  aux_info_type = avio_rb32(pb);
7996  aux_info_param = avio_rb32(pb);
7997  if (sc->cenc.default_encrypted_sample) {
7998  if (aux_info_type != sc->cenc.default_encrypted_sample->scheme) {
7999  av_log(c->fc, AV_LOG_DEBUG, "Ignoring saio box with non-zero aux_info_type\n");
8000  return 0;
8001  }
8002  if (aux_info_param != 0) {
8003  av_log(c->fc, AV_LOG_DEBUG, "Ignoring saio box with non-zero aux_info_type_parameter\n");
8004  return 0;
8005  }
8006  } else {
8007  // Didn't see 'schm' or 'tenc', so this isn't encrypted.
8008  if ((aux_info_type == MKBETAG('c','e','n','c') ||
8009  aux_info_type == MKBETAG('c','e','n','s') ||
8010  aux_info_type == MKBETAG('c','b','c','1') ||
8011  aux_info_type == MKBETAG('c','b','c','s')) &&
8012  aux_info_param == 0) {
8013  av_log(c->fc, AV_LOG_ERROR, "Saw encrypted saio without schm/tenc\n");
8014  return AVERROR_INVALIDDATA;
8015  } else {
8016  return 0;
8017  }
8018  }
8019  } else if (!sc->cenc.default_encrypted_sample) {
8020  // Didn't see 'schm' or 'tenc', so this isn't encrypted.
8021  return 0;
8022  }
8023 
8024  entry_count = avio_rb32(pb);
8025  if (entry_count >= INT_MAX / sizeof(*auxiliary_offsets))
8026  return AVERROR(ENOMEM);
8027 
8028  for (i = 0; i < entry_count && !pb->eof_reached; i++) {
8029  unsigned int min_offsets = FFMIN(FFMAX(i + 1, 1024), entry_count);
8030  auxiliary_offsets = av_fast_realloc(
8031  encryption_index->auxiliary_offsets, &alloc_size,
8032  min_offsets * sizeof(*auxiliary_offsets));
8033  if (!auxiliary_offsets) {
8034  av_freep(&encryption_index->auxiliary_offsets);
8035  return AVERROR(ENOMEM);
8036  }
8037  encryption_index->auxiliary_offsets = auxiliary_offsets;
8038 
8039  if (version == 0) {
8040  encryption_index->auxiliary_offsets[i] = avio_rb32(pb);
8041  } else {
8042  encryption_index->auxiliary_offsets[i] = avio_rb64(pb);
8043  }
8044  if (c->frag_index.current >= 0) {
8045  encryption_index->auxiliary_offsets[i] += c->fragment.base_data_offset;
8046  }
8047  }
8048 
8049  if (pb->eof_reached) {
8050  av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading saio\n");
8051  av_freep(&encryption_index->auxiliary_offsets);
8052  return AVERROR_INVALIDDATA;
8053  }
8054 
8055  encryption_index->auxiliary_offsets_count = entry_count;
8056 
8057  if (encryption_index->auxiliary_info_sample_count) {
8058  return mov_parse_auxiliary_info(c, sc, pb, encryption_index);
8059  }
8060 
8061  return 0;
8062 }
8063 
8065 {
8066  AVEncryptionInitInfo *info, *old_init_info;
8067  uint8_t **key_ids;
8068  AVStream *st;
8069  const AVPacketSideData *old_side_data;
8070  uint8_t *side_data, *extra_data;
8071  size_t side_data_size;
8072  int ret = 0;
8073  unsigned int version, kid_count, extra_data_size, alloc_size = 0;
8074 
8075  if (c->fc->nb_streams < 1)
8076  return 0;
8077  st = c->fc->streams[c->fc->nb_streams-1];
8078 
8079  version = avio_r8(pb); /* version */
8080  avio_rb24(pb); /* flags */
8081 
8082  info = av_encryption_init_info_alloc(/* system_id_size */ 16, /* num_key_ids */ 0,
8083  /* key_id_size */ 16, /* data_size */ 0);
8084  if (!info)
8085  return AVERROR(ENOMEM);
8086 
8087  if ((ret = ffio_read_size(pb, info->system_id, 16)) < 0) {
8088  av_log(c->fc, AV_LOG_ERROR, "Failed to read the system id\n");
8089  goto finish;
8090  }
8091 
8092  if (version > 0) {
8093  kid_count = avio_rb32(pb);
8094  if (kid_count >= INT_MAX / sizeof(*key_ids)) {
8095  ret = AVERROR(ENOMEM);
8096  goto finish;
8097  }
8098 
8099  for (unsigned int i = 0; i < kid_count && !pb->eof_reached; i++) {
8100  unsigned int min_kid_count = FFMIN(FFMAX(i + 1, 1024), kid_count);
8101  key_ids = av_fast_realloc(info->key_ids, &alloc_size,
8102  min_kid_count * sizeof(*key_ids));
8103  if (!key_ids) {
8104  ret = AVERROR(ENOMEM);
8105  goto finish;
8106  }
8107  info->key_ids = key_ids;
8108 
8109  info->key_ids[i] = av_mallocz(16);
8110  if (!info->key_ids[i]) {
8111  ret = AVERROR(ENOMEM);
8112  goto finish;
8113  }
8114  info->num_key_ids = i + 1;
8115 
8116  if ((ret = ffio_read_size(pb, info->key_ids[i], 16)) < 0) {
8117  av_log(c->fc, AV_LOG_ERROR, "Failed to read the key id\n");
8118  goto finish;
8119  }
8120  }
8121 
8122  if (pb->eof_reached) {
8123  av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading pssh\n");
8125  goto finish;
8126  }
8127  }
8128 
8129  extra_data_size = avio_rb32(pb);
8130  extra_data = av_malloc(extra_data_size);
8131  if (!extra_data) {
8132  ret = AVERROR(ENOMEM);
8133  goto finish;
8134  }
8135  ret = avio_read(pb, extra_data, extra_data_size);
8136  if (ret != extra_data_size) {
8137  av_free(extra_data);
8138 
8139  if (ret >= 0)
8141  goto finish;
8142  }
8143 
8144  av_freep(&info->data); // malloc(0) may still allocate something.
8145  info->data = extra_data;
8146  info->data_size = extra_data_size;
8147 
8148  // If there is existing initialization data, append to the list.
8151  if (old_side_data) {
8152  old_init_info = av_encryption_init_info_get_side_data(old_side_data->data, old_side_data->size);
8153  if (old_init_info) {
8154  // Append to the end of the list.
8155  for (AVEncryptionInitInfo *cur = old_init_info;; cur = cur->next) {
8156  if (!cur->next) {
8157  cur->next = info;
8158  break;
8159  }
8160  }
8161  info = old_init_info;
8162  } else {
8163  // Assume existing side-data will be valid, so the only error we could get is OOM.
8164  ret = AVERROR(ENOMEM);
8165  goto finish;
8166  }
8167  }
8168 
8169  side_data = av_encryption_init_info_add_side_data(info, &side_data_size);
8170  if (!side_data) {
8171  ret = AVERROR(ENOMEM);
8172  goto finish;
8173  }
8177  side_data, side_data_size, 0))
8178  av_free(side_data);
8179 
8180 finish:
8182  return ret;
8183 }
8184 
8186 {
8187  AVStream *st;
8188  MOVStreamContext *sc;
8189 
8190  if (c->fc->nb_streams < 1)
8191  return 0;
8192  st = c->fc->streams[c->fc->nb_streams-1];
8193  sc = st->priv_data;
8194 
8195  if (sc->pseudo_stream_id != 0) {
8196  av_log(c->fc, AV_LOG_ERROR, "schm boxes are only supported in first sample descriptor\n");
8197  return AVERROR_PATCHWELCOME;
8198  }
8199 
8200  if (atom.size < 8)
8201  return AVERROR_INVALIDDATA;
8202 
8203  avio_rb32(pb); /* version and flags */
8204 
8205  if (!sc->cenc.default_encrypted_sample) {
8207  if (!sc->cenc.default_encrypted_sample) {
8208  return AVERROR(ENOMEM);
8209  }
8210  }
8211 
8213  return 0;
8214 }
8215 
8217 {
8218  AVStream *st;
8219  MOVStreamContext *sc;
8220  unsigned int version, pattern, is_protected, iv_size;
8221 
8222  if (c->fc->nb_streams < 1)
8223  return 0;
8224  st = c->fc->streams[c->fc->nb_streams-1];
8225  sc = st->priv_data;
8226 
8227  if (sc->pseudo_stream_id != 0) {
8228  av_log(c->fc, AV_LOG_ERROR, "tenc atom are only supported in first sample descriptor\n");
8229  return AVERROR_PATCHWELCOME;
8230  }
8231 
8232  if (!sc->cenc.default_encrypted_sample) {
8234  if (!sc->cenc.default_encrypted_sample) {
8235  return AVERROR(ENOMEM);
8236  }
8237  }
8238 
8239  if (atom.size < 20)
8240  return AVERROR_INVALIDDATA;
8241 
8242  version = avio_r8(pb); /* version */
8243  avio_rb24(pb); /* flags */
8244 
8245  avio_r8(pb); /* reserved */
8246  pattern = avio_r8(pb);
8247 
8248  if (version > 0) {
8249  sc->cenc.default_encrypted_sample->crypt_byte_block = pattern >> 4;
8250  sc->cenc.default_encrypted_sample->skip_byte_block = pattern & 0xf;
8251  }
8252 
8253  is_protected = avio_r8(pb);
8254  if (is_protected && !sc->cenc.encryption_index) {
8255  // The whole stream should be by-default encrypted.
8257  if (!sc->cenc.encryption_index)
8258  return AVERROR(ENOMEM);
8259  }
8260  sc->cenc.per_sample_iv_size = avio_r8(pb);
8261  if (sc->cenc.per_sample_iv_size != 0 && sc->cenc.per_sample_iv_size != 8 &&
8262  sc->cenc.per_sample_iv_size != 16) {
8263  av_log(c->fc, AV_LOG_ERROR, "invalid per-sample IV size value\n");
8264  return AVERROR_INVALIDDATA;
8265  }
8266  if (avio_read(pb, sc->cenc.default_encrypted_sample->key_id, 16) != 16) {
8267  av_log(c->fc, AV_LOG_ERROR, "failed to read the default key ID\n");
8268  return AVERROR_INVALIDDATA;
8269  }
8270 
8271  if (is_protected && !sc->cenc.per_sample_iv_size) {
8272  iv_size = avio_r8(pb);
8273  if (iv_size != 8 && iv_size != 16) {
8274  av_log(c->fc, AV_LOG_ERROR, "invalid default_constant_IV_size in tenc atom\n");
8275  return AVERROR_INVALIDDATA;
8276  }
8277 
8278  if (avio_read(pb, sc->cenc.default_encrypted_sample->iv, iv_size) != iv_size) {
8279  av_log(c->fc, AV_LOG_ERROR, "failed to read the default IV\n");
8280  return AVERROR_INVALIDDATA;
8281  }
8282  }
8283 
8284  return 0;
8285 }
8286 
8288 {
8289  AVStream *st;
8290  int last, type, size, ret;
8291  uint8_t buf[4];
8292 
8293  if (c->fc->nb_streams < 1)
8294  return 0;
8295  st = c->fc->streams[c->fc->nb_streams-1];
8296 
8297  if ((uint64_t)atom.size > (1<<30) || atom.size < 42)
8298  return AVERROR_INVALIDDATA;
8299 
8300  /* Check FlacSpecificBox version. */
8301  if (avio_r8(pb) != 0)
8302  return AVERROR_INVALIDDATA;
8303 
8304  avio_rb24(pb); /* Flags */
8305 
8306  if (avio_read(pb, buf, sizeof(buf)) != sizeof(buf)) {
8307  av_log(c->fc, AV_LOG_ERROR, "failed to read FLAC metadata block header\n");
8308  return pb->error < 0 ? pb->error : AVERROR_INVALIDDATA;
8309  }
8310  flac_parse_block_header(buf, &last, &type, &size);
8311 
8313  av_log(c->fc, AV_LOG_ERROR, "STREAMINFO must be first FLACMetadataBlock\n");
8314  return AVERROR_INVALIDDATA;
8315  }
8316 
8317  ret = ff_get_extradata(c->fc, st->codecpar, pb, size);
8318  if (ret < 0)
8319  return ret;
8320 
8321  if (!last)
8322  av_log(c->fc, AV_LOG_WARNING, "non-STREAMINFO FLACMetadataBlock(s) ignored\n");
8323 
8324  return 0;
8325 }
8326 
8327 static int get_key_from_kid(uint8_t* out, int len, MOVContext *c, AVEncryptionInfo *sample) {
8328  AVDictionaryEntry *key_entry_hex;
8329  char kid_hex[16*2+1];
8330 
8331  if (c->decryption_default_key && c->decryption_default_key_len != len) {
8332  av_log(c->fc, AV_LOG_ERROR, "invalid default decryption key length: got %d, expected %d\n", c->decryption_default_key_len, len);
8333  return -1;
8334  }
8335 
8336  if (!c->decryption_keys) {
8337  av_assert0(c->decryption_default_key);
8338  memcpy(out, c->decryption_default_key, len);
8339  return 0;
8340  }
8341 
8342  if (sample->key_id_size != 16) {
8343  av_log(c->fc, AV_LOG_ERROR, "invalid key ID size: got %u, expected 16\n", sample->key_id_size);
8344  return -1;
8345  }
8346 
8347  ff_data_to_hex(kid_hex, sample->key_id, 16, 1);
8348  key_entry_hex = av_dict_get(c->decryption_keys, kid_hex, NULL, AV_DICT_DONT_STRDUP_KEY|AV_DICT_DONT_STRDUP_VAL);
8349  if (!key_entry_hex) {
8350  if (!c->decryption_default_key) {
8351  av_log(c->fc, AV_LOG_ERROR, "unable to find KID %s\n", kid_hex);
8352  return -1;
8353  }
8354  memcpy(out, c->decryption_default_key, len);
8355  return 0;
8356  }
8357  if (strlen(key_entry_hex->value) != len*2) {
8358  return -1;
8359  }
8360  ff_hex_to_data(out, key_entry_hex->value);
8361  return 0;
8362 }
8363 
8365 {
8366  int i, ret;
8367  int bytes_of_protected_data;
8368  uint8_t decryption_key[AES_CTR_KEY_SIZE];
8369 
8370  if (!sc->cenc.aes_ctr) {
8371  ret = get_key_from_kid(decryption_key, sizeof(decryption_key), c, sample);
8372  if (ret < 0) {
8373  return ret;
8374  }
8375 
8376  /* initialize the cipher */
8377  sc->cenc.aes_ctr = av_aes_ctr_alloc();
8378  if (!sc->cenc.aes_ctr) {
8379  return AVERROR(ENOMEM);
8380  }
8381 
8382  ret = av_aes_ctr_init(sc->cenc.aes_ctr, decryption_key);
8383  if (ret < 0) {
8384  return ret;
8385  }
8386  }
8387 
8389 
8390  if (!sample->subsample_count) {
8391  /* decrypt the whole packet */
8393  return 0;
8394  }
8395 
8396  for (i = 0; i < sample->subsample_count; i++) {
8397  if (sample->subsamples[i].bytes_of_clear_data + (int64_t)sample->subsamples[i].bytes_of_protected_data > size) {
8398  av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n");
8399  return AVERROR_INVALIDDATA;
8400  }
8401 
8402  /* skip the clear bytes */
8403  input += sample->subsamples[i].bytes_of_clear_data;
8404  size -= sample->subsamples[i].bytes_of_clear_data;
8405 
8406  /* decrypt the encrypted bytes */
8407 
8408  bytes_of_protected_data = sample->subsamples[i].bytes_of_protected_data;
8409  av_aes_ctr_crypt(sc->cenc.aes_ctr, input, input, bytes_of_protected_data);
8410 
8411  input += bytes_of_protected_data;
8412  size -= bytes_of_protected_data;
8413  }
8414 
8415  if (size > 0) {
8416  av_log(c->fc, AV_LOG_ERROR, "leftover packet bytes after subsample processing\n");
8417  return AVERROR_INVALIDDATA;
8418  }
8419 
8420  return 0;
8421 }
8422 
8424 {
8425  int i, ret;
8426  int num_of_encrypted_blocks;
8427  uint8_t iv[16];
8428  uint8_t decryption_key[16];
8429 
8430  if (!sc->cenc.aes_ctx) {
8431  ret = get_key_from_kid(decryption_key, sizeof(decryption_key), c, sample);
8432  if (ret < 0) {
8433  return ret;
8434  }
8435 
8436  /* initialize the cipher */
8437  sc->cenc.aes_ctx = av_aes_alloc();
8438  if (!sc->cenc.aes_ctx) {
8439  return AVERROR(ENOMEM);
8440  }
8441 
8442  ret = av_aes_init(sc->cenc.aes_ctx, decryption_key, 16 * 8, 1);
8443  if (ret < 0) {
8444  return ret;
8445  }
8446  }
8447 
8448  memcpy(iv, sample->iv, 16);
8449 
8450  /* whole-block full sample encryption */
8451  if (!sample->subsample_count) {
8452  /* decrypt the whole packet */
8453  av_aes_crypt(sc->cenc.aes_ctx, input, input, size/16, iv, 1);
8454  return 0;
8455  }
8456 
8457  for (i = 0; i < sample->subsample_count; i++) {
8458  if (sample->subsamples[i].bytes_of_clear_data + (int64_t)sample->subsamples[i].bytes_of_protected_data > size) {
8459  av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n");
8460  return AVERROR_INVALIDDATA;
8461  }
8462 
8463  if (sample->subsamples[i].bytes_of_protected_data % 16) {
8464  av_log(c->fc, AV_LOG_ERROR, "subsample BytesOfProtectedData is not a multiple of 16\n");
8465  return AVERROR_INVALIDDATA;
8466  }
8467 
8468  /* skip the clear bytes */
8469  input += sample->subsamples[i].bytes_of_clear_data;
8470  size -= sample->subsamples[i].bytes_of_clear_data;
8471 
8472  /* decrypt the encrypted bytes */
8473  num_of_encrypted_blocks = sample->subsamples[i].bytes_of_protected_data/16;
8474  if (num_of_encrypted_blocks > 0) {
8475  av_aes_crypt(sc->cenc.aes_ctx, input, input, num_of_encrypted_blocks, iv, 1);
8476  }
8477  input += sample->subsamples[i].bytes_of_protected_data;
8478  size -= sample->subsamples[i].bytes_of_protected_data;
8479  }
8480 
8481  if (size > 0) {
8482  av_log(c->fc, AV_LOG_ERROR, "leftover packet bytes after subsample processing\n");
8483  return AVERROR_INVALIDDATA;
8484  }
8485 
8486  return 0;
8487 }
8488 
8490 {
8491  int i, ret, rem_bytes;
8492  uint8_t *data;
8493  uint8_t decryption_key[AES_CTR_KEY_SIZE];
8494 
8495  if (!sc->cenc.aes_ctr) {
8496  ret = get_key_from_kid(decryption_key, sizeof(decryption_key), c, sample);
8497  if (ret < 0) {
8498  return ret;
8499  }
8500 
8501  /* initialize the cipher */
8502  sc->cenc.aes_ctr = av_aes_ctr_alloc();
8503  if (!sc->cenc.aes_ctr) {
8504  return AVERROR(ENOMEM);
8505  }
8506 
8507  ret = av_aes_ctr_init(sc->cenc.aes_ctr, decryption_key);
8508  if (ret < 0) {
8509  return ret;
8510  }
8511  }
8512 
8514 
8515  /* whole-block full sample encryption */
8516  if (!sample->subsample_count) {
8517  /* decrypt the whole packet */
8519  return 0;
8520  } else if (!sample->crypt_byte_block && !sample->skip_byte_block) {
8521  av_log(c->fc, AV_LOG_ERROR, "pattern encryption is not present in 'cens' scheme\n");
8522  return AVERROR_INVALIDDATA;
8523  }
8524 
8525  for (i = 0; i < sample->subsample_count; i++) {
8526  if (sample->subsamples[i].bytes_of_clear_data + (int64_t)sample->subsamples[i].bytes_of_protected_data > size) {
8527  av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n");
8528  return AVERROR_INVALIDDATA;
8529  }
8530 
8531  /* skip the clear bytes */
8532  input += sample->subsamples[i].bytes_of_clear_data;
8533  size -= sample->subsamples[i].bytes_of_clear_data;
8534 
8535  /* decrypt the encrypted bytes */
8536  data = input;
8537  rem_bytes = sample->subsamples[i].bytes_of_protected_data;
8538  while (rem_bytes > 0) {
8539  if (rem_bytes < 16*sample->crypt_byte_block) {
8540  break;
8541  }
8542  av_aes_ctr_crypt(sc->cenc.aes_ctr, data, data, 16*sample->crypt_byte_block);
8543  data += 16*sample->crypt_byte_block;
8544  rem_bytes -= 16*sample->crypt_byte_block;
8545  data += FFMIN(16*sample->skip_byte_block, rem_bytes);
8546  rem_bytes -= FFMIN(16*sample->skip_byte_block, rem_bytes);
8547  }
8548  input += sample->subsamples[i].bytes_of_protected_data;
8549  size -= sample->subsamples[i].bytes_of_protected_data;
8550  }
8551 
8552  if (size > 0) {
8553  av_log(c->fc, AV_LOG_ERROR, "leftover packet bytes after subsample processing\n");
8554  return AVERROR_INVALIDDATA;
8555  }
8556 
8557  return 0;
8558 }
8559 
8561 {
8562  int i, ret, rem_bytes;
8563  uint8_t iv[16];
8564  uint8_t *data;
8565  uint8_t decryption_key[16];
8566 
8567  if (!sc->cenc.aes_ctx) {
8568  ret = get_key_from_kid(decryption_key, sizeof(decryption_key), c, sample);
8569  if (ret < 0) {
8570  return ret;
8571  }
8572 
8573  /* initialize the cipher */
8574  sc->cenc.aes_ctx = av_aes_alloc();
8575  if (!sc->cenc.aes_ctx) {
8576  return AVERROR(ENOMEM);
8577  }
8578 
8579  ret = av_aes_init(sc->cenc.aes_ctx, decryption_key, 16 * 8, 1);
8580  if (ret < 0) {
8581  return ret;
8582  }
8583  }
8584 
8585  /* whole-block full sample encryption */
8586  if (!sample->subsample_count) {
8587  /* decrypt the whole packet */
8588  memcpy(iv, sample->iv, 16);
8589  av_aes_crypt(sc->cenc.aes_ctx, input, input, size/16, iv, 1);
8590  return 0;
8591  } else if (!sample->crypt_byte_block && !sample->skip_byte_block) {
8592  av_log(c->fc, AV_LOG_ERROR, "pattern encryption is not present in 'cbcs' scheme\n");
8593  return AVERROR_INVALIDDATA;
8594  }
8595 
8596  for (i = 0; i < sample->subsample_count; i++) {
8597  if (sample->subsamples[i].bytes_of_clear_data + (int64_t)sample->subsamples[i].bytes_of_protected_data > size) {
8598  av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n");
8599  return AVERROR_INVALIDDATA;
8600  }
8601 
8602  /* skip the clear bytes */
8603  input += sample->subsamples[i].bytes_of_clear_data;
8604  size -= sample->subsamples[i].bytes_of_clear_data;
8605 
8606  /* decrypt the encrypted bytes */
8607  memcpy(iv, sample->iv, 16);
8608  data = input;
8609  rem_bytes = sample->subsamples[i].bytes_of_protected_data;
8610  while (rem_bytes > 0) {
8611  if (rem_bytes < 16*sample->crypt_byte_block) {
8612  break;
8613  }
8614  av_aes_crypt(sc->cenc.aes_ctx, data, data, sample->crypt_byte_block, iv, 1);
8615  data += 16*sample->crypt_byte_block;
8616  rem_bytes -= 16*sample->crypt_byte_block;
8617  data += FFMIN(16*sample->skip_byte_block, rem_bytes);
8618  rem_bytes -= FFMIN(16*sample->skip_byte_block, rem_bytes);
8619  }
8620  input += sample->subsamples[i].bytes_of_protected_data;
8621  size -= sample->subsamples[i].bytes_of_protected_data;
8622  }
8623 
8624  if (size > 0) {
8625  av_log(c->fc, AV_LOG_ERROR, "leftover packet bytes after subsample processing\n");
8626  return AVERROR_INVALIDDATA;
8627  }
8628 
8629  return 0;
8630 }
8631 
8633 {
8634  if (sample->scheme == MKBETAG('c','e','n','c') && !sample->crypt_byte_block && !sample->skip_byte_block) {
8635  return cenc_scheme_decrypt(c, sc, sample, input, size);
8636  } else if (sample->scheme == MKBETAG('c','b','c','1') && !sample->crypt_byte_block && !sample->skip_byte_block) {
8637  return cbc1_scheme_decrypt(c, sc, sample, input, size);
8638  } else if (sample->scheme == MKBETAG('c','e','n','s')) {
8639  return cens_scheme_decrypt(c, sc, sample, input, size);
8640  } else if (sample->scheme == MKBETAG('c','b','c','s')) {
8641  return cbcs_scheme_decrypt(c, sc, sample, input, size);
8642  } else {
8643  av_log(c->fc, AV_LOG_ERROR, "invalid encryption scheme\n");
8644  return AVERROR_INVALIDDATA;
8645  }
8646 }
8647 
8649 {
8650  int current = frag_index->current;
8651 
8652  if (!frag_index->nb_items)
8653  return NULL;
8654 
8655  // Check frag_index->current is the right one for pkt. It can out of sync.
8656  if (current >= 0 && current < frag_index->nb_items) {
8657  if (frag_index->item[current].moof_offset < pkt->pos &&
8658  (current + 1 == frag_index->nb_items ||
8659  frag_index->item[current + 1].moof_offset > pkt->pos))
8660  return get_frag_stream_info(frag_index, current, id);
8661  }
8662 
8663 
8664  for (int i = 0; i < frag_index->nb_items; i++) {
8665  if (frag_index->item[i].moof_offset > pkt->pos)
8666  break;
8667  current = i;
8668  }
8669  frag_index->current = current;
8670  return get_frag_stream_info(frag_index, current, id);
8671 }
8672 
8673 static int cenc_filter(MOVContext *mov, AVStream* st, MOVStreamContext *sc, AVPacket *pkt, int current_index)
8674 {
8675  MOVFragmentStreamInfo *frag_stream_info;
8676  MOVEncryptionIndex *encryption_index;
8677  AVEncryptionInfo *encrypted_sample;
8678  int encrypted_index, ret;
8679 
8680  frag_stream_info = get_frag_stream_info_from_pkt(&mov->frag_index, pkt, sc->id);
8681  encrypted_index = current_index;
8682  encryption_index = NULL;
8683  if (frag_stream_info) {
8684  // Note this only supports encryption info in the first sample descriptor.
8685  if (frag_stream_info->stsd_id == 1) {
8686  if (frag_stream_info->encryption_index) {
8687  encrypted_index = current_index - frag_stream_info->index_base;
8688  encryption_index = frag_stream_info->encryption_index;
8689  } else {
8690  encryption_index = sc->cenc.encryption_index;
8691  }
8692  }
8693  } else {
8694  encryption_index = sc->cenc.encryption_index;
8695  }
8696 
8697  if (encryption_index) {
8698  if (encryption_index->auxiliary_info_sample_count &&
8699  !encryption_index->nb_encrypted_samples) {
8700  av_log(mov->fc, AV_LOG_ERROR, "saiz atom found without saio\n");
8701  return AVERROR_INVALIDDATA;
8702  }
8703  if (encryption_index->auxiliary_offsets_count &&
8704  !encryption_index->nb_encrypted_samples) {
8705  av_log(mov->fc, AV_LOG_ERROR, "saio atom found without saiz\n");
8706  return AVERROR_INVALIDDATA;
8707  }
8708 
8709  encrypted_sample = NULL;
8710  if (!encryption_index->nb_encrypted_samples) {
8711  // Full-sample encryption with default settings.
8712  encrypted_sample = sc->cenc.default_encrypted_sample;
8713  } else if (encrypted_index >= 0 && encrypted_index < encryption_index->nb_encrypted_samples) {
8714  // Per-sample setting override.
8715  encrypted_sample = encryption_index->encrypted_samples[encrypted_index];
8716  if (!encrypted_sample) {
8717  encrypted_sample = sc->cenc.default_encrypted_sample;
8718  }
8719  }
8720 
8721  if (!encrypted_sample) {
8722  av_log(mov->fc, AV_LOG_ERROR, "Incorrect number of samples in encryption info\n");
8723  return AVERROR_INVALIDDATA;
8724  }
8725 
8726  if (mov->decryption_keys || mov->decryption_default_key) {
8727  return cenc_decrypt(mov, sc, encrypted_sample, pkt->data, pkt->size);
8728  } else {
8729  size_t size;
8730  uint8_t *side_data = av_encryption_info_add_side_data(encrypted_sample, &size);
8731  if (!side_data)
8732  return AVERROR(ENOMEM);
8734  if (ret < 0)
8735  av_free(side_data);
8736  return ret;
8737  }
8738  }
8739 
8740  return 0;
8741 }
8742 
8744 {
8745  const int OPUS_SEEK_PREROLL_MS = 80;
8746  int ret;
8747  AVStream *st;
8748  size_t size;
8749  uint16_t pre_skip;
8750 
8751  if (c->fc->nb_streams < 1)
8752  return 0;
8753  st = c->fc->streams[c->fc->nb_streams-1];
8754 
8755  if ((uint64_t)atom.size > (1<<30) || atom.size < 11 || st->codecpar->extradata)
8756  return AVERROR_INVALIDDATA;
8757 
8758  /* Check OpusSpecificBox version. */
8759  if (avio_r8(pb) != 0) {
8760  av_log(c->fc, AV_LOG_ERROR, "unsupported OpusSpecificBox version\n");
8761  return AVERROR_INVALIDDATA;
8762  }
8763 
8764  /* OpusSpecificBox size plus magic for Ogg OpusHead header. */
8765  size = atom.size + 8;
8766 
8767  if ((ret = ff_alloc_extradata(st->codecpar, size)) < 0)
8768  return ret;
8769 
8770  AV_WL32A(st->codecpar->extradata, MKTAG('O','p','u','s'));
8771  AV_WL32A(st->codecpar->extradata + 4, MKTAG('H','e','a','d'));
8772  AV_WB8(st->codecpar->extradata + 8, 1); /* OpusHead version */
8773  if ((ret = ffio_read_size(pb, st->codecpar->extradata + 9, size - 9)) < 0) {
8774  av_freep(&st->codecpar->extradata);
8775  st->codecpar->extradata_size = 0;
8776  return ret;
8777  }
8778 
8779  /* OpusSpecificBox is stored in big-endian, but OpusHead is
8780  little-endian; aside from the preceding magic and version they're
8781  otherwise currently identical. Data after output gain at offset 16
8782  doesn't need to be bytewapped. */
8783  pre_skip = AV_RB16A(st->codecpar->extradata + 10);
8784  AV_WL16A(st->codecpar->extradata + 10, pre_skip);
8785  AV_WL32A(st->codecpar->extradata + 12, AV_RB32A(st->codecpar->extradata + 12));
8786  AV_WL16A(st->codecpar->extradata + 16, AV_RB16A(st->codecpar->extradata + 16));
8787 
8788  st->codecpar->initial_padding = pre_skip;
8790  (AVRational){1, 1000},
8791  (AVRational){1, 48000});
8792 
8793  return 0;
8794 }
8795 
8797 {
8798  AVStream *st;
8799  unsigned format_info;
8800  int channel_assignment, channel_assignment1, channel_assignment2;
8801  int ratebits;
8802  uint64_t chmask;
8803 
8804  if (c->fc->nb_streams < 1)
8805  return 0;
8806  st = c->fc->streams[c->fc->nb_streams-1];
8807 
8808  if (atom.size < 10)
8809  return AVERROR_INVALIDDATA;
8810 
8811  format_info = avio_rb32(pb);
8812 
8813  ratebits = (format_info >> 28) & 0xF;
8814  channel_assignment1 = (format_info >> 15) & 0x1F;
8815  channel_assignment2 = format_info & 0x1FFF;
8816  if (channel_assignment2)
8817  channel_assignment = channel_assignment2;
8818  else
8819  channel_assignment = channel_assignment1;
8820 
8821  st->codecpar->frame_size = 40 << (ratebits & 0x7);
8822  st->codecpar->sample_rate = mlp_samplerate(ratebits);
8823 
8825  chmask = truehd_layout(channel_assignment);
8827 
8828  return 0;
8829 }
8830 
8832 {
8833  AVStream *st;
8834  uint8_t buf[ISOM_DVCC_DVVC_SIZE];
8835  int ret;
8836  int64_t read_size = atom.size;
8837 
8838  if (c->fc->nb_streams < 1)
8839  return 0;
8840  st = c->fc->streams[c->fc->nb_streams-1];
8841 
8842  // At most 24 bytes
8843  read_size = FFMIN(read_size, ISOM_DVCC_DVVC_SIZE);
8844 
8845  if ((ret = ffio_read_size(pb, buf, read_size)) < 0)
8846  return ret;
8847 
8848  return ff_isom_parse_dvcc_dvvc(c->fc, st, buf, read_size);
8849 }
8850 
8852 {
8853  AVStream *st;
8854  AVPacketSideData *sd;
8855  int ret;
8856 
8857  if (c->fc->nb_streams < 1)
8858  return 0;
8859  st = c->fc->streams[c->fc->nb_streams - 1];
8860 
8861  if (atom.size < 23 || atom.size > INT_MAX - AV_INPUT_BUFFER_PADDING_SIZE)
8862  return AVERROR_INVALIDDATA;
8863 
8867  atom.size, 0);
8868  if (!sd)
8869  return AVERROR(ENOMEM);
8870 
8871  ret = ffio_read_size(pb, sd->data, atom.size);
8872  if (ret < 0)
8873  return ret;
8874 
8875  return 0;
8876 }
8877 
8879 {
8880  AVStream *st;
8881  uint8_t *buf;
8882  int ret, old_size, num_arrays;
8883 
8884  if (c->fc->nb_streams < 1)
8885  return 0;
8886  st = c->fc->streams[c->fc->nb_streams-1];
8887 
8888  if (!st->codecpar->extradata_size)
8889  // TODO: handle lhvC when present before hvcC
8890  return 0;
8891 
8892  if (atom.size < 6 || st->codecpar->extradata_size < 23 ||
8893  atom.size > INT_MAX - AV_INPUT_BUFFER_PADDING_SIZE) {
8894  return AVERROR_INVALIDDATA;
8895  }
8896 
8898  if (!buf)
8899  return AVERROR(ENOMEM);
8900  memset(buf + atom.size, 0, AV_INPUT_BUFFER_PADDING_SIZE);
8901 
8902  ret = ffio_read_size(pb, buf, atom.size);
8903  if (ret < 0) {
8904  av_free(buf);
8905  av_log(c->fc, AV_LOG_WARNING, "lhvC atom truncated\n");
8906  return 0;
8907  }
8908 
8909  num_arrays = buf[5];
8910  old_size = st->codecpar->extradata_size;
8911  atom.size -= 8 /* account for mov_realloc_extradata offsetting */
8912  + 6 /* lhvC bytes before the arrays*/;
8913 
8914  ret = mov_realloc_extradata(st->codecpar, atom);
8915  if (ret < 0) {
8916  av_free(buf);
8917  return ret;
8918  }
8919 
8920  st->codecpar->extradata[22] += num_arrays;
8921  memcpy(st->codecpar->extradata + old_size, buf + 6, atom.size + 8);
8922 
8924 
8925  av_free(buf);
8926  return 0;
8927 }
8928 
8930 {
8931  AVFormatContext *ctx = c->fc;
8932  AVStream *st = NULL;
8933  AVBPrint scheme_buf, value_buf;
8934  int64_t scheme_str_len = 0, value_str_len = 0;
8935  int version, flags, ret = AVERROR_BUG;
8936  int64_t size = atom.size;
8937 
8938  if (atom.size < 6)
8939  // 4 bytes for version + flags, 2x 1 byte for null
8940  return AVERROR_INVALIDDATA;
8941 
8942  if (c->fc->nb_streams < 1)
8943  return 0;
8944  st = c->fc->streams[c->fc->nb_streams-1];
8945 
8946  version = avio_r8(pb);
8947  flags = avio_rb24(pb);
8948  size -= 4;
8949 
8950  if (version != 0 || flags != 0) {
8952  "Unsupported 'kind' box with version %d, flags: %x",
8953  version, flags);
8954  return AVERROR_INVALIDDATA;
8955  }
8956 
8957  av_bprint_init(&scheme_buf, 0, AV_BPRINT_SIZE_UNLIMITED);
8958  av_bprint_init(&value_buf, 0, AV_BPRINT_SIZE_UNLIMITED);
8959 
8960  if ((scheme_str_len = ff_read_string_to_bprint_overwrite(pb, &scheme_buf,
8961  size)) < 0) {
8962  ret = scheme_str_len;
8963  goto cleanup;
8964  }
8965 
8966  if (scheme_str_len + 1 >= size) {
8967  // we need to have another string, even if nullptr.
8968  // we check with + 1 since we expect that if size was not hit,
8969  // an additional null was read.
8971  goto cleanup;
8972  }
8973 
8974  size -= scheme_str_len + 1;
8975 
8976  if ((value_str_len = ff_read_string_to_bprint_overwrite(pb, &value_buf,
8977  size)) < 0) {
8978  ret = value_str_len;
8979  goto cleanup;
8980  }
8981 
8982  if (value_str_len == size) {
8983  // in case of no trailing null, box is not valid.
8985  goto cleanup;
8986  }
8987 
8989  "%s stream %d KindBox(scheme: %s, value: %s)\n",
8991  st->index,
8992  scheme_buf.str, value_buf.str);
8993 
8994  for (int i = 0; ff_mov_track_kind_table[i].scheme_uri; i++) {
8996  if (!av_strstart(scheme_buf.str, map.scheme_uri, NULL))
8997  continue;
8998 
8999  for (int j = 0; map.value_maps[j].disposition; j++) {
9000  const struct MP4TrackKindValueMapping value_map = map.value_maps[j];
9001  if (!av_strstart(value_buf.str, value_map.value, NULL))
9002  continue;
9003 
9004  st->disposition |= value_map.disposition;
9005  }
9006  }
9007 
9008  ret = 0;
9009 
9010 cleanup:
9011 
9012  av_bprint_finalize(&scheme_buf, NULL);
9013  av_bprint_finalize(&value_buf, NULL);
9014 
9015  return ret;
9016 }
9017 
9019 {
9020  AVStream *st;
9021  AVChannelLayout ch_layout = { 0 };
9022  int ret, i, version, type;
9023  int ambisonic_order, channel_order, normalization, channel_count;
9024  int ambi_channels, non_diegetic_channels;
9025 
9026  if (c->fc->nb_streams < 1)
9027  return 0;
9028 
9029  st = c->fc->streams[c->fc->nb_streams - 1];
9030 
9031  if (atom.size < 16) {
9032  av_log(c->fc, AV_LOG_ERROR, "SA3D audio box too small\n");
9033  return AVERROR_INVALIDDATA;
9034  }
9035 
9036  version = avio_r8(pb);
9037  if (version) {
9038  av_log(c->fc, AV_LOG_WARNING, "Unsupported SA3D box version %d\n", version);
9039  return 0;
9040  }
9041 
9042  type = avio_r8(pb);
9043  if (type & 0x7f) {
9044  av_log(c->fc, AV_LOG_WARNING,
9045  "Unsupported ambisonic type %d\n", type & 0x7f);
9046  return 0;
9047  }
9048  non_diegetic_channels = (type >> 7) * 2; // head_locked_stereo
9049 
9050  ambisonic_order = avio_rb32(pb);
9051 
9052  channel_order = avio_r8(pb);
9053  if (channel_order) {
9054  av_log(c->fc, AV_LOG_WARNING,
9055  "Unsupported channel_order %d\n", channel_order);
9056  return 0;
9057  }
9058 
9059  normalization = avio_r8(pb);
9060  if (normalization) {
9061  av_log(c->fc, AV_LOG_WARNING,
9062  "Unsupported normalization %d\n", normalization);
9063  return 0;
9064  }
9065 
9066  channel_count = avio_rb32(pb);
9067  if (ambisonic_order < 0 || ambisonic_order > 31 ||
9068  channel_count != ((ambisonic_order + 1LL) * (ambisonic_order + 1LL) +
9069  non_diegetic_channels)) {
9070  av_log(c->fc, AV_LOG_ERROR,
9071  "Invalid number of channels (%d / %d)\n",
9072  channel_count, ambisonic_order);
9073  return 0;
9074  }
9075  ambi_channels = channel_count - non_diegetic_channels;
9076 
9077  ret = av_channel_layout_custom_init(&ch_layout, channel_count);
9078  if (ret < 0)
9079  return 0;
9080 
9081  for (i = 0; i < channel_count; i++) {
9082  unsigned channel = avio_rb32(pb);
9083 
9084  if (channel >= channel_count) {
9085  av_log(c->fc, AV_LOG_ERROR, "Invalid channel index (%d / %d)\n",
9086  channel, ambisonic_order);
9087  av_channel_layout_uninit(&ch_layout);
9088  return 0;
9089  }
9090  if (channel >= ambi_channels)
9091  ch_layout.u.map[i].id = channel - ambi_channels;
9092  else
9093  ch_layout.u.map[i].id = AV_CHAN_AMBISONIC_BASE + channel;
9094  }
9095 
9097  if (ret < 0) {
9098  av_channel_layout_uninit(&ch_layout);
9099  return 0;
9100  }
9101 
9103  st->codecpar->ch_layout = ch_layout;
9104 
9105  return 0;
9106 }
9107 
9109 {
9110  AVStream *st;
9111  int version;
9112 
9113  if (c->fc->nb_streams < 1)
9114  return 0;
9115 
9116  st = c->fc->streams[c->fc->nb_streams - 1];
9117 
9118  if (atom.size < 5) {
9119  av_log(c->fc, AV_LOG_ERROR, "Empty SAND audio box\n");
9120  return AVERROR_INVALIDDATA;
9121  }
9122 
9123  version = avio_r8(pb);
9124  if (version) {
9125  av_log(c->fc, AV_LOG_WARNING, "Unsupported SAND box version %d\n", version);
9126  return 0;
9127  }
9128 
9130 
9131  return 0;
9132 }
9133 
9134 static int rb_size(AVIOContext *pb, int64_t *value, int size)
9135 {
9136  if (size == 0)
9137  *value = 0;
9138  else if (size == 1)
9139  *value = avio_r8(pb);
9140  else if (size == 2)
9141  *value = avio_rb16(pb);
9142  else if (size == 4)
9143  *value = avio_rb32(pb);
9144  else if (size == 8) {
9145  *value = avio_rb64(pb);
9146  if (*value < 0)
9147  return -1;
9148  } else
9149  return -1;
9150  return size;
9151 }
9152 
9154 {
9155  avio_rb32(pb); // version & flags.
9156  c->primary_item_id = avio_rb16(pb);
9157  av_log(c->fc, AV_LOG_TRACE, "pitm: primary_item_id %d\n", c->primary_item_id);
9158  return atom.size;
9159 }
9160 
9162 {
9163  c->idat_offset = avio_tell(pb);
9164  return 0;
9165 }
9166 
9168 {
9169  HEIFItem **heif_item;
9170  int version, offset_size, length_size, base_offset_size, index_size;
9171  int item_count, extent_count;
9172  int64_t base_offset, extent_offset, extent_length;
9173  uint8_t value;
9174 
9175  if (c->found_iloc) {
9176  av_log(c->fc, AV_LOG_INFO, "Duplicate iloc box found\n");
9177  return 0;
9178  }
9179 
9180  version = avio_r8(pb);
9181  avio_rb24(pb); // flags.
9182 
9183  value = avio_r8(pb);
9184  offset_size = (value >> 4) & 0xF;
9185  length_size = value & 0xF;
9186  value = avio_r8(pb);
9187  base_offset_size = (value >> 4) & 0xF;
9188  index_size = !version ? 0 : (value & 0xF);
9189  if (index_size) {
9190  avpriv_report_missing_feature(c->fc, "iloc: index_size != 0");
9191  return AVERROR_PATCHWELCOME;
9192  }
9193  item_count = (version < 2) ? avio_rb16(pb) : avio_rb32(pb);
9194 
9195  heif_item = av_realloc_array(c->heif_item, FFMAX(item_count, c->nb_heif_item), sizeof(*c->heif_item));
9196  if (!heif_item)
9197  return AVERROR(ENOMEM);
9198  c->heif_item = heif_item;
9199  if (item_count > c->nb_heif_item)
9200  memset(&c->heif_item[c->nb_heif_item], 0,
9201  sizeof(*c->heif_item) * (item_count - c->nb_heif_item));
9202  c->nb_heif_item = FFMAX(c->nb_heif_item, item_count);
9203 
9204  av_log(c->fc, AV_LOG_TRACE, "iloc: item_count %d\n", item_count);
9205  for (int i = 0; i < item_count; i++) {
9206  HEIFItem *item = NULL;
9207  int item_id = (version < 2) ? avio_rb16(pb) : avio_rb32(pb);
9208  int offset_type = (version > 0) ? avio_rb16(pb) & 0xf : 0;
9209  int j;
9210 
9211  if (avio_feof(pb))
9212  return AVERROR_INVALIDDATA;
9213  if (offset_type > 1) {
9214  avpriv_report_missing_feature(c->fc, "iloc offset type %d", offset_type);
9215  return AVERROR_PATCHWELCOME;
9216  }
9217 
9218  avio_rb16(pb); // data_reference_index.
9219  if (rb_size(pb, &base_offset, base_offset_size) < 0)
9220  return AVERROR_INVALIDDATA;
9221  extent_count = avio_rb16(pb);
9222  if (extent_count > 1) {
9223  // For still AVIF images, we only support one extent item.
9224  avpriv_report_missing_feature(c->fc, "iloc: extent_count > 1");
9225  return AVERROR_PATCHWELCOME;
9226  }
9227 
9228  if (rb_size(pb, &extent_offset, offset_size) < 0 ||
9229  rb_size(pb, &extent_length, length_size) < 0 ||
9230  base_offset > INT64_MAX - extent_offset)
9231  return AVERROR_INVALIDDATA;
9232 
9233  for (j = 0; j < c->nb_heif_item; j++) {
9234  item = c->heif_item[j];
9235  if (!item)
9236  item = c->heif_item[j] = av_mallocz(sizeof(*item));
9237  else if (item->item_id != item_id)
9238  continue;
9239  break;
9240  }
9241  if (!item)
9242  return AVERROR(ENOMEM);
9243  if (j == c->nb_heif_item)
9244  return AVERROR_INVALIDDATA;
9245 
9246  item->item_id = item_id;
9247 
9248  if (offset_type == 1)
9249  item->is_idat_relative = 1;
9250  item->extent_length = extent_length;
9251  item->extent_offset = base_offset + extent_offset;
9252  av_log(c->fc, AV_LOG_TRACE, "iloc: item_idx %d, item->item_id %d, offset_type %d, "
9253  "extent_offset %"PRId64", extent_length %"PRId64"\n",
9254  i, item->item_id, offset_type, item->extent_offset, item->extent_length);
9255  }
9256 
9257  c->found_iloc = 1;
9258  return atom.size;
9259 }
9260 
9262 {
9263  HEIFItem *item = NULL;
9264  AVBPrint item_name;
9265  int64_t size = atom.size;
9266  uint32_t item_type;
9267  int item_id;
9268  int i, version, ret;
9269 
9270  version = avio_r8(pb);
9271  avio_rb24(pb); // flags.
9272  size -= 4;
9273  if (size < 0)
9274  return AVERROR_INVALIDDATA;
9275 
9276  if (version < 2) {
9277  avpriv_report_missing_feature(c->fc, "infe version < 2");
9278  avio_skip(pb, size);
9279  return 1;
9280  }
9281 
9282  item_id = version > 2 ? avio_rb32(pb) : avio_rb16(pb);
9283  avio_rb16(pb); // item_protection_index
9284  item_type = avio_rl32(pb);
9285  size -= 8;
9286  if (size < 1)
9287  return AVERROR_INVALIDDATA;
9288 
9291  if (ret < 0) {
9293  return ret;
9294  }
9295 
9296  av_log(c->fc, AV_LOG_TRACE, "infe: item_id %d, item_type %s, item_name %s\n",
9297  item_id, av_fourcc2str(item_type), item_name.str);
9298 
9299  size -= ret + 1;
9300  if (size > 0)
9301  avio_skip(pb, size);
9302 
9303  for (i = 0; i < c->nb_heif_item; i++) {
9304  item = c->heif_item[i];
9305  if (!item)
9306  item = c->heif_item[i] = av_mallocz(sizeof(*item));
9307  else if (item->item_id != item_id)
9308  continue;
9309  break;
9310  }
9311  if (!item) {
9313  return AVERROR(ENOMEM);
9314  }
9315  if (i == c->nb_heif_item) {
9317  return AVERROR_INVALIDDATA;
9318  }
9319 
9320  av_freep(&item->name);
9321  av_bprint_finalize(&item_name, ret ? &item->name : NULL);
9322  item->item_id = item_id;
9323  item->type = item_type;
9324 
9325  switch (item_type) {
9326  case MKTAG('a','v','0','1'):
9327  case MKTAG('j','p','e','g'):
9328  case MKTAG('h','v','c','1'):
9329  ret = heif_add_stream(c, item);
9330  if (ret < 0)
9331  return ret;
9332  break;
9333  }
9334 
9335  return 0;
9336 }
9337 
9339 {
9340  HEIFItem **heif_item;
9341  int entry_count;
9342  int version, got_stream = 0, ret, i;
9343 
9344  if (c->found_iinf) {
9345  av_log(c->fc, AV_LOG_WARNING, "Duplicate iinf box found\n");
9346  return 0;
9347  }
9348 
9349  version = avio_r8(pb);
9350  avio_rb24(pb); // flags.
9351  entry_count = version ? avio_rb32(pb) : avio_rb16(pb);
9352 
9353  heif_item = av_realloc_array(c->heif_item, FFMAX(entry_count, c->nb_heif_item), sizeof(*c->heif_item));
9354  if (!heif_item)
9355  return AVERROR(ENOMEM);
9356  c->heif_item = heif_item;
9357  if (entry_count > c->nb_heif_item)
9358  memset(&c->heif_item[c->nb_heif_item], 0,
9359  sizeof(*c->heif_item) * (entry_count - c->nb_heif_item));
9360  c->nb_heif_item = FFMAX(c->nb_heif_item, entry_count);
9361 
9362  for (i = 0; i < entry_count; i++) {
9363  MOVAtom infe;
9364 
9365  infe.size = avio_rb32(pb) - 8;
9366  infe.type = avio_rl32(pb);
9367  if (avio_feof(pb)) {
9369  goto fail;
9370  }
9371  ret = mov_read_infe(c, pb, infe);
9372  if (ret < 0)
9373  goto fail;
9374  if (!ret)
9375  got_stream = 1;
9376  }
9377 
9378  c->found_iinf = got_stream;
9379  return 0;
9380 fail:
9381  for (; i >= 0; i--) {
9382  HEIFItem *item = c->heif_item[i];
9383 
9384  if (!item)
9385  continue;
9386 
9387  av_freep(&item->name);
9388  }
9389  return ret;
9390 }
9391 
9393 {
9394  HEIFItem *item = NULL;
9395  HEIFGrid *grid;
9396  int entries, i;
9397  int from_item_id = version ? avio_rb32(pb) : avio_rb16(pb);
9398  int ret = 0;
9399 
9400  for (int i = 0; i < c->nb_heif_grid; i++) {
9401  if (c->heif_grid[i].item->item_id == from_item_id) {
9402  av_log(c->fc, AV_LOG_ERROR, "More than one 'dimg' box "
9403  "referencing the same Derived Image item\n");
9404  return AVERROR_INVALIDDATA;
9405  }
9406  }
9407  for (int i = 0; i < c->nb_heif_item; i++) {
9408  if (!c->heif_item[i] || c->heif_item[i]->item_id != from_item_id)
9409  continue;
9410  item = c->heif_item[i];
9411 
9412  switch (item->type) {
9413  case MKTAG('g','r','i','d'):
9414  case MKTAG('i','o','v','l'):
9415  break;
9416  default:
9417  avpriv_report_missing_feature(c->fc, "Derived Image item of type %s",
9418  av_fourcc2str(item->type));
9419  return 0;
9420  }
9421  break;
9422  }
9423  if (!item) {
9424  av_log(c->fc, AV_LOG_ERROR, "Missing grid information\n");
9425  return AVERROR_INVALIDDATA;
9426  }
9427 
9428  entries = avio_rb16(pb);
9429  if (!entries) {
9430  av_log(c->fc, AV_LOG_ERROR,
9431  "Derived image item references no input images\n");
9432  return AVERROR_INVALIDDATA;
9433  }
9434 
9435  grid = av_realloc_array(c->heif_grid, c->nb_heif_grid + 1U,
9436  sizeof(*c->heif_grid));
9437  if (!grid)
9438  return AVERROR(ENOMEM);
9439  c->heif_grid = grid;
9440  grid = &grid[c->nb_heif_grid];
9441 
9442  grid->tile_id_list = av_malloc_array(entries, sizeof(*grid->tile_id_list));
9443  grid->tile_idx_list = av_calloc(entries, sizeof(*grid->tile_idx_list));
9444  grid->tile_item_list = av_calloc(entries, sizeof(*grid->tile_item_list));
9445  if (!grid->tile_id_list || !grid->tile_item_list || !grid->tile_idx_list) {
9446  ret = AVERROR(ENOMEM);
9447  goto fail;
9448  }
9449  /* 'to' item ids */
9450  for (i = 0; i < entries; i++) {
9451  grid->tile_id_list[i] = version ? avio_rb32(pb) : avio_rb16(pb);
9452 
9453  if (avio_feof(pb)) {
9455  goto fail;
9456  }
9457  }
9458 
9459  grid->nb_tiles = entries;
9460  grid->item = item;
9461  ++c->nb_heif_grid;
9462 
9463  av_log(c->fc, AV_LOG_TRACE, "dimg: from_item_id %d, entries %d\n",
9464  from_item_id, entries);
9465 
9466  return 0;
9467 fail:
9468  av_freep(&grid->tile_id_list);
9469  av_freep(&grid->tile_idx_list);
9470  av_freep(&grid->tile_item_list);
9471 
9472  return ret;
9473 }
9474 
9475 static int mov_read_iref_cdsc(MOVContext *c, AVIOContext *pb, uint32_t type, int version, uint32_t size)
9476 {
9477  HEIFItem *from_item = NULL;
9478  int entries;
9479  int item_id_size = version ? 4 : 2;
9480  int from_item_id = version ? avio_rb32(pb) : avio_rb16(pb);
9481  const HEIFItemRef ref = { type, from_item_id };
9482 
9483  from_item = get_heif_item(c, from_item_id);
9484  if (!from_item) {
9485  av_log(c->fc, AV_LOG_ERROR, "Missing stream referenced by thmb item\n");
9486  return AVERROR_INVALIDDATA;
9487  }
9488 
9489  entries = avio_rb16(pb);
9490  if ((int64_t)entries * item_id_size > (int64_t)size - item_id_size - 2) {
9491  av_log(c->fc, AV_LOG_ERROR, "iref %s entry count %d exceeds the sub-box size\n",
9492  av_fourcc2str(type), entries);
9493  return AVERROR_INVALIDDATA;
9494  }
9495  /* 'to' item ids */
9496  for (int i = 0; i < entries; i++) {
9497  HEIFItem *item = get_heif_item(c, version ? avio_rb32(pb) : avio_rb16(pb));
9498 
9499  if (avio_feof(pb))
9500  return AVERROR_INVALIDDATA;
9501 
9502  if (!item) {
9503  av_log(c->fc, AV_LOG_WARNING, "Missing stream referenced by %s item\n",
9504  av_fourcc2str(type));
9505  continue;
9506  }
9507 
9508  if (!av_dynarray2_add((void **)&item->iref_list, &item->nb_iref_list,
9509  sizeof(*item->iref_list), (const uint8_t *)&ref))
9510  return AVERROR(ENOMEM);
9511  }
9512 
9513  av_log(c->fc, AV_LOG_TRACE, "%s: from_item_id %d, entries %d\n",
9514  av_fourcc2str(type), from_item_id, entries);
9515 
9516  return 0;
9517 }
9518 
9520 {
9521  int version = avio_r8(pb);
9522  int ret;
9523 
9524  avio_rb24(pb); // flags
9525  atom.size -= 4;
9526 
9527  if (version > 1) {
9528  av_log(c->fc, AV_LOG_WARNING, "Unknown iref box version %d\n", version);
9529  return 0;
9530  }
9531 
9532  while (atom.size) {
9533  int64_t next = avio_tell(pb);
9534  uint32_t type, size = avio_rb32(pb);
9535 
9536  if (size < 14 || size > atom.size || next > INT64_MAX - size)
9537  return AVERROR_INVALIDDATA;
9538 
9539  next += size;
9540  type = avio_rl32(pb);
9541  switch (type) {
9542  case MKTAG('d','i','m','g'):
9543  ret = mov_read_iref_dimg(c, pb, version);
9544  if (ret < 0)
9545  return ret;
9546  break;
9547  case MKTAG('c','d','s','c'):
9548  case MKTAG('t','h','m','b'):
9549  ret = mov_read_iref_cdsc(c, pb, type, version, size - 8);
9550  if (ret < 0)
9551  return ret;
9552  break;
9553  default:
9554  av_log(c->fc, AV_LOG_DEBUG, "Unknown iref type %s size %"PRIu32"\n",
9555  av_fourcc2str(type), size);
9556  }
9557 
9558  atom.size -= size;
9559  avio_seek(pb, next, SEEK_SET);
9560  }
9561  return 0;
9562 }
9563 
9565 {
9566  HEIFItem *item;
9567  uint32_t width, height;
9568 
9569  avio_r8(pb); /* version */
9570  avio_rb24(pb); /* flags */
9571  width = avio_rb32(pb);
9572  height = avio_rb32(pb);
9573 
9574  av_log(c->fc, AV_LOG_TRACE, "ispe: item_id %d, width %"PRIu32", height %"PRIu32"\n",
9575  c->cur_item_id, width, height);
9576 
9577  if (!width || !height || width > INT_MAX || height > INT_MAX) {
9578  av_log(c->fc, AV_LOG_ERROR, "Invalid ispe dimensions %"PRIu32"x%"PRIu32"\n",
9579  width, height);
9580  return AVERROR_INVALIDDATA;
9581  }
9582 
9583  item = get_heif_item(c, c->cur_item_id);
9584  if (item) {
9585  item->width = width;
9586  item->height = height;
9587  }
9588 
9589  return 0;
9590 }
9591 
9593 {
9594  HEIFItem *item;
9595  int angle;
9596 
9597  angle = avio_r8(pb) & 0x3;
9598 
9599  av_log(c->fc, AV_LOG_TRACE, "irot: item_id %d, angle %u\n",
9600  c->cur_item_id, angle);
9601 
9602  item = get_heif_item(c, c->cur_item_id);
9603  if (item) {
9604  // angle * 90 specifies the angle (in anti-clockwise direction)
9605  // in units of degrees.
9606  item->rotation = angle * 90;
9607  }
9608 
9609  return 0;
9610 }
9611 
9613 {
9614  HEIFItem *item;
9615  int axis;
9616 
9617  axis = avio_r8(pb) & 0x1;
9618 
9619  av_log(c->fc, AV_LOG_TRACE, "imir: item_id %d, axis %u\n",
9620  c->cur_item_id, axis);
9621 
9622  item = get_heif_item(c, c->cur_item_id);
9623  if (item) {
9624  item->hflip = axis;
9625  item->vflip = !axis;
9626  }
9627 
9628  return 0;
9629 }
9630 
9632 {
9633  typedef struct MOVAtoms {
9634  FFIOContext b;
9635  uint32_t type;
9636  int64_t size;
9637  uint8_t *data;
9638  } MOVAtoms;
9639  MOVAtoms *atoms = NULL;
9640  MOVAtom a;
9641  unsigned count;
9642  int nb_atoms = 0;
9643  int version, flags;
9644  int ret;
9645 
9646  a.size = avio_rb32(pb);
9647  a.type = avio_rl32(pb);
9648 
9649  if (a.size < 8 || a.type != MKTAG('i','p','c','o'))
9650  return AVERROR_INVALIDDATA;
9651 
9652  a.size -= 8;
9653  while (a.size >= 8) {
9654  MOVAtoms *ref = av_dynarray2_add((void**)&atoms, &nb_atoms, sizeof(MOVAtoms), NULL);
9655  if (!ref) {
9656  ret = AVERROR(ENOMEM);
9657  goto fail;
9658  }
9659  ref->data = NULL;
9660  ref->size = avio_rb32(pb);
9661  ref->type = avio_rl32(pb);
9662  if (ref->size > a.size || ref->size < 8)
9663  break;
9664  ref->data = av_malloc(ref->size);
9665  if (!ref->data) {
9667  goto fail;
9668  }
9669  av_log(c->fc, AV_LOG_TRACE, "ipco: index %d, box type %s\n", nb_atoms, av_fourcc2str(ref->type));
9670  avio_seek(pb, -8, SEEK_CUR);
9671  if (avio_read(pb, ref->data, ref->size) != ref->size) {
9673  goto fail;
9674  }
9675  ffio_init_read_context(&ref->b, ref->data, ref->size);
9676  a.size -= ref->size;
9677  }
9678 
9679  if (a.size) {
9681  goto fail;
9682  }
9683 
9684  a.size = avio_rb32(pb);
9685  a.type = avio_rl32(pb);
9686 
9687  if (a.size < 8 || a.type != MKTAG('i','p','m','a')) {
9689  goto fail;
9690  }
9691 
9692  version = avio_r8(pb);
9693  flags = avio_rb24(pb);
9694  count = avio_rb32(pb);
9695 
9696  for (int i = 0; i < count; i++) {
9697  int item_id = version ? avio_rb32(pb) : avio_rb16(pb);
9698  int assoc_count = avio_r8(pb);
9699 
9700  if (avio_feof(pb)) {
9702  goto fail;
9703  }
9704 
9705  for (int j = 0; j < assoc_count; j++) {
9706  MOVAtoms *ref;
9707  int index = avio_r8(pb) & 0x7f;
9708  if (flags & 1) {
9709  index <<= 8;
9710  index |= avio_r8(pb);
9711  }
9712  if (index > nb_atoms || index <= 0) {
9714  goto fail;
9715  }
9716  ref = &atoms[--index];
9717 
9718  av_log(c->fc, AV_LOG_TRACE, "ipma: property_index %d, item_id %d, item_type %s\n",
9719  index + 1, item_id, av_fourcc2str(ref->type));
9720 
9721  c->cur_item_id = item_id;
9722 
9723  ret = mov_read_default(c, &ref->b.pub,
9724  (MOVAtom) { .size = ref->size,
9725  .type = MKTAG('i','p','c','o') });
9726  if (ret < 0)
9727  goto fail;
9728  ffio_init_read_context(&ref->b, ref->data, ref->size);
9729  }
9730  }
9731 
9732  ret = 0;
9733 fail:
9734  c->cur_item_id = -1;
9735  for (int i = 0; i < nb_atoms; i++)
9736  av_free(atoms[i].data);
9737  av_free(atoms);
9738 
9739  return ret;
9740 }
9741 
9743 { MKTAG('A','C','L','R'), mov_read_aclr },
9744 { MKTAG('A','P','R','G'), mov_read_avid },
9745 { MKTAG('A','A','L','P'), mov_read_avid },
9746 { MKTAG('A','R','E','S'), mov_read_ares },
9747 { MKTAG('a','v','s','s'), mov_read_avss },
9748 { MKTAG('a','v','1','C'), mov_read_glbl },
9749 { MKTAG('c','h','p','l'), mov_read_chpl },
9750 { MKTAG('c','o','6','4'), mov_read_stco },
9751 { MKTAG('c','o','l','r'), mov_read_colr },
9752 { MKTAG('c','t','t','s'), mov_read_ctts }, /* composition time to sample */
9753 { MKTAG('d','i','n','f'), mov_read_default },
9754 { MKTAG('D','p','x','E'), mov_read_dpxe },
9755 { MKTAG('d','r','e','f'), mov_read_dref },
9756 { MKTAG('e','d','t','s'), mov_read_default },
9757 { MKTAG('e','l','s','t'), mov_read_elst },
9758 { MKTAG('e','n','d','a'), mov_read_enda },
9759 { MKTAG('f','i','e','l'), mov_read_fiel },
9760 { MKTAG('a','d','r','m'), mov_read_adrm },
9761 { MKTAG('f','t','y','p'), mov_read_ftyp },
9762 { MKTAG('g','l','b','l'), mov_read_glbl },
9763 { MKTAG('h','d','l','r'), mov_read_hdlr },
9764 { MKTAG('i','l','s','t'), mov_read_ilst },
9765 { MKTAG('j','p','2','h'), mov_read_jp2h },
9766 { MKTAG('m','d','a','t'), mov_read_mdat },
9767 { MKTAG('m','d','h','d'), mov_read_mdhd },
9768 { MKTAG('m','d','i','a'), mov_read_default },
9769 { MKTAG('m','e','t','a'), mov_read_meta },
9770 { MKTAG('m','i','n','f'), mov_read_default },
9771 { MKTAG('m','o','o','f'), mov_read_moof },
9772 { MKTAG('m','o','o','v'), mov_read_moov },
9773 { MKTAG('m','v','e','x'), mov_read_default },
9774 { MKTAG('m','v','h','d'), mov_read_mvhd },
9775 { MKTAG('S','M','I',' '), mov_read_svq3 },
9776 { MKTAG('a','l','a','c'), mov_read_alac }, /* alac specific atom */
9777 { MKTAG('a','v','c','C'), mov_read_glbl },
9778 { MKTAG('p','a','s','p'), mov_read_pasp },
9779 { MKTAG('c','l','a','p'), mov_read_clap },
9780 { MKTAG('s','b','a','s'), mov_read_sbas },
9781 { MKTAG('v','d','e','p'), mov_read_vdep },
9782 { MKTAG('s','i','d','x'), mov_read_sidx },
9783 { MKTAG('s','t','b','l'), mov_read_default },
9784 { MKTAG('s','t','c','o'), mov_read_stco },
9785 { MKTAG('s','t','p','s'), mov_read_stps },
9786 { MKTAG('s','t','r','f'), mov_read_strf },
9787 { MKTAG('s','t','s','c'), mov_read_stsc },
9788 { MKTAG('s','t','s','d'), mov_read_stsd }, /* sample description */
9789 { MKTAG('s','t','s','s'), mov_read_stss }, /* sync sample */
9790 { MKTAG('s','t','s','z'), mov_read_stsz }, /* sample size */
9791 { MKTAG('s','t','t','s'), mov_read_stts },
9792 { MKTAG('s','t','z','2'), mov_read_stsz }, /* compact sample size */
9793 { MKTAG('s','d','t','p'), mov_read_sdtp }, /* independent and disposable samples */
9794 { MKTAG('t','k','h','d'), mov_read_tkhd }, /* track header */
9795 { MKTAG('t','f','d','t'), mov_read_tfdt },
9796 { MKTAG('t','f','h','d'), mov_read_tfhd }, /* track fragment header */
9797 { MKTAG('t','r','a','k'), mov_read_trak },
9798 { MKTAG('t','r','a','f'), mov_read_default },
9799 { MKTAG('t','r','e','f'), mov_read_default },
9800 { MKTAG('t','m','c','d'), mov_read_tmcd },
9801 { MKTAG('c','h','a','p'), mov_read_chap },
9802 { MKTAG('t','r','e','x'), mov_read_trex },
9803 { MKTAG('t','r','u','n'), mov_read_trun },
9804 { MKTAG('u','d','t','a'), mov_read_default },
9805 { MKTAG('w','a','v','e'), mov_read_wave },
9806 { MKTAG('e','s','d','s'), mov_read_esds },
9807 { MKTAG('d','a','c','3'), mov_read_dac3 }, /* AC-3 info */
9808 { MKTAG('d','e','c','3'), mov_read_dec3 }, /* EAC-3 info */
9809 { MKTAG('d','d','t','s'), mov_read_ddts }, /* DTS audio descriptor */
9810 { MKTAG('w','i','d','e'), mov_read_wide }, /* place holder */
9811 { MKTAG('w','f','e','x'), mov_read_wfex },
9812 { MKTAG('c','m','o','v'), mov_read_cmov },
9813 { MKTAG('c','h','a','n'), mov_read_chan }, /* channel layout from quicktime */
9814 { MKTAG('c','h','n','l'), mov_read_chnl }, /* channel layout from ISO-14496-12 */
9815 { MKTAG('d','v','c','1'), mov_read_dvc1 },
9816 { MKTAG('s','g','p','d'), mov_read_sgpd },
9817 { MKTAG('s','b','g','p'), mov_read_sbgp },
9818 { MKTAG('h','v','c','C'), mov_read_glbl },
9819 { MKTAG('v','v','c','C'), mov_read_glbl },
9820 { MKTAG('u','u','i','d'), mov_read_uuid },
9821 { MKTAG('C','i','n', 0x8e), mov_read_targa_y216 },
9822 { MKTAG('f','r','e','e'), mov_read_free },
9823 { MKTAG('-','-','-','-'), mov_read_custom },
9824 { MKTAG('s','i','n','f'), mov_read_default },
9825 { MKTAG('f','r','m','a'), mov_read_frma },
9826 { MKTAG('s','e','n','c'), mov_read_senc },
9827 { MKTAG('s','a','i','z'), mov_read_saiz },
9828 { MKTAG('s','a','i','o'), mov_read_saio },
9829 { MKTAG('p','s','s','h'), mov_read_pssh },
9830 { MKTAG('s','c','h','m'), mov_read_schm },
9831 { MKTAG('s','c','h','i'), mov_read_default },
9832 { MKTAG('t','e','n','c'), mov_read_tenc },
9833 { MKTAG('d','f','L','a'), mov_read_dfla },
9834 { MKTAG('s','t','3','d'), mov_read_st3d }, /* stereoscopic 3D video box */
9835 { MKTAG('s','v','3','d'), mov_read_sv3d }, /* spherical video box */
9836 { MKTAG('v','e','x','u'), mov_read_vexu }, /* video extension usage */
9837 { MKTAG('h','f','o','v'), mov_read_hfov },
9838 { MKTAG('d','O','p','s'), mov_read_dops },
9839 { MKTAG('d','m','l','p'), mov_read_dmlp },
9840 { MKTAG('S','m','D','m'), mov_read_smdm },
9841 { MKTAG('C','o','L','L'), mov_read_coll },
9842 { MKTAG('v','p','c','C'), mov_read_vpcc },
9843 { MKTAG('m','d','c','v'), mov_read_mdcv },
9844 { MKTAG('c','l','l','i'), mov_read_clli },
9845 { MKTAG('d','v','c','C'), mov_read_dvcc_dvvc },
9846 { MKTAG('d','v','v','C'), mov_read_dvcc_dvvc },
9847 { MKTAG('d','v','w','C'), mov_read_dvcc_dvvc },
9848 { MKTAG('h','v','c','E'), mov_read_hvce },
9849 { MKTAG('k','i','n','d'), mov_read_kind },
9850 { MKTAG('S','A','3','D'), mov_read_SA3D }, /* ambisonic audio box */
9851 { MKTAG('S','A','N','D'), mov_read_SAND }, /* non diegetic audio box */
9852 { MKTAG('i','l','o','c'), mov_read_iloc },
9853 { MKTAG('p','c','m','C'), mov_read_pcmc }, /* PCM configuration box */
9854 { MKTAG('p','i','t','m'), mov_read_pitm },
9855 { MKTAG('e','v','c','C'), mov_read_glbl },
9856 { MKTAG('i','d','a','t'), mov_read_idat },
9857 { MKTAG('i','m','i','r'), mov_read_imir },
9858 { MKTAG('i','r','e','f'), mov_read_iref },
9859 { MKTAG('i','s','p','e'), mov_read_ispe },
9860 { MKTAG('i','r','o','t'), mov_read_irot },
9861 { MKTAG('i','p','r','p'), mov_read_iprp },
9862 { MKTAG('i','i','n','f'), mov_read_iinf },
9863 { MKTAG('a','m','v','e'), mov_read_amve }, /* ambient viewing environment box */
9864 { MKTAG('l','h','v','C'), mov_read_lhvc },
9865 { MKTAG('l','v','c','C'), mov_read_glbl },
9866 { MKTAG('a','p','v','C'), mov_read_glbl },
9867 #if CONFIG_IAMFDEC
9868 { MKTAG('i','a','c','b'), mov_read_iacb },
9869 #endif
9870 { MKTAG('s','r','a','t'), mov_read_srat },
9871 { 0, NULL }
9872 };
9873 
9875 {
9876  int64_t total_size = 0;
9877  MOVAtom a;
9878  int i;
9879 
9880  if (c->atom_depth > 10) {
9881  av_log(c->fc, AV_LOG_ERROR, "Atoms too deeply nested\n");
9882  return AVERROR_INVALIDDATA;
9883  }
9884  c->atom_depth ++;
9885 
9886  if (atom.size < 0)
9887  atom.size = INT64_MAX;
9888  while (total_size <= atom.size - 8) {
9889  int (*parse)(MOVContext*, AVIOContext*, MOVAtom) = NULL;
9890  a.size = avio_rb32(pb);
9891  a.type = avio_rl32(pb);
9892  if (avio_feof(pb))
9893  break;
9894  if (((a.type == MKTAG('f','r','e','e') && c->moov_retry) ||
9895  a.type == MKTAG('h','o','o','v')) &&
9896  a.size >= 8 &&
9897  c->fc->strict_std_compliance < FF_COMPLIANCE_STRICT) {
9898  uint32_t type;
9899  avio_skip(pb, 4);
9900  type = avio_rl32(pb);
9901  if (avio_feof(pb))
9902  break;
9903  avio_seek(pb, -8, SEEK_CUR);
9904  if (type == MKTAG('m','v','h','d') ||
9905  type == MKTAG('c','m','o','v')) {
9906  av_log(c->fc, AV_LOG_ERROR, "Detected moov in a free or hoov atom.\n");
9907  a.type = MKTAG('m','o','o','v');
9908  }
9909  }
9910  if (atom.type != MKTAG('r','o','o','t') &&
9911  atom.type != MKTAG('m','o','o','v')) {
9912  if (a.type == MKTAG('t','r','a','k') ||
9913  a.type == MKTAG('m','d','a','t')) {
9914  av_log(c->fc, AV_LOG_ERROR, "Broken file, trak/mdat not at top-level\n");
9915  avio_skip(pb, -8);
9916  c->atom_depth --;
9917  return 0;
9918  }
9919  }
9920  total_size += 8;
9921  if (a.size == 1 && total_size + 8 <= atom.size) { /* 64 bit extended size */
9922  a.size = avio_rb64(pb) - 8;
9923  total_size += 8;
9924  }
9925  av_log(c->fc, AV_LOG_TRACE, "type:'%s' parent:'%s' sz: %"PRId64" %"PRId64" %"PRId64"\n",
9926  av_fourcc2str(a.type), av_fourcc2str(atom.type), a.size, total_size, atom.size);
9927  if (a.size == 0) {
9928  a.size = atom.size - total_size + 8;
9929  }
9930  if (a.size < 0)
9931  break;
9932  a.size -= 8;
9933  if (a.size < 0)
9934  break;
9935  a.size = FFMIN(a.size, atom.size - total_size);
9936 
9937  for (i = 0; mov_default_parse_table[i].type; i++)
9938  if (mov_default_parse_table[i].type == a.type) {
9940  break;
9941  }
9942 
9943  // container is user data
9944  if (!parse && (atom.type == MKTAG('u','d','t','a') ||
9945  atom.type == MKTAG('i','l','s','t')))
9947 
9948  // Supports parsing the QuickTime Metadata Keys.
9949  // https://developer.apple.com/library/mac/documentation/QuickTime/QTFF/Metadata/Metadata.html
9950  if (!parse && c->found_hdlr_mdta &&
9951  atom.type == MKTAG('m','e','t','a') &&
9952  a.type == MKTAG('k','e','y','s') &&
9953  c->meta_keys_count == 0) {
9954  parse = mov_read_keys;
9955  }
9956 
9957  if (!parse) { /* skip leaf atoms data */
9958  avio_skip(pb, a.size);
9959  } else {
9960  int64_t start_pos = avio_tell(pb);
9961  int64_t left;
9962  int err = parse(c, pb, a);
9963  if (err < 0) {
9964  c->atom_depth --;
9965  return err;
9966  }
9967  if (c->found_moov && c->found_mdat && a.size <= INT64_MAX - start_pos &&
9968  ((!(pb->seekable & AVIO_SEEKABLE_NORMAL) || c->fc->flags & AVFMT_FLAG_IGNIDX || c->frag_index.complete) ||
9969  start_pos + a.size == avio_size(pb))) {
9970  if (!(pb->seekable & AVIO_SEEKABLE_NORMAL) || c->fc->flags & AVFMT_FLAG_IGNIDX || c->frag_index.complete)
9971  c->next_root_atom = start_pos + a.size;
9972  c->atom_depth --;
9973  return 0;
9974  }
9975  left = a.size - avio_tell(pb) + start_pos;
9976  if (left > 0) /* skip garbage at atom end */
9977  avio_skip(pb, left);
9978  else if (left < 0) {
9979  av_log(c->fc, AV_LOG_WARNING,
9980  "overread end of atom '%s' by %"PRId64" bytes\n",
9981  av_fourcc2str(a.type), -left);
9982  avio_seek(pb, left, SEEK_CUR);
9983  }
9984  }
9985 
9986  total_size += a.size;
9987  }
9988 
9989  if (total_size < atom.size && atom.size < 0x7ffff)
9990  avio_skip(pb, atom.size - total_size);
9991 
9992  c->atom_depth --;
9993  return 0;
9994 }
9995 
9996 static int mov_probe(const AVProbeData *p)
9997 {
9998  int64_t offset;
9999  uint32_t tag;
10000  int score = 0;
10001  int moov_offset = -1;
10002 
10003  /* check file header */
10004  offset = 0;
10005  for (;;) {
10006  int64_t size;
10007  int minsize = 8;
10008  /* ignore invalid offset */
10009  if ((offset + 8ULL) > (unsigned int)p->buf_size)
10010  break;
10011  size = AV_RB32(p->buf + offset);
10012  if (size == 1 && offset + 16 <= (unsigned int)p->buf_size) {
10013  size = AV_RB64(p->buf+offset + 8);
10014  minsize = 16;
10015  } else if (size == 0) {
10016  size = p->buf_size - offset;
10017  }
10018  if (size < minsize) {
10019  offset += 4;
10020  continue;
10021  }
10022  tag = AV_RL32(p->buf + offset + 4);
10023  switch(tag) {
10024  /* check for obvious tags */
10025  case MKTAG('m','o','o','v'):
10026  moov_offset = offset + 4;
10028  case MKTAG('m','d','a','t'):
10029  case MKTAG('p','n','o','t'): /* detect movs with preview pics like ew.mov and april.mov */
10030  case MKTAG('u','d','t','a'): /* Packet Video PVAuthor adds this and a lot of more junk */
10031  case MKTAG('f','t','y','p'):
10032  if (tag == MKTAG('f','t','y','p') &&
10033  ( AV_RL32(p->buf + offset + 8) == MKTAG('j','p','2',' ')
10034  || AV_RL32(p->buf + offset + 8) == MKTAG('j','p','x',' ')
10035  || AV_RL32(p->buf + offset + 8) == MKTAG('j','x','l',' ')
10036  )) {
10037  score = FFMAX(score, 5);
10038  } else {
10039  score = AVPROBE_SCORE_MAX;
10040  }
10041  break;
10042  /* those are more common words, so rate then a bit less */
10043  case MKTAG('e','d','i','w'): /* xdcam files have reverted first tags */
10044  case MKTAG('w','i','d','e'):
10045  case MKTAG('f','r','e','e'):
10046  case MKTAG('j','u','n','k'):
10047  case MKTAG('p','i','c','t'):
10048  score = FFMAX(score, AVPROBE_SCORE_MAX - 5);
10049  break;
10050  case MKTAG(0x82,0x82,0x7f,0x7d):
10051  score = FFMAX(score, AVPROBE_SCORE_EXTENSION - 5);
10052  break;
10053  case MKTAG('s','k','i','p'):
10054  case MKTAG('u','u','i','d'):
10055  case MKTAG('p','r','f','l'):
10056  /* if we only find those cause probedata is too small at least rate them */
10057  score = FFMAX(score, AVPROBE_SCORE_EXTENSION);
10058  break;
10059  }
10060  if (size > INT64_MAX - offset)
10061  break;
10062  offset += size;
10063  }
10064  if (score > AVPROBE_SCORE_MAX - 50 && moov_offset != -1) {
10065  /* moov atom in the header - we should make sure that this is not a
10066  * MOV-packed MPEG-PS */
10067  offset = moov_offset;
10068 
10069  while (offset < (p->buf_size - 16)) { /* Sufficient space */
10070  /* We found an actual hdlr atom */
10071  if (AV_RL32(p->buf + offset ) == MKTAG('h','d','l','r') &&
10072  AV_RL32(p->buf + offset + 8) == MKTAG('m','h','l','r') &&
10073  AV_RL32(p->buf + offset + 12) == MKTAG('M','P','E','G')) {
10074  av_log(NULL, AV_LOG_WARNING, "Found media data tag MPEG indicating this is a MOV-packed MPEG-PS.\n");
10075  /* We found a media handler reference atom describing an
10076  * MPEG-PS-in-MOV, return a
10077  * low score to force expanding the probe window until
10078  * mpegps_probe finds what it needs */
10079  return 5;
10080  } else {
10081  /* Keep looking */
10082  offset += 2;
10083  }
10084  }
10085  }
10086 
10087  return score;
10088 }
10089 
10090 // must be done after parsing all trak because there's no order requirement
10092 {
10093  MOVContext *mov = s->priv_data;
10094  MOVStreamContext *sc;
10095  int64_t cur_pos;
10096  int i, j;
10097  int chapter_track;
10098 
10099  for (j = 0; j < mov->nb_chapter_tracks; j++) {
10100  AVStream *st = NULL;
10101  FFStream *sti = NULL;
10102  chapter_track = mov->chapter_tracks[j];
10103  for (i = 0; i < s->nb_streams; i++) {
10104  sc = mov->fc->streams[i]->priv_data;
10105  if (sc->id == chapter_track) {
10106  st = s->streams[i];
10107  break;
10108  }
10109  }
10110  if (!st) {
10111  av_log(s, AV_LOG_ERROR, "Referenced QT chapter track not found\n");
10112  continue;
10113  }
10114  sti = ffstream(st);
10115 
10116  sc = st->priv_data;
10117  cur_pos = avio_tell(sc->pb);
10118 
10119  if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
10121  if (!st->attached_pic.data && sti->nb_index_entries) {
10122  // Retrieve the first frame, if possible
10123  AVIndexEntry *sample = &sti->index_entries[0];
10124  if (avio_seek(sc->pb, sample->pos, SEEK_SET) != sample->pos) {
10125  av_log(s, AV_LOG_ERROR, "Failed to retrieve first frame\n");
10126  goto finish;
10127  }
10128 
10129  if (ff_add_attached_pic(s, st, sc->pb, NULL, sample->size) < 0)
10130  goto finish;
10131  }
10132  } else {
10135  st->discard = AVDISCARD_ALL;
10136  for (int i = 0; i < sti->nb_index_entries; i++) {
10137  AVIndexEntry *sample = &sti->index_entries[i];
10138  int64_t end = i+1 < sti->nb_index_entries ? sti->index_entries[i+1].timestamp : st->duration;
10139  uint8_t *title;
10140  uint16_t ch;
10141  int len, title_len;
10142 
10143  if (end < sample->timestamp) {
10144  av_log(s, AV_LOG_WARNING, "ignoring stream duration which is shorter than chapters\n");
10145  end = AV_NOPTS_VALUE;
10146  }
10147 
10148  if (avio_seek(sc->pb, sample->pos, SEEK_SET) != sample->pos) {
10149  av_log(s, AV_LOG_ERROR, "Chapter %d not found in file\n", i);
10150  goto finish;
10151  }
10152 
10153  // the first two bytes are the length of the title
10154  len = avio_rb16(sc->pb);
10155  if (len > sample->size-2)
10156  continue;
10157  title_len = 2*len + 1;
10158  if (!(title = av_mallocz(title_len)))
10159  goto finish;
10160 
10161  // The samples could theoretically be in any encoding if there's an encd
10162  // atom following, but in practice are only utf-8 or utf-16, distinguished
10163  // instead by the presence of a BOM
10164  if (!len) {
10165  title[0] = 0;
10166  } else {
10167  ch = avio_rb16(sc->pb);
10168  if (ch == 0xfeff)
10169  avio_get_str16be(sc->pb, len, title, title_len);
10170  else if (ch == 0xfffe)
10171  avio_get_str16le(sc->pb, len, title, title_len);
10172  else {
10173  AV_WB16(title, ch);
10174  if (len == 1 || len == 2)
10175  title[len] = 0;
10176  else
10177  avio_get_str(sc->pb, INT_MAX, title + 2, len - 1);
10178  }
10179  }
10180 
10181  avpriv_new_chapter(s, i, st->time_base, sample->timestamp, end, title);
10182  av_freep(&title);
10183  }
10184  }
10185 finish:
10186  avio_seek(sc->pb, cur_pos, SEEK_SET);
10187  }
10188 }
10189 
10191  int64_t value, int flags)
10192 {
10193  AVTimecode tc;
10194  char buf[AV_TIMECODE_STR_SIZE];
10195  AVRational rate = st->avg_frame_rate;
10196  int ret = av_timecode_init(&tc, rate, flags, 0, s);
10197  if (ret < 0)
10198  return ret;
10199  av_dict_set(&st->metadata, "timecode",
10200  av_timecode_make_string(&tc, buf, value), 0);
10201  return 0;
10202 }
10203 
10205 {
10206  MOVStreamContext *sc = st->priv_data;
10207  FFStream *const sti = ffstream(st);
10208  char buf[AV_TIMECODE_STR_SIZE];
10209  int64_t cur_pos = avio_tell(sc->pb);
10210  int hh, mm, ss, ff, drop;
10211 
10212  if (!sti->nb_index_entries)
10213  return -1;
10214 
10215  avio_seek(sc->pb, sti->index_entries->pos, SEEK_SET);
10216  avio_skip(s->pb, 13);
10217  hh = avio_r8(s->pb);
10218  mm = avio_r8(s->pb);
10219  ss = avio_r8(s->pb);
10220  drop = avio_r8(s->pb);
10221  ff = avio_r8(s->pb);
10222  snprintf(buf, AV_TIMECODE_STR_SIZE, "%02d:%02d:%02d%c%02d",
10223  hh, mm, ss, drop ? ';' : ':', ff);
10224  av_dict_set(&st->metadata, "timecode", buf, 0);
10225 
10226  avio_seek(sc->pb, cur_pos, SEEK_SET);
10227  return 0;
10228 }
10229 
10231 {
10232  MOVStreamContext *sc = st->priv_data;
10233  FFStream *const sti = ffstream(st);
10234  int flags = 0;
10235  int64_t cur_pos = avio_tell(sc->pb);
10236  int64_t value;
10237  AVRational tc_rate = st->avg_frame_rate;
10238  int tmcd_nb_frames = sc->tmcd_nb_frames;
10239  int rounded_tc_rate;
10240 
10241  if (!sti->nb_index_entries)
10242  return -1;
10243 
10244  if (!tc_rate.num || !tc_rate.den || !tmcd_nb_frames)
10245  return -1;
10246 
10247  avio_seek(sc->pb, sti->index_entries->pos, SEEK_SET);
10248  value = avio_rb32(s->pb);
10249 
10250  if (sc->tmcd_flags & 0x0001) flags |= AV_TIMECODE_FLAG_DROPFRAME;
10251  if (sc->tmcd_flags & 0x0002) flags |= AV_TIMECODE_FLAG_24HOURSMAX;
10252  if (sc->tmcd_flags & 0x0004) flags |= AV_TIMECODE_FLAG_ALLOWNEGATIVE;
10253 
10254  /* Assume Counter flag is set to 1 in tmcd track (even though it is likely
10255  * not the case) and thus assume "frame number format" instead of QT one.
10256  * No sample with tmcd track can be found with a QT timecode at the moment,
10257  * despite what the tmcd track "suggests" (Counter flag set to 0 means QT
10258  * format). */
10259 
10260  /* 60 fps content have tmcd_nb_frames set to 30 but tc_rate set to 60, so
10261  * we multiply the frame number with the quotient.
10262  * See tickets #9492, #9710. */
10263  rounded_tc_rate = (tc_rate.num + tc_rate.den / 2LL) / tc_rate.den;
10264  /* Work around files where tmcd_nb_frames is rounded down from frame rate
10265  * instead of up. See ticket #5978. */
10266  if (tmcd_nb_frames == tc_rate.num / tc_rate.den &&
10267  s->strict_std_compliance < FF_COMPLIANCE_STRICT)
10268  tmcd_nb_frames = rounded_tc_rate;
10269  value = av_rescale(value, rounded_tc_rate, tmcd_nb_frames);
10270 
10272 
10273  avio_seek(sc->pb, cur_pos, SEEK_SET);
10274  return 0;
10275 }
10276 
10278  int i;
10279  if (!index || !*index) return;
10280  for (i = 0; i < (*index)->nb_encrypted_samples; i++) {
10281  av_encryption_info_free((*index)->encrypted_samples[i]);
10282  }
10283  av_freep(&(*index)->encrypted_samples);
10284  av_freep(&(*index)->auxiliary_info_sizes);
10285  av_freep(&(*index)->auxiliary_offsets);
10286  av_freep(index);
10287 }
10288 
10290 {
10291  MOVStreamContext *sc = st->priv_data;
10292 
10293  if (!sc || --sc->refcount) {
10294  st->priv_data = NULL;
10295  return;
10296  }
10297 
10298  av_freep(&sc->tts_data);
10299  for (int i = 0; i < sc->drefs_count; i++) {
10300  av_freep(&sc->drefs[i].path);
10301  av_freep(&sc->drefs[i].dir);
10302  }
10303  av_freep(&sc->drefs);
10304 
10305  sc->drefs_count = 0;
10306 
10307  if (!sc->pb_is_copied)
10308  ff_format_io_close(s, &sc->pb);
10309 
10310  sc->pb = NULL;
10311  av_freep(&sc->chunk_offsets);
10312  av_freep(&sc->stsc_data);
10313  av_freep(&sc->sample_sizes);
10314  av_freep(&sc->keyframes);
10315  av_freep(&sc->ctts_data);
10316  av_freep(&sc->stts_data);
10317  av_freep(&sc->sdtp_data);
10318  av_freep(&sc->stps_data);
10319  av_freep(&sc->elst_data);
10320  av_freep(&sc->rap_group);
10321  av_freep(&sc->sync_group);
10322  av_freep(&sc->sgpd_sync);
10323  av_freep(&sc->sample_offsets);
10324  av_freep(&sc->open_key_samples);
10325  av_freep(&sc->display_matrix);
10326  av_freep(&sc->index_ranges);
10327  for (int i = 0; i < sc->nb_tref_tags; i++)
10328  av_freep(&sc->tref_tags[i].id);
10329  av_freep(&sc->tref_tags);
10330 
10331  if (sc->extradata)
10332  for (int i = 0; i < sc->stsd_count; i++)
10333  av_free(sc->extradata[i]);
10334  av_freep(&sc->extradata);
10335  av_freep(&sc->extradata_size);
10336 
10340 
10341  av_freep(&sc->stereo3d);
10342  av_freep(&sc->spherical);
10343  av_freep(&sc->mastering);
10344  av_freep(&sc->coll);
10345  av_freep(&sc->ambient);
10346 
10347 #if CONFIG_IAMFDEC
10348  if (sc->iamf)
10350 #endif
10351  av_freep(&sc->iamf);
10352 }
10353 
10355 {
10356  MOVContext *mov = s->priv_data;
10357  int i, j;
10358 
10359  for (i = 0; i < s->nb_streams; i++) {
10360  AVStream *st = s->streams[i];
10361 
10363  }
10364 
10365  av_freep(&mov->dv_demux);
10367  mov->dv_fctx = NULL;
10368 
10369  if (mov->meta_keys) {
10370  for (i = 1; i < mov->meta_keys_count; i++) {
10371  av_freep(&mov->meta_keys[i]);
10372  }
10373  av_freep(&mov->meta_keys);
10374  }
10375 
10376  av_freep(&mov->trex_data);
10377  av_freep(&mov->bitrates);
10378 
10379  for (i = 0; i < mov->frag_index.nb_items; i++) {
10381  for (j = 0; j < mov->frag_index.item[i].nb_stream_info; j++) {
10382  mov_free_encryption_index(&frag[j].encryption_index);
10383  }
10385  }
10386  av_freep(&mov->frag_index.item);
10387 
10388  av_freep(&mov->aes_decrypt);
10389  av_freep(&mov->chapter_tracks);
10390  for (i = 0; i < mov->nb_heif_item; i++) {
10391  if (!mov->heif_item[i])
10392  continue;
10393  av_freep(&mov->heif_item[i]->name);
10394  av_freep(&mov->heif_item[i]->iref_list);
10395  av_freep(&mov->heif_item[i]->icc_profile);
10396  av_freep(&mov->heif_item[i]);
10397  }
10398  av_freep(&mov->heif_item);
10399  for (i = 0; i < mov->nb_heif_grid; i++) {
10400  av_freep(&mov->heif_grid[i].tile_id_list);
10403  }
10404  av_freep(&mov->heif_grid);
10405 
10406  return 0;
10407 }
10408 
10409 static int tmcd_is_referenced(AVFormatContext *s, int tmcd_id)
10410 {
10411  int i;
10412 
10413  for (i = 0; i < s->nb_streams; i++) {
10414  AVStream *st = s->streams[i];
10415  MOVStreamContext *sc = st->priv_data;
10416  MovTref *tag = mov_find_tref_tag(sc, MKTAG('t','m','c','d'));
10417 
10418  if (!tag)
10419  continue;
10420  if (mov_find_tref_id(tag, tmcd_id))
10421  return 1;
10422  }
10423  return 0;
10424 }
10425 
10426 /* look for a tmcd track not referenced by any video track, and export it globally */
10428 {
10429  int i;
10430 
10431  for (i = 0; i < s->nb_streams; i++) {
10432  AVStream *st = s->streams[i];
10433 
10434  if (st->codecpar->codec_tag == MKTAG('t','m','c','d') &&
10435  !tmcd_is_referenced(s, st->id)) {
10436  AVDictionaryEntry *tcr = av_dict_get(st->metadata, "timecode", NULL, 0);
10437  if (tcr) {
10438  av_dict_set(&s->metadata, "timecode", tcr->value, 0);
10439  break;
10440  }
10441  }
10442  }
10443 }
10444 
10445 static int read_tfra(MOVContext *mov, AVIOContext *f)
10446 {
10447  int version, fieldlength, i, j;
10448  int64_t pos = avio_tell(f);
10449  uint32_t size = avio_rb32(f);
10450  unsigned track_id, item_count;
10451 
10452  if (avio_rb32(f) != MKBETAG('t', 'f', 'r', 'a')) {
10453  return 1;
10454  }
10455  av_log(mov->fc, AV_LOG_VERBOSE, "found tfra\n");
10456 
10457  version = avio_r8(f);
10458  avio_rb24(f);
10459  track_id = avio_rb32(f);
10460  fieldlength = avio_rb32(f);
10461  item_count = avio_rb32(f);
10462  for (i = 0; i < item_count; i++) {
10463  int64_t time, offset;
10464  int index;
10465  MOVFragmentStreamInfo * frag_stream_info;
10466 
10467  if (avio_feof(f)) {
10468  return AVERROR_INVALIDDATA;
10469  }
10470 
10471  if (version == 1) {
10472  time = avio_rb64(f);
10473  offset = avio_rb64(f);
10474  } else {
10475  time = avio_rb32(f);
10476  offset = avio_rb32(f);
10477  }
10478 
10479  // The first sample of each stream in a fragment is always a random
10480  // access sample. So it's entry in the tfra can be used as the
10481  // initial PTS of the fragment.
10482  index = update_frag_index(mov, offset);
10483  frag_stream_info = get_frag_stream_info(&mov->frag_index, index, track_id);
10484  if (frag_stream_info &&
10485  frag_stream_info->first_tfra_pts == AV_NOPTS_VALUE)
10486  frag_stream_info->first_tfra_pts = time;
10487 
10488  for (j = 0; j < ((fieldlength >> 4) & 3) + 1; j++)
10489  avio_r8(f);
10490  for (j = 0; j < ((fieldlength >> 2) & 3) + 1; j++)
10491  avio_r8(f);
10492  for (j = 0; j < ((fieldlength >> 0) & 3) + 1; j++)
10493  avio_r8(f);
10494  }
10495 
10496  avio_seek(f, pos + size, SEEK_SET);
10497  return 0;
10498 }
10499 
10501 {
10502  int64_t stream_size = avio_size(f);
10503  int64_t original_pos = avio_tell(f);
10504  int64_t seek_ret;
10505  int ret = -1;
10506  if ((seek_ret = avio_seek(f, stream_size - 4, SEEK_SET)) < 0) {
10507  ret = seek_ret;
10508  goto fail;
10509  }
10510  c->mfra_size = avio_rb32(f);
10511  c->have_read_mfra_size = 1;
10512  if (!c->mfra_size || c->mfra_size > stream_size) {
10513  av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (unreasonable size)\n");
10514  goto fail;
10515  }
10516  if ((seek_ret = avio_seek(f, -((int64_t) c->mfra_size), SEEK_CUR)) < 0) {
10517  ret = seek_ret;
10518  goto fail;
10519  }
10520  if (avio_rb32(f) != c->mfra_size) {
10521  av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (size mismatch)\n");
10522  goto fail;
10523  }
10524  if (avio_rb32(f) != MKBETAG('m', 'f', 'r', 'a')) {
10525  av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (tag mismatch)\n");
10526  goto fail;
10527  }
10528  av_log(c->fc, AV_LOG_VERBOSE, "stream has mfra\n");
10529  do {
10530  ret = read_tfra(c, f);
10531  if (ret < 0)
10532  goto fail;
10533  } while (!ret);
10534  ret = 0;
10535  c->frag_index.complete = 1;
10536 fail:
10537  seek_ret = avio_seek(f, original_pos, SEEK_SET);
10538  if (seek_ret < 0) {
10539  av_log(c->fc, AV_LOG_ERROR,
10540  "failed to seek back after looking for mfra\n");
10541  ret = seek_ret;
10542  }
10543  return ret;
10544 }
10545 
10546 static int set_icc_profile_from_item(AVPacketSideData **coded_side_data, int *nb_coded_side_data,
10547  const HEIFItem *item)
10548 {
10549  AVPacketSideData *sd = av_packet_side_data_new(coded_side_data, nb_coded_side_data,
10551  item->icc_profile_size, 0);
10552  if (!sd)
10553  return AVERROR(ENOMEM);
10554 
10555  memcpy(sd->data, item->icc_profile, item->icc_profile_size);
10556 
10557  return 0;
10558 }
10559 
10560 static int set_display_matrix_from_item(AVPacketSideData **coded_side_data, int *nb_coded_side_data,
10561  const HEIFItem *item)
10562 {
10563  int32_t *matrix;
10564  AVPacketSideData *sd = av_packet_side_data_new(coded_side_data,
10565  nb_coded_side_data,
10567  9 * sizeof(*matrix), 0);
10568  if (!sd)
10569  return AVERROR(ENOMEM);
10570 
10571  matrix = (int32_t*)sd->data;
10572  /* rotation is in the counter-clockwise direction whereas
10573  * av_display_rotation_set() expects its argument to be
10574  * oriented clockwise, so we need to negate it. */
10576  av_display_matrix_flip(matrix, item->hflip, item->vflip);
10577 
10578  return 0;
10579 }
10580 
10581 static int read_image_grid(AVFormatContext *s, const HEIFGrid *grid,
10582  AVStreamGroupTileGrid *tile_grid)
10583 {
10584  MOVContext *c = s->priv_data;
10585  const HEIFItem *item = grid->item;
10586  int64_t coded_width = 0, coded_height = 0;
10587  int64_t offset = 0, pos = avio_tell(s->pb);
10588  int64_t x = 0, y = 0;
10589  int i = 0;
10590  int tile_rows, tile_cols;
10591  int flags, size;
10592 
10593  if (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL)) {
10594  av_log(c->fc, AV_LOG_INFO, "grid box with non seekable input\n");
10595  return AVERROR_PATCHWELCOME;
10596  }
10597  if (item->is_idat_relative) {
10598  if (!c->idat_offset) {
10599  av_log(c->fc, AV_LOG_ERROR, "missing idat box required by the image grid\n");
10600  return AVERROR_INVALIDDATA;
10601  }
10602  offset = c->idat_offset;
10603  }
10604 
10605  if (offset > INT64_MAX - item->extent_offset)
10606  return AVERROR_INVALIDDATA;
10607 
10608  avio_seek(s->pb, item->extent_offset + offset, SEEK_SET);
10609 
10610  avio_r8(s->pb); /* version */
10611  flags = avio_r8(s->pb);
10612 
10613  tile_rows = avio_r8(s->pb) + 1;
10614  tile_cols = avio_r8(s->pb) + 1;
10615  /* actual width and height of output image */
10616  tile_grid->width = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
10617  tile_grid->height = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
10618 
10619  av_log(c->fc, AV_LOG_TRACE, "grid: grid_rows %d grid_cols %d output_width %d output_height %d\n",
10620  tile_rows, tile_cols, tile_grid->width, tile_grid->height);
10621 
10622  avio_seek(s->pb, pos, SEEK_SET);
10623 
10624  size = tile_rows * tile_cols;
10625  tile_grid->nb_tiles = grid->nb_tiles;
10626 
10627  if (tile_grid->nb_tiles != size)
10628  return AVERROR_INVALIDDATA;
10629 
10630  for (int i = 0; i < tile_cols; i++)
10631  coded_width += grid->tile_item_list[i]->width;
10632  for (int i = 0; i < size; i += tile_cols)
10633  coded_height += grid->tile_item_list[i]->height;
10634 
10635  if (coded_width > INT_MAX || coded_height > INT_MAX)
10636  return AVERROR_INVALIDDATA;
10637 
10638  tile_grid->coded_width = coded_width;
10639  tile_grid->coded_height = coded_height;
10640 
10641  tile_grid->offsets = av_calloc(tile_grid->nb_tiles, sizeof(*tile_grid->offsets));
10642  if (!tile_grid->offsets)
10643  return AVERROR(ENOMEM);
10644 
10645  while (y < tile_grid->coded_height) {
10646  int left_col = i;
10647 
10648  while (x < tile_grid->coded_width) {
10649  if (i == tile_grid->nb_tiles)
10650  return AVERROR_INVALIDDATA;
10651 
10652  tile_grid->offsets[i].idx = grid->tile_idx_list[i];
10653  tile_grid->offsets[i].horizontal = x;
10654  tile_grid->offsets[i].vertical = y;
10655 
10656  x += grid->tile_item_list[i++]->width;
10657  }
10658 
10659  if (x > tile_grid->coded_width) {
10660  av_log(c->fc, AV_LOG_ERROR, "Non uniform HEIF tiles\n");
10661  return AVERROR_INVALIDDATA;
10662  }
10663 
10664  x = 0;
10665  y += grid->tile_item_list[left_col]->height;
10666  }
10667 
10668  if (y > tile_grid->coded_height || i != tile_grid->nb_tiles) {
10669  av_log(c->fc, AV_LOG_ERROR, "Non uniform HEIF tiles\n");
10670  return AVERROR_INVALIDDATA;
10671  }
10672 
10673  return 0;
10674 }
10675 
10676 static int read_image_iovl(AVFormatContext *s, const HEIFGrid *grid,
10677  AVStreamGroupTileGrid *tile_grid)
10678 {
10679  MOVContext *c = s->priv_data;
10680  const HEIFItem *item = grid->item;
10681  uint16_t canvas_fill_value[4];
10682  int64_t offset = 0, pos = avio_tell(s->pb);
10683  int ret = 0, flags;
10684 
10685  if (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL)) {
10686  av_log(c->fc, AV_LOG_INFO, "iovl box with non seekable input\n");
10687  return AVERROR_PATCHWELCOME;
10688  }
10689  if (item->is_idat_relative) {
10690  if (!c->idat_offset) {
10691  av_log(c->fc, AV_LOG_ERROR, "missing idat box required by the image overlay\n");
10692  return AVERROR_INVALIDDATA;
10693  }
10694  offset = c->idat_offset;
10695  }
10696 
10697  if (offset > INT64_MAX - item->extent_offset)
10698  return AVERROR_INVALIDDATA;
10699 
10700  avio_seek(s->pb, item->extent_offset + offset, SEEK_SET);
10701 
10702  avio_r8(s->pb); /* version */
10703  flags = avio_r8(s->pb);
10704 
10705  for (int i = 0; i < 4; i++)
10706  canvas_fill_value[i] = avio_rb16(s->pb);
10707  av_log(c->fc, AV_LOG_TRACE, "iovl: canvas_fill_value { %u, %u, %u, %u }\n",
10708  canvas_fill_value[0], canvas_fill_value[1],
10709  canvas_fill_value[2], canvas_fill_value[3]);
10710  for (int i = 0; i < 4; i++)
10711  tile_grid->background[i] = canvas_fill_value[i];
10712 
10713  /* actual width and height of output image */
10714  tile_grid->width =
10715  tile_grid->coded_width = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
10716  tile_grid->height =
10717  tile_grid->coded_height = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
10718 
10719  av_log(c->fc, AV_LOG_TRACE, "iovl: output_width %d, output_height %d\n",
10720  tile_grid->width, tile_grid->height);
10721 
10722  tile_grid->nb_tiles = grid->nb_tiles;
10723  tile_grid->offsets = av_malloc_array(tile_grid->nb_tiles, sizeof(*tile_grid->offsets));
10724  if (!tile_grid->offsets) {
10725  ret = AVERROR(ENOMEM);
10726  goto fail;
10727  }
10728 
10729  for (int i = 0; i < tile_grid->nb_tiles; i++) {
10730  tile_grid->offsets[i].idx = grid->tile_idx_list[i];
10731  tile_grid->offsets[i].horizontal = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
10732  tile_grid->offsets[i].vertical = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
10733  av_log(c->fc, AV_LOG_TRACE, "iovl: stream_idx[%d] %u, "
10734  "horizontal_offset[%d] %d, vertical_offset[%d] %d\n",
10735  i, tile_grid->offsets[i].idx,
10736  i, tile_grid->offsets[i].horizontal, i, tile_grid->offsets[i].vertical);
10737  }
10738 
10739 fail:
10740  avio_seek(s->pb, pos, SEEK_SET);
10741 
10742  return ret;
10743 }
10744 
10746  AVPacketSideData **coded_side_data, int *nb_coded_side_data,
10747  const HEIFItem *ref)
10748 {
10749  MOVContext *c = s->priv_data;
10750  AVPacketSideData *sd;
10751  AVExifMetadata ifd = { 0 };
10752  AVBufferRef *buf;
10753  int64_t offset = 0, pos = avio_tell(s->pb);
10754  unsigned orientation_id = av_exif_get_tag_id("Orientation");
10755  int err;
10756 
10757  if (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL)) {
10758  av_log(c->fc, AV_LOG_WARNING, "Exif metadata with non seekable input\n");
10759  return AVERROR_PATCHWELCOME;
10760  }
10761  if (ref->is_idat_relative) {
10762  if (!c->idat_offset) {
10763  av_log(c->fc, AV_LOG_ERROR, "missing idat box required by the Exif metadata\n");
10764  return AVERROR_INVALIDDATA;
10765  }
10766  offset = c->idat_offset;
10767  }
10768 
10769  buf = av_buffer_alloc(ref->extent_length);
10770  if (!buf)
10771  return AVERROR(ENOMEM);
10772 
10773  if (offset > INT64_MAX - ref->extent_offset) {
10774  err = AVERROR(ENOMEM);
10775  goto fail;
10776  }
10777 
10778  avio_seek(s->pb, ref->extent_offset + offset, SEEK_SET);
10779  err = avio_read(s->pb, buf->data, ref->extent_length);
10780  if (err != ref->extent_length) {
10781  if (err > 0)
10782  err = AVERROR_INVALIDDATA;
10783  goto fail;
10784  }
10785 
10786  // HEIF spec states that Exif metadata is informative. The irot item property is
10787  // the normative source of rotation information. So we remove any Orientation tag
10788  // present in the Exif buffer.
10789  err = av_exif_parse_buffer(s, buf->data, ref->extent_length, &ifd, AV_EXIF_T_OFF);
10790  if (err < 0) {
10791  av_log(s, AV_LOG_ERROR, "Unable to parse Exif metadata\n");
10792  goto fail;
10793  }
10794 
10795  err = av_exif_remove_entry(s, &ifd, orientation_id, 0);
10796  if (err < 0)
10797  goto fail;
10798  else if (!err)
10799  goto finish;
10800 
10801  av_buffer_unref(&buf);
10802  err = av_exif_write(s, &ifd, &buf, AV_EXIF_T_OFF);
10803  if (err < 0)
10804  goto fail;
10805 
10806 finish:
10807  offset = AV_RB32(buf->data) + 4;
10808  if (offset >= buf->size) {
10809  err = AVERROR_INVALIDDATA;
10810  goto fail;
10811  }
10812  sd = av_packet_side_data_new(coded_side_data, nb_coded_side_data,
10813  AV_PKT_DATA_EXIF, buf->size - offset, 0);
10814  if (!sd) {
10815  err = AVERROR(ENOMEM);
10816  goto fail;
10817  }
10818  memcpy(sd->data, buf->data + offset, buf->size - offset);
10819 
10820  err = 0;
10821 fail:
10822  av_buffer_unref(&buf);
10823  av_exif_free(&ifd);
10824  avio_seek(s->pb, pos, SEEK_SET);
10825 
10826  return err;
10827 }
10828 
10830 {
10831  MOVContext *mov = s->priv_data;
10832 
10833  for (int i = 0; i < mov->nb_heif_grid; i++) {
10835  AVStreamGroupTileGrid *tile_grid;
10836  const HEIFGrid *grid = &mov->heif_grid[i];
10837  int err, loop = 1;
10838 
10839  if (!stg)
10840  return AVERROR(ENOMEM);
10841 
10842  stg->id = grid->item->item_id;
10843  tile_grid = stg->params.tile_grid;
10844 
10845  for (int j = 0; j < grid->nb_tiles; j++) {
10846  int tile_id = grid->tile_id_list[j];
10847  int k;
10848 
10849  for (k = 0; k < mov->nb_heif_item; k++) {
10850  HEIFItem *item = mov->heif_item[k];
10851  AVStream *st;
10852 
10853  if (!item || item->item_id != tile_id)
10854  continue;
10855  st = item->st;
10856  if (!st) {
10857  av_log(s, AV_LOG_WARNING, "HEIF item id %d from grid id %d doesn't "
10858  "reference a stream\n",
10859  tile_id, grid->item->item_id);
10860  ff_remove_stream_group(s, stg);
10861  loop = 0;
10862  break;
10863  }
10864 
10865  grid->tile_item_list[j] = item;
10866  grid->tile_idx_list[j] = stg->nb_streams;
10867 
10868  err = avformat_stream_group_add_stream(stg, st);
10869  if (err < 0) {
10870  int l;
10871  if (err != AVERROR(EEXIST))
10872  return err;
10873 
10874  for (l = 0; l < stg->nb_streams; l++)
10875  if (stg->streams[l]->index == st->index)
10876  break;
10877  av_assert0(l < stg->nb_streams);
10878  grid->tile_idx_list[j] = l;
10879  }
10880 
10881  if (item->item_id != mov->primary_item_id)
10883  break;
10884  }
10885 
10886  if (k == mov->nb_heif_item) {
10887  av_assert0(loop);
10888  av_log(s, AV_LOG_WARNING, "HEIF item id %d referenced by grid id %d doesn't "
10889  "exist\n",
10890  tile_id, grid->item->item_id);
10891  ff_remove_stream_group(s, stg);
10892  loop = 0;
10893  }
10894  if (!loop)
10895  break;
10896  }
10897 
10898  if (!loop)
10899  continue;
10900 
10901  switch (grid->item->type) {
10902  case MKTAG('g','r','i','d'):
10903  err = read_image_grid(s, grid, tile_grid);
10904  break;
10905  case MKTAG('i','o','v','l'):
10906  err = read_image_iovl(s, grid, tile_grid);
10907  break;
10908  default:
10909  av_assert0(0);
10910  }
10911  if (err < 0)
10912  return err;
10913 
10914  for (int j = 0; j < grid->item->nb_iref_list; j++) {
10915  HEIFItem *ref = get_heif_item(mov, grid->item->iref_list[j].item_id);
10916 
10917  av_assert0(ref);
10918  switch(ref->type) {
10919  case MKTAG('E','x','i','f'):
10920  err = mov_parse_exif_item(s, &tile_grid->coded_side_data,
10921  &tile_grid->nb_coded_side_data, ref);
10922  if (err < 0 && (s->error_recognition & AV_EF_EXPLODE))
10923  return err;
10924  break;
10925  default:
10926  break;
10927  }
10928  }
10929 
10930  /* rotation */
10931  if (grid->item->rotation || grid->item->hflip || grid->item->vflip) {
10933  &tile_grid->nb_coded_side_data, grid->item);
10934  if (err < 0)
10935  return err;
10936  }
10937 
10938  /* ICC profile */
10939  if (grid->item->icc_profile_size) {
10940  err = set_icc_profile_from_item(&tile_grid->coded_side_data,
10941  &tile_grid->nb_coded_side_data, grid->item);
10942  if (err < 0)
10943  return err;
10944  }
10945 
10946  if (grid->item->name)
10947  av_dict_set(&stg->metadata, "title", grid->item->name, 0);
10948  if (grid->item->item_id == mov->primary_item_id)
10950  }
10951 
10952  return 0;
10953 }
10954 
10956 {
10957  MOVContext *mov = s->priv_data;
10958  int err;
10959 
10960  for (int i = 0; i < mov->nb_heif_item; i++) {
10961  HEIFItem *item = mov->heif_item[i];
10962  MOVStreamContext *sc;
10963  AVStream *st;
10964  int64_t offset = 0;
10965 
10966  if (!item)
10967  continue;
10968  if (!item->st) {
10969  continue;
10970  }
10971  if (item->is_idat_relative) {
10972  if (!mov->idat_offset) {
10973  av_log(s, AV_LOG_ERROR, "Missing idat box for item %d\n", item->item_id);
10974  return AVERROR_INVALIDDATA;
10975  }
10976  offset = mov->idat_offset;
10977  }
10978 
10979  st = item->st;
10980  sc = st->priv_data;
10981  st->codecpar->width = item->width;
10982  st->codecpar->height = item->height;
10983 
10984  sc->sample_size = sc->stsz_sample_size = item->extent_length;
10985  sc->sample_count = 1;
10986 
10987  err = sanity_checks(s, sc, st->index);
10988  if (err)
10989  return AVERROR_INVALIDDATA;
10990 
10991  if (offset > INT64_MAX - item->extent_offset)
10992  return AVERROR_INVALIDDATA;
10993 
10994  sc->chunk_offsets[0] = item->extent_offset + offset;
10995 
10996  if (item->item_id == mov->primary_item_id)
10998 
10999  for (int j = 0; j < item->nb_iref_list; j++) {
11000  HEIFItem *ref = get_heif_item(mov, item->iref_list[j].item_id);
11001 
11002  av_assert0(ref);
11003  switch(ref->type) {
11004  case MKTAG('E','x','i','f'):
11007  if (err < 0 && (s->error_recognition & AV_EF_EXPLODE))
11008  return err;
11009  break;
11010  default:
11011  break;
11012  }
11013  }
11014 
11015  if (item->rotation || item->hflip || item->vflip) {
11017  &st->codecpar->nb_coded_side_data, item);
11018  if (err < 0)
11019  return err;
11020  }
11021 
11022  mov_build_index(mov, st);
11023  }
11024 
11025  if (mov->nb_heif_grid) {
11026  err = mov_parse_tiles(s);
11027  if (err < 0)
11028  return err;
11029  }
11030 
11031  return 0;
11032 }
11033 
11035 {
11036  int err;
11037 
11038  for (int i = 0; i < s->nb_streams; i++) {
11039  AVStreamGroup *stg;
11040  const AVDictionaryEntry *tcr;
11041  AVStream *st = s->streams[i];
11042 
11043  if (st->codecpar->codec_tag != MKTAG('t','m','c','d'))
11044  continue;
11045 
11047  if (!stg)
11048  return AVERROR(ENOMEM);
11049 
11050  stg->id = st->id;
11051  tcr = av_dict_get(st->metadata, "timecode", NULL, 0);
11052 
11053  for (int j = 0; j < s->nb_streams; j++) {
11054  AVStream *st2 = s->streams[j];
11055  MOVStreamContext *sc2 = st2->priv_data;
11056  MovTref *tag = mov_find_tref_tag(sc2, MKTAG('t','m','c','d'));
11057 
11058  if (!tag)
11059  continue;
11060 
11061  for (int k = 0; k < tag->nb_id; k++) {
11062  if (tag->id[k] != st->id)
11063  continue;
11064 
11065  err = avformat_stream_group_add_stream(stg, st2);
11066  if (err < 0)
11067  return err;
11068 
11069  if (tcr)
11070  av_dict_set(&st2->metadata, "timecode", tcr->value, AV_DICT_DONT_OVERWRITE);
11071  }
11072  }
11073 
11074  if (!stg->nb_streams) {
11075  ff_remove_stream_group(s, stg);
11076  continue;
11077  }
11078 
11079  err = avformat_stream_group_add_stream(stg, st);
11080  if (err < 0)
11081  return err;
11082 
11083  stg->params.tref->metadata_index = stg->nb_streams - 1;
11084  }
11086 
11087  return 0;
11088 }
11089 
11091  uint32_t *tref_id, int nb_tref_id, int first_index)
11092 {
11093  if (!nb_tref_id)
11094  return NULL;
11095 
11096  for (int i = first_index; i < s->nb_streams; i++)
11097  for (int j = 0; j < nb_tref_id; j++)
11098  if (s->streams[i]->index != st->index &&
11099  s->streams[i]->id == tref_id[j])
11100  return s->streams[i];
11101 
11102  return NULL;
11103 }
11104 
11106 {
11107  int err;
11108 
11109  // Don't try to add a group if there's only one track
11110  if (s->nb_streams <= 1)
11111  return 0;
11112 
11113  for (int i = 0; i < s->nb_streams; i++) {
11114  AVStreamGroup *stg;
11115  AVStream *st = s->streams[i];
11116  AVStream *st_base;
11117  MOVStreamContext *sc = st->priv_data;
11118  MovTref *tag = mov_find_tref_tag(sc, MKTAG('s','b','a','s'));
11119  int j = 0;
11120 
11121  /* Find an enhancement stream. */
11122  if (st->codecpar->codec_id != AV_CODEC_ID_LCEVC || !tag)
11123  continue;
11124 
11126  if (!stg)
11127  return AVERROR(ENOMEM);
11128 
11129  stg->id = st->id;
11130  stg->params.layered_video->width = st->codecpar->width;
11131  stg->params.layered_video->height = st->codecpar->height;
11132 
11133  while (st_base = mov_find_reference_track(s, st, tag->id, tag->nb_id, j)) {
11134  err = avformat_stream_group_add_stream(stg, st_base);
11135  if (err < 0)
11136  return err;
11137 
11138  j = st_base->index + 1;
11139  }
11140  if (!j) {
11141  int loglevel = (s->error_recognition & AV_EF_EXPLODE) ? AV_LOG_ERROR : AV_LOG_WARNING;
11142  av_log(s, loglevel, "Failed to find base stream for LCEVC stream\n");
11143  ff_remove_stream_group(s, stg);
11144  if (s->error_recognition & AV_EF_EXPLODE)
11145  return AVERROR_INVALIDDATA;
11146  continue;
11147  }
11148 
11149  err = avformat_stream_group_add_stream(stg, st);
11150  if (err < 0)
11151  return err;
11152 
11153  stg->params.layered_video->el_index = stg->nb_streams - 1;
11154  }
11155 
11156  return 0;
11157 }
11158 
11160 {
11161  int err;
11162 
11163  if (s->nb_streams <= 1)
11164  return 0;
11165 
11166  /* Identify legacy dual-track Dolby Vision profile 7 carriage per Annex
11167  * C of "Dolby Vision Streams Within the ISO Base Media File Format",
11168  * v2.7.1. The 'vdep' track reference type is shared with depth video
11169  * and multi-view dependencies. The spec-mandated DV-specific sample
11170  * entry combined with the dvcC configuration record disambiguates
11171  * those uses. */
11172  for (int i = 0; i < s->nb_streams; i++) {
11173  AVStreamGroup *stg;
11174  AVStream *st = s->streams[i];
11175  AVStream *st_base;
11176  MOVStreamContext *sc = st->priv_data;
11177  MovTref *tag = mov_find_tref_tag(sc, MKTAG('v','d','e','p'));
11178  const AVPacketSideData *sd;
11180 
11181  if (st->codecpar->codec_id != AV_CODEC_ID_HEVC || !tag)
11182  continue;
11183 
11184  if (st->codecpar->codec_tag != MKTAG('d','v','h','e') &&
11185  st->codecpar->codec_tag != MKTAG('d','v','h','1'))
11186  continue;
11187 
11191  if (!sd)
11192  continue;
11193  dovi = (const AVDOVIDecoderConfigurationRecord *)sd->data;
11194 
11195  /* EL track of a dual-track stream: rpu_present_flag = 1,
11196  * el_present_flag = 1, bl_present_flag = 0, dv_profile = 7. */
11197  if (dovi->dv_profile != 7 || !dovi->rpu_present_flag ||
11198  !dovi->el_present_flag || dovi->bl_present_flag)
11199  continue;
11200 
11201  st_base = mov_find_reference_track(s, st, tag->id, tag->nb_id, 0);
11202  if (!st_base) {
11203  int loglevel = (s->error_recognition & AV_EF_EXPLODE) ? AV_LOG_ERROR : AV_LOG_WARNING;
11204  av_log(s, loglevel, "Failed to find base layer for Dolby Vision EL stream\n");
11205  if (s->error_recognition & AV_EF_EXPLODE)
11206  return AVERROR_INVALIDDATA;
11207  continue;
11208  }
11209 
11211  if (!stg)
11212  return AVERROR(ENOMEM);
11213 
11214  stg->id = st->id;
11215 
11216  err = avformat_stream_group_add_stream(stg, st_base);
11217  if (err < 0)
11218  return err;
11219 
11220  err = avformat_stream_group_add_stream(stg, st);
11221  if (err < 0)
11222  return err;
11223 
11224  stg->params.layered_video->el_index = stg->nb_streams - 1;
11225  stg->params.layered_video->width = st_base->codecpar->width;
11226  stg->params.layered_video->height = st_base->codecpar->height;
11227  }
11228 
11229  return 0;
11230 }
11231 
11233 {
11234  int highest_id = 0, lowest_iamf_id = INT_MAX;
11235 
11236  for (int i = 0; i < s->nb_streams; i++) {
11237  const AVStream *st = s->streams[i];
11238  const MOVStreamContext *sc = st->priv_data;
11239  if (!sc->iamf)
11240  highest_id = FFMAX(highest_id, st->id);
11241  }
11242 
11243  for (int i = 0; i < s->nb_stream_groups; i++) {
11244  AVStreamGroup *stg = s->stream_groups[i];
11246  continue;
11247  for (int j = 0; j < stg->nb_streams; j++) {
11248  AVStream *st = stg->streams[j];
11249  lowest_iamf_id = FFMIN(lowest_iamf_id, st->id);
11250  }
11251  }
11252 
11253  if (highest_id < lowest_iamf_id)
11254  return;
11255 
11256  highest_id += !lowest_iamf_id;
11257  for (int i = 0; highest_id > 1 && i < s->nb_stream_groups; i++) {
11258  AVStreamGroup *stg = s->stream_groups[i];
11260  continue;
11261  for (int j = 0; j < stg->nb_streams; j++) {
11262  AVStream *st = stg->streams[j];
11263  MOVStreamContext *sc = st->priv_data;
11264  st->id += highest_id;
11265  sc->iamf_stream_offset = highest_id;
11266  }
11267  }
11268 }
11269 
11271 {
11272  MOVContext *mov = s->priv_data;
11273  AVIOContext *pb = s->pb;
11274  int j, err;
11275  MOVAtom atom = { AV_RL32("root") };
11276  int i;
11277 
11278  mov->fc = s;
11279  mov->trak_index = -1;
11280  mov->primary_item_id = -1;
11281  mov->cur_item_id = -1;
11282  /* .mov and .mp4 aren't streamable anyway (only progressive download if moov is before mdat) */
11283  if (pb->seekable & AVIO_SEEKABLE_NORMAL)
11284  atom.size = avio_size(pb);
11285  else
11286  atom.size = INT64_MAX;
11287 
11288  /* check MOV header */
11289  do {
11290  if (mov->moov_retry)
11291  avio_seek(pb, 0, SEEK_SET);
11292  if ((err = mov_read_default(mov, pb, atom)) < 0) {
11293  av_log(s, AV_LOG_ERROR, "error reading header\n");
11294  return err;
11295  }
11296  } while ((pb->seekable & AVIO_SEEKABLE_NORMAL) &&
11297  !mov->found_moov && (!mov->found_iloc || !mov->found_iinf) && !mov->moov_retry++);
11298  if (!mov->found_moov && !mov->found_iloc && !mov->found_iinf) {
11299  av_log(s, AV_LOG_ERROR, "moov atom not found\n");
11300  return AVERROR_INVALIDDATA;
11301  }
11302  av_log(mov->fc, AV_LOG_TRACE, "on_parse_exit_offset=%"PRId64"\n", avio_tell(pb));
11303 
11304  if (mov->found_iloc && mov->found_iinf) {
11305  err = mov_parse_heif_items(s);
11306  if (err < 0)
11307  return err;
11308  }
11309  // prevent iloc and iinf boxes from being parsed while reading packets.
11310  // this is needed because an iinf box may have been parsed but ignored
11311  // for having old infe boxes which create no streams.
11312  mov->found_iloc = mov->found_iinf = 1;
11313 
11314  if (pb->seekable & AVIO_SEEKABLE_NORMAL) {
11315  if (mov->nb_chapter_tracks > 0 && !mov->ignore_chapters)
11317  for (i = 0; i < s->nb_streams; i++)
11318  if (s->streams[i]->codecpar->codec_tag == AV_RL32("tmcd")) {
11319  mov_read_timecode_track(s, s->streams[i]);
11320  } else if (s->streams[i]->codecpar->codec_tag == AV_RL32("rtmd")) {
11321  mov_read_rtmd_track(s, s->streams[i]);
11322  }
11323  }
11324 
11325  /* copy timecode metadata from tmcd tracks to the related video streams */
11326  err = mov_parse_tmcd_streams(s);
11327  if (err < 0)
11328  return err;
11329 
11330  /* Create LCEVC stream groups. */
11331  err = mov_parse_lcevc_streams(s);
11332  if (err < 0)
11333  return err;
11334 
11335  /* Create Dolby Vision Profile 7 stream groups. */
11336  err = mov_parse_dovi_streams(s);
11337  if (err < 0)
11338  return err;
11339 
11340  for (i = 0; i < s->nb_streams; i++) {
11341  AVStream *st = s->streams[i];
11342  FFStream *const sti = ffstream(st);
11343  MOVStreamContext *sc = st->priv_data;
11344  uint32_t dvdsub_clut[FF_DVDCLUT_CLUT_LEN] = {0};
11345  fix_timescale(mov, sc);
11346 
11347  /* Set the primary extradata based on the first Sample if it doesn't reference the first stsd entry. */
11348  if (sc->stsc_count && sc->extradata_size && !sc->iamf &&
11349  sc->stsc_data[0].id > 1 && sc->stsc_data[0].id <= sc->stsd_count) {
11350  sc->last_stsd_index = sc->stsc_data[0].id - 1;
11351  av_freep(&st->codecpar->extradata);
11353  if (sc->extradata_size[sc->last_stsd_index]) {
11355  if (!st->codecpar->extradata)
11356  return AVERROR(ENOMEM);
11357  memcpy(st->codecpar->extradata, sc->extradata[sc->last_stsd_index], sc->extradata_size[sc->last_stsd_index]);
11358  }
11359  }
11360 
11361  if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
11362  st->codecpar->codec_id == AV_CODEC_ID_AAC) {
11364  }
11365  if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && sc->nb_frames_for_fps > 0 && sc->duration_for_fps > 0)
11367  sc->time_scale*(int64_t)sc->nb_frames_for_fps, sc->duration_for_fps, INT_MAX);
11369  if (st->codecpar->width <= 0 || st->codecpar->height <= 0) {
11370  st->codecpar->width = sc->width;
11371  st->codecpar->height = sc->height;
11372  }
11375 
11376  for (j = 0; j < FF_DVDCLUT_CLUT_LEN; j++)
11377  dvdsub_clut[j] = AV_RB32(st->codecpar->extradata + j * 4);
11378 
11379  err = ff_dvdclut_yuv_to_rgb(dvdsub_clut, FF_DVDCLUT_CLUT_SIZE);
11380  if (err < 0)
11381  return err;
11382 
11383  av_freep(&st->codecpar->extradata);
11384  st->codecpar->extradata_size = 0;
11385 
11387  st->codecpar);
11388  if (err < 0)
11389  return err;
11390  }
11391  }
11392  if (mov->handbrake_version &&
11393  mov->handbrake_version <= 1000000*0 + 1000*10 + 2 && // 0.10.2
11394  st->codecpar->codec_id == AV_CODEC_ID_MP3) {
11395  av_log(s, AV_LOG_VERBOSE, "Forcing full parsing for mp3 stream\n");
11397  }
11398  }
11399 
11400  if (mov->trex_data || mov->use_mfra_for > 0) {
11401  for (i = 0; i < s->nb_streams; i++) {
11402  AVStream *st = s->streams[i];
11403  MOVStreamContext *sc = st->priv_data;
11404  if (sc->duration_for_fps > 0) {
11405  /* Akin to sc->data_size * 8 * sc->time_scale / sc->duration_for_fps but accounting for overflows. */
11407  if (st->codecpar->bit_rate == INT64_MIN) {
11408  av_log(s, AV_LOG_WARNING, "Overflow during bit rate calculation %"PRId64" * 8 * %d\n",
11409  sc->data_size, sc->time_scale);
11410  st->codecpar->bit_rate = 0;
11411  if (s->error_recognition & AV_EF_EXPLODE)
11412  return AVERROR_INVALIDDATA;
11413  }
11414  }
11415  }
11416  }
11417 
11418  for (i = 0; i < mov->bitrates_count && i < s->nb_streams; i++) {
11419  if (mov->bitrates[i]) {
11420  s->streams[i]->codecpar->bit_rate = mov->bitrates[i];
11421  }
11422  }
11423 
11425 
11426  for (i = 0; i < s->nb_streams; i++) {
11427  AVStream *st = s->streams[i];
11428  MOVStreamContext *sc = st->priv_data;
11429 
11430  switch (st->codecpar->codec_type) {
11431  case AVMEDIA_TYPE_AUDIO:
11432  err = ff_replaygain_export(st, s->metadata);
11433  if (err < 0)
11434  return err;
11435  break;
11436  case AVMEDIA_TYPE_VIDEO:
11437  if (sc->display_matrix) {
11440  (uint8_t*)sc->display_matrix, sizeof(int32_t) * 9, 0))
11441  return AVERROR(ENOMEM);
11442 
11443  sc->display_matrix = NULL;
11444  }
11445  if (sc->stereo3d) {
11448  (uint8_t *)sc->stereo3d, sc->stereo3d_size, 0))
11449  return AVERROR(ENOMEM);
11450 
11451  sc->stereo3d = NULL;
11452  }
11453  if (sc->spherical) {
11456  (uint8_t *)sc->spherical, sc->spherical_size, 0))
11457  return AVERROR(ENOMEM);
11458 
11459  sc->spherical = NULL;
11460  }
11461  if (sc->mastering) {
11464  (uint8_t *)sc->mastering, sc->mastering_size, 0))
11465  return AVERROR(ENOMEM);
11466 
11467  sc->mastering = NULL;
11468  }
11469  if (sc->coll) {
11472  (uint8_t *)sc->coll, sc->coll_size, 0))
11473  return AVERROR(ENOMEM);
11474 
11475  sc->coll = NULL;
11476  }
11477  if (sc->ambient) {
11480  (uint8_t *) sc->ambient, sc->ambient_size, 0))
11481  return AVERROR(ENOMEM);
11482 
11483  sc->ambient = NULL;
11484  }
11485  break;
11486  }
11487  }
11488 
11489  fix_stream_ids(s);
11490 
11492 
11493  for (i = 0; i < mov->frag_index.nb_items; i++)
11494  if (mov->frag_index.item[i].moof_offset <= mov->fragment.moof_offset)
11495  mov->frag_index.item[i].headers_read = 1;
11496 
11497  return 0;
11498 }
11499 
11501 {
11503  int64_t best_dts = INT64_MAX;
11504  int i;
11505  MOVContext *mov = s->priv_data;
11506  int no_interleave = !mov->interleaved_read || !(s->pb->seekable & AVIO_SEEKABLE_NORMAL);
11507  for (i = 0; i < s->nb_streams; i++) {
11508  AVStream *avst = s->streams[i];
11509  FFStream *const avsti = ffstream(avst);
11510  MOVStreamContext *msc = avst->priv_data;
11511  if (msc->pb && msc->current_sample < avsti->nb_index_entries) {
11512  AVIndexEntry *current_sample = &avsti->index_entries[msc->current_sample];
11513  int64_t dts = av_rescale(current_sample->timestamp, AV_TIME_BASE, msc->time_scale);
11514  uint64_t dtsdiff = best_dts > dts ? best_dts - (uint64_t)dts : ((uint64_t)dts - best_dts);
11515  av_log(s, AV_LOG_TRACE, "stream %d, sample %d, dts %"PRId64"\n", i, msc->current_sample, dts);
11516  if (!sample || (no_interleave && current_sample->pos < sample->pos) ||
11517  ((s->pb->seekable & AVIO_SEEKABLE_NORMAL) &&
11518  ((msc->pb != s->pb && dts < best_dts) || (msc->pb == s->pb && dts != AV_NOPTS_VALUE &&
11519  ((dtsdiff <= AV_TIME_BASE && current_sample->pos < sample->pos) ||
11520  (dtsdiff > AV_TIME_BASE && dts < best_dts && mov->interleaved_read)))))) {
11521  sample = current_sample;
11522  best_dts = dts;
11523  *st = avst;
11524  }
11525  }
11526  }
11527  return sample;
11528 }
11529 
11530 static int should_retry(AVIOContext *pb, int error_code) {
11531  if (error_code == AVERROR_EOF || avio_feof(pb))
11532  return 0;
11533 
11534  return 1;
11535 }
11536 
11537 static int mov_switch_root(AVFormatContext *s, int64_t target, int index)
11538 {
11539  int ret;
11540  MOVContext *mov = s->priv_data;
11541 
11542  if (index >= 0 && index < mov->frag_index.nb_items)
11543  target = mov->frag_index.item[index].moof_offset;
11544  if (target >= 0 && avio_seek(s->pb, target, SEEK_SET) != target) {
11545  av_log(mov->fc, AV_LOG_ERROR, "root atom offset 0x%"PRIx64": partial file\n", target);
11546  return AVERROR_INVALIDDATA;
11547  }
11548 
11549  mov->next_root_atom = 0;
11550  if ((index < 0 && target >= 0) || index >= mov->frag_index.nb_items)
11551  index = search_frag_moof_offset(&mov->frag_index, target);
11552  if (index >= 0 && index < mov->frag_index.nb_items &&
11553  mov->frag_index.item[index].moof_offset == target) {
11554  if (index + 1 < mov->frag_index.nb_items)
11555  mov->next_root_atom = mov->frag_index.item[index + 1].moof_offset;
11556  if (mov->frag_index.item[index].headers_read)
11557  return 0;
11558  mov->frag_index.item[index].headers_read = 1;
11559  }
11560 
11561  mov->found_mdat = 0;
11562 
11563  ret = mov_read_default(mov, s->pb, (MOVAtom){ AV_RL32("root"), INT64_MAX });
11564  if (ret < 0)
11565  return ret;
11566  if (avio_feof(s->pb))
11567  return AVERROR_EOF;
11568  av_log(s, AV_LOG_TRACE, "read fragments, offset 0x%"PRIx64"\n", avio_tell(s->pb));
11569 
11570  return 1;
11571 }
11572 
11574 {
11575  MOVStreamContext *sc = st->priv_data;
11576  uint8_t *side, *extradata;
11577  int extradata_size;
11578 
11579  /* Save the current index. */
11580  sc->last_stsd_index = sc->stsc_data[sc->stsc_index].id - 1;
11581 
11582  /* Notify the decoder that extradata changed. */
11583  extradata_size = sc->extradata_size[sc->last_stsd_index];
11584  extradata = sc->extradata[sc->last_stsd_index];
11585  if (st->discard != AVDISCARD_ALL && extradata_size > 0 && extradata) {
11588  extradata_size);
11589  if (!side)
11590  return AVERROR(ENOMEM);
11591  memcpy(side, extradata, extradata_size);
11592  }
11593 
11594  return 0;
11595 }
11596 
11597 static int get_eia608_packet(AVIOContext *pb, AVPacket *pkt, int src_size)
11598 {
11599  /* We can't make assumptions about the structure of the payload,
11600  because it may include multiple cdat and cdt2 samples. */
11601  const uint32_t cdat = AV_RB32("cdat");
11602  const uint32_t cdt2 = AV_RB32("cdt2");
11603  int ret, out_size = 0;
11604 
11605  /* a valid payload must have size, 4cc, and at least 1 byte pair: */
11606  if (src_size < 10)
11607  return AVERROR_INVALIDDATA;
11608 
11609  /* avoid an int overflow: */
11610  if ((src_size - 8) / 2 >= INT_MAX / 3)
11611  return AVERROR_INVALIDDATA;
11612 
11613  ret = av_new_packet(pkt, ((src_size - 8) / 2) * 3);
11614  if (ret < 0)
11615  return ret;
11616 
11617  /* parse and re-format the c608 payload in one pass. */
11618  while (src_size >= 10) {
11619  const uint32_t atom_size = avio_rb32(pb);
11620  const uint32_t atom_type = avio_rb32(pb);
11621  const uint32_t data_size = atom_size - 8;
11622  const uint8_t cc_field =
11623  atom_type == cdat ? 1 :
11624  atom_type == cdt2 ? 2 :
11625  0;
11626 
11627  /* account for bytes consumed for atom size and type. */
11628  src_size -= 8;
11629 
11630  /* make sure the data size stays within the buffer boundaries. */
11631  if (data_size < 2 || data_size > src_size) {
11633  break;
11634  }
11635 
11636  /* make sure the data size is consistent with N byte pairs. */
11637  if (data_size % 2 != 0) {
11639  break;
11640  }
11641 
11642  if (!cc_field) {
11643  /* neither cdat or cdt2 ... skip it */
11644  avio_skip(pb, data_size);
11645  src_size -= data_size;
11646  continue;
11647  }
11648 
11649  for (uint32_t i = 0; i < data_size; i += 2) {
11650  pkt->data[out_size] = (0x1F << 3) | (1 << 2) | (cc_field - 1);
11651  pkt->data[out_size + 1] = avio_r8(pb);
11652  pkt->data[out_size + 2] = avio_r8(pb);
11653  out_size += 3;
11654  src_size -= 2;
11655  }
11656  }
11657 
11658  if (src_size > 0)
11659  /* skip any remaining unread portion of the input payload */
11660  avio_skip(pb, src_size);
11661 
11663  return ret;
11664 }
11665 
11667  int64_t current_index, AVPacket *pkt)
11668 {
11669  MOVContext *mov = s->priv_data;
11670  MOVStreamContext *sc = st->priv_data;
11671 
11672  pkt->stream_index = sc->ffindex;
11673  pkt->dts = sample->timestamp;
11674  if (sample->flags & AVINDEX_DISCARD_FRAME) {
11676  }
11677  if (sc->stts_count && sc->tts_index < sc->tts_count)
11678  pkt->duration = sc->tts_data[sc->tts_index].duration;
11679  if (sc->ctts_count && sc->tts_index < sc->tts_count) {
11681  } else {
11682  if (pkt->duration == 0) {
11683  int64_t next_dts = (sc->current_sample < ffstream(st)->nb_index_entries) ?
11685  if (next_dts >= pkt->dts)
11686  pkt->duration = next_dts - pkt->dts;
11687  }
11688  pkt->pts = pkt->dts;
11689  }
11690 
11691  if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO && !mov->fragment.found_tfhd &&
11693  int64_t pts = av_rescale_q(pkt->pts, st->time_base, (AVRational){ 1, st->codecpar->sample_rate });
11694  int64_t total = av_rescale_q(st->duration, st->time_base, (AVRational){ 1, st->codecpar->sample_rate });
11696 
11697  if (st->duration < pkt->pts) {
11698  duration = 0;
11699  } else
11700  duration = FFMIN(duration, (uint64_t)st->duration - pkt->pts);
11701 
11702  duration = av_rescale_q(duration, st->time_base, (AVRational){ 1, st->codecpar->sample_rate });
11703 
11704  if (!ffstream(st)->first_discard_sample)
11706  if (!ffstream(st)->last_discard_sample)
11707  ffstream(st)->last_discard_sample = total;
11708  }
11709 
11710  if (sc->tts_data && sc->tts_index < sc->tts_count) {
11711  /* update tts context */
11712  sc->tts_sample++;
11713  if (sc->tts_index < sc->tts_count &&
11714  sc->tts_data[sc->tts_index].count == sc->tts_sample) {
11715  sc->tts_index++;
11716  sc->tts_sample = 0;
11717  }
11718  }
11719 
11720  if (sc->sdtp_data && sc->current_sample <= sc->sdtp_count) {
11721  uint8_t sample_flags = sc->sdtp_data[sc->current_sample - 1];
11722  uint8_t sample_is_depended_on = (sample_flags >> 2) & 0x3;
11723  pkt->flags |= sample_is_depended_on == MOV_SAMPLE_DEPENDENCY_NO ? AV_PKT_FLAG_DISPOSABLE : 0;
11724  }
11725  pkt->flags |= sample->flags & AVINDEX_KEYFRAME ? AV_PKT_FLAG_KEY : 0;
11726  pkt->pos = sample->pos;
11727 
11728  /* Multiple stsd handling. */
11729  if (sc->stsc_data) {
11730  if (sc->stsc_data[sc->stsc_index].id > 0 &&
11731  sc->stsc_data[sc->stsc_index].id - 1 < sc->stsd_count &&
11732  sc->stsc_data[sc->stsc_index].id - 1 != sc->last_stsd_index) {
11733  int ret = mov_change_extradata(st, pkt);
11734  if (ret < 0)
11735  return ret;
11736  }
11737 
11738  /* Update the stsc index for the next sample */
11739  sc->stsc_sample++;
11740  if (mov_stsc_index_valid(sc->stsc_index, sc->stsc_count) &&
11741  mov_get_stsc_samples(sc, sc->stsc_index) == sc->stsc_sample) {
11742  sc->stsc_index++;
11743  sc->stsc_sample = 0;
11744  }
11745  }
11746 
11747  return 0;
11748 }
11749 
11751 {
11752  MOVContext *mov = s->priv_data;
11753  MOVStreamContext *sc;
11755  AVStream *st = NULL;
11756  FFStream *avsti = NULL;
11757  int64_t current_index;
11758  int ret;
11759  int i;
11760  mov->fc = s;
11761  retry:
11762  if (s->pb->pos == 0) {
11763 
11764  // Discard current fragment index
11765  if (mov->frag_index.allocated_size > 0) {
11766  for(int i = 0; i < mov->frag_index.nb_items; i++) {
11768  }
11769  av_freep(&mov->frag_index.item);
11770  mov->frag_index.nb_items = 0;
11771  mov->frag_index.allocated_size = 0;
11772  mov->frag_index.current = -1;
11773  mov->frag_index.complete = 0;
11774  }
11775 
11776  for (i = 0; i < s->nb_streams; i++) {
11777  AVStream *avst = s->streams[i];
11778  MOVStreamContext *msc = avst->priv_data;
11779 
11780  // Clear current sample
11781  mov_current_sample_set(msc, 0);
11782  msc->tts_index = 0;
11783 
11784  // Discard current index entries
11785  avsti = ffstream(avst);
11786  if (avsti->index_entries_allocated_size > 0) {
11787  av_freep(&avsti->index_entries);
11788  avsti->index_entries_allocated_size = 0;
11789  avsti->nb_index_entries = 0;
11790  }
11791  }
11792 
11793  if ((ret = mov_switch_root(s, -1, -1)) < 0)
11794  return ret;
11795  }
11796  sample = mov_find_next_sample(s, &st);
11797  if (!sample || (mov->next_root_atom && sample->pos > mov->next_root_atom)) {
11798  if (!mov->next_root_atom)
11799  return AVERROR_EOF;
11800  if ((ret = mov_switch_root(s, mov->next_root_atom, -1)) < 0)
11801  return ret;
11802  goto retry;
11803  }
11804  sc = st->priv_data;
11805  /* must be done just before reading, to avoid infinite loop on sample */
11806  current_index = sc->current_index;
11808 
11809  if (mov->next_root_atom) {
11810  sample->pos = FFMIN(sample->pos, mov->next_root_atom);
11811  sample->size = FFMIN(sample->size, (mov->next_root_atom - sample->pos));
11812  }
11813 
11814  if (st->discard != AVDISCARD_ALL || sc->iamf) {
11815  int64_t ret64 = avio_seek(sc->pb, sample->pos, SEEK_SET);
11816  if (ret64 != sample->pos) {
11817  av_log(mov->fc, AV_LOG_ERROR, "stream %d, offset 0x%"PRIx64": partial file\n",
11818  sc->ffindex, sample->pos);
11819  if (should_retry(sc->pb, ret64)) {
11821  } else if (ret64 < 0) {
11822  return (int)ret64;
11823  }
11824  return AVERROR_INVALIDDATA;
11825  }
11826 
11827  if (st->discard == AVDISCARD_NONKEY && !(sample->flags & AVINDEX_KEYFRAME)) {
11828  av_log(mov->fc, AV_LOG_DEBUG, "Nonkey frame from stream %d discarded due to AVDISCARD_NONKEY\n", sc->ffindex);
11829  goto retry;
11830  }
11831 
11832  if (st->codecpar->codec_id == AV_CODEC_ID_EIA_608 && sample->size > 8)
11833  ret = get_eia608_packet(sc->pb, pkt, sample->size);
11834 #if CONFIG_IAMFDEC
11835  else if (sc->iamf) {
11836  int64_t pts, dts, pos, duration;
11837  int flags, size = sample->size;
11838  ret = mov_finalize_packet(s, st, sample, current_index, pkt);
11839  pts = pkt->pts; dts = pkt->dts;
11840  pos = pkt->pos; flags = pkt->flags;
11841  duration = pkt->duration;
11842  while (!ret && size > 0) {
11843  ret = ff_iamf_read_packet(s, sc->iamf, sc->pb, size, sc->iamf_stream_offset, pkt);
11844  if (ret < 0) {
11845  if (should_retry(sc->pb, ret))
11847  return ret;
11848  }
11849  size -= ret;
11850 
11851  if (pkt->flags & AV_PKT_FLAG_DISCARD) {
11853  ret = 0;
11854  continue;
11855  }
11856  pkt->pts = pts; pkt->dts = dts;
11857  pkt->pos = pos; pkt->flags |= flags;
11858  pkt->duration = duration;
11859  ret = ff_buffer_packet(s, pkt);
11860  }
11861  if (!ret)
11862  return FFERROR_REDO;
11863  }
11864 #endif
11865  else if (st->codecpar->codec_id == AV_CODEC_ID_APV && sample->size > 4) {
11866  uint32_t au_size = avio_rb32(sc->pb);
11867  int explode = !!(mov->fc->error_recognition & AV_EF_EXPLODE);
11868  if (au_size > sample->size - 4) {
11869  av_log(s, explode ? AV_LOG_ERROR : AV_LOG_WARNING,
11870  "APV au_size %u exceeds sample body %d\n",
11871  au_size, sample->size - 4);
11872  if (explode)
11873  return AVERROR_INVALIDDATA;
11874  au_size = sample->size - 4;
11875  }
11876  ret = av_get_packet(sc->pb, pkt, au_size);
11877  } else
11878  ret = av_get_packet(sc->pb, pkt, sample->size);
11879  if (ret < 0) {
11880  if (should_retry(sc->pb, ret)) {
11882  }
11883  return ret;
11884  }
11885 #if CONFIG_DV_DEMUXER
11886  if (mov->dv_demux && sc->dv_audio_container) {
11889  if (ret < 0)
11890  return ret;
11892  if (ret < 0)
11893  return ret;
11894  }
11895 #endif
11896  if (sc->has_palette) {
11897  uint8_t *pal;
11898 
11900  if (!pal) {
11901  av_log(mov->fc, AV_LOG_ERROR, "Cannot append palette to packet\n");
11902  } else {
11903  memcpy(pal, sc->palette, AVPALETTE_SIZE);
11904  sc->has_palette = 0;
11905  }
11906  }
11907  if (st->codecpar->codec_id == AV_CODEC_ID_MP3 && !ffstream(st)->need_parsing && pkt->size > 4) {
11908  if (ff_mpa_check_header(AV_RB32(pkt->data)) < 0)
11910  }
11911  }
11912 
11913  ret = mov_finalize_packet(s, st, sample, current_index, pkt);
11914  if (ret < 0)
11915  return ret;
11916 
11917  if (st->discard == AVDISCARD_ALL)
11918  goto retry;
11919 
11920  if (mov->aax_mode)
11921  aax_filter(pkt->data, pkt->size, mov);
11922 
11923  ret = cenc_filter(mov, st, sc, pkt, current_index);
11924  if (ret < 0) {
11925  return ret;
11926  }
11927 
11928  return 0;
11929 }
11930 
11932 {
11933  MOVContext *mov = s->priv_data;
11934  int index;
11935 
11936  if (!mov->frag_index.complete)
11937  return 0;
11938 
11939  index = search_frag_timestamp(s, &mov->frag_index, st, timestamp);
11940  if (index < 0)
11941  index = 0;
11942  if (!mov->frag_index.item[index].headers_read)
11943  return mov_switch_root(s, -1, index);
11944  if (index + 1 < mov->frag_index.nb_items)
11945  mov->next_root_atom = mov->frag_index.item[index + 1].moof_offset;
11946 
11947  return 0;
11948 }
11949 
11950 static int is_open_key_sample(const MOVStreamContext *sc, int sample)
11951 {
11952  // TODO: a bisect search would scale much better
11953  for (int i = 0; i < sc->open_key_samples_count; i++) {
11954  const int oks = sc->open_key_samples[i];
11955  if (oks == sample)
11956  return 1;
11957  if (oks > sample) /* list is monotically increasing so we can stop early */
11958  break;
11959  }
11960  return 0;
11961 }
11962 
11963 /*
11964  * Some key sample may be key frames but not IDR frames, so a random access to
11965  * them may not be allowed.
11966  */
11967 static int can_seek_to_key_sample(AVStream *st, int sample, int64_t requested_pts)
11968 {
11969  MOVStreamContext *sc = st->priv_data;
11970  FFStream *const sti = ffstream(st);
11971  int64_t key_sample_dts, key_sample_pts;
11972 
11973  if (st->codecpar->codec_id != AV_CODEC_ID_HEVC)
11974  return 1;
11975 
11976  if (sample >= sc->sample_offsets_count)
11977  return 1;
11978 
11979  av_assert0(sample >= 0);
11980  key_sample_dts = sti->index_entries[sample].timestamp;
11981  key_sample_pts = key_sample_dts + sc->sample_offsets[sample] + sc->dts_shift;
11982 
11983  /*
11984  * If the sample needs to be presented before an open key sample, they may
11985  * not be decodable properly, even though they come after in decoding
11986  * order.
11987  */
11988  if (is_open_key_sample(sc, sample) && key_sample_pts > requested_pts)
11989  return 0;
11990 
11991  return 1;
11992 }
11993 
11994 static int mov_seek_stream(AVFormatContext *s, AVStream *st, int64_t timestamp, int flags)
11995 {
11996  MOVStreamContext *sc = st->priv_data;
11997  FFStream *const sti = ffstream(st);
11998  int sample, time_sample, ret, requested_sample;
11999  int64_t next_ts;
12000  unsigned int i;
12001 
12002  // Here we consider timestamp to be PTS, hence try to offset it so that we
12003  // can search over the DTS timeline.
12004  timestamp -= (sc->min_corrected_pts + sc->dts_shift);
12005 
12006  ret = mov_seek_fragment(s, st, timestamp);
12007  if (ret < 0)
12008  return ret;
12009 
12010  for (;;) {
12011  sample = av_index_search_timestamp(st, timestamp, flags);
12012  av_log(s, AV_LOG_TRACE, "stream %d, timestamp %"PRId64", sample %d\n", st->index, timestamp, sample);
12013  if (sample < 0 && sti->nb_index_entries && timestamp < sti->index_entries[0].timestamp)
12014  sample = 0;
12015  if (sample < 0) /* not sure what to do */
12016  return AVERROR_INVALIDDATA;
12017 
12018  if (!sample || can_seek_to_key_sample(st, sample, timestamp))
12019  break;
12020 
12021  next_ts = timestamp - FFMAX(sc->min_sample_duration, 1);
12022  requested_sample = av_index_search_timestamp(st, next_ts, flags);
12023  if (requested_sample < 0)
12024  return AVERROR_INVALIDDATA;
12025 
12026  // If we've reached a different sample trying to find a good pts to
12027  // seek to, give up searching because we'll end up seeking back to
12028  // sample 0 on every seek.
12029  if (sample != requested_sample && !can_seek_to_key_sample(st, requested_sample, next_ts))
12030  break;
12031 
12032  timestamp = next_ts;
12033  }
12034 
12036  av_log(s, AV_LOG_TRACE, "stream %d, found sample %d\n", st->index, sc->current_sample);
12037  /* adjust time to sample index */
12038  if (sc->tts_data) {
12039  time_sample = 0;
12040  for (i = 0; i < sc->tts_count; i++) {
12041  int next = time_sample + sc->tts_data[i].count;
12042  if (next > sc->current_sample) {
12043  sc->tts_index = i;
12044  sc->tts_sample = sc->current_sample - time_sample;
12045  break;
12046  }
12047  time_sample = next;
12048  }
12049  }
12050 
12051  /* adjust stsd index */
12052  if (sc->chunk_count) {
12053  time_sample = 0;
12054  for (i = 0; i < sc->stsc_count; i++) {
12055  int64_t next = time_sample + mov_get_stsc_samples(sc, i);
12056  if (next > sc->current_sample) {
12057  sc->stsc_index = i;
12058  sc->stsc_sample = sc->current_sample - time_sample;
12059  break;
12060  }
12061  av_assert0(next == (int)next);
12062  time_sample = next;
12063  }
12064  }
12065 
12066  return sample;
12067 }
12068 
12070 {
12071  FFStream *const sti = ffstream(st);
12072  int64_t first_ts = sti->index_entries[0].timestamp;
12074  int64_t off;
12075 
12077  return 0;
12078 
12079  /* compute skip samples according to stream initial_padding, seek ts and first ts */
12080  off = av_rescale_q(ts - first_ts, st->time_base,
12081  (AVRational){1, st->codecpar->sample_rate});
12082  return FFMAX(st->codecpar->initial_padding - off, 0);
12083 }
12084 
12085 static int mov_read_seek(AVFormatContext *s, int stream_index, int64_t sample_time, int flags)
12086 {
12087  MOVContext *mc = s->priv_data;
12088  AVStream *st;
12089  FFStream *sti;
12090  int sample;
12091  int i;
12092 
12093  if (stream_index >= s->nb_streams)
12094  return AVERROR_INVALIDDATA;
12095 
12096  st = s->streams[stream_index];
12097  sti = ffstream(st);
12098  sample = mov_seek_stream(s, st, sample_time, flags);
12099  if (sample < 0)
12100  return sample;
12101 
12102  if (mc->seek_individually) {
12103  /* adjust seek timestamp to found sample timestamp */
12104  int64_t seek_timestamp = sti->index_entries[sample].timestamp;
12106 
12107  for (i = 0; i < s->nb_streams; i++) {
12108  AVStream *const st = s->streams[i];
12109  FFStream *const sti = ffstream(st);
12110  int64_t timestamp;
12111 
12112  if (stream_index == i)
12113  continue;
12114 
12115  timestamp = av_rescale_q(seek_timestamp, s->streams[stream_index]->time_base, st->time_base);
12116  sample = mov_seek_stream(s, st, timestamp, flags);
12117  if (sample >= 0)
12119  }
12120  } else {
12121  for (i = 0; i < s->nb_streams; i++) {
12122  MOVStreamContext *sc;
12123  st = s->streams[i];
12124  sc = st->priv_data;
12125  mov_current_sample_set(sc, 0);
12126  }
12127  while (1) {
12128  MOVStreamContext *sc;
12130  if (!entry)
12131  return AVERROR_INVALIDDATA;
12132  sc = st->priv_data;
12133  if (sc->ffindex == stream_index && sc->current_sample == sample)
12134  break;
12136  }
12137  }
12138  return 0;
12139 }
12140 
12141 #define OFFSET(x) offsetof(MOVContext, x)
12142 #define FLAGS AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM
12143 static const AVOption mov_options[] = {
12144  {"use_absolute_path",
12145  "allow using absolute path when opening alias, this is a possible security issue",
12146  OFFSET(use_absolute_path), AV_OPT_TYPE_BOOL, {.i64 = 0},
12147  0, 1, FLAGS},
12148  {"seek_streams_individually",
12149  "Seek each stream individually to the closest point",
12150  OFFSET(seek_individually), AV_OPT_TYPE_BOOL, { .i64 = 1 },
12151  0, 1, FLAGS},
12152  {"ignore_editlist", "Ignore the edit list atom.", OFFSET(ignore_editlist), AV_OPT_TYPE_BOOL, {.i64 = 0},
12153  0, 1, FLAGS},
12154  {"advanced_editlist",
12155  "Modify the AVIndex according to the editlists. Use this option to decode in the order specified by the edits.",
12156  OFFSET(advanced_editlist), AV_OPT_TYPE_BOOL, {.i64 = 1},
12157  0, 1, FLAGS},
12158  {"ignore_chapters", "", OFFSET(ignore_chapters), AV_OPT_TYPE_BOOL, {.i64 = 0},
12159  0, 1, FLAGS},
12160  {"use_mfra_for",
12161  "use mfra for fragment timestamps",
12162  OFFSET(use_mfra_for), AV_OPT_TYPE_INT, {.i64 = FF_MOV_FLAG_MFRA_AUTO},
12164  .unit = "use_mfra_for"},
12165  {"auto", "auto", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_AUTO}, 0, 0,
12166  FLAGS, .unit = "use_mfra_for" },
12167  {"dts", "dts", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_DTS}, 0, 0,
12168  FLAGS, .unit = "use_mfra_for" },
12169  {"pts", "pts", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_PTS}, 0, 0,
12170  FLAGS, .unit = "use_mfra_for" },
12171  {"use_tfdt", "use tfdt for fragment timestamps", OFFSET(use_tfdt), AV_OPT_TYPE_BOOL, {.i64 = 1},
12172  0, 1, FLAGS},
12173  { "export_all", "Export unrecognized metadata entries", OFFSET(export_all),
12174  AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = FLAGS },
12175  { "export_xmp", "Export full XMP metadata", OFFSET(export_xmp),
12176  AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = FLAGS },
12177  { "activation_bytes", "Secret bytes for Audible AAX files", OFFSET(activation_bytes),
12179  { "audible_key", "AES-128 Key for Audible AAXC files", OFFSET(audible_key),
12181  { "audible_iv", "AES-128 IV for Audible AAXC files", OFFSET(audible_iv),
12183  { "audible_fixed_key", // extracted from libAAX_SDK.so and AAXSDKWin.dll files!
12184  "Fixed key used for handling Audible AAX files", OFFSET(audible_fixed_key),
12185  AV_OPT_TYPE_BINARY, {.str="77214d4b196a87cd520045fd20a51d67"},
12186  .flags = AV_OPT_FLAG_DECODING_PARAM },
12187  { "decryption_key", "The default media decryption key (hex)", OFFSET(decryption_default_key), AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM },
12188  { "decryption_keys", "The media decryption keys by KID (hex)", OFFSET(decryption_keys), AV_OPT_TYPE_DICT, .flags = AV_OPT_FLAG_DECODING_PARAM },
12189  { "enable_drefs", "Enable external track support.", OFFSET(enable_drefs), AV_OPT_TYPE_BOOL,
12190  {.i64 = 0}, 0, 1, FLAGS },
12191  { "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 },
12192  { "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 },
12193 
12194  { NULL },
12195 };
12196 
12197 static const AVClass mov_class = {
12198  .class_name = "mov,mp4,m4a,3gp,3g2,mj2",
12199  .item_name = av_default_item_name,
12200  .option = mov_options,
12201  .version = LIBAVUTIL_VERSION_INT,
12202 };
12203 
12205  .p.name = "mov,mp4,m4a,3gp,3g2,mj2",
12206  .p.long_name = NULL_IF_CONFIG_SMALL("QuickTime / MOV"),
12207  .p.priv_class = &mov_class,
12208  .p.extensions = "mov,mp4,m4a,3gp,3g2,mj2,psp,m4v,m4b,ism,ismv,isma,f4v,avif,heic,heif",
12210  .priv_data_size = sizeof(MOVContext),
12211  .flags_internal = FF_INFMT_FLAG_INIT_CLEANUP,
12212  .read_probe = mov_probe,
12217 };
HEIFItemRef::item_id
int item_id
Definition: isom.h:295
avpriv_new_chapter
AVChapter * avpriv_new_chapter(AVFormatContext *s, int64_t id, AVRational time_base, int64_t start, int64_t end, const char *title)
Add a new chapter.
Definition: demux_utils.c:43
MOVStreamContext::ctts_allocated_size
unsigned int ctts_allocated_size
Definition: isom.h:197
item_name
item_name
Definition: libkvazaar.c:311
AV_CODEC_ID_PCM_S16LE
@ AV_CODEC_ID_PCM_S16LE
Definition: codec_id.h:330
flags
const SwsFlags flags[]
Definition: swscale.c:85
AV_EXIF_T_OFF
@ AV_EXIF_T_OFF
The first four bytes point to the actual start, then it's AV_EXIF_TIFF_HEADER.
Definition: exif.h:68
mov_finalize_stsd_entry
static int mov_finalize_stsd_entry(MOVContext *c, AVStream *st)
Definition: mov.c:3194
mov_read_chpl
static int mov_read_chpl(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:614
AVMasteringDisplayMetadata::has_primaries
int has_primaries
Flag indicating whether the display primaries (and white point) are set.
Definition: mastering_display_metadata.h:62
mov_read_frma
static int mov_read_frma(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:7615
mov_read_meta
static int mov_read_meta(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5682
AV_CODEC_ID_EIA_608
@ AV_CODEC_ID_EIA_608
Definition: codec_id.h:575
AV_PKT_DATA_DISPLAYMATRIX
@ AV_PKT_DATA_DISPLAYMATRIX
This side data contains a 3x3 transformation matrix describing an affine transformation that needs to...
Definition: packet.h:105
av_packet_unref
void av_packet_unref(AVPacket *pkt)
Wipe the packet.
Definition: packet.c:434
MOVContext::found_iloc
int found_iloc
'iloc' atom has been found
Definition: isom.h:331
AV_CODEC_ID_MACE6
@ AV_CODEC_ID_MACE6
Definition: codec_id.h:462
MOVFragmentStreamInfo::first_tfra_pts
int64_t first_tfra_pts
Definition: isom.h:148
ff_rfps_add_frame
int ff_rfps_add_frame(AVFormatContext *ic, AVStream *st, int64_t ts)
add frame for rfps calculation.
Definition: demux.c:2336
read_image_iovl
static int read_image_iovl(AVFormatContext *s, const HEIFGrid *grid, AVStreamGroupTileGrid *tile_grid)
Definition: mov.c:10676
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:9592
AVMEDIA_TYPE_SUBTITLE
@ AVMEDIA_TYPE_SUBTITLE
Definition: avutil.h:203
AVIAMFSubmix::elements
AVIAMFSubmixElement ** elements
Array of submix elements.
Definition: iamf.h:568
skip_bits_long
static void skip_bits_long(GetBitContext *s, int n)
Skips the specified number of bits.
Definition: get_bits.h:280
AV_LOG_WARNING
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:216
AV_BPRINT_SIZE_UNLIMITED
#define AV_BPRINT_SIZE_UNLIMITED
MOV_TFHD_DEFAULT_FLAGS
#define MOV_TFHD_DEFAULT_FLAGS
Definition: isom.h:412
PUT_UTF8
#define PUT_UTF8(val, tmp, PUT_BYTE)
Definition: common.h:530
AV_TIMECODE_STR_SIZE
#define AV_TIMECODE_STR_SIZE
Definition: timecode.h:33
av_aes_init
int av_aes_init(AVAES *a, const uint8_t *key, int key_bits, int decrypt)
Initialize an AVAES context.
Definition: aes.c:231
AV_CODEC_ID_PCM_F32BE
@ AV_CODEC_ID_PCM_F32BE
Definition: codec_id.h:350
FFStream::skip_samples
int skip_samples
Number of samples to skip at the start of the frame decoded from the next packet.
Definition: internal.h:208
MOVStreamContext::audio_cid
int16_t audio_cid
stsd audio compression id
Definition: isom.h:227
AVMasteringDisplayMetadata::max_luminance
AVRational max_luminance
Max luminance of mastering display (cd/m^2).
Definition: mastering_display_metadata.h:57
AVSphericalProjection
AVSphericalProjection
Projection of the video surface(s) on a sphere.
Definition: spherical.h:47
AV_CODEC_ID_ADPCM_MS
@ AV_CODEC_ID_ADPCM_MS
Definition: codec_id.h:375
AVCodecParameters::extradata
uint8_t * extradata
Extra binary data needed for initializing the decoder, codec-dependent.
Definition: codec_par.h:71
mov_read_dops
static int mov_read_dops(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:8743
can_seek_to_key_sample
static int can_seek_to_key_sample(AVStream *st, int sample, int64_t requested_pts)
Definition: mov.c:11967
name
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf default minimum maximum flags name is the option name
Definition: writing_filters.txt:88
AV_CODEC_ID_ADPCM_IMA_QT
@ AV_CODEC_ID_ADPCM_IMA_QT
Definition: codec_id.h:369
entry
#define entry
Definition: aom_film_grain_template.c:66
AVFMT_NO_BYTE_SEEK
#define AVFMT_NO_BYTE_SEEK
Format does not allow seeking by bytes.
Definition: avformat.h:487
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:1159
AV_CODEC_ID_AC3
@ AV_CODEC_ID_AC3
Definition: codec_id.h:455
HEIFItem::name
char * name
Definition: isom.h:302
AV_STEREO3D_VIEW_LEFT
@ AV_STEREO3D_VIEW_LEFT
Frame contains only the left view.
Definition: stereo3d.h:158
MOVStreamContext::sync_group
MOVSbgp * sync_group
Definition: isom.h:247
MOVStreamContext::height
int height
tkhd height
Definition: isom.h:234
MOVContext::moov_retry
int moov_retry
Definition: isom.h:359
MOV_TRUN_SAMPLE_FLAGS
#define MOV_TRUN_SAMPLE_FLAGS
Definition: isom.h:420
AV_PKT_DATA_AMBIENT_VIEWING_ENVIRONMENT
@ AV_PKT_DATA_AMBIENT_VIEWING_ENVIRONMENT
Ambient viewing environment metadata, as defined by H.274.
Definition: packet.h:327
MOVContext::nb_chapter_tracks
unsigned int nb_chapter_tracks
Definition: isom.h:347
mix
static int mix(int c0, int c1)
Definition: 4xm.c:717
MOVStreamContext::last_stsd_index
int last_stsd_index
Definition: isom.h:262
ff_ac3_channel_layout_tab
const uint16_t ff_ac3_channel_layout_tab[8]
Map audio coding mode (acmod) to channel layout mask.
Definition: ac3_channel_layout_tab.h:31
r
const char * r
Definition: vf_curves.c:127
AVERROR
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later. That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another. Frame references ownership and permissions
opt.h
flag
int flag
Definition: cpu.c:40
get_heif_item
static HEIFItem * get_heif_item(MOVContext *c, unsigned id)
Get the requested item.
Definition: mov.c:195
MOV_TKHD_FLAG_ENABLED
#define MOV_TKHD_FLAG_ENABLED
Definition: isom.h:433
AVCodecParameters::codec_type
enum AVMediaType codec_type
General type of the encoded data.
Definition: codec_par.h:53
AVStreamGroup::tile_grid
struct AVStreamGroupTileGrid * tile_grid
Definition: avformat.h:1175
AVFMT_SHOW_IDS
#define AVFMT_SHOW_IDS
Show format stream IDs numbers.
Definition: avformat.h:477
AVSphericalMapping::projection
enum AVSphericalProjection projection
Projection type.
Definition: spherical.h:104
AV_WL32
#define AV_WL32(p, v)
Definition: intreadwrite.h:422
av_exif_parse_buffer
int av_exif_parse_buffer(void *logctx, const uint8_t *buf, size_t size, AVExifMetadata *ifd, enum AVExifHeaderMode header_mode)
Decodes the EXIF data provided in the buffer and writes it into the struct *ifd.
Definition: exif.c:882
AV_STREAM_GROUP_PARAMS_LCEVC
@ AV_STREAM_GROUP_PARAMS_LCEVC
Definition: avformat.h:1132
MOVStreamContext::extradata
uint8_t ** extradata
extradata array (and size) for multiple stsd
Definition: isom.h:260
mov_class
static const AVClass mov_class
Definition: mov.c:12197
AVSphericalMapping::bound_bottom
uint32_t bound_bottom
Distance from the bottom edge.
Definition: spherical.h:188
MOVStreamContext::open_key_samples
int * open_key_samples
Definition: isom.h:252
AVUUID
uint8_t AVUUID[AV_UUID_LEN]
Definition: uuid.h:60
MovTref
Definition: isom.h:94
mov_parse_tmcd_streams
static int mov_parse_tmcd_streams(AVFormatContext *s)
Definition: mov.c:11034
out
static FILE * out
Definition: movenc.c:55
MOVFragmentStreamInfo
Definition: isom.h:145
AVFieldOrder
AVFieldOrder
Definition: defs.h:211
mov_read_targa_y216
static int mov_read_targa_y216(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2339
mov_read_chnl
static int mov_read_chnl(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1241
mov_read_moof
static int mov_read_moof(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1869
av_bprint_init
void av_bprint_init(AVBPrint *buf, unsigned size_init, unsigned size_max)
Definition: bprint.c:69
ctype
#define ctype
Definition: afir_template.c:46
AV_PKT_DATA_FRAME_CROPPING
@ AV_PKT_DATA_FRAME_CROPPING
The number of pixels to discard from the top/bottom/left/right border of the decoded frame to obtain ...
Definition: packet.h:340
av_exif_write
int av_exif_write(void *logctx, const AVExifMetadata *ifd, AVBufferRef **buffer, enum AVExifHeaderMode header_mode)
Allocates a buffer using av_malloc of an appropriate size and writes the EXIF data represented by ifd...
Definition: exif.c:753
AVCodecParameters
This struct describes the properties of an encoded stream.
Definition: codec_par.h:49
HEIFItem::icc_profile
uint8_t * icc_profile
Definition: isom.h:313
AVFMT_FLAG_IGNIDX
#define AVFMT_FLAG_IGNIDX
Ignore index.
Definition: avformat.h:1467
AVExifMetadata
Definition: exif.h:75
sanity_checks
static int sanity_checks(void *log_obj, MOVStreamContext *sc, int index)
Definition: mov.c:5298
av_stristr
char * av_stristr(const char *s1, const char *s2)
Locate the first case-independent occurrence in the string haystack of the string needle.
Definition: avstring.c:58
AVCodecParameters::color_space
enum AVColorSpace color_space
Definition: codec_par.h:192
avformat_new_stream
AVStream * avformat_new_stream(AVFormatContext *s, const struct AVCodec *c)
Add a new stream to a media file.
ff_replaygain_export
int ff_replaygain_export(AVStream *st, AVDictionary *metadata)
Parse replaygain tags and export them as per-stream side data.
Definition: replaygain.c:94
tmcd_is_referenced
static int tmcd_is_referenced(AVFormatContext *s, int tmcd_id)
Definition: mov.c:10409
HEIFItem::hflip
int hflip
Definition: isom.h:309
AV_PKT_DATA_NEW_EXTRADATA
@ AV_PKT_DATA_NEW_EXTRADATA
The AV_PKT_DATA_NEW_EXTRADATA is used to notify the codec or the format that the extradata buffer was...
Definition: packet.h:56
IAMFAudioElement::nb_substreams
unsigned int nb_substreams
Definition: iamf.h:99
AVStream::priv_data
void * priv_data
Definition: avformat.h:772
AVERROR_EOF
#define AVERROR_EOF
End of file.
Definition: error.h:57
AVBufferRef::data
uint8_t * data
The data buffer.
Definition: buffer.h:90
AV_DISPOSITION_ATTACHED_PIC
#define AV_DISPOSITION_ATTACHED_PIC
The stream is stored in the file as an attached picture/"cover art" (e.g.
Definition: avformat.h:673
AVStream::discard
enum AVDiscard discard
Selects which packets can be discarded at will and do not need to be demuxed.
Definition: avformat.h:818
AV_FIELD_PROGRESSIVE
@ AV_FIELD_PROGRESSIVE
Definition: defs.h:213
mov_options
static const AVOption mov_options[]
Definition: mov.c:12143
mov_codec_id
static int mov_codec_id(AVStream *st, uint32_t format)
Definition: mov.c:2777
AV_PKT_DATA_MASTERING_DISPLAY_METADATA
@ AV_PKT_DATA_MASTERING_DISPLAY_METADATA
Mastering display metadata (based on SMPTE-2086:2014).
Definition: packet.h:219
MOVStreamContext::sample_offsets
int32_t * sample_offsets
Definition: isom.h:250
av_int2double
static av_always_inline double av_int2double(uint64_t i)
Reinterpret a 64-bit integer as a double.
Definition: intfloat.h:60
mov_read_iloc
static int mov_read_iloc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:9167
matrix
Definition: vc1dsp.c:43
AVMasteringDisplayMetadata::display_primaries
AVRational display_primaries[3][2]
CIE 1931 xy chromaticity coords of color primaries (r, g, b order).
Definition: mastering_display_metadata.h:42
AV_PKT_FLAG_DISCARD
#define AV_PKT_FLAG_DISCARD
Flag is used to discard packets which are required to maintain valid decoder state but are not requir...
Definition: packet.h:657
AVMasteringDisplayMetadata::has_luminance
int has_luminance
Flag indicating whether the luminance (min_ and max_) have been set.
Definition: mastering_display_metadata.h:67
get_bits_long
static unsigned int get_bits_long(GetBitContext *s, int n)
Read 0-32 bits.
Definition: get_bits.h:424
int64_t
long long int64_t
Definition: coverity.c:34
output
filter_frame For filters that do not use the this method is called when a frame is pushed to the filter s input It can be called at any time except in a reentrant way If the input frame is enough to produce output
Definition: filter_design.txt:226
mov_read_alac
static int mov_read_alac(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2311
test_same_origin
static int test_same_origin(const char *src, const char *ref)
Definition: mov.c:5141
cbcs_scheme_decrypt
static int cbcs_scheme_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
Definition: mov.c:8560
MOVFragment::base_data_offset
uint64_t base_data_offset
Definition: isom.h:110
MOVStreamContext
Definition: isom.h:179
AVChannelLayout::map
AVChannelCustom * map
This member must be used when the channel order is AV_CHANNEL_ORDER_CUSTOM.
Definition: channel_layout.h:370
MOVStreamContext::stsc_data
MOVStsc * stsc_data
Definition: isom.h:200
ff_buffer_packet
int ff_buffer_packet(AVFormatContext *s, AVPacket *pkt)
Definition: demux.c:622
IS_MATRIX_IDENT
#define IS_MATRIX_IDENT(matrix)
Definition: mov.c:5700
AVStreamGroup::disposition
int disposition
Stream group disposition - a combination of AV_DISPOSITION_* flags.
Definition: avformat.h:1225
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:620
mov_update_dts_shift
static void mov_update_dts_shift(MOVStreamContext *sc, int duration, void *logctx)
Definition: mov.c:3830
MOVStreamContext::spherical
AVSphericalMapping * spherical
Definition: isom.h:269
mask
int mask
Definition: mediacodecdec_common.c:154
out_size
static int out_size
Definition: movenc.c:56
AV_CODEC_ID_MPEG4
@ AV_CODEC_ID_MPEG4
Definition: codec_id.h:62
AVContentLightMetadata::MaxCLL
unsigned MaxCLL
Max content light level (cd/m^2).
Definition: mastering_display_metadata.h:111
avio_get_str16be
int avio_get_str16be(AVIOContext *pb, int maxlen, char *buf, int buflen)
MOVEncryptionIndex
Definition: isom.h:132
av_encryption_init_info_free
void av_encryption_init_info_free(AVEncryptionInitInfo *info)
Frees the given encryption init info object.
Definition: encryption_info.c:216
FFStream::first_discard_sample
int64_t first_discard_sample
If not 0, the first audio sample that should be discarded from the stream.
Definition: internal.h:225
mov_read_avss
static int mov_read_avss(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2316
AV_RB32A
#define AV_RB32A(p)
Definition: intreadwrite.h:575
MOVContext::primary_item_id
int primary_item_id
Definition: isom.h:384
mode
Definition: swscale.c:71
MOVContext::found_moov
int found_moov
'moov' atom has been found
Definition: isom.h:330
ff_iamf_read_packet
int ff_iamf_read_packet(AVFormatContext *s, IAMFDemuxContext *c, AVIOContext *pb, int max_size, int stream_id_offset, AVPacket *pkt)
Definition: iamf_reader.c:308
mov_read_custom
static int mov_read_custom(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5523
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:1382
HEIFGrid::nb_tiles
int nb_tiles
Definition: isom.h:322
ID3v1_GENRE_MAX
#define ID3v1_GENRE_MAX
Definition: id3v1.h:29
MOVSbgp
Definition: isom.h:127
MOVCtts
Definition: isom.h:68
AVPacketSideData
This structure stores auxiliary information for decoding, presenting, or otherwise processing the cod...
Definition: packet.h:424
mov_read_extradata
static int mov_read_extradata(MOVContext *c, AVIOContext *pb, MOVAtom atom, enum AVCodecID codec_id)
Definition: mov.c:2285
AVCOL_RANGE_JPEG
@ AVCOL_RANGE_JPEG
Full range content.
Definition: pixfmt.h:777
mpegaudiodecheader.h
MOVStreamContext::rap_group_count
unsigned int rap_group_count
Definition: isom.h:244
av_display_matrix_flip
void av_display_matrix_flip(int32_t matrix[9], int hflip, int vflip)
Flip the input matrix horizontally and/or vertically.
Definition: display.c:66
mov_read_iref_cdsc
static int mov_read_iref_cdsc(MOVContext *c, AVIOContext *pb, uint32_t type, int version, uint32_t size)
Definition: mov.c:9475
av_sha_init
av_cold int av_sha_init(AVSHA *ctx, int bits)
Initialize SHA-1 or SHA-2 hashing.
Definition: sha.c:274
HEIFItem::type
int type
Definition: isom.h:311
mov_read_mvhd
static int mov_read_mvhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1971
mov_read_idat
static int mov_read_idat(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:9161
AVPacket::data
uint8_t * data
Definition: packet.h:603
MOVContext::found_mdat
int found_mdat
'mdat' atom has been found
Definition: isom.h:333
MOVStreamContext::drefs_count
unsigned drefs_count
Definition: isom.h:228
AVEncryptionInfo::crypt_byte_block
uint32_t crypt_byte_block
Only used for pattern encryption.
Definition: encryption_info.h:51
AV_PKT_DATA_ENCRYPTION_INIT_INFO
@ AV_PKT_DATA_ENCRYPTION_INIT_INFO
This side data is encryption initialization data.
Definition: packet.h:246
mov_read_avid
static int mov_read_avid(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2331
AVAmbientViewingEnvironment::ambient_light_x
AVRational ambient_light_x
Normalized x chromaticity coordinate of the environmental ambient light in the nominal viewing enviro...
Definition: ambient_viewing_environment.h:47
AVCodecParameters::seek_preroll
int seek_preroll
Number of audio samples to skip after a discontinuity.
Definition: codec_par.h:256
av_dynarray2_add
void * av_dynarray2_add(void **tab_ptr, int *nb_ptr, size_t elem_size, const uint8_t *elem_data)
Add an element of size elem_size to a dynamic array.
Definition: mem.c:343
AVOption
AVOption.
Definition: opt.h:428
MOVContext::trex_data
MOVTrackExt * trex_data
Definition: isom.h:342
mov_read_stps
static int mov_read_stps(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:3483
MOVContext::bitrates
int * bitrates
bitrates read before streams creation
Definition: isom.h:357
b
#define b
Definition: input.c:43
AVCOL_TRC_UNSPECIFIED
@ AVCOL_TRC_UNSPECIFIED
Definition: pixfmt.h:669
MOVContext::interleaved_read
int interleaved_read
Definition: isom.h:391
mov_read_tkhd
static int mov_read_tkhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5708
MOVElst::rate
float rate
Definition: isom.h:82
AVStream::avg_frame_rate
AVRational avg_frame_rate
Average framerate.
Definition: avformat.h:836
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:2125
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:2010
mov_read_strf
static int mov_read_strf(MOVContext *c, AVIOContext *pb, MOVAtom atom)
An strf atom is a BITMAPINFOHEADER struct.
Definition: mov.c:2690
AV_CODEC_ID_ALAC
@ AV_CODEC_ID_ALAC
Definition: codec_id.h:468
HEIFItem::st
AVStream * st
Definition: isom.h:299
FF_COMPLIANCE_STRICT
#define FF_COMPLIANCE_STRICT
Strictly conform to all the things in the spec no matter what consequences.
Definition: defs.h:59
AV_DICT_APPEND
#define AV_DICT_APPEND
If the entry already exists, append to it.
Definition: dict.h:82
AVIOContext::error
int error
contains the error code or 0 if no error happened
Definition: avio.h:239
AV_CODEC_ID_AMR_NB
@ AV_CODEC_ID_AMR_NB
Definition: codec_id.h:433
av_iamf_mix_presentation_free
void av_iamf_mix_presentation_free(AVIAMFMixPresentation **pmix_presentation)
Free an AVIAMFMixPresentation and all its contents.
Definition: iamf.c:536
AVStreamGroupTREF::metadata_index
unsigned int metadata_index
Index of the metadata stream in the AVStreamGroup.
Definition: avformat.h:1124
mov_parse_auxiliary_info
static int mov_parse_auxiliary_info(MOVContext *c, MOVStreamContext *sc, AVIOContext *pb, MOVEncryptionIndex *encryption_index)
Definition: mov.c:7823
mov_seek_stream
static int mov_seek_stream(AVFormatContext *s, AVStream *st, int64_t timestamp, int flags)
Definition: mov.c:11994
mov_read_saio
static int mov_read_saio(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:7969
mov_get_stsc_samples
static int64_t mov_get_stsc_samples(MOVStreamContext *sc, unsigned int index)
Definition: mov.c:3468
AV_LOG_VERBOSE
#define AV_LOG_VERBOSE
Detailed information.
Definition: log.h:226
ff_codec_wav_tags
const AVCodecTag ff_codec_wav_tags[]
Definition: riff.c:525
get_edit_list_entry
static int get_edit_list_entry(MOVContext *mov, const MOVStreamContext *msc, unsigned int edit_list_index, int64_t *edit_list_media_time, int64_t *edit_list_duration, int64_t global_timescale)
Get ith edit list entry (media time, duration).
Definition: mov.c:4042
MOVFragmentIndexItem::moof_offset
int64_t moof_offset
Definition: isom.h:159
MOVStreamContext::spherical_size
size_t spherical_size
Definition: isom.h:270
mov_change_extradata
static int mov_change_extradata(AVStream *st, AVPacket *pkt)
Definition: mov.c:11573
nb_streams
static unsigned int nb_streams
Definition: ffprobe.c:352
HEIFItemRef
Definition: isom.h:293
MP4TrackKindMapping::scheme_uri
const char * scheme_uri
Definition: isom.h:493
AVINDEX_DISCARD_FRAME
#define AVINDEX_DISCARD_FRAME
Definition: avformat.h:610
av_display_rotation_set
void av_display_rotation_set(int32_t matrix[9], double angle)
Initialize a transformation matrix describing a pure clockwise rotation by the specified angle (in de...
Definition: display.c:51
AVPacket::duration
int64_t duration
Duration of this packet in AVStream->time_base units, 0 if unknown.
Definition: packet.h:621
AVStreamGroup::tref
struct AVStreamGroupTREF * tref
Definition: avformat.h:1184
AVCodecParameters::codec_tag
uint32_t codec_tag
Additional information about the codec (corresponds to the AVI FOURCC).
Definition: codec_par.h:61
fixed_key
static const uint8_t fixed_key[]
Definition: aes_ctr.c:45
AV_SPHERICAL_EQUIRECTANGULAR_TILE
@ AV_SPHERICAL_EQUIRECTANGULAR_TILE
Video represents a portion of a sphere mapped on a flat surface using equirectangular projection.
Definition: spherical.h:68
AVStereo3D::baseline
uint32_t baseline
The distance between the centres of the lenses of the camera system, in micrometers.
Definition: stereo3d.h:228
MOVDref::dir
char * dir
Definition: isom.h:88
mov_current_sample_set
static void mov_current_sample_set(MOVStreamContext *sc, int current_sample)
Definition: mov.c:4346
mathematics.h
AVDictionary
Definition: dict.c:32
ffio_init_read_context
void ffio_init_read_context(FFIOContext *s, const uint8_t *buffer, int buffer_size)
Wrap a buffer in an AVIOContext for reading.
Definition: aviobuf.c:99
AV_PKT_FLAG_DISPOSABLE
#define AV_PKT_FLAG_DISPOSABLE
Flag is used to indicate packets that contain frames that can be discarded by the decoder.
Definition: packet.h:669
AVChannelLayout::order
enum AVChannelOrder order
Channel order used in this layout.
Definition: channel_layout.h:324
FFMAX
#define FFMAX(a, b)
Definition: macros.h:47
MOVAtom
Definition: isom.h:100
AVStreamGroupTileGrid::vertical
int vertical
Offset in pixels from the top edge of the canvas where the tile should be placed.
Definition: avformat.h:1003
iamf_parse.h
mov_read_moov
static int mov_read_moov(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1619
av_sub_q
AVRational av_sub_q(AVRational b, AVRational c)
Subtract one rational from another.
Definition: rational.c:101
cffstream
static const av_always_inline FFStream * cffstream(const AVStream *st)
Definition: internal.h:363
mov_read_esds
static int mov_read_esds(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:863
MOVStreamContext::sample_count
unsigned int sample_count
Definition: isom.h:211
MOVFragmentIndex::allocated_size
int allocated_size
Definition: isom.h:167
MOVTrackExt::flags
unsigned flags
Definition: isom.h:124
AVChannelLayout::nb_channels
int nb_channels
Number of channels in this layout.
Definition: channel_layout.h:329
HEIFItem::height
int height
Definition: isom.h:307
AV_SPHERICAL_EQUIRECTANGULAR
@ AV_SPHERICAL_EQUIRECTANGULAR
Video represents a sphere mapped on a flat surface using equirectangular projection.
Definition: spherical.h:52
intfloat.h
id3v1.h
MOVStreamContext::ctts_data
MOVCtts * ctts_data
Definition: isom.h:198
ff_dvdclut_yuv_to_rgb
int ff_dvdclut_yuv_to_rgb(uint32_t *clut, const size_t clut_size)
Definition: dvdclut.c:50
AV_CODEC_ID_R10K
@ AV_CODEC_ID_R10K
Definition: codec_id.h:195
av_encryption_init_info_get_side_data
AVEncryptionInitInfo * av_encryption_init_info_get_side_data(const uint8_t *side_data, size_t side_data_size)
Creates a copy of the AVEncryptionInitInfo that is contained in the given side data.
Definition: encryption_info.c:231
AV_STEREO3D_VIEW_RIGHT
@ AV_STEREO3D_VIEW_RIGHT
Frame contains only the right view.
Definition: stereo3d.h:163
MOVContext::advanced_editlist_autodisabled
int advanced_editlist_autodisabled
Definition: isom.h:351
avio_size
int64_t avio_size(AVIOContext *s)
Get the filesize.
Definition: aviobuf.c:326
av_strlcatf
size_t av_strlcatf(char *dst, size_t size, const char *fmt,...)
Definition: avstring.c:103
mov_read_stco
static int mov_read_stco(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2712
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:7334
FFIOContext
Definition: avio_internal.h:28
AV_PKT_FLAG_KEY
#define AV_PKT_FLAG_KEY
The packet contains a keyframe.
Definition: packet.h:650
init_get_bits
static int init_get_bits(GetBitContext *s, const uint8_t *buffer, int bit_size)
Initialize GetBitContext.
Definition: get_bits.h:517
MOVStreamContext::aes_ctr
struct AVAESCTR * aes_ctr
Definition: isom.h:282
cenc_filter
static int cenc_filter(MOVContext *mov, AVStream *st, MOVStreamContext *sc, AVPacket *pkt, int current_index)
Definition: mov.c:8673
mov_read_sdtp
static int mov_read_sdtp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:3792
mov_read_jp2h
static int mov_read_jp2h(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2321
AV_STEREO3D_UNSPEC
@ AV_STEREO3D_UNSPEC
Video is stereoscopic but the packing is unspecified.
Definition: stereo3d.h:143
AVIndexEntry
Definition: avformat.h:601
AV_WB64
#define AV_WB64(p, v)
Definition: intreadwrite.h:429
AVStreamGroupTileGrid::offsets
struct AVStreamGroupTileGrid::@453 * offsets
An nb_tiles sized array of offsets in pixels from the topleft edge of the canvas, indicating where ea...
MOVStreamContext::dv_audio_container
int dv_audio_container
Definition: isom.h:225
AV_CODEC_ID_AMR_WB
@ AV_CODEC_ID_AMR_WB
Definition: codec_id.h:434
mov_read_tfhd
static int mov_read_tfhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5813
AV_CODEC_ID_BIN_DATA
@ AV_CODEC_ID_BIN_DATA
Definition: codec_id.h:606
OPUS_SEEK_PREROLL_MS
#define OPUS_SEEK_PREROLL_MS
Definition: oggparseopus.c:36
AV_CODEC_ID_H261
@ AV_CODEC_ID_H261
Definition: codec_id.h:53
IAMFMixPresentation::cmix
const AVIAMFMixPresentation * cmix
Definition: iamf.h:108
MOVContext::decryption_default_key
uint8_t * decryption_default_key
Definition: isom.h:377
mov_read_wide
static int mov_read_wide(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6418
AVINDEX_KEYFRAME
#define AVINDEX_KEYFRAME
Definition: avformat.h:609
AV_FIELD_BT
@ AV_FIELD_BT
Bottom coded first, top displayed first.
Definition: defs.h:217
MOVStreamContext::stsd_count
int stsd_count
Definition: isom.h:263
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:205
ff_get_extradata
int ff_get_extradata(void *logctx, AVCodecParameters *par, AVIOContext *pb, int size)
Allocate extradata with additional AV_INPUT_BUFFER_PADDING_SIZE at end which is always set to 0 and f...
Definition: demux_utils.c:340
mov_add_tref_id
static int mov_add_tref_id(MovTref *tag, uint32_t id)
Definition: mov.c:2583
AV_PKT_DATA_DOVI_CONF
@ AV_PKT_DATA_DOVI_CONF
DOVI configuration ref: dolby-vision-bitstreams-within-the-iso-base-media-file-format-v2....
Definition: packet.h:280
AVStereo3D::horizontal_field_of_view
AVRational horizontal_field_of_view
Horizontal field of view, in degrees.
Definition: stereo3d.h:239
skip_bits
static void skip_bits(GetBitContext *s, int n)
Definition: get_bits.h:383
AVCodecParameters::color_primaries
enum AVColorPrimaries color_primaries
Definition: codec_par.h:190
AVEncryptionInfo::scheme
uint32_t scheme
The fourcc encryption scheme, in big-endian byte order.
Definition: encryption_info.h:45
MOVStreamContext::stsc_count
unsigned int stsc_count
Definition: isom.h:199
MOVStreamContext::has_palette
int has_palette
Definition: isom.h:239
AVPROBE_SCORE_MAX
#define AVPROBE_SCORE_MAX
maximum score
Definition: avformat.h:464
AV_STEREO3D_SIDEBYSIDE
@ AV_STEREO3D_SIDEBYSIDE
Views are next to each other.
Definition: stereo3d.h:64
MOVIndexRange::start
int64_t start
Definition: isom.h:175
AVPacketSideData::size
size_t size
Definition: packet.h:426
get_bits
static unsigned int get_bits(GetBitContext *s, int n)
Read 1-25 bits.
Definition: get_bits.h:337
ff_remove_stream
void ff_remove_stream(AVFormatContext *s, AVStream *st)
Remove a stream from its AVFormatContext and free it.
Definition: avformat.c:120
OFFSET
#define OFFSET(x)
Definition: mov.c:12141
HEIFGrid::tile_item_list
HEIFItem ** tile_item_list
Definition: isom.h:319
set_icc_profile_from_item
static int set_icc_profile_from_item(AVPacketSideData **coded_side_data, int *nb_coded_side_data, const HEIFItem *item)
Definition: mov.c:10546
AV_FIELD_TT
@ AV_FIELD_TT
Top coded_first, top displayed first.
Definition: defs.h:214
AV_STEREO3D_VIEW_PACKED
@ AV_STEREO3D_VIEW_PACKED
Frame contains two packed views.
Definition: stereo3d.h:153
AV_SPHERICAL_PARAMETRIC_IMMERSIVE
@ AV_SPHERICAL_PARAMETRIC_IMMERSIVE
Parametric Immersive projection (Apple).
Definition: spherical.h:90
MOVStreamContext::nb_frames_for_fps
int nb_frames_for_fps
Definition: isom.h:256
avpriv_dv_produce_packet
int avpriv_dv_produce_packet(DVDemuxContext *c, AVPacket *pkt, uint8_t *buf, int buf_size, int64_t pos)
Definition: dv.c:738
avpriv_set_pts_info
void avpriv_set_pts_info(AVStream *st, int pts_wrap_bits, unsigned int pts_num, unsigned int pts_den)
Set the time base and wrapping info for a given stream.
Definition: avformat.c:830
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:1557
AV_OPT_TYPE_BINARY
@ AV_OPT_TYPE_BINARY
Underlying C type is a uint8_t* that is either NULL or points to an array allocated with the av_mallo...
Definition: opt.h:285
av_color_space_name
const char * av_color_space_name(enum AVColorSpace space)
Definition: pixdesc.c:3856
av_packet_add_side_data
int av_packet_add_side_data(AVPacket *pkt, enum AVPacketSideDataType type, uint8_t *data, size_t size)
Wrap an existing array as a packet side data.
Definition: packet.c:197
MOVStreamContext::mastering
AVMasteringDisplayMetadata * mastering
Definition: isom.h:271
AV_CODEC_ID_SPEEX
@ AV_CODEC_ID_SPEEX
Definition: codec_id.h:487
AV_FOURCC_MAX_STRING_SIZE
#define AV_FOURCC_MAX_STRING_SIZE
Definition: avutil.h:321
AV_PKT_DATA_PALETTE
@ AV_PKT_DATA_PALETTE
An AV_PKT_DATA_PALETTE side data packet contains exactly AVPALETTE_SIZE bytes worth of palette.
Definition: packet.h:47
mov_find_tref_id
static int mov_find_tref_id(const MovTref *tag, uint32_t id)
Definition: mov.c:2574
ffstream
static av_always_inline FFStream * ffstream(AVStream *st)
Definition: internal.h:358
MOVFragmentIndexItem::current
int current
Definition: isom.h:161
mov_add_tref_tag
static MovTref * mov_add_tref_tag(MOVStreamContext *sc, uint32_t name)
Definition: mov.c:2609
AVFMT_SEEK_TO_PTS
#define AVFMT_SEEK_TO_PTS
Seeking is based on PTS.
Definition: avformat.h:501
AV_CODEC_ID_PCM_S16BE
@ AV_CODEC_ID_PCM_S16BE
Definition: codec_id.h:331
mov_read_mdhd
static int mov_read_mdhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1925
mov_read_ctts
static int mov_read_ctts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:3841
MOVTrackExt
Definition: isom.h:119
MOV_FRAG_SAMPLE_FLAG_IS_NON_SYNC
#define MOV_FRAG_SAMPLE_FLAG_IS_NON_SYNC
Definition: isom.h:424
mov_read_aclr
static int mov_read_aclr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2398
AVSEEK_FLAG_ANY
#define AVSEEK_FLAG_ANY
seek to any frame, even non-keyframes
Definition: avformat.h:2575
av_int2float
static av_always_inline float av_int2float(uint32_t i)
Reinterpret a 32-bit integer as a float.
Definition: intfloat.h:40
MOVFragment::found_tfhd
int found_tfhd
Definition: isom.h:108
AVStreamGroupTileGrid
AVStreamGroupTileGrid holds information on how to combine several independent images on a single canv...
Definition: avformat.h:954
FF_DVDCLUT_CLUT_SIZE
#define FF_DVDCLUT_CLUT_SIZE
Definition: dvdclut.h:29
AV_STEREO3D_2D
@ AV_STEREO3D_2D
Video is not stereoscopic (and metadata has to be there).
Definition: stereo3d.h:52
read_seek
static int read_seek(AVFormatContext *ctx, int stream_index, int64_t timestamp, int flags)
Definition: libcdio.c:151
HEIFItem::item_id
int item_id
Definition: isom.h:303
av_shrink_packet
void av_shrink_packet(AVPacket *pkt, int size)
Reduce packet size, correctly zeroing padding.
Definition: packet.c:113
timecode.h
get_current_frag_stream_info
static MOVFragmentStreamInfo * get_current_frag_stream_info(MOVFragmentIndex *frag_index)
Definition: mov.c:1676
GetBitContext
Definition: get_bits.h:109
MOVStreamContext::mastering_size
size_t mastering_size
Definition: isom.h:272
AVStreamGroupTileGrid::coded_width
int coded_width
Width of the canvas.
Definition: avformat.h:969
av_iamf_audio_element_free
void av_iamf_audio_element_free(AVIAMFAudioElement **paudio_element)
Free an AVIAMFAudioElement and all its contents.
Definition: iamf.c:338
FFStream::index_entries_allocated_size
unsigned int index_entries_allocated_size
Definition: internal.h:187
read_close
static av_cold int read_close(AVFormatContext *ctx)
Definition: libcdio.c:143
mov_read_amve
static int mov_read_amve(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6794
mov_read_enda
static int mov_read_enda(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2039
mov_read_chap
static int mov_read_chap(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5860
MOVParseTableEntry
Definition: mov.c:83
avio_tell
static av_always_inline int64_t avio_tell(AVIOContext *s)
ftell() equivalent for AVIOContext.
Definition: avio.h:494
av_exif_free
void av_exif_free(AVExifMetadata *ifd)
Frees all resources associated with the given EXIF metadata struct.
Definition: exif.c:659
MOV_TRUN_SAMPLE_DURATION
#define MOV_TRUN_SAMPLE_DURATION
Definition: isom.h:418
val
static double val(void *priv, double ch)
Definition: aeval.c:77
set_display_matrix_from_item
static int set_display_matrix_from_item(AVPacketSideData **coded_side_data, int *nb_coded_side_data, const HEIFItem *item)
Definition: mov.c:10560
type
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf type
Definition: writing_filters.txt:86
MOVContext
Definition: isom.h:325
AV_DISPOSITION_TIMED_THUMBNAILS
#define AV_DISPOSITION_TIMED_THUMBNAILS
The stream is sparse, and contains thumbnail images, often corresponding to chapter markers.
Definition: avformat.h:678
AVStreamGroupTileGrid::coded_height
int coded_height
Width of the canvas.
Definition: avformat.h:975
pts
static int64_t pts
Definition: transcode_aac.c:649
MOVStreamContext::v_spacing
int v_spacing
pasp vSpacing
Definition: isom.h:236
AVEncryptionInfo::iv
uint8_t * iv
The initialization vector.
Definition: encryption_info.h:71
AV_CODEC_ID_MP3
@ AV_CODEC_ID_MP3
preferred ID for decoding MPEG audio layer 1, 2 or 3
Definition: codec_id.h:453
AVStream::duration
int64_t duration
Decoding: duration of the stream, in stream time base.
Definition: avformat.h:806
AVAmbientViewingEnvironment::ambient_illuminance
AVRational ambient_illuminance
Environmental illuminance of the ambient viewing environment in lux.
Definition: ambient_viewing_environment.h:40
ss
#define ss(width, name, subs,...)
Definition: cbs_vp9.c:202
MOVStreamContext::width
int width
tkhd width
Definition: isom.h:233
MOVContext::meta_keys
char ** meta_keys
Definition: isom.h:336
get_key_from_kid
static int get_key_from_kid(uint8_t *out, int len, MOVContext *c, AVEncryptionInfo *sample)
Definition: mov.c:8327
av_reduce
int av_reduce(int *dst_num, int *dst_den, int64_t num, int64_t den, int64_t max)
Reduce a fraction.
Definition: rational.c:35
MOVStreamContext::extradata_size
int * extradata_size
Definition: isom.h:261
AVIAMFAudioElement::audio_element_type
enum AVIAMFAudioElementType audio_element_type
Audio element type as defined in section 3.6 of IAMF.
Definition: iamf.h:391
loop
static int loop
Definition: ffplay.c:337
AV_STREAM_GROUP_PARAMS_DOLBY_VISION
@ AV_STREAM_GROUP_PARAMS_DOLBY_VISION
Definition: avformat.h:1134
ff_data_to_hex
char * ff_data_to_hex(char *buf, const uint8_t *src, int size, int lowercase)
Write hexadecimal string corresponding to given binary data.
Definition: utils.c:464
update_frag_index
static int update_frag_index(MOVContext *c, int64_t offset)
Definition: mov.c:1793
AV_CODEC_ID_PRORES_RAW
@ AV_CODEC_ID_PRORES_RAW
Definition: codec_id.h:324
AVRational::num
int num
Numerator.
Definition: rational.h:59
av_clip64
#define av_clip64
Definition: common.h:103
MOVStreamContext::keyframes
int * keyframes
Definition: isom.h:215
av_unused
#define av_unused
Definition: attributes.h:164
MOVEncryptionIndex::auxiliary_info_sample_count
size_t auxiliary_info_sample_count
Definition: isom.h:139
AV_FIELD_TB
@ AV_FIELD_TB
Top coded first, bottom displayed first.
Definition: defs.h:216
mov_read_pack
static int mov_read_pack(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6866
AVStream::attached_pic
AVPacket attached_pic
For streams with AV_DISPOSITION_ATTACHED_PIC disposition, this packet will contain the attached pictu...
Definition: avformat.h:845
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:7885
MOV_FRAG_SAMPLE_FLAG_DEPENDS_YES
#define MOV_FRAG_SAMPLE_FLAG_DEPENDS_YES
Definition: isom.h:431
mov_merge_tts_data
static int mov_merge_tts_data(MOVContext *mov, AVStream *st, int flags)
Definition: mov.c:4762
MOVContext::idat_offset
int64_t idat_offset
Definition: isom.h:390
MOV_TRUN_DATA_OFFSET
#define MOV_TRUN_DATA_OFFSET
Definition: isom.h:416
av_encryption_info_clone
AVEncryptionInfo * av_encryption_info_clone(const AVEncryptionInfo *info)
Allocates an AVEncryptionInfo structure with a copy of the given data.
Definition: encryption_info.c:65
av_ambient_viewing_environment_alloc
AVAmbientViewingEnvironment * av_ambient_viewing_environment_alloc(size_t *size)
Allocate an AVAmbientViewingEnvironment structure.
Definition: ambient_viewing_environment.c:31
AV_DICT_DONT_STRDUP_VAL
#define AV_DICT_DONT_STRDUP_VAL
Take ownership of a value that's been allocated with av_malloc() or another memory allocation functio...
Definition: dict.h:79
IAMFAudioElement::element
AVIAMFAudioElement * element
element backs celement iff the AVIAMFAudioElement is owned by this structure.
Definition: iamf.h:95
MOVStreamContext::elst_data
MOVElst * elst_data
Definition: isom.h:205
mov_read_ares
static int mov_read_ares(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2353
mov_read_adrm
static int mov_read_adrm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1431
av_get_bits_per_sample
int av_get_bits_per_sample(enum AVCodecID codec_id)
Return codec bits per sample.
Definition: utils.c:556
AVCodecParameters::color_trc
enum AVColorTransferCharacteristic color_trc
Definition: codec_par.h:191
IAMFContext::audio_elements
IAMFAudioElement ** audio_elements
Definition: iamf.h:131
MOVFragmentIndex::complete
int complete
Definition: isom.h:168
AV_CODEC_ID_PCM_S8
@ AV_CODEC_ID_PCM_S8
Definition: codec_id.h:334
avassert.h
avio_rb32
unsigned int avio_rb32(AVIOContext *s)
Definition: aviobuf.c:764
AV_LOG_TRACE
#define AV_LOG_TRACE
Extremely verbose debugging, useful for libav* development.
Definition: log.h:236
MOVStreamContext::stsc_sample
int stsc_sample
Definition: isom.h:202
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:210
AV_CODEC_ID_MACE3
@ AV_CODEC_ID_MACE3
Definition: codec_id.h:461
MOVTrackExt::track_id
unsigned track_id
Definition: isom.h:120
mov_free_encryption_index
static void mov_free_encryption_index(MOVEncryptionIndex **index)
Definition: mov.c:10277
AV_CH_LOW_FREQUENCY
#define AV_CH_LOW_FREQUENCY
Definition: channel_layout.h:178
MOVEncryptionIndex::auxiliary_offsets
uint64_t * auxiliary_offsets
Absolute seek position.
Definition: isom.h:141
read_packet
static int read_packet(void *opaque, uint8_t *buf, int buf_size)
Definition: avio_read_callback.c:42
AV_FIELD_UNKNOWN
@ AV_FIELD_UNKNOWN
Definition: defs.h:212
MOVStreamContext::dts_shift
int dts_shift
dts shift when ctts is negative
Definition: isom.h:237
av_timecode_init
int av_timecode_init(AVTimecode *tc, AVRational rate, int flags, int frame_start, void *log_ctx)
Init a timecode struct with the passed parameters.
Definition: timecode.c:201
AVCodecParameters::frame_size
int frame_size
Audio frame size, if known.
Definition: codec_par.h:227
mov_read_srat
static int mov_read_srat(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1092
avio_get_str16le
int avio_get_str16le(AVIOContext *pb, int maxlen, char *buf, int buflen)
Read a UTF-16 string from pb and convert it to UTF-8.
mov_metadata_track_or_disc_number
static int mov_metadata_track_or_disc_number(MOVContext *c, AVIOContext *pb, unsigned len, const char *key)
Definition: mov.c:92
av_dict_get
AVDictionaryEntry * av_dict_get(const AVDictionary *m, const char *key, const AVDictionaryEntry *prev, int flags)
Get a dictionary entry with matching key.
Definition: dict.c:60
AES_CTR_KEY_SIZE
#define AES_CTR_KEY_SIZE
Definition: aes_ctr.h:35
MOVStreamContext::stsd_version
int stsd_version
Definition: isom.h:264
mov_parse_exif_item
static int mov_parse_exif_item(AVFormatContext *s, AVPacketSideData **coded_side_data, int *nb_coded_side_data, const HEIFItem *ref)
Definition: mov.c:10745
AV_STREAM_GROUP_PARAMS_IAMF_MIX_PRESENTATION
@ AV_STREAM_GROUP_PARAMS_IAMF_MIX_PRESENTATION
Definition: avformat.h:1130
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:4237
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:466
MOV_MERGE_STTS
#define MOV_MERGE_STTS
Definition: mov.c:4756
MOVStreamContext::iamf_stream_offset
int iamf_stream_offset
Definition: isom.h:290
ff_mov_read_esds
int ff_mov_read_esds(AVFormatContext *fc, AVIOContext *pb)
Definition: mov_esds.c:23
stereo3d.h
AVMasteringDisplayMetadata::white_point
AVRational white_point[2]
CIE 1931 xy chromaticity coords of white point.
Definition: mastering_display_metadata.h:47
intreadwrite.h
mov_read_coll
static int mov_read_coll(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6728
s
#define s(width, name)
Definition: cbs_vp9.c:198
MOVFragmentStreamInfo::encryption_index
MOVEncryptionIndex * encryption_index
Definition: isom.h:154
mov_read_trak
static int mov_read_trak(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5317
IAMFSubStream::audio_substream_id
unsigned int audio_substream_id
Definition: iamf.h:83
MOVContext::fc
AVFormatContext * fc
Definition: isom.h:327
MOV_TFHD_DEFAULT_BASE_IS_MOOF
#define MOV_TFHD_DEFAULT_BASE_IS_MOOF
Definition: isom.h:414
av_new_packet
int av_new_packet(AVPacket *pkt, int size)
Allocate the payload of a packet and initialize its fields with default values.
Definition: packet.c:98
AV_CODEC_ID_BMP
@ AV_CODEC_ID_BMP
Definition: codec_id.h:128
AV_CODEC_ID_EVC
@ AV_CODEC_ID_EVC
Definition: codec_id.h:316
IAMFLayer::substream_count
unsigned int substream_count
Definition: iamf.h:78
MOV_TFHD_DEFAULT_DURATION
#define MOV_TFHD_DEFAULT_DURATION
Definition: isom.h:410
ALAC_EXTRADATA_SIZE
#define ALAC_EXTRADATA_SIZE
DRM_BLOB_SIZE
#define DRM_BLOB_SIZE
Definition: mov.c:1429
MOVStreamContext::sample_offsets_count
int sample_offsets_count
Definition: isom.h:251
MOVCtts::count
unsigned int count
Definition: isom.h:69
MOVStreamContext::drefs
MOVDref * drefs
Definition: isom.h:229
av_realloc_array
void * av_realloc_array(void *ptr, size_t nmemb, size_t size)
Definition: mem.c:217
AVInputFormat::name
const char * name
A comma separated list of short names for the format.
Definition: avformat.h:551
MOVContext::aes_decrypt
struct AVAES * aes_decrypt
Definition: isom.h:376
AVSphericalMapping::bound_top
uint32_t bound_top
Distance from the top edge.
Definition: spherical.h:186
AVMEDIA_TYPE_AUDIO
@ AVMEDIA_TYPE_AUDIO
Definition: avutil.h:201
AV_CODEC_ID_VP9
@ AV_CODEC_ID_VP9
Definition: codec_id.h:217
MOVFragmentIndex::nb_items
int nb_items
Definition: isom.h:170
AVCodecParameters::width
int width
The width of the video frame in pixels.
Definition: codec_par.h:143
MOVTimeToSample
Definition: isom.h:57
AV_CHANNEL_ORDER_UNSPEC
@ AV_CHANNEL_ORDER_UNSPEC
Only the channel count is specified, without any further information about the channel order.
Definition: channel_layout.h:119
AV_CODEC_ID_MP2
@ AV_CODEC_ID_MP2
Definition: codec_id.h:452
HEIFGrid::tile_idx_list
unsigned * tile_idx_list
Definition: isom.h:321
MOV_TRUN_FIRST_SAMPLE_FLAGS
#define MOV_TRUN_FIRST_SAMPLE_FLAGS
Definition: isom.h:417
av_q2d
static double av_q2d(AVRational a)
Convert an AVRational to a double.
Definition: rational.h:104
AVIndexEntry::size
int size
Definition: avformat.h:612
av_channel_layout_from_mask
int av_channel_layout_from_mask(AVChannelLayout *channel_layout, uint64_t mask)
Initialize a native channel layout from a bitmask indicating which channels are present.
Definition: channel_layout.c:253
MOVStreamContext::keyframe_absent
int keyframe_absent
Definition: isom.h:213
info
MIPS optimizations info
Definition: mips.txt:2
MOVStts::duration
unsigned int duration
Definition: isom.h:65
fc
#define fc(width, name, range_min, range_max)
Definition: cbs_av1.c:494
MOVStreamContext::coll_size
size_t coll_size
Definition: isom.h:274
tile_rows
int tile_rows
Definition: h265_levels.c:217
mov_estimate_video_delay
static void mov_estimate_video_delay(MOVContext *c, AVStream *st)
Definition: mov.c:4266
AVIndexEntry::timestamp
int64_t timestamp
Timestamp in AVStream.time_base units, preferably the time from which on correctly decoded frames are...
Definition: avformat.h:603
av_assert0
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:42
MOVStreamContext::min_corrected_pts
int64_t min_corrected_pts
minimum Composition time shown by the edits excluding empty edits.
Definition: isom.h:218
ffio_read_leb
unsigned int ffio_read_leb(AVIOContext *s)
Read a unsigned integer coded as a variable number of up to eight little-endian bytes,...
Definition: aviobuf.c:930
tile_cols
int tile_cols
Definition: av1_levels.c:73
MOVStreamContext::sdtp_count
unsigned int sdtp_count
Definition: isom.h:194
dvdclut.h
MOVStreamContext::nb_tref_tags
int nb_tref_tags
Definition: isom.h:231
mov_read_lhvc
static int mov_read_lhvc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:8878
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:425
AVDOVIDecoderConfigurationRecord::dv_profile
uint8_t dv_profile
Definition: dovi_meta.h:58
ctx
static AVFormatContext * ctx
Definition: movenc.c:49
hevc.h
get_bits.h
limits.h
mov_read_sidx
static int mov_read_sidx(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6279
AV_PKT_DATA_STEREO3D
@ AV_PKT_DATA_STEREO3D
This side data should be associated with a video stream and contains Stereoscopic 3D information in f...
Definition: packet.h:111
av_rescale_q
int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq)
Rescale a 64-bit integer by 2 rational numbers.
Definition: mathematics.c:142
ff_iamfdec_read_descriptors
int ff_iamfdec_read_descriptors(IAMFContext *c, AVIOContext *pb, int max_size, void *log_ctx)
Definition: iamf_parse.c:1262
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:11500
ff_mov_read_chnl
int ff_mov_read_chnl(AVFormatContext *s, AVIOContext *pb, AVStream *st, int version)
Read 'chnl' tag from the input stream.
Definition: mov_chan.c:768
AV_CODEC_ID_TARGA_Y216
@ AV_CODEC_ID_TARGA_Y216
Definition: codec_id.h:253
AVIndexEntry::min_distance
int min_distance
Minimum distance between this and the previous keyframe, used to avoid unneeded searching.
Definition: avformat.h:613
mov_read_dvcc_dvvc
static int mov_read_dvcc_dvvc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:8831
MOVParseTableEntry::parse
int(* parse)(MOVContext *ctx, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:85
codec_id
enum AVCodecID codec_id
Definition: vaapi_decode.c:410
MOVStreamContext::tref_tags
MovTref * tref_tags
Definition: isom.h:232
AV_CODEC_ID_SVQ3
@ AV_CODEC_ID_SVQ3
Definition: codec_id.h:73
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:88
MOVStreamContext::sdtp_data
uint8_t * sdtp_data
Definition: isom.h:195
color_range
color_range
Definition: vf_selectivecolor.c:43
AVMEDIA_TYPE_DATA
@ AVMEDIA_TYPE_DATA
Opaque data information usually continuous.
Definition: avutil.h:202
mov_read_udta_string
static int mov_read_udta_string(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:346
av_mallocz
#define av_mallocz(s)
Definition: tableprint_vlc.h:31
mov_read_stss
static int mov_read_stss(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:3524
mov_read_ddts
static int mov_read_ddts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1169
mov_read_uuid
static int mov_read_uuid(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:7488
AVCOL_PRI_UNSPECIFIED
@ AVCOL_PRI_UNSPECIFIED
Definition: pixfmt.h:639
MOVTrackExt::duration
unsigned duration
Definition: isom.h:122
AV_CODEC_ID_H264
@ AV_CODEC_ID_H264
Definition: codec_id.h:77
AVStreamGroup::layered_video
struct AVStreamGroupLayeredVideo * layered_video
Definition: avformat.h:1176
av_content_light_metadata_alloc
AVContentLightMetadata * av_content_light_metadata_alloc(size_t *size)
Allocate an AVContentLightMetadata structure and set its fields to default values.
Definition: mastering_display_metadata.c:73
tmp
static uint8_t tmp[40]
Definition: aes_ctr.c:52
av_sha_final
void av_sha_final(AVSHA *ctx, uint8_t *digest)
Finish hashing and output digest value.
Definition: sha.c:347
MOVStreamContext::current_sample
int current_sample
Definition: isom.h:219
MOVFragmentStreamInfo::sidx_pts
int64_t sidx_pts
Definition: isom.h:147
MAX_REORDER_DELAY
#define MAX_REORDER_DELAY
Definition: mov.c:4265
MOVFragmentIndex::current
int current
Definition: isom.h:169
MOVEncryptionIndex::encrypted_samples
AVEncryptionInfo ** encrypted_samples
Definition: isom.h:136
mov_read_close
static int mov_read_close(AVFormatContext *s)
Definition: mov.c:10354
ff_hex_to_data
int ff_hex_to_data(uint8_t *data, const char *p)
Parse a string of hexadecimal strings.
Definition: utils.c:485
MOVAtom::size
int64_t size
Definition: isom.h:102
MOVStreamContext::refcount
int refcount
Definition: isom.h:181
AVStereo3D::flags
int flags
Additional information about the frame packing.
Definition: stereo3d.h:212
ff_mov_get_lpcm_codec_id
static enum AVCodecID ff_mov_get_lpcm_codec_id(int bps, int flags)
Compute codec id for 'lpcm' tag.
Definition: isom.h:472
AV_CODEC_ID_PNG
@ AV_CODEC_ID_PNG
Definition: codec_id.h:111
AV_CODEC_ID_AVUI
@ AV_CODEC_ID_AVUI
Definition: codec_id.h:252
if
if(ret)
Definition: filter_design.txt:179
mov_read_cmov
static int mov_read_cmov(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6438
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:7713
FFStream::need_parsing
enum AVStreamParseType need_parsing
Definition: internal.h:314
MOVStreamContext::keyframe_count
unsigned int keyframe_count
Definition: isom.h:214
mov_read_SAND
static int mov_read_SAND(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:9108
IAMFAudioElement::audio_element_id
unsigned int audio_element_id
Definition: iamf.h:96
AVDISCARD_ALL
@ AVDISCARD_ALL
discard all
Definition: defs.h:232
AVFormatContext
Format I/O context.
Definition: avformat.h:1314
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:3672
MOVStreamContext::index_ranges
MOVIndexRange * index_ranges
Definition: isom.h:221
fail
#define fail
Definition: test.h:478
DDTS_SIZE
#define DDTS_SIZE
internal.h
MOVStreamContext::cenc
struct MOVStreamContext::@485 cenc
MOVTrackExt::stsd_id
unsigned stsd_id
Definition: isom.h:121
find_prev_closest_index
static int find_prev_closest_index(AVStream *st, AVIndexEntry *e_old, int nb_old, MOVTimeToSample *tts_data, int64_t tts_count, int64_t timestamp_pts, int flag, int64_t *index, int64_t *tts_index, int64_t *tts_sample)
Find the closest previous frame to the timestamp_pts, in e_old index entries.
Definition: mov.c:4088
set_frag_stream
static void set_frag_stream(MOVFragmentIndex *frag_index, int id)
Definition: mov.c:1656
mov_read_free
static int mov_read_free(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:7593
mov_realloc_extradata
static int mov_realloc_extradata(AVCodecParameters *par, MOVAtom atom)
Definition: mov.c:2248
AVStream::codecpar
AVCodecParameters * codecpar
Codec parameters associated with this stream.
Definition: avformat.h:770
LIBAVUTIL_VERSION_INT
#define LIBAVUTIL_VERSION_INT
Definition: version.h:85
av_exif_get_tag_id
int32_t av_exif_get_tag_id(const char *name)
Retrieves the tag ID associated with the provided tag string name.
Definition: exif.c:244
AV_PKT_DATA_EXIF
@ AV_PKT_DATA_EXIF
Extensible image file format metadata.
Definition: packet.h:369
AVSEEK_FLAG_BACKWARD
#define AVSEEK_FLAG_BACKWARD
Definition: avformat.h:2573
aes.h
AVClass
Describe the class of an AVClass context structure.
Definition: log.h:76
MOVStreamContext::tts_sample
int tts_sample
Definition: isom.h:208
avpriv_dv_get_packet
int avpriv_dv_get_packet(DVDemuxContext *c, AVPacket *pkt)
Definition: dv.c:733
MOVContext::ignore_editlist
int ignore_editlist
Definition: isom.h:349
result
and forward the result(frame or status change) to the corresponding input. If nothing is possible
fabs
static __device__ float fabs(float a)
Definition: cuda_runtime.h:182
metadata
Stream codec metadata
Definition: ogg-flac-chained-meta.txt:2
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:786
NULL
#define NULL
Definition: coverity.c:32
sha.h
truehd_layout
static uint64_t truehd_layout(int chanmap)
Definition: mlp_parse.h:105
MOVDref
Definition: isom.h:85
AVERROR_PATCHWELCOME
#define AVERROR_PATCHWELCOME
Not yet implemented in FFmpeg, patches welcome.
Definition: error.h:64
format
New swscale design to change SwsGraph is what coordinates multiple passes These can include cascaded scaling error diffusion and so on Or we could have separate passes for the vertical and horizontal scaling In between each SwsPass lies a fully allocated image buffer Graph passes may have different levels of e g we can have a single threaded error diffusion pass following a multi threaded scaling pass SwsGraph is internally recreated whenever the image format
Definition: swscale-v2.txt:14
av_buffer_unref
void av_buffer_unref(AVBufferRef **buf)
Free a given reference and automatically free the buffer if there are no more references to it.
Definition: buffer.c:139
AV_CODEC_ID_AV1
@ AV_CODEC_ID_AV1
Definition: codec_id.h:275
MOVStreamContext::ctts_count
unsigned int ctts_count
Definition: isom.h:196
AVEncryptionInitInfo
This describes info used to initialize an encryption key system.
Definition: encryption_info.h:88
isom.h
MP4TrackKindValueMapping::disposition
int disposition
Definition: isom.h:488
mov_read_ftyp
static int mov_read_ftyp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1571
AV_WB16
#define AV_WB16(p, v)
Definition: intreadwrite.h:401
MOVContext::nb_heif_grid
int nb_heif_grid
Definition: isom.h:389
read_image_grid
static int read_image_grid(AVFormatContext *s, const HEIFGrid *grid, AVStreamGroupTileGrid *tile_grid)
Definition: mov.c:10581
MOVElst
Definition: isom.h:79
av_aes_ctr_alloc
struct AVAESCTR * av_aes_ctr_alloc(void)
Allocate an AVAESCTR context.
Definition: aes_ctr.c:41
flac_parse_block_header
static av_always_inline void flac_parse_block_header(const uint8_t *block_header, int *last, int *type, int *size)
Parse the metadata block parameters from the header.
Definition: flac.h:63
AVStreamGroupTileGrid::coded_side_data
AVPacketSideData * coded_side_data
Additional data associated with the grid.
Definition: avformat.h:1057
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:3922
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:9996
AVPALETTE_SIZE
#define AVPALETTE_SIZE
Definition: pixfmt.h:32
AV_OPT_TYPE_DICT
@ AV_OPT_TYPE_DICT
Underlying C type is AVDictionary*.
Definition: opt.h:289
MOVDref::nlvl_to
int16_t nlvl_to
Definition: isom.h:91
get_eia608_packet
static int get_eia608_packet(AVIOContext *pb, AVPacket *pkt, int src_size)
Definition: mov.c:11597
av_fallthrough
#define av_fallthrough
Definition: attributes.h:67
AV_CODEC_ID_DVD_SUBTITLE
@ AV_CODEC_ID_DVD_SUBTITLE
Definition: codec_id.h:565
AVIndexEntry::flags
int flags
Definition: avformat.h:611
MOVStreamContext::time_offset
int64_t time_offset
time offset of the edit list entries
Definition: isom.h:217
mov_read_smdm
static int mov_read_smdm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6637
av_default_item_name
const char * av_default_item_name(void *ptr)
Return the context name.
Definition: log.c:242
AVStereo3D::horizontal_disparity_adjustment
AVRational horizontal_disparity_adjustment
Relative shift of the left and right images, which changes the zero parallax plane.
Definition: stereo3d.h:234
avio_rb64
uint64_t avio_rb64(AVIOContext *s)
Definition: aviobuf.c:911
av_aes_crypt
void av_aes_crypt(AVAES *a, uint8_t *dst, const uint8_t *src, int count, uint8_t *iv, int decrypt)
Encrypt or decrypt a buffer using a previously initialized context.
Definition: aes.c:171
MOVStreamContext::current_index_range
MOVIndexRange * current_index_range
Definition: isom.h:222
mov_open_dref
static int mov_open_dref(MOVContext *c, AVIOContext **pb, const char *src, MOVDref *ref)
Definition: mov.c:5170
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:452
av_aes_alloc
struct AVAES * av_aes_alloc(void)
Allocate an AVAES context.
Definition: aes.c:37
TAG_IS_AVCI
#define TAG_IS_AVCI(tag)
Definition: isom.h:442
IAMFSubStream
Definition: iamf.h:82
IAMFAudioElement::layers
IAMFLayer * layers
Definition: iamf.h:103
mov_read_schm
static int mov_read_schm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:8185
AVStream::metadata
AVDictionary * metadata
Definition: avformat.h:827
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:3790
FF_MOV_FLAG_MFRA_DTS
#define FF_MOV_FLAG_MFRA_DTS
Definition: isom.h:465
MOV_SAMPLE_DEPENDENCY_NO
#define MOV_SAMPLE_DEPENDENCY_NO
Definition: isom.h:440
AV_DICT_DONT_OVERWRITE
#define AV_DICT_DONT_OVERWRITE
Don't overwrite existing entries.
Definition: dict.h:81
ff_codec_movvideo_tags
const AVCodecTag ff_codec_movvideo_tags[]
Definition: isom_tags.c:29
attributes.h
MOVStreamContext::tts_index
int tts_index
Definition: isom.h:207
AV_DISPOSITION_MULTILAYER
#define AV_DISPOSITION_MULTILAYER
The video stream contains multiple layers, e.g.
Definition: avformat.h:717
MOVFragmentStreamInfo::index_base
int index_base
Definition: isom.h:152
MOVStreamContext::rap_group
MOVSbgp * rap_group
Definition: isom.h:245
AV_CODEC_ID_QDM2
@ AV_CODEC_ID_QDM2
Definition: codec_id.h:471
mov_read_ilst
static int mov_read_ilst(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5468
MOVTimeToSample::duration
unsigned int duration
Definition: isom.h:59
AV_CH_FRONT_CENTER
#define AV_CH_FRONT_CENTER
Definition: channel_layout.h:177
AVCodecParameters::ch_layout
AVChannelLayout ch_layout
The channel layout and number of channels.
Definition: codec_par.h:207
get_frag_stream_info_from_pkt
static MOVFragmentStreamInfo * get_frag_stream_info_from_pkt(MOVFragmentIndex *frag_index, AVPacket *pkt, int id)
Definition: mov.c:8648
get_sgpd_sync_index
static uint32_t get_sgpd_sync_index(const MOVStreamContext *sc, int nal_unit_type)
Definition: mov.c:4684
mov_read_fiel
static int mov_read_fiel(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2214
parse
static int parse(AVCodecParserContext *s, AVCodecContext *avctx, const uint8_t **poutbuf, int *poutbuf_size, const uint8_t *buf, int buf_size)
Definition: apv_parser.c:92
MOV_MP4_TTML_TAG
#define MOV_MP4_TTML_TAG
Definition: isom.h:483
AV_PKT_DATA_CONTENT_LIGHT_LEVEL
@ AV_PKT_DATA_CONTENT_LIGHT_LEVEL
Content light level (based on CTA-861.3).
Definition: packet.h:232
av_encryption_info_add_side_data
uint8_t * av_encryption_info_add_side_data(const AVEncryptionInfo *info, size_t *size)
Allocates and initializes side data that holds a copy of the given encryption info.
Definition: encryption_info.c:127
MOV_TFHD_BASE_DATA_OFFSET
#define MOV_TFHD_BASE_DATA_OFFSET
Definition: isom.h:408
MOVFragmentStreamInfo::stsd_id
int stsd_id
Definition: isom.h:155
av_exif_remove_entry
int av_exif_remove_entry(void *logctx, AVExifMetadata *ifd, uint16_t id, int flags)
Remove an entry from the provided EXIF metadata struct.
Definition: exif.c:1272
MOVStreamContext::open_key_samples_count
int open_key_samples_count
Definition: isom.h:253
HEIFItem
Definition: isom.h:298
ff_codec_movaudio_tags
const AVCodecTag ff_codec_movaudio_tags[]
Definition: isom_tags.c:306
ff_codec_movdata_tags
const AVCodecTag ff_codec_movdata_tags[]
Definition: isom.c:82
mov_read_wfex
static int mov_read_wfex(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1275
av_stereo3d_alloc_size
AVStereo3D * av_stereo3d_alloc_size(size_t *size)
Allocate an AVStereo3D structure and set its fields to default values.
Definition: stereo3d.c:39
index
int index
Definition: gxfenc.c:90
c
Undefined Behavior In the C some operations are like signed integer dereferencing freed accessing outside allocated Undefined Behavior must not occur in a C it is not safe even if the output of undefined operations is unused The unsafety may seem nit picking but Optimizing compilers have in fact optimized code on the assumption that no undefined Behavior occurs Optimizing code based on wrong assumptions can and has in some cases lead to effects beyond the output of computations The signed integer overflow problem in speed critical code Code which is highly optimized and works with signed integers sometimes has the problem that often the output of the computation does not c
Definition: undefined.txt:32
AVPROBE_SCORE_EXTENSION
#define AVPROBE_SCORE_EXTENSION
score for file extension
Definition: avformat.h:462
MOVSbgp::count
unsigned int count
Definition: isom.h:128
AVCodecParameters::sample_rate
int sample_rate
The number of audio samples per second.
Definition: codec_par.h:213
mov_parse_stsd_subtitle
static void mov_parse_stsd_subtitle(MOVContext *c, AVIOContext *pb, AVStream *st, MOVStreamContext *sc, int64_t size)
Definition: mov.c:3002
cid
uint16_t cid
Definition: mxfenc.c:2335
mov_skip_multiple_stsd
static int mov_skip_multiple_stsd(MOVContext *c, AVIOContext *pb, int codec_tag, int format, int64_t size)
Definition: mov.c:3168
MOVStts
Definition: isom.h:63
AVAudioServiceType
AVAudioServiceType
Definition: defs.h:235
AV_CODEC_ID_MPEG1VIDEO
@ AV_CODEC_ID_MPEG1VIDEO
Definition: codec_id.h:51
AV_CODEC_ID_GSM
@ AV_CODEC_ID_GSM
as in Berlin toast format
Definition: codec_id.h:470
AVStream::nb_frames
int64_t nb_frames
number of frames in this stream if known or 0
Definition: avformat.h:808
AVCodecID
AVCodecID
Identify the syntax and semantics of the bitstream.
Definition: codec_id.h:47
av_packet_side_data_get
const AVPacketSideData * av_packet_side_data_get(const AVPacketSideData *sd, int nb_sd, enum AVPacketSideDataType type)
Get side information from a side data array.
Definition: packet.c:570
AVIAMFSubmixElement::audio_element_id
unsigned int audio_element_id
The id of the Audio Element this submix element references.
Definition: iamf.h:455
AV_CODEC_ID_EAC3
@ AV_CODEC_ID_EAC3
Definition: codec_id.h:492
should_retry
static int should_retry(AVIOContext *pb, int error_code)
Definition: mov.c:11530
avformat_stream_group_add_stream
int avformat_stream_group_add_stream(AVStreamGroup *stg, AVStream *st)
Add an already allocated stream to a stream group.
Definition: options.c:557
AV_PKT_DATA_SPHERICAL
@ AV_PKT_DATA_SPHERICAL
This side data should be associated with a video stream and corresponds to the AVSphericalMapping str...
Definition: packet.h:225
AVCodecParameters::extradata_size
int extradata_size
Size of the extradata content in bytes.
Definition: codec_par.h:75
AVIAMFSubmix
Submix layout as defined in section 3.7 of IAMF.
Definition: iamf.h:559
AV_WB32
#define AV_WB32(p, v)
Definition: intreadwrite.h:415
mov_read_pasp
static int mov_read_pasp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1399
MOVContext::dv_demux
DVDemuxContext * dv_demux
Definition: isom.h:338
AV_CODEC_ID_AAC
@ AV_CODEC_ID_AAC
Definition: codec_id.h:454
AVStereo3D::primary_eye
enum AVStereo3DPrimaryEye primary_eye
Which eye is the primary eye when rendering in 2D.
Definition: stereo3d.h:222
ff_dlog
#define ff_dlog(a,...)
Definition: tableprint_vlc.h:28
color_primaries
static const AVColorPrimariesDesc color_primaries[AVCOL_PRI_NB]
Definition: csp.c:76
mov_read_SA3D
static int mov_read_SA3D(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:9018
mov_read_elst
static int mov_read_elst(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6491
MOVEncryptionIndex::auxiliary_info_default_size
uint8_t auxiliary_info_default_size
Definition: isom.h:140
AV_STREAM_GROUP_PARAMS_TILE_GRID
@ AV_STREAM_GROUP_PARAMS_TILE_GRID
Definition: avformat.h:1131
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:11270
AV_CODEC_ID_QCELP
@ AV_CODEC_ID_QCELP
Definition: codec_id.h:476
mov_read_vdep
static int mov_read_vdep(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2658
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:8423
avio_rl32
unsigned int avio_rl32(AVIOContext *s)
Definition: aviobuf.c:733
AVDISCARD_NONKEY
@ AVDISCARD_NONKEY
discard all frames except keyframes
Definition: defs.h:231
MOVFragment::flags
unsigned flags
Definition: isom.h:116
f
f
Definition: af_crystalizer.c:122
AVIOContext
Bytestream IO Context.
Definition: avio.h:160
AV_CODEC_ID_PCM_S24LE
@ AV_CODEC_ID_PCM_S24LE
Definition: codec_id.h:342
mov_read_wave
static int mov_read_wave(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2446
AV_SPHERICAL_CUBEMAP
@ AV_SPHERICAL_CUBEMAP
Video frame is split into 6 faces of a cube, and arranged on a 3x2 layout.
Definition: spherical.h:61
avio_rb24
unsigned int avio_rb24(AVIOContext *s)
Definition: aviobuf.c:757
ff_mpa_check_header
static int ff_mpa_check_header(uint32_t header)
Definition: mpegaudiodecheader.h:62
MOVStreamContext::aes_ctx
struct AVAES * aes_ctx
Definition: isom.h:283
cens_scheme_decrypt
static int cens_scheme_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
Definition: mov.c:8489
MOVContext::handbrake_version
int handbrake_version
Definition: isom.h:345
mov_free_stream_context
static void mov_free_stream_context(AVFormatContext *s, AVStream *st)
Definition: mov.c:10289
AVPacket::size
int size
Definition: packet.h:604
NULL_IF_CONFIG_SMALL
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
Definition: internal.h:88
AV_STREAM_GROUP_PARAMS_TREF
@ AV_STREAM_GROUP_PARAMS_TREF
Definition: avformat.h:1133
ff_codec_get_id
enum AVCodecID ff_codec_get_id(const AVCodecTag *tags, unsigned int tag)
Definition: utils.c:143
avformat_alloc_context
AVFormatContext * avformat_alloc_context(void)
Allocate an AVFormatContext.
Definition: options.c:164
MOVFragmentIndexItem
Definition: isom.h:158
get_current_encryption_info
static int get_current_encryption_info(MOVContext *c, MOVEncryptionIndex **encryption_index, MOVStreamContext **sc)
Gets the current encryption info and associated current stream context.
Definition: mov.c:7662
AVIOContext::seekable
int seekable
A combination of AVIO_SEEKABLE_ flags or 0 when the stream is not seekable.
Definition: avio.h:261
av_aes_ctr_init
int av_aes_ctr_init(struct AVAESCTR *a, const uint8_t *key)
Initialize an AVAESCTR context.
Definition: aes_ctr.c:74
height
#define height
Definition: dsp.h:89
qtpalette.h
av_bprint_finalize
int av_bprint_finalize(AVBPrint *buf, char **ret_str)
Finalize a print buffer.
Definition: bprint.c:235
AVChannelLayout
An AVChannelLayout holds information about the channel layout of audio data.
Definition: channel_layout.h:319
FFStream
Definition: internal.h:128
mov_read_dref
static int mov_read_dref(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:653
mov_current_sample_dec
static void mov_current_sample_dec(MOVStreamContext *sc)
Definition: mov.c:4334
AVSphericalMapping::bound_right
uint32_t bound_right
Distance from the right edge.
Definition: spherical.h:187
MOVStsc::first
int first
Definition: isom.h:74
dst
uint8_t ptrdiff_t const uint8_t ptrdiff_t int intptr_t intptr_t int int16_t * dst
Definition: dsp.h:87
FFStream::last_discard_sample
int64_t last_discard_sample
The sample after last sample that is intended to be discarded after first_discard_sample.
Definition: internal.h:232
av_bswap32
#define av_bswap32
Definition: bswap.h:47
i
#define i(width, name, range_min, range_max)
Definition: cbs_h264.c:63
MOVStreamContext::stsz_sample_size
unsigned int stsz_sample_size
always contains sample size from stsz atom
Definition: isom.h:210
FF_MOV_FLAG_MFRA_AUTO
#define FF_MOV_FLAG_MFRA_AUTO
Definition: isom.h:464
ff_dict_set_timestamp
int ff_dict_set_timestamp(AVDictionary **dict, const char *key, int64_t timestamp)
Set a dictionary value to an ISO-8601 compliant timestamp string.
Definition: utils.c:616
av_err2str
#define av_err2str(errnum)
Convenience macro, the return value should be used only directly in function arguments but never stan...
Definition: error.h:122
for
for(k=2;k<=8;++k)
Definition: h264pred_template.c:424
MOVStreamContext::sgpd_sync
uint8_t * sgpd_sync
Definition: isom.h:248
start_time
static int64_t start_time
Definition: ffplay.c:328
uuid.h
ff_dvdclut_palette_extradata_cat
int ff_dvdclut_palette_extradata_cat(const uint32_t *clut, const size_t clut_size, AVCodecParameters *par)
Definition: dvdclut.c:28
mov_read_trun
static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5946
MOVStreamContext::stereo3d_size
size_t stereo3d_size
Definition: isom.h:268
avio_get_str
int avio_get_str(AVIOContext *pb, int maxlen, char *buf, int buflen)
Read a string from pb into buf.
Definition: aviobuf.c:869
mov_read_iprp
static int mov_read_iprp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:9631
av_sha_update
void av_sha_update(struct AVSHA *ctx, const uint8_t *data, size_t len)
Update hash value.
Definition: sha.c:315
sample
#define sample
Definition: flacdsp_template.c:44
hypot
static av_const double hypot(double x, double y)
Definition: libm.h:368
AV_CODEC_ID_H263
@ AV_CODEC_ID_H263
Definition: codec_id.h:54
MOV_TFHD_STSD_ID
#define MOV_TFHD_STSD_ID
Definition: isom.h:409
size
int size
Definition: twinvq_data.h:10344
mov_read_chan
static int mov_read_chan(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1222
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:3382
AV_WL32A
#define AV_WL32A(p, v)
Definition: intreadwrite.h:571
av_reallocp
int av_reallocp(void *ptr, size_t size)
Allocate, reallocate, or free a block of memory through a pointer to a pointer.
Definition: mem.c:188
ff_get_qtpalette
int ff_get_qtpalette(int codec_id, AVIOContext *pb, uint32_t *palette)
Retrieve the palette (or "color table" in QuickTime terms), either from the video sample description,...
Definition: qtpalette.c:323
AV_NOPTS_VALUE
#define AV_NOPTS_VALUE
Undefined timestamp value.
Definition: avutil.h:247
MKBETAG
#define MKBETAG(a, b, c, d)
Definition: macros.h:56
AV_CODEC_ID_QDMC
@ AV_CODEC_ID_QDMC
Definition: codec_id.h:502
av_fourcc_make_string
char * av_fourcc_make_string(char *buf, uint32_t fourcc)
Fill the provided buffer with a string containing a FourCC (four-character code) representation.
Definition: utils.c:54
AV_RB32
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_WL16 uint64_t_TMPL AV_WB64 unsigned int_TMPL AV_RB32
Definition: bytestream.h:96
avpriv_report_missing_feature
void avpriv_report_missing_feature(void *avc, const char *msg,...) av_printf_format(2
Log a generic warning message about a missing feature.
av_aes_ctr_set_full_iv
void av_aes_ctr_set_full_iv(struct AVAESCTR *a, const uint8_t *iv)
Forcefully change the "full" 16-byte iv, including the counter.
Definition: aes_ctr.c:53
AVStreamGroup::iamf_audio_element
struct AVIAMFAudioElement * iamf_audio_element
Definition: avformat.h:1173
MOVStreamContext::coll
AVContentLightMetadata * coll
Definition: isom.h:273
aes_ctr.h
ff_format_io_close
int ff_format_io_close(AVFormatContext *s, AVIOContext **pb)
Definition: avformat.c:952
mov_parse_heif_items
static int mov_parse_heif_items(AVFormatContext *s)
Definition: mov.c:10955
HEIFItem::is_idat_relative
int is_idat_relative
Definition: isom.h:312
IAMFContext
Definition: iamf.h:128
add_index_entry
static int64_t add_index_entry(AVStream *st, int64_t pos, int64_t timestamp, int size, int distance, int flags)
Add index entry with the given values, to the end of ffstream(st)->index_entries.
Definition: mov.c:4184
MOVDref::path
char * path
Definition: isom.h:87
FLAC_METADATA_TYPE_STREAMINFO
@ FLAC_METADATA_TYPE_STREAMINFO
Definition: flac.h:46
mov_current_sample_inc
static void mov_current_sample_inc(MOVStreamContext *sc)
Definition: mov.c:4322
AVStream::sample_aspect_ratio
AVRational sample_aspect_ratio
sample aspect ratio (0 if unknown)
Definition: avformat.h:825
FFInputFormat::p
AVInputFormat p
The public AVInputFormat.
Definition: demux.h:70
dovi_isom.h
AVPacket::dts
int64_t dts
Decompression timestamp in AVStream->time_base units; the time at which the packet is decompressed.
Definition: packet.h:602
mov_read_vexu_proj
static int mov_read_vexu_proj(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:7084
fix_timescale
static void fix_timescale(MOVContext *c, MOVStreamContext *sc)
Definition: mov.c:5242
avio_r8
int avio_r8(AVIOContext *s)
Definition: aviobuf.c:606
IAMFAudioElement::substreams
IAMFSubStream * substreams
Definition: iamf.h:98
AVSphericalMapping::padding
uint32_t padding
Number of pixels to pad from the edge of each cube face.
Definition: spherical.h:200
a
The reader does not expect b to be semantically here and if the code is changed by maybe adding a a division or other the signedness will almost certainly be mistaken To avoid this confusion a new type was SUINT is the C unsigned type but it holds a signed int to use the same example SUINT a
Definition: undefined.txt:41
av_channel_layout_retype
int av_channel_layout_retype(AVChannelLayout *channel_layout, enum AVChannelOrder order, int flags)
Change the AVChannelOrder of a channel layout.
Definition: channel_layout.c:887
mov_parse_dovi_streams
static int mov_parse_dovi_streams(AVFormatContext *s)
Definition: mov.c:11159
av_reallocp_array
int av_reallocp_array(void *ptr, size_t nmemb, size_t size)
Allocate, reallocate an array through a pointer to a pointer.
Definition: mem.c:225
AVIAMFAudioElement
Information on how to combine one or more audio streams, as defined in section 3.6 of IAMF.
Definition: iamf.h:359
AV_PRIMARY_EYE_NONE
@ AV_PRIMARY_EYE_NONE
Neither eye.
Definition: stereo3d.h:178
mov_read_default
static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:9874
AV_TIMECODE_FLAG_24HOURSMAX
@ AV_TIMECODE_FLAG_24HOURSMAX
timecode wraps after 24 hours
Definition: timecode.h:37
mov_find_reference_track
static AVStream * mov_find_reference_track(AVFormatContext *s, AVStream *st, uint32_t *tref_id, int nb_tref_id, int first_index)
Definition: mov.c:11090
MOV_MP4_FPCM_TAG
#define MOV_MP4_FPCM_TAG
Definition: isom.h:484
ffio_ensure_seekback
int ffio_ensure_seekback(AVIOContext *s, int64_t buf_size)
Ensures that the requested seekback buffer size will be available.
Definition: aviobuf.c:1026
AVStreamGroupTileGrid::nb_tiles
unsigned int nb_tiles
Amount of tiles in the grid.
Definition: avformat.h:962
av_packet_side_data_add
AVPacketSideData * av_packet_side_data_add(AVPacketSideData **psd, int *pnb_sd, enum AVPacketSideDataType type, void *data, size_t size, int flags)
Wrap existing data as packet side data.
Definition: packet.c:613
mov_read_packet
static int mov_read_packet(AVFormatContext *s, AVPacket *pkt)
Definition: mov.c:11750
mov_read_infe
static int mov_read_infe(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:9261
offset
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf offset
Definition: writing_filters.txt:86
AV_CODEC_ID_LCEVC
@ AV_CODEC_ID_LCEVC
Definition: codec_id.h:608
MOVEncryptionIndex::auxiliary_offsets_count
size_t auxiliary_offsets_count
Definition: isom.h:142
HEIFItem::vflip
int vflip
Definition: isom.h:310
AVPacket::flags
int flags
A combination of AV_PKT_FLAG values.
Definition: packet.h:609
av_dict_free
void av_dict_free(AVDictionary **pm)
Free all the memory allocated for an AVDictionary struct and all keys and values.
Definition: dict.c:233
av_encryption_info_free
void av_encryption_info_free(AVEncryptionInfo *info)
Frees the given encryption info object.
Definition: encryption_info.c:82
AVStreamGroup::params
union AVStreamGroup::@454 params
Group type-specific parameters.
read_header
static int read_header(FFV1Context *f, RangeCoder *c)
Definition: ffv1dec.c:578
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
AVSubsampleEncryptionInfo
This file is part of FFmpeg.
Definition: encryption_info.h:25
av_buffer_alloc
AVBufferRef * av_buffer_alloc(size_t size)
Allocate an AVBuffer of the given size using av_malloc().
Definition: buffer.c:77
MOVFragmentIndexItem::stream_info
MOVFragmentStreamInfo * stream_info
Definition: isom.h:163
version
version
Definition: libkvazaar.c:313
AV_STREAM_GROUP_PARAMS_IAMF_AUDIO_ELEMENT
@ AV_STREAM_GROUP_PARAMS_IAMF_AUDIO_ELEMENT
Definition: avformat.h:1129
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:1215
ff_rfps_calculate
void ff_rfps_calculate(AVFormatContext *ic)
Definition: demux.c:2397
input
and forward the test the status of outputs and forward it to the corresponding return FFERROR_NOT_READY If the filters stores internally one or a few frame for some input
Definition: filter_design.txt:172
MOV_MP4_IPCM_TAG
#define MOV_MP4_IPCM_TAG
Definition: isom.h:485
mov_read_clli
static int mov_read_clli(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6765
MOVStreamContext::chunk_offsets
int64_t * chunk_offsets
Definition: isom.h:187
MovTref::id
uint32_t * id
trackID of the referenced track
Definition: isom.h:97
AVStreamGroup::iamf_mix_presentation
struct AVIAMFMixPresentation * iamf_mix_presentation
Definition: avformat.h:1174
AVBufferRef::size
size_t size
Size of data in bytes.
Definition: buffer.h:94
AVChannelLayout::u
union AVChannelLayout::@522 u
Details about which channels are present in this layout.
MOVFragmentIndex::item
MOVFragmentIndexItem * item
Definition: isom.h:171
AV_LOG_INFO
#define AV_LOG_INFO
Standard information.
Definition: log.h:221
MOVStreamContext::iamf
struct IAMFDemuxContext * iamf
Definition: isom.h:289
FFERROR_REDO
#define FFERROR_REDO
Returned by demuxers to indicate that data was consumed but discarded (ignored streams or junk data).
Definition: demux.h:224
av_encryption_init_info_alloc
AVEncryptionInitInfo * av_encryption_init_info_alloc(uint32_t system_id_size, uint32_t num_key_ids, uint32_t key_id_size, uint32_t data_size)
Allocates an AVEncryptionInitInfo structure and sub-pointers to hold the given sizes.
Definition: encryption_info.c:178
av_channel_layout_custom_init
int av_channel_layout_custom_init(AVChannelLayout *channel_layout, int nb_channels)
Initialize a custom channel layout with the specified number of channels.
Definition: channel_layout.c:233
av_aes_ctr_free
void av_aes_ctr_free(struct AVAESCTR *a)
Release an AVAESCTR context.
Definition: aes_ctr.c:84
AVFormatContext::error_recognition
int error_recognition
Error recognition; higher values will detect more errors but may misdetect some more or less valid pa...
Definition: avformat.h:1573
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:8287
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:9742
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:1062
mov_metadata_creation_time
static void mov_metadata_creation_time(MOVContext *c, AVIOContext *pb, AVDictionary **metadata, int version)
Definition: mov.c:1895
mov_metadata_hmmt
static int mov_metadata_hmmt(MOVContext *c, AVIOContext *pb, unsigned len)
Definition: mov.c:325
AV_CODEC_ID_MJPEG
@ AV_CODEC_ID_MJPEG
Definition: codec_id.h:57
MOVFragmentStreamInfo::next_trun_dts
int64_t next_trun_dts
Definition: isom.h:150
MOVStreamContext::stsc_index
unsigned int stsc_index
Definition: isom.h:201
av_sha_alloc
struct AVSHA * av_sha_alloc(void)
Allocate an AVSHA context.
Definition: sha.c:46
mov_read_tenc
static int mov_read_tenc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:8216
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:3462
mov_finalize_packet
static int mov_finalize_packet(AVFormatContext *s, AVStream *st, AVIndexEntry *sample, int64_t current_index, AVPacket *pkt)
Definition: mov.c:11666
MOVIndexRange
Definition: isom.h:174
mov_read_seek
static int mov_read_seek(AVFormatContext *s, int stream_index, int64_t sample_time, int flags)
Definition: mov.c:12085
bprint.h
MOVContext::advanced_editlist
int advanced_editlist
Definition: isom.h:350
MOVStreamContext::time_scale
int time_scale
Definition: isom.h:216
mlp_parse.h
mac_to_unicode
static const uint32_t mac_to_unicode[128]
Definition: mov.c:151
AVStreamGroupTileGrid::width
int width
Width of the final image for presentation.
Definition: avformat.h:1039
MOVStreamContext::bytes_per_frame
unsigned int bytes_per_frame
Definition: isom.h:223
AVSphericalMapping::roll
int32_t roll
Rotation around the forward vector [-180, 180].
Definition: spherical.h:146
IAMFContext::nb_audio_elements
int nb_audio_elements
Definition: iamf.h:132
MOVIndexRange::end
int64_t end
Definition: isom.h:176
av_malloc
#define av_malloc(s)
Definition: ops_asmgen.c:44
AV_CODEC_ID_NONE
@ AV_CODEC_ID_NONE
Definition: codec_id.h:48
AVPacket::pts
int64_t pts
Presentation timestamp in AVStream->time_base units; the time at which the decompressed packet will b...
Definition: packet.h:596
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:5881
search_frag_timestamp
static int search_frag_timestamp(AVFormatContext *s, MOVFragmentIndex *frag_index, AVStream *st, int64_t timestamp)
Definition: mov.c:1768
HEIFItem::width
int width
Definition: isom.h:306
FLAGS
#define FLAGS
Definition: mov.c:12142
MOVStreamContext::stereo3d
AVStereo3D * stereo3d
Definition: isom.h:267
mov_fix_index
static void mov_fix_index(MOVContext *mov, AVStream *st)
Fix ffstream(st)->index_entries, so that it contains only the entries (and the entries which are need...
Definition: mov.c:4374
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:8064
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:3316
internal.h
AV_SPHERICAL_FISHEYE
@ AV_SPHERICAL_FISHEYE
Fisheye projection (Apple).
Definition: spherical.h:84
AVCodecParameters::height
int height
The height of the video frame in pixels.
Definition: codec_par.h:150
AV_TIME_BASE
#define AV_TIME_BASE
Internal time base represented as integer.
Definition: avutil.h:253
MOVStreamContext::stps_count
unsigned int stps_count
Definition: isom.h:203
AVCodecParameters::block_align
int block_align
The number of bytes per coded audio frame, required by some formats.
Definition: codec_par.h:221
AV_CODEC_ID_TTML
@ AV_CODEC_ID_TTML
Definition: codec_id.h:589
rb_size
static int rb_size(AVIOContext *pb, int64_t *value, int size)
Definition: mov.c:9134
AVStereo3DPrimaryEye
AVStereo3DPrimaryEye
List of possible primary eyes.
Definition: stereo3d.h:174
av_malloc_array
#define av_malloc_array(a, b)
Definition: tableprint_vlc.h:32
AV_CODEC_ID_CAVS
@ AV_CODEC_ID_CAVS
Definition: codec_id.h:137
display.h
ff_mov_read_stsd_entries
int ff_mov_read_stsd_entries(MOVContext *c, AVIOContext *pb, int entries)
Definition: mov.c:3215
AV_FIELD_BB
@ AV_FIELD_BB
Bottom coded first, bottom displayed first.
Definition: defs.h:215
AV_PKT_DATA_ICC_PROFILE
@ AV_PKT_DATA_ICC_PROFILE
ICC profile data consisting of an opaque octet buffer following the format described by ISO 15076-1.
Definition: packet.h:271
AV_STEREO3D_TOPBOTTOM
@ AV_STEREO3D_TOPBOTTOM
Views are on top of each other.
Definition: stereo3d.h:76
MOVFragment::duration
unsigned duration
Definition: isom.h:114
AVIAMFMixPresentation
Information on how to render and mix one or more AVIAMFAudioElement to generate the final audio outpu...
Definition: iamf.h:616
ff_id3v1_genre_str
const char *const ff_id3v1_genre_str[ID3v1_GENRE_MAX+1]
ID3v1 genres.
Definition: id3v1.c:26
MOVStreamContext::sample_sizes
unsigned int * sample_sizes
Definition: isom.h:212
MOVContext::frag_index
MOVFragmentIndex frag_index
Definition: isom.h:363
mov_read_vpcc
static int mov_read_vpcc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6593
AV_CODEC_ID_PCM_F64BE
@ AV_CODEC_ID_PCM_F64BE
Definition: codec_id.h:352
AVStreamGroupLayeredVideo::width
int width
Width of the final stream for presentation.
Definition: avformat.h:1095
AV_CODEC_ID_HEVC
@ AV_CODEC_ID_HEVC
Definition: codec_id.h:223
value
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf default value
Definition: writing_filters.txt:86
av_url_split
void av_url_split(char *proto, int proto_size, char *authorization, int authorization_size, char *hostname, int hostname_size, int *port_ptr, char *path, int path_size, const char *url)
Split a URL string into components.
Definition: utils.c:361
MOVStreamContext::dref_id
int dref_id
Definition: isom.h:230
FFMIN
#define FFMIN(a, b)
Definition: macros.h:49
av_d2q
AVRational av_d2q(double d, int max)
Convert a double precision floating point number to a rational.
Definition: rational.c:110
fix_frag_index_entries
static void fix_frag_index_entries(MOVFragmentIndex *frag_index, int index, int id, int entries)
Definition: mov.c:1854
mov_finalize_stsd_codec
static int mov_finalize_stsd_codec(MOVContext *c, AVIOContext *pb, AVStream *st, MOVStreamContext *sc)
Definition: mov.c:3064
AV_CH_FRONT_LEFT
#define AV_CH_FRONT_LEFT
Definition: channel_layout.h:175
AV_CODEC_ID_PCM_S32BE
@ AV_CODEC_ID_PCM_S32BE
Definition: codec_id.h:339
mov_read_mdcv
static int mov_read_mdcv(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6684
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:1421
AV_CODEC_ID_VC1
@ AV_CODEC_ID_VC1
Definition: codec_id.h:120
demux.h
AV_DISPOSITION_DEPENDENT
#define AV_DISPOSITION_DEPENDENT
The stream is intended to be mixed with another stream before presentation.
Definition: avformat.h:708
MOVStreamContext::pb
AVIOContext * pb
Definition: isom.h:180
mov_read_keys
static int mov_read_keys(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5477
AVCodecParameters::color_range
enum AVColorRange color_range
Additional colorspace characteristics.
Definition: codec_par.h:189
AV_CH_SIDE_RIGHT
#define AV_CH_SIDE_RIGHT
Definition: channel_layout.h:185
len
int len
Definition: vorbis_enc_data.h:426
AV_CODEC_ID_JPEG2000
@ AV_CODEC_ID_JPEG2000
Definition: codec_id.h:138
exif.h
MOVFragment::size
unsigned size
Definition: isom.h:115
MOV_TFHD_DEFAULT_SIZE
#define MOV_TFHD_DEFAULT_SIZE
Definition: isom.h:411
MOVTimeToSample::count
unsigned int count
Definition: isom.h:58
ff_get_wav_header
int ff_get_wav_header(AVFormatContext *s, AVIOContext *pb, AVCodecParameters *par, int size, int big_endian)
Definition: riffdec.c:141
AVCOL_SPC_UNSPECIFIED
@ AVCOL_SPC_UNSPECIFIED
Definition: pixfmt.h:703
fix_stream_ids
static void fix_stream_ids(AVFormatContext *s)
Definition: mov.c:11232
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:4825
AVCodecParameters::coded_side_data
AVPacketSideData * coded_side_data
Additional data associated with the entire stream.
Definition: codec_par.h:83
mov_read_svq3
static int mov_read_svq3(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2441
mov_find_tref_tag
static MovTref * mov_find_tref_tag(const MOVStreamContext *sc, uint32_t name)
Definition: mov.c:2598
AVSHA
hash context
Definition: sha.c:35
AVCOL_RANGE_MPEG
@ AVCOL_RANGE_MPEG
Narrow or limited range content.
Definition: pixfmt.h:760
av_calloc
void * av_calloc(size_t nmemb, size_t size)
Definition: mem.c:264
MOVFragmentStreamInfo::tfdt_dts
int64_t tfdt_dts
Definition: isom.h:149
AV_IAMF_AUDIO_ELEMENT_TYPE_SCENE
@ AV_IAMF_AUDIO_ELEMENT_TYPE_SCENE
Definition: iamf.h:349
AVCodecParameters::field_order
enum AVFieldOrder field_order
The order of the fields in interlaced video.
Definition: codec_par.h:182
av_get_packet
int av_get_packet(AVIOContext *s, AVPacket *pkt, int size)
Allocate and read the payload of a packet and initialize its fields with default values.
Definition: utils.c:98
mov_read_iinf
static int mov_read_iinf(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:9338
ff_read_string_to_bprint_overwrite
int64_t ff_read_string_to_bprint_overwrite(AVIOContext *s, struct AVBPrint *bp, int64_t max_len)
Read a whole null-terminated string of text from AVIOContext to an AVBPrint buffer overwriting its co...
Definition: aviobuf.c:863
AVStreamGroupTileGrid::horizontal
int horizontal
Offset in pixels from the left edge of the canvas where the tile should be placed.
Definition: avformat.h:998
get_stream_info_time
static int64_t get_stream_info_time(MOVFragmentStreamInfo *frag_stream_info)
Definition: mov.c:1716
MP4TrackKindValueMapping
Definition: isom.h:487
fix_index_entry_timestamps
static void fix_index_entry_timestamps(AVStream *st, int end_index, int64_t end_ts, int64_t *frame_duration_buffer, int frame_duration_buffer_size)
Rewrite timestamps of index entries in the range [end_index - frame_duration_buffer_size,...
Definition: mov.c:4225
AV_WB8
#define AV_WB8(p, d)
Definition: intreadwrite.h:392
MOVStreamContext::chunk_count
unsigned int chunk_count
Definition: isom.h:186
av_cmp_q
static int av_cmp_q(AVRational a, AVRational b)
Compare two rationals.
Definition: rational.h:89
MOVStreamContext::data_size
int64_t data_size
Definition: isom.h:240
AV_TIMECODE_FLAG_DROPFRAME
@ AV_TIMECODE_FLAG_DROPFRAME
timecode is drop frame
Definition: timecode.h:36
language
Undefined Behavior In the C language
Definition: undefined.txt:3
MOVStreamContext::ambient
AVAmbientViewingEnvironment * ambient
Definition: isom.h:275
AVCodecParameters::avcodec_parameters_copy
int avcodec_parameters_copy(AVCodecParameters *dst, const AVCodecParameters *src)
Copy the contents of src to dst.
Definition: codec_par.c:107
mov_read_tmcd
static int mov_read_tmcd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6565
mov_chan.h
AVStream::disposition
int disposition
Stream disposition - a combination of AV_DISPOSITION_* flags.
Definition: avformat.h:816
MOVStreamContext::ambient_size
size_t ambient_size
Definition: isom.h:276
tag
uint32_t tag
Definition: movenc.c:2054
AVStream::id
int id
Format-specific stream ID.
Definition: avformat.h:759
ret
ret
Definition: filter_design.txt:187
AVStream
Stream structure.
Definition: avformat.h:747
AV_CODEC_ID_APV
@ AV_CODEC_ID_APV
Definition: codec_id.h:323
AV_LOG_FATAL
#define AV_LOG_FATAL
Something went wrong and recovery is not possible.
Definition: log.h:204
HEIFItem::extent_length
int64_t extent_length
Definition: isom.h:304
MOVEncryptionIndex::nb_encrypted_samples
unsigned int nb_encrypted_samples
Definition: isom.h:135
mov_read_senc
static int mov_read_senc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:7767
avio_seek
int64_t avio_seek(AVIOContext *s, int64_t offset, int whence)
fseek() equivalent for AVIOContext.
Definition: aviobuf.c:236
AVStreamGroupLayeredVideo::height
int height
Height of the final image for presentation.
Definition: avformat.h:1099
FFSWAP
#define FFSWAP(type, a, b)
Definition: macros.h:52
AVClass::class_name
const char * class_name
The name of the class; usually it is the same name as the context structure type to which the AVClass...
Definition: log.h:81
AVEncryptionInfo::key_id
uint8_t * key_id
The ID of the key used to encrypt the packet.
Definition: encryption_info.h:63
av_strlcat
size_t av_strlcat(char *dst, const char *src, size_t size)
Append the string src to the string dst, but to a total length of no more than size - 1 bytes,...
Definition: avstring.c:95
MOVStreamContext::stts_data
MOVStts * stts_data
Definition: isom.h:193
AVSphericalMapping::pitch
int32_t pitch
Rotation around the right vector [-90, 90].
Definition: spherical.h:145
AVStreamGroup::metadata
AVDictionary * metadata
Metadata that applies to the whole group.
Definition: avformat.h:1195
avio_rb16
unsigned int avio_rb16(AVIOContext *s)
Definition: aviobuf.c:749
AVStereo3D::type
enum AVStereo3DType type
How views are packed within the video.
Definition: stereo3d.h:207
MOVSbgp::index
unsigned int index
Definition: isom.h:129
HEIFItem::icc_profile_size
size_t icc_profile_size
Definition: isom.h:314
MOVContext::chapter_tracks
int * chapter_tracks
Definition: isom.h:346
cdt2
static const int16_t cdt2[8]
Definition: truemotion1data.h:43
AVSTREAM_PARSE_HEADERS
@ AVSTREAM_PARSE_HEADERS
Only parse headers, do not repack.
Definition: avformat.h:593
pos
unsigned int pos
Definition: spdifenc.c:414
avformat.h
dovi_meta.h
MOVFragment::implicit_offset
uint64_t implicit_offset
Definition: isom.h:112
dict.h
av_packet_side_data_new
AVPacketSideData * av_packet_side_data_new(AVPacketSideData **psd, int *pnb_sd, enum AVPacketSideDataType type, size_t size, int flags)
Allocate a new packet side data.
Definition: packet.c:620
AV_AUDIO_SERVICE_TYPE_KARAOKE
@ AV_AUDIO_SERVICE_TYPE_KARAOKE
Definition: defs.h:244
mov_read_dmlp
static int mov_read_dmlp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:8796
AV_INPUT_BUFFER_PADDING_SIZE
#define AV_INPUT_BUFFER_PADDING_SIZE
Definition: defs.h:40
MOVStreamContext::pseudo_stream_id
int pseudo_stream_id
-1 means demux all ids
Definition: isom.h:226
MOVContext::time_scale
int time_scale
Definition: isom.h:328
id
enum AVCodecID id
Definition: dts2pts.c:607
mov_read_tfdt
static int mov_read_tfdt(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5907
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:5623
search_frag_moof_offset
static int search_frag_moof_offset(MOVFragmentIndex *frag_index, int64_t offset)
Definition: mov.c:1692
MOVFragment
Definition: isom.h:107
AV_DICT_MATCH_CASE
#define AV_DICT_MATCH_CASE
Only get an entry with exact-case key match.
Definition: dict.h:74
AV_RL32
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_RL32
Definition: bytestream.h:92
U
#define U(x)
Definition: vpx_arith.h:37
mov_switch_root
static int mov_switch_root(AVFormatContext *s, int64_t target, int index)
Definition: mov.c:11537
MOVContext::use_mfra_for
int use_mfra_for
Definition: isom.h:360
AVEncryptionInfo
This describes encryption info for a packet.
Definition: encryption_info.h:43
MOVStreamContext::encryption_index
MOVEncryptionIndex * encryption_index
Definition: isom.h:286
MIN_DATA_ENTRY_BOX_SIZE
#define MIN_DATA_ENTRY_BOX_SIZE
Definition: mov.c:652
AVStreamGroup
Definition: avformat.h:1140
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:753
avpriv_dv_init_demux
DVDemuxContext * avpriv_dv_init_demux(AVFormatContext *s)
Definition: dv.c:728
mov_seek_fragment
static int mov_seek_fragment(AVFormatContext *s, AVStream *st, int64_t timestamp)
Definition: mov.c:11931
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:2817
ff_codec_bmp_tags
const AVCodecTag ff_codec_bmp_tags[]
Definition: riff.c:36
MOVStreamContext::h_spacing
int h_spacing
pasp hSpacing
Definition: isom.h:235
mov_read_dec3
static int mov_read_dec3(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1126
get_frag_time
static int64_t get_frag_time(AVFormatContext *s, AVStream *dst_st, MOVFragmentIndex *frag_index, int index)
Definition: mov.c:1726
MOVStreamContext::sample_size
unsigned int sample_size
may contain value calculated from stsd or value from stsz atom
Definition: isom.h:209
HEVC_NAL_CRA_NUT
@ HEVC_NAL_CRA_NUT
Definition: hevc.h:50
AVStreamGroup::nb_streams
unsigned int nb_streams
Number of elements in AVStreamGroup.streams.
Definition: avformat.h:1202
mlp_samplerate
static int mlp_samplerate(int in)
Definition: mlp_parse.h:87
channel_layout.h
MOVStreamContext::duration_for_fps
int64_t duration_for_fps
Definition: isom.h:257
ISOM_DVCC_DVVC_SIZE
#define ISOM_DVCC_DVVC_SIZE
Definition: dovi_isom.h:29
mov_read_sbgp
static int mov_read_sbgp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:3981
MOVFragment::moof_offset
uint64_t moof_offset
Definition: isom.h:111
AVIO_SEEKABLE_NORMAL
#define AVIO_SEEKABLE_NORMAL
Seeking works like for a local file.
Definition: avio.h:41
av_packet_new_side_data
uint8_t * av_packet_new_side_data(AVPacket *pkt, enum AVPacketSideDataType type, size_t size)
Allocate new information of a packet.
Definition: packet.c:231
buffer
the frame and frame reference mechanism is intended to as much as expensive copies of that data while still allowing the filters to produce correct results The data is stored in buffers represented by AVFrame structures Several references can point to the same frame buffer
Definition: filter_design.txt:49
mov_read_glbl
static int mov_read_glbl(MOVContext *c, AVIOContext *pb, MOVAtom atom)
This function reads atom content and puts data in extradata without tag nor size unlike mov_read_extr...
Definition: mov.c:2503
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:7425
MOVTrackExt::size
unsigned size
Definition: isom.h:123
AVDOVIDecoderConfigurationRecord::bl_present_flag
uint8_t bl_present_flag
Definition: dovi_meta.h:62
ff_remove_stream_group
void ff_remove_stream_group(AVFormatContext *s, AVStreamGroup *stg)
Remove a stream group from its AVFormatContext and free it.
Definition: avformat.c:128
AV_OPT_TYPE_INT
@ AV_OPT_TYPE_INT
Underlying C type is int.
Definition: opt.h:258
MOVContext::dv_fctx
AVFormatContext * dv_fctx
Definition: isom.h:339
av_channel_layout_uninit
void av_channel_layout_uninit(AVChannelLayout *channel_layout)
Free any allocated data in the channel layout and reset the channel count to 0.
Definition: channel_layout.c:443
AV_CODEC_ID_DVAUDIO
@ AV_CODEC_ID_DVAUDIO
Definition: codec_id.h:458
avformat_free_context
void avformat_free_context(AVFormatContext *s)
Free an AVFormatContext and all its streams.
Definition: avformat.c:148
MOVContext::aax_mode
unsigned int aax_mode
'aax' file has been detected
Definition: isom.h:365
mov_read_sv3d
static int mov_read_sv3d(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6947
avio_read
int avio_read(AVIOContext *s, unsigned char *buf, int size)
Read size bytes from AVIOContext into buf.
Definition: aviobuf.c:615
mov_aaxc_crypto
static int mov_aaxc_crypto(MOVContext *c)
Definition: mov.c:1532
mov_get_skip_samples
static int64_t mov_get_skip_samples(AVStream *st, int sample)
Definition: mov.c:12069
MOVFragmentIndex
Definition: isom.h:166
AV_RB8
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_WL16 uint64_t_TMPL AV_WB64 unsigned int_TMPL AV_WB32 unsigned int_TMPL AV_WB24 unsigned int_TMPL AV_WB16 unsigned int_TMPL AV_RB8
Definition: bytestream.h:99
ref
static int ref[MAX_W *MAX_W]
Definition: jpeg2000dwt.c:117
AVStream::r_frame_rate
AVRational r_frame_rate
Real base framerate of the stream.
Definition: avformat.h:881
MOVStreamContext::tts_count
unsigned int tts_count
Definition: isom.h:188
MOVStreamContext::track_end
int64_t track_end
used for dts generation in fragmented movie files
Definition: isom.h:243
MOVStreamContext::sgpd_sync_count
uint32_t sgpd_sync_count
Definition: isom.h:249
MOVContext::fragment
MOVFragment fragment
current fragment in moof atom
Definition: isom.h:341
AVDOVIDecoderConfigurationRecord::rpu_present_flag
uint8_t rpu_present_flag
Definition: dovi_meta.h:60
AVIndexEntry::pos
int64_t pos
Definition: avformat.h:602
AVIOContext::eof_reached
int eof_reached
true if was unable to read due to error or eof
Definition: avio.h:238
mov_metadata_int8_bypass_padding
static int mov_metadata_int8_bypass_padding(MOVContext *c, AVIOContext *pb, unsigned len, const char *key)
Definition: mov.c:112
AVDOVIDecoderConfigurationRecord::el_present_flag
uint8_t el_present_flag
Definition: dovi_meta.h:61
MOVDref::type
uint32_t type
Definition: isom.h:86
samples
Filter the word “frame” indicates either a video frame or a group of audio samples
Definition: filter_design.txt:8
mean
static float mean(const float *input, int size)
Definition: vf_nnedi.c:861
mov_read_covr
static int mov_read_covr(MOVContext *c, AVIOContext *pb, int type, int len)
Definition: mov.c:232
MOVParseTableEntry::type
uint32_t type
Definition: mov.c:84
Windows::Graphics::DirectX::Direct3D11::p
IDirect3DDxgiInterfaceAccess _COM_Outptr_ void ** p
Definition: vsrc_gfxcapture_winrt.hpp:53
AVMasteringDisplayMetadata::min_luminance
AVRational min_luminance
Min luminance of mastering display (cd/m^2).
Definition: mastering_display_metadata.h:52
MOVStreamContext::per_sample_iv_size
unsigned int per_sample_iv_size
Definition: isom.h:284
ff_codec_movsubtitle_tags
const AVCodecTag ff_codec_movsubtitle_tags[]
Definition: isom.c:75
av_mul_q
AVRational av_mul_q(AVRational b, AVRational c)
Multiply two rationals.
Definition: rational.c:80
AVPacket::stream_index
int stream_index
Definition: packet.h:605
MOVFragmentIndexItem::nb_stream_info
int nb_stream_info
Definition: isom.h:162
avio_skip
int64_t avio_skip(AVIOContext *s, int64_t offset)
Skip given number of bytes forward.
Definition: aviobuf.c:321
export_orphan_timecode
static void export_orphan_timecode(AVFormatContext *s)
Definition: mov.c:10427
mov_read_sbas
static int mov_read_sbas(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2626
MOVStreamContext::has_sidx
int has_sidx
Definition: isom.h:280
AV_CH_FRONT_RIGHT
#define AV_CH_FRONT_RIGHT
Definition: channel_layout.h:176
av_aes_ctr_crypt
void av_aes_ctr_crypt(struct AVAESCTR *a, uint8_t *dst, const uint8_t *src, int count)
Process a buffer using a previously initialized context.
Definition: aes_ctr.c:102
mov_metadata_gnre
static int mov_metadata_gnre(MOVContext *c, AVIOContext *pb, unsigned len, const char *key)
Definition: mov.c:135
AV_PKT_DATA_ENCRYPTION_INFO
@ AV_PKT_DATA_ENCRYPTION_INFO
This side data contains encryption info for how to decrypt the packet.
Definition: packet.h:252
av_realloc
#define av_realloc(p, s)
Definition: ops_asmgen.c:46
MOV_MERGE_CTTS
#define MOV_MERGE_CTTS
Definition: mov.c:4755
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:2326
AVIAMFSubmix::nb_elements
unsigned int nb_elements
Number of elements in the submix.
Definition: iamf.h:575
MOVFragmentStreamInfo::id
int id
Definition: isom.h:146
AVIO_FLAG_READ
#define AVIO_FLAG_READ
read-only
Definition: avio.h:617
AV_PKT_DATA_AUDIO_SERVICE_TYPE
@ AV_PKT_DATA_AUDIO_SERVICE_TYPE
This side data should be associated with an audio stream and corresponds to enum AVAudioServiceType.
Definition: packet.h:117
av_spherical_alloc
AVSphericalMapping * av_spherical_alloc(size_t *size)
Allocate a AVSphericalVideo structure and initialize its fields to default values.
Definition: spherical.c:26
AV_OPT_FLAG_DECODING_PARAM
#define AV_OPT_FLAG_DECODING_PARAM
A generic parameter which can be set by the user for demuxing or decoding.
Definition: opt.h:355
mov_read_rtmd_track
static int mov_read_rtmd_track(AVFormatContext *s, AVStream *st)
Definition: mov.c:10204
AVMEDIA_TYPE_VIDEO
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:200
read_probe
static int read_probe(const AVProbeData *p)
Definition: cdg.c:30
MOVStreamContext::pb_is_copied
int pb_is_copied
Definition: isom.h:182
AV_CODEC_ID_PCM_S32LE
@ AV_CODEC_ID_PCM_S32LE
Definition: codec_id.h:338
AVCodecParameters::bits_per_coded_sample
int bits_per_coded_sample
The number of bits per sample in the codedwords.
Definition: codec_par.h:113
mov_parse_tiles
static int mov_parse_tiles(AVFormatContext *s)
Definition: mov.c:10829
mem.h
AVStreamGroup::type
enum AVStreamGroupParamsType type
Group type.
Definition: avformat.h:1167
MOVElst::time
int64_t time
Definition: isom.h:81
AVBufferRef
A reference to a data buffer.
Definition: buffer.h:82
HEIFGrid
Definition: isom.h:317
mov_read_iref_dimg
static int mov_read_iref_dimg(MOVContext *c, AVIOContext *pb, int version)
Definition: mov.c:9392
mov_read_pcmc
static int mov_read_pcmc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2048
build_open_gop_key_points
static int build_open_gop_key_points(AVStream *st)
Definition: mov.c:4692
mov_parse_stsd_audio
static void mov_parse_stsd_audio(MOVContext *c, AVIOContext *pb, AVStream *st, MOVStreamContext *sc)
Definition: mov.c:2881
IAMFContext::mix_presentations
IAMFMixPresentation ** mix_presentations
Definition: iamf.h:133
current
static struct @592 current
AV_CODEC_ID_PCM_U8
@ AV_CODEC_ID_PCM_U8
Definition: codec_id.h:335
MOVContext::trak_index
int trak_index
Index of the current 'trak'.
Definition: isom.h:335
mov_read_timecode_track
static int mov_read_timecode_track(AVFormatContext *s, AVStream *st)
Definition: mov.c:10230
HEIFGrid::item
HEIFItem * item
Definition: isom.h:318
AVSphericalMapping::bound_left
uint32_t bound_left
Distance from the left edge.
Definition: spherical.h:185
mov_read_mac_string
static int mov_read_mac_string(MOVContext *c, AVIOContext *pb, int len, char *dst, int dstlen)
Definition: mov.c:170
MOVEncryptionIndex::auxiliary_info_sizes
uint8_t * auxiliary_info_sizes
Definition: isom.h:138
MOVFragment::stsd_id
unsigned stsd_id
Definition: isom.h:113
AVCodecParameters::video_delay
int video_delay
Number of delayed frames.
Definition: codec_par.h:200
HEIFGrid::tile_id_list
int16_t * tile_id_list
Definition: isom.h:320
avpriv_request_sample
#define avpriv_request_sample(...)
Definition: tableprint_vlc.h:37
MOVStreamContext::tts_data
MOVTimeToSample * tts_data
Definition: isom.h:190
map
const VDPAUPixFmtMap * map
Definition: hwcontext_vdpau.c:71
avformat_stream_group_create
AVStreamGroup * avformat_stream_group_create(AVFormatContext *s, enum AVStreamGroupParamsType type, AVDictionary **options)
Add a new empty stream group to a media file.
Definition: options.c:469
AV_CHANNEL_LAYOUT_MONO
#define AV_CHANNEL_LAYOUT_MONO
Definition: channel_layout.h:394
AV_CODEC_ID_PCM_F64LE
@ AV_CODEC_ID_PCM_F64LE
Definition: codec_id.h:353
AVStreamGroupTileGrid::height
int height
Height of the final image for presentation.
Definition: avformat.h:1049
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:10445
av_free
#define av_free(p)
Definition: tableprint_vlc.h:34
AVDictionaryEntry
Definition: dict.h:90
mov_read_hvce
static int mov_read_hvce(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:8851
av_add_q
AVRational av_add_q(AVRational b, AVRational c)
Add two rationals.
Definition: rational.c:93
AVCodecParameters::codec_id
enum AVCodecID codec_id
Specific type of the encoded data (the codec used).
Definition: codec_par.h:57
AV_PKT_DATA_HEVC_CONF
@ AV_PKT_DATA_HEVC_CONF
Dolby Vision enhancement-layer HEVC decoder configuration.
Definition: packet.h:384
AVStereo3DView
AVStereo3DView
List of possible view types.
Definition: stereo3d.h:149
AVPacket
This structure stores compressed data.
Definition: packet.h:580
AVContentLightMetadata::MaxFALL
unsigned MaxFALL
Max average light level per frame (cd/m^2).
Definition: mastering_display_metadata.h:116
mov_parse_lcevc_streams
static int mov_parse_lcevc_streams(AVFormatContext *s)
Definition: mov.c:11105
mov_read_hfov
static int mov_read_hfov(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:7396
AV_OPT_TYPE_BOOL
@ AV_OPT_TYPE_BOOL
Underlying C type is int.
Definition: opt.h:326
MOVStreamContext::stps_data
unsigned * stps_data
partial sync sample for mpeg-2 open gop
Definition: isom.h:204
AV_CODEC_ID_ADPCM_IMA_WAV
@ AV_CODEC_ID_ADPCM_IMA_WAV
Definition: codec_id.h:370
MOVContext::nb_heif_item
int nb_heif_item
Definition: isom.h:387
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:35
av_dict_set
int av_dict_set(AVDictionary **pm, const char *key, const char *value, int flags)
Set the given entry in *pm, overwriting an existing entry.
Definition: dict.c:86
riff.h
av_dict_copy
int av_dict_copy(AVDictionary **dst, const AVDictionary *src, int flags)
Copy entries from one AVDictionary struct into another.
Definition: dict.c:247
av_encryption_info_alloc
AVEncryptionInfo * av_encryption_info_alloc(uint32_t subsample_count, uint32_t key_id_size, uint32_t iv_size)
Allocates an AVEncryptionInfo structure and sub-pointers to hold the given number of subsamples.
Definition: encryption_info.c:41
AVPacket::pos
int64_t pos
byte position in stream, -1 if unknown
Definition: packet.h:623
FFInputFormat
Definition: demux.h:66
MOVContext::decryption_keys
AVDictionary * decryption_keys
Definition: isom.h:392
mov_metadata_loci
static int mov_metadata_loci(MOVContext *c, AVIOContext *pb, unsigned len)
Definition: mov.c:275
mov_read_eyes
static int mov_read_eyes(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:7157
AV_CODEC_ID_ILBC
@ AV_CODEC_ID_ILBC
Definition: codec_id.h:511
AV_CHAN_AMBISONIC_BASE
@ AV_CHAN_AMBISONIC_BASE
Range of channels between AV_CHAN_AMBISONIC_BASE and AV_CHAN_AMBISONIC_END represent Ambisonic compon...
Definition: channel_layout.h:108
MOV_TRUN_SAMPLE_SIZE
#define MOV_TRUN_SAMPLE_SIZE
Definition: isom.h:419
MOVStreamContext::tmcd_flags
uint32_t tmcd_flags
tmcd track flags
Definition: isom.h:241
int32_t
int32_t
Definition: audioconvert.c:56
HEIFItem::rotation
int rotation
Definition: isom.h:308
MOVAtom::type
uint32_t type
Definition: isom.h:101
distance
static float distance(float x, float y, int band)
Definition: nellymoserenc.c:231
AVSTREAM_PARSE_FULL
@ AVSTREAM_PARSE_FULL
full parsing and repack
Definition: avformat.h:592
parse_timecode_in_framenum_format
static int parse_timecode_in_framenum_format(AVFormatContext *s, AVStream *st, int64_t value, int flags)
Definition: mov.c:10190
MOVStreamContext::tmcd_nb_frames
uint8_t tmcd_nb_frames
tmcd number of frames per tick / second
Definition: isom.h:242
AVIAMFSubmixElement
Submix element as defined in section 3.7 of IAMF.
Definition: iamf.h:449
replaygain.h
MOVFragmentIndexItem::headers_read
int headers_read
Definition: isom.h:160
AV_CODEC_ID_VP8
@ AV_CODEC_ID_VP8
Definition: codec_id.h:190
AVERROR_BUG
#define AVERROR_BUG
Internal bug, also see AVERROR_BUG2.
Definition: error.h:52
MP4TrackKindValueMapping::value
const char * value
Definition: isom.h:489
AVStereo3DType
AVStereo3DType
List of possible 3D Types.
Definition: stereo3d.h:48
MOVDref::filename
char filename[64]
Definition: isom.h:90
MOVStsc::count
int count
Definition: isom.h:75
AV_CODEC_ID_PCM_F32LE
@ AV_CODEC_ID_PCM_F32LE
Definition: codec_id.h:351
ff_mov_demuxer
const FFInputFormat ff_mov_demuxer
Definition: mov.c:12204
AVCodecParameters::bit_rate
int64_t bit_rate
The average bitrate of the encoded data (in bits per second).
Definition: codec_par.h:99
MOVStts::count
unsigned int count
Definition: isom.h:64
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
MOVStreamContext::display_matrix
int32_t * display_matrix
Definition: isom.h:266
MOVContext::heif_grid
HEIFGrid * heif_grid
Definition: isom.h:388
MOVStreamContext::min_sample_duration
uint32_t min_sample_duration
Definition: isom.h:254
MOVStreamContext::current_index
int64_t current_index
Definition: isom.h:220
AVERROR_INVALIDDATA
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:61
ff_mov_track_kind_table
const struct MP4TrackKindMapping ff_mov_track_kind_table[]
Definition: isom.c:464
get_curr_st
static AVStream * get_curr_st(MOVContext *c)
Get the current stream in the parsing process.
Definition: mov.c:214
MOVStreamContext::stts_allocated_size
unsigned int stts_allocated_size
Definition: isom.h:192
MOVFragmentStreamInfo::index_entry
int index_entry
Definition: isom.h:153
cenc_decrypt
static int cenc_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
Definition: mov.c:8632
MOVStreamContext::format
uint32_t format
Definition: isom.h:278
MKTAG
#define MKTAG(a, b, c, d)
Definition: macros.h:55
ffio_read_size
int ffio_read_size(AVIOContext *s, unsigned char *buf, int size)
Read size bytes from AVIOContext into buf.
Definition: aviobuf.c:665
MOVStreamContext::sync_group_count
unsigned int sync_group_count
Definition: isom.h:246
MOVContext::bitrates_count
int bitrates_count
Definition: isom.h:358
AV_CODEC_ID_VORBIS
@ AV_CODEC_ID_VORBIS
Definition: codec_id.h:457
AVDictionaryEntry::value
char * value
Definition: dict.h:92
AVStream::start_time
int64_t start_time
Decoding: pts of the first frame of the stream in presentation order, in stream time base.
Definition: avformat.h:796
MOVStreamContext::id
int id
AVStream id.
Definition: isom.h:183
MOVStreamContext::samples_per_frame
unsigned int samples_per_frame
Definition: isom.h:224
MOVStreamContext::tts_allocated_size
unsigned int tts_allocated_size
Definition: isom.h:189
pkt
static AVPacket * pkt
Definition: demux_decode.c:55
MOVElst::duration
int64_t duration
Definition: isom.h:80
ac3tab.h
avstring.h
mov_read_ispe
static int mov_read_ispe(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:9564
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:9519
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:1290
mov_read_mfra
static int mov_read_mfra(MOVContext *c, AVIOContext *f)
Definition: mov.c:10500
AV_CODEC_ID_FLV1
@ AV_CODEC_ID_FLV1
Definition: codec_id.h:71
mov_metadata_int8_no_padding
static int mov_metadata_int8_no_padding(MOVContext *c, AVIOContext *pb, unsigned len, const char *key)
Definition: mov.c:126
flac.h
AVStreamGroupTileGrid::idx
unsigned int idx
Index of the stream in the group this tile references.
Definition: avformat.h:993
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:1637
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:8929
MOVContext::heif_item
HEIFItem ** heif_item
Definition: isom.h:386
MOVStreamContext::stts_count
unsigned int stts_count
Definition: isom.h:191
AVStreamGroupLayeredVideo::el_index
unsigned int el_index
Index of the enhancement layer stream in AVStreamGroup.
Definition: avformat.h:1083
MOV_TRUN_SAMPLE_CTS
#define MOV_TRUN_SAMPLE_CTS
Definition: isom.h:421
HEIFItem::iref_list
HEIFItemRef * iref_list
Definition: isom.h:300
AV_OPT_TYPE_CONST
@ AV_OPT_TYPE_CONST
Special option type for declaring named constants.
Definition: opt.h:298
MOV_ISMV_TTML_TAG
#define MOV_ISMV_TTML_TAG
Definition: isom.h:482
snprintf
#define snprintf
Definition: snprintf.h:34
IAMFMixPresentation::mix_presentation_id
unsigned int mix_presentation_id
Definition: iamf.h:114
AVCodecParameters::initial_padding
int initial_padding
Number of padding audio samples at the start.
Definition: codec_par.h:239
AV_CODEC_ID_PCM_S24BE
@ AV_CODEC_ID_PCM_S24BE
Definition: codec_id.h:343
mov_read_st3d
static int mov_read_st3d(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6819
mov_read_imir
static int mov_read_imir(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:9612
is_open_key_sample
static int is_open_key_sample(const MOVStreamContext *sc, int sample)
Definition: mov.c:11950
mov_read_dvc1
static int mov_read_dvc1(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2549
MOVStreamContext::elst_count
unsigned int elst_count
Definition: isom.h:206
av_color_transfer_name
const char * av_color_transfer_name(enum AVColorTransferCharacteristic transfer)
Definition: pixdesc.c:3823
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:2263
AV_WL16A
#define AV_WL16A(p, v)
Definition: intreadwrite.h:557
AV_RB64
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_WL16 uint64_t_TMPL AV_RB64
Definition: bytestream.h:95
AVSphericalMapping::yaw
int32_t yaw
Rotation around the up vector [-180, 180].
Definition: spherical.h:144
src
#define src
Definition: vp8dsp.c:248
mov_read_chapters
static void mov_read_chapters(AVFormatContext *s)
Definition: mov.c:10091
AV_CODEC_ID_DNXHD
@ AV_CODEC_ID_DNXHD
Definition: codec_id.h:149
channel
channel
Definition: ebur128.h:39
MOVStreamContext::default_encrypted_sample
AVEncryptionInfo * default_encrypted_sample
Definition: isom.h:285
duration
static int64_t duration
Definition: ffplay.c:329
MOVContext::cur_item_id
int cur_item_id
Definition: isom.h:385
av_timecode_make_string
char * av_timecode_make_string(const AVTimecode *tc, char *buf, int framenum_arg)
Load timecode string in buf.
Definition: timecode.c:104
AVFMT_EVENT_FLAG_METADATA_UPDATED
#define AVFMT_EVENT_FLAG_METADATA_UPDATED
Definition: avformat.h:1693
AV_DICT_DONT_STRDUP_KEY
#define AV_DICT_DONT_STRDUP_KEY
Take ownership of a key that's been allocated with av_malloc() or another memory allocation function.
Definition: dict.h:77
MOVContext::next_root_atom
int64_t next_root_atom
offset of the next root atom
Definition: isom.h:354
MOVContext::found_iinf
int found_iinf
'iinf' atom has been found
Definition: isom.h:332
MOVContext::meta_keys_count
unsigned meta_keys_count
Definition: isom.h:337
iamf_reader.h
AVStreamGroupTileGrid::background
uint8_t background[4]
The pixel value per channel in RGBA format used if no pixel of any tile is located at a particular pi...
Definition: avformat.h:1013
MOVStreamContext::palette
uint32_t palette[256]
Definition: isom.h:238
cenc_scheme_decrypt
static int cenc_scheme_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
Definition: mov.c:8364
MOVFragment::track_id
unsigned track_id
Definition: isom.h:109
mov_read_hdlr
static int mov_read_hdlr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:797
mov_parse_stsd_data
static int mov_parse_stsd_data(MOVContext *c, AVIOContext *pb, AVStream *st, MOVStreamContext *sc, int64_t size)
Definition: mov.c:3018
AV_CH_SIDE_LEFT
#define AV_CH_SIDE_LEFT
Definition: channel_layout.h:184
ff_iamf_read_deinit
void ff_iamf_read_deinit(IAMFDemuxContext *c)
Definition: iamf_reader.c:371
AV_CODEC_ID_PRORES
@ AV_CODEC_ID_PRORES
Definition: codec_id.h:198
AV_RB16
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_WL16 uint64_t_TMPL AV_WB64 unsigned int_TMPL AV_WB32 unsigned int_TMPL AV_WB24 unsigned int_TMPL AV_RB16
Definition: bytestream.h:98
av_encryption_init_info_add_side_data
uint8_t * av_encryption_init_info_add_side_data(const AVEncryptionInitInfo *info, size_t *side_data_size)
Allocates and initializes side data that holds a copy of the given encryption init info.
Definition: encryption_info.c:292
av_fourcc2str
#define av_fourcc2str(fourcc)
Definition: avutil.h:323
ff_mov_read_chan
int ff_mov_read_chan(AVFormatContext *s, AVIOContext *pb, AVStream *st, int64_t size)
Read 'chan' tag from the input stream.
Definition: mov_chan.c:550
av_index_search_timestamp
int av_index_search_timestamp(AVStream *st, int64_t timestamp, int flags)
Get the index for a specific timestamp.
Definition: seek.c:245
mov_read_pitm
static int mov_read_pitm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:9153
MOVContext::ignore_chapters
int ignore_chapters
Definition: isom.h:352
MOVTimeToSample::offset
int offset
Definition: isom.h:60
mov_read_dac3
static int mov_read_dac3(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:868
MP4TrackKindMapping
Definition: isom.h:492
ff_alloc_extradata
int ff_alloc_extradata(AVCodecParameters *par, int size)
Allocate extradata with additional AV_INPUT_BUFFER_PADDING_SIZE at end which is always set to 0.
Definition: utils.c:237
AVDOVIDecoderConfigurationRecord
Definition: dovi_meta.h:55
HEIFItem::nb_iref_list
int nb_iref_list
Definition: isom.h:301
AV_DISPOSITION_NON_DIEGETIC
#define AV_DISPOSITION_NON_DIEGETIC
The stream is intended to be mixed with a spatial audio track.
Definition: avformat.h:685
avio_feof
int avio_feof(AVIOContext *s)
Similar to feof() but also returns nonzero on read errors.
Definition: aviobuf.c:349
mc
#define mc
Definition: vf_colormatrix.c:100
MOVStreamContext::ffindex
int ffindex
AVStream index.
Definition: isom.h:184
HEIFItem::extent_offset
int64_t extent_offset
Definition: isom.h:305
mov_read_stsz
static int mov_read_stsz(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:3579