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"
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/flac.h"
56 #include "libavcodec/hevc/hevc.h"
58 #include "libavcodec/mlp_parse.h"
59 #include "avformat.h"
60 #include "internal.h"
61 #include "avio_internal.h"
62 #include "demux.h"
63 #include "iamf_parse.h"
64 #include "iamf_reader.h"
65 #include "dovi_isom.h"
66 #include "riff.h"
67 #include "isom.h"
68 #include "libavcodec/get_bits.h"
69 #include "id3v1.h"
70 #include "mov_chan.h"
71 #include "replaygain.h"
72 
73 #if CONFIG_ZLIB
74 #include <zlib.h>
75 #endif
76 
77 #include "qtpalette.h"
78 
79 /* those functions parse an atom */
80 /* links atom IDs to parse functions */
81 typedef struct MOVParseTableEntry {
82  uint32_t type;
83  int (*parse)(MOVContext *ctx, AVIOContext *pb, MOVAtom atom);
85 
86 static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom);
87 static int mov_read_mfra(MOVContext *c, AVIOContext *f);
89 static int64_t add_ctts_entry(MOVCtts** ctts_data, unsigned int* ctts_count, unsigned int* allocated_size,
90  int count, int duration);
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 current item in the parsing process.
194  */
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 != c->cur_item_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 = heif_cur_item(c);
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;
358 
359  switch (atom.type) {
360  case MKTAG( '@','P','R','M'): key = "premiere_version"; raw = 1; break;
361  case MKTAG( '@','P','R','Q'): key = "quicktime_version"; raw = 1; break;
362  case MKTAG( 'X','M','P','_'):
363  if (c->export_xmp) { key = "xmp"; raw = 1; } break;
364  case MKTAG( 'a','A','R','T'): key = "album_artist"; break;
365  case MKTAG( 'a','k','I','D'): key = "account_type";
367  case MKTAG( 'a','p','I','D'): key = "account_id"; break;
368  case MKTAG( 'c','a','t','g'): key = "category"; break;
369  case MKTAG( 'c','p','i','l'): key = "compilation";
371  case MKTAG( 'c','p','r','t'): key = "copyright"; break;
372  case MKTAG( 'd','e','s','c'): key = "description"; break;
373  case MKTAG( 'd','i','s','k'): key = "disc";
375  case MKTAG( 'e','g','i','d'): key = "episode_uid";
377  case MKTAG( 'F','I','R','M'): key = "firmware"; raw = 1; break;
378  case MKTAG( 'g','n','r','e'): key = "genre";
379  parse = mov_metadata_gnre; break;
380  case MKTAG( 'h','d','v','d'): key = "hd_video";
382  case MKTAG( 'H','M','M','T'):
383  return mov_metadata_hmmt(c, pb, atom.size);
384  case MKTAG( 'k','e','y','w'): key = "keywords"; break;
385  case MKTAG( 'l','d','e','s'): key = "synopsis"; break;
386  case MKTAG( 'l','o','c','i'):
387  return mov_metadata_loci(c, pb, atom.size);
388  case MKTAG( 'm','a','n','u'): key = "make"; break;
389  case MKTAG( 'm','o','d','l'): key = "model"; break;
390  case MKTAG( 'p','c','s','t'): key = "podcast";
392  case MKTAG( 'p','g','a','p'): key = "gapless_playback";
394  case MKTAG( 'p','u','r','d'): key = "purchase_date"; break;
395  case MKTAG( 'r','t','n','g'): key = "rating";
397  case MKTAG( 's','o','a','a'): key = "sort_album_artist"; break;
398  case MKTAG( 's','o','a','l'): key = "sort_album"; break;
399  case MKTAG( 's','o','a','r'): key = "sort_artist"; break;
400  case MKTAG( 's','o','c','o'): key = "sort_composer"; break;
401  case MKTAG( 's','o','n','m'): key = "sort_name"; break;
402  case MKTAG( 's','o','s','n'): key = "sort_show"; break;
403  case MKTAG( 's','t','i','k'): key = "media_type";
405  case MKTAG( 't','r','k','n'): key = "track";
407  case MKTAG( 't','v','e','n'): key = "episode_id"; break;
408  case MKTAG( 't','v','e','s'): key = "episode_sort";
410  case MKTAG( 't','v','n','n'): key = "network"; break;
411  case MKTAG( 't','v','s','h'): key = "show"; break;
412  case MKTAG( 't','v','s','n'): key = "season_number";
414  case MKTAG(0xa9,'A','R','T'): key = "artist"; break;
415  case MKTAG(0xa9,'P','R','D'): key = "producer"; break;
416  case MKTAG(0xa9,'a','l','b'): key = "album"; break;
417  case MKTAG(0xa9,'a','u','t'): key = "artist"; break;
418  case MKTAG(0xa9,'c','h','p'): key = "chapter"; break;
419  case MKTAG(0xa9,'c','m','t'): key = "comment"; break;
420  case MKTAG(0xa9,'c','o','m'): key = "composer"; break;
421  case MKTAG(0xa9,'c','p','y'): key = "copyright"; break;
422  case MKTAG(0xa9,'d','a','y'): key = "date"; break;
423  case MKTAG(0xa9,'d','i','r'): key = "director"; break;
424  case MKTAG(0xa9,'d','i','s'): key = "disclaimer"; break;
425  case MKTAG(0xa9,'e','d','1'): key = "edit_date"; break;
426  case MKTAG(0xa9,'e','n','c'): key = "encoder"; break;
427  case MKTAG(0xa9,'f','m','t'): key = "original_format"; break;
428  case MKTAG(0xa9,'g','e','n'): key = "genre"; break;
429  case MKTAG(0xa9,'g','r','p'): key = "grouping"; break;
430  case MKTAG(0xa9,'h','s','t'): key = "host_computer"; break;
431  case MKTAG(0xa9,'i','n','f'): key = "comment"; break;
432  case MKTAG(0xa9,'l','y','r'): key = "lyrics"; break;
433  case MKTAG(0xa9,'m','a','k'): key = "make"; break;
434  case MKTAG(0xa9,'m','o','d'): key = "model"; break;
435  case MKTAG(0xa9,'n','a','m'): key = "title"; break;
436  case MKTAG(0xa9,'o','p','e'): key = "original_artist"; break;
437  case MKTAG(0xa9,'p','r','d'): key = "producer"; break;
438  case MKTAG(0xa9,'p','r','f'): key = "performers"; break;
439  case MKTAG(0xa9,'r','e','q'): key = "playback_requirements"; break;
440  case MKTAG(0xa9,'s','r','c'): key = "original_source"; break;
441  case MKTAG(0xa9,'s','t','3'): key = "subtitle"; break;
442  case MKTAG(0xa9,'s','w','r'): key = "encoder"; break;
443  case MKTAG(0xa9,'t','o','o'): key = "encoder"; break;
444  case MKTAG(0xa9,'t','r','k'): key = "track"; break;
445  case MKTAG(0xa9,'u','r','l'): key = "URL"; break;
446  case MKTAG(0xa9,'w','r','n'): key = "warning"; break;
447  case MKTAG(0xa9,'w','r','t'): key = "composer"; break;
448  case MKTAG(0xa9,'x','y','z'): key = "location"; break;
449  }
450 retry:
451  if (c->itunes_metadata && atom.size > 8) {
452  int data_size = avio_rb32(pb);
453  int tag = avio_rl32(pb);
454  if (tag == MKTAG('d','a','t','a') && data_size <= atom.size && data_size >= 16) {
455  data_type = avio_rb32(pb); // type
456  avio_rb32(pb); // unknown
457  str_size = data_size - 16;
458  atom.size -= 16;
459 
460  if (!key && c->found_hdlr_mdta && c->meta_keys) {
461  uint32_t index = av_bswap32(atom.type); // BE number has been read as LE
462  if (index < c->meta_keys_count && index > 0) {
463  key = c->meta_keys[index];
464  } else if (atom.type != MKTAG('c', 'o', 'v', 'r')) {
465  av_log(c->fc, AV_LOG_WARNING,
466  "The index of 'data' is out of range: %"PRId32" < 1 or >= %d.\n",
467  index, c->meta_keys_count);
468  }
469  }
470  if (atom.type == MKTAG('c', 'o', 'v', 'r') ||
471  (key && !strcmp(key, "com.apple.quicktime.artwork"))) {
472  int ret = mov_read_covr(c, pb, data_type, str_size);
473  if (ret < 0) {
474  av_log(c->fc, AV_LOG_ERROR, "Error parsing cover art.\n");
475  return ret;
476  }
477  atom.size -= str_size;
478  if (atom.size > 8)
479  goto retry;
480  return ret;
481  }
482  } else return 0;
483  } else if (atom.size > 4 && key && !c->itunes_metadata && !raw) {
484  str_size = avio_rb16(pb); // string length
485  if (str_size > atom.size) {
486  raw = 1;
487  avio_seek(pb, -2, SEEK_CUR);
488  av_log(c->fc, AV_LOG_WARNING, "UDTA parsing failed retrying raw\n");
489  goto retry;
490  }
491  langcode = avio_rb16(pb);
492  ff_mov_lang_to_iso639(langcode, language);
493  atom.size -= 4;
494  } else
495  str_size = atom.size;
496 
497  if (c->export_all && !key) {
498  key = av_fourcc_make_string(tmp_key, atom.type);
499  }
500 
501  if (!key)
502  return 0;
503  if (atom.size < 0 || str_size >= INT_MAX/2)
504  return AVERROR_INVALIDDATA;
505 
506  // Allocates enough space if data_type is a int32 or float32 number, otherwise
507  // worst-case requirement for output string in case of utf8 coded input
508  num = (data_type >= 21 && data_type <= 23);
509  str_size_alloc = (num ? 512 : (raw ? str_size : str_size * 2)) + 1;
510  str = av_mallocz(str_size_alloc);
511  if (!str)
512  return AVERROR(ENOMEM);
513 
514  if (parse)
515  parse(c, pb, str_size, key);
516  else {
517  if (!raw && (data_type == 3 || (data_type == 0 && (langcode < 0x400 || langcode == 0x7fff)))) { // MAC Encoded
518  mov_read_mac_string(c, pb, str_size, str, str_size_alloc);
519  } else if (data_type == 21) { // BE signed integer, variable size
520  int val = 0;
521  if (str_size == 1)
522  val = (int8_t)avio_r8(pb);
523  else if (str_size == 2)
524  val = (int16_t)avio_rb16(pb);
525  else if (str_size == 3)
526  val = ((int32_t)(avio_rb24(pb)<<8))>>8;
527  else if (str_size == 4)
528  val = (int32_t)avio_rb32(pb);
529  if (snprintf(str, str_size_alloc, "%d", val) >= str_size_alloc) {
530  av_log(c->fc, AV_LOG_ERROR,
531  "Failed to store the number (%d) in string.\n", val);
532  av_free(str);
533  return AVERROR_INVALIDDATA;
534  }
535  } else if (data_type == 22) { // BE unsigned integer, variable size
536  unsigned int val = 0;
537  if (str_size == 1)
538  val = avio_r8(pb);
539  else if (str_size == 2)
540  val = avio_rb16(pb);
541  else if (str_size == 3)
542  val = avio_rb24(pb);
543  else if (str_size == 4)
544  val = avio_rb32(pb);
545  if (snprintf(str, str_size_alloc, "%u", val) >= str_size_alloc) {
546  av_log(c->fc, AV_LOG_ERROR,
547  "Failed to store the number (%u) in string.\n", val);
548  av_free(str);
549  return AVERROR_INVALIDDATA;
550  }
551  } else if (data_type == 23 && str_size >= 4) { // BE float32
552  float val = av_int2float(avio_rb32(pb));
553  if (snprintf(str, str_size_alloc, "%f", val) >= str_size_alloc) {
554  av_log(c->fc, AV_LOG_ERROR,
555  "Failed to store the float32 number (%f) in string.\n", val);
556  av_free(str);
557  return AVERROR_INVALIDDATA;
558  }
559  } else if (data_type > 1 && data_type != 4) {
560  // data_type can be 0 if not set at all above. data_type 1 means
561  // UTF8 and 4 means "UTF8 sort". For any other type (UTF16 or e.g.
562  // a picture), don't return it blindly in a string that is supposed
563  // to be UTF8 text.
564  av_log(c->fc, AV_LOG_WARNING, "Skipping unhandled metadata %s of type %d\n", key, data_type);
565  av_free(str);
566  return 0;
567  } else {
568  int ret = ffio_read_size(pb, str, str_size);
569  if (ret < 0) {
570  av_free(str);
571  return ret;
572  }
573  str[str_size] = 0;
574  }
575  c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
576  av_dict_set(&c->fc->metadata, key, str, 0);
577  if (*language && strcmp(language, "und")) {
578  snprintf(key2, sizeof(key2), "%s-%s", key, language);
579  av_dict_set(&c->fc->metadata, key2, str, 0);
580  }
581  if (!strcmp(key, "encoder")) {
582  int major, minor, micro;
583  if (sscanf(str, "HandBrake %d.%d.%d", &major, &minor, &micro) == 3) {
584  c->handbrake_version = 1000000*major + 1000*minor + micro;
585  }
586  }
587  }
588 
589  av_freep(&str);
590  return 0;
591 }
592 
594 {
595  int64_t start;
596  int i, nb_chapters, str_len, version;
597  char str[256+1];
598  int ret;
599 
600  if (c->ignore_chapters)
601  return 0;
602 
603  if ((atom.size -= 5) < 0)
604  return 0;
605 
606  version = avio_r8(pb);
607  avio_rb24(pb);
608  if (version)
609  avio_rb32(pb); // ???
610  nb_chapters = avio_r8(pb);
611 
612  for (i = 0; i < nb_chapters; i++) {
613  if (atom.size < 9)
614  return 0;
615 
616  start = avio_rb64(pb);
617  str_len = avio_r8(pb);
618 
619  if ((atom.size -= 9+str_len) < 0)
620  return 0;
621 
622  ret = ffio_read_size(pb, str, str_len);
623  if (ret < 0)
624  return ret;
625  str[str_len] = 0;
626  avpriv_new_chapter(c->fc, i, (AVRational){1,10000000}, start, AV_NOPTS_VALUE, str);
627  }
628  return 0;
629 }
630 
631 #define MIN_DATA_ENTRY_BOX_SIZE 12
633 {
634  AVStream *st;
635  MOVStreamContext *sc;
636  int entries, i, j;
637 
638  if (c->fc->nb_streams < 1)
639  return 0;
640  st = c->fc->streams[c->fc->nb_streams-1];
641  sc = st->priv_data;
642 
643  avio_rb32(pb); // version + flags
644  entries = avio_rb32(pb);
645  if (!entries ||
646  entries > (atom.size - 1) / MIN_DATA_ENTRY_BOX_SIZE + 1 ||
647  entries >= UINT_MAX / sizeof(*sc->drefs))
648  return AVERROR_INVALIDDATA;
649 
650  for (i = 0; i < sc->drefs_count; i++) {
651  MOVDref *dref = &sc->drefs[i];
652  av_freep(&dref->path);
653  av_freep(&dref->dir);
654  }
655  av_free(sc->drefs);
656  sc->drefs_count = 0;
657  sc->drefs = av_mallocz(entries * sizeof(*sc->drefs));
658  if (!sc->drefs)
659  return AVERROR(ENOMEM);
660  sc->drefs_count = entries;
661 
662  for (i = 0; i < entries; i++) {
663  MOVDref *dref = &sc->drefs[i];
664  uint32_t size = avio_rb32(pb);
665  int64_t next = avio_tell(pb);
666 
667  if (size < 12 || next < 0 || next > INT64_MAX - size)
668  return AVERROR_INVALIDDATA;
669 
670  next += size - 4;
671 
672  dref->type = avio_rl32(pb);
673  avio_rb32(pb); // version + flags
674 
675  if (dref->type == MKTAG('a','l','i','s') && size > 150) {
676  /* macintosh alias record */
677  uint16_t volume_len, len;
678  int16_t type;
679  int ret;
680 
681  avio_skip(pb, 10);
682 
683  volume_len = avio_r8(pb);
684  volume_len = FFMIN(volume_len, 27);
685  ret = ffio_read_size(pb, dref->volume, 27);
686  if (ret < 0)
687  return ret;
688  dref->volume[volume_len] = 0;
689  av_log(c->fc, AV_LOG_DEBUG, "volume %s, len %d\n", dref->volume, volume_len);
690 
691  avio_skip(pb, 12);
692 
693  len = avio_r8(pb);
694  len = FFMIN(len, 63);
695  ret = ffio_read_size(pb, dref->filename, 63);
696  if (ret < 0)
697  return ret;
698  dref->filename[len] = 0;
699  av_log(c->fc, AV_LOG_DEBUG, "filename %s, len %d\n", dref->filename, len);
700 
701  avio_skip(pb, 16);
702 
703  /* read next level up_from_alias/down_to_target */
704  dref->nlvl_from = avio_rb16(pb);
705  dref->nlvl_to = avio_rb16(pb);
706  av_log(c->fc, AV_LOG_DEBUG, "nlvl from %d, nlvl to %d\n",
707  dref->nlvl_from, dref->nlvl_to);
708 
709  avio_skip(pb, 16);
710 
711  for (type = 0; type != -1 && avio_tell(pb) < next; ) {
712  if (avio_feof(pb))
713  return AVERROR_EOF;
714  type = avio_rb16(pb);
715  len = avio_rb16(pb);
716  av_log(c->fc, AV_LOG_DEBUG, "type %d, len %d\n", type, len);
717  if (len&1)
718  len += 1;
719  if (type == 2) { // absolute path
720  av_free(dref->path);
721  dref->path = av_mallocz(len+1);
722  if (!dref->path)
723  return AVERROR(ENOMEM);
724 
725  ret = ffio_read_size(pb, dref->path, len);
726  if (ret < 0) {
727  av_freep(&dref->path);
728  return ret;
729  }
730  if (len > volume_len && !strncmp(dref->path, dref->volume, volume_len)) {
731  len -= volume_len;
732  memmove(dref->path, dref->path+volume_len, len);
733  dref->path[len] = 0;
734  }
735  // trim string of any ending zeros
736  for (j = len - 1; j >= 0; j--) {
737  if (dref->path[j] == 0)
738  len--;
739  else
740  break;
741  }
742  for (j = 0; j < len; j++)
743  if (dref->path[j] == ':' || dref->path[j] == 0)
744  dref->path[j] = '/';
745  av_log(c->fc, AV_LOG_DEBUG, "path %s\n", dref->path);
746  } else if (type == 0) { // directory name
747  av_free(dref->dir);
748  dref->dir = av_malloc(len+1);
749  if (!dref->dir)
750  return AVERROR(ENOMEM);
751 
752  ret = ffio_read_size(pb, dref->dir, len);
753  if (ret < 0) {
754  av_freep(&dref->dir);
755  return ret;
756  }
757  dref->dir[len] = 0;
758  for (j = 0; j < len; j++)
759  if (dref->dir[j] == ':')
760  dref->dir[j] = '/';
761  av_log(c->fc, AV_LOG_DEBUG, "dir %s\n", dref->dir);
762  } else
763  avio_skip(pb, len);
764  }
765  } else {
766  av_log(c->fc, AV_LOG_DEBUG, "Unknown dref type 0x%08"PRIx32" size %"PRIu32"\n",
767  dref->type, size);
768  entries--;
769  i--;
770  }
771  avio_seek(pb, next, SEEK_SET);
772  }
773  return 0;
774 }
775 
777 {
778  AVStream *st;
779  uint32_t type;
780  uint32_t ctype;
781  int64_t title_size;
782  char *title_str;
783  int ret;
784 
785  avio_r8(pb); /* version */
786  avio_rb24(pb); /* flags */
787 
788  /* component type */
789  ctype = avio_rl32(pb);
790  type = avio_rl32(pb); /* component subtype */
791 
792  av_log(c->fc, AV_LOG_TRACE, "ctype=%s\n", av_fourcc2str(ctype));
793  av_log(c->fc, AV_LOG_TRACE, "stype=%s\n", av_fourcc2str(type));
794 
795  if (c->trak_index < 0) { // meta not inside a trak
796  if (type == MKTAG('m','d','t','a')) {
797  c->found_hdlr_mdta = 1;
798  }
799  return 0;
800  }
801 
802  st = c->fc->streams[c->fc->nb_streams-1];
803 
804  if (type == MKTAG('v','i','d','e'))
806  else if (type == MKTAG('s','o','u','n'))
808  else if (type == MKTAG('m','1','a',' '))
810  else if ((type == MKTAG('s','u','b','p')) || (type == MKTAG('c','l','c','p')))
812 
813  avio_rb32(pb); /* component manufacture */
814  avio_rb32(pb); /* component flags */
815  avio_rb32(pb); /* component flags mask */
816 
817  title_size = atom.size - 24;
818  if (title_size > 0) {
819  if (title_size > FFMIN(INT_MAX, SIZE_MAX-1))
820  return AVERROR_INVALIDDATA;
821  title_str = av_malloc(title_size + 1); /* Add null terminator */
822  if (!title_str)
823  return AVERROR(ENOMEM);
824 
825  ret = ffio_read_size(pb, title_str, title_size);
826  if (ret < 0) {
827  av_freep(&title_str);
828  return ret;
829  }
830  title_str[title_size] = 0;
831  if (title_str[0]) {
832  int off = (!c->isom && title_str[0] == title_size - 1);
833  // flag added so as to not set stream handler name if already set from mdia->hdlr
834  av_dict_set(&st->metadata, "handler_name", title_str + off, AV_DICT_DONT_OVERWRITE);
835  }
836  av_freep(&title_str);
837  }
838 
839  return 0;
840 }
841 
843 {
844  return ff_mov_read_esds(c->fc, pb);
845 }
846 
848 {
849  AVStream *st;
850  AVPacketSideData *sd;
851  enum AVAudioServiceType *ast;
852  int ac3info, acmod, lfeon, bsmod;
853  uint64_t mask;
854 
855  if (c->fc->nb_streams < 1)
856  return 0;
857  st = c->fc->streams[c->fc->nb_streams-1];
858 
862  sizeof(*ast), 0);
863  if (!sd)
864  return AVERROR(ENOMEM);
865 
866  ast = (enum AVAudioServiceType*)sd->data;
867  ac3info = avio_rb24(pb);
868  bsmod = (ac3info >> 14) & 0x7;
869  acmod = (ac3info >> 11) & 0x7;
870  lfeon = (ac3info >> 10) & 0x1;
871 
873  if (lfeon)
877 
878  *ast = bsmod;
879  if (st->codecpar->ch_layout.nb_channels > 1 && bsmod == 0x7)
881 
882  return 0;
883 }
884 
885 #if CONFIG_IAMFDEC
886 static int mov_read_iacb(MOVContext *c, AVIOContext *pb, MOVAtom atom)
887 {
888  AVStream *st;
889  MOVStreamContext *sc;
890  FFIOContext b;
891  AVIOContext *descriptor_pb;
892  AVDictionary *metadata;
893  IAMFContext *iamf;
895  unsigned descriptors_size;
896  int nb_frames, disposition;
897  int version, ret;
898 
899  if (atom.size < 5)
900  return AVERROR_INVALIDDATA;
901 
902  if (c->fc->nb_streams < 1)
903  return 0;
904 
905  version = avio_r8(pb);
906  if (version != 1) {
907  av_log(c->fc, AV_LOG_ERROR, "%s configurationVersion %d",
908  version < 1 ? "invalid" : "unsupported", version);
909  return AVERROR_INVALIDDATA;
910  }
911 
912  descriptors_size = ffio_read_leb(pb);
913  if (!descriptors_size || descriptors_size > INT_MAX)
914  return AVERROR_INVALIDDATA;
915 
916  st = c->fc->streams[c->fc->nb_streams - 1];
917  sc = st->priv_data;
918 
919  if (st->codecpar->extradata) {
920  av_log(c->fc, AV_LOG_WARNING, "ignoring iacb\n");
921  return 0;
922  }
923 
924  sc->iamf = av_mallocz(sizeof(*sc->iamf));
925  if (!sc->iamf)
926  return AVERROR(ENOMEM);
927  iamf = &sc->iamf->iamf;
928 
929  st->codecpar->extradata = av_malloc(descriptors_size);
930  if (!st->codecpar->extradata)
931  return AVERROR(ENOMEM);
932  st->codecpar->extradata_size = descriptors_size;
933 
934  ret = avio_read(pb, st->codecpar->extradata, descriptors_size);
935  if (ret != descriptors_size)
936  return ret < 0 ? ret : AVERROR_INVALIDDATA;
937 
938  ffio_init_read_context(&b, st->codecpar->extradata, descriptors_size);
939  descriptor_pb = &b.pub;
940 
941  ret = ff_iamfdec_read_descriptors(iamf, descriptor_pb, descriptors_size, c->fc);
942  if (ret < 0)
943  return ret;
944 
945  metadata = st->metadata;
946  st->metadata = NULL;
947  start_time = st->start_time;
948  nb_frames = st->nb_frames;
949  duration = st->duration;
950  disposition = st->disposition;
951 
952  for (int i = 0; i < iamf->nb_audio_elements; i++) {
953  IAMFAudioElement *audio_element = iamf->audio_elements[i];
954  const AVIAMFAudioElement *element;
955  AVStreamGroup *stg =
957 
958  if (!stg) {
959  ret = AVERROR(ENOMEM);
960  goto fail;
961  }
962 
964  stg->id = audio_element->audio_element_id;
965  /* Transfer ownership */
966  element = stg->params.iamf_audio_element = audio_element->element;
967  audio_element->element = NULL;
968 
969  for (int j = 0; j < audio_element->nb_substreams; j++) {
970  IAMFSubStream *substream = &audio_element->substreams[j];
971  AVStream *stream;
972 
973  if (!i && !j) {
974  if (audio_element->layers[0].substream_count != 1)
975  disposition &= ~AV_DISPOSITION_DEFAULT;
976  stream = st;
977  } else
978  stream = avformat_new_stream(c->fc, NULL);
979  if (!stream) {
980  ret = AVERROR(ENOMEM);
981  goto fail;
982  }
983 
984  stream->start_time = start_time;
985  stream->nb_frames = nb_frames;
986  stream->duration = duration;
987  stream->disposition = disposition;
988  if (stream != st) {
989  stream->priv_data = sc;
990  sc->refcount++;
991  }
992 
995  if (i || j) {
997  if (audio_element->layers[0].substream_count == 1)
999  }
1000 
1001  ret = avcodec_parameters_copy(stream->codecpar, substream->codecpar);
1002  if (ret < 0)
1003  goto fail;
1004 
1005  stream->id = substream->audio_substream_id;
1006 
1007  avpriv_set_pts_info(st, 64, 1, sc->time_scale);
1008 
1009  ret = avformat_stream_group_add_stream(stg, stream);
1010  if (ret < 0)
1011  goto fail;
1012  }
1013 
1014  ret = av_dict_copy(&stg->metadata, metadata, 0);
1015  if (ret < 0)
1016  goto fail;
1017  }
1018 
1019  for (int i = 0; i < iamf->nb_mix_presentations; i++) {
1020  IAMFMixPresentation *mix_presentation = iamf->mix_presentations[i];
1021  const AVIAMFMixPresentation *mix = mix_presentation->cmix;
1022  AVStreamGroup *stg =
1024 
1025  if (!stg) {
1026  ret = AVERROR(ENOMEM);
1027  goto fail;
1028  }
1029 
1031  stg->id = mix_presentation->mix_presentation_id;
1032  /* Transfer ownership */
1033  stg->params.iamf_mix_presentation = mix_presentation->mix;
1034  mix_presentation->mix = NULL;
1035 
1036  for (int j = 0; j < mix->nb_submixes; j++) {
1037  const AVIAMFSubmix *submix = mix->submixes[j];
1038 
1039  for (int k = 0; k < submix->nb_elements; k++) {
1040  const AVIAMFSubmixElement *submix_element = submix->elements[k];
1041  const AVStreamGroup *audio_element = NULL;
1042 
1043  for (int l = 0; l < c->fc->nb_stream_groups; l++)
1044  if (c->fc->stream_groups[l]->type == AV_STREAM_GROUP_PARAMS_IAMF_AUDIO_ELEMENT &&
1045  c->fc->stream_groups[l]->id == submix_element->audio_element_id) {
1046  audio_element = c->fc->stream_groups[l];
1047  break;
1048  }
1049  av_assert0(audio_element);
1050 
1051  for (int l = 0; l < audio_element->nb_streams; l++) {
1052  ret = avformat_stream_group_add_stream(stg, audio_element->streams[l]);
1053  if (ret < 0 && ret != AVERROR(EEXIST))
1054  goto fail;
1055  }
1056  }
1057  }
1058 
1059  ret = av_dict_copy(&stg->metadata, metadata, 0);
1060  if (ret < 0)
1061  goto fail;
1062  }
1063 
1064  ret = 0;
1065 fail:
1066  av_dict_free(&metadata);
1067 
1068  return ret;
1069 }
1070 #endif
1071 
1073 {
1074  AVStream *st;
1075  AVPacketSideData *sd;
1076  enum AVAudioServiceType *ast;
1077  int eac3info, acmod, lfeon, bsmod;
1078  uint64_t mask;
1079 
1080  if (c->fc->nb_streams < 1)
1081  return 0;
1082  st = c->fc->streams[c->fc->nb_streams-1];
1083 
1087  sizeof(*ast), 0);
1088  if (!sd)
1089  return AVERROR(ENOMEM);
1090 
1091  ast = (enum AVAudioServiceType*)sd->data;
1092 
1093  /* No need to parse fields for additional independent substreams and its
1094  * associated dependent substreams since libavcodec's E-AC-3 decoder
1095  * does not support them yet. */
1096  avio_rb16(pb); /* data_rate and num_ind_sub */
1097  eac3info = avio_rb24(pb);
1098  bsmod = (eac3info >> 12) & 0x1f;
1099  acmod = (eac3info >> 9) & 0x7;
1100  lfeon = (eac3info >> 8) & 0x1;
1101 
1103  if (lfeon)
1107 
1108  *ast = bsmod;
1109  if (st->codecpar->ch_layout.nb_channels > 1 && bsmod == 0x7)
1111 
1112  return 0;
1113 }
1114 
1116 {
1117 #define DDTS_SIZE 20
1118  uint8_t buf[DDTS_SIZE + AV_INPUT_BUFFER_PADDING_SIZE];
1119  AVStream *st = NULL;
1120  uint32_t frame_duration_code = 0;
1121  uint32_t channel_layout_code = 0;
1122  GetBitContext gb;
1123  int ret;
1124 
1125  if ((ret = ffio_read_size(pb, buf, DDTS_SIZE)) < 0)
1126  return ret;
1127 
1128  init_get_bits(&gb, buf, 8 * DDTS_SIZE);
1129 
1130  if (c->fc->nb_streams < 1) {
1131  return 0;
1132  }
1133  st = c->fc->streams[c->fc->nb_streams-1];
1134 
1135  st->codecpar->sample_rate = get_bits_long(&gb, 32);
1136  if (st->codecpar->sample_rate <= 0) {
1137  av_log(c->fc, AV_LOG_ERROR, "Invalid sample rate %d\n", st->codecpar->sample_rate);
1138  return AVERROR_INVALIDDATA;
1139  }
1140  skip_bits_long(&gb, 32); /* max bitrate */
1141  st->codecpar->bit_rate = get_bits_long(&gb, 32);
1142  st->codecpar->bits_per_coded_sample = get_bits(&gb, 8);
1143  frame_duration_code = get_bits(&gb, 2);
1144  skip_bits(&gb, 30); /* various fields */
1145  channel_layout_code = get_bits(&gb, 16);
1146 
1147  st->codecpar->frame_size =
1148  (frame_duration_code == 0) ? 512 :
1149  (frame_duration_code == 1) ? 1024 :
1150  (frame_duration_code == 2) ? 2048 :
1151  (frame_duration_code == 3) ? 4096 : 0;
1152 
1153  if (channel_layout_code > 0xff) {
1154  av_log(c->fc, AV_LOG_WARNING, "Unsupported DTS audio channel layout\n");
1155  }
1158  ((channel_layout_code & 0x1) ? AV_CH_FRONT_CENTER : 0) |
1159  ((channel_layout_code & 0x2) ? AV_CH_FRONT_LEFT : 0) |
1160  ((channel_layout_code & 0x2) ? AV_CH_FRONT_RIGHT : 0) |
1161  ((channel_layout_code & 0x4) ? AV_CH_SIDE_LEFT : 0) |
1162  ((channel_layout_code & 0x4) ? AV_CH_SIDE_RIGHT : 0) |
1163  ((channel_layout_code & 0x8) ? AV_CH_LOW_FREQUENCY : 0));
1164 
1165  return 0;
1166 }
1167 
1169 {
1170  AVStream *st;
1171 
1172  if (c->fc->nb_streams < 1)
1173  return 0;
1174  st = c->fc->streams[c->fc->nb_streams-1];
1175 
1176  if (atom.size < 16)
1177  return 0;
1178 
1179  /* skip version and flags */
1180  avio_skip(pb, 4);
1181 
1182  ff_mov_read_chan(c->fc, pb, st, atom.size - 4);
1183 
1184  return 0;
1185 }
1186 
1188 {
1189  int64_t end = av_sat_add64(avio_tell(pb), atom.size);
1190  int version, flags;
1191  int ret;
1192  AVStream *st;
1193 
1194  if (c->fc->nb_streams < 1)
1195  return 0;
1196  st = c->fc->streams[c->fc->nb_streams-1];
1197 
1198  version = avio_r8(pb);
1199  flags = avio_rb24(pb);
1200  if (version != 0 || flags != 0) {
1201  av_log(c->fc, AV_LOG_ERROR,
1202  "Unsupported 'chnl' box with version %d, flags: %#x",
1203  version, flags);
1204  return AVERROR_INVALIDDATA;
1205  }
1206 
1207  ret = ff_mov_read_chnl(c->fc, pb, st);
1208  if (ret < 0)
1209  return ret;
1210 
1211  if (avio_tell(pb) != end) {
1212  av_log(c->fc, AV_LOG_WARNING, "skip %" PRId64 " bytes of unknown data inside chnl\n",
1213  end - avio_tell(pb));
1214  avio_seek(pb, end, SEEK_SET);
1215  }
1216  return ret;
1217 }
1218 
1220 {
1221  AVStream *st;
1222  int ret;
1223 
1224  if (c->fc->nb_streams < 1)
1225  return 0;
1226  st = c->fc->streams[c->fc->nb_streams-1];
1227 
1228  if ((ret = ff_get_wav_header(c->fc, pb, st->codecpar, atom.size, 0)) < 0)
1229  av_log(c->fc, AV_LOG_WARNING, "get_wav_header failed\n");
1230 
1231  return ret;
1232 }
1233 
1235 {
1236  AVStream *st;
1237  HEIFItem *item;
1238  AVPacketSideData *sd;
1239  int width, height, err = 0;
1240  AVRational aperture_width, aperture_height, horiz_off, vert_off;
1241  AVRational pc_x, pc_y;
1242  uint64_t top, bottom, left, right;
1243 
1244  item = heif_cur_item(c);
1245  st = get_curr_st(c);
1246  if (!st)
1247  return 0;
1248 
1249  width = st->codecpar->width;
1250  height = st->codecpar->height;
1251  if ((!width || !height) && item) {
1252  width = item->width;
1253  height = item->height;
1254  }
1255  if (!width || !height) {
1256  err = AVERROR_INVALIDDATA;
1257  goto fail;
1258  }
1259 
1260  aperture_width.num = avio_rb32(pb);
1261  aperture_width.den = avio_rb32(pb);
1262  aperture_height.num = avio_rb32(pb);
1263  aperture_height.den = avio_rb32(pb);
1264 
1265  horiz_off.num = avio_rb32(pb);
1266  horiz_off.den = avio_rb32(pb);
1267  vert_off.num = avio_rb32(pb);
1268  vert_off.den = avio_rb32(pb);
1269 
1270  if (aperture_width.num < 0 || aperture_width.den < 0 ||
1271  aperture_height.num < 0 || aperture_height.den < 0 ||
1272  horiz_off.den < 0 || vert_off.den < 0) {
1273  err = AVERROR_INVALIDDATA;
1274  goto fail;
1275  }
1276  av_log(c->fc, AV_LOG_TRACE, "clap: apertureWidth %d/%d, apertureHeight %d/%d "
1277  "horizOff %d/%d vertOff %d/%d\n",
1278  aperture_width.num, aperture_width.den, aperture_height.num, aperture_height.den,
1279  horiz_off.num, horiz_off.den, vert_off.num, vert_off.den);
1280 
1281  pc_x = av_mul_q((AVRational) { width - 1, 1 }, (AVRational) { 1, 2 });
1282  pc_x = av_add_q(pc_x, horiz_off);
1283  pc_y = av_mul_q((AVRational) { height - 1, 1 }, (AVRational) { 1, 2 });
1284  pc_y = av_add_q(pc_y, vert_off);
1285 
1286  aperture_width = av_sub_q(aperture_width, (AVRational) { 1, 1 });
1287  aperture_width = av_mul_q(aperture_width, (AVRational) { 1, 2 });
1288  aperture_height = av_sub_q(aperture_height, (AVRational) { 1, 1 });
1289  aperture_height = av_mul_q(aperture_height, (AVRational) { 1, 2 });
1290 
1291  left = av_q2d(av_sub_q(pc_x, aperture_width));
1292  right = av_q2d(av_add_q(pc_x, aperture_width));
1293  top = av_q2d(av_sub_q(pc_y, aperture_height));
1294  bottom = av_q2d(av_add_q(pc_y, aperture_height));
1295 
1296  if (bottom > (height - 1) ||
1297  right > (width - 1)) {
1298  err = AVERROR_INVALIDDATA;
1299  goto fail;
1300  }
1301 
1302  bottom = height - 1 - bottom;
1303  right = width - 1 - right;
1304 
1305  if (!(left | right | top | bottom))
1306  return 0;
1307 
1308  if ((left + right) >= width ||
1309  (top + bottom) >= height) {
1310  err = AVERROR_INVALIDDATA;
1311  goto fail;
1312  }
1313 
1317  sizeof(uint32_t) * 4, 0);
1318  if (!sd)
1319  return AVERROR(ENOMEM);
1320 
1321  AV_WL32A(sd->data, top);
1322  AV_WL32A(sd->data + 4, bottom);
1323  AV_WL32A(sd->data + 8, left);
1324  AV_WL32A(sd->data + 12, right);
1325 
1326 fail:
1327  if (err < 0) {
1328  int explode = !!(c->fc->error_recognition & AV_EF_EXPLODE);
1329  av_log(c->fc, explode ? AV_LOG_ERROR : AV_LOG_WARNING, "Invalid clap box\n");
1330  if (!explode)
1331  err = 0;
1332  }
1333 
1334  return err;
1335 }
1336 
1337 /* This atom overrides any previously set aspect ratio */
1339 {
1340  const int num = avio_rb32(pb);
1341  const int den = avio_rb32(pb);
1342  AVStream *st;
1343  MOVStreamContext *sc;
1344 
1345  if (c->fc->nb_streams < 1)
1346  return 0;
1347  st = c->fc->streams[c->fc->nb_streams-1];
1348  sc = st->priv_data;
1349 
1350  av_log(c->fc, AV_LOG_TRACE, "pasp: hSpacing %d, vSpacing %d\n", num, den);
1351 
1352  if (den != 0) {
1353  sc->h_spacing = num;
1354  sc->v_spacing = den;
1355  }
1356  return 0;
1357 }
1358 
1359 /* this atom contains actual media data */
1361 {
1362  if (atom.size == 0) /* wrong one (MP4) */
1363  return 0;
1364  c->found_mdat=1;
1365  return 0; /* now go for moov */
1366 }
1367 
1368 #define DRM_BLOB_SIZE 56
1369 
1371 {
1372  uint8_t intermediate_key[20];
1373  uint8_t intermediate_iv[20];
1374  uint8_t input[64];
1375  uint8_t output[64];
1376  uint8_t file_checksum[20];
1377  uint8_t calculated_checksum[20];
1378  char checksum_string[2 * sizeof(file_checksum) + 1];
1379  struct AVSHA *sha;
1380  int i;
1381  int ret = 0;
1382  uint8_t *activation_bytes = c->activation_bytes;
1383  uint8_t *fixed_key = c->audible_fixed_key;
1384 
1385  c->aax_mode = 1;
1386 
1387  sha = av_sha_alloc();
1388  if (!sha)
1389  return AVERROR(ENOMEM);
1390  av_free(c->aes_decrypt);
1391  c->aes_decrypt = av_aes_alloc();
1392  if (!c->aes_decrypt) {
1393  ret = AVERROR(ENOMEM);
1394  goto fail;
1395  }
1396 
1397  /* drm blob processing */
1398  avio_read(pb, output, 8); // go to offset 8, absolute position 0x251
1400  avio_read(pb, output, 4); // go to offset 4, absolute position 0x28d
1401  avio_read(pb, file_checksum, 20);
1402 
1403  // required by external tools
1404  ff_data_to_hex(checksum_string, file_checksum, sizeof(file_checksum), 1);
1405  av_log(c->fc, AV_LOG_INFO, "[aax] file checksum == %s\n", checksum_string);
1406 
1407  /* verify activation data */
1408  if (!activation_bytes) {
1409  av_log(c->fc, AV_LOG_WARNING, "[aax] activation_bytes option is missing!\n");
1410  ret = 0; /* allow ffprobe to continue working on .aax files */
1411  goto fail;
1412  }
1413  if (c->activation_bytes_size != 4) {
1414  av_log(c->fc, AV_LOG_FATAL, "[aax] activation_bytes value needs to be 4 bytes!\n");
1415  ret = AVERROR(EINVAL);
1416  goto fail;
1417  }
1418 
1419  /* verify fixed key */
1420  if (c->audible_fixed_key_size != 16) {
1421  av_log(c->fc, AV_LOG_FATAL, "[aax] audible_fixed_key value needs to be 16 bytes!\n");
1422  ret = AVERROR(EINVAL);
1423  goto fail;
1424  }
1425 
1426  /* AAX (and AAX+) key derivation */
1427  av_sha_init(sha, 160);
1428  av_sha_update(sha, fixed_key, 16);
1429  av_sha_update(sha, activation_bytes, 4);
1430  av_sha_final(sha, intermediate_key);
1431  av_sha_init(sha, 160);
1432  av_sha_update(sha, fixed_key, 16);
1433  av_sha_update(sha, intermediate_key, 20);
1434  av_sha_update(sha, activation_bytes, 4);
1435  av_sha_final(sha, intermediate_iv);
1436  av_sha_init(sha, 160);
1437  av_sha_update(sha, intermediate_key, 16);
1438  av_sha_update(sha, intermediate_iv, 16);
1439  av_sha_final(sha, calculated_checksum);
1440  if (memcmp(calculated_checksum, file_checksum, 20)) { // critical error
1441  av_log(c->fc, AV_LOG_ERROR, "[aax] mismatch in checksums!\n");
1443  goto fail;
1444  }
1445  av_aes_init(c->aes_decrypt, intermediate_key, 128, 1);
1446  av_aes_crypt(c->aes_decrypt, output, input, DRM_BLOB_SIZE >> 4, intermediate_iv, 1);
1447  for (i = 0; i < 4; i++) {
1448  // file data (in output) is stored in big-endian mode
1449  if (activation_bytes[i] != output[3 - i]) { // critical error
1450  av_log(c->fc, AV_LOG_ERROR, "[aax] error in drm blob decryption!\n");
1452  goto fail;
1453  }
1454  }
1455  memcpy(c->file_key, output + 8, 16);
1456  memcpy(input, output + 26, 16);
1457  av_sha_init(sha, 160);
1458  av_sha_update(sha, input, 16);
1459  av_sha_update(sha, c->file_key, 16);
1460  av_sha_update(sha, fixed_key, 16);
1461  av_sha_final(sha, c->file_iv);
1462 
1463 fail:
1464  av_free(sha);
1465 
1466  return ret;
1467 }
1468 
1470 {
1471  if (c->audible_key_size != 16) {
1472  av_log(c->fc, AV_LOG_FATAL, "[aaxc] audible_key value needs to be 16 bytes!\n");
1473  return AVERROR(EINVAL);
1474  }
1475 
1476  if (c->audible_iv_size != 16) {
1477  av_log(c->fc, AV_LOG_FATAL, "[aaxc] audible_iv value needs to be 16 bytes!\n");
1478  return AVERROR(EINVAL);
1479  }
1480 
1481  c->aes_decrypt = av_aes_alloc();
1482  if (!c->aes_decrypt) {
1483  return AVERROR(ENOMEM);
1484  }
1485 
1486  memcpy(c->file_key, c->audible_key, 16);
1487  memcpy(c->file_iv, c->audible_iv, 16);
1488  c->aax_mode = 1;
1489 
1490  return 0;
1491 }
1492 
1493 // Audible AAX (and AAX+) bytestream decryption
1494 static int aax_filter(uint8_t *input, int size, MOVContext *c)
1495 {
1496  int blocks = 0;
1497  unsigned char iv[16];
1498 
1499  memcpy(iv, c->file_iv, 16); // iv is overwritten
1500  blocks = size >> 4; // trailing bytes are not encrypted!
1501  av_aes_init(c->aes_decrypt, c->file_key, 128, 1);
1502  av_aes_crypt(c->aes_decrypt, input, input, blocks, iv, 1);
1503 
1504  return 0;
1505 }
1506 
1507 /* read major brand, minor version and compatible brands and store them as metadata */
1509 {
1510  uint32_t minor_ver;
1511  int comp_brand_size;
1512  char* comp_brands_str;
1513  uint8_t type[5] = {0};
1514  int ret = ffio_read_size(pb, type, 4);
1515  if (ret < 0)
1516  return ret;
1517  if (c->fc->nb_streams) {
1518  if (c->fc->strict_std_compliance >= FF_COMPLIANCE_STRICT)
1519  return AVERROR_INVALIDDATA;
1520  av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate FTYP\n");
1521  return 0;
1522  }
1523 
1524  if (strcmp(type, "qt "))
1525  c->isom = 1;
1526  av_log(c->fc, AV_LOG_DEBUG, "ISO: File Type Major Brand: %.4s\n",(char *)&type);
1527  av_dict_set(&c->fc->metadata, "major_brand", type, 0);
1528  minor_ver = avio_rb32(pb); /* minor version */
1529  av_dict_set_int(&c->fc->metadata, "minor_version", minor_ver, 0);
1530 
1531  comp_brand_size = atom.size - 8;
1532  if (comp_brand_size < 0 || comp_brand_size == INT_MAX)
1533  return AVERROR_INVALIDDATA;
1534  comp_brands_str = av_malloc(comp_brand_size + 1); /* Add null terminator */
1535  if (!comp_brands_str)
1536  return AVERROR(ENOMEM);
1537 
1538  ret = ffio_read_size(pb, comp_brands_str, comp_brand_size);
1539  if (ret < 0) {
1540  av_freep(&comp_brands_str);
1541  return ret;
1542  }
1543  comp_brands_str[comp_brand_size] = 0;
1544  av_dict_set(&c->fc->metadata, "compatible_brands",
1545  comp_brands_str, AV_DICT_DONT_STRDUP_VAL);
1546 
1547  // Logic for handling Audible's .aaxc files
1548  if (!strcmp(type, "aaxc")) {
1549  mov_aaxc_crypto(c);
1550  }
1551 
1552  return 0;
1553 }
1554 
1555 /* this atom should contain all header atoms */
1557 {
1558  int ret;
1559 
1560  if (c->found_moov) {
1561  av_log(c->fc, AV_LOG_WARNING, "Found duplicated MOOV Atom. Skipped it\n");
1562  avio_skip(pb, atom.size);
1563  return 0;
1564  }
1565 
1566  if ((ret = mov_read_default(c, pb, atom)) < 0)
1567  return ret;
1568  /* we parsed the 'moov' atom, we can terminate the parsing as soon as we find the 'mdat' */
1569  /* so we don't parse the whole file if over a network */
1570  c->found_moov=1;
1571  return 0; /* now go for mdat */
1572 }
1573 
1575  MOVFragmentIndex *frag_index,
1576  int index,
1577  int id)
1578 {
1579  int i;
1580  MOVFragmentIndexItem * item;
1581 
1582  if (index < 0 || index >= frag_index->nb_items)
1583  return NULL;
1584  item = &frag_index->item[index];
1585  for (i = 0; i < item->nb_stream_info; i++)
1586  if (item->stream_info[i].id == id)
1587  return &item->stream_info[i];
1588 
1589  // This shouldn't happen
1590  return NULL;
1591 }
1592 
1593 static void set_frag_stream(MOVFragmentIndex *frag_index, int id)
1594 {
1595  int i;
1596  MOVFragmentIndexItem * item;
1597 
1598  if (frag_index->current < 0 ||
1599  frag_index->current >= frag_index->nb_items)
1600  return;
1601 
1602  item = &frag_index->item[frag_index->current];
1603  for (i = 0; i < item->nb_stream_info; i++)
1604  if (item->stream_info[i].id == id) {
1605  item->current = i;
1606  return;
1607  }
1608 
1609  // id not found. This shouldn't happen.
1610  item->current = -1;
1611 }
1612 
1614  MOVFragmentIndex *frag_index)
1615 {
1616  MOVFragmentIndexItem *item;
1617  if (frag_index->current < 0 ||
1618  frag_index->current >= frag_index->nb_items)
1619  return NULL;
1620 
1621  item = &frag_index->item[frag_index->current];
1622  if (item->current >= 0 && item->current < item->nb_stream_info)
1623  return &item->stream_info[item->current];
1624 
1625  // This shouldn't happen
1626  return NULL;
1627 }
1628 
1630 {
1631  int a, b, m;
1632  int64_t moof_offset;
1633 
1634  // Optimize for appending new entries
1635  if (!frag_index->nb_items ||
1636  frag_index->item[frag_index->nb_items - 1].moof_offset < offset)
1637  return frag_index->nb_items;
1638 
1639  a = -1;
1640  b = frag_index->nb_items;
1641 
1642  while (b - a > 1) {
1643  m = (a + b) >> 1;
1644  moof_offset = frag_index->item[m].moof_offset;
1645  if (moof_offset >= offset)
1646  b = m;
1647  if (moof_offset <= offset)
1648  a = m;
1649  }
1650  return b;
1651 }
1652 
1654 {
1655  av_assert0(frag_stream_info);
1656  if (frag_stream_info->sidx_pts != AV_NOPTS_VALUE)
1657  return frag_stream_info->sidx_pts;
1658  if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE)
1659  return frag_stream_info->first_tfra_pts;
1660  return frag_stream_info->tfdt_dts;
1661 }
1662 
1664  MOVFragmentIndex *frag_index, int index)
1665 {
1666  MOVFragmentStreamInfo * frag_stream_info;
1667  MOVStreamContext *sc = dst_st->priv_data;
1668  int64_t timestamp;
1669  int i, j;
1670 
1671  // If the stream is referenced by any sidx, limit the search
1672  // to fragments that referenced this stream in the sidx
1673  if (sc->has_sidx) {
1674  frag_stream_info = get_frag_stream_info(frag_index, index, sc->id);
1675  if (frag_stream_info->sidx_pts != AV_NOPTS_VALUE)
1676  return frag_stream_info->sidx_pts;
1677  if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE)
1678  return frag_stream_info->first_tfra_pts;
1679  return frag_stream_info->sidx_pts;
1680  }
1681 
1682  for (i = 0; i < frag_index->item[index].nb_stream_info; i++) {
1683  AVStream *frag_stream = NULL;
1684  frag_stream_info = &frag_index->item[index].stream_info[i];
1685  for (j = 0; j < s->nb_streams; j++) {
1686  MOVStreamContext *sc2 = s->streams[j]->priv_data;
1687  if (sc2->id == frag_stream_info->id)
1688  frag_stream = s->streams[j];
1689  }
1690  if (!frag_stream) {
1691  av_log(s, AV_LOG_WARNING, "No stream matching sidx ID found.\n");
1692  continue;
1693  }
1694  timestamp = get_stream_info_time(frag_stream_info);
1695  if (timestamp != AV_NOPTS_VALUE)
1696  return av_rescale_q(timestamp, frag_stream->time_base, dst_st->time_base);
1697  }
1698  return AV_NOPTS_VALUE;
1699 }
1700 
1702  AVStream *st, int64_t timestamp)
1703 {
1704  int a, b, m, m0;
1705  int64_t frag_time;
1706 
1707  a = -1;
1708  b = frag_index->nb_items;
1709 
1710  while (b - a > 1) {
1711  m0 = m = (a + b) >> 1;
1712 
1713  while (m < b &&
1714  (frag_time = get_frag_time(s, st, frag_index, m)) == AV_NOPTS_VALUE)
1715  m++;
1716 
1717  if (m < b && frag_time <= timestamp)
1718  a = m;
1719  else
1720  b = m0;
1721  }
1722 
1723  return a;
1724 }
1725 
1727 {
1728  int index, i;
1729  MOVFragmentIndexItem * item;
1730  MOVFragmentStreamInfo * frag_stream_info;
1731 
1732  // If moof_offset already exists in frag_index, return index to it
1733  index = search_frag_moof_offset(&c->frag_index, offset);
1734  if (index < c->frag_index.nb_items &&
1735  c->frag_index.item[index].moof_offset == offset)
1736  return index;
1737 
1738  // offset is not yet in frag index.
1739  // Insert new item at index (sorted by moof offset)
1740  item = av_fast_realloc(c->frag_index.item,
1741  &c->frag_index.allocated_size,
1742  (c->frag_index.nb_items + 1) *
1743  sizeof(*c->frag_index.item));
1744  if (!item)
1745  return -1;
1746  c->frag_index.item = item;
1747 
1748  frag_stream_info = av_realloc_array(NULL, c->fc->nb_streams,
1749  sizeof(*item->stream_info));
1750  if (!frag_stream_info)
1751  return -1;
1752 
1753  for (i = 0; i < c->fc->nb_streams; i++) {
1754  // Avoid building frag index if streams lack track id.
1755  MOVStreamContext *sc = c->fc->streams[i]->priv_data;
1756  if (sc->id < 0) {
1757  av_free(frag_stream_info);
1758  return AVERROR_INVALIDDATA;
1759  }
1760 
1761  frag_stream_info[i].id = sc->id;
1762  frag_stream_info[i].sidx_pts = AV_NOPTS_VALUE;
1763  frag_stream_info[i].tfdt_dts = AV_NOPTS_VALUE;
1764  frag_stream_info[i].next_trun_dts = AV_NOPTS_VALUE;
1765  frag_stream_info[i].first_tfra_pts = AV_NOPTS_VALUE;
1766  frag_stream_info[i].index_base = -1;
1767  frag_stream_info[i].index_entry = -1;
1768  frag_stream_info[i].encryption_index = NULL;
1769  frag_stream_info[i].stsd_id = -1;
1770  }
1771 
1772  if (index < c->frag_index.nb_items)
1773  memmove(c->frag_index.item + index + 1, c->frag_index.item + index,
1774  (c->frag_index.nb_items - index) * sizeof(*c->frag_index.item));
1775 
1776  item = &c->frag_index.item[index];
1777  item->headers_read = 0;
1778  item->current = 0;
1779  item->nb_stream_info = c->fc->nb_streams;
1780  item->moof_offset = offset;
1781  item->stream_info = frag_stream_info;
1782  c->frag_index.nb_items++;
1783 
1784  return index;
1785 }
1786 
1787 static void fix_frag_index_entries(MOVFragmentIndex *frag_index, int index,
1788  int id, int entries)
1789 {
1790  int i;
1791  MOVFragmentStreamInfo * frag_stream_info;
1792 
1793  if (index < 0)
1794  return;
1795  for (i = index; i < frag_index->nb_items; i++) {
1796  frag_stream_info = get_frag_stream_info(frag_index, i, id);
1797  if (frag_stream_info && frag_stream_info->index_entry >= 0)
1798  frag_stream_info->index_entry += entries;
1799  }
1800 }
1801 
1803 {
1804  // Set by mov_read_tfhd(). mov_read_trun() will reject files missing tfhd.
1805  c->fragment.found_tfhd = 0;
1806 
1807  if (!c->has_looked_for_mfra && c->use_mfra_for > 0) {
1808  c->has_looked_for_mfra = 1;
1809  if (pb->seekable & AVIO_SEEKABLE_NORMAL) {
1810  int ret;
1811  av_log(c->fc, AV_LOG_VERBOSE, "stream has moof boxes, will look "
1812  "for a mfra\n");
1813  if ((ret = mov_read_mfra(c, pb)) < 0) {
1814  av_log(c->fc, AV_LOG_VERBOSE, "found a moof box but failed to "
1815  "read the mfra (may be a live ismv)\n");
1816  }
1817  } else {
1818  av_log(c->fc, AV_LOG_VERBOSE, "found a moof box but stream is not "
1819  "seekable, can not look for mfra\n");
1820  }
1821  }
1822  c->fragment.moof_offset = c->fragment.implicit_offset = avio_tell(pb) - 8;
1823  av_log(c->fc, AV_LOG_TRACE, "moof offset %"PRIx64"\n", c->fragment.moof_offset);
1824  c->frag_index.current = update_frag_index(c, c->fragment.moof_offset);
1825  return mov_read_default(c, pb, atom);
1826 }
1827 
1829 {
1830  int64_t time;
1831  if (version == 1) {
1832  time = avio_rb64(pb);
1833  avio_rb64(pb);
1834  if (time < 0) {
1835  av_log(c->fc, AV_LOG_DEBUG, "creation_time is negative\n");
1836  return;
1837  }
1838  } else {
1839  time = avio_rb32(pb);
1840  avio_rb32(pb); /* modification time */
1841  if (time > 0 && time < 2082844800) {
1842  av_log(c->fc, AV_LOG_WARNING, "Detected creation time before 1970, parsing as unix timestamp.\n");
1843  time += 2082844800;
1844  }
1845  }
1846  if (time) {
1847  time -= 2082844800; /* seconds between 1904-01-01 and Epoch */
1848 
1849  if ((int64_t)(time * 1000000ULL) / 1000000 != time) {
1850  av_log(c->fc, AV_LOG_DEBUG, "creation_time is not representable\n");
1851  return;
1852  }
1853 
1854  avpriv_dict_set_timestamp(metadata, "creation_time", time * 1000000);
1855  }
1856 }
1857 
1859 {
1860  AVStream *st;
1861  MOVStreamContext *sc;
1862  int version;
1863  char language[4] = {0};
1864  unsigned lang;
1865 
1866  if (c->fc->nb_streams < 1)
1867  return 0;
1868  st = c->fc->streams[c->fc->nb_streams-1];
1869  sc = st->priv_data;
1870 
1871  if (sc->time_scale) {
1872  av_log(c->fc, AV_LOG_ERROR, "Multiple mdhd?\n");
1873  return AVERROR_INVALIDDATA;
1874  }
1875 
1876  version = avio_r8(pb);
1877  if (version > 1) {
1878  avpriv_request_sample(c->fc, "Version %d", version);
1879  return AVERROR_PATCHWELCOME;
1880  }
1881  avio_rb24(pb); /* flags */
1883 
1884  sc->time_scale = avio_rb32(pb);
1885  if (sc->time_scale <= 0) {
1886  av_log(c->fc, AV_LOG_ERROR, "Invalid mdhd time scale %d, defaulting to 1\n", sc->time_scale);
1887  sc->time_scale = 1;
1888  }
1889  st->duration = (version == 1) ? avio_rb64(pb) : avio_rb32(pb); /* duration */
1890 
1891  if ((version == 1 && st->duration == UINT64_MAX) ||
1892  (version != 1 && st->duration == UINT32_MAX)) {
1893  st->duration = 0;
1894  }
1895 
1896  lang = avio_rb16(pb); /* language */
1897  if (ff_mov_lang_to_iso639(lang, language))
1898  av_dict_set(&st->metadata, "language", language, 0);
1899  avio_rb16(pb); /* quality */
1900 
1901  return 0;
1902 }
1903 
1905 {
1906  int i;
1907  int version = avio_r8(pb); /* version */
1908  avio_rb24(pb); /* flags */
1909 
1910  mov_metadata_creation_time(c, pb, &c->fc->metadata, version);
1911  c->time_scale = avio_rb32(pb); /* time scale */
1912  if (c->time_scale <= 0) {
1913  av_log(c->fc, AV_LOG_ERROR, "Invalid mvhd time scale %d, defaulting to 1\n", c->time_scale);
1914  c->time_scale = 1;
1915  }
1916  av_log(c->fc, AV_LOG_TRACE, "time scale = %i\n", c->time_scale);
1917 
1918  c->duration = (version == 1) ? avio_rb64(pb) : avio_rb32(pb); /* duration */
1919  avio_rb32(pb); /* preferred scale */
1920 
1921  avio_rb16(pb); /* preferred volume */
1922 
1923  avio_skip(pb, 10); /* reserved */
1924 
1925  /* movie display matrix, store it in main context and use it later on */
1926  for (i = 0; i < 3; i++) {
1927  c->movie_display_matrix[i][0] = avio_rb32(pb); // 16.16 fixed point
1928  c->movie_display_matrix[i][1] = avio_rb32(pb); // 16.16 fixed point
1929  c->movie_display_matrix[i][2] = avio_rb32(pb); // 2.30 fixed point
1930  }
1931 
1932  avio_rb32(pb); /* preview time */
1933  avio_rb32(pb); /* preview duration */
1934  avio_rb32(pb); /* poster time */
1935  avio_rb32(pb); /* selection time */
1936  avio_rb32(pb); /* selection duration */
1937  avio_rb32(pb); /* current time */
1938  avio_rb32(pb); /* next track ID */
1939 
1940  return 0;
1941 }
1942 
1944 {
1945  AVStream *st;
1946 
1947  if (fc->nb_streams < 1)
1948  return;
1949  st = fc->streams[fc->nb_streams-1];
1950 
1951  switch (st->codecpar->codec_id) {
1952  case AV_CODEC_ID_PCM_S16BE:
1954  break;
1955  case AV_CODEC_ID_PCM_S24BE:
1957  break;
1958  case AV_CODEC_ID_PCM_S32BE:
1960  break;
1961  case AV_CODEC_ID_PCM_F32BE:
1963  break;
1964  case AV_CODEC_ID_PCM_F64BE:
1966  break;
1967  default:
1968  break;
1969  }
1970 }
1971 
1973 {
1974  int little_endian = avio_rb16(pb) & 0xFF;
1975  av_log(c->fc, AV_LOG_TRACE, "enda %d\n", little_endian);
1976  if (little_endian == 1)
1978  return 0;
1979 }
1980 
1982 {
1983  int format_flags;
1984  int version, flags;
1985  int pcm_sample_size;
1986  AVFormatContext *fc = c->fc;
1987  AVStream *st;
1988  MOVStreamContext *sc;
1989 
1990  if (atom.size < 6) {
1991  av_log(c->fc, AV_LOG_ERROR, "Empty pcmC box\n");
1992  return AVERROR_INVALIDDATA;
1993  }
1994 
1995  version = avio_r8(pb);
1996  flags = avio_rb24(pb);
1997 
1998  if (version != 0 || flags != 0) {
1999  av_log(c->fc, AV_LOG_ERROR,
2000  "Unsupported 'pcmC' box with version %d, flags: %x",
2001  version, flags);
2002  return AVERROR_INVALIDDATA;
2003  }
2004 
2005  format_flags = avio_r8(pb);
2006  pcm_sample_size = avio_r8(pb);
2007 
2008  if (fc->nb_streams < 1)
2009  return AVERROR_INVALIDDATA;
2010 
2011  st = fc->streams[fc->nb_streams - 1];
2012  sc = st->priv_data;
2013 
2014  if (sc->format == MOV_MP4_FPCM_TAG) {
2015  switch (pcm_sample_size) {
2016  case 32:
2018  break;
2019  case 64:
2021  break;
2022  default:
2023  av_log(fc, AV_LOG_ERROR, "invalid pcm_sample_size %d for %s\n",
2024  pcm_sample_size,
2025  av_fourcc2str(sc->format));
2026  return AVERROR_INVALIDDATA;
2027  }
2028  } else if (sc->format == MOV_MP4_IPCM_TAG) {
2029  switch (pcm_sample_size) {
2030  case 16:
2032  break;
2033  case 24:
2035  break;
2036  case 32:
2038  break;
2039  default:
2040  av_log(fc, AV_LOG_ERROR, "invalid pcm_sample_size %d for %s\n",
2041  pcm_sample_size,
2042  av_fourcc2str(sc->format));
2043  return AVERROR_INVALIDDATA;
2044  }
2045  } else {
2046  av_log(fc, AV_LOG_ERROR, "'pcmC' with invalid sample entry '%s'\n",
2047  av_fourcc2str(sc->format));
2048  return AVERROR_INVALIDDATA;
2049  }
2050 
2051  if (format_flags & 1) // indicates little-endian format. If not present, big-endian format is used
2054 
2055  return 0;
2056 }
2057 
2059 {
2060  AVStream *st;
2061  HEIFItem *item = NULL;
2062  char color_parameter_type[5] = { 0 };
2063  uint16_t color_primaries, color_trc, color_matrix;
2064  int ret;
2065 
2066  st = get_curr_st(c);
2067  if (!st) {
2068  item = heif_cur_item(c);
2069  if (!item)
2070  return 0;
2071  }
2072 
2073  ret = ffio_read_size(pb, color_parameter_type, 4);
2074  if (ret < 0)
2075  return ret;
2076  if (strncmp(color_parameter_type, "nclx", 4) &&
2077  strncmp(color_parameter_type, "nclc", 4) &&
2078  strncmp(color_parameter_type, "prof", 4)) {
2079  av_log(c->fc, AV_LOG_WARNING, "unsupported color_parameter_type %s\n",
2080  color_parameter_type);
2081  return 0;
2082  }
2083 
2084  if (!strncmp(color_parameter_type, "prof", 4)) {
2085  AVPacketSideData *sd;
2086  uint8_t *icc_profile;
2087  if (st) {
2091  atom.size - 4, 0);
2092  if (!sd)
2093  return AVERROR(ENOMEM);
2094  icc_profile = sd->data;
2095  } else {
2096  av_freep(&item->icc_profile);
2097  icc_profile = item->icc_profile = av_malloc(atom.size - 4);
2098  if (!icc_profile) {
2099  item->icc_profile_size = 0;
2100  return AVERROR(ENOMEM);
2101  }
2102  item->icc_profile_size = atom.size - 4;
2103  }
2104  ret = ffio_read_size(pb, icc_profile, atom.size - 4);
2105  if (ret < 0)
2106  return ret;
2107  } else if (st) {
2108  color_primaries = avio_rb16(pb);
2109  color_trc = avio_rb16(pb);
2110  color_matrix = avio_rb16(pb);
2111 
2112  av_log(c->fc, AV_LOG_TRACE,
2113  "%s: pri %d trc %d matrix %d",
2114  color_parameter_type, color_primaries, color_trc, color_matrix);
2115 
2116  if (!strncmp(color_parameter_type, "nclx", 4)) {
2117  uint8_t color_range = avio_r8(pb) >> 7;
2118  av_log(c->fc, AV_LOG_TRACE, " full %"PRIu8"", color_range);
2119  if (color_range)
2121  else
2123  }
2124 
2127  if (!av_color_transfer_name(color_trc))
2128  color_trc = AVCOL_TRC_UNSPECIFIED;
2129  if (!av_color_space_name(color_matrix))
2130  color_matrix = AVCOL_SPC_UNSPECIFIED;
2131 
2133  st->codecpar->color_trc = color_trc;
2134  st->codecpar->color_space = color_matrix;
2135  av_log(c->fc, AV_LOG_TRACE, "\n");
2136  }
2137  return 0;
2138 }
2139 
2141 {
2142  AVStream *st;
2143  unsigned mov_field_order;
2144  enum AVFieldOrder decoded_field_order = AV_FIELD_UNKNOWN;
2145 
2146  if (c->fc->nb_streams < 1) // will happen with jp2 files
2147  return 0;
2148  st = c->fc->streams[c->fc->nb_streams-1];
2149  if (atom.size < 2)
2150  return AVERROR_INVALIDDATA;
2151  mov_field_order = avio_rb16(pb);
2152  if ((mov_field_order & 0xFF00) == 0x0100)
2153  decoded_field_order = AV_FIELD_PROGRESSIVE;
2154  else if ((mov_field_order & 0xFF00) == 0x0200) {
2155  switch (mov_field_order & 0xFF) {
2156  case 0x01: decoded_field_order = AV_FIELD_TT;
2157  break;
2158  case 0x06: decoded_field_order = AV_FIELD_BB;
2159  break;
2160  case 0x09: decoded_field_order = AV_FIELD_TB;
2161  break;
2162  case 0x0E: decoded_field_order = AV_FIELD_BT;
2163  break;
2164  }
2165  }
2166  if (decoded_field_order == AV_FIELD_UNKNOWN && mov_field_order) {
2167  av_log(c->fc, AV_LOG_ERROR, "Unknown MOV field order 0x%04x\n", mov_field_order);
2168  }
2169  st->codecpar->field_order = decoded_field_order;
2170 
2171  return 0;
2172 }
2173 
2175 {
2176  int err = 0;
2177  uint64_t size = (uint64_t)par->extradata_size + atom.size + 8 + AV_INPUT_BUFFER_PADDING_SIZE;
2178  if (size > INT_MAX || (uint64_t)atom.size > INT_MAX)
2179  return AVERROR_INVALIDDATA;
2180  if ((err = av_reallocp(&par->extradata, size)) < 0) {
2181  par->extradata_size = 0;
2182  return err;
2183  }
2185  return 0;
2186 }
2187 
2188 /* Read a whole atom into the extradata return the size of the atom read, possibly truncated if != atom.size */
2190  AVCodecParameters *par, uint8_t *buf)
2191 {
2192  int64_t result = atom.size;
2193  int err;
2194 
2195  AV_WB32(buf , atom.size + 8);
2196  AV_WL32(buf + 4, atom.type);
2197  err = ffio_read_size(pb, buf + 8, atom.size);
2198  if (err < 0) {
2199  par->extradata_size -= atom.size;
2200  return err;
2201  } else if (err < atom.size) {
2202  av_log(c->fc, AV_LOG_WARNING, "truncated extradata\n");
2203  par->extradata_size -= atom.size - err;
2204  result = err;
2205  }
2206  memset(buf + 8 + err, 0, AV_INPUT_BUFFER_PADDING_SIZE);
2207  return result;
2208 }
2209 
2210 /* FIXME modify QDM2/SVQ3/H.264 decoders to take full atom as extradata */
2212  enum AVCodecID codec_id)
2213 {
2214  AVStream *st;
2215  uint64_t original_size;
2216  int err;
2217 
2218  if (c->fc->nb_streams < 1) // will happen with jp2 files
2219  return 0;
2220  st = c->fc->streams[c->fc->nb_streams-1];
2221 
2222  if (st->codecpar->codec_id != codec_id)
2223  return 0; /* unexpected codec_id - don't mess with extradata */
2224 
2225  original_size = st->codecpar->extradata_size;
2226  err = mov_realloc_extradata(st->codecpar, atom);
2227  if (err)
2228  return err;
2229 
2230  err = mov_read_atom_into_extradata(c, pb, atom, st->codecpar, st->codecpar->extradata + original_size);
2231  if (err < 0)
2232  return err;
2233  return 0; // Note: this is the original behavior to ignore truncation.
2234 }
2235 
2236 /* wrapper functions for reading ALAC/AVS/MJPEG/MJPEG2000 extradata atoms only for those codecs */
2238 {
2239  return mov_read_extradata(c, pb, atom, AV_CODEC_ID_ALAC);
2240 }
2241 
2243 {
2244  return mov_read_extradata(c, pb, atom, AV_CODEC_ID_CAVS);
2245 }
2246 
2248 {
2249  return mov_read_extradata(c, pb, atom, AV_CODEC_ID_JPEG2000);
2250 }
2251 
2253 {
2254  return mov_read_extradata(c, pb, atom, AV_CODEC_ID_R10K);
2255 }
2256 
2258 {
2259  int ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_AVUI);
2260  if (!ret)
2261  ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_DNXHD);
2262  return ret;
2263 }
2264 
2266 {
2267  int ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_TARGA_Y216);
2268 
2269  if (!ret && c->fc->nb_streams >= 1) {
2270  AVCodecParameters *par = c->fc->streams[c->fc->nb_streams-1]->codecpar;
2271  if (par->extradata_size >= 40) {
2272  par->height = AV_RB16(&par->extradata[36]);
2273  par->width = AV_RB16(&par->extradata[38]);
2274  }
2275  }
2276  return ret;
2277 }
2278 
2280 {
2281  if (c->fc->nb_streams >= 1) {
2282  AVStream *const st = c->fc->streams[c->fc->nb_streams - 1];
2283  FFStream *const sti = ffstream(st);
2284  AVCodecParameters *par = st->codecpar;
2285 
2286  if (par->codec_tag == MKTAG('A', 'V', 'i', 'n') &&
2287  par->codec_id == AV_CODEC_ID_H264 &&
2288  atom.size > 11) {
2289  int cid;
2290  avio_skip(pb, 10);
2291  cid = avio_rb16(pb);
2292  /* For AVID AVCI50, force width of 1440 to be able to select the correct SPS and PPS */
2293  if (cid == 0xd4d || cid == 0xd4e)
2294  par->width = 1440;
2295  return 0;
2296  } else if ((par->codec_tag == MKTAG('A', 'V', 'd', '1') ||
2297  par->codec_tag == MKTAG('A', 'V', 'j', '2') ||
2298  par->codec_tag == MKTAG('A', 'V', 'd', 'n')) &&
2299  atom.size >= 24) {
2300  int num, den;
2301  avio_skip(pb, 12);
2302  num = avio_rb32(pb);
2303  den = avio_rb32(pb);
2304  if (num <= 0 || den <= 0)
2305  return 0;
2306  switch (avio_rb32(pb)) {
2307  case 2:
2308  if (den >= INT_MAX / 2)
2309  return 0;
2310  den *= 2;
2311  case 1:
2312  sti->display_aspect_ratio = (AVRational){ num, den };
2313  default:
2314  return 0;
2315  }
2316  }
2317  }
2318 
2319  return mov_read_avid(c, pb, atom);
2320 }
2321 
2323 {
2324  int ret = 0;
2325  int length = 0;
2326  uint64_t original_size;
2327  if (c->fc->nb_streams >= 1) {
2328  AVCodecParameters *par = c->fc->streams[c->fc->nb_streams-1]->codecpar;
2329  if (par->codec_id == AV_CODEC_ID_H264)
2330  return 0;
2331  if (atom.size == 16) {
2332  original_size = par->extradata_size;
2333  ret = mov_realloc_extradata(par, atom);
2334  if (!ret) {
2335  length = mov_read_atom_into_extradata(c, pb, atom, par, par->extradata + original_size);
2336  if (length == atom.size) {
2337  const uint8_t range_value = par->extradata[original_size + 19];
2338  switch (range_value) {
2339  case 1:
2341  break;
2342  case 2:
2344  break;
2345  default:
2346  av_log(c->fc, AV_LOG_WARNING, "ignored unknown aclr value (%d)\n", range_value);
2347  break;
2348  }
2349  ff_dlog(c->fc, "color_range: %d\n", par->color_range);
2350  } else {
2351  /* For some reason the whole atom was not added to the extradata */
2352  av_log(c->fc, AV_LOG_ERROR, "aclr not decoded - incomplete atom\n");
2353  }
2354  } else {
2355  av_log(c->fc, AV_LOG_ERROR, "aclr not decoded - unable to add atom to extradata\n");
2356  }
2357  } else {
2358  av_log(c->fc, AV_LOG_WARNING, "aclr not decoded - unexpected size %"PRId64"\n", atom.size);
2359  }
2360  }
2361 
2362  return ret;
2363 }
2364 
2366 {
2367  return mov_read_extradata(c, pb, atom, AV_CODEC_ID_SVQ3);
2368 }
2369 
2371 {
2372  AVStream *st;
2373  int ret;
2374 
2375  if (c->fc->nb_streams < 1)
2376  return 0;
2377  st = c->fc->streams[c->fc->nb_streams-1];
2378 
2379  if ((uint64_t)atom.size > (1<<30))
2380  return AVERROR_INVALIDDATA;
2381 
2382  if (st->codecpar->codec_id == AV_CODEC_ID_QDM2 ||
2385  // pass all frma atom to codec, needed at least for QDMC and QDM2
2386  ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size);
2387  if (ret < 0)
2388  return ret;
2389  } else if (atom.size > 8) { /* to read frma, esds atoms */
2390  if (st->codecpar->codec_id == AV_CODEC_ID_ALAC && atom.size >= 24) {
2391  uint64_t buffer;
2392  ret = ffio_ensure_seekback(pb, 8);
2393  if (ret < 0)
2394  return ret;
2395  buffer = avio_rb64(pb);
2396  atom.size -= 8;
2397  if ( (buffer & 0xFFFFFFFF) == MKBETAG('f','r','m','a')
2398  && buffer >> 32 <= atom.size
2399  && buffer >> 32 >= 8) {
2400  avio_skip(pb, -8);
2401  atom.size += 8;
2402  } else if (!st->codecpar->extradata_size) {
2403 #define ALAC_EXTRADATA_SIZE 36
2405  if (!st->codecpar->extradata)
2406  return AVERROR(ENOMEM);
2409  AV_WB32(st->codecpar->extradata + 4, MKTAG('a','l','a','c'));
2410  AV_WB64(st->codecpar->extradata + 12, buffer);
2411  avio_read(pb, st->codecpar->extradata + 20, 16);
2412  avio_skip(pb, atom.size - 24);
2413  return 0;
2414  }
2415  }
2416  if ((ret = mov_read_default(c, pb, atom)) < 0)
2417  return ret;
2418  } else
2419  avio_skip(pb, atom.size);
2420  return 0;
2421 }
2422 
2423 /**
2424  * This function reads atom content and puts data in extradata without tag
2425  * nor size unlike mov_read_extradata.
2426  */
2428 {
2429  AVStream *st;
2430  int ret;
2431 
2432  st = get_curr_st(c);
2433  if (!st)
2434  return 0;
2435 
2436  if ((uint64_t)atom.size > (1<<30))
2437  return AVERROR_INVALIDDATA;
2438 
2439  if (atom.type == MKTAG('v','v','c','C')) {
2440  avio_skip(pb, 4);
2441  atom.size -= 4;
2442  }
2443 
2444  if (atom.size >= 10) {
2445  // Broken files created by legacy versions of libavformat will
2446  // wrap a whole fiel atom inside of a glbl atom.
2447  unsigned size = avio_rb32(pb);
2448  unsigned type = avio_rl32(pb);
2449  if (avio_feof(pb))
2450  return AVERROR_INVALIDDATA;
2451  avio_seek(pb, -8, SEEK_CUR);
2452  if (type == MKTAG('f','i','e','l') && size == atom.size)
2453  return mov_read_default(c, pb, atom);
2454  }
2455  if (st->codecpar->extradata_size > 1 && st->codecpar->extradata) {
2456  av_log(c->fc, AV_LOG_WARNING, "ignoring multiple glbl\n");
2457  return 0;
2458  }
2459  ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size);
2460  if (ret < 0)
2461  return ret;
2462  if (atom.type == MKTAG('h','v','c','C') && st->codecpar->codec_tag == MKTAG('d','v','h','1'))
2463  /* HEVC-based Dolby Vision derived from hvc1.
2464  Happens to match with an identifier
2465  previously utilized for DV. Thus, if we have
2466  the hvcC extradata box available as specified,
2467  set codec to HEVC */
2469 
2470  return 0;
2471 }
2472 
2474 {
2475  AVStream *st;
2476  uint8_t profile_level;
2477  int ret;
2478 
2479  if (c->fc->nb_streams < 1)
2480  return 0;
2481  st = c->fc->streams[c->fc->nb_streams-1];
2482 
2483  if (atom.size >= (1<<28) || atom.size < 7)
2484  return AVERROR_INVALIDDATA;
2485 
2486  profile_level = avio_r8(pb);
2487  if ((profile_level & 0xf0) != 0xc0)
2488  return 0;
2489 
2490  avio_seek(pb, 6, SEEK_CUR);
2491  ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size - 7);
2492  if (ret < 0)
2493  return ret;
2494 
2495  return 0;
2496 }
2497 
2499 {
2500  AVStream* st;
2501  MOVStreamContext* sc;
2502 
2503  if (c->fc->nb_streams < 1)
2504  return 0;
2505 
2506  /* For SBAS this should be fine - though beware if someone implements a
2507  * tref atom processor that doesn't drop down to default then this may
2508  * be lost. */
2509  if (atom.size > 4) {
2510  av_log(c->fc, AV_LOG_ERROR, "Only a single tref of type sbas is supported\n");
2511  return AVERROR_PATCHWELCOME;
2512  }
2513 
2514  st = c->fc->streams[c->fc->nb_streams - 1];
2515  sc = st->priv_data;
2516  sc->tref_id = avio_rb32(pb);
2518 
2519  return 0;
2520 }
2521 
2522 /**
2523  * An strf atom is a BITMAPINFOHEADER struct. This struct is 40 bytes itself,
2524  * but can have extradata appended at the end after the 40 bytes belonging
2525  * to the struct.
2526  */
2528 {
2529  AVStream *st;
2530  int ret;
2531 
2532  if (c->fc->nb_streams < 1)
2533  return 0;
2534  if (atom.size <= 40)
2535  return 0;
2536  st = c->fc->streams[c->fc->nb_streams-1];
2537 
2538  if ((uint64_t)atom.size > (1<<30))
2539  return AVERROR_INVALIDDATA;
2540 
2541  avio_skip(pb, 40);
2542  ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size - 40);
2543  if (ret < 0)
2544  return ret;
2545 
2546  return 0;
2547 }
2548 
2550 {
2551  AVStream *st;
2552  MOVStreamContext *sc;
2553  unsigned int i, entries;
2554 
2555  if (c->trak_index < 0) {
2556  av_log(c->fc, AV_LOG_WARNING, "STCO outside TRAK\n");
2557  return 0;
2558  }
2559  if (c->fc->nb_streams < 1)
2560  return 0;
2561  st = c->fc->streams[c->fc->nb_streams-1];
2562  sc = st->priv_data;
2563 
2564  avio_r8(pb); /* version */
2565  avio_rb24(pb); /* flags */
2566 
2567  // Clamp allocation size for `chunk_offsets` -- don't throw an error for an
2568  // invalid count since the EOF path doesn't throw either.
2569  entries = avio_rb32(pb);
2570  entries =
2571  FFMIN(entries,
2572  FFMAX(0, (atom.size - 8) /
2573  (atom.type == MKTAG('s', 't', 'c', 'o') ? 4 : 8)));
2574 
2575  if (!entries)
2576  return 0;
2577 
2578  if (sc->chunk_offsets) {
2579  av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicated STCO atom\n");
2580  return 0;
2581  }
2582 
2583  av_free(sc->chunk_offsets);
2584  sc->chunk_count = 0;
2585  sc->chunk_offsets = av_malloc_array(entries, sizeof(*sc->chunk_offsets));
2586  if (!sc->chunk_offsets)
2587  return AVERROR(ENOMEM);
2588  sc->chunk_count = entries;
2589 
2590  if (atom.type == MKTAG('s','t','c','o'))
2591  for (i = 0; i < entries && !pb->eof_reached; i++)
2592  sc->chunk_offsets[i] = avio_rb32(pb);
2593  else if (atom.type == MKTAG('c','o','6','4'))
2594  for (i = 0; i < entries && !pb->eof_reached; i++) {
2595  sc->chunk_offsets[i] = avio_rb64(pb);
2596  if (sc->chunk_offsets[i] < 0) {
2597  av_log(c->fc, AV_LOG_WARNING, "Impossible chunk_offset\n");
2598  sc->chunk_offsets[i] = 0;
2599  }
2600  }
2601  else
2602  return AVERROR_INVALIDDATA;
2603 
2604  sc->chunk_count = i;
2605 
2606  if (pb->eof_reached) {
2607  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STCO atom\n");
2608  return AVERROR_EOF;
2609  }
2610 
2611  return 0;
2612 }
2613 
2614 static int mov_codec_id(AVStream *st, uint32_t format)
2615 {
2617 
2618  if (id <= 0 &&
2619  ((format & 0xFFFF) == 'm' + ('s' << 8) ||
2620  (format & 0xFFFF) == 'T' + ('S' << 8)))
2622 
2623  if (st->codecpar->codec_type != AVMEDIA_TYPE_VIDEO && id > 0) {
2625  } else if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO &&
2626  /* skip old ASF MPEG-4 tag */
2627  format && format != MKTAG('m','p','4','s')) {
2629  if (id <= 0)
2631  if (id > 0)
2633  else if (st->codecpar->codec_type == AVMEDIA_TYPE_DATA ||
2635  st->codecpar->codec_id == AV_CODEC_ID_NONE)) {
2637  if (id <= 0) {
2639  AV_CODEC_ID_TTML : id;
2640  }
2641 
2642  if (id > 0)
2644  else
2646  }
2647  }
2648 
2649  st->codecpar->codec_tag = format;
2650 
2651  return id;
2652 }
2653 
2655  AVStream *st, MOVStreamContext *sc)
2656 {
2657  uint8_t codec_name[32] = { 0 };
2658  int64_t stsd_start;
2659  unsigned int len;
2660  uint32_t id = 0;
2661 
2662  /* The first 16 bytes of the video sample description are already
2663  * read in ff_mov_read_stsd_entries() */
2664  stsd_start = avio_tell(pb) - 16;
2665 
2666  avio_rb16(pb); /* version */
2667  avio_rb16(pb); /* revision level */
2668  id = avio_rl32(pb); /* vendor */
2669  av_dict_set(&st->metadata, "vendor_id", av_fourcc2str(id), 0);
2670  avio_rb32(pb); /* temporal quality */
2671  avio_rb32(pb); /* spatial quality */
2672 
2673  st->codecpar->width = avio_rb16(pb); /* width */
2674  st->codecpar->height = avio_rb16(pb); /* height */
2675 
2676  avio_rb32(pb); /* horiz resolution */
2677  avio_rb32(pb); /* vert resolution */
2678  avio_rb32(pb); /* data size, always 0 */
2679  avio_rb16(pb); /* frames per samples */
2680 
2681  len = avio_r8(pb); /* codec name, pascal string */
2682  if (len > 31)
2683  len = 31;
2684  mov_read_mac_string(c, pb, len, codec_name, sizeof(codec_name));
2685  if (len < 31)
2686  avio_skip(pb, 31 - len);
2687 
2688  if (codec_name[0])
2689  av_dict_set(&st->metadata, "encoder", codec_name, 0);
2690 
2691  /* codec_tag YV12 triggers an UV swap in rawdec.c */
2692  if (!strncmp(codec_name, "Planar Y'CbCr 8-bit 4:2:0", 25)) {
2693  st->codecpar->codec_tag = MKTAG('I', '4', '2', '0');
2694  st->codecpar->width &= ~1;
2695  st->codecpar->height &= ~1;
2696  }
2697  /* Flash Media Server uses tag H.263 with Sorenson Spark */
2698  if (st->codecpar->codec_tag == MKTAG('H','2','6','3') &&
2699  !strncmp(codec_name, "Sorenson H263", 13))
2701 
2702  st->codecpar->bits_per_coded_sample = avio_rb16(pb); /* depth */
2703 
2704  avio_seek(pb, stsd_start, SEEK_SET);
2705 
2706  if (ff_get_qtpalette(st->codecpar->codec_id, pb, sc->palette)) {
2707  st->codecpar->bits_per_coded_sample &= 0x1F;
2708  sc->has_palette = 1;
2709  }
2710 }
2711 
2713  AVStream *st, MOVStreamContext *sc)
2714 {
2715  int bits_per_sample, flags;
2716  uint16_t version = avio_rb16(pb);
2717  uint32_t id = 0;
2718  AVDictionaryEntry *compatible_brands = av_dict_get(c->fc->metadata, "compatible_brands", NULL, AV_DICT_MATCH_CASE);
2719  int channel_count;
2720 
2721  avio_rb16(pb); /* revision level */
2722  id = avio_rl32(pb); /* vendor */
2723  av_dict_set(&st->metadata, "vendor_id", av_fourcc2str(id), 0);
2724 
2725  channel_count = avio_rb16(pb);
2726 
2728  st->codecpar->ch_layout.nb_channels = channel_count;
2729  st->codecpar->bits_per_coded_sample = avio_rb16(pb); /* sample size */
2730  av_log(c->fc, AV_LOG_TRACE, "audio channels %d\n", channel_count);
2731 
2732  sc->audio_cid = avio_rb16(pb);
2733  avio_rb16(pb); /* packet size = 0 */
2734 
2735  st->codecpar->sample_rate = ((avio_rb32(pb) >> 16));
2736 
2737  // Read QT version 1 fields. In version 0 these do not exist.
2738  av_log(c->fc, AV_LOG_TRACE, "version =%d, isom =%d\n", version, c->isom);
2739  if (!c->isom ||
2740  (compatible_brands && strstr(compatible_brands->value, "qt ")) ||
2741  (sc->stsd_version == 0 && version > 0)) {
2742  if (version == 1) {
2743  sc->samples_per_frame = avio_rb32(pb);
2744  avio_rb32(pb); /* bytes per packet */
2745  sc->bytes_per_frame = avio_rb32(pb);
2746  avio_rb32(pb); /* bytes per sample */
2747  } else if (version == 2) {
2748  avio_rb32(pb); /* sizeof struct only */
2750  channel_count = avio_rb32(pb);
2752  st->codecpar->ch_layout.nb_channels = channel_count;
2753  avio_rb32(pb); /* always 0x7F000000 */
2755 
2756  flags = avio_rb32(pb); /* lpcm format specific flag */
2757  sc->bytes_per_frame = avio_rb32(pb);
2758  sc->samples_per_frame = avio_rb32(pb);
2759  if (st->codecpar->codec_tag == MKTAG('l','p','c','m'))
2760  st->codecpar->codec_id =
2762  flags);
2763  }
2764  if (version == 0 || (version == 1 && sc->audio_cid != -2)) {
2765  /* can't correctly handle variable sized packet as audio unit */
2766  switch (st->codecpar->codec_id) {
2767  case AV_CODEC_ID_MP2:
2768  case AV_CODEC_ID_MP3:
2770  break;
2771  }
2772  }
2773  }
2774 
2775  if (sc->format == 0) {
2776  if (st->codecpar->bits_per_coded_sample == 8)
2777  st->codecpar->codec_id = mov_codec_id(st, MKTAG('r','a','w',' '));
2778  else if (st->codecpar->bits_per_coded_sample == 16)
2779  st->codecpar->codec_id = mov_codec_id(st, MKTAG('t','w','o','s'));
2780  }
2781 
2782  switch (st->codecpar->codec_id) {
2783  case AV_CODEC_ID_PCM_S8:
2784  case AV_CODEC_ID_PCM_U8:
2785  if (st->codecpar->bits_per_coded_sample == 16)
2787  break;
2788  case AV_CODEC_ID_PCM_S16LE:
2789  case AV_CODEC_ID_PCM_S16BE:
2790  if (st->codecpar->bits_per_coded_sample == 8)
2792  else if (st->codecpar->bits_per_coded_sample == 24)
2793  st->codecpar->codec_id =
2796  else if (st->codecpar->bits_per_coded_sample == 32)
2797  st->codecpar->codec_id =
2800  break;
2801  /* set values for old format before stsd version 1 appeared */
2802  case AV_CODEC_ID_MACE3:
2803  sc->samples_per_frame = 6;
2805  break;
2806  case AV_CODEC_ID_MACE6:
2807  sc->samples_per_frame = 6;
2809  break;
2811  sc->samples_per_frame = 64;
2813  break;
2814  case AV_CODEC_ID_GSM:
2815  sc->samples_per_frame = 160;
2816  sc->bytes_per_frame = 33;
2817  break;
2818  default:
2819  break;
2820  }
2821 
2822  bits_per_sample = av_get_bits_per_sample(st->codecpar->codec_id);
2823  if (bits_per_sample && (bits_per_sample >> 3) * (uint64_t)st->codecpar->ch_layout.nb_channels <= INT_MAX) {
2824  st->codecpar->bits_per_coded_sample = bits_per_sample;
2825  sc->sample_size = (bits_per_sample >> 3) * st->codecpar->ch_layout.nb_channels;
2826  }
2827 }
2828 
2830  AVStream *st, MOVStreamContext *sc,
2831  int64_t size)
2832 {
2833  // ttxt stsd contains display flags, justification, background
2834  // color, fonts, and default styles, so fake an atom to read it
2835  MOVAtom fake_atom = { .size = size };
2836  // mp4s contains a regular esds atom, dfxp ISMV TTML has no content
2837  // in extradata unlike stpp MP4 TTML.
2838  if (st->codecpar->codec_tag != AV_RL32("mp4s") &&
2840  mov_read_glbl(c, pb, fake_atom);
2841  st->codecpar->width = sc->width;
2842  st->codecpar->height = sc->height;
2843 }
2844 
2845 static uint32_t yuv_to_rgba(uint32_t ycbcr)
2846 {
2847  uint8_t r, g, b;
2848  int y, cb, cr;
2849 
2850  y = (ycbcr >> 16) & 0xFF;
2851  cr = (ycbcr >> 8) & 0xFF;
2852  cb = ycbcr & 0xFF;
2853 
2854  b = av_clip_uint8((1164 * (y - 16) + 2018 * (cb - 128)) / 1000);
2855  g = av_clip_uint8((1164 * (y - 16) - 813 * (cr - 128) - 391 * (cb - 128)) / 1000);
2856  r = av_clip_uint8((1164 * (y - 16) + 1596 * (cr - 128) ) / 1000);
2857 
2858  return (r << 16) | (g << 8) | b;
2859 }
2860 
2862 {
2863  char buf[256] = {0};
2864  uint8_t *src = st->codecpar->extradata;
2865  int i, ret;
2866 
2867  if (st->codecpar->extradata_size != 64)
2868  return 0;
2869 
2870  if (st->codecpar->width > 0 && st->codecpar->height > 0)
2871  snprintf(buf, sizeof(buf), "size: %dx%d\n",
2872  st->codecpar->width, st->codecpar->height);
2873  av_strlcat(buf, "palette: ", sizeof(buf));
2874 
2875  for (i = 0; i < 16; i++) {
2876  uint32_t yuv = AV_RB32(src + i * 4);
2877  uint32_t rgba = yuv_to_rgba(yuv);
2878 
2879  av_strlcatf(buf, sizeof(buf), "%06"PRIx32"%s", rgba, i != 15 ? ", " : "");
2880  }
2881 
2882  if (av_strlcat(buf, "\n", sizeof(buf)) >= sizeof(buf))
2883  return 0;
2884 
2885  ret = ff_alloc_extradata(st->codecpar, strlen(buf));
2886  if (ret < 0)
2887  return ret;
2888  memcpy(st->codecpar->extradata, buf, st->codecpar->extradata_size);
2889 
2890  return 0;
2891 }
2892 
2894  AVStream *st, MOVStreamContext *sc,
2895  int64_t size)
2896 {
2897  int ret;
2898 
2899  if (st->codecpar->codec_tag == MKTAG('t','m','c','d')) {
2900  if ((int)size != size)
2901  return AVERROR(ENOMEM);
2902 
2903  ret = ff_get_extradata(c->fc, st->codecpar, pb, size);
2904  if (ret < 0)
2905  return ret;
2906  if (size > 16) {
2907  MOVStreamContext *tmcd_ctx = st->priv_data;
2908  int val;
2909  val = AV_RB32(st->codecpar->extradata + 4);
2910  tmcd_ctx->tmcd_flags = val;
2911  st->avg_frame_rate.num = AV_RB32(st->codecpar->extradata + 8); /* timescale */
2912  st->avg_frame_rate.den = AV_RB32(st->codecpar->extradata + 12); /* frameDuration */
2913  tmcd_ctx->tmcd_nb_frames = st->codecpar->extradata[16]; /* number of frames */
2914  if (size > 30) {
2915  uint32_t len = AV_RB32(st->codecpar->extradata + 18); /* name atom length */
2916  uint32_t format = AV_RB32(st->codecpar->extradata + 22);
2917  if (format == AV_RB32("name") && (int64_t)size >= (int64_t)len + 18) {
2918  uint16_t str_size = AV_RB16(st->codecpar->extradata + 26); /* string length */
2919  if (str_size > 0 && size >= (int)str_size + 30 &&
2920  st->codecpar->extradata[30] /* Don't add empty string */) {
2921  char *reel_name = av_malloc(str_size + 1);
2922  if (!reel_name)
2923  return AVERROR(ENOMEM);
2924  memcpy(reel_name, st->codecpar->extradata + 30, str_size);
2925  reel_name[str_size] = 0; /* Add null terminator */
2926  av_dict_set(&st->metadata, "reel_name", reel_name,
2928  }
2929  }
2930  }
2931  }
2932  } else {
2933  /* other codec type, just skip (rtp, mp4s ...) */
2934  avio_skip(pb, size);
2935  }
2936  return 0;
2937 }
2938 
2940  AVStream *st, MOVStreamContext *sc)
2941 {
2942  FFStream *const sti = ffstream(st);
2943 
2944  if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
2945  !st->codecpar->sample_rate && sc->time_scale > 1)
2946  st->codecpar->sample_rate = sc->time_scale;
2947 
2948  /* special codec parameters handling */
2949  switch (st->codecpar->codec_id) {
2950 #if CONFIG_DV_DEMUXER
2951  case AV_CODEC_ID_DVAUDIO:
2952  if (c->dv_fctx) {
2953  avpriv_request_sample(c->fc, "multiple DV audio streams");
2954  return AVERROR(ENOSYS);
2955  }
2956 
2957  c->dv_fctx = avformat_alloc_context();
2958  if (!c->dv_fctx) {
2959  av_log(c->fc, AV_LOG_ERROR, "dv demux context alloc error\n");
2960  return AVERROR(ENOMEM);
2961  }
2962  c->dv_demux = avpriv_dv_init_demux(c->dv_fctx);
2963  if (!c->dv_demux) {
2964  av_log(c->fc, AV_LOG_ERROR, "dv demux context init error\n");
2965  return AVERROR(ENOMEM);
2966  }
2967  sc->dv_audio_container = 1;
2969  break;
2970 #endif
2971  /* no ifdef since parameters are always those */
2972  case AV_CODEC_ID_QCELP:
2975  // force sample rate for qcelp when not stored in mov
2976  if (st->codecpar->codec_tag != MKTAG('Q','c','l','p'))
2977  st->codecpar->sample_rate = 8000;
2978  // FIXME: Why is the following needed for some files?
2979  sc->samples_per_frame = 160;
2980  if (!sc->bytes_per_frame)
2981  sc->bytes_per_frame = 35;
2982  break;
2983  case AV_CODEC_ID_AMR_NB:
2986  /* force sample rate for amr, stsd in 3gp does not store sample rate */
2987  st->codecpar->sample_rate = 8000;
2988  break;
2989  case AV_CODEC_ID_AMR_WB:
2992  st->codecpar->sample_rate = 16000;
2993  break;
2994  case AV_CODEC_ID_MP2:
2995  case AV_CODEC_ID_MP3:
2996  /* force type after stsd for m1a hdlr */
2998  break;
2999  case AV_CODEC_ID_GSM:
3000  case AV_CODEC_ID_ADPCM_MS:
3002  case AV_CODEC_ID_ILBC:
3003  case AV_CODEC_ID_MACE3:
3004  case AV_CODEC_ID_MACE6:
3005  case AV_CODEC_ID_QDM2:
3007  break;
3008  case AV_CODEC_ID_ALAC:
3009  if (st->codecpar->extradata_size == 36) {
3010  int channel_count = AV_RB8(st->codecpar->extradata + 21);
3011  if (st->codecpar->ch_layout.nb_channels != channel_count) {
3014  st->codecpar->ch_layout.nb_channels = channel_count;
3015  }
3016  st->codecpar->sample_rate = AV_RB32(st->codecpar->extradata + 32);
3017  }
3018  break;
3019  case AV_CODEC_ID_AC3:
3020  case AV_CODEC_ID_EAC3:
3022  case AV_CODEC_ID_VC1:
3023  case AV_CODEC_ID_VP8:
3024  case AV_CODEC_ID_VP9:
3026  break;
3027  case AV_CODEC_ID_EVC:
3028  case AV_CODEC_ID_AV1:
3029  /* field_order detection of H264 requires parsing */
3030  case AV_CODEC_ID_H264:
3032  break;
3033  default:
3034  break;
3035  }
3036  return 0;
3037 }
3038 
3040  int codec_tag, int format,
3041  int64_t size)
3042 {
3043  if (codec_tag &&
3044  (codec_tag != format &&
3045  // AVID 1:1 samples with differing data format and codec tag exist
3046  (codec_tag != AV_RL32("AV1x") || format != AV_RL32("AVup")) &&
3047  // prores is allowed to have differing data format and codec tag
3048  codec_tag != AV_RL32("apcn") && codec_tag != AV_RL32("apch") &&
3049  // so is dv (sigh)
3050  codec_tag != AV_RL32("dvpp") && codec_tag != AV_RL32("dvcp") &&
3051  (c->fc->video_codec_id ? ff_codec_get_id(ff_codec_movvideo_tags, format) != c->fc->video_codec_id
3052  : codec_tag != MKTAG('j','p','e','g')))) {
3053  /* Multiple fourcc, we skip JPEG. This is not correct, we should
3054  * export it as a separate AVStream but this needs a few changes
3055  * in the MOV demuxer, patch welcome. */
3056 
3057  av_log(c->fc, AV_LOG_WARNING, "multiple fourcc not supported\n");
3058  avio_skip(pb, size);
3059  return 1;
3060  }
3061 
3062  return 0;
3063 }
3064 
3066 {
3067  AVStream *st;
3068  MOVStreamContext *sc;
3069  int pseudo_stream_id;
3070 
3071  av_assert0 (c->fc->nb_streams >= 1);
3072  st = c->fc->streams[c->fc->nb_streams-1];
3073  sc = st->priv_data;
3074 
3075  for (pseudo_stream_id = 0;
3076  pseudo_stream_id < entries && !pb->eof_reached;
3077  pseudo_stream_id++) {
3078  //Parsing Sample description table
3079  enum AVCodecID id;
3080  int ret, dref_id = 1;
3081  MOVAtom a = { AV_RL32("stsd") };
3082  int64_t start_pos = avio_tell(pb);
3083  int64_t size = avio_rb32(pb); /* size */
3084  uint32_t format = avio_rl32(pb); /* data format */
3085 
3086  if (size >= 16) {
3087  avio_rb32(pb); /* reserved */
3088  avio_rb16(pb); /* reserved */
3089  dref_id = avio_rb16(pb);
3090  } else if (size <= 7) {
3091  av_log(c->fc, AV_LOG_ERROR,
3092  "invalid size %"PRId64" in stsd\n", size);
3093  return AVERROR_INVALIDDATA;
3094  }
3095 
3097  size - (avio_tell(pb) - start_pos))) {
3098  sc->stsd_count++;
3099  continue;
3100  }
3101 
3102  sc->pseudo_stream_id = st->codecpar->codec_tag ? -1 : pseudo_stream_id;
3103  sc->dref_id= dref_id;
3104  sc->format = format;
3105 
3106  id = mov_codec_id(st, format);
3107 
3108  av_log(c->fc, AV_LOG_TRACE,
3109  "size=%"PRId64" 4CC=%s codec_type=%d\n", size,
3111 
3112  st->codecpar->codec_id = id;
3114  mov_parse_stsd_video(c, pb, st, sc);
3115  } else if (st->codecpar->codec_type==AVMEDIA_TYPE_AUDIO) {
3116  mov_parse_stsd_audio(c, pb, st, sc);
3117  if (st->codecpar->sample_rate < 0) {
3118  av_log(c->fc, AV_LOG_ERROR, "Invalid sample rate %d\n", st->codecpar->sample_rate);
3119  return AVERROR_INVALIDDATA;
3120  }
3121  if (st->codecpar->ch_layout.nb_channels < 0) {
3122  av_log(c->fc, AV_LOG_ERROR, "Invalid channels %d\n", st->codecpar->ch_layout.nb_channels);
3123  return AVERROR_INVALIDDATA;
3124  }
3125  } else if (st->codecpar->codec_type==AVMEDIA_TYPE_SUBTITLE){
3126  mov_parse_stsd_subtitle(c, pb, st, sc,
3127  size - (avio_tell(pb) - start_pos));
3128  } else {
3129  ret = mov_parse_stsd_data(c, pb, st, sc,
3130  size - (avio_tell(pb) - start_pos));
3131  if (ret < 0)
3132  return ret;
3133  }
3134  /* this will read extra atoms at the end (wave, alac, damr, avcC, hvcC, SMI ...) */
3135  a.size = size - (avio_tell(pb) - start_pos);
3136  if (a.size > 8) {
3137  if ((ret = mov_read_default(c, pb, a)) < 0)
3138  return ret;
3139  } else if (a.size > 0)
3140  avio_skip(pb, a.size);
3141 
3142  if (sc->extradata && st->codecpar->extradata) {
3143  int extra_size = st->codecpar->extradata_size;
3144 
3145  /* Move the current stream extradata to the stream context one. */
3146  sc->extradata_size[pseudo_stream_id] = extra_size;
3147  sc->extradata[pseudo_stream_id] = st->codecpar->extradata;
3148  st->codecpar->extradata = NULL;
3149  st->codecpar->extradata_size = 0;
3150  }
3151  sc->stsd_count++;
3152  }
3153 
3154  if (pb->eof_reached) {
3155  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSD atom\n");
3156  return AVERROR_EOF;
3157  }
3158 
3159  return 0;
3160 }
3161 
3163 {
3164  AVStream *st;
3165  MOVStreamContext *sc;
3166  int ret, entries;
3167 
3168  if (c->fc->nb_streams < 1)
3169  return 0;
3170  st = c->fc->streams[c->fc->nb_streams - 1];
3171  sc = st->priv_data;
3172 
3173  sc->stsd_version = avio_r8(pb);
3174  avio_rb24(pb); /* flags */
3175  entries = avio_rb32(pb);
3176 
3177  /* Each entry contains a size (4 bytes) and format (4 bytes). */
3178  if (entries <= 0 || entries > atom.size / 8 || entries > 1024) {
3179  av_log(c->fc, AV_LOG_ERROR, "invalid STSD entries %d\n", entries);
3180  return AVERROR_INVALIDDATA;
3181  }
3182 
3183  if (sc->extradata) {
3184  av_log(c->fc, AV_LOG_ERROR,
3185  "Duplicate stsd found in this track.\n");
3186  return AVERROR_INVALIDDATA;
3187  }
3188 
3189  /* Prepare space for hosting multiple extradata. */
3190  sc->extradata = av_calloc(entries, sizeof(*sc->extradata));
3191  if (!sc->extradata)
3192  return AVERROR(ENOMEM);
3193 
3194  sc->extradata_size = av_calloc(entries, sizeof(*sc->extradata_size));
3195  if (!sc->extradata_size) {
3196  ret = AVERROR(ENOMEM);
3197  goto fail;
3198  }
3199 
3200  ret = ff_mov_read_stsd_entries(c, pb, entries);
3201  if (ret < 0)
3202  goto fail;
3203 
3204  /* Restore back the primary extradata. */
3205  av_freep(&st->codecpar->extradata);
3206  st->codecpar->extradata_size = sc->extradata_size[0];
3207  if (sc->extradata_size[0]) {
3209  if (!st->codecpar->extradata)
3210  return AVERROR(ENOMEM);
3211  memcpy(st->codecpar->extradata, sc->extradata[0], sc->extradata_size[0]);
3212  }
3213 
3214  return mov_finalize_stsd_codec(c, pb, st, sc);
3215 fail:
3216  if (sc->extradata) {
3217  int j;
3218  for (j = 0; j < sc->stsd_count; j++)
3219  av_freep(&sc->extradata[j]);
3220  }
3221 
3222  av_freep(&sc->extradata);
3223  av_freep(&sc->extradata_size);
3224  return ret;
3225 }
3226 
3228 {
3229  AVStream *st;
3230  MOVStreamContext *sc;
3231  unsigned int i, entries;
3232 
3233  if (c->trak_index < 0) {
3234  av_log(c->fc, AV_LOG_WARNING, "STSC outside TRAK\n");
3235  return 0;
3236  }
3237 
3238  if (c->fc->nb_streams < 1)
3239  return 0;
3240  st = c->fc->streams[c->fc->nb_streams-1];
3241  sc = st->priv_data;
3242 
3243  avio_r8(pb); /* version */
3244  avio_rb24(pb); /* flags */
3245 
3246  entries = avio_rb32(pb);
3247  if ((uint64_t)entries * 12 + 4 > atom.size)
3248  return AVERROR_INVALIDDATA;
3249 
3250  av_log(c->fc, AV_LOG_TRACE, "track[%u].stsc.entries = %u\n", c->fc->nb_streams - 1, entries);
3251 
3252  if (!entries)
3253  return 0;
3254  if (sc->stsc_data) {
3255  av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicated STSC atom\n");
3256  return 0;
3257  }
3258  av_free(sc->stsc_data);
3259  sc->stsc_count = 0;
3260  sc->stsc_data = av_malloc_array(entries, sizeof(*sc->stsc_data));
3261  if (!sc->stsc_data)
3262  return AVERROR(ENOMEM);
3263 
3264  for (i = 0; i < entries && !pb->eof_reached; i++) {
3265  sc->stsc_data[i].first = avio_rb32(pb);
3266  sc->stsc_data[i].count = avio_rb32(pb);
3267  sc->stsc_data[i].id = avio_rb32(pb);
3268  }
3269 
3270  sc->stsc_count = i;
3271  for (i = sc->stsc_count - 1; i < UINT_MAX; i--) {
3272  int64_t first_min = i + 1;
3273  if ((i+1 < sc->stsc_count && sc->stsc_data[i].first >= sc->stsc_data[i+1].first) ||
3274  (i > 0 && sc->stsc_data[i].first <= sc->stsc_data[i-1].first) ||
3275  sc->stsc_data[i].first < first_min ||
3276  sc->stsc_data[i].count < 1 ||
3277  sc->stsc_data[i].id < 1) {
3278  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);
3279  if (i+1 >= sc->stsc_count) {
3280  if (sc->stsc_data[i].count == 0 && i > 0) {
3281  sc->stsc_count --;
3282  continue;
3283  }
3284  sc->stsc_data[i].first = FFMAX(sc->stsc_data[i].first, first_min);
3285  if (i > 0 && sc->stsc_data[i].first <= sc->stsc_data[i-1].first)
3286  sc->stsc_data[i].first = FFMIN(sc->stsc_data[i-1].first + 1LL, INT_MAX);
3287  sc->stsc_data[i].count = FFMAX(sc->stsc_data[i].count, 1);
3288  sc->stsc_data[i].id = FFMAX(sc->stsc_data[i].id, 1);
3289  continue;
3290  }
3291  av_assert0(sc->stsc_data[i+1].first >= 2);
3292  // We replace this entry by the next valid
3293  sc->stsc_data[i].first = sc->stsc_data[i+1].first - 1;
3294  sc->stsc_data[i].count = sc->stsc_data[i+1].count;
3295  sc->stsc_data[i].id = sc->stsc_data[i+1].id;
3296  }
3297  }
3298 
3299  if (pb->eof_reached) {
3300  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSC atom\n");
3301  return AVERROR_EOF;
3302  }
3303 
3304  return 0;
3305 }
3306 
3307 static inline int mov_stsc_index_valid(unsigned int index, unsigned int count)
3308 {
3309  return index < count - 1;
3310 }
3311 
3312 /* Compute the samples value for the stsc entry at the given index. */
3313 static inline int64_t mov_get_stsc_samples(MOVStreamContext *sc, unsigned int index)
3314 {
3315  int chunk_count;
3316 
3318  chunk_count = sc->stsc_data[index + 1].first - sc->stsc_data[index].first;
3319  else {
3320  // Validation for stsc / stco happens earlier in mov_read_stsc + mov_read_trak.
3322  chunk_count = sc->chunk_count - (sc->stsc_data[index].first - 1);
3323  }
3324 
3325  return sc->stsc_data[index].count * (int64_t)chunk_count;
3326 }
3327 
3329 {
3330  AVStream *st;
3331  MOVStreamContext *sc;
3332  unsigned i, entries;
3333 
3334  if (c->trak_index < 0) {
3335  av_log(c->fc, AV_LOG_WARNING, "STPS outside TRAK\n");
3336  return 0;
3337  }
3338 
3339  if (c->fc->nb_streams < 1)
3340  return 0;
3341  st = c->fc->streams[c->fc->nb_streams-1];
3342  sc = st->priv_data;
3343 
3344  avio_rb32(pb); // version + flags
3345 
3346  entries = avio_rb32(pb);
3347  if (sc->stps_data)
3348  av_log(c->fc, AV_LOG_WARNING, "Duplicated STPS atom\n");
3349  av_free(sc->stps_data);
3350  sc->stps_count = 0;
3351  sc->stps_data = av_malloc_array(entries, sizeof(*sc->stps_data));
3352  if (!sc->stps_data)
3353  return AVERROR(ENOMEM);
3354 
3355  for (i = 0; i < entries && !pb->eof_reached; i++) {
3356  sc->stps_data[i] = avio_rb32(pb);
3357  }
3358 
3359  sc->stps_count = i;
3360 
3361  if (pb->eof_reached) {
3362  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STPS atom\n");
3363  return AVERROR_EOF;
3364  }
3365 
3366  return 0;
3367 }
3368 
3370 {
3371  AVStream *st;
3372  FFStream *sti;
3373  MOVStreamContext *sc;
3374  unsigned int i, entries;
3375 
3376  if (c->trak_index < 0) {
3377  av_log(c->fc, AV_LOG_WARNING, "STSS outside TRAK\n");
3378  return 0;
3379  }
3380 
3381  if (c->fc->nb_streams < 1)
3382  return 0;
3383  st = c->fc->streams[c->fc->nb_streams-1];
3384  sti = ffstream(st);
3385  sc = st->priv_data;
3386 
3387  avio_r8(pb); /* version */
3388  avio_rb24(pb); /* flags */
3389 
3390  entries = avio_rb32(pb);
3391 
3392  av_log(c->fc, AV_LOG_TRACE, "keyframe_count = %u\n", entries);
3393 
3394  if (!entries) {
3395  sc->keyframe_absent = 1;
3396  if (!sti->need_parsing && st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
3398  return 0;
3399  }
3400  if (sc->keyframes)
3401  av_log(c->fc, AV_LOG_WARNING, "Duplicated STSS atom\n");
3402  if (entries >= UINT_MAX / sizeof(int))
3403  return AVERROR_INVALIDDATA;
3404  av_freep(&sc->keyframes);
3405  sc->keyframe_count = 0;
3406  sc->keyframes = av_malloc_array(entries, sizeof(*sc->keyframes));
3407  if (!sc->keyframes)
3408  return AVERROR(ENOMEM);
3409 
3410  for (i = 0; i < entries && !pb->eof_reached; i++) {
3411  sc->keyframes[i] = avio_rb32(pb);
3412  }
3413 
3414  sc->keyframe_count = i;
3415 
3416  if (pb->eof_reached) {
3417  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSS atom\n");
3418  return AVERROR_EOF;
3419  }
3420 
3421  return 0;
3422 }
3423 
3425 {
3426  AVStream *st;
3427  MOVStreamContext *sc;
3428  unsigned int i, entries, sample_size, field_size, num_bytes;
3429  GetBitContext gb;
3430  unsigned char* buf;
3431  int ret;
3432 
3433  if (c->trak_index < 0) {
3434  av_log(c->fc, AV_LOG_WARNING, "STSZ outside TRAK\n");
3435  return 0;
3436  }
3437 
3438  if (c->fc->nb_streams < 1)
3439  return 0;
3440  st = c->fc->streams[c->fc->nb_streams-1];
3441  sc = st->priv_data;
3442 
3443  avio_r8(pb); /* version */
3444  avio_rb24(pb); /* flags */
3445 
3446  if (atom.type == MKTAG('s','t','s','z')) {
3447  sample_size = avio_rb32(pb);
3448  if (!sc->sample_size) /* do not overwrite value computed in stsd */
3449  sc->sample_size = sample_size;
3450  sc->stsz_sample_size = sample_size;
3451  field_size = 32;
3452  } else {
3453  sample_size = 0;
3454  avio_rb24(pb); /* reserved */
3455  field_size = avio_r8(pb);
3456  }
3457  entries = avio_rb32(pb);
3458 
3459  av_log(c->fc, AV_LOG_TRACE, "sample_size = %u sample_count = %u\n", sc->sample_size, entries);
3460 
3461  sc->sample_count = entries;
3462  if (sample_size)
3463  return 0;
3464 
3465  if (field_size != 4 && field_size != 8 && field_size != 16 && field_size != 32) {
3466  av_log(c->fc, AV_LOG_ERROR, "Invalid sample field size %u\n", field_size);
3467  return AVERROR_INVALIDDATA;
3468  }
3469 
3470  if (!entries)
3471  return 0;
3472  if (entries >= (INT_MAX - 4 - 8 * AV_INPUT_BUFFER_PADDING_SIZE) / field_size)
3473  return AVERROR_INVALIDDATA;
3474  if (sc->sample_sizes)
3475  av_log(c->fc, AV_LOG_WARNING, "Duplicated STSZ atom\n");
3476  av_free(sc->sample_sizes);
3477  sc->sample_count = 0;
3478  sc->sample_sizes = av_malloc_array(entries, sizeof(*sc->sample_sizes));
3479  if (!sc->sample_sizes)
3480  return AVERROR(ENOMEM);
3481 
3482  num_bytes = (entries*field_size+4)>>3;
3483 
3484  buf = av_malloc(num_bytes+AV_INPUT_BUFFER_PADDING_SIZE);
3485  if (!buf) {
3486  av_freep(&sc->sample_sizes);
3487  return AVERROR(ENOMEM);
3488  }
3489 
3490  ret = ffio_read_size(pb, buf, num_bytes);
3491  if (ret < 0) {
3492  av_freep(&sc->sample_sizes);
3493  av_free(buf);
3494  av_log(c->fc, AV_LOG_WARNING, "STSZ atom truncated\n");
3495  return 0;
3496  }
3497 
3498  init_get_bits(&gb, buf, 8*num_bytes);
3499 
3500  for (i = 0; i < entries; i++) {
3501  sc->sample_sizes[i] = get_bits_long(&gb, field_size);
3502  if (sc->sample_sizes[i] > INT64_MAX - sc->data_size) {
3503  av_free(buf);
3504  av_log(c->fc, AV_LOG_ERROR, "Sample size overflow in STSZ\n");
3505  return AVERROR_INVALIDDATA;
3506  }
3507  sc->data_size += sc->sample_sizes[i];
3508  }
3509 
3510  sc->sample_count = i;
3511 
3512  av_free(buf);
3513 
3514  return 0;
3515 }
3516 
3518 {
3519  AVStream *st;
3520  MOVStreamContext *sc;
3521  unsigned int i, entries, alloc_size = 0;
3522  int64_t duration = 0;
3523  int64_t total_sample_count = 0;
3524  int64_t current_dts = 0;
3525  int64_t corrected_dts = 0;
3526 
3527  if (c->trak_index < 0) {
3528  av_log(c->fc, AV_LOG_WARNING, "STTS outside TRAK\n");
3529  return 0;
3530  }
3531 
3532  if (c->fc->nb_streams < 1)
3533  return 0;
3534  st = c->fc->streams[c->fc->nb_streams-1];
3535  sc = st->priv_data;
3536 
3537  avio_r8(pb); /* version */
3538  avio_rb24(pb); /* flags */
3539  entries = avio_rb32(pb);
3540 
3541  av_log(c->fc, AV_LOG_TRACE, "track[%u].stts.entries = %u\n",
3542  c->fc->nb_streams-1, entries);
3543 
3544  if (sc->stts_data)
3545  av_log(c->fc, AV_LOG_WARNING, "Duplicated STTS atom\n");
3546  av_freep(&sc->stts_data);
3547  sc->stts_count = 0;
3548  if (entries >= INT_MAX / sizeof(*sc->stts_data))
3549  return AVERROR(ENOMEM);
3550 
3551  for (i = 0; i < entries && !pb->eof_reached; i++) {
3552  unsigned int sample_duration;
3553  unsigned int sample_count;
3554  unsigned int min_entries = FFMIN(FFMAX(i + 1, 1024 * 1024), entries);
3555  MOVStts *stts_data = av_fast_realloc(sc->stts_data, &alloc_size,
3556  min_entries * sizeof(*sc->stts_data));
3557  if (!stts_data) {
3558  av_freep(&sc->stts_data);
3559  sc->stts_count = 0;
3560  return AVERROR(ENOMEM);
3561  }
3562  sc->stts_count = min_entries;
3563  sc->stts_data = stts_data;
3564 
3565  sample_count = avio_rb32(pb);
3566  sample_duration = avio_rb32(pb);
3567 
3568  sc->stts_data[i].count= sample_count;
3569  sc->stts_data[i].duration= sample_duration;
3570 
3571  av_log(c->fc, AV_LOG_TRACE, "sample_count=%u, sample_duration=%u\n",
3572  sample_count, sample_duration);
3573 
3574  /* STTS sample offsets are uint32 but some files store it as int32
3575  * with negative values used to correct DTS delays.
3576  There may be abnormally large values as well. */
3577  if (sample_duration > c->max_stts_delta) {
3578  // assume high delta is a correction if negative when cast as int32
3579  int32_t delta_magnitude = (int32_t)sample_duration;
3580  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",
3581  sample_duration, i, sample_count, st->index);
3582  sc->stts_data[i].duration = 1;
3583  corrected_dts += (delta_magnitude < 0 ? (int64_t)delta_magnitude : 1) * sample_count;
3584  } else {
3585  corrected_dts += sample_duration * (uint64_t)sample_count;
3586  }
3587 
3588  current_dts += sc->stts_data[i].duration * (uint64_t)sample_count;
3589 
3590  if (current_dts > corrected_dts) {
3591  int64_t drift = (current_dts - corrected_dts)/FFMAX(sample_count, 1);
3592  uint32_t correction = (sc->stts_data[i].duration > drift) ? drift : sc->stts_data[i].duration - 1;
3593  current_dts -= correction * (uint64_t)sample_count;
3594  sc->stts_data[i].duration -= correction;
3595  }
3596 
3597  duration+=(int64_t)sc->stts_data[i].duration*(uint64_t)sc->stts_data[i].count;
3598  total_sample_count+=sc->stts_data[i].count;
3599  }
3600 
3601  sc->stts_count = i;
3602 
3603  if (duration > 0 &&
3604  duration <= INT64_MAX - sc->duration_for_fps &&
3605  total_sample_count <= INT_MAX - sc->nb_frames_for_fps) {
3606  sc->duration_for_fps += duration;
3607  sc->nb_frames_for_fps += total_sample_count;
3608  }
3609 
3610  if (pb->eof_reached) {
3611  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STTS atom\n");
3612  return AVERROR_EOF;
3613  }
3614 
3615  st->nb_frames= total_sample_count;
3616  if (duration)
3617  st->duration= FFMIN(st->duration, duration);
3618 
3619  // All samples have zero duration. They have higher chance be chose by
3620  // mov_find_next_sample, which leads to seek again and again.
3621  //
3622  // It's AVERROR_INVALIDDATA actually, but such files exist in the wild.
3623  // So only mark data stream as discarded for safety.
3624  if (!duration && sc->stts_count &&
3626  av_log(c->fc, AV_LOG_WARNING,
3627  "All samples in data stream index:id [%d:%d] have zero "
3628  "duration, stream set to be discarded by default. Override "
3629  "using AVStream->discard or -discard for ffmpeg command.\n",
3630  st->index, sc->id);
3631  st->discard = AVDISCARD_ALL;
3632  }
3633  sc->track_end = duration;
3634  return 0;
3635 }
3636 
3638 {
3639  AVStream *st;
3640  MOVStreamContext *sc;
3641  int64_t i, entries;
3642 
3643  if (c->fc->nb_streams < 1)
3644  return 0;
3645  st = c->fc->streams[c->fc->nb_streams - 1];
3646  sc = st->priv_data;
3647 
3648  avio_r8(pb); /* version */
3649  avio_rb24(pb); /* flags */
3650  entries = atom.size - 4;
3651 
3652  av_log(c->fc, AV_LOG_TRACE, "track[%u].sdtp.entries = %" PRId64 "\n",
3653  c->fc->nb_streams - 1, entries);
3654 
3655  if (sc->sdtp_data)
3656  av_log(c->fc, AV_LOG_WARNING, "Duplicated SDTP atom\n");
3657  av_freep(&sc->sdtp_data);
3658  sc->sdtp_count = 0;
3659 
3660  sc->sdtp_data = av_malloc(entries);
3661  if (!sc->sdtp_data)
3662  return AVERROR(ENOMEM);
3663 
3664  for (i = 0; i < entries && !pb->eof_reached; i++)
3665  sc->sdtp_data[i] = avio_r8(pb);
3666  sc->sdtp_count = i;
3667 
3668  return 0;
3669 }
3670 
3671 static void mov_update_dts_shift(MOVStreamContext *sc, int duration, void *logctx)
3672 {
3673  if (duration < 0) {
3674  if (duration == INT_MIN) {
3675  av_log(logctx, AV_LOG_WARNING, "mov_update_dts_shift(): dts_shift set to %d\n", INT_MAX);
3676  duration++;
3677  }
3678  sc->dts_shift = FFMAX(sc->dts_shift, -duration);
3679  }
3680 }
3681 
3683 {
3684  AVStream *st;
3685  MOVStreamContext *sc;
3686  unsigned int i, entries, ctts_count = 0;
3687 
3688  if (c->trak_index < 0) {
3689  av_log(c->fc, AV_LOG_WARNING, "CTTS outside TRAK\n");
3690  return 0;
3691  }
3692 
3693  if (c->fc->nb_streams < 1)
3694  return 0;
3695  st = c->fc->streams[c->fc->nb_streams-1];
3696  sc = st->priv_data;
3697 
3698  avio_r8(pb); /* version */
3699  avio_rb24(pb); /* flags */
3700  entries = avio_rb32(pb);
3701 
3702  av_log(c->fc, AV_LOG_TRACE, "track[%u].ctts.entries = %u\n", c->fc->nb_streams - 1, entries);
3703 
3704  if (!entries)
3705  return 0;
3706  if (entries >= UINT_MAX / sizeof(*sc->ctts_data))
3707  return AVERROR_INVALIDDATA;
3708  av_freep(&sc->ctts_data);
3709  sc->ctts_data = av_fast_realloc(NULL, &sc->ctts_allocated_size, entries * sizeof(*sc->ctts_data));
3710  if (!sc->ctts_data)
3711  return AVERROR(ENOMEM);
3712 
3713  for (i = 0; i < entries && !pb->eof_reached; i++) {
3714  int count = avio_rb32(pb);
3715  int duration = avio_rb32(pb);
3716 
3717  if (count <= 0) {
3718  av_log(c->fc, AV_LOG_TRACE,
3719  "ignoring CTTS entry with count=%d duration=%d\n",
3720  count, duration);
3721  continue;
3722  }
3723 
3724  add_ctts_entry(&sc->ctts_data, &ctts_count, &sc->ctts_allocated_size,
3725  count, duration);
3726 
3727  av_log(c->fc, AV_LOG_TRACE, "count=%d, duration=%d\n",
3728  count, duration);
3729 
3730  if (FFNABS(duration) < -(1<<28) && i+2<entries) {
3731  av_log(c->fc, AV_LOG_WARNING, "CTTS invalid\n");
3732  av_freep(&sc->ctts_data);
3733  sc->ctts_count = 0;
3734  return 0;
3735  }
3736 
3737  if (i+2<entries)
3738  mov_update_dts_shift(sc, duration, c->fc);
3739  }
3740 
3741  sc->ctts_count = ctts_count;
3742 
3743  if (pb->eof_reached) {
3744  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted CTTS atom\n");
3745  return AVERROR_EOF;
3746  }
3747 
3748  av_log(c->fc, AV_LOG_TRACE, "dts shift %d\n", sc->dts_shift);
3749 
3750  return 0;
3751 }
3752 
3754 {
3755  AVStream *st;
3756  MOVStreamContext *sc;
3757  uint8_t version;
3758  uint32_t grouping_type;
3759  uint32_t default_length;
3760  av_unused uint32_t default_group_description_index;
3761  uint32_t entry_count;
3762 
3763  if (c->fc->nb_streams < 1)
3764  return 0;
3765  st = c->fc->streams[c->fc->nb_streams - 1];
3766  sc = st->priv_data;
3767 
3768  version = avio_r8(pb); /* version */
3769  avio_rb24(pb); /* flags */
3770  grouping_type = avio_rl32(pb);
3771 
3772  /*
3773  * This function only supports "sync" boxes, but the code is able to parse
3774  * other boxes (such as "tscl", "tsas" and "stsa")
3775  */
3776  if (grouping_type != MKTAG('s','y','n','c'))
3777  return 0;
3778 
3779  default_length = version >= 1 ? avio_rb32(pb) : 0;
3780  default_group_description_index = version >= 2 ? avio_rb32(pb) : 0;
3781  entry_count = avio_rb32(pb);
3782 
3783  av_freep(&sc->sgpd_sync);
3784  sc->sgpd_sync_count = entry_count;
3785  sc->sgpd_sync = av_calloc(entry_count, sizeof(*sc->sgpd_sync));
3786  if (!sc->sgpd_sync)
3787  return AVERROR(ENOMEM);
3788 
3789  for (uint32_t i = 0; i < entry_count && !pb->eof_reached; i++) {
3790  uint32_t description_length = default_length;
3791  if (version >= 1 && default_length == 0)
3792  description_length = avio_rb32(pb);
3793  if (grouping_type == MKTAG('s','y','n','c')) {
3794  const uint8_t nal_unit_type = avio_r8(pb) & 0x3f;
3795  sc->sgpd_sync[i] = nal_unit_type;
3796  description_length -= 1;
3797  }
3798  avio_skip(pb, description_length);
3799  }
3800 
3801  if (pb->eof_reached) {
3802  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted SGPD atom\n");
3803  return AVERROR_EOF;
3804  }
3805 
3806  return 0;
3807 }
3808 
3810 {
3811  AVStream *st;
3812  MOVStreamContext *sc;
3813  unsigned int i, entries;
3814  uint8_t version;
3815  uint32_t grouping_type;
3816  MOVSbgp *table, **tablep;
3817  int *table_count;
3818 
3819  if (c->fc->nb_streams < 1)
3820  return 0;
3821  st = c->fc->streams[c->fc->nb_streams-1];
3822  sc = st->priv_data;
3823 
3824  version = avio_r8(pb); /* version */
3825  avio_rb24(pb); /* flags */
3826  grouping_type = avio_rl32(pb);
3827 
3828  if (grouping_type == MKTAG('r','a','p',' ')) {
3829  tablep = &sc->rap_group;
3830  table_count = &sc->rap_group_count;
3831  } else if (grouping_type == MKTAG('s','y','n','c')) {
3832  tablep = &sc->sync_group;
3833  table_count = &sc->sync_group_count;
3834  } else {
3835  return 0;
3836  }
3837 
3838  if (version == 1)
3839  avio_rb32(pb); /* grouping_type_parameter */
3840 
3841  entries = avio_rb32(pb);
3842  if (!entries)
3843  return 0;
3844  if (*tablep)
3845  av_log(c->fc, AV_LOG_WARNING, "Duplicated SBGP %s atom\n", av_fourcc2str(grouping_type));
3846  av_freep(tablep);
3847  table = av_malloc_array(entries, sizeof(*table));
3848  if (!table)
3849  return AVERROR(ENOMEM);
3850  *tablep = table;
3851 
3852  for (i = 0; i < entries && !pb->eof_reached; i++) {
3853  table[i].count = avio_rb32(pb); /* sample_count */
3854  table[i].index = avio_rb32(pb); /* group_description_index */
3855  }
3856 
3857  *table_count = i;
3858 
3859  if (pb->eof_reached) {
3860  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted SBGP atom\n");
3861  return AVERROR_EOF;
3862  }
3863 
3864  return 0;
3865 }
3866 
3867 /**
3868  * Get ith edit list entry (media time, duration).
3869  */
3871  const MOVStreamContext *msc,
3872  unsigned int edit_list_index,
3873  int64_t *edit_list_media_time,
3874  int64_t *edit_list_duration,
3875  int64_t global_timescale)
3876 {
3877  if (edit_list_index == msc->elst_count) {
3878  return 0;
3879  }
3880  *edit_list_media_time = msc->elst_data[edit_list_index].time;
3881  *edit_list_duration = msc->elst_data[edit_list_index].duration;
3882 
3883  /* duration is in global timescale units;convert to msc timescale */
3884  if (global_timescale == 0) {
3885  avpriv_request_sample(mov->fc, "Support for mvhd.timescale = 0 with editlists");
3886  return 0;
3887  }
3888  *edit_list_duration = av_rescale(*edit_list_duration, msc->time_scale,
3889  global_timescale);
3890 
3891  if (*edit_list_duration + (uint64_t)*edit_list_media_time > INT64_MAX)
3892  *edit_list_duration = 0;
3893 
3894  return 1;
3895 }
3896 
3897 /**
3898  * Find the closest previous frame to the timestamp_pts, in e_old index
3899  * entries. Searching for just any frame / just key frames can be controlled by
3900  * last argument 'flag'.
3901  * Note that if ctts_data is not NULL, we will always search for a key frame
3902  * irrespective of the value of 'flag'. If we don't find any keyframe, we will
3903  * return the first frame of the video.
3904  *
3905  * Here the timestamp_pts is considered to be a presentation timestamp and
3906  * the timestamp of index entries are considered to be decoding timestamps.
3907  *
3908  * Returns 0 if successful in finding a frame, else returns -1.
3909  * Places the found index corresponding output arg.
3910  *
3911  * If ctts_old is not NULL, then refines the searched entry by searching
3912  * backwards from the found timestamp, to find the frame with correct PTS.
3913  *
3914  * Places the found ctts_index and ctts_sample in corresponding output args.
3915  */
3917  AVIndexEntry *e_old,
3918  int nb_old,
3919  MOVCtts* ctts_data,
3920  int64_t ctts_count,
3921  int64_t timestamp_pts,
3922  int flag,
3923  int64_t* index,
3924  int64_t* ctts_index,
3925  int64_t* ctts_sample)
3926 {
3927  MOVStreamContext *msc = st->priv_data;
3928  FFStream *const sti = ffstream(st);
3929  AVIndexEntry *e_keep = sti->index_entries;
3930  int nb_keep = sti->nb_index_entries;
3931  int64_t i = 0;
3932  int64_t index_ctts_count;
3933 
3934  av_assert0(index);
3935 
3936  // If dts_shift > 0, then all the index timestamps will have to be offset by
3937  // at least dts_shift amount to obtain PTS.
3938  // Hence we decrement the searched timestamp_pts by dts_shift to find the closest index element.
3939  if (msc->dts_shift > 0) {
3940  timestamp_pts -= msc->dts_shift;
3941  }
3942 
3943  sti->index_entries = e_old;
3944  sti->nb_index_entries = nb_old;
3945  *index = av_index_search_timestamp(st, timestamp_pts, flag | AVSEEK_FLAG_BACKWARD);
3946 
3947  // Keep going backwards in the index entries until the timestamp is the same.
3948  if (*index >= 0) {
3949  for (i = *index; i > 0 && e_old[i].timestamp == e_old[i - 1].timestamp;
3950  i--) {
3951  if ((flag & AVSEEK_FLAG_ANY) ||
3952  (e_old[i - 1].flags & AVINDEX_KEYFRAME)) {
3953  *index = i - 1;
3954  }
3955  }
3956  }
3957 
3958  // If we have CTTS then refine the search, by searching backwards over PTS
3959  // computed by adding corresponding CTTS durations to index timestamps.
3960  if (ctts_data && *index >= 0) {
3961  av_assert0(ctts_index);
3962  av_assert0(ctts_sample);
3963  // Find out the ctts_index for the found frame.
3964  *ctts_index = 0;
3965  *ctts_sample = 0;
3966  for (index_ctts_count = 0; index_ctts_count < *index; index_ctts_count++) {
3967  if (*ctts_index < ctts_count) {
3968  (*ctts_sample)++;
3969  if (ctts_data[*ctts_index].count == *ctts_sample) {
3970  (*ctts_index)++;
3971  *ctts_sample = 0;
3972  }
3973  }
3974  }
3975 
3976  while (*index >= 0 && (*ctts_index) >= 0 && (*ctts_index) < ctts_count) {
3977  // Find a "key frame" with PTS <= timestamp_pts (So that we can decode B-frames correctly).
3978  // No need to add dts_shift to the timestamp here becase timestamp_pts has already been
3979  // compensated by dts_shift above.
3980  if ((e_old[*index].timestamp + ctts_data[*ctts_index].duration) <= timestamp_pts &&
3981  (e_old[*index].flags & AVINDEX_KEYFRAME)) {
3982  break;
3983  }
3984 
3985  (*index)--;
3986  if (*ctts_sample == 0) {
3987  (*ctts_index)--;
3988  if (*ctts_index >= 0)
3989  *ctts_sample = ctts_data[*ctts_index].count - 1;
3990  } else {
3991  (*ctts_sample)--;
3992  }
3993  }
3994  }
3995 
3996  /* restore AVStream state*/
3997  sti->index_entries = e_keep;
3998  sti->nb_index_entries = nb_keep;
3999  return *index >= 0 ? 0 : -1;
4000 }
4001 
4002 /**
4003  * Add index entry with the given values, to the end of ffstream(st)->index_entries.
4004  * Returns the new size ffstream(st)->index_entries if successful, else returns -1.
4005  *
4006  * This function is similar to ff_add_index_entry in libavformat/utils.c
4007  * except that here we are always unconditionally adding an index entry to
4008  * the end, instead of searching the entries list and skipping the add if
4009  * there is an existing entry with the same timestamp.
4010  * This is needed because the mov_fix_index calls this func with the same
4011  * unincremented timestamp for successive discarded frames.
4012  */
4014  int size, int distance, int flags)
4015 {
4016  FFStream *const sti = ffstream(st);
4017  AVIndexEntry *entries, *ie;
4018  int64_t index = -1;
4019  const size_t min_size_needed = (sti->nb_index_entries + 1) * sizeof(AVIndexEntry);
4020 
4021  // Double the allocation each time, to lower memory fragmentation.
4022  // Another difference from ff_add_index_entry function.
4023  const size_t requested_size =
4024  min_size_needed > sti->index_entries_allocated_size ?
4025  FFMAX(min_size_needed, 2 * sti->index_entries_allocated_size) :
4026  min_size_needed;
4027 
4028  if (sti->nb_index_entries + 1U >= UINT_MAX / sizeof(AVIndexEntry))
4029  return -1;
4030 
4031  entries = av_fast_realloc(sti->index_entries,
4033  requested_size);
4034  if (!entries)
4035  return -1;
4036 
4037  sti->index_entries = entries;
4038 
4039  index = sti->nb_index_entries++;
4040  ie= &entries[index];
4041 
4042  ie->pos = pos;
4043  ie->timestamp = timestamp;
4044  ie->min_distance= distance;
4045  ie->size= size;
4046  ie->flags = flags;
4047  return index;
4048 }
4049 
4050 /**
4051  * Rewrite timestamps of index entries in the range [end_index - frame_duration_buffer_size, end_index)
4052  * by subtracting end_ts successively by the amounts given in frame_duration_buffer.
4053  */
4054 static void fix_index_entry_timestamps(AVStream* st, int end_index, int64_t end_ts,
4055  int64_t* frame_duration_buffer,
4056  int frame_duration_buffer_size) {
4057  FFStream *const sti = ffstream(st);
4058  int i = 0;
4059  av_assert0(end_index >= 0 && end_index <= sti->nb_index_entries);
4060  for (i = 0; i < frame_duration_buffer_size; i++) {
4061  end_ts -= frame_duration_buffer[frame_duration_buffer_size - 1 - i];
4062  sti->index_entries[end_index - 1 - i].timestamp = end_ts;
4063  }
4064 }
4065 
4066 /**
4067  * Append a new ctts entry to ctts_data.
4068  * Returns the new ctts_count if successful, else returns -1.
4069  */
4070 static int64_t add_ctts_entry(MOVCtts** ctts_data, unsigned int* ctts_count, unsigned int* allocated_size,
4071  int count, int duration)
4072 {
4073  MOVCtts *ctts_buf_new;
4074  const size_t min_size_needed = (*ctts_count + 1) * sizeof(MOVCtts);
4075  const size_t requested_size =
4076  min_size_needed > *allocated_size ?
4077  FFMAX(min_size_needed, 2 * (*allocated_size)) :
4078  min_size_needed;
4079 
4080  if ((unsigned)(*ctts_count) >= UINT_MAX / sizeof(MOVCtts) - 1)
4081  return -1;
4082 
4083  ctts_buf_new = av_fast_realloc(*ctts_data, allocated_size, requested_size);
4084 
4085  if (!ctts_buf_new)
4086  return -1;
4087 
4088  *ctts_data = ctts_buf_new;
4089 
4090  ctts_buf_new[*ctts_count].count = count;
4091  ctts_buf_new[*ctts_count].duration = duration;
4092 
4093  *ctts_count = (*ctts_count) + 1;
4094  return *ctts_count;
4095 }
4096 
4097 #define MAX_REORDER_DELAY 16
4099 {
4100  MOVStreamContext *msc = st->priv_data;
4101  FFStream *const sti = ffstream(st);
4102  int ctts_ind = 0;
4103  int ctts_sample = 0;
4104  int64_t pts_buf[MAX_REORDER_DELAY + 1]; // Circular buffer to sort pts.
4105  int buf_start = 0;
4106  int j, r, num_swaps;
4107 
4108  for (j = 0; j < MAX_REORDER_DELAY + 1; j++)
4109  pts_buf[j] = INT64_MIN;
4110 
4111  if (st->codecpar->video_delay <= 0 && msc->ctts_data &&
4113  st->codecpar->video_delay = 0;
4114  for (int ind = 0; ind < sti->nb_index_entries && ctts_ind < msc->ctts_count; ++ind) {
4115  // Point j to the last elem of the buffer and insert the current pts there.
4116  j = buf_start;
4117  buf_start = (buf_start + 1);
4118  if (buf_start == MAX_REORDER_DELAY + 1)
4119  buf_start = 0;
4120 
4121  pts_buf[j] = sti->index_entries[ind].timestamp + msc->ctts_data[ctts_ind].duration;
4122 
4123  // The timestamps that are already in the sorted buffer, and are greater than the
4124  // current pts, are exactly the timestamps that need to be buffered to output PTS
4125  // in correct sorted order.
4126  // Hence the video delay (which is the buffer size used to sort DTS and output PTS),
4127  // can be computed as the maximum no. of swaps any particular timestamp needs to
4128  // go through, to keep this buffer in sorted order.
4129  num_swaps = 0;
4130  while (j != buf_start) {
4131  r = j - 1;
4132  if (r < 0) r = MAX_REORDER_DELAY;
4133  if (pts_buf[j] < pts_buf[r]) {
4134  FFSWAP(int64_t, pts_buf[j], pts_buf[r]);
4135  ++num_swaps;
4136  } else {
4137  break;
4138  }
4139  j = r;
4140  }
4141  st->codecpar->video_delay = FFMAX(st->codecpar->video_delay, num_swaps);
4142 
4143  ctts_sample++;
4144  if (ctts_sample == msc->ctts_data[ctts_ind].count) {
4145  ctts_ind++;
4146  ctts_sample = 0;
4147  }
4148  }
4149  av_log(c->fc, AV_LOG_DEBUG, "Setting codecpar->delay to %d for stream st: %d\n",
4150  st->codecpar->video_delay, st->index);
4151  }
4152 }
4153 
4155 {
4156  sc->current_sample++;
4157  sc->current_index++;
4158  if (sc->index_ranges &&
4159  sc->current_index >= sc->current_index_range->end &&
4160  sc->current_index_range->end) {
4161  sc->current_index_range++;
4163  }
4164 }
4165 
4167 {
4168  sc->current_sample--;
4169  sc->current_index--;
4170  if (sc->index_ranges &&
4172  sc->current_index_range > sc->index_ranges) {
4173  sc->current_index_range--;
4174  sc->current_index = sc->current_index_range->end - 1;
4175  }
4176 }
4177 
4178 static void mov_current_sample_set(MOVStreamContext *sc, int current_sample)
4179 {
4180  int64_t range_size;
4181 
4182  sc->current_sample = current_sample;
4183  sc->current_index = current_sample;
4184  if (!sc->index_ranges) {
4185  return;
4186  }
4187 
4188  for (sc->current_index_range = sc->index_ranges;
4189  sc->current_index_range->end;
4190  sc->current_index_range++) {
4191  range_size = sc->current_index_range->end - sc->current_index_range->start;
4192  if (range_size > current_sample) {
4193  sc->current_index = sc->current_index_range->start + current_sample;
4194  break;
4195  }
4196  current_sample -= range_size;
4197  }
4198 }
4199 
4200 /**
4201  * Fix ffstream(st)->index_entries, so that it contains only the entries (and the entries
4202  * which are needed to decode them) that fall in the edit list time ranges.
4203  * Also fixes the timestamps of the index entries to match the timeline
4204  * specified the edit lists.
4205  */
4206 static void mov_fix_index(MOVContext *mov, AVStream *st)
4207 {
4208  MOVStreamContext *msc = st->priv_data;
4209  FFStream *const sti = ffstream(st);
4210  AVIndexEntry *e_old = sti->index_entries;
4211  int nb_old = sti->nb_index_entries;
4212  const AVIndexEntry *e_old_end = e_old + nb_old;
4213  const AVIndexEntry *current = NULL;
4214  MOVCtts *ctts_data_old = msc->ctts_data;
4215  int64_t ctts_index_old = 0;
4216  int64_t ctts_sample_old = 0;
4217  int64_t ctts_count_old = msc->ctts_count;
4218  int64_t edit_list_media_time = 0;
4219  int64_t edit_list_duration = 0;
4220  int64_t frame_duration = 0;
4221  int64_t edit_list_dts_counter = 0;
4222  int64_t edit_list_dts_entry_end = 0;
4223  int64_t edit_list_start_ctts_sample = 0;
4224  int64_t curr_cts;
4225  int64_t curr_ctts = 0;
4226  int64_t empty_edits_sum_duration = 0;
4227  int64_t edit_list_index = 0;
4228  int64_t index;
4229  int flags;
4230  int64_t start_dts = 0;
4231  int64_t edit_list_start_encountered = 0;
4232  int64_t search_timestamp = 0;
4233  int64_t* frame_duration_buffer = NULL;
4234  int num_discarded_begin = 0;
4235  int first_non_zero_audio_edit = -1;
4236  int packet_skip_samples = 0;
4237  MOVIndexRange *current_index_range = NULL;
4238  int found_keyframe_after_edit = 0;
4239  int found_non_empty_edit = 0;
4240 
4241  if (!msc->elst_data || msc->elst_count <= 0 || nb_old <= 0) {
4242  return;
4243  }
4244 
4245  // allocate the index ranges array
4246  msc->index_ranges = av_malloc_array(msc->elst_count + 1,
4247  sizeof(msc->index_ranges[0]));
4248  if (!msc->index_ranges) {
4249  av_log(mov->fc, AV_LOG_ERROR, "Cannot allocate index ranges buffer\n");
4250  return;
4251  }
4252  msc->current_index_range = msc->index_ranges;
4253 
4254  // Clean AVStream from traces of old index
4255  sti->index_entries = NULL;
4257  sti->nb_index_entries = 0;
4258 
4259  // Clean ctts fields of MOVStreamContext
4260  msc->ctts_data = NULL;
4261  msc->ctts_count = 0;
4262  msc->ctts_index = 0;
4263  msc->ctts_sample = 0;
4264  msc->ctts_allocated_size = 0;
4265 
4266  // Reinitialize min_corrected_pts so that it can be computed again.
4267  msc->min_corrected_pts = -1;
4268 
4269  // If the dts_shift is positive (in case of negative ctts values in mov),
4270  // then negate the DTS by dts_shift
4271  if (msc->dts_shift > 0) {
4272  edit_list_dts_entry_end -= msc->dts_shift;
4273  av_log(mov->fc, AV_LOG_DEBUG, "Shifting DTS by %d because of negative CTTS.\n", msc->dts_shift);
4274  }
4275 
4276  start_dts = edit_list_dts_entry_end;
4277 
4278  while (get_edit_list_entry(mov, msc, edit_list_index, &edit_list_media_time,
4279  &edit_list_duration, mov->time_scale)) {
4280  av_log(mov->fc, AV_LOG_DEBUG, "Processing st: %d, edit list %"PRId64" - media time: %"PRId64", duration: %"PRId64"\n",
4281  st->index, edit_list_index, edit_list_media_time, edit_list_duration);
4282  edit_list_index++;
4283  edit_list_dts_counter = edit_list_dts_entry_end;
4284  edit_list_dts_entry_end += edit_list_duration;
4285  num_discarded_begin = 0;
4286  if (!found_non_empty_edit && edit_list_media_time == -1) {
4287  empty_edits_sum_duration += edit_list_duration;
4288  continue;
4289  }
4290  found_non_empty_edit = 1;
4291 
4292  // If we encounter a non-negative edit list reset the skip_samples/start_pad fields and set them
4293  // according to the edit list below.
4294  if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
4295  if (first_non_zero_audio_edit < 0) {
4296  first_non_zero_audio_edit = 1;
4297  } else {
4298  first_non_zero_audio_edit = 0;
4299  }
4300 
4301  if (first_non_zero_audio_edit > 0)
4302  sti->skip_samples = msc->start_pad = 0;
4303  }
4304 
4305  // While reordering frame index according to edit list we must handle properly
4306  // the scenario when edit list entry starts from none key frame.
4307  // We find closest previous key frame and preserve it and consequent frames in index.
4308  // All frames which are outside edit list entry time boundaries will be dropped after decoding.
4309  search_timestamp = edit_list_media_time;
4310  if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
4311  // Audio decoders like AAC need need a decoder delay samples previous to the current sample,
4312  // to correctly decode this frame. Hence for audio we seek to a frame 1 sec. before the
4313  // edit_list_media_time to cover the decoder delay.
4314  search_timestamp = FFMAX(search_timestamp - msc->time_scale, e_old[0].timestamp);
4315  }
4316 
4317  if (find_prev_closest_index(st, e_old, nb_old, ctts_data_old, ctts_count_old, search_timestamp, 0,
4318  &index, &ctts_index_old, &ctts_sample_old) < 0) {
4319  av_log(mov->fc, AV_LOG_WARNING,
4320  "st: %d edit list: %"PRId64" Missing key frame while searching for timestamp: %"PRId64"\n",
4321  st->index, edit_list_index, search_timestamp);
4322  if (find_prev_closest_index(st, e_old, nb_old, ctts_data_old, ctts_count_old, search_timestamp, AVSEEK_FLAG_ANY,
4323  &index, &ctts_index_old, &ctts_sample_old) < 0) {
4324  av_log(mov->fc, AV_LOG_WARNING,
4325  "st: %d edit list %"PRId64" Cannot find an index entry before timestamp: %"PRId64".\n",
4326  st->index, edit_list_index, search_timestamp);
4327  index = 0;
4328  ctts_index_old = 0;
4329  ctts_sample_old = 0;
4330  }
4331  }
4332  current = e_old + index;
4333  edit_list_start_ctts_sample = ctts_sample_old;
4334 
4335  // Iterate over index and arrange it according to edit list
4336  edit_list_start_encountered = 0;
4337  found_keyframe_after_edit = 0;
4338  for (; current < e_old_end; current++, index++) {
4339  // check if frame outside edit list mark it for discard
4340  frame_duration = (current + 1 < e_old_end) ?
4341  ((current + 1)->timestamp - current->timestamp) : edit_list_duration;
4342 
4343  flags = current->flags;
4344 
4345  // frames (pts) before or after edit list
4346  curr_cts = current->timestamp + msc->dts_shift;
4347  curr_ctts = 0;
4348 
4349  if (ctts_data_old && ctts_index_old < ctts_count_old) {
4350  curr_ctts = ctts_data_old[ctts_index_old].duration;
4351  av_log(mov->fc, AV_LOG_TRACE, "stts: %"PRId64" ctts: %"PRId64", ctts_index: %"PRId64", ctts_count: %"PRId64"\n",
4352  curr_cts, curr_ctts, ctts_index_old, ctts_count_old);
4353  curr_cts += curr_ctts;
4354  ctts_sample_old++;
4355  if (ctts_sample_old == ctts_data_old[ctts_index_old].count) {
4356  if (add_ctts_entry(&msc->ctts_data, &msc->ctts_count,
4357  &msc->ctts_allocated_size,
4358  ctts_data_old[ctts_index_old].count - edit_list_start_ctts_sample,
4359  ctts_data_old[ctts_index_old].duration) == -1) {
4360  av_log(mov->fc, AV_LOG_ERROR, "Cannot add CTTS entry %"PRId64" - {%"PRId64", %d}\n",
4361  ctts_index_old,
4362  ctts_data_old[ctts_index_old].count - edit_list_start_ctts_sample,
4363  ctts_data_old[ctts_index_old].duration);
4364  break;
4365  }
4366  ctts_index_old++;
4367  ctts_sample_old = 0;
4368  edit_list_start_ctts_sample = 0;
4369  }
4370  }
4371 
4372  if (curr_cts < edit_list_media_time || curr_cts >= (edit_list_duration + edit_list_media_time)) {
4374  curr_cts < edit_list_media_time && curr_cts + frame_duration > edit_list_media_time &&
4375  first_non_zero_audio_edit > 0) {
4376  packet_skip_samples = edit_list_media_time - curr_cts;
4377  sti->skip_samples += packet_skip_samples;
4378 
4379  // Shift the index entry timestamp by packet_skip_samples to be correct.
4380  edit_list_dts_counter -= packet_skip_samples;
4381  if (edit_list_start_encountered == 0) {
4382  edit_list_start_encountered = 1;
4383  // Make timestamps strictly monotonically increasing for audio, by rewriting timestamps for
4384  // discarded packets.
4385  if (frame_duration_buffer) {
4386  fix_index_entry_timestamps(st, sti->nb_index_entries, edit_list_dts_counter,
4387  frame_duration_buffer, num_discarded_begin);
4388  av_freep(&frame_duration_buffer);
4389  }
4390  }
4391 
4392  av_log(mov->fc, AV_LOG_DEBUG, "skip %d audio samples from curr_cts: %"PRId64"\n", packet_skip_samples, curr_cts);
4393  } else {
4395  av_log(mov->fc, AV_LOG_DEBUG, "drop a frame at curr_cts: %"PRId64" @ %"PRId64"\n", curr_cts, index);
4396 
4397  if (edit_list_start_encountered == 0) {
4398  num_discarded_begin++;
4399  frame_duration_buffer = av_realloc(frame_duration_buffer,
4400  num_discarded_begin * sizeof(int64_t));
4401  if (!frame_duration_buffer) {
4402  av_log(mov->fc, AV_LOG_ERROR, "Cannot reallocate frame duration buffer\n");
4403  break;
4404  }
4405  frame_duration_buffer[num_discarded_begin - 1] = frame_duration;
4406 
4407  // Increment skip_samples for the first non-zero audio edit list
4408  if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
4409  first_non_zero_audio_edit > 0 && st->codecpar->codec_id != AV_CODEC_ID_VORBIS) {
4410  sti->skip_samples += frame_duration;
4411  }
4412  }
4413  }
4414  } else {
4415  if (msc->min_corrected_pts < 0) {
4416  msc->min_corrected_pts = edit_list_dts_counter + curr_ctts + msc->dts_shift;
4417  } else {
4418  msc->min_corrected_pts = FFMIN(msc->min_corrected_pts, edit_list_dts_counter + curr_ctts + msc->dts_shift);
4419  }
4420  if (edit_list_start_encountered == 0) {
4421  edit_list_start_encountered = 1;
4422  // Make timestamps strictly monotonically increasing by rewriting timestamps for
4423  // discarded packets.
4424  if (frame_duration_buffer) {
4425  fix_index_entry_timestamps(st, sti->nb_index_entries, edit_list_dts_counter,
4426  frame_duration_buffer, num_discarded_begin);
4427  av_freep(&frame_duration_buffer);
4428  }
4429  }
4430  }
4431 
4432  if (add_index_entry(st, current->pos, edit_list_dts_counter, current->size,
4433  current->min_distance, flags) == -1) {
4434  av_log(mov->fc, AV_LOG_ERROR, "Cannot add index entry\n");
4435  break;
4436  }
4437 
4438  // Update the index ranges array
4439  if (!current_index_range || index != current_index_range->end) {
4440  current_index_range = current_index_range ? current_index_range + 1
4441  : msc->index_ranges;
4442  current_index_range->start = index;
4443  }
4444  current_index_range->end = index + 1;
4445 
4446  // Only start incrementing DTS in frame_duration amounts, when we encounter a frame in edit list.
4447  if (edit_list_start_encountered > 0) {
4448  edit_list_dts_counter = edit_list_dts_counter + frame_duration;
4449  }
4450 
4451  // Break when found first key frame after edit entry completion
4452  if ((curr_cts + frame_duration >= (edit_list_duration + edit_list_media_time)) &&
4454  if (ctts_data_old) {
4455  // If we have CTTS and this is the first keyframe after edit elist,
4456  // wait for one more, because there might be trailing B-frames after this I-frame
4457  // that do belong to the edit.
4458  if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO && found_keyframe_after_edit == 0) {
4459  found_keyframe_after_edit = 1;
4460  continue;
4461  }
4462  if (ctts_sample_old != 0) {
4463  if (add_ctts_entry(&msc->ctts_data, &msc->ctts_count,
4464  &msc->ctts_allocated_size,
4465  ctts_sample_old - edit_list_start_ctts_sample,
4466  ctts_data_old[ctts_index_old].duration) == -1) {
4467  av_log(mov->fc, AV_LOG_ERROR, "Cannot add CTTS entry %"PRId64" - {%"PRId64", %d}\n",
4468  ctts_index_old, ctts_sample_old - edit_list_start_ctts_sample,
4469  ctts_data_old[ctts_index_old].duration);
4470  break;
4471  }
4472  }
4473  }
4474  break;
4475  }
4476  }
4477  }
4478  // If there are empty edits, then msc->min_corrected_pts might be positive
4479  // intentionally. So we subtract the sum duration of emtpy edits here.
4480  msc->min_corrected_pts -= empty_edits_sum_duration;
4481 
4482  // If the minimum pts turns out to be greater than zero after fixing the index, then we subtract the
4483  // dts by that amount to make the first pts zero.
4484  if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
4485  if (msc->min_corrected_pts > 0) {
4486  av_log(mov->fc, AV_LOG_DEBUG, "Offset DTS by %"PRId64" to make first pts zero.\n", msc->min_corrected_pts);
4487  for (int i = 0; i < sti->nb_index_entries; ++i)
4489  }
4490  }
4491  // Start time should be equal to zero or the duration of any empty edits.
4492  st->start_time = empty_edits_sum_duration;
4493 
4494  // Update av stream length, if it ends up shorter than the track's media duration
4495  st->duration = FFMIN(st->duration, edit_list_dts_entry_end - start_dts);
4496  msc->start_pad = sti->skip_samples;
4497 
4498  // Free the old index and the old CTTS structures
4499  av_free(e_old);
4500  av_free(ctts_data_old);
4501  av_freep(&frame_duration_buffer);
4502 
4503  // Null terminate the index ranges array
4504  current_index_range = current_index_range ? current_index_range + 1
4505  : msc->index_ranges;
4506  current_index_range->start = 0;
4507  current_index_range->end = 0;
4508  msc->current_index = msc->index_ranges[0].start;
4509 }
4510 
4511 static uint32_t get_sgpd_sync_index(const MOVStreamContext *sc, int nal_unit_type)
4512 {
4513  for (uint32_t i = 0; i < sc->sgpd_sync_count; i++)
4514  if (sc->sgpd_sync[i] == HEVC_NAL_CRA_NUT)
4515  return i + 1;
4516  return 0;
4517 }
4518 
4520 {
4521  int k;
4522  int sample_id = 0;
4523  uint32_t cra_index;
4524  MOVStreamContext *sc = st->priv_data;
4525 
4526  if (st->codecpar->codec_id != AV_CODEC_ID_HEVC || !sc->sync_group_count)
4527  return 0;
4528 
4529  /* Build an unrolled index of the samples */
4530  sc->sample_offsets_count = 0;
4531  for (uint32_t i = 0; i < sc->ctts_count; i++) {
4532  if (sc->ctts_data[i].count > INT_MAX - sc->sample_offsets_count)
4533  return AVERROR(ENOMEM);
4534  sc->sample_offsets_count += sc->ctts_data[i].count;
4535  }
4536  av_freep(&sc->sample_offsets);
4538  if (!sc->sample_offsets)
4539  return AVERROR(ENOMEM);
4540  k = 0;
4541  for (uint32_t i = 0; i < sc->ctts_count; i++)
4542  for (int j = 0; j < sc->ctts_data[i].count; j++)
4543  sc->sample_offsets[k++] = sc->ctts_data[i].duration;
4544 
4545  /* The following HEVC NAL type reveal the use of open GOP sync points
4546  * (TODO: BLA types may also be concerned) */
4547  cra_index = get_sgpd_sync_index(sc, HEVC_NAL_CRA_NUT); /* Clean Random Access */
4548  if (!cra_index)
4549  return 0;
4550 
4551  /* Build a list of open-GOP key samples */
4552  sc->open_key_samples_count = 0;
4553  for (uint32_t i = 0; i < sc->sync_group_count; i++)
4554  if (sc->sync_group[i].index == cra_index) {
4555  if (sc->sync_group[i].count > INT_MAX - sc->open_key_samples_count)
4556  return AVERROR(ENOMEM);
4558  }
4559  av_freep(&sc->open_key_samples);
4561  if (!sc->open_key_samples)
4562  return AVERROR(ENOMEM);
4563  k = 0;
4564  for (uint32_t i = 0; i < sc->sync_group_count; i++) {
4565  const MOVSbgp *sg = &sc->sync_group[i];
4566  if (sg->index == cra_index)
4567  for (uint32_t j = 0; j < sg->count; j++)
4568  sc->open_key_samples[k++] = sample_id;
4569  if (sg->count > INT_MAX - sample_id)
4570  return AVERROR_PATCHWELCOME;
4571  sample_id += sg->count;
4572  }
4573 
4574  /* Identify the minimal time step between samples */
4575  sc->min_sample_duration = UINT_MAX;
4576  for (uint32_t i = 0; i < sc->stts_count; i++)
4578 
4579  return 0;
4580 }
4581 
4582 static void mov_build_index(MOVContext *mov, AVStream *st)
4583 {
4584  MOVStreamContext *sc = st->priv_data;
4585  FFStream *const sti = ffstream(st);
4586  int64_t current_offset;
4587  int64_t current_dts = 0;
4588  unsigned int stts_index = 0;
4589  unsigned int stsc_index = 0;
4590  unsigned int stss_index = 0;
4591  unsigned int stps_index = 0;
4592  unsigned int i, j;
4593  uint64_t stream_size = 0;
4594  MOVCtts *ctts_data_old = sc->ctts_data;
4595  unsigned int ctts_count_old = sc->ctts_count;
4596 
4597  int ret = build_open_gop_key_points(st);
4598  if (ret < 0)
4599  return;
4600 
4601  if (sc->elst_count) {
4602  int i, edit_start_index = 0, multiple_edits = 0;
4603  int64_t empty_duration = 0; // empty duration of the first edit list entry
4604  int64_t start_time = 0; // start time of the media
4605 
4606  for (i = 0; i < sc->elst_count; i++) {
4607  const MOVElst *e = &sc->elst_data[i];
4608  if (i == 0 && e->time == -1) {
4609  /* if empty, the first entry is the start time of the stream
4610  * relative to the presentation itself */
4611  empty_duration = e->duration;
4612  edit_start_index = 1;
4613  } else if (i == edit_start_index && e->time >= 0) {
4614  start_time = e->time;
4615  } else {
4616  multiple_edits = 1;
4617  }
4618  }
4619 
4620  if (multiple_edits && !mov->advanced_editlist) {
4622  av_log(mov->fc, AV_LOG_WARNING, "multiple edit list entries, "
4623  "not supported in fragmented MP4 files\n");
4624  else
4625  av_log(mov->fc, AV_LOG_WARNING, "multiple edit list entries, "
4626  "Use -advanced_editlist to correctly decode otherwise "
4627  "a/v desync might occur\n");
4628  }
4629 
4630  /* adjust first dts according to edit list */
4631  if ((empty_duration || start_time) && mov->time_scale > 0) {
4632  if (empty_duration)
4633  empty_duration = av_rescale(empty_duration, sc->time_scale, mov->time_scale);
4634 
4635  if (av_sat_sub64(start_time, empty_duration) != start_time - (uint64_t)empty_duration)
4636  av_log(mov->fc, AV_LOG_WARNING, "start_time - empty_duration is not representable\n");
4637 
4638  sc->time_offset = start_time - (uint64_t)empty_duration;
4640  if (!mov->advanced_editlist)
4641  current_dts = -sc->time_offset;
4642  }
4643 
4644  if (!multiple_edits && !mov->advanced_editlist &&
4646  sc->start_pad = start_time;
4647  }
4648 
4649  /* only use old uncompressed audio chunk demuxing when stts specifies it */
4650  if (!(st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
4651  sc->stts_count == 1 && sc->stts_data[0].duration == 1)) {
4652  unsigned int current_sample = 0;
4653  unsigned int stts_sample = 0;
4654  unsigned int sample_size;
4655  unsigned int distance = 0;
4656  unsigned int rap_group_index = 0;
4657  unsigned int rap_group_sample = 0;
4658  int rap_group_present = sc->rap_group_count && sc->rap_group;
4659  int key_off = (sc->keyframe_count && sc->keyframes[0] > 0) || (sc->stps_count && sc->stps_data[0] > 0);
4660 
4661  current_dts -= sc->dts_shift;
4662 
4663  if (!sc->sample_count || sti->nb_index_entries)
4664  return;
4665  if (sc->sample_count >= UINT_MAX / sizeof(*sti->index_entries) - sti->nb_index_entries)
4666  return;
4667  if (av_reallocp_array(&sti->index_entries,
4668  sti->nb_index_entries + sc->sample_count,
4669  sizeof(*sti->index_entries)) < 0) {
4670  sti->nb_index_entries = 0;
4671  return;
4672  }
4673  sti->index_entries_allocated_size = (sti->nb_index_entries + sc->sample_count) * sizeof(*sti->index_entries);
4674 
4675  if (ctts_data_old) {
4676  // Expand ctts entries such that we have a 1-1 mapping with samples
4677  if (sc->sample_count >= UINT_MAX / sizeof(*sc->ctts_data))
4678  return;
4679  sc->ctts_count = 0;
4680  sc->ctts_allocated_size = 0;
4682  sc->sample_count * sizeof(*sc->ctts_data));
4683  if (!sc->ctts_data) {
4684  av_free(ctts_data_old);
4685  return;
4686  }
4687 
4688  memset((uint8_t*)(sc->ctts_data), 0, sc->ctts_allocated_size);
4689 
4690  for (i = 0; i < ctts_count_old &&
4691  sc->ctts_count < sc->sample_count; i++)
4692  for (j = 0; j < ctts_data_old[i].count &&
4693  sc->ctts_count < sc->sample_count; j++)
4694  add_ctts_entry(&sc->ctts_data, &sc->ctts_count,
4695  &sc->ctts_allocated_size, 1,
4696  ctts_data_old[i].duration);
4697  av_free(ctts_data_old);
4698  }
4699 
4700  for (i = 0; i < sc->chunk_count; i++) {
4701  int64_t next_offset = i+1 < sc->chunk_count ? sc->chunk_offsets[i+1] : INT64_MAX;
4702  current_offset = sc->chunk_offsets[i];
4703  while (mov_stsc_index_valid(stsc_index, sc->stsc_count) &&
4704  i + 1 == sc->stsc_data[stsc_index + 1].first)
4705  stsc_index++;
4706 
4707  if (next_offset > current_offset && sc->sample_size>0 && sc->sample_size < sc->stsz_sample_size &&
4708  sc->stsc_data[stsc_index].count * (int64_t)sc->stsz_sample_size > next_offset - current_offset) {
4709  av_log(mov->fc, AV_LOG_WARNING, "STSZ sample size %d invalid (too large), ignoring\n", sc->stsz_sample_size);
4710  sc->stsz_sample_size = sc->sample_size;
4711  }
4712  if (sc->stsz_sample_size>0 && sc->stsz_sample_size < sc->sample_size) {
4713  av_log(mov->fc, AV_LOG_WARNING, "STSZ sample size %d invalid (too small), ignoring\n", sc->stsz_sample_size);
4714  sc->stsz_sample_size = sc->sample_size;
4715  }
4716 
4717  for (j = 0; j < sc->stsc_data[stsc_index].count; j++) {
4718  int keyframe = 0;
4719  if (current_sample >= sc->sample_count) {
4720  av_log(mov->fc, AV_LOG_ERROR, "wrong sample count\n");
4721  return;
4722  }
4723 
4724  if (!sc->keyframe_absent && (!sc->keyframe_count || current_sample+key_off == sc->keyframes[stss_index])) {
4725  keyframe = 1;
4726  if (stss_index + 1 < sc->keyframe_count)
4727  stss_index++;
4728  } else if (sc->stps_count && current_sample+key_off == sc->stps_data[stps_index]) {
4729  keyframe = 1;
4730  if (stps_index + 1 < sc->stps_count)
4731  stps_index++;
4732  }
4733  if (rap_group_present && rap_group_index < sc->rap_group_count) {
4734  if (sc->rap_group[rap_group_index].index > 0)
4735  keyframe = 1;
4736  if (++rap_group_sample == sc->rap_group[rap_group_index].count) {
4737  rap_group_sample = 0;
4738  rap_group_index++;
4739  }
4740  }
4741  if (sc->keyframe_absent
4742  && !sc->stps_count
4743  && !rap_group_present
4744  && (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO || (i==0 && j==0)))
4745  keyframe = 1;
4746  if (keyframe)
4747  distance = 0;
4748  sample_size = sc->stsz_sample_size > 0 ? sc->stsz_sample_size : sc->sample_sizes[current_sample];
4749  if (current_offset > INT64_MAX - sample_size) {
4750  av_log(mov->fc, AV_LOG_ERROR, "Current offset %"PRId64" or sample size %u is too large\n",
4751  current_offset,
4752  sample_size);
4753  return;
4754  }
4755 
4756  if (sc->pseudo_stream_id == -1 ||
4757  sc->stsc_data[stsc_index].id - 1 == sc->pseudo_stream_id) {
4758  AVIndexEntry *e;
4759  if (sample_size > 0x3FFFFFFF) {
4760  av_log(mov->fc, AV_LOG_ERROR, "Sample size %u is too large\n", sample_size);
4761  return;
4762  }
4763  e = &sti->index_entries[sti->nb_index_entries++];
4764  e->pos = current_offset;
4765  e->timestamp = current_dts;
4766  e->size = sample_size;
4767  e->min_distance = distance;
4768  e->flags = keyframe ? AVINDEX_KEYFRAME : 0;
4769  av_log(mov->fc, AV_LOG_TRACE, "AVIndex stream %d, sample %u, offset %"PRIx64", dts %"PRId64", "
4770  "size %u, distance %u, keyframe %d\n", st->index, current_sample,
4771  current_offset, current_dts, sample_size, distance, keyframe);
4772  if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && sti->nb_index_entries < 100)
4773  ff_rfps_add_frame(mov->fc, st, current_dts);
4774  }
4775 
4776  current_offset += sample_size;
4777  stream_size += sample_size;
4778 
4779  current_dts += sc->stts_data[stts_index].duration;
4780 
4781  distance++;
4782  stts_sample++;
4783  current_sample++;
4784  if (stts_index + 1 < sc->stts_count && stts_sample == sc->stts_data[stts_index].count) {
4785  stts_sample = 0;
4786  stts_index++;
4787  }
4788  }
4789  }
4790  if (st->duration > 0)
4791  st->codecpar->bit_rate = stream_size*8*sc->time_scale/st->duration;
4792  } else {
4793  unsigned chunk_samples, total = 0;
4794 
4795  if (!sc->chunk_count)
4796  return;
4797 
4798  // compute total chunk count
4799  for (i = 0; i < sc->stsc_count; i++) {
4800  unsigned count, chunk_count;
4801 
4802  chunk_samples = sc->stsc_data[i].count;
4803  if (i != sc->stsc_count - 1 &&
4804  sc->samples_per_frame && chunk_samples % sc->samples_per_frame) {
4805  av_log(mov->fc, AV_LOG_ERROR, "error unaligned chunk\n");
4806  return;
4807  }
4808 
4809  if (sc->samples_per_frame >= 160) { // gsm
4810  count = chunk_samples / sc->samples_per_frame;
4811  } else if (sc->samples_per_frame > 1) {
4812  unsigned samples = (1024/sc->samples_per_frame)*sc->samples_per_frame;
4813  count = (chunk_samples+samples-1) / samples;
4814  } else {
4815  count = (chunk_samples+1023) / 1024;
4816  }
4817 
4818  if (mov_stsc_index_valid(i, sc->stsc_count))
4819  chunk_count = sc->stsc_data[i+1].first - sc->stsc_data[i].first;
4820  else
4821  chunk_count = sc->chunk_count - (sc->stsc_data[i].first - 1);
4822  total += chunk_count * count;
4823  }
4824 
4825  av_log(mov->fc, AV_LOG_TRACE, "chunk count %u\n", total);
4826  if (total >= UINT_MAX / sizeof(*sti->index_entries) - sti->nb_index_entries)
4827  return;
4828  if (av_reallocp_array(&sti->index_entries,
4829  sti->nb_index_entries + total,
4830  sizeof(*sti->index_entries)) < 0) {
4831  sti->nb_index_entries = 0;
4832  return;
4833  }
4834  sti->index_entries_allocated_size = (sti->nb_index_entries + total) * sizeof(*sti->index_entries);
4835 
4836  // populate index
4837  for (i = 0; i < sc->chunk_count; i++) {
4838  current_offset = sc->chunk_offsets[i];
4839  if (mov_stsc_index_valid(stsc_index, sc->stsc_count) &&
4840  i + 1 == sc->stsc_data[stsc_index + 1].first)
4841  stsc_index++;
4842  chunk_samples = sc->stsc_data[stsc_index].count;
4843 
4844  while (chunk_samples > 0) {
4845  AVIndexEntry *e;
4846  unsigned size, samples;
4847 
4848  if (sc->samples_per_frame > 1 && !sc->bytes_per_frame) {
4850  "Zero bytes per frame, but %d samples per frame",
4851  sc->samples_per_frame);
4852  return;
4853  }
4854 
4855  if (sc->samples_per_frame >= 160) { // gsm
4856  samples = sc->samples_per_frame;
4857  size = sc->bytes_per_frame;
4858  } else {
4859  if (sc->samples_per_frame > 1) {
4860  samples = FFMIN((1024 / sc->samples_per_frame)*
4861  sc->samples_per_frame, chunk_samples);
4863  } else {
4864  samples = FFMIN(1024, chunk_samples);
4865  size = samples * sc->sample_size;
4866  }
4867  }
4868 
4869  if (sti->nb_index_entries >= total) {
4870  av_log(mov->fc, AV_LOG_ERROR, "wrong chunk count %u\n", total);
4871  return;
4872  }
4873  if (size > 0x3FFFFFFF) {
4874  av_log(mov->fc, AV_LOG_ERROR, "Sample size %u is too large\n", size);
4875  return;
4876  }
4877  e = &sti->index_entries[sti->nb_index_entries++];
4878  e->pos = current_offset;
4879  e->timestamp = current_dts;
4880  e->size = size;
4881  e->min_distance = 0;
4882  e->flags = AVINDEX_KEYFRAME;
4883  av_log(mov->fc, AV_LOG_TRACE, "AVIndex stream %d, chunk %u, offset %"PRIx64", dts %"PRId64", "
4884  "size %u, duration %u\n", st->index, i, current_offset, current_dts,
4885  size, samples);
4886 
4887  current_offset += size;
4888  current_dts += samples;
4889  chunk_samples -= samples;
4890  }
4891  }
4892  }
4893 
4894  if (!mov->ignore_editlist && mov->advanced_editlist) {
4895  // Fix index according to edit lists.
4896  mov_fix_index(mov, st);
4897  }
4898 
4899  // Update start time of the stream.
4901  st->start_time = sti->index_entries[0].timestamp + sc->dts_shift;
4902  if (sc->ctts_data) {
4903  st->start_time += sc->ctts_data[0].duration;
4904  }
4905  }
4906 
4907  mov_estimate_video_delay(mov, st);
4908 }
4909 
4910 static int test_same_origin(const char *src, const char *ref) {
4911  char src_proto[64];
4912  char ref_proto[64];
4913  char src_auth[256];
4914  char ref_auth[256];
4915  char src_host[256];
4916  char ref_host[256];
4917  int src_port=-1;
4918  int ref_port=-1;
4919 
4920  av_url_split(src_proto, sizeof(src_proto), src_auth, sizeof(src_auth), src_host, sizeof(src_host), &src_port, NULL, 0, src);
4921  av_url_split(ref_proto, sizeof(ref_proto), ref_auth, sizeof(ref_auth), ref_host, sizeof(ref_host), &ref_port, NULL, 0, ref);
4922 
4923  if (strlen(src) == 0) {
4924  return -1;
4925  } else if (strlen(src_auth) + 1 >= sizeof(src_auth) ||
4926  strlen(ref_auth) + 1 >= sizeof(ref_auth) ||
4927  strlen(src_host) + 1 >= sizeof(src_host) ||
4928  strlen(ref_host) + 1 >= sizeof(ref_host)) {
4929  return 0;
4930  } else if (strcmp(src_proto, ref_proto) ||
4931  strcmp(src_auth, ref_auth) ||
4932  strcmp(src_host, ref_host) ||
4933  src_port != ref_port) {
4934  return 0;
4935  } else
4936  return 1;
4937 }
4938 
4939 static int mov_open_dref(MOVContext *c, AVIOContext **pb, const char *src, MOVDref *ref)
4940 {
4941  /* try relative path, we do not try the absolute because it can leak information about our
4942  system to an attacker */
4943  if (ref->nlvl_to > 0 && ref->nlvl_from > 0) {
4944  char filename[1025];
4945  const char *src_path;
4946  int i, l;
4947 
4948  /* find a source dir */
4949  src_path = strrchr(src, '/');
4950  if (src_path)
4951  src_path++;
4952  else
4953  src_path = src;
4954 
4955  /* find a next level down to target */
4956  for (i = 0, l = strlen(ref->path) - 1; l >= 0; l--)
4957  if (ref->path[l] == '/') {
4958  if (i == ref->nlvl_to - 1)
4959  break;
4960  else
4961  i++;
4962  }
4963 
4964  /* compose filename if next level down to target was found */
4965  if (i == ref->nlvl_to - 1 && src_path - src < sizeof(filename)) {
4966  memcpy(filename, src, src_path - src);
4967  filename[src_path - src] = 0;
4968 
4969  for (i = 1; i < ref->nlvl_from; i++)
4970  av_strlcat(filename, "../", sizeof(filename));
4971 
4972  av_strlcat(filename, ref->path + l + 1, sizeof(filename));
4973  if (!c->use_absolute_path) {
4974  int same_origin = test_same_origin(src, filename);
4975 
4976  if (!same_origin) {
4977  av_log(c->fc, AV_LOG_ERROR,
4978  "Reference with mismatching origin, %s not tried for security reasons, "
4979  "set demuxer option use_absolute_path to allow it anyway\n",
4980  ref->path);
4981  return AVERROR(ENOENT);
4982  }
4983 
4984  if (strstr(ref->path + l + 1, "..") ||
4985  strstr(ref->path + l + 1, ":") ||
4986  (ref->nlvl_from > 1 && same_origin < 0) ||
4987  (filename[0] == '/' && src_path == src))
4988  return AVERROR(ENOENT);
4989  }
4990 
4991  if (strlen(filename) + 1 == sizeof(filename))
4992  return AVERROR(ENOENT);
4993  if (!c->fc->io_open(c->fc, pb, filename, AVIO_FLAG_READ, NULL))
4994  return 0;
4995  }
4996  } else if (c->use_absolute_path) {
4997  av_log(c->fc, AV_LOG_WARNING, "Using absolute path on user request, "
4998  "this is a possible security issue\n");
4999  if (!c->fc->io_open(c->fc, pb, ref->path, AVIO_FLAG_READ, NULL))
5000  return 0;
5001  } else {
5002  av_log(c->fc, AV_LOG_ERROR,
5003  "Absolute path %s not tried for security reasons, "
5004  "set demuxer option use_absolute_path to allow absolute paths\n",
5005  ref->path);
5006  }
5007 
5008  return AVERROR(ENOENT);
5009 }
5010 
5012 {
5013  if (sc->time_scale <= 0) {
5014  av_log(c->fc, AV_LOG_WARNING, "stream %d, timescale not set\n", sc->ffindex);
5015  sc->time_scale = c->time_scale;
5016  if (sc->time_scale <= 0)
5017  sc->time_scale = 1;
5018  }
5019 }
5020 
5021 #if CONFIG_IAMFDEC
5022 static int mov_update_iamf_streams(MOVContext *c, const AVStream *st)
5023 {
5024  const MOVStreamContext *sc = st->priv_data;
5025  const IAMFContext *iamf = &sc->iamf->iamf;
5026 
5027  for (int i = 0; i < iamf->nb_audio_elements; i++) {
5028  const AVStreamGroup *stg = NULL;
5029 
5030  for (int j = 0; j < c->fc->nb_stream_groups; j++)
5031  if (c->fc->stream_groups[j]->id == iamf->audio_elements[i]->audio_element_id)
5032  stg = c->fc->stream_groups[j];
5033  av_assert0(stg);
5034 
5035  for (int j = 0; j < stg->nb_streams; j++) {
5036  const FFStream *sti = cffstream(st);
5037  AVStream *out = stg->streams[j];
5038  FFStream *out_sti = ffstream(stg->streams[j]);
5039 
5040  out->codecpar->bit_rate = 0;
5041 
5042  if (out == st)
5043  continue;
5044 
5045  out->time_base = st->time_base;
5046  out->start_time = st->start_time;
5047  out->duration = st->duration;
5048  out->nb_frames = st->nb_frames;
5049  out->discard = st->discard;
5050 
5051  av_assert0(!out_sti->index_entries);
5053  if (!out_sti->index_entries)
5054  return AVERROR(ENOMEM);
5055 
5057  out_sti->nb_index_entries = sti->nb_index_entries;
5058  out_sti->skip_samples = sti->skip_samples;
5059  memcpy(out_sti->index_entries, sti->index_entries, sti->index_entries_allocated_size);
5060  }
5061  }
5062 
5063  return 0;
5064 }
5065 #endif
5066 
5068 {
5069  AVStream *st;
5070  MOVStreamContext *sc;
5071  int ret;
5072 
5073  st = avformat_new_stream(c->fc, NULL);
5074  if (!st) return AVERROR(ENOMEM);
5075  st->id = -1;
5076  sc = av_mallocz(sizeof(MOVStreamContext));
5077  if (!sc) return AVERROR(ENOMEM);
5078 
5079  st->priv_data = sc;
5081  sc->ffindex = st->index;
5082  c->trak_index = st->index;
5083  sc->tref_flags = 0;
5084  sc->tref_id = -1;
5085  sc->refcount = 1;
5086 
5087  if ((ret = mov_read_default(c, pb, atom)) < 0)
5088  return ret;
5089 
5090  c->trak_index = -1;
5091 
5092  // Here stsc refers to a chunk not described in stco. This is technically invalid,
5093  // but we can overlook it (clearing stsc) whenever stts_count == 0 (indicating no samples).
5094  if (!sc->chunk_count && !sc->stts_count && sc->stsc_count) {
5095  sc->stsc_count = 0;
5096  av_freep(&sc->stsc_data);
5097  }
5098 
5099  /* sanity checks */
5100  if ((sc->chunk_count && (!sc->stts_count || !sc->stsc_count ||
5101  (!sc->sample_size && !sc->sample_count))) ||
5102  (!sc->chunk_count && sc->sample_count)) {
5103  av_log(c->fc, AV_LOG_ERROR, "stream %d, missing mandatory atoms, broken header\n",
5104  st->index);
5105  return 0;
5106  }
5107  if (sc->stsc_count && sc->stsc_data[ sc->stsc_count - 1 ].first > sc->chunk_count) {
5108  av_log(c->fc, AV_LOG_ERROR, "stream %d, contradictionary STSC and STCO\n",
5109  st->index);
5110  return AVERROR_INVALIDDATA;
5111  }
5112 
5113  fix_timescale(c, sc);
5114 
5115  avpriv_set_pts_info(st, 64, 1, sc->time_scale);
5116 
5117  /*
5118  * Advanced edit list support does not work with fragemented MP4s, which
5119  * have stsc, stsz, stco, and stts with zero entries in the moov atom.
5120  * In these files, trun atoms may be streamed in.
5121  */
5122  if (!sc->stts_count && c->advanced_editlist) {
5123 
5124  av_log(c->fc, AV_LOG_VERBOSE, "advanced_editlist does not work with fragmented "
5125  "MP4. disabling.\n");
5126  c->advanced_editlist = 0;
5127  c->advanced_editlist_autodisabled = 1;
5128  }
5129 
5130  mov_build_index(c, st);
5131 
5132 #if CONFIG_IAMFDEC
5133  if (sc->iamf) {
5134  ret = mov_update_iamf_streams(c, st);
5135  if (ret < 0)
5136  return ret;
5137  }
5138 #endif
5139 
5140  if (sc->dref_id-1 < sc->drefs_count && sc->drefs[sc->dref_id-1].path) {
5141  MOVDref *dref = &sc->drefs[sc->dref_id - 1];
5142  if (c->enable_drefs) {
5143  if (mov_open_dref(c, &sc->pb, c->fc->url, dref) < 0)
5144  av_log(c->fc, AV_LOG_ERROR,
5145  "stream %d, error opening alias: path='%s', dir='%s', "
5146  "filename='%s', volume='%s', nlvl_from=%d, nlvl_to=%d\n",
5147  st->index, dref->path, dref->dir, dref->filename,
5148  dref->volume, dref->nlvl_from, dref->nlvl_to);
5149  } else {
5150  av_log(c->fc, AV_LOG_WARNING,
5151  "Skipped opening external track: "
5152  "stream %d, alias: path='%s', dir='%s', "
5153  "filename='%s', volume='%s', nlvl_from=%d, nlvl_to=%d."
5154  "Set enable_drefs to allow this.\n",
5155  st->index, dref->path, dref->dir, dref->filename,
5156  dref->volume, dref->nlvl_from, dref->nlvl_to);
5157  }
5158  } else {
5159  sc->pb = c->fc->pb;
5160  sc->pb_is_copied = 1;
5161  }
5162 
5163  if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
5164  if (sc->h_spacing && sc->v_spacing)
5166  sc->h_spacing, sc->v_spacing, INT_MAX);
5167  if (!st->sample_aspect_ratio.num && st->codecpar->width && st->codecpar->height &&
5168  sc->height && sc->width &&
5169  (st->codecpar->width != sc->width || st->codecpar->height != sc->height)) {
5171  (int64_t)st->codecpar->height * sc->width,
5172  (int64_t)st->codecpar->width * sc->height, INT_MAX);
5173  }
5174 
5175 #if FF_API_R_FRAME_RATE
5176  if (sc->stts_count == 1 || (sc->stts_count == 2 && sc->stts_data[1].count == 1))
5178  sc->time_scale, sc->stts_data[0].duration, INT_MAX);
5179 #endif
5180  }
5181 
5182  // done for ai5q, ai52, ai55, ai1q, ai12 and ai15.
5183  if (!st->codecpar->extradata_size && st->codecpar->codec_id == AV_CODEC_ID_H264 &&
5184  TAG_IS_AVCI(st->codecpar->codec_tag)) {
5186  if (ret < 0)
5187  return ret;
5188  }
5189 
5190  switch (st->codecpar->codec_id) {
5191 #if CONFIG_H261_DECODER
5192  case AV_CODEC_ID_H261:
5193 #endif
5194 #if CONFIG_H263_DECODER
5195  case AV_CODEC_ID_H263:
5196 #endif
5197 #if CONFIG_MPEG4_DECODER
5198  case AV_CODEC_ID_MPEG4:
5199 #endif
5200  st->codecpar->width = 0; /* let decoder init width/height */
5201  st->codecpar->height= 0;
5202  break;
5203  }
5204 
5205  // If the duration of the mp3 packets is not constant, then they could need a parser
5206  if (st->codecpar->codec_id == AV_CODEC_ID_MP3
5207  && sc->stts_count > 3
5208  && sc->stts_count*10 > st->nb_frames
5209  && sc->time_scale == st->codecpar->sample_rate) {
5211  }
5212  /* Do not need those anymore. */
5213  av_freep(&sc->chunk_offsets);
5214  av_freep(&sc->sample_sizes);
5215  av_freep(&sc->keyframes);
5216  av_freep(&sc->stts_data);
5217  av_freep(&sc->stps_data);
5218  av_freep(&sc->elst_data);
5219  av_freep(&sc->rap_group);
5220  av_freep(&sc->sync_group);
5221  av_freep(&sc->sgpd_sync);
5222 
5223  return 0;
5224 }
5225 
5227 {
5228  int ret;
5229  c->itunes_metadata = 1;
5230  ret = mov_read_default(c, pb, atom);
5231  c->itunes_metadata = 0;
5232  return ret;
5233 }
5234 
5236 {
5237  uint32_t count;
5238  uint32_t i;
5239 
5240  if (atom.size < 8)
5241  return 0;
5242 
5243  avio_skip(pb, 4);
5244  count = avio_rb32(pb);
5245  atom.size -= 8;
5246  if (count >= UINT_MAX / sizeof(*c->meta_keys)) {
5247  av_log(c->fc, AV_LOG_ERROR,
5248  "The 'keys' atom with the invalid key count: %"PRIu32"\n", count);
5249  return AVERROR_INVALIDDATA;
5250  }
5251 
5252  c->meta_keys_count = count + 1;
5253  c->meta_keys = av_mallocz(c->meta_keys_count * sizeof(*c->meta_keys));
5254  if (!c->meta_keys)
5255  return AVERROR(ENOMEM);
5256 
5257  for (i = 1; i <= count; ++i) {
5258  uint32_t key_size = avio_rb32(pb);
5259  uint32_t type = avio_rl32(pb);
5260  if (key_size < 8 || key_size > atom.size) {
5261  av_log(c->fc, AV_LOG_ERROR,
5262  "The key# %"PRIu32" in meta has invalid size:"
5263  "%"PRIu32"\n", i, key_size);
5264  return AVERROR_INVALIDDATA;
5265  }
5266  atom.size -= key_size;
5267  key_size -= 8;
5268  if (type != MKTAG('m','d','t','a')) {
5269  avio_skip(pb, key_size);
5270  continue;
5271  }
5272  c->meta_keys[i] = av_mallocz(key_size + 1);
5273  if (!c->meta_keys[i])
5274  return AVERROR(ENOMEM);
5275  avio_read(pb, c->meta_keys[i], key_size);
5276  }
5277 
5278  return 0;
5279 }
5280 
5282 {
5283  int64_t end = av_sat_add64(avio_tell(pb), atom.size);
5284  uint8_t *key = NULL, *val = NULL, *mean = NULL;
5285  int i;
5286  int ret = 0;
5287  AVStream *st;
5288  MOVStreamContext *sc;
5289 
5290  if (c->fc->nb_streams < 1)
5291  return 0;
5292  st = c->fc->streams[c->fc->nb_streams-1];
5293  sc = st->priv_data;
5294 
5295  for (i = 0; i < 3; i++) {
5296  uint8_t **p;
5297  uint32_t len, tag;
5298 
5299  if (end - avio_tell(pb) <= 12)
5300  break;
5301 
5302  len = avio_rb32(pb);
5303  tag = avio_rl32(pb);
5304  avio_skip(pb, 4); // flags
5305 
5306  if (len < 12 || len - 12 > end - avio_tell(pb))
5307  break;
5308  len -= 12;
5309 
5310  if (tag == MKTAG('m', 'e', 'a', 'n'))
5311  p = &mean;
5312  else if (tag == MKTAG('n', 'a', 'm', 'e'))
5313  p = &key;
5314  else if (tag == MKTAG('d', 'a', 't', 'a') && len > 4) {
5315  avio_skip(pb, 4);
5316  len -= 4;
5317  p = &val;
5318  } else
5319  break;
5320 
5321  if (*p)
5322  break;
5323 
5324  *p = av_malloc(len + 1);
5325  if (!*p) {
5326  ret = AVERROR(ENOMEM);
5327  break;
5328  }
5329  ret = ffio_read_size(pb, *p, len);
5330  if (ret < 0) {
5331  av_freep(p);
5332  break;
5333  }
5334  (*p)[len] = 0;
5335  }
5336 
5337  if (mean && key && val) {
5338  if (strcmp(key, "iTunSMPB") == 0) {
5339  int priming, remainder, samples;
5340  if(sscanf(val, "%*X %X %X %X", &priming, &remainder, &samples) == 3){
5341  if(priming>0 && priming<16384)
5342  sc->start_pad = priming;
5343  }
5344  }
5345  if (strcmp(key, "cdec") != 0) {
5346  av_dict_set(&c->fc->metadata, key, val,
5348  key = val = NULL;
5349  }
5350  } else {
5351  av_log(c->fc, AV_LOG_VERBOSE,
5352  "Unhandled or malformed custom metadata of size %"PRId64"\n", atom.size);
5353  }
5354 
5355  avio_seek(pb, end, SEEK_SET);
5356  av_freep(&key);
5357  av_freep(&val);
5358  av_freep(&mean);
5359  return ret;
5360 }
5361 
5363 {
5364  MOVStreamContext *sc;
5365  AVStream *st;
5366 
5367  st = avformat_new_stream(c->fc, NULL);
5368  if (!st)
5369  return AVERROR(ENOMEM);
5370  sc = av_mallocz(sizeof(MOVStreamContext));
5371  if (!sc)
5372  return AVERROR(ENOMEM);
5373 
5374  item->st = st;
5375  st->id = item->item_id;
5376  st->priv_data = sc;
5378  st->codecpar->codec_id = mov_codec_id(st, item->type);
5379  sc->id = st->id;
5380  sc->ffindex = st->index;
5381  st->avg_frame_rate.num = st->avg_frame_rate.den = 1;
5382  st->time_base.num = st->time_base.den = 1;
5383  st->nb_frames = 1;
5384  sc->time_scale = 1;
5385  sc->pb = c->fc->pb;
5386  sc->pb_is_copied = 1;
5387  sc->refcount = 1;
5388 
5389  if (item->name)
5390  av_dict_set(&st->metadata, "title", item->name, 0);
5391 
5392  // Populate the necessary fields used by mov_build_index.
5393  sc->stsc_count = 1;
5394  sc->stsc_data = av_malloc_array(1, sizeof(*sc->stsc_data));
5395  if (!sc->stsc_data)
5396  return AVERROR(ENOMEM);
5397  sc->stsc_data[0].first = 1;
5398  sc->stsc_data[0].count = 1;
5399  sc->stsc_data[0].id = 1;
5400  sc->chunk_count = 1;
5401  sc->chunk_offsets = av_malloc_array(1, sizeof(*sc->chunk_offsets));
5402  if (!sc->chunk_offsets)
5403  return AVERROR(ENOMEM);
5404  sc->sample_count = 1;
5405  sc->sample_sizes = av_malloc_array(1, sizeof(*sc->sample_sizes));
5406  if (!sc->sample_sizes)
5407  return AVERROR(ENOMEM);
5408  sc->stts_count = 1;
5409  sc->stts_data = av_malloc_array(1, sizeof(*sc->stts_data));
5410  if (!sc->stts_data)
5411  return AVERROR(ENOMEM);
5412  sc->stts_data[0].count = 1;
5413  // Not used for still images. But needed by mov_build_index.
5414  sc->stts_data[0].duration = 0;
5415 
5416  return 0;
5417 }
5418 
5420 {
5421  while (atom.size > 8) {
5422  uint32_t tag;
5423  if (avio_feof(pb))
5424  return AVERROR_EOF;
5425  tag = avio_rl32(pb);
5426  atom.size -= 4;
5427  if (tag == MKTAG('h','d','l','r')) {
5428  avio_seek(pb, -8, SEEK_CUR);
5429  atom.size += 8;
5430  return mov_read_default(c, pb, atom);
5431  }
5432  }
5433  return 0;
5434 }
5435 
5436 // return 1 when matrix is identity, 0 otherwise
5437 #define IS_MATRIX_IDENT(matrix) \
5438  ( (matrix)[0][0] == (1 << 16) && \
5439  (matrix)[1][1] == (1 << 16) && \
5440  (matrix)[2][2] == (1 << 30) && \
5441  !(matrix)[0][1] && !(matrix)[0][2] && \
5442  !(matrix)[1][0] && !(matrix)[1][2] && \
5443  !(matrix)[2][0] && !(matrix)[2][1])
5444 
5446 {
5447  int i, j, e;
5448  int width;
5449  int height;
5450  int display_matrix[3][3];
5451  int res_display_matrix[3][3] = { { 0 } };
5452  AVStream *st;
5453  MOVStreamContext *sc;
5454  int version;
5455  int flags;
5456 
5457  if (c->fc->nb_streams < 1)
5458  return 0;
5459  st = c->fc->streams[c->fc->nb_streams-1];
5460  sc = st->priv_data;
5461 
5462  // Each stream (trak) should have exactly 1 tkhd. This catches bad files and
5463  // avoids corrupting AVStreams mapped to an earlier tkhd.
5464  if (st->id != -1)
5465  return AVERROR_INVALIDDATA;
5466 
5467  version = avio_r8(pb);
5468  flags = avio_rb24(pb);
5470 
5471  if (version == 1) {
5472  avio_rb64(pb);
5473  avio_rb64(pb);
5474  } else {
5475  avio_rb32(pb); /* creation time */
5476  avio_rb32(pb); /* modification time */
5477  }
5478  st->id = (int)avio_rb32(pb); /* track id (NOT 0 !)*/
5479  sc->id = st->id;
5480  avio_rb32(pb); /* reserved */
5481 
5482  /* highlevel (considering edits) duration in movie timebase */
5483  (version == 1) ? avio_rb64(pb) : avio_rb32(pb);
5484  avio_rb32(pb); /* reserved */
5485  avio_rb32(pb); /* reserved */
5486 
5487  avio_rb16(pb); /* layer */
5488  avio_rb16(pb); /* alternate group */
5489  avio_rb16(pb); /* volume */
5490  avio_rb16(pb); /* reserved */
5491 
5492  //read in the display matrix (outlined in ISO 14496-12, Section 6.2.2)
5493  // they're kept in fixed point format through all calculations
5494  // save u,v,z to store the whole matrix in the AV_PKT_DATA_DISPLAYMATRIX
5495  // side data, but the scale factor is not needed to calculate aspect ratio
5496  for (i = 0; i < 3; i++) {
5497  display_matrix[i][0] = avio_rb32(pb); // 16.16 fixed point
5498  display_matrix[i][1] = avio_rb32(pb); // 16.16 fixed point
5499  display_matrix[i][2] = avio_rb32(pb); // 2.30 fixed point
5500  }
5501 
5502  width = avio_rb32(pb); // 16.16 fixed point track width
5503  height = avio_rb32(pb); // 16.16 fixed point track height
5504  sc->width = width >> 16;
5505  sc->height = height >> 16;
5506 
5507  // apply the moov display matrix (after the tkhd one)
5508  for (i = 0; i < 3; i++) {
5509  const int sh[3] = { 16, 16, 30 };
5510  for (j = 0; j < 3; j++) {
5511  for (e = 0; e < 3; e++) {
5512  res_display_matrix[i][j] +=
5513  ((int64_t) display_matrix[i][e] *
5514  c->movie_display_matrix[e][j]) >> sh[e];
5515  }
5516  }
5517  }
5518 
5519  // save the matrix when it is not the default identity
5520  if (!IS_MATRIX_IDENT(res_display_matrix)) {
5521  av_freep(&sc->display_matrix);
5522  sc->display_matrix = av_malloc(sizeof(int32_t) * 9);
5523  if (!sc->display_matrix)
5524  return AVERROR(ENOMEM);
5525 
5526  for (i = 0; i < 3; i++)
5527  for (j = 0; j < 3; j++)
5528  sc->display_matrix[i * 3 + j] = res_display_matrix[i][j];
5529  }
5530 
5531  // transform the display width/height according to the matrix
5532  // to keep the same scale, use [width height 1<<16]
5533  if (width && height && sc->display_matrix) {
5534  double disp_transform[2];
5535 
5536  for (i = 0; i < 2; i++)
5537  disp_transform[i] = hypot(sc->display_matrix[0 + i],
5538  sc->display_matrix[3 + i]);
5539 
5540  if (disp_transform[0] > 1 && disp_transform[1] > 1 &&
5541  disp_transform[0] < (1<<24) && disp_transform[1] < (1<<24) &&
5542  fabs((disp_transform[0] / disp_transform[1]) - 1.0) > 0.01)
5544  disp_transform[0] / disp_transform[1],
5545  INT_MAX);
5546  }
5547  return 0;
5548 }
5549 
5551 {
5552  MOVFragment *frag = &c->fragment;
5553  MOVTrackExt *trex = NULL;
5554  int flags, track_id, i;
5555  MOVFragmentStreamInfo * frag_stream_info;
5556 
5557  avio_r8(pb); /* version */
5558  flags = avio_rb24(pb);
5559 
5560  track_id = avio_rb32(pb);
5561  if (!track_id)
5562  return AVERROR_INVALIDDATA;
5563  for (i = 0; i < c->trex_count; i++)
5564  if (c->trex_data[i].track_id == track_id) {
5565  trex = &c->trex_data[i];
5566  break;
5567  }
5568  if (!trex) {
5569  av_log(c->fc, AV_LOG_WARNING, "could not find corresponding trex (id %u)\n", track_id);
5570  return 0;
5571  }
5572  c->fragment.found_tfhd = 1;
5573  frag->track_id = track_id;
5574  set_frag_stream(&c->frag_index, track_id);
5575 
5578  frag->moof_offset : frag->implicit_offset;
5579  frag->stsd_id = flags & MOV_TFHD_STSD_ID ? avio_rb32(pb) : trex->stsd_id;
5580 
5582  avio_rb32(pb) : trex->duration;
5583  frag->size = flags & MOV_TFHD_DEFAULT_SIZE ?
5584  avio_rb32(pb) : trex->size;
5585  frag->flags = flags & MOV_TFHD_DEFAULT_FLAGS ?
5586  avio_rb32(pb) : trex->flags;
5587  av_log(c->fc, AV_LOG_TRACE, "frag flags 0x%x\n", frag->flags);
5588 
5589  frag_stream_info = get_current_frag_stream_info(&c->frag_index);
5590  if (frag_stream_info) {
5591  frag_stream_info->next_trun_dts = AV_NOPTS_VALUE;
5592  frag_stream_info->stsd_id = frag->stsd_id;
5593  }
5594  return 0;
5595 }
5596 
5598 {
5599  unsigned i, num;
5600  void *new_tracks;
5601 
5602  num = atom.size / 4;
5603  if (!(new_tracks = av_malloc_array(num, sizeof(int))))
5604  return AVERROR(ENOMEM);
5605 
5606  av_free(c->chapter_tracks);
5607  c->chapter_tracks = new_tracks;
5608  c->nb_chapter_tracks = num;
5609 
5610  for (i = 0; i < num && !pb->eof_reached; i++)
5611  c->chapter_tracks[i] = avio_rb32(pb);
5612 
5613  c->nb_chapter_tracks = i;
5614 
5615  return 0;
5616 }
5617 
5619 {
5620  MOVTrackExt *trex;
5621  int err;
5622 
5623  if ((uint64_t)c->trex_count+1 >= UINT_MAX / sizeof(*c->trex_data))
5624  return AVERROR_INVALIDDATA;
5625  if ((err = av_reallocp_array(&c->trex_data, c->trex_count + 1,
5626  sizeof(*c->trex_data))) < 0) {
5627  c->trex_count = 0;
5628  return err;
5629  }
5630 
5631  c->fc->duration = AV_NOPTS_VALUE; // the duration from mvhd is not representing the whole file when fragments are used.
5632 
5633  trex = &c->trex_data[c->trex_count++];
5634  avio_r8(pb); /* version */
5635  avio_rb24(pb); /* flags */
5636  trex->track_id = avio_rb32(pb);
5637  trex->stsd_id = avio_rb32(pb);
5638  trex->duration = avio_rb32(pb);
5639  trex->size = avio_rb32(pb);
5640  trex->flags = avio_rb32(pb);
5641  return 0;
5642 }
5643 
5645 {
5646  MOVFragment *frag = &c->fragment;
5647  AVStream *st = NULL;
5648  MOVStreamContext *sc;
5649  int version, i;
5650  MOVFragmentStreamInfo * frag_stream_info;
5651  int64_t base_media_decode_time;
5652 
5653  for (i = 0; i < c->fc->nb_streams; i++) {
5654  sc = c->fc->streams[i]->priv_data;
5655  if (sc->id == frag->track_id) {
5656  st = c->fc->streams[i];
5657  break;
5658  }
5659  }
5660  if (!st) {
5661  av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %u\n", frag->track_id);
5662  return 0;
5663  }
5664  sc = st->priv_data;
5665  if (sc->pseudo_stream_id + 1 != frag->stsd_id && sc->pseudo_stream_id != -1)
5666  return 0;
5667  version = avio_r8(pb);
5668  avio_rb24(pb); /* flags */
5669  if (version) {
5670  base_media_decode_time = avio_rb64(pb);
5671  } else {
5672  base_media_decode_time = avio_rb32(pb);
5673  }
5674 
5675  frag_stream_info = get_current_frag_stream_info(&c->frag_index);
5676  if (frag_stream_info)
5677  frag_stream_info->tfdt_dts = base_media_decode_time;
5678  sc->track_end = base_media_decode_time;
5679 
5680  return 0;
5681 }
5682 
5684 {
5685  MOVFragment *frag = &c->fragment;
5686  AVStream *st = NULL;
5687  FFStream *sti = NULL;
5688  MOVStreamContext *sc;
5689  MOVCtts *ctts_data;
5690  uint64_t offset;
5691  int64_t dts, pts = AV_NOPTS_VALUE;
5692  int data_offset = 0;
5693  unsigned entries, first_sample_flags = frag->flags;
5694  int flags, distance, i;
5695  int64_t prev_dts = AV_NOPTS_VALUE;
5696  int next_frag_index = -1, index_entry_pos;
5697  size_t requested_size;
5698  size_t old_ctts_allocated_size;
5699  AVIndexEntry *new_entries;
5700  MOVFragmentStreamInfo * frag_stream_info;
5701 
5702  if (!frag->found_tfhd) {
5703  av_log(c->fc, AV_LOG_ERROR, "trun track id unknown, no tfhd was found\n");
5704  return AVERROR_INVALIDDATA;
5705  }
5706 
5707  for (i = 0; i < c->fc->nb_streams; i++) {
5708  sc = c->fc->streams[i]->priv_data;
5709  if (sc->id == frag->track_id) {
5710  st = c->fc->streams[i];
5711  sti = ffstream(st);
5712  break;
5713  }
5714  }
5715  if (!st) {
5716  av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %u\n", frag->track_id);
5717  return 0;
5718  }
5719  sc = st->priv_data;
5720  if (sc->pseudo_stream_id+1 != frag->stsd_id && sc->pseudo_stream_id != -1)
5721  return 0;
5722 
5723  // Find the next frag_index index that has a valid index_entry for
5724  // the current track_id.
5725  //
5726  // A valid index_entry means the trun for the fragment was read
5727  // and it's samples are in index_entries at the given position.
5728  // New index entries will be inserted before the index_entry found.
5729  index_entry_pos = sti->nb_index_entries;
5730  for (i = c->frag_index.current + 1; i < c->frag_index.nb_items; i++) {
5731  frag_stream_info = get_frag_stream_info(&c->frag_index, i, frag->track_id);
5732  if (frag_stream_info && frag_stream_info->index_entry >= 0) {
5733  next_frag_index = i;
5734  index_entry_pos = frag_stream_info->index_entry;
5735  break;
5736  }
5737  }
5738  av_assert0(index_entry_pos <= sti->nb_index_entries);
5739 
5740  avio_r8(pb); /* version */
5741  flags = avio_rb24(pb);
5742  entries = avio_rb32(pb);
5743  av_log(c->fc, AV_LOG_TRACE, "flags 0x%x entries %u\n", flags, entries);
5744 
5745  if ((uint64_t)entries+sc->ctts_count >= UINT_MAX/sizeof(*sc->ctts_data))
5746  return AVERROR_INVALIDDATA;
5747  if (flags & MOV_TRUN_DATA_OFFSET) data_offset = avio_rb32(pb);
5748  if (flags & MOV_TRUN_FIRST_SAMPLE_FLAGS) first_sample_flags = avio_rb32(pb);
5749 
5750  frag_stream_info = get_current_frag_stream_info(&c->frag_index);
5751  if (frag_stream_info) {
5752  if (frag_stream_info->next_trun_dts != AV_NOPTS_VALUE) {
5753  dts = frag_stream_info->next_trun_dts - sc->time_offset;
5754  } else if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE &&
5755  c->use_mfra_for == FF_MOV_FLAG_MFRA_PTS) {
5756  pts = frag_stream_info->first_tfra_pts;
5757  av_log(c->fc, AV_LOG_DEBUG, "found mfra time %"PRId64
5758  ", using it for pts\n", pts);
5759  } else if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE &&
5760  c->use_mfra_for == FF_MOV_FLAG_MFRA_DTS) {
5761  dts = frag_stream_info->first_tfra_pts;
5762  av_log(c->fc, AV_LOG_DEBUG, "found mfra time %"PRId64
5763  ", using it for dts\n", pts);
5764  } else {
5765  int has_tfdt = frag_stream_info->tfdt_dts != AV_NOPTS_VALUE;
5766  int has_sidx = frag_stream_info->sidx_pts != AV_NOPTS_VALUE;
5767  int fallback_tfdt = !c->use_tfdt && !has_sidx && has_tfdt;
5768  int fallback_sidx = c->use_tfdt && !has_tfdt && has_sidx;
5769 
5770  if (fallback_sidx) {
5771  av_log(c->fc, AV_LOG_DEBUG, "use_tfdt set but no tfdt found, using sidx instead\n");
5772  }
5773  if (fallback_tfdt) {
5774  av_log(c->fc, AV_LOG_DEBUG, "use_tfdt not set but no sidx found, using tfdt instead\n");
5775  }
5776 
5777  if (has_tfdt && c->use_tfdt || fallback_tfdt) {
5778  dts = frag_stream_info->tfdt_dts - sc->time_offset;
5779  av_log(c->fc, AV_LOG_DEBUG, "found tfdt time %"PRId64
5780  ", using it for dts\n", dts);
5781  } else if (has_sidx && !c->use_tfdt || fallback_sidx) {
5782  // FIXME: sidx earliest_presentation_time is *PTS*, s.b.
5783  // pts = frag_stream_info->sidx_pts;
5784  dts = frag_stream_info->sidx_pts - sc->time_offset;
5785  av_log(c->fc, AV_LOG_DEBUG, "found sidx time %"PRId64
5786  ", using it for dts\n", frag_stream_info->sidx_pts);
5787  } else {
5788  dts = sc->track_end - sc->time_offset;
5789  av_log(c->fc, AV_LOG_DEBUG, "found track end time %"PRId64
5790  ", using it for dts\n", dts);
5791  }
5792  }
5793  } else {
5794  dts = sc->track_end - sc->time_offset;
5795  av_log(c->fc, AV_LOG_DEBUG, "found track end time %"PRId64
5796  ", using it for dts\n", dts);
5797  }
5798  offset = frag->base_data_offset + data_offset;
5799  distance = 0;
5800  av_log(c->fc, AV_LOG_TRACE, "first sample flags 0x%x\n", first_sample_flags);
5801 
5802  // realloc space for new index entries
5803  if ((uint64_t)sti->nb_index_entries + entries >= UINT_MAX / sizeof(AVIndexEntry)) {
5804  entries = UINT_MAX / sizeof(AVIndexEntry) - sti->nb_index_entries;
5805  av_log(c->fc, AV_LOG_ERROR, "Failed to add index entry\n");
5806  }
5807  if (entries == 0)
5808  return 0;
5809 
5810  requested_size = (sti->nb_index_entries + entries) * sizeof(AVIndexEntry);
5811  new_entries = av_fast_realloc(sti->index_entries,
5813  requested_size);
5814  if (!new_entries)
5815  return AVERROR(ENOMEM);
5816  sti->index_entries= new_entries;
5817 
5818  requested_size = (sti->nb_index_entries + entries) * sizeof(*sc->ctts_data);
5819  old_ctts_allocated_size = sc->ctts_allocated_size;
5820  ctts_data = av_fast_realloc(sc->ctts_data, &sc->ctts_allocated_size,
5821  requested_size);
5822  if (!ctts_data)
5823  return AVERROR(ENOMEM);
5824  sc->ctts_data = ctts_data;
5825 
5826  // In case there were samples without ctts entries, ensure they get
5827  // zero valued entries. This ensures clips which mix boxes with and
5828  // without ctts entries don't pickup uninitialized data.
5829  memset((uint8_t*)(sc->ctts_data) + old_ctts_allocated_size, 0,
5830  sc->ctts_allocated_size - old_ctts_allocated_size);
5831 
5832  if (index_entry_pos < sti->nb_index_entries) {
5833  // Make hole in index_entries and ctts_data for new samples
5834  memmove(sti->index_entries + index_entry_pos + entries,
5835  sti->index_entries + index_entry_pos,
5836  sizeof(*sti->index_entries) *
5837  (sti->nb_index_entries - index_entry_pos));
5838  memmove(sc->ctts_data + index_entry_pos + entries,
5839  sc->ctts_data + index_entry_pos,
5840  sizeof(*sc->ctts_data) * (sc->ctts_count - index_entry_pos));
5841  if (index_entry_pos < sc->current_sample) {
5842  sc->current_sample += entries;
5843  }
5844  }
5845 
5846  sti->nb_index_entries += entries;
5847  sc->ctts_count = sti->nb_index_entries;
5848 
5849  // Record the index_entry position in frag_index of this fragment
5850  if (frag_stream_info) {
5851  frag_stream_info->index_entry = index_entry_pos;
5852  if (frag_stream_info->index_base < 0)
5853  frag_stream_info->index_base = index_entry_pos;
5854  }
5855 
5856  if (index_entry_pos > 0)
5857  prev_dts = sti->index_entries[index_entry_pos-1].timestamp;
5858 
5859  for (i = 0; i < entries && !pb->eof_reached; i++) {
5860  unsigned sample_size = frag->size;
5861  int sample_flags = i ? frag->flags : first_sample_flags;
5862  unsigned sample_duration = frag->duration;
5863  unsigned ctts_duration = 0;
5864  int keyframe = 0;
5865  int index_entry_flags = 0;
5866 
5867  if (flags & MOV_TRUN_SAMPLE_DURATION) sample_duration = avio_rb32(pb);
5868  if (flags & MOV_TRUN_SAMPLE_SIZE) sample_size = avio_rb32(pb);
5869  if (flags & MOV_TRUN_SAMPLE_FLAGS) sample_flags = avio_rb32(pb);
5870  if (flags & MOV_TRUN_SAMPLE_CTS) ctts_duration = avio_rb32(pb);
5871 
5872  mov_update_dts_shift(sc, ctts_duration, c->fc);
5873  if (pts != AV_NOPTS_VALUE) {
5874  dts = pts - sc->dts_shift;
5875  if (flags & MOV_TRUN_SAMPLE_CTS) {
5876  dts -= ctts_duration;
5877  } else {
5878  dts -= sc->time_offset;
5879  }
5880  av_log(c->fc, AV_LOG_DEBUG,
5881  "pts %"PRId64" calculated dts %"PRId64
5882  " sc->dts_shift %d ctts.duration %d"
5883  " sc->time_offset %"PRId64
5884  " flags & MOV_TRUN_SAMPLE_CTS %d\n",
5885  pts, dts,
5886  sc->dts_shift, ctts_duration,
5888  pts = AV_NOPTS_VALUE;
5889  }
5890 
5892  keyframe = 1;
5893  else
5894  keyframe =
5895  !(sample_flags & (MOV_FRAG_SAMPLE_FLAG_IS_NON_SYNC |
5897  if (keyframe) {
5898  distance = 0;
5899  index_entry_flags |= AVINDEX_KEYFRAME;
5900  }
5901  // Fragments can overlap in time. Discard overlapping frames after
5902  // decoding.
5903  if (prev_dts >= dts)
5904  index_entry_flags |= AVINDEX_DISCARD_FRAME;
5905 
5906  sti->index_entries[index_entry_pos].pos = offset;
5907  sti->index_entries[index_entry_pos].timestamp = dts;
5908  sti->index_entries[index_entry_pos].size = sample_size;
5909  sti->index_entries[index_entry_pos].min_distance = distance;
5910  sti->index_entries[index_entry_pos].flags = index_entry_flags;
5911 
5912  sc->ctts_data[index_entry_pos].count = 1;
5913  sc->ctts_data[index_entry_pos].duration = ctts_duration;
5914  index_entry_pos++;
5915 
5916  av_log(c->fc, AV_LOG_TRACE, "AVIndex stream %d, sample %d, offset %"PRIx64", dts %"PRId64", "
5917  "size %u, distance %d, keyframe %d\n", st->index,
5918  index_entry_pos, offset, dts, sample_size, distance, keyframe);
5919  distance++;
5920  if (av_sat_add64(dts, sample_duration) != dts + (uint64_t)sample_duration)
5921  return AVERROR_INVALIDDATA;
5922  if (!sample_size)
5923  return AVERROR_INVALIDDATA;
5924  dts += sample_duration;
5925  offset += sample_size;
5926  sc->data_size += sample_size;
5927 
5928  if (sample_duration <= INT64_MAX - sc->duration_for_fps &&
5929  1 <= INT_MAX - sc->nb_frames_for_fps
5930  ) {
5931  sc->duration_for_fps += sample_duration;
5932  sc->nb_frames_for_fps ++;
5933  }
5934  }
5935  if (frag_stream_info)
5936  frag_stream_info->next_trun_dts = dts + sc->time_offset;
5937  if (i < entries) {
5938  // EOF found before reading all entries. Fix the hole this would
5939  // leave in index_entries and ctts_data
5940  int gap = entries - i;
5941  memmove(sti->index_entries + index_entry_pos,
5942  sti->index_entries + index_entry_pos + gap,
5943  sizeof(*sti->index_entries) *
5944  (sti->nb_index_entries - (index_entry_pos + gap)));
5945  memmove(sc->ctts_data + index_entry_pos,
5946  sc->ctts_data + index_entry_pos + gap,
5947  sizeof(*sc->ctts_data) *
5948  (sc->ctts_count - (index_entry_pos + gap)));
5949 
5950  sti->nb_index_entries -= gap;
5951  sc->ctts_count -= gap;
5952  if (index_entry_pos < sc->current_sample) {
5953  sc->current_sample -= gap;
5954  }
5955  entries = i;
5956  }
5957 
5958  // The end of this new fragment may overlap in time with the start
5959  // of the next fragment in index_entries. Mark the samples in the next
5960  // fragment that overlap with AVINDEX_DISCARD_FRAME
5961  prev_dts = AV_NOPTS_VALUE;
5962  if (index_entry_pos > 0)
5963  prev_dts = sti->index_entries[index_entry_pos-1].timestamp;
5964  for (int i = index_entry_pos; i < sti->nb_index_entries; i++) {
5965  if (prev_dts < sti->index_entries[i].timestamp)
5966  break;
5968  }
5969 
5970  // If a hole was created to insert the new index_entries into,
5971  // the index_entry recorded for all subsequent moof must
5972  // be incremented by the number of entries inserted.
5973  fix_frag_index_entries(&c->frag_index, next_frag_index,
5974  frag->track_id, entries);
5975 
5976  if (pb->eof_reached) {
5977  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted TRUN atom\n");
5978  return AVERROR_EOF;
5979  }
5980 
5981  frag->implicit_offset = offset;
5982 
5983  sc->track_end = dts + sc->time_offset;
5984  if (st->duration < sc->track_end)
5985  st->duration = sc->track_end;
5986 
5987  return 0;
5988 }
5989 
5991 {
5992  int64_t stream_size = avio_size(pb);
5993  int64_t offset = av_sat_add64(avio_tell(pb), atom.size), pts, timestamp;
5994  uint8_t version, is_complete;
5995  int64_t offadd;
5996  unsigned i, j, track_id, item_count;
5997  AVStream *st = NULL;
5998  AVStream *ref_st = NULL;
5999  MOVStreamContext *sc, *ref_sc = NULL;
6000  AVRational timescale;
6001 
6002  version = avio_r8(pb);
6003  if (version > 1) {
6004  avpriv_request_sample(c->fc, "sidx version %u", version);
6005  return 0;
6006  }
6007 
6008  avio_rb24(pb); // flags
6009 
6010  track_id = avio_rb32(pb); // Reference ID
6011  for (i = 0; i < c->fc->nb_streams; i++) {
6012  sc = c->fc->streams[i]->priv_data;
6013  if (sc->id == track_id) {
6014  st = c->fc->streams[i];
6015  break;
6016  }
6017  }
6018  if (!st) {
6019  av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %d\n", track_id);
6020  return 0;
6021  }
6022 
6023  sc = st->priv_data;
6024 
6025  timescale = av_make_q(1, avio_rb32(pb));
6026 
6027  if (timescale.den <= 0) {
6028  av_log(c->fc, AV_LOG_ERROR, "Invalid sidx timescale 1/%d\n", timescale.den);
6029  return AVERROR_INVALIDDATA;
6030  }
6031 
6032  if (version == 0) {
6033  pts = avio_rb32(pb);
6034  offadd= avio_rb32(pb);
6035  } else {
6036  pts = avio_rb64(pb);
6037  offadd= avio_rb64(pb);
6038  }
6039  if (av_sat_add64(offset, offadd) != offset + (uint64_t)offadd)
6040  return AVERROR_INVALIDDATA;
6041 
6042  offset += (uint64_t)offadd;
6043 
6044  avio_rb16(pb); // reserved
6045 
6046  item_count = avio_rb16(pb);
6047  if (item_count == 0)
6048  return AVERROR_INVALIDDATA;
6049 
6050  for (i = 0; i < item_count; i++) {
6051  int index;
6052  MOVFragmentStreamInfo * frag_stream_info;
6053  uint32_t size = avio_rb32(pb);
6054  uint32_t duration = avio_rb32(pb);
6055  if (size & 0x80000000) {
6056  avpriv_request_sample(c->fc, "sidx reference_type 1");
6057  return AVERROR_PATCHWELCOME;
6058  }
6059  avio_rb32(pb); // sap_flags
6060  timestamp = av_rescale_q(pts, timescale, st->time_base);
6061 
6063  frag_stream_info = get_frag_stream_info(&c->frag_index, index, track_id);
6064  if (frag_stream_info)
6065  frag_stream_info->sidx_pts = timestamp;
6066 
6067  if (av_sat_add64(offset, size) != offset + (uint64_t)size ||
6068  av_sat_add64(pts, duration) != pts + (uint64_t)duration
6069  )
6070  return AVERROR_INVALIDDATA;
6071  offset += size;
6072  pts += duration;
6073  }
6074 
6075  st->duration = sc->track_end = pts;
6076 
6077  sc->has_sidx = 1;
6078 
6079  // See if the remaining bytes are just an mfra which we can ignore.
6080  is_complete = offset == stream_size;
6081  if (!is_complete && (pb->seekable & AVIO_SEEKABLE_NORMAL) && stream_size > 0 ) {
6082  int64_t ret;
6083  int64_t original_pos = avio_tell(pb);
6084  if (!c->have_read_mfra_size) {
6085  if ((ret = avio_seek(pb, stream_size - 4, SEEK_SET)) < 0)
6086  return ret;
6087  c->mfra_size = avio_rb32(pb);
6088  c->have_read_mfra_size = 1;
6089  if ((ret = avio_seek(pb, original_pos, SEEK_SET)) < 0)
6090  return ret;
6091  }
6092  if (offset == stream_size - c->mfra_size)
6093  is_complete = 1;
6094  }
6095 
6096  if (is_complete) {
6097  // Find first entry in fragment index that came from an sidx.
6098  // This will pretty much always be the first entry.
6099  for (i = 0; i < c->frag_index.nb_items; i++) {
6100  MOVFragmentIndexItem * item = &c->frag_index.item[i];
6101  for (j = 0; ref_st == NULL && j < item->nb_stream_info; j++) {
6102  MOVFragmentStreamInfo * si;
6103  si = &item->stream_info[j];
6104  if (si->sidx_pts != AV_NOPTS_VALUE) {
6105  ref_st = c->fc->streams[j];
6106  ref_sc = ref_st->priv_data;
6107  break;
6108  }
6109  }
6110  }
6111  if (ref_st) for (i = 0; i < c->fc->nb_streams; i++) {
6112  st = c->fc->streams[i];
6113  sc = st->priv_data;
6114  if (!sc->has_sidx) {
6115  st->duration = sc->track_end = av_rescale(ref_st->duration, sc->time_scale, ref_sc->time_scale);
6116  }
6117  }
6118 
6119  c->frag_index.complete = 1;
6120  }
6121 
6122  return 0;
6123 }
6124 
6125 /* this atom should be null (from specs), but some buggy files put the 'moov' atom inside it... */
6126 /* like the files created with Adobe Premiere 5.0, for samples see */
6127 /* http://graphics.tudelft.nl/~wouter/publications/soundtests/ */
6129 {
6130  int err;
6131 
6132  if (atom.size < 8)
6133  return 0; /* continue */
6134  if (avio_rb32(pb) != 0) { /* 0 sized mdat atom... use the 'wide' atom size */
6135  avio_skip(pb, atom.size - 4);
6136  return 0;
6137  }
6138  atom.type = avio_rl32(pb);
6139  atom.size -= 8;
6140  if (atom.type != MKTAG('m','d','a','t')) {
6141  avio_skip(pb, atom.size);
6142  return 0;
6143  }
6144  err = mov_read_mdat(c, pb, atom);
6145  return err;
6146 }
6147 
6149 {
6150 #if CONFIG_ZLIB
6151  FFIOContext ctx;
6152  uint8_t *cmov_data;
6153  uint8_t *moov_data; /* uncompressed data */
6154  long cmov_len, moov_len;
6155  int ret = -1;
6156 
6157  avio_rb32(pb); /* dcom atom */
6158  if (avio_rl32(pb) != MKTAG('d','c','o','m'))
6159  return AVERROR_INVALIDDATA;
6160  if (avio_rl32(pb) != MKTAG('z','l','i','b')) {
6161  av_log(c->fc, AV_LOG_ERROR, "unknown compression for cmov atom !\n");
6162  return AVERROR_INVALIDDATA;
6163  }
6164  avio_rb32(pb); /* cmvd atom */
6165  if (avio_rl32(pb) != MKTAG('c','m','v','d'))
6166  return AVERROR_INVALIDDATA;
6167  moov_len = avio_rb32(pb); /* uncompressed size */
6168  cmov_len = atom.size - 6 * 4;
6169 
6170  cmov_data = av_malloc(cmov_len);
6171  if (!cmov_data)
6172  return AVERROR(ENOMEM);
6173  moov_data = av_malloc(moov_len);
6174  if (!moov_data) {
6175  av_free(cmov_data);
6176  return AVERROR(ENOMEM);
6177  }
6178  ret = ffio_read_size(pb, cmov_data, cmov_len);
6179  if (ret < 0)
6180  goto free_and_return;
6181 
6183  if (uncompress (moov_data, (uLongf *) &moov_len, (const Bytef *)cmov_data, cmov_len) != Z_OK)
6184  goto free_and_return;
6185  ffio_init_read_context(&ctx, moov_data, moov_len);
6186  ctx.pub.seekable = AVIO_SEEKABLE_NORMAL;
6187  atom.type = MKTAG('m','o','o','v');
6188  atom.size = moov_len;
6189  ret = mov_read_default(c, &ctx.pub, atom);
6190 free_and_return:
6191  av_free(moov_data);
6192  av_free(cmov_data);
6193  return ret;
6194 #else
6195  av_log(c->fc, AV_LOG_ERROR, "this file requires zlib support compiled in\n");
6196  return AVERROR(ENOSYS);
6197 #endif
6198 }
6199 
6200 /* edit list atom */
6202 {
6203  MOVStreamContext *sc;
6204  int i, edit_count, version;
6205  int64_t elst_entry_size;
6206 
6207  if (c->fc->nb_streams < 1 || c->ignore_editlist)
6208  return 0;
6209  sc = c->fc->streams[c->fc->nb_streams-1]->priv_data;
6210 
6211  version = avio_r8(pb); /* version */
6212  avio_rb24(pb); /* flags */
6213  edit_count = avio_rb32(pb); /* entries */
6214  atom.size -= 8;
6215 
6216  elst_entry_size = version == 1 ? 20 : 12;
6217  if (atom.size != edit_count * elst_entry_size) {
6218  if (c->fc->strict_std_compliance >= FF_COMPLIANCE_STRICT) {
6219  av_log(c->fc, AV_LOG_ERROR, "Invalid edit list entry_count: %d for elst atom of size: %"PRId64" bytes.\n",
6220  edit_count, atom.size + 8);
6221  return AVERROR_INVALIDDATA;
6222  } else {
6223  edit_count = atom.size / elst_entry_size;
6224  if (edit_count * elst_entry_size != atom.size) {
6225  av_log(c->fc, AV_LOG_WARNING, "ELST atom of %"PRId64" bytes, bigger than %d entries.\n", atom.size, edit_count);
6226  }
6227  }
6228  }
6229 
6230  if (!edit_count)
6231  return 0;
6232  if (sc->elst_data)
6233  av_log(c->fc, AV_LOG_WARNING, "Duplicated ELST atom\n");
6234  av_free(sc->elst_data);
6235  sc->elst_count = 0;
6236  sc->elst_data = av_malloc_array(edit_count, sizeof(*sc->elst_data));
6237  if (!sc->elst_data)
6238  return AVERROR(ENOMEM);
6239 
6240  av_log(c->fc, AV_LOG_TRACE, "track[%u].edit_count = %i\n", c->fc->nb_streams - 1, edit_count);
6241  for (i = 0; i < edit_count && atom.size > 0 && !pb->eof_reached; i++) {
6242  MOVElst *e = &sc->elst_data[i];
6243 
6244  if (version == 1) {
6245  e->duration = avio_rb64(pb);
6246  e->time = avio_rb64(pb);
6247  atom.size -= 16;
6248  } else {
6249  e->duration = avio_rb32(pb); /* segment duration */
6250  e->time = (int32_t)avio_rb32(pb); /* media time */
6251  atom.size -= 8;
6252  }
6253  e->rate = avio_rb32(pb) / 65536.0;
6254  atom.size -= 4;
6255  av_log(c->fc, AV_LOG_TRACE, "duration=%"PRId64" time=%"PRId64" rate=%f\n",
6256  e->duration, e->time, e->rate);
6257 
6258  if (e->time < 0 && e->time != -1 &&
6259  c->fc->strict_std_compliance >= FF_COMPLIANCE_STRICT) {
6260  av_log(c->fc, AV_LOG_ERROR, "Track %d, edit %d: Invalid edit list media time=%"PRId64"\n",
6261  c->fc->nb_streams-1, i, e->time);
6262  return AVERROR_INVALIDDATA;
6263  }
6264  }
6265  sc->elst_count = i;
6266 
6267  return 0;
6268 }
6269 
6271 {
6272  MOVStreamContext *sc;
6273 
6274  if (c->fc->nb_streams < 1)
6275  return AVERROR_INVALIDDATA;
6276  sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
6277  sc->timecode_track = avio_rb32(pb);
6278  return 0;
6279 }
6280 
6282 {
6283  AVStream *st;
6284  int version, color_range, color_primaries, color_trc, color_space;
6285 
6286  if (c->fc->nb_streams < 1)
6287  return 0;
6288  st = c->fc->streams[c->fc->nb_streams - 1];
6289 
6290  if (atom.size < 5) {
6291  av_log(c->fc, AV_LOG_ERROR, "Empty VP Codec Configuration box\n");
6292  return AVERROR_INVALIDDATA;
6293  }
6294 
6295  version = avio_r8(pb);
6296  if (version != 1) {
6297  av_log(c->fc, AV_LOG_WARNING, "Unsupported VP Codec Configuration box version %d\n", version);
6298  return 0;
6299  }
6300  avio_skip(pb, 3); /* flags */
6301 
6302  avio_skip(pb, 2); /* profile + level */
6303  color_range = avio_r8(pb); /* bitDepth, chromaSubsampling, videoFullRangeFlag */
6304  color_primaries = avio_r8(pb);
6305  color_trc = avio_r8(pb);
6306  color_space = avio_r8(pb);
6307  if (avio_rb16(pb)) /* codecIntializationDataSize */
6308  return AVERROR_INVALIDDATA;
6309 
6312  if (!av_color_transfer_name(color_trc))
6313  color_trc = AVCOL_TRC_UNSPECIFIED;
6314  if (!av_color_space_name(color_space))
6315  color_space = AVCOL_SPC_UNSPECIFIED;
6316 
6319  st->codecpar->color_trc = color_trc;
6320  st->codecpar->color_space = color_space;
6321 
6322  return 0;
6323 }
6324 
6326 {
6327  MOVStreamContext *sc;
6328  int i, version;
6329 
6330  if (c->fc->nb_streams < 1)
6331  return AVERROR_INVALIDDATA;
6332 
6333  sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
6334 
6335  if (atom.size < 5) {
6336  av_log(c->fc, AV_LOG_ERROR, "Empty Mastering Display Metadata box\n");
6337  return AVERROR_INVALIDDATA;
6338  }
6339 
6340  version = avio_r8(pb);
6341  if (version) {
6342  av_log(c->fc, AV_LOG_WARNING, "Unsupported Mastering Display Metadata box version %d\n", version);
6343  return 0;
6344  }
6345  if (sc->mastering) {
6346  av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicate Mastering Display Metadata\n");
6347  return 0;
6348  }
6349 
6350  avio_skip(pb, 3); /* flags */
6351 
6353  if (!sc->mastering)
6354  return AVERROR(ENOMEM);
6355 
6356  for (i = 0; i < 3; i++) {
6357  sc->mastering->display_primaries[i][0] = av_make_q(avio_rb16(pb), 1 << 16);
6358  sc->mastering->display_primaries[i][1] = av_make_q(avio_rb16(pb), 1 << 16);
6359  }
6360  sc->mastering->white_point[0] = av_make_q(avio_rb16(pb), 1 << 16);
6361  sc->mastering->white_point[1] = av_make_q(avio_rb16(pb), 1 << 16);
6362 
6363  sc->mastering->max_luminance = av_make_q(avio_rb32(pb), 1 << 8);
6364  sc->mastering->min_luminance = av_make_q(avio_rb32(pb), 1 << 14);
6365 
6366  sc->mastering->has_primaries = 1;
6367  sc->mastering->has_luminance = 1;
6368 
6369  return 0;
6370 }
6371 
6373 {
6374  MOVStreamContext *sc;
6375  const int mapping[3] = {1, 2, 0};
6376  const int chroma_den = 50000;
6377  const int luma_den = 10000;
6378  int i;
6379 
6380  if (c->fc->nb_streams < 1)
6381  return AVERROR_INVALIDDATA;
6382 
6383  sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
6384 
6385  if (atom.size < 24) {
6386  av_log(c->fc, AV_LOG_ERROR, "Invalid Mastering Display Color Volume box\n");
6387  return AVERROR_INVALIDDATA;
6388  }
6389 
6390  if (sc->mastering) {
6391  av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicate Mastering Display Color Volume\n");
6392  return 0;
6393  }
6394 
6396  if (!sc->mastering)
6397  return AVERROR(ENOMEM);
6398 
6399  for (i = 0; i < 3; i++) {
6400  const int j = mapping[i];
6401  sc->mastering->display_primaries[j][0] = av_make_q(avio_rb16(pb), chroma_den);
6402  sc->mastering->display_primaries[j][1] = av_make_q(avio_rb16(pb), chroma_den);
6403  }
6404  sc->mastering->white_point[0] = av_make_q(avio_rb16(pb), chroma_den);
6405  sc->mastering->white_point[1] = av_make_q(avio_rb16(pb), chroma_den);
6406 
6407  sc->mastering->max_luminance = av_make_q(avio_rb32(pb), luma_den);
6408  sc->mastering->min_luminance = av_make_q(avio_rb32(pb), luma_den);
6409 
6410  sc->mastering->has_luminance = 1;
6411  sc->mastering->has_primaries = 1;
6412 
6413  return 0;
6414 }
6415 
6417 {
6418  MOVStreamContext *sc;
6419  int version;
6420 
6421  if (c->fc->nb_streams < 1)
6422  return AVERROR_INVALIDDATA;
6423 
6424  sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
6425 
6426  if (atom.size < 5) {
6427  av_log(c->fc, AV_LOG_ERROR, "Empty Content Light Level box\n");
6428  return AVERROR_INVALIDDATA;
6429  }
6430 
6431  version = avio_r8(pb);
6432  if (version) {
6433  av_log(c->fc, AV_LOG_WARNING, "Unsupported Content Light Level box version %d\n", version);
6434  return 0;
6435  }
6436  avio_skip(pb, 3); /* flags */
6437 
6438  if (sc->coll){
6439  av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicate COLL\n");
6440  return 0;
6441  }
6442 
6444  if (!sc->coll)
6445  return AVERROR(ENOMEM);
6446 
6447  sc->coll->MaxCLL = avio_rb16(pb);
6448  sc->coll->MaxFALL = avio_rb16(pb);
6449 
6450  return 0;
6451 }
6452 
6454 {
6455  MOVStreamContext *sc;
6456 
6457  if (c->fc->nb_streams < 1)
6458  return AVERROR_INVALIDDATA;
6459 
6460  sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
6461 
6462  if (atom.size < 4) {
6463  av_log(c->fc, AV_LOG_ERROR, "Empty Content Light Level Info box\n");
6464  return AVERROR_INVALIDDATA;
6465  }
6466 
6467  if (sc->coll){
6468  av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicate CLLI/COLL\n");
6469  return 0;
6470  }
6471 
6473  if (!sc->coll)
6474  return AVERROR(ENOMEM);
6475 
6476  sc->coll->MaxCLL = avio_rb16(pb);
6477  sc->coll->MaxFALL = avio_rb16(pb);
6478 
6479  return 0;
6480 }
6481 
6483 {
6484  MOVStreamContext *sc;
6485  const int illuminance_den = 10000;
6486  const int ambient_den = 50000;
6487  if (c->fc->nb_streams < 1)
6488  return AVERROR_INVALIDDATA;
6489  sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
6490  if (atom.size < 6) {
6491  av_log(c->fc, AV_LOG_ERROR, "Empty Ambient Viewing Environment Info box\n");
6492  return AVERROR_INVALIDDATA;
6493  }
6494  if (sc->ambient){
6495  av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicate AMVE\n");
6496  return 0;
6497  }
6499  if (!sc->ambient)
6500  return AVERROR(ENOMEM);
6501  sc->ambient->ambient_illuminance = av_make_q(avio_rb32(pb), illuminance_den);
6502  sc->ambient->ambient_light_x = av_make_q(avio_rb16(pb), ambient_den);
6503  sc->ambient->ambient_light_y = av_make_q(avio_rb16(pb), ambient_den);
6504  return 0;
6505 }
6506 
6508 {
6509  AVStream *st;
6510  MOVStreamContext *sc;
6511  enum AVStereo3DType type;
6512  int mode;
6513 
6514  if (c->fc->nb_streams < 1)
6515  return 0;
6516 
6517  st = c->fc->streams[c->fc->nb_streams - 1];
6518  sc = st->priv_data;
6519 
6520  if (atom.size < 5) {
6521  av_log(c->fc, AV_LOG_ERROR, "Empty stereoscopic video box\n");
6522  return AVERROR_INVALIDDATA;
6523  }
6524 
6525  if (sc->stereo3d)
6526  return AVERROR_INVALIDDATA;
6527 
6528  avio_skip(pb, 4); /* version + flags */
6529 
6530  mode = avio_r8(pb);
6531  switch (mode) {
6532  case 0:
6533  type = AV_STEREO3D_2D;
6534  break;
6535  case 1:
6537  break;
6538  case 2:
6540  break;
6541  default:
6542  av_log(c->fc, AV_LOG_WARNING, "Unknown st3d mode value %d\n", mode);
6543  return 0;
6544  }
6545 
6547  if (!sc->stereo3d)
6548  return AVERROR(ENOMEM);
6549 
6550  sc->stereo3d->type = type;
6551  return 0;
6552 }
6553 
6555 {
6556  AVStream *st;
6557  MOVStreamContext *sc;
6558  int size, version, layout;
6559  int32_t yaw, pitch, roll;
6560  uint32_t l = 0, t = 0, r = 0, b = 0;
6561  uint32_t tag, padding = 0;
6562  enum AVSphericalProjection projection;
6563 
6564  if (c->fc->nb_streams < 1)
6565  return 0;
6566 
6567  st = c->fc->streams[c->fc->nb_streams - 1];
6568  sc = st->priv_data;
6569 
6570  if (atom.size < 8) {
6571  av_log(c->fc, AV_LOG_ERROR, "Empty spherical video box\n");
6572  return AVERROR_INVALIDDATA;
6573  }
6574 
6575  size = avio_rb32(pb);
6576  if (size <= 12 || size > atom.size)
6577  return AVERROR_INVALIDDATA;
6578 
6579  tag = avio_rl32(pb);
6580  if (tag != MKTAG('s','v','h','d')) {
6581  av_log(c->fc, AV_LOG_ERROR, "Missing spherical video header\n");
6582  return 0;
6583  }
6584  version = avio_r8(pb);
6585  if (version != 0) {
6586  av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
6587  version);
6588  return 0;
6589  }
6590  avio_skip(pb, 3); /* flags */
6591  avio_skip(pb, size - 12); /* metadata_source */
6592 
6593  size = avio_rb32(pb);
6594  if (size > atom.size)
6595  return AVERROR_INVALIDDATA;
6596 
6597  tag = avio_rl32(pb);
6598  if (tag != MKTAG('p','r','o','j')) {
6599  av_log(c->fc, AV_LOG_ERROR, "Missing projection box\n");
6600  return 0;
6601  }
6602 
6603  size = avio_rb32(pb);
6604  if (size > atom.size)
6605  return AVERROR_INVALIDDATA;
6606 
6607  tag = avio_rl32(pb);
6608  if (tag != MKTAG('p','r','h','d')) {
6609  av_log(c->fc, AV_LOG_ERROR, "Missing projection header box\n");
6610  return 0;
6611  }
6612  version = avio_r8(pb);
6613  if (version != 0) {
6614  av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
6615  version);
6616  return 0;
6617  }
6618  avio_skip(pb, 3); /* flags */
6619 
6620  /* 16.16 fixed point */
6621  yaw = avio_rb32(pb);
6622  pitch = avio_rb32(pb);
6623  roll = avio_rb32(pb);
6624 
6625  size = avio_rb32(pb);
6626  if (size > atom.size)
6627  return AVERROR_INVALIDDATA;
6628 
6629  tag = avio_rl32(pb);
6630  version = avio_r8(pb);
6631  if (version != 0) {
6632  av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
6633  version);
6634  return 0;
6635  }
6636  avio_skip(pb, 3); /* flags */
6637  switch (tag) {
6638  case MKTAG('c','b','m','p'):
6639  layout = avio_rb32(pb);
6640  if (layout) {
6641  av_log(c->fc, AV_LOG_WARNING,
6642  "Unsupported cubemap layout %d\n", layout);
6643  return 0;
6644  }
6645  projection = AV_SPHERICAL_CUBEMAP;
6646  padding = avio_rb32(pb);
6647  break;
6648  case MKTAG('e','q','u','i'):
6649  t = avio_rb32(pb);
6650  b = avio_rb32(pb);
6651  l = avio_rb32(pb);
6652  r = avio_rb32(pb);
6653 
6654  if (b >= UINT_MAX - t || r >= UINT_MAX - l) {
6655  av_log(c->fc, AV_LOG_ERROR,
6656  "Invalid bounding rectangle coordinates "
6657  "%"PRIu32",%"PRIu32",%"PRIu32",%"PRIu32"\n", l, t, r, b);
6658  return AVERROR_INVALIDDATA;
6659  }
6660 
6661  if (l || t || r || b)
6662  projection = AV_SPHERICAL_EQUIRECTANGULAR_TILE;
6663  else
6664  projection = AV_SPHERICAL_EQUIRECTANGULAR;
6665  break;
6666  default:
6667  av_log(c->fc, AV_LOG_ERROR, "Unknown projection type: %s\n", av_fourcc2str(tag));
6668  return 0;
6669  }
6670 
6672  if (!sc->spherical)
6673  return AVERROR(ENOMEM);
6674 
6675  sc->spherical->projection = projection;
6676 
6677  sc->spherical->yaw = yaw;
6678  sc->spherical->pitch = pitch;
6679  sc->spherical->roll = roll;
6680 
6681  sc->spherical->padding = padding;
6682 
6683  sc->spherical->bound_left = l;
6684  sc->spherical->bound_top = t;
6685  sc->spherical->bound_right = r;
6686  sc->spherical->bound_bottom = b;
6687 
6688  return 0;
6689 }
6690 
6692 {
6693  AVStream *st;
6694  MOVStreamContext *sc;
6695  int size;
6696  uint32_t tag;
6697  enum AVSphericalProjection projection;
6698 
6699  if (c->fc->nb_streams < 1)
6700  return 0;
6701 
6702  st = c->fc->streams[c->fc->nb_streams - 1];
6703  sc = st->priv_data;
6704 
6705  if (atom.size != 16) {
6706  av_log(c->fc, AV_LOG_ERROR, "Invalid size for proj box: %"PRIu64"\n", atom.size);
6707  return AVERROR_INVALIDDATA;
6708  }
6709 
6710  size = avio_rb32(pb);
6711  if (size != 16) {
6712  av_log(c->fc, AV_LOG_ERROR, "Invalid size for prji box: %d\n", size);
6713  return AVERROR_INVALIDDATA;
6714  }
6715 
6716  tag = avio_rl32(pb);
6717  if (tag != MKTAG('p','r','j','i')) {
6718  av_log(c->fc, AV_LOG_ERROR, "Invalid child box of proj box: 0x%08X\n", tag);
6719  return AVERROR_INVALIDDATA;
6720  }
6721 
6722  avio_skip(pb, 1); // version
6723  avio_skip(pb, 3); // flags
6724 
6725  tag = avio_rl32(pb);
6726  switch (tag) {
6727  case MKTAG('r','e','c','t'):
6728  projection = AV_SPHERICAL_RECTILINEAR;
6729  break;
6730  case MKTAG('e','q','u','i'):
6731  projection = AV_SPHERICAL_EQUIRECTANGULAR;
6732  break;
6733  case MKTAG('h','e','q','u'):
6734  projection = AV_SPHERICAL_HALF_EQUIRECTANGULAR;
6735  break;
6736  case MKTAG('f','i','s','h'):
6737  projection = AV_SPHERICAL_FISHEYE;
6738  break;
6739  default:
6740  av_log(c->fc, AV_LOG_ERROR, "Invalid projection type in prji box: 0x%08X\n", tag);
6741  return AVERROR_INVALIDDATA;
6742  }
6743 
6745  if (!sc->spherical)
6746  return AVERROR(ENOMEM);
6747 
6748  sc->spherical->projection = projection;
6749 
6750  return 0;
6751 }
6752 
6754 {
6755  AVStream *st;
6756  MOVStreamContext *sc;
6757  int size, flags = 0;
6758  int64_t remaining;
6759  uint32_t tag, baseline = 0;
6762  enum AVStereo3DPrimaryEye primary_eye = AV_PRIMARY_EYE_NONE;
6763  AVRational horizontal_disparity_adjustment = { 0, 1 };
6764 
6765  if (c->fc->nb_streams < 1)
6766  return 0;
6767 
6768  st = c->fc->streams[c->fc->nb_streams - 1];
6769  sc = st->priv_data;
6770 
6771  remaining = atom.size;
6772  while (remaining > 0) {
6773  size = avio_rb32(pb);
6774  if (size < 8 || size > remaining ) {
6775  av_log(c->fc, AV_LOG_ERROR, "Invalid child size in eyes box\n");
6776  return AVERROR_INVALIDDATA;
6777  }
6778 
6779  tag = avio_rl32(pb);
6780  switch (tag) {
6781  case MKTAG('s','t','r','i'): {
6782  int has_right, has_left;
6783  uint8_t tmp;
6784  if (size != 13) {
6785  av_log(c->fc, AV_LOG_ERROR, "Invalid size of stri box: %d\n", size);
6786  return AVERROR_INVALIDDATA;
6787  }
6788  avio_skip(pb, 1); // version
6789  avio_skip(pb, 3); // flags
6790 
6791  tmp = avio_r8(pb);
6792 
6793  // eye_views_reversed
6794  if (tmp & 8) {
6796  }
6797  // has_additional_views
6798  if (tmp & 4) {
6799  // skip...
6800  }
6801 
6802  has_right = tmp & 2; // has_right_eye_view
6803  has_left = tmp & 1; // has_left_eye_view
6804 
6805  if (has_left && has_right)
6806  view = AV_STEREO3D_VIEW_PACKED;
6807  else if (has_left)
6808  view = AV_STEREO3D_VIEW_LEFT;
6809  else if (has_right)
6810  view = AV_STEREO3D_VIEW_RIGHT;
6811  if (has_left || has_right)
6813 
6814  break;
6815  }
6816  case MKTAG('h','e','r','o'): {
6817  int tmp;
6818  if (size != 13) {
6819  av_log(c->fc, AV_LOG_ERROR, "Invalid size of hero box: %d\n", size);
6820  return AVERROR_INVALIDDATA;
6821  }
6822  avio_skip(pb, 1); // version
6823  avio_skip(pb, 3); // flags
6824 
6825  tmp = avio_r8(pb);
6826  if (tmp == 0)
6827  primary_eye = AV_PRIMARY_EYE_NONE;
6828  else if (tmp == 1)
6829  primary_eye = AV_PRIMARY_EYE_LEFT;
6830  else if (tmp == 2)
6831  primary_eye = AV_PRIMARY_EYE_RIGHT;
6832  else
6833  av_log(c->fc, AV_LOG_WARNING, "Unknown hero eye type: %d\n", tmp);
6834 
6835  break;
6836  }
6837  case MKTAG('c','a','m','s'): {
6838  uint32_t subtag;
6839  int subsize;
6840  if (size != 24) {
6841  av_log(c->fc, AV_LOG_ERROR, "Invalid size of cams box: %d\n", size);
6842  return AVERROR_INVALIDDATA;
6843  }
6844 
6845  subsize = avio_rb32(pb);
6846  if (subsize != 16) {
6847  av_log(c->fc, AV_LOG_ERROR, "Invalid size of blin box: %d\n", size);
6848  return AVERROR_INVALIDDATA;
6849  }
6850 
6851  subtag = avio_rl32(pb);
6852  if (subtag != MKTAG('b','l','i','n')) {
6853  av_log(c->fc, AV_LOG_ERROR, "Expected blin box, got 0x%08X\n", subtag);
6854  return AVERROR_INVALIDDATA;
6855  }
6856 
6857  avio_skip(pb, 1); // version
6858  avio_skip(pb, 3); // flags
6859 
6860  baseline = avio_rb32(pb);
6861 
6862  break;
6863  }
6864  case MKTAG('c','m','f','y'): {
6865  uint32_t subtag;
6866  int subsize;
6867  int32_t adjustment;
6868  if (size != 24) {
6869  av_log(c->fc, AV_LOG_ERROR, "Invalid size of cmfy box: %d\n", size);
6870  return AVERROR_INVALIDDATA;
6871  }
6872 
6873  subsize = avio_rb32(pb);
6874  if (subsize != 16) {
6875  av_log(c->fc, AV_LOG_ERROR, "Invalid size of dadj box: %d\n", size);
6876  return AVERROR_INVALIDDATA;
6877  }
6878 
6879  subtag = avio_rl32(pb);
6880  if (subtag != MKTAG('d','a','d','j')) {
6881  av_log(c->fc, AV_LOG_ERROR, "Expected dadj box, got 0x%08X\n", subtag);
6882  return AVERROR_INVALIDDATA;
6883  }
6884 
6885  avio_skip(pb, 1); // version
6886  avio_skip(pb, 3); // flags
6887 
6888  adjustment = (int32_t) avio_rb32(pb);
6889 
6890  horizontal_disparity_adjustment.num = (int) adjustment;
6891  horizontal_disparity_adjustment.den = 10000;
6892 
6893  break;
6894  }
6895  default:
6896  av_log(c->fc, AV_LOG_WARNING, "Unknown tag in eyes: 0x%08X\n", tag);
6897  avio_skip(pb, size - 8);
6898  break;
6899  }
6900  remaining -= size;
6901  }
6902 
6903  if (remaining != 0) {
6904  av_log(c->fc, AV_LOG_ERROR, "Broken eyes box\n");
6905  return AVERROR_INVALIDDATA;
6906  }
6907 
6908  if (type == AV_STEREO3D_2D)
6909  return 0;
6910 
6911  if (!sc->stereo3d) {
6913  if (!sc->stereo3d)
6914  return AVERROR(ENOMEM);
6915  }
6916 
6917  sc->stereo3d->flags = flags;
6918  sc->stereo3d->type = type;
6919  sc->stereo3d->view = view;
6920  sc->stereo3d->primary_eye = primary_eye;
6921  sc->stereo3d->baseline = baseline;
6922  sc->stereo3d->horizontal_disparity_adjustment = horizontal_disparity_adjustment;
6923 
6924  return 0;
6925 }
6926 
6928 {
6929  int size;
6930  int64_t remaining;
6931  uint32_t tag;
6932 
6933  if (c->fc->nb_streams < 1)
6934  return 0;
6935 
6936  if (atom.size < 8) {
6937  av_log(c->fc, AV_LOG_ERROR, "Empty video extension usage box\n");
6938  return AVERROR_INVALIDDATA;
6939  }
6940 
6941  remaining = atom.size;
6942  while (remaining > 0) {
6943  size = avio_rb32(pb);
6944  if (size < 8 || size > remaining ) {
6945  av_log(c->fc, AV_LOG_ERROR, "Invalid child size in vexu box\n");
6946  return AVERROR_INVALIDDATA;
6947  }
6948 
6949  tag = avio_rl32(pb);
6950  switch (tag) {
6951  case MKTAG('p','r','o','j'): {
6952  MOVAtom proj = { tag, size - 8 };
6953  int ret = mov_read_vexu_proj(c, pb, proj);
6954  if (ret < 0)
6955  return ret;
6956  break;
6957  }
6958  case MKTAG('e','y','e','s'): {
6959  MOVAtom eyes = { tag, size - 8 };
6960  int ret = mov_read_eyes(c, pb, eyes);
6961  if (ret < 0)
6962  return ret;
6963  break;
6964  }
6965  default:
6966  av_log(c->fc, AV_LOG_WARNING, "Unknown tag in vexu: 0x%08X\n", tag);
6967  avio_skip(pb, size - 8);
6968  break;
6969  }
6970  remaining -= size;
6971  }
6972 
6973  if (remaining != 0) {
6974  av_log(c->fc, AV_LOG_ERROR, "Broken vexu box\n");
6975  return AVERROR_INVALIDDATA;
6976  }
6977 
6978  return 0;
6979 }
6980 
6982 {
6983  AVStream *st;
6984  MOVStreamContext *sc;
6985 
6986  if (c->fc->nb_streams < 1)
6987  return 0;
6988 
6989  st = c->fc->streams[c->fc->nb_streams - 1];
6990  sc = st->priv_data;
6991 
6992  if (atom.size != 4) {
6993  av_log(c->fc, AV_LOG_ERROR, "Invalid size of hfov box: %"PRIu64"\n", atom.size);
6994  return AVERROR_INVALIDDATA;
6995  }
6996 
6997 
6998  if (!sc->stereo3d) {
7000  if (!sc->stereo3d)
7001  return AVERROR(ENOMEM);
7002  }
7003 
7005  sc->stereo3d->horizontal_field_of_view.den = 1000; // thousands of a degree
7006 
7007  return 0;
7008 }
7009 
7011 {
7012  int ret = 0;
7013  uint8_t *buffer = av_malloc(len + 1);
7014  const char *val;
7015 
7016  if (!buffer)
7017  return AVERROR(ENOMEM);
7018  buffer[len] = '\0';
7019 
7020  ret = ffio_read_size(pb, buffer, len);
7021  if (ret < 0)
7022  goto out;
7023 
7024  /* Check for mandatory keys and values, try to support XML as best-effort */
7025  if (!sc->spherical &&
7026  av_stristr(buffer, "<GSpherical:StitchingSoftware>") &&
7027  (val = av_stristr(buffer, "<GSpherical:Spherical>")) &&
7028  av_stristr(val, "true") &&
7029  (val = av_stristr(buffer, "<GSpherical:Stitched>")) &&
7030  av_stristr(val, "true") &&
7031  (val = av_stristr(buffer, "<GSpherical:ProjectionType>")) &&
7032  av_stristr(val, "equirectangular")) {
7034  if (!sc->spherical)
7035  goto out;
7036 
7038 
7039  if (av_stristr(buffer, "<GSpherical:StereoMode>") && !sc->stereo3d) {
7040  enum AVStereo3DType mode;
7041 
7042  if (av_stristr(buffer, "left-right"))
7044  else if (av_stristr(buffer, "top-bottom"))
7046  else
7047  mode = AV_STEREO3D_2D;
7048 
7050  if (!sc->stereo3d)
7051  goto out;
7052 
7053  sc->stereo3d->type = mode;
7054  }
7055 
7056  /* orientation */
7057  val = av_stristr(buffer, "<GSpherical:InitialViewHeadingDegrees>");
7058  if (val)
7059  sc->spherical->yaw = strtol(val, NULL, 10) * (1 << 16);
7060  val = av_stristr(buffer, "<GSpherical:InitialViewPitchDegrees>");
7061  if (val)
7062  sc->spherical->pitch = strtol(val, NULL, 10) * (1 << 16);
7063  val = av_stristr(buffer, "<GSpherical:InitialViewRollDegrees>");
7064  if (val)
7065  sc->spherical->roll = strtol(val, NULL, 10) * (1 << 16);
7066  }
7067 
7068 out:
7069  av_free(buffer);
7070  return ret;
7071 }
7072 
7074 {
7075  AVStream *st;
7076  MOVStreamContext *sc;
7077  int64_t ret;
7078  AVUUID uuid;
7079  static const AVUUID uuid_isml_manifest = {
7080  0xa5, 0xd4, 0x0b, 0x30, 0xe8, 0x14, 0x11, 0xdd,
7081  0xba, 0x2f, 0x08, 0x00, 0x20, 0x0c, 0x9a, 0x66
7082  };
7083  static const AVUUID uuid_xmp = {
7084  0xbe, 0x7a, 0xcf, 0xcb, 0x97, 0xa9, 0x42, 0xe8,
7085  0x9c, 0x71, 0x99, 0x94, 0x91, 0xe3, 0xaf, 0xac
7086  };
7087  static const AVUUID uuid_spherical = {
7088  0xff, 0xcc, 0x82, 0x63, 0xf8, 0x55, 0x4a, 0x93,
7089  0x88, 0x14, 0x58, 0x7a, 0x02, 0x52, 0x1f, 0xdd,
7090  };
7091 
7092  if (atom.size < AV_UUID_LEN || atom.size >= FFMIN(INT_MAX, SIZE_MAX))
7093  return AVERROR_INVALIDDATA;
7094 
7095  if (c->fc->nb_streams < 1)
7096  return 0;
7097  st = c->fc->streams[c->fc->nb_streams - 1];
7098  sc = st->priv_data;
7099 
7100  ret = ffio_read_size(pb, uuid, AV_UUID_LEN);
7101  if (ret < 0)
7102  return ret;
7103  if (av_uuid_equal(uuid, uuid_isml_manifest)) {
7104  uint8_t *buffer, *ptr;
7105  char *endptr;
7106  size_t len = atom.size - AV_UUID_LEN;
7107 
7108  if (len < 4) {
7109  return AVERROR_INVALIDDATA;
7110  }
7111  ret = avio_skip(pb, 4); // zeroes
7112  len -= 4;
7113 
7114  buffer = av_mallocz(len + 1);
7115  if (!buffer) {
7116  return AVERROR(ENOMEM);
7117  }
7118  ret = ffio_read_size(pb, buffer, len);
7119  if (ret < 0) {
7120  av_free(buffer);
7121  return ret;
7122  }
7123 
7124  ptr = buffer;
7125  while ((ptr = av_stristr(ptr, "systemBitrate=\""))) {
7126  ptr += sizeof("systemBitrate=\"") - 1;
7127  c->bitrates_count++;
7128  c->bitrates = av_realloc_f(c->bitrates, c->bitrates_count, sizeof(*c->bitrates));
7129  if (!c->bitrates) {
7130  c->bitrates_count = 0;
7131  av_free(buffer);
7132  return AVERROR(ENOMEM);
7133  }
7134  errno = 0;
7135  ret = strtol(ptr, &endptr, 10);
7136  if (ret < 0 || errno || *endptr != '"') {
7137  c->bitrates[c->bitrates_count - 1] = 0;
7138  } else {
7139  c->bitrates[c->bitrates_count - 1] = ret;
7140  }
7141  }
7142 
7143  av_free(buffer);
7144  } else if (av_uuid_equal(uuid, uuid_xmp)) {
7145  uint8_t *buffer;
7146  size_t len = atom.size - AV_UUID_LEN;
7147  if (c->export_xmp) {
7148  buffer = av_mallocz(len + 1);
7149  if (!buffer) {
7150  return AVERROR(ENOMEM);
7151  }
7152  ret = ffio_read_size(pb, buffer, len);
7153  if (ret < 0) {
7154  av_free(buffer);
7155  return ret;
7156  }
7157  buffer[len] = '\0';
7158  av_dict_set(&c->fc->metadata, "xmp",
7160  } else {
7161  // skip all uuid atom, which makes it fast for long uuid-xmp file
7162  ret = avio_skip(pb, len);
7163  if (ret < 0)
7164  return ret;
7165  }
7166  } else if (av_uuid_equal(uuid, uuid_spherical)) {
7167  size_t len = atom.size - AV_UUID_LEN;
7168  ret = mov_parse_uuid_spherical(sc, pb, len);
7169  if (ret < 0)
7170  return ret;
7171  if (!sc->spherical)
7172  av_log(c->fc, AV_LOG_WARNING, "Invalid spherical metadata found\n");
7173  }
7174 
7175  return 0;
7176 }
7177 
7179 {
7180  int ret;
7181  uint8_t content[16];
7182 
7183  if (atom.size < 8)
7184  return 0;
7185 
7186  ret = ffio_read_size(pb, content, FFMIN(sizeof(content), atom.size));
7187  if (ret < 0)
7188  return ret;
7189 
7190  if ( !c->found_moov
7191  && !c->found_mdat
7192  && !memcmp(content, "Anevia\x1A\x1A", 8)
7193  && c->use_mfra_for == FF_MOV_FLAG_MFRA_AUTO) {
7194  c->use_mfra_for = FF_MOV_FLAG_MFRA_PTS;
7195  }
7196 
7197  return 0;
7198 }
7199 
7201 {
7202  uint32_t format = avio_rl32(pb);
7203  MOVStreamContext *sc;
7204  enum AVCodecID id;
7205  AVStream *st;
7206 
7207  if (c->fc->nb_streams < 1)
7208  return 0;
7209  st = c->fc->streams[c->fc->nb_streams - 1];
7210  sc = st->priv_data;
7211 
7212  switch (sc->format)
7213  {
7214  case MKTAG('e','n','c','v'): // encrypted video
7215  case MKTAG('e','n','c','a'): // encrypted audio
7216  id = mov_codec_id(st, format);
7217  if (st->codecpar->codec_id != AV_CODEC_ID_NONE &&
7218  st->codecpar->codec_id != id) {
7219  av_log(c->fc, AV_LOG_WARNING,
7220  "ignoring 'frma' atom of '%.4s', stream has codec id %d\n",
7221  (char*)&format, st->codecpar->codec_id);
7222  break;
7223  }
7224 
7225  st->codecpar->codec_id = id;
7226  sc->format = format;
7227  break;
7228 
7229  default:
7230  if (format != sc->format) {
7231  av_log(c->fc, AV_LOG_WARNING,
7232  "ignoring 'frma' atom of '%.4s', stream format is '%.4s'\n",
7233  (char*)&format, (char*)&sc->format);
7234  }
7235  break;
7236  }
7237 
7238  return 0;
7239 }
7240 
7241 /**
7242  * Gets the current encryption info and associated current stream context. If
7243  * we are parsing a track fragment, this will return the specific encryption
7244  * info for this fragment; otherwise this will return the global encryption
7245  * info for the current stream.
7246  */
7248 {
7249  MOVFragmentStreamInfo *frag_stream_info;
7250  AVStream *st;
7251  int i;
7252 
7253  frag_stream_info = get_current_frag_stream_info(&c->frag_index);
7254  if (frag_stream_info) {
7255  for (i = 0; i < c->fc->nb_streams; i++) {
7256  *sc = c->fc->streams[i]->priv_data;
7257  if ((*sc)->id == frag_stream_info->id) {
7258  st = c->fc->streams[i];
7259  break;
7260  }
7261  }
7262  if (i == c->fc->nb_streams)
7263  return 0;
7264  *sc = st->priv_data;
7265 
7266  if (!frag_stream_info->encryption_index) {
7267  // If this stream isn't encrypted, don't create the index.
7268  if (!(*sc)->cenc.default_encrypted_sample)
7269  return 0;
7270  frag_stream_info->encryption_index = av_mallocz(sizeof(*frag_stream_info->encryption_index));
7271  if (!frag_stream_info->encryption_index)
7272  return AVERROR(ENOMEM);
7273  }
7274  *encryption_index = frag_stream_info->encryption_index;
7275  return 1;
7276  } else {
7277  // No current track fragment, using stream level encryption info.
7278 
7279  if (c->fc->nb_streams < 1)
7280  return 0;
7281  st = c->fc->streams[c->fc->nb_streams - 1];
7282  *sc = st->priv_data;
7283 
7284  if (!(*sc)->cenc.encryption_index) {
7285  // If this stream isn't encrypted, don't create the index.
7286  if (!(*sc)->cenc.default_encrypted_sample)
7287  return 0;
7288  (*sc)->cenc.encryption_index = av_mallocz(sizeof(*frag_stream_info->encryption_index));
7289  if (!(*sc)->cenc.encryption_index)
7290  return AVERROR(ENOMEM);
7291  }
7292 
7293  *encryption_index = (*sc)->cenc.encryption_index;
7294  return 1;
7295  }
7296 }
7297 
7299 {
7300  int i, ret;
7301  unsigned int subsample_count;
7302  AVSubsampleEncryptionInfo *subsamples;
7303 
7304  if (!sc->cenc.default_encrypted_sample) {
7305  av_log(c->fc, AV_LOG_ERROR, "Missing schm or tenc\n");
7306  return AVERROR_INVALIDDATA;
7307  }
7308 
7309  if (sc->cenc.per_sample_iv_size || use_subsamples) {
7311  if (!*sample)
7312  return AVERROR(ENOMEM);
7313  } else
7314  *sample = NULL;
7315 
7316  if (sc->cenc.per_sample_iv_size != 0) {
7317  if ((ret = ffio_read_size(pb, (*sample)->iv, sc->cenc.per_sample_iv_size)) < 0) {
7318  av_log(c->fc, AV_LOG_ERROR, "failed to read the initialization vector\n");
7320  *sample = NULL;
7321  return ret;
7322  }
7323  }
7324 
7325  if (use_subsamples) {
7326  subsample_count = avio_rb16(pb);
7327  av_free((*sample)->subsamples);
7328  (*sample)->subsamples = av_calloc(subsample_count, sizeof(*subsamples));
7329  if (!(*sample)->subsamples) {
7331  *sample = NULL;
7332  return AVERROR(ENOMEM);
7333  }
7334 
7335  for (i = 0; i < subsample_count && !pb->eof_reached; i++) {
7336  (*sample)->subsamples[i].bytes_of_clear_data = avio_rb16(pb);
7337  (*sample)->subsamples[i].bytes_of_protected_data = avio_rb32(pb);
7338  }
7339 
7340  if (pb->eof_reached) {
7341  av_log(c->fc, AV_LOG_ERROR, "hit EOF while reading sub-sample encryption info\n");
7343  *sample = NULL;
7344  return AVERROR_INVALIDDATA;
7345  }
7346  (*sample)->subsample_count = subsample_count;
7347  }
7348 
7349  return 0;
7350 }
7351 
7353 {
7354  AVEncryptionInfo **encrypted_samples;
7355  MOVEncryptionIndex *encryption_index;
7356  MOVStreamContext *sc;
7357  int use_subsamples, ret;
7358  unsigned int sample_count, i, alloc_size = 0;
7359 
7360  ret = get_current_encryption_info(c, &encryption_index, &sc);
7361  if (ret != 1)
7362  return ret;
7363 
7364  if (encryption_index->nb_encrypted_samples) {
7365  // This can happen if we have both saio/saiz and senc atoms.
7366  av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in senc\n");
7367  return 0;
7368  }
7369 
7370  avio_r8(pb); /* version */
7371  use_subsamples = avio_rb24(pb) & 0x02; /* flags */
7372 
7373  sample_count = avio_rb32(pb);
7374  if (sample_count >= INT_MAX / sizeof(*encrypted_samples))
7375  return AVERROR(ENOMEM);
7376 
7377  for (i = 0; i < sample_count; i++) {
7378  unsigned int min_samples = FFMIN(FFMAX(i + 1, 1024 * 1024), sample_count);
7379  encrypted_samples = av_fast_realloc(encryption_index->encrypted_samples, &alloc_size,
7380  min_samples * sizeof(*encrypted_samples));
7381  if (encrypted_samples) {
7382  encryption_index->encrypted_samples = encrypted_samples;
7383 
7385  c, pb, sc, &encryption_index->encrypted_samples[i], use_subsamples);
7386  } else {
7387  ret = AVERROR(ENOMEM);
7388  }
7389  if (pb->eof_reached) {
7390  av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading senc\n");
7391  if (ret >= 0)
7392  av_encryption_info_free(encryption_index->encrypted_samples[i]);
7394  }
7395 
7396  if (ret < 0) {
7397  for (; i > 0; i--)
7398  av_encryption_info_free(encryption_index->encrypted_samples[i - 1]);
7399  av_freep(&encryption_index->encrypted_samples);
7400  return ret;
7401  }
7402  }
7403  encryption_index->nb_encrypted_samples = sample_count;
7404 
7405  return 0;
7406 }
7407 
7409 {
7410  AVEncryptionInfo **sample, **encrypted_samples;
7411  int64_t prev_pos;
7412  size_t sample_count, sample_info_size, i;
7413  int ret = 0;
7414  unsigned int alloc_size = 0;
7415 
7416  if (encryption_index->nb_encrypted_samples)
7417  return 0;
7418  sample_count = encryption_index->auxiliary_info_sample_count;
7419  if (encryption_index->auxiliary_offsets_count != 1) {
7420  av_log(c->fc, AV_LOG_ERROR, "Multiple auxiliary info chunks are not supported\n");
7421  return AVERROR_PATCHWELCOME;
7422  }
7423  if (sample_count >= INT_MAX / sizeof(*encrypted_samples))
7424  return AVERROR(ENOMEM);
7425 
7426  prev_pos = avio_tell(pb);
7427  if (!(pb->seekable & AVIO_SEEKABLE_NORMAL) ||
7428  avio_seek(pb, encryption_index->auxiliary_offsets[0], SEEK_SET) != encryption_index->auxiliary_offsets[0]) {
7429  av_log(c->fc, AV_LOG_INFO, "Failed to seek for auxiliary info, will only parse senc atoms for encryption info\n");
7430  goto finish;
7431  }
7432 
7433  for (i = 0; i < sample_count && !pb->eof_reached; i++) {
7434  unsigned int min_samples = FFMIN(FFMAX(i + 1, 1024 * 1024), sample_count);
7435  encrypted_samples = av_fast_realloc(encryption_index->encrypted_samples, &alloc_size,
7436  min_samples * sizeof(*encrypted_samples));
7437  if (!encrypted_samples) {
7438  ret = AVERROR(ENOMEM);
7439  goto finish;
7440  }
7441  encryption_index->encrypted_samples = encrypted_samples;
7442 
7443  sample = &encryption_index->encrypted_samples[i];
7444  sample_info_size = encryption_index->auxiliary_info_default_size
7445  ? encryption_index->auxiliary_info_default_size
7446  : encryption_index->auxiliary_info_sizes[i];
7447 
7448  ret = mov_read_sample_encryption_info(c, pb, sc, sample, sample_info_size > sc->cenc.per_sample_iv_size);
7449  if (ret < 0)
7450  goto finish;
7451  }
7452  if (pb->eof_reached) {
7453  av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading auxiliary info\n");
7455  } else {
7456  encryption_index->nb_encrypted_samples = sample_count;
7457  }
7458 
7459 finish:
7460  avio_seek(pb, prev_pos, SEEK_SET);
7461  if (ret < 0) {
7462  for (; i > 0; i--) {
7463  av_encryption_info_free(encryption_index->encrypted_samples[i - 1]);
7464  }
7465  av_freep(&encryption_index->encrypted_samples);
7466  }
7467  return ret;
7468 }
7469 
7471 {
7472  MOVEncryptionIndex *encryption_index;
7473  MOVStreamContext *sc;
7474  int ret;
7475  unsigned int sample_count, aux_info_type, aux_info_param;
7476 
7477  ret = get_current_encryption_info(c, &encryption_index, &sc);
7478  if (ret != 1)
7479  return ret;
7480 
7481  if (encryption_index->nb_encrypted_samples) {
7482  // This can happen if we have both saio/saiz and senc atoms.
7483  av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in saiz\n");
7484  return 0;
7485  }
7486 
7487  if (encryption_index->auxiliary_info_sample_count) {
7488  av_log(c->fc, AV_LOG_ERROR, "Duplicate saiz atom\n");
7489  return AVERROR_INVALIDDATA;
7490  }
7491 
7492  avio_r8(pb); /* version */
7493  if (avio_rb24(pb) & 0x01) { /* flags */
7494  aux_info_type = avio_rb32(pb);
7495  aux_info_param = avio_rb32(pb);
7496  if (sc->cenc.default_encrypted_sample) {
7497  if (aux_info_type != sc->cenc.default_encrypted_sample->scheme) {
7498  av_log(c->fc, AV_LOG_DEBUG, "Ignoring saiz box with non-zero aux_info_type\n");
7499  return 0;
7500  }
7501  if (aux_info_param != 0) {
7502  av_log(c->fc, AV_LOG_DEBUG, "Ignoring saiz box with non-zero aux_info_type_parameter\n");
7503  return 0;
7504  }
7505  } else {
7506  // Didn't see 'schm' or 'tenc', so this isn't encrypted.
7507  if ((aux_info_type == MKBETAG('c','e','n','c') ||
7508  aux_info_type == MKBETAG('c','e','n','s') ||
7509  aux_info_type == MKBETAG('c','b','c','1') ||
7510  aux_info_type == MKBETAG('c','b','c','s')) &&
7511  aux_info_param == 0) {
7512  av_log(c->fc, AV_LOG_ERROR, "Saw encrypted saiz without schm/tenc\n");
7513  return AVERROR_INVALIDDATA;
7514  } else {
7515  return 0;
7516  }
7517  }
7518  } else if (!sc->cenc.default_encrypted_sample) {
7519  // Didn't see 'schm' or 'tenc', so this isn't encrypted.
7520  return 0;
7521  }
7522 
7523  encryption_index->auxiliary_info_default_size = avio_r8(pb);
7524  sample_count = avio_rb32(pb);
7525 
7526  if (encryption_index->auxiliary_info_default_size == 0) {
7527  if (sample_count == 0)
7528  return AVERROR_INVALIDDATA;
7529 
7530  encryption_index->auxiliary_info_sizes = av_malloc(sample_count);
7531  if (!encryption_index->auxiliary_info_sizes)
7532  return AVERROR(ENOMEM);
7533 
7534  ret = avio_read(pb, encryption_index->auxiliary_info_sizes, sample_count);
7535  if (ret != sample_count) {
7536  av_freep(&encryption_index->auxiliary_info_sizes);
7537 
7538  if (ret >= 0)
7540  av_log(c->fc, AV_LOG_ERROR, "Failed to read the auxiliary info, %s\n",
7541  av_err2str(ret));
7542  return ret;
7543  }
7544  }
7545  encryption_index->auxiliary_info_sample_count = sample_count;
7546 
7547  if (encryption_index->auxiliary_offsets_count) {
7548  return mov_parse_auxiliary_info(c, sc, pb, encryption_index);
7549  }
7550 
7551  return 0;
7552 }
7553 
7555 {
7556  uint64_t *auxiliary_offsets;
7557  MOVEncryptionIndex *encryption_index;
7558  MOVStreamContext *sc;
7559  int i, ret;
7560  unsigned int version, entry_count, aux_info_type, aux_info_param;
7561  unsigned int alloc_size = 0;
7562 
7563  ret = get_current_encryption_info(c, &encryption_index, &sc);
7564  if (ret != 1)
7565  return ret;
7566 
7567  if (encryption_index->nb_encrypted_samples) {
7568  // This can happen if we have both saio/saiz and senc atoms.
7569  av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in saio\n");
7570  return 0;
7571  }
7572 
7573  if (encryption_index->auxiliary_offsets_count) {
7574  av_log(c->fc, AV_LOG_ERROR, "Duplicate saio atom\n");
7575  return AVERROR_INVALIDDATA;
7576  }
7577 
7578  version = avio_r8(pb); /* version */
7579  if (avio_rb24(pb) & 0x01) { /* flags */
7580  aux_info_type = avio_rb32(pb);
7581  aux_info_param = avio_rb32(pb);
7582  if (sc->cenc.default_encrypted_sample) {
7583  if (aux_info_type != sc->cenc.default_encrypted_sample->scheme) {
7584  av_log(c->fc, AV_LOG_DEBUG, "Ignoring saio box with non-zero aux_info_type\n");
7585  return 0;
7586  }
7587  if (aux_info_param != 0) {
7588  av_log(c->fc, AV_LOG_DEBUG, "Ignoring saio box with non-zero aux_info_type_parameter\n");
7589  return 0;
7590  }
7591  } else {
7592  // Didn't see 'schm' or 'tenc', so this isn't encrypted.
7593  if ((aux_info_type == MKBETAG('c','e','n','c') ||
7594  aux_info_type == MKBETAG('c','e','n','s') ||
7595  aux_info_type == MKBETAG('c','b','c','1') ||
7596  aux_info_type == MKBETAG('c','b','c','s')) &&
7597  aux_info_param == 0) {
7598  av_log(c->fc, AV_LOG_ERROR, "Saw encrypted saio without schm/tenc\n");
7599  return AVERROR_INVALIDDATA;
7600  } else {
7601  return 0;
7602  }
7603  }
7604  } else if (!sc->cenc.default_encrypted_sample) {
7605  // Didn't see 'schm' or 'tenc', so this isn't encrypted.
7606  return 0;
7607  }
7608 
7609  entry_count = avio_rb32(pb);
7610  if (entry_count >= INT_MAX / sizeof(*auxiliary_offsets))
7611  return AVERROR(ENOMEM);
7612 
7613  for (i = 0; i < entry_count && !pb->eof_reached; i++) {
7614  unsigned int min_offsets = FFMIN(FFMAX(i + 1, 1024), entry_count);
7615  auxiliary_offsets = av_fast_realloc(
7616  encryption_index->auxiliary_offsets, &alloc_size,
7617  min_offsets * sizeof(*auxiliary_offsets));
7618  if (!auxiliary_offsets) {
7619  av_freep(&encryption_index->auxiliary_offsets);
7620  return AVERROR(ENOMEM);
7621  }
7622  encryption_index->auxiliary_offsets = auxiliary_offsets;
7623 
7624  if (version == 0) {
7625  encryption_index->auxiliary_offsets[i] = avio_rb32(pb);
7626  } else {
7627  encryption_index->auxiliary_offsets[i] = avio_rb64(pb);
7628  }
7629  if (c->frag_index.current >= 0) {
7630  encryption_index->auxiliary_offsets[i] += c->fragment.base_data_offset;
7631  }
7632  }
7633 
7634  if (pb->eof_reached) {
7635  av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading saio\n");
7636  av_freep(&encryption_index->auxiliary_offsets);
7637  return AVERROR_INVALIDDATA;
7638  }
7639 
7640  encryption_index->auxiliary_offsets_count = entry_count;
7641 
7642  if (encryption_index->auxiliary_info_sample_count) {
7643  return mov_parse_auxiliary_info(c, sc, pb, encryption_index);
7644  }
7645 
7646  return 0;
7647 }
7648 
7650 {
7651  AVEncryptionInitInfo *info, *old_init_info;
7652  uint8_t **key_ids;
7653  AVStream *st;
7654  const AVPacketSideData *old_side_data;
7655  uint8_t *side_data, *extra_data;
7656  size_t side_data_size;
7657  int ret = 0;
7658  unsigned int version, kid_count, extra_data_size, alloc_size = 0;
7659 
7660  if (c->fc->nb_streams < 1)
7661  return 0;
7662  st = c->fc->streams[c->fc->nb_streams-1];
7663 
7664  version = avio_r8(pb); /* version */
7665  avio_rb24(pb); /* flags */
7666 
7667  info = av_encryption_init_info_alloc(/* system_id_size */ 16, /* num_key_ids */ 0,
7668  /* key_id_size */ 16, /* data_size */ 0);
7669  if (!info)
7670  return AVERROR(ENOMEM);
7671 
7672  if ((ret = ffio_read_size(pb, info->system_id, 16)) < 0) {
7673  av_log(c->fc, AV_LOG_ERROR, "Failed to read the system id\n");
7674  goto finish;
7675  }
7676 
7677  if (version > 0) {
7678  kid_count = avio_rb32(pb);
7679  if (kid_count >= INT_MAX / sizeof(*key_ids)) {
7680  ret = AVERROR(ENOMEM);
7681  goto finish;
7682  }
7683 
7684  for (unsigned int i = 0; i < kid_count && !pb->eof_reached; i++) {
7685  unsigned int min_kid_count = FFMIN(FFMAX(i + 1, 1024), kid_count);
7686  key_ids = av_fast_realloc(info->key_ids, &alloc_size,
7687  min_kid_count * sizeof(*key_ids));
7688  if (!key_ids) {
7689  ret = AVERROR(ENOMEM);
7690  goto finish;
7691  }
7692  info->key_ids = key_ids;
7693 
7694  info->key_ids[i] = av_mallocz(16);
7695  if (!info->key_ids[i]) {
7696  ret = AVERROR(ENOMEM);
7697  goto finish;
7698  }
7699  info->num_key_ids = i + 1;
7700 
7701  if ((ret = ffio_read_size(pb, info->key_ids[i], 16)) < 0) {
7702  av_log(c->fc, AV_LOG_ERROR, "Failed to read the key id\n");
7703  goto finish;
7704  }
7705  }
7706 
7707  if (pb->eof_reached) {
7708  av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading pssh\n");
7710  goto finish;
7711  }
7712  }
7713 
7714  extra_data_size = avio_rb32(pb);
7715  extra_data = av_malloc(extra_data_size);
7716  if (!extra_data) {
7717  ret = AVERROR(ENOMEM);
7718  goto finish;
7719  }
7720  ret = avio_read(pb, extra_data, extra_data_size);
7721  if (ret != extra_data_size) {
7722  av_free(extra_data);
7723 
7724  if (ret >= 0)
7726  goto finish;
7727  }
7728 
7729  av_freep(&info->data); // malloc(0) may still allocate something.
7730  info->data = extra_data;
7731  info->data_size = extra_data_size;
7732 
7733  // If there is existing initialization data, append to the list.
7736  if (old_side_data) {
7737  old_init_info = av_encryption_init_info_get_side_data(old_side_data->data, old_side_data->size);
7738  if (old_init_info) {
7739  // Append to the end of the list.
7740  for (AVEncryptionInitInfo *cur = old_init_info;; cur = cur->next) {
7741  if (!cur->next) {
7742  cur->next = info;
7743  break;
7744  }
7745  }
7746  info = old_init_info;
7747  } else {
7748  // Assume existing side-data will be valid, so the only error we could get is OOM.
7749  ret = AVERROR(ENOMEM);
7750  goto finish;
7751  }
7752  }
7753 
7754  side_data = av_encryption_init_info_add_side_data(info, &side_data_size);
7755  if (!side_data) {
7756  ret = AVERROR(ENOMEM);
7757  goto finish;
7758  }
7762  side_data, side_data_size, 0))
7763  av_free(side_data);
7764 
7765 finish:
7767  return ret;
7768 }
7769 
7771 {
7772  AVStream *st;
7773  MOVStreamContext *sc;
7774 
7775  if (c->fc->nb_streams < 1)
7776  return 0;
7777  st = c->fc->streams[c->fc->nb_streams-1];
7778  sc = st->priv_data;
7779 
7780  if (sc->pseudo_stream_id != 0) {
7781  av_log(c->fc, AV_LOG_ERROR, "schm boxes are only supported in first sample descriptor\n");
7782  return AVERROR_PATCHWELCOME;
7783  }
7784 
7785  if (atom.size < 8)
7786  return AVERROR_INVALIDDATA;
7787 
7788  avio_rb32(pb); /* version and flags */
7789 
7790  if (!sc->cenc.default_encrypted_sample) {
7792  if (!sc->cenc.default_encrypted_sample) {
7793  return AVERROR(ENOMEM);
7794  }
7795  }
7796 
7798  return 0;
7799 }
7800 
7802 {
7803  AVStream *st;
7804  MOVStreamContext *sc;
7805  unsigned int version, pattern, is_protected, iv_size;
7806 
7807  if (c->fc->nb_streams < 1)
7808  return 0;
7809  st = c->fc->streams[c->fc->nb_streams-1];
7810  sc = st->priv_data;
7811 
7812  if (sc->pseudo_stream_id != 0) {
7813  av_log(c->fc, AV_LOG_ERROR, "tenc atom are only supported in first sample descriptor\n");
7814  return AVERROR_PATCHWELCOME;
7815  }
7816 
7817  if (!sc->cenc.default_encrypted_sample) {
7819  if (!sc->cenc.default_encrypted_sample) {
7820  return AVERROR(ENOMEM);
7821  }
7822  }
7823 
7824  if (atom.size < 20)
7825  return AVERROR_INVALIDDATA;
7826 
7827  version = avio_r8(pb); /* version */
7828  avio_rb24(pb); /* flags */
7829 
7830  avio_r8(pb); /* reserved */
7831  pattern = avio_r8(pb);
7832 
7833  if (version > 0) {
7834  sc->cenc.default_encrypted_sample->crypt_byte_block = pattern >> 4;
7835  sc->cenc.default_encrypted_sample->skip_byte_block = pattern & 0xf;
7836  }
7837 
7838  is_protected = avio_r8(pb);
7839  if (is_protected && !sc->cenc.encryption_index) {
7840  // The whole stream should be by-default encrypted.
7842  if (!sc->cenc.encryption_index)
7843  return AVERROR(ENOMEM);
7844  }
7845  sc->cenc.per_sample_iv_size = avio_r8(pb);
7846  if (sc->cenc.per_sample_iv_size != 0 && sc->cenc.per_sample_iv_size != 8 &&
7847  sc->cenc.per_sample_iv_size != 16) {
7848  av_log(c->fc, AV_LOG_ERROR, "invalid per-sample IV size value\n");
7849  return AVERROR_INVALIDDATA;
7850  }
7851  if (avio_read(pb, sc->cenc.default_encrypted_sample->key_id, 16) != 16) {
7852  av_log(c->fc, AV_LOG_ERROR, "failed to read the default key ID\n");
7853  return AVERROR_INVALIDDATA;
7854  }
7855 
7856  if (is_protected && !sc->cenc.per_sample_iv_size) {
7857  iv_size = avio_r8(pb);
7858  if (iv_size != 8 && iv_size != 16) {
7859  av_log(c->fc, AV_LOG_ERROR, "invalid default_constant_IV_size in tenc atom\n");
7860  return AVERROR_INVALIDDATA;
7861  }
7862 
7863  if (avio_read(pb, sc->cenc.default_encrypted_sample->iv, iv_size) != iv_size) {
7864  av_log(c->fc, AV_LOG_ERROR, "failed to read the default IV\n");
7865  return AVERROR_INVALIDDATA;
7866  }
7867  }
7868 
7869  return 0;
7870 }
7871 
7873 {
7874  AVStream *st;
7875  int last, type, size, ret;
7876  uint8_t buf[4];
7877 
7878  if (c->fc->nb_streams < 1)
7879  return 0;
7880  st = c->fc->streams[c->fc->nb_streams-1];
7881 
7882  if ((uint64_t)atom.size > (1<<30) || atom.size < 42)
7883  return AVERROR_INVALIDDATA;
7884 
7885  /* Check FlacSpecificBox version. */
7886  if (avio_r8(pb) != 0)
7887  return AVERROR_INVALIDDATA;
7888 
7889  avio_rb24(pb); /* Flags */
7890 
7891  if (avio_read(pb, buf, sizeof(buf)) != sizeof(buf)) {
7892  av_log(c->fc, AV_LOG_ERROR, "failed to read FLAC metadata block header\n");
7893  return pb->error < 0 ? pb->error : AVERROR_INVALIDDATA;
7894  }
7895  flac_parse_block_header(buf, &last, &type, &size);
7896 
7898  av_log(c->fc, AV_LOG_ERROR, "STREAMINFO must be first FLACMetadataBlock\n");
7899  return AVERROR_INVALIDDATA;
7900  }
7901 
7902  ret = ff_get_extradata(c->fc, st->codecpar, pb, size);
7903  if (ret < 0)
7904  return ret;
7905 
7906  if (!last)
7907  av_log(c->fc, AV_LOG_WARNING, "non-STREAMINFO FLACMetadataBlock(s) ignored\n");
7908 
7909  return 0;
7910 }
7911 
7913 {
7914  int i, ret;
7915  int bytes_of_protected_data;
7916 
7917  if (!sc->cenc.aes_ctr) {
7918  /* initialize the cipher */
7919  sc->cenc.aes_ctr = av_aes_ctr_alloc();
7920  if (!sc->cenc.aes_ctr) {
7921  return AVERROR(ENOMEM);
7922  }
7923 
7924  ret = av_aes_ctr_init(sc->cenc.aes_ctr, c->decryption_key);
7925  if (ret < 0) {
7926  return ret;
7927  }
7928  }
7929 
7931 
7932  if (!sample->subsample_count) {
7933  /* decrypt the whole packet */
7935  return 0;
7936  }
7937 
7938  for (i = 0; i < sample->subsample_count; i++) {
7939  if (sample->subsamples[i].bytes_of_clear_data + sample->subsamples[i].bytes_of_protected_data > size) {
7940  av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n");
7941  return AVERROR_INVALIDDATA;
7942  }
7943 
7944  /* skip the clear bytes */
7945  input += sample->subsamples[i].bytes_of_clear_data;
7946  size -= sample->subsamples[i].bytes_of_clear_data;
7947 
7948  /* decrypt the encrypted bytes */
7949 
7950  bytes_of_protected_data = sample->subsamples[i].bytes_of_protected_data;
7951  av_aes_ctr_crypt(sc->cenc.aes_ctr, input, input, bytes_of_protected_data);
7952 
7953  input += bytes_of_protected_data;
7954  size -= bytes_of_protected_data;
7955  }
7956 
7957  if (size > 0) {
7958  av_log(c->fc, AV_LOG_ERROR, "leftover packet bytes after subsample processing\n");
7959  return AVERROR_INVALIDDATA;
7960  }
7961 
7962  return 0;
7963 }
7964 
7966 {
7967  int i, ret;
7968  int num_of_encrypted_blocks;
7969  uint8_t iv[16];
7970 
7971  if (!sc->cenc.aes_ctx) {
7972  /* initialize the cipher */
7973  sc->cenc.aes_ctx = av_aes_alloc();
7974  if (!sc->cenc.aes_ctx) {
7975  return AVERROR(ENOMEM);
7976  }
7977 
7978  ret = av_aes_init(sc->cenc.aes_ctx, c->decryption_key, 16 * 8, 1);
7979  if (ret < 0) {
7980  return ret;
7981  }
7982  }
7983 
7984  memcpy(iv, sample->iv, 16);
7985 
7986  /* whole-block full sample encryption */
7987  if (!sample->subsample_count) {
7988  /* decrypt the whole packet */
7989  av_aes_crypt(sc->cenc.aes_ctx, input, input, size/16, iv, 1);
7990  return 0;
7991  }
7992 
7993  for (i = 0; i < sample->subsample_count; i++) {
7994  if (sample->subsamples[i].bytes_of_clear_data + sample->subsamples[i].bytes_of_protected_data > size) {
7995  av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n");
7996  return AVERROR_INVALIDDATA;
7997  }
7998 
7999  if (sample->subsamples[i].bytes_of_protected_data % 16) {
8000  av_log(c->fc, AV_LOG_ERROR, "subsample BytesOfProtectedData is not a multiple of 16\n");
8001  return AVERROR_INVALIDDATA;
8002  }
8003 
8004  /* skip the clear bytes */
8005  input += sample->subsamples[i].bytes_of_clear_data;
8006  size -= sample->subsamples[i].bytes_of_clear_data;
8007 
8008  /* decrypt the encrypted bytes */
8009  num_of_encrypted_blocks = sample->subsamples[i].bytes_of_protected_data/16;
8010  if (num_of_encrypted_blocks > 0) {
8011  av_aes_crypt(sc->cenc.aes_ctx, input, input, num_of_encrypted_blocks, iv, 1);
8012  }
8013  input += sample->subsamples[i].bytes_of_protected_data;
8014  size -= sample->subsamples[i].bytes_of_protected_data;
8015  }
8016 
8017  if (size > 0) {
8018  av_log(c->fc, AV_LOG_ERROR, "leftover packet bytes after subsample processing\n");
8019  return AVERROR_INVALIDDATA;
8020  }
8021 
8022  return 0;
8023 }
8024 
8026 {
8027  int i, ret, rem_bytes;
8028  uint8_t *data;
8029 
8030  if (!sc->cenc.aes_ctr) {
8031  /* initialize the cipher */
8032  sc->cenc.aes_ctr = av_aes_ctr_alloc();
8033  if (!sc->cenc.aes_ctr) {
8034  return AVERROR(ENOMEM);
8035  }
8036 
8037  ret = av_aes_ctr_init(sc->cenc.aes_ctr, c->decryption_key);
8038  if (ret < 0) {
8039  return ret;
8040  }
8041  }
8042 
8044 
8045  /* whole-block full sample encryption */
8046  if (!sample->subsample_count) {
8047  /* decrypt the whole packet */
8049  return 0;
8050  } else if (!sample->crypt_byte_block && !sample->skip_byte_block) {
8051  av_log(c->fc, AV_LOG_ERROR, "pattern encryption is not present in 'cens' scheme\n");
8052  return AVERROR_INVALIDDATA;
8053  }
8054 
8055  for (i = 0; i < sample->subsample_count; i++) {
8056  if (sample->subsamples[i].bytes_of_clear_data + sample->subsamples[i].bytes_of_protected_data > size) {
8057  av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n");
8058  return AVERROR_INVALIDDATA;
8059  }
8060 
8061  /* skip the clear bytes */
8062  input += sample->subsamples[i].bytes_of_clear_data;
8063  size -= sample->subsamples[i].bytes_of_clear_data;
8064 
8065  /* decrypt the encrypted bytes */
8066  data = input;
8067  rem_bytes = sample->subsamples[i].bytes_of_protected_data;
8068  while (rem_bytes > 0) {
8069  if (rem_bytes < 16*sample->crypt_byte_block) {
8070  break;
8071  }
8072  av_aes_ctr_crypt(sc->cenc.aes_ctr, data, data, 16*sample->crypt_byte_block);
8073  data += 16*sample->crypt_byte_block;
8074  rem_bytes -= 16*sample->crypt_byte_block;
8075  data += FFMIN(16*sample->skip_byte_block, rem_bytes);
8076  rem_bytes -= FFMIN(16*sample->skip_byte_block, rem_bytes);
8077  }
8078  input += sample->subsamples[i].bytes_of_protected_data;
8079  size -= sample->subsamples[i].bytes_of_protected_data;
8080  }
8081 
8082  if (size > 0) {
8083  av_log(c->fc, AV_LOG_ERROR, "leftover packet bytes after subsample processing\n");
8084  return AVERROR_INVALIDDATA;
8085  }
8086 
8087  return 0;
8088 }
8089 
8091 {
8092  int i, ret, rem_bytes;
8093  uint8_t iv[16];
8094  uint8_t *data;
8095 
8096  if (!sc->cenc.aes_ctx) {
8097  /* initialize the cipher */
8098  sc->cenc.aes_ctx = av_aes_alloc();
8099  if (!sc->cenc.aes_ctx) {
8100  return AVERROR(ENOMEM);
8101  }
8102 
8103  ret = av_aes_init(sc->cenc.aes_ctx, c->decryption_key, 16 * 8, 1);
8104  if (ret < 0) {
8105  return ret;
8106  }
8107  }
8108 
8109  /* whole-block full sample encryption */
8110  if (!sample->subsample_count) {
8111  /* decrypt the whole packet */
8112  memcpy(iv, sample->iv, 16);
8113  av_aes_crypt(sc->cenc.aes_ctx, input, input, size/16, iv, 1);
8114  return 0;
8115  } else if (!sample->crypt_byte_block && !sample->skip_byte_block) {
8116  av_log(c->fc, AV_LOG_ERROR, "pattern encryption is not present in 'cbcs' scheme\n");
8117  return AVERROR_INVALIDDATA;
8118  }
8119 
8120  for (i = 0; i < sample->subsample_count; i++) {
8121  if (sample->subsamples[i].bytes_of_clear_data + sample->subsamples[i].bytes_of_protected_data > size) {
8122  av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n");
8123  return AVERROR_INVALIDDATA;
8124  }
8125 
8126  /* skip the clear bytes */
8127  input += sample->subsamples[i].bytes_of_clear_data;
8128  size -= sample->subsamples[i].bytes_of_clear_data;
8129 
8130  /* decrypt the encrypted bytes */
8131  memcpy(iv, sample->iv, 16);
8132  data = input;
8133  rem_bytes = sample->subsamples[i].bytes_of_protected_data;
8134  while (rem_bytes > 0) {
8135  if (rem_bytes < 16*sample->crypt_byte_block) {
8136  break;
8137  }
8138  av_aes_crypt(sc->cenc.aes_ctx, data, data, sample->crypt_byte_block, iv, 1);
8139  data += 16*sample->crypt_byte_block;
8140  rem_bytes -= 16*sample->crypt_byte_block;
8141  data += FFMIN(16*sample->skip_byte_block, rem_bytes);
8142  rem_bytes -= FFMIN(16*sample->skip_byte_block, rem_bytes);
8143  }
8144  input += sample->subsamples[i].bytes_of_protected_data;
8145  size -= sample->subsamples[i].bytes_of_protected_data;
8146  }
8147 
8148  if (size > 0) {
8149  av_log(c->fc, AV_LOG_ERROR, "leftover packet bytes after subsample processing\n");
8150  return AVERROR_INVALIDDATA;
8151  }
8152 
8153  return 0;
8154 }
8155 
8157 {
8158  if (sample->scheme == MKBETAG('c','e','n','c') && !sample->crypt_byte_block && !sample->skip_byte_block) {
8159  return cenc_scheme_decrypt(c, sc, sample, input, size);
8160  } else if (sample->scheme == MKBETAG('c','b','c','1') && !sample->crypt_byte_block && !sample->skip_byte_block) {
8161  return cbc1_scheme_decrypt(c, sc, sample, input, size);
8162  } else if (sample->scheme == MKBETAG('c','e','n','s')) {
8163  return cens_scheme_decrypt(c, sc, sample, input, size);
8164  } else if (sample->scheme == MKBETAG('c','b','c','s')) {
8165  return cbcs_scheme_decrypt(c, sc, sample, input, size);
8166  } else {
8167  av_log(c->fc, AV_LOG_ERROR, "invalid encryption scheme\n");
8168  return AVERROR_INVALIDDATA;
8169  }
8170 }
8171 
8173 {
8174  int current = frag_index->current;
8175 
8176  if (!frag_index->nb_items)
8177  return NULL;
8178 
8179  // Check frag_index->current is the right one for pkt. It can out of sync.
8180  if (current >= 0 && current < frag_index->nb_items) {
8181  if (frag_index->item[current].moof_offset < pkt->pos &&
8182  (current + 1 == frag_index->nb_items ||
8183  frag_index->item[current + 1].moof_offset > pkt->pos))
8184  return get_frag_stream_info(frag_index, current, id);
8185  }
8186 
8187 
8188  for (int i = 0; i < frag_index->nb_items; i++) {
8189  if (frag_index->item[i].moof_offset > pkt->pos)
8190  break;
8191  current = i;
8192  }
8193  frag_index->current = current;
8194  return get_frag_stream_info(frag_index, current, id);
8195 }
8196 
8197 static int cenc_filter(MOVContext *mov, AVStream* st, MOVStreamContext *sc, AVPacket *pkt, int current_index)
8198 {
8199  MOVFragmentStreamInfo *frag_stream_info;
8200  MOVEncryptionIndex *encryption_index;
8201  AVEncryptionInfo *encrypted_sample;
8202  int encrypted_index, ret;
8203 
8204  frag_stream_info = get_frag_stream_info_from_pkt(&mov->frag_index, pkt, sc->id);
8205  encrypted_index = current_index;
8206  encryption_index = NULL;
8207  if (frag_stream_info) {
8208  // Note this only supports encryption info in the first sample descriptor.
8209  if (frag_stream_info->stsd_id == 1) {
8210  if (frag_stream_info->encryption_index) {
8211  encrypted_index = current_index - frag_stream_info->index_base;
8212  encryption_index = frag_stream_info->encryption_index;
8213  } else {
8214  encryption_index = sc->cenc.encryption_index;
8215  }
8216  }
8217  } else {
8218  encryption_index = sc->cenc.encryption_index;
8219  }
8220 
8221  if (encryption_index) {
8222  if (encryption_index->auxiliary_info_sample_count &&
8223  !encryption_index->nb_encrypted_samples) {
8224  av_log(mov->fc, AV_LOG_ERROR, "saiz atom found without saio\n");
8225  return AVERROR_INVALIDDATA;
8226  }
8227  if (encryption_index->auxiliary_offsets_count &&
8228  !encryption_index->nb_encrypted_samples) {
8229  av_log(mov->fc, AV_LOG_ERROR, "saio atom found without saiz\n");
8230  return AVERROR_INVALIDDATA;
8231  }
8232 
8233  encrypted_sample = NULL;
8234  if (!encryption_index->nb_encrypted_samples) {
8235  // Full-sample encryption with default settings.
8236  encrypted_sample = sc->cenc.default_encrypted_sample;
8237  } else if (encrypted_index >= 0 && encrypted_index < encryption_index->nb_encrypted_samples) {
8238  // Per-sample setting override.
8239  encrypted_sample = encryption_index->encrypted_samples[encrypted_index];
8240  if (!encrypted_sample) {
8241  encrypted_sample = sc->cenc.default_encrypted_sample;
8242  }
8243  }
8244 
8245  if (!encrypted_sample) {
8246  av_log(mov->fc, AV_LOG_ERROR, "Incorrect number of samples in encryption info\n");
8247  return AVERROR_INVALIDDATA;
8248  }
8249 
8250  if (mov->decryption_key) {
8251  return cenc_decrypt(mov, sc, encrypted_sample, pkt->data, pkt->size);
8252  } else {
8253  size_t size;
8254  uint8_t *side_data = av_encryption_info_add_side_data(encrypted_sample, &size);
8255  if (!side_data)
8256  return AVERROR(ENOMEM);
8258  if (ret < 0)
8259  av_free(side_data);
8260  return ret;
8261  }
8262  }
8263 
8264  return 0;
8265 }
8266 
8268 {
8269  const int OPUS_SEEK_PREROLL_MS = 80;
8270  int ret;
8271  AVStream *st;
8272  size_t size;
8273  uint16_t pre_skip;
8274 
8275  if (c->fc->nb_streams < 1)
8276  return 0;
8277  st = c->fc->streams[c->fc->nb_streams-1];
8278 
8279  if ((uint64_t)atom.size > (1<<30) || atom.size < 11)
8280  return AVERROR_INVALIDDATA;
8281 
8282  /* Check OpusSpecificBox version. */
8283  if (avio_r8(pb) != 0) {
8284  av_log(c->fc, AV_LOG_ERROR, "unsupported OpusSpecificBox version\n");
8285  return AVERROR_INVALIDDATA;
8286  }
8287 
8288  /* OpusSpecificBox size plus magic for Ogg OpusHead header. */
8289  size = atom.size + 8;
8290 
8291  if ((ret = ff_alloc_extradata(st->codecpar, size)) < 0)
8292  return ret;
8293 
8294  AV_WL32A(st->codecpar->extradata, MKTAG('O','p','u','s'));
8295  AV_WL32A(st->codecpar->extradata + 4, MKTAG('H','e','a','d'));
8296  AV_WB8(st->codecpar->extradata + 8, 1); /* OpusHead version */
8297  avio_read(pb, st->codecpar->extradata + 9, size - 9);
8298 
8299  /* OpusSpecificBox is stored in big-endian, but OpusHead is
8300  little-endian; aside from the preceeding magic and version they're
8301  otherwise currently identical. Data after output gain at offset 16
8302  doesn't need to be bytewapped. */
8303  pre_skip = AV_RB16A(st->codecpar->extradata + 10);
8304  AV_WL16A(st->codecpar->extradata + 10, pre_skip);
8305  AV_WL32A(st->codecpar->extradata + 12, AV_RB32A(st->codecpar->extradata + 12));
8306  AV_WL16A(st->codecpar->extradata + 16, AV_RB16A(st->codecpar->extradata + 16));
8307 
8308  st->codecpar->initial_padding = pre_skip;
8310  (AVRational){1, 1000},
8311  (AVRational){1, 48000});
8312 
8313  return 0;
8314 }
8315 
8317 {
8318  AVStream *st;
8319  unsigned format_info;
8320  int channel_assignment, channel_assignment1, channel_assignment2;
8321  int ratebits;
8322  uint64_t chmask;
8323 
8324  if (c->fc->nb_streams < 1)
8325  return 0;
8326  st = c->fc->streams[c->fc->nb_streams-1];
8327 
8328  if (atom.size < 10)
8329  return AVERROR_INVALIDDATA;
8330 
8331  format_info = avio_rb32(pb);
8332 
8333  ratebits = (format_info >> 28) & 0xF;
8334  channel_assignment1 = (format_info >> 15) & 0x1F;
8335  channel_assignment2 = format_info & 0x1FFF;
8336  if (channel_assignment2)
8337  channel_assignment = channel_assignment2;
8338  else
8339  channel_assignment = channel_assignment1;
8340 
8341  st->codecpar->frame_size = 40 << (ratebits & 0x7);
8342  st->codecpar->sample_rate = mlp_samplerate(ratebits);
8343 
8345  chmask = truehd_layout(channel_assignment);
8347 
8348  return 0;
8349 }
8350 
8352 {
8353  AVStream *st;
8354  uint8_t buf[ISOM_DVCC_DVVC_SIZE];
8355  int ret;
8356  int64_t read_size = atom.size;
8357 
8358  if (c->fc->nb_streams < 1)
8359  return 0;
8360  st = c->fc->streams[c->fc->nb_streams-1];
8361 
8362  // At most 24 bytes
8363  read_size = FFMIN(read_size, ISOM_DVCC_DVVC_SIZE);
8364 
8365  if ((ret = ffio_read_size(pb, buf, read_size)) < 0)
8366  return ret;
8367 
8368  return ff_isom_parse_dvcc_dvvc(c->fc, st, buf, read_size);
8369 }
8370 
8372 {
8373  AVStream *st;
8374  uint8_t *buf;
8375  int ret, old_size, num_arrays;
8376 
8377  if (c->fc->nb_streams < 1)
8378  return 0;
8379  st = c->fc->streams[c->fc->nb_streams-1];
8380 
8381  if (!st->codecpar->extradata_size)
8382  // TODO: handle lhvC when present before hvcC
8383  return 0;
8384 
8385  if (atom.size < 6 || st->codecpar->extradata_size < 23)
8386  return AVERROR_INVALIDDATA;
8387 
8389  if (!buf)
8390  return AVERROR(ENOMEM);
8391  memset(buf + atom.size, 0, AV_INPUT_BUFFER_PADDING_SIZE);
8392 
8393  ret = ffio_read_size(pb, buf, atom.size);
8394  if (ret < 0) {
8395  av_free(buf);
8396  av_log(c->fc, AV_LOG_WARNING, "lhvC atom truncated\n");
8397  return 0;
8398  }
8399 
8400  num_arrays = buf[5];
8401  old_size = st->codecpar->extradata_size;
8402  atom.size -= 8 /* account for mov_realloc_extradata offseting */
8403  + 6 /* lhvC bytes before the arrays*/;
8404 
8405  ret = mov_realloc_extradata(st->codecpar, atom);
8406  if (ret < 0) {
8407  av_free(buf);
8408  return ret;
8409  }
8410 
8411  st->codecpar->extradata[22] += num_arrays;
8412  memcpy(st->codecpar->extradata + old_size, buf + 6, atom.size + 8);
8413 
8415 
8416  av_free(buf);
8417  return 0;
8418 }
8419 
8421 {
8422  AVFormatContext *ctx = c->fc;
8423  AVStream *st = NULL;
8424  AVBPrint scheme_buf, value_buf;
8425  int64_t scheme_str_len = 0, value_str_len = 0;
8426  int version, flags, ret = AVERROR_BUG;
8427  int64_t size = atom.size;
8428 
8429  if (atom.size < 6)
8430  // 4 bytes for version + flags, 2x 1 byte for null
8431  return AVERROR_INVALIDDATA;
8432 
8433  if (c->fc->nb_streams < 1)
8434  return 0;
8435  st = c->fc->streams[c->fc->nb_streams-1];
8436 
8437  version = avio_r8(pb);
8438  flags = avio_rb24(pb);
8439  size -= 4;
8440 
8441  if (version != 0 || flags != 0) {
8443  "Unsupported 'kind' box with version %d, flags: %x",
8444  version, flags);
8445  return AVERROR_INVALIDDATA;
8446  }
8447 
8448  av_bprint_init(&scheme_buf, 0, AV_BPRINT_SIZE_UNLIMITED);
8449  av_bprint_init(&value_buf, 0, AV_BPRINT_SIZE_UNLIMITED);
8450 
8451  if ((scheme_str_len = ff_read_string_to_bprint_overwrite(pb, &scheme_buf,
8452  size)) < 0) {
8453  ret = scheme_str_len;
8454  goto cleanup;
8455  }
8456 
8457  if (scheme_str_len + 1 >= size) {
8458  // we need to have another string, even if nullptr.
8459  // we check with + 1 since we expect that if size was not hit,
8460  // an additional null was read.
8462  goto cleanup;
8463  }
8464 
8465  size -= scheme_str_len + 1;
8466 
8467  if ((value_str_len = ff_read_string_to_bprint_overwrite(pb, &value_buf,
8468  size)) < 0) {
8469  ret = value_str_len;
8470  goto cleanup;
8471  }
8472 
8473  if (value_str_len == size) {
8474  // in case of no trailing null, box is not valid.
8476  goto cleanup;
8477  }
8478 
8480  "%s stream %d KindBox(scheme: %s, value: %s)\n",
8482  st->index,
8483  scheme_buf.str, value_buf.str);
8484 
8485  for (int i = 0; ff_mov_track_kind_table[i].scheme_uri; i++) {
8487  if (!av_strstart(scheme_buf.str, map.scheme_uri, NULL))
8488  continue;
8489 
8490  for (int j = 0; map.value_maps[j].disposition; j++) {
8491  const struct MP4TrackKindValueMapping value_map = map.value_maps[j];
8492  if (!av_strstart(value_buf.str, value_map.value, NULL))
8493  continue;
8494 
8495  st->disposition |= value_map.disposition;
8496  }
8497  }
8498 
8499  ret = 0;
8500 
8501 cleanup:
8502 
8503  av_bprint_finalize(&scheme_buf, NULL);
8504  av_bprint_finalize(&value_buf, NULL);
8505 
8506  return ret;
8507 }
8508 
8510 {
8511  AVStream *st;
8512  AVChannelLayout ch_layout = { 0 };
8513  int ret, i, version, type;
8514  int ambisonic_order, channel_order, normalization, channel_count;
8515  int ambi_channels, non_diegetic_channels;
8516 
8517  if (c->fc->nb_streams < 1)
8518  return 0;
8519 
8520  st = c->fc->streams[c->fc->nb_streams - 1];
8521 
8522  if (atom.size < 16) {
8523  av_log(c->fc, AV_LOG_ERROR, "SA3D audio box too small\n");
8524  return AVERROR_INVALIDDATA;
8525  }
8526 
8527  version = avio_r8(pb);
8528  if (version) {
8529  av_log(c->fc, AV_LOG_WARNING, "Unsupported SA3D box version %d\n", version);
8530  return 0;
8531  }
8532 
8533  type = avio_r8(pb);
8534  if (type & 0x7f) {
8535  av_log(c->fc, AV_LOG_WARNING,
8536  "Unsupported ambisonic type %d\n", type & 0x7f);
8537  return 0;
8538  }
8539  non_diegetic_channels = (type >> 7) * 2; // head_locked_stereo
8540 
8541  ambisonic_order = avio_rb32(pb);
8542 
8543  channel_order = avio_r8(pb);
8544  if (channel_order) {
8545  av_log(c->fc, AV_LOG_WARNING,
8546  "Unsupported channel_order %d\n", channel_order);
8547  return 0;
8548  }
8549 
8550  normalization = avio_r8(pb);
8551  if (normalization) {
8552  av_log(c->fc, AV_LOG_WARNING,
8553  "Unsupported normalization %d\n", normalization);
8554  return 0;
8555  }
8556 
8557  channel_count = avio_rb32(pb);
8558  if (ambisonic_order < 0 || ambisonic_order > 31 ||
8559  channel_count != ((ambisonic_order + 1LL) * (ambisonic_order + 1LL) +
8560  non_diegetic_channels)) {
8561  av_log(c->fc, AV_LOG_ERROR,
8562  "Invalid number of channels (%d / %d)\n",
8563  channel_count, ambisonic_order);
8564  return 0;
8565  }
8566  ambi_channels = channel_count - non_diegetic_channels;
8567 
8568  ret = av_channel_layout_custom_init(&ch_layout, channel_count);
8569  if (ret < 0)
8570  return 0;
8571 
8572  for (i = 0; i < channel_count; i++) {
8573  unsigned channel = avio_rb32(pb);
8574 
8575  if (channel >= channel_count) {
8576  av_log(c->fc, AV_LOG_ERROR, "Invalid channel index (%d / %d)\n",
8577  channel, ambisonic_order);
8578  av_channel_layout_uninit(&ch_layout);
8579  return 0;
8580  }
8581  if (channel >= ambi_channels)
8582  ch_layout.u.map[i].id = channel - ambi_channels;
8583  else
8584  ch_layout.u.map[i].id = AV_CHAN_AMBISONIC_BASE + channel;
8585  }
8586 
8588  if (ret < 0) {
8589  av_channel_layout_uninit(&ch_layout);
8590  return 0;
8591  }
8592 
8594  st->codecpar->ch_layout = ch_layout;
8595 
8596  return 0;
8597 }
8598 
8600 {
8601  AVStream *st;
8602  int version;
8603 
8604  if (c->fc->nb_streams < 1)
8605  return 0;
8606 
8607  st = c->fc->streams[c->fc->nb_streams - 1];
8608 
8609  if (atom.size < 5) {
8610  av_log(c->fc, AV_LOG_ERROR, "Empty SAND audio box\n");
8611  return AVERROR_INVALIDDATA;
8612  }
8613 
8614  version = avio_r8(pb);
8615  if (version) {
8616  av_log(c->fc, AV_LOG_WARNING, "Unsupported SAND box version %d\n", version);
8617  return 0;
8618  }
8619 
8621 
8622  return 0;
8623 }
8624 
8625 static int rb_size(AVIOContext *pb, int64_t *value, int size)
8626 {
8627  if (size == 0)
8628  *value = 0;
8629  else if (size == 1)
8630  *value = avio_r8(pb);
8631  else if (size == 2)
8632  *value = avio_rb16(pb);
8633  else if (size == 4)
8634  *value = avio_rb32(pb);
8635  else if (size == 8) {
8636  *value = avio_rb64(pb);
8637  if (*value < 0)
8638  return -1;
8639  } else
8640  return -1;
8641  return size;
8642 }
8643 
8645 {
8646  avio_rb32(pb); // version & flags.
8647  c->primary_item_id = avio_rb16(pb);
8648  av_log(c->fc, AV_LOG_TRACE, "pitm: primary_item_id %d\n", c->primary_item_id);
8649  return atom.size;
8650 }
8651 
8653 {
8654  c->idat_offset = avio_tell(pb);
8655  return 0;
8656 }
8657 
8659 {
8660  HEIFItem **heif_item;
8661  int version, offset_size, length_size, base_offset_size, index_size;
8662  int item_count, extent_count;
8663  int64_t base_offset, extent_offset, extent_length;
8664  uint8_t value;
8665 
8666  if (c->found_iloc) {
8667  av_log(c->fc, AV_LOG_INFO, "Duplicate iloc box found\n");
8668  return 0;
8669  }
8670 
8671  version = avio_r8(pb);
8672  avio_rb24(pb); // flags.
8673 
8674  value = avio_r8(pb);
8675  offset_size = (value >> 4) & 0xF;
8676  length_size = value & 0xF;
8677  value = avio_r8(pb);
8678  base_offset_size = (value >> 4) & 0xF;
8679  index_size = !version ? 0 : (value & 0xF);
8680  if (index_size) {
8681  avpriv_report_missing_feature(c->fc, "iloc: index_size != 0");
8682  return AVERROR_PATCHWELCOME;
8683  }
8684  item_count = (version < 2) ? avio_rb16(pb) : avio_rb32(pb);
8685 
8686  heif_item = av_realloc_array(c->heif_item, FFMAX(item_count, c->nb_heif_item), sizeof(*c->heif_item));
8687  if (!heif_item)
8688  return AVERROR(ENOMEM);
8689  c->heif_item = heif_item;
8690  if (item_count > c->nb_heif_item)
8691  memset(&c->heif_item[c->nb_heif_item], 0,
8692  sizeof(*c->heif_item) * (item_count - c->nb_heif_item));
8693  c->nb_heif_item = FFMAX(c->nb_heif_item, item_count);
8694 
8695  av_log(c->fc, AV_LOG_TRACE, "iloc: item_count %d\n", item_count);
8696  for (int i = 0; i < item_count; i++) {
8697  HEIFItem *item = c->heif_item[i];
8698  int item_id = (version < 2) ? avio_rb16(pb) : avio_rb32(pb);
8699  int offset_type = (version > 0) ? avio_rb16(pb) & 0xf : 0;
8700 
8701  if (avio_feof(pb))
8702  return AVERROR_INVALIDDATA;
8703  if (offset_type > 1) {
8704  avpriv_report_missing_feature(c->fc, "iloc offset type %d", offset_type);
8705  return AVERROR_PATCHWELCOME;
8706  }
8707 
8708  avio_rb16(pb); // data_reference_index.
8709  if (rb_size(pb, &base_offset, base_offset_size) < 0)
8710  return AVERROR_INVALIDDATA;
8711  extent_count = avio_rb16(pb);
8712  if (extent_count > 1) {
8713  // For still AVIF images, we only support one extent item.
8714  avpriv_report_missing_feature(c->fc, "iloc: extent_count > 1");
8715  return AVERROR_PATCHWELCOME;
8716  }
8717 
8718  if (rb_size(pb, &extent_offset, offset_size) < 0 ||
8719  rb_size(pb, &extent_length, length_size) < 0 ||
8720  base_offset > INT64_MAX - extent_offset)
8721  return AVERROR_INVALIDDATA;
8722 
8723  if (!item)
8724  item = c->heif_item[i] = av_mallocz(sizeof(*item));
8725  if (!item)
8726  return AVERROR(ENOMEM);
8727 
8728  item->item_id = item_id;
8729 
8730  if (offset_type == 1)
8731  item->is_idat_relative = 1;
8732  item->extent_length = extent_length;
8733  item->extent_offset = base_offset + extent_offset;
8734  av_log(c->fc, AV_LOG_TRACE, "iloc: item_idx %d, offset_type %d, "
8735  "extent_offset %"PRId64", extent_length %"PRId64"\n",
8736  i, offset_type, item->extent_offset, item->extent_length);
8737  }
8738 
8739  c->found_iloc = 1;
8740  return atom.size;
8741 }
8742 
8743 static int mov_read_infe(MOVContext *c, AVIOContext *pb, MOVAtom atom, int idx)
8744 {
8745  HEIFItem *item;
8746  AVBPrint item_name;
8747  int64_t size = atom.size;
8748  uint32_t item_type;
8749  int item_id;
8750  int version, ret;
8751 
8752  version = avio_r8(pb);
8753  avio_rb24(pb); // flags.
8754  size -= 4;
8755  if (size < 0)
8756  return AVERROR_INVALIDDATA;
8757 
8758  if (version < 2) {
8759  avpriv_report_missing_feature(c->fc, "infe version < 2");
8760  avio_skip(pb, size);
8761  return 1;
8762  }
8763 
8764  item_id = version > 2 ? avio_rb32(pb) : avio_rb16(pb);
8765  avio_rb16(pb); // item_protection_index
8766  item_type = avio_rl32(pb);
8767  size -= 8;
8768  if (size < 1)
8769  return AVERROR_INVALIDDATA;
8770 
8773  if (ret < 0) {
8775  return ret;
8776  }
8777 
8778  av_log(c->fc, AV_LOG_TRACE, "infe: item_id %d, item_type %s, item_name %s\n",
8779  item_id, av_fourcc2str(item_type), item_name.str);
8780 
8781  size -= ret + 1;
8782  if (size > 0)
8783  avio_skip(pb, size);
8784 
8785  item = c->heif_item[idx];
8786  if (!item)
8787  item = c->heif_item[idx] = av_mallocz(sizeof(*item));
8788  if (!item)
8789  return AVERROR(ENOMEM);
8790 
8791  if (ret)
8792  av_bprint_finalize(&item_name, &c->heif_item[idx]->name);
8793  c->heif_item[idx]->item_id = item_id;
8794  c->heif_item[idx]->type = item_type;
8795 
8796  switch (item_type) {
8797  case MKTAG('a','v','0','1'):
8798  case MKTAG('h','v','c','1'):
8799  ret = heif_add_stream(c, c->heif_item[idx]);
8800  if (ret < 0)
8801  return ret;
8802  break;
8803  }
8804 
8805  return 0;
8806 }
8807 
8809 {
8810  HEIFItem **heif_item;
8811  int entry_count;
8812  int version, got_stream = 0, ret, i;
8813 
8814  if (c->found_iinf) {
8815  av_log(c->fc, AV_LOG_WARNING, "Duplicate iinf box found\n");
8816  return 0;
8817  }
8818 
8819  version = avio_r8(pb);
8820  avio_rb24(pb); // flags.
8821  entry_count = version ? avio_rb32(pb) : avio_rb16(pb);
8822 
8823  heif_item = av_realloc_array(c->heif_item, FFMAX(entry_count, c->nb_heif_item), sizeof(*c->heif_item));
8824  if (!heif_item)
8825  return AVERROR(ENOMEM);
8826  c->heif_item = heif_item;
8827  if (entry_count > c->nb_heif_item)
8828  memset(&c->heif_item[c->nb_heif_item], 0,
8829  sizeof(*c->heif_item) * (entry_count - c->nb_heif_item));
8830  c->nb_heif_item = FFMAX(c->nb_heif_item, entry_count);
8831 
8832  for (i = 0; i < entry_count; i++) {
8833  MOVAtom infe;
8834 
8835  if (avio_feof(pb)) {
8837  goto fail;
8838  }
8839  infe.size = avio_rb32(pb) - 8;
8840  infe.type = avio_rl32(pb);
8841  ret = mov_read_infe(c, pb, infe, i);
8842  if (ret < 0)
8843  goto fail;
8844  if (!ret)
8845  got_stream = 1;
8846  }
8847 
8848  c->found_iinf = got_stream;
8849  return 0;
8850 fail:
8851  for (; i >= 0; i--) {
8852  HEIFItem *item = c->heif_item[i];
8853 
8854  if (!item)
8855  continue;
8856 
8857  av_freep(&item->name);
8858  if (!item->st)
8859  continue;
8860 
8861  mov_free_stream_context(c->fc, item->st);
8862  ff_remove_stream(c->fc, item->st);
8863  item->st = NULL;
8864  }
8865  return ret;
8866 }
8867 
8869 {
8870  HEIFItem *item = NULL;
8871  HEIFGrid *grid;
8872  int entries, i;
8873  int from_item_id = version ? avio_rb32(pb) : avio_rb16(pb);
8874 
8875  for (int i = 0; i < c->nb_heif_grid; i++) {
8876  if (c->heif_grid[i].item->item_id == from_item_id) {
8877  av_log(c->fc, AV_LOG_ERROR, "More than one 'dimg' box "
8878  "referencing the same Derived Image item\n");
8879  return AVERROR_INVALIDDATA;
8880  }
8881  }
8882  for (int i = 0; i < c->nb_heif_item; i++) {
8883  if (!c->heif_item[i] || c->heif_item[i]->item_id != from_item_id)
8884  continue;
8885  item = c->heif_item[i];
8886 
8887  switch (item->type) {
8888  case MKTAG('g','r','i','d'):
8889  case MKTAG('i','o','v','l'):
8890  break;
8891  default:
8892  avpriv_report_missing_feature(c->fc, "Derived Image item of type %s",
8893  av_fourcc2str(item->type));
8894  return 0;
8895  }
8896  break;
8897  }
8898  if (!item) {
8899  av_log(c->fc, AV_LOG_ERROR, "Missing grid information\n");
8900  return AVERROR_INVALIDDATA;
8901  }
8902 
8903  grid = av_realloc_array(c->heif_grid, c->nb_heif_grid + 1U,
8904  sizeof(*c->heif_grid));
8905  if (!grid)
8906  return AVERROR(ENOMEM);
8907  c->heif_grid = grid;
8908  grid = &grid[c->nb_heif_grid++];
8909 
8910  entries = avio_rb16(pb);
8911  grid->tile_id_list = av_malloc_array(entries, sizeof(*grid->tile_id_list));
8912  grid->tile_item_list = av_calloc(entries, sizeof(*grid->tile_item_list));
8913  if (!grid->tile_id_list || !grid->tile_item_list)
8914  return AVERROR(ENOMEM);
8915  /* 'to' item ids */
8916  for (i = 0; i < entries; i++)
8917  grid->tile_id_list[i] = version ? avio_rb32(pb) : avio_rb16(pb);
8918  grid->nb_tiles = entries;
8919  grid->item = item;
8920 
8921  av_log(c->fc, AV_LOG_TRACE, "dimg: from_item_id %d, entries %d\n",
8922  from_item_id, entries);
8923 
8924  return 0;
8925 }
8926 
8928 {
8929  int entries;
8930  int to_item_id, from_item_id = version ? avio_rb32(pb) : avio_rb16(pb);
8931 
8932  entries = avio_rb16(pb);
8933  if (entries > 1) {
8934  avpriv_request_sample(c->fc, "thmb in iref referencing several items");
8935  return AVERROR_PATCHWELCOME;
8936  }
8937  /* 'to' item ids */
8938  to_item_id = version ? avio_rb32(pb) : avio_rb16(pb);
8939 
8940  if (to_item_id != c->primary_item_id)
8941  return 0;
8942 
8943  c->thmb_item_id = from_item_id;
8944 
8945  av_log(c->fc, AV_LOG_TRACE, "thmb: from_item_id %d, entries %d\n",
8946  from_item_id, entries);
8947 
8948  return 0;
8949 }
8950 
8952 {
8953  int version = avio_r8(pb);
8954  avio_rb24(pb); // flags
8955  atom.size -= 4;
8956 
8957  if (version > 1) {
8958  av_log(c->fc, AV_LOG_WARNING, "Unknown iref box version %d\n", version);
8959  return 0;
8960  }
8961 
8962  while (atom.size) {
8963  uint32_t type, size = avio_rb32(pb);
8964  int64_t next = avio_tell(pb);
8965 
8966  if (size < 14 || next < 0 || next > INT64_MAX - size)
8967  return AVERROR_INVALIDDATA;
8968 
8969  next += size - 4;
8970  type = avio_rl32(pb);
8971  switch (type) {
8972  case MKTAG('d','i','m','g'):
8974  break;
8975  case MKTAG('t','h','m','b'):
8977  break;
8978  default:
8979  av_log(c->fc, AV_LOG_DEBUG, "Unknown iref type %s size %"PRIu32"\n",
8980  av_fourcc2str(type), size);
8981  }
8982 
8983  atom.size -= size;
8984  avio_seek(pb, next, SEEK_SET);
8985  }
8986  return 0;
8987 }
8988 
8990 {
8991  HEIFItem *item;
8992  uint32_t width, height;
8993 
8994  avio_r8(pb); /* version */
8995  avio_rb24(pb); /* flags */
8996  width = avio_rb32(pb);
8997  height = avio_rb32(pb);
8998 
8999  av_log(c->fc, AV_LOG_TRACE, "ispe: item_id %d, width %u, height %u\n",
9000  c->cur_item_id, width, height);
9001 
9002  item = heif_cur_item(c);
9003  if (item) {
9004  item->width = width;
9005  item->height = height;
9006  }
9007 
9008  return 0;
9009 }
9010 
9012 {
9013  HEIFItem *item;
9014  int angle;
9015 
9016  angle = avio_r8(pb) & 0x3;
9017 
9018  av_log(c->fc, AV_LOG_TRACE, "irot: item_id %d, angle %u\n",
9019  c->cur_item_id, angle);
9020 
9021  item = heif_cur_item(c);
9022  if (item) {
9023  // angle * 90 specifies the angle (in anti-clockwise direction)
9024  // in units of degrees.
9025  item->rotation = angle * 90;
9026  }
9027 
9028  return 0;
9029 }
9030 
9032 {
9033  HEIFItem *item;
9034  int axis;
9035 
9036  axis = avio_r8(pb) & 0x1;
9037 
9038  av_log(c->fc, AV_LOG_TRACE, "imir: item_id %d, axis %u\n",
9039  c->cur_item_id, axis);
9040 
9041  item = heif_cur_item(c);
9042  if (item) {
9043  item->hflip = axis;
9044  item->vflip = !axis;
9045  }
9046 
9047  return 0;
9048 }
9049 
9051 {
9052  typedef struct MOVAtoms {
9053  FFIOContext b;
9054  uint32_t type;
9055  int64_t size;
9056  uint8_t *data;
9057  } MOVAtoms;
9058  MOVAtoms *atoms = NULL;
9059  MOVAtom a;
9060  unsigned count;
9061  int nb_atoms = 0;
9062  int version, flags;
9063  int ret;
9064 
9065  a.size = avio_rb32(pb);
9066  a.type = avio_rl32(pb);
9067 
9068  if (a.size < 8 || a.type != MKTAG('i','p','c','o'))
9069  return AVERROR_INVALIDDATA;
9070 
9071  a.size -= 8;
9072  while (a.size >= 8) {
9073  MOVAtoms *ref = av_dynarray2_add((void**)&atoms, &nb_atoms, sizeof(MOVAtoms), NULL);
9074  if (!ref) {
9075  ret = AVERROR(ENOMEM);
9076  goto fail;
9077  }
9078  ref->data = NULL;
9079  ref->size = avio_rb32(pb);
9080  ref->type = avio_rl32(pb);
9081  if (ref->size > a.size || ref->size < 8)
9082  break;
9083  ref->data = av_malloc(ref->size);
9084  if (!ref->data) {
9086  goto fail;
9087  }
9088  av_log(c->fc, AV_LOG_TRACE, "ipco: index %d, box type %s\n", nb_atoms, av_fourcc2str(ref->type));
9089  avio_seek(pb, -8, SEEK_CUR);
9090  if (avio_read(pb, ref->data, ref->size) != ref->size) {
9092  goto fail;
9093  }
9094  ffio_init_read_context(&ref->b, ref->data, ref->size);
9095  a.size -= ref->size;
9096  }
9097 
9098  if (a.size) {
9100  goto fail;
9101  }
9102 
9103  a.size = avio_rb32(pb);
9104  a.type = avio_rl32(pb);
9105 
9106  if (a.size < 8 || a.type != MKTAG('i','p','m','a')) {
9108  goto fail;
9109  }
9110 
9111  version = avio_r8(pb);
9112  flags = avio_rb24(pb);
9113  count = avio_rb32(pb);
9114 
9115  for (int i = 0; i < count; i++) {
9116  int item_id = version ? avio_rb32(pb) : avio_rb16(pb);
9117  int assoc_count = avio_r8(pb);
9118 
9119  if (avio_feof(pb)) {
9121  goto fail;
9122  }
9123 
9124  for (int j = 0; j < assoc_count; j++) {
9125  MOVAtoms *ref;
9126  int index = avio_r8(pb) & 0x7f;
9127  if (flags & 1) {
9128  index <<= 8;
9129  index |= avio_r8(pb);
9130  }
9131  if (index > nb_atoms || index <= 0) {
9133  goto fail;
9134  }
9135  ref = &atoms[--index];
9136 
9137  av_log(c->fc, AV_LOG_TRACE, "ipma: property_index %d, item_id %d, item_type %s\n",
9138  index + 1, item_id, av_fourcc2str(ref->type));
9139 
9140  c->cur_item_id = item_id;
9141 
9142  ret = mov_read_default(c, &ref->b.pub,
9143  (MOVAtom) { .size = ref->size,
9144  .type = MKTAG('i','p','c','o') });
9145  if (ret < 0)
9146  goto fail;
9147  ffio_init_read_context(&ref->b, ref->data, ref->size);
9148  }
9149  }
9150 
9151  ret = 0;
9152 fail:
9153  c->cur_item_id = -1;
9154  for (int i = 0; i < nb_atoms; i++)
9155  av_free(atoms[i].data);
9156  av_free(atoms);
9157 
9158  return ret;
9159 }
9160 
9162 { MKTAG('A','C','L','R'), mov_read_aclr },
9163 { MKTAG('A','P','R','G'), mov_read_avid },
9164 { MKTAG('A','A','L','P'), mov_read_avid },
9165 { MKTAG('A','R','E','S'), mov_read_ares },
9166 { MKTAG('a','v','s','s'), mov_read_avss },
9167 { MKTAG('a','v','1','C'), mov_read_glbl },
9168 { MKTAG('c','h','p','l'), mov_read_chpl },
9169 { MKTAG('c','o','6','4'), mov_read_stco },
9170 { MKTAG('c','o','l','r'), mov_read_colr },
9171 { MKTAG('c','t','t','s'), mov_read_ctts }, /* composition time to sample */
9172 { MKTAG('d','i','n','f'), mov_read_default },
9173 { MKTAG('D','p','x','E'), mov_read_dpxe },
9174 { MKTAG('d','r','e','f'), mov_read_dref },
9175 { MKTAG('e','d','t','s'), mov_read_default },
9176 { MKTAG('e','l','s','t'), mov_read_elst },
9177 { MKTAG('e','n','d','a'), mov_read_enda },
9178 { MKTAG('f','i','e','l'), mov_read_fiel },
9179 { MKTAG('a','d','r','m'), mov_read_adrm },
9180 { MKTAG('f','t','y','p'), mov_read_ftyp },
9181 { MKTAG('g','l','b','l'), mov_read_glbl },
9182 { MKTAG('h','d','l','r'), mov_read_hdlr },
9183 { MKTAG('i','l','s','t'), mov_read_ilst },
9184 { MKTAG('j','p','2','h'), mov_read_jp2h },
9185 { MKTAG('m','d','a','t'), mov_read_mdat },
9186 { MKTAG('m','d','h','d'), mov_read_mdhd },
9187 { MKTAG('m','d','i','a'), mov_read_default },
9188 { MKTAG('m','e','t','a'), mov_read_meta },
9189 { MKTAG('m','i','n','f'), mov_read_default },
9190 { MKTAG('m','o','o','f'), mov_read_moof },
9191 { MKTAG('m','o','o','v'), mov_read_moov },
9192 { MKTAG('m','v','e','x'), mov_read_default },
9193 { MKTAG('m','v','h','d'), mov_read_mvhd },
9194 { MKTAG('S','M','I',' '), mov_read_svq3 },
9195 { MKTAG('a','l','a','c'), mov_read_alac }, /* alac specific atom */
9196 { MKTAG('a','v','c','C'), mov_read_glbl },
9197 { MKTAG('p','a','s','p'), mov_read_pasp },
9198 { MKTAG('c','l','a','p'), mov_read_clap },
9199 { MKTAG('s','b','a','s'), mov_read_sbas },
9200 { MKTAG('s','i','d','x'), mov_read_sidx },
9201 { MKTAG('s','t','b','l'), mov_read_default },
9202 { MKTAG('s','t','c','o'), mov_read_stco },
9203 { MKTAG('s','t','p','s'), mov_read_stps },
9204 { MKTAG('s','t','r','f'), mov_read_strf },
9205 { MKTAG('s','t','s','c'), mov_read_stsc },
9206 { MKTAG('s','t','s','d'), mov_read_stsd }, /* sample description */
9207 { MKTAG('s','t','s','s'), mov_read_stss }, /* sync sample */
9208 { MKTAG('s','t','s','z'), mov_read_stsz }, /* sample size */
9209 { MKTAG('s','t','t','s'), mov_read_stts },
9210 { MKTAG('s','t','z','2'), mov_read_stsz }, /* compact sample size */
9211 { MKTAG('s','d','t','p'), mov_read_sdtp }, /* independent and disposable samples */
9212 { MKTAG('t','k','h','d'), mov_read_tkhd }, /* track header */
9213 { MKTAG('t','f','d','t'), mov_read_tfdt },
9214 { MKTAG('t','f','h','d'), mov_read_tfhd }, /* track fragment header */
9215 { MKTAG('t','r','a','k'), mov_read_trak },
9216 { MKTAG('t','r','a','f'), mov_read_default },
9217 { MKTAG('t','r','e','f'), mov_read_default },
9218 { MKTAG('t','m','c','d'), mov_read_tmcd },
9219 { MKTAG('c','h','a','p'), mov_read_chap },
9220 { MKTAG('t','r','e','x'), mov_read_trex },
9221 { MKTAG('t','r','u','n'), mov_read_trun },
9222 { MKTAG('u','d','t','a'), mov_read_default },
9223 { MKTAG('w','a','v','e'), mov_read_wave },
9224 { MKTAG('e','s','d','s'), mov_read_esds },
9225 { MKTAG('d','a','c','3'), mov_read_dac3 }, /* AC-3 info */
9226 { MKTAG('d','e','c','3'), mov_read_dec3 }, /* EAC-3 info */
9227 { MKTAG('d','d','t','s'), mov_read_ddts }, /* DTS audio descriptor */
9228 { MKTAG('w','i','d','e'), mov_read_wide }, /* place holder */
9229 { MKTAG('w','f','e','x'), mov_read_wfex },
9230 { MKTAG('c','m','o','v'), mov_read_cmov },
9231 { MKTAG('c','h','a','n'), mov_read_chan }, /* channel layout from quicktime */
9232 { MKTAG('c','h','n','l'), mov_read_chnl }, /* channel layout from ISO-14496-12 */
9233 { MKTAG('d','v','c','1'), mov_read_dvc1 },
9234 { MKTAG('s','g','p','d'), mov_read_sgpd },
9235 { MKTAG('s','b','g','p'), mov_read_sbgp },
9236 { MKTAG('h','v','c','C'), mov_read_glbl },
9237 { MKTAG('v','v','c','C'), mov_read_glbl },
9238 { MKTAG('u','u','i','d'), mov_read_uuid },
9239 { MKTAG('C','i','n', 0x8e), mov_read_targa_y216 },
9240 { MKTAG('f','r','e','e'), mov_read_free },
9241 { MKTAG('-','-','-','-'), mov_read_custom },
9242 { MKTAG('s','i','n','f'), mov_read_default },
9243 { MKTAG('f','r','m','a'), mov_read_frma },
9244 { MKTAG('s','e','n','c'), mov_read_senc },
9245 { MKTAG('s','a','i','z'), mov_read_saiz },
9246 { MKTAG('s','a','i','o'), mov_read_saio },
9247 { MKTAG('p','s','s','h'), mov_read_pssh },
9248 { MKTAG('s','c','h','m'), mov_read_schm },
9249 { MKTAG('s','c','h','i'), mov_read_default },
9250 { MKTAG('t','e','n','c'), mov_read_tenc },
9251 { MKTAG('d','f','L','a'), mov_read_dfla },
9252 { MKTAG('s','t','3','d'), mov_read_st3d }, /* stereoscopic 3D video box */
9253 { MKTAG('s','v','3','d'), mov_read_sv3d }, /* spherical video box */
9254 { MKTAG('v','e','x','u'), mov_read_vexu }, /* video extension usage */
9255 { MKTAG('h','f','o','v'), mov_read_hfov },
9256 { MKTAG('d','O','p','s'), mov_read_dops },
9257 { MKTAG('d','m','l','p'), mov_read_dmlp },
9258 { MKTAG('S','m','D','m'), mov_read_smdm },
9259 { MKTAG('C','o','L','L'), mov_read_coll },
9260 { MKTAG('v','p','c','C'), mov_read_vpcc },
9261 { MKTAG('m','d','c','v'), mov_read_mdcv },
9262 { MKTAG('c','l','l','i'), mov_read_clli },
9263 { MKTAG('d','v','c','C'), mov_read_dvcc_dvvc },
9264 { MKTAG('d','v','v','C'), mov_read_dvcc_dvvc },
9265 { MKTAG('d','v','w','C'), mov_read_dvcc_dvvc },
9266 { MKTAG('k','i','n','d'), mov_read_kind },
9267 { MKTAG('S','A','3','D'), mov_read_SA3D }, /* ambisonic audio box */
9268 { MKTAG('S','A','N','D'), mov_read_SAND }, /* non diegetic audio box */
9269 { MKTAG('i','l','o','c'), mov_read_iloc },
9270 { MKTAG('p','c','m','C'), mov_read_pcmc }, /* PCM configuration box */
9271 { MKTAG('p','i','t','m'), mov_read_pitm },
9272 { MKTAG('e','v','c','C'), mov_read_glbl },
9273 { MKTAG('i','d','a','t'), mov_read_idat },
9274 { MKTAG('i','m','i','r'), mov_read_imir },
9275 { MKTAG('i','r','e','f'), mov_read_iref },
9276 { MKTAG('i','s','p','e'), mov_read_ispe },
9277 { MKTAG('i','r','o','t'), mov_read_irot },
9278 { MKTAG('i','p','r','p'), mov_read_iprp },
9279 { MKTAG('i','i','n','f'), mov_read_iinf },
9280 { MKTAG('a','m','v','e'), mov_read_amve }, /* ambient viewing environment box */
9281 { MKTAG('l','h','v','C'), mov_read_lhvc },
9282 { MKTAG('l','v','c','C'), mov_read_glbl },
9283 #if CONFIG_IAMFDEC
9284 { MKTAG('i','a','c','b'), mov_read_iacb },
9285 #endif
9286 { 0, NULL }
9287 };
9288 
9290 {
9291  int64_t total_size = 0;
9292  MOVAtom a;
9293  int i;
9294 
9295  if (c->atom_depth > 10) {
9296  av_log(c->fc, AV_LOG_ERROR, "Atoms too deeply nested\n");
9297  return AVERROR_INVALIDDATA;
9298  }
9299  c->atom_depth ++;
9300 
9301  if (atom.size < 0)
9302  atom.size = INT64_MAX;
9303  while (total_size <= atom.size - 8) {
9304  int (*parse)(MOVContext*, AVIOContext*, MOVAtom) = NULL;
9305  a.size = avio_rb32(pb);
9306  a.type = avio_rl32(pb);
9307  if (avio_feof(pb))
9308  break;
9309  if (((a.type == MKTAG('f','r','e','e') && c->moov_retry) ||
9310  a.type == MKTAG('h','o','o','v')) &&
9311  a.size >= 8 &&
9312  c->fc->strict_std_compliance < FF_COMPLIANCE_STRICT) {
9313  uint32_t type;
9314  avio_skip(pb, 4);
9315  type = avio_rl32(pb);
9316  if (avio_feof(pb))
9317  break;
9318  avio_seek(pb, -8, SEEK_CUR);
9319  if (type == MKTAG('m','v','h','d') ||
9320  type == MKTAG('c','m','o','v')) {
9321  av_log(c->fc, AV_LOG_ERROR, "Detected moov in a free or hoov atom.\n");
9322  a.type = MKTAG('m','o','o','v');
9323  }
9324  }
9325  if (atom.type != MKTAG('r','o','o','t') &&
9326  atom.type != MKTAG('m','o','o','v')) {
9327  if (a.type == MKTAG('t','r','a','k') ||
9328  a.type == MKTAG('m','d','a','t')) {
9329  av_log(c->fc, AV_LOG_ERROR, "Broken file, trak/mdat not at top-level\n");
9330  avio_skip(pb, -8);
9331  c->atom_depth --;
9332  return 0;
9333  }
9334  }
9335  total_size += 8;
9336  if (a.size == 1 && total_size + 8 <= atom.size) { /* 64 bit extended size */
9337  a.size = avio_rb64(pb) - 8;
9338  total_size += 8;
9339  }
9340  av_log(c->fc, AV_LOG_TRACE, "type:'%s' parent:'%s' sz: %"PRId64" %"PRId64" %"PRId64"\n",
9341  av_fourcc2str(a.type), av_fourcc2str(atom.type), a.size, total_size, atom.size);
9342  if (a.size == 0) {
9343  a.size = atom.size - total_size + 8;
9344  }
9345  if (a.size < 0)
9346  break;
9347  a.size -= 8;
9348  if (a.size < 0)
9349  break;
9350  a.size = FFMIN(a.size, atom.size - total_size);
9351 
9352  for (i = 0; mov_default_parse_table[i].type; i++)
9353  if (mov_default_parse_table[i].type == a.type) {
9355  break;
9356  }
9357 
9358  // container is user data
9359  if (!parse && (atom.type == MKTAG('u','d','t','a') ||
9360  atom.type == MKTAG('i','l','s','t')))
9362 
9363  // Supports parsing the QuickTime Metadata Keys.
9364  // https://developer.apple.com/library/mac/documentation/QuickTime/QTFF/Metadata/Metadata.html
9365  if (!parse && c->found_hdlr_mdta &&
9366  atom.type == MKTAG('m','e','t','a') &&
9367  a.type == MKTAG('k','e','y','s') &&
9368  c->meta_keys_count == 0) {
9369  parse = mov_read_keys;
9370  }
9371 
9372  if (!parse) { /* skip leaf atoms data */
9373  avio_skip(pb, a.size);
9374  } else {
9375  int64_t start_pos = avio_tell(pb);
9376  int64_t left;
9377  int err = parse(c, pb, a);
9378  if (err < 0) {
9379  c->atom_depth --;
9380  return err;
9381  }
9382  if (c->found_moov && c->found_mdat && a.size <= INT64_MAX - start_pos &&
9383  ((!(pb->seekable & AVIO_SEEKABLE_NORMAL) || c->fc->flags & AVFMT_FLAG_IGNIDX || c->frag_index.complete) ||
9384  start_pos + a.size == avio_size(pb))) {
9385  if (!(pb->seekable & AVIO_SEEKABLE_NORMAL) || c->fc->flags & AVFMT_FLAG_IGNIDX || c->frag_index.complete)
9386  c->next_root_atom = start_pos + a.size;
9387  c->atom_depth --;
9388  return 0;
9389  }
9390  left = a.size - avio_tell(pb) + start_pos;
9391  if (left > 0) /* skip garbage at atom end */
9392  avio_skip(pb, left);
9393  else if (left < 0) {
9394  av_log(c->fc, AV_LOG_WARNING,
9395  "overread end of atom '%s' by %"PRId64" bytes\n",
9396  av_fourcc2str(a.type), -left);
9397  avio_seek(pb, left, SEEK_CUR);
9398  }
9399  }
9400 
9401  total_size += a.size;
9402  }
9403 
9404  if (total_size < atom.size && atom.size < 0x7ffff)
9405  avio_skip(pb, atom.size - total_size);
9406 
9407  c->atom_depth --;
9408  return 0;
9409 }
9410 
9411 static int mov_probe(const AVProbeData *p)
9412 {
9413  int64_t offset;
9414  uint32_t tag;
9415  int score = 0;
9416  int moov_offset = -1;
9417 
9418  /* check file header */
9419  offset = 0;
9420  for (;;) {
9421  int64_t size;
9422  int minsize = 8;
9423  /* ignore invalid offset */
9424  if ((offset + 8ULL) > (unsigned int)p->buf_size)
9425  break;
9426  size = AV_RB32(p->buf + offset);
9427  if (size == 1 && offset + 16 <= (unsigned int)p->buf_size) {
9428  size = AV_RB64(p->buf+offset + 8);
9429  minsize = 16;
9430  } else if (size == 0) {
9431  size = p->buf_size - offset;
9432  }
9433  if (size < minsize) {
9434  offset += 4;
9435  continue;
9436  }
9437  tag = AV_RL32(p->buf + offset + 4);
9438  switch(tag) {
9439  /* check for obvious tags */
9440  case MKTAG('m','o','o','v'):
9441  moov_offset = offset + 4;
9442  case MKTAG('m','d','a','t'):
9443  case MKTAG('p','n','o','t'): /* detect movs with preview pics like ew.mov and april.mov */
9444  case MKTAG('u','d','t','a'): /* Packet Video PVAuthor adds this and a lot of more junk */
9445  case MKTAG('f','t','y','p'):
9446  if (tag == MKTAG('f','t','y','p') &&
9447  ( AV_RL32(p->buf + offset + 8) == MKTAG('j','p','2',' ')
9448  || AV_RL32(p->buf + offset + 8) == MKTAG('j','p','x',' ')
9449  || AV_RL32(p->buf + offset + 8) == MKTAG('j','x','l',' ')
9450  )) {
9451  score = FFMAX(score, 5);
9452  } else {
9453  score = AVPROBE_SCORE_MAX;
9454  }
9455  break;
9456  /* those are more common words, so rate then a bit less */
9457  case MKTAG('e','d','i','w'): /* xdcam files have reverted first tags */
9458  case MKTAG('w','i','d','e'):
9459  case MKTAG('f','r','e','e'):
9460  case MKTAG('j','u','n','k'):
9461  case MKTAG('p','i','c','t'):
9462  score = FFMAX(score, AVPROBE_SCORE_MAX - 5);
9463  break;
9464  case MKTAG(0x82,0x82,0x7f,0x7d):
9465  score = FFMAX(score, AVPROBE_SCORE_EXTENSION - 5);
9466  break;
9467  case MKTAG('s','k','i','p'):
9468  case MKTAG('u','u','i','d'):
9469  case MKTAG('p','r','f','l'):
9470  /* if we only find those cause probedata is too small at least rate them */
9471  score = FFMAX(score, AVPROBE_SCORE_EXTENSION);
9472  break;
9473  }
9474  if (size > INT64_MAX - offset)
9475  break;
9476  offset += size;
9477  }
9478  if (score > AVPROBE_SCORE_MAX - 50 && moov_offset != -1) {
9479  /* moov atom in the header - we should make sure that this is not a
9480  * MOV-packed MPEG-PS */
9481  offset = moov_offset;
9482 
9483  while (offset < (p->buf_size - 16)) { /* Sufficient space */
9484  /* We found an actual hdlr atom */
9485  if (AV_RL32(p->buf + offset ) == MKTAG('h','d','l','r') &&
9486  AV_RL32(p->buf + offset + 8) == MKTAG('m','h','l','r') &&
9487  AV_RL32(p->buf + offset + 12) == MKTAG('M','P','E','G')) {
9488  av_log(NULL, AV_LOG_WARNING, "Found media data tag MPEG indicating this is a MOV-packed MPEG-PS.\n");
9489  /* We found a media handler reference atom describing an
9490  * MPEG-PS-in-MOV, return a
9491  * low score to force expanding the probe window until
9492  * mpegps_probe finds what it needs */
9493  return 5;
9494  } else {
9495  /* Keep looking */
9496  offset += 2;
9497  }
9498  }
9499  }
9500 
9501  return score;
9502 }
9503 
9504 // must be done after parsing all trak because there's no order requirement
9506 {
9507  MOVContext *mov = s->priv_data;
9508  MOVStreamContext *sc;
9509  int64_t cur_pos;
9510  int i, j;
9511  int chapter_track;
9512 
9513  for (j = 0; j < mov->nb_chapter_tracks; j++) {
9514  AVStream *st = NULL;
9515  FFStream *sti = NULL;
9516  chapter_track = mov->chapter_tracks[j];
9517  for (i = 0; i < s->nb_streams; i++) {
9518  sc = mov->fc->streams[i]->priv_data;
9519  if (sc->id == chapter_track) {
9520  st = s->streams[i];
9521  break;
9522  }
9523  }
9524  if (!st) {
9525  av_log(s, AV_LOG_ERROR, "Referenced QT chapter track not found\n");
9526  continue;
9527  }
9528  sti = ffstream(st);
9529 
9530  sc = st->priv_data;
9531  cur_pos = avio_tell(sc->pb);
9532 
9533  if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
9535  if (!st->attached_pic.data && sti->nb_index_entries) {
9536  // Retrieve the first frame, if possible
9537  AVIndexEntry *sample = &sti->index_entries[0];
9538  if (avio_seek(sc->pb, sample->pos, SEEK_SET) != sample->pos) {
9539  av_log(s, AV_LOG_ERROR, "Failed to retrieve first frame\n");
9540  goto finish;
9541  }
9542 
9543  if (ff_add_attached_pic(s, st, sc->pb, NULL, sample->size) < 0)
9544  goto finish;
9545  }
9546  } else {
9549  st->discard = AVDISCARD_ALL;
9550  for (int i = 0; i < sti->nb_index_entries; i++) {
9551  AVIndexEntry *sample = &sti->index_entries[i];
9552  int64_t end = i+1 < sti->nb_index_entries ? sti->index_entries[i+1].timestamp : st->duration;
9553  uint8_t *title;
9554  uint16_t ch;
9555  int len, title_len;
9556 
9557  if (end < sample->timestamp) {
9558  av_log(s, AV_LOG_WARNING, "ignoring stream duration which is shorter than chapters\n");
9559  end = AV_NOPTS_VALUE;
9560  }
9561 
9562  if (avio_seek(sc->pb, sample->pos, SEEK_SET) != sample->pos) {
9563  av_log(s, AV_LOG_ERROR, "Chapter %d not found in file\n", i);
9564  goto finish;
9565  }
9566 
9567  // the first two bytes are the length of the title
9568  len = avio_rb16(sc->pb);
9569  if (len > sample->size-2)
9570  continue;
9571  title_len = 2*len + 1;
9572  if (!(title = av_mallocz(title_len)))
9573  goto finish;
9574 
9575  // The samples could theoretically be in any encoding if there's an encd
9576  // atom following, but in practice are only utf-8 or utf-16, distinguished
9577  // instead by the presence of a BOM
9578  if (!len) {
9579  title[0] = 0;
9580  } else {
9581  ch = avio_rb16(sc->pb);
9582  if (ch == 0xfeff)
9583  avio_get_str16be(sc->pb, len, title, title_len);
9584  else if (ch == 0xfffe)
9585  avio_get_str16le(sc->pb, len, title, title_len);
9586  else {
9587  AV_WB16(title, ch);
9588  if (len == 1 || len == 2)
9589  title[len] = 0;
9590  else
9591  avio_get_str(sc->pb, INT_MAX, title + 2, len - 1);
9592  }
9593  }
9594 
9595  avpriv_new_chapter(s, i, st->time_base, sample->timestamp, end, title);
9596  av_freep(&title);
9597  }
9598  }
9599 finish:
9600  avio_seek(sc->pb, cur_pos, SEEK_SET);
9601  }
9602 }
9603 
9605  int64_t value, int flags)
9606 {
9607  AVTimecode tc;
9608  char buf[AV_TIMECODE_STR_SIZE];
9609  AVRational rate = st->avg_frame_rate;
9610  int ret = av_timecode_init(&tc, rate, flags, 0, s);
9611  if (ret < 0)
9612  return ret;
9613  av_dict_set(&st->metadata, "timecode",
9614  av_timecode_make_string(&tc, buf, value), 0);
9615  return 0;
9616 }
9617 
9619 {
9620  MOVStreamContext *sc = st->priv_data;
9621  FFStream *const sti = ffstream(st);
9622  char buf[AV_TIMECODE_STR_SIZE];
9623  int64_t cur_pos = avio_tell(sc->pb);
9624  int hh, mm, ss, ff, drop;
9625 
9626  if (!sti->nb_index_entries)
9627  return -1;
9628 
9629  avio_seek(sc->pb, sti->index_entries->pos, SEEK_SET);
9630  avio_skip(s->pb, 13);
9631  hh = avio_r8(s->pb);
9632  mm = avio_r8(s->pb);
9633  ss = avio_r8(s->pb);
9634  drop = avio_r8(s->pb);
9635  ff = avio_r8(s->pb);
9636  snprintf(buf, AV_TIMECODE_STR_SIZE, "%02d:%02d:%02d%c%02d",
9637  hh, mm, ss, drop ? ';' : ':', ff);
9638  av_dict_set(&st->metadata, "timecode", buf, 0);
9639 
9640  avio_seek(sc->pb, cur_pos, SEEK_SET);
9641  return 0;
9642 }
9643 
9645 {
9646  MOVStreamContext *sc = st->priv_data;
9647  FFStream *const sti = ffstream(st);
9648  int flags = 0;
9649  int64_t cur_pos = avio_tell(sc->pb);
9650  int64_t value;
9651  AVRational tc_rate = st->avg_frame_rate;
9652  int tmcd_nb_frames = sc->tmcd_nb_frames;
9653  int rounded_tc_rate;
9654 
9655  if (!sti->nb_index_entries)
9656  return -1;
9657 
9658  if (!tc_rate.num || !tc_rate.den || !tmcd_nb_frames)
9659  return -1;
9660 
9661  avio_seek(sc->pb, sti->index_entries->pos, SEEK_SET);
9662  value = avio_rb32(s->pb);
9663 
9664  if (sc->tmcd_flags & 0x0001) flags |= AV_TIMECODE_FLAG_DROPFRAME;
9665  if (sc->tmcd_flags & 0x0002) flags |= AV_TIMECODE_FLAG_24HOURSMAX;
9666  if (sc->tmcd_flags & 0x0004) flags |= AV_TIMECODE_FLAG_ALLOWNEGATIVE;
9667 
9668  /* Assume Counter flag is set to 1 in tmcd track (even though it is likely
9669  * not the case) and thus assume "frame number format" instead of QT one.
9670  * No sample with tmcd track can be found with a QT timecode at the moment,
9671  * despite what the tmcd track "suggests" (Counter flag set to 0 means QT
9672  * format). */
9673 
9674  /* 60 fps content have tmcd_nb_frames set to 30 but tc_rate set to 60, so
9675  * we multiply the frame number with the quotient.
9676  * See tickets #9492, #9710. */
9677  rounded_tc_rate = (tc_rate.num + tc_rate.den / 2LL) / tc_rate.den;
9678  /* Work around files where tmcd_nb_frames is rounded down from frame rate
9679  * instead of up. See ticket #5978. */
9680  if (tmcd_nb_frames == tc_rate.num / tc_rate.den &&
9681  s->strict_std_compliance < FF_COMPLIANCE_STRICT)
9682  tmcd_nb_frames = rounded_tc_rate;
9683  value = av_rescale(value, rounded_tc_rate, tmcd_nb_frames);
9684 
9686 
9687  avio_seek(sc->pb, cur_pos, SEEK_SET);
9688  return 0;
9689 }
9690 
9692  int i;
9693  if (!index || !*index) return;
9694  for (i = 0; i < (*index)->nb_encrypted_samples; i++) {
9695  av_encryption_info_free((*index)->encrypted_samples[i]);
9696  }
9697  av_freep(&(*index)->encrypted_samples);
9698  av_freep(&(*index)->auxiliary_info_sizes);
9699  av_freep(&(*index)->auxiliary_offsets);
9700  av_freep(index);
9701 }
9702 
9704 {
9705  MOVStreamContext *sc = st->priv_data;
9706 
9707  if (!sc || --sc->refcount) {
9708  st->priv_data = NULL;
9709  return;
9710  }
9711 
9712  av_freep(&sc->ctts_data);
9713  for (int i = 0; i < sc->drefs_count; i++) {
9714  av_freep(&sc->drefs[i].path);
9715  av_freep(&sc->drefs[i].dir);
9716  }
9717  av_freep(&sc->drefs);
9718 
9719  sc->drefs_count = 0;
9720 
9721  if (!sc->pb_is_copied)
9722  ff_format_io_close(s, &sc->pb);
9723 
9724  sc->pb = NULL;
9725  av_freep(&sc->chunk_offsets);
9726  av_freep(&sc->stsc_data);
9727  av_freep(&sc->sample_sizes);
9728  av_freep(&sc->keyframes);
9729  av_freep(&sc->stts_data);
9730  av_freep(&sc->sdtp_data);
9731  av_freep(&sc->stps_data);
9732  av_freep(&sc->elst_data);
9733  av_freep(&sc->rap_group);
9734  av_freep(&sc->sync_group);
9735  av_freep(&sc->sgpd_sync);
9736  av_freep(&sc->sample_offsets);
9737  av_freep(&sc->open_key_samples);
9738  av_freep(&sc->display_matrix);
9739  av_freep(&sc->index_ranges);
9740 
9741  if (sc->extradata)
9742  for (int i = 0; i < sc->stsd_count; i++)
9743  av_free(sc->extradata[i]);
9744  av_freep(&sc->extradata);
9745  av_freep(&sc->extradata_size);
9746 
9750 
9751  av_freep(&sc->stereo3d);
9752  av_freep(&sc->spherical);
9753  av_freep(&sc->mastering);
9754  av_freep(&sc->coll);
9755  av_freep(&sc->ambient);
9756 
9757 #if CONFIG_IAMFDEC
9758  if (sc->iamf)
9760 #endif
9761  av_freep(&sc->iamf);
9762 }
9763 
9765 {
9766  MOVContext *mov = s->priv_data;
9767  int i, j;
9768 
9769  for (i = 0; i < s->nb_streams; i++) {
9770  AVStream *st = s->streams[i];
9771 
9773  }
9774 
9775  av_freep(&mov->dv_demux);
9777  mov->dv_fctx = NULL;
9778 
9779  if (mov->meta_keys) {
9780  for (i = 1; i < mov->meta_keys_count; i++) {
9781  av_freep(&mov->meta_keys[i]);
9782  }
9783  av_freep(&mov->meta_keys);
9784  }
9785 
9786  av_freep(&mov->trex_data);
9787  av_freep(&mov->bitrates);
9788 
9789  for (i = 0; i < mov->frag_index.nb_items; i++) {
9791  for (j = 0; j < mov->frag_index.item[i].nb_stream_info; j++) {
9792  mov_free_encryption_index(&frag[j].encryption_index);
9793  }
9795  }
9796  av_freep(&mov->frag_index.item);
9797 
9798  av_freep(&mov->aes_decrypt);
9799  av_freep(&mov->chapter_tracks);
9800  for (i = 0; i < mov->nb_heif_item; i++) {
9801  if (!mov->heif_item[i])
9802  continue;
9803  av_freep(&mov->heif_item[i]->name);
9804  av_freep(&mov->heif_item[i]->icc_profile);
9805  av_freep(&mov->heif_item[i]);
9806  }
9807  av_freep(&mov->heif_item);
9808  for (i = 0; i < mov->nb_heif_grid; i++) {
9809  av_freep(&mov->heif_grid[i].tile_id_list);
9811  }
9812  av_freep(&mov->heif_grid);
9813 
9814  return 0;
9815 }
9816 
9817 static int tmcd_is_referenced(AVFormatContext *s, int tmcd_id)
9818 {
9819  int i;
9820 
9821  for (i = 0; i < s->nb_streams; i++) {
9822  AVStream *st = s->streams[i];
9823  MOVStreamContext *sc = st->priv_data;
9824 
9825  if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO &&
9826  sc->timecode_track == tmcd_id)
9827  return 1;
9828  }
9829  return 0;
9830 }
9831 
9832 /* look for a tmcd track not referenced by any video track, and export it globally */
9834 {
9835  int i;
9836 
9837  for (i = 0; i < s->nb_streams; i++) {
9838  AVStream *st = s->streams[i];
9839 
9840  if (st->codecpar->codec_tag == MKTAG('t','m','c','d') &&
9841  !tmcd_is_referenced(s, i + 1)) {
9842  AVDictionaryEntry *tcr = av_dict_get(st->metadata, "timecode", NULL, 0);
9843  if (tcr) {
9844  av_dict_set(&s->metadata, "timecode", tcr->value, 0);
9845  break;
9846  }
9847  }
9848  }
9849 }
9850 
9851 static int read_tfra(MOVContext *mov, AVIOContext *f)
9852 {
9853  int version, fieldlength, i, j;
9854  int64_t pos = avio_tell(f);
9855  uint32_t size = avio_rb32(f);
9856  unsigned track_id, item_count;
9857 
9858  if (avio_rb32(f) != MKBETAG('t', 'f', 'r', 'a')) {
9859  return 1;
9860  }
9861  av_log(mov->fc, AV_LOG_VERBOSE, "found tfra\n");
9862 
9863  version = avio_r8(f);
9864  avio_rb24(f);
9865  track_id = avio_rb32(f);
9866  fieldlength = avio_rb32(f);
9867  item_count = avio_rb32(f);
9868  for (i = 0; i < item_count; i++) {
9869  int64_t time, offset;
9870  int index;
9871  MOVFragmentStreamInfo * frag_stream_info;
9872 
9873  if (avio_feof(f)) {
9874  return AVERROR_INVALIDDATA;
9875  }
9876 
9877  if (version == 1) {
9878  time = avio_rb64(f);
9879  offset = avio_rb64(f);
9880  } else {
9881  time = avio_rb32(f);
9882  offset = avio_rb32(f);
9883  }
9884 
9885  // The first sample of each stream in a fragment is always a random
9886  // access sample. So it's entry in the tfra can be used as the
9887  // initial PTS of the fragment.
9888  index = update_frag_index(mov, offset);
9889  frag_stream_info = get_frag_stream_info(&mov->frag_index, index, track_id);
9890  if (frag_stream_info &&
9891  frag_stream_info->first_tfra_pts == AV_NOPTS_VALUE)
9892  frag_stream_info->first_tfra_pts = time;
9893 
9894  for (j = 0; j < ((fieldlength >> 4) & 3) + 1; j++)
9895  avio_r8(f);
9896  for (j = 0; j < ((fieldlength >> 2) & 3) + 1; j++)
9897  avio_r8(f);
9898  for (j = 0; j < ((fieldlength >> 0) & 3) + 1; j++)
9899  avio_r8(f);
9900  }
9901 
9902  avio_seek(f, pos + size, SEEK_SET);
9903  return 0;
9904 }
9905 
9907 {
9908  int64_t stream_size = avio_size(f);
9909  int64_t original_pos = avio_tell(f);
9910  int64_t seek_ret;
9911  int ret = -1;
9912  if ((seek_ret = avio_seek(f, stream_size - 4, SEEK_SET)) < 0) {
9913  ret = seek_ret;
9914  goto fail;
9915  }
9916  c->mfra_size = avio_rb32(f);
9917  c->have_read_mfra_size = 1;
9918  if (!c->mfra_size || c->mfra_size > stream_size) {
9919  av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (unreasonable size)\n");
9920  goto fail;
9921  }
9922  if ((seek_ret = avio_seek(f, -((int64_t) c->mfra_size), SEEK_CUR)) < 0) {
9923  ret = seek_ret;
9924  goto fail;
9925  }
9926  if (avio_rb32(f) != c->mfra_size) {
9927  av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (size mismatch)\n");
9928  goto fail;
9929  }
9930  if (avio_rb32(f) != MKBETAG('m', 'f', 'r', 'a')) {
9931  av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (tag mismatch)\n");
9932  goto fail;
9933  }
9934  av_log(c->fc, AV_LOG_VERBOSE, "stream has mfra\n");
9935  do {
9936  ret = read_tfra(c, f);
9937  if (ret < 0)
9938  goto fail;
9939  } while (!ret);
9940  ret = 0;
9941  c->frag_index.complete = 1;
9942 fail:
9943  seek_ret = avio_seek(f, original_pos, SEEK_SET);
9944  if (seek_ret < 0) {
9945  av_log(c->fc, AV_LOG_ERROR,
9946  "failed to seek back after looking for mfra\n");
9947  ret = seek_ret;
9948  }
9949  return ret;
9950 }
9951 
9952 static int set_icc_profile_from_item(AVPacketSideData **coded_side_data, int *nb_coded_side_data,
9953  const HEIFItem *item)
9954 {
9955  AVPacketSideData *sd = av_packet_side_data_new(coded_side_data, nb_coded_side_data,
9957  item->icc_profile_size, 0);
9958  if (!sd)
9959  return AVERROR(ENOMEM);
9960 
9961  memcpy(sd->data, item->icc_profile, item->icc_profile_size);
9962 
9963  return 0;
9964 }
9965 
9966 static int set_display_matrix_from_item(AVPacketSideData **coded_side_data, int *nb_coded_side_data,
9967  const HEIFItem *item)
9968 {
9969  int32_t *matrix;
9970  AVPacketSideData *sd = av_packet_side_data_new(coded_side_data,
9971  nb_coded_side_data,
9973  9 * sizeof(*matrix), 0);
9974  if (!sd)
9975  return AVERROR(ENOMEM);
9976 
9977  matrix = (int32_t*)sd->data;
9978  /* rotation is in the counter-clockwise direction whereas
9979  * av_display_rotation_set() expects its argument to be
9980  * oriented clockwise, so we need to negate it. */
9982  av_display_matrix_flip(matrix, item->hflip, item->vflip);
9983 
9984  return 0;
9985 }
9986 
9987 static int read_image_grid(AVFormatContext *s, const HEIFGrid *grid,
9988  AVStreamGroupTileGrid *tile_grid)
9989 {
9990  MOVContext *c = s->priv_data;
9991  const HEIFItem *item = grid->item;
9992  int64_t offset = 0, pos = avio_tell(s->pb);
9993  int x = 0, y = 0, i = 0;
9994  int tile_rows, tile_cols;
9995  int flags, size;
9996 
9997  if (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL)) {
9998  av_log(c->fc, AV_LOG_INFO, "grid box with non seekable input\n");
9999  return AVERROR_PATCHWELCOME;
10000  }
10001  if (item->is_idat_relative) {
10002  if (!c->idat_offset) {
10003  av_log(c->fc, AV_LOG_ERROR, "missing idat box required by the image grid\n");
10004  return AVERROR_INVALIDDATA;
10005  }
10006  offset = c->idat_offset;
10007  }
10008 
10009  avio_seek(s->pb, item->extent_offset + offset, SEEK_SET);
10010 
10011  avio_r8(s->pb); /* version */
10012  flags = avio_r8(s->pb);
10013 
10014  tile_rows = avio_r8(s->pb) + 1;
10015  tile_cols = avio_r8(s->pb) + 1;
10016  /* actual width and height of output image */
10017  tile_grid->width = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
10018  tile_grid->height = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
10019 
10020  /* ICC profile */
10021  if (item->icc_profile_size) {
10022  int ret = set_icc_profile_from_item(&tile_grid->coded_side_data,
10023  &tile_grid->nb_coded_side_data, item);
10024  if (ret < 0)
10025  return ret;
10026  }
10027  /* rotation */
10028  if (item->rotation || item->hflip || item->vflip) {
10030  &tile_grid->nb_coded_side_data, item);
10031  if (ret < 0)
10032  return ret;
10033  }
10034 
10035  av_log(c->fc, AV_LOG_TRACE, "grid: grid_rows %d grid_cols %d output_width %d output_height %d\n",
10036  tile_rows, tile_cols, tile_grid->width, tile_grid->height);
10037 
10038  avio_seek(s->pb, pos, SEEK_SET);
10039 
10040  size = tile_rows * tile_cols;
10041  tile_grid->nb_tiles = grid->nb_tiles;
10042 
10043  if (tile_grid->nb_tiles != size)
10044  return AVERROR_INVALIDDATA;
10045 
10046  for (int i = 0; i < tile_cols; i++)
10047  tile_grid->coded_width += grid->tile_item_list[i]->width;
10048  for (int i = 0; i < size; i += tile_cols)
10049  tile_grid->coded_height += grid->tile_item_list[i]->height;
10050 
10051  tile_grid->offsets = av_calloc(tile_grid->nb_tiles, sizeof(*tile_grid->offsets));
10052  if (!tile_grid->offsets)
10053  return AVERROR(ENOMEM);
10054 
10055  while (y < tile_grid->coded_height) {
10056  int left_col = i;
10057 
10058  while (x < tile_grid->coded_width) {
10059  if (i == tile_grid->nb_tiles)
10060  return AVERROR_INVALIDDATA;
10061 
10062  tile_grid->offsets[i].idx = i;
10063  tile_grid->offsets[i].horizontal = x;
10064  tile_grid->offsets[i].vertical = y;
10065 
10066  x += grid->tile_item_list[i++]->width;
10067  }
10068 
10069  if (x > tile_grid->coded_width) {
10070  av_log(c->fc, AV_LOG_ERROR, "Non uniform HEIF tiles\n");
10071  return AVERROR_INVALIDDATA;
10072  }
10073 
10074  x = 0;
10075  y += grid->tile_item_list[left_col]->height;
10076  }
10077 
10078  if (y > tile_grid->coded_height || i != tile_grid->nb_tiles) {
10079  av_log(c->fc, AV_LOG_ERROR, "Non uniform HEIF tiles\n");
10080  return AVERROR_INVALIDDATA;
10081  }
10082 
10083  return 0;
10084 }
10085 
10086 static int read_image_iovl(AVFormatContext *s, const HEIFGrid *grid,
10087  AVStreamGroupTileGrid *tile_grid)
10088 {
10089  MOVContext *c = s->priv_data;
10090  const HEIFItem *item = grid->item;
10091  uint16_t canvas_fill_value[4];
10092  int64_t offset = 0, pos = avio_tell(s->pb);
10093  int ret = 0, flags;
10094 
10095  if (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL)) {
10096  av_log(c->fc, AV_LOG_INFO, "iovl box with non seekable input\n");
10097  return AVERROR_PATCHWELCOME;
10098  }
10099  if (item->is_idat_relative) {
10100  if (!c->idat_offset) {
10101  av_log(c->fc, AV_LOG_ERROR, "missing idat box required by the image overlay\n");
10102  return AVERROR_INVALIDDATA;
10103  }
10104  offset = c->idat_offset;
10105  }
10106 
10107  avio_seek(s->pb, item->extent_offset + offset, SEEK_SET);
10108 
10109  avio_r8(s->pb); /* version */
10110  flags = avio_r8(s->pb);
10111 
10112  for (int i = 0; i < 4; i++)
10113  canvas_fill_value[i] = avio_rb16(s->pb);
10114  av_log(c->fc, AV_LOG_TRACE, "iovl: canvas_fill_value { %u, %u, %u, %u }\n",
10115  canvas_fill_value[0], canvas_fill_value[1],
10116  canvas_fill_value[2], canvas_fill_value[3]);
10117  for (int i = 0; i < 4; i++)
10118  tile_grid->background[i] = canvas_fill_value[i];
10119 
10120  /* actual width and height of output image */
10121  tile_grid->width =
10122  tile_grid->coded_width = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
10123  tile_grid->height =
10124  tile_grid->coded_height = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
10125 
10126  /* rotation */
10127  if (item->rotation || item->hflip || item->vflip) {
10129  &tile_grid->nb_coded_side_data, item);
10130  if (ret < 0)
10131  return ret;
10132  }
10133 
10134  /* ICC profile */
10135  if (item->icc_profile_size) {
10136  int ret = set_icc_profile_from_item(&tile_grid->coded_side_data,
10137  &tile_grid->nb_coded_side_data, item);
10138  if (ret < 0)
10139  return ret;
10140  }
10141 
10142  av_log(c->fc, AV_LOG_TRACE, "iovl: output_width %d, output_height %d\n",
10143  tile_grid->width, tile_grid->height);
10144 
10145  tile_grid->nb_tiles = grid->nb_tiles;
10146  tile_grid->offsets = av_malloc_array(tile_grid->nb_tiles, sizeof(*tile_grid->offsets));
10147  if (!tile_grid->offsets) {
10148  ret = AVERROR(ENOMEM);
10149  goto fail;
10150  }
10151 
10152  for (int i = 0; i < tile_grid->nb_tiles; i++) {
10153  tile_grid->offsets[i].idx = grid->tile_item_list[i]->st->index;
10154  tile_grid->offsets[i].horizontal = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
10155  tile_grid->offsets[i].vertical = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
10156  av_log(c->fc, AV_LOG_TRACE, "iovl: stream_idx[%d] %u, "
10157  "horizontal_offset[%d] %d, vertical_offset[%d] %d\n",
10158  i, tile_grid->offsets[i].idx,
10159  i, tile_grid->offsets[i].horizontal, i, tile_grid->offsets[i].vertical);
10160  }
10161 
10162 fail:
10163  avio_seek(s->pb, pos, SEEK_SET);
10164 
10165  return ret;
10166 }
10167 
10169 {
10170  MOVContext *mov = s->priv_data;
10171 
10172  for (int i = 0; i < mov->nb_heif_grid; i++) {
10174  AVStreamGroupTileGrid *tile_grid;
10175  const HEIFGrid *grid = &mov->heif_grid[i];
10176  int err, loop = 1;
10177 
10178  if (!stg)
10179  return AVERROR(ENOMEM);
10180 
10181  stg->id = grid->item->item_id;
10182  tile_grid = stg->params.tile_grid;
10183 
10184  for (int j = 0; j < grid->nb_tiles; j++) {
10185  int tile_id = grid->tile_id_list[j];
10186  int k;
10187 
10188  for (k = 0; k < mov->nb_heif_item; k++) {
10189  HEIFItem *item = mov->heif_item[k];
10190  AVStream *st = item->st;
10191 
10192  if (!item || item->item_id != tile_id)
10193  continue;
10194  if (!st) {
10195  av_log(s, AV_LOG_WARNING, "HEIF item id %d from grid id %d doesn't "
10196  "reference a stream\n",
10197  tile_id, grid->item->item_id);
10198  ff_remove_stream_group(s, stg);
10199  loop = 0;
10200  break;
10201  }
10202 
10203  grid->tile_item_list[j] = item;
10204 
10205  err = avformat_stream_group_add_stream(stg, st);
10206  if (err < 0 && err != AVERROR(EEXIST))
10207  return err;
10208 
10209  if (item->item_id != mov->primary_item_id)
10211  break;
10212  }
10213 
10214  if (k == mov->nb_heif_item) {
10215  av_assert0(loop);
10216  av_log(s, AV_LOG_WARNING, "HEIF item id %d referenced by grid id %d doesn't "
10217  "exist\n",
10218  tile_id, grid->item->item_id);
10219  ff_remove_stream_group(s, stg);
10220  loop = 0;
10221  }
10222  if (!loop)
10223  break;
10224  }
10225 
10226  if (!loop)
10227  continue;
10228 
10229  switch (grid->item->type) {
10230  case MKTAG('g','r','i','d'):
10231  err = read_image_grid(s, grid, tile_grid);
10232  break;
10233  case MKTAG('i','o','v','l'):
10234  err = read_image_iovl(s, grid, tile_grid);
10235  break;
10236  default:
10237  av_assert0(0);
10238  }
10239  if (err < 0)
10240  return err;
10241 
10242 
10243  if (grid->item->name)
10244  av_dict_set(&stg->metadata, "title", grid->item->name, 0);
10245  if (grid->item->item_id == mov->primary_item_id)
10247  }
10248 
10249  return 0;
10250 }
10251 
10253 {
10254  MOVContext *mov = s->priv_data;
10255  int err;
10256 
10257  for (int i = 0; i < mov->nb_heif_item; i++) {
10258  HEIFItem *item = mov->heif_item[i];
10259  MOVStreamContext *sc;
10260  AVStream *st;
10261  int64_t offset = 0;
10262 
10263  if (!item)
10264  continue;
10265  if (!item->st) {
10266  if (item->item_id == mov->thmb_item_id) {
10267  av_log(s, AV_LOG_ERROR, "HEIF thumbnail doesn't reference a stream\n");
10268  return AVERROR_INVALIDDATA;
10269  }
10270  continue;
10271  }
10272  if (item->is_idat_relative) {
10273  if (!mov->idat_offset) {
10274  av_log(s, AV_LOG_ERROR, "Missing idat box for item %d\n", item->item_id);
10275  return AVERROR_INVALIDDATA;
10276  }
10277  offset = mov->idat_offset;
10278  }
10279 
10280  st = item->st;
10281  sc = st->priv_data;
10282  st->codecpar->width = item->width;
10283  st->codecpar->height = item->height;
10284 
10285  if (sc->sample_count != 1 || sc->chunk_count != 1)
10286  return AVERROR_INVALIDDATA;
10287 
10288  sc->sample_sizes[0] = item->extent_length;
10289  sc->chunk_offsets[0] = item->extent_offset + offset;
10290 
10291  if (item->item_id == mov->primary_item_id)
10293 
10294  if (item->rotation || item->hflip || item->vflip) {
10296  &st->codecpar->nb_coded_side_data, item);
10297  if (err < 0)
10298  return err;
10299  }
10300 
10301  mov_build_index(mov, st);
10302  }
10303 
10304  if (mov->nb_heif_grid) {
10305  err = mov_parse_tiles(s);
10306  if (err < 0)
10307  return err;
10308  }
10309 
10310  return 0;
10311 }
10312 
10314  int first_index)
10315 {
10316  MOVStreamContext *sc = st->priv_data;
10317 
10318  if (sc->tref_id < 0)
10319  return NULL;
10320 
10321  for (int i = first_index; i < s->nb_streams; i++)
10322  if (s->streams[i]->id == sc->tref_id)
10323  return s->streams[i];
10324 
10325  return NULL;
10326 }
10327 
10329 {
10330  int err;
10331 
10332  for (int i = 0; i < s->nb_streams; i++) {
10333  AVStreamGroup *stg;
10334  AVStream *st = s->streams[i];
10335  AVStream *st_base;
10336  MOVStreamContext *sc = st->priv_data;
10337  int j = 0;
10338 
10339  /* Find an enhancement stream. */
10340  if (st->codecpar->codec_id != AV_CODEC_ID_LCEVC ||
10342  continue;
10343 
10345 
10347  if (!stg)
10348  return AVERROR(ENOMEM);
10349 
10350  stg->id = st->id;
10351  stg->params.lcevc->width = st->codecpar->width;
10352  stg->params.lcevc->height = st->codecpar->height;
10353  st->codecpar->width = 0;
10354  st->codecpar->height = 0;
10355 
10356  while (st_base = mov_find_reference_track(s, st, j)) {
10357  err = avformat_stream_group_add_stream(stg, st_base);
10358  if (err < 0)
10359  return err;
10360 
10361  j = st_base->index + 1;
10362  }
10363  if (!j) {
10364  av_log(s, AV_LOG_ERROR, "Failed to find base stream for enhancement stream\n");
10365  return AVERROR_INVALIDDATA;
10366  }
10367 
10368  err = avformat_stream_group_add_stream(stg, st);
10369  if (err < 0)
10370  return err;
10371 
10372  stg->params.lcevc->lcevc_index = stg->nb_streams - 1;
10373  }
10374 
10375  return 0;
10376 }
10377 
10379 {
10380  MOVContext *mov = s->priv_data;
10381  AVIOContext *pb = s->pb;
10382  int j, err;
10383  MOVAtom atom = { AV_RL32("root") };
10384  int i;
10385 
10386  if (mov->decryption_key_len != 0 && mov->decryption_key_len != AES_CTR_KEY_SIZE) {
10387  av_log(s, AV_LOG_ERROR, "Invalid decryption key len %d expected %d\n",
10389  return AVERROR(EINVAL);
10390  }
10391 
10392  mov->fc = s;
10393  mov->trak_index = -1;
10394  mov->thmb_item_id = -1;
10395  mov->primary_item_id = -1;
10396  mov->cur_item_id = -1;
10397  /* .mov and .mp4 aren't streamable anyway (only progressive download if moov is before mdat) */
10398  if (pb->seekable & AVIO_SEEKABLE_NORMAL)
10399  atom.size = avio_size(pb);
10400  else
10401  atom.size = INT64_MAX;
10402 
10403  /* check MOV header */
10404  do {
10405  if (mov->moov_retry)
10406  avio_seek(pb, 0, SEEK_SET);
10407  if ((err = mov_read_default(mov, pb, atom)) < 0) {
10408  av_log(s, AV_LOG_ERROR, "error reading header\n");
10409  return err;
10410  }
10411  } while ((pb->seekable & AVIO_SEEKABLE_NORMAL) &&
10412  !mov->found_moov && (!mov->found_iloc || !mov->found_iinf) && !mov->moov_retry++);
10413  if (!mov->found_moov && !mov->found_iloc && !mov->found_iinf) {
10414  av_log(s, AV_LOG_ERROR, "moov atom not found\n");
10415  return AVERROR_INVALIDDATA;
10416  }
10417  av_log(mov->fc, AV_LOG_TRACE, "on_parse_exit_offset=%"PRId64"\n", avio_tell(pb));
10418 
10419  if (mov->found_iloc && mov->found_iinf) {
10420  err = mov_parse_heif_items(s);
10421  if (err < 0)
10422  return err;
10423  }
10424  // prevent iloc and iinf boxes from being parsed while reading packets.
10425  // this is needed because an iinf box may have been parsed but ignored
10426  // for having old infe boxes which create no streams.
10427  mov->found_iloc = mov->found_iinf = 1;
10428 
10429  if (pb->seekable & AVIO_SEEKABLE_NORMAL) {
10430  if (mov->nb_chapter_tracks > 0 && !mov->ignore_chapters)
10432  for (i = 0; i < s->nb_streams; i++)
10433  if (s->streams[i]->codecpar->codec_tag == AV_RL32("tmcd")) {
10434  mov_read_timecode_track(s, s->streams[i]);
10435  } else if (s->streams[i]->codecpar->codec_tag == AV_RL32("rtmd")) {
10436  mov_read_rtmd_track(s, s->streams[i]);
10437  }
10438  }
10439 
10440  /* copy timecode metadata from tmcd tracks to the related video streams */
10441  for (i = 0; i < s->nb_streams; i++) {
10442  AVStream *st = s->streams[i];
10443  MOVStreamContext *sc = st->priv_data;
10444  if (sc->timecode_track > 0) {
10445  AVDictionaryEntry *tcr;
10446  int tmcd_st_id = -1;
10447 
10448  for (j = 0; j < s->nb_streams; j++) {
10449  MOVStreamContext *sc2 = s->streams[j]->priv_data;
10450  if (sc2->id == sc->timecode_track)
10451  tmcd_st_id = j;
10452  }
10453 
10454  if (tmcd_st_id < 0 || tmcd_st_id == i)
10455  continue;
10456  tcr = av_dict_get(s->streams[tmcd_st_id]->metadata, "timecode", NULL, 0);
10457  if (tcr)
10458  av_dict_set(&st->metadata, "timecode", tcr->value, 0);
10459  }
10460  }
10462 
10463  /* Create LCEVC stream groups. */
10464  err = mov_parse_lcevc_streams(s);
10465  if (err < 0)
10466  return err;
10467 
10468  for (i = 0; i < s->nb_streams; i++) {
10469  AVStream *st = s->streams[i];
10470  FFStream *const sti = ffstream(st);
10471  MOVStreamContext *sc = st->priv_data;
10472  fix_timescale(mov, sc);
10473  if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
10474  st->codecpar->codec_id == AV_CODEC_ID_AAC) {
10475  sti->skip_samples = sc->start_pad;
10476  }
10477  if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && sc->nb_frames_for_fps > 0 && sc->duration_for_fps > 0)
10479  sc->time_scale*(int64_t)sc->nb_frames_for_fps, sc->duration_for_fps, INT_MAX);
10481  if (st->codecpar->width <= 0 || st->codecpar->height <= 0) {
10482  st->codecpar->width = sc->width;
10483  st->codecpar->height = sc->height;
10484  }
10486  if ((err = mov_rewrite_dvd_sub_extradata(st)) < 0)
10487  return err;
10488  }
10489  }
10490  if (mov->handbrake_version &&
10491  mov->handbrake_version <= 1000000*0 + 1000*10 + 2 && // 0.10.2
10492  st->codecpar->codec_id == AV_CODEC_ID_MP3) {
10493  av_log(s, AV_LOG_VERBOSE, "Forcing full parsing for mp3 stream\n");
10495  }
10496  }
10497 
10498  if (mov->trex_data || mov->use_mfra_for > 0) {
10499  for (i = 0; i < s->nb_streams; i++) {
10500  AVStream *st = s->streams[i];
10501  MOVStreamContext *sc = st->priv_data;
10502  if (sc->duration_for_fps > 0) {
10503  /* Akin to sc->data_size * 8 * sc->time_scale / sc->duration_for_fps but accounting for overflows. */
10505  if (st->codecpar->bit_rate == INT64_MIN) {
10506  av_log(s, AV_LOG_WARNING, "Overflow during bit rate calculation %"PRId64" * 8 * %d\n",
10507  sc->data_size, sc->time_scale);
10508  st->codecpar->bit_rate = 0;
10509  if (s->error_recognition & AV_EF_EXPLODE)
10510  return AVERROR_INVALIDDATA;
10511  }
10512  }
10513  }
10514  }
10515 
10516  for (i = 0; i < mov->bitrates_count && i < s->nb_streams; i++) {
10517  if (mov->bitrates[i]) {
10518  s->streams[i]->codecpar->bit_rate = mov->bitrates[i];
10519  }
10520  }
10521 
10523 
10524  for (i = 0; i < s->nb_streams; i++) {
10525  AVStream *st = s->streams[i];
10526  MOVStreamContext *sc = st->priv_data;
10527 
10528  switch (st->codecpar->codec_type) {
10529  case AVMEDIA_TYPE_AUDIO:
10530  err = ff_replaygain_export(st, s->metadata);
10531  if (err < 0)
10532  return err;
10533  break;
10534  case AVMEDIA_TYPE_VIDEO:
10535  if (sc->display_matrix) {
10538  (uint8_t*)sc->display_matrix, sizeof(int32_t) * 9, 0))
10539  return AVERROR(ENOMEM);
10540 
10541  sc->display_matrix = NULL;
10542  }
10543  if (sc->stereo3d) {
10546  (uint8_t *)sc->stereo3d, sc->stereo3d_size, 0))
10547  return AVERROR(ENOMEM);
10548 
10549  sc->stereo3d = NULL;
10550  }
10551  if (sc->spherical) {
10554  (uint8_t *)sc->spherical, sc->spherical_size, 0))
10555  return AVERROR(ENOMEM);
10556 
10557  sc->spherical = NULL;
10558  }
10559  if (sc->mastering) {
10562  (uint8_t *)sc->mastering, sc->mastering_size, 0))
10563  return AVERROR(ENOMEM);
10564 
10565  sc->mastering = NULL;
10566  }
10567  if (sc->coll) {
10570  (uint8_t *)sc->coll, sc->coll_size, 0))
10571  return AVERROR(ENOMEM);
10572 
10573  sc->coll = NULL;
10574  }
10575  if (sc->ambient) {
10578  (uint8_t *) sc->ambient, sc->ambient_size, 0))
10579  return AVERROR(ENOMEM);
10580 
10581  sc->ambient = NULL;
10582  }
10583  break;
10584  }
10585  }
10587 
10588  for (i = 0; i < mov->frag_index.nb_items; i++)
10589  if (mov->frag_index.item[i].moof_offset <= mov->fragment.moof_offset)
10590  mov->frag_index.item[i].headers_read = 1;
10591 
10592  return 0;
10593 }
10594 
10596 {
10598  int64_t best_dts = INT64_MAX;
10599  int i;
10600  MOVContext *mov = s->priv_data;
10601  int no_interleave = !mov->interleaved_read || !(s->pb->seekable & AVIO_SEEKABLE_NORMAL);
10602  for (i = 0; i < s->nb_streams; i++) {
10603  AVStream *avst = s->streams[i];
10604  FFStream *const avsti = ffstream(avst);
10605  MOVStreamContext *msc = avst->priv_data;
10606  if (msc->pb && msc->current_sample < avsti->nb_index_entries) {
10607  AVIndexEntry *current_sample = &avsti->index_entries[msc->current_sample];
10608  int64_t dts = av_rescale(current_sample->timestamp, AV_TIME_BASE, msc->time_scale);
10609  uint64_t dtsdiff = best_dts > dts ? best_dts - (uint64_t)dts : ((uint64_t)dts - best_dts);
10610  av_log(s, AV_LOG_TRACE, "stream %d, sample %d, dts %"PRId64"\n", i, msc->current_sample, dts);
10611  if (!sample || (no_interleave && current_sample->pos < sample->pos) ||
10612  ((s->pb->seekable & AVIO_SEEKABLE_NORMAL) &&
10613  ((msc->pb != s->pb && dts < best_dts) || (msc->pb == s->pb && dts != AV_NOPTS_VALUE &&
10614  ((dtsdiff <= AV_TIME_BASE && current_sample->pos < sample->pos) ||
10615  (dtsdiff > AV_TIME_BASE && dts < best_dts)))))) {
10616  sample = current_sample;
10617  best_dts = dts;
10618  *st = avst;
10619  }
10620  }
10621  }
10622  return sample;
10623 }
10624 
10625 static int should_retry(AVIOContext *pb, int error_code) {
10626  if (error_code == AVERROR_EOF || avio_feof(pb))
10627  return 0;
10628 
10629  return 1;
10630 }
10631 
10632 static int mov_switch_root(AVFormatContext *s, int64_t target, int index)
10633 {
10634  int ret;
10635  MOVContext *mov = s->priv_data;
10636 
10637  if (index >= 0 && index < mov->frag_index.nb_items)
10638  target = mov->frag_index.item[index].moof_offset;
10639  if (target >= 0 && avio_seek(s->pb, target, SEEK_SET) != target) {
10640  av_log(mov->fc, AV_LOG_ERROR, "root atom offset 0x%"PRIx64": partial file\n", target);
10641  return AVERROR_INVALIDDATA;
10642  }
10643 
10644  mov->next_root_atom = 0;
10645  if ((index < 0 && target >= 0) || index >= mov->frag_index.nb_items)
10646  index = search_frag_moof_offset(&mov->frag_index, target);
10647  if (index >= 0 && index < mov->frag_index.nb_items &&
10648  mov->frag_index.item[index].moof_offset == target) {
10649  if (index + 1 < mov->frag_index.nb_items)
10650  mov->next_root_atom = mov->frag_index.item[index + 1].moof_offset;
10651  if (mov->frag_index.item[index].headers_read)
10652  return 0;
10653  mov->frag_index.item[index].headers_read = 1;
10654  }
10655 
10656  mov->found_mdat = 0;
10657 
10658  ret = mov_read_default(mov, s->pb, (MOVAtom){ AV_RL32("root"), INT64_MAX });
10659  if (ret < 0)
10660  return ret;
10661  if (avio_feof(s->pb))
10662  return AVERROR_EOF;
10663  av_log(s, AV_LOG_TRACE, "read fragments, offset 0x%"PRIx64"\n", avio_tell(s->pb));
10664 
10665  return 1;
10666 }
10667 
10669 {
10670  MOVStreamContext *sc = st->priv_data;
10671  uint8_t *side, *extradata;
10672  int extradata_size;
10673 
10674  /* Save the current index. */
10675  sc->last_stsd_index = sc->stsc_data[sc->stsc_index].id - 1;
10676 
10677  /* Notify the decoder that extradata changed. */
10678  extradata_size = sc->extradata_size[sc->last_stsd_index];
10679  extradata = sc->extradata[sc->last_stsd_index];
10680  if (st->discard != AVDISCARD_ALL && extradata_size > 0 && extradata) {
10683  extradata_size);
10684  if (!side)
10685  return AVERROR(ENOMEM);
10686  memcpy(side, extradata, extradata_size);
10687  }
10688 
10689  return 0;
10690 }
10691 
10693 {
10694  int new_size, ret;
10695 
10696  if (size <= 8)
10697  return AVERROR_INVALIDDATA;
10698  new_size = ((size - 8) / 2) * 3;
10699  ret = av_new_packet(pkt, new_size);
10700  if (ret < 0)
10701  return ret;
10702 
10703  avio_skip(pb, 8);
10704  for (int j = 0; j < new_size; j += 3) {
10705  pkt->data[j] = 0xFC;
10706  pkt->data[j+1] = avio_r8(pb);
10707  pkt->data[j+2] = avio_r8(pb);
10708  }
10709 
10710  return 0;
10711 }
10712 
10714  int64_t current_index, AVPacket *pkt)
10715 {
10716  MOVStreamContext *sc = st->priv_data;
10717 
10718  pkt->stream_index = sc->ffindex;
10719  pkt->dts = sample->timestamp;
10720  if (sample->flags & AVINDEX_DISCARD_FRAME) {
10722  }
10723  if (sc->ctts_data && sc->ctts_index < sc->ctts_count) {
10725  /* update ctts context */
10726  sc->ctts_sample++;
10727  if (sc->ctts_index < sc->ctts_count &&
10728  sc->ctts_data[sc->ctts_index].count == sc->ctts_sample) {
10729  sc->ctts_index++;
10730  sc->ctts_sample = 0;
10731  }
10732  } else {
10733  int64_t next_dts = (sc->current_sample < ffstream(st)->nb_index_entries) ?
10735 
10736  if (next_dts >= pkt->dts)
10737  pkt->duration = next_dts - pkt->dts;
10738  pkt->pts = pkt->dts;
10739  }
10740 
10741  if (sc->sdtp_data && sc->current_sample <= sc->sdtp_count) {
10742  uint8_t sample_flags = sc->sdtp_data[sc->current_sample - 1];
10743  uint8_t sample_is_depended_on = (sample_flags >> 2) & 0x3;
10744  pkt->flags |= sample_is_depended_on == MOV_SAMPLE_DEPENDENCY_NO ? AV_PKT_FLAG_DISPOSABLE : 0;
10745  }
10746  pkt->flags |= sample->flags & AVINDEX_KEYFRAME ? AV_PKT_FLAG_KEY : 0;
10747  pkt->pos = sample->pos;
10748 
10749  /* Multiple stsd handling. */
10750  if (sc->stsc_data) {
10751  if (sc->stsc_data[sc->stsc_index].id > 0 &&
10752  sc->stsc_data[sc->stsc_index].id - 1 < sc->stsd_count &&
10753  sc->stsc_data[sc->stsc_index].id - 1 != sc->last_stsd_index) {
10754  int ret = mov_change_extradata(st, pkt);
10755  if (ret < 0)
10756  return ret;
10757  }
10758 
10759  /* Update the stsc index for the next sample */
10760  sc->stsc_sample++;
10761  if (mov_stsc_index_valid(sc->stsc_index, sc->stsc_count) &&
10762  mov_get_stsc_samples(sc, sc->stsc_index) == sc->stsc_sample) {
10763  sc->stsc_index++;
10764  sc->stsc_sample = 0;
10765  }
10766  }
10767 
10768  return 0;
10769 }
10770 
10772 {
10773  MOVContext *mov = s->priv_data;
10774  MOVStreamContext *sc;
10776  AVStream *st = NULL;
10777  FFStream *avsti = NULL;
10778  int64_t current_index;
10779  int ret;
10780  int i;
10781  mov->fc = s;
10782  retry:
10783  if (s->pb->pos == 0) {
10784 
10785  // Discard current fragment index
10786  if (mov->frag_index.allocated_size > 0) {
10787  av_freep(&mov->frag_index.item);
10788  mov->frag_index.nb_items = 0;
10789  mov->frag_index.allocated_size = 0;
10790  mov->frag_index.current = -1;
10791  mov->frag_index.complete = 0;
10792  }
10793 
10794  for (i = 0; i < s->nb_streams; i++) {
10795  AVStream *avst = s->streams[i];
10796  MOVStreamContext *msc = avst->priv_data;
10797 
10798  // Clear current sample
10799  mov_current_sample_set(msc, 0);
10800  msc->ctts_index = 0;
10801 
10802  // Discard current index entries
10803  avsti = ffstream(avst);
10804  if (avsti->index_entries_allocated_size > 0) {
10805  av_freep(&avsti->index_entries);
10806  avsti->index_entries_allocated_size = 0;
10807  avsti->nb_index_entries = 0;
10808  }
10809  }
10810 
10811  if ((ret = mov_switch_root(s, -1, -1)) < 0)
10812  return ret;
10813  }
10814  sample = mov_find_next_sample(s, &st);
10815  if (!sample || (mov->next_root_atom && sample->pos > mov->next_root_atom)) {
10816  if (!mov->next_root_atom)
10817  return AVERROR_EOF;
10818  if ((ret = mov_switch_root(s, mov->next_root_atom, -1)) < 0)
10819  return ret;
10820  goto retry;
10821  }
10822  sc = st->priv_data;
10823  /* must be done just before reading, to avoid infinite loop on sample */
10824  current_index = sc->current_index;
10826 
10827  if (mov->next_root_atom) {
10828  sample->pos = FFMIN(sample->pos, mov->next_root_atom);
10829  sample->size = FFMIN(sample->size, (mov->next_root_atom - sample->pos));
10830  }
10831 
10832  if (st->discard != AVDISCARD_ALL) {
10833  int64_t ret64 = avio_seek(sc->pb, sample->pos, SEEK_SET);
10834  if (ret64 != sample->pos) {
10835  av_log(mov->fc, AV_LOG_ERROR, "stream %d, offset 0x%"PRIx64": partial file\n",
10836  sc->ffindex, sample->pos);
10837  if (should_retry(sc->pb, ret64)) {
10839  } else if (ret64 < 0) {
10840  return (int)ret64;
10841  }
10842  return AVERROR_INVALIDDATA;
10843  }
10844 
10845  if (st->discard == AVDISCARD_NONKEY && !(sample->flags & AVINDEX_KEYFRAME)) {
10846  av_log(mov->fc, AV_LOG_DEBUG, "Nonkey frame from stream %d discarded due to AVDISCARD_NONKEY\n", sc->ffindex);
10847  goto retry;
10848  }
10849 
10850  if (st->codecpar->codec_id == AV_CODEC_ID_EIA_608 && sample->size > 8)
10851  ret = get_eia608_packet(sc->pb, pkt, sample->size);
10852 #if CONFIG_IAMFDEC
10853  else if (sc->iamf) {
10854  int64_t pts, dts, pos, duration;
10855  int flags, size = sample->size;
10856  ret = mov_finalize_packet(s, st, sample, current_index, pkt);
10857  pts = pkt->pts; dts = pkt->dts;
10858  pos = pkt->pos; flags = pkt->flags;
10859  duration = pkt->duration;
10860  while (!ret && size > 0) {
10861  ret = ff_iamf_read_packet(s, sc->iamf, sc->pb, size, pkt);
10862  if (ret < 0) {
10863  if (should_retry(sc->pb, ret))
10865  return ret;
10866  }
10867  size -= ret;
10868  pkt->pts = pts; pkt->dts = dts;
10869  pkt->pos = pos; pkt->flags |= flags;
10870  pkt->duration = duration;
10871  ret = ff_buffer_packet(s, pkt);
10872  }
10873  if (!ret)
10874  return FFERROR_REDO;
10875  }
10876 #endif
10877  else
10878  ret = av_get_packet(sc->pb, pkt, sample->size);
10879  if (ret < 0) {
10880  if (should_retry(sc->pb, ret)) {
10882  }
10883  return ret;
10884  }
10885 #if CONFIG_DV_DEMUXER
10886  if (mov->dv_demux && sc->dv_audio_container) {
10889  if (ret < 0)
10890  return ret;
10892  if (ret < 0)
10893  return ret;
10894  }
10895 #endif
10896  if (sc->has_palette) {
10897  uint8_t *pal;
10898 
10900  if (!pal) {
10901  av_log(mov->fc, AV_LOG_ERROR, "Cannot append palette to packet\n");
10902  } else {
10903  memcpy(pal, sc->palette, AVPALETTE_SIZE);
10904  sc->has_palette = 0;
10905  }
10906  }
10907  if (st->codecpar->codec_id == AV_CODEC_ID_MP3 && !ffstream(st)->need_parsing && pkt->size > 4) {
10908  if (ff_mpa_check_header(AV_RB32(pkt->data)) < 0)
10910  }
10911  }
10912 
10913  ret = mov_finalize_packet(s, st, sample, current_index, pkt);
10914  if (ret < 0)
10915  return ret;
10916 
10917  if (st->discard == AVDISCARD_ALL)
10918  goto retry;
10919 
10920  if (mov->aax_mode)
10921  aax_filter(pkt->data, pkt->size, mov);
10922 
10923  ret = cenc_filter(mov, st, sc, pkt, current_index);
10924  if (ret < 0) {
10925  return ret;
10926  }
10927 
10928  return 0;
10929 }
10930 
10932 {
10933  MOVContext *mov = s->priv_data;
10934  int index;
10935 
10936  if (!mov->frag_index.complete)
10937  return 0;
10938 
10939  index = search_frag_timestamp(s, &mov->frag_index, st, timestamp);
10940  if (index < 0)
10941  index = 0;
10942  if (!mov->frag_index.item[index].headers_read)
10943  return mov_switch_root(s, -1, index);
10944  if (index + 1 < mov->frag_index.nb_items)
10945  mov->next_root_atom = mov->frag_index.item[index + 1].moof_offset;
10946 
10947  return 0;
10948 }
10949 
10950 static int is_open_key_sample(const MOVStreamContext *sc, int sample)
10951 {
10952  // TODO: a bisect search would scale much better
10953  for (int i = 0; i < sc->open_key_samples_count; i++) {
10954  const int oks = sc->open_key_samples[i];
10955  if (oks == sample)
10956  return 1;
10957  if (oks > sample) /* list is monotically increasing so we can stop early */
10958  break;
10959  }
10960  return 0;
10961 }
10962 
10963 /*
10964  * Some key sample may be key frames but not IDR frames, so a random access to
10965  * them may not be allowed.
10966  */
10967 static int can_seek_to_key_sample(AVStream *st, int sample, int64_t requested_pts)
10968 {
10969  MOVStreamContext *sc = st->priv_data;
10970  FFStream *const sti = ffstream(st);
10971  int64_t key_sample_dts, key_sample_pts;
10972 
10973  if (st->codecpar->codec_id != AV_CODEC_ID_HEVC)
10974  return 1;
10975 
10976  if (sample >= sc->sample_offsets_count)
10977  return 1;
10978 
10979  key_sample_dts = sti->index_entries[sample].timestamp;
10980  key_sample_pts = key_sample_dts + sc->sample_offsets[sample] + sc->dts_shift;
10981 
10982  /*
10983  * If the sample needs to be presented before an open key sample, they may
10984  * not be decodable properly, even though they come after in decoding
10985  * order.
10986  */
10987  if (is_open_key_sample(sc, sample) && key_sample_pts > requested_pts)
10988  return 0;
10989 
10990  return 1;
10991 }
10992 
10993 static int mov_seek_stream(AVFormatContext *s, AVStream *st, int64_t timestamp, int flags)
10994 {
10995  MOVStreamContext *sc = st->priv_data;
10996  FFStream *const sti = ffstream(st);
10997  int sample, time_sample, ret, next_ts, requested_sample;
10998  unsigned int i;
10999 
11000  // Here we consider timestamp to be PTS, hence try to offset it so that we
11001  // can search over the DTS timeline.
11002  timestamp -= (sc->min_corrected_pts + sc->dts_shift);
11003 
11004  ret = mov_seek_fragment(s, st, timestamp);
11005  if (ret < 0)
11006  return ret;
11007 
11008  for (;;) {
11009  sample = av_index_search_timestamp(st, timestamp, flags);
11010  av_log(s, AV_LOG_TRACE, "stream %d, timestamp %"PRId64", sample %d\n", st->index, timestamp, sample);
11011  if (sample < 0 && sti->nb_index_entries && timestamp < sti->index_entries[0].timestamp)
11012  sample = 0;
11013  if (sample < 0) /* not sure what to do */
11014  return AVERROR_INVALIDDATA;
11015 
11016  if (!sample || can_seek_to_key_sample(st, sample, timestamp))
11017  break;
11018 
11019  next_ts = timestamp - FFMAX(sc->min_sample_duration, 1);
11020  requested_sample = av_index_search_timestamp(st, next_ts, flags);
11021 
11022  // If we've reached a different sample trying to find a good pts to
11023  // seek to, give up searching because we'll end up seeking back to
11024  // sample 0 on every seek.
11025  if (sample != requested_sample && !can_seek_to_key_sample(st, requested_sample, next_ts))
11026  break;
11027 
11028  timestamp = next_ts;
11029  }
11030 
11032  av_log(s, AV_LOG_TRACE, "stream %d, found sample %d\n", st->index, sc->current_sample);
11033  /* adjust ctts index */
11034  if (sc->ctts_data) {
11035  time_sample = 0;
11036  for (i = 0; i < sc->ctts_count; i++) {
11037  int next = time_sample + sc->ctts_data[i].count;
11038  if (next > sc->current_sample) {
11039  sc->ctts_index = i;
11040  sc->ctts_sample = sc->current_sample - time_sample;
11041  break;
11042  }
11043  time_sample = next;
11044  }
11045  }
11046 
11047  /* adjust stsd index */
11048  if (sc->chunk_count) {
11049  time_sample = 0;
11050  for (i = 0; i < sc->stsc_count; i++) {
11051  int64_t next = time_sample + mov_get_stsc_samples(sc, i);
11052  if (next > sc->current_sample) {
11053  sc->stsc_index = i;
11054  sc->stsc_sample = sc->current_sample - time_sample;
11055  break;
11056  }
11057  av_assert0(next == (int)next);
11058  time_sample = next;
11059  }
11060  }
11061 
11062  return sample;
11063 }
11064 
11066 {
11067  MOVStreamContext *sc = st->priv_data;
11068  FFStream *const sti = ffstream(st);
11069  int64_t first_ts = sti->index_entries[0].timestamp;
11071  int64_t off;
11072 
11074  return 0;
11075 
11076  /* compute skip samples according to stream start_pad, seek ts and first ts */
11077  off = av_rescale_q(ts - first_ts, st->time_base,
11078  (AVRational){1, st->codecpar->sample_rate});
11079  return FFMAX(sc->start_pad - off, 0);
11080 }
11081 
11082 static int mov_read_seek(AVFormatContext *s, int stream_index, int64_t sample_time, int flags)
11083 {
11084  MOVContext *mc = s->priv_data;
11085  AVStream *st;
11086  FFStream *sti;
11087  int sample;
11088  int i;
11089 
11090  if (stream_index >= s->nb_streams)
11091  return AVERROR_INVALIDDATA;
11092 
11093  st = s->streams[stream_index];
11094  sti = ffstream(st);
11095  sample = mov_seek_stream(s, st, sample_time, flags);
11096  if (sample < 0)
11097  return sample;
11098 
11099  if (mc->seek_individually) {
11100  /* adjust seek timestamp to found sample timestamp */
11101  int64_t seek_timestamp = sti->index_entries[sample].timestamp;
11103 
11104  for (i = 0; i < s->nb_streams; i++) {
11105  AVStream *const st = s->streams[i];
11106  FFStream *const sti = ffstream(st);
11107  int64_t timestamp;
11108 
11109  if (stream_index == i)
11110  continue;
11111 
11112  timestamp = av_rescale_q(seek_timestamp, s->streams[stream_index]->time_base, st->time_base);
11113  sample = mov_seek_stream(s, st, timestamp, flags);
11114  if (sample >= 0)
11116  }
11117  } else {
11118  for (i = 0; i < s->nb_streams; i++) {
11119  MOVStreamContext *sc;
11120  st = s->streams[i];
11121  sc = st->priv_data;
11122  mov_current_sample_set(sc, 0);
11123  }
11124  while (1) {
11125  MOVStreamContext *sc;
11127  if (!entry)
11128  return AVERROR_INVALIDDATA;
11129  sc = st->priv_data;
11130  if (sc->ffindex == stream_index && sc->current_sample == sample)
11131  break;
11133  }
11134  }
11135  return 0;
11136 }
11137 
11138 #define OFFSET(x) offsetof(MOVContext, x)
11139 #define FLAGS AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM
11140 static const AVOption mov_options[] = {
11141  {"use_absolute_path",
11142  "allow using absolute path when opening alias, this is a possible security issue",
11143  OFFSET(use_absolute_path), AV_OPT_TYPE_BOOL, {.i64 = 0},
11144  0, 1, FLAGS},
11145  {"seek_streams_individually",
11146  "Seek each stream individually to the closest point",
11147  OFFSET(seek_individually), AV_OPT_TYPE_BOOL, { .i64 = 1 },
11148  0, 1, FLAGS},
11149  {"ignore_editlist", "Ignore the edit list atom.", OFFSET(ignore_editlist), AV_OPT_TYPE_BOOL, {.i64 = 0},
11150  0, 1, FLAGS},
11151  {"advanced_editlist",
11152  "Modify the AVIndex according to the editlists. Use this option to decode in the order specified by the edits.",
11153  OFFSET(advanced_editlist), AV_OPT_TYPE_BOOL, {.i64 = 1},
11154  0, 1, FLAGS},
11155  {"ignore_chapters", "", OFFSET(ignore_chapters), AV_OPT_TYPE_BOOL, {.i64 = 0},
11156  0, 1, FLAGS},
11157  {"use_mfra_for",
11158  "use mfra for fragment timestamps",
11159  OFFSET(use_mfra_for), AV_OPT_TYPE_INT, {.i64 = FF_MOV_FLAG_MFRA_AUTO},
11161  .unit = "use_mfra_for"},
11162  {"auto", "auto", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_AUTO}, 0, 0,
11163  FLAGS, .unit = "use_mfra_for" },
11164  {"dts", "dts", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_DTS}, 0, 0,
11165  FLAGS, .unit = "use_mfra_for" },
11166  {"pts", "pts", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_PTS}, 0, 0,
11167  FLAGS, .unit = "use_mfra_for" },
11168  {"use_tfdt", "use tfdt for fragment timestamps", OFFSET(use_tfdt), AV_OPT_TYPE_BOOL, {.i64 = 1},
11169  0, 1, FLAGS},
11170  { "export_all", "Export unrecognized metadata entries", OFFSET(export_all),
11171  AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = FLAGS },
11172  { "export_xmp", "Export full XMP metadata", OFFSET(export_xmp),
11173  AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = FLAGS },
11174  { "activation_bytes", "Secret bytes for Audible AAX files", OFFSET(activation_bytes),
11176  { "audible_key", "AES-128 Key for Audible AAXC files", OFFSET(audible_key),
11178  { "audible_iv", "AES-128 IV for Audible AAXC files", OFFSET(audible_iv),
11180  { "audible_fixed_key", // extracted from libAAX_SDK.so and AAXSDKWin.dll files!
11181  "Fixed key used for handling Audible AAX files", OFFSET(audible_fixed_key),
11182  AV_OPT_TYPE_BINARY, {.str="77214d4b196a87cd520045fd20a51d67"},
11183  .flags = AV_OPT_FLAG_DECODING_PARAM },
11184  { "decryption_key", "The media decryption key (hex)", OFFSET(decryption_key), AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM },
11185  { "enable_drefs", "Enable external track support.", OFFSET(enable_drefs), AV_OPT_TYPE_BOOL,
11186  {.i64 = 0}, 0, 1, FLAGS },
11187  { "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 },
11188  { "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 },
11189 
11190  { NULL },
11191 };
11192 
11193 static const AVClass mov_class = {
11194  .class_name = "mov,mp4,m4a,3gp,3g2,mj2",
11195  .item_name = av_default_item_name,
11196  .option = mov_options,
11197  .version = LIBAVUTIL_VERSION_INT,
11198 };
11199 
11201  .p.name = "mov,mp4,m4a,3gp,3g2,mj2",
11202  .p.long_name = NULL_IF_CONFIG_SMALL("QuickTime / MOV"),
11203  .p.priv_class = &mov_class,
11204  .p.extensions = "mov,mp4,m4a,3gp,3g2,mj2,psp,m4b,ism,ismv,isma,f4v,avif,heic,heif",
11206  .priv_data_size = sizeof(MOVContext),
11207  .flags_internal = FF_INFMT_FLAG_INIT_CLEANUP,
11208  .read_probe = mov_probe,
11213 };
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:181
item_name
item_name
Definition: libkvazaar.c:319
AV_CODEC_ID_PCM_S16LE
@ AV_CODEC_ID_PCM_S16LE
Definition: codec_id.h:334
AVChannelLayout::u
union AVChannelLayout::@427 u
Details about which channels are present in this layout.
mov_read_chpl
static int mov_read_chpl(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:593
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:7200
mov_read_meta
static int mov_read_meta(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5419
AV_CODEC_ID_EIA_608
@ AV_CODEC_ID_EIA_608
Definition: codec_id.h:566
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:429
MOVContext::found_iloc
int found_iloc
'iloc' atom has been found
Definition: isom.h:308
AV_CODEC_ID_MACE6
@ AV_CODEC_ID_MACE6
Definition: codec_id.h:456
MOVFragmentStreamInfo::first_tfra_pts
int64_t first_tfra_pts
Definition: isom.h:136
AVStreamGroup::params
union AVStreamGroup::@365 params
Group type-specific parameters.
ff_rfps_add_frame
int ff_rfps_add_frame(AVFormatContext *ic, AVStream *st, int64_t ts)
add frame for rfps calculation.
Definition: demux.c:2295
read_image_iovl
static int read_image_iovl(AVFormatContext *s, const HEIFGrid *grid, AVStreamGroupTileGrid *tile_grid)
Definition: mov.c:10086
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:9011
AVMEDIA_TYPE_SUBTITLE
@ AVMEDIA_TYPE_SUBTITLE
Definition: avutil.h:204
AVIAMFSubmix::elements
AVIAMFSubmixElement ** elements
Array of submix elements.
Definition: iamf.h:565
skip_bits_long
static void skip_bits_long(GetBitContext *s, int n)
Skips the specified number of bits.
Definition: get_bits.h:278
AV_LOG_WARNING
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:215
AV_BPRINT_SIZE_UNLIMITED
#define AV_BPRINT_SIZE_UNLIMITED
MOV_TFHD_DEFAULT_FLAGS
#define MOV_TFHD_DEFAULT_FLAGS
Definition: isom.h:388
PUT_UTF8
#define PUT_UTF8(val, tmp, PUT_BYTE)
Definition: common.h:541
AV_TIMECODE_STR_SIZE
#define AV_TIMECODE_STR_SIZE
Definition: timecode.h:33
av_aes_init
int av_aes_init(AVAES *a, const uint8_t *key, int key_bits, int decrypt)
Initialize an AVAES context.
Definition: aes.c:201
AV_CODEC_ID_PCM_F32BE
@ AV_CODEC_ID_PCM_F32BE
Definition: codec_id.h:354
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:212
MOVStreamContext::audio_cid
int16_t audio_cid
stsd audio compression id
Definition: isom.h:211
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:379
AVCodecParameters::extradata
uint8_t * extradata
Extra binary data needed for initializing the decoder, codec-dependent.
Definition: codec_par.h:69
mov_read_dops
static int mov_read_dops(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:8267
can_seek_to_key_sample
static int can_seek_to_key_sample(AVStream *st, int sample, int64_t requested_pts)
Definition: mov.c:10967
AV_CODEC_ID_ADPCM_IMA_QT
@ AV_CODEC_ID_ADPCM_IMA_QT
Definition: codec_id.h:373
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:1153
AV_CODEC_ID_AC3
@ AV_CODEC_ID_AC3
Definition: codec_id.h:449
HEIFItem::name
char * name
Definition: isom.h:280
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:233
MOVStreamContext::height
int height
tkhd height
Definition: isom.h:219
MOVContext::moov_retry
int moov_retry
Definition: isom.h:336
MOV_TRUN_SAMPLE_FLAGS
#define MOV_TRUN_SAMPLE_FLAGS
Definition: isom.h:396
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:324
mix
static int mix(int c0, int c1)
Definition: 4xm.c:716
MOVStreamContext::last_stsd_index
int last_stsd_index
Definition: isom.h:248
ff_ac3_channel_layout_tab
const uint16_t ff_ac3_channel_layout_tab[8]
Map audio coding mode (acmod) to channel layout mask.
Definition: ac3_channel_layout_tab.h:31
r
const char * r
Definition: vf_curves.c:127
AVERROR
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later. That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another. Frame references ownership and permissions
opt.h
MOV_TKHD_FLAG_ENABLED
#define MOV_TKHD_FLAG_ENABLED
Definition: isom.h:409
AVCodecParameters::codec_type
enum AVMediaType codec_type
General type of the encoded data.
Definition: codec_par.h:51
AVStreamGroup::tile_grid
struct AVStreamGroupTileGrid * tile_grid
Definition: avformat.h:1169
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:98
AV_WL32
#define AV_WL32(p, v)
Definition: intreadwrite.h:422
MOVStreamContext::cenc
struct MOVStreamContext::@392 cenc
AV_STREAM_GROUP_PARAMS_LCEVC
@ AV_STREAM_GROUP_PARAMS_LCEVC
Definition: avformat.h:1128
MOVStreamContext::extradata
uint8_t ** extradata
extradata array (and size) for multiple stsd
Definition: isom.h:246
mov_class
static const AVClass mov_class
Definition: mov.c:11193
AVSphericalMapping::bound_bottom
uint32_t bound_bottom
Distance from the bottom edge.
Definition: spherical.h:182
MOVStreamContext::open_key_samples
int * open_key_samples
Definition: isom.h:238
AVUUID
uint8_t AVUUID[AV_UUID_LEN]
Definition: uuid.h:60
out
FILE * out
Definition: movenc.c:55
MOVFragmentStreamInfo
Definition: isom.h:133
AVFieldOrder
AVFieldOrder
Definition: defs.h:200
mov_read_targa_y216
static int mov_read_targa_y216(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2265
mov_read_chnl
static int mov_read_chnl(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1187
mov_read_moof
static int mov_read_moof(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1802
av_bprint_init
void av_bprint_init(AVBPrint *buf, unsigned size_init, unsigned size_max)
Definition: bprint.c:69
cb
static double cb(void *priv, double x, double y)
Definition: vf_geq.c:247
ctype
#define ctype
Definition: afir_template.c:46
AV_PKT_DATA_FRAME_CROPPING
@ AV_PKT_DATA_FRAME_CROPPING
The number of pixels to discard from the top/bottom/left/right border of the decoded frame to obtain ...
Definition: packet.h:340
AVCodecParameters
This struct describes the properties of an encoded stream.
Definition: codec_par.h:47
HEIFItem::icc_profile
uint8_t * icc_profile
Definition: isom.h:291
AVFMT_FLAG_IGNIDX
#define AVFMT_FLAG_IGNIDX
Ignore index.
Definition: avformat.h:1453
av_stristr
char * av_stristr(const char *s1, const char *s2)
Locate the first case-independent occurrence in the string haystack of the string needle.
Definition: avstring.c:58
AVCodecParameters::color_space
enum AVColorSpace color_space
Definition: codec_par.h:169
avformat_new_stream
AVStream * avformat_new_stream(AVFormatContext *s, const struct AVCodec *c)
Add a new stream to a media file.
ff_replaygain_export
int ff_replaygain_export(AVStream *st, AVDictionary *metadata)
Parse replaygain tags and export them as per-stream side data.
Definition: replaygain.c:94
tmcd_is_referenced
static int tmcd_is_referenced(AVFormatContext *s, int tmcd_id)
Definition: mov.c:9817
HEIFItem::hflip
int hflip
Definition: isom.h:287
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:773
AVERROR_EOF
#define AVERROR_EOF
End of file.
Definition: error.h:57
AV_DISPOSITION_ATTACHED_PIC
#define AV_DISPOSITION_ATTACHED_PIC
The stream is stored in the file as an attached picture/"cover art" (e.g.
Definition: avformat.h:674
AVStream::discard
enum AVDiscard discard
Selects which packets can be discarded at will and do not need to be demuxed.
Definition: avformat.h:819
AV_FIELD_PROGRESSIVE
@ AV_FIELD_PROGRESSIVE
Definition: defs.h:202
mov_options
static const AVOption mov_options[]
Definition: mov.c:11140
mov_codec_id
static int mov_codec_id(AVStream *st, uint32_t format)
Definition: mov.c:2614
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:236
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:8658
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:601
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:421
int64_t
long long int64_t
Definition: coverity.c:34
output
filter_frame For filters that do not use the this method is called when a frame is pushed to the filter s input It can be called at any time except in a reentrant way If the input frame is enough to produce output
Definition: filter_design.txt:225
mov_read_alac
static int mov_read_alac(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2237
test_same_origin
static int test_same_origin(const char *src, const char *ref)
Definition: mov.c:4910
cbcs_scheme_decrypt
static int cbcs_scheme_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
Definition: mov.c:8090
MOVFragment::base_data_offset
uint64_t base_data_offset
Definition: isom.h:98
MOVStreamContext
Definition: isom.h:167
AVChannelLayout::map
AVChannelCustom * map
This member must be used when the channel order is AV_CHANNEL_ORDER_CUSTOM.
Definition: channel_layout.h:368
MOVStreamContext::stsc_data
MOVStsc * stsc_data
Definition: isom.h:184
ff_buffer_packet
int ff_buffer_packet(AVFormatContext *s, AVPacket *pkt)
Definition: demux.c:612
IS_MATRIX_IDENT
#define IS_MATRIX_IDENT(matrix)
Definition: mov.c:5437
AVStreamGroup::disposition
int disposition
Stream group disposition - a combination of AV_DISPOSITION_* flags.
Definition: avformat.h:1211
dict_internal.h
av_unused
#define av_unused
Definition: attributes.h:131
AV_DISPOSITION_DEFAULT
#define AV_DISPOSITION_DEFAULT
The stream should be chosen by default among other streams of the same type, unless the user has expl...
Definition: avformat.h:621
mov_update_dts_shift
static void mov_update_dts_shift(MOVStreamContext *sc, int duration, void *logctx)
Definition: mov.c:3671
MOVStreamContext::spherical
AVSphericalMapping * spherical
Definition: isom.h:255
mask
int mask
Definition: mediacodecdec_common.c:154
AV_CODEC_ID_MPEG4
@ AV_CODEC_ID_MPEG4
Definition: codec_id.h:64
AVContentLightMetadata::MaxCLL
unsigned MaxCLL
Max content light level (cd/m^2).
Definition: mastering_display_metadata.h:111
avio_get_str16be
int avio_get_str16be(AVIOContext *pb, int maxlen, char *buf, int buflen)
MOVEncryptionIndex
Definition: isom.h:120
av_encryption_init_info_free
void av_encryption_init_info_free(AVEncryptionInitInfo *info)
Frees the given encryption init info object.
Definition: encryption_info.c:216
mov_read_avss
static int mov_read_avss(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2242
AV_RB32A
#define AV_RB32A(p)
Definition: intreadwrite.h:575
MOVContext::primary_item_id
int primary_item_id
Definition: isom.h:361
MOVContext::found_moov
int found_moov
'moov' atom has been found
Definition: isom.h:307
tmp
static uint8_t tmp[11]
Definition: aes_ctr.c:28
mov_read_custom
static int mov_read_custom(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5281
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:1368
HEIFGrid::nb_tiles
int nb_tiles
Definition: isom.h:299
ID3v1_GENRE_MAX
#define ID3v1_GENRE_MAX
Definition: id3v1.h:29
MOVSbgp
Definition: isom.h:115
MOVCtts
Definition: isom.h:62
AVPacketSideData
This structure stores auxiliary information for decoding, presenting, or otherwise processing the cod...
Definition: packet.h:390
mov_read_extradata
static int mov_read_extradata(MOVContext *c, AVIOContext *pb, MOVAtom atom, enum AVCodecID codec_id)
Definition: mov.c:2211
AVCOL_RANGE_JPEG
@ AVCOL_RANGE_JPEG
Full range content.
Definition: pixfmt.h:717
mpegaudiodecheader.h
MOVStreamContext::rap_group_count
unsigned int rap_group_count
Definition: isom.h:230
av_display_matrix_flip
void av_display_matrix_flip(int32_t matrix[9], int hflip, int vflip)
Flip the input matrix horizontally and/or vertically.
Definition: display.c:66
av_sha_init
av_cold int av_sha_init(AVSHA *ctx, int bits)
Initialize SHA-1 or SHA-2 hashing.
Definition: sha.c:274
HEIFItem::type
int type
Definition: isom.h:289
mov_read_mvhd
static int mov_read_mvhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1904
mov_read_idat
static int mov_read_idat(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:8652
AVPacket::data
uint8_t * data
Definition: packet.h:539
MOVContext::found_mdat
int found_mdat
'mdat' atom has been found
Definition: isom.h:310
MOVStreamContext::drefs_count
unsigned drefs_count
Definition: isom.h:212
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:2257
AVAmbientViewingEnvironment::ambient_light_x
AVRational ambient_light_x
Normalized x chromaticity coordinate of the environmental ambient light in the nominal viewing enviro...
Definition: ambient_viewing_environment.h:47
AVCodecParameters::seek_preroll
int seek_preroll
Audio only.
Definition: codec_par.h:214
av_dynarray2_add
void * av_dynarray2_add(void **tab_ptr, int *nb_ptr, size_t elem_size, const uint8_t *elem_data)
Add an element of size elem_size to a dynamic array.
Definition: mem.c:343
AVOption
AVOption.
Definition: opt.h:429
MOVContext::trex_data
MOVTrackExt * trex_data
Definition: isom.h:319
parse
static int parse(AVCodecParserContext *s, AVCodecContext *avctx, const uint8_t **poutbuf, int *poutbuf_size, const uint8_t *buf, int buf_size)
Definition: vp3_parser.c:23
mov_read_stps
static int mov_read_stps(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:3328
MOVContext::bitrates
int * bitrates
bitrates read before streams creation
Definition: isom.h:334
b
#define b
Definition: input.c:41
AVCOL_TRC_UNSPECIFIED
@ AVCOL_TRC_UNSPECIFIED
Definition: pixfmt.h:614
MOVContext::interleaved_read
int interleaved_read
Definition: isom.h:369
mov_read_tkhd
static int mov_read_tkhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5445
MOVElst::rate
float rate
Definition: isom.h:76
AVStream::avg_frame_rate
AVRational avg_frame_rate
Average framerate.
Definition: avformat.h:837
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:2058
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:1943
mov_read_strf
static int mov_read_strf(MOVContext *c, AVIOContext *pb, MOVAtom atom)
An strf atom is a BITMAPINFOHEADER struct.
Definition: mov.c:2527
AV_CODEC_ID_ALAC
@ AV_CODEC_ID_ALAC
Definition: codec_id.h:462
HEIFItem::st
AVStream * st
Definition: isom.h:279
yuv_to_rgba
static uint32_t yuv_to_rgba(uint32_t ycbcr)
Definition: mov.c:2845
FF_COMPLIANCE_STRICT
#define FF_COMPLIANCE_STRICT
Strictly conform to all the things in the spec no matter what consequences.
Definition: defs.h:59
AVIOContext::error
int error
contains the error code or 0 if no error happened
Definition: avio.h:239
AV_CODEC_ID_AMR_NB
@ AV_CODEC_ID_AMR_NB
Definition: codec_id.h:427
av_iamf_mix_presentation_free
void av_iamf_mix_presentation_free(AVIAMFMixPresentation **pmix_presentation)
Free an AVIAMFMixPresentation and all its contents.
Definition: iamf.c:534
mov_parse_auxiliary_info
static int mov_parse_auxiliary_info(MOVContext *c, MOVStreamContext *sc, AVIOContext *pb, MOVEncryptionIndex *encryption_index)
Definition: mov.c:7408
mov_seek_stream
static int mov_seek_stream(AVFormatContext *s, AVStream *st, int64_t timestamp, int flags)
Definition: mov.c:10993
mov_read_saio
static int mov_read_saio(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:7554
mov_get_stsc_samples
static int64_t mov_get_stsc_samples(MOVStreamContext *sc, unsigned int index)
Definition: mov.c:3313
ff_get_wav_header
int ff_get_wav_header(void *logctx, AVIOContext *pb, AVCodecParameters *par, int size, int big_endian)
Definition: riffdec.c:95
AV_LOG_VERBOSE
#define AV_LOG_VERBOSE
Detailed information.
Definition: log.h:225
ff_codec_wav_tags
const AVCodecTag ff_codec_wav_tags[]
Definition: riff.c:530
get_edit_list_entry
static int get_edit_list_entry(MOVContext *mov, const MOVStreamContext *msc, unsigned int edit_list_index, int64_t *edit_list_media_time, int64_t *edit_list_duration, int64_t global_timescale)
Get ith edit list entry (media time, duration).
Definition: mov.c:3870
MOVFragmentIndexItem::moof_offset
int64_t moof_offset
Definition: isom.h:147
MOVStreamContext::spherical_size
size_t spherical_size
Definition: isom.h:256
mov_change_extradata
static int mov_change_extradata(AVStream *st, AVPacket *pkt)
Definition: mov.c:10668
fc
#define fc(width, name, range_min, range_max)
Definition: cbs_av1.c:472
MOVStreamContext::tref_id
int tref_id
Definition: isom.h:216
MP4TrackKindMapping::scheme_uri
const char * scheme_uri
Definition: isom.h:471
AVINDEX_DISCARD_FRAME
#define AVINDEX_DISCARD_FRAME
Definition: avformat.h:611
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:557
AVCodecParameters::codec_tag
uint32_t codec_tag
Additional information about the codec (corresponds to the AVI FOURCC).
Definition: codec_par.h:59
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:82
mov_current_sample_set
static void mov_current_sample_set(MOVStreamContext *sc, int current_sample)
Definition: mov.c:4178
mathematics.h
AVDictionary
Definition: dict.c:34
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:613
AVProbeData::buf_size
int buf_size
Size of buf except extra allocated bytes.
Definition: avformat.h:454
AVChannelLayout::order
enum AVChannelOrder order
Channel order used in this layout.
Definition: channel_layout.h:322
FFMAX
#define FFMAX(a, b)
Definition: macros.h:47
MOVAtom
Definition: isom.h:88
AVStreamGroupTileGrid::vertical
int vertical
Offset in pixels from the top edge of the canvas where the tile should be placed.
Definition: avformat.h:1036
iamf_parse.h
mov_read_moov
static int mov_read_moov(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1556
FFNABS
#define FFNABS(a)
Negative Absolute value.
Definition: common.h:83
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:842
MOVStreamContext::sample_count
unsigned int sample_count
Definition: isom.h:195
MOVFragmentIndex::allocated_size
int allocated_size
Definition: isom.h:155
MOVTrackExt::flags
unsigned flags
Definition: isom.h:112
AVChannelLayout::nb_channels
int nb_channels
Number of channels in this layout.
Definition: channel_layout.h:327
HEIFItem::height
int height
Definition: isom.h:285
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:182
AV_CODEC_ID_R10K
@ AV_CODEC_ID_R10K
Definition: codec_id.h:197
heif_cur_item
static HEIFItem * heif_cur_item(MOVContext *c)
Get the current item in the parsing process.
Definition: mov.c: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:328
avio_size
int64_t avio_size(AVIOContext *s)
Get the filesize.
Definition: aviobuf.c:323
av_strlcatf
size_t av_strlcatf(char *dst, size_t size, const char *fmt,...)
Definition: avstring.c:103
mov_read_stco
static int mov_read_stco(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2549
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:6927
FFIOContext
Definition: avio_internal.h:28
AV_PKT_FLAG_KEY
#define AV_PKT_FLAG_KEY
The packet contains a keyframe.
Definition: packet.h:594
init_get_bits
static int init_get_bits(GetBitContext *s, const uint8_t *buffer, int bit_size)
Initialize GetBitContext.
Definition: get_bits.h:514
MOVStreamContext::aes_ctr
struct AVAESCTR * aes_ctr
Definition: isom.h:268
cenc_filter
static int cenc_filter(MOVContext *mov, AVStream *st, MOVStreamContext *sc, AVPacket *pkt, int current_index)
Definition: mov.c:8197
mov_read_sdtp
static int mov_read_sdtp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:3637
mov_read_jp2h
static int mov_read_jp2h(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2247
AV_STEREO3D_UNSPEC
@ AV_STEREO3D_UNSPEC
Video is stereoscopic but the packing is unspecified.
Definition: stereo3d.h:143
AVIndexEntry
Definition: avformat.h:602
AV_WB64
#define AV_WB64(p, v)
Definition: intreadwrite.h:429
MOVStreamContext::dv_audio_container
int dv_audio_container
Definition: isom.h:209
AV_CODEC_ID_AMR_WB
@ AV_CODEC_ID_AMR_WB
Definition: codec_id.h:428
mov_read_tfhd
static int mov_read_tfhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5550
AV_CODEC_ID_BIN_DATA
@ AV_CODEC_ID_BIN_DATA
Definition: codec_id.h:596
av_malloc
#define av_malloc(s)
Definition: tableprint_vlc.h:30
OPUS_SEEK_PREROLL_MS
#define OPUS_SEEK_PREROLL_MS
Definition: oggparseopus.c:36
AV_CODEC_ID_H261
@ AV_CODEC_ID_H261
Definition: codec_id.h:55
IAMFMixPresentation::cmix
const AVIAMFMixPresentation * cmix
Definition: iamf.h:108
mov_read_wide
static int mov_read_wide(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6128
AVINDEX_KEYFRAME
#define AVINDEX_KEYFRAME
Definition: avformat.h:610
AV_FIELD_BT
@ AV_FIELD_BT
Bottom coded first, top displayed first.
Definition: defs.h:206
MOVStreamContext::stsd_count
int stsd_count
Definition: isom.h:249
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:203
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:338
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:381
AVCodecParameters::color_primaries
enum AVColorPrimaries color_primaries
Definition: codec_par.h:167
AVEncryptionInfo::scheme
uint32_t scheme
The fourcc encryption scheme, in big-endian byte order.
Definition: encryption_info.h:45
MOVStreamContext::stsc_count
unsigned int stsc_count
Definition: isom.h:183
MOVStreamContext::has_palette
int has_palette
Definition: isom.h:224
AVPROBE_SCORE_MAX
#define AVPROBE_SCORE_MAX
maximum score
Definition: avformat.h:463
AV_STEREO3D_SIDEBYSIDE
@ AV_STEREO3D_SIDEBYSIDE
Views are next to each other.
Definition: stereo3d.h:64
MOVIndexRange::start
int64_t start
Definition: isom.h:163
AVPacketSideData::size
size_t size
Definition: packet.h:392
get_bits
static unsigned int get_bits(GetBitContext *s, int n)
Read 1-25 bits.
Definition: get_bits.h:335
ff_remove_stream
void ff_remove_stream(AVFormatContext *s, AVStream *st)
Remove a stream from its AVFormatContext and free it.
Definition: avformat.c:121
OFFSET
#define OFFSET(x)
Definition: mov.c:11138
HEIFGrid::tile_item_list
HEIFItem ** tile_item_list
Definition: isom.h:297
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:9952
AV_FIELD_TT
@ AV_FIELD_TT
Top coded_first, top displayed first.
Definition: defs.h:203
ff_iamf_read_packet
int ff_iamf_read_packet(AVFormatContext *s, IAMFDemuxContext *c, AVIOContext *pb, int max_size, AVPacket *pkt)
Definition: iamf_reader.c:267
AV_STEREO3D_VIEW_PACKED
@ AV_STEREO3D_VIEW_PACKED
Frame contains two packed views.
Definition: stereo3d.h:153
MOVStreamContext::nb_frames_for_fps
int nb_frames_for_fps
Definition: isom.h:242
avpriv_dv_produce_packet
int avpriv_dv_produce_packet(DVDemuxContext *c, AVPacket *pkt, uint8_t *buf, int buf_size, int64_t pos)
Definition: dv.c:736
avpriv_set_pts_info
void avpriv_set_pts_info(AVStream *st, int pts_wrap_bits, unsigned int pts_num, unsigned int pts_den)
Set the time base and wrapping info for a given stream.
Definition: avformat.c:867
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:373
aax_filter
static int aax_filter(uint8_t *input, int size, MOVContext *c)
Definition: mov.c:1494
AV_OPT_TYPE_BINARY
@ AV_OPT_TYPE_BINARY
Underlying C type is a uint8_t* that is either NULL or points to an array allocated with the av_mallo...
Definition: opt.h:286
av_color_space_name
const char * av_color_space_name(enum AVColorSpace space)
Definition: pixdesc.c:3546
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:257
AV_CODEC_ID_SPEEX
@ AV_CODEC_ID_SPEEX
Definition: codec_id.h:481
AV_FOURCC_MAX_STRING_SIZE
#define AV_FOURCC_MAX_STRING_SIZE
Definition: avutil.h:346
AV_PKT_DATA_PALETTE
@ AV_PKT_DATA_PALETTE
An AV_PKT_DATA_PALETTE side data packet contains exactly AVPALETTE_SIZE bytes worth of palette.
Definition: packet.h:47
ffstream
static av_always_inline FFStream * ffstream(AVStream *st)
Definition: internal.h:358
MOVFragmentIndexItem::current
int current
Definition: isom.h:149
AVFMT_SEEK_TO_PTS
#define AVFMT_SEEK_TO_PTS
Seeking is based on PTS.
Definition: avformat.h:503
AV_CODEC_ID_PCM_S16BE
@ AV_CODEC_ID_PCM_S16BE
Definition: codec_id.h:335
mov_read_mdhd
static int mov_read_mdhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1858
mov_read_ctts
static int mov_read_ctts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:3682
MOVTrackExt
Definition: isom.h:107
MOV_FRAG_SAMPLE_FLAG_IS_NON_SYNC
#define MOV_FRAG_SAMPLE_FLAG_IS_NON_SYNC
Definition: isom.h:400
fail
#define fail()
Definition: checkasm.h:188
mov_read_aclr
static int mov_read_aclr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2322
AVSEEK_FLAG_ANY
#define AVSEEK_FLAG_ANY
seek to any frame, even non-keyframes
Definition: avformat.h:2500
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:96
AVStreamGroupTileGrid
AVStreamGroupTileGrid holds information on how to combine several independent images on a single canv...
Definition: avformat.h:987
MOVContext::decryption_key
uint8_t * decryption_key
Definition: isom.h:354
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:281
timecode.h
get_current_frag_stream_info
static MOVFragmentStreamInfo * get_current_frag_stream_info(MOVFragmentIndex *frag_index)
Definition: mov.c:1613
MOVStreamContext::ctts_index
int ctts_index
Definition: isom.h:191
GetBitContext
Definition: get_bits.h:108
MOVStreamContext::mastering_size
size_t mastering_size
Definition: isom.h:258
AVStreamGroupTileGrid::coded_width
int coded_width
Width of the canvas.
Definition: avformat.h:1002
av_iamf_audio_element_free
void av_iamf_audio_element_free(AVIAMFAudioElement **paudio_element)
Free an AVIAMFAudioElement and all its contents.
Definition: iamf.c:336
FFStream::index_entries_allocated_size
unsigned int index_entries_allocated_size
Definition: internal.h:191
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:6482
mov_read_enda
static int mov_read_enda(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1972
mov_read_chap
static int mov_read_chap(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5597
MOVParseTableEntry
Definition: mov.c:81
avio_tell
static av_always_inline int64_t avio_tell(AVIOContext *s)
ftell() equivalent for AVIOContext.
Definition: avio.h:494
MOV_TRUN_SAMPLE_DURATION
#define MOV_TRUN_SAMPLE_DURATION
Definition: isom.h:394
val
static double val(void *priv, double ch)
Definition: aeval.c:77
MOVCtts::duration
int duration
Definition: isom.h:64
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:9966
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:302
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:679
AVStreamGroupTileGrid::coded_height
int coded_height
Width of the canvas.
Definition: avformat.h:1008
pts
static int64_t pts
Definition: transcode_aac.c:644
MOVStreamContext::v_spacing
int v_spacing
pasp vSpacing
Definition: isom.h:221
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:447
AVStream::duration
int64_t duration
Decoding: duration of the stream, in stream time base.
Definition: avformat.h:807
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:218
MOVContext::meta_keys
char ** meta_keys
Definition: isom.h:313
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:247
AVIAMFAudioElement::audio_element_type
enum AVIAMFAudioElementType audio_element_type
Audio element type as defined in section 3.6 of IAMF.
Definition: iamf.h:388
loop
static int loop
Definition: ffplay.c:335
ff_data_to_hex
char * ff_data_to_hex(char *buf, const uint8_t *src, int size, int lowercase)
Write hexadecimal string corresponding to given binary data.
Definition: utils.c:448
update_frag_index
static int update_frag_index(MOVContext *c, int64_t offset)
Definition: mov.c:1726
AVRational::num
int num
Numerator.
Definition: rational.h:59
MOVStreamContext::keyframes
int * keyframes
Definition: isom.h:199
MOVEncryptionIndex::auxiliary_info_sample_count
size_t auxiliary_info_sample_count
Definition: isom.h:127
AV_FIELD_TB
@ AV_FIELD_TB
Top coded first, bottom displayed first.
Definition: defs.h:205
AVStream::attached_pic
AVPacket attached_pic
For streams with AV_DISPOSITION_ATTACHED_PIC disposition, this packet will contain the attached pictu...
Definition: avformat.h:846
MOVStsc::id
int id
Definition: isom.h:70
mov_read_saiz
static int mov_read_saiz(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:7470
MOV_FRAG_SAMPLE_FLAG_DEPENDS_YES
#define MOV_FRAG_SAMPLE_FLAG_DEPENDS_YES
Definition: isom.h:407
MOVContext::idat_offset
int64_t idat_offset
Definition: isom.h:368
MOV_TRUN_DATA_OFFSET
#define MOV_TRUN_DATA_OFFSET
Definition: isom.h:392
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:189
mov_read_ares
static int mov_read_ares(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2279
mov_read_adrm
static int mov_read_adrm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1370
av_get_bits_per_sample
int av_get_bits_per_sample(enum AVCodecID codec_id)
Return codec bits per sample.
Definition: utils.c:550
AVCodecParameters::color_trc
enum AVColorTransferCharacteristic color_trc
Definition: codec_par.h:168
IAMFContext::audio_elements
IAMFAudioElement ** audio_elements
Definition: iamf.h:131
MOVFragmentIndex::complete
int complete
Definition: isom.h:156
AV_CODEC_ID_PCM_S8
@ AV_CODEC_ID_PCM_S8
Definition: codec_id.h:338
avassert.h
FLAC_METADATA_TYPE_STREAMINFO
@ FLAC_METADATA_TYPE_STREAMINFO
Definition: flac.h:46
avio_rb32
unsigned int avio_rb32(AVIOContext *s)
Definition: aviobuf.c:761
AV_LOG_TRACE
#define AV_LOG_TRACE
Extremely verbose debugging, useful for libav* development.
Definition: log.h:235
MOVStreamContext::stsc_sample
int stsc_sample
Definition: isom.h:186
pkt
AVPacket * pkt
Definition: movenc.c:60
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:209
AV_CODEC_ID_MACE3
@ AV_CODEC_ID_MACE3
Definition: codec_id.h:455
MOVTrackExt::track_id
unsigned track_id
Definition: isom.h:108
mov_free_encryption_index
static void mov_free_encryption_index(MOVEncryptionIndex **index)
Definition: mov.c:9691
AV_CH_LOW_FREQUENCY
#define AV_CH_LOW_FREQUENCY
Definition: channel_layout.h:178
duration
int64_t duration
Definition: movenc.c:65
MOVEncryptionIndex::auxiliary_offsets
uint64_t * auxiliary_offsets
Absolute seek position.
Definition: isom.h:129
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:201
MOVStreamContext::dts_shift
int dts_shift
dts shift when ctts is negative
Definition: isom.h:222
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:222
AVCodecParameters::frame_size
int frame_size
Audio only.
Definition: codec_par.h:195
avio_get_str16le
int avio_get_str16le(AVIOContext *pb, int maxlen, char *buf, int buflen)
Read a UTF-16 string from pb and convert it to UTF-8.
mov_metadata_track_or_disc_number
static int mov_metadata_track_or_disc_number(MOVContext *c, AVIOContext *pb, unsigned len, const char *key)
Definition: mov.c: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:62
AES_CTR_KEY_SIZE
#define AES_CTR_KEY_SIZE
Definition: aes_ctr.h:35
MOVStreamContext::stsd_version
int stsd_version
Definition: isom.h:250
AV_STREAM_GROUP_PARAMS_IAMF_MIX_PRESENTATION
@ AV_STREAM_GROUP_PARAMS_IAMF_MIX_PRESENTATION
Definition: avformat.h:1126
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:119
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:444
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:6416
s
#define s(width, name)
Definition: cbs_vp9.c:198
MOVFragmentStreamInfo::encryption_index
MOVEncryptionIndex * encryption_index
Definition: isom.h:142
mov_read_trak
static int mov_read_trak(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5067
IAMFSubStream::audio_substream_id
unsigned int audio_substream_id
Definition: iamf.h:83
MOVContext::fc
AVFormatContext * fc
Definition: isom.h:304
MOV_TFHD_DEFAULT_BASE_IS_MOOF
#define MOV_TFHD_DEFAULT_BASE_IS_MOOF
Definition: isom.h:390
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:130
AV_CODEC_ID_EVC
@ AV_CODEC_ID_EVC
Definition: codec_id.h:325
IAMFLayer::substream_count
unsigned int substream_count
Definition: iamf.h:78
MOV_TFHD_DEFAULT_DURATION
#define MOV_TFHD_DEFAULT_DURATION
Definition: isom.h:386
ALAC_EXTRADATA_SIZE
#define ALAC_EXTRADATA_SIZE
DRM_BLOB_SIZE
#define DRM_BLOB_SIZE
Definition: mov.c:1368
MOVStreamContext::sample_offsets_count
int sample_offsets_count
Definition: isom.h:237
MOVCtts::count
unsigned int count
Definition: isom.h:63
MOVStreamContext::drefs
MOVDref * drefs
Definition: isom.h:213
av_realloc_array
void * av_realloc_array(void *ptr, size_t nmemb, size_t size)
Definition: mem.c:217
format
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 format(the sample packing is implied by the sample format) and sample rate. The lists are not just lists
AVInputFormat::name
const char * name
A comma separated list of short names for the format.
Definition: avformat.h:553
MOVContext::aes_decrypt
struct AVAES * aes_decrypt
Definition: isom.h:353
g
const char * g
Definition: vf_curves.c:128
AVProbeData::buf
unsigned char * buf
Buffer must have AVPROBE_PADDING_SIZE of extra allocated bytes filled with zero.
Definition: avformat.h:453
AVSphericalMapping::bound_top
uint32_t bound_top
Distance from the top edge.
Definition: spherical.h:180
AVMEDIA_TYPE_AUDIO
@ AVMEDIA_TYPE_AUDIO
Definition: avutil.h:202
AV_CODEC_ID_VP9
@ AV_CODEC_ID_VP9
Definition: codec_id.h:222
MOVFragmentIndex::nb_items
int nb_items
Definition: isom.h:158
AVCodecParameters::width
int width
Video only.
Definition: codec_par.h:134
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:446
MOV_TRUN_FIRST_SAMPLE_FLAGS
#define MOV_TRUN_FIRST_SAMPLE_FLAGS
Definition: isom.h:393
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:613
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:250
MOVStreamContext::keyframe_absent
int keyframe_absent
Definition: isom.h:197
info
MIPS optimizations info
Definition: mips.txt:2
MOVStts::duration
unsigned int duration
Definition: isom.h:59
MOVStreamContext::coll_size
size_t coll_size
Definition: isom.h:260
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:4098
AVIndexEntry::timestamp
int64_t timestamp
Timestamp in AVStream.time_base units, preferably the time from which on correctly decoded frames are...
Definition: avformat.h:604
av_assert0
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:40
MOVStreamContext::min_corrected_pts
int64_t min_corrected_pts
minimum Composition time shown by the edits excluding empty edits.
Definition: isom.h:202
ffio_read_leb
unsigned int ffio_read_leb(AVIOContext *s)
Read a unsigned integer coded as a variable number of up to eight little-endian bytes,...
Definition: aviobuf.c:927
tile_cols
int tile_cols
Definition: av1_levels.c:73
MOVStreamContext::sdtp_count
unsigned int sdtp_count
Definition: isom.h:178
mov_read_lhvc
static int mov_read_lhvc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:8371
AV_LOG_DEBUG
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:230
AVPacketSideData::data
uint8_t * data
Definition: packet.h:391
ctx
AVFormatContext * ctx
Definition: movenc.c:49
hevc.h
get_bits.h
limits.h
mov_read_sidx
static int mov_read_sidx(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5990
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:1059
FFStream::display_aspect_ratio
AVRational display_aspect_ratio
display aspect ratio (0 if unknown)
Definition: internal.h:307
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:10595
AV_CODEC_ID_TARGA_Y216
@ AV_CODEC_ID_TARGA_Y216
Definition: codec_id.h:258
AVIndexEntry::min_distance
int min_distance
Minimum distance between this and the previous keyframe, used to avoid unneeded searching.
Definition: avformat.h:614
mov_read_dvcc_dvvc
static int mov_read_dvcc_dvvc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:8351
MOVParseTableEntry::parse
int(* parse)(MOVContext *ctx, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:83
codec_id
enum AVCodecID codec_id
Definition: vaapi_decode.c:410
AV_CODEC_ID_SVQ3
@ AV_CODEC_ID_SVQ3
Definition: codec_id.h:75
key
const char * key
Definition: hwcontext_opencl.c:189
AVCodecParameters::nb_coded_side_data
int nb_coded_side_data
Amount of entries in coded_side_data.
Definition: codec_par.h:86
MOVStreamContext::sdtp_data
uint8_t * sdtp_data
Definition: isom.h:179
color_range
color_range
Definition: vf_selectivecolor.c:43
AVMEDIA_TYPE_DATA
@ AVMEDIA_TYPE_DATA
Opaque data information usually continuous.
Definition: avutil.h:203
mov_read_udta_string
static int mov_read_udta_string(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:346
mov_read_stss
static int mov_read_stss(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:3369
mov_read_ddts
static int mov_read_ddts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1115
mov_read_uuid
static int mov_read_uuid(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:7073
AVCOL_PRI_UNSPECIFIED
@ AVCOL_PRI_UNSPECIFIED
Definition: pixfmt.h:589
MOVTrackExt::duration
unsigned duration
Definition: isom.h:110
AV_CODEC_ID_H264
@ AV_CODEC_ID_H264
Definition: codec_id.h:79
av_content_light_metadata_alloc
AVContentLightMetadata * av_content_light_metadata_alloc(size_t *size)
Allocate an AVContentLightMetadata structure and set its fields to default values.
Definition: mastering_display_metadata.c:72
av_sha_final
void av_sha_final(AVSHA *ctx, uint8_t *digest)
Finish hashing and output digest value.
Definition: sha.c:347
MOVStreamContext::current_sample
int current_sample
Definition: isom.h:203
MOVFragmentStreamInfo::sidx_pts
int64_t sidx_pts
Definition: isom.h:135
MAX_REORDER_DELAY
#define MAX_REORDER_DELAY
Definition: mov.c:4097
MOVFragmentIndex::current
int current
Definition: isom.h:157
MOVEncryptionIndex::encrypted_samples
AVEncryptionInfo ** encrypted_samples
Definition: isom.h:124
mov_read_close
static int mov_read_close(AVFormatContext *s)
Definition: mov.c:9764
MOVAtom::size
int64_t size
Definition: isom.h:90
MOVStreamContext::refcount
int refcount
Definition: isom.h:169
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:450
AV_CODEC_ID_PNG
@ AV_CODEC_ID_PNG
Definition: codec_id.h:113
AV_CODEC_ID_AVUI
@ AV_CODEC_ID_AVUI
Definition: codec_id.h:257
if
if(ret)
Definition: filter_design.txt:179
mov_read_cmov
static int mov_read_cmov(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6148
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:7298
FFStream::need_parsing
enum AVStreamParseType need_parsing
Definition: internal.h:325
MOVStreamContext::keyframe_count
unsigned int keyframe_count
Definition: isom.h:198
mov_read_SAND
static int mov_read_SAND(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:8599
IAMFAudioElement::audio_element_id
unsigned int audio_element_id
Definition: iamf.h:96
AVDISCARD_ALL
@ AVDISCARD_ALL
discard all
Definition: defs.h:221
AVFormatContext
Format I/O context.
Definition: avformat.h:1300
av_realloc_f
#define av_realloc_f(p, o, n)
Definition: tableprint_vlc.h:32
mov_read_stts
static int mov_read_stts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:3517
MOVStreamContext::index_ranges
MOVIndexRange * index_ranges
Definition: isom.h:205
DDTS_SIZE
#define DDTS_SIZE
internal.h
MOVTrackExt::stsd_id
unsigned stsd_id
Definition: isom.h:109
AVStreamGroupLCEVC::height
int height
Height of the final image for presentation.
Definition: avformat.h:1120
set_frag_stream
static void set_frag_stream(MOVFragmentIndex *frag_index, int id)
Definition: mov.c:1593
mov_read_free
static int mov_read_free(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:7178
mov_realloc_extradata
static int mov_realloc_extradata(AVCodecParameters *par, MOVAtom atom)
Definition: mov.c:2174
AVStream::codecpar
AVCodecParameters * codecpar
Codec parameters associated with this stream.
Definition: avformat.h:771
LIBAVUTIL_VERSION_INT
#define LIBAVUTIL_VERSION_INT
Definition: version.h:85
AVSEEK_FLAG_BACKWARD
#define AVSEEK_FLAG_BACKWARD
Definition: avformat.h:2498
read_header
static int read_header(FFV1Context *f)
Definition: ffv1dec.c:540
aes.h
AVClass
Describe the class of an AVClass context structure.
Definition: log.h:75
avpriv_dv_get_packet
int avpriv_dv_get_packet(DVDemuxContext *c, AVPacket *pkt)
Definition: dv.c:731
MOVContext::ignore_editlist
int ignore_editlist
Definition: isom.h:326
result
and forward the result(frame or status change) to the corresponding input. If nothing is possible
fabs
static __device__ float fabs(float a)
Definition: cuda_runtime.h:182
AVStream::time_base
AVRational time_base
This is the fundamental unit of time (in seconds) in terms of which frame timestamps are represented.
Definition: avformat.h:787
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:79
AVERROR_PATCHWELCOME
#define AVERROR_PATCHWELCOME
Not yet implemented in FFmpeg, patches welcome.
Definition: error.h:64
AV_CODEC_ID_AV1
@ AV_CODEC_ID_AV1
Definition: codec_id.h:284
MOVStreamContext::ctts_count
unsigned int ctts_count
Definition: isom.h:180
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:466
mov_read_ftyp
static int mov_read_ftyp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1508
AV_WB16
#define AV_WB16(p, v)
Definition: intreadwrite.h:401
MOVContext::nb_heif_grid
int nb_heif_grid
Definition: isom.h:366
read_image_grid
static int read_image_grid(AVFormatContext *s, const HEIFGrid *grid, AVStreamGroupTileGrid *tile_grid)
Definition: mov.c:9987
MOVElst
Definition: isom.h:73
av_aes_ctr_alloc
struct AVAESCTR * av_aes_ctr_alloc(void)
Allocate an AVAESCTR context.
Definition: aes_ctr.c:40
flac_parse_block_header
static av_always_inline void flac_parse_block_header(const uint8_t *block_header, int *last, int *type, int *size)
Parse the metadata block parameters from the header.
Definition: flac.h:63
AVStreamGroupTileGrid::coded_side_data
AVPacketSideData * coded_side_data
Additional data associated with the grid.
Definition: avformat.h:1090
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:3753
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:717
mov_probe
static int mov_probe(const AVProbeData *p)
Definition: mov.c:9411
AVPALETTE_SIZE
#define AVPALETTE_SIZE
Definition: pixfmt.h:32
MOVDref::nlvl_to
int16_t nlvl_to
Definition: isom.h:85
AV_CODEC_ID_DVD_SUBTITLE
@ AV_CODEC_ID_DVD_SUBTITLE
Definition: codec_id.h:556
AVIndexEntry::flags
int flags
Definition: avformat.h:612
MOVStreamContext::time_offset
int64_t time_offset
time offset of the edit list entries
Definition: isom.h:201
mov_read_smdm
static int mov_read_smdm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6325
av_default_item_name
const char * av_default_item_name(void *ptr)
Return the context name.
Definition: log.c:237
AVStereo3D::horizontal_disparity_adjustment
AVRational horizontal_disparity_adjustment
Relative shift of the left and right images, which changes the zero parallax plane.
Definition: stereo3d.h:234
avio_rb64
uint64_t avio_rb64(AVIOContext *s)
Definition: aviobuf.c:908
av_aes_crypt
void av_aes_crypt(AVAES *a, uint8_t *dst, const uint8_t *src, int count, uint8_t *iv, int decrypt)
Encrypt or decrypt a buffer using a previously initialized context.
Definition: aes.c:169
MOVStreamContext::current_index_range
MOVIndexRange * current_index_range
Definition: isom.h:206
mov_open_dref
static int mov_open_dref(MOVContext *c, AVIOContext **pb, const char *src, MOVDref *ref)
Definition: mov.c:4939
FFStream::nb_index_entries
int nb_index_entries
Definition: internal.h:190
AVProbeData
This structure contains the data a format has to probe a file.
Definition: avformat.h:451
av_aes_alloc
struct AVAES * av_aes_alloc(void)
Allocate an AVAES context.
Definition: aes.c:35
TAG_IS_AVCI
#define TAG_IS_AVCI(tag)
Definition: isom.h:420
IAMFSubStream
Definition: iamf.h:82
MOVStreamContext::timecode_track
int timecode_track
Definition: isom.h:217
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:7770
AVStream::metadata
AVDictionary * metadata
Definition: avformat.h:828
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:3504
FF_MOV_FLAG_MFRA_DTS
#define FF_MOV_FLAG_MFRA_DTS
Definition: isom.h:443
MOV_SAMPLE_DEPENDENCY_NO
#define MOV_SAMPLE_DEPENDENCY_NO
Definition: isom.h:416
mov_read_iref_thmb
static int mov_read_iref_thmb(MOVContext *c, AVIOContext *pb, int version)
Definition: mov.c:8927
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
AV_DISPOSITION_MULTILAYER
#define AV_DISPOSITION_MULTILAYER
The video stream contains multiple layers, e.g.
Definition: avformat.h:718
MOVFragmentStreamInfo::index_base
int index_base
Definition: isom.h:140
MOVStreamContext::rap_group
MOVSbgp * rap_group
Definition: isom.h:231
AV_CODEC_ID_QDM2
@ AV_CODEC_ID_QDM2
Definition: codec_id.h:465
mov_read_ilst
static int mov_read_ilst(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5226
AV_CH_FRONT_CENTER
#define AV_CH_FRONT_CENTER
Definition: channel_layout.h:177
AVCodecParameters::ch_layout
AVChannelLayout ch_layout
Audio only.
Definition: codec_par.h:180
get_frag_stream_info_from_pkt
static MOVFragmentStreamInfo * get_frag_stream_info_from_pkt(MOVFragmentIndex *frag_index, AVPacket *pkt, int id)
Definition: mov.c:8172
get_sgpd_sync_index
static uint32_t get_sgpd_sync_index(const MOVStreamContext *sc, int nal_unit_type)
Definition: mov.c:4511
mov_read_fiel
static int mov_read_fiel(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2140
MOV_MP4_TTML_TAG
#define MOV_MP4_TTML_TAG
Definition: isom.h:461
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:384
MOVFragmentStreamInfo::stsd_id
int stsd_id
Definition: isom.h:143
MOVStreamContext::open_key_samples_count
int open_key_samples_count
Definition: isom.h:239
HEIFItem
Definition: isom.h:278
ff_codec_movaudio_tags
const AVCodecTag ff_codec_movaudio_tags[]
Definition: isom_tags.c:303
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:1219
av_stereo3d_alloc_size
AVStereo3D * av_stereo3d_alloc_size(size_t *size)
Allocate an AVStereo3D structure and set its fields to default values.
Definition: stereo3d.c:40
index
int index
Definition: gxfenc.c:90
c
Undefined Behavior In the C some operations are like signed integer dereferencing freed accessing outside allocated Undefined Behavior must not occur in a C it is not safe even if the output of undefined operations is unused The unsafety may seem nit picking but Optimizing compilers have in fact optimized code on the assumption that no undefined Behavior occurs Optimizing code based on wrong assumptions can and has in some cases lead to effects beyond the output of computations The signed integer overflow problem in speed critical code Code which is highly optimized and works with signed integers sometimes has the problem that often the output of the computation does not c
Definition: undefined.txt:32
AVPROBE_SCORE_EXTENSION
#define AVPROBE_SCORE_EXTENSION
score for file extension
Definition: avformat.h:461
MOVSbgp::count
unsigned int count
Definition: isom.h:116
AVCodecParameters::sample_rate
int sample_rate
Audio only.
Definition: codec_par.h:184
mov_parse_stsd_subtitle
static void mov_parse_stsd_subtitle(MOVContext *c, AVIOContext *pb, AVStream *st, MOVStreamContext *sc, int64_t size)
Definition: mov.c:2829
cid
uint16_t cid
Definition: mxfenc.c:2269
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:3039
MOVStts
Definition: isom.h:57
AVAudioServiceType
AVAudioServiceType
Definition: defs.h:224
AV_CODEC_ID_MPEG1VIDEO
@ AV_CODEC_ID_MPEG1VIDEO
Definition: codec_id.h:53
AV_CODEC_ID_GSM
@ AV_CODEC_ID_GSM
as in Berlin toast format
Definition: codec_id.h:464
AVStream::nb_frames
int64_t nb_frames
number of frames in this stream if known or 0
Definition: avformat.h:809
AVCodecID
AVCodecID
Identify the syntax and semantics of the bitstream.
Definition: codec_id.h:49
av_packet_side_data_get
const AVPacketSideData * av_packet_side_data_get(const AVPacketSideData *sd, int nb_sd, enum AVPacketSideDataType type)
Get side information from a side data array.
Definition: packet.c:656
AVIAMFSubmixElement::audio_element_id
unsigned int audio_element_id
The id of the Audio Element this submix element references.
Definition: iamf.h:452
AV_CODEC_ID_EAC3
@ AV_CODEC_ID_EAC3
Definition: codec_id.h:486
should_retry
static int should_retry(AVIOContext *pb, int error_code)
Definition: mov.c:10625
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:529
AV_PKT_DATA_SPHERICAL
@ AV_PKT_DATA_SPHERICAL
This side data should be associated with a video stream and corresponds to the AVSphericalMapping str...
Definition: packet.h:225
AVCodecParameters::extradata_size
int extradata_size
Size of the extradata content in bytes.
Definition: codec_par.h:73
AVIAMFSubmix
Submix layout as defined in section 3.7 of IAMF.
Definition: iamf.h:556
AV_WB32
#define AV_WB32(p, v)
Definition: intreadwrite.h:415
mov_read_pasp
static int mov_read_pasp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1338
MOVContext::dv_demux
DVDemuxContext * dv_demux
Definition: isom.h:315
AV_CODEC_ID_AAC
@ AV_CODEC_ID_AAC
Definition: codec_id.h:448
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:8509
mov_read_elst
static int mov_read_elst(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6201
MOVEncryptionIndex::auxiliary_info_default_size
uint8_t auxiliary_info_default_size
Definition: isom.h:128
AV_STREAM_GROUP_PARAMS_TILE_GRID
@ AV_STREAM_GROUP_PARAMS_TILE_GRID
Definition: avformat.h:1127
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:10378
AV_CODEC_ID_QCELP
@ AV_CODEC_ID_QCELP
Definition: codec_id.h:470
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:7965
avio_rl32
unsigned int avio_rl32(AVIOContext *s)
Definition: aviobuf.c:730
MOVStreamContext::tref_flags
unsigned tref_flags
Definition: isom.h:215
AVDISCARD_NONKEY
@ AVDISCARD_NONKEY
discard all frames except keyframes
Definition: defs.h:220
MOVFragment::flags
unsigned flags
Definition: isom.h:104
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:346
mov_read_wave
static int mov_read_wave(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2370
AV_SPHERICAL_CUBEMAP
@ AV_SPHERICAL_CUBEMAP
Video frame is split into 6 faces of a cube, and arranged on a 3x2 layout.
Definition: spherical.h:61
avio_rb24
unsigned int avio_rb24(AVIOContext *s)
Definition: aviobuf.c:754
ff_mpa_check_header
static int ff_mpa_check_header(uint32_t header)
Definition: mpegaudiodecheader.h:62
MOVStreamContext::aes_ctx
struct AVAES * aes_ctx
Definition: isom.h:269
MOV_TREF_FLAG_ENHANCEMENT
#define MOV_TREF_FLAG_ENHANCEMENT
Definition: isom.h:418
cens_scheme_decrypt
static int cens_scheme_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
Definition: mov.c:8025
MOVContext::handbrake_version
int handbrake_version
Definition: isom.h:322
mov_free_stream_context
static void mov_free_stream_context(AVFormatContext *s, AVStream *st)
Definition: mov.c:9703
AVPacket::size
int size
Definition: packet.h:540
MOVStreamContext::ctts_sample
int ctts_sample
Definition: isom.h:192
NULL_IF_CONFIG_SMALL
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
Definition: internal.h:94
ff_codec_get_id
enum AVCodecID ff_codec_get_id(const AVCodecTag *tags, unsigned int tag)
Definition: utils.c:133
avformat_alloc_context
AVFormatContext * avformat_alloc_context(void)
Allocate an AVFormatContext.
Definition: options.c:162
MOVFragmentIndexItem
Definition: isom.h:146
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:7247
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:73
height
#define height
Definition: dsp.h:85
qtpalette.h
av_bprint_finalize
int av_bprint_finalize(AVBPrint *buf, char **ret_str)
Finalize a print buffer.
Definition: bprint.c:240
AVChannelLayout
An AVChannelLayout holds information about the channel layout of audio data.
Definition: channel_layout.h:317
FFStream
Definition: internal.h:132
mov_read_dref
static int mov_read_dref(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:632
mov_current_sample_dec
static void mov_current_sample_dec(MOVStreamContext *sc)
Definition: mov.c:4166
AVSphericalMapping::bound_right
uint32_t bound_right
Distance from the right edge.
Definition: spherical.h:181
MOVStsc::first
int first
Definition: isom.h:68
dst
uint8_t ptrdiff_t const uint8_t ptrdiff_t int intptr_t intptr_t int int16_t * dst
Definition: dsp.h:83
find_prev_closest_index
static int find_prev_closest_index(AVStream *st, AVIndexEntry *e_old, int nb_old, MOVCtts *ctts_data, int64_t ctts_count, int64_t timestamp_pts, int flag, int64_t *index, int64_t *ctts_index, int64_t *ctts_sample)
Find the closest previous frame to the timestamp_pts, in e_old index entries.
Definition: mov.c:3916
av_bswap32
#define av_bswap32
Definition: bswap.h:47
MOVStreamContext::stsz_sample_size
unsigned int stsz_sample_size
always contains sample size from stsz atom
Definition: isom.h:194
FF_MOV_FLAG_MFRA_AUTO
#define FF_MOV_FLAG_MFRA_AUTO
Definition: isom.h:442
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:425
MOVStreamContext::sgpd_sync
uint8_t * sgpd_sync
Definition: isom.h:234
start_time
static int64_t start_time
Definition: ffplay.c:326
uuid.h
mov_read_trun
static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5683
MOVStreamContext::stereo3d_size
size_t stereo3d_size
Definition: isom.h:254
avio_get_str
int avio_get_str(AVIOContext *pb, int maxlen, char *buf, int buflen)
Read a string from pb into buf.
Definition: aviobuf.c:866
mov_read_iprp
static int mov_read_iprp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:9050
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:366
AV_CODEC_ID_H263
@ AV_CODEC_ID_H263
Definition: codec_id.h:56
MOV_TFHD_STSD_ID
#define MOV_TFHD_STSD_ID
Definition: isom.h:385
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:1168
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:3227
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:248
MKBETAG
#define MKBETAG(a, b, c, d)
Definition: macros.h:56
AV_CODEC_ID_QDMC
@ AV_CODEC_ID_QDMC
Definition: codec_id.h:496
av_fourcc_make_string
char * av_fourcc_make_string(char *buf, uint32_t fourcc)
Fill the provided buffer with a string containing a FourCC (four-character code) representation.
Definition: utils.c:75
AV_RB32
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_WL16 uint64_t_TMPL AV_WB64 unsigned int_TMPL AV_RB32
Definition: bytestream.h:96
avpriv_report_missing_feature
void avpriv_report_missing_feature(void *avc, const char *msg,...) av_printf_format(2
Log a generic warning message about a missing feature.
av_aes_ctr_set_full_iv
void av_aes_ctr_set_full_iv(struct AVAESCTR *a, const uint8_t *iv)
Forcefully change the "full" 16-byte iv, including the counter.
Definition: aes_ctr.c:52
AVStreamGroup::iamf_audio_element
struct AVIAMFAudioElement * iamf_audio_element
Definition: avformat.h:1167
MOVStreamContext::coll
AVContentLightMetadata * coll
Definition: isom.h:259
aes_ctr.h
ff_format_io_close
int ff_format_io_close(AVFormatContext *s, AVIOContext **pb)
Definition: avformat.c:958
mov_parse_heif_items
static int mov_parse_heif_items(AVFormatContext *s)
Definition: mov.c:10252
HEIFItem::is_idat_relative
int is_idat_relative
Definition: isom.h:290
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:4013
MOVDref::path
char * path
Definition: isom.h:81
mov_current_sample_inc
static void mov_current_sample_inc(MOVStreamContext *sc)
Definition: mov.c:4154
AVStream::sample_aspect_ratio
AVRational sample_aspect_ratio
sample aspect ratio (0 if unknown)
Definition: avformat.h:826
FFInputFormat::p
AVInputFormat p
The public AVInputFormat.
Definition: demux.h:46
dovi_isom.h
AVPacket::dts
int64_t dts
Decompression timestamp in AVStream->time_base units; the time at which the packet is decompressed.
Definition: packet.h:538
mov_read_vexu_proj
static int mov_read_vexu_proj(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6691
fix_timescale
static void fix_timescale(MOVContext *c, MOVStreamContext *sc)
Definition: mov.c:5011
avio_r8
int avio_r8(AVIOContext *s)
Definition: aviobuf.c:603
IAMFAudioElement::substreams
IAMFSubStream * substreams
Definition: iamf.h:98
AVSphericalMapping::padding
uint32_t padding
Number of pixels to pad from the edge of each cube face.
Definition: spherical.h:194
a
The reader does not expect b to be semantically here and if the code is changed by maybe adding a a division or other the signedness will almost certainly be mistaken To avoid this confusion a new type was SUINT is the C unsigned type but it holds a signed int to use the same example SUINT a
Definition: undefined.txt:41
av_channel_layout_retype
int av_channel_layout_retype(AVChannelLayout *channel_layout, enum AVChannelOrder order, int flags)
Change the AVChannelOrder of a channel layout.
Definition: channel_layout.c:883
av_reallocp_array
int av_reallocp_array(void *ptr, size_t nmemb, size_t size)
Allocate, reallocate an array through a pointer to a pointer.
Definition: mem.c:225
AVIAMFAudioElement
Information on how to combine one or more audio streams, as defined in section 3.6 of IAMF.
Definition: iamf.h:356
AV_PRIMARY_EYE_NONE
@ AV_PRIMARY_EYE_NONE
Neither eye.
Definition: stereo3d.h:178
mov_read_default
static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:9289
AV_TIMECODE_FLAG_24HOURSMAX
@ AV_TIMECODE_FLAG_24HOURSMAX
timecode wraps after 24 hours
Definition: timecode.h:37
MOV_MP4_FPCM_TAG
#define MOV_MP4_FPCM_TAG
Definition: isom.h:462
ffio_ensure_seekback
int ffio_ensure_seekback(AVIOContext *s, int64_t buf_size)
Ensures that the requested seekback buffer size will be available.
Definition: aviobuf.c:1023
AVStreamGroupTileGrid::nb_tiles
unsigned int nb_tiles
Amount of tiles in the grid.
Definition: avformat.h:995
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:699
mov_read_packet
static int mov_read_packet(AVFormatContext *s, AVPacket *pkt)
Definition: mov.c:10771
offset
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf offset
Definition: writing_filters.txt:86
AVStreamGroupLCEVC::lcevc_index
unsigned int lcevc_index
Index of the LCEVC data stream in AVStreamGroup.
Definition: avformat.h:1112
AVStreamGroup::lcevc
struct AVStreamGroupLCEVC * lcevc
Definition: avformat.h:1170
attributes.h
AV_CODEC_ID_LCEVC
@ AV_CODEC_ID_LCEVC
Definition: codec_id.h:598
MOVEncryptionIndex::auxiliary_offsets_count
size_t auxiliary_offsets_count
Definition: isom.h:130
HEIFItem::vflip
int vflip
Definition: isom.h:288
AVPacket::flags
int flags
A combination of AV_PKT_FLAG values.
Definition: packet.h:545
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:223
av_encryption_info_free
void av_encryption_info_free(AVEncryptionInfo *info)
Frees the given encryption info object.
Definition: encryption_info.c:82
av_strstart
int av_strstart(const char *str, const char *pfx, const char **ptr)
Return non-zero if pfx is a prefix of str.
Definition: avstring.c:36
mov_find_reference_track
static AVStream * mov_find_reference_track(AVFormatContext *s, AVStream *st, int first_index)
Definition: mov.c:10313
AVSubsampleEncryptionInfo
This file is part of FFmpeg.
Definition: encryption_info.h:25
MOVFragmentIndexItem::stream_info
MOVFragmentStreamInfo * stream_info
Definition: isom.h:151
version
version
Definition: libkvazaar.c:321
AV_STREAM_GROUP_PARAMS_IAMF_AUDIO_ELEMENT
@ AV_STREAM_GROUP_PARAMS_IAMF_AUDIO_ELEMENT
Definition: avformat.h:1125
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:1201
ff_rfps_calculate
void ff_rfps_calculate(AVFormatContext *ic)
Definition: demux.c:2356
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:463
mov_read_clli
static int mov_read_clli(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6453
MOVStreamContext::chunk_offsets
int64_t * chunk_offsets
Definition: isom.h:175
AVStreamGroup::iamf_mix_presentation
struct AVIAMFMixPresentation * iamf_mix_presentation
Definition: avformat.h:1168
MOVFragmentIndex::item
MOVFragmentIndexItem * item
Definition: isom.h:159
AV_LOG_INFO
#define AV_LOG_INFO
Standard information.
Definition: log.h:220
MOVStreamContext::iamf
struct IAMFDemuxContext * iamf
Definition: isom.h:275
FFERROR_REDO
#define FFERROR_REDO
Returned by demuxers to indicate that data was consumed but discarded (ignored streams or junk data).
Definition: demux.h:176
av_encryption_init_info_alloc
AVEncryptionInitInfo * av_encryption_init_info_alloc(uint32_t system_id_size, uint32_t num_key_ids, uint32_t key_id_size, uint32_t data_size)
Allocates an AVEncryptionInitInfo structure and sub-pointers to hold the given sizes.
Definition: encryption_info.c:178
av_channel_layout_custom_init
int av_channel_layout_custom_init(AVChannelLayout *channel_layout, int nb_channels)
Initialize a custom channel layout with the specified number of channels.
Definition: channel_layout.c:230
MOVContext::decryption_key_len
int decryption_key_len
Definition: isom.h:355
av_aes_ctr_free
void av_aes_ctr_free(struct AVAESCTR *a)
Release an AVAESCTR context.
Definition: aes_ctr.c:83
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:7872
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:9161
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:85
flag
#define flag(name)
Definition: cbs_av1.c:474
AVStreamGroupTileGrid::nb_coded_side_data
int nb_coded_side_data
Amount of entries in coded_side_data.
Definition: avformat.h:1095
mov_metadata_creation_time
static void mov_metadata_creation_time(MOVContext *c, AVIOContext *pb, AVDictionary **metadata, int version)
Definition: mov.c:1828
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:59
MOVFragmentStreamInfo::next_trun_dts
int64_t next_trun_dts
Definition: isom.h:138
MOVStreamContext::stsc_index
unsigned int stsc_index
Definition: isom.h:185
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:7801
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:3307
mov_finalize_packet
static int mov_finalize_packet(AVFormatContext *s, AVStream *st, AVIndexEntry *sample, int64_t current_index, AVPacket *pkt)
Definition: mov.c:10713
MOVIndexRange
Definition: isom.h:162
mov_read_seek
static int mov_read_seek(AVFormatContext *s, int stream_index, int64_t sample_time, int flags)
Definition: mov.c:11082
bprint.h
MOVContext::advanced_editlist
int advanced_editlist
Definition: isom.h:327
MOVStreamContext::time_scale
int time_scale
Definition: isom.h:200
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:1072
MOVStreamContext::bytes_per_frame
unsigned int bytes_per_frame
Definition: isom.h:207
AVSphericalMapping::roll
int32_t roll
Rotation around the forward vector [-180, 180].
Definition: spherical.h:140
IAMFContext::nb_audio_elements
int nb_audio_elements
Definition: iamf.h:132
MOVIndexRange::end
int64_t end
Definition: isom.h:164
AV_CODEC_ID_NONE
@ AV_CODEC_ID_NONE
Definition: codec_id.h:50
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:256
AVPacket::pts
int64_t pts
Presentation timestamp in AVStream->time_base units; the time at which the decompressed packet will b...
Definition: packet.h:532
avio_internal.h
mov_read_trex
static int mov_read_trex(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5618
search_frag_timestamp
static int search_frag_timestamp(AVFormatContext *s, MOVFragmentIndex *frag_index, AVStream *st, int64_t timestamp)
Definition: mov.c:1701
HEIFItem::width
int width
Definition: isom.h:284
FLAGS
#define FLAGS
Definition: mov.c:11139
MOVStreamContext::stereo3d
AVStereo3D * stereo3d
Definition: isom.h:253
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:4206
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:7649
MOVDref::volume
char volume[28]
Definition: isom.h:83
mov_read_stsd
static int mov_read_stsd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:3162
internal.h
AV_SPHERICAL_FISHEYE
@ AV_SPHERICAL_FISHEYE
Fisheye projection (Apple).
Definition: spherical.h:84
AVCodecParameters::height
int height
Definition: codec_par.h:135
mov_rewrite_dvd_sub_extradata
static int mov_rewrite_dvd_sub_extradata(AVStream *st)
Definition: mov.c:2861
AV_TIME_BASE
#define AV_TIME_BASE
Internal time base represented as integer.
Definition: avutil.h:254
MOVStreamContext::stps_count
unsigned int stps_count
Definition: isom.h:187
AVCodecParameters::block_align
int block_align
Audio only.
Definition: codec_par.h:191
AV_CODEC_ID_TTML
@ AV_CODEC_ID_TTML
Definition: codec_id.h:580
rb_size
static int rb_size(AVIOContext *pb, int64_t *value, int size)
Definition: mov.c:8625
AVStereo3DPrimaryEye
AVStereo3DPrimaryEye
List of possible primary eyes.
Definition: stereo3d.h:174
av_malloc_array
#define av_malloc_array(a, b)
Definition: tableprint_vlc.h:31
AV_CODEC_ID_CAVS
@ AV_CODEC_ID_CAVS
Definition: codec_id.h:139
display.h
ff_mov_read_stsd_entries
int ff_mov_read_stsd_entries(MOVContext *c, AVIOContext *pb, int entries)
Definition: mov.c:3065
AV_FIELD_BB
@ AV_FIELD_BB
Bottom coded first, bottom displayed first.
Definition: defs.h:204
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:102
AVIAMFMixPresentation
Information on how to render and mix one or more AVIAMFAudioElement to generate the final audio outpu...
Definition: iamf.h:613
ff_id3v1_genre_str
const char *const ff_id3v1_genre_str[ID3v1_GENRE_MAX+1]
ID3v1 genres.
Definition: id3v1.c:26
MOVStreamContext::sample_sizes
unsigned int * sample_sizes
Definition: isom.h:196
MOVContext::frag_index
MOVFragmentIndex frag_index
Definition: isom.h:340
mov_read_vpcc
static int mov_read_vpcc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6281
AV_CODEC_ID_PCM_F64BE
@ AV_CODEC_ID_PCM_F64BE
Definition: codec_id.h:356
AV_CODEC_ID_HEVC
@ AV_CODEC_ID_HEVC
Definition: codec_id.h:228
value
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf default value
Definition: writing_filters.txt:86
av_url_split
void av_url_split(char *proto, int proto_size, char *authorization, int authorization_size, char *hostname, int hostname_size, int *port_ptr, char *path, int path_size, const char *url)
Split a URL string into components.
Definition: utils.c:351
MOVStreamContext::dref_id
int dref_id
Definition: isom.h:214
FFMIN
#define FFMIN(a, b)
Definition: macros.h:49
av_d2q
AVRational av_d2q(double d, int max)
Convert a double precision floating point number to a rational.
Definition: rational.c:106
fix_frag_index_entries
static void fix_frag_index_entries(MOVFragmentIndex *frag_index, int index, int id, int entries)
Definition: mov.c:1787
mov_finalize_stsd_codec
static int mov_finalize_stsd_codec(MOVContext *c, AVIOContext *pb, AVStream *st, MOVStreamContext *sc)
Definition: mov.c:2939
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:343
mov_read_mdcv
static int mov_read_mdcv(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6372
av_mallocz
void * av_mallocz(size_t size)
Allocate a memory block with alignment suitable for all memory accesses (including vectors if availab...
Definition: mem.c:256
AV_TIMECODE_FLAG_ALLOWNEGATIVE
@ AV_TIMECODE_FLAG_ALLOWNEGATIVE
negative time values are allowed
Definition: timecode.h:38
mov_read_mdat
static int mov_read_mdat(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1360
AV_CODEC_ID_VC1
@ AV_CODEC_ID_VC1
Definition: codec_id.h:122
demux.h
AV_DISPOSITION_DEPENDENT
#define AV_DISPOSITION_DEPENDENT
The stream is intended to be mixed with another stream before presentation.
Definition: avformat.h:709
MOVStreamContext::pb
AVIOContext * pb
Definition: isom.h:168
mov_read_keys
static int mov_read_keys(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5235
AVCodecParameters::color_range
enum AVColorRange color_range
Video only.
Definition: codec_par.h:166
AV_CH_SIDE_RIGHT
#define AV_CH_SIDE_RIGHT
Definition: channel_layout.h:185
len
int len
Definition: vorbis_enc_data.h:426
AV_CODEC_ID_JPEG2000
@ AV_CODEC_ID_JPEG2000
Definition: codec_id.h:140
MOVFragment::size
unsigned size
Definition: isom.h:103
MOV_TFHD_DEFAULT_SIZE
#define MOV_TFHD_DEFAULT_SIZE
Definition: isom.h:387
AVCOL_SPC_UNSPECIFIED
@ AVCOL_SPC_UNSPECIFIED
Definition: pixfmt.h:643
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:4582
AVCodecParameters::coded_side_data
AVPacketSideData * coded_side_data
Additional data associated with the entire stream.
Definition: codec_par.h:81
mov_read_svq3
static int mov_read_svq3(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2365
AVSHA
hash context
Definition: sha.c:35
AVCOL_RANGE_MPEG
@ AVCOL_RANGE_MPEG
Narrow or limited range content.
Definition: pixfmt.h:700
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:137
AV_IAMF_AUDIO_ELEMENT_TYPE_SCENE
@ AV_IAMF_AUDIO_ELEMENT_TYPE_SCENE
Definition: iamf.h:346
AVCodecParameters::field_order
enum AVFieldOrder field_order
Video only.
Definition: codec_par.h:161
av_get_packet
int av_get_packet(AVIOContext *s, AVPacket *pkt, int size)
Allocate and read the payload of a packet and initialize its fields with default values.
Definition: utils.c:91
mov_read_iinf
static int mov_read_iinf(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:8808
ff_read_string_to_bprint_overwrite
int64_t ff_read_string_to_bprint_overwrite(AVIOContext *s, struct AVBPrint *bp, int64_t max_len)
Read a whole null-terminated string of text from AVIOContext to an AVBPrint buffer overwriting its co...
Definition: aviobuf.c:860
AVStreamGroupTileGrid::horizontal
int horizontal
Offset in pixels from the left edge of the canvas where the tile should be placed.
Definition: avformat.h:1031
get_stream_info_time
static int64_t get_stream_info_time(MOVFragmentStreamInfo *frag_stream_info)
Definition: mov.c:1653
MP4TrackKindValueMapping
Definition: isom.h:465
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:4054
AVStreamGroupTileGrid::offsets
struct AVStreamGroupTileGrid::@364 * offsets
An nb_tiles sized array of offsets in pixels from the topleft edge of the canvas, indicating where ea...
AV_WB8
#define AV_WB8(p, d)
Definition: intreadwrite.h:392
MOVStreamContext::chunk_count
unsigned int chunk_count
Definition: isom.h:174
MOVStreamContext::data_size
int64_t data_size
Definition: isom.h:225
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:261
mov_read_tmcd
static int mov_read_tmcd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6270
mov_chan.h
AVStream::disposition
int disposition
Stream disposition - a combination of AV_DISPOSITION_* flags.
Definition: avformat.h:817
MOVStreamContext::ambient_size
size_t ambient_size
Definition: isom.h:262
tag
uint32_t tag
Definition: movenc.c:1876
AVStream::id
int id
Format-specific stream ID.
Definition: avformat.h:760
ret
ret
Definition: filter_design.txt:187
AVStream
Stream structure.
Definition: avformat.h:748
AV_LOG_FATAL
#define AV_LOG_FATAL
Something went wrong and recovery is not possible.
Definition: log.h:203
HEIFItem::extent_length
int64_t extent_length
Definition: isom.h:282
MOVEncryptionIndex::nb_encrypted_samples
unsigned int nb_encrypted_samples
Definition: isom.h:123
mov_read_senc
static int mov_read_senc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:7352
avio_seek
int64_t avio_seek(AVIOContext *s, int64_t offset, int whence)
fseek() equivalent for AVIOContext.
Definition: aviobuf.c:231
FFSWAP
#define FFSWAP(type, a, b)
Definition: macros.h:52
AVClass::class_name
const char * class_name
The name of the class; usually it is the same name as the context structure type to which the AVClass...
Definition: log.h:80
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:177
AVSphericalMapping::pitch
int32_t pitch
Rotation around the right vector [-90, 90].
Definition: spherical.h:139
AVStreamGroup::metadata
AVDictionary * metadata
Metadata that applies to the whole group.
Definition: avformat.h:1181
avio_rb16
unsigned int avio_rb16(AVIOContext *s)
Definition: aviobuf.c:746
AVStereo3D::type
enum AVStereo3DType type
How views are packed within the video.
Definition: stereo3d.h:207
MOVSbgp::index
unsigned int index
Definition: isom.h:117
HEIFItem::icc_profile_size
size_t icc_profile_size
Definition: isom.h:292
MOVContext::chapter_tracks
int * chapter_tracks
Definition: isom.h:323
AVSTREAM_PARSE_HEADERS
@ AVSTREAM_PARSE_HEADERS
Only parse headers, do not repack.
Definition: avformat.h:594
pos
unsigned int pos
Definition: spdifenc.c:414
avformat.h
MOVFragment::implicit_offset
uint64_t implicit_offset
Definition: isom.h:100
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:706
AV_AUDIO_SERVICE_TYPE_KARAOKE
@ AV_AUDIO_SERVICE_TYPE_KARAOKE
Definition: defs.h:233
mov_read_dmlp
static int mov_read_dmlp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:8316
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:210
MOVContext::time_scale
int time_scale
Definition: isom.h:305
id
enum AVCodecID id
Definition: dts2pts.c:367
mov_read_tfdt
static int mov_read_tfdt(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5644
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:5362
search_frag_moof_offset
static int search_frag_moof_offset(MOVFragmentIndex *frag_index, int64_t offset)
Definition: mov.c:1629
MOVFragment
Definition: isom.h:95
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:10632
MOVContext::use_mfra_for
int use_mfra_for
Definition: isom.h:337
AVEncryptionInfo
This describes encryption info for a packet.
Definition: encryption_info.h:43
add_ctts_entry
static int64_t add_ctts_entry(MOVCtts **ctts_data, unsigned int *ctts_count, unsigned int *allocated_size, int count, int duration)
Append a new ctts entry to ctts_data.
Definition: mov.c:4070
MOVStreamContext::encryption_index
MOVEncryptionIndex * encryption_index
Definition: isom.h:272
MIN_DATA_ENTRY_BOX_SIZE
#define MIN_DATA_ENTRY_BOX_SIZE
Definition: mov.c:631
AVStreamGroup
Definition: avformat.h:1134
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:754
avpriv_dv_init_demux
DVDemuxContext * avpriv_dv_init_demux(AVFormatContext *s)
Definition: dv.c:726
mov_seek_fragment
static int mov_seek_fragment(AVFormatContext *s, AVStream *st, int64_t timestamp)
Definition: mov.c:10931
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:2654
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:220
mov_read_dec3
static int mov_read_dec3(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1072
get_frag_time
static int64_t get_frag_time(AVFormatContext *s, AVStream *dst_st, MOVFragmentIndex *frag_index, int index)
Definition: mov.c:1663
MOVStreamContext::sample_size
unsigned int sample_size
may contain value calculated from stsd or value from stsz atom
Definition: isom.h:193
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:1188
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:243
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:3809
MOVFragment::moof_offset
uint64_t moof_offset
Definition: isom.h:99
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:2427
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:7010
MOVTrackExt::size
unsigned size
Definition: isom.h:111
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:129
AV_OPT_TYPE_INT
@ AV_OPT_TYPE_INT
Underlying C type is int.
Definition: opt.h:259
MOVContext::dv_fctx
AVFormatContext * dv_fctx
Definition: isom.h:316
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:440
AV_CODEC_ID_DVAUDIO
@ AV_CODEC_ID_DVAUDIO
Definition: codec_id.h:452
avformat_free_context
void avformat_free_context(AVFormatContext *s)
Free an AVFormatContext and all its streams.
Definition: avformat.c:149
MOVContext::aax_mode
unsigned int aax_mode
'aax' file has been detected
Definition: isom.h:342
mov_read_sv3d
static int mov_read_sv3d(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6554
avio_read
int avio_read(AVIOContext *s, unsigned char *buf, int size)
Read size bytes from AVIOContext into buf.
Definition: aviobuf.c:612
mov_aaxc_crypto
static int mov_aaxc_crypto(MOVContext *c)
Definition: mov.c:1469
mov_get_skip_samples
static int64_t mov_get_skip_samples(AVStream *st, int sample)
Definition: mov.c:11065
MOVFragmentIndex
Definition: isom.h:154
mov_read_infe
static int mov_read_infe(MOVContext *c, AVIOContext *pb, MOVAtom atom, int idx)
Definition: mov.c:8743
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:914
MOVStreamContext::track_end
int64_t track_end
used for dts generation in fragmented movie files
Definition: isom.h:228
MOVStreamContext::sgpd_sync_count
uint32_t sgpd_sync_count
Definition: isom.h:235
MOVContext::fragment
MOVFragment fragment
current fragment in moof atom
Definition: isom.h:318
AVIndexEntry::pos
int64_t pos
Definition: avformat.h:603
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
AVStreamGroupLCEVC::width
int width
Width of the final stream for presentation.
Definition: avformat.h:1116
MOVDref::type
uint32_t type
Definition: isom.h:80
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:866
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:82
AVMasteringDisplayMetadata::min_luminance
AVRational min_luminance
Min luminance of mastering display (cd/m^2).
Definition: mastering_display_metadata.h:52
MOVStreamContext::per_sample_iv_size
unsigned int per_sample_iv_size
Definition: isom.h:270
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:541
av_clip_uint8
#define av_clip_uint8
Definition: common.h:106
MOVFragmentIndexItem::nb_stream_info
int nb_stream_info
Definition: isom.h:150
avio_skip
int64_t avio_skip(AVIOContext *s, int64_t offset)
Skip given number of bytes forward.
Definition: aviobuf.c:318
export_orphan_timecode
static void export_orphan_timecode(AVFormatContext *s)
Definition: mov.c:9833
mov_read_sbas
static int mov_read_sbas(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2498
MOVStreamContext::has_sidx
int has_sidx
Definition: isom.h:266
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:107
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
FFStream::index_entries
AVIndexEntry * index_entries
Only used if the format does not support seeking natively.
Definition: internal.h:188
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:167
mov_read_dpxe
static int mov_read_dpxe(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2252
AVIAMFSubmix::nb_elements
unsigned int nb_elements
Number of elements in the submix.
Definition: iamf.h:572
MOVFragmentStreamInfo::id
int id
Definition: isom.h:134
AVIO_FLAG_READ
#define AVIO_FLAG_READ
read-only
Definition: avio.h:617
AV_PKT_DATA_AUDIO_SERVICE_TYPE
@ AV_PKT_DATA_AUDIO_SERVICE_TYPE
This side data should be associated with an audio stream and corresponds to enum AVAudioServiceType.
Definition: packet.h:117
av_spherical_alloc
AVSphericalMapping * av_spherical_alloc(size_t *size)
Allocate a AVSphericalVideo structure and initialize its fields to default values.
Definition: spherical.c:26
AV_OPT_FLAG_DECODING_PARAM
#define AV_OPT_FLAG_DECODING_PARAM
A generic parameter which can be set by the user for demuxing or decoding.
Definition: opt.h:356
MOVContext::thmb_item_id
int thmb_item_id
Definition: isom.h:367
mov_read_rtmd_track
static int mov_read_rtmd_track(AVFormatContext *s, AVStream *st)
Definition: mov.c:9618
AVMEDIA_TYPE_VIDEO
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:201
read_probe
static int read_probe(const AVProbeData *p)
Definition: cdg.c:30
MOVStreamContext::pb_is_copied
int pb_is_copied
Definition: isom.h:170
AV_CODEC_ID_PCM_S32LE
@ AV_CODEC_ID_PCM_S32LE
Definition: codec_id.h:342
AVCodecParameters::bits_per_coded_sample
int bits_per_coded_sample
The number of bits per sample in the codedwords.
Definition: codec_par.h:110
mov_parse_tiles
static int mov_parse_tiles(AVFormatContext *s)
Definition: mov.c:10168
mem.h
MOVElst::time
int64_t time
Definition: isom.h:75
HEIFGrid
Definition: isom.h:295
mov_read_iref_dimg
static int mov_read_iref_dimg(MOVContext *c, AVIOContext *pb, int version)
Definition: mov.c:8868
mov_read_pcmc
static int mov_read_pcmc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1981
build_open_gop_key_points
static int build_open_gop_key_points(AVStream *st)
Definition: mov.c:4519
mov_parse_stsd_audio
static void mov_parse_stsd_audio(MOVContext *c, AVIOContext *pb, AVStream *st, MOVStreamContext *sc)
Definition: mov.c:2712
IAMFContext::mix_presentations
IAMFMixPresentation ** mix_presentations
Definition: iamf.h:133
AV_CODEC_ID_PCM_U8
@ AV_CODEC_ID_PCM_U8
Definition: codec_id.h:339
MOVContext::trak_index
int trak_index
Index of the current 'trak'.
Definition: isom.h:312
mov_read_timecode_track
static int mov_read_timecode_track(AVFormatContext *s, AVStream *st)
Definition: mov.c:9644
HEIFGrid::item
HEIFItem * item
Definition: isom.h:296
AVSphericalMapping::bound_left
uint32_t bound_left
Distance from the left edge.
Definition: spherical.h:179
mov_read_mac_string
static int mov_read_mac_string(MOVContext *c, AVIOContext *pb, int len, char *dst, int dstlen)
Definition: mov.c:170
MOVEncryptionIndex::auxiliary_info_sizes
uint8_t * auxiliary_info_sizes
Definition: isom.h:126
MOVFragment::stsd_id
unsigned stsd_id
Definition: isom.h:101
AVCodecParameters::video_delay
int video_delay
Video only.
Definition: codec_par.h:175
HEIFGrid::tile_id_list
int16_t * tile_id_list
Definition: isom.h:298
avpriv_request_sample
#define avpriv_request_sample(...)
Definition: tableprint_vlc.h:36
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:449
AV_CHANNEL_LAYOUT_MONO
#define AV_CHANNEL_LAYOUT_MONO
Definition: channel_layout.h:392
AV_CODEC_ID_PCM_F64LE
@ AV_CODEC_ID_PCM_F64LE
Definition: codec_id.h:357
AVStreamGroupTileGrid::height
int height
Height of the final image for presentation.
Definition: avformat.h:1082
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:9851
av_free
#define av_free(p)
Definition: tableprint_vlc.h:33
AVDictionaryEntry
Definition: dict.h:89
av_add_q
AVRational av_add_q(AVRational b, AVRational c)
Add two rationals.
Definition: rational.c:93
AVCodecParameters::codec_id
enum AVCodecID codec_id
Specific type of the encoded data (the codec used).
Definition: codec_par.h:55
AVStereo3DView
AVStereo3DView
List of possible view types.
Definition: stereo3d.h:149
AVPacket
This structure stores compressed data.
Definition: packet.h:516
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:10328
mov_read_hfov
static int mov_read_hfov(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6981
AV_OPT_TYPE_BOOL
@ AV_OPT_TYPE_BOOL
Underlying C type is int.
Definition: opt.h:327
cr
static double cr(void *priv, double x, double y)
Definition: vf_geq.c:248
MOVStreamContext::stps_data
unsigned * stps_data
partial sync sample for mpeg-2 open gop
Definition: isom.h:188
AV_CODEC_ID_ADPCM_IMA_WAV
@ AV_CODEC_ID_ADPCM_IMA_WAV
Definition: codec_id.h:374
MOVContext::nb_heif_item
int nb_heif_item
Definition: isom.h:364
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:34
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:88
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:237
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:559
FFInputFormat
Definition: demux.h:42
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:6753
AV_CODEC_ID_ILBC
@ AV_CODEC_ID_ILBC
Definition: codec_id.h:505
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:395
MOVStreamContext::tmcd_flags
uint32_t tmcd_flags
tmcd track flags
Definition: isom.h:226
int32_t
int32_t
Definition: audioconvert.c:56
HEIFItem::rotation
int rotation
Definition: isom.h:286
MOVAtom::type
uint32_t type
Definition: isom.h:89
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:593
parse_timecode_in_framenum_format
static int parse_timecode_in_framenum_format(AVFormatContext *s, AVStream *st, int64_t value, int flags)
Definition: mov.c:9604
MOVStreamContext::tmcd_nb_frames
uint8_t tmcd_nb_frames
tmcd number of frames per tick / second
Definition: isom.h:227
AVIAMFSubmixElement
Submix element as defined in section 3.7 of IAMF.
Definition: iamf.h:446
replaygain.h
MOVFragmentIndexItem::headers_read
int headers_read
Definition: isom.h:148
AV_CODEC_ID_VP8
@ AV_CODEC_ID_VP8
Definition: codec_id.h:192
flags
#define flags(name, subs,...)
Definition: cbs_av1.c:482
AVERROR_BUG
#define AVERROR_BUG
Internal bug, also see AVERROR_BUG2.
Definition: error.h:52
MOVStreamContext::start_pad
int start_pad
amount of samples to skip due to enc-dec delay
Definition: isom.h:229
MP4TrackKindValueMapping::value
const char * value
Definition: isom.h:467
AVStereo3DType
AVStereo3DType
List of possible 3D Types.
Definition: stereo3d.h:48
MOVDref::filename
char filename[64]
Definition: isom.h:84
ff_mov_read_chnl
int ff_mov_read_chnl(AVFormatContext *s, AVIOContext *pb, AVStream *st)
Read 'chnl' tag from the input stream.
Definition: mov_chan.c:729
MOVStsc::count
int count
Definition: isom.h:69
AV_CODEC_ID_PCM_F32LE
@ AV_CODEC_ID_PCM_F32LE
Definition: codec_id.h:355
ff_mov_demuxer
const FFInputFormat ff_mov_demuxer
Definition: mov.c:11200
AVCodecParameters::bit_rate
int64_t bit_rate
The average bitrate of the encoded data (in bits per second).
Definition: codec_par.h:97
MOVStts::count
unsigned int count
Definition: isom.h:58
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
MOVStreamContext::display_matrix
int32_t * display_matrix
Definition: isom.h:252
MOVContext::heif_grid
HEIFGrid * heif_grid
Definition: isom.h:365
MOVStreamContext::min_sample_duration
uint32_t min_sample_duration
Definition: isom.h:240
MOVStreamContext::current_index
int64_t current_index
Definition: isom.h:204
AVERROR_INVALIDDATA
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:61
ff_mov_track_kind_table
const struct MP4TrackKindMapping ff_mov_track_kind_table[]
Definition: isom.c:451
get_curr_st
static AVStream * get_curr_st(MOVContext *c)
Get the current stream in the parsing process.
Definition: mov.c:214
MOVFragmentStreamInfo::index_entry
int index_entry
Definition: isom.h:141
cenc_decrypt
static int cenc_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
Definition: mov.c:8156
MOVStreamContext::format
uint32_t format
Definition: isom.h:264
MKTAG
#define MKTAG(a, b, c, d)
Definition: macros.h:55
ffio_read_size
int ffio_read_size(AVIOContext *s, unsigned char *buf, int size)
Read size bytes from AVIOContext into buf.
Definition: aviobuf.c:662
MOVStreamContext::sync_group_count
unsigned int sync_group_count
Definition: isom.h:232
MOVContext::bitrates_count
int bitrates_count
Definition: isom.h:335
AV_CODEC_ID_VORBIS
@ AV_CODEC_ID_VORBIS
Definition: codec_id.h:451
AVDictionaryEntry::value
char * value
Definition: dict.h:91
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:797
MOVStreamContext::id
int id
AVStream id.
Definition: isom.h:171
MOVStreamContext::samples_per_frame
unsigned int samples_per_frame
Definition: isom.h:208
MOVElst::duration
int64_t duration
Definition: isom.h:74
ac3tab.h
avstring.h
mov_read_ispe
static int mov_read_ispe(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:8989
width
#define width
Definition: dsp.h:85
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:8951
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:1234
mov_read_mfra
static int mov_read_mfra(MOVContext *c, AVIOContext *f)
Definition: mov.c:9906
AV_CODEC_ID_FLV1
@ AV_CODEC_ID_FLV1
Definition: codec_id.h:73
mov_metadata_int8_no_padding
static int mov_metadata_int8_no_padding(MOVContext *c, AVIOContext *pb, unsigned len, const char *key)
Definition: mov.c:126
flac.h
AVStreamGroupTileGrid::idx
unsigned int idx
Index of the stream in the group this tile references.
Definition: avformat.h:1026
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:1574
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:8420
MOVContext::heif_item
HEIFItem ** heif_item
Definition: isom.h:363
MOVStreamContext::stts_count
unsigned int stts_count
Definition: isom.h:176
MOV_TRUN_SAMPLE_CTS
#define MOV_TRUN_SAMPLE_CTS
Definition: isom.h:397
AV_OPT_TYPE_CONST
@ AV_OPT_TYPE_CONST
Special option type for declaring named constants.
Definition: opt.h:299
MOV_ISMV_TTML_TAG
#define MOV_ISMV_TTML_TAG
Definition: isom.h:460
snprintf
#define snprintf
Definition: snprintf.h:34
IAMFMixPresentation::mix_presentation_id
unsigned int mix_presentation_id
Definition: iamf.h:114
AVCodecParameters::initial_padding
int initial_padding
Audio only.
Definition: codec_par.h:203
AV_CODEC_ID_PCM_S24BE
@ AV_CODEC_ID_PCM_S24BE
Definition: codec_id.h:347
get_eia608_packet
static int get_eia608_packet(AVIOContext *pb, AVPacket *pkt, int size)
Definition: mov.c:10692
mov_read_st3d
static int mov_read_st3d(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6507
mov_read_imir
static int mov_read_imir(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:9031
is_open_key_sample
static int is_open_key_sample(const MOVStreamContext *sc, int sample)
Definition: mov.c:10950
mov_read_dvc1
static int mov_read_dvc1(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2473
MOVStreamContext::elst_count
unsigned int elst_count
Definition: isom.h:190
av_color_transfer_name
const char * av_color_transfer_name(enum AVColorTransferCharacteristic transfer)
Definition: pixdesc.c:3525
avpriv_dict_set_timestamp
int avpriv_dict_set_timestamp(AVDictionary **dict, const char *key, int64_t timestamp)
Set a dictionary value to an ISO-8601 compliant timestamp string.
Definition: dict.c:278
AVChannelCustom::id
enum AVChannel id
Definition: channel_layout.h:282
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:2189
AV_WL16A
#define AV_WL16A(p, v)
Definition: intreadwrite.h:557
AV_RB64
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_WL16 uint64_t_TMPL AV_RB64
Definition: bytestream.h:95
AVSphericalMapping::yaw
int32_t yaw
Rotation around the up vector [-180, 180].
Definition: spherical.h:138
src
#define src
Definition: vp8dsp.c:248
mov_read_chapters
static void mov_read_chapters(AVFormatContext *s)
Definition: mov.c:9505
AV_CODEC_ID_DNXHD
@ AV_CODEC_ID_DNXHD
Definition: codec_id.h:151
channel
channel
Definition: ebur128.h:39
MOVStreamContext::default_encrypted_sample
AVEncryptionInfo * default_encrypted_sample
Definition: isom.h:271
MOVContext::cur_item_id
int cur_item_id
Definition: isom.h:362
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:103
AVFMT_EVENT_FLAG_METADATA_UPDATED
#define AVFMT_EVENT_FLAG_METADATA_UPDATED
Definition: avformat.h:1677
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:331
MOVContext::found_iinf
int found_iinf
'iinf' atom has been found
Definition: isom.h:309
MOVContext::meta_keys_count
unsigned meta_keys_count
Definition: isom.h:314
avcodec_parameters_copy
int avcodec_parameters_copy(AVCodecParameters *dst, const AVCodecParameters *src)
Copy the contents of src to dst.
Definition: codec_par.c:106
iamf_reader.h
AVStreamGroupTileGrid::background
uint8_t background[4]
The pixel value per channel in RGBA format used if no pixel of any tile is located at a particular pi...
Definition: avformat.h:1046
MOVStreamContext::palette
uint32_t palette[256]
Definition: isom.h:223
cenc_scheme_decrypt
static int cenc_scheme_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
Definition: mov.c:7912
MOVFragment::track_id
unsigned track_id
Definition: isom.h:97
mov_read_hdlr
static int mov_read_hdlr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:776
mov_parse_stsd_data
static int mov_parse_stsd_data(MOVContext *c, AVIOContext *pb, AVStream *st, MOVStreamContext *sc, int64_t size)
Definition: mov.c:2893
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:328
AV_RB16
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_WL16 uint64_t_TMPL AV_WB64 unsigned int_TMPL AV_WB32 unsigned int_TMPL AV_WB24 unsigned int_TMPL AV_RB16
Definition: bytestream.h:98
av_realloc
void * av_realloc(void *ptr, size_t size)
Allocate, reallocate, or free a block of memory.
Definition: mem.c:155
av_encryption_init_info_add_side_data
uint8_t * av_encryption_init_info_add_side_data(const AVEncryptionInitInfo *info, size_t *side_data_size)
Allocates and initializes side data that holds a copy of the given encryption init info.
Definition: encryption_info.c:292
av_fourcc2str
#define av_fourcc2str(fourcc)
Definition: avutil.h:348
ff_mov_read_chan
int ff_mov_read_chan(AVFormatContext *s, AVIOContext *pb, AVStream *st, int64_t size)
Read 'chan' tag from the input stream.
Definition: mov_chan.c:524
av_index_search_timestamp
int av_index_search_timestamp(AVStream *st, int64_t timestamp, int flags)
Get the index for a specific timestamp.
Definition: seek.c:245
mov_read_pitm
static int mov_read_pitm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:8644
MOVContext::ignore_chapters
int ignore_chapters
Definition: isom.h:329
mov_read_dac3
static int mov_read_dac3(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:847
MP4TrackKindMapping
Definition: isom.h:470
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:227
AV_DISPOSITION_NON_DIEGETIC
#define AV_DISPOSITION_NON_DIEGETIC
The stream is intended to be mixed with a spatial audio track.
Definition: avformat.h:686
avio_feof
int avio_feof(AVIOContext *s)
Similar to feof() but also returns nonzero on read errors.
Definition: aviobuf.c:346
mc
#define mc
Definition: vf_colormatrix.c:100
MOVStreamContext::ffindex
int ffindex
AVStream index.
Definition: isom.h:172
HEIFItem::extent_offset
int64_t extent_offset
Definition: isom.h:283
mov_read_stsz
static int mov_read_stsz(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:3424