FFmpeg
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
mov.c
Go to the documentation of this file.
1 /*
2  * MOV demuxer
3  * Copyright (c) 2001 Fabrice Bellard
4  * Copyright (c) 2009 Baptiste Coudurier <baptiste dot coudurier at gmail dot com>
5  *
6  * first version by Francois Revol <revol@free.fr>
7  * seek function by Gael Chardon <gael.dev@4now.net>
8  *
9  * This file is part of FFmpeg.
10  *
11  * FFmpeg is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU Lesser General Public
13  * License as published by the Free Software Foundation; either
14  * version 2.1 of the License, or (at your option) any later version.
15  *
16  * FFmpeg is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19  * Lesser General Public License for more details.
20  *
21  * You should have received a copy of the GNU Lesser General Public
22  * License along with FFmpeg; if not, write to the Free Software
23  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
24  */
25 
26 #include "config_components.h"
27 
28 #include <inttypes.h>
29 #include <limits.h>
30 #include <stdint.h>
31 
32 #include "libavutil/attributes.h"
33 #include "libavutil/bprint.h"
35 #include "libavutil/internal.h"
36 #include "libavutil/intreadwrite.h"
37 #include "libavutil/intfloat.h"
38 #include "libavutil/mathematics.h"
39 #include "libavutil/avassert.h"
40 #include "libavutil/avstring.h"
41 #include "libavutil/dict.h"
42 #include "libavutil/display.h"
43 #include "libavutil/mem.h"
44 #include "libavutil/opt.h"
45 #include "libavutil/aes.h"
46 #include "libavutil/aes_ctr.h"
47 #include "libavutil/pixdesc.h"
48 #include "libavutil/sha.h"
49 #include "libavutil/spherical.h"
50 #include "libavutil/stereo3d.h"
51 #include "libavutil/timecode.h"
52 #include "libavutil/uuid.h"
53 #include "libavcodec/ac3tab.h"
54 #include "libavcodec/flac.h"
55 #include "libavcodec/hevc/hevc.h"
57 #include "libavcodec/mlp_parse.h"
58 #include "avformat.h"
59 #include "internal.h"
60 #include "avio_internal.h"
61 #include "demux.h"
62 #include "dvdclut.h"
63 #include "iamf_parse.h"
64 #include "iamf_reader.h"
65 #include "dovi_isom.h"
66 #include "riff.h"
67 #include "isom.h"
68 #include "libavcodec/get_bits.h"
69 #include "id3v1.h"
70 #include "mov_chan.h"
71 #include "replaygain.h"
72 
73 #if CONFIG_ZLIB
74 #include <zlib.h>
75 #endif
76 
77 #include "qtpalette.h"
78 
79 /* those functions parse an atom */
80 /* links atom IDs to parse functions */
81 typedef struct MOVParseTableEntry {
82  uint32_t type;
83  int (*parse)(MOVContext *ctx, AVIOContext *pb, MOVAtom atom);
85 
86 static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom);
87 static int mov_read_mfra(MOVContext *c, AVIOContext *f);
89 
91  unsigned len, const char *key)
92 {
93  char buf[16];
94 
95  short current, total = 0;
96  avio_rb16(pb); // unknown
97  current = avio_rb16(pb);
98  if (len >= 6)
99  total = avio_rb16(pb);
100  if (!total)
101  snprintf(buf, sizeof(buf), "%d", current);
102  else
103  snprintf(buf, sizeof(buf), "%d/%d", current, total);
104  c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
105  av_dict_set(&c->fc->metadata, key, buf, 0);
106 
107  return 0;
108 }
109 
111  unsigned len, const char *key)
112 {
113  /* bypass padding bytes */
114  avio_r8(pb);
115  avio_r8(pb);
116  avio_r8(pb);
117 
118  c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
119  av_dict_set_int(&c->fc->metadata, key, avio_r8(pb), 0);
120 
121  return 0;
122 }
123 
125  unsigned len, const char *key)
126 {
127  c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
128  av_dict_set_int(&c->fc->metadata, key, avio_r8(pb), 0);
129 
130  return 0;
131 }
132 
134  unsigned len, const char *key)
135 {
136  short genre;
137 
138  avio_r8(pb); // unknown
139 
140  genre = avio_r8(pb);
141  if (genre < 1 || genre > ID3v1_GENRE_MAX)
142  return 0;
143  c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
144  av_dict_set(&c->fc->metadata, key, ff_id3v1_genre_str[genre-1], 0);
145 
146  return 0;
147 }
148 
149 static const uint32_t mac_to_unicode[128] = {
150  0x00C4,0x00C5,0x00C7,0x00C9,0x00D1,0x00D6,0x00DC,0x00E1,
151  0x00E0,0x00E2,0x00E4,0x00E3,0x00E5,0x00E7,0x00E9,0x00E8,
152  0x00EA,0x00EB,0x00ED,0x00EC,0x00EE,0x00EF,0x00F1,0x00F3,
153  0x00F2,0x00F4,0x00F6,0x00F5,0x00FA,0x00F9,0x00FB,0x00FC,
154  0x2020,0x00B0,0x00A2,0x00A3,0x00A7,0x2022,0x00B6,0x00DF,
155  0x00AE,0x00A9,0x2122,0x00B4,0x00A8,0x2260,0x00C6,0x00D8,
156  0x221E,0x00B1,0x2264,0x2265,0x00A5,0x00B5,0x2202,0x2211,
157  0x220F,0x03C0,0x222B,0x00AA,0x00BA,0x03A9,0x00E6,0x00F8,
158  0x00BF,0x00A1,0x00AC,0x221A,0x0192,0x2248,0x2206,0x00AB,
159  0x00BB,0x2026,0x00A0,0x00C0,0x00C3,0x00D5,0x0152,0x0153,
160  0x2013,0x2014,0x201C,0x201D,0x2018,0x2019,0x00F7,0x25CA,
161  0x00FF,0x0178,0x2044,0x20AC,0x2039,0x203A,0xFB01,0xFB02,
162  0x2021,0x00B7,0x201A,0x201E,0x2030,0x00C2,0x00CA,0x00C1,
163  0x00CB,0x00C8,0x00CD,0x00CE,0x00CF,0x00CC,0x00D3,0x00D4,
164  0xF8FF,0x00D2,0x00DA,0x00DB,0x00D9,0x0131,0x02C6,0x02DC,
165  0x00AF,0x02D8,0x02D9,0x02DA,0x00B8,0x02DD,0x02DB,0x02C7,
166 };
167 
169  char *dst, int dstlen)
170 {
171  char *p = dst;
172  char *end = dst+dstlen-1;
173  int i;
174 
175  for (i = 0; i < len; i++) {
176  uint8_t t, c = avio_r8(pb);
177 
178  if (p >= end)
179  continue;
180 
181  if (c < 0x80)
182  *p++ = c;
183  else if (p < end)
184  PUT_UTF8(mac_to_unicode[c-0x80], t, if (p < end) *p++ = t;);
185  }
186  *p = 0;
187  return p - dst;
188 }
189 
190 /**
191  * Get the current item in the parsing process.
192  */
194 {
195  HEIFItem *item = NULL;
196 
197  for (int i = 0; i < c->nb_heif_item; i++) {
198  if (!c->heif_item[i] || c->heif_item[i]->item_id != c->cur_item_id)
199  continue;
200 
201  item = c->heif_item[i];
202  break;
203  }
204 
205  return item;
206 }
207 
208 /**
209  * Get the current stream in the parsing process. This can either be the
210  * latest stream added to the context, or the stream referenced by an item.
211  */
213 {
214  AVStream *st = NULL;
215  HEIFItem *item;
216 
217  if (c->fc->nb_streams < 1)
218  return NULL;
219 
220  if (c->cur_item_id == -1)
221  return c->fc->streams[c->fc->nb_streams-1];
222 
223  item = heif_cur_item(c);
224  if (item)
225  st = item->st;
226 
227  return st;
228 }
229 
230 static int mov_read_covr(MOVContext *c, AVIOContext *pb, int type, int len)
231 {
232  AVStream *st;
233  MOVStreamContext *sc;
234  enum AVCodecID id;
235  int ret;
236 
237  switch (type) {
238  case 0xd: id = AV_CODEC_ID_MJPEG; break;
239  case 0xe: id = AV_CODEC_ID_PNG; break;
240  case 0x1b: id = AV_CODEC_ID_BMP; break;
241  default:
242  av_log(c->fc, AV_LOG_WARNING, "Unknown cover type: 0x%x.\n", type);
243  avio_skip(pb, len);
244  return 0;
245  }
246 
247  sc = av_mallocz(sizeof(*sc));
248  if (!sc)
249  return AVERROR(ENOMEM);
250  ret = ff_add_attached_pic(c->fc, NULL, pb, NULL, len);
251  if (ret < 0) {
252  av_free(sc);
253  return ret;
254  }
255  st = c->fc->streams[c->fc->nb_streams - 1];
256  st->priv_data = sc;
257  sc->id = st->id;
258  sc->refcount = 1;
259 
260  if (st->attached_pic.size >= 8 && id != AV_CODEC_ID_BMP) {
261  if (AV_RB64(st->attached_pic.data) == 0x89504e470d0a1a0a) {
262  id = AV_CODEC_ID_PNG;
263  } else {
264  id = AV_CODEC_ID_MJPEG;
265  }
266  }
267  st->codecpar->codec_id = id;
268 
269  return 0;
270 }
271 
272 // 3GPP TS 26.244
273 static int mov_metadata_loci(MOVContext *c, AVIOContext *pb, unsigned len)
274 {
275  char language[4] = { 0 };
276  char buf[200], place[100];
277  uint16_t langcode = 0;
278  double longitude, latitude, altitude;
279  const char *key = "location";
280 
281  if (len < 4 + 2 + 1 + 1 + 4 + 4 + 4) {
282  av_log(c->fc, AV_LOG_ERROR, "loci too short\n");
283  return AVERROR_INVALIDDATA;
284  }
285 
286  avio_skip(pb, 4); // version+flags
287  langcode = avio_rb16(pb);
288  ff_mov_lang_to_iso639(langcode, language);
289  len -= 6;
290 
291  len -= avio_get_str(pb, len, place, sizeof(place));
292  if (len < 1) {
293  av_log(c->fc, AV_LOG_ERROR, "place name too long\n");
294  return AVERROR_INVALIDDATA;
295  }
296  avio_skip(pb, 1); // role
297  len -= 1;
298 
299  if (len < 12) {
300  av_log(c->fc, AV_LOG_ERROR,
301  "loci too short (%u bytes left, need at least %d)\n", len, 12);
302  return AVERROR_INVALIDDATA;
303  }
304  longitude = ((int32_t) avio_rb32(pb)) / (float) (1 << 16);
305  latitude = ((int32_t) avio_rb32(pb)) / (float) (1 << 16);
306  altitude = ((int32_t) avio_rb32(pb)) / (float) (1 << 16);
307 
308  // Try to output in the same format as the ?xyz field
309  snprintf(buf, sizeof(buf), "%+08.4f%+09.4f", latitude, longitude);
310  if (altitude)
311  av_strlcatf(buf, sizeof(buf), "%+f", altitude);
312  av_strlcatf(buf, sizeof(buf), "/%s", place);
313 
314  if (*language && strcmp(language, "und")) {
315  char key2[16];
316  snprintf(key2, sizeof(key2), "%s-%s", key, language);
317  av_dict_set(&c->fc->metadata, key2, buf, 0);
318  }
319  c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
320  return av_dict_set(&c->fc->metadata, key, buf, 0);
321 }
322 
323 static int mov_metadata_hmmt(MOVContext *c, AVIOContext *pb, unsigned len)
324 {
325  int i, n_hmmt;
326 
327  if (len < 2)
328  return 0;
329  if (c->ignore_chapters)
330  return 0;
331 
332  n_hmmt = avio_rb32(pb);
333  if (n_hmmt > len / 4)
334  return AVERROR_INVALIDDATA;
335  for (i = 0; i < n_hmmt && !pb->eof_reached; i++) {
336  int moment_time = avio_rb32(pb);
337  avpriv_new_chapter(c->fc, i, av_make_q(1, 1000), moment_time, AV_NOPTS_VALUE, NULL);
338  }
339  if (avio_feof(pb))
340  return AVERROR_INVALIDDATA;
341  return 0;
342 }
343 
345 {
346  char tmp_key[AV_FOURCC_MAX_STRING_SIZE] = {0};
347  char key2[32], language[4] = {0};
348  char *str = NULL;
349  const char *key = NULL;
350  uint16_t langcode = 0;
351  uint32_t data_type = 0, str_size_alloc;
352  uint64_t str_size;
353  int (*parse)(MOVContext*, AVIOContext*, unsigned, const char*) = NULL;
354  int raw = 0;
355  int num = 0;
357 
358  if (c->trak_index >= 0 && c->trak_index < c->fc->nb_streams)
359  metadata = &c->fc->streams[c->trak_index]->metadata;
360  else
361  metadata = &c->fc->metadata;
362 
363  switch (atom.type) {
364  case MKTAG( '@','P','R','M'): key = "premiere_version"; raw = 1; break;
365  case MKTAG( '@','P','R','Q'): key = "quicktime_version"; raw = 1; break;
366  case MKTAG( 'X','M','P','_'):
367  if (c->export_xmp) { key = "xmp"; raw = 1; } break;
368  case MKTAG( 'a','A','R','T'): key = "album_artist"; break;
369  case MKTAG( 'a','k','I','D'): key = "account_type";
371  case MKTAG( 'a','p','I','D'): key = "account_id"; break;
372  case MKTAG( 'c','a','t','g'): key = "category"; break;
373  case MKTAG( 'c','p','i','l'): key = "compilation";
375  case MKTAG( 'c','p','r','t'): key = "copyright"; break;
376  case MKTAG( 'd','e','s','c'): key = "description"; break;
377  case MKTAG( 'd','i','s','k'): key = "disc";
379  case MKTAG( 'e','g','i','d'): key = "episode_uid";
381  case MKTAG( 'F','I','R','M'): key = "firmware"; raw = 1; break;
382  case MKTAG( 'g','n','r','e'): key = "genre";
383  parse = mov_metadata_gnre; break;
384  case MKTAG( 'h','d','v','d'): key = "hd_video";
386  case MKTAG( 'H','M','M','T'):
387  return mov_metadata_hmmt(c, pb, atom.size);
388  case MKTAG( 'k','e','y','w'): key = "keywords"; break;
389  case MKTAG( 'l','d','e','s'): key = "synopsis"; break;
390  case MKTAG( 'l','o','c','i'):
391  return mov_metadata_loci(c, pb, atom.size);
392  case MKTAG( 'm','a','n','u'): key = "make"; break;
393  case MKTAG( 'm','o','d','l'): key = "model"; break;
394  case MKTAG( 'p','c','s','t'): key = "podcast";
396  case MKTAG( 'p','g','a','p'): key = "gapless_playback";
398  case MKTAG( 'p','u','r','d'): key = "purchase_date"; break;
399  case MKTAG( 'r','t','n','g'): key = "rating";
401  case MKTAG( 's','o','a','a'): key = "sort_album_artist"; break;
402  case MKTAG( 's','o','a','l'): key = "sort_album"; break;
403  case MKTAG( 's','o','a','r'): key = "sort_artist"; break;
404  case MKTAG( 's','o','c','o'): key = "sort_composer"; break;
405  case MKTAG( 's','o','n','m'): key = "sort_name"; break;
406  case MKTAG( 's','o','s','n'): key = "sort_show"; break;
407  case MKTAG( 's','t','i','k'): key = "media_type";
409  case MKTAG( 't','r','k','n'): key = "track";
411  case MKTAG( 't','v','e','n'): key = "episode_id"; break;
412  case MKTAG( 't','v','e','s'): key = "episode_sort";
414  case MKTAG( 't','v','n','n'): key = "network"; break;
415  case MKTAG( 't','v','s','h'): key = "show"; break;
416  case MKTAG( 't','v','s','n'): key = "season_number";
418  case MKTAG(0xa9,'A','R','T'): key = "artist"; break;
419  case MKTAG(0xa9,'P','R','D'): key = "producer"; break;
420  case MKTAG(0xa9,'a','l','b'): key = "album"; break;
421  case MKTAG(0xa9,'a','u','t'): key = "artist"; break;
422  case MKTAG(0xa9,'c','h','p'): key = "chapter"; break;
423  case MKTAG(0xa9,'c','m','t'): key = "comment"; break;
424  case MKTAG(0xa9,'c','o','m'): key = "composer"; break;
425  case MKTAG(0xa9,'c','p','y'): key = "copyright"; break;
426  case MKTAG(0xa9,'d','a','y'): key = "date"; break;
427  case MKTAG(0xa9,'d','i','r'): key = "director"; break;
428  case MKTAG(0xa9,'d','i','s'): key = "disclaimer"; break;
429  case MKTAG(0xa9,'e','d','1'): key = "edit_date"; break;
430  case MKTAG(0xa9,'e','n','c'): key = "encoder"; break;
431  case MKTAG(0xa9,'f','m','t'): key = "original_format"; break;
432  case MKTAG(0xa9,'g','e','n'): key = "genre"; break;
433  case MKTAG(0xa9,'g','r','p'): key = "grouping"; break;
434  case MKTAG(0xa9,'h','s','t'): key = "host_computer"; break;
435  case MKTAG(0xa9,'i','n','f'): key = "comment"; break;
436  case MKTAG(0xa9,'l','y','r'): key = "lyrics"; break;
437  case MKTAG(0xa9,'m','a','k'): key = "make"; break;
438  case MKTAG(0xa9,'m','o','d'): key = "model"; break;
439  case MKTAG(0xa9,'n','a','m'): key = "title"; break;
440  case MKTAG(0xa9,'o','p','e'): key = "original_artist"; break;
441  case MKTAG(0xa9,'p','r','d'): key = "producer"; break;
442  case MKTAG(0xa9,'p','r','f'): key = "performers"; break;
443  case MKTAG(0xa9,'r','e','q'): key = "playback_requirements"; break;
444  case MKTAG(0xa9,'s','r','c'): key = "original_source"; break;
445  case MKTAG(0xa9,'s','t','3'): key = "subtitle"; break;
446  case MKTAG(0xa9,'s','w','r'): key = "encoder"; break;
447  case MKTAG(0xa9,'t','o','o'): key = "encoder"; break;
448  case MKTAG(0xa9,'t','r','k'): key = "track"; break;
449  case MKTAG(0xa9,'u','r','l'): key = "URL"; break;
450  case MKTAG(0xa9,'w','r','n'): key = "warning"; break;
451  case MKTAG(0xa9,'w','r','t'): key = "composer"; break;
452  case MKTAG(0xa9,'x','y','z'): key = "location"; break;
453  }
454 retry:
455  if (c->itunes_metadata && atom.size > 8) {
456  int data_size = avio_rb32(pb);
457  int tag = avio_rl32(pb);
458  if (tag == MKTAG('d','a','t','a') && data_size <= atom.size && data_size >= 16) {
459  data_type = avio_rb32(pb); // type
460  avio_rb32(pb); // unknown
461  str_size = data_size - 16;
462  atom.size -= 16;
463 
464  if (!key && c->found_hdlr_mdta && c->meta_keys) {
465  uint32_t index = av_bswap32(atom.type); // BE number has been read as LE
466  if (index < c->meta_keys_count && index > 0) {
467  key = c->meta_keys[index];
468  } else if (atom.type != MKTAG('c', 'o', 'v', 'r')) {
469  av_log(c->fc, AV_LOG_WARNING,
470  "The index of 'data' is out of range: %"PRId32" < 1 or >= %d.\n",
471  index, c->meta_keys_count);
472  }
473  }
474  if (atom.type == MKTAG('c', 'o', 'v', 'r') ||
475  (key && !strcmp(key, "com.apple.quicktime.artwork"))) {
476  int ret = mov_read_covr(c, pb, data_type, str_size);
477  if (ret < 0) {
478  av_log(c->fc, AV_LOG_ERROR, "Error parsing cover art.\n");
479  return ret;
480  }
481  atom.size -= str_size;
482  if (atom.size > 8)
483  goto retry;
484  return ret;
485  }
486  } else return 0;
487  } else if (atom.size > 4 && key && !c->itunes_metadata && !raw) {
488  str_size = avio_rb16(pb); // string length
489  if (str_size > atom.size) {
490  raw = 1;
491  avio_seek(pb, -2, SEEK_CUR);
492  av_log(c->fc, AV_LOG_WARNING, "UDTA parsing failed retrying raw\n");
493  goto retry;
494  }
495  langcode = avio_rb16(pb);
496  ff_mov_lang_to_iso639(langcode, language);
497  atom.size -= 4;
498  } else
499  str_size = atom.size;
500 
501  if (c->export_all && !key) {
502  key = av_fourcc_make_string(tmp_key, atom.type);
503  }
504 
505  if (!key)
506  return 0;
507  if (atom.size < 0 || str_size >= INT_MAX/2)
508  return AVERROR_INVALIDDATA;
509 
510  // Allocates enough space if data_type is a int32 or float32 number, otherwise
511  // worst-case requirement for output string in case of utf8 coded input
512  num = (data_type >= 21 && data_type <= 23);
513  str_size_alloc = (num ? 512 : (raw ? str_size : str_size * 2)) + 1;
514  str = av_mallocz(str_size_alloc);
515  if (!str)
516  return AVERROR(ENOMEM);
517 
518  if (parse)
519  parse(c, pb, str_size, key);
520  else {
521  if (!raw && (data_type == 3 || (data_type == 0 && (langcode < 0x400 || langcode == 0x7fff)))) { // MAC Encoded
522  mov_read_mac_string(c, pb, str_size, str, str_size_alloc);
523  } else if (data_type == 21) { // BE signed integer, variable size
524  int val = 0;
525  if (str_size == 1)
526  val = (int8_t)avio_r8(pb);
527  else if (str_size == 2)
528  val = (int16_t)avio_rb16(pb);
529  else if (str_size == 3)
530  val = ((int32_t)(avio_rb24(pb)<<8))>>8;
531  else if (str_size == 4)
532  val = (int32_t)avio_rb32(pb);
533  if (snprintf(str, str_size_alloc, "%d", val) >= str_size_alloc) {
534  av_log(c->fc, AV_LOG_ERROR,
535  "Failed to store the number (%d) in string.\n", val);
536  av_free(str);
537  return AVERROR_INVALIDDATA;
538  }
539  } else if (data_type == 22) { // BE unsigned integer, variable size
540  unsigned int val = 0;
541  if (str_size == 1)
542  val = avio_r8(pb);
543  else if (str_size == 2)
544  val = avio_rb16(pb);
545  else if (str_size == 3)
546  val = avio_rb24(pb);
547  else if (str_size == 4)
548  val = avio_rb32(pb);
549  if (snprintf(str, str_size_alloc, "%u", val) >= str_size_alloc) {
550  av_log(c->fc, AV_LOG_ERROR,
551  "Failed to store the number (%u) in string.\n", val);
552  av_free(str);
553  return AVERROR_INVALIDDATA;
554  }
555  } else if (data_type == 23 && str_size >= 4) { // BE float32
556  float val = av_int2float(avio_rb32(pb));
557  if (snprintf(str, str_size_alloc, "%f", val) >= str_size_alloc) {
558  av_log(c->fc, AV_LOG_ERROR,
559  "Failed to store the float32 number (%f) in string.\n", val);
560  av_free(str);
561  return AVERROR_INVALIDDATA;
562  }
563  } else if (data_type > 1 && data_type != 4) {
564  // data_type can be 0 if not set at all above. data_type 1 means
565  // UTF8 and 4 means "UTF8 sort". For any other type (UTF16 or e.g.
566  // a picture), don't return it blindly in a string that is supposed
567  // to be UTF8 text.
568  av_log(c->fc, AV_LOG_WARNING, "Skipping unhandled metadata %s of type %d\n", key, data_type);
569  av_free(str);
570  return 0;
571  } else {
572  int ret = ffio_read_size(pb, str, str_size);
573  if (ret < 0) {
574  av_free(str);
575  return ret;
576  }
577  str[str_size] = 0;
578  }
579  c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
580  av_dict_set(metadata, key, str, 0);
581  if (*language && strcmp(language, "und")) {
582  snprintf(key2, sizeof(key2), "%s-%s", key, language);
583  av_dict_set(metadata, key2, str, 0);
584  }
585  if (!strcmp(key, "encoder")) {
586  int major, minor, micro;
587  if (sscanf(str, "HandBrake %d.%d.%d", &major, &minor, &micro) == 3) {
588  c->handbrake_version = 1000000*major + 1000*minor + micro;
589  }
590  }
591  }
592 
593  av_freep(&str);
594  return 0;
595 }
596 
598 {
599  int64_t start;
600  int i, nb_chapters, str_len, version;
601  char str[256+1];
602  int ret;
603 
604  if (c->ignore_chapters)
605  return 0;
606 
607  if ((atom.size -= 5) < 0)
608  return 0;
609 
610  version = avio_r8(pb);
611  avio_rb24(pb);
612  if (version)
613  avio_rb32(pb); // ???
614  nb_chapters = avio_r8(pb);
615 
616  for (i = 0; i < nb_chapters; i++) {
617  if (atom.size < 9)
618  return 0;
619 
620  start = avio_rb64(pb);
621  str_len = avio_r8(pb);
622 
623  if ((atom.size -= 9+str_len) < 0)
624  return 0;
625 
626  ret = ffio_read_size(pb, str, str_len);
627  if (ret < 0)
628  return ret;
629  str[str_len] = 0;
630  avpriv_new_chapter(c->fc, i, (AVRational){1,10000000}, start, AV_NOPTS_VALUE, str);
631  }
632  return 0;
633 }
634 
635 #define MIN_DATA_ENTRY_BOX_SIZE 12
637 {
638  AVStream *st;
639  MOVStreamContext *sc;
640  int entries, i, j;
641 
642  if (c->fc->nb_streams < 1)
643  return 0;
644  st = c->fc->streams[c->fc->nb_streams-1];
645  sc = st->priv_data;
646 
647  avio_rb32(pb); // version + flags
648  entries = avio_rb32(pb);
649  if (!entries ||
650  entries > (atom.size - 1) / MIN_DATA_ENTRY_BOX_SIZE + 1 ||
651  entries >= UINT_MAX / sizeof(*sc->drefs))
652  return AVERROR_INVALIDDATA;
653 
654  for (i = 0; i < sc->drefs_count; i++) {
655  MOVDref *dref = &sc->drefs[i];
656  av_freep(&dref->path);
657  av_freep(&dref->dir);
658  }
659  av_free(sc->drefs);
660  sc->drefs_count = 0;
661  sc->drefs = av_mallocz(entries * sizeof(*sc->drefs));
662  if (!sc->drefs)
663  return AVERROR(ENOMEM);
664  sc->drefs_count = entries;
665 
666  for (i = 0; i < entries; i++) {
667  MOVDref *dref = &sc->drefs[i];
668  uint32_t size = avio_rb32(pb);
669  int64_t next = avio_tell(pb);
670 
671  if (size < 12 || next < 0 || next > INT64_MAX - size)
672  return AVERROR_INVALIDDATA;
673 
674  next += size - 4;
675 
676  dref->type = avio_rl32(pb);
677  avio_rb32(pb); // version + flags
678 
679  if (dref->type == MKTAG('a','l','i','s') && size > 150) {
680  /* macintosh alias record */
681  uint16_t volume_len, len;
682  int16_t type;
683  int ret;
684 
685  avio_skip(pb, 10);
686 
687  volume_len = avio_r8(pb);
688  volume_len = FFMIN(volume_len, 27);
689  ret = ffio_read_size(pb, dref->volume, 27);
690  if (ret < 0)
691  return ret;
692  dref->volume[volume_len] = 0;
693  av_log(c->fc, AV_LOG_DEBUG, "volume %s, len %d\n", dref->volume, volume_len);
694 
695  avio_skip(pb, 12);
696 
697  len = avio_r8(pb);
698  len = FFMIN(len, 63);
699  ret = ffio_read_size(pb, dref->filename, 63);
700  if (ret < 0)
701  return ret;
702  dref->filename[len] = 0;
703  av_log(c->fc, AV_LOG_DEBUG, "filename %s, len %d\n", dref->filename, len);
704 
705  avio_skip(pb, 16);
706 
707  /* read next level up_from_alias/down_to_target */
708  dref->nlvl_from = avio_rb16(pb);
709  dref->nlvl_to = avio_rb16(pb);
710  av_log(c->fc, AV_LOG_DEBUG, "nlvl from %d, nlvl to %d\n",
711  dref->nlvl_from, dref->nlvl_to);
712 
713  avio_skip(pb, 16);
714 
715  for (type = 0; type != -1 && avio_tell(pb) < next; ) {
716  if (avio_feof(pb))
717  return AVERROR_EOF;
718  type = avio_rb16(pb);
719  len = avio_rb16(pb);
720  av_log(c->fc, AV_LOG_DEBUG, "type %d, len %d\n", type, len);
721  if (len&1)
722  len += 1;
723  if (type == 2) { // absolute path
724  av_free(dref->path);
725  dref->path = av_mallocz(len+1);
726  if (!dref->path)
727  return AVERROR(ENOMEM);
728 
729  ret = ffio_read_size(pb, dref->path, len);
730  if (ret < 0) {
731  av_freep(&dref->path);
732  return ret;
733  }
734  if (len > volume_len && !strncmp(dref->path, dref->volume, volume_len)) {
735  len -= volume_len;
736  memmove(dref->path, dref->path+volume_len, len);
737  dref->path[len] = 0;
738  }
739  // trim string of any ending zeros
740  for (j = len - 1; j >= 0; j--) {
741  if (dref->path[j] == 0)
742  len--;
743  else
744  break;
745  }
746  for (j = 0; j < len; j++)
747  if (dref->path[j] == ':' || dref->path[j] == 0)
748  dref->path[j] = '/';
749  av_log(c->fc, AV_LOG_DEBUG, "path %s\n", dref->path);
750  } else if (type == 0) { // directory name
751  av_free(dref->dir);
752  dref->dir = av_malloc(len+1);
753  if (!dref->dir)
754  return AVERROR(ENOMEM);
755 
756  ret = ffio_read_size(pb, dref->dir, len);
757  if (ret < 0) {
758  av_freep(&dref->dir);
759  return ret;
760  }
761  dref->dir[len] = 0;
762  for (j = 0; j < len; j++)
763  if (dref->dir[j] == ':')
764  dref->dir[j] = '/';
765  av_log(c->fc, AV_LOG_DEBUG, "dir %s\n", dref->dir);
766  } else
767  avio_skip(pb, len);
768  }
769  } else {
770  av_log(c->fc, AV_LOG_DEBUG, "Unknown dref type 0x%08"PRIx32" size %"PRIu32"\n",
771  dref->type, size);
772  entries--;
773  i--;
774  }
775  avio_seek(pb, next, SEEK_SET);
776  }
777  return 0;
778 }
779 
781 {
782  AVStream *st;
783  uint32_t type;
784  uint32_t ctype;
785  int64_t title_size;
786  char *title_str;
787  int ret;
788 
789  avio_r8(pb); /* version */
790  avio_rb24(pb); /* flags */
791 
792  /* component type */
793  ctype = avio_rl32(pb);
794  type = avio_rl32(pb); /* component subtype */
795 
796  av_log(c->fc, AV_LOG_TRACE, "ctype=%s\n", av_fourcc2str(ctype));
797  av_log(c->fc, AV_LOG_TRACE, "stype=%s\n", av_fourcc2str(type));
798 
799  if (c->trak_index < 0) { // meta not inside a trak
800  if (type == MKTAG('m','d','t','a')) {
801  c->found_hdlr_mdta = 1;
802  }
803  return 0;
804  }
805 
806  st = c->fc->streams[c->fc->nb_streams-1];
807 
808  if (type == MKTAG('v','i','d','e'))
810  else if (type == MKTAG('s','o','u','n'))
812  else if (type == MKTAG('m','1','a',' '))
814  else if ((type == MKTAG('s','u','b','p')) || (type == MKTAG('c','l','c','p')))
816 
817  avio_rb32(pb); /* component manufacture */
818  avio_rb32(pb); /* component flags */
819  avio_rb32(pb); /* component flags mask */
820 
821  title_size = atom.size - 24;
822  if (title_size > 0) {
823  if (title_size > FFMIN(INT_MAX, SIZE_MAX-1))
824  return AVERROR_INVALIDDATA;
825  title_str = av_malloc(title_size + 1); /* Add null terminator */
826  if (!title_str)
827  return AVERROR(ENOMEM);
828 
829  ret = ffio_read_size(pb, title_str, title_size);
830  if (ret < 0) {
831  av_freep(&title_str);
832  return ret;
833  }
834  title_str[title_size] = 0;
835  if (title_str[0]) {
836  int off = (!c->isom && title_str[0] == title_size - 1);
837  // flag added so as to not set stream handler name if already set from mdia->hdlr
838  av_dict_set(&st->metadata, "handler_name", title_str + off, AV_DICT_DONT_OVERWRITE);
839  }
840  av_freep(&title_str);
841  }
842 
843  return 0;
844 }
845 
847 {
848  return ff_mov_read_esds(c->fc, pb);
849 }
850 
852 {
853  AVStream *st;
854  AVPacketSideData *sd;
855  enum AVAudioServiceType *ast;
856  int ac3info, acmod, lfeon, bsmod;
857  uint64_t mask;
858 
859  if (c->fc->nb_streams < 1)
860  return 0;
861  st = c->fc->streams[c->fc->nb_streams-1];
862 
866  sizeof(*ast), 0);
867  if (!sd)
868  return AVERROR(ENOMEM);
869 
870  ast = (enum AVAudioServiceType*)sd->data;
871  ac3info = avio_rb24(pb);
872  bsmod = (ac3info >> 14) & 0x7;
873  acmod = (ac3info >> 11) & 0x7;
874  lfeon = (ac3info >> 10) & 0x1;
875 
877  if (lfeon)
881 
882  *ast = bsmod;
883  if (st->codecpar->ch_layout.nb_channels > 1 && bsmod == 0x7)
885 
886  return 0;
887 }
888 
889 #if CONFIG_IAMFDEC
890 static int mov_read_iacb(MOVContext *c, AVIOContext *pb, MOVAtom atom)
891 {
892  AVStream *st;
893  MOVStreamContext *sc;
894  FFIOContext b;
895  AVIOContext *descriptor_pb;
897  IAMFContext *iamf;
899  unsigned descriptors_size;
900  int nb_frames, disposition;
901  int version, ret;
902 
903  if (atom.size < 5)
904  return AVERROR_INVALIDDATA;
905 
906  if (c->fc->nb_streams < 1)
907  return 0;
908 
909  version = avio_r8(pb);
910  if (version != 1) {
911  av_log(c->fc, AV_LOG_ERROR, "%s configurationVersion %d",
912  version < 1 ? "invalid" : "unsupported", version);
913  return AVERROR_INVALIDDATA;
914  }
915 
916  descriptors_size = ffio_read_leb(pb);
917  if (!descriptors_size || descriptors_size > INT_MAX)
918  return AVERROR_INVALIDDATA;
919 
920  st = c->fc->streams[c->fc->nb_streams - 1];
921  sc = st->priv_data;
922 
923  if (st->codecpar->extradata) {
924  av_log(c->fc, AV_LOG_WARNING, "ignoring iacb\n");
925  return 0;
926  }
927 
928  sc->iamf = av_mallocz(sizeof(*sc->iamf));
929  if (!sc->iamf)
930  return AVERROR(ENOMEM);
931  iamf = &sc->iamf->iamf;
932 
933  st->codecpar->extradata = av_malloc(descriptors_size);
934  if (!st->codecpar->extradata)
935  return AVERROR(ENOMEM);
936  st->codecpar->extradata_size = descriptors_size;
937 
938  ret = avio_read(pb, st->codecpar->extradata, descriptors_size);
939  if (ret != descriptors_size)
940  return ret < 0 ? ret : AVERROR_INVALIDDATA;
941 
942  ffio_init_read_context(&b, st->codecpar->extradata, descriptors_size);
943  descriptor_pb = &b.pub;
944 
945  ret = ff_iamfdec_read_descriptors(iamf, descriptor_pb, descriptors_size, c->fc);
946  if (ret < 0)
947  return ret;
948 
949  metadata = st->metadata;
950  st->metadata = NULL;
951  start_time = st->start_time;
952  nb_frames = st->nb_frames;
953  duration = st->duration;
954  disposition = st->disposition;
955 
956  for (int i = 0; i < iamf->nb_audio_elements; i++) {
957  IAMFAudioElement *audio_element = iamf->audio_elements[i];
958  const AVIAMFAudioElement *element;
959  AVStreamGroup *stg =
961 
962  if (!stg) {
963  ret = AVERROR(ENOMEM);
964  goto fail;
965  }
966 
968  stg->id = audio_element->audio_element_id;
969  /* Transfer ownership */
970  element = stg->params.iamf_audio_element = audio_element->element;
971  audio_element->element = NULL;
972 
973  for (int j = 0; j < audio_element->nb_substreams; j++) {
974  IAMFSubStream *substream = &audio_element->substreams[j];
975  AVStream *stream;
976 
977  if (!i && !j) {
978  if (audio_element->layers[0].substream_count != 1)
979  disposition &= ~AV_DISPOSITION_DEFAULT;
980  stream = st;
981  } else
982  stream = avformat_new_stream(c->fc, NULL);
983  if (!stream) {
984  ret = AVERROR(ENOMEM);
985  goto fail;
986  }
987 
988  stream->start_time = start_time;
989  stream->nb_frames = nb_frames;
990  stream->duration = duration;
991  stream->disposition = disposition;
992  if (stream != st) {
993  stream->priv_data = sc;
994  sc->refcount++;
995  }
996 
999  if (i || j) {
1001  if (audio_element->layers[0].substream_count == 1)
1002  stream->disposition &= ~AV_DISPOSITION_DEFAULT;
1003  }
1004 
1005  ret = avcodec_parameters_copy(stream->codecpar, substream->codecpar);
1006  if (ret < 0)
1007  goto fail;
1008 
1009  stream->id = substream->audio_substream_id;
1010 
1011  avpriv_set_pts_info(st, 64, 1, sc->time_scale);
1012 
1013  ret = avformat_stream_group_add_stream(stg, stream);
1014  if (ret < 0)
1015  goto fail;
1016  }
1017 
1018  ret = av_dict_copy(&stg->metadata, metadata, 0);
1019  if (ret < 0)
1020  goto fail;
1021  }
1022 
1023  for (int i = 0; i < iamf->nb_mix_presentations; i++) {
1024  IAMFMixPresentation *mix_presentation = iamf->mix_presentations[i];
1025  const AVIAMFMixPresentation *mix = mix_presentation->cmix;
1026  AVStreamGroup *stg =
1028 
1029  if (!stg) {
1030  ret = AVERROR(ENOMEM);
1031  goto fail;
1032  }
1033 
1035  stg->id = mix_presentation->mix_presentation_id;
1036  /* Transfer ownership */
1037  stg->params.iamf_mix_presentation = mix_presentation->mix;
1038  mix_presentation->mix = NULL;
1039 
1040  for (int j = 0; j < mix->nb_submixes; j++) {
1041  const AVIAMFSubmix *submix = mix->submixes[j];
1042 
1043  for (int k = 0; k < submix->nb_elements; k++) {
1044  const AVIAMFSubmixElement *submix_element = submix->elements[k];
1045  const AVStreamGroup *audio_element = NULL;
1046 
1047  for (int l = 0; l < c->fc->nb_stream_groups; l++)
1048  if (c->fc->stream_groups[l]->type == AV_STREAM_GROUP_PARAMS_IAMF_AUDIO_ELEMENT &&
1049  c->fc->stream_groups[l]->id == submix_element->audio_element_id) {
1050  audio_element = c->fc->stream_groups[l];
1051  break;
1052  }
1053  av_assert0(audio_element);
1054 
1055  for (int l = 0; l < audio_element->nb_streams; l++) {
1056  ret = avformat_stream_group_add_stream(stg, audio_element->streams[l]);
1057  if (ret < 0 && ret != AVERROR(EEXIST))
1058  goto fail;
1059  }
1060  }
1061  }
1062 
1063  ret = av_dict_copy(&stg->metadata, metadata, 0);
1064  if (ret < 0)
1065  goto fail;
1066  }
1067 
1068  ret = 0;
1069 fail:
1071 
1072  return ret;
1073 }
1074 #endif
1075 
1077 {
1078  AVStream *st;
1079  AVPacketSideData *sd;
1080  enum AVAudioServiceType *ast;
1081  int eac3info, acmod, lfeon, bsmod;
1082  uint64_t mask;
1083 
1084  if (c->fc->nb_streams < 1)
1085  return 0;
1086  st = c->fc->streams[c->fc->nb_streams-1];
1087 
1091  sizeof(*ast), 0);
1092  if (!sd)
1093  return AVERROR(ENOMEM);
1094 
1095  ast = (enum AVAudioServiceType*)sd->data;
1096 
1097  /* No need to parse fields for additional independent substreams and its
1098  * associated dependent substreams since libavcodec's E-AC-3 decoder
1099  * does not support them yet. */
1100  avio_rb16(pb); /* data_rate and num_ind_sub */
1101  eac3info = avio_rb24(pb);
1102  bsmod = (eac3info >> 12) & 0x1f;
1103  acmod = (eac3info >> 9) & 0x7;
1104  lfeon = (eac3info >> 8) & 0x1;
1105 
1107  if (lfeon)
1111 
1112  *ast = bsmod;
1113  if (st->codecpar->ch_layout.nb_channels > 1 && bsmod == 0x7)
1115 
1116  return 0;
1117 }
1118 
1120 {
1121 #define DDTS_SIZE 20
1122  uint8_t buf[DDTS_SIZE + AV_INPUT_BUFFER_PADDING_SIZE];
1123  AVStream *st = NULL;
1124  uint32_t frame_duration_code = 0;
1125  uint32_t channel_layout_code = 0;
1126  GetBitContext gb;
1127  int ret;
1128 
1129  if ((ret = ffio_read_size(pb, buf, DDTS_SIZE)) < 0)
1130  return ret;
1131 
1132  init_get_bits(&gb, buf, 8 * DDTS_SIZE);
1133 
1134  if (c->fc->nb_streams < 1) {
1135  return 0;
1136  }
1137  st = c->fc->streams[c->fc->nb_streams-1];
1138 
1139  st->codecpar->sample_rate = get_bits_long(&gb, 32);
1140  if (st->codecpar->sample_rate <= 0) {
1141  av_log(c->fc, AV_LOG_ERROR, "Invalid sample rate %d\n", st->codecpar->sample_rate);
1142  return AVERROR_INVALIDDATA;
1143  }
1144  skip_bits_long(&gb, 32); /* max bitrate */
1145  st->codecpar->bit_rate = get_bits_long(&gb, 32);
1146  st->codecpar->bits_per_coded_sample = get_bits(&gb, 8);
1147  frame_duration_code = get_bits(&gb, 2);
1148  skip_bits(&gb, 30); /* various fields */
1149  channel_layout_code = get_bits(&gb, 16);
1150 
1151  st->codecpar->frame_size =
1152  (frame_duration_code == 0) ? 512 :
1153  (frame_duration_code == 1) ? 1024 :
1154  (frame_duration_code == 2) ? 2048 :
1155  (frame_duration_code == 3) ? 4096 : 0;
1156 
1157  if (channel_layout_code > 0xff) {
1158  av_log(c->fc, AV_LOG_WARNING, "Unsupported DTS audio channel layout\n");
1159  }
1162  ((channel_layout_code & 0x1) ? AV_CH_FRONT_CENTER : 0) |
1163  ((channel_layout_code & 0x2) ? AV_CH_FRONT_LEFT : 0) |
1164  ((channel_layout_code & 0x2) ? AV_CH_FRONT_RIGHT : 0) |
1165  ((channel_layout_code & 0x4) ? AV_CH_SIDE_LEFT : 0) |
1166  ((channel_layout_code & 0x4) ? AV_CH_SIDE_RIGHT : 0) |
1167  ((channel_layout_code & 0x8) ? AV_CH_LOW_FREQUENCY : 0));
1168 
1169  return 0;
1170 }
1171 
1173 {
1174  AVStream *st;
1175 
1176  if (c->fc->nb_streams < 1)
1177  return 0;
1178  st = c->fc->streams[c->fc->nb_streams-1];
1179 
1180  if (atom.size < 16)
1181  return 0;
1182 
1183  /* skip version and flags */
1184  avio_skip(pb, 4);
1185 
1186  ff_mov_read_chan(c->fc, pb, st, atom.size - 4);
1187 
1188  return 0;
1189 }
1190 
1192 {
1193  int64_t end = av_sat_add64(avio_tell(pb), atom.size);
1194  int version, flags;
1195  int ret;
1196  AVStream *st;
1197 
1198  if (c->fc->nb_streams < 1)
1199  return 0;
1200  st = c->fc->streams[c->fc->nb_streams-1];
1201 
1202  version = avio_r8(pb);
1203  flags = avio_rb24(pb);
1204  if (version != 0 || flags != 0) {
1205  av_log(c->fc, AV_LOG_ERROR,
1206  "Unsupported 'chnl' box with version %d, flags: %#x",
1207  version, flags);
1208  return AVERROR_INVALIDDATA;
1209  }
1210 
1211  ret = ff_mov_read_chnl(c->fc, pb, st);
1212  if (ret < 0)
1213  return ret;
1214 
1215  if (avio_tell(pb) != end) {
1216  av_log(c->fc, AV_LOG_WARNING, "skip %" PRId64 " bytes of unknown data inside chnl\n",
1217  end - avio_tell(pb));
1218  avio_seek(pb, end, SEEK_SET);
1219  }
1220  return ret;
1221 }
1222 
1224 {
1225  AVStream *st;
1226  int ret;
1227 
1228  if (c->fc->nb_streams < 1)
1229  return 0;
1230  st = c->fc->streams[c->fc->nb_streams-1];
1231 
1232  if ((ret = ff_get_wav_header(c->fc, pb, st->codecpar, atom.size, 0)) < 0)
1233  av_log(c->fc, AV_LOG_WARNING, "get_wav_header failed\n");
1234 
1235  return ret;
1236 }
1237 
1239 {
1240  AVStream *st;
1241  HEIFItem *item;
1242  AVPacketSideData *sd;
1243  int width, height, err = 0;
1244  AVRational aperture_width, aperture_height, horiz_off, vert_off;
1245  AVRational pc_x, pc_y;
1246  uint64_t top, bottom, left, right;
1247 
1248  item = heif_cur_item(c);
1249  st = get_curr_st(c);
1250  if (!st)
1251  return 0;
1252 
1253  width = st->codecpar->width;
1254  height = st->codecpar->height;
1255  if ((!width || !height) && item) {
1256  width = item->width;
1257  height = item->height;
1258  }
1259  if (!width || !height) {
1260  err = AVERROR_INVALIDDATA;
1261  goto fail;
1262  }
1263 
1264  aperture_width.num = avio_rb32(pb);
1265  aperture_width.den = avio_rb32(pb);
1266  aperture_height.num = avio_rb32(pb);
1267  aperture_height.den = avio_rb32(pb);
1268 
1269  horiz_off.num = avio_rb32(pb);
1270  horiz_off.den = avio_rb32(pb);
1271  vert_off.num = avio_rb32(pb);
1272  vert_off.den = avio_rb32(pb);
1273 
1274  if (aperture_width.num < 0 || aperture_width.den < 0 ||
1275  aperture_height.num < 0 || aperture_height.den < 0 ||
1276  horiz_off.den < 0 || vert_off.den < 0) {
1277  err = AVERROR_INVALIDDATA;
1278  goto fail;
1279  }
1280  av_log(c->fc, AV_LOG_TRACE, "clap: apertureWidth %d/%d, apertureHeight %d/%d "
1281  "horizOff %d/%d vertOff %d/%d\n",
1282  aperture_width.num, aperture_width.den, aperture_height.num, aperture_height.den,
1283  horiz_off.num, horiz_off.den, vert_off.num, vert_off.den);
1284 
1285  pc_x = av_mul_q((AVRational) { width - 1, 1 }, (AVRational) { 1, 2 });
1286  pc_x = av_add_q(pc_x, horiz_off);
1287  pc_y = av_mul_q((AVRational) { height - 1, 1 }, (AVRational) { 1, 2 });
1288  pc_y = av_add_q(pc_y, vert_off);
1289 
1290  aperture_width = av_sub_q(aperture_width, (AVRational) { 1, 1 });
1291  aperture_width = av_mul_q(aperture_width, (AVRational) { 1, 2 });
1292  aperture_height = av_sub_q(aperture_height, (AVRational) { 1, 1 });
1293  aperture_height = av_mul_q(aperture_height, (AVRational) { 1, 2 });
1294 
1295  left = av_q2d(av_sub_q(pc_x, aperture_width));
1296  right = av_q2d(av_add_q(pc_x, aperture_width));
1297  top = av_q2d(av_sub_q(pc_y, aperture_height));
1298  bottom = av_q2d(av_add_q(pc_y, aperture_height));
1299 
1300  if (bottom > (height - 1) ||
1301  right > (width - 1)) {
1302  err = AVERROR_INVALIDDATA;
1303  goto fail;
1304  }
1305 
1306  bottom = height - 1 - bottom;
1307  right = width - 1 - right;
1308 
1309  if (!(left | right | top | bottom))
1310  return 0;
1311 
1312  if ((left + right) >= width ||
1313  (top + bottom) >= height) {
1314  err = AVERROR_INVALIDDATA;
1315  goto fail;
1316  }
1317 
1321  sizeof(uint32_t) * 4, 0);
1322  if (!sd)
1323  return AVERROR(ENOMEM);
1324 
1325  AV_WL32A(sd->data, top);
1326  AV_WL32A(sd->data + 4, bottom);
1327  AV_WL32A(sd->data + 8, left);
1328  AV_WL32A(sd->data + 12, right);
1329 
1330 fail:
1331  if (err < 0) {
1332  int explode = !!(c->fc->error_recognition & AV_EF_EXPLODE);
1333  av_log(c->fc, explode ? AV_LOG_ERROR : AV_LOG_WARNING, "Invalid clap box\n");
1334  if (!explode)
1335  err = 0;
1336  }
1337 
1338  return err;
1339 }
1340 
1341 /* This atom overrides any previously set aspect ratio */
1343 {
1344  const int num = avio_rb32(pb);
1345  const int den = avio_rb32(pb);
1346  AVStream *st;
1347  MOVStreamContext *sc;
1348 
1349  if (c->fc->nb_streams < 1)
1350  return 0;
1351  st = c->fc->streams[c->fc->nb_streams-1];
1352  sc = st->priv_data;
1353 
1354  av_log(c->fc, AV_LOG_TRACE, "pasp: hSpacing %d, vSpacing %d\n", num, den);
1355 
1356  if (den != 0) {
1357  sc->h_spacing = num;
1358  sc->v_spacing = den;
1359  }
1360  return 0;
1361 }
1362 
1363 /* this atom contains actual media data */
1365 {
1366  if (atom.size == 0) /* wrong one (MP4) */
1367  return 0;
1368  c->found_mdat=1;
1369  return 0; /* now go for moov */
1370 }
1371 
1372 #define DRM_BLOB_SIZE 56
1373 
1375 {
1376  uint8_t intermediate_key[20];
1377  uint8_t intermediate_iv[20];
1378  uint8_t input[64];
1379  uint8_t output[64];
1380  uint8_t file_checksum[20];
1381  uint8_t calculated_checksum[20];
1382  char checksum_string[2 * sizeof(file_checksum) + 1];
1383  struct AVSHA *sha;
1384  int i;
1385  int ret = 0;
1386  uint8_t *activation_bytes = c->activation_bytes;
1387  uint8_t *fixed_key = c->audible_fixed_key;
1388 
1389  c->aax_mode = 1;
1390 
1391  sha = av_sha_alloc();
1392  if (!sha)
1393  return AVERROR(ENOMEM);
1394  av_free(c->aes_decrypt);
1395  c->aes_decrypt = av_aes_alloc();
1396  if (!c->aes_decrypt) {
1397  ret = AVERROR(ENOMEM);
1398  goto fail;
1399  }
1400 
1401  /* drm blob processing */
1402  avio_read(pb, output, 8); // go to offset 8, absolute position 0x251
1404  avio_read(pb, output, 4); // go to offset 4, absolute position 0x28d
1405  avio_read(pb, file_checksum, 20);
1406 
1407  // required by external tools
1408  ff_data_to_hex(checksum_string, file_checksum, sizeof(file_checksum), 1);
1409  av_log(c->fc, AV_LOG_INFO, "[aax] file checksum == %s\n", checksum_string);
1410 
1411  /* verify activation data */
1412  if (!activation_bytes) {
1413  av_log(c->fc, AV_LOG_WARNING, "[aax] activation_bytes option is missing!\n");
1414  ret = 0; /* allow ffprobe to continue working on .aax files */
1415  goto fail;
1416  }
1417  if (c->activation_bytes_size != 4) {
1418  av_log(c->fc, AV_LOG_FATAL, "[aax] activation_bytes value needs to be 4 bytes!\n");
1419  ret = AVERROR(EINVAL);
1420  goto fail;
1421  }
1422 
1423  /* verify fixed key */
1424  if (c->audible_fixed_key_size != 16) {
1425  av_log(c->fc, AV_LOG_FATAL, "[aax] audible_fixed_key value needs to be 16 bytes!\n");
1426  ret = AVERROR(EINVAL);
1427  goto fail;
1428  }
1429 
1430  /* AAX (and AAX+) key derivation */
1431  av_sha_init(sha, 160);
1432  av_sha_update(sha, fixed_key, 16);
1433  av_sha_update(sha, activation_bytes, 4);
1434  av_sha_final(sha, intermediate_key);
1435  av_sha_init(sha, 160);
1436  av_sha_update(sha, fixed_key, 16);
1437  av_sha_update(sha, intermediate_key, 20);
1438  av_sha_update(sha, activation_bytes, 4);
1439  av_sha_final(sha, intermediate_iv);
1440  av_sha_init(sha, 160);
1441  av_sha_update(sha, intermediate_key, 16);
1442  av_sha_update(sha, intermediate_iv, 16);
1443  av_sha_final(sha, calculated_checksum);
1444  if (memcmp(calculated_checksum, file_checksum, 20)) { // critical error
1445  av_log(c->fc, AV_LOG_ERROR, "[aax] mismatch in checksums!\n");
1447  goto fail;
1448  }
1449  av_aes_init(c->aes_decrypt, intermediate_key, 128, 1);
1450  av_aes_crypt(c->aes_decrypt, output, input, DRM_BLOB_SIZE >> 4, intermediate_iv, 1);
1451  for (i = 0; i < 4; i++) {
1452  // file data (in output) is stored in big-endian mode
1453  if (activation_bytes[i] != output[3 - i]) { // critical error
1454  av_log(c->fc, AV_LOG_ERROR, "[aax] error in drm blob decryption!\n");
1456  goto fail;
1457  }
1458  }
1459  memcpy(c->file_key, output + 8, 16);
1460  memcpy(input, output + 26, 16);
1461  av_sha_init(sha, 160);
1462  av_sha_update(sha, input, 16);
1463  av_sha_update(sha, c->file_key, 16);
1464  av_sha_update(sha, fixed_key, 16);
1465  av_sha_final(sha, c->file_iv);
1466 
1467 fail:
1468  av_free(sha);
1469 
1470  return ret;
1471 }
1472 
1474 {
1475  if (c->audible_key_size != 16) {
1476  av_log(c->fc, AV_LOG_FATAL, "[aaxc] audible_key value needs to be 16 bytes!\n");
1477  return AVERROR(EINVAL);
1478  }
1479 
1480  if (c->audible_iv_size != 16) {
1481  av_log(c->fc, AV_LOG_FATAL, "[aaxc] audible_iv value needs to be 16 bytes!\n");
1482  return AVERROR(EINVAL);
1483  }
1484 
1485  c->aes_decrypt = av_aes_alloc();
1486  if (!c->aes_decrypt) {
1487  return AVERROR(ENOMEM);
1488  }
1489 
1490  memcpy(c->file_key, c->audible_key, 16);
1491  memcpy(c->file_iv, c->audible_iv, 16);
1492  c->aax_mode = 1;
1493 
1494  return 0;
1495 }
1496 
1497 // Audible AAX (and AAX+) bytestream decryption
1498 static int aax_filter(uint8_t *input, int size, MOVContext *c)
1499 {
1500  int blocks = 0;
1501  unsigned char iv[16];
1502 
1503  memcpy(iv, c->file_iv, 16); // iv is overwritten
1504  blocks = size >> 4; // trailing bytes are not encrypted!
1505  av_aes_init(c->aes_decrypt, c->file_key, 128, 1);
1506  av_aes_crypt(c->aes_decrypt, input, input, blocks, iv, 1);
1507 
1508  return 0;
1509 }
1510 
1511 /* read major brand, minor version and compatible brands and store them as metadata */
1513 {
1514  uint32_t minor_ver;
1515  int comp_brand_size;
1516  char* comp_brands_str;
1517  uint8_t type[5] = {0};
1518  int ret = ffio_read_size(pb, type, 4);
1519  if (ret < 0)
1520  return ret;
1521  if (c->fc->nb_streams) {
1522  if (c->fc->strict_std_compliance >= FF_COMPLIANCE_STRICT)
1523  return AVERROR_INVALIDDATA;
1524  av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate FTYP\n");
1525  return 0;
1526  }
1527 
1528  if (strcmp(type, "qt "))
1529  c->isom = 1;
1530  av_log(c->fc, AV_LOG_DEBUG, "ISO: File Type Major Brand: %.4s\n",(char *)&type);
1531  av_dict_set(&c->fc->metadata, "major_brand", type, 0);
1532  minor_ver = avio_rb32(pb); /* minor version */
1533  av_dict_set_int(&c->fc->metadata, "minor_version", minor_ver, 0);
1534 
1535  comp_brand_size = atom.size - 8;
1536  if (comp_brand_size < 0 || comp_brand_size == INT_MAX)
1537  return AVERROR_INVALIDDATA;
1538  comp_brands_str = av_malloc(comp_brand_size + 1); /* Add null terminator */
1539  if (!comp_brands_str)
1540  return AVERROR(ENOMEM);
1541 
1542  ret = ffio_read_size(pb, comp_brands_str, comp_brand_size);
1543  if (ret < 0) {
1544  av_freep(&comp_brands_str);
1545  return ret;
1546  }
1547  comp_brands_str[comp_brand_size] = 0;
1548  av_dict_set(&c->fc->metadata, "compatible_brands",
1549  comp_brands_str, AV_DICT_DONT_STRDUP_VAL);
1550 
1551  // Logic for handling Audible's .aaxc files
1552  if (!strcmp(type, "aaxc")) {
1553  mov_aaxc_crypto(c);
1554  }
1555 
1556  return 0;
1557 }
1558 
1559 /* this atom should contain all header atoms */
1561 {
1562  int ret;
1563 
1564  if (c->found_moov) {
1565  av_log(c->fc, AV_LOG_WARNING, "Found duplicated MOOV Atom. Skipped it\n");
1566  avio_skip(pb, atom.size);
1567  return 0;
1568  }
1569 
1570  if ((ret = mov_read_default(c, pb, atom)) < 0)
1571  return ret;
1572  /* we parsed the 'moov' atom, we can terminate the parsing as soon as we find the 'mdat' */
1573  /* so we don't parse the whole file if over a network */
1574  c->found_moov=1;
1575  return 0; /* now go for mdat */
1576 }
1577 
1579  MOVFragmentIndex *frag_index,
1580  int index,
1581  int id)
1582 {
1583  int i;
1584  MOVFragmentIndexItem * item;
1585 
1586  if (index < 0 || index >= frag_index->nb_items)
1587  return NULL;
1588  item = &frag_index->item[index];
1589  for (i = 0; i < item->nb_stream_info; i++)
1590  if (item->stream_info[i].id == id)
1591  return &item->stream_info[i];
1592 
1593  // This shouldn't happen
1594  return NULL;
1595 }
1596 
1597 static void set_frag_stream(MOVFragmentIndex *frag_index, int id)
1598 {
1599  int i;
1600  MOVFragmentIndexItem * item;
1601 
1602  if (frag_index->current < 0 ||
1603  frag_index->current >= frag_index->nb_items)
1604  return;
1605 
1606  item = &frag_index->item[frag_index->current];
1607  for (i = 0; i < item->nb_stream_info; i++)
1608  if (item->stream_info[i].id == id) {
1609  item->current = i;
1610  return;
1611  }
1612 
1613  // id not found. This shouldn't happen.
1614  item->current = -1;
1615 }
1616 
1618  MOVFragmentIndex *frag_index)
1619 {
1620  MOVFragmentIndexItem *item;
1621  if (frag_index->current < 0 ||
1622  frag_index->current >= frag_index->nb_items)
1623  return NULL;
1624 
1625  item = &frag_index->item[frag_index->current];
1626  if (item->current >= 0 && item->current < item->nb_stream_info)
1627  return &item->stream_info[item->current];
1628 
1629  // This shouldn't happen
1630  return NULL;
1631 }
1632 
1634 {
1635  int a, b, m;
1636  int64_t moof_offset;
1637 
1638  // Optimize for appending new entries
1639  if (!frag_index->nb_items ||
1640  frag_index->item[frag_index->nb_items - 1].moof_offset < offset)
1641  return frag_index->nb_items;
1642 
1643  a = -1;
1644  b = frag_index->nb_items;
1645 
1646  while (b - a > 1) {
1647  m = (a + b) >> 1;
1648  moof_offset = frag_index->item[m].moof_offset;
1649  if (moof_offset >= offset)
1650  b = m;
1651  if (moof_offset <= offset)
1652  a = m;
1653  }
1654  return b;
1655 }
1656 
1658 {
1659  av_assert0(frag_stream_info);
1660  if (frag_stream_info->sidx_pts != AV_NOPTS_VALUE)
1661  return frag_stream_info->sidx_pts;
1662  if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE)
1663  return frag_stream_info->first_tfra_pts;
1664  return frag_stream_info->tfdt_dts;
1665 }
1666 
1668  MOVFragmentIndex *frag_index, int index)
1669 {
1670  MOVFragmentStreamInfo * frag_stream_info;
1671  MOVStreamContext *sc = dst_st->priv_data;
1672  int64_t timestamp;
1673  int i, j;
1674 
1675  // If the stream is referenced by any sidx, limit the search
1676  // to fragments that referenced this stream in the sidx
1677  if (sc->has_sidx) {
1678  frag_stream_info = get_frag_stream_info(frag_index, index, sc->id);
1679  if (!frag_stream_info)
1680  return AV_NOPTS_VALUE;
1681  if (frag_stream_info->sidx_pts != AV_NOPTS_VALUE)
1682  return frag_stream_info->sidx_pts;
1683  if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE)
1684  return frag_stream_info->first_tfra_pts;
1685  return frag_stream_info->sidx_pts;
1686  }
1687 
1688  for (i = 0; i < frag_index->item[index].nb_stream_info; i++) {
1689  AVStream *frag_stream = NULL;
1690  frag_stream_info = &frag_index->item[index].stream_info[i];
1691  for (j = 0; j < s->nb_streams; j++) {
1692  MOVStreamContext *sc2 = s->streams[j]->priv_data;
1693  if (sc2->id == frag_stream_info->id)
1694  frag_stream = s->streams[j];
1695  }
1696  if (!frag_stream) {
1697  av_log(s, AV_LOG_WARNING, "No stream matching sidx ID found.\n");
1698  continue;
1699  }
1700  timestamp = get_stream_info_time(frag_stream_info);
1701  if (timestamp != AV_NOPTS_VALUE)
1702  return av_rescale_q(timestamp, frag_stream->time_base, dst_st->time_base);
1703  }
1704  return AV_NOPTS_VALUE;
1705 }
1706 
1708  AVStream *st, int64_t timestamp)
1709 {
1710  int a, b, m, m0;
1711  int64_t frag_time;
1712 
1713  a = -1;
1714  b = frag_index->nb_items;
1715 
1716  while (b - a > 1) {
1717  m0 = m = (a + b) >> 1;
1718 
1719  while (m < b &&
1720  (frag_time = get_frag_time(s, st, frag_index, m)) == AV_NOPTS_VALUE)
1721  m++;
1722 
1723  if (m < b && frag_time <= timestamp)
1724  a = m;
1725  else
1726  b = m0;
1727  }
1728 
1729  return a;
1730 }
1731 
1733 {
1734  int index, i;
1735  MOVFragmentIndexItem * item;
1736  MOVFragmentStreamInfo * frag_stream_info;
1737 
1738  // If moof_offset already exists in frag_index, return index to it
1739  index = search_frag_moof_offset(&c->frag_index, offset);
1740  if (index < c->frag_index.nb_items &&
1741  c->frag_index.item[index].moof_offset == offset)
1742  return index;
1743 
1744  // offset is not yet in frag index.
1745  // Insert new item at index (sorted by moof offset)
1746  item = av_fast_realloc(c->frag_index.item,
1747  &c->frag_index.allocated_size,
1748  (c->frag_index.nb_items + 1) *
1749  sizeof(*c->frag_index.item));
1750  if (!item)
1751  return -1;
1752  c->frag_index.item = item;
1753 
1754  frag_stream_info = av_realloc_array(NULL, c->fc->nb_streams,
1755  sizeof(*item->stream_info));
1756  if (!frag_stream_info)
1757  return -1;
1758 
1759  for (i = 0; i < c->fc->nb_streams; i++) {
1760  // Avoid building frag index if streams lack track id.
1761  MOVStreamContext *sc = c->fc->streams[i]->priv_data;
1762  if (sc->id < 0) {
1763  av_free(frag_stream_info);
1764  return AVERROR_INVALIDDATA;
1765  }
1766 
1767  frag_stream_info[i].id = sc->id;
1768  frag_stream_info[i].sidx_pts = AV_NOPTS_VALUE;
1769  frag_stream_info[i].tfdt_dts = AV_NOPTS_VALUE;
1770  frag_stream_info[i].next_trun_dts = AV_NOPTS_VALUE;
1771  frag_stream_info[i].first_tfra_pts = AV_NOPTS_VALUE;
1772  frag_stream_info[i].index_base = -1;
1773  frag_stream_info[i].index_entry = -1;
1774  frag_stream_info[i].encryption_index = NULL;
1775  frag_stream_info[i].stsd_id = -1;
1776  }
1777 
1778  if (index < c->frag_index.nb_items)
1779  memmove(c->frag_index.item + index + 1, c->frag_index.item + index,
1780  (c->frag_index.nb_items - index) * sizeof(*c->frag_index.item));
1781 
1782  item = &c->frag_index.item[index];
1783  item->headers_read = 0;
1784  item->current = 0;
1785  item->nb_stream_info = c->fc->nb_streams;
1786  item->moof_offset = offset;
1787  item->stream_info = frag_stream_info;
1788  c->frag_index.nb_items++;
1789 
1790  return index;
1791 }
1792 
1793 static void fix_frag_index_entries(MOVFragmentIndex *frag_index, int index,
1794  int id, int entries)
1795 {
1796  int i;
1797  MOVFragmentStreamInfo * frag_stream_info;
1798 
1799  if (index < 0)
1800  return;
1801  for (i = index; i < frag_index->nb_items; i++) {
1802  frag_stream_info = get_frag_stream_info(frag_index, i, id);
1803  if (frag_stream_info && frag_stream_info->index_entry >= 0)
1804  frag_stream_info->index_entry += entries;
1805  }
1806 }
1807 
1809 {
1810  // Set by mov_read_tfhd(). mov_read_trun() will reject files missing tfhd.
1811  c->fragment.found_tfhd = 0;
1812 
1813  if (!c->has_looked_for_mfra && c->use_mfra_for > 0) {
1814  c->has_looked_for_mfra = 1;
1815  if (pb->seekable & AVIO_SEEKABLE_NORMAL) {
1816  int ret;
1817  av_log(c->fc, AV_LOG_VERBOSE, "stream has moof boxes, will look "
1818  "for a mfra\n");
1819  if ((ret = mov_read_mfra(c, pb)) < 0) {
1820  av_log(c->fc, AV_LOG_VERBOSE, "found a moof box but failed to "
1821  "read the mfra (may be a live ismv)\n");
1822  }
1823  } else {
1824  av_log(c->fc, AV_LOG_VERBOSE, "found a moof box but stream is not "
1825  "seekable, can not look for mfra\n");
1826  }
1827  }
1828  c->fragment.moof_offset = c->fragment.implicit_offset = avio_tell(pb) - 8;
1829  av_log(c->fc, AV_LOG_TRACE, "moof offset %"PRIx64"\n", c->fragment.moof_offset);
1830  c->frag_index.current = update_frag_index(c, c->fragment.moof_offset);
1831  return mov_read_default(c, pb, atom);
1832 }
1833 
1835 {
1836  int64_t time;
1837  if (version == 1) {
1838  time = avio_rb64(pb);
1839  avio_rb64(pb);
1840  if (time < 0) {
1841  av_log(c->fc, AV_LOG_DEBUG, "creation_time is negative\n");
1842  return;
1843  }
1844  } else {
1845  time = avio_rb32(pb);
1846  avio_rb32(pb); /* modification time */
1847  if (time > 0 && time < 2082844800) {
1848  av_log(c->fc, AV_LOG_WARNING, "Detected creation time before 1970, parsing as unix timestamp.\n");
1849  time += 2082844800;
1850  }
1851  }
1852  if (time) {
1853  time -= 2082844800; /* seconds between 1904-01-01 and Epoch */
1854 
1855  if ((int64_t)(time * 1000000ULL) / 1000000 != time) {
1856  av_log(c->fc, AV_LOG_DEBUG, "creation_time is not representable\n");
1857  return;
1858  }
1859 
1860  ff_dict_set_timestamp(metadata, "creation_time", time * 1000000);
1861  }
1862 }
1863 
1865 {
1866  AVStream *st;
1867  MOVStreamContext *sc;
1868  int version;
1869  char language[4] = {0};
1870  unsigned lang;
1871 
1872  if (c->fc->nb_streams < 1)
1873  return 0;
1874  st = c->fc->streams[c->fc->nb_streams-1];
1875  sc = st->priv_data;
1876 
1877  if (sc->time_scale) {
1878  av_log(c->fc, AV_LOG_ERROR, "Multiple mdhd?\n");
1879  return AVERROR_INVALIDDATA;
1880  }
1881 
1882  version = avio_r8(pb);
1883  if (version > 1) {
1884  avpriv_request_sample(c->fc, "Version %d", version);
1885  return AVERROR_PATCHWELCOME;
1886  }
1887  avio_rb24(pb); /* flags */
1889 
1890  sc->time_scale = avio_rb32(pb);
1891  if (sc->time_scale <= 0) {
1892  av_log(c->fc, AV_LOG_ERROR, "Invalid mdhd time scale %d, defaulting to 1\n", sc->time_scale);
1893  sc->time_scale = 1;
1894  }
1895  st->duration = (version == 1) ? avio_rb64(pb) : avio_rb32(pb); /* duration */
1896 
1897  if ((version == 1 && st->duration == UINT64_MAX) ||
1898  (version != 1 && st->duration == UINT32_MAX)) {
1899  st->duration = 0;
1900  }
1901 
1902  lang = avio_rb16(pb); /* language */
1903  if (ff_mov_lang_to_iso639(lang, language))
1904  av_dict_set(&st->metadata, "language", language, 0);
1905  avio_rb16(pb); /* quality */
1906 
1907  return 0;
1908 }
1909 
1911 {
1912  int i;
1913  int version = avio_r8(pb); /* version */
1914  avio_rb24(pb); /* flags */
1915 
1916  mov_metadata_creation_time(c, pb, &c->fc->metadata, version);
1917  c->time_scale = avio_rb32(pb); /* time scale */
1918  if (c->time_scale <= 0) {
1919  av_log(c->fc, AV_LOG_ERROR, "Invalid mvhd time scale %d, defaulting to 1\n", c->time_scale);
1920  c->time_scale = 1;
1921  }
1922  av_log(c->fc, AV_LOG_TRACE, "time scale = %i\n", c->time_scale);
1923 
1924  c->duration = (version == 1) ? avio_rb64(pb) : avio_rb32(pb); /* duration */
1925  avio_rb32(pb); /* preferred scale */
1926 
1927  avio_rb16(pb); /* preferred volume */
1928 
1929  avio_skip(pb, 10); /* reserved */
1930 
1931  /* movie display matrix, store it in main context and use it later on */
1932  for (i = 0; i < 3; i++) {
1933  c->movie_display_matrix[i][0] = avio_rb32(pb); // 16.16 fixed point
1934  c->movie_display_matrix[i][1] = avio_rb32(pb); // 16.16 fixed point
1935  c->movie_display_matrix[i][2] = avio_rb32(pb); // 2.30 fixed point
1936  }
1937 
1938  avio_rb32(pb); /* preview time */
1939  avio_rb32(pb); /* preview duration */
1940  avio_rb32(pb); /* poster time */
1941  avio_rb32(pb); /* selection time */
1942  avio_rb32(pb); /* selection duration */
1943  avio_rb32(pb); /* current time */
1944  avio_rb32(pb); /* next track ID */
1945 
1946  return 0;
1947 }
1948 
1950 {
1951  AVStream *st;
1952 
1953  if (fc->nb_streams < 1)
1954  return;
1955  st = fc->streams[fc->nb_streams-1];
1956 
1957  switch (st->codecpar->codec_id) {
1958  case AV_CODEC_ID_PCM_S16BE:
1960  break;
1961  case AV_CODEC_ID_PCM_S24BE:
1963  break;
1964  case AV_CODEC_ID_PCM_S32BE:
1966  break;
1967  case AV_CODEC_ID_PCM_F32BE:
1969  break;
1970  case AV_CODEC_ID_PCM_F64BE:
1972  break;
1973  default:
1974  break;
1975  }
1976 }
1977 
1979 {
1980  int little_endian = avio_rb16(pb) & 0xFF;
1981  av_log(c->fc, AV_LOG_TRACE, "enda %d\n", little_endian);
1982  if (little_endian == 1)
1984  return 0;
1985 }
1986 
1988 {
1989  int format_flags;
1990  int version, flags;
1991  int pcm_sample_size;
1992  AVFormatContext *fc = c->fc;
1993  AVStream *st;
1994  MOVStreamContext *sc;
1995 
1996  if (atom.size < 6) {
1997  av_log(c->fc, AV_LOG_ERROR, "Empty pcmC box\n");
1998  return AVERROR_INVALIDDATA;
1999  }
2000 
2001  version = avio_r8(pb);
2002  flags = avio_rb24(pb);
2003 
2004  if (version != 0 || flags != 0) {
2005  av_log(c->fc, AV_LOG_ERROR,
2006  "Unsupported 'pcmC' box with version %d, flags: %x",
2007  version, flags);
2008  return AVERROR_INVALIDDATA;
2009  }
2010 
2011  format_flags = avio_r8(pb);
2012  pcm_sample_size = avio_r8(pb);
2013 
2014  if (fc->nb_streams < 1)
2015  return AVERROR_INVALIDDATA;
2016 
2017  st = fc->streams[fc->nb_streams - 1];
2018  sc = st->priv_data;
2019 
2020  if (sc->format == MOV_MP4_FPCM_TAG) {
2021  switch (pcm_sample_size) {
2022  case 32:
2024  break;
2025  case 64:
2027  break;
2028  default:
2029  av_log(fc, AV_LOG_ERROR, "invalid pcm_sample_size %d for %s\n",
2030  pcm_sample_size,
2031  av_fourcc2str(sc->format));
2032  return AVERROR_INVALIDDATA;
2033  }
2034  } else if (sc->format == MOV_MP4_IPCM_TAG) {
2035  switch (pcm_sample_size) {
2036  case 16:
2038  break;
2039  case 24:
2041  break;
2042  case 32:
2044  break;
2045  default:
2046  av_log(fc, AV_LOG_ERROR, "invalid pcm_sample_size %d for %s\n",
2047  pcm_sample_size,
2048  av_fourcc2str(sc->format));
2049  return AVERROR_INVALIDDATA;
2050  }
2051  } else {
2052  av_log(fc, AV_LOG_ERROR, "'pcmC' with invalid sample entry '%s'\n",
2053  av_fourcc2str(sc->format));
2054  return AVERROR_INVALIDDATA;
2055  }
2056 
2057  if (format_flags & 1) // indicates little-endian format. If not present, big-endian format is used
2060 
2061  return 0;
2062 }
2063 
2065 {
2066  AVStream *st;
2067  HEIFItem *item = NULL;
2068  char color_parameter_type[5] = { 0 };
2069  uint16_t color_primaries, color_trc, color_matrix;
2070  int ret;
2071 
2072  st = get_curr_st(c);
2073  if (!st) {
2074  item = heif_cur_item(c);
2075  if (!item)
2076  return 0;
2077  }
2078 
2079  ret = ffio_read_size(pb, color_parameter_type, 4);
2080  if (ret < 0)
2081  return ret;
2082  if (strncmp(color_parameter_type, "nclx", 4) &&
2083  strncmp(color_parameter_type, "nclc", 4) &&
2084  strncmp(color_parameter_type, "prof", 4)) {
2085  av_log(c->fc, AV_LOG_WARNING, "unsupported color_parameter_type %s\n",
2086  color_parameter_type);
2087  return 0;
2088  }
2089 
2090  if (!strncmp(color_parameter_type, "prof", 4)) {
2091  AVPacketSideData *sd;
2092  uint8_t *icc_profile;
2093  if (st) {
2097  atom.size - 4, 0);
2098  if (!sd)
2099  return AVERROR(ENOMEM);
2100  icc_profile = sd->data;
2101  } else {
2102  av_freep(&item->icc_profile);
2103  icc_profile = item->icc_profile = av_malloc(atom.size - 4);
2104  if (!icc_profile) {
2105  item->icc_profile_size = 0;
2106  return AVERROR(ENOMEM);
2107  }
2108  item->icc_profile_size = atom.size - 4;
2109  }
2110  ret = ffio_read_size(pb, icc_profile, atom.size - 4);
2111  if (ret < 0)
2112  return ret;
2113  } else if (st) {
2114  color_primaries = avio_rb16(pb);
2115  color_trc = avio_rb16(pb);
2116  color_matrix = avio_rb16(pb);
2117 
2118  av_log(c->fc, AV_LOG_TRACE,
2119  "%s: pri %d trc %d matrix %d",
2120  color_parameter_type, color_primaries, color_trc, color_matrix);
2121 
2122  if (!strncmp(color_parameter_type, "nclx", 4)) {
2123  uint8_t color_range = avio_r8(pb) >> 7;
2124  av_log(c->fc, AV_LOG_TRACE, " full %"PRIu8"", color_range);
2125  if (color_range)
2127  else
2129  }
2130 
2133  if (!av_color_transfer_name(color_trc))
2134  color_trc = AVCOL_TRC_UNSPECIFIED;
2135  if (!av_color_space_name(color_matrix))
2136  color_matrix = AVCOL_SPC_UNSPECIFIED;
2137 
2139  st->codecpar->color_trc = color_trc;
2140  st->codecpar->color_space = color_matrix;
2141  av_log(c->fc, AV_LOG_TRACE, "\n");
2142  }
2143  return 0;
2144 }
2145 
2147 {
2148  AVStream *st;
2149  unsigned mov_field_order;
2150  enum AVFieldOrder decoded_field_order = AV_FIELD_UNKNOWN;
2151 
2152  if (c->fc->nb_streams < 1) // will happen with jp2 files
2153  return 0;
2154  st = c->fc->streams[c->fc->nb_streams-1];
2155  if (atom.size < 2)
2156  return AVERROR_INVALIDDATA;
2157  mov_field_order = avio_rb16(pb);
2158  if ((mov_field_order & 0xFF00) == 0x0100)
2159  decoded_field_order = AV_FIELD_PROGRESSIVE;
2160  else if ((mov_field_order & 0xFF00) == 0x0200) {
2161  switch (mov_field_order & 0xFF) {
2162  case 0x01: decoded_field_order = AV_FIELD_TT;
2163  break;
2164  case 0x06: decoded_field_order = AV_FIELD_BB;
2165  break;
2166  case 0x09: decoded_field_order = AV_FIELD_TB;
2167  break;
2168  case 0x0E: decoded_field_order = AV_FIELD_BT;
2169  break;
2170  }
2171  }
2172  if (decoded_field_order == AV_FIELD_UNKNOWN && mov_field_order) {
2173  av_log(c->fc, AV_LOG_ERROR, "Unknown MOV field order 0x%04x\n", mov_field_order);
2174  }
2175  st->codecpar->field_order = decoded_field_order;
2176 
2177  return 0;
2178 }
2179 
2181 {
2182  int err = 0;
2183  uint64_t size = (uint64_t)par->extradata_size + atom.size + 8 + AV_INPUT_BUFFER_PADDING_SIZE;
2184  if (size > INT_MAX || (uint64_t)atom.size > INT_MAX)
2185  return AVERROR_INVALIDDATA;
2186  if ((err = av_reallocp(&par->extradata, size)) < 0) {
2187  par->extradata_size = 0;
2188  return err;
2189  }
2191  return 0;
2192 }
2193 
2194 /* Read a whole atom into the extradata return the size of the atom read, possibly truncated if != atom.size */
2196  AVCodecParameters *par, uint8_t *buf)
2197 {
2198  int64_t result = atom.size;
2199  int err;
2200 
2201  AV_WB32(buf , atom.size + 8);
2202  AV_WL32(buf + 4, atom.type);
2203  err = ffio_read_size(pb, buf + 8, atom.size);
2204  if (err < 0) {
2205  par->extradata_size -= atom.size;
2206  return err;
2207  } else if (err < atom.size) {
2208  av_log(c->fc, AV_LOG_WARNING, "truncated extradata\n");
2209  par->extradata_size -= atom.size - err;
2210  result = err;
2211  }
2212  memset(buf + 8 + err, 0, AV_INPUT_BUFFER_PADDING_SIZE);
2213  return result;
2214 }
2215 
2216 /* FIXME modify QDM2/SVQ3/H.264 decoders to take full atom as extradata */
2218  enum AVCodecID codec_id)
2219 {
2220  AVStream *st;
2221  uint64_t original_size;
2222  int err;
2223 
2224  if (c->fc->nb_streams < 1) // will happen with jp2 files
2225  return 0;
2226  st = c->fc->streams[c->fc->nb_streams-1];
2227 
2228  if (st->codecpar->codec_id != codec_id)
2229  return 0; /* unexpected codec_id - don't mess with extradata */
2230 
2231  original_size = st->codecpar->extradata_size;
2232  err = mov_realloc_extradata(st->codecpar, atom);
2233  if (err)
2234  return err;
2235 
2236  err = mov_read_atom_into_extradata(c, pb, atom, st->codecpar, st->codecpar->extradata + original_size);
2237  if (err < 0)
2238  return err;
2239  return 0; // Note: this is the original behavior to ignore truncation.
2240 }
2241 
2242 /* wrapper functions for reading ALAC/AVS/MJPEG/MJPEG2000 extradata atoms only for those codecs */
2244 {
2245  return mov_read_extradata(c, pb, atom, AV_CODEC_ID_ALAC);
2246 }
2247 
2249 {
2250  return mov_read_extradata(c, pb, atom, AV_CODEC_ID_CAVS);
2251 }
2252 
2254 {
2255  return mov_read_extradata(c, pb, atom, AV_CODEC_ID_JPEG2000);
2256 }
2257 
2259 {
2260  return mov_read_extradata(c, pb, atom, AV_CODEC_ID_R10K);
2261 }
2262 
2264 {
2265  int ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_AVUI);
2266  if (!ret)
2267  ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_DNXHD);
2268  return ret;
2269 }
2270 
2272 {
2273  int ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_TARGA_Y216);
2274 
2275  if (!ret && c->fc->nb_streams >= 1) {
2276  AVCodecParameters *par = c->fc->streams[c->fc->nb_streams-1]->codecpar;
2277  if (par->extradata_size >= 40) {
2278  par->height = AV_RB16(&par->extradata[36]);
2279  par->width = AV_RB16(&par->extradata[38]);
2280  }
2281  }
2282  return ret;
2283 }
2284 
2286 {
2287  if (c->fc->nb_streams >= 1) {
2288  AVStream *const st = c->fc->streams[c->fc->nb_streams - 1];
2289  FFStream *const sti = ffstream(st);
2290  AVCodecParameters *par = st->codecpar;
2291 
2292  if (par->codec_tag == MKTAG('A', 'V', 'i', 'n') &&
2293  par->codec_id == AV_CODEC_ID_H264 &&
2294  atom.size > 11) {
2295  int cid;
2296  avio_skip(pb, 10);
2297  cid = avio_rb16(pb);
2298  /* For AVID AVCI50, force width of 1440 to be able to select the correct SPS and PPS */
2299  if (cid == 0xd4d || cid == 0xd4e)
2300  par->width = 1440;
2301  return 0;
2302  } else if ((par->codec_tag == MKTAG('A', 'V', 'd', '1') ||
2303  par->codec_tag == MKTAG('A', 'V', 'j', '2') ||
2304  par->codec_tag == MKTAG('A', 'V', 'd', 'n')) &&
2305  atom.size >= 24) {
2306  int num, den;
2307  avio_skip(pb, 12);
2308  num = avio_rb32(pb);
2309  den = avio_rb32(pb);
2310  if (num <= 0 || den <= 0)
2311  return 0;
2312  switch (avio_rb32(pb)) {
2313  case 2:
2314  if (den >= INT_MAX / 2)
2315  return 0;
2316  den *= 2;
2317  case 1:
2318  sti->display_aspect_ratio = (AVRational){ num, den };
2319  default:
2320  return 0;
2321  }
2322  }
2323  }
2324 
2325  return mov_read_avid(c, pb, atom);
2326 }
2327 
2329 {
2330  int ret = 0;
2331  int length = 0;
2332  uint64_t original_size;
2333  if (c->fc->nb_streams >= 1) {
2334  AVCodecParameters *par = c->fc->streams[c->fc->nb_streams-1]->codecpar;
2335  if (par->codec_id == AV_CODEC_ID_H264)
2336  return 0;
2337  if (atom.size == 16) {
2338  original_size = par->extradata_size;
2339  ret = mov_realloc_extradata(par, atom);
2340  if (!ret) {
2341  length = mov_read_atom_into_extradata(c, pb, atom, par, par->extradata + original_size);
2342  if (length == atom.size) {
2343  const uint8_t range_value = par->extradata[original_size + 19];
2344  switch (range_value) {
2345  case 1:
2347  break;
2348  case 2:
2350  break;
2351  default:
2352  av_log(c->fc, AV_LOG_WARNING, "ignored unknown aclr value (%d)\n", range_value);
2353  break;
2354  }
2355  ff_dlog(c->fc, "color_range: %d\n", par->color_range);
2356  } else {
2357  /* For some reason the whole atom was not added to the extradata */
2358  av_log(c->fc, AV_LOG_ERROR, "aclr not decoded - incomplete atom\n");
2359  }
2360  } else {
2361  av_log(c->fc, AV_LOG_ERROR, "aclr not decoded - unable to add atom to extradata\n");
2362  }
2363  } else {
2364  av_log(c->fc, AV_LOG_WARNING, "aclr not decoded - unexpected size %"PRId64"\n", atom.size);
2365  }
2366  }
2367 
2368  return ret;
2369 }
2370 
2372 {
2373  return mov_read_extradata(c, pb, atom, AV_CODEC_ID_SVQ3);
2374 }
2375 
2377 {
2378  AVStream *st;
2379  int ret;
2380 
2381  if (c->fc->nb_streams < 1)
2382  return 0;
2383  st = c->fc->streams[c->fc->nb_streams-1];
2384 
2385  if ((uint64_t)atom.size > (1<<30))
2386  return AVERROR_INVALIDDATA;
2387 
2388  if (st->codecpar->codec_id == AV_CODEC_ID_QDM2 ||
2391  // pass all frma atom to codec, needed at least for QDMC and QDM2
2392  ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size);
2393  if (ret < 0)
2394  return ret;
2395  } else if (atom.size > 8) { /* to read frma, esds atoms */
2396  if (st->codecpar->codec_id == AV_CODEC_ID_ALAC && atom.size >= 24) {
2397  uint64_t buffer;
2398  ret = ffio_ensure_seekback(pb, 8);
2399  if (ret < 0)
2400  return ret;
2401  buffer = avio_rb64(pb);
2402  atom.size -= 8;
2403  if ( (buffer & 0xFFFFFFFF) == MKBETAG('f','r','m','a')
2404  && buffer >> 32 <= atom.size
2405  && buffer >> 32 >= 8) {
2406  avio_skip(pb, -8);
2407  atom.size += 8;
2408  } else if (!st->codecpar->extradata_size) {
2409 #define ALAC_EXTRADATA_SIZE 36
2411  if (!st->codecpar->extradata)
2412  return AVERROR(ENOMEM);
2415  AV_WB32(st->codecpar->extradata + 4, MKTAG('a','l','a','c'));
2416  AV_WB64(st->codecpar->extradata + 12, buffer);
2417  avio_read(pb, st->codecpar->extradata + 20, 16);
2418  avio_skip(pb, atom.size - 24);
2419  return 0;
2420  }
2421  }
2422  if ((ret = mov_read_default(c, pb, atom)) < 0)
2423  return ret;
2424  } else
2425  avio_skip(pb, atom.size);
2426  return 0;
2427 }
2428 
2429 /**
2430  * This function reads atom content and puts data in extradata without tag
2431  * nor size unlike mov_read_extradata.
2432  */
2434 {
2435  AVStream *st;
2436  int ret;
2437 
2438  st = get_curr_st(c);
2439  if (!st)
2440  return 0;
2441 
2442  if ((uint64_t)atom.size > (1<<30))
2443  return AVERROR_INVALIDDATA;
2444 
2445  if (atom.type == MKTAG('v','v','c','C')) {
2446  avio_skip(pb, 4);
2447  atom.size -= 4;
2448  }
2449 
2450  if (atom.size >= 10) {
2451  // Broken files created by legacy versions of libavformat will
2452  // wrap a whole fiel atom inside of a glbl atom.
2453  unsigned size = avio_rb32(pb);
2454  unsigned type = avio_rl32(pb);
2455  if (avio_feof(pb))
2456  return AVERROR_INVALIDDATA;
2457  avio_seek(pb, -8, SEEK_CUR);
2458  if (type == MKTAG('f','i','e','l') && size == atom.size)
2459  return mov_read_default(c, pb, atom);
2460  }
2461  if (st->codecpar->extradata_size > 1 && st->codecpar->extradata) {
2462  av_log(c->fc, AV_LOG_WARNING, "ignoring multiple glbl\n");
2463  return 0;
2464  }
2465  ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size);
2466  if (ret < 0)
2467  return ret;
2468  if (atom.type == MKTAG('h','v','c','C') && st->codecpar->codec_tag == MKTAG('d','v','h','1'))
2469  /* HEVC-based Dolby Vision derived from hvc1.
2470  Happens to match with an identifier
2471  previously utilized for DV. Thus, if we have
2472  the hvcC extradata box available as specified,
2473  set codec to HEVC */
2475 
2476  return 0;
2477 }
2478 
2480 {
2481  AVStream *st;
2482  uint8_t profile_level;
2483  int ret;
2484 
2485  if (c->fc->nb_streams < 1)
2486  return 0;
2487  st = c->fc->streams[c->fc->nb_streams-1];
2488 
2489  if (atom.size >= (1<<28) || atom.size < 7)
2490  return AVERROR_INVALIDDATA;
2491 
2492  profile_level = avio_r8(pb);
2493  if ((profile_level & 0xf0) != 0xc0)
2494  return 0;
2495 
2496  avio_seek(pb, 6, SEEK_CUR);
2497  ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size - 7);
2498  if (ret < 0)
2499  return ret;
2500 
2501  return 0;
2502 }
2503 
2505 {
2506  AVStream* st;
2507  MOVStreamContext* sc;
2508 
2509  if (c->fc->nb_streams < 1)
2510  return 0;
2511 
2512  /* For SBAS this should be fine - though beware if someone implements a
2513  * tref atom processor that doesn't drop down to default then this may
2514  * be lost. */
2515  if (atom.size > 4) {
2516  av_log(c->fc, AV_LOG_ERROR, "Only a single tref of type sbas is supported\n");
2517  return AVERROR_PATCHWELCOME;
2518  }
2519 
2520  st = c->fc->streams[c->fc->nb_streams - 1];
2521  sc = st->priv_data;
2522  sc->tref_id = avio_rb32(pb);
2524 
2525  return 0;
2526 }
2527 
2528 /**
2529  * An strf atom is a BITMAPINFOHEADER struct. This struct is 40 bytes itself,
2530  * but can have extradata appended at the end after the 40 bytes belonging
2531  * to the struct.
2532  */
2534 {
2535  AVStream *st;
2536  int ret;
2537 
2538  if (c->fc->nb_streams < 1)
2539  return 0;
2540  if (atom.size <= 40)
2541  return 0;
2542  st = c->fc->streams[c->fc->nb_streams-1];
2543 
2544  if ((uint64_t)atom.size > (1<<30))
2545  return AVERROR_INVALIDDATA;
2546 
2547  avio_skip(pb, 40);
2548  ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size - 40);
2549  if (ret < 0)
2550  return ret;
2551 
2552  return 0;
2553 }
2554 
2556 {
2557  AVStream *st;
2558  MOVStreamContext *sc;
2559  unsigned int i, entries;
2560 
2561  if (c->trak_index < 0) {
2562  av_log(c->fc, AV_LOG_WARNING, "STCO outside TRAK\n");
2563  return 0;
2564  }
2565  if (c->fc->nb_streams < 1)
2566  return 0;
2567  st = c->fc->streams[c->fc->nb_streams-1];
2568  sc = st->priv_data;
2569 
2570  avio_r8(pb); /* version */
2571  avio_rb24(pb); /* flags */
2572 
2573  // Clamp allocation size for `chunk_offsets` -- don't throw an error for an
2574  // invalid count since the EOF path doesn't throw either.
2575  entries = avio_rb32(pb);
2576  entries =
2577  FFMIN(entries,
2578  FFMAX(0, (atom.size - 8) /
2579  (atom.type == MKTAG('s', 't', 'c', 'o') ? 4 : 8)));
2580 
2581  if (!entries)
2582  return 0;
2583 
2584  if (sc->chunk_offsets) {
2585  av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicated STCO atom\n");
2586  return 0;
2587  }
2588 
2589  av_free(sc->chunk_offsets);
2590  sc->chunk_count = 0;
2591  sc->chunk_offsets = av_malloc_array(entries, sizeof(*sc->chunk_offsets));
2592  if (!sc->chunk_offsets)
2593  return AVERROR(ENOMEM);
2594  sc->chunk_count = entries;
2595 
2596  if (atom.type == MKTAG('s','t','c','o'))
2597  for (i = 0; i < entries && !pb->eof_reached; i++)
2598  sc->chunk_offsets[i] = avio_rb32(pb);
2599  else if (atom.type == MKTAG('c','o','6','4'))
2600  for (i = 0; i < entries && !pb->eof_reached; i++) {
2601  sc->chunk_offsets[i] = avio_rb64(pb);
2602  if (sc->chunk_offsets[i] < 0) {
2603  av_log(c->fc, AV_LOG_WARNING, "Impossible chunk_offset\n");
2604  sc->chunk_offsets[i] = 0;
2605  }
2606  }
2607  else
2608  return AVERROR_INVALIDDATA;
2609 
2610  sc->chunk_count = i;
2611 
2612  if (pb->eof_reached) {
2613  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STCO atom\n");
2614  return AVERROR_EOF;
2615  }
2616 
2617  return 0;
2618 }
2619 
2620 static int mov_codec_id(AVStream *st, uint32_t format)
2621 {
2623 
2624  if (id <= 0 &&
2625  ((format & 0xFFFF) == 'm' + ('s' << 8) ||
2626  (format & 0xFFFF) == 'T' + ('S' << 8)))
2628 
2629  if (st->codecpar->codec_type != AVMEDIA_TYPE_VIDEO && id > 0) {
2631  } else if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO &&
2632  /* skip old ASF MPEG-4 tag */
2633  format && format != MKTAG('m','p','4','s')) {
2635  if (id <= 0)
2637  if (id > 0)
2639  else if (st->codecpar->codec_type == AVMEDIA_TYPE_DATA ||
2641  st->codecpar->codec_id == AV_CODEC_ID_NONE)) {
2643  if (id <= 0) {
2645  AV_CODEC_ID_TTML : id;
2646  }
2647 
2648  if (id > 0)
2650  else
2652  }
2653  }
2654 
2655  st->codecpar->codec_tag = format;
2656 
2657  return id;
2658 }
2659 
2661  AVStream *st, MOVStreamContext *sc)
2662 {
2663  uint8_t codec_name[32] = { 0 };
2664  int64_t stsd_start;
2665  unsigned int len;
2666  uint32_t id = 0;
2667 
2668  /* The first 16 bytes of the video sample description are already
2669  * read in ff_mov_read_stsd_entries() */
2670  stsd_start = avio_tell(pb) - 16;
2671 
2672  avio_rb16(pb); /* version */
2673  avio_rb16(pb); /* revision level */
2674  id = avio_rl32(pb); /* vendor */
2675  av_dict_set(&st->metadata, "vendor_id", av_fourcc2str(id), 0);
2676  avio_rb32(pb); /* temporal quality */
2677  avio_rb32(pb); /* spatial quality */
2678 
2679  st->codecpar->width = avio_rb16(pb); /* width */
2680  st->codecpar->height = avio_rb16(pb); /* height */
2681 
2682  avio_rb32(pb); /* horiz resolution */
2683  avio_rb32(pb); /* vert resolution */
2684  avio_rb32(pb); /* data size, always 0 */
2685  avio_rb16(pb); /* frames per samples */
2686 
2687  len = avio_r8(pb); /* codec name, pascal string */
2688  if (len > 31)
2689  len = 31;
2690  mov_read_mac_string(c, pb, len, codec_name, sizeof(codec_name));
2691  if (len < 31)
2692  avio_skip(pb, 31 - len);
2693 
2694  if (codec_name[0])
2695  av_dict_set(&st->metadata, "encoder", codec_name, 0);
2696 
2697  /* codec_tag YV12 triggers an UV swap in rawdec.c */
2698  if (!strncmp(codec_name, "Planar Y'CbCr 8-bit 4:2:0", 25)) {
2699  st->codecpar->codec_tag = MKTAG('I', '4', '2', '0');
2700  st->codecpar->width &= ~1;
2701  st->codecpar->height &= ~1;
2702  }
2703  /* Flash Media Server uses tag H.263 with Sorenson Spark */
2704  if (st->codecpar->codec_tag == MKTAG('H','2','6','3') &&
2705  !strncmp(codec_name, "Sorenson H263", 13))
2707 
2708  st->codecpar->bits_per_coded_sample = avio_rb16(pb); /* depth */
2709 
2710  avio_seek(pb, stsd_start, SEEK_SET);
2711 
2712  if (ff_get_qtpalette(st->codecpar->codec_id, pb, sc->palette)) {
2713  st->codecpar->bits_per_coded_sample &= 0x1F;
2714  sc->has_palette = 1;
2715  }
2716 }
2717 
2719  AVStream *st, MOVStreamContext *sc)
2720 {
2721  int bits_per_sample, flags;
2722  uint16_t version = avio_rb16(pb);
2723  uint32_t id = 0;
2724  AVDictionaryEntry *compatible_brands = av_dict_get(c->fc->metadata, "compatible_brands", NULL, AV_DICT_MATCH_CASE);
2725  int channel_count;
2726 
2727  avio_rb16(pb); /* revision level */
2728  id = avio_rl32(pb); /* vendor */
2729  av_dict_set(&st->metadata, "vendor_id", av_fourcc2str(id), 0);
2730 
2731  channel_count = avio_rb16(pb);
2732 
2734  st->codecpar->ch_layout.nb_channels = channel_count;
2735  st->codecpar->bits_per_coded_sample = avio_rb16(pb); /* sample size */
2736  av_log(c->fc, AV_LOG_TRACE, "audio channels %d\n", channel_count);
2737 
2738  sc->audio_cid = avio_rb16(pb);
2739  avio_rb16(pb); /* packet size = 0 */
2740 
2741  st->codecpar->sample_rate = ((avio_rb32(pb) >> 16));
2742 
2743  // Read QT version 1 fields. In version 0 these do not exist.
2744  av_log(c->fc, AV_LOG_TRACE, "version =%d, isom =%d\n", version, c->isom);
2745  if (!c->isom ||
2746  (compatible_brands && strstr(compatible_brands->value, "qt ")) ||
2747  (sc->stsd_version == 0 && version > 0)) {
2748  if (version == 1) {
2749  sc->samples_per_frame = avio_rb32(pb);
2750  avio_rb32(pb); /* bytes per packet */
2751  sc->bytes_per_frame = avio_rb32(pb);
2752  avio_rb32(pb); /* bytes per sample */
2753  } else if (version == 2) {
2754  avio_rb32(pb); /* sizeof struct only */
2756  channel_count = avio_rb32(pb);
2758  st->codecpar->ch_layout.nb_channels = channel_count;
2759  avio_rb32(pb); /* always 0x7F000000 */
2761 
2762  flags = avio_rb32(pb); /* lpcm format specific flag */
2763  sc->bytes_per_frame = avio_rb32(pb);
2764  sc->samples_per_frame = avio_rb32(pb);
2765  if (st->codecpar->codec_tag == MKTAG('l','p','c','m'))
2766  st->codecpar->codec_id =
2768  flags);
2769  }
2770  if (version == 0 || (version == 1 && sc->audio_cid != -2)) {
2771  /* can't correctly handle variable sized packet as audio unit */
2772  switch (st->codecpar->codec_id) {
2773  case AV_CODEC_ID_MP2:
2774  case AV_CODEC_ID_MP3:
2776  break;
2777  }
2778  }
2779  }
2780 
2781  if (sc->format == 0) {
2782  if (st->codecpar->bits_per_coded_sample == 8)
2783  st->codecpar->codec_id = mov_codec_id(st, MKTAG('r','a','w',' '));
2784  else if (st->codecpar->bits_per_coded_sample == 16)
2785  st->codecpar->codec_id = mov_codec_id(st, MKTAG('t','w','o','s'));
2786  }
2787 
2788  switch (st->codecpar->codec_id) {
2789  case AV_CODEC_ID_PCM_S8:
2790  case AV_CODEC_ID_PCM_U8:
2791  if (st->codecpar->bits_per_coded_sample == 16)
2793  break;
2794  case AV_CODEC_ID_PCM_S16LE:
2795  case AV_CODEC_ID_PCM_S16BE:
2796  if (st->codecpar->bits_per_coded_sample == 8)
2798  else if (st->codecpar->bits_per_coded_sample == 24)
2799  st->codecpar->codec_id =
2802  else if (st->codecpar->bits_per_coded_sample == 32)
2803  st->codecpar->codec_id =
2806  break;
2807  /* set values for old format before stsd version 1 appeared */
2808  case AV_CODEC_ID_MACE3:
2809  sc->samples_per_frame = 6;
2811  break;
2812  case AV_CODEC_ID_MACE6:
2813  sc->samples_per_frame = 6;
2815  break;
2817  sc->samples_per_frame = 64;
2819  break;
2820  case AV_CODEC_ID_GSM:
2821  sc->samples_per_frame = 160;
2822  sc->bytes_per_frame = 33;
2823  break;
2824  default:
2825  break;
2826  }
2827 
2828  bits_per_sample = av_get_bits_per_sample(st->codecpar->codec_id);
2829  if (bits_per_sample && (bits_per_sample >> 3) * (uint64_t)st->codecpar->ch_layout.nb_channels <= INT_MAX) {
2830  st->codecpar->bits_per_coded_sample = bits_per_sample;
2831  sc->sample_size = (bits_per_sample >> 3) * st->codecpar->ch_layout.nb_channels;
2832  }
2833 }
2834 
2836  AVStream *st, MOVStreamContext *sc,
2837  int64_t size)
2838 {
2839  // ttxt stsd contains display flags, justification, background
2840  // color, fonts, and default styles, so fake an atom to read it
2841  MOVAtom fake_atom = { .size = size };
2842  // mp4s contains a regular esds atom, dfxp ISMV TTML has no content
2843  // in extradata unlike stpp MP4 TTML.
2844  if (st->codecpar->codec_tag != AV_RL32("mp4s") &&
2846  mov_read_glbl(c, pb, fake_atom);
2847  st->codecpar->width = sc->width;
2848  st->codecpar->height = sc->height;
2849 }
2850 
2852  AVStream *st, MOVStreamContext *sc,
2853  int64_t size)
2854 {
2855  int ret;
2856 
2857  if (st->codecpar->codec_tag == MKTAG('t','m','c','d')) {
2858  if ((int)size != size)
2859  return AVERROR(ENOMEM);
2860 
2861  ret = ff_get_extradata(c->fc, st->codecpar, pb, size);
2862  if (ret < 0)
2863  return ret;
2864  if (size > 16) {
2865  MOVStreamContext *tmcd_ctx = st->priv_data;
2866  int val;
2867  val = AV_RB32(st->codecpar->extradata + 4);
2868  tmcd_ctx->tmcd_flags = val;
2869  st->avg_frame_rate.num = AV_RB32(st->codecpar->extradata + 8); /* timescale */
2870  st->avg_frame_rate.den = AV_RB32(st->codecpar->extradata + 12); /* frameDuration */
2871  tmcd_ctx->tmcd_nb_frames = st->codecpar->extradata[16]; /* number of frames */
2872  if (size > 30) {
2873  uint32_t len = AV_RB32(st->codecpar->extradata + 18); /* name atom length */
2874  uint32_t format = AV_RB32(st->codecpar->extradata + 22);
2875  if (format == AV_RB32("name") && (int64_t)size >= (int64_t)len + 18) {
2876  uint16_t str_size = AV_RB16(st->codecpar->extradata + 26); /* string length */
2877  if (str_size > 0 && size >= (int)str_size + 30 &&
2878  st->codecpar->extradata[30] /* Don't add empty string */) {
2879  char *reel_name = av_malloc(str_size + 1);
2880  if (!reel_name)
2881  return AVERROR(ENOMEM);
2882  memcpy(reel_name, st->codecpar->extradata + 30, str_size);
2883  reel_name[str_size] = 0; /* Add null terminator */
2884  av_dict_set(&st->metadata, "reel_name", reel_name,
2886  }
2887  }
2888  }
2889  }
2890  } else {
2891  /* other codec type, just skip (rtp, mp4s ...) */
2892  avio_skip(pb, size);
2893  }
2894  return 0;
2895 }
2896 
2898  AVStream *st, MOVStreamContext *sc)
2899 {
2900  FFStream *const sti = ffstream(st);
2901 
2902  if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
2903  !st->codecpar->sample_rate && sc->time_scale > 1)
2904  st->codecpar->sample_rate = sc->time_scale;
2905 
2906  /* special codec parameters handling */
2907  switch (st->codecpar->codec_id) {
2908 #if CONFIG_DV_DEMUXER
2909  case AV_CODEC_ID_DVAUDIO:
2910  if (c->dv_fctx) {
2911  avpriv_request_sample(c->fc, "multiple DV audio streams");
2912  return AVERROR(ENOSYS);
2913  }
2914 
2915  c->dv_fctx = avformat_alloc_context();
2916  if (!c->dv_fctx) {
2917  av_log(c->fc, AV_LOG_ERROR, "dv demux context alloc error\n");
2918  return AVERROR(ENOMEM);
2919  }
2920  c->dv_demux = avpriv_dv_init_demux(c->dv_fctx);
2921  if (!c->dv_demux) {
2922  av_log(c->fc, AV_LOG_ERROR, "dv demux context init error\n");
2923  return AVERROR(ENOMEM);
2924  }
2925  sc->dv_audio_container = 1;
2927  break;
2928 #endif
2929  /* no ifdef since parameters are always those */
2930  case AV_CODEC_ID_QCELP:
2933  // force sample rate for qcelp when not stored in mov
2934  if (st->codecpar->codec_tag != MKTAG('Q','c','l','p'))
2935  st->codecpar->sample_rate = 8000;
2936  // FIXME: Why is the following needed for some files?
2937  sc->samples_per_frame = 160;
2938  if (!sc->bytes_per_frame)
2939  sc->bytes_per_frame = 35;
2940  break;
2941  case AV_CODEC_ID_AMR_NB:
2944  /* force sample rate for amr, stsd in 3gp does not store sample rate */
2945  st->codecpar->sample_rate = 8000;
2946  break;
2947  case AV_CODEC_ID_AMR_WB:
2950  st->codecpar->sample_rate = 16000;
2951  break;
2952  case AV_CODEC_ID_MP2:
2953  case AV_CODEC_ID_MP3:
2954  /* force type after stsd for m1a hdlr */
2956  break;
2957  case AV_CODEC_ID_GSM:
2958  case AV_CODEC_ID_ADPCM_MS:
2960  case AV_CODEC_ID_ILBC:
2961  case AV_CODEC_ID_MACE3:
2962  case AV_CODEC_ID_MACE6:
2963  case AV_CODEC_ID_QDM2:
2965  break;
2966  case AV_CODEC_ID_ALAC:
2967  if (st->codecpar->extradata_size == 36) {
2968  int channel_count = AV_RB8(st->codecpar->extradata + 21);
2969  if (st->codecpar->ch_layout.nb_channels != channel_count) {
2972  st->codecpar->ch_layout.nb_channels = channel_count;
2973  }
2974  st->codecpar->sample_rate = AV_RB32(st->codecpar->extradata + 32);
2975  }
2976  break;
2977  case AV_CODEC_ID_AC3:
2978  case AV_CODEC_ID_EAC3:
2980  case AV_CODEC_ID_VC1:
2981  case AV_CODEC_ID_VP8:
2982  case AV_CODEC_ID_VP9:
2984  break;
2985  case AV_CODEC_ID_EVC:
2986  case AV_CODEC_ID_AV1:
2987  /* field_order detection of H264 requires parsing */
2988  case AV_CODEC_ID_H264:
2990  break;
2991  default:
2992  break;
2993  }
2994  return 0;
2995 }
2996 
2998  int codec_tag, int format,
2999  int64_t size)
3000 {
3001  if (codec_tag &&
3002  (codec_tag != format &&
3003  // AVID 1:1 samples with differing data format and codec tag exist
3004  (codec_tag != AV_RL32("AV1x") || format != AV_RL32("AVup")) &&
3005  // prores is allowed to have differing data format and codec tag
3006  codec_tag != AV_RL32("apcn") && codec_tag != AV_RL32("apch") &&
3007  // so is dv (sigh)
3008  codec_tag != AV_RL32("dvpp") && codec_tag != AV_RL32("dvcp") &&
3009  (c->fc->video_codec_id ? ff_codec_get_id(ff_codec_movvideo_tags, format) != c->fc->video_codec_id
3010  : codec_tag != MKTAG('j','p','e','g')))) {
3011  /* Multiple fourcc, we skip JPEG. This is not correct, we should
3012  * export it as a separate AVStream but this needs a few changes
3013  * in the MOV demuxer, patch welcome. */
3014 
3015  av_log(c->fc, AV_LOG_WARNING, "multiple fourcc not supported\n");
3016  avio_skip(pb, size);
3017  return 1;
3018  }
3019 
3020  return 0;
3021 }
3022 
3024 {
3025  AVStream *st;
3026  MOVStreamContext *sc;
3027  int pseudo_stream_id;
3028 
3029  av_assert0 (c->fc->nb_streams >= 1);
3030  st = c->fc->streams[c->fc->nb_streams-1];
3031  sc = st->priv_data;
3032 
3033  for (pseudo_stream_id = 0;
3034  pseudo_stream_id < entries && !pb->eof_reached;
3035  pseudo_stream_id++) {
3036  //Parsing Sample description table
3037  enum AVCodecID id;
3038  int ret, dref_id = 1;
3039  MOVAtom a = { AV_RL32("stsd") };
3040  int64_t start_pos = avio_tell(pb);
3041  int64_t size = avio_rb32(pb); /* size */
3042  uint32_t format = avio_rl32(pb); /* data format */
3043 
3044  if (size >= 16) {
3045  avio_rb32(pb); /* reserved */
3046  avio_rb16(pb); /* reserved */
3047  dref_id = avio_rb16(pb);
3048  } else if (size <= 7) {
3049  av_log(c->fc, AV_LOG_ERROR,
3050  "invalid size %"PRId64" in stsd\n", size);
3051  return AVERROR_INVALIDDATA;
3052  }
3053 
3055  size - (avio_tell(pb) - start_pos))) {
3056  sc->stsd_count++;
3057  continue;
3058  }
3059 
3060  sc->pseudo_stream_id = st->codecpar->codec_tag ? -1 : pseudo_stream_id;
3061  sc->dref_id= dref_id;
3062  sc->format = format;
3063 
3064  id = mov_codec_id(st, format);
3065 
3066  av_log(c->fc, AV_LOG_TRACE,
3067  "size=%"PRId64" 4CC=%s codec_type=%d\n", size,
3069 
3070  st->codecpar->codec_id = id;
3072  mov_parse_stsd_video(c, pb, st, sc);
3073  } else if (st->codecpar->codec_type==AVMEDIA_TYPE_AUDIO) {
3074  mov_parse_stsd_audio(c, pb, st, sc);
3075  if (st->codecpar->sample_rate < 0) {
3076  av_log(c->fc, AV_LOG_ERROR, "Invalid sample rate %d\n", st->codecpar->sample_rate);
3077  return AVERROR_INVALIDDATA;
3078  }
3079  if (st->codecpar->ch_layout.nb_channels < 0) {
3080  av_log(c->fc, AV_LOG_ERROR, "Invalid channels %d\n", st->codecpar->ch_layout.nb_channels);
3081  return AVERROR_INVALIDDATA;
3082  }
3083  } else if (st->codecpar->codec_type==AVMEDIA_TYPE_SUBTITLE){
3084  mov_parse_stsd_subtitle(c, pb, st, sc,
3085  size - (avio_tell(pb) - start_pos));
3086  } else {
3087  ret = mov_parse_stsd_data(c, pb, st, sc,
3088  size - (avio_tell(pb) - start_pos));
3089  if (ret < 0)
3090  return ret;
3091  }
3092  /* this will read extra atoms at the end (wave, alac, damr, avcC, hvcC, SMI ...) */
3093  a.size = size - (avio_tell(pb) - start_pos);
3094  if (a.size > 8) {
3095  if ((ret = mov_read_default(c, pb, a)) < 0)
3096  return ret;
3097  } else if (a.size > 0)
3098  avio_skip(pb, a.size);
3099 
3100  if (sc->extradata && st->codecpar->extradata) {
3101  int extra_size = st->codecpar->extradata_size;
3102 
3103  /* Move the current stream extradata to the stream context one. */
3104  sc->extradata_size[pseudo_stream_id] = extra_size;
3105  sc->extradata[pseudo_stream_id] = st->codecpar->extradata;
3106  st->codecpar->extradata = NULL;
3107  st->codecpar->extradata_size = 0;
3108  }
3109  sc->stsd_count++;
3110  }
3111 
3112  if (pb->eof_reached) {
3113  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSD atom\n");
3114  return AVERROR_EOF;
3115  }
3116 
3117  return 0;
3118 }
3119 
3121 {
3122  AVStream *st;
3123  MOVStreamContext *sc;
3124  int ret, entries;
3125 
3126  if (c->fc->nb_streams < 1)
3127  return 0;
3128  st = c->fc->streams[c->fc->nb_streams - 1];
3129  sc = st->priv_data;
3130 
3131  sc->stsd_version = avio_r8(pb);
3132  avio_rb24(pb); /* flags */
3133  entries = avio_rb32(pb);
3134 
3135  /* Each entry contains a size (4 bytes) and format (4 bytes). */
3136  if (entries <= 0 || entries > atom.size / 8 || entries > 1024) {
3137  av_log(c->fc, AV_LOG_ERROR, "invalid STSD entries %d\n", entries);
3138  return AVERROR_INVALIDDATA;
3139  }
3140 
3141  if (sc->extradata) {
3142  av_log(c->fc, AV_LOG_ERROR,
3143  "Duplicate stsd found in this track.\n");
3144  return AVERROR_INVALIDDATA;
3145  }
3146 
3147  /* Prepare space for hosting multiple extradata. */
3148  sc->extradata = av_calloc(entries, sizeof(*sc->extradata));
3149  if (!sc->extradata)
3150  return AVERROR(ENOMEM);
3151 
3152  sc->extradata_size = av_calloc(entries, sizeof(*sc->extradata_size));
3153  if (!sc->extradata_size) {
3154  ret = AVERROR(ENOMEM);
3155  goto fail;
3156  }
3157 
3158  ret = ff_mov_read_stsd_entries(c, pb, entries);
3159  if (ret < 0)
3160  goto fail;
3161 
3162  /* Restore back the primary extradata. */
3163  av_freep(&st->codecpar->extradata);
3164  st->codecpar->extradata_size = sc->extradata_size[0];
3165  if (sc->extradata_size[0]) {
3167  if (!st->codecpar->extradata)
3168  return AVERROR(ENOMEM);
3169  memcpy(st->codecpar->extradata, sc->extradata[0], sc->extradata_size[0]);
3170  }
3171 
3172  return mov_finalize_stsd_codec(c, pb, st, sc);
3173 fail:
3174  if (sc->extradata) {
3175  int j;
3176  for (j = 0; j < sc->stsd_count; j++)
3177  av_freep(&sc->extradata[j]);
3178  }
3179 
3180  av_freep(&sc->extradata);
3181  av_freep(&sc->extradata_size);
3182  return ret;
3183 }
3184 
3186 {
3187  AVStream *st;
3188  MOVStreamContext *sc;
3189  unsigned int i, entries;
3190 
3191  if (c->trak_index < 0) {
3192  av_log(c->fc, AV_LOG_WARNING, "STSC outside TRAK\n");
3193  return 0;
3194  }
3195 
3196  if (c->fc->nb_streams < 1)
3197  return 0;
3198  st = c->fc->streams[c->fc->nb_streams-1];
3199  sc = st->priv_data;
3200 
3201  avio_r8(pb); /* version */
3202  avio_rb24(pb); /* flags */
3203 
3204  entries = avio_rb32(pb);
3205  if ((uint64_t)entries * 12 + 4 > atom.size)
3206  return AVERROR_INVALIDDATA;
3207 
3208  av_log(c->fc, AV_LOG_TRACE, "track[%u].stsc.entries = %u\n", c->fc->nb_streams - 1, entries);
3209 
3210  if (!entries)
3211  return 0;
3212  if (sc->stsc_data) {
3213  av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicated STSC atom\n");
3214  return 0;
3215  }
3216  av_free(sc->stsc_data);
3217  sc->stsc_count = 0;
3218  sc->stsc_data = av_malloc_array(entries, sizeof(*sc->stsc_data));
3219  if (!sc->stsc_data)
3220  return AVERROR(ENOMEM);
3221 
3222  for (i = 0; i < entries && !pb->eof_reached; i++) {
3223  sc->stsc_data[i].first = avio_rb32(pb);
3224  sc->stsc_data[i].count = avio_rb32(pb);
3225  sc->stsc_data[i].id = avio_rb32(pb);
3226  }
3227 
3228  sc->stsc_count = i;
3229  for (i = sc->stsc_count - 1; i < UINT_MAX; i--) {
3230  int64_t first_min = i + 1;
3231  if ((i+1 < sc->stsc_count && sc->stsc_data[i].first >= sc->stsc_data[i+1].first) ||
3232  (i > 0 && sc->stsc_data[i].first <= sc->stsc_data[i-1].first) ||
3233  sc->stsc_data[i].first < first_min ||
3234  sc->stsc_data[i].count < 1 ||
3235  sc->stsc_data[i].id < 1) {
3236  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);
3237  if (i+1 >= sc->stsc_count) {
3238  if (sc->stsc_data[i].count == 0 && i > 0) {
3239  sc->stsc_count --;
3240  continue;
3241  }
3242  sc->stsc_data[i].first = FFMAX(sc->stsc_data[i].first, first_min);
3243  if (i > 0 && sc->stsc_data[i].first <= sc->stsc_data[i-1].first)
3244  sc->stsc_data[i].first = FFMIN(sc->stsc_data[i-1].first + 1LL, INT_MAX);
3245  sc->stsc_data[i].count = FFMAX(sc->stsc_data[i].count, 1);
3246  sc->stsc_data[i].id = FFMAX(sc->stsc_data[i].id, 1);
3247  continue;
3248  }
3249  av_assert0(sc->stsc_data[i+1].first >= 2);
3250  // We replace this entry by the next valid
3251  sc->stsc_data[i].first = sc->stsc_data[i+1].first - 1;
3252  sc->stsc_data[i].count = sc->stsc_data[i+1].count;
3253  sc->stsc_data[i].id = sc->stsc_data[i+1].id;
3254  }
3255  }
3256 
3257  if (pb->eof_reached) {
3258  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSC atom\n");
3259  return AVERROR_EOF;
3260  }
3261 
3262  return 0;
3263 }
3264 
3265 static inline int mov_stsc_index_valid(unsigned int index, unsigned int count)
3266 {
3267  return index < count - 1;
3268 }
3269 
3270 /* Compute the samples value for the stsc entry at the given index. */
3271 static inline int64_t mov_get_stsc_samples(MOVStreamContext *sc, unsigned int index)
3272 {
3273  int chunk_count;
3274 
3276  chunk_count = sc->stsc_data[index + 1].first - sc->stsc_data[index].first;
3277  else {
3278  // Validation for stsc / stco happens earlier in mov_read_stsc + mov_read_trak.
3280  chunk_count = sc->chunk_count - (sc->stsc_data[index].first - 1);
3281  }
3282 
3283  return sc->stsc_data[index].count * (int64_t)chunk_count;
3284 }
3285 
3287 {
3288  AVStream *st;
3289  MOVStreamContext *sc;
3290  unsigned i, entries;
3291 
3292  if (c->trak_index < 0) {
3293  av_log(c->fc, AV_LOG_WARNING, "STPS outside TRAK\n");
3294  return 0;
3295  }
3296 
3297  if (c->fc->nb_streams < 1)
3298  return 0;
3299  st = c->fc->streams[c->fc->nb_streams-1];
3300  sc = st->priv_data;
3301 
3302  avio_rb32(pb); // version + flags
3303 
3304  entries = avio_rb32(pb);
3305  if (sc->stps_data)
3306  av_log(c->fc, AV_LOG_WARNING, "Duplicated STPS atom\n");
3307  av_free(sc->stps_data);
3308  sc->stps_count = 0;
3309  sc->stps_data = av_malloc_array(entries, sizeof(*sc->stps_data));
3310  if (!sc->stps_data)
3311  return AVERROR(ENOMEM);
3312 
3313  for (i = 0; i < entries && !pb->eof_reached; i++) {
3314  sc->stps_data[i] = avio_rb32(pb);
3315  }
3316 
3317  sc->stps_count = i;
3318 
3319  if (pb->eof_reached) {
3320  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STPS atom\n");
3321  return AVERROR_EOF;
3322  }
3323 
3324  return 0;
3325 }
3326 
3328 {
3329  AVStream *st;
3330  FFStream *sti;
3331  MOVStreamContext *sc;
3332  unsigned int i, entries;
3333 
3334  if (c->trak_index < 0) {
3335  av_log(c->fc, AV_LOG_WARNING, "STSS 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  sti = ffstream(st);
3343  sc = st->priv_data;
3344 
3345  avio_r8(pb); /* version */
3346  avio_rb24(pb); /* flags */
3347 
3348  entries = avio_rb32(pb);
3349 
3350  av_log(c->fc, AV_LOG_TRACE, "keyframe_count = %u\n", entries);
3351 
3352  if (!entries) {
3353  sc->keyframe_absent = 1;
3354  if (!sti->need_parsing && st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
3356  return 0;
3357  }
3358  if (sc->keyframes)
3359  av_log(c->fc, AV_LOG_WARNING, "Duplicated STSS atom\n");
3360  if (entries >= UINT_MAX / sizeof(int))
3361  return AVERROR_INVALIDDATA;
3362  av_freep(&sc->keyframes);
3363  sc->keyframe_count = 0;
3364  sc->keyframes = av_malloc_array(entries, sizeof(*sc->keyframes));
3365  if (!sc->keyframes)
3366  return AVERROR(ENOMEM);
3367 
3368  for (i = 0; i < entries && !pb->eof_reached; i++) {
3369  sc->keyframes[i] = avio_rb32(pb);
3370  }
3371 
3372  sc->keyframe_count = i;
3373 
3374  if (pb->eof_reached) {
3375  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSS atom\n");
3376  return AVERROR_EOF;
3377  }
3378 
3379  return 0;
3380 }
3381 
3383 {
3384  AVStream *st;
3385  MOVStreamContext *sc;
3386  unsigned int i, entries, sample_size, field_size, num_bytes;
3387  GetBitContext gb;
3388  unsigned char* buf;
3389  int ret;
3390 
3391  if (c->trak_index < 0) {
3392  av_log(c->fc, AV_LOG_WARNING, "STSZ outside TRAK\n");
3393  return 0;
3394  }
3395 
3396  if (c->fc->nb_streams < 1)
3397  return 0;
3398  st = c->fc->streams[c->fc->nb_streams-1];
3399  sc = st->priv_data;
3400 
3401  avio_r8(pb); /* version */
3402  avio_rb24(pb); /* flags */
3403 
3404  if (atom.type == MKTAG('s','t','s','z')) {
3405  sample_size = avio_rb32(pb);
3406  if (!sc->sample_size) /* do not overwrite value computed in stsd */
3407  sc->sample_size = sample_size;
3408  sc->stsz_sample_size = sample_size;
3409  field_size = 32;
3410  } else {
3411  sample_size = 0;
3412  avio_rb24(pb); /* reserved */
3413  field_size = avio_r8(pb);
3414  }
3415  entries = avio_rb32(pb);
3416 
3417  av_log(c->fc, AV_LOG_TRACE, "sample_size = %u sample_count = %u\n", sc->sample_size, entries);
3418 
3419  sc->sample_count = entries;
3420  if (sample_size)
3421  return 0;
3422 
3423  if (field_size != 4 && field_size != 8 && field_size != 16 && field_size != 32) {
3424  av_log(c->fc, AV_LOG_ERROR, "Invalid sample field size %u\n", field_size);
3425  return AVERROR_INVALIDDATA;
3426  }
3427 
3428  if (!entries)
3429  return 0;
3430  if (entries >= (INT_MAX - 4 - 8 * AV_INPUT_BUFFER_PADDING_SIZE) / field_size)
3431  return AVERROR_INVALIDDATA;
3432  if (sc->sample_sizes)
3433  av_log(c->fc, AV_LOG_WARNING, "Duplicated STSZ atom\n");
3434  av_free(sc->sample_sizes);
3435  sc->sample_count = 0;
3436  sc->sample_sizes = av_malloc_array(entries, sizeof(*sc->sample_sizes));
3437  if (!sc->sample_sizes)
3438  return AVERROR(ENOMEM);
3439 
3440  num_bytes = (entries*field_size+4)>>3;
3441 
3442  buf = av_malloc(num_bytes+AV_INPUT_BUFFER_PADDING_SIZE);
3443  if (!buf) {
3444  av_freep(&sc->sample_sizes);
3445  return AVERROR(ENOMEM);
3446  }
3447 
3448  ret = ffio_read_size(pb, buf, num_bytes);
3449  if (ret < 0) {
3450  av_freep(&sc->sample_sizes);
3451  av_free(buf);
3452  av_log(c->fc, AV_LOG_WARNING, "STSZ atom truncated\n");
3453  return 0;
3454  }
3455 
3456  init_get_bits(&gb, buf, 8*num_bytes);
3457 
3458  for (i = 0; i < entries; i++) {
3459  sc->sample_sizes[i] = get_bits_long(&gb, field_size);
3460  if (sc->sample_sizes[i] > INT64_MAX - sc->data_size) {
3461  av_free(buf);
3462  av_log(c->fc, AV_LOG_ERROR, "Sample size overflow in STSZ\n");
3463  return AVERROR_INVALIDDATA;
3464  }
3465  sc->data_size += sc->sample_sizes[i];
3466  }
3467 
3468  sc->sample_count = i;
3469 
3470  av_free(buf);
3471 
3472  return 0;
3473 }
3474 
3476 {
3477  AVStream *st;
3478  MOVStreamContext *sc;
3479  unsigned int i, entries;
3480  int64_t duration = 0;
3481  int64_t total_sample_count = 0;
3482  int64_t current_dts = 0;
3483  int64_t corrected_dts = 0;
3484 
3485  if (c->trak_index < 0) {
3486  av_log(c->fc, AV_LOG_WARNING, "STTS outside TRAK\n");
3487  return 0;
3488  }
3489 
3490  if (c->fc->nb_streams < 1)
3491  return 0;
3492  st = c->fc->streams[c->fc->nb_streams-1];
3493  sc = st->priv_data;
3494 
3495  avio_r8(pb); /* version */
3496  avio_rb24(pb); /* flags */
3497  entries = avio_rb32(pb);
3498 
3499  av_log(c->fc, AV_LOG_TRACE, "track[%u].stts.entries = %u\n",
3500  c->fc->nb_streams-1, entries);
3501 
3502  if (sc->stts_data)
3503  av_log(c->fc, AV_LOG_WARNING, "Duplicated STTS atom\n");
3504  av_freep(&sc->stts_data);
3505  sc->stts_count = 0;
3506  if (entries >= INT_MAX / sizeof(*sc->stts_data))
3507  return AVERROR(ENOMEM);
3508 
3509  for (i = 0; i < entries && !pb->eof_reached; i++) {
3510  unsigned int sample_duration;
3511  unsigned int sample_count;
3512  unsigned int min_entries = FFMIN(FFMAX(i + 1, 1024 * 1024), entries);
3513  MOVStts *stts_data = av_fast_realloc(sc->stts_data, &sc->stts_allocated_size,
3514  min_entries * sizeof(*sc->stts_data));
3515  if (!stts_data) {
3516  av_freep(&sc->stts_data);
3517  sc->stts_count = 0;
3518  return AVERROR(ENOMEM);
3519  }
3520  sc->stts_count = min_entries;
3521  sc->stts_data = stts_data;
3522 
3523  sample_count = avio_rb32(pb);
3524  sample_duration = avio_rb32(pb);
3525 
3526  sc->stts_data[i].count= sample_count;
3527  sc->stts_data[i].duration= sample_duration;
3528 
3529  av_log(c->fc, AV_LOG_TRACE, "sample_count=%u, sample_duration=%u\n",
3530  sample_count, sample_duration);
3531 
3532  /* STTS sample offsets are uint32 but some files store it as int32
3533  * with negative values used to correct DTS delays.
3534  There may be abnormally large values as well. */
3535  if (sample_duration > c->max_stts_delta) {
3536  // assume high delta is a correction if negative when cast as int32
3537  int32_t delta_magnitude = (int32_t)sample_duration;
3538  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",
3539  sample_duration, i, sample_count, st->index);
3540  sc->stts_data[i].duration = 1;
3541  corrected_dts = av_sat_add64(corrected_dts, (delta_magnitude < 0 ? (int64_t)delta_magnitude : 1) * sample_count);
3542  } else {
3543  corrected_dts += sample_duration * (uint64_t)sample_count;
3544  }
3545 
3546  current_dts += sc->stts_data[i].duration * (uint64_t)sample_count;
3547 
3548  if (current_dts > corrected_dts) {
3549  int64_t drift = av_sat_sub64(current_dts, corrected_dts) / FFMAX(sample_count, 1);
3550  uint32_t correction = (sc->stts_data[i].duration > drift) ? drift : sc->stts_data[i].duration - 1;
3551  current_dts -= correction * (uint64_t)sample_count;
3552  sc->stts_data[i].duration -= correction;
3553  }
3554 
3555  duration+=(int64_t)sc->stts_data[i].duration*(uint64_t)sc->stts_data[i].count;
3556  total_sample_count+=sc->stts_data[i].count;
3557  }
3558 
3559  sc->stts_count = i;
3560 
3561  if (duration > 0 &&
3562  duration <= INT64_MAX - sc->duration_for_fps &&
3563  total_sample_count <= INT_MAX - sc->nb_frames_for_fps) {
3564  sc->duration_for_fps += duration;
3565  sc->nb_frames_for_fps += total_sample_count;
3566  }
3567 
3568  if (pb->eof_reached) {
3569  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STTS atom\n");
3570  return AVERROR_EOF;
3571  }
3572 
3573  st->nb_frames= total_sample_count;
3574  if (duration)
3575  st->duration= FFMIN(st->duration, duration);
3576 
3577  // All samples have zero duration. They have higher chance be chose by
3578  // mov_find_next_sample, which leads to seek again and again.
3579  //
3580  // It's AVERROR_INVALIDDATA actually, but such files exist in the wild.
3581  // So only mark data stream as discarded for safety.
3582  if (!duration && sc->stts_count &&
3584  av_log(c->fc, AV_LOG_WARNING,
3585  "All samples in data stream index:id [%d:%d] have zero "
3586  "duration, stream set to be discarded by default. Override "
3587  "using AVStream->discard or -discard for ffmpeg command.\n",
3588  st->index, sc->id);
3589  st->discard = AVDISCARD_ALL;
3590  }
3591  sc->track_end = duration;
3592  return 0;
3593 }
3594 
3596 {
3597  AVStream *st;
3598  MOVStreamContext *sc;
3599  int64_t i, entries;
3600 
3601  if (c->fc->nb_streams < 1)
3602  return 0;
3603  st = c->fc->streams[c->fc->nb_streams - 1];
3604  sc = st->priv_data;
3605 
3606  avio_r8(pb); /* version */
3607  avio_rb24(pb); /* flags */
3608  entries = atom.size - 4;
3609 
3610  av_log(c->fc, AV_LOG_TRACE, "track[%u].sdtp.entries = %" PRId64 "\n",
3611  c->fc->nb_streams - 1, entries);
3612 
3613  if (sc->sdtp_data)
3614  av_log(c->fc, AV_LOG_WARNING, "Duplicated SDTP atom\n");
3615  av_freep(&sc->sdtp_data);
3616  sc->sdtp_count = 0;
3617 
3618  sc->sdtp_data = av_malloc(entries);
3619  if (!sc->sdtp_data)
3620  return AVERROR(ENOMEM);
3621 
3622  for (i = 0; i < entries && !pb->eof_reached; i++)
3623  sc->sdtp_data[i] = avio_r8(pb);
3624  sc->sdtp_count = i;
3625 
3626  return 0;
3627 }
3628 
3629 static void mov_update_dts_shift(MOVStreamContext *sc, int duration, void *logctx)
3630 {
3631  if (duration < 0) {
3632  if (duration == INT_MIN) {
3633  av_log(logctx, AV_LOG_WARNING, "mov_update_dts_shift(): dts_shift set to %d\n", INT_MAX);
3634  duration++;
3635  }
3636  sc->dts_shift = FFMAX(sc->dts_shift, -duration);
3637  }
3638 }
3639 
3641 {
3642  AVStream *st;
3643  MOVStreamContext *sc;
3644  unsigned int i, entries, ctts_count = 0;
3645 
3646  if (c->trak_index < 0) {
3647  av_log(c->fc, AV_LOG_WARNING, "CTTS outside TRAK\n");
3648  return 0;
3649  }
3650 
3651  if (c->fc->nb_streams < 1)
3652  return 0;
3653  st = c->fc->streams[c->fc->nb_streams-1];
3654  sc = st->priv_data;
3655 
3656  avio_r8(pb); /* version */
3657  avio_rb24(pb); /* flags */
3658  entries = avio_rb32(pb);
3659 
3660  av_log(c->fc, AV_LOG_TRACE, "track[%u].ctts.entries = %u\n", c->fc->nb_streams - 1, entries);
3661 
3662  if (!entries)
3663  return 0;
3664  if (entries >= UINT_MAX / sizeof(*sc->ctts_data))
3665  return AVERROR_INVALIDDATA;
3666  av_freep(&sc->ctts_data);
3667  sc->ctts_data = av_fast_realloc(NULL, &sc->ctts_allocated_size, entries * sizeof(*sc->ctts_data));
3668  if (!sc->ctts_data)
3669  return AVERROR(ENOMEM);
3670 
3671  for (i = 0; i < entries && !pb->eof_reached; i++) {
3672  MOVCtts *ctts_data;
3673  const size_t min_size_needed = (ctts_count + 1) * sizeof(MOVCtts);
3674  const size_t requested_size =
3675  min_size_needed > sc->ctts_allocated_size ?
3676  FFMAX(min_size_needed, 2 * sc->ctts_allocated_size) :
3677  min_size_needed;
3678  int count = avio_rb32(pb);
3679  int duration = avio_rb32(pb);
3680 
3681  if (count <= 0) {
3682  av_log(c->fc, AV_LOG_TRACE,
3683  "ignoring CTTS entry with count=%d duration=%d\n",
3684  count, duration);
3685  continue;
3686  }
3687 
3688  if (ctts_count >= UINT_MAX / sizeof(MOVCtts) - 1)
3689  return AVERROR(ENOMEM);
3690 
3691  ctts_data = av_fast_realloc(sc->ctts_data, &sc->ctts_allocated_size, requested_size);
3692 
3693  if (!ctts_data)
3694  return AVERROR(ENOMEM);
3695 
3696  sc->ctts_data = ctts_data;
3697 
3698  ctts_data[ctts_count].count = count;
3699  ctts_data[ctts_count].offset = duration;
3700  ctts_count++;
3701 
3702  av_log(c->fc, AV_LOG_TRACE, "count=%d, duration=%d\n",
3703  count, duration);
3704 
3705  if (i+2<entries)
3706  mov_update_dts_shift(sc, duration, c->fc);
3707  }
3708 
3709  sc->ctts_count = ctts_count;
3710 
3711  if (pb->eof_reached) {
3712  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted CTTS atom\n");
3713  return AVERROR_EOF;
3714  }
3715 
3716  av_log(c->fc, AV_LOG_TRACE, "dts shift %d\n", sc->dts_shift);
3717 
3718  return 0;
3719 }
3720 
3722 {
3723  AVStream *st;
3724  MOVStreamContext *sc;
3725  uint8_t version;
3726  uint32_t grouping_type;
3727  uint32_t default_length;
3728  av_unused uint32_t default_group_description_index;
3729  uint32_t entry_count;
3730 
3731  if (c->fc->nb_streams < 1)
3732  return 0;
3733  st = c->fc->streams[c->fc->nb_streams - 1];
3734  sc = st->priv_data;
3735 
3736  version = avio_r8(pb); /* version */
3737  avio_rb24(pb); /* flags */
3738  grouping_type = avio_rl32(pb);
3739 
3740  /*
3741  * This function only supports "sync" boxes, but the code is able to parse
3742  * other boxes (such as "tscl", "tsas" and "stsa")
3743  */
3744  if (grouping_type != MKTAG('s','y','n','c'))
3745  return 0;
3746 
3747  default_length = version >= 1 ? avio_rb32(pb) : 0;
3748  default_group_description_index = version >= 2 ? avio_rb32(pb) : 0;
3749  entry_count = avio_rb32(pb);
3750 
3751  av_freep(&sc->sgpd_sync);
3752  sc->sgpd_sync_count = entry_count;
3753  sc->sgpd_sync = av_calloc(entry_count, sizeof(*sc->sgpd_sync));
3754  if (!sc->sgpd_sync)
3755  return AVERROR(ENOMEM);
3756 
3757  for (uint32_t i = 0; i < entry_count && !pb->eof_reached; i++) {
3758  uint32_t description_length = default_length;
3759  if (version >= 1 && default_length == 0)
3760  description_length = avio_rb32(pb);
3761  if (grouping_type == MKTAG('s','y','n','c')) {
3762  const uint8_t nal_unit_type = avio_r8(pb) & 0x3f;
3763  sc->sgpd_sync[i] = nal_unit_type;
3764  description_length -= 1;
3765  }
3766  avio_skip(pb, description_length);
3767  }
3768 
3769  if (pb->eof_reached) {
3770  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted SGPD atom\n");
3771  return AVERROR_EOF;
3772  }
3773 
3774  return 0;
3775 }
3776 
3778 {
3779  AVStream *st;
3780  MOVStreamContext *sc;
3781  unsigned int i, entries;
3782  uint8_t version;
3783  uint32_t grouping_type;
3784  MOVSbgp *table, **tablep;
3785  int *table_count;
3786 
3787  if (c->fc->nb_streams < 1)
3788  return 0;
3789  st = c->fc->streams[c->fc->nb_streams-1];
3790  sc = st->priv_data;
3791 
3792  version = avio_r8(pb); /* version */
3793  avio_rb24(pb); /* flags */
3794  grouping_type = avio_rl32(pb);
3795 
3796  if (grouping_type == MKTAG('r','a','p',' ')) {
3797  tablep = &sc->rap_group;
3798  table_count = &sc->rap_group_count;
3799  } else if (grouping_type == MKTAG('s','y','n','c')) {
3800  tablep = &sc->sync_group;
3801  table_count = &sc->sync_group_count;
3802  } else {
3803  return 0;
3804  }
3805 
3806  if (version == 1)
3807  avio_rb32(pb); /* grouping_type_parameter */
3808 
3809  entries = avio_rb32(pb);
3810  if (!entries)
3811  return 0;
3812  if (*tablep)
3813  av_log(c->fc, AV_LOG_WARNING, "Duplicated SBGP %s atom\n", av_fourcc2str(grouping_type));
3814  av_freep(tablep);
3815  table = av_malloc_array(entries, sizeof(*table));
3816  if (!table)
3817  return AVERROR(ENOMEM);
3818  *tablep = table;
3819 
3820  for (i = 0; i < entries && !pb->eof_reached; i++) {
3821  table[i].count = avio_rb32(pb); /* sample_count */
3822  table[i].index = avio_rb32(pb); /* group_description_index */
3823  }
3824 
3825  *table_count = i;
3826 
3827  if (pb->eof_reached) {
3828  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted SBGP atom\n");
3829  return AVERROR_EOF;
3830  }
3831 
3832  return 0;
3833 }
3834 
3835 /**
3836  * Get ith edit list entry (media time, duration).
3837  */
3839  const MOVStreamContext *msc,
3840  unsigned int edit_list_index,
3841  int64_t *edit_list_media_time,
3842  int64_t *edit_list_duration,
3843  int64_t global_timescale)
3844 {
3845  if (edit_list_index == msc->elst_count) {
3846  return 0;
3847  }
3848  *edit_list_media_time = msc->elst_data[edit_list_index].time;
3849  *edit_list_duration = msc->elst_data[edit_list_index].duration;
3850 
3851  /* duration is in global timescale units;convert to msc timescale */
3852  if (global_timescale == 0) {
3853  avpriv_request_sample(mov->fc, "Support for mvhd.timescale = 0 with editlists");
3854  return 0;
3855  }
3856  *edit_list_duration = av_rescale(*edit_list_duration, msc->time_scale,
3857  global_timescale);
3858 
3859  if (*edit_list_duration + (uint64_t)*edit_list_media_time > INT64_MAX)
3860  *edit_list_duration = 0;
3861 
3862  return 1;
3863 }
3864 
3865 /**
3866  * Find the closest previous frame to the timestamp_pts, in e_old index
3867  * entries. Searching for just any frame / just key frames can be controlled by
3868  * last argument 'flag'.
3869  * Note that if ctts_data is not NULL, we will always search for a key frame
3870  * irrespective of the value of 'flag'. If we don't find any keyframe, we will
3871  * return the first frame of the video.
3872  *
3873  * Here the timestamp_pts is considered to be a presentation timestamp and
3874  * the timestamp of index entries are considered to be decoding timestamps.
3875  *
3876  * Returns 0 if successful in finding a frame, else returns -1.
3877  * Places the found index corresponding output arg.
3878  *
3879  * If ctts_old is not NULL, then refines the searched entry by searching
3880  * backwards from the found timestamp, to find the frame with correct PTS.
3881  *
3882  * Places the found ctts_index and ctts_sample in corresponding output args.
3883  */
3885  AVIndexEntry *e_old,
3886  int nb_old,
3887  MOVTimeToSample *tts_data,
3888  int64_t tts_count,
3889  int64_t timestamp_pts,
3890  int flag,
3891  int64_t* index,
3892  int64_t* tts_index,
3893  int64_t* tts_sample)
3894 {
3895  MOVStreamContext *msc = st->priv_data;
3896  FFStream *const sti = ffstream(st);
3897  AVIndexEntry *e_keep = sti->index_entries;
3898  int nb_keep = sti->nb_index_entries;
3899  int64_t i = 0;
3900 
3901  av_assert0(index);
3902 
3903  // If dts_shift > 0, then all the index timestamps will have to be offset by
3904  // at least dts_shift amount to obtain PTS.
3905  // Hence we decrement the searched timestamp_pts by dts_shift to find the closest index element.
3906  if (msc->dts_shift > 0) {
3907  timestamp_pts -= msc->dts_shift;
3908  }
3909 
3910  sti->index_entries = e_old;
3911  sti->nb_index_entries = nb_old;
3912  *index = av_index_search_timestamp(st, timestamp_pts, flag | AVSEEK_FLAG_BACKWARD);
3913 
3914  // Keep going backwards in the index entries until the timestamp is the same.
3915  if (*index >= 0) {
3916  for (i = *index; i > 0 && e_old[i].timestamp == e_old[i - 1].timestamp;
3917  i--) {
3918  if ((flag & AVSEEK_FLAG_ANY) ||
3919  (e_old[i - 1].flags & AVINDEX_KEYFRAME)) {
3920  *index = i - 1;
3921  }
3922  }
3923  }
3924 
3925  // If we have CTTS then refine the search, by searching backwards over PTS
3926  // computed by adding corresponding CTTS durations to index timestamps.
3927  if (msc->ctts_count && *index >= 0) {
3928  av_assert0(tts_index);
3929  av_assert0(tts_sample);
3930  // Find out the ctts_index for the found frame.
3931  *tts_index = 0;
3932  *tts_sample = 0;
3933  for (int64_t index_tts_count = 0; index_tts_count < *index; index_tts_count++) {
3934  if (*tts_index < tts_count) {
3935  (*tts_sample)++;
3936  if (tts_data[*tts_index].count == *tts_sample) {
3937  (*tts_index)++;
3938  *tts_sample = 0;
3939  }
3940  }
3941  }
3942 
3943  while (*index >= 0 && (*tts_index) >= 0 && (*tts_index) < tts_count) {
3944  // Find a "key frame" with PTS <= timestamp_pts (So that we can decode B-frames correctly).
3945  // No need to add dts_shift to the timestamp here becase timestamp_pts has already been
3946  // compensated by dts_shift above.
3947  if ((e_old[*index].timestamp + tts_data[*tts_index].offset) <= timestamp_pts &&
3948  (e_old[*index].flags & AVINDEX_KEYFRAME)) {
3949  break;
3950  }
3951 
3952  (*index)--;
3953  if (*tts_sample == 0) {
3954  (*tts_index)--;
3955  if (*tts_index >= 0)
3956  *tts_sample = tts_data[*tts_index].count - 1;
3957  } else {
3958  (*tts_sample)--;
3959  }
3960  }
3961  }
3962 
3963  /* restore AVStream state*/
3964  sti->index_entries = e_keep;
3965  sti->nb_index_entries = nb_keep;
3966  return *index >= 0 ? 0 : -1;
3967 }
3968 
3969 /**
3970  * Add index entry with the given values, to the end of ffstream(st)->index_entries.
3971  * Returns the new size ffstream(st)->index_entries if successful, else returns -1.
3972  *
3973  * This function is similar to ff_add_index_entry in libavformat/utils.c
3974  * except that here we are always unconditionally adding an index entry to
3975  * the end, instead of searching the entries list and skipping the add if
3976  * there is an existing entry with the same timestamp.
3977  * This is needed because the mov_fix_index calls this func with the same
3978  * unincremented timestamp for successive discarded frames.
3979  */
3981  int size, int distance, int flags)
3982 {
3983  FFStream *const sti = ffstream(st);
3984  AVIndexEntry *entries, *ie;
3985  int64_t index = -1;
3986  const size_t min_size_needed = (sti->nb_index_entries + 1) * sizeof(AVIndexEntry);
3987 
3988  // Double the allocation each time, to lower memory fragmentation.
3989  // Another difference from ff_add_index_entry function.
3990  const size_t requested_size =
3991  min_size_needed > sti->index_entries_allocated_size ?
3992  FFMAX(min_size_needed, 2 * sti->index_entries_allocated_size) :
3993  min_size_needed;
3994 
3995  if (sti->nb_index_entries + 1U >= UINT_MAX / sizeof(AVIndexEntry))
3996  return -1;
3997 
3998  entries = av_fast_realloc(sti->index_entries,
4000  requested_size);
4001  if (!entries)
4002  return -1;
4003 
4004  sti->index_entries = entries;
4005 
4006  index = sti->nb_index_entries++;
4007  ie= &entries[index];
4008 
4009  ie->pos = pos;
4010  ie->timestamp = timestamp;
4011  ie->min_distance= distance;
4012  ie->size= size;
4013  ie->flags = flags;
4014  return index;
4015 }
4016 
4017 /**
4018  * Rewrite timestamps of index entries in the range [end_index - frame_duration_buffer_size, end_index)
4019  * by subtracting end_ts successively by the amounts given in frame_duration_buffer.
4020  */
4021 static void fix_index_entry_timestamps(AVStream* st, int end_index, int64_t end_ts,
4022  int64_t* frame_duration_buffer,
4023  int frame_duration_buffer_size) {
4024  FFStream *const sti = ffstream(st);
4025  int i = 0;
4026  av_assert0(end_index >= 0 && end_index <= sti->nb_index_entries);
4027  for (i = 0; i < frame_duration_buffer_size; i++) {
4028  end_ts -= frame_duration_buffer[frame_duration_buffer_size - 1 - i];
4029  sti->index_entries[end_index - 1 - i].timestamp = end_ts;
4030  }
4031 }
4032 
4033 static int add_tts_entry(MOVTimeToSample **tts_data, unsigned int *tts_count, unsigned int *allocated_size,
4034  int count, int offset, unsigned int duration)
4035 {
4036  MOVTimeToSample *tts_buf_new;
4037  const size_t min_size_needed = (*tts_count + 1) * sizeof(MOVTimeToSample);
4038  const size_t requested_size =
4039  min_size_needed > *allocated_size ?
4040  FFMAX(min_size_needed, 2 * (*allocated_size)) :
4041  min_size_needed;
4042 
4043  if ((unsigned)(*tts_count) >= UINT_MAX / sizeof(MOVTimeToSample) - 1)
4044  return -1;
4045 
4046  tts_buf_new = av_fast_realloc(*tts_data, allocated_size, requested_size);
4047 
4048  if (!tts_buf_new)
4049  return -1;
4050 
4051  *tts_data = tts_buf_new;
4052 
4053  tts_buf_new[*tts_count].count = count;
4054  tts_buf_new[*tts_count].offset = offset;
4055  tts_buf_new[*tts_count].duration = duration;
4056 
4057  *tts_count = (*tts_count) + 1;
4058  return 0;
4059 }
4060 
4061 #define MAX_REORDER_DELAY 16
4063 {
4064  MOVStreamContext *msc = st->priv_data;
4065  FFStream *const sti = ffstream(st);
4066  int ctts_ind = 0;
4067  int ctts_sample = 0;
4068  int64_t pts_buf[MAX_REORDER_DELAY + 1]; // Circular buffer to sort pts.
4069  int buf_start = 0;
4070  int j, r, num_swaps;
4071 
4072  for (j = 0; j < MAX_REORDER_DELAY + 1; j++)
4073  pts_buf[j] = INT64_MIN;
4074 
4075  if (st->codecpar->video_delay <= 0 && msc->ctts_count &&
4077  st->codecpar->video_delay = 0;
4078  for (int ind = 0; ind < sti->nb_index_entries && ctts_ind < msc->tts_count; ++ind) {
4079  // Point j to the last elem of the buffer and insert the current pts there.
4080  j = buf_start;
4081  buf_start = (buf_start + 1);
4082  if (buf_start == MAX_REORDER_DELAY + 1)
4083  buf_start = 0;
4084 
4085  pts_buf[j] = sti->index_entries[ind].timestamp + msc->tts_data[ctts_ind].offset;
4086 
4087  // The timestamps that are already in the sorted buffer, and are greater than the
4088  // current pts, are exactly the timestamps that need to be buffered to output PTS
4089  // in correct sorted order.
4090  // Hence the video delay (which is the buffer size used to sort DTS and output PTS),
4091  // can be computed as the maximum no. of swaps any particular timestamp needs to
4092  // go through, to keep this buffer in sorted order.
4093  num_swaps = 0;
4094  while (j != buf_start) {
4095  r = j - 1;
4096  if (r < 0) r = MAX_REORDER_DELAY;
4097  if (pts_buf[j] < pts_buf[r]) {
4098  FFSWAP(int64_t, pts_buf[j], pts_buf[r]);
4099  ++num_swaps;
4100  } else {
4101  break;
4102  }
4103  j = r;
4104  }
4105  st->codecpar->video_delay = FFMAX(st->codecpar->video_delay, num_swaps);
4106 
4107  ctts_sample++;
4108  if (ctts_sample == msc->tts_data[ctts_ind].count) {
4109  ctts_ind++;
4110  ctts_sample = 0;
4111  }
4112  }
4113  av_log(c->fc, AV_LOG_DEBUG, "Setting codecpar->delay to %d for stream st: %d\n",
4114  st->codecpar->video_delay, st->index);
4115  }
4116 }
4117 
4119 {
4120  sc->current_sample++;
4121  sc->current_index++;
4122  if (sc->index_ranges &&
4123  sc->current_index >= sc->current_index_range->end &&
4124  sc->current_index_range->end) {
4125  sc->current_index_range++;
4127  }
4128 }
4129 
4131 {
4132  sc->current_sample--;
4133  sc->current_index--;
4134  if (sc->index_ranges &&
4136  sc->current_index_range > sc->index_ranges) {
4137  sc->current_index_range--;
4138  sc->current_index = sc->current_index_range->end - 1;
4139  }
4140 }
4141 
4142 static void mov_current_sample_set(MOVStreamContext *sc, int current_sample)
4143 {
4144  int64_t range_size;
4145 
4146  sc->current_sample = current_sample;
4147  sc->current_index = current_sample;
4148  if (!sc->index_ranges) {
4149  return;
4150  }
4151 
4152  for (sc->current_index_range = sc->index_ranges;
4153  sc->current_index_range->end;
4154  sc->current_index_range++) {
4155  range_size = sc->current_index_range->end - sc->current_index_range->start;
4156  if (range_size > current_sample) {
4157  sc->current_index = sc->current_index_range->start + current_sample;
4158  break;
4159  }
4160  current_sample -= range_size;
4161  }
4162 }
4163 
4164 /**
4165  * Fix ffstream(st)->index_entries, so that it contains only the entries (and the entries
4166  * which are needed to decode them) that fall in the edit list time ranges.
4167  * Also fixes the timestamps of the index entries to match the timeline
4168  * specified the edit lists.
4169  */
4170 static void mov_fix_index(MOVContext *mov, AVStream *st)
4171 {
4172  MOVStreamContext *msc = st->priv_data;
4173  FFStream *const sti = ffstream(st);
4174  AVIndexEntry *e_old = sti->index_entries;
4175  int nb_old = sti->nb_index_entries;
4176  const AVIndexEntry *e_old_end = e_old + nb_old;
4177  const AVIndexEntry *current = NULL;
4178  MOVTimeToSample *tts_data_old = msc->tts_data;
4179  int64_t tts_index_old = 0;
4180  int64_t tts_sample_old = 0;
4181  int64_t tts_count_old = msc->tts_count;
4182  int64_t edit_list_media_time = 0;
4183  int64_t edit_list_duration = 0;
4184  int64_t frame_duration = 0;
4185  int64_t edit_list_dts_counter = 0;
4186  int64_t edit_list_dts_entry_end = 0;
4187  int64_t edit_list_start_tts_sample = 0;
4188  int64_t curr_cts;
4189  int64_t curr_ctts = 0;
4190  int64_t empty_edits_sum_duration = 0;
4191  int64_t edit_list_index = 0;
4192  int64_t index;
4193  int flags;
4194  int64_t start_dts = 0;
4195  int64_t edit_list_start_encountered = 0;
4196  int64_t search_timestamp = 0;
4197  int64_t* frame_duration_buffer = NULL;
4198  int num_discarded_begin = 0;
4199  int first_non_zero_audio_edit = -1;
4200  int packet_skip_samples = 0;
4201  MOVIndexRange *current_index_range = NULL;
4202  int found_keyframe_after_edit = 0;
4203  int found_non_empty_edit = 0;
4204 
4205  if (!msc->elst_data || msc->elst_count <= 0 || nb_old <= 0) {
4206  return;
4207  }
4208 
4209  // allocate the index ranges array
4210  msc->index_ranges = av_malloc_array(msc->elst_count + 1,
4211  sizeof(msc->index_ranges[0]));
4212  if (!msc->index_ranges) {
4213  av_log(mov->fc, AV_LOG_ERROR, "Cannot allocate index ranges buffer\n");
4214  return;
4215  }
4216  msc->current_index_range = msc->index_ranges;
4217 
4218  // Clean AVStream from traces of old index
4219  sti->index_entries = NULL;
4221  sti->nb_index_entries = 0;
4222 
4223  // Clean time to sample fields of MOVStreamContext
4224  msc->tts_data = NULL;
4225  msc->tts_count = 0;
4226  msc->tts_index = 0;
4227  msc->tts_sample = 0;
4228  msc->tts_allocated_size = 0;
4229 
4230  // Reinitialize min_corrected_pts so that it can be computed again.
4231  msc->min_corrected_pts = -1;
4232 
4233  // If the dts_shift is positive (in case of negative ctts values in mov),
4234  // then negate the DTS by dts_shift
4235  if (msc->dts_shift > 0) {
4236  edit_list_dts_entry_end -= msc->dts_shift;
4237  av_log(mov->fc, AV_LOG_DEBUG, "Shifting DTS by %d because of negative CTTS.\n", msc->dts_shift);
4238  }
4239 
4240  start_dts = edit_list_dts_entry_end;
4241 
4242  while (get_edit_list_entry(mov, msc, edit_list_index, &edit_list_media_time,
4243  &edit_list_duration, mov->time_scale)) {
4244  av_log(mov->fc, AV_LOG_DEBUG, "Processing st: %d, edit list %"PRId64" - media time: %"PRId64", duration: %"PRId64"\n",
4245  st->index, edit_list_index, edit_list_media_time, edit_list_duration);
4246  edit_list_index++;
4247  edit_list_dts_counter = edit_list_dts_entry_end;
4248  edit_list_dts_entry_end += edit_list_duration;
4249  num_discarded_begin = 0;
4250  if (!found_non_empty_edit && edit_list_media_time == -1) {
4251  empty_edits_sum_duration += edit_list_duration;
4252  continue;
4253  }
4254  found_non_empty_edit = 1;
4255 
4256  // If we encounter a non-negative edit list reset the skip_samples/start_pad fields and set them
4257  // according to the edit list below.
4258  if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
4259  if (first_non_zero_audio_edit < 0) {
4260  first_non_zero_audio_edit = 1;
4261  } else {
4262  first_non_zero_audio_edit = 0;
4263  }
4264 
4265  if (first_non_zero_audio_edit > 0)
4266  sti->skip_samples = msc->start_pad = 0;
4267  }
4268 
4269  // While reordering frame index according to edit list we must handle properly
4270  // the scenario when edit list entry starts from none key frame.
4271  // We find closest previous key frame and preserve it and consequent frames in index.
4272  // All frames which are outside edit list entry time boundaries will be dropped after decoding.
4273  search_timestamp = edit_list_media_time;
4274  if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
4275  // Audio decoders like AAC need need a decoder delay samples previous to the current sample,
4276  // to correctly decode this frame. Hence for audio we seek to a frame 1 sec. before the
4277  // edit_list_media_time to cover the decoder delay.
4278  search_timestamp = FFMAX(search_timestamp - msc->time_scale, e_old[0].timestamp);
4279  }
4280 
4281  if (find_prev_closest_index(st, e_old, nb_old, tts_data_old, tts_count_old, search_timestamp, 0,
4282  &index, &tts_index_old, &tts_sample_old) < 0) {
4283  av_log(mov->fc, AV_LOG_WARNING,
4284  "st: %d edit list: %"PRId64" Missing key frame while searching for timestamp: %"PRId64"\n",
4285  st->index, edit_list_index, search_timestamp);
4286  if (find_prev_closest_index(st, e_old, nb_old, tts_data_old, tts_count_old, search_timestamp, AVSEEK_FLAG_ANY,
4287  &index, &tts_index_old, &tts_sample_old) < 0) {
4288  av_log(mov->fc, AV_LOG_WARNING,
4289  "st: %d edit list %"PRId64" Cannot find an index entry before timestamp: %"PRId64".\n",
4290  st->index, edit_list_index, search_timestamp);
4291  index = 0;
4292  tts_index_old = 0;
4293  tts_sample_old = 0;
4294  }
4295  }
4296  current = e_old + index;
4297  edit_list_start_tts_sample = tts_sample_old;
4298 
4299  // Iterate over index and arrange it according to edit list
4300  edit_list_start_encountered = 0;
4301  found_keyframe_after_edit = 0;
4302  for (; current < e_old_end; current++, index++) {
4303  // check if frame outside edit list mark it for discard
4304  frame_duration = (current + 1 < e_old_end) ?
4305  ((current + 1)->timestamp - current->timestamp) : edit_list_duration;
4306 
4307  flags = current->flags;
4308 
4309  // frames (pts) before or after edit list
4310  curr_cts = current->timestamp + msc->dts_shift;
4311  curr_ctts = 0;
4312 
4313  if (tts_data_old && tts_index_old < tts_count_old) {
4314  curr_ctts = tts_data_old[tts_index_old].offset;
4315  av_log(mov->fc, AV_LOG_TRACE, "stts: %"PRId64" ctts: %"PRId64", tts_index: %"PRId64", tts_count: %"PRId64"\n",
4316  curr_cts, curr_ctts, tts_index_old, tts_count_old);
4317  curr_cts += curr_ctts;
4318  tts_sample_old++;
4319  if (tts_sample_old == tts_data_old[tts_index_old].count) {
4320  if (add_tts_entry(&msc->tts_data, &msc->tts_count,
4321  &msc->tts_allocated_size,
4322  tts_data_old[tts_index_old].count - edit_list_start_tts_sample,
4323  tts_data_old[tts_index_old].offset, tts_data_old[tts_index_old].duration) == -1) {
4324  av_log(mov->fc, AV_LOG_ERROR, "Cannot add Time To Sample entry %"PRId64" - {%"PRId64", %d}\n",
4325  tts_index_old,
4326  tts_data_old[tts_index_old].count - edit_list_start_tts_sample,
4327  tts_data_old[tts_index_old].offset);
4328  break;
4329  }
4330  tts_index_old++;
4331  tts_sample_old = 0;
4332  edit_list_start_tts_sample = 0;
4333  }
4334  }
4335 
4336  if (curr_cts < edit_list_media_time || curr_cts >= (edit_list_duration + edit_list_media_time)) {
4338  curr_cts < edit_list_media_time && curr_cts + frame_duration > edit_list_media_time &&
4339  first_non_zero_audio_edit > 0) {
4340  packet_skip_samples = edit_list_media_time - curr_cts;
4341  sti->skip_samples += packet_skip_samples;
4342 
4343  // Shift the index entry timestamp by packet_skip_samples to be correct.
4344  edit_list_dts_counter -= packet_skip_samples;
4345  if (edit_list_start_encountered == 0) {
4346  edit_list_start_encountered = 1;
4347  // Make timestamps strictly monotonically increasing for audio, by rewriting timestamps for
4348  // discarded packets.
4349  if (frame_duration_buffer) {
4350  fix_index_entry_timestamps(st, sti->nb_index_entries, edit_list_dts_counter,
4351  frame_duration_buffer, num_discarded_begin);
4352  av_freep(&frame_duration_buffer);
4353  }
4354  }
4355 
4356  av_log(mov->fc, AV_LOG_DEBUG, "skip %d audio samples from curr_cts: %"PRId64"\n", packet_skip_samples, curr_cts);
4357  } else {
4359  av_log(mov->fc, AV_LOG_DEBUG, "drop a frame at curr_cts: %"PRId64" @ %"PRId64"\n", curr_cts, index);
4360 
4361  if (edit_list_start_encountered == 0) {
4362  num_discarded_begin++;
4363  frame_duration_buffer = av_realloc(frame_duration_buffer,
4364  num_discarded_begin * sizeof(int64_t));
4365  if (!frame_duration_buffer) {
4366  av_log(mov->fc, AV_LOG_ERROR, "Cannot reallocate frame duration buffer\n");
4367  break;
4368  }
4369  frame_duration_buffer[num_discarded_begin - 1] = frame_duration;
4370 
4371  // Increment skip_samples for the first non-zero audio edit list
4372  if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
4373  first_non_zero_audio_edit > 0 && st->codecpar->codec_id != AV_CODEC_ID_VORBIS) {
4374  sti->skip_samples += frame_duration;
4375  }
4376  }
4377  }
4378  } else {
4379  if (msc->min_corrected_pts < 0) {
4380  msc->min_corrected_pts = edit_list_dts_counter + curr_ctts + msc->dts_shift;
4381  } else {
4382  msc->min_corrected_pts = FFMIN(msc->min_corrected_pts, edit_list_dts_counter + curr_ctts + msc->dts_shift);
4383  }
4384  if (edit_list_start_encountered == 0) {
4385  edit_list_start_encountered = 1;
4386  // Make timestamps strictly monotonically increasing by rewriting timestamps for
4387  // discarded packets.
4388  if (frame_duration_buffer) {
4389  fix_index_entry_timestamps(st, sti->nb_index_entries, edit_list_dts_counter,
4390  frame_duration_buffer, num_discarded_begin);
4391  av_freep(&frame_duration_buffer);
4392  }
4393  }
4394  }
4395 
4396  if (add_index_entry(st, current->pos, edit_list_dts_counter, current->size,
4397  current->min_distance, flags) == -1) {
4398  av_log(mov->fc, AV_LOG_ERROR, "Cannot add index entry\n");
4399  break;
4400  }
4401 
4402  // Update the index ranges array
4403  if (!current_index_range || index != current_index_range->end) {
4404  current_index_range = current_index_range ? current_index_range + 1
4405  : msc->index_ranges;
4406  current_index_range->start = index;
4407  }
4408  current_index_range->end = index + 1;
4409 
4410  // Only start incrementing DTS in frame_duration amounts, when we encounter a frame in edit list.
4411  if (edit_list_start_encountered > 0) {
4412  edit_list_dts_counter = edit_list_dts_counter + frame_duration;
4413  }
4414 
4415  // Break when found first key frame after edit entry completion
4416  if ((curr_cts + frame_duration >= (edit_list_duration + edit_list_media_time)) &&
4418  if (msc->ctts_count) {
4419  // If we have CTTS and this is the first keyframe after edit elist,
4420  // wait for one more, because there might be trailing B-frames after this I-frame
4421  // that do belong to the edit.
4422  if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO && found_keyframe_after_edit == 0) {
4423  found_keyframe_after_edit = 1;
4424  continue;
4425  }
4426  if (tts_sample_old != 0) {
4427  if (add_tts_entry(&msc->tts_data, &msc->tts_count,
4428  &msc->tts_allocated_size,
4429  tts_sample_old - edit_list_start_tts_sample,
4430  tts_data_old[tts_index_old].offset, tts_data_old[tts_index_old].duration) == -1) {
4431  av_log(mov->fc, AV_LOG_ERROR, "Cannot add Time To Sample entry %"PRId64" - {%"PRId64", %d}\n",
4432  tts_index_old, tts_sample_old - edit_list_start_tts_sample,
4433  tts_data_old[tts_index_old].offset);
4434  break;
4435  }
4436  }
4437  }
4438  break;
4439  }
4440  }
4441  }
4442  // If there are empty edits, then msc->min_corrected_pts might be positive
4443  // intentionally. So we subtract the sum duration of emtpy edits here.
4444  msc->min_corrected_pts -= empty_edits_sum_duration;
4445 
4446  // If the minimum pts turns out to be greater than zero after fixing the index, then we subtract the
4447  // dts by that amount to make the first pts zero.
4448  if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
4449  if (msc->min_corrected_pts > 0) {
4450  av_log(mov->fc, AV_LOG_DEBUG, "Offset DTS by %"PRId64" to make first pts zero.\n", msc->min_corrected_pts);
4451  for (int i = 0; i < sti->nb_index_entries; ++i)
4453  }
4454  }
4455  // Start time should be equal to zero or the duration of any empty edits.
4456  st->start_time = empty_edits_sum_duration;
4457 
4458  // Update av stream length, if it ends up shorter than the track's media duration
4459  st->duration = FFMIN(st->duration, edit_list_dts_entry_end - start_dts);
4460  msc->start_pad = sti->skip_samples;
4461 
4462  // Free the old index and the old CTTS structures
4463  av_free(e_old);
4464  av_free(tts_data_old);
4465  av_freep(&frame_duration_buffer);
4466 
4467  // Null terminate the index ranges array
4468  current_index_range = current_index_range ? current_index_range + 1
4469  : msc->index_ranges;
4470  current_index_range->start = 0;
4471  current_index_range->end = 0;
4472  msc->current_index = msc->index_ranges[0].start;
4473 }
4474 
4475 static uint32_t get_sgpd_sync_index(const MOVStreamContext *sc, int nal_unit_type)
4476 {
4477  for (uint32_t i = 0; i < sc->sgpd_sync_count; i++)
4478  if (sc->sgpd_sync[i] == nal_unit_type)
4479  return i + 1;
4480  return 0;
4481 }
4482 
4484 {
4485  int k;
4486  int sample_id = 0;
4487  uint32_t cra_index;
4488  MOVStreamContext *sc = st->priv_data;
4489 
4490  if (st->codecpar->codec_id != AV_CODEC_ID_HEVC || !sc->sync_group_count)
4491  return 0;
4492 
4493  /* Build an unrolled index of the samples */
4494  sc->sample_offsets_count = 0;
4495  for (uint32_t i = 0; i < sc->ctts_count; i++) {
4496  if (sc->ctts_data[i].count > INT_MAX - sc->sample_offsets_count)
4497  return AVERROR(ENOMEM);
4498  sc->sample_offsets_count += sc->ctts_data[i].count;
4499  }
4500  av_freep(&sc->sample_offsets);
4502  if (!sc->sample_offsets)
4503  return AVERROR(ENOMEM);
4504  k = 0;
4505  for (uint32_t i = 0; i < sc->ctts_count; i++)
4506  for (int j = 0; j < sc->ctts_data[i].count; j++)
4507  sc->sample_offsets[k++] = sc->ctts_data[i].offset;
4508 
4509  /* The following HEVC NAL type reveal the use of open GOP sync points
4510  * (TODO: BLA types may also be concerned) */
4511  cra_index = get_sgpd_sync_index(sc, HEVC_NAL_CRA_NUT); /* Clean Random Access */
4512  if (!cra_index)
4513  return 0;
4514 
4515  /* Build a list of open-GOP key samples */
4516  sc->open_key_samples_count = 0;
4517  for (uint32_t i = 0; i < sc->sync_group_count; i++)
4518  if (sc->sync_group[i].index == cra_index) {
4519  if (sc->sync_group[i].count > INT_MAX - sc->open_key_samples_count)
4520  return AVERROR(ENOMEM);
4522  }
4523  av_freep(&sc->open_key_samples);
4525  if (!sc->open_key_samples)
4526  return AVERROR(ENOMEM);
4527  k = 0;
4528  for (uint32_t i = 0; i < sc->sync_group_count; i++) {
4529  const MOVSbgp *sg = &sc->sync_group[i];
4530  if (sg->index == cra_index)
4531  for (uint32_t j = 0; j < sg->count; j++)
4532  sc->open_key_samples[k++] = sample_id;
4533  if (sg->count > INT_MAX - sample_id)
4534  return AVERROR_PATCHWELCOME;
4535  sample_id += sg->count;
4536  }
4537 
4538  /* Identify the minimal time step between samples */
4539  sc->min_sample_duration = UINT_MAX;
4540  for (uint32_t i = 0; i < sc->stts_count; i++)
4542 
4543  return 0;
4544 }
4545 
4546 #define MOV_MERGE_CTTS 1
4547 #define MOV_MERGE_STTS 2
4548 /*
4549  * Merge stts and ctts arrays into a new combined array.
4550  * stts_count and ctts_count may be left untouched as they will be
4551  * used to check for the presence of either of them.
4552  */
4553 static int mov_merge_tts_data(MOVContext *mov, AVStream *st, int flags)
4554 {
4555  MOVStreamContext *sc = st->priv_data;
4556  int ctts = sc->ctts_data && (flags & MOV_MERGE_CTTS);
4557  int stts = sc->stts_data && (flags & MOV_MERGE_STTS);
4558  int idx = 0;
4559 
4560  if (!sc->ctts_data && !sc->stts_data)
4561  return 0;
4562  // Expand time to sample entries such that we have a 1-1 mapping with samples
4563  if (!sc->sample_count || sc->sample_count >= UINT_MAX / sizeof(*sc->tts_data))
4564  return -1;
4565 
4566  if (ctts) {
4568  sc->sample_count * sizeof(*sc->tts_data));
4569  if (!sc->tts_data)
4570  return -1;
4571 
4572  memset(sc->tts_data, 0, sc->tts_allocated_size);
4573 
4574  for (int i = 0; i < sc->ctts_count &&
4575  idx < sc->sample_count; i++)
4576  for (int j = 0; j < sc->ctts_data[i].count &&
4577  idx < sc->sample_count; j++) {
4578  sc->tts_data[idx].offset = sc->ctts_data[i].offset;
4579  sc->tts_data[idx++].count = 1;
4580  }
4581 
4582  sc->tts_count = idx;
4583  } else
4584  sc->ctts_count = 0;
4585  av_freep(&sc->ctts_data);
4586  sc->ctts_allocated_size = 0;
4587 
4588  idx = 0;
4589  if (stts) {
4591  sc->sample_count * sizeof(*sc->tts_data));
4592  if (!tts_data)
4593  return -1;
4594 
4595  if (!sc->tts_data)
4596  memset(tts_data, 0, sc->tts_allocated_size);
4597  sc->tts_data = tts_data;
4598 
4599  for (int i = 0; i < sc->stts_count &&
4600  idx < sc->sample_count; i++)
4601  for (int j = 0; j < sc->stts_data[i].count &&
4602  idx < sc->sample_count; j++) {
4603  sc->tts_data[idx].duration = sc->stts_data[i].duration;
4604  sc->tts_data[idx++].count = 1;
4605  }
4606 
4607  sc->tts_count = FFMAX(sc->tts_count, idx);
4608  } else
4609  sc->stts_count = 0;
4610  av_freep(&sc->stts_data);
4611  sc->stts_allocated_size = 0;
4612 
4613  return 0;
4614 }
4615 
4616 static void mov_build_index(MOVContext *mov, AVStream *st)
4617 {
4618  MOVStreamContext *sc = st->priv_data;
4619  FFStream *const sti = ffstream(st);
4620  int64_t current_offset;
4621  int64_t current_dts = 0;
4622  unsigned int stts_index = 0;
4623  unsigned int stsc_index = 0;
4624  unsigned int stss_index = 0;
4625  unsigned int stps_index = 0;
4626  unsigned int i, j;
4627  uint64_t stream_size = 0;
4628 
4629  int ret = build_open_gop_key_points(st);
4630  if (ret < 0)
4631  return;
4632 
4633  if (sc->elst_count) {
4634  int i, edit_start_index = 0, multiple_edits = 0;
4635  int64_t empty_duration = 0; // empty duration of the first edit list entry
4636  int64_t start_time = 0; // start time of the media
4637 
4638  for (i = 0; i < sc->elst_count; i++) {
4639  const MOVElst *e = &sc->elst_data[i];
4640  if (i == 0 && e->time == -1) {
4641  /* if empty, the first entry is the start time of the stream
4642  * relative to the presentation itself */
4643  empty_duration = e->duration;
4644  edit_start_index = 1;
4645  } else if (i == edit_start_index && e->time >= 0) {
4646  start_time = e->time;
4647  } else {
4648  multiple_edits = 1;
4649  }
4650  }
4651 
4652  if (multiple_edits && !mov->advanced_editlist) {
4654  av_log(mov->fc, AV_LOG_WARNING, "multiple edit list entries, "
4655  "not supported in fragmented MP4 files\n");
4656  else
4657  av_log(mov->fc, AV_LOG_WARNING, "multiple edit list entries, "
4658  "Use -advanced_editlist to correctly decode otherwise "
4659  "a/v desync might occur\n");
4660  }
4661 
4662  /* adjust first dts according to edit list */
4663  if ((empty_duration || start_time) && mov->time_scale > 0) {
4664  if (empty_duration)
4665  empty_duration = av_rescale(empty_duration, sc->time_scale, mov->time_scale);
4666 
4667  if (av_sat_sub64(start_time, empty_duration) != start_time - (uint64_t)empty_duration)
4668  av_log(mov->fc, AV_LOG_WARNING, "start_time - empty_duration is not representable\n");
4669 
4670  sc->time_offset = start_time - (uint64_t)empty_duration;
4672  if (!mov->advanced_editlist)
4673  current_dts = -sc->time_offset;
4674  }
4675 
4676  if (!multiple_edits && !mov->advanced_editlist &&
4678  sc->start_pad = start_time;
4679  }
4680 
4681  /* only use old uncompressed audio chunk demuxing when stts specifies it */
4682  if (!(st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
4683  sc->stts_count == 1 && sc->stts_data && sc->stts_data[0].duration == 1)) {
4684  unsigned int current_sample = 0;
4685  unsigned int stts_sample = 0;
4686  unsigned int sample_size;
4687  unsigned int distance = 0;
4688  unsigned int rap_group_index = 0;
4689  unsigned int rap_group_sample = 0;
4690  int rap_group_present = sc->rap_group_count && sc->rap_group;
4691  int key_off = (sc->keyframe_count && sc->keyframes[0] > 0) || (sc->stps_count && sc->stps_data[0] > 0);
4692 
4693  current_dts -= sc->dts_shift;
4694 
4695  if (!sc->sample_count || sti->nb_index_entries || sc->tts_count)
4696  return;
4697  if (sc->sample_count >= UINT_MAX / sizeof(*sti->index_entries) - sti->nb_index_entries)
4698  return;
4699  if (av_reallocp_array(&sti->index_entries,
4700  sti->nb_index_entries + sc->sample_count,
4701  sizeof(*sti->index_entries)) < 0) {
4702  sti->nb_index_entries = 0;
4703  return;
4704  }
4705  sti->index_entries_allocated_size = (sti->nb_index_entries + sc->sample_count) * sizeof(*sti->index_entries);
4706 
4708  if (ret < 0)
4709  return;
4710 
4711  for (i = 0; i < sc->chunk_count; i++) {
4712  int64_t next_offset = i+1 < sc->chunk_count ? sc->chunk_offsets[i+1] : INT64_MAX;
4713  current_offset = sc->chunk_offsets[i];
4714  while (mov_stsc_index_valid(stsc_index, sc->stsc_count) &&
4715  i + 1 == sc->stsc_data[stsc_index + 1].first)
4716  stsc_index++;
4717 
4718  if (next_offset > current_offset && sc->sample_size>0 && sc->sample_size < sc->stsz_sample_size &&
4719  sc->stsc_data[stsc_index].count * (int64_t)sc->stsz_sample_size > next_offset - current_offset) {
4720  av_log(mov->fc, AV_LOG_WARNING, "STSZ sample size %d invalid (too large), ignoring\n", sc->stsz_sample_size);
4721  sc->stsz_sample_size = sc->sample_size;
4722  }
4723  if (sc->stsz_sample_size>0 && sc->stsz_sample_size < sc->sample_size) {
4724  av_log(mov->fc, AV_LOG_WARNING, "STSZ sample size %d invalid (too small), ignoring\n", sc->stsz_sample_size);
4725  sc->stsz_sample_size = sc->sample_size;
4726  }
4727 
4728  for (j = 0; j < sc->stsc_data[stsc_index].count; j++) {
4729  int keyframe = 0;
4730  if (current_sample >= sc->sample_count) {
4731  av_log(mov->fc, AV_LOG_ERROR, "wrong sample count\n");
4732  return;
4733  }
4734 
4735  if (!sc->keyframe_absent && (!sc->keyframe_count || current_sample+key_off == sc->keyframes[stss_index])) {
4736  keyframe = 1;
4737  if (stss_index + 1 < sc->keyframe_count)
4738  stss_index++;
4739  } else if (sc->stps_count && current_sample+key_off == sc->stps_data[stps_index]) {
4740  keyframe = 1;
4741  if (stps_index + 1 < sc->stps_count)
4742  stps_index++;
4743  }
4744  if (rap_group_present && rap_group_index < sc->rap_group_count) {
4745  if (sc->rap_group[rap_group_index].index > 0)
4746  keyframe = 1;
4747  if (++rap_group_sample == sc->rap_group[rap_group_index].count) {
4748  rap_group_sample = 0;
4749  rap_group_index++;
4750  }
4751  }
4752  if (sc->keyframe_absent
4753  && !sc->stps_count
4754  && !rap_group_present
4755  && (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO || (i==0 && j==0)))
4756  keyframe = 1;
4757  if (keyframe)
4758  distance = 0;
4759  sample_size = sc->stsz_sample_size > 0 ? sc->stsz_sample_size : sc->sample_sizes[current_sample];
4760  if (current_offset > INT64_MAX - sample_size) {
4761  av_log(mov->fc, AV_LOG_ERROR, "Current offset %"PRId64" or sample size %u is too large\n",
4762  current_offset,
4763  sample_size);
4764  return;
4765  }
4766 
4767  if (sc->pseudo_stream_id == -1 ||
4768  sc->stsc_data[stsc_index].id - 1 == sc->pseudo_stream_id) {
4769  AVIndexEntry *e;
4770  if (sample_size > 0x3FFFFFFF) {
4771  av_log(mov->fc, AV_LOG_ERROR, "Sample size %u is too large\n", sample_size);
4772  return;
4773  }
4774  e = &sti->index_entries[sti->nb_index_entries++];
4775  e->pos = current_offset;
4776  e->timestamp = current_dts;
4777  e->size = sample_size;
4778  e->min_distance = distance;
4779  e->flags = keyframe ? AVINDEX_KEYFRAME : 0;
4780  av_log(mov->fc, AV_LOG_TRACE, "AVIndex stream %d, sample %u, offset %"PRIx64", dts %"PRId64", "
4781  "size %u, distance %u, keyframe %d\n", st->index, current_sample,
4782  current_offset, current_dts, sample_size, distance, keyframe);
4783  if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && sti->nb_index_entries < 100)
4784  ff_rfps_add_frame(mov->fc, st, current_dts);
4785  }
4786 
4787  current_offset += sample_size;
4788  stream_size += sample_size;
4789 
4790  current_dts += sc->tts_data[stts_index].duration;
4791 
4792  distance++;
4793  stts_sample++;
4794  current_sample++;
4795  if (stts_index + 1 < sc->tts_count && stts_sample == sc->tts_data[stts_index].count) {
4796  stts_sample = 0;
4797  stts_index++;
4798  }
4799  }
4800  }
4801  if (st->duration > 0)
4802  st->codecpar->bit_rate = stream_size*8*sc->time_scale/st->duration;
4803  } else {
4804  unsigned chunk_samples, total = 0;
4805 
4806  if (!sc->chunk_count || sc->tts_count)
4807  return;
4808 
4810  if (ret < 0)
4811  return;
4812 
4813  // compute total chunk count
4814  for (i = 0; i < sc->stsc_count; i++) {
4815  unsigned count, chunk_count;
4816 
4817  chunk_samples = sc->stsc_data[i].count;
4818  if (i != sc->stsc_count - 1 &&
4819  sc->samples_per_frame && chunk_samples % sc->samples_per_frame) {
4820  av_log(mov->fc, AV_LOG_ERROR, "error unaligned chunk\n");
4821  return;
4822  }
4823 
4824  if (sc->samples_per_frame >= 160) { // gsm
4825  count = chunk_samples / sc->samples_per_frame;
4826  } else if (sc->samples_per_frame > 1) {
4827  unsigned samples = (1024/sc->samples_per_frame)*sc->samples_per_frame;
4828  count = (chunk_samples+samples-1) / samples;
4829  } else {
4830  count = (chunk_samples+1023) / 1024;
4831  }
4832 
4833  if (mov_stsc_index_valid(i, sc->stsc_count))
4834  chunk_count = sc->stsc_data[i+1].first - sc->stsc_data[i].first;
4835  else
4836  chunk_count = sc->chunk_count - (sc->stsc_data[i].first - 1);
4837  total += chunk_count * count;
4838  }
4839 
4840  av_log(mov->fc, AV_LOG_TRACE, "chunk count %u\n", total);
4841  if (total >= UINT_MAX / sizeof(*sti->index_entries) - sti->nb_index_entries)
4842  return;
4843  if (av_reallocp_array(&sti->index_entries,
4844  sti->nb_index_entries + total,
4845  sizeof(*sti->index_entries)) < 0) {
4846  sti->nb_index_entries = 0;
4847  return;
4848  }
4849  sti->index_entries_allocated_size = (sti->nb_index_entries + total) * sizeof(*sti->index_entries);
4850 
4851  // populate index
4852  for (i = 0; i < sc->chunk_count; i++) {
4853  current_offset = sc->chunk_offsets[i];
4854  if (mov_stsc_index_valid(stsc_index, sc->stsc_count) &&
4855  i + 1 == sc->stsc_data[stsc_index + 1].first)
4856  stsc_index++;
4857  chunk_samples = sc->stsc_data[stsc_index].count;
4858 
4859  while (chunk_samples > 0) {
4860  AVIndexEntry *e;
4861  unsigned size, samples;
4862 
4863  if (sc->samples_per_frame > 1 && !sc->bytes_per_frame) {
4865  "Zero bytes per frame, but %d samples per frame",
4866  sc->samples_per_frame);
4867  return;
4868  }
4869 
4870  if (sc->samples_per_frame >= 160) { // gsm
4871  samples = sc->samples_per_frame;
4872  size = sc->bytes_per_frame;
4873  } else {
4874  if (sc->samples_per_frame > 1) {
4875  samples = FFMIN((1024 / sc->samples_per_frame)*
4876  sc->samples_per_frame, chunk_samples);
4878  } else {
4879  samples = FFMIN(1024, chunk_samples);
4880  size = samples * sc->sample_size;
4881  }
4882  }
4883 
4884  if (sti->nb_index_entries >= total) {
4885  av_log(mov->fc, AV_LOG_ERROR, "wrong chunk count %u\n", total);
4886  return;
4887  }
4888  if (size > 0x3FFFFFFF) {
4889  av_log(mov->fc, AV_LOG_ERROR, "Sample size %u is too large\n", size);
4890  return;
4891  }
4892  e = &sti->index_entries[sti->nb_index_entries++];
4893  e->pos = current_offset;
4894  e->timestamp = current_dts;
4895  e->size = size;
4896  e->min_distance = 0;
4897  e->flags = AVINDEX_KEYFRAME;
4898  av_log(mov->fc, AV_LOG_TRACE, "AVIndex stream %d, chunk %u, offset %"PRIx64", dts %"PRId64", "
4899  "size %u, duration %u\n", st->index, i, current_offset, current_dts,
4900  size, samples);
4901 
4902  current_offset += size;
4903  current_dts += samples;
4904  chunk_samples -= samples;
4905  }
4906  }
4907  }
4908 
4909  if (!mov->ignore_editlist && mov->advanced_editlist) {
4910  // Fix index according to edit lists.
4911  mov_fix_index(mov, st);
4912  }
4913 
4914  // Update start time of the stream.
4916  st->start_time = sti->index_entries[0].timestamp + sc->dts_shift;
4917  if (sc->tts_data) {
4918  st->start_time += sc->tts_data[0].offset;
4919  }
4920  }
4921 
4922  mov_estimate_video_delay(mov, st);
4923 }
4924 
4925 static int test_same_origin(const char *src, const char *ref) {
4926  char src_proto[64];
4927  char ref_proto[64];
4928  char src_auth[256];
4929  char ref_auth[256];
4930  char src_host[256];
4931  char ref_host[256];
4932  int src_port=-1;
4933  int ref_port=-1;
4934 
4935  av_url_split(src_proto, sizeof(src_proto), src_auth, sizeof(src_auth), src_host, sizeof(src_host), &src_port, NULL, 0, src);
4936  av_url_split(ref_proto, sizeof(ref_proto), ref_auth, sizeof(ref_auth), ref_host, sizeof(ref_host), &ref_port, NULL, 0, ref);
4937 
4938  if (strlen(src) == 0) {
4939  return -1;
4940  } else if (strlen(src_auth) + 1 >= sizeof(src_auth) ||
4941  strlen(ref_auth) + 1 >= sizeof(ref_auth) ||
4942  strlen(src_host) + 1 >= sizeof(src_host) ||
4943  strlen(ref_host) + 1 >= sizeof(ref_host)) {
4944  return 0;
4945  } else if (strcmp(src_proto, ref_proto) ||
4946  strcmp(src_auth, ref_auth) ||
4947  strcmp(src_host, ref_host) ||
4948  src_port != ref_port) {
4949  return 0;
4950  } else
4951  return 1;
4952 }
4953 
4954 static int mov_open_dref(MOVContext *c, AVIOContext **pb, const char *src, MOVDref *ref)
4955 {
4956  /* try relative path, we do not try the absolute because it can leak information about our
4957  system to an attacker */
4958  if (ref->nlvl_to > 0 && ref->nlvl_from > 0) {
4959  char filename[1025];
4960  const char *src_path;
4961  int i, l;
4962 
4963  /* find a source dir */
4964  src_path = strrchr(src, '/');
4965  if (src_path)
4966  src_path++;
4967  else
4968  src_path = src;
4969 
4970  /* find a next level down to target */
4971  for (i = 0, l = strlen(ref->path) - 1; l >= 0; l--)
4972  if (ref->path[l] == '/') {
4973  if (i == ref->nlvl_to - 1)
4974  break;
4975  else
4976  i++;
4977  }
4978 
4979  /* compose filename if next level down to target was found */
4980  if (i == ref->nlvl_to - 1 && src_path - src < sizeof(filename)) {
4981  memcpy(filename, src, src_path - src);
4982  filename[src_path - src] = 0;
4983 
4984  for (i = 1; i < ref->nlvl_from; i++)
4985  av_strlcat(filename, "../", sizeof(filename));
4986 
4987  av_strlcat(filename, ref->path + l + 1, sizeof(filename));
4988  if (!c->use_absolute_path) {
4989  int same_origin = test_same_origin(src, filename);
4990 
4991  if (!same_origin) {
4992  av_log(c->fc, AV_LOG_ERROR,
4993  "Reference with mismatching origin, %s not tried for security reasons, "
4994  "set demuxer option use_absolute_path to allow it anyway\n",
4995  ref->path);
4996  return AVERROR(ENOENT);
4997  }
4998 
4999  if (strstr(ref->path + l + 1, "..") ||
5000  strstr(ref->path + l + 1, ":") ||
5001  (ref->nlvl_from > 1 && same_origin < 0) ||
5002  (filename[0] == '/' && src_path == src))
5003  return AVERROR(ENOENT);
5004  }
5005 
5006  if (strlen(filename) + 1 == sizeof(filename))
5007  return AVERROR(ENOENT);
5008  if (!c->fc->io_open(c->fc, pb, filename, AVIO_FLAG_READ, NULL))
5009  return 0;
5010  }
5011  } else if (c->use_absolute_path) {
5012  av_log(c->fc, AV_LOG_WARNING, "Using absolute path on user request, "
5013  "this is a possible security issue\n");
5014  if (!c->fc->io_open(c->fc, pb, ref->path, AVIO_FLAG_READ, NULL))
5015  return 0;
5016  } else {
5017  av_log(c->fc, AV_LOG_ERROR,
5018  "Absolute path %s not tried for security reasons, "
5019  "set demuxer option use_absolute_path to allow absolute paths\n",
5020  ref->path);
5021  }
5022 
5023  return AVERROR(ENOENT);
5024 }
5025 
5027 {
5028  if (sc->time_scale <= 0) {
5029  av_log(c->fc, AV_LOG_WARNING, "stream %d, timescale not set\n", sc->ffindex);
5030  sc->time_scale = c->time_scale;
5031  if (sc->time_scale <= 0)
5032  sc->time_scale = 1;
5033  }
5034 }
5035 
5036 #if CONFIG_IAMFDEC
5037 static int mov_update_iamf_streams(MOVContext *c, const AVStream *st)
5038 {
5039  const MOVStreamContext *sc = st->priv_data;
5040  const IAMFContext *iamf = &sc->iamf->iamf;
5041 
5042  for (int i = 0; i < iamf->nb_audio_elements; i++) {
5043  const AVStreamGroup *stg = NULL;
5044 
5045  for (int j = 0; j < c->fc->nb_stream_groups; j++)
5046  if (c->fc->stream_groups[j]->id == iamf->audio_elements[i]->audio_element_id)
5047  stg = c->fc->stream_groups[j];
5048  av_assert0(stg);
5049 
5050  for (int j = 0; j < stg->nb_streams; j++) {
5051  const FFStream *sti = cffstream(st);
5052  AVStream *out = stg->streams[j];
5053  FFStream *out_sti = ffstream(stg->streams[j]);
5054 
5055  out->codecpar->bit_rate = 0;
5056 
5057  if (out == st)
5058  continue;
5059 
5060  out->time_base = st->time_base;
5061  out->start_time = st->start_time;
5062  out->duration = st->duration;
5063  out->nb_frames = st->nb_frames;
5064  out->discard = st->discard;
5065 
5066  av_assert0(!out_sti->index_entries);
5068  if (!out_sti->index_entries)
5069  return AVERROR(ENOMEM);
5070 
5072  out_sti->nb_index_entries = sti->nb_index_entries;
5073  out_sti->skip_samples = sti->skip_samples;
5074  memcpy(out_sti->index_entries, sti->index_entries, sti->index_entries_allocated_size);
5075  }
5076  }
5077 
5078  return 0;
5079 }
5080 #endif
5081 
5082 static int sanity_checks(void *log_obj, MOVStreamContext *sc, int index)
5083 {
5084  if ((sc->chunk_count && (!sc->stts_count || !sc->stsc_count ||
5085  (!sc->sample_size && !sc->sample_count))) ||
5086  (!sc->chunk_count && sc->sample_count)) {
5087  av_log(log_obj, AV_LOG_ERROR, "stream %d, missing mandatory atoms, broken header\n",
5088  index);
5089  return 1;
5090  }
5091 
5092  if (sc->stsc_count && sc->stsc_data[ sc->stsc_count - 1 ].first > sc->chunk_count) {
5093  av_log(log_obj, AV_LOG_ERROR, "stream %d, contradictionary STSC and STCO\n",
5094  index);
5095  return 2;
5096  }
5097  return 0;
5098 }
5099 
5101 {
5102  AVStream *st;
5103  MOVStreamContext *sc;
5104  int ret;
5105 
5106  st = avformat_new_stream(c->fc, NULL);
5107  if (!st) return AVERROR(ENOMEM);
5108  st->id = -1;
5109  sc = av_mallocz(sizeof(MOVStreamContext));
5110  if (!sc) return AVERROR(ENOMEM);
5111 
5112  st->priv_data = sc;
5114  sc->ffindex = st->index;
5115  c->trak_index = st->index;
5116  sc->tref_flags = 0;
5117  sc->tref_id = -1;
5118  sc->refcount = 1;
5119 
5120  if ((ret = mov_read_default(c, pb, atom)) < 0)
5121  return ret;
5122 
5123  c->trak_index = -1;
5124 
5125  // Here stsc refers to a chunk not described in stco. This is technically invalid,
5126  // but we can overlook it (clearing stsc) whenever stts_count == 0 (indicating no samples).
5127  if (!sc->chunk_count && !sc->stts_count && sc->stsc_count) {
5128  sc->stsc_count = 0;
5129  av_freep(&sc->stsc_data);
5130  }
5131 
5132  ret = sanity_checks(c->fc, sc, st->index);
5133  if (ret)
5134  return ret > 1 ? AVERROR_INVALIDDATA : 0;
5135 
5136  fix_timescale(c, sc);
5137 
5138  avpriv_set_pts_info(st, 64, 1, sc->time_scale);
5139 
5140  /*
5141  * Advanced edit list support does not work with fragemented MP4s, which
5142  * have stsc, stsz, stco, and stts with zero entries in the moov atom.
5143  * In these files, trun atoms may be streamed in.
5144  */
5145  if (!sc->stts_count && c->advanced_editlist) {
5146 
5147  av_log(c->fc, AV_LOG_VERBOSE, "advanced_editlist does not work with fragmented "
5148  "MP4. disabling.\n");
5149  c->advanced_editlist = 0;
5150  c->advanced_editlist_autodisabled = 1;
5151  }
5152 
5153  mov_build_index(c, st);
5154 
5155 #if CONFIG_IAMFDEC
5156  if (sc->iamf) {
5157  ret = mov_update_iamf_streams(c, st);
5158  if (ret < 0)
5159  return ret;
5160  }
5161 #endif
5162 
5163  if (sc->dref_id-1 < sc->drefs_count && sc->drefs[sc->dref_id-1].path) {
5164  MOVDref *dref = &sc->drefs[sc->dref_id - 1];
5165  if (c->enable_drefs) {
5166  if (mov_open_dref(c, &sc->pb, c->fc->url, dref) < 0)
5167  av_log(c->fc, AV_LOG_ERROR,
5168  "stream %d, error opening alias: path='%s', dir='%s', "
5169  "filename='%s', volume='%s', nlvl_from=%d, nlvl_to=%d\n",
5170  st->index, dref->path, dref->dir, dref->filename,
5171  dref->volume, dref->nlvl_from, dref->nlvl_to);
5172  } else {
5173  av_log(c->fc, AV_LOG_WARNING,
5174  "Skipped opening external track: "
5175  "stream %d, alias: path='%s', dir='%s', "
5176  "filename='%s', volume='%s', nlvl_from=%d, nlvl_to=%d."
5177  "Set enable_drefs to allow this.\n",
5178  st->index, dref->path, dref->dir, dref->filename,
5179  dref->volume, dref->nlvl_from, dref->nlvl_to);
5180  }
5181  } else {
5182  sc->pb = c->fc->pb;
5183  sc->pb_is_copied = 1;
5184  }
5185 
5186  if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
5187  int stts_constant = sc->stts_count && sc->tts_count;
5188  if (sc->h_spacing && sc->v_spacing)
5190  sc->h_spacing, sc->v_spacing, INT_MAX);
5191  if (!st->sample_aspect_ratio.num && st->codecpar->width && st->codecpar->height &&
5192  sc->height && sc->width &&
5193  (st->codecpar->width != sc->width || st->codecpar->height != sc->height)) {
5195  (int64_t)st->codecpar->height * sc->width,
5196  (int64_t)st->codecpar->width * sc->height, INT_MAX);
5197  }
5198 
5199 #if FF_API_R_FRAME_RATE
5200  for (unsigned int i = 1; sc->stts_count && i + 1 < sc->tts_count; i++) {
5201  if (sc->tts_data[i].duration == sc->tts_data[0].duration)
5202  continue;
5203  stts_constant = 0;
5204  }
5205  if (stts_constant)
5207  sc->time_scale, sc->tts_data[0].duration, INT_MAX);
5208 #endif
5209  }
5210 
5211  // done for ai5q, ai52, ai55, ai1q, ai12 and ai15.
5212  if (!st->codecpar->extradata_size && st->codecpar->codec_id == AV_CODEC_ID_H264 &&
5213  TAG_IS_AVCI(st->codecpar->codec_tag)) {
5215  if (ret < 0)
5216  return ret;
5217  }
5218 
5219  switch (st->codecpar->codec_id) {
5220 #if CONFIG_H261_DECODER
5221  case AV_CODEC_ID_H261:
5222 #endif
5223 #if CONFIG_H263_DECODER
5224  case AV_CODEC_ID_H263:
5225 #endif
5226 #if CONFIG_MPEG4_DECODER
5227  case AV_CODEC_ID_MPEG4:
5228 #endif
5229  st->codecpar->width = 0; /* let decoder init width/height */
5230  st->codecpar->height= 0;
5231  break;
5232  }
5233 
5234  // If the duration of the mp3 packets is not constant, then they could need a parser
5235  if (st->codecpar->codec_id == AV_CODEC_ID_MP3
5236  && sc->time_scale == st->codecpar->sample_rate) {
5237  int stts_constant = 1;
5238  for (int i = 1; sc->stts_count && i < sc->tts_count; i++) {
5239  if (sc->tts_data[i].duration == sc->tts_data[0].duration)
5240  continue;
5241  stts_constant = 0;
5242  }
5243  if (!stts_constant)
5245  }
5246  /* Do not need those anymore. */
5247  av_freep(&sc->chunk_offsets);
5248  av_freep(&sc->sample_sizes);
5249  av_freep(&sc->keyframes);
5250  av_freep(&sc->stps_data);
5251  av_freep(&sc->elst_data);
5252  av_freep(&sc->rap_group);
5253  av_freep(&sc->sync_group);
5254  av_freep(&sc->sgpd_sync);
5255 
5256  return 0;
5257 }
5258 
5260 {
5261  int ret;
5262  c->itunes_metadata = 1;
5263  ret = mov_read_default(c, pb, atom);
5264  c->itunes_metadata = 0;
5265  return ret;
5266 }
5267 
5269 {
5270  uint32_t count;
5271  uint32_t i;
5272 
5273  if (atom.size < 8)
5274  return 0;
5275 
5276  avio_skip(pb, 4);
5277  count = avio_rb32(pb);
5278  atom.size -= 8;
5279  if (count >= UINT_MAX / sizeof(*c->meta_keys)) {
5280  av_log(c->fc, AV_LOG_ERROR,
5281  "The 'keys' atom with the invalid key count: %"PRIu32"\n", count);
5282  return AVERROR_INVALIDDATA;
5283  }
5284 
5285  c->meta_keys_count = count + 1;
5286  c->meta_keys = av_mallocz(c->meta_keys_count * sizeof(*c->meta_keys));
5287  if (!c->meta_keys)
5288  return AVERROR(ENOMEM);
5289 
5290  for (i = 1; i <= count; ++i) {
5291  uint32_t key_size = avio_rb32(pb);
5292  uint32_t type = avio_rl32(pb);
5293  if (key_size < 8 || key_size > atom.size) {
5294  av_log(c->fc, AV_LOG_ERROR,
5295  "The key# %"PRIu32" in meta has invalid size:"
5296  "%"PRIu32"\n", i, key_size);
5297  return AVERROR_INVALIDDATA;
5298  }
5299  atom.size -= key_size;
5300  key_size -= 8;
5301  if (type != MKTAG('m','d','t','a')) {
5302  avio_skip(pb, key_size);
5303  continue;
5304  }
5305  c->meta_keys[i] = av_mallocz(key_size + 1);
5306  if (!c->meta_keys[i])
5307  return AVERROR(ENOMEM);
5308  avio_read(pb, c->meta_keys[i], key_size);
5309  }
5310 
5311  return 0;
5312 }
5313 
5315 {
5316  int64_t end = av_sat_add64(avio_tell(pb), atom.size);
5317  uint8_t *key = NULL, *val = NULL, *mean = NULL;
5318  int i;
5319  int ret = 0;
5320  AVStream *st;
5321  MOVStreamContext *sc;
5322 
5323  if (c->fc->nb_streams < 1)
5324  return 0;
5325  st = c->fc->streams[c->fc->nb_streams-1];
5326  sc = st->priv_data;
5327 
5328  for (i = 0; i < 3; i++) {
5329  uint8_t **p;
5330  uint32_t len, tag;
5331 
5332  if (end - avio_tell(pb) <= 12)
5333  break;
5334 
5335  len = avio_rb32(pb);
5336  tag = avio_rl32(pb);
5337  avio_skip(pb, 4); // flags
5338 
5339  if (len < 12 || len - 12 > end - avio_tell(pb))
5340  break;
5341  len -= 12;
5342 
5343  if (tag == MKTAG('m', 'e', 'a', 'n'))
5344  p = &mean;
5345  else if (tag == MKTAG('n', 'a', 'm', 'e'))
5346  p = &key;
5347  else if (tag == MKTAG('d', 'a', 't', 'a') && len > 4) {
5348  avio_skip(pb, 4);
5349  len -= 4;
5350  p = &val;
5351  } else
5352  break;
5353 
5354  if (*p)
5355  break;
5356 
5357  *p = av_malloc(len + 1);
5358  if (!*p) {
5359  ret = AVERROR(ENOMEM);
5360  break;
5361  }
5362  ret = ffio_read_size(pb, *p, len);
5363  if (ret < 0) {
5364  av_freep(p);
5365  break;
5366  }
5367  (*p)[len] = 0;
5368  }
5369 
5370  if (mean && key && val) {
5371  if (strcmp(key, "iTunSMPB") == 0) {
5372  int priming, remainder, samples;
5373  if(sscanf(val, "%*X %X %X %X", &priming, &remainder, &samples) == 3){
5374  if(priming>0 && priming<16384)
5375  sc->start_pad = priming;
5376  }
5377  }
5378  if (strcmp(key, "cdec") != 0) {
5379  av_dict_set(&c->fc->metadata, key, val,
5381  key = val = NULL;
5382  }
5383  } else {
5384  av_log(c->fc, AV_LOG_VERBOSE,
5385  "Unhandled or malformed custom metadata of size %"PRId64"\n", atom.size);
5386  }
5387 
5388  avio_seek(pb, end, SEEK_SET);
5389  av_freep(&key);
5390  av_freep(&val);
5391  av_freep(&mean);
5392  return ret;
5393 }
5394 
5396 {
5397  MOVStreamContext *sc;
5398  AVStream *st;
5399 
5400  st = avformat_new_stream(c->fc, NULL);
5401  if (!st)
5402  return AVERROR(ENOMEM);
5403  sc = av_mallocz(sizeof(MOVStreamContext));
5404  if (!sc)
5405  return AVERROR(ENOMEM);
5406 
5407  item->st = st;
5408  st->id = item->item_id;
5409  st->priv_data = sc;
5411  st->codecpar->codec_id = mov_codec_id(st, item->type);
5412  sc->id = st->id;
5413  sc->ffindex = st->index;
5414  st->avg_frame_rate.num = st->avg_frame_rate.den = 1;
5415  st->time_base.num = st->time_base.den = 1;
5416  st->nb_frames = 1;
5417  sc->time_scale = 1;
5418  sc->pb = c->fc->pb;
5419  sc->pb_is_copied = 1;
5420  sc->refcount = 1;
5421 
5422  if (item->name)
5423  av_dict_set(&st->metadata, "title", item->name, 0);
5424 
5425  // Populate the necessary fields used by mov_build_index.
5426  sc->stsc_count = 1;
5427  sc->stsc_data = av_malloc_array(1, sizeof(*sc->stsc_data));
5428  if (!sc->stsc_data)
5429  return AVERROR(ENOMEM);
5430  sc->stsc_data[0].first = 1;
5431  sc->stsc_data[0].count = 1;
5432  sc->stsc_data[0].id = 1;
5433  sc->chunk_count = 1;
5434  sc->chunk_offsets = av_malloc_array(1, sizeof(*sc->chunk_offsets));
5435  if (!sc->chunk_offsets)
5436  return AVERROR(ENOMEM);
5437  sc->sample_count = 1;
5438  sc->sample_sizes = av_malloc_array(1, sizeof(*sc->sample_sizes));
5439  if (!sc->sample_sizes)
5440  return AVERROR(ENOMEM);
5441  sc->stts_count = 1;
5442  sc->stts_data = av_malloc_array(1, sizeof(*sc->stts_data));
5443  if (!sc->stts_data)
5444  return AVERROR(ENOMEM);
5445  sc->stts_data[0].count = 1;
5446  // Not used for still images. But needed by mov_build_index.
5447  sc->stts_data[0].duration = 0;
5448 
5449  return 0;
5450 }
5451 
5453 {
5454  while (atom.size > 8) {
5455  uint32_t tag;
5456  if (avio_feof(pb))
5457  return AVERROR_EOF;
5458  tag = avio_rl32(pb);
5459  atom.size -= 4;
5460  if (tag == MKTAG('h','d','l','r')) {
5461  avio_seek(pb, -8, SEEK_CUR);
5462  atom.size += 8;
5463  return mov_read_default(c, pb, atom);
5464  }
5465  }
5466  return 0;
5467 }
5468 
5469 // return 1 when matrix is identity, 0 otherwise
5470 #define IS_MATRIX_IDENT(matrix) \
5471  ( (matrix)[0][0] == (1 << 16) && \
5472  (matrix)[1][1] == (1 << 16) && \
5473  (matrix)[2][2] == (1 << 30) && \
5474  !(matrix)[0][1] && !(matrix)[0][2] && \
5475  !(matrix)[1][0] && !(matrix)[1][2] && \
5476  !(matrix)[2][0] && !(matrix)[2][1])
5477 
5479 {
5480  int i, j, e;
5481  int width;
5482  int height;
5483  int display_matrix[3][3];
5484  int res_display_matrix[3][3] = { { 0 } };
5485  AVStream *st;
5486  MOVStreamContext *sc;
5487  int version;
5488  int flags;
5489 
5490  if (c->fc->nb_streams < 1)
5491  return 0;
5492  st = c->fc->streams[c->fc->nb_streams-1];
5493  sc = st->priv_data;
5494 
5495  // Each stream (trak) should have exactly 1 tkhd. This catches bad files and
5496  // avoids corrupting AVStreams mapped to an earlier tkhd.
5497  if (st->id != -1)
5498  return AVERROR_INVALIDDATA;
5499 
5500  version = avio_r8(pb);
5501  flags = avio_rb24(pb);
5503 
5504  if (version == 1) {
5505  avio_rb64(pb);
5506  avio_rb64(pb);
5507  } else {
5508  avio_rb32(pb); /* creation time */
5509  avio_rb32(pb); /* modification time */
5510  }
5511  st->id = (int)avio_rb32(pb); /* track id (NOT 0 !)*/
5512  sc->id = st->id;
5513  avio_rb32(pb); /* reserved */
5514 
5515  /* highlevel (considering edits) duration in movie timebase */
5516  (version == 1) ? avio_rb64(pb) : avio_rb32(pb);
5517  avio_rb32(pb); /* reserved */
5518  avio_rb32(pb); /* reserved */
5519 
5520  avio_rb16(pb); /* layer */
5521  avio_rb16(pb); /* alternate group */
5522  avio_rb16(pb); /* volume */
5523  avio_rb16(pb); /* reserved */
5524 
5525  //read in the display matrix (outlined in ISO 14496-12, Section 6.2.2)
5526  // they're kept in fixed point format through all calculations
5527  // save u,v,z to store the whole matrix in the AV_PKT_DATA_DISPLAYMATRIX
5528  // side data, but the scale factor is not needed to calculate aspect ratio
5529  for (i = 0; i < 3; i++) {
5530  display_matrix[i][0] = avio_rb32(pb); // 16.16 fixed point
5531  display_matrix[i][1] = avio_rb32(pb); // 16.16 fixed point
5532  display_matrix[i][2] = avio_rb32(pb); // 2.30 fixed point
5533  }
5534 
5535  width = avio_rb32(pb); // 16.16 fixed point track width
5536  height = avio_rb32(pb); // 16.16 fixed point track height
5537  sc->width = width >> 16;
5538  sc->height = height >> 16;
5539 
5540  // apply the moov display matrix (after the tkhd one)
5541  for (i = 0; i < 3; i++) {
5542  const int sh[3] = { 16, 16, 30 };
5543  for (j = 0; j < 3; j++) {
5544  for (e = 0; e < 3; e++) {
5545  res_display_matrix[i][j] +=
5546  ((int64_t) display_matrix[i][e] *
5547  c->movie_display_matrix[e][j]) >> sh[e];
5548  }
5549  }
5550  }
5551 
5552  // save the matrix when it is not the default identity
5553  if (!IS_MATRIX_IDENT(res_display_matrix)) {
5554  av_freep(&sc->display_matrix);
5555  sc->display_matrix = av_malloc(sizeof(int32_t) * 9);
5556  if (!sc->display_matrix)
5557  return AVERROR(ENOMEM);
5558 
5559  for (i = 0; i < 3; i++)
5560  for (j = 0; j < 3; j++)
5561  sc->display_matrix[i * 3 + j] = res_display_matrix[i][j];
5562  }
5563 
5564  // transform the display width/height according to the matrix
5565  // to keep the same scale, use [width height 1<<16]
5566  if (width && height && sc->display_matrix) {
5567  double disp_transform[2];
5568 
5569  for (i = 0; i < 2; i++)
5570  disp_transform[i] = hypot(sc->display_matrix[0 + i],
5571  sc->display_matrix[3 + i]);
5572 
5573  if (disp_transform[0] > 1 && disp_transform[1] > 1 &&
5574  disp_transform[0] < (1<<24) && disp_transform[1] < (1<<24) &&
5575  fabs((disp_transform[0] / disp_transform[1]) - 1.0) > 0.01)
5577  disp_transform[0] / disp_transform[1],
5578  INT_MAX);
5579  }
5580  return 0;
5581 }
5582 
5584 {
5585  MOVFragment *frag = &c->fragment;
5586  MOVTrackExt *trex = NULL;
5587  int flags, track_id, i;
5588  MOVFragmentStreamInfo * frag_stream_info;
5589 
5590  avio_r8(pb); /* version */
5591  flags = avio_rb24(pb);
5592 
5593  track_id = avio_rb32(pb);
5594  if (!track_id)
5595  return AVERROR_INVALIDDATA;
5596  for (i = 0; i < c->trex_count; i++)
5597  if (c->trex_data[i].track_id == track_id) {
5598  trex = &c->trex_data[i];
5599  break;
5600  }
5601  if (!trex) {
5602  av_log(c->fc, AV_LOG_WARNING, "could not find corresponding trex (id %u)\n", track_id);
5603  return 0;
5604  }
5605  c->fragment.found_tfhd = 1;
5606  frag->track_id = track_id;
5607  set_frag_stream(&c->frag_index, track_id);
5608 
5611  frag->moof_offset : frag->implicit_offset;
5612  frag->stsd_id = flags & MOV_TFHD_STSD_ID ? avio_rb32(pb) : trex->stsd_id;
5613 
5615  avio_rb32(pb) : trex->duration;
5616  frag->size = flags & MOV_TFHD_DEFAULT_SIZE ?
5617  avio_rb32(pb) : trex->size;
5618  frag->flags = flags & MOV_TFHD_DEFAULT_FLAGS ?
5619  avio_rb32(pb) : trex->flags;
5620  av_log(c->fc, AV_LOG_TRACE, "frag flags 0x%x\n", frag->flags);
5621 
5622  frag_stream_info = get_current_frag_stream_info(&c->frag_index);
5623  if (frag_stream_info) {
5624  frag_stream_info->next_trun_dts = AV_NOPTS_VALUE;
5625  frag_stream_info->stsd_id = frag->stsd_id;
5626  }
5627  return 0;
5628 }
5629 
5631 {
5632  unsigned i, num;
5633  void *new_tracks;
5634 
5635  num = atom.size / 4;
5636  if (!(new_tracks = av_malloc_array(num, sizeof(int))))
5637  return AVERROR(ENOMEM);
5638 
5639  av_free(c->chapter_tracks);
5640  c->chapter_tracks = new_tracks;
5641  c->nb_chapter_tracks = num;
5642 
5643  for (i = 0; i < num && !pb->eof_reached; i++)
5644  c->chapter_tracks[i] = avio_rb32(pb);
5645 
5646  c->nb_chapter_tracks = i;
5647 
5648  return 0;
5649 }
5650 
5652 {
5653  MOVTrackExt *trex;
5654  int err;
5655 
5656  if ((uint64_t)c->trex_count+1 >= UINT_MAX / sizeof(*c->trex_data))
5657  return AVERROR_INVALIDDATA;
5658  if ((err = av_reallocp_array(&c->trex_data, c->trex_count + 1,
5659  sizeof(*c->trex_data))) < 0) {
5660  c->trex_count = 0;
5661  return err;
5662  }
5663 
5664  c->fc->duration = AV_NOPTS_VALUE; // the duration from mvhd is not representing the whole file when fragments are used.
5665 
5666  trex = &c->trex_data[c->trex_count++];
5667  avio_r8(pb); /* version */
5668  avio_rb24(pb); /* flags */
5669  trex->track_id = avio_rb32(pb);
5670  trex->stsd_id = avio_rb32(pb);
5671  trex->duration = avio_rb32(pb);
5672  trex->size = avio_rb32(pb);
5673  trex->flags = avio_rb32(pb);
5674  return 0;
5675 }
5676 
5678 {
5679  MOVFragment *frag = &c->fragment;
5680  AVStream *st = NULL;
5681  MOVStreamContext *sc;
5682  int version, i;
5683  MOVFragmentStreamInfo * frag_stream_info;
5684  int64_t base_media_decode_time;
5685 
5686  for (i = 0; i < c->fc->nb_streams; i++) {
5687  sc = c->fc->streams[i]->priv_data;
5688  if (sc->id == frag->track_id) {
5689  st = c->fc->streams[i];
5690  break;
5691  }
5692  }
5693  if (!st) {
5694  av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %u\n", frag->track_id);
5695  return 0;
5696  }
5697  sc = st->priv_data;
5698  if (sc->pseudo_stream_id + 1 != frag->stsd_id && sc->pseudo_stream_id != -1)
5699  return 0;
5700  version = avio_r8(pb);
5701  avio_rb24(pb); /* flags */
5702  if (version) {
5703  base_media_decode_time = avio_rb64(pb);
5704  } else {
5705  base_media_decode_time = avio_rb32(pb);
5706  }
5707 
5708  frag_stream_info = get_current_frag_stream_info(&c->frag_index);
5709  if (frag_stream_info)
5710  frag_stream_info->tfdt_dts = base_media_decode_time;
5711  sc->track_end = base_media_decode_time;
5712 
5713  return 0;
5714 }
5715 
5717 {
5718  MOVFragment *frag = &c->fragment;
5719  AVStream *st = NULL;
5720  FFStream *sti = NULL;
5721  MOVStreamContext *sc;
5722  MOVTimeToSample *tts_data;
5723  uint64_t offset;
5724  int64_t dts, pts = AV_NOPTS_VALUE;
5725  int data_offset = 0;
5726  unsigned entries, first_sample_flags = frag->flags;
5727  int flags, distance, i;
5728  int64_t prev_dts = AV_NOPTS_VALUE;
5729  int next_frag_index = -1, index_entry_pos;
5730  size_t requested_size;
5731  size_t old_allocated_size;
5732  AVIndexEntry *new_entries;
5733  MOVFragmentStreamInfo * frag_stream_info;
5734 
5735  if (!frag->found_tfhd) {
5736  av_log(c->fc, AV_LOG_ERROR, "trun track id unknown, no tfhd was found\n");
5737  return AVERROR_INVALIDDATA;
5738  }
5739 
5740  for (i = 0; i < c->fc->nb_streams; i++) {
5741  sc = c->fc->streams[i]->priv_data;
5742  if (sc->id == frag->track_id) {
5743  st = c->fc->streams[i];
5744  sti = ffstream(st);
5745  break;
5746  }
5747  }
5748  if (!st) {
5749  av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %u\n", frag->track_id);
5750  return 0;
5751  }
5752  sc = st->priv_data;
5753  if (sc->pseudo_stream_id+1 != frag->stsd_id && sc->pseudo_stream_id != -1)
5754  return 0;
5755 
5756  // Find the next frag_index index that has a valid index_entry for
5757  // the current track_id.
5758  //
5759  // A valid index_entry means the trun for the fragment was read
5760  // and it's samples are in index_entries at the given position.
5761  // New index entries will be inserted before the index_entry found.
5762  index_entry_pos = sti->nb_index_entries;
5763  for (i = c->frag_index.current + 1; i < c->frag_index.nb_items; i++) {
5764  frag_stream_info = get_frag_stream_info(&c->frag_index, i, frag->track_id);
5765  if (frag_stream_info && frag_stream_info->index_entry >= 0) {
5766  next_frag_index = i;
5767  index_entry_pos = frag_stream_info->index_entry;
5768  break;
5769  }
5770  }
5771  av_assert0(index_entry_pos <= sti->nb_index_entries);
5772 
5773  avio_r8(pb); /* version */
5774  flags = avio_rb24(pb);
5775  entries = avio_rb32(pb);
5776  av_log(c->fc, AV_LOG_TRACE, "flags 0x%x entries %u\n", flags, entries);
5777 
5778  if ((uint64_t)entries+sc->tts_count >= UINT_MAX/sizeof(*sc->tts_data))
5779  return AVERROR_INVALIDDATA;
5780  if (flags & MOV_TRUN_DATA_OFFSET) data_offset = avio_rb32(pb);
5781  if (flags & MOV_TRUN_FIRST_SAMPLE_FLAGS) first_sample_flags = avio_rb32(pb);
5782 
5783  frag_stream_info = get_current_frag_stream_info(&c->frag_index);
5784  if (frag_stream_info) {
5785  if (frag_stream_info->next_trun_dts != AV_NOPTS_VALUE) {
5786  dts = frag_stream_info->next_trun_dts - sc->time_offset;
5787  } else if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE &&
5788  c->use_mfra_for == FF_MOV_FLAG_MFRA_PTS) {
5789  pts = frag_stream_info->first_tfra_pts;
5790  av_log(c->fc, AV_LOG_DEBUG, "found mfra time %"PRId64
5791  ", using it for pts\n", pts);
5792  } else if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE &&
5793  c->use_mfra_for == FF_MOV_FLAG_MFRA_DTS) {
5794  dts = frag_stream_info->first_tfra_pts;
5795  av_log(c->fc, AV_LOG_DEBUG, "found mfra time %"PRId64
5796  ", using it for dts\n", pts);
5797  } else {
5798  int has_tfdt = frag_stream_info->tfdt_dts != AV_NOPTS_VALUE;
5799  int has_sidx = frag_stream_info->sidx_pts != AV_NOPTS_VALUE;
5800  int fallback_tfdt = !c->use_tfdt && !has_sidx && has_tfdt;
5801  int fallback_sidx = c->use_tfdt && !has_tfdt && has_sidx;
5802 
5803  if (fallback_sidx) {
5804  av_log(c->fc, AV_LOG_DEBUG, "use_tfdt set but no tfdt found, using sidx instead\n");
5805  }
5806  if (fallback_tfdt) {
5807  av_log(c->fc, AV_LOG_DEBUG, "use_tfdt not set but no sidx found, using tfdt instead\n");
5808  }
5809 
5810  if (has_tfdt && c->use_tfdt || fallback_tfdt) {
5811  dts = frag_stream_info->tfdt_dts - sc->time_offset;
5812  av_log(c->fc, AV_LOG_DEBUG, "found tfdt time %"PRId64
5813  ", using it for dts\n", dts);
5814  } else if (has_sidx && !c->use_tfdt || fallback_sidx) {
5815  // FIXME: sidx earliest_presentation_time is *PTS*, s.b.
5816  // pts = frag_stream_info->sidx_pts;
5817  dts = frag_stream_info->sidx_pts - sc->time_offset;
5818  av_log(c->fc, AV_LOG_DEBUG, "found sidx time %"PRId64
5819  ", using it for dts\n", frag_stream_info->sidx_pts);
5820  } else {
5821  dts = sc->track_end - sc->time_offset;
5822  av_log(c->fc, AV_LOG_DEBUG, "found track end time %"PRId64
5823  ", using it for dts\n", dts);
5824  }
5825  }
5826  } else {
5827  dts = sc->track_end - sc->time_offset;
5828  av_log(c->fc, AV_LOG_DEBUG, "found track end time %"PRId64
5829  ", using it for dts\n", dts);
5830  }
5831  offset = frag->base_data_offset + data_offset;
5832  distance = 0;
5833  av_log(c->fc, AV_LOG_TRACE, "first sample flags 0x%x\n", first_sample_flags);
5834 
5835  // realloc space for new index entries
5836  if ((uint64_t)sti->nb_index_entries + entries >= UINT_MAX / sizeof(AVIndexEntry)) {
5837  entries = UINT_MAX / sizeof(AVIndexEntry) - sti->nb_index_entries;
5838  av_log(c->fc, AV_LOG_ERROR, "Failed to add index entry\n");
5839  }
5840  if (entries == 0)
5841  return 0;
5842 
5843  requested_size = (sti->nb_index_entries + entries) * sizeof(AVIndexEntry);
5844  new_entries = av_fast_realloc(sti->index_entries,
5846  requested_size);
5847  if (!new_entries)
5848  return AVERROR(ENOMEM);
5849  sti->index_entries= new_entries;
5850 
5851  requested_size = (sti->nb_index_entries + entries) * sizeof(*sc->tts_data);
5852  old_allocated_size = sc->tts_allocated_size;
5853  tts_data = av_fast_realloc(sc->tts_data, &sc->tts_allocated_size,
5854  requested_size);
5855  if (!tts_data)
5856  return AVERROR(ENOMEM);
5857  sc->tts_data = tts_data;
5858 
5859  // In case there were samples without time to sample entries, ensure they get
5860  // zero valued entries. This ensures clips which mix boxes with and
5861  // without time to sample entries don't pickup uninitialized data.
5862  memset((uint8_t*)(sc->tts_data) + old_allocated_size, 0,
5863  sc->tts_allocated_size - old_allocated_size);
5864 
5865  if (index_entry_pos < sti->nb_index_entries) {
5866  // Make hole in index_entries and tts_data for new samples
5867  memmove(sti->index_entries + index_entry_pos + entries,
5868  sti->index_entries + index_entry_pos,
5869  sizeof(*sti->index_entries) *
5870  (sti->nb_index_entries - index_entry_pos));
5871  memmove(sc->tts_data + index_entry_pos + entries,
5872  sc->tts_data + index_entry_pos,
5873  sizeof(*sc->tts_data) * (sc->tts_count - index_entry_pos));
5874  if (index_entry_pos < sc->current_sample) {
5875  sc->current_sample += entries;
5876  }
5877  }
5878 
5879  sti->nb_index_entries += entries;
5880  sc->tts_count = sti->nb_index_entries;
5881  sc->stts_count = sti->nb_index_entries;
5882  if (flags & MOV_TRUN_SAMPLE_CTS)
5883  sc->ctts_count = sti->nb_index_entries;
5884 
5885  // Record the index_entry position in frag_index of this fragment
5886  if (frag_stream_info) {
5887  frag_stream_info->index_entry = index_entry_pos;
5888  if (frag_stream_info->index_base < 0)
5889  frag_stream_info->index_base = index_entry_pos;
5890  }
5891 
5892  if (index_entry_pos > 0)
5893  prev_dts = sti->index_entries[index_entry_pos-1].timestamp;
5894 
5895  for (i = 0; i < entries && !pb->eof_reached; i++) {
5896  unsigned sample_size = frag->size;
5897  int sample_flags = i ? frag->flags : first_sample_flags;
5898  unsigned sample_duration = frag->duration;
5899  unsigned ctts_duration = 0;
5900  int keyframe = 0;
5901  int index_entry_flags = 0;
5902 
5903  if (flags & MOV_TRUN_SAMPLE_DURATION) sample_duration = avio_rb32(pb);
5904  if (flags & MOV_TRUN_SAMPLE_SIZE) sample_size = avio_rb32(pb);
5905  if (flags & MOV_TRUN_SAMPLE_FLAGS) sample_flags = avio_rb32(pb);
5906  if (flags & MOV_TRUN_SAMPLE_CTS) ctts_duration = avio_rb32(pb);
5907 
5908  mov_update_dts_shift(sc, ctts_duration, c->fc);
5909  if (pts != AV_NOPTS_VALUE) {
5910  dts = pts - sc->dts_shift;
5911  if (flags & MOV_TRUN_SAMPLE_CTS) {
5912  dts -= ctts_duration;
5913  } else {
5914  dts -= sc->time_offset;
5915  }
5916  av_log(c->fc, AV_LOG_DEBUG,
5917  "pts %"PRId64" calculated dts %"PRId64
5918  " sc->dts_shift %d ctts.duration %d"
5919  " sc->time_offset %"PRId64
5920  " flags & MOV_TRUN_SAMPLE_CTS %d\n",
5921  pts, dts,
5922  sc->dts_shift, ctts_duration,
5924  pts = AV_NOPTS_VALUE;
5925  }
5926 
5927  keyframe =
5928  !(sample_flags & (MOV_FRAG_SAMPLE_FLAG_IS_NON_SYNC |
5930  if (keyframe) {
5931  distance = 0;
5932  index_entry_flags |= AVINDEX_KEYFRAME;
5933  }
5934  // Fragments can overlap in time. Discard overlapping frames after
5935  // decoding.
5936  if (prev_dts >= dts)
5937  index_entry_flags |= AVINDEX_DISCARD_FRAME;
5938 
5939  sti->index_entries[index_entry_pos].pos = offset;
5940  sti->index_entries[index_entry_pos].timestamp = dts;
5941  sti->index_entries[index_entry_pos].size = sample_size;
5942  sti->index_entries[index_entry_pos].min_distance = distance;
5943  sti->index_entries[index_entry_pos].flags = index_entry_flags;
5944 
5945  sc->tts_data[index_entry_pos].count = 1;
5946  sc->tts_data[index_entry_pos].offset = ctts_duration;
5947  sc->tts_data[index_entry_pos].duration = sample_duration;
5948  index_entry_pos++;
5949 
5950  av_log(c->fc, AV_LOG_TRACE, "AVIndex stream %d, sample %d, offset %"PRIx64", dts %"PRId64", "
5951  "size %u, distance %d, keyframe %d\n", st->index,
5952  index_entry_pos, offset, dts, sample_size, distance, keyframe);
5953  distance++;
5954  if (av_sat_add64(dts, sample_duration) != dts + (uint64_t)sample_duration)
5955  return AVERROR_INVALIDDATA;
5956  if (!sample_size)
5957  return AVERROR_INVALIDDATA;
5958  dts += sample_duration;
5959  offset += sample_size;
5960  sc->data_size += sample_size;
5961 
5962  if (sample_duration <= INT64_MAX - sc->duration_for_fps &&
5963  1 <= INT_MAX - sc->nb_frames_for_fps
5964  ) {
5965  sc->duration_for_fps += sample_duration;
5966  sc->nb_frames_for_fps ++;
5967  }
5968  }
5969  if (frag_stream_info)
5970  frag_stream_info->next_trun_dts = dts + sc->time_offset;
5971  if (i < entries) {
5972  // EOF found before reading all entries. Fix the hole this would
5973  // leave in index_entries and tts_data
5974  int gap = entries - i;
5975  memmove(sti->index_entries + index_entry_pos,
5976  sti->index_entries + index_entry_pos + gap,
5977  sizeof(*sti->index_entries) *
5978  (sti->nb_index_entries - (index_entry_pos + gap)));
5979  memmove(sc->tts_data + index_entry_pos,
5980  sc->tts_data + index_entry_pos + gap,
5981  sizeof(*sc->tts_data) *
5982  (sc->tts_count - (index_entry_pos + gap)));
5983 
5984  sti->nb_index_entries -= gap;
5985  sc->tts_count -= gap;
5986  if (index_entry_pos < sc->current_sample) {
5987  sc->current_sample -= gap;
5988  }
5989  entries = i;
5990  }
5991 
5992  // The end of this new fragment may overlap in time with the start
5993  // of the next fragment in index_entries. Mark the samples in the next
5994  // fragment that overlap with AVINDEX_DISCARD_FRAME
5995  prev_dts = AV_NOPTS_VALUE;
5996  if (index_entry_pos > 0)
5997  prev_dts = sti->index_entries[index_entry_pos-1].timestamp;
5998  for (int i = index_entry_pos; i < sti->nb_index_entries; i++) {
5999  if (prev_dts < sti->index_entries[i].timestamp)
6000  break;
6002  }
6003 
6004  // If a hole was created to insert the new index_entries into,
6005  // the index_entry recorded for all subsequent moof must
6006  // be incremented by the number of entries inserted.
6007  fix_frag_index_entries(&c->frag_index, next_frag_index,
6008  frag->track_id, entries);
6009 
6010  if (pb->eof_reached) {
6011  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted TRUN atom\n");
6012  return AVERROR_EOF;
6013  }
6014 
6015  frag->implicit_offset = offset;
6016 
6017  sc->track_end = dts + sc->time_offset;
6018  if (st->duration < sc->track_end)
6019  st->duration = sc->track_end;
6020 
6021  return 0;
6022 }
6023 
6025 {
6026  int64_t stream_size = avio_size(pb);
6027  int64_t offset = av_sat_add64(avio_tell(pb), atom.size), pts, timestamp;
6028  uint8_t version, is_complete;
6029  int64_t offadd;
6030  unsigned i, j, track_id, item_count;
6031  AVStream *st = NULL;
6032  AVStream *ref_st = NULL;
6033  MOVStreamContext *sc, *ref_sc = NULL;
6034  AVRational timescale;
6035 
6036  version = avio_r8(pb);
6037  if (version > 1) {
6038  avpriv_request_sample(c->fc, "sidx version %u", version);
6039  return 0;
6040  }
6041 
6042  avio_rb24(pb); // flags
6043 
6044  track_id = avio_rb32(pb); // Reference ID
6045  for (i = 0; i < c->fc->nb_streams; i++) {
6046  sc = c->fc->streams[i]->priv_data;
6047  if (sc->id == track_id) {
6048  st = c->fc->streams[i];
6049  break;
6050  }
6051  }
6052  if (!st) {
6053  av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %d\n", track_id);
6054  return 0;
6055  }
6056 
6057  sc = st->priv_data;
6058 
6059  timescale = av_make_q(1, avio_rb32(pb));
6060 
6061  if (timescale.den <= 0) {
6062  av_log(c->fc, AV_LOG_ERROR, "Invalid sidx timescale 1/%d\n", timescale.den);
6063  return AVERROR_INVALIDDATA;
6064  }
6065 
6066  if (version == 0) {
6067  pts = avio_rb32(pb);
6068  offadd= avio_rb32(pb);
6069  } else {
6070  pts = avio_rb64(pb);
6071  offadd= avio_rb64(pb);
6072  }
6073  if (av_sat_add64(offset, offadd) != offset + (uint64_t)offadd)
6074  return AVERROR_INVALIDDATA;
6075 
6076  offset += (uint64_t)offadd;
6077 
6078  avio_rb16(pb); // reserved
6079 
6080  item_count = avio_rb16(pb);
6081  if (item_count == 0)
6082  return AVERROR_INVALIDDATA;
6083 
6084  for (i = 0; i < item_count; i++) {
6085  int index;
6086  MOVFragmentStreamInfo * frag_stream_info;
6087  uint32_t size = avio_rb32(pb);
6088  uint32_t duration = avio_rb32(pb);
6089  if (size & 0x80000000) {
6090  avpriv_request_sample(c->fc, "sidx reference_type 1");
6091  return AVERROR_PATCHWELCOME;
6092  }
6093  avio_rb32(pb); // sap_flags
6094  timestamp = av_rescale_q(pts, timescale, st->time_base);
6095 
6097  frag_stream_info = get_frag_stream_info(&c->frag_index, index, track_id);
6098  if (frag_stream_info)
6099  frag_stream_info->sidx_pts = timestamp;
6100 
6101  if (av_sat_add64(offset, size) != offset + (uint64_t)size ||
6102  av_sat_add64(pts, duration) != pts + (uint64_t)duration
6103  )
6104  return AVERROR_INVALIDDATA;
6105  offset += size;
6106  pts += duration;
6107  }
6108 
6109  st->duration = sc->track_end = pts;
6110 
6111  sc->has_sidx = 1;
6112 
6113  // See if the remaining bytes are just an mfra which we can ignore.
6114  is_complete = offset == stream_size;
6115  if (!is_complete && (pb->seekable & AVIO_SEEKABLE_NORMAL) && stream_size > 0 ) {
6116  int64_t ret;
6117  int64_t original_pos = avio_tell(pb);
6118  if (!c->have_read_mfra_size) {
6119  if ((ret = avio_seek(pb, stream_size - 4, SEEK_SET)) < 0)
6120  return ret;
6121  c->mfra_size = avio_rb32(pb);
6122  c->have_read_mfra_size = 1;
6123  if ((ret = avio_seek(pb, original_pos, SEEK_SET)) < 0)
6124  return ret;
6125  }
6126  if (offset == stream_size - c->mfra_size)
6127  is_complete = 1;
6128  }
6129 
6130  if (is_complete) {
6131  // Find first entry in fragment index that came from an sidx.
6132  // This will pretty much always be the first entry.
6133  for (i = 0; i < c->frag_index.nb_items; i++) {
6134  MOVFragmentIndexItem * item = &c->frag_index.item[i];
6135  for (j = 0; ref_st == NULL && j < item->nb_stream_info; j++) {
6136  MOVFragmentStreamInfo * si;
6137  si = &item->stream_info[j];
6138  if (si->sidx_pts != AV_NOPTS_VALUE) {
6139  ref_st = c->fc->streams[j];
6140  ref_sc = ref_st->priv_data;
6141  break;
6142  }
6143  }
6144  }
6145  if (ref_st) for (i = 0; i < c->fc->nb_streams; i++) {
6146  st = c->fc->streams[i];
6147  sc = st->priv_data;
6148  if (!sc->has_sidx) {
6149  st->duration = sc->track_end = av_rescale(ref_st->duration, sc->time_scale, ref_sc->time_scale);
6150  }
6151  }
6152 
6153  c->frag_index.complete = 1;
6154  }
6155 
6156  return 0;
6157 }
6158 
6159 /* this atom should be null (from specs), but some buggy files put the 'moov' atom inside it... */
6160 /* like the files created with Adobe Premiere 5.0, for samples see */
6161 /* http://graphics.tudelft.nl/~wouter/publications/soundtests/ */
6163 {
6164  int err;
6165 
6166  if (atom.size < 8)
6167  return 0; /* continue */
6168  if (avio_rb32(pb) != 0) { /* 0 sized mdat atom... use the 'wide' atom size */
6169  avio_skip(pb, atom.size - 4);
6170  return 0;
6171  }
6172  atom.type = avio_rl32(pb);
6173  atom.size -= 8;
6174  if (atom.type != MKTAG('m','d','a','t')) {
6175  avio_skip(pb, atom.size);
6176  return 0;
6177  }
6178  err = mov_read_mdat(c, pb, atom);
6179  return err;
6180 }
6181 
6183 {
6184 #if CONFIG_ZLIB
6185  FFIOContext ctx;
6186  uint8_t *cmov_data;
6187  uint8_t *moov_data; /* uncompressed data */
6188  long cmov_len, moov_len;
6189  int ret = -1;
6190 
6191  avio_rb32(pb); /* dcom atom */
6192  if (avio_rl32(pb) != MKTAG('d','c','o','m'))
6193  return AVERROR_INVALIDDATA;
6194  if (avio_rl32(pb) != MKTAG('z','l','i','b')) {
6195  av_log(c->fc, AV_LOG_ERROR, "unknown compression for cmov atom !\n");
6196  return AVERROR_INVALIDDATA;
6197  }
6198  avio_rb32(pb); /* cmvd atom */
6199  if (avio_rl32(pb) != MKTAG('c','m','v','d'))
6200  return AVERROR_INVALIDDATA;
6201  moov_len = avio_rb32(pb); /* uncompressed size */
6202  cmov_len = atom.size - 6 * 4;
6203 
6204  cmov_data = av_malloc(cmov_len);
6205  if (!cmov_data)
6206  return AVERROR(ENOMEM);
6207  moov_data = av_malloc(moov_len);
6208  if (!moov_data) {
6209  av_free(cmov_data);
6210  return AVERROR(ENOMEM);
6211  }
6212  ret = ffio_read_size(pb, cmov_data, cmov_len);
6213  if (ret < 0)
6214  goto free_and_return;
6215 
6217  if (uncompress (moov_data, (uLongf *) &moov_len, (const Bytef *)cmov_data, cmov_len) != Z_OK)
6218  goto free_and_return;
6219  ffio_init_read_context(&ctx, moov_data, moov_len);
6220  ctx.pub.seekable = AVIO_SEEKABLE_NORMAL;
6221  atom.type = MKTAG('m','o','o','v');
6222  atom.size = moov_len;
6223  ret = mov_read_default(c, &ctx.pub, atom);
6224 free_and_return:
6225  av_free(moov_data);
6226  av_free(cmov_data);
6227  return ret;
6228 #else
6229  av_log(c->fc, AV_LOG_ERROR, "this file requires zlib support compiled in\n");
6230  return AVERROR(ENOSYS);
6231 #endif
6232 }
6233 
6234 /* edit list atom */
6236 {
6237  MOVStreamContext *sc;
6238  int i, edit_count, version;
6239  int64_t elst_entry_size;
6240 
6241  if (c->fc->nb_streams < 1 || c->ignore_editlist)
6242  return 0;
6243  sc = c->fc->streams[c->fc->nb_streams-1]->priv_data;
6244 
6245  version = avio_r8(pb); /* version */
6246  avio_rb24(pb); /* flags */
6247  edit_count = avio_rb32(pb); /* entries */
6248  atom.size -= 8;
6249 
6250  elst_entry_size = version == 1 ? 20 : 12;
6251  if (atom.size != edit_count * elst_entry_size) {
6252  if (c->fc->strict_std_compliance >= FF_COMPLIANCE_STRICT) {
6253  av_log(c->fc, AV_LOG_ERROR, "Invalid edit list entry_count: %d for elst atom of size: %"PRId64" bytes.\n",
6254  edit_count, atom.size + 8);
6255  return AVERROR_INVALIDDATA;
6256  } else {
6257  edit_count = atom.size / elst_entry_size;
6258  if (edit_count * elst_entry_size != atom.size) {
6259  av_log(c->fc, AV_LOG_WARNING, "ELST atom of %"PRId64" bytes, bigger than %d entries.\n", atom.size, edit_count);
6260  }
6261  }
6262  }
6263 
6264  if (!edit_count)
6265  return 0;
6266  if (sc->elst_data)
6267  av_log(c->fc, AV_LOG_WARNING, "Duplicated ELST atom\n");
6268  av_free(sc->elst_data);
6269  sc->elst_count = 0;
6270  sc->elst_data = av_malloc_array(edit_count, sizeof(*sc->elst_data));
6271  if (!sc->elst_data)
6272  return AVERROR(ENOMEM);
6273 
6274  av_log(c->fc, AV_LOG_TRACE, "track[%u].edit_count = %i\n", c->fc->nb_streams - 1, edit_count);
6275  for (i = 0; i < edit_count && atom.size > 0 && !pb->eof_reached; i++) {
6276  MOVElst *e = &sc->elst_data[i];
6277 
6278  if (version == 1) {
6279  e->duration = avio_rb64(pb);
6280  e->time = avio_rb64(pb);
6281  atom.size -= 16;
6282  } else {
6283  e->duration = avio_rb32(pb); /* segment duration */
6284  e->time = (int32_t)avio_rb32(pb); /* media time */
6285  atom.size -= 8;
6286  }
6287  e->rate = avio_rb32(pb) / 65536.0;
6288  atom.size -= 4;
6289  av_log(c->fc, AV_LOG_TRACE, "duration=%"PRId64" time=%"PRId64" rate=%f\n",
6290  e->duration, e->time, e->rate);
6291 
6292  if (e->time < 0 && e->time != -1 &&
6293  c->fc->strict_std_compliance >= FF_COMPLIANCE_STRICT) {
6294  av_log(c->fc, AV_LOG_ERROR, "Track %d, edit %d: Invalid edit list media time=%"PRId64"\n",
6295  c->fc->nb_streams-1, i, e->time);
6296  return AVERROR_INVALIDDATA;
6297  }
6298  if (e->duration < 0) {
6299  av_log(c->fc, AV_LOG_ERROR, "Track %d, edit %d: Invalid edit list duration=%"PRId64"\n",
6300  c->fc->nb_streams-1, i, e->duration);
6301  return AVERROR_INVALIDDATA;
6302  }
6303  }
6304  sc->elst_count = i;
6305 
6306  return 0;
6307 }
6308 
6310 {
6311  MOVStreamContext *sc;
6312 
6313  if (c->fc->nb_streams < 1)
6314  return AVERROR_INVALIDDATA;
6315  sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
6316  sc->timecode_track = avio_rb32(pb);
6317  return 0;
6318 }
6319 
6321 {
6322  AVStream *st;
6323  int version, color_range, color_primaries, color_trc, color_space;
6324 
6325  if (c->fc->nb_streams < 1)
6326  return 0;
6327  st = c->fc->streams[c->fc->nb_streams - 1];
6328 
6329  if (atom.size < 5) {
6330  av_log(c->fc, AV_LOG_ERROR, "Empty VP Codec Configuration box\n");
6331  return AVERROR_INVALIDDATA;
6332  }
6333 
6334  version = avio_r8(pb);
6335  if (version != 1) {
6336  av_log(c->fc, AV_LOG_WARNING, "Unsupported VP Codec Configuration box version %d\n", version);
6337  return 0;
6338  }
6339  avio_skip(pb, 3); /* flags */
6340 
6341  avio_skip(pb, 2); /* profile + level */
6342  color_range = avio_r8(pb); /* bitDepth, chromaSubsampling, videoFullRangeFlag */
6343  color_primaries = avio_r8(pb);
6344  color_trc = avio_r8(pb);
6345  color_space = avio_r8(pb);
6346  if (avio_rb16(pb)) /* codecIntializationDataSize */
6347  return AVERROR_INVALIDDATA;
6348 
6351  if (!av_color_transfer_name(color_trc))
6352  color_trc = AVCOL_TRC_UNSPECIFIED;
6353  if (!av_color_space_name(color_space))
6354  color_space = AVCOL_SPC_UNSPECIFIED;
6355 
6358  st->codecpar->color_trc = color_trc;
6359  st->codecpar->color_space = color_space;
6360 
6361  return 0;
6362 }
6363 
6365 {
6366  MOVStreamContext *sc;
6367  int i, version;
6368 
6369  if (c->fc->nb_streams < 1)
6370  return AVERROR_INVALIDDATA;
6371 
6372  sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
6373 
6374  if (atom.size < 5) {
6375  av_log(c->fc, AV_LOG_ERROR, "Empty Mastering Display Metadata box\n");
6376  return AVERROR_INVALIDDATA;
6377  }
6378 
6379  version = avio_r8(pb);
6380  if (version) {
6381  av_log(c->fc, AV_LOG_WARNING, "Unsupported Mastering Display Metadata box version %d\n", version);
6382  return 0;
6383  }
6384  if (sc->mastering) {
6385  av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicate Mastering Display Metadata\n");
6386  return 0;
6387  }
6388 
6389  avio_skip(pb, 3); /* flags */
6390 
6392  if (!sc->mastering)
6393  return AVERROR(ENOMEM);
6394 
6395  for (i = 0; i < 3; i++) {
6396  sc->mastering->display_primaries[i][0] = av_make_q(avio_rb16(pb), 1 << 16);
6397  sc->mastering->display_primaries[i][1] = av_make_q(avio_rb16(pb), 1 << 16);
6398  }
6399  sc->mastering->white_point[0] = av_make_q(avio_rb16(pb), 1 << 16);
6400  sc->mastering->white_point[1] = av_make_q(avio_rb16(pb), 1 << 16);
6401 
6402  sc->mastering->max_luminance = av_make_q(avio_rb32(pb), 1 << 8);
6403  sc->mastering->min_luminance = av_make_q(avio_rb32(pb), 1 << 14);
6404 
6405  sc->mastering->has_primaries = 1;
6406  sc->mastering->has_luminance = 1;
6407 
6408  return 0;
6409 }
6410 
6412 {
6413  MOVStreamContext *sc;
6414  const int mapping[3] = {1, 2, 0};
6415  const int chroma_den = 50000;
6416  const int luma_den = 10000;
6417  int i;
6418 
6419  if (c->fc->nb_streams < 1)
6420  return AVERROR_INVALIDDATA;
6421 
6422  sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
6423 
6424  if (atom.size < 24) {
6425  av_log(c->fc, AV_LOG_ERROR, "Invalid Mastering Display Color Volume box\n");
6426  return AVERROR_INVALIDDATA;
6427  }
6428 
6429  if (sc->mastering) {
6430  av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicate Mastering Display Color Volume\n");
6431  return 0;
6432  }
6433 
6435  if (!sc->mastering)
6436  return AVERROR(ENOMEM);
6437 
6438  for (i = 0; i < 3; i++) {
6439  const int j = mapping[i];
6440  sc->mastering->display_primaries[j][0] = av_make_q(avio_rb16(pb), chroma_den);
6441  sc->mastering->display_primaries[j][1] = av_make_q(avio_rb16(pb), chroma_den);
6442  }
6443  sc->mastering->white_point[0] = av_make_q(avio_rb16(pb), chroma_den);
6444  sc->mastering->white_point[1] = av_make_q(avio_rb16(pb), chroma_den);
6445 
6446  sc->mastering->max_luminance = av_make_q(avio_rb32(pb), luma_den);
6447  sc->mastering->min_luminance = av_make_q(avio_rb32(pb), luma_den);
6448 
6449  sc->mastering->has_luminance = 1;
6450  sc->mastering->has_primaries = 1;
6451 
6452  return 0;
6453 }
6454 
6456 {
6457  MOVStreamContext *sc;
6458  int version;
6459 
6460  if (c->fc->nb_streams < 1)
6461  return AVERROR_INVALIDDATA;
6462 
6463  sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
6464 
6465  if (atom.size < 5) {
6466  av_log(c->fc, AV_LOG_ERROR, "Empty Content Light Level box\n");
6467  return AVERROR_INVALIDDATA;
6468  }
6469 
6470  version = avio_r8(pb);
6471  if (version) {
6472  av_log(c->fc, AV_LOG_WARNING, "Unsupported Content Light Level box version %d\n", version);
6473  return 0;
6474  }
6475  avio_skip(pb, 3); /* flags */
6476 
6477  if (sc->coll){
6478  av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicate COLL\n");
6479  return 0;
6480  }
6481 
6483  if (!sc->coll)
6484  return AVERROR(ENOMEM);
6485 
6486  sc->coll->MaxCLL = avio_rb16(pb);
6487  sc->coll->MaxFALL = avio_rb16(pb);
6488 
6489  return 0;
6490 }
6491 
6493 {
6494  MOVStreamContext *sc;
6495 
6496  if (c->fc->nb_streams < 1)
6497  return AVERROR_INVALIDDATA;
6498 
6499  sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
6500 
6501  if (atom.size < 4) {
6502  av_log(c->fc, AV_LOG_ERROR, "Empty Content Light Level Info box\n");
6503  return AVERROR_INVALIDDATA;
6504  }
6505 
6506  if (sc->coll){
6507  av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicate CLLI/COLL\n");
6508  return 0;
6509  }
6510 
6512  if (!sc->coll)
6513  return AVERROR(ENOMEM);
6514 
6515  sc->coll->MaxCLL = avio_rb16(pb);
6516  sc->coll->MaxFALL = avio_rb16(pb);
6517 
6518  return 0;
6519 }
6520 
6522 {
6523  MOVStreamContext *sc;
6524  const int illuminance_den = 10000;
6525  const int ambient_den = 50000;
6526  if (c->fc->nb_streams < 1)
6527  return AVERROR_INVALIDDATA;
6528  sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
6529  if (atom.size < 6) {
6530  av_log(c->fc, AV_LOG_ERROR, "Empty Ambient Viewing Environment Info box\n");
6531  return AVERROR_INVALIDDATA;
6532  }
6533  if (sc->ambient){
6534  av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicate AMVE\n");
6535  return 0;
6536  }
6538  if (!sc->ambient)
6539  return AVERROR(ENOMEM);
6540  sc->ambient->ambient_illuminance = av_make_q(avio_rb32(pb), illuminance_den);
6541  sc->ambient->ambient_light_x = av_make_q(avio_rb16(pb), ambient_den);
6542  sc->ambient->ambient_light_y = av_make_q(avio_rb16(pb), ambient_den);
6543  return 0;
6544 }
6545 
6547 {
6548  AVStream *st;
6549  MOVStreamContext *sc;
6550  enum AVStereo3DType type;
6551  int mode;
6552 
6553  if (c->fc->nb_streams < 1)
6554  return 0;
6555 
6556  st = c->fc->streams[c->fc->nb_streams - 1];
6557  sc = st->priv_data;
6558 
6559  if (atom.size < 5) {
6560  av_log(c->fc, AV_LOG_ERROR, "Empty stereoscopic video box\n");
6561  return AVERROR_INVALIDDATA;
6562  }
6563 
6564  if (sc->stereo3d)
6565  return AVERROR_INVALIDDATA;
6566 
6567  avio_skip(pb, 4); /* version + flags */
6568 
6569  mode = avio_r8(pb);
6570  switch (mode) {
6571  case 0:
6572  type = AV_STEREO3D_2D;
6573  break;
6574  case 1:
6576  break;
6577  case 2:
6579  break;
6580  default:
6581  av_log(c->fc, AV_LOG_WARNING, "Unknown st3d mode value %d\n", mode);
6582  return 0;
6583  }
6584 
6586  if (!sc->stereo3d)
6587  return AVERROR(ENOMEM);
6588 
6589  sc->stereo3d->type = type;
6590  return 0;
6591 }
6592 
6594 {
6595  AVStream *st;
6596  MOVStreamContext *sc;
6597  int size, version, layout;
6598  int32_t yaw, pitch, roll;
6599  uint32_t l = 0, t = 0, r = 0, b = 0;
6600  uint32_t tag, padding = 0;
6601  enum AVSphericalProjection projection;
6602 
6603  if (c->fc->nb_streams < 1)
6604  return 0;
6605 
6606  st = c->fc->streams[c->fc->nb_streams - 1];
6607  sc = st->priv_data;
6608 
6609  if (atom.size < 8) {
6610  av_log(c->fc, AV_LOG_ERROR, "Empty spherical video box\n");
6611  return AVERROR_INVALIDDATA;
6612  }
6613 
6614  size = avio_rb32(pb);
6615  if (size <= 12 || size > atom.size)
6616  return AVERROR_INVALIDDATA;
6617 
6618  tag = avio_rl32(pb);
6619  if (tag != MKTAG('s','v','h','d')) {
6620  av_log(c->fc, AV_LOG_ERROR, "Missing spherical video header\n");
6621  return 0;
6622  }
6623  version = avio_r8(pb);
6624  if (version != 0) {
6625  av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
6626  version);
6627  return 0;
6628  }
6629  avio_skip(pb, 3); /* flags */
6630  avio_skip(pb, size - 12); /* metadata_source */
6631 
6632  size = avio_rb32(pb);
6633  if (size > atom.size)
6634  return AVERROR_INVALIDDATA;
6635 
6636  tag = avio_rl32(pb);
6637  if (tag != MKTAG('p','r','o','j')) {
6638  av_log(c->fc, AV_LOG_ERROR, "Missing projection box\n");
6639  return 0;
6640  }
6641 
6642  size = avio_rb32(pb);
6643  if (size > atom.size)
6644  return AVERROR_INVALIDDATA;
6645 
6646  tag = avio_rl32(pb);
6647  if (tag != MKTAG('p','r','h','d')) {
6648  av_log(c->fc, AV_LOG_ERROR, "Missing projection header box\n");
6649  return 0;
6650  }
6651  version = avio_r8(pb);
6652  if (version != 0) {
6653  av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
6654  version);
6655  return 0;
6656  }
6657  avio_skip(pb, 3); /* flags */
6658 
6659  /* 16.16 fixed point */
6660  yaw = avio_rb32(pb);
6661  pitch = avio_rb32(pb);
6662  roll = avio_rb32(pb);
6663 
6664  size = avio_rb32(pb);
6665  if (size > atom.size)
6666  return AVERROR_INVALIDDATA;
6667 
6668  tag = avio_rl32(pb);
6669  version = avio_r8(pb);
6670  if (version != 0) {
6671  av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
6672  version);
6673  return 0;
6674  }
6675  avio_skip(pb, 3); /* flags */
6676  switch (tag) {
6677  case MKTAG('c','b','m','p'):
6678  layout = avio_rb32(pb);
6679  if (layout) {
6680  av_log(c->fc, AV_LOG_WARNING,
6681  "Unsupported cubemap layout %d\n", layout);
6682  return 0;
6683  }
6684  projection = AV_SPHERICAL_CUBEMAP;
6685  padding = avio_rb32(pb);
6686  break;
6687  case MKTAG('e','q','u','i'):
6688  t = avio_rb32(pb);
6689  b = avio_rb32(pb);
6690  l = avio_rb32(pb);
6691  r = avio_rb32(pb);
6692 
6693  if (b >= UINT_MAX - t || r >= UINT_MAX - l) {
6694  av_log(c->fc, AV_LOG_ERROR,
6695  "Invalid bounding rectangle coordinates "
6696  "%"PRIu32",%"PRIu32",%"PRIu32",%"PRIu32"\n", l, t, r, b);
6697  return AVERROR_INVALIDDATA;
6698  }
6699 
6700  if (l || t || r || b)
6701  projection = AV_SPHERICAL_EQUIRECTANGULAR_TILE;
6702  else
6703  projection = AV_SPHERICAL_EQUIRECTANGULAR;
6704  break;
6705  default:
6706  av_log(c->fc, AV_LOG_ERROR, "Unknown projection type: %s\n", av_fourcc2str(tag));
6707  return 0;
6708  }
6709 
6711  if (!sc->spherical)
6712  return AVERROR(ENOMEM);
6713 
6714  sc->spherical->projection = projection;
6715 
6716  sc->spherical->yaw = yaw;
6717  sc->spherical->pitch = pitch;
6718  sc->spherical->roll = roll;
6719 
6720  sc->spherical->padding = padding;
6721 
6722  sc->spherical->bound_left = l;
6723  sc->spherical->bound_top = t;
6724  sc->spherical->bound_right = r;
6725  sc->spherical->bound_bottom = b;
6726 
6727  return 0;
6728 }
6729 
6731 {
6732  AVStream *st;
6733  MOVStreamContext *sc;
6734  int size;
6735  uint32_t tag;
6736  enum AVSphericalProjection projection;
6737 
6738  if (c->fc->nb_streams < 1)
6739  return 0;
6740 
6741  st = c->fc->streams[c->fc->nb_streams - 1];
6742  sc = st->priv_data;
6743 
6744  if (atom.size != 16) {
6745  av_log(c->fc, AV_LOG_ERROR, "Invalid size for proj box: %"PRIu64"\n", atom.size);
6746  return AVERROR_INVALIDDATA;
6747  }
6748 
6749  size = avio_rb32(pb);
6750  if (size != 16) {
6751  av_log(c->fc, AV_LOG_ERROR, "Invalid size for prji box: %d\n", size);
6752  return AVERROR_INVALIDDATA;
6753  }
6754 
6755  tag = avio_rl32(pb);
6756  if (tag != MKTAG('p','r','j','i')) {
6757  av_log(c->fc, AV_LOG_ERROR, "Invalid child box of proj box: 0x%08X\n", tag);
6758  return AVERROR_INVALIDDATA;
6759  }
6760 
6761  avio_skip(pb, 1); // version
6762  avio_skip(pb, 3); // flags
6763 
6764  tag = avio_rl32(pb);
6765  switch (tag) {
6766  case MKTAG('r','e','c','t'):
6767  projection = AV_SPHERICAL_RECTILINEAR;
6768  break;
6769  case MKTAG('e','q','u','i'):
6770  projection = AV_SPHERICAL_EQUIRECTANGULAR;
6771  break;
6772  case MKTAG('h','e','q','u'):
6773  projection = AV_SPHERICAL_HALF_EQUIRECTANGULAR;
6774  break;
6775  case MKTAG('f','i','s','h'):
6776  projection = AV_SPHERICAL_FISHEYE;
6777  break;
6778  default:
6779  av_log(c->fc, AV_LOG_ERROR, "Invalid projection type in prji box: 0x%08X\n", tag);
6780  return AVERROR_INVALIDDATA;
6781  }
6782 
6784  if (!sc->spherical)
6785  return AVERROR(ENOMEM);
6786 
6787  sc->spherical->projection = projection;
6788 
6789  return 0;
6790 }
6791 
6793 {
6794  AVStream *st;
6795  MOVStreamContext *sc;
6796  int size, flags = 0;
6797  int64_t remaining;
6798  uint32_t tag, baseline = 0;
6801  enum AVStereo3DPrimaryEye primary_eye = AV_PRIMARY_EYE_NONE;
6802  AVRational horizontal_disparity_adjustment = { 0, 1 };
6803 
6804  if (c->fc->nb_streams < 1)
6805  return 0;
6806 
6807  st = c->fc->streams[c->fc->nb_streams - 1];
6808  sc = st->priv_data;
6809 
6810  remaining = atom.size;
6811  while (remaining > 0) {
6812  size = avio_rb32(pb);
6813  if (size < 8 || size > remaining ) {
6814  av_log(c->fc, AV_LOG_ERROR, "Invalid child size in eyes box\n");
6815  return AVERROR_INVALIDDATA;
6816  }
6817 
6818  tag = avio_rl32(pb);
6819  switch (tag) {
6820  case MKTAG('s','t','r','i'): {
6821  int has_right, has_left;
6822  uint8_t tmp;
6823  if (size != 13) {
6824  av_log(c->fc, AV_LOG_ERROR, "Invalid size of stri box: %d\n", size);
6825  return AVERROR_INVALIDDATA;
6826  }
6827  avio_skip(pb, 1); // version
6828  avio_skip(pb, 3); // flags
6829 
6830  tmp = avio_r8(pb);
6831 
6832  // eye_views_reversed
6833  if (tmp & 8) {
6835  }
6836  // has_additional_views
6837  if (tmp & 4) {
6838  // skip...
6839  }
6840 
6841  has_right = tmp & 2; // has_right_eye_view
6842  has_left = tmp & 1; // has_left_eye_view
6843 
6844  if (has_left && has_right)
6845  view = AV_STEREO3D_VIEW_PACKED;
6846  else if (has_left)
6847  view = AV_STEREO3D_VIEW_LEFT;
6848  else if (has_right)
6849  view = AV_STEREO3D_VIEW_RIGHT;
6850  if (has_left || has_right)
6852 
6853  break;
6854  }
6855  case MKTAG('h','e','r','o'): {
6856  int tmp;
6857  if (size != 13) {
6858  av_log(c->fc, AV_LOG_ERROR, "Invalid size of hero box: %d\n", size);
6859  return AVERROR_INVALIDDATA;
6860  }
6861  avio_skip(pb, 1); // version
6862  avio_skip(pb, 3); // flags
6863 
6864  tmp = avio_r8(pb);
6865  if (tmp == 0)
6866  primary_eye = AV_PRIMARY_EYE_NONE;
6867  else if (tmp == 1)
6868  primary_eye = AV_PRIMARY_EYE_LEFT;
6869  else if (tmp == 2)
6870  primary_eye = AV_PRIMARY_EYE_RIGHT;
6871  else
6872  av_log(c->fc, AV_LOG_WARNING, "Unknown hero eye type: %d\n", tmp);
6873 
6874  break;
6875  }
6876  case MKTAG('c','a','m','s'): {
6877  uint32_t subtag;
6878  int subsize;
6879  if (size != 24) {
6880  av_log(c->fc, AV_LOG_ERROR, "Invalid size of cams box: %d\n", size);
6881  return AVERROR_INVALIDDATA;
6882  }
6883 
6884  subsize = avio_rb32(pb);
6885  if (subsize != 16) {
6886  av_log(c->fc, AV_LOG_ERROR, "Invalid size of blin box: %d\n", size);
6887  return AVERROR_INVALIDDATA;
6888  }
6889 
6890  subtag = avio_rl32(pb);
6891  if (subtag != MKTAG('b','l','i','n')) {
6892  av_log(c->fc, AV_LOG_ERROR, "Expected blin box, got 0x%08X\n", subtag);
6893  return AVERROR_INVALIDDATA;
6894  }
6895 
6896  avio_skip(pb, 1); // version
6897  avio_skip(pb, 3); // flags
6898 
6899  baseline = avio_rb32(pb);
6900 
6901  break;
6902  }
6903  case MKTAG('c','m','f','y'): {
6904  uint32_t subtag;
6905  int subsize;
6906  int32_t adjustment;
6907  if (size != 24) {
6908  av_log(c->fc, AV_LOG_ERROR, "Invalid size of cmfy box: %d\n", size);
6909  return AVERROR_INVALIDDATA;
6910  }
6911 
6912  subsize = avio_rb32(pb);
6913  if (subsize != 16) {
6914  av_log(c->fc, AV_LOG_ERROR, "Invalid size of dadj box: %d\n", size);
6915  return AVERROR_INVALIDDATA;
6916  }
6917 
6918  subtag = avio_rl32(pb);
6919  if (subtag != MKTAG('d','a','d','j')) {
6920  av_log(c->fc, AV_LOG_ERROR, "Expected dadj box, got 0x%08X\n", subtag);
6921  return AVERROR_INVALIDDATA;
6922  }
6923 
6924  avio_skip(pb, 1); // version
6925  avio_skip(pb, 3); // flags
6926 
6927  adjustment = (int32_t) avio_rb32(pb);
6928 
6929  horizontal_disparity_adjustment.num = (int) adjustment;
6930  horizontal_disparity_adjustment.den = 10000;
6931 
6932  break;
6933  }
6934  default:
6935  av_log(c->fc, AV_LOG_WARNING, "Unknown tag in eyes: 0x%08X\n", tag);
6936  avio_skip(pb, size - 8);
6937  break;
6938  }
6939  remaining -= size;
6940  }
6941 
6942  if (remaining != 0) {
6943  av_log(c->fc, AV_LOG_ERROR, "Broken eyes box\n");
6944  return AVERROR_INVALIDDATA;
6945  }
6946 
6947  if (type == AV_STEREO3D_2D)
6948  return 0;
6949 
6950  if (!sc->stereo3d) {
6952  if (!sc->stereo3d)
6953  return AVERROR(ENOMEM);
6954  }
6955 
6956  sc->stereo3d->flags = flags;
6957  sc->stereo3d->type = type;
6958  sc->stereo3d->view = view;
6959  sc->stereo3d->primary_eye = primary_eye;
6960  sc->stereo3d->baseline = baseline;
6961  sc->stereo3d->horizontal_disparity_adjustment = horizontal_disparity_adjustment;
6962 
6963  return 0;
6964 }
6965 
6967 {
6968  int size;
6969  int64_t remaining;
6970  uint32_t tag;
6971 
6972  if (c->fc->nb_streams < 1)
6973  return 0;
6974 
6975  if (atom.size < 8) {
6976  av_log(c->fc, AV_LOG_ERROR, "Empty video extension usage box\n");
6977  return AVERROR_INVALIDDATA;
6978  }
6979 
6980  remaining = atom.size;
6981  while (remaining > 0) {
6982  size = avio_rb32(pb);
6983  if (size < 8 || size > remaining ) {
6984  av_log(c->fc, AV_LOG_ERROR, "Invalid child size in vexu box\n");
6985  return AVERROR_INVALIDDATA;
6986  }
6987 
6988  tag = avio_rl32(pb);
6989  switch (tag) {
6990  case MKTAG('p','r','o','j'): {
6991  MOVAtom proj = { tag, size - 8 };
6992  int ret = mov_read_vexu_proj(c, pb, proj);
6993  if (ret < 0)
6994  return ret;
6995  break;
6996  }
6997  case MKTAG('e','y','e','s'): {
6998  MOVAtom eyes = { tag, size - 8 };
6999  int ret = mov_read_eyes(c, pb, eyes);
7000  if (ret < 0)
7001  return ret;
7002  break;
7003  }
7004  default:
7005  av_log(c->fc, AV_LOG_WARNING, "Unknown tag in vexu: 0x%08X\n", tag);
7006  avio_skip(pb, size - 8);
7007  break;
7008  }
7009  remaining -= size;
7010  }
7011 
7012  if (remaining != 0) {
7013  av_log(c->fc, AV_LOG_ERROR, "Broken vexu box\n");
7014  return AVERROR_INVALIDDATA;
7015  }
7016 
7017  return 0;
7018 }
7019 
7021 {
7022  AVStream *st;
7023  MOVStreamContext *sc;
7024 
7025  if (c->fc->nb_streams < 1)
7026  return 0;
7027 
7028  st = c->fc->streams[c->fc->nb_streams - 1];
7029  sc = st->priv_data;
7030 
7031  if (atom.size != 4) {
7032  av_log(c->fc, AV_LOG_ERROR, "Invalid size of hfov box: %"PRIu64"\n", atom.size);
7033  return AVERROR_INVALIDDATA;
7034  }
7035 
7036 
7037  if (!sc->stereo3d) {
7039  if (!sc->stereo3d)
7040  return AVERROR(ENOMEM);
7041  }
7042 
7044  sc->stereo3d->horizontal_field_of_view.den = 1000; // thousands of a degree
7045 
7046  return 0;
7047 }
7048 
7050 {
7051  int ret = 0;
7052  uint8_t *buffer = av_malloc(len + 1);
7053  const char *val;
7054 
7055  if (!buffer)
7056  return AVERROR(ENOMEM);
7057  buffer[len] = '\0';
7058 
7059  ret = ffio_read_size(pb, buffer, len);
7060  if (ret < 0)
7061  goto out;
7062 
7063  /* Check for mandatory keys and values, try to support XML as best-effort */
7064  if (!sc->spherical &&
7065  av_stristr(buffer, "<GSpherical:StitchingSoftware>") &&
7066  (val = av_stristr(buffer, "<GSpherical:Spherical>")) &&
7067  av_stristr(val, "true") &&
7068  (val = av_stristr(buffer, "<GSpherical:Stitched>")) &&
7069  av_stristr(val, "true") &&
7070  (val = av_stristr(buffer, "<GSpherical:ProjectionType>")) &&
7071  av_stristr(val, "equirectangular")) {
7073  if (!sc->spherical)
7074  goto out;
7075 
7077 
7078  if (av_stristr(buffer, "<GSpherical:StereoMode>") && !sc->stereo3d) {
7079  enum AVStereo3DType mode;
7080 
7081  if (av_stristr(buffer, "left-right"))
7083  else if (av_stristr(buffer, "top-bottom"))
7085  else
7086  mode = AV_STEREO3D_2D;
7087 
7089  if (!sc->stereo3d)
7090  goto out;
7091 
7092  sc->stereo3d->type = mode;
7093  }
7094 
7095  /* orientation */
7096  val = av_stristr(buffer, "<GSpherical:InitialViewHeadingDegrees>");
7097  if (val)
7098  sc->spherical->yaw = strtol(val, NULL, 10) * (1 << 16);
7099  val = av_stristr(buffer, "<GSpherical:InitialViewPitchDegrees>");
7100  if (val)
7101  sc->spherical->pitch = strtol(val, NULL, 10) * (1 << 16);
7102  val = av_stristr(buffer, "<GSpherical:InitialViewRollDegrees>");
7103  if (val)
7104  sc->spherical->roll = strtol(val, NULL, 10) * (1 << 16);
7105  }
7106 
7107 out:
7108  av_free(buffer);
7109  return ret;
7110 }
7111 
7113 {
7114  AVStream *st;
7115  MOVStreamContext *sc;
7116  int64_t ret;
7117  AVUUID uuid;
7118  static const AVUUID uuid_isml_manifest = {
7119  0xa5, 0xd4, 0x0b, 0x30, 0xe8, 0x14, 0x11, 0xdd,
7120  0xba, 0x2f, 0x08, 0x00, 0x20, 0x0c, 0x9a, 0x66
7121  };
7122  static const AVUUID uuid_xmp = {
7123  0xbe, 0x7a, 0xcf, 0xcb, 0x97, 0xa9, 0x42, 0xe8,
7124  0x9c, 0x71, 0x99, 0x94, 0x91, 0xe3, 0xaf, 0xac
7125  };
7126  static const AVUUID uuid_spherical = {
7127  0xff, 0xcc, 0x82, 0x63, 0xf8, 0x55, 0x4a, 0x93,
7128  0x88, 0x14, 0x58, 0x7a, 0x02, 0x52, 0x1f, 0xdd,
7129  };
7130 
7131  if (atom.size < AV_UUID_LEN || atom.size >= FFMIN(INT_MAX, SIZE_MAX))
7132  return AVERROR_INVALIDDATA;
7133 
7134  if (c->fc->nb_streams < 1)
7135  return 0;
7136  st = c->fc->streams[c->fc->nb_streams - 1];
7137  sc = st->priv_data;
7138 
7139  ret = ffio_read_size(pb, uuid, AV_UUID_LEN);
7140  if (ret < 0)
7141  return ret;
7142  if (av_uuid_equal(uuid, uuid_isml_manifest)) {
7143  uint8_t *buffer, *ptr;
7144  char *endptr;
7145  size_t len = atom.size - AV_UUID_LEN;
7146 
7147  if (len < 4) {
7148  return AVERROR_INVALIDDATA;
7149  }
7150  ret = avio_skip(pb, 4); // zeroes
7151  len -= 4;
7152 
7153  buffer = av_mallocz(len + 1);
7154  if (!buffer) {
7155  return AVERROR(ENOMEM);
7156  }
7157  ret = ffio_read_size(pb, buffer, len);
7158  if (ret < 0) {
7159  av_free(buffer);
7160  return ret;
7161  }
7162 
7163  ptr = buffer;
7164  while ((ptr = av_stristr(ptr, "systemBitrate=\""))) {
7165  ptr += sizeof("systemBitrate=\"") - 1;
7166  c->bitrates_count++;
7167  c->bitrates = av_realloc_f(c->bitrates, c->bitrates_count, sizeof(*c->bitrates));
7168  if (!c->bitrates) {
7169  c->bitrates_count = 0;
7170  av_free(buffer);
7171  return AVERROR(ENOMEM);
7172  }
7173  errno = 0;
7174  ret = strtol(ptr, &endptr, 10);
7175  if (ret < 0 || errno || *endptr != '"') {
7176  c->bitrates[c->bitrates_count - 1] = 0;
7177  } else {
7178  c->bitrates[c->bitrates_count - 1] = ret;
7179  }
7180  }
7181 
7182  av_free(buffer);
7183  } else if (av_uuid_equal(uuid, uuid_xmp)) {
7184  uint8_t *buffer;
7185  size_t len = atom.size - AV_UUID_LEN;
7186  if (c->export_xmp) {
7187  buffer = av_mallocz(len + 1);
7188  if (!buffer) {
7189  return AVERROR(ENOMEM);
7190  }
7191  ret = ffio_read_size(pb, buffer, len);
7192  if (ret < 0) {
7193  av_free(buffer);
7194  return ret;
7195  }
7196  buffer[len] = '\0';
7197  av_dict_set(&c->fc->metadata, "xmp",
7199  } else {
7200  // skip all uuid atom, which makes it fast for long uuid-xmp file
7201  ret = avio_skip(pb, len);
7202  if (ret < 0)
7203  return ret;
7204  }
7205  } else if (av_uuid_equal(uuid, uuid_spherical)) {
7206  size_t len = atom.size - AV_UUID_LEN;
7207  ret = mov_parse_uuid_spherical(sc, pb, len);
7208  if (ret < 0)
7209  return ret;
7210  if (!sc->spherical)
7211  av_log(c->fc, AV_LOG_WARNING, "Invalid spherical metadata found\n");
7212  }
7213 
7214  return 0;
7215 }
7216 
7218 {
7219  int ret;
7220  uint8_t content[16];
7221 
7222  if (atom.size < 8)
7223  return 0;
7224 
7225  ret = ffio_read_size(pb, content, FFMIN(sizeof(content), atom.size));
7226  if (ret < 0)
7227  return ret;
7228 
7229  if ( !c->found_moov
7230  && !c->found_mdat
7231  && !memcmp(content, "Anevia\x1A\x1A", 8)
7232  && c->use_mfra_for == FF_MOV_FLAG_MFRA_AUTO) {
7233  c->use_mfra_for = FF_MOV_FLAG_MFRA_PTS;
7234  }
7235 
7236  return 0;
7237 }
7238 
7240 {
7241  uint32_t format = avio_rl32(pb);
7242  MOVStreamContext *sc;
7243  enum AVCodecID id;
7244  AVStream *st;
7245 
7246  if (c->fc->nb_streams < 1)
7247  return 0;
7248  st = c->fc->streams[c->fc->nb_streams - 1];
7249  sc = st->priv_data;
7250 
7251  switch (sc->format)
7252  {
7253  case MKTAG('e','n','c','v'): // encrypted video
7254  case MKTAG('e','n','c','a'): // encrypted audio
7255  id = mov_codec_id(st, format);
7256  if (st->codecpar->codec_id != AV_CODEC_ID_NONE &&
7257  st->codecpar->codec_id != id) {
7258  av_log(c->fc, AV_LOG_WARNING,
7259  "ignoring 'frma' atom of '%.4s', stream has codec id %d\n",
7260  (char*)&format, st->codecpar->codec_id);
7261  break;
7262  }
7263 
7264  st->codecpar->codec_id = id;
7265  sc->format = format;
7266  break;
7267 
7268  default:
7269  if (format != sc->format) {
7270  av_log(c->fc, AV_LOG_WARNING,
7271  "ignoring 'frma' atom of '%.4s', stream format is '%.4s'\n",
7272  (char*)&format, (char*)&sc->format);
7273  }
7274  break;
7275  }
7276 
7277  return 0;
7278 }
7279 
7280 /**
7281  * Gets the current encryption info and associated current stream context. If
7282  * we are parsing a track fragment, this will return the specific encryption
7283  * info for this fragment; otherwise this will return the global encryption
7284  * info for the current stream.
7285  */
7287 {
7288  MOVFragmentStreamInfo *frag_stream_info;
7289  AVStream *st;
7290  int i;
7291 
7292  frag_stream_info = get_current_frag_stream_info(&c->frag_index);
7293  if (frag_stream_info) {
7294  for (i = 0; i < c->fc->nb_streams; i++) {
7295  *sc = c->fc->streams[i]->priv_data;
7296  if ((*sc)->id == frag_stream_info->id) {
7297  st = c->fc->streams[i];
7298  break;
7299  }
7300  }
7301  if (i == c->fc->nb_streams)
7302  return 0;
7303  *sc = st->priv_data;
7304 
7305  if (!frag_stream_info->encryption_index) {
7306  // If this stream isn't encrypted, don't create the index.
7307  if (!(*sc)->cenc.default_encrypted_sample)
7308  return 0;
7309  frag_stream_info->encryption_index = av_mallocz(sizeof(*frag_stream_info->encryption_index));
7310  if (!frag_stream_info->encryption_index)
7311  return AVERROR(ENOMEM);
7312  }
7313  *encryption_index = frag_stream_info->encryption_index;
7314  return 1;
7315  } else {
7316  // No current track fragment, using stream level encryption info.
7317 
7318  if (c->fc->nb_streams < 1)
7319  return 0;
7320  st = c->fc->streams[c->fc->nb_streams - 1];
7321  *sc = st->priv_data;
7322 
7323  if (!(*sc)->cenc.encryption_index) {
7324  // If this stream isn't encrypted, don't create the index.
7325  if (!(*sc)->cenc.default_encrypted_sample)
7326  return 0;
7327  (*sc)->cenc.encryption_index = av_mallocz(sizeof(*frag_stream_info->encryption_index));
7328  if (!(*sc)->cenc.encryption_index)
7329  return AVERROR(ENOMEM);
7330  }
7331 
7332  *encryption_index = (*sc)->cenc.encryption_index;
7333  return 1;
7334  }
7335 }
7336 
7338 {
7339  int i, ret;
7340  unsigned int subsample_count;
7341  AVSubsampleEncryptionInfo *subsamples;
7342 
7343  if (!sc->cenc.default_encrypted_sample) {
7344  av_log(c->fc, AV_LOG_ERROR, "Missing schm or tenc\n");
7345  return AVERROR_INVALIDDATA;
7346  }
7347 
7348  if (sc->cenc.per_sample_iv_size || use_subsamples) {
7350  if (!*sample)
7351  return AVERROR(ENOMEM);
7352  } else
7353  *sample = NULL;
7354 
7355  if (sc->cenc.per_sample_iv_size != 0) {
7356  if ((ret = ffio_read_size(pb, (*sample)->iv, sc->cenc.per_sample_iv_size)) < 0) {
7357  av_log(c->fc, AV_LOG_ERROR, "failed to read the initialization vector\n");
7359  *sample = NULL;
7360  return ret;
7361  }
7362  }
7363 
7364  if (use_subsamples) {
7365  subsample_count = avio_rb16(pb);
7366  av_free((*sample)->subsamples);
7367  (*sample)->subsamples = av_calloc(subsample_count, sizeof(*subsamples));
7368  if (!(*sample)->subsamples) {
7370  *sample = NULL;
7371  return AVERROR(ENOMEM);
7372  }
7373 
7374  for (i = 0; i < subsample_count && !pb->eof_reached; i++) {
7375  (*sample)->subsamples[i].bytes_of_clear_data = avio_rb16(pb);
7376  (*sample)->subsamples[i].bytes_of_protected_data = avio_rb32(pb);
7377  }
7378 
7379  if (pb->eof_reached) {
7380  av_log(c->fc, AV_LOG_ERROR, "hit EOF while reading sub-sample encryption info\n");
7382  *sample = NULL;
7383  return AVERROR_INVALIDDATA;
7384  }
7385  (*sample)->subsample_count = subsample_count;
7386  }
7387 
7388  return 0;
7389 }
7390 
7392 {
7393  AVEncryptionInfo **encrypted_samples;
7394  MOVEncryptionIndex *encryption_index;
7395  MOVStreamContext *sc;
7396  int use_subsamples, ret;
7397  unsigned int sample_count, i, alloc_size = 0;
7398 
7399  ret = get_current_encryption_info(c, &encryption_index, &sc);
7400  if (ret != 1)
7401  return ret;
7402 
7403  if (encryption_index->nb_encrypted_samples) {
7404  // This can happen if we have both saio/saiz and senc atoms.
7405  av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in senc\n");
7406  return 0;
7407  }
7408 
7409  avio_r8(pb); /* version */
7410  use_subsamples = avio_rb24(pb) & 0x02; /* flags */
7411 
7412  sample_count = avio_rb32(pb);
7413  if (sample_count >= INT_MAX / sizeof(*encrypted_samples))
7414  return AVERROR(ENOMEM);
7415 
7416  for (i = 0; i < sample_count; i++) {
7417  unsigned int min_samples = FFMIN(FFMAX(i + 1, 1024 * 1024), sample_count);
7418  encrypted_samples = av_fast_realloc(encryption_index->encrypted_samples, &alloc_size,
7419  min_samples * sizeof(*encrypted_samples));
7420  if (encrypted_samples) {
7421  encryption_index->encrypted_samples = encrypted_samples;
7422 
7424  c, pb, sc, &encryption_index->encrypted_samples[i], use_subsamples);
7425  } else {
7426  ret = AVERROR(ENOMEM);
7427  }
7428  if (pb->eof_reached) {
7429  av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading senc\n");
7430  if (ret >= 0)
7431  av_encryption_info_free(encryption_index->encrypted_samples[i]);
7433  }
7434 
7435  if (ret < 0) {
7436  for (; i > 0; i--)
7437  av_encryption_info_free(encryption_index->encrypted_samples[i - 1]);
7438  av_freep(&encryption_index->encrypted_samples);
7439  return ret;
7440  }
7441  }
7442  encryption_index->nb_encrypted_samples = sample_count;
7443 
7444  return 0;
7445 }
7446 
7448 {
7449  AVEncryptionInfo **sample, **encrypted_samples;
7450  int64_t prev_pos;
7451  size_t sample_count, sample_info_size, i;
7452  int ret = 0;
7453  unsigned int alloc_size = 0;
7454 
7455  if (encryption_index->nb_encrypted_samples)
7456  return 0;
7457  sample_count = encryption_index->auxiliary_info_sample_count;
7458  if (encryption_index->auxiliary_offsets_count != 1) {
7459  av_log(c->fc, AV_LOG_ERROR, "Multiple auxiliary info chunks are not supported\n");
7460  return AVERROR_PATCHWELCOME;
7461  }
7462  if (sample_count >= INT_MAX / sizeof(*encrypted_samples))
7463  return AVERROR(ENOMEM);
7464 
7465  prev_pos = avio_tell(pb);
7466  if (!(pb->seekable & AVIO_SEEKABLE_NORMAL) ||
7467  avio_seek(pb, encryption_index->auxiliary_offsets[0], SEEK_SET) != encryption_index->auxiliary_offsets[0]) {
7468  av_log(c->fc, AV_LOG_INFO, "Failed to seek for auxiliary info, will only parse senc atoms for encryption info\n");
7469  goto finish;
7470  }
7471 
7472  for (i = 0; i < sample_count && !pb->eof_reached; i++) {
7473  unsigned int min_samples = FFMIN(FFMAX(i + 1, 1024 * 1024), sample_count);
7474  encrypted_samples = av_fast_realloc(encryption_index->encrypted_samples, &alloc_size,
7475  min_samples * sizeof(*encrypted_samples));
7476  if (!encrypted_samples) {
7477  ret = AVERROR(ENOMEM);
7478  goto finish;
7479  }
7480  encryption_index->encrypted_samples = encrypted_samples;
7481 
7482  sample = &encryption_index->encrypted_samples[i];
7483  sample_info_size = encryption_index->auxiliary_info_default_size
7484  ? encryption_index->auxiliary_info_default_size
7485  : encryption_index->auxiliary_info_sizes[i];
7486 
7487  ret = mov_read_sample_encryption_info(c, pb, sc, sample, sample_info_size > sc->cenc.per_sample_iv_size);
7488  if (ret < 0)
7489  goto finish;
7490  }
7491  if (pb->eof_reached) {
7492  av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading auxiliary info\n");
7494  } else {
7495  encryption_index->nb_encrypted_samples = sample_count;
7496  }
7497 
7498 finish:
7499  avio_seek(pb, prev_pos, SEEK_SET);
7500  if (ret < 0) {
7501  for (; i > 0; i--) {
7502  av_encryption_info_free(encryption_index->encrypted_samples[i - 1]);
7503  }
7504  av_freep(&encryption_index->encrypted_samples);
7505  }
7506  return ret;
7507 }
7508 
7510 {
7511  MOVEncryptionIndex *encryption_index;
7512  MOVStreamContext *sc;
7513  int ret;
7514  unsigned int sample_count, aux_info_type, aux_info_param;
7515 
7516  ret = get_current_encryption_info(c, &encryption_index, &sc);
7517  if (ret != 1)
7518  return ret;
7519 
7520  if (encryption_index->nb_encrypted_samples) {
7521  // This can happen if we have both saio/saiz and senc atoms.
7522  av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in saiz\n");
7523  return 0;
7524  }
7525 
7526  if (encryption_index->auxiliary_info_sample_count) {
7527  av_log(c->fc, AV_LOG_ERROR, "Duplicate saiz atom\n");
7528  return AVERROR_INVALIDDATA;
7529  }
7530 
7531  avio_r8(pb); /* version */
7532  if (avio_rb24(pb) & 0x01) { /* flags */
7533  aux_info_type = avio_rb32(pb);
7534  aux_info_param = avio_rb32(pb);
7535  if (sc->cenc.default_encrypted_sample) {
7536  if (aux_info_type != sc->cenc.default_encrypted_sample->scheme) {
7537  av_log(c->fc, AV_LOG_DEBUG, "Ignoring saiz box with non-zero aux_info_type\n");
7538  return 0;
7539  }
7540  if (aux_info_param != 0) {
7541  av_log(c->fc, AV_LOG_DEBUG, "Ignoring saiz box with non-zero aux_info_type_parameter\n");
7542  return 0;
7543  }
7544  } else {
7545  // Didn't see 'schm' or 'tenc', so this isn't encrypted.
7546  if ((aux_info_type == MKBETAG('c','e','n','c') ||
7547  aux_info_type == MKBETAG('c','e','n','s') ||
7548  aux_info_type == MKBETAG('c','b','c','1') ||
7549  aux_info_type == MKBETAG('c','b','c','s')) &&
7550  aux_info_param == 0) {
7551  av_log(c->fc, AV_LOG_ERROR, "Saw encrypted saiz without schm/tenc\n");
7552  return AVERROR_INVALIDDATA;
7553  } else {
7554  return 0;
7555  }
7556  }
7557  } else if (!sc->cenc.default_encrypted_sample) {
7558  // Didn't see 'schm' or 'tenc', so this isn't encrypted.
7559  return 0;
7560  }
7561 
7562  encryption_index->auxiliary_info_default_size = avio_r8(pb);
7563  sample_count = avio_rb32(pb);
7564 
7565  if (encryption_index->auxiliary_info_default_size == 0) {
7566  if (sample_count == 0)
7567  return AVERROR_INVALIDDATA;
7568 
7569  encryption_index->auxiliary_info_sizes = av_malloc(sample_count);
7570  if (!encryption_index->auxiliary_info_sizes)
7571  return AVERROR(ENOMEM);
7572 
7573  ret = avio_read(pb, encryption_index->auxiliary_info_sizes, sample_count);
7574  if (ret != sample_count) {
7575  av_freep(&encryption_index->auxiliary_info_sizes);
7576 
7577  if (ret >= 0)
7579  av_log(c->fc, AV_LOG_ERROR, "Failed to read the auxiliary info, %s\n",
7580  av_err2str(ret));
7581  return ret;
7582  }
7583  }
7584  encryption_index->auxiliary_info_sample_count = sample_count;
7585 
7586  if (encryption_index->auxiliary_offsets_count) {
7587  return mov_parse_auxiliary_info(c, sc, pb, encryption_index);
7588  }
7589 
7590  return 0;
7591 }
7592 
7594 {
7595  uint64_t *auxiliary_offsets;
7596  MOVEncryptionIndex *encryption_index;
7597  MOVStreamContext *sc;
7598  int i, ret;
7599  unsigned int version, entry_count, aux_info_type, aux_info_param;
7600  unsigned int alloc_size = 0;
7601 
7602  ret = get_current_encryption_info(c, &encryption_index, &sc);
7603  if (ret != 1)
7604  return ret;
7605 
7606  if (encryption_index->nb_encrypted_samples) {
7607  // This can happen if we have both saio/saiz and senc atoms.
7608  av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in saio\n");
7609  return 0;
7610  }
7611 
7612  if (encryption_index->auxiliary_offsets_count) {
7613  av_log(c->fc, AV_LOG_ERROR, "Duplicate saio atom\n");
7614  return AVERROR_INVALIDDATA;
7615  }
7616 
7617  version = avio_r8(pb); /* version */
7618  if (avio_rb24(pb) & 0x01) { /* flags */
7619  aux_info_type = avio_rb32(pb);
7620  aux_info_param = avio_rb32(pb);
7621  if (sc->cenc.default_encrypted_sample) {
7622  if (aux_info_type != sc->cenc.default_encrypted_sample->scheme) {
7623  av_log(c->fc, AV_LOG_DEBUG, "Ignoring saio box with non-zero aux_info_type\n");
7624  return 0;
7625  }
7626  if (aux_info_param != 0) {
7627  av_log(c->fc, AV_LOG_DEBUG, "Ignoring saio box with non-zero aux_info_type_parameter\n");
7628  return 0;
7629  }
7630  } else {
7631  // Didn't see 'schm' or 'tenc', so this isn't encrypted.
7632  if ((aux_info_type == MKBETAG('c','e','n','c') ||
7633  aux_info_type == MKBETAG('c','e','n','s') ||
7634  aux_info_type == MKBETAG('c','b','c','1') ||
7635  aux_info_type == MKBETAG('c','b','c','s')) &&
7636  aux_info_param == 0) {
7637  av_log(c->fc, AV_LOG_ERROR, "Saw encrypted saio without schm/tenc\n");
7638  return AVERROR_INVALIDDATA;
7639  } else {
7640  return 0;
7641  }
7642  }
7643  } else if (!sc->cenc.default_encrypted_sample) {
7644  // Didn't see 'schm' or 'tenc', so this isn't encrypted.
7645  return 0;
7646  }
7647 
7648  entry_count = avio_rb32(pb);
7649  if (entry_count >= INT_MAX / sizeof(*auxiliary_offsets))
7650  return AVERROR(ENOMEM);
7651 
7652  for (i = 0; i < entry_count && !pb->eof_reached; i++) {
7653  unsigned int min_offsets = FFMIN(FFMAX(i + 1, 1024), entry_count);
7654  auxiliary_offsets = av_fast_realloc(
7655  encryption_index->auxiliary_offsets, &alloc_size,
7656  min_offsets * sizeof(*auxiliary_offsets));
7657  if (!auxiliary_offsets) {
7658  av_freep(&encryption_index->auxiliary_offsets);
7659  return AVERROR(ENOMEM);
7660  }
7661  encryption_index->auxiliary_offsets = auxiliary_offsets;
7662 
7663  if (version == 0) {
7664  encryption_index->auxiliary_offsets[i] = avio_rb32(pb);
7665  } else {
7666  encryption_index->auxiliary_offsets[i] = avio_rb64(pb);
7667  }
7668  if (c->frag_index.current >= 0) {
7669  encryption_index->auxiliary_offsets[i] += c->fragment.base_data_offset;
7670  }
7671  }
7672 
7673  if (pb->eof_reached) {
7674  av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading saio\n");
7675  av_freep(&encryption_index->auxiliary_offsets);
7676  return AVERROR_INVALIDDATA;
7677  }
7678 
7679  encryption_index->auxiliary_offsets_count = entry_count;
7680 
7681  if (encryption_index->auxiliary_info_sample_count) {
7682  return mov_parse_auxiliary_info(c, sc, pb, encryption_index);
7683  }
7684 
7685  return 0;
7686 }
7687 
7689 {
7690  AVEncryptionInitInfo *info, *old_init_info;
7691  uint8_t **key_ids;
7692  AVStream *st;
7693  const AVPacketSideData *old_side_data;
7694  uint8_t *side_data, *extra_data;
7695  size_t side_data_size;
7696  int ret = 0;
7697  unsigned int version, kid_count, extra_data_size, alloc_size = 0;
7698 
7699  if (c->fc->nb_streams < 1)
7700  return 0;
7701  st = c->fc->streams[c->fc->nb_streams-1];
7702 
7703  version = avio_r8(pb); /* version */
7704  avio_rb24(pb); /* flags */
7705 
7706  info = av_encryption_init_info_alloc(/* system_id_size */ 16, /* num_key_ids */ 0,
7707  /* key_id_size */ 16, /* data_size */ 0);
7708  if (!info)
7709  return AVERROR(ENOMEM);
7710 
7711  if ((ret = ffio_read_size(pb, info->system_id, 16)) < 0) {
7712  av_log(c->fc, AV_LOG_ERROR, "Failed to read the system id\n");
7713  goto finish;
7714  }
7715 
7716  if (version > 0) {
7717  kid_count = avio_rb32(pb);
7718  if (kid_count >= INT_MAX / sizeof(*key_ids)) {
7719  ret = AVERROR(ENOMEM);
7720  goto finish;
7721  }
7722 
7723  for (unsigned int i = 0; i < kid_count && !pb->eof_reached; i++) {
7724  unsigned int min_kid_count = FFMIN(FFMAX(i + 1, 1024), kid_count);
7725  key_ids = av_fast_realloc(info->key_ids, &alloc_size,
7726  min_kid_count * sizeof(*key_ids));
7727  if (!key_ids) {
7728  ret = AVERROR(ENOMEM);
7729  goto finish;
7730  }
7731  info->key_ids = key_ids;
7732 
7733  info->key_ids[i] = av_mallocz(16);
7734  if (!info->key_ids[i]) {
7735  ret = AVERROR(ENOMEM);
7736  goto finish;
7737  }
7738  info->num_key_ids = i + 1;
7739 
7740  if ((ret = ffio_read_size(pb, info->key_ids[i], 16)) < 0) {
7741  av_log(c->fc, AV_LOG_ERROR, "Failed to read the key id\n");
7742  goto finish;
7743  }
7744  }
7745 
7746  if (pb->eof_reached) {
7747  av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading pssh\n");
7749  goto finish;
7750  }
7751  }
7752 
7753  extra_data_size = avio_rb32(pb);
7754  extra_data = av_malloc(extra_data_size);
7755  if (!extra_data) {
7756  ret = AVERROR(ENOMEM);
7757  goto finish;
7758  }
7759  ret = avio_read(pb, extra_data, extra_data_size);
7760  if (ret != extra_data_size) {
7761  av_free(extra_data);
7762 
7763  if (ret >= 0)
7765  goto finish;
7766  }
7767 
7768  av_freep(&info->data); // malloc(0) may still allocate something.
7769  info->data = extra_data;
7770  info->data_size = extra_data_size;
7771 
7772  // If there is existing initialization data, append to the list.
7775  if (old_side_data) {
7776  old_init_info = av_encryption_init_info_get_side_data(old_side_data->data, old_side_data->size);
7777  if (old_init_info) {
7778  // Append to the end of the list.
7779  for (AVEncryptionInitInfo *cur = old_init_info;; cur = cur->next) {
7780  if (!cur->next) {
7781  cur->next = info;
7782  break;
7783  }
7784  }
7785  info = old_init_info;
7786  } else {
7787  // Assume existing side-data will be valid, so the only error we could get is OOM.
7788  ret = AVERROR(ENOMEM);
7789  goto finish;
7790  }
7791  }
7792 
7793  side_data = av_encryption_init_info_add_side_data(info, &side_data_size);
7794  if (!side_data) {
7795  ret = AVERROR(ENOMEM);
7796  goto finish;
7797  }
7801  side_data, side_data_size, 0))
7802  av_free(side_data);
7803 
7804 finish:
7806  return ret;
7807 }
7808 
7810 {
7811  AVStream *st;
7812  MOVStreamContext *sc;
7813 
7814  if (c->fc->nb_streams < 1)
7815  return 0;
7816  st = c->fc->streams[c->fc->nb_streams-1];
7817  sc = st->priv_data;
7818 
7819  if (sc->pseudo_stream_id != 0) {
7820  av_log(c->fc, AV_LOG_ERROR, "schm boxes are only supported in first sample descriptor\n");
7821  return AVERROR_PATCHWELCOME;
7822  }
7823 
7824  if (atom.size < 8)
7825  return AVERROR_INVALIDDATA;
7826 
7827  avio_rb32(pb); /* version and flags */
7828 
7829  if (!sc->cenc.default_encrypted_sample) {
7831  if (!sc->cenc.default_encrypted_sample) {
7832  return AVERROR(ENOMEM);
7833  }
7834  }
7835 
7837  return 0;
7838 }
7839 
7841 {
7842  AVStream *st;
7843  MOVStreamContext *sc;
7844  unsigned int version, pattern, is_protected, iv_size;
7845 
7846  if (c->fc->nb_streams < 1)
7847  return 0;
7848  st = c->fc->streams[c->fc->nb_streams-1];
7849  sc = st->priv_data;
7850 
7851  if (sc->pseudo_stream_id != 0) {
7852  av_log(c->fc, AV_LOG_ERROR, "tenc atom are only supported in first sample descriptor\n");
7853  return AVERROR_PATCHWELCOME;
7854  }
7855 
7856  if (!sc->cenc.default_encrypted_sample) {
7858  if (!sc->cenc.default_encrypted_sample) {
7859  return AVERROR(ENOMEM);
7860  }
7861  }
7862 
7863  if (atom.size < 20)
7864  return AVERROR_INVALIDDATA;
7865 
7866  version = avio_r8(pb); /* version */
7867  avio_rb24(pb); /* flags */
7868 
7869  avio_r8(pb); /* reserved */
7870  pattern = avio_r8(pb);
7871 
7872  if (version > 0) {
7873  sc->cenc.default_encrypted_sample->crypt_byte_block = pattern >> 4;
7874  sc->cenc.default_encrypted_sample->skip_byte_block = pattern & 0xf;
7875  }
7876 
7877  is_protected = avio_r8(pb);
7878  if (is_protected && !sc->cenc.encryption_index) {
7879  // The whole stream should be by-default encrypted.
7881  if (!sc->cenc.encryption_index)
7882  return AVERROR(ENOMEM);
7883  }
7884  sc->cenc.per_sample_iv_size = avio_r8(pb);
7885  if (sc->cenc.per_sample_iv_size != 0 && sc->cenc.per_sample_iv_size != 8 &&
7886  sc->cenc.per_sample_iv_size != 16) {
7887  av_log(c->fc, AV_LOG_ERROR, "invalid per-sample IV size value\n");
7888  return AVERROR_INVALIDDATA;
7889  }
7890  if (avio_read(pb, sc->cenc.default_encrypted_sample->key_id, 16) != 16) {
7891  av_log(c->fc, AV_LOG_ERROR, "failed to read the default key ID\n");
7892  return AVERROR_INVALIDDATA;
7893  }
7894 
7895  if (is_protected && !sc->cenc.per_sample_iv_size) {
7896  iv_size = avio_r8(pb);
7897  if (iv_size != 8 && iv_size != 16) {
7898  av_log(c->fc, AV_LOG_ERROR, "invalid default_constant_IV_size in tenc atom\n");
7899  return AVERROR_INVALIDDATA;
7900  }
7901 
7902  if (avio_read(pb, sc->cenc.default_encrypted_sample->iv, iv_size) != iv_size) {
7903  av_log(c->fc, AV_LOG_ERROR, "failed to read the default IV\n");
7904  return AVERROR_INVALIDDATA;
7905  }
7906  }
7907 
7908  return 0;
7909 }
7910 
7912 {
7913  AVStream *st;
7914  int last, type, size, ret;
7915  uint8_t buf[4];
7916 
7917  if (c->fc->nb_streams < 1)
7918  return 0;
7919  st = c->fc->streams[c->fc->nb_streams-1];
7920 
7921  if ((uint64_t)atom.size > (1<<30) || atom.size < 42)
7922  return AVERROR_INVALIDDATA;
7923 
7924  /* Check FlacSpecificBox version. */
7925  if (avio_r8(pb) != 0)
7926  return AVERROR_INVALIDDATA;
7927 
7928  avio_rb24(pb); /* Flags */
7929 
7930  if (avio_read(pb, buf, sizeof(buf)) != sizeof(buf)) {
7931  av_log(c->fc, AV_LOG_ERROR, "failed to read FLAC metadata block header\n");
7932  return pb->error < 0 ? pb->error : AVERROR_INVALIDDATA;
7933  }
7934  flac_parse_block_header(buf, &last, &type, &size);
7935 
7937  av_log(c->fc, AV_LOG_ERROR, "STREAMINFO must be first FLACMetadataBlock\n");
7938  return AVERROR_INVALIDDATA;
7939  }
7940 
7941  ret = ff_get_extradata(c->fc, st->codecpar, pb, size);
7942  if (ret < 0)
7943  return ret;
7944 
7945  if (!last)
7946  av_log(c->fc, AV_LOG_WARNING, "non-STREAMINFO FLACMetadataBlock(s) ignored\n");
7947 
7948  return 0;
7949 }
7950 
7952 {
7953  int i, ret;
7954  int bytes_of_protected_data;
7955 
7956  if (!sc->cenc.aes_ctr) {
7957  /* initialize the cipher */
7958  sc->cenc.aes_ctr = av_aes_ctr_alloc();
7959  if (!sc->cenc.aes_ctr) {
7960  return AVERROR(ENOMEM);
7961  }
7962 
7963  ret = av_aes_ctr_init(sc->cenc.aes_ctr, c->decryption_key);
7964  if (ret < 0) {
7965  return ret;
7966  }
7967  }
7968 
7970 
7971  if (!sample->subsample_count) {
7972  /* decrypt the whole packet */
7974  return 0;
7975  }
7976 
7977  for (i = 0; i < sample->subsample_count; i++) {
7978  if (sample->subsamples[i].bytes_of_clear_data + sample->subsamples[i].bytes_of_protected_data > size) {
7979  av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n");
7980  return AVERROR_INVALIDDATA;
7981  }
7982 
7983  /* skip the clear bytes */
7984  input += sample->subsamples[i].bytes_of_clear_data;
7985  size -= sample->subsamples[i].bytes_of_clear_data;
7986 
7987  /* decrypt the encrypted bytes */
7988 
7989  bytes_of_protected_data = sample->subsamples[i].bytes_of_protected_data;
7990  av_aes_ctr_crypt(sc->cenc.aes_ctr, input, input, bytes_of_protected_data);
7991 
7992  input += bytes_of_protected_data;
7993  size -= bytes_of_protected_data;
7994  }
7995 
7996  if (size > 0) {
7997  av_log(c->fc, AV_LOG_ERROR, "leftover packet bytes after subsample processing\n");
7998  return AVERROR_INVALIDDATA;
7999  }
8000 
8001  return 0;
8002 }
8003 
8005 {
8006  int i, ret;
8007  int num_of_encrypted_blocks;
8008  uint8_t iv[16];
8009 
8010  if (!sc->cenc.aes_ctx) {
8011  /* initialize the cipher */
8012  sc->cenc.aes_ctx = av_aes_alloc();
8013  if (!sc->cenc.aes_ctx) {
8014  return AVERROR(ENOMEM);
8015  }
8016 
8017  ret = av_aes_init(sc->cenc.aes_ctx, c->decryption_key, 16 * 8, 1);
8018  if (ret < 0) {
8019  return ret;
8020  }
8021  }
8022 
8023  memcpy(iv, sample->iv, 16);
8024 
8025  /* whole-block full sample encryption */
8026  if (!sample->subsample_count) {
8027  /* decrypt the whole packet */
8028  av_aes_crypt(sc->cenc.aes_ctx, input, input, size/16, iv, 1);
8029  return 0;
8030  }
8031 
8032  for (i = 0; i < sample->subsample_count; i++) {
8033  if (sample->subsamples[i].bytes_of_clear_data + sample->subsamples[i].bytes_of_protected_data > size) {
8034  av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n");
8035  return AVERROR_INVALIDDATA;
8036  }
8037 
8038  if (sample->subsamples[i].bytes_of_protected_data % 16) {
8039  av_log(c->fc, AV_LOG_ERROR, "subsample BytesOfProtectedData is not a multiple of 16\n");
8040  return AVERROR_INVALIDDATA;
8041  }
8042 
8043  /* skip the clear bytes */
8044  input += sample->subsamples[i].bytes_of_clear_data;
8045  size -= sample->subsamples[i].bytes_of_clear_data;
8046 
8047  /* decrypt the encrypted bytes */
8048  num_of_encrypted_blocks = sample->subsamples[i].bytes_of_protected_data/16;
8049  if (num_of_encrypted_blocks > 0) {
8050  av_aes_crypt(sc->cenc.aes_ctx, input, input, num_of_encrypted_blocks, iv, 1);
8051  }
8052  input += sample->subsamples[i].bytes_of_protected_data;
8053  size -= sample->subsamples[i].bytes_of_protected_data;
8054  }
8055 
8056  if (size > 0) {
8057  av_log(c->fc, AV_LOG_ERROR, "leftover packet bytes after subsample processing\n");
8058  return AVERROR_INVALIDDATA;
8059  }
8060 
8061  return 0;
8062 }
8063 
8065 {
8066  int i, ret, rem_bytes;
8067  uint8_t *data;
8068 
8069  if (!sc->cenc.aes_ctr) {
8070  /* initialize the cipher */
8071  sc->cenc.aes_ctr = av_aes_ctr_alloc();
8072  if (!sc->cenc.aes_ctr) {
8073  return AVERROR(ENOMEM);
8074  }
8075 
8076  ret = av_aes_ctr_init(sc->cenc.aes_ctr, c->decryption_key);
8077  if (ret < 0) {
8078  return ret;
8079  }
8080  }
8081 
8083 
8084  /* whole-block full sample encryption */
8085  if (!sample->subsample_count) {
8086  /* decrypt the whole packet */
8088  return 0;
8089  } else if (!sample->crypt_byte_block && !sample->skip_byte_block) {
8090  av_log(c->fc, AV_LOG_ERROR, "pattern encryption is not present in 'cens' scheme\n");
8091  return AVERROR_INVALIDDATA;
8092  }
8093 
8094  for (i = 0; i < sample->subsample_count; i++) {
8095  if (sample->subsamples[i].bytes_of_clear_data + sample->subsamples[i].bytes_of_protected_data > size) {
8096  av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n");
8097  return AVERROR_INVALIDDATA;
8098  }
8099 
8100  /* skip the clear bytes */
8101  input += sample->subsamples[i].bytes_of_clear_data;
8102  size -= sample->subsamples[i].bytes_of_clear_data;
8103 
8104  /* decrypt the encrypted bytes */
8105  data = input;
8106  rem_bytes = sample->subsamples[i].bytes_of_protected_data;
8107  while (rem_bytes > 0) {
8108  if (rem_bytes < 16*sample->crypt_byte_block) {
8109  break;
8110  }
8111  av_aes_ctr_crypt(sc->cenc.aes_ctr, data, data, 16*sample->crypt_byte_block);
8112  data += 16*sample->crypt_byte_block;
8113  rem_bytes -= 16*sample->crypt_byte_block;
8114  data += FFMIN(16*sample->skip_byte_block, rem_bytes);
8115  rem_bytes -= FFMIN(16*sample->skip_byte_block, rem_bytes);
8116  }
8117  input += sample->subsamples[i].bytes_of_protected_data;
8118  size -= sample->subsamples[i].bytes_of_protected_data;
8119  }
8120 
8121  if (size > 0) {
8122  av_log(c->fc, AV_LOG_ERROR, "leftover packet bytes after subsample processing\n");
8123  return AVERROR_INVALIDDATA;
8124  }
8125 
8126  return 0;
8127 }
8128 
8130 {
8131  int i, ret, rem_bytes;
8132  uint8_t iv[16];
8133  uint8_t *data;
8134 
8135  if (!sc->cenc.aes_ctx) {
8136  /* initialize the cipher */
8137  sc->cenc.aes_ctx = av_aes_alloc();
8138  if (!sc->cenc.aes_ctx) {
8139  return AVERROR(ENOMEM);
8140  }
8141 
8142  ret = av_aes_init(sc->cenc.aes_ctx, c->decryption_key, 16 * 8, 1);
8143  if (ret < 0) {
8144  return ret;
8145  }
8146  }
8147 
8148  /* whole-block full sample encryption */
8149  if (!sample->subsample_count) {
8150  /* decrypt the whole packet */
8151  memcpy(iv, sample->iv, 16);
8152  av_aes_crypt(sc->cenc.aes_ctx, input, input, size/16, iv, 1);
8153  return 0;
8154  } else if (!sample->crypt_byte_block && !sample->skip_byte_block) {
8155  av_log(c->fc, AV_LOG_ERROR, "pattern encryption is not present in 'cbcs' scheme\n");
8156  return AVERROR_INVALIDDATA;
8157  }
8158 
8159  for (i = 0; i < sample->subsample_count; i++) {
8160  if (sample->subsamples[i].bytes_of_clear_data + sample->subsamples[i].bytes_of_protected_data > size) {
8161  av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n");
8162  return AVERROR_INVALIDDATA;
8163  }
8164 
8165  /* skip the clear bytes */
8166  input += sample->subsamples[i].bytes_of_clear_data;
8167  size -= sample->subsamples[i].bytes_of_clear_data;
8168 
8169  /* decrypt the encrypted bytes */
8170  memcpy(iv, sample->iv, 16);
8171  data = input;
8172  rem_bytes = sample->subsamples[i].bytes_of_protected_data;
8173  while (rem_bytes > 0) {
8174  if (rem_bytes < 16*sample->crypt_byte_block) {
8175  break;
8176  }
8177  av_aes_crypt(sc->cenc.aes_ctx, data, data, sample->crypt_byte_block, iv, 1);
8178  data += 16*sample->crypt_byte_block;
8179  rem_bytes -= 16*sample->crypt_byte_block;
8180  data += FFMIN(16*sample->skip_byte_block, rem_bytes);
8181  rem_bytes -= FFMIN(16*sample->skip_byte_block, rem_bytes);
8182  }
8183  input += sample->subsamples[i].bytes_of_protected_data;
8184  size -= sample->subsamples[i].bytes_of_protected_data;
8185  }
8186 
8187  if (size > 0) {
8188  av_log(c->fc, AV_LOG_ERROR, "leftover packet bytes after subsample processing\n");
8189  return AVERROR_INVALIDDATA;
8190  }
8191 
8192  return 0;
8193 }
8194 
8196 {
8197  if (sample->scheme == MKBETAG('c','e','n','c') && !sample->crypt_byte_block && !sample->skip_byte_block) {
8198  return cenc_scheme_decrypt(c, sc, sample, input, size);
8199  } else if (sample->scheme == MKBETAG('c','b','c','1') && !sample->crypt_byte_block && !sample->skip_byte_block) {
8200  return cbc1_scheme_decrypt(c, sc, sample, input, size);
8201  } else if (sample->scheme == MKBETAG('c','e','n','s')) {
8202  return cens_scheme_decrypt(c, sc, sample, input, size);
8203  } else if (sample->scheme == MKBETAG('c','b','c','s')) {
8204  return cbcs_scheme_decrypt(c, sc, sample, input, size);
8205  } else {
8206  av_log(c->fc, AV_LOG_ERROR, "invalid encryption scheme\n");
8207  return AVERROR_INVALIDDATA;
8208  }
8209 }
8210 
8212 {
8213  int current = frag_index->current;
8214 
8215  if (!frag_index->nb_items)
8216  return NULL;
8217 
8218  // Check frag_index->current is the right one for pkt. It can out of sync.
8219  if (current >= 0 && current < frag_index->nb_items) {
8220  if (frag_index->item[current].moof_offset < pkt->pos &&
8221  (current + 1 == frag_index->nb_items ||
8222  frag_index->item[current + 1].moof_offset > pkt->pos))
8223  return get_frag_stream_info(frag_index, current, id);
8224  }
8225 
8226 
8227  for (int i = 0; i < frag_index->nb_items; i++) {
8228  if (frag_index->item[i].moof_offset > pkt->pos)
8229  break;
8230  current = i;
8231  }
8232  frag_index->current = current;
8233  return get_frag_stream_info(frag_index, current, id);
8234 }
8235 
8236 static int cenc_filter(MOVContext *mov, AVStream* st, MOVStreamContext *sc, AVPacket *pkt, int current_index)
8237 {
8238  MOVFragmentStreamInfo *frag_stream_info;
8239  MOVEncryptionIndex *encryption_index;
8240  AVEncryptionInfo *encrypted_sample;
8241  int encrypted_index, ret;
8242 
8243  frag_stream_info = get_frag_stream_info_from_pkt(&mov->frag_index, pkt, sc->id);
8244  encrypted_index = current_index;
8245  encryption_index = NULL;
8246  if (frag_stream_info) {
8247  // Note this only supports encryption info in the first sample descriptor.
8248  if (frag_stream_info->stsd_id == 1) {
8249  if (frag_stream_info->encryption_index) {
8250  encrypted_index = current_index - frag_stream_info->index_base;
8251  encryption_index = frag_stream_info->encryption_index;
8252  } else {
8253  encryption_index = sc->cenc.encryption_index;
8254  }
8255  }
8256  } else {
8257  encryption_index = sc->cenc.encryption_index;
8258  }
8259 
8260  if (encryption_index) {
8261  if (encryption_index->auxiliary_info_sample_count &&
8262  !encryption_index->nb_encrypted_samples) {
8263  av_log(mov->fc, AV_LOG_ERROR, "saiz atom found without saio\n");
8264  return AVERROR_INVALIDDATA;
8265  }
8266  if (encryption_index->auxiliary_offsets_count &&
8267  !encryption_index->nb_encrypted_samples) {
8268  av_log(mov->fc, AV_LOG_ERROR, "saio atom found without saiz\n");
8269  return AVERROR_INVALIDDATA;
8270  }
8271 
8272  encrypted_sample = NULL;
8273  if (!encryption_index->nb_encrypted_samples) {
8274  // Full-sample encryption with default settings.
8275  encrypted_sample = sc->cenc.default_encrypted_sample;
8276  } else if (encrypted_index >= 0 && encrypted_index < encryption_index->nb_encrypted_samples) {
8277  // Per-sample setting override.
8278  encrypted_sample = encryption_index->encrypted_samples[encrypted_index];
8279  if (!encrypted_sample) {
8280  encrypted_sample = sc->cenc.default_encrypted_sample;
8281  }
8282  }
8283 
8284  if (!encrypted_sample) {
8285  av_log(mov->fc, AV_LOG_ERROR, "Incorrect number of samples in encryption info\n");
8286  return AVERROR_INVALIDDATA;
8287  }
8288 
8289  if (mov->decryption_key) {
8290  return cenc_decrypt(mov, sc, encrypted_sample, pkt->data, pkt->size);
8291  } else {
8292  size_t size;
8293  uint8_t *side_data = av_encryption_info_add_side_data(encrypted_sample, &size);
8294  if (!side_data)
8295  return AVERROR(ENOMEM);
8297  if (ret < 0)
8298  av_free(side_data);
8299  return ret;
8300  }
8301  }
8302 
8303  return 0;
8304 }
8305 
8307 {
8308  const int OPUS_SEEK_PREROLL_MS = 80;
8309  int ret;
8310  AVStream *st;
8311  size_t size;
8312  uint16_t pre_skip;
8313 
8314  if (c->fc->nb_streams < 1)
8315  return 0;
8316  st = c->fc->streams[c->fc->nb_streams-1];
8317 
8318  if ((uint64_t)atom.size > (1<<30) || atom.size < 11)
8319  return AVERROR_INVALIDDATA;
8320 
8321  /* Check OpusSpecificBox version. */
8322  if (avio_r8(pb) != 0) {
8323  av_log(c->fc, AV_LOG_ERROR, "unsupported OpusSpecificBox version\n");
8324  return AVERROR_INVALIDDATA;
8325  }
8326 
8327  /* OpusSpecificBox size plus magic for Ogg OpusHead header. */
8328  size = atom.size + 8;
8329 
8330  if ((ret = ff_alloc_extradata(st->codecpar, size)) < 0)
8331  return ret;
8332 
8333  AV_WL32A(st->codecpar->extradata, MKTAG('O','p','u','s'));
8334  AV_WL32A(st->codecpar->extradata + 4, MKTAG('H','e','a','d'));
8335  AV_WB8(st->codecpar->extradata + 8, 1); /* OpusHead version */
8336  avio_read(pb, st->codecpar->extradata + 9, size - 9);
8337 
8338  /* OpusSpecificBox is stored in big-endian, but OpusHead is
8339  little-endian; aside from the preceeding magic and version they're
8340  otherwise currently identical. Data after output gain at offset 16
8341  doesn't need to be bytewapped. */
8342  pre_skip = AV_RB16A(st->codecpar->extradata + 10);
8343  AV_WL16A(st->codecpar->extradata + 10, pre_skip);
8344  AV_WL32A(st->codecpar->extradata + 12, AV_RB32A(st->codecpar->extradata + 12));
8345  AV_WL16A(st->codecpar->extradata + 16, AV_RB16A(st->codecpar->extradata + 16));
8346 
8347  st->codecpar->initial_padding = pre_skip;
8349  (AVRational){1, 1000},
8350  (AVRational){1, 48000});
8351 
8352  return 0;
8353 }
8354 
8356 {
8357  AVStream *st;
8358  unsigned format_info;
8359  int channel_assignment, channel_assignment1, channel_assignment2;
8360  int ratebits;
8361  uint64_t chmask;
8362 
8363  if (c->fc->nb_streams < 1)
8364  return 0;
8365  st = c->fc->streams[c->fc->nb_streams-1];
8366 
8367  if (atom.size < 10)
8368  return AVERROR_INVALIDDATA;
8369 
8370  format_info = avio_rb32(pb);
8371 
8372  ratebits = (format_info >> 28) & 0xF;
8373  channel_assignment1 = (format_info >> 15) & 0x1F;
8374  channel_assignment2 = format_info & 0x1FFF;
8375  if (channel_assignment2)
8376  channel_assignment = channel_assignment2;
8377  else
8378  channel_assignment = channel_assignment1;
8379 
8380  st->codecpar->frame_size = 40 << (ratebits & 0x7);
8381  st->codecpar->sample_rate = mlp_samplerate(ratebits);
8382 
8384  chmask = truehd_layout(channel_assignment);
8386 
8387  return 0;
8388 }
8389 
8391 {
8392  AVStream *st;
8393  uint8_t buf[ISOM_DVCC_DVVC_SIZE];
8394  int ret;
8395  int64_t read_size = atom.size;
8396 
8397  if (c->fc->nb_streams < 1)
8398  return 0;
8399  st = c->fc->streams[c->fc->nb_streams-1];
8400 
8401  // At most 24 bytes
8402  read_size = FFMIN(read_size, ISOM_DVCC_DVVC_SIZE);
8403 
8404  if ((ret = ffio_read_size(pb, buf, read_size)) < 0)
8405  return ret;
8406 
8407  return ff_isom_parse_dvcc_dvvc(c->fc, st, buf, read_size);
8408 }
8409 
8411 {
8412  AVStream *st;
8413  uint8_t *buf;
8414  int ret, old_size, num_arrays;
8415 
8416  if (c->fc->nb_streams < 1)
8417  return 0;
8418  st = c->fc->streams[c->fc->nb_streams-1];
8419 
8420  if (!st->codecpar->extradata_size)
8421  // TODO: handle lhvC when present before hvcC
8422  return 0;
8423 
8424  if (atom.size < 6 || st->codecpar->extradata_size < 23)
8425  return AVERROR_INVALIDDATA;
8426 
8428  if (!buf)
8429  return AVERROR(ENOMEM);
8430  memset(buf + atom.size, 0, AV_INPUT_BUFFER_PADDING_SIZE);
8431 
8432  ret = ffio_read_size(pb, buf, atom.size);
8433  if (ret < 0) {
8434  av_free(buf);
8435  av_log(c->fc, AV_LOG_WARNING, "lhvC atom truncated\n");
8436  return 0;
8437  }
8438 
8439  num_arrays = buf[5];
8440  old_size = st->codecpar->extradata_size;
8441  atom.size -= 8 /* account for mov_realloc_extradata offseting */
8442  + 6 /* lhvC bytes before the arrays*/;
8443 
8444  ret = mov_realloc_extradata(st->codecpar, atom);
8445  if (ret < 0) {
8446  av_free(buf);
8447  return ret;
8448  }
8449 
8450  st->codecpar->extradata[22] += num_arrays;
8451  memcpy(st->codecpar->extradata + old_size, buf + 6, atom.size + 8);
8452 
8454 
8455  av_free(buf);
8456  return 0;
8457 }
8458 
8460 {
8461  AVFormatContext *ctx = c->fc;
8462  AVStream *st = NULL;
8463  AVBPrint scheme_buf, value_buf;
8464  int64_t scheme_str_len = 0, value_str_len = 0;
8465  int version, flags, ret = AVERROR_BUG;
8466  int64_t size = atom.size;
8467 
8468  if (atom.size < 6)
8469  // 4 bytes for version + flags, 2x 1 byte for null
8470  return AVERROR_INVALIDDATA;
8471 
8472  if (c->fc->nb_streams < 1)
8473  return 0;
8474  st = c->fc->streams[c->fc->nb_streams-1];
8475 
8476  version = avio_r8(pb);
8477  flags = avio_rb24(pb);
8478  size -= 4;
8479 
8480  if (version != 0 || flags != 0) {
8482  "Unsupported 'kind' box with version %d, flags: %x",
8483  version, flags);
8484  return AVERROR_INVALIDDATA;
8485  }
8486 
8487  av_bprint_init(&scheme_buf, 0, AV_BPRINT_SIZE_UNLIMITED);
8488  av_bprint_init(&value_buf, 0, AV_BPRINT_SIZE_UNLIMITED);
8489 
8490  if ((scheme_str_len = ff_read_string_to_bprint_overwrite(pb, &scheme_buf,
8491  size)) < 0) {
8492  ret = scheme_str_len;
8493  goto cleanup;
8494  }
8495 
8496  if (scheme_str_len + 1 >= size) {
8497  // we need to have another string, even if nullptr.
8498  // we check with + 1 since we expect that if size was not hit,
8499  // an additional null was read.
8501  goto cleanup;
8502  }
8503 
8504  size -= scheme_str_len + 1;
8505 
8506  if ((value_str_len = ff_read_string_to_bprint_overwrite(pb, &value_buf,
8507  size)) < 0) {
8508  ret = value_str_len;
8509  goto cleanup;
8510  }
8511 
8512  if (value_str_len == size) {
8513  // in case of no trailing null, box is not valid.
8515  goto cleanup;
8516  }
8517 
8519  "%s stream %d KindBox(scheme: %s, value: %s)\n",
8521  st->index,
8522  scheme_buf.str, value_buf.str);
8523 
8524  for (int i = 0; ff_mov_track_kind_table[i].scheme_uri; i++) {
8526  if (!av_strstart(scheme_buf.str, map.scheme_uri, NULL))
8527  continue;
8528 
8529  for (int j = 0; map.value_maps[j].disposition; j++) {
8530  const struct MP4TrackKindValueMapping value_map = map.value_maps[j];
8531  if (!av_strstart(value_buf.str, value_map.value, NULL))
8532  continue;
8533 
8534  st->disposition |= value_map.disposition;
8535  }
8536  }
8537 
8538  ret = 0;
8539 
8540 cleanup:
8541 
8542  av_bprint_finalize(&scheme_buf, NULL);
8543  av_bprint_finalize(&value_buf, NULL);
8544 
8545  return ret;
8546 }
8547 
8549 {
8550  AVStream *st;
8551  AVChannelLayout ch_layout = { 0 };
8552  int ret, i, version, type;
8553  int ambisonic_order, channel_order, normalization, channel_count;
8554  int ambi_channels, non_diegetic_channels;
8555 
8556  if (c->fc->nb_streams < 1)
8557  return 0;
8558 
8559  st = c->fc->streams[c->fc->nb_streams - 1];
8560 
8561  if (atom.size < 16) {
8562  av_log(c->fc, AV_LOG_ERROR, "SA3D audio box too small\n");
8563  return AVERROR_INVALIDDATA;
8564  }
8565 
8566  version = avio_r8(pb);
8567  if (version) {
8568  av_log(c->fc, AV_LOG_WARNING, "Unsupported SA3D box version %d\n", version);
8569  return 0;
8570  }
8571 
8572  type = avio_r8(pb);
8573  if (type & 0x7f) {
8574  av_log(c->fc, AV_LOG_WARNING,
8575  "Unsupported ambisonic type %d\n", type & 0x7f);
8576  return 0;
8577  }
8578  non_diegetic_channels = (type >> 7) * 2; // head_locked_stereo
8579 
8580  ambisonic_order = avio_rb32(pb);
8581 
8582  channel_order = avio_r8(pb);
8583  if (channel_order) {
8584  av_log(c->fc, AV_LOG_WARNING,
8585  "Unsupported channel_order %d\n", channel_order);
8586  return 0;
8587  }
8588 
8589  normalization = avio_r8(pb);
8590  if (normalization) {
8591  av_log(c->fc, AV_LOG_WARNING,
8592  "Unsupported normalization %d\n", normalization);
8593  return 0;
8594  }
8595 
8596  channel_count = avio_rb32(pb);
8597  if (ambisonic_order < 0 || ambisonic_order > 31 ||
8598  channel_count != ((ambisonic_order + 1LL) * (ambisonic_order + 1LL) +
8599  non_diegetic_channels)) {
8600  av_log(c->fc, AV_LOG_ERROR,
8601  "Invalid number of channels (%d / %d)\n",
8602  channel_count, ambisonic_order);
8603  return 0;
8604  }
8605  ambi_channels = channel_count - non_diegetic_channels;
8606 
8607  ret = av_channel_layout_custom_init(&ch_layout, channel_count);
8608  if (ret < 0)
8609  return 0;
8610 
8611  for (i = 0; i < channel_count; i++) {
8612  unsigned channel = avio_rb32(pb);
8613 
8614  if (channel >= channel_count) {
8615  av_log(c->fc, AV_LOG_ERROR, "Invalid channel index (%d / %d)\n",
8616  channel, ambisonic_order);
8617  av_channel_layout_uninit(&ch_layout);
8618  return 0;
8619  }
8620  if (channel >= ambi_channels)
8621  ch_layout.u.map[i].id = channel - ambi_channels;
8622  else
8623  ch_layout.u.map[i].id = AV_CHAN_AMBISONIC_BASE + channel;
8624  }
8625 
8627  if (ret < 0) {
8628  av_channel_layout_uninit(&ch_layout);
8629  return 0;
8630  }
8631 
8633  st->codecpar->ch_layout = ch_layout;
8634 
8635  return 0;
8636 }
8637 
8639 {
8640  AVStream *st;
8641  int version;
8642 
8643  if (c->fc->nb_streams < 1)
8644  return 0;
8645 
8646  st = c->fc->streams[c->fc->nb_streams - 1];
8647 
8648  if (atom.size < 5) {
8649  av_log(c->fc, AV_LOG_ERROR, "Empty SAND audio box\n");
8650  return AVERROR_INVALIDDATA;
8651  }
8652 
8653  version = avio_r8(pb);
8654  if (version) {
8655  av_log(c->fc, AV_LOG_WARNING, "Unsupported SAND box version %d\n", version);
8656  return 0;
8657  }
8658 
8660 
8661  return 0;
8662 }
8663 
8664 static int rb_size(AVIOContext *pb, int64_t *value, int size)
8665 {
8666  if (size == 0)
8667  *value = 0;
8668  else if (size == 1)
8669  *value = avio_r8(pb);
8670  else if (size == 2)
8671  *value = avio_rb16(pb);
8672  else if (size == 4)
8673  *value = avio_rb32(pb);
8674  else if (size == 8) {
8675  *value = avio_rb64(pb);
8676  if (*value < 0)
8677  return -1;
8678  } else
8679  return -1;
8680  return size;
8681 }
8682 
8684 {
8685  avio_rb32(pb); // version & flags.
8686  c->primary_item_id = avio_rb16(pb);
8687  av_log(c->fc, AV_LOG_TRACE, "pitm: primary_item_id %d\n", c->primary_item_id);
8688  return atom.size;
8689 }
8690 
8692 {
8693  c->idat_offset = avio_tell(pb);
8694  return 0;
8695 }
8696 
8698 {
8699  HEIFItem **heif_item;
8700  int version, offset_size, length_size, base_offset_size, index_size;
8701  int item_count, extent_count;
8702  int64_t base_offset, extent_offset, extent_length;
8703  uint8_t value;
8704 
8705  if (c->found_iloc) {
8706  av_log(c->fc, AV_LOG_INFO, "Duplicate iloc box found\n");
8707  return 0;
8708  }
8709 
8710  version = avio_r8(pb);
8711  avio_rb24(pb); // flags.
8712 
8713  value = avio_r8(pb);
8714  offset_size = (value >> 4) & 0xF;
8715  length_size = value & 0xF;
8716  value = avio_r8(pb);
8717  base_offset_size = (value >> 4) & 0xF;
8718  index_size = !version ? 0 : (value & 0xF);
8719  if (index_size) {
8720  avpriv_report_missing_feature(c->fc, "iloc: index_size != 0");
8721  return AVERROR_PATCHWELCOME;
8722  }
8723  item_count = (version < 2) ? avio_rb16(pb) : avio_rb32(pb);
8724 
8725  heif_item = av_realloc_array(c->heif_item, FFMAX(item_count, c->nb_heif_item), sizeof(*c->heif_item));
8726  if (!heif_item)
8727  return AVERROR(ENOMEM);
8728  c->heif_item = heif_item;
8729  if (item_count > c->nb_heif_item)
8730  memset(&c->heif_item[c->nb_heif_item], 0,
8731  sizeof(*c->heif_item) * (item_count - c->nb_heif_item));
8732  c->nb_heif_item = FFMAX(c->nb_heif_item, item_count);
8733 
8734  av_log(c->fc, AV_LOG_TRACE, "iloc: item_count %d\n", item_count);
8735  for (int i = 0; i < item_count; i++) {
8736  HEIFItem *item = c->heif_item[i];
8737  int item_id = (version < 2) ? avio_rb16(pb) : avio_rb32(pb);
8738  int offset_type = (version > 0) ? avio_rb16(pb) & 0xf : 0;
8739 
8740  if (avio_feof(pb))
8741  return AVERROR_INVALIDDATA;
8742  if (offset_type > 1) {
8743  avpriv_report_missing_feature(c->fc, "iloc offset type %d", offset_type);
8744  return AVERROR_PATCHWELCOME;
8745  }
8746 
8747  avio_rb16(pb); // data_reference_index.
8748  if (rb_size(pb, &base_offset, base_offset_size) < 0)
8749  return AVERROR_INVALIDDATA;
8750  extent_count = avio_rb16(pb);
8751  if (extent_count > 1) {
8752  // For still AVIF images, we only support one extent item.
8753  avpriv_report_missing_feature(c->fc, "iloc: extent_count > 1");
8754  return AVERROR_PATCHWELCOME;
8755  }
8756 
8757  if (rb_size(pb, &extent_offset, offset_size) < 0 ||
8758  rb_size(pb, &extent_length, length_size) < 0 ||
8759  base_offset > INT64_MAX - extent_offset)
8760  return AVERROR_INVALIDDATA;
8761 
8762  if (!item)
8763  item = c->heif_item[i] = av_mallocz(sizeof(*item));
8764  if (!item)
8765  return AVERROR(ENOMEM);
8766 
8767  item->item_id = item_id;
8768 
8769  if (offset_type == 1)
8770  item->is_idat_relative = 1;
8771  item->extent_length = extent_length;
8772  item->extent_offset = base_offset + extent_offset;
8773  av_log(c->fc, AV_LOG_TRACE, "iloc: item_idx %d, offset_type %d, "
8774  "extent_offset %"PRId64", extent_length %"PRId64"\n",
8775  i, offset_type, item->extent_offset, item->extent_length);
8776  }
8777 
8778  c->found_iloc = 1;
8779  return atom.size;
8780 }
8781 
8782 static int mov_read_infe(MOVContext *c, AVIOContext *pb, MOVAtom atom, int idx)
8783 {
8784  HEIFItem *item;
8785  AVBPrint item_name;
8786  int64_t size = atom.size;
8787  uint32_t item_type;
8788  int item_id;
8789  int version, ret;
8790 
8791  version = avio_r8(pb);
8792  avio_rb24(pb); // flags.
8793  size -= 4;
8794  if (size < 0)
8795  return AVERROR_INVALIDDATA;
8796 
8797  if (version < 2) {
8798  avpriv_report_missing_feature(c->fc, "infe version < 2");
8799  avio_skip(pb, size);
8800  return 1;
8801  }
8802 
8803  item_id = version > 2 ? avio_rb32(pb) : avio_rb16(pb);
8804  avio_rb16(pb); // item_protection_index
8805  item_type = avio_rl32(pb);
8806  size -= 8;
8807  if (size < 1)
8808  return AVERROR_INVALIDDATA;
8809 
8812  if (ret < 0) {
8814  return ret;
8815  }
8816 
8817  av_log(c->fc, AV_LOG_TRACE, "infe: item_id %d, item_type %s, item_name %s\n",
8818  item_id, av_fourcc2str(item_type), item_name.str);
8819 
8820  size -= ret + 1;
8821  if (size > 0)
8822  avio_skip(pb, size);
8823 
8824  item = c->heif_item[idx];
8825  if (!item)
8826  item = c->heif_item[idx] = av_mallocz(sizeof(*item));
8827  if (!item)
8828  return AVERROR(ENOMEM);
8829 
8830  if (ret)
8831  av_bprint_finalize(&item_name, &c->heif_item[idx]->name);
8832  c->heif_item[idx]->item_id = item_id;
8833  c->heif_item[idx]->type = item_type;
8834 
8835  switch (item_type) {
8836  case MKTAG('a','v','0','1'):
8837  case MKTAG('h','v','c','1'):
8838  ret = heif_add_stream(c, c->heif_item[idx]);
8839  if (ret < 0)
8840  return ret;
8841  break;
8842  }
8843 
8844  return 0;
8845 }
8846 
8848 {
8849  HEIFItem **heif_item;
8850  int entry_count;
8851  int version, got_stream = 0, ret, i;
8852 
8853  if (c->found_iinf) {
8854  av_log(c->fc, AV_LOG_WARNING, "Duplicate iinf box found\n");
8855  return 0;
8856  }
8857 
8858  version = avio_r8(pb);
8859  avio_rb24(pb); // flags.
8860  entry_count = version ? avio_rb32(pb) : avio_rb16(pb);
8861 
8862  heif_item = av_realloc_array(c->heif_item, FFMAX(entry_count, c->nb_heif_item), sizeof(*c->heif_item));
8863  if (!heif_item)
8864  return AVERROR(ENOMEM);
8865  c->heif_item = heif_item;
8866  if (entry_count > c->nb_heif_item)
8867  memset(&c->heif_item[c->nb_heif_item], 0,
8868  sizeof(*c->heif_item) * (entry_count - c->nb_heif_item));
8869  c->nb_heif_item = FFMAX(c->nb_heif_item, entry_count);
8870 
8871  for (i = 0; i < entry_count; i++) {
8872  MOVAtom infe;
8873 
8874  infe.size = avio_rb32(pb) - 8;
8875  infe.type = avio_rl32(pb);
8876  if (avio_feof(pb)) {
8878  goto fail;
8879  }
8880  ret = mov_read_infe(c, pb, infe, i);
8881  if (ret < 0)
8882  goto fail;
8883  if (!ret)
8884  got_stream = 1;
8885  }
8886 
8887  c->found_iinf = got_stream;
8888  return 0;
8889 fail:
8890  for (; i >= 0; i--) {
8891  HEIFItem *item = c->heif_item[i];
8892 
8893  if (!item)
8894  continue;
8895 
8896  av_freep(&item->name);
8897  if (!item->st)
8898  continue;
8899 
8900  mov_free_stream_context(c->fc, item->st);
8901  ff_remove_stream(c->fc, item->st);
8902  item->st = NULL;
8903  }
8904  return ret;
8905 }
8906 
8908 {
8909  HEIFItem *item = NULL;
8910  HEIFGrid *grid;
8911  int entries, i;
8912  int from_item_id = version ? avio_rb32(pb) : avio_rb16(pb);
8913 
8914  for (int i = 0; i < c->nb_heif_grid; i++) {
8915  if (c->heif_grid[i].item->item_id == from_item_id) {
8916  av_log(c->fc, AV_LOG_ERROR, "More than one 'dimg' box "
8917  "referencing the same Derived Image item\n");
8918  return AVERROR_INVALIDDATA;
8919  }
8920  }
8921  for (int i = 0; i < c->nb_heif_item; i++) {
8922  if (!c->heif_item[i] || c->heif_item[i]->item_id != from_item_id)
8923  continue;
8924  item = c->heif_item[i];
8925 
8926  switch (item->type) {
8927  case MKTAG('g','r','i','d'):
8928  case MKTAG('i','o','v','l'):
8929  break;
8930  default:
8931  avpriv_report_missing_feature(c->fc, "Derived Image item of type %s",
8932  av_fourcc2str(item->type));
8933  return 0;
8934  }
8935  break;
8936  }
8937  if (!item) {
8938  av_log(c->fc, AV_LOG_ERROR, "Missing grid information\n");
8939  return AVERROR_INVALIDDATA;
8940  }
8941 
8942  grid = av_realloc_array(c->heif_grid, c->nb_heif_grid + 1U,
8943  sizeof(*c->heif_grid));
8944  if (!grid)
8945  return AVERROR(ENOMEM);
8946  c->heif_grid = grid;
8947  grid = &grid[c->nb_heif_grid++];
8948 
8949  entries = avio_rb16(pb);
8950  grid->tile_id_list = av_malloc_array(entries, sizeof(*grid->tile_id_list));
8951  grid->tile_idx_list = av_calloc(entries, sizeof(*grid->tile_idx_list));
8952  grid->tile_item_list = av_calloc(entries, sizeof(*grid->tile_item_list));
8953  if (!grid->tile_id_list || !grid->tile_item_list || !grid->tile_idx_list)
8954  return AVERROR(ENOMEM);
8955  /* 'to' item ids */
8956  for (i = 0; i < entries; i++)
8957  grid->tile_id_list[i] = version ? avio_rb32(pb) : avio_rb16(pb);
8958  grid->nb_tiles = entries;
8959  grid->item = item;
8960 
8961  av_log(c->fc, AV_LOG_TRACE, "dimg: from_item_id %d, entries %d\n",
8962  from_item_id, entries);
8963 
8964  return 0;
8965 }
8966 
8968 {
8969  int entries;
8970  int to_item_id, from_item_id = version ? avio_rb32(pb) : avio_rb16(pb);
8971 
8972  entries = avio_rb16(pb);
8973  if (entries > 1) {
8974  avpriv_request_sample(c->fc, "thmb in iref referencing several items");
8975  return AVERROR_PATCHWELCOME;
8976  }
8977  /* 'to' item ids */
8978  to_item_id = version ? avio_rb32(pb) : avio_rb16(pb);
8979 
8980  if (to_item_id != c->primary_item_id)
8981  return 0;
8982 
8983  c->thmb_item_id = from_item_id;
8984 
8985  av_log(c->fc, AV_LOG_TRACE, "thmb: from_item_id %d, entries %d\n",
8986  from_item_id, entries);
8987 
8988  return 0;
8989 }
8990 
8992 {
8993  int version = avio_r8(pb);
8994  avio_rb24(pb); // flags
8995  atom.size -= 4;
8996 
8997  if (version > 1) {
8998  av_log(c->fc, AV_LOG_WARNING, "Unknown iref box version %d\n", version);
8999  return 0;
9000  }
9001 
9002  while (atom.size) {
9003  uint32_t type, size = avio_rb32(pb);
9004  int64_t next = avio_tell(pb);
9005 
9006  if (size < 14 || next < 0 || next > INT64_MAX - size)
9007  return AVERROR_INVALIDDATA;
9008 
9009  next += size - 4;
9010  type = avio_rl32(pb);
9011  switch (type) {
9012  case MKTAG('d','i','m','g'):
9014  break;
9015  case MKTAG('t','h','m','b'):
9017  break;
9018  default:
9019  av_log(c->fc, AV_LOG_DEBUG, "Unknown iref type %s size %"PRIu32"\n",
9020  av_fourcc2str(type), size);
9021  }
9022 
9023  atom.size -= size;
9024  avio_seek(pb, next, SEEK_SET);
9025  }
9026  return 0;
9027 }
9028 
9030 {
9031  HEIFItem *item;
9032  uint32_t width, height;
9033 
9034  avio_r8(pb); /* version */
9035  avio_rb24(pb); /* flags */
9036  width = avio_rb32(pb);
9037  height = avio_rb32(pb);
9038 
9039  av_log(c->fc, AV_LOG_TRACE, "ispe: item_id %d, width %u, height %u\n",
9040  c->cur_item_id, width, height);
9041 
9042  item = heif_cur_item(c);
9043  if (item) {
9044  item->width = width;
9045  item->height = height;
9046  }
9047 
9048  return 0;
9049 }
9050 
9052 {
9053  HEIFItem *item;
9054  int angle;
9055 
9056  angle = avio_r8(pb) & 0x3;
9057 
9058  av_log(c->fc, AV_LOG_TRACE, "irot: item_id %d, angle %u\n",
9059  c->cur_item_id, angle);
9060 
9061  item = heif_cur_item(c);
9062  if (item) {
9063  // angle * 90 specifies the angle (in anti-clockwise direction)
9064  // in units of degrees.
9065  item->rotation = angle * 90;
9066  }
9067 
9068  return 0;
9069 }
9070 
9072 {
9073  HEIFItem *item;
9074  int axis;
9075 
9076  axis = avio_r8(pb) & 0x1;
9077 
9078  av_log(c->fc, AV_LOG_TRACE, "imir: item_id %d, axis %u\n",
9079  c->cur_item_id, axis);
9080 
9081  item = heif_cur_item(c);
9082  if (item) {
9083  item->hflip = axis;
9084  item->vflip = !axis;
9085  }
9086 
9087  return 0;
9088 }
9089 
9091 {
9092  typedef struct MOVAtoms {
9093  FFIOContext b;
9094  uint32_t type;
9095  int64_t size;
9096  uint8_t *data;
9097  } MOVAtoms;
9098  MOVAtoms *atoms = NULL;
9099  MOVAtom a;
9100  unsigned count;
9101  int nb_atoms = 0;
9102  int version, flags;
9103  int ret;
9104 
9105  a.size = avio_rb32(pb);
9106  a.type = avio_rl32(pb);
9107 
9108  if (a.size < 8 || a.type != MKTAG('i','p','c','o'))
9109  return AVERROR_INVALIDDATA;
9110 
9111  a.size -= 8;
9112  while (a.size >= 8) {
9113  MOVAtoms *ref = av_dynarray2_add((void**)&atoms, &nb_atoms, sizeof(MOVAtoms), NULL);
9114  if (!ref) {
9115  ret = AVERROR(ENOMEM);
9116  goto fail;
9117  }
9118  ref->data = NULL;
9119  ref->size = avio_rb32(pb);
9120  ref->type = avio_rl32(pb);
9121  if (ref->size > a.size || ref->size < 8)
9122  break;
9123  ref->data = av_malloc(ref->size);
9124  if (!ref->data) {
9126  goto fail;
9127  }
9128  av_log(c->fc, AV_LOG_TRACE, "ipco: index %d, box type %s\n", nb_atoms, av_fourcc2str(ref->type));
9129  avio_seek(pb, -8, SEEK_CUR);
9130  if (avio_read(pb, ref->data, ref->size) != ref->size) {
9132  goto fail;
9133  }
9134  ffio_init_read_context(&ref->b, ref->data, ref->size);
9135  a.size -= ref->size;
9136  }
9137 
9138  if (a.size) {
9140  goto fail;
9141  }
9142 
9143  a.size = avio_rb32(pb);
9144  a.type = avio_rl32(pb);
9145 
9146  if (a.size < 8 || a.type != MKTAG('i','p','m','a')) {
9148  goto fail;
9149  }
9150 
9151  version = avio_r8(pb);
9152  flags = avio_rb24(pb);
9153  count = avio_rb32(pb);
9154 
9155  for (int i = 0; i < count; i++) {
9156  int item_id = version ? avio_rb32(pb) : avio_rb16(pb);
9157  int assoc_count = avio_r8(pb);
9158 
9159  if (avio_feof(pb)) {
9161  goto fail;
9162  }
9163 
9164  for (int j = 0; j < assoc_count; j++) {
9165  MOVAtoms *ref;
9166  int index = avio_r8(pb) & 0x7f;
9167  if (flags & 1) {
9168  index <<= 8;
9169  index |= avio_r8(pb);
9170  }
9171  if (index > nb_atoms || index <= 0) {
9173  goto fail;
9174  }
9175  ref = &atoms[--index];
9176 
9177  av_log(c->fc, AV_LOG_TRACE, "ipma: property_index %d, item_id %d, item_type %s\n",
9178  index + 1, item_id, av_fourcc2str(ref->type));
9179 
9180  c->cur_item_id = item_id;
9181 
9182  ret = mov_read_default(c, &ref->b.pub,
9183  (MOVAtom) { .size = ref->size,
9184  .type = MKTAG('i','p','c','o') });
9185  if (ret < 0)
9186  goto fail;
9187  ffio_init_read_context(&ref->b, ref->data, ref->size);
9188  }
9189  }
9190 
9191  ret = 0;
9192 fail:
9193  c->cur_item_id = -1;
9194  for (int i = 0; i < nb_atoms; i++)
9195  av_free(atoms[i].data);
9196  av_free(atoms);
9197 
9198  return ret;
9199 }
9200 
9202 { MKTAG('A','C','L','R'), mov_read_aclr },
9203 { MKTAG('A','P','R','G'), mov_read_avid },
9204 { MKTAG('A','A','L','P'), mov_read_avid },
9205 { MKTAG('A','R','E','S'), mov_read_ares },
9206 { MKTAG('a','v','s','s'), mov_read_avss },
9207 { MKTAG('a','v','1','C'), mov_read_glbl },
9208 { MKTAG('c','h','p','l'), mov_read_chpl },
9209 { MKTAG('c','o','6','4'), mov_read_stco },
9210 { MKTAG('c','o','l','r'), mov_read_colr },
9211 { MKTAG('c','t','t','s'), mov_read_ctts }, /* composition time to sample */
9212 { MKTAG('d','i','n','f'), mov_read_default },
9213 { MKTAG('D','p','x','E'), mov_read_dpxe },
9214 { MKTAG('d','r','e','f'), mov_read_dref },
9215 { MKTAG('e','d','t','s'), mov_read_default },
9216 { MKTAG('e','l','s','t'), mov_read_elst },
9217 { MKTAG('e','n','d','a'), mov_read_enda },
9218 { MKTAG('f','i','e','l'), mov_read_fiel },
9219 { MKTAG('a','d','r','m'), mov_read_adrm },
9220 { MKTAG('f','t','y','p'), mov_read_ftyp },
9221 { MKTAG('g','l','b','l'), mov_read_glbl },
9222 { MKTAG('h','d','l','r'), mov_read_hdlr },
9223 { MKTAG('i','l','s','t'), mov_read_ilst },
9224 { MKTAG('j','p','2','h'), mov_read_jp2h },
9225 { MKTAG('m','d','a','t'), mov_read_mdat },
9226 { MKTAG('m','d','h','d'), mov_read_mdhd },
9227 { MKTAG('m','d','i','a'), mov_read_default },
9228 { MKTAG('m','e','t','a'), mov_read_meta },
9229 { MKTAG('m','i','n','f'), mov_read_default },
9230 { MKTAG('m','o','o','f'), mov_read_moof },
9231 { MKTAG('m','o','o','v'), mov_read_moov },
9232 { MKTAG('m','v','e','x'), mov_read_default },
9233 { MKTAG('m','v','h','d'), mov_read_mvhd },
9234 { MKTAG('S','M','I',' '), mov_read_svq3 },
9235 { MKTAG('a','l','a','c'), mov_read_alac }, /* alac specific atom */
9236 { MKTAG('a','v','c','C'), mov_read_glbl },
9237 { MKTAG('p','a','s','p'), mov_read_pasp },
9238 { MKTAG('c','l','a','p'), mov_read_clap },
9239 { MKTAG('s','b','a','s'), mov_read_sbas },
9240 { MKTAG('s','i','d','x'), mov_read_sidx },
9241 { MKTAG('s','t','b','l'), mov_read_default },
9242 { MKTAG('s','t','c','o'), mov_read_stco },
9243 { MKTAG('s','t','p','s'), mov_read_stps },
9244 { MKTAG('s','t','r','f'), mov_read_strf },
9245 { MKTAG('s','t','s','c'), mov_read_stsc },
9246 { MKTAG('s','t','s','d'), mov_read_stsd }, /* sample description */
9247 { MKTAG('s','t','s','s'), mov_read_stss }, /* sync sample */
9248 { MKTAG('s','t','s','z'), mov_read_stsz }, /* sample size */
9249 { MKTAG('s','t','t','s'), mov_read_stts },
9250 { MKTAG('s','t','z','2'), mov_read_stsz }, /* compact sample size */
9251 { MKTAG('s','d','t','p'), mov_read_sdtp }, /* independent and disposable samples */
9252 { MKTAG('t','k','h','d'), mov_read_tkhd }, /* track header */
9253 { MKTAG('t','f','d','t'), mov_read_tfdt },
9254 { MKTAG('t','f','h','d'), mov_read_tfhd }, /* track fragment header */
9255 { MKTAG('t','r','a','k'), mov_read_trak },
9256 { MKTAG('t','r','a','f'), mov_read_default },
9257 { MKTAG('t','r','e','f'), mov_read_default },
9258 { MKTAG('t','m','c','d'), mov_read_tmcd },
9259 { MKTAG('c','h','a','p'), mov_read_chap },
9260 { MKTAG('t','r','e','x'), mov_read_trex },
9261 { MKTAG('t','r','u','n'), mov_read_trun },
9262 { MKTAG('u','d','t','a'), mov_read_default },
9263 { MKTAG('w','a','v','e'), mov_read_wave },
9264 { MKTAG('e','s','d','s'), mov_read_esds },
9265 { MKTAG('d','a','c','3'), mov_read_dac3 }, /* AC-3 info */
9266 { MKTAG('d','e','c','3'), mov_read_dec3 }, /* EAC-3 info */
9267 { MKTAG('d','d','t','s'), mov_read_ddts }, /* DTS audio descriptor */
9268 { MKTAG('w','i','d','e'), mov_read_wide }, /* place holder */
9269 { MKTAG('w','f','e','x'), mov_read_wfex },
9270 { MKTAG('c','m','o','v'), mov_read_cmov },
9271 { MKTAG('c','h','a','n'), mov_read_chan }, /* channel layout from quicktime */
9272 { MKTAG('c','h','n','l'), mov_read_chnl }, /* channel layout from ISO-14496-12 */
9273 { MKTAG('d','v','c','1'), mov_read_dvc1 },
9274 { MKTAG('s','g','p','d'), mov_read_sgpd },
9275 { MKTAG('s','b','g','p'), mov_read_sbgp },
9276 { MKTAG('h','v','c','C'), mov_read_glbl },
9277 { MKTAG('v','v','c','C'), mov_read_glbl },
9278 { MKTAG('u','u','i','d'), mov_read_uuid },
9279 { MKTAG('C','i','n', 0x8e), mov_read_targa_y216 },
9280 { MKTAG('f','r','e','e'), mov_read_free },
9281 { MKTAG('-','-','-','-'), mov_read_custom },
9282 { MKTAG('s','i','n','f'), mov_read_default },
9283 { MKTAG('f','r','m','a'), mov_read_frma },
9284 { MKTAG('s','e','n','c'), mov_read_senc },
9285 { MKTAG('s','a','i','z'), mov_read_saiz },
9286 { MKTAG('s','a','i','o'), mov_read_saio },
9287 { MKTAG('p','s','s','h'), mov_read_pssh },
9288 { MKTAG('s','c','h','m'), mov_read_schm },
9289 { MKTAG('s','c','h','i'), mov_read_default },
9290 { MKTAG('t','e','n','c'), mov_read_tenc },
9291 { MKTAG('d','f','L','a'), mov_read_dfla },
9292 { MKTAG('s','t','3','d'), mov_read_st3d }, /* stereoscopic 3D video box */
9293 { MKTAG('s','v','3','d'), mov_read_sv3d }, /* spherical video box */
9294 { MKTAG('v','e','x','u'), mov_read_vexu }, /* video extension usage */
9295 { MKTAG('h','f','o','v'), mov_read_hfov },
9296 { MKTAG('d','O','p','s'), mov_read_dops },
9297 { MKTAG('d','m','l','p'), mov_read_dmlp },
9298 { MKTAG('S','m','D','m'), mov_read_smdm },
9299 { MKTAG('C','o','L','L'), mov_read_coll },
9300 { MKTAG('v','p','c','C'), mov_read_vpcc },
9301 { MKTAG('m','d','c','v'), mov_read_mdcv },
9302 { MKTAG('c','l','l','i'), mov_read_clli },
9303 { MKTAG('d','v','c','C'), mov_read_dvcc_dvvc },
9304 { MKTAG('d','v','v','C'), mov_read_dvcc_dvvc },
9305 { MKTAG('d','v','w','C'), mov_read_dvcc_dvvc },
9306 { MKTAG('k','i','n','d'), mov_read_kind },
9307 { MKTAG('S','A','3','D'), mov_read_SA3D }, /* ambisonic audio box */
9308 { MKTAG('S','A','N','D'), mov_read_SAND }, /* non diegetic audio box */
9309 { MKTAG('i','l','o','c'), mov_read_iloc },
9310 { MKTAG('p','c','m','C'), mov_read_pcmc }, /* PCM configuration box */
9311 { MKTAG('p','i','t','m'), mov_read_pitm },
9312 { MKTAG('e','v','c','C'), mov_read_glbl },
9313 { MKTAG('i','d','a','t'), mov_read_idat },
9314 { MKTAG('i','m','i','r'), mov_read_imir },
9315 { MKTAG('i','r','e','f'), mov_read_iref },
9316 { MKTAG('i','s','p','e'), mov_read_ispe },
9317 { MKTAG('i','r','o','t'), mov_read_irot },
9318 { MKTAG('i','p','r','p'), mov_read_iprp },
9319 { MKTAG('i','i','n','f'), mov_read_iinf },
9320 { MKTAG('a','m','v','e'), mov_read_amve }, /* ambient viewing environment box */
9321 { MKTAG('l','h','v','C'), mov_read_lhvc },
9322 { MKTAG('l','v','c','C'), mov_read_glbl },
9323 #if CONFIG_IAMFDEC
9324 { MKTAG('i','a','c','b'), mov_read_iacb },
9325 #endif
9326 { 0, NULL }
9327 };
9328 
9330 {
9331  int64_t total_size = 0;
9332  MOVAtom a;
9333  int i;
9334 
9335  if (c->atom_depth > 10) {
9336  av_log(c->fc, AV_LOG_ERROR, "Atoms too deeply nested\n");
9337  return AVERROR_INVALIDDATA;
9338  }
9339  c->atom_depth ++;
9340 
9341  if (atom.size < 0)
9342  atom.size = INT64_MAX;
9343  while (total_size <= atom.size - 8) {
9344  int (*parse)(MOVContext*, AVIOContext*, MOVAtom) = NULL;
9345  a.size = avio_rb32(pb);
9346  a.type = avio_rl32(pb);
9347  if (avio_feof(pb))
9348  break;
9349  if (((a.type == MKTAG('f','r','e','e') && c->moov_retry) ||
9350  a.type == MKTAG('h','o','o','v')) &&
9351  a.size >= 8 &&
9352  c->fc->strict_std_compliance < FF_COMPLIANCE_STRICT) {
9353  uint32_t type;
9354  avio_skip(pb, 4);
9355  type = avio_rl32(pb);
9356  if (avio_feof(pb))
9357  break;
9358  avio_seek(pb, -8, SEEK_CUR);
9359  if (type == MKTAG('m','v','h','d') ||
9360  type == MKTAG('c','m','o','v')) {
9361  av_log(c->fc, AV_LOG_ERROR, "Detected moov in a free or hoov atom.\n");
9362  a.type = MKTAG('m','o','o','v');
9363  }
9364  }
9365  if (atom.type != MKTAG('r','o','o','t') &&
9366  atom.type != MKTAG('m','o','o','v')) {
9367  if (a.type == MKTAG('t','r','a','k') ||
9368  a.type == MKTAG('m','d','a','t')) {
9369  av_log(c->fc, AV_LOG_ERROR, "Broken file, trak/mdat not at top-level\n");
9370  avio_skip(pb, -8);
9371  c->atom_depth --;
9372  return 0;
9373  }
9374  }
9375  total_size += 8;
9376  if (a.size == 1 && total_size + 8 <= atom.size) { /* 64 bit extended size */
9377  a.size = avio_rb64(pb) - 8;
9378  total_size += 8;
9379  }
9380  av_log(c->fc, AV_LOG_TRACE, "type:'%s' parent:'%s' sz: %"PRId64" %"PRId64" %"PRId64"\n",
9381  av_fourcc2str(a.type), av_fourcc2str(atom.type), a.size, total_size, atom.size);
9382  if (a.size == 0) {
9383  a.size = atom.size - total_size + 8;
9384  }
9385  if (a.size < 0)
9386  break;
9387  a.size -= 8;
9388  if (a.size < 0)
9389  break;
9390  a.size = FFMIN(a.size, atom.size - total_size);
9391 
9392  for (i = 0; mov_default_parse_table[i].type; i++)
9393  if (mov_default_parse_table[i].type == a.type) {
9395  break;
9396  }
9397 
9398  // container is user data
9399  if (!parse && (atom.type == MKTAG('u','d','t','a') ||
9400  atom.type == MKTAG('i','l','s','t')))
9402 
9403  // Supports parsing the QuickTime Metadata Keys.
9404  // https://developer.apple.com/library/mac/documentation/QuickTime/QTFF/Metadata/Metadata.html
9405  if (!parse && c->found_hdlr_mdta &&
9406  atom.type == MKTAG('m','e','t','a') &&
9407  a.type == MKTAG('k','e','y','s') &&
9408  c->meta_keys_count == 0) {
9409  parse = mov_read_keys;
9410  }
9411 
9412  if (!parse) { /* skip leaf atoms data */
9413  avio_skip(pb, a.size);
9414  } else {
9415  int64_t start_pos = avio_tell(pb);
9416  int64_t left;
9417  int err = parse(c, pb, a);
9418  if (err < 0) {
9419  c->atom_depth --;
9420  return err;
9421  }
9422  if (c->found_moov && c->found_mdat && a.size <= INT64_MAX - start_pos &&
9423  ((!(pb->seekable & AVIO_SEEKABLE_NORMAL) || c->fc->flags & AVFMT_FLAG_IGNIDX || c->frag_index.complete) ||
9424  start_pos + a.size == avio_size(pb))) {
9425  if (!(pb->seekable & AVIO_SEEKABLE_NORMAL) || c->fc->flags & AVFMT_FLAG_IGNIDX || c->frag_index.complete)
9426  c->next_root_atom = start_pos + a.size;
9427  c->atom_depth --;
9428  return 0;
9429  }
9430  left = a.size - avio_tell(pb) + start_pos;
9431  if (left > 0) /* skip garbage at atom end */
9432  avio_skip(pb, left);
9433  else if (left < 0) {
9434  av_log(c->fc, AV_LOG_WARNING,
9435  "overread end of atom '%s' by %"PRId64" bytes\n",
9436  av_fourcc2str(a.type), -left);
9437  avio_seek(pb, left, SEEK_CUR);
9438  }
9439  }
9440 
9441  total_size += a.size;
9442  }
9443 
9444  if (total_size < atom.size && atom.size < 0x7ffff)
9445  avio_skip(pb, atom.size - total_size);
9446 
9447  c->atom_depth --;
9448  return 0;
9449 }
9450 
9451 static int mov_probe(const AVProbeData *p)
9452 {
9453  int64_t offset;
9454  uint32_t tag;
9455  int score = 0;
9456  int moov_offset = -1;
9457 
9458  /* check file header */
9459  offset = 0;
9460  for (;;) {
9461  int64_t size;
9462  int minsize = 8;
9463  /* ignore invalid offset */
9464  if ((offset + 8ULL) > (unsigned int)p->buf_size)
9465  break;
9466  size = AV_RB32(p->buf + offset);
9467  if (size == 1 && offset + 16 <= (unsigned int)p->buf_size) {
9468  size = AV_RB64(p->buf+offset + 8);
9469  minsize = 16;
9470  } else if (size == 0) {
9471  size = p->buf_size - offset;
9472  }
9473  if (size < minsize) {
9474  offset += 4;
9475  continue;
9476  }
9477  tag = AV_RL32(p->buf + offset + 4);
9478  switch(tag) {
9479  /* check for obvious tags */
9480  case MKTAG('m','o','o','v'):
9481  moov_offset = offset + 4;
9482  case MKTAG('m','d','a','t'):
9483  case MKTAG('p','n','o','t'): /* detect movs with preview pics like ew.mov and april.mov */
9484  case MKTAG('u','d','t','a'): /* Packet Video PVAuthor adds this and a lot of more junk */
9485  case MKTAG('f','t','y','p'):
9486  if (tag == MKTAG('f','t','y','p') &&
9487  ( AV_RL32(p->buf + offset + 8) == MKTAG('j','p','2',' ')
9488  || AV_RL32(p->buf + offset + 8) == MKTAG('j','p','x',' ')
9489  || AV_RL32(p->buf + offset + 8) == MKTAG('j','x','l',' ')
9490  )) {
9491  score = FFMAX(score, 5);
9492  } else {
9493  score = AVPROBE_SCORE_MAX;
9494  }
9495  break;
9496  /* those are more common words, so rate then a bit less */
9497  case MKTAG('e','d','i','w'): /* xdcam files have reverted first tags */
9498  case MKTAG('w','i','d','e'):
9499  case MKTAG('f','r','e','e'):
9500  case MKTAG('j','u','n','k'):
9501  case MKTAG('p','i','c','t'):
9502  score = FFMAX(score, AVPROBE_SCORE_MAX - 5);
9503  break;
9504  case MKTAG(0x82,0x82,0x7f,0x7d):
9505  score = FFMAX(score, AVPROBE_SCORE_EXTENSION - 5);
9506  break;
9507  case MKTAG('s','k','i','p'):
9508  case MKTAG('u','u','i','d'):
9509  case MKTAG('p','r','f','l'):
9510  /* if we only find those cause probedata is too small at least rate them */
9511  score = FFMAX(score, AVPROBE_SCORE_EXTENSION);
9512  break;
9513  }
9514  if (size > INT64_MAX - offset)
9515  break;
9516  offset += size;
9517  }
9518  if (score > AVPROBE_SCORE_MAX - 50 && moov_offset != -1) {
9519  /* moov atom in the header - we should make sure that this is not a
9520  * MOV-packed MPEG-PS */
9521  offset = moov_offset;
9522 
9523  while (offset < (p->buf_size - 16)) { /* Sufficient space */
9524  /* We found an actual hdlr atom */
9525  if (AV_RL32(p->buf + offset ) == MKTAG('h','d','l','r') &&
9526  AV_RL32(p->buf + offset + 8) == MKTAG('m','h','l','r') &&
9527  AV_RL32(p->buf + offset + 12) == MKTAG('M','P','E','G')) {
9528  av_log(NULL, AV_LOG_WARNING, "Found media data tag MPEG indicating this is a MOV-packed MPEG-PS.\n");
9529  /* We found a media handler reference atom describing an
9530  * MPEG-PS-in-MOV, return a
9531  * low score to force expanding the probe window until
9532  * mpegps_probe finds what it needs */
9533  return 5;
9534  } else {
9535  /* Keep looking */
9536  offset += 2;
9537  }
9538  }
9539  }
9540 
9541  return score;
9542 }
9543 
9544 // must be done after parsing all trak because there's no order requirement
9546 {
9547  MOVContext *mov = s->priv_data;
9548  MOVStreamContext *sc;
9549  int64_t cur_pos;
9550  int i, j;
9551  int chapter_track;
9552 
9553  for (j = 0; j < mov->nb_chapter_tracks; j++) {
9554  AVStream *st = NULL;
9555  FFStream *sti = NULL;
9556  chapter_track = mov->chapter_tracks[j];
9557  for (i = 0; i < s->nb_streams; i++) {
9558  sc = mov->fc->streams[i]->priv_data;
9559  if (sc->id == chapter_track) {
9560  st = s->streams[i];
9561  break;
9562  }
9563  }
9564  if (!st) {
9565  av_log(s, AV_LOG_ERROR, "Referenced QT chapter track not found\n");
9566  continue;
9567  }
9568  sti = ffstream(st);
9569 
9570  sc = st->priv_data;
9571  cur_pos = avio_tell(sc->pb);
9572 
9573  if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
9575  if (!st->attached_pic.data && sti->nb_index_entries) {
9576  // Retrieve the first frame, if possible
9577  AVIndexEntry *sample = &sti->index_entries[0];
9578  if (avio_seek(sc->pb, sample->pos, SEEK_SET) != sample->pos) {
9579  av_log(s, AV_LOG_ERROR, "Failed to retrieve first frame\n");
9580  goto finish;
9581  }
9582 
9583  if (ff_add_attached_pic(s, st, sc->pb, NULL, sample->size) < 0)
9584  goto finish;
9585  }
9586  } else {
9589  st->discard = AVDISCARD_ALL;
9590  for (int i = 0; i < sti->nb_index_entries; i++) {
9591  AVIndexEntry *sample = &sti->index_entries[i];
9592  int64_t end = i+1 < sti->nb_index_entries ? sti->index_entries[i+1].timestamp : st->duration;
9593  uint8_t *title;
9594  uint16_t ch;
9595  int len, title_len;
9596 
9597  if (end < sample->timestamp) {
9598  av_log(s, AV_LOG_WARNING, "ignoring stream duration which is shorter than chapters\n");
9599  end = AV_NOPTS_VALUE;
9600  }
9601 
9602  if (avio_seek(sc->pb, sample->pos, SEEK_SET) != sample->pos) {
9603  av_log(s, AV_LOG_ERROR, "Chapter %d not found in file\n", i);
9604  goto finish;
9605  }
9606 
9607  // the first two bytes are the length of the title
9608  len = avio_rb16(sc->pb);
9609  if (len > sample->size-2)
9610  continue;
9611  title_len = 2*len + 1;
9612  if (!(title = av_mallocz(title_len)))
9613  goto finish;
9614 
9615  // The samples could theoretically be in any encoding if there's an encd
9616  // atom following, but in practice are only utf-8 or utf-16, distinguished
9617  // instead by the presence of a BOM
9618  if (!len) {
9619  title[0] = 0;
9620  } else {
9621  ch = avio_rb16(sc->pb);
9622  if (ch == 0xfeff)
9623  avio_get_str16be(sc->pb, len, title, title_len);
9624  else if (ch == 0xfffe)
9625  avio_get_str16le(sc->pb, len, title, title_len);
9626  else {
9627  AV_WB16(title, ch);
9628  if (len == 1 || len == 2)
9629  title[len] = 0;
9630  else
9631  avio_get_str(sc->pb, INT_MAX, title + 2, len - 1);
9632  }
9633  }
9634 
9635  avpriv_new_chapter(s, i, st->time_base, sample->timestamp, end, title);
9636  av_freep(&title);
9637  }
9638  }
9639 finish:
9640  avio_seek(sc->pb, cur_pos, SEEK_SET);
9641  }
9642 }
9643 
9645  int64_t value, int flags)
9646 {
9647  AVTimecode tc;
9648  char buf[AV_TIMECODE_STR_SIZE];
9649  AVRational rate = st->avg_frame_rate;
9650  int ret = av_timecode_init(&tc, rate, flags, 0, s);
9651  if (ret < 0)
9652  return ret;
9653  av_dict_set(&st->metadata, "timecode",
9654  av_timecode_make_string(&tc, buf, value), 0);
9655  return 0;
9656 }
9657 
9659 {
9660  MOVStreamContext *sc = st->priv_data;
9661  FFStream *const sti = ffstream(st);
9662  char buf[AV_TIMECODE_STR_SIZE];
9663  int64_t cur_pos = avio_tell(sc->pb);
9664  int hh, mm, ss, ff, drop;
9665 
9666  if (!sti->nb_index_entries)
9667  return -1;
9668 
9669  avio_seek(sc->pb, sti->index_entries->pos, SEEK_SET);
9670  avio_skip(s->pb, 13);
9671  hh = avio_r8(s->pb);
9672  mm = avio_r8(s->pb);
9673  ss = avio_r8(s->pb);
9674  drop = avio_r8(s->pb);
9675  ff = avio_r8(s->pb);
9676  snprintf(buf, AV_TIMECODE_STR_SIZE, "%02d:%02d:%02d%c%02d",
9677  hh, mm, ss, drop ? ';' : ':', ff);
9678  av_dict_set(&st->metadata, "timecode", buf, 0);
9679 
9680  avio_seek(sc->pb, cur_pos, SEEK_SET);
9681  return 0;
9682 }
9683 
9685 {
9686  MOVStreamContext *sc = st->priv_data;
9687  FFStream *const sti = ffstream(st);
9688  int flags = 0;
9689  int64_t cur_pos = avio_tell(sc->pb);
9690  int64_t value;
9691  AVRational tc_rate = st->avg_frame_rate;
9692  int tmcd_nb_frames = sc->tmcd_nb_frames;
9693  int rounded_tc_rate;
9694 
9695  if (!sti->nb_index_entries)
9696  return -1;
9697 
9698  if (!tc_rate.num || !tc_rate.den || !tmcd_nb_frames)
9699  return -1;
9700 
9701  avio_seek(sc->pb, sti->index_entries->pos, SEEK_SET);
9702  value = avio_rb32(s->pb);
9703 
9704  if (sc->tmcd_flags & 0x0001) flags |= AV_TIMECODE_FLAG_DROPFRAME;
9705  if (sc->tmcd_flags & 0x0002) flags |= AV_TIMECODE_FLAG_24HOURSMAX;
9706  if (sc->tmcd_flags & 0x0004) flags |= AV_TIMECODE_FLAG_ALLOWNEGATIVE;
9707 
9708  /* Assume Counter flag is set to 1 in tmcd track (even though it is likely
9709  * not the case) and thus assume "frame number format" instead of QT one.
9710  * No sample with tmcd track can be found with a QT timecode at the moment,
9711  * despite what the tmcd track "suggests" (Counter flag set to 0 means QT
9712  * format). */
9713 
9714  /* 60 fps content have tmcd_nb_frames set to 30 but tc_rate set to 60, so
9715  * we multiply the frame number with the quotient.
9716  * See tickets #9492, #9710. */
9717  rounded_tc_rate = (tc_rate.num + tc_rate.den / 2LL) / tc_rate.den;
9718  /* Work around files where tmcd_nb_frames is rounded down from frame rate
9719  * instead of up. See ticket #5978. */
9720  if (tmcd_nb_frames == tc_rate.num / tc_rate.den &&
9721  s->strict_std_compliance < FF_COMPLIANCE_STRICT)
9722  tmcd_nb_frames = rounded_tc_rate;
9723  value = av_rescale(value, rounded_tc_rate, tmcd_nb_frames);
9724 
9726 
9727  avio_seek(sc->pb, cur_pos, SEEK_SET);
9728  return 0;
9729 }
9730 
9732  int i;
9733  if (!index || !*index) return;
9734  for (i = 0; i < (*index)->nb_encrypted_samples; i++) {
9735  av_encryption_info_free((*index)->encrypted_samples[i]);
9736  }
9737  av_freep(&(*index)->encrypted_samples);
9738  av_freep(&(*index)->auxiliary_info_sizes);
9739  av_freep(&(*index)->auxiliary_offsets);
9740  av_freep(index);
9741 }
9742 
9744 {
9745  MOVStreamContext *sc = st->priv_data;
9746 
9747  if (!sc || --sc->refcount) {
9748  st->priv_data = NULL;
9749  return;
9750  }
9751 
9752  av_freep(&sc->tts_data);
9753  for (int i = 0; i < sc->drefs_count; i++) {
9754  av_freep(&sc->drefs[i].path);
9755  av_freep(&sc->drefs[i].dir);
9756  }
9757  av_freep(&sc->drefs);
9758 
9759  sc->drefs_count = 0;
9760 
9761  if (!sc->pb_is_copied)
9762  ff_format_io_close(s, &sc->pb);
9763 
9764  sc->pb = NULL;
9765  av_freep(&sc->chunk_offsets);
9766  av_freep(&sc->stsc_data);
9767  av_freep(&sc->sample_sizes);
9768  av_freep(&sc->keyframes);
9769  av_freep(&sc->ctts_data);
9770  av_freep(&sc->stts_data);
9771  av_freep(&sc->sdtp_data);
9772  av_freep(&sc->stps_data);
9773  av_freep(&sc->elst_data);
9774  av_freep(&sc->rap_group);
9775  av_freep(&sc->sync_group);
9776  av_freep(&sc->sgpd_sync);
9777  av_freep(&sc->sample_offsets);
9778  av_freep(&sc->open_key_samples);
9779  av_freep(&sc->display_matrix);
9780  av_freep(&sc->index_ranges);
9781 
9782  if (sc->extradata)
9783  for (int i = 0; i < sc->stsd_count; i++)
9784  av_free(sc->extradata[i]);
9785  av_freep(&sc->extradata);
9786  av_freep(&sc->extradata_size);
9787 
9791 
9792  av_freep(&sc->stereo3d);
9793  av_freep(&sc->spherical);
9794  av_freep(&sc->mastering);
9795  av_freep(&sc->coll);
9796  av_freep(&sc->ambient);
9797 
9798 #if CONFIG_IAMFDEC
9799  if (sc->iamf)
9801 #endif
9802  av_freep(&sc->iamf);
9803 }
9804 
9806 {
9807  MOVContext *mov = s->priv_data;
9808  int i, j;
9809 
9810  for (i = 0; i < s->nb_streams; i++) {
9811  AVStream *st = s->streams[i];
9812 
9814  }
9815 
9816  av_freep(&mov->dv_demux);
9818  mov->dv_fctx = NULL;
9819 
9820  if (mov->meta_keys) {
9821  for (i = 1; i < mov->meta_keys_count; i++) {
9822  av_freep(&mov->meta_keys[i]);
9823  }
9824  av_freep(&mov->meta_keys);
9825  }
9826 
9827  av_freep(&mov->trex_data);
9828  av_freep(&mov->bitrates);
9829 
9830  for (i = 0; i < mov->frag_index.nb_items; i++) {
9832  for (j = 0; j < mov->frag_index.item[i].nb_stream_info; j++) {
9833  mov_free_encryption_index(&frag[j].encryption_index);
9834  }
9836  }
9837  av_freep(&mov->frag_index.item);
9838 
9839  av_freep(&mov->aes_decrypt);
9840  av_freep(&mov->chapter_tracks);
9841  for (i = 0; i < mov->nb_heif_item; i++) {
9842  if (!mov->heif_item[i])
9843  continue;
9844  av_freep(&mov->heif_item[i]->name);
9845  av_freep(&mov->heif_item[i]->icc_profile);
9846  av_freep(&mov->heif_item[i]);
9847  }
9848  av_freep(&mov->heif_item);
9849  for (i = 0; i < mov->nb_heif_grid; i++) {
9850  av_freep(&mov->heif_grid[i].tile_id_list);
9853  }
9854  av_freep(&mov->heif_grid);
9855 
9856  return 0;
9857 }
9858 
9859 static int tmcd_is_referenced(AVFormatContext *s, int tmcd_id)
9860 {
9861  int i;
9862 
9863  for (i = 0; i < s->nb_streams; i++) {
9864  AVStream *st = s->streams[i];
9865  MOVStreamContext *sc = st->priv_data;
9866 
9867  if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO &&
9868  sc->timecode_track == tmcd_id)
9869  return 1;
9870  }
9871  return 0;
9872 }
9873 
9874 /* look for a tmcd track not referenced by any video track, and export it globally */
9876 {
9877  int i;
9878 
9879  for (i = 0; i < s->nb_streams; i++) {
9880  AVStream *st = s->streams[i];
9881 
9882  if (st->codecpar->codec_tag == MKTAG('t','m','c','d') &&
9883  !tmcd_is_referenced(s, i + 1)) {
9884  AVDictionaryEntry *tcr = av_dict_get(st->metadata, "timecode", NULL, 0);
9885  if (tcr) {
9886  av_dict_set(&s->metadata, "timecode", tcr->value, 0);
9887  break;
9888  }
9889  }
9890  }
9891 }
9892 
9893 static int read_tfra(MOVContext *mov, AVIOContext *f)
9894 {
9895  int version, fieldlength, i, j;
9896  int64_t pos = avio_tell(f);
9897  uint32_t size = avio_rb32(f);
9898  unsigned track_id, item_count;
9899 
9900  if (avio_rb32(f) != MKBETAG('t', 'f', 'r', 'a')) {
9901  return 1;
9902  }
9903  av_log(mov->fc, AV_LOG_VERBOSE, "found tfra\n");
9904 
9905  version = avio_r8(f);
9906  avio_rb24(f);
9907  track_id = avio_rb32(f);
9908  fieldlength = avio_rb32(f);
9909  item_count = avio_rb32(f);
9910  for (i = 0; i < item_count; i++) {
9911  int64_t time, offset;
9912  int index;
9913  MOVFragmentStreamInfo * frag_stream_info;
9914 
9915  if (avio_feof(f)) {
9916  return AVERROR_INVALIDDATA;
9917  }
9918 
9919  if (version == 1) {
9920  time = avio_rb64(f);
9921  offset = avio_rb64(f);
9922  } else {
9923  time = avio_rb32(f);
9924  offset = avio_rb32(f);
9925  }
9926 
9927  // The first sample of each stream in a fragment is always a random
9928  // access sample. So it's entry in the tfra can be used as the
9929  // initial PTS of the fragment.
9930  index = update_frag_index(mov, offset);
9931  frag_stream_info = get_frag_stream_info(&mov->frag_index, index, track_id);
9932  if (frag_stream_info &&
9933  frag_stream_info->first_tfra_pts == AV_NOPTS_VALUE)
9934  frag_stream_info->first_tfra_pts = time;
9935 
9936  for (j = 0; j < ((fieldlength >> 4) & 3) + 1; j++)
9937  avio_r8(f);
9938  for (j = 0; j < ((fieldlength >> 2) & 3) + 1; j++)
9939  avio_r8(f);
9940  for (j = 0; j < ((fieldlength >> 0) & 3) + 1; j++)
9941  avio_r8(f);
9942  }
9943 
9944  avio_seek(f, pos + size, SEEK_SET);
9945  return 0;
9946 }
9947 
9949 {
9950  int64_t stream_size = avio_size(f);
9951  int64_t original_pos = avio_tell(f);
9952  int64_t seek_ret;
9953  int ret = -1;
9954  if ((seek_ret = avio_seek(f, stream_size - 4, SEEK_SET)) < 0) {
9955  ret = seek_ret;
9956  goto fail;
9957  }
9958  c->mfra_size = avio_rb32(f);
9959  c->have_read_mfra_size = 1;
9960  if (!c->mfra_size || c->mfra_size > stream_size) {
9961  av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (unreasonable size)\n");
9962  goto fail;
9963  }
9964  if ((seek_ret = avio_seek(f, -((int64_t) c->mfra_size), SEEK_CUR)) < 0) {
9965  ret = seek_ret;
9966  goto fail;
9967  }
9968  if (avio_rb32(f) != c->mfra_size) {
9969  av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (size mismatch)\n");
9970  goto fail;
9971  }
9972  if (avio_rb32(f) != MKBETAG('m', 'f', 'r', 'a')) {
9973  av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (tag mismatch)\n");
9974  goto fail;
9975  }
9976  av_log(c->fc, AV_LOG_VERBOSE, "stream has mfra\n");
9977  do {
9978  ret = read_tfra(c, f);
9979  if (ret < 0)
9980  goto fail;
9981  } while (!ret);
9982  ret = 0;
9983  c->frag_index.complete = 1;
9984 fail:
9985  seek_ret = avio_seek(f, original_pos, SEEK_SET);
9986  if (seek_ret < 0) {
9987  av_log(c->fc, AV_LOG_ERROR,
9988  "failed to seek back after looking for mfra\n");
9989  ret = seek_ret;
9990  }
9991  return ret;
9992 }
9993 
9994 static int set_icc_profile_from_item(AVPacketSideData **coded_side_data, int *nb_coded_side_data,
9995  const HEIFItem *item)
9996 {
9997  AVPacketSideData *sd = av_packet_side_data_new(coded_side_data, nb_coded_side_data,
9999  item->icc_profile_size, 0);
10000  if (!sd)
10001  return AVERROR(ENOMEM);
10002 
10003  memcpy(sd->data, item->icc_profile, item->icc_profile_size);
10004 
10005  return 0;
10006 }
10007 
10008 static int set_display_matrix_from_item(AVPacketSideData **coded_side_data, int *nb_coded_side_data,
10009  const HEIFItem *item)
10010 {
10011  int32_t *matrix;
10012  AVPacketSideData *sd = av_packet_side_data_new(coded_side_data,
10013  nb_coded_side_data,
10015  9 * sizeof(*matrix), 0);
10016  if (!sd)
10017  return AVERROR(ENOMEM);
10018 
10019  matrix = (int32_t*)sd->data;
10020  /* rotation is in the counter-clockwise direction whereas
10021  * av_display_rotation_set() expects its argument to be
10022  * oriented clockwise, so we need to negate it. */
10024  av_display_matrix_flip(matrix, item->hflip, item->vflip);
10025 
10026  return 0;
10027 }
10028 
10029 static int read_image_grid(AVFormatContext *s, const HEIFGrid *grid,
10030  AVStreamGroupTileGrid *tile_grid)
10031 {
10032  MOVContext *c = s->priv_data;
10033  const HEIFItem *item = grid->item;
10034  int64_t offset = 0, pos = avio_tell(s->pb);
10035  int x = 0, y = 0, i = 0;
10036  int tile_rows, tile_cols;
10037  int flags, size;
10038 
10039  if (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL)) {
10040  av_log(c->fc, AV_LOG_INFO, "grid box with non seekable input\n");
10041  return AVERROR_PATCHWELCOME;
10042  }
10043  if (item->is_idat_relative) {
10044  if (!c->idat_offset) {
10045  av_log(c->fc, AV_LOG_ERROR, "missing idat box required by the image grid\n");
10046  return AVERROR_INVALIDDATA;
10047  }
10048  offset = c->idat_offset;
10049  }
10050 
10051  avio_seek(s->pb, item->extent_offset + offset, SEEK_SET);
10052 
10053  avio_r8(s->pb); /* version */
10054  flags = avio_r8(s->pb);
10055 
10056  tile_rows = avio_r8(s->pb) + 1;
10057  tile_cols = avio_r8(s->pb) + 1;
10058  /* actual width and height of output image */
10059  tile_grid->width = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
10060  tile_grid->height = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
10061 
10062  /* ICC profile */
10063  if (item->icc_profile_size) {
10064  int ret = set_icc_profile_from_item(&tile_grid->coded_side_data,
10065  &tile_grid->nb_coded_side_data, item);
10066  if (ret < 0)
10067  return ret;
10068  }
10069  /* rotation */
10070  if (item->rotation || item->hflip || item->vflip) {
10072  &tile_grid->nb_coded_side_data, item);
10073  if (ret < 0)
10074  return ret;
10075  }
10076 
10077  av_log(c->fc, AV_LOG_TRACE, "grid: grid_rows %d grid_cols %d output_width %d output_height %d\n",
10078  tile_rows, tile_cols, tile_grid->width, tile_grid->height);
10079 
10080  avio_seek(s->pb, pos, SEEK_SET);
10081 
10082  size = tile_rows * tile_cols;
10083  tile_grid->nb_tiles = grid->nb_tiles;
10084 
10085  if (tile_grid->nb_tiles != size)
10086  return AVERROR_INVALIDDATA;
10087 
10088  for (int i = 0; i < tile_cols; i++)
10089  tile_grid->coded_width += grid->tile_item_list[i]->width;
10090  for (int i = 0; i < size; i += tile_cols)
10091  tile_grid->coded_height += grid->tile_item_list[i]->height;
10092 
10093  tile_grid->offsets = av_calloc(tile_grid->nb_tiles, sizeof(*tile_grid->offsets));
10094  if (!tile_grid->offsets)
10095  return AVERROR(ENOMEM);
10096 
10097  while (y < tile_grid->coded_height) {
10098  int left_col = i;
10099 
10100  while (x < tile_grid->coded_width) {
10101  if (i == tile_grid->nb_tiles)
10102  return AVERROR_INVALIDDATA;
10103 
10104  tile_grid->offsets[i].idx = grid->tile_idx_list[i];
10105  tile_grid->offsets[i].horizontal = x;
10106  tile_grid->offsets[i].vertical = y;
10107 
10108  x += grid->tile_item_list[i++]->width;
10109  }
10110 
10111  if (x > tile_grid->coded_width) {
10112  av_log(c->fc, AV_LOG_ERROR, "Non uniform HEIF tiles\n");
10113  return AVERROR_INVALIDDATA;
10114  }
10115 
10116  x = 0;
10117  y += grid->tile_item_list[left_col]->height;
10118  }
10119 
10120  if (y > tile_grid->coded_height || i != tile_grid->nb_tiles) {
10121  av_log(c->fc, AV_LOG_ERROR, "Non uniform HEIF tiles\n");
10122  return AVERROR_INVALIDDATA;
10123  }
10124 
10125  return 0;
10126 }
10127 
10128 static int read_image_iovl(AVFormatContext *s, const HEIFGrid *grid,
10129  AVStreamGroupTileGrid *tile_grid)
10130 {
10131  MOVContext *c = s->priv_data;
10132  const HEIFItem *item = grid->item;
10133  uint16_t canvas_fill_value[4];
10134  int64_t offset = 0, pos = avio_tell(s->pb);
10135  int ret = 0, flags;
10136 
10137  if (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL)) {
10138  av_log(c->fc, AV_LOG_INFO, "iovl box with non seekable input\n");
10139  return AVERROR_PATCHWELCOME;
10140  }
10141  if (item->is_idat_relative) {
10142  if (!c->idat_offset) {
10143  av_log(c->fc, AV_LOG_ERROR, "missing idat box required by the image overlay\n");
10144  return AVERROR_INVALIDDATA;
10145  }
10146  offset = c->idat_offset;
10147  }
10148 
10149  avio_seek(s->pb, item->extent_offset + offset, SEEK_SET);
10150 
10151  avio_r8(s->pb); /* version */
10152  flags = avio_r8(s->pb);
10153 
10154  for (int i = 0; i < 4; i++)
10155  canvas_fill_value[i] = avio_rb16(s->pb);
10156  av_log(c->fc, AV_LOG_TRACE, "iovl: canvas_fill_value { %u, %u, %u, %u }\n",
10157  canvas_fill_value[0], canvas_fill_value[1],
10158  canvas_fill_value[2], canvas_fill_value[3]);
10159  for (int i = 0; i < 4; i++)
10160  tile_grid->background[i] = canvas_fill_value[i];
10161 
10162  /* actual width and height of output image */
10163  tile_grid->width =
10164  tile_grid->coded_width = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
10165  tile_grid->height =
10166  tile_grid->coded_height = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
10167 
10168  /* rotation */
10169  if (item->rotation || item->hflip || item->vflip) {
10171  &tile_grid->nb_coded_side_data, item);
10172  if (ret < 0)
10173  return ret;
10174  }
10175 
10176  /* ICC profile */
10177  if (item->icc_profile_size) {
10178  int ret = set_icc_profile_from_item(&tile_grid->coded_side_data,
10179  &tile_grid->nb_coded_side_data, item);
10180  if (ret < 0)
10181  return ret;
10182  }
10183 
10184  av_log(c->fc, AV_LOG_TRACE, "iovl: output_width %d, output_height %d\n",
10185  tile_grid->width, tile_grid->height);
10186 
10187  tile_grid->nb_tiles = grid->nb_tiles;
10188  tile_grid->offsets = av_malloc_array(tile_grid->nb_tiles, sizeof(*tile_grid->offsets));
10189  if (!tile_grid->offsets) {
10190  ret = AVERROR(ENOMEM);
10191  goto fail;
10192  }
10193 
10194  for (int i = 0; i < tile_grid->nb_tiles; i++) {
10195  tile_grid->offsets[i].idx = grid->tile_idx_list[i];
10196  tile_grid->offsets[i].horizontal = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
10197  tile_grid->offsets[i].vertical = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
10198  av_log(c->fc, AV_LOG_TRACE, "iovl: stream_idx[%d] %u, "
10199  "horizontal_offset[%d] %d, vertical_offset[%d] %d\n",
10200  i, tile_grid->offsets[i].idx,
10201  i, tile_grid->offsets[i].horizontal, i, tile_grid->offsets[i].vertical);
10202  }
10203 
10204 fail:
10205  avio_seek(s->pb, pos, SEEK_SET);
10206 
10207  return ret;
10208 }
10209 
10211 {
10212  MOVContext *mov = s->priv_data;
10213 
10214  for (int i = 0; i < mov->nb_heif_grid; i++) {
10216  AVStreamGroupTileGrid *tile_grid;
10217  const HEIFGrid *grid = &mov->heif_grid[i];
10218  int err, loop = 1;
10219 
10220  if (!stg)
10221  return AVERROR(ENOMEM);
10222 
10223  stg->id = grid->item->item_id;
10224  tile_grid = stg->params.tile_grid;
10225 
10226  for (int j = 0; j < grid->nb_tiles; j++) {
10227  int tile_id = grid->tile_id_list[j];
10228  int k;
10229 
10230  for (k = 0; k < mov->nb_heif_item; k++) {
10231  HEIFItem *item = mov->heif_item[k];
10232  AVStream *st;
10233 
10234  if (!item || item->item_id != tile_id)
10235  continue;
10236  st = item->st;
10237  if (!st) {
10238  av_log(s, AV_LOG_WARNING, "HEIF item id %d from grid id %d doesn't "
10239  "reference a stream\n",
10240  tile_id, grid->item->item_id);
10241  ff_remove_stream_group(s, stg);
10242  loop = 0;
10243  break;
10244  }
10245 
10246  grid->tile_item_list[j] = item;
10247  grid->tile_idx_list[j] = stg->nb_streams;
10248 
10249  err = avformat_stream_group_add_stream(stg, st);
10250  if (err < 0) {
10251  int l;
10252  if (err != AVERROR(EEXIST))
10253  return err;
10254 
10255  for (l = 0; l < stg->nb_streams; l++)
10256  if (stg->streams[l]->index == st->index)
10257  break;
10258  av_assert0(l < stg->nb_streams);
10259  grid->tile_idx_list[j] = l;
10260  }
10261 
10262  if (item->item_id != mov->primary_item_id)
10264  break;
10265  }
10266 
10267  if (k == mov->nb_heif_item) {
10268  av_assert0(loop);
10269  av_log(s, AV_LOG_WARNING, "HEIF item id %d referenced by grid id %d doesn't "
10270  "exist\n",
10271  tile_id, grid->item->item_id);
10272  ff_remove_stream_group(s, stg);
10273  loop = 0;
10274  }
10275  if (!loop)
10276  break;
10277  }
10278 
10279  if (!loop)
10280  continue;
10281 
10282  switch (grid->item->type) {
10283  case MKTAG('g','r','i','d'):
10284  err = read_image_grid(s, grid, tile_grid);
10285  break;
10286  case MKTAG('i','o','v','l'):
10287  err = read_image_iovl(s, grid, tile_grid);
10288  break;
10289  default:
10290  av_assert0(0);
10291  }
10292  if (err < 0)
10293  return err;
10294 
10295 
10296  if (grid->item->name)
10297  av_dict_set(&stg->metadata, "title", grid->item->name, 0);
10298  if (grid->item->item_id == mov->primary_item_id)
10300  }
10301 
10302  return 0;
10303 }
10304 
10306 {
10307  MOVContext *mov = s->priv_data;
10308  int err;
10309 
10310  for (int i = 0; i < mov->nb_heif_item; i++) {
10311  HEIFItem *item = mov->heif_item[i];
10312  MOVStreamContext *sc;
10313  AVStream *st;
10314  int64_t offset = 0;
10315 
10316  if (!item)
10317  continue;
10318  if (!item->st) {
10319  if (item->item_id == mov->thmb_item_id) {
10320  av_log(s, AV_LOG_ERROR, "HEIF thumbnail doesn't reference a stream\n");
10321  return AVERROR_INVALIDDATA;
10322  }
10323  continue;
10324  }
10325  if (item->is_idat_relative) {
10326  if (!mov->idat_offset) {
10327  av_log(s, AV_LOG_ERROR, "Missing idat box for item %d\n", item->item_id);
10328  return AVERROR_INVALIDDATA;
10329  }
10330  offset = mov->idat_offset;
10331  }
10332 
10333  st = item->st;
10334  sc = st->priv_data;
10335  st->codecpar->width = item->width;
10336  st->codecpar->height = item->height;
10337 
10338  err = sanity_checks(s, sc, item->item_id);
10339  if (err)
10340  return AVERROR_INVALIDDATA;
10341 
10342  sc->sample_sizes[0] = item->extent_length;
10343  sc->chunk_offsets[0] = item->extent_offset + offset;
10344 
10345  if (item->item_id == mov->primary_item_id)
10347 
10348  if (item->rotation || item->hflip || item->vflip) {
10350  &st->codecpar->nb_coded_side_data, item);
10351  if (err < 0)
10352  return err;
10353  }
10354 
10355  mov_build_index(mov, st);
10356  }
10357 
10358  if (mov->nb_heif_grid) {
10359  err = mov_parse_tiles(s);
10360  if (err < 0)
10361  return err;
10362  }
10363 
10364  return 0;
10365 }
10366 
10368  int first_index)
10369 {
10370  MOVStreamContext *sc = st->priv_data;
10371 
10372  if (sc->tref_id < 0)
10373  return NULL;
10374 
10375  for (int i = first_index; i < s->nb_streams; i++)
10376  if (s->streams[i]->id == sc->tref_id)
10377  return s->streams[i];
10378 
10379  return NULL;
10380 }
10381 
10383 {
10384  int err;
10385 
10386  for (int i = 0; i < s->nb_streams; i++) {
10387  AVStreamGroup *stg;
10388  AVStream *st = s->streams[i];
10389  AVStream *st_base;
10390  MOVStreamContext *sc = st->priv_data;
10391  int j = 0;
10392 
10393  /* Find an enhancement stream. */
10394  if (st->codecpar->codec_id != AV_CODEC_ID_LCEVC ||
10396  continue;
10397 
10399 
10401  if (!stg)
10402  return AVERROR(ENOMEM);
10403 
10404  stg->id = st->id;
10405  stg->params.lcevc->width = st->codecpar->width;
10406  stg->params.lcevc->height = st->codecpar->height;
10407  st->codecpar->width = 0;
10408  st->codecpar->height = 0;
10409 
10410  while (st_base = mov_find_reference_track(s, st, j)) {
10411  err = avformat_stream_group_add_stream(stg, st_base);
10412  if (err < 0)
10413  return err;
10414 
10415  j = st_base->index + 1;
10416  }
10417  if (!j) {
10418  av_log(s, AV_LOG_ERROR, "Failed to find base stream for enhancement stream\n");
10419  return AVERROR_INVALIDDATA;
10420  }
10421 
10422  err = avformat_stream_group_add_stream(stg, st);
10423  if (err < 0)
10424  return err;
10425 
10426  stg->params.lcevc->lcevc_index = stg->nb_streams - 1;
10427  }
10428 
10429  return 0;
10430 }
10431 
10433 {
10434  int highest_id = 0;
10435 
10436  for (int i = 0; i < s->nb_streams; i++) {
10437  const AVStream *st = s->streams[i];
10438  const MOVStreamContext *sc = st->priv_data;
10439  if (!sc->iamf)
10440  highest_id = FFMAX(highest_id, st->id);
10441  }
10442  highest_id += !highest_id;
10443  for (int i = 0; highest_id > 1 && i < s->nb_stream_groups; i++) {
10444  AVStreamGroup *stg = s->stream_groups[i];
10446  continue;
10447  for (int j = 0; j < stg->nb_streams; j++) {
10448  AVStream *st = stg->streams[j];
10449  MOVStreamContext *sc = st->priv_data;
10450  st->id += highest_id;
10451  sc->iamf_stream_offset = highest_id;
10452  }
10453  }
10454 }
10455 
10457 {
10458  MOVContext *mov = s->priv_data;
10459  AVIOContext *pb = s->pb;
10460  int j, err;
10461  MOVAtom atom = { AV_RL32("root") };
10462  int i;
10463 
10464  if (mov->decryption_key_len != 0 && mov->decryption_key_len != AES_CTR_KEY_SIZE) {
10465  av_log(s, AV_LOG_ERROR, "Invalid decryption key len %d expected %d\n",
10467  return AVERROR(EINVAL);
10468  }
10469 
10470  mov->fc = s;
10471  mov->trak_index = -1;
10472  mov->thmb_item_id = -1;
10473  mov->primary_item_id = -1;
10474  mov->cur_item_id = -1;
10475  /* .mov and .mp4 aren't streamable anyway (only progressive download if moov is before mdat) */
10476  if (pb->seekable & AVIO_SEEKABLE_NORMAL)
10477  atom.size = avio_size(pb);
10478  else
10479  atom.size = INT64_MAX;
10480 
10481  /* check MOV header */
10482  do {
10483  if (mov->moov_retry)
10484  avio_seek(pb, 0, SEEK_SET);
10485  if ((err = mov_read_default(mov, pb, atom)) < 0) {
10486  av_log(s, AV_LOG_ERROR, "error reading header\n");
10487  return err;
10488  }
10489  } while ((pb->seekable & AVIO_SEEKABLE_NORMAL) &&
10490  !mov->found_moov && (!mov->found_iloc || !mov->found_iinf) && !mov->moov_retry++);
10491  if (!mov->found_moov && !mov->found_iloc && !mov->found_iinf) {
10492  av_log(s, AV_LOG_ERROR, "moov atom not found\n");
10493  return AVERROR_INVALIDDATA;
10494  }
10495  av_log(mov->fc, AV_LOG_TRACE, "on_parse_exit_offset=%"PRId64"\n", avio_tell(pb));
10496 
10497  if (mov->found_iloc && mov->found_iinf) {
10498  err = mov_parse_heif_items(s);
10499  if (err < 0)
10500  return err;
10501  }
10502  // prevent iloc and iinf boxes from being parsed while reading packets.
10503  // this is needed because an iinf box may have been parsed but ignored
10504  // for having old infe boxes which create no streams.
10505  mov->found_iloc = mov->found_iinf = 1;
10506 
10507  if (pb->seekable & AVIO_SEEKABLE_NORMAL) {
10508  if (mov->nb_chapter_tracks > 0 && !mov->ignore_chapters)
10510  for (i = 0; i < s->nb_streams; i++)
10511  if (s->streams[i]->codecpar->codec_tag == AV_RL32("tmcd")) {
10512  mov_read_timecode_track(s, s->streams[i]);
10513  } else if (s->streams[i]->codecpar->codec_tag == AV_RL32("rtmd")) {
10514  mov_read_rtmd_track(s, s->streams[i]);
10515  }
10516  }
10517 
10518  /* copy timecode metadata from tmcd tracks to the related video streams */
10519  for (i = 0; i < s->nb_streams; i++) {
10520  AVStream *st = s->streams[i];
10521  MOVStreamContext *sc = st->priv_data;
10522  if (sc->timecode_track > 0) {
10523  AVDictionaryEntry *tcr;
10524  int tmcd_st_id = -1;
10525 
10526  for (j = 0; j < s->nb_streams; j++) {
10527  MOVStreamContext *sc2 = s->streams[j]->priv_data;
10528  if (sc2->id == sc->timecode_track)
10529  tmcd_st_id = j;
10530  }
10531 
10532  if (tmcd_st_id < 0 || tmcd_st_id == i)
10533  continue;
10534  tcr = av_dict_get(s->streams[tmcd_st_id]->metadata, "timecode", NULL, 0);
10535  if (tcr)
10536  av_dict_set(&st->metadata, "timecode", tcr->value, 0);
10537  }
10538  }
10540 
10541  /* Create LCEVC stream groups. */
10542  err = mov_parse_lcevc_streams(s);
10543  if (err < 0)
10544  return err;
10545 
10546  for (i = 0; i < s->nb_streams; i++) {
10547  AVStream *st = s->streams[i];
10548  FFStream *const sti = ffstream(st);
10549  MOVStreamContext *sc = st->priv_data;
10550  uint32_t dvdsub_clut[FF_DVDCLUT_CLUT_LEN] = {0};
10551  fix_timescale(mov, sc);
10552  if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
10553  st->codecpar->codec_id == AV_CODEC_ID_AAC) {
10554  sti->skip_samples = sc->start_pad;
10555  }
10556  if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && sc->nb_frames_for_fps > 0 && sc->duration_for_fps > 0)
10558  sc->time_scale*(int64_t)sc->nb_frames_for_fps, sc->duration_for_fps, INT_MAX);
10560  if (st->codecpar->width <= 0 || st->codecpar->height <= 0) {
10561  st->codecpar->width = sc->width;
10562  st->codecpar->height = sc->height;
10563  }
10566 
10567  for (j = 0; j < FF_DVDCLUT_CLUT_LEN; j++)
10568  dvdsub_clut[j] = AV_RB32(st->codecpar->extradata + j * 4);
10569 
10570  err = ff_dvdclut_yuv_to_rgb(dvdsub_clut, FF_DVDCLUT_CLUT_SIZE);
10571  if (err < 0)
10572  return err;
10573 
10574  av_freep(&st->codecpar->extradata);
10575  st->codecpar->extradata_size = 0;
10576 
10578  st->codecpar);
10579  if (err < 0)
10580  return err;
10581  }
10582  }
10583  if (mov->handbrake_version &&
10584  mov->handbrake_version <= 1000000*0 + 1000*10 + 2 && // 0.10.2
10585  st->codecpar->codec_id == AV_CODEC_ID_MP3) {
10586  av_log(s, AV_LOG_VERBOSE, "Forcing full parsing for mp3 stream\n");
10588  }
10589  }
10590 
10591  if (mov->trex_data || mov->use_mfra_for > 0) {
10592  for (i = 0; i < s->nb_streams; i++) {
10593  AVStream *st = s->streams[i];
10594  MOVStreamContext *sc = st->priv_data;
10595  if (sc->duration_for_fps > 0) {
10596  /* Akin to sc->data_size * 8 * sc->time_scale / sc->duration_for_fps but accounting for overflows. */
10598  if (st->codecpar->bit_rate == INT64_MIN) {
10599  av_log(s, AV_LOG_WARNING, "Overflow during bit rate calculation %"PRId64" * 8 * %d\n",
10600  sc->data_size, sc->time_scale);
10601  st->codecpar->bit_rate = 0;
10602  if (s->error_recognition & AV_EF_EXPLODE)
10603  return AVERROR_INVALIDDATA;
10604  }
10605  }
10606  }
10607  }
10608 
10609  for (i = 0; i < mov->bitrates_count && i < s->nb_streams; i++) {
10610  if (mov->bitrates[i]) {
10611  s->streams[i]->codecpar->bit_rate = mov->bitrates[i];
10612  }
10613  }
10614 
10616 
10617  for (i = 0; i < s->nb_streams; i++) {
10618  AVStream *st = s->streams[i];
10619  MOVStreamContext *sc = st->priv_data;
10620 
10621  switch (st->codecpar->codec_type) {
10622  case AVMEDIA_TYPE_AUDIO:
10623  err = ff_replaygain_export(st, s->metadata);
10624  if (err < 0)
10625  return err;
10626  break;
10627  case AVMEDIA_TYPE_VIDEO:
10628  if (sc->display_matrix) {
10631  (uint8_t*)sc->display_matrix, sizeof(int32_t) * 9, 0))
10632  return AVERROR(ENOMEM);
10633 
10634  sc->display_matrix = NULL;
10635  }
10636  if (sc->stereo3d) {
10639  (uint8_t *)sc->stereo3d, sc->stereo3d_size, 0))
10640  return AVERROR(ENOMEM);
10641 
10642  sc->stereo3d = NULL;
10643  }
10644  if (sc->spherical) {
10647  (uint8_t *)sc->spherical, sc->spherical_size, 0))
10648  return AVERROR(ENOMEM);
10649 
10650  sc->spherical = NULL;
10651  }
10652  if (sc->mastering) {
10655  (uint8_t *)sc->mastering, sc->mastering_size, 0))
10656  return AVERROR(ENOMEM);
10657 
10658  sc->mastering = NULL;
10659  }
10660  if (sc->coll) {
10663  (uint8_t *)sc->coll, sc->coll_size, 0))
10664  return AVERROR(ENOMEM);
10665 
10666  sc->coll = NULL;
10667  }
10668  if (sc->ambient) {
10671  (uint8_t *) sc->ambient, sc->ambient_size, 0))
10672  return AVERROR(ENOMEM);
10673 
10674  sc->ambient = NULL;
10675  }
10676  break;
10677  }
10678  }
10679 
10680  fix_stream_ids(s);
10681 
10683 
10684  for (i = 0; i < mov->frag_index.nb_items; i++)
10685  if (mov->frag_index.item[i].moof_offset <= mov->fragment.moof_offset)
10686  mov->frag_index.item[i].headers_read = 1;
10687 
10688  return 0;
10689 }
10690 
10692 {
10694  int64_t best_dts = INT64_MAX;
10695  int i;
10696  MOVContext *mov = s->priv_data;
10697  int no_interleave = !mov->interleaved_read || !(s->pb->seekable & AVIO_SEEKABLE_NORMAL);
10698  for (i = 0; i < s->nb_streams; i++) {
10699  AVStream *avst = s->streams[i];
10700  FFStream *const avsti = ffstream(avst);
10701  MOVStreamContext *msc = avst->priv_data;
10702  if (msc->pb && msc->current_sample < avsti->nb_index_entries) {
10703  AVIndexEntry *current_sample = &avsti->index_entries[msc->current_sample];
10704  int64_t dts = av_rescale(current_sample->timestamp, AV_TIME_BASE, msc->time_scale);
10705  uint64_t dtsdiff = best_dts > dts ? best_dts - (uint64_t)dts : ((uint64_t)dts - best_dts);
10706  av_log(s, AV_LOG_TRACE, "stream %d, sample %d, dts %"PRId64"\n", i, msc->current_sample, dts);
10707  if (!sample || (no_interleave && current_sample->pos < sample->pos) ||
10708  ((s->pb->seekable & AVIO_SEEKABLE_NORMAL) &&
10709  ((msc->pb != s->pb && dts < best_dts) || (msc->pb == s->pb && dts != AV_NOPTS_VALUE &&
10710  ((dtsdiff <= AV_TIME_BASE && current_sample->pos < sample->pos) ||
10711  (dtsdiff > AV_TIME_BASE && dts < best_dts && mov->interleaved_read)))))) {
10712  sample = current_sample;
10713  best_dts = dts;
10714  *st = avst;
10715  }
10716  }
10717  }
10718  return sample;
10719 }
10720 
10721 static int should_retry(AVIOContext *pb, int error_code) {
10722  if (error_code == AVERROR_EOF || avio_feof(pb))
10723  return 0;
10724 
10725  return 1;
10726 }
10727 
10728 static int mov_switch_root(AVFormatContext *s, int64_t target, int index)
10729 {
10730  int ret;
10731  MOVContext *mov = s->priv_data;
10732 
10733  if (index >= 0 && index < mov->frag_index.nb_items)
10734  target = mov->frag_index.item[index].moof_offset;
10735  if (target >= 0 && avio_seek(s->pb, target, SEEK_SET) != target) {
10736  av_log(mov->fc, AV_LOG_ERROR, "root atom offset 0x%"PRIx64": partial file\n", target);
10737  return AVERROR_INVALIDDATA;
10738  }
10739 
10740  mov->next_root_atom = 0;
10741  if ((index < 0 && target >= 0) || index >= mov->frag_index.nb_items)
10742  index = search_frag_moof_offset(&mov->frag_index, target);
10743  if (index >= 0 && index < mov->frag_index.nb_items &&
10744  mov->frag_index.item[index].moof_offset == target) {
10745  if (index + 1 < mov->frag_index.nb_items)
10746  mov->next_root_atom = mov->frag_index.item[index + 1].moof_offset;
10747  if (mov->frag_index.item[index].headers_read)
10748  return 0;
10749  mov->frag_index.item[index].headers_read = 1;
10750  }
10751 
10752  mov->found_mdat = 0;
10753 
10754  ret = mov_read_default(mov, s->pb, (MOVAtom){ AV_RL32("root"), INT64_MAX });
10755  if (ret < 0)
10756  return ret;
10757  if (avio_feof(s->pb))
10758  return AVERROR_EOF;
10759  av_log(s, AV_LOG_TRACE, "read fragments, offset 0x%"PRIx64"\n", avio_tell(s->pb));
10760 
10761  return 1;
10762 }
10763 
10765 {
10766  MOVStreamContext *sc = st->priv_data;
10767  uint8_t *side, *extradata;
10768  int extradata_size;
10769 
10770  /* Save the current index. */
10771  sc->last_stsd_index = sc->stsc_data[sc->stsc_index].id - 1;
10772 
10773  /* Notify the decoder that extradata changed. */
10774  extradata_size = sc->extradata_size[sc->last_stsd_index];
10775  extradata = sc->extradata[sc->last_stsd_index];
10776  if (st->discard != AVDISCARD_ALL && extradata_size > 0 && extradata) {
10779  extradata_size);
10780  if (!side)
10781  return AVERROR(ENOMEM);
10782  memcpy(side, extradata, extradata_size);
10783  }
10784 
10785  return 0;
10786 }
10787 
10788 static int get_eia608_packet(AVIOContext *pb, AVPacket *pkt, int src_size)
10789 {
10790  /* We can't make assumptions about the structure of the payload,
10791  because it may include multiple cdat and cdt2 samples. */
10792  const uint32_t cdat = AV_RB32("cdat");
10793  const uint32_t cdt2 = AV_RB32("cdt2");
10794  int ret, out_size = 0;
10795 
10796  /* a valid payload must have size, 4cc, and at least 1 byte pair: */
10797  if (src_size < 10)
10798  return AVERROR_INVALIDDATA;
10799 
10800  /* avoid an int overflow: */
10801  if ((src_size - 8) / 2 >= INT_MAX / 3)
10802  return AVERROR_INVALIDDATA;
10803 
10804  ret = av_new_packet(pkt, ((src_size - 8) / 2) * 3);
10805  if (ret < 0)
10806  return ret;
10807 
10808  /* parse and re-format the c608 payload in one pass. */
10809  while (src_size >= 10) {
10810  const uint32_t atom_size = avio_rb32(pb);
10811  const uint32_t atom_type = avio_rb32(pb);
10812  const uint32_t data_size = atom_size - 8;
10813  const uint8_t cc_field =
10814  atom_type == cdat ? 1 :
10815  atom_type == cdt2 ? 2 :
10816  0;
10817 
10818  /* account for bytes consumed for atom size and type. */
10819  src_size -= 8;
10820 
10821  /* make sure the data size stays within the buffer boundaries. */
10822  if (data_size < 2 || data_size > src_size) {
10824  break;
10825  }
10826 
10827  /* make sure the data size is consistent with N byte pairs. */
10828  if (data_size % 2 != 0) {
10830  break;
10831  }
10832 
10833  if (!cc_field) {
10834  /* neither cdat or cdt2 ... skip it */
10835  avio_skip(pb, data_size);
10836  src_size -= data_size;
10837  continue;
10838  }
10839 
10840  for (uint32_t i = 0; i < data_size; i += 2) {
10841  pkt->data[out_size] = (0x1F << 3) | (1 << 2) | (cc_field - 1);
10842  pkt->data[out_size + 1] = avio_r8(pb);
10843  pkt->data[out_size + 2] = avio_r8(pb);
10844  out_size += 3;
10845  src_size -= 2;
10846  }
10847  }
10848 
10849  if (src_size > 0)
10850  /* skip any remaining unread portion of the input payload */
10851  avio_skip(pb, src_size);
10852 
10854  return ret;
10855 }
10856 
10858  int64_t current_index, AVPacket *pkt)
10859 {
10860  MOVStreamContext *sc = st->priv_data;
10861 
10862  pkt->stream_index = sc->ffindex;
10863  pkt->dts = sample->timestamp;
10864  if (sample->flags & AVINDEX_DISCARD_FRAME) {
10866  }
10867  if (sc->stts_count && sc->tts_index < sc->tts_count)
10868  pkt->duration = sc->tts_data[sc->tts_index].duration;
10869  if (sc->ctts_count && sc->tts_index < sc->tts_count) {
10871  } else {
10872  if (pkt->duration == 0) {
10873  int64_t next_dts = (sc->current_sample < ffstream(st)->nb_index_entries) ?
10875  if (next_dts >= pkt->dts)
10876  pkt->duration = next_dts - pkt->dts;
10877  }
10878  pkt->pts = pkt->dts;
10879  }
10880 
10881  if (sc->tts_data && sc->tts_index < sc->tts_count) {
10882  /* update tts context */
10883  sc->tts_sample++;
10884  if (sc->tts_index < sc->tts_count &&
10885  sc->tts_data[sc->tts_index].count == sc->tts_sample) {
10886  sc->tts_index++;
10887  sc->tts_sample = 0;
10888  }
10889  }
10890 
10891  if (sc->sdtp_data && sc->current_sample <= sc->sdtp_count) {
10892  uint8_t sample_flags = sc->sdtp_data[sc->current_sample - 1];
10893  uint8_t sample_is_depended_on = (sample_flags >> 2) & 0x3;
10894  pkt->flags |= sample_is_depended_on == MOV_SAMPLE_DEPENDENCY_NO ? AV_PKT_FLAG_DISPOSABLE : 0;
10895  }
10896  pkt->flags |= sample->flags & AVINDEX_KEYFRAME ? AV_PKT_FLAG_KEY : 0;
10897  pkt->pos = sample->pos;
10898 
10899  /* Multiple stsd handling. */
10900  if (sc->stsc_data) {
10901  if (sc->stsc_data[sc->stsc_index].id > 0 &&
10902  sc->stsc_data[sc->stsc_index].id - 1 < sc->stsd_count &&
10903  sc->stsc_data[sc->stsc_index].id - 1 != sc->last_stsd_index) {
10904  int ret = mov_change_extradata(st, pkt);
10905  if (ret < 0)
10906  return ret;
10907  }
10908 
10909  /* Update the stsc index for the next sample */
10910  sc->stsc_sample++;
10911  if (mov_stsc_index_valid(sc->stsc_index, sc->stsc_count) &&
10912  mov_get_stsc_samples(sc, sc->stsc_index) == sc->stsc_sample) {
10913  sc->stsc_index++;
10914  sc->stsc_sample = 0;
10915  }
10916  }
10917 
10918  return 0;
10919 }
10920 
10922 {
10923  MOVContext *mov = s->priv_data;
10924  MOVStreamContext *sc;
10926  AVStream *st = NULL;
10927  FFStream *avsti = NULL;
10928  int64_t current_index;
10929  int ret;
10930  int i;
10931  mov->fc = s;
10932  retry:
10933  if (s->pb->pos == 0) {
10934 
10935  // Discard current fragment index
10936  if (mov->frag_index.allocated_size > 0) {
10937  for(int i = 0; i < mov->frag_index.nb_items; i++) {
10939  }
10940  av_freep(&mov->frag_index.item);
10941  mov->frag_index.nb_items = 0;
10942  mov->frag_index.allocated_size = 0;
10943  mov->frag_index.current = -1;
10944  mov->frag_index.complete = 0;
10945  }
10946 
10947  for (i = 0; i < s->nb_streams; i++) {
10948  AVStream *avst = s->streams[i];
10949  MOVStreamContext *msc = avst->priv_data;
10950 
10951  // Clear current sample
10952  mov_current_sample_set(msc, 0);
10953  msc->tts_index = 0;
10954 
10955  // Discard current index entries
10956  avsti = ffstream(avst);
10957  if (avsti->index_entries_allocated_size > 0) {
10958  av_freep(&avsti->index_entries);
10959  avsti->index_entries_allocated_size = 0;
10960  avsti->nb_index_entries = 0;
10961  }
10962  }
10963 
10964  if ((ret = mov_switch_root(s, -1, -1)) < 0)
10965  return ret;
10966  }
10967  sample = mov_find_next_sample(s, &st);
10968  if (!sample || (mov->next_root_atom && sample->pos > mov->next_root_atom)) {
10969  if (!mov->next_root_atom)
10970  return AVERROR_EOF;
10971  if ((ret = mov_switch_root(s, mov->next_root_atom, -1)) < 0)
10972  return ret;
10973  goto retry;
10974  }
10975  sc = st->priv_data;
10976  /* must be done just before reading, to avoid infinite loop on sample */
10977  current_index = sc->current_index;
10979 
10980  if (mov->next_root_atom) {
10981  sample->pos = FFMIN(sample->pos, mov->next_root_atom);
10982  sample->size = FFMIN(sample->size, (mov->next_root_atom - sample->pos));
10983  }
10984 
10985  if (st->discard != AVDISCARD_ALL) {
10986  int64_t ret64 = avio_seek(sc->pb, sample->pos, SEEK_SET);
10987  if (ret64 != sample->pos) {
10988  av_log(mov->fc, AV_LOG_ERROR, "stream %d, offset 0x%"PRIx64": partial file\n",
10989  sc->ffindex, sample->pos);
10990  if (should_retry(sc->pb, ret64)) {
10992  } else if (ret64 < 0) {
10993  return (int)ret64;
10994  }
10995  return AVERROR_INVALIDDATA;
10996  }
10997 
10998  if (st->discard == AVDISCARD_NONKEY && !(sample->flags & AVINDEX_KEYFRAME)) {
10999  av_log(mov->fc, AV_LOG_DEBUG, "Nonkey frame from stream %d discarded due to AVDISCARD_NONKEY\n", sc->ffindex);
11000  goto retry;
11001  }
11002 
11003  if (st->codecpar->codec_id == AV_CODEC_ID_EIA_608 && sample->size > 8)
11004  ret = get_eia608_packet(sc->pb, pkt, sample->size);
11005 #if CONFIG_IAMFDEC
11006  else if (sc->iamf) {
11007  int64_t pts, dts, pos, duration;
11008  int flags, size = sample->size;
11009  ret = mov_finalize_packet(s, st, sample, current_index, pkt);
11010  pts = pkt->pts; dts = pkt->dts;
11011  pos = pkt->pos; flags = pkt->flags;
11012  duration = pkt->duration;
11013  while (!ret && size > 0) {
11014  ret = ff_iamf_read_packet(s, sc->iamf, sc->pb, size, sc->iamf_stream_offset, pkt);
11015  if (ret < 0) {
11016  if (should_retry(sc->pb, ret))
11018  return ret;
11019  }
11020  size -= ret;
11021  pkt->pts = pts; pkt->dts = dts;
11022  pkt->pos = pos; pkt->flags |= flags;
11023  pkt->duration = duration;
11024  ret = ff_buffer_packet(s, pkt);
11025  }
11026  if (!ret)
11027  return FFERROR_REDO;
11028  }
11029 #endif
11030  else
11031  ret = av_get_packet(sc->pb, pkt, sample->size);
11032  if (ret < 0) {
11033  if (should_retry(sc->pb, ret)) {
11035  }
11036  return ret;
11037  }
11038 #if CONFIG_DV_DEMUXER
11039  if (mov->dv_demux && sc->dv_audio_container) {
11042  if (ret < 0)
11043  return ret;
11045  if (ret < 0)
11046  return ret;
11047  }
11048 #endif
11049  if (sc->has_palette) {
11050  uint8_t *pal;
11051 
11053  if (!pal) {
11054  av_log(mov->fc, AV_LOG_ERROR, "Cannot append palette to packet\n");
11055  } else {
11056  memcpy(pal, sc->palette, AVPALETTE_SIZE);
11057  sc->has_palette = 0;
11058  }
11059  }
11060  if (st->codecpar->codec_id == AV_CODEC_ID_MP3 && !ffstream(st)->need_parsing && pkt->size > 4) {
11061  if (ff_mpa_check_header(AV_RB32(pkt->data)) < 0)
11063  }
11064  }
11065 
11066  ret = mov_finalize_packet(s, st, sample, current_index, pkt);
11067  if (ret < 0)
11068  return ret;
11069 
11070  if (st->discard == AVDISCARD_ALL)
11071  goto retry;
11072 
11073  if (mov->aax_mode)
11074  aax_filter(pkt->data, pkt->size, mov);
11075 
11076  ret = cenc_filter(mov, st, sc, pkt, current_index);
11077  if (ret < 0) {
11078  return ret;
11079  }
11080 
11081  return 0;
11082 }
11083 
11085 {
11086  MOVContext *mov = s->priv_data;
11087  int index;
11088 
11089  if (!mov->frag_index.complete)
11090  return 0;
11091 
11092  index = search_frag_timestamp(s, &mov->frag_index, st, timestamp);
11093  if (index < 0)
11094  index = 0;
11095  if (!mov->frag_index.item[index].headers_read)
11096  return mov_switch_root(s, -1, index);
11097  if (index + 1 < mov->frag_index.nb_items)
11098  mov->next_root_atom = mov->frag_index.item[index + 1].moof_offset;
11099 
11100  return 0;
11101 }
11102 
11103 static int is_open_key_sample(const MOVStreamContext *sc, int sample)
11104 {
11105  // TODO: a bisect search would scale much better
11106  for (int i = 0; i < sc->open_key_samples_count; i++) {
11107  const int oks = sc->open_key_samples[i];
11108  if (oks == sample)
11109  return 1;
11110  if (oks > sample) /* list is monotically increasing so we can stop early */
11111  break;
11112  }
11113  return 0;
11114 }
11115 
11116 /*
11117  * Some key sample may be key frames but not IDR frames, so a random access to
11118  * them may not be allowed.
11119  */
11120 static int can_seek_to_key_sample(AVStream *st, int sample, int64_t requested_pts)
11121 {
11122  MOVStreamContext *sc = st->priv_data;
11123  FFStream *const sti = ffstream(st);
11124  int64_t key_sample_dts, key_sample_pts;
11125 
11126  if (st->codecpar->codec_id != AV_CODEC_ID_HEVC)
11127  return 1;
11128 
11129  if (sample >= sc->sample_offsets_count)
11130  return 1;
11131 
11132  key_sample_dts = sti->index_entries[sample].timestamp;
11133  key_sample_pts = key_sample_dts + sc->sample_offsets[sample] + sc->dts_shift;
11134 
11135  /*
11136  * If the sample needs to be presented before an open key sample, they may
11137  * not be decodable properly, even though they come after in decoding
11138  * order.
11139  */
11140  if (is_open_key_sample(sc, sample) && key_sample_pts > requested_pts)
11141  return 0;
11142 
11143  return 1;
11144 }
11145 
11146 static int mov_seek_stream(AVFormatContext *s, AVStream *st, int64_t timestamp, int flags)
11147 {
11148  MOVStreamContext *sc = st->priv_data;
11149  FFStream *const sti = ffstream(st);
11150  int sample, time_sample, ret, next_ts, requested_sample;
11151  unsigned int i;
11152 
11153  // Here we consider timestamp to be PTS, hence try to offset it so that we
11154  // can search over the DTS timeline.
11155  timestamp -= (sc->min_corrected_pts + sc->dts_shift);
11156 
11157  ret = mov_seek_fragment(s, st, timestamp);
11158  if (ret < 0)
11159  return ret;
11160 
11161  for (;;) {
11162  sample = av_index_search_timestamp(st, timestamp, flags);
11163  av_log(s, AV_LOG_TRACE, "stream %d, timestamp %"PRId64", sample %d\n", st->index, timestamp, sample);
11164  if (sample < 0 && sti->nb_index_entries && timestamp < sti->index_entries[0].timestamp)
11165  sample = 0;
11166  if (sample < 0) /* not sure what to do */
11167  return AVERROR_INVALIDDATA;
11168 
11169  if (!sample || can_seek_to_key_sample(st, sample, timestamp))
11170  break;
11171 
11172  next_ts = timestamp - FFMAX(sc->min_sample_duration, 1);
11173  requested_sample = av_index_search_timestamp(st, next_ts, flags);
11174 
11175  // If we've reached a different sample trying to find a good pts to
11176  // seek to, give up searching because we'll end up seeking back to
11177  // sample 0 on every seek.
11178  if (sample != requested_sample && !can_seek_to_key_sample(st, requested_sample, next_ts))
11179  break;
11180 
11181  timestamp = next_ts;
11182  }
11183 
11185  av_log(s, AV_LOG_TRACE, "stream %d, found sample %d\n", st->index, sc->current_sample);
11186  /* adjust time to sample index */
11187  if (sc->tts_data) {
11188  time_sample = 0;
11189  for (i = 0; i < sc->tts_count; i++) {
11190  int next = time_sample + sc->tts_data[i].count;
11191  if (next > sc->current_sample) {
11192  sc->tts_index = i;
11193  sc->tts_sample = sc->current_sample - time_sample;
11194  break;
11195  }
11196  time_sample = next;
11197  }
11198  }
11199 
11200  /* adjust stsd index */
11201  if (sc->chunk_count) {
11202  time_sample = 0;
11203  for (i = 0; i < sc->stsc_count; i++) {
11204  int64_t next = time_sample + mov_get_stsc_samples(sc, i);
11205  if (next > sc->current_sample) {
11206  sc->stsc_index = i;
11207  sc->stsc_sample = sc->current_sample - time_sample;
11208  break;
11209  }
11210  av_assert0(next == (int)next);
11211  time_sample = next;
11212  }
11213  }
11214 
11215  return sample;
11216 }
11217 
11219 {
11220  MOVStreamContext *sc = st->priv_data;
11221  FFStream *const sti = ffstream(st);
11222  int64_t first_ts = sti->index_entries[0].timestamp;
11224  int64_t off;
11225 
11227  return 0;
11228 
11229  /* compute skip samples according to stream start_pad, seek ts and first ts */
11230  off = av_rescale_q(ts - first_ts, st->time_base,
11231  (AVRational){1, st->codecpar->sample_rate});
11232  return FFMAX(sc->start_pad - off, 0);
11233 }
11234 
11235 static int mov_read_seek(AVFormatContext *s, int stream_index, int64_t sample_time, int flags)
11236 {
11237  MOVContext *mc = s->priv_data;
11238  AVStream *st;
11239  FFStream *sti;
11240  int sample;
11241  int i;
11242 
11243  if (stream_index >= s->nb_streams)
11244  return AVERROR_INVALIDDATA;
11245 
11246  st = s->streams[stream_index];
11247  sti = ffstream(st);
11248  sample = mov_seek_stream(s, st, sample_time, flags);
11249  if (sample < 0)
11250  return sample;
11251 
11252  if (mc->seek_individually) {
11253  /* adjust seek timestamp to found sample timestamp */
11254  int64_t seek_timestamp = sti->index_entries[sample].timestamp;
11256 
11257  for (i = 0; i < s->nb_streams; i++) {
11258  AVStream *const st = s->streams[i];
11259  FFStream *const sti = ffstream(st);
11260  int64_t timestamp;
11261 
11262  if (stream_index == i)
11263  continue;
11264 
11265  timestamp = av_rescale_q(seek_timestamp, s->streams[stream_index]->time_base, st->time_base);
11266  sample = mov_seek_stream(s, st, timestamp, flags);
11267  if (sample >= 0)
11269  }
11270  } else {
11271  for (i = 0; i < s->nb_streams; i++) {
11272  MOVStreamContext *sc;
11273  st = s->streams[i];
11274  sc = st->priv_data;
11275  mov_current_sample_set(sc, 0);
11276  }
11277  while (1) {
11278  MOVStreamContext *sc;
11280  if (!entry)
11281  return AVERROR_INVALIDDATA;
11282  sc = st->priv_data;
11283  if (sc->ffindex == stream_index && sc->current_sample == sample)
11284  break;
11286  }
11287  }
11288  return 0;
11289 }
11290 
11291 #define OFFSET(x) offsetof(MOVContext, x)
11292 #define FLAGS AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM
11293 static const AVOption mov_options[] = {
11294  {"use_absolute_path",
11295  "allow using absolute path when opening alias, this is a possible security issue",
11296  OFFSET(use_absolute_path), AV_OPT_TYPE_BOOL, {.i64 = 0},
11297  0, 1, FLAGS},
11298  {"seek_streams_individually",
11299  "Seek each stream individually to the closest point",
11300  OFFSET(seek_individually), AV_OPT_TYPE_BOOL, { .i64 = 1 },
11301  0, 1, FLAGS},
11302  {"ignore_editlist", "Ignore the edit list atom.", OFFSET(ignore_editlist), AV_OPT_TYPE_BOOL, {.i64 = 0},
11303  0, 1, FLAGS},
11304  {"advanced_editlist",
11305  "Modify the AVIndex according to the editlists. Use this option to decode in the order specified by the edits.",
11306  OFFSET(advanced_editlist), AV_OPT_TYPE_BOOL, {.i64 = 1},
11307  0, 1, FLAGS},
11308  {"ignore_chapters", "", OFFSET(ignore_chapters), AV_OPT_TYPE_BOOL, {.i64 = 0},
11309  0, 1, FLAGS},
11310  {"use_mfra_for",
11311  "use mfra for fragment timestamps",
11312  OFFSET(use_mfra_for), AV_OPT_TYPE_INT, {.i64 = FF_MOV_FLAG_MFRA_AUTO},
11314  .unit = "use_mfra_for"},
11315  {"auto", "auto", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_AUTO}, 0, 0,
11316  FLAGS, .unit = "use_mfra_for" },
11317  {"dts", "dts", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_DTS}, 0, 0,
11318  FLAGS, .unit = "use_mfra_for" },
11319  {"pts", "pts", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_PTS}, 0, 0,
11320  FLAGS, .unit = "use_mfra_for" },
11321  {"use_tfdt", "use tfdt for fragment timestamps", OFFSET(use_tfdt), AV_OPT_TYPE_BOOL, {.i64 = 1},
11322  0, 1, FLAGS},
11323  { "export_all", "Export unrecognized metadata entries", OFFSET(export_all),
11324  AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = FLAGS },
11325  { "export_xmp", "Export full XMP metadata", OFFSET(export_xmp),
11326  AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = FLAGS },
11327  { "activation_bytes", "Secret bytes for Audible AAX files", OFFSET(activation_bytes),
11329  { "audible_key", "AES-128 Key for Audible AAXC files", OFFSET(audible_key),
11331  { "audible_iv", "AES-128 IV for Audible AAXC files", OFFSET(audible_iv),
11333  { "audible_fixed_key", // extracted from libAAX_SDK.so and AAXSDKWin.dll files!
11334  "Fixed key used for handling Audible AAX files", OFFSET(audible_fixed_key),
11335  AV_OPT_TYPE_BINARY, {.str="77214d4b196a87cd520045fd20a51d67"},
11336  .flags = AV_OPT_FLAG_DECODING_PARAM },
11337  { "decryption_key", "The media decryption key (hex)", OFFSET(decryption_key), AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM },
11338  { "enable_drefs", "Enable external track support.", OFFSET(enable_drefs), AV_OPT_TYPE_BOOL,
11339  {.i64 = 0}, 0, 1, FLAGS },
11340  { "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 },
11341  { "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 },
11342 
11343  { NULL },
11344 };
11345 
11346 static const AVClass mov_class = {
11347  .class_name = "mov,mp4,m4a,3gp,3g2,mj2",
11348  .item_name = av_default_item_name,
11349  .option = mov_options,
11350  .version = LIBAVUTIL_VERSION_INT,
11351 };
11352 
11354  .p.name = "mov,mp4,m4a,3gp,3g2,mj2",
11355  .p.long_name = NULL_IF_CONFIG_SMALL("QuickTime / MOV"),
11356  .p.priv_class = &mov_class,
11357  .p.extensions = "mov,mp4,m4a,3gp,3g2,mj2,psp,m4b,ism,ismv,isma,f4v,avif,heic,heif",
11359  .priv_data_size = sizeof(MOVContext),
11360  .flags_internal = FF_INFMT_FLAG_INIT_CLEANUP,
11361  .read_probe = mov_probe,
11366 };
avpriv_new_chapter
AVChapter * avpriv_new_chapter(AVFormatContext *s, int64_t id, AVRational time_base, int64_t start, int64_t end, const char *title)
Add a new chapter.
Definition: demux_utils.c:43
MOVStreamContext::ctts_allocated_size
unsigned int ctts_allocated_size
Definition: isom.h:191
item_name
item_name
Definition: libkvazaar.c:313
AV_CODEC_ID_PCM_S16LE
@ AV_CODEC_ID_PCM_S16LE
Definition: codec_id.h:336
flags
const SwsFlags flags[]
Definition: swscale.c:61
mov_read_chpl
static int mov_read_chpl(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:597
AVMasteringDisplayMetadata::has_primaries
int has_primaries
Flag indicating whether the display primaries (and white point) are set.
Definition: mastering_display_metadata.h:62
mov_read_frma
static int mov_read_frma(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:7239
mov_read_meta
static int mov_read_meta(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5452
AV_CODEC_ID_EIA_608
@ AV_CODEC_ID_EIA_608
Definition: codec_id.h:569
AV_PKT_DATA_DISPLAYMATRIX
@ AV_PKT_DATA_DISPLAYMATRIX
This side data contains a 3x3 transformation matrix describing an affine transformation that needs to...
Definition: packet.h:105
av_packet_unref
void av_packet_unref(AVPacket *pkt)
Wipe the packet.
Definition: packet.c:430
MOVContext::found_iloc
int found_iloc
'iloc' atom has been found
Definition: isom.h:320
AV_CODEC_ID_MACE6
@ AV_CODEC_ID_MACE6
Definition: codec_id.h:459
MOVFragmentStreamInfo::first_tfra_pts
int64_t first_tfra_pts
Definition: isom.h:142
ff_rfps_add_frame
int ff_rfps_add_frame(AVFormatContext *ic, AVStream *st, int64_t ts)
add frame for rfps calculation.
Definition: demux.c:2277
read_image_iovl
static int read_image_iovl(AVFormatContext *s, const HEIFGrid *grid, AVStreamGroupTileGrid *tile_grid)
Definition: mov.c:10128
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:9051
AVMEDIA_TYPE_SUBTITLE
@ AVMEDIA_TYPE_SUBTITLE
Definition: avutil.h:203
AVIAMFSubmix::elements
AVIAMFSubmixElement ** elements
Array of submix elements.
Definition: iamf.h:565
skip_bits_long
static void skip_bits_long(GetBitContext *s, int n)
Skips the specified number of bits.
Definition: get_bits.h:261
AV_LOG_WARNING
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:216
AV_BPRINT_SIZE_UNLIMITED
#define AV_BPRINT_SIZE_UNLIMITED
MOV_TFHD_DEFAULT_FLAGS
#define MOV_TFHD_DEFAULT_FLAGS
Definition: isom.h:400
PUT_UTF8
#define PUT_UTF8(val, tmp, PUT_BYTE)
Definition: common.h:541
AV_TIMECODE_STR_SIZE
#define AV_TIMECODE_STR_SIZE
Definition: timecode.h:33
av_aes_init
int av_aes_init(AVAES *a, const uint8_t *key, int key_bits, int decrypt)
Initialize an AVAES context.
Definition: aes.c:231
AV_CODEC_ID_PCM_F32BE
@ AV_CODEC_ID_PCM_F32BE
Definition: codec_id.h:356
FFStream::skip_samples
int skip_samples
Number of samples to skip at the start of the frame decoded from the next packet.
Definition: internal.h:208
MOVStreamContext::audio_cid
int16_t audio_cid
stsd audio compression id
Definition: isom.h:221
AVMasteringDisplayMetadata::max_luminance
AVRational max_luminance
Max luminance of mastering display (cd/m^2).
Definition: mastering_display_metadata.h:57
AVSphericalProjection
AVSphericalProjection
Projection of the video surface(s) on a sphere.
Definition: spherical.h:47
AV_CODEC_ID_ADPCM_MS
@ AV_CODEC_ID_ADPCM_MS
Definition: codec_id.h:381
AVCodecParameters::extradata
uint8_t * extradata
Extra binary data needed for initializing the decoder, codec-dependent.
Definition: codec_par.h:69
mov_read_dops
static int mov_read_dops(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:8306
can_seek_to_key_sample
static int can_seek_to_key_sample(AVStream *st, int sample, int64_t requested_pts)
Definition: mov.c:11120
AV_CODEC_ID_ADPCM_IMA_QT
@ AV_CODEC_ID_ADPCM_IMA_QT
Definition: codec_id.h:375
entry
#define entry
Definition: aom_film_grain_template.c:66
AVFMT_NO_BYTE_SEEK
#define AVFMT_NO_BYTE_SEEK
Format does not allow seeking by bytes.
Definition: avformat.h: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:1118
AV_CODEC_ID_AC3
@ AV_CODEC_ID_AC3
Definition: codec_id.h:452
HEIFItem::name
char * name
Definition: isom.h:291
AV_STEREO3D_VIEW_LEFT
@ AV_STEREO3D_VIEW_LEFT
Frame contains only the left view.
Definition: stereo3d.h:158
MOVStreamContext::sync_group
MOVSbgp * sync_group
Definition: isom.h:243
MOVStreamContext::height
int height
tkhd height
Definition: isom.h:229
MOVContext::moov_retry
int moov_retry
Definition: isom.h:348
MOV_TRUN_SAMPLE_FLAGS
#define MOV_TRUN_SAMPLE_FLAGS
Definition: isom.h:408
AV_PKT_DATA_AMBIENT_VIEWING_ENVIRONMENT
@ AV_PKT_DATA_AMBIENT_VIEWING_ENVIRONMENT
Ambient viewing environment metadata, as defined by H.274.
Definition: packet.h:327
MOVContext::nb_chapter_tracks
unsigned int nb_chapter_tracks
Definition: isom.h:336
mix
static int mix(int c0, int c1)
Definition: 4xm.c:717
MOVStreamContext::last_stsd_index
int last_stsd_index
Definition: isom.h:258
ff_ac3_channel_layout_tab
const uint16_t ff_ac3_channel_layout_tab[8]
Map audio coding mode (acmod) to channel layout mask.
Definition: ac3_channel_layout_tab.h:31
r
const char * r
Definition: vf_curves.c:127
AVERROR
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later. That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another. Frame references ownership and permissions
opt.h
MOV_TKHD_FLAG_ENABLED
#define MOV_TKHD_FLAG_ENABLED
Definition: isom.h:421
AVCodecParameters::codec_type
enum AVMediaType codec_type
General type of the encoded data.
Definition: codec_par.h:51
AVStreamGroup::tile_grid
struct AVStreamGroupTileGrid * tile_grid
Definition: avformat.h:1134
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
AV_STREAM_GROUP_PARAMS_LCEVC
@ AV_STREAM_GROUP_PARAMS_LCEVC
Definition: avformat.h:1093
MOVStreamContext::extradata
uint8_t ** extradata
extradata array (and size) for multiple stsd
Definition: isom.h:256
mov_class
static const AVClass mov_class
Definition: mov.c:11346
AVSphericalMapping::bound_bottom
uint32_t bound_bottom
Distance from the bottom edge.
Definition: spherical.h:182
MOVStreamContext::open_key_samples
int * open_key_samples
Definition: isom.h:248
AVUUID
uint8_t AVUUID[AV_UUID_LEN]
Definition: uuid.h:60
out
FILE * out
Definition: movenc.c:55
MOVFragmentStreamInfo
Definition: isom.h:139
AVFieldOrder
AVFieldOrder
Definition: defs.h:208
mov_read_targa_y216
static int mov_read_targa_y216(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2271
mov_read_chnl
static int mov_read_chnl(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1191
mov_read_moof
static int mov_read_moof(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1808
av_bprint_init
void av_bprint_init(AVBPrint *buf, unsigned size_init, unsigned size_max)
Definition: bprint.c:69
ctype
#define ctype
Definition: afir_template.c:46
AV_PKT_DATA_FRAME_CROPPING
@ AV_PKT_DATA_FRAME_CROPPING
The number of pixels to discard from the top/bottom/left/right border of the decoded frame to obtain ...
Definition: packet.h:340
AVCodecParameters
This struct describes the properties of an encoded stream.
Definition: codec_par.h:47
HEIFItem::icc_profile
uint8_t * icc_profile
Definition: isom.h:302
AVFMT_FLAG_IGNIDX
#define AVFMT_FLAG_IGNIDX
Ignore index.
Definition: avformat.h:1418
sanity_checks
static int sanity_checks(void *log_obj, MOVStreamContext *sc, int index)
Definition: mov.c:5082
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:9859
HEIFItem::hflip
int hflip
Definition: isom.h:298
AV_PKT_DATA_NEW_EXTRADATA
@ AV_PKT_DATA_NEW_EXTRADATA
The AV_PKT_DATA_NEW_EXTRADATA is used to notify the codec or the format that the extradata buffer was...
Definition: packet.h:56
IAMFAudioElement::nb_substreams
unsigned int nb_substreams
Definition: iamf.h:99
AVStream::priv_data
void * priv_data
Definition: avformat.h:770
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:671
AVStream::discard
enum AVDiscard discard
Selects which packets can be discarded at will and do not need to be demuxed.
Definition: avformat.h:816
AV_FIELD_PROGRESSIVE
@ AV_FIELD_PROGRESSIVE
Definition: defs.h:210
mov_options
static const AVOption mov_options[]
Definition: mov.c:11293
mov_codec_id
static int mov_codec_id(AVStream *st, uint32_t format)
Definition: mov.c:2620
AV_PKT_DATA_MASTERING_DISPLAY_METADATA
@ AV_PKT_DATA_MASTERING_DISPLAY_METADATA
Mastering display metadata (based on SMPTE-2086:2014).
Definition: packet.h:219
MOVStreamContext::sample_offsets
int32_t * sample_offsets
Definition: isom.h:246
av_int2double
static av_always_inline double av_int2double(uint64_t i)
Reinterpret a 64-bit integer as a double.
Definition: intfloat.h:60
mov_read_iloc
static int mov_read_iloc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:8697
matrix
Definition: vc1dsp.c:43
AVMasteringDisplayMetadata::display_primaries
AVRational display_primaries[3][2]
CIE 1931 xy chromaticity coords of color primaries (r, g, b order).
Definition: mastering_display_metadata.h:42
AV_PKT_FLAG_DISCARD
#define AV_PKT_FLAG_DISCARD
Flag is used to discard packets which are required to maintain valid decoder state but are not requir...
Definition: packet.h:597
AVMasteringDisplayMetadata::has_luminance
int has_luminance
Flag indicating whether the luminance (min_ and max_) have been set.
Definition: mastering_display_metadata.h:67
get_bits_long
static unsigned int get_bits_long(GetBitContext *s, int n)
Read 0-32 bits.
Definition: get_bits.h:404
int64_t
long long int64_t
Definition: coverity.c:34
output
filter_frame For filters that do not use the this method is called when a frame is pushed to the filter s input It can be called at any time except in a reentrant way If the input frame is enough to produce output
Definition: filter_design.txt:225
mov_read_alac
static int mov_read_alac(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2243
test_same_origin
static int test_same_origin(const char *src, const char *ref)
Definition: mov.c:4925
metadata
Stream codec metadata
Definition: ogg-flac-chained-meta.txt:2
cbcs_scheme_decrypt
static int cbcs_scheme_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
Definition: mov.c:8129
MOVFragment::base_data_offset
uint64_t base_data_offset
Definition: isom.h:104
MOVStreamContext
Definition: isom.h:173
AVChannelLayout::map
AVChannelCustom * map
This member must be used when the channel order is AV_CHANNEL_ORDER_CUSTOM.
Definition: channel_layout.h:370
MOVStreamContext::stsc_data
MOVStsc * stsc_data
Definition: isom.h:194
ff_buffer_packet
int ff_buffer_packet(AVFormatContext *s, AVPacket *pkt)
Definition: demux.c:613
IS_MATRIX_IDENT
#define IS_MATRIX_IDENT(matrix)
Definition: mov.c:5470
AVStreamGroup::disposition
int disposition
Stream group disposition - a combination of AV_DISPOSITION_* flags.
Definition: avformat.h:1176
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:618
mov_update_dts_shift
static void mov_update_dts_shift(MOVStreamContext *sc, int duration, void *logctx)
Definition: mov.c:3629
MOVStreamContext::spherical
AVSphericalMapping * spherical
Definition: isom.h:265
mask
int mask
Definition: mediacodecdec_common.c:154
out_size
int out_size
Definition: movenc.c:56
AV_CODEC_ID_MPEG4
@ AV_CODEC_ID_MPEG4
Definition: codec_id.h:64
AVContentLightMetadata::MaxCLL
unsigned MaxCLL
Max content light level (cd/m^2).
Definition: mastering_display_metadata.h:111
avio_get_str16be
int avio_get_str16be(AVIOContext *pb, int maxlen, char *buf, int buflen)
MOVEncryptionIndex
Definition: isom.h:126
av_encryption_init_info_free
void av_encryption_init_info_free(AVEncryptionInitInfo *info)
Frees the given encryption init info object.
Definition: encryption_info.c:216
mov_read_avss
static int mov_read_avss(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2248
AV_RB32A
#define AV_RB32A(p)
Definition: intreadwrite.h:575
MOVContext::primary_item_id
int primary_item_id
Definition: isom.h:373
mode
Definition: swscale.c:56
MOVContext::found_moov
int found_moov
'moov' atom has been found
Definition: isom.h:319
ff_iamf_read_packet
int ff_iamf_read_packet(AVFormatContext *s, IAMFDemuxContext *c, AVIOContext *pb, int max_size, int stream_id_offset, AVPacket *pkt)
Definition: iamf_reader.c:279
mov_read_custom
static int mov_read_custom(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5314
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:1333
HEIFGrid::nb_tiles
int nb_tiles
Definition: isom.h:311
ID3v1_GENRE_MAX
#define ID3v1_GENRE_MAX
Definition: id3v1.h:29
MOVSbgp
Definition: isom.h:121
MOVCtts
Definition: isom.h:68
AVPacketSideData
This structure stores auxiliary information for decoding, presenting, or otherwise processing the cod...
Definition: packet.h:386
mov_read_extradata
static int mov_read_extradata(MOVContext *c, AVIOContext *pb, MOVAtom atom, enum AVCodecID codec_id)
Definition: mov.c:2217
AVCOL_RANGE_JPEG
@ AVCOL_RANGE_JPEG
Full range content.
Definition: pixfmt.h:750
mpegaudiodecheader.h
MOVStreamContext::rap_group_count
unsigned int rap_group_count
Definition: isom.h:240
av_display_matrix_flip
void av_display_matrix_flip(int32_t matrix[9], int hflip, int vflip)
Flip the input matrix horizontally and/or vertically.
Definition: display.c:66
av_sha_init
av_cold int av_sha_init(AVSHA *ctx, int bits)
Initialize SHA-1 or SHA-2 hashing.
Definition: sha.c:274
HEIFItem::type
int type
Definition: isom.h:300
mov_read_mvhd
static int mov_read_mvhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1910
mov_read_idat
static int mov_read_idat(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:8691
AVPacket::data
uint8_t * data
Definition: packet.h:535
MOVContext::found_mdat
int found_mdat
'mdat' atom has been found
Definition: isom.h:322
MOVStreamContext::drefs_count
unsigned drefs_count
Definition: isom.h:222
AVEncryptionInfo::crypt_byte_block
uint32_t crypt_byte_block
Only used for pattern encryption.
Definition: encryption_info.h:51
AV_PKT_DATA_ENCRYPTION_INIT_INFO
@ AV_PKT_DATA_ENCRYPTION_INIT_INFO
This side data is encryption initialization data.
Definition: packet.h:246
mov_read_avid
static int mov_read_avid(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2263
AVAmbientViewingEnvironment::ambient_light_x
AVRational ambient_light_x
Normalized x chromaticity coordinate of the environmental ambient light in the nominal viewing enviro...
Definition: ambient_viewing_environment.h:47
AVCodecParameters::seek_preroll
int seek_preroll
Audio only.
Definition: codec_par.h:214
av_dynarray2_add
void * av_dynarray2_add(void **tab_ptr, int *nb_ptr, size_t elem_size, const uint8_t *elem_data)
Add an element of size elem_size to a dynamic array.
Definition: mem.c:343
AVOption
AVOption.
Definition: opt.h:429
MOVContext::trex_data
MOVTrackExt * trex_data
Definition: isom.h:331
mov_read_stps
static int mov_read_stps(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:3286
MOVContext::bitrates
int * bitrates
bitrates read before streams creation
Definition: isom.h:346
b
#define b
Definition: input.c:42
MOVStreamContext::cenc
struct MOVStreamContext::@424 cenc
AVCOL_TRC_UNSPECIFIED
@ AVCOL_TRC_UNSPECIFIED
Definition: pixfmt.h:647
MOVContext::interleaved_read
int interleaved_read
Definition: isom.h:381
mov_read_tkhd
static int mov_read_tkhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5478
MOVElst::rate
float rate
Definition: isom.h:82
AVStream::avg_frame_rate
AVRational avg_frame_rate
Average framerate.
Definition: avformat.h:834
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:2064
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:1949
mov_read_strf
static int mov_read_strf(MOVContext *c, AVIOContext *pb, MOVAtom atom)
An strf atom is a BITMAPINFOHEADER struct.
Definition: mov.c:2533
AV_CODEC_ID_ALAC
@ AV_CODEC_ID_ALAC
Definition: codec_id.h:465
HEIFItem::st
AVStream * st
Definition: isom.h:290
FF_COMPLIANCE_STRICT
#define FF_COMPLIANCE_STRICT
Strictly conform to all the things in the spec no matter what consequences.
Definition: defs.h:59
AVIOContext::error
int error
contains the error code or 0 if no error happened
Definition: avio.h:239
AV_CODEC_ID_AMR_NB
@ AV_CODEC_ID_AMR_NB
Definition: codec_id.h:430
av_iamf_mix_presentation_free
void av_iamf_mix_presentation_free(AVIAMFMixPresentation **pmix_presentation)
Free an AVIAMFMixPresentation and all its contents.
Definition: iamf.c:534
mov_parse_auxiliary_info
static int mov_parse_auxiliary_info(MOVContext *c, MOVStreamContext *sc, AVIOContext *pb, MOVEncryptionIndex *encryption_index)
Definition: mov.c:7447
mov_seek_stream
static int mov_seek_stream(AVFormatContext *s, AVStream *st, int64_t timestamp, int flags)
Definition: mov.c:11146
mov_read_saio
static int mov_read_saio(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:7593
mov_get_stsc_samples
static int64_t mov_get_stsc_samples(MOVStreamContext *sc, unsigned int index)
Definition: mov.c:3271
AV_LOG_VERBOSE
#define AV_LOG_VERBOSE
Detailed information.
Definition: log.h:226
ff_codec_wav_tags
const AVCodecTag ff_codec_wav_tags[]
Definition: riff.c:530
get_edit_list_entry
static int get_edit_list_entry(MOVContext *mov, const MOVStreamContext *msc, unsigned int edit_list_index, int64_t *edit_list_media_time, int64_t *edit_list_duration, int64_t global_timescale)
Get ith edit list entry (media time, duration).
Definition: mov.c:3838
MOVFragmentIndexItem::moof_offset
int64_t moof_offset
Definition: isom.h:153
MOVStreamContext::spherical_size
size_t spherical_size
Definition: isom.h:266
mov_change_extradata
static int mov_change_extradata(AVStream *st, AVPacket *pkt)
Definition: mov.c:10764
MOVStreamContext::tref_id
int tref_id
Definition: isom.h:226
MP4TrackKindMapping::scheme_uri
const char * scheme_uri
Definition: isom.h:483
AVINDEX_DISCARD_FRAME
#define AVINDEX_DISCARD_FRAME
Definition: avformat.h:608
av_display_rotation_set
void av_display_rotation_set(int32_t matrix[9], double angle)
Initialize a transformation matrix describing a pure clockwise rotation by the specified angle (in de...
Definition: display.c:51
AVPacket::duration
int64_t duration
Duration of this packet in AVStream->time_base units, 0 if unknown.
Definition: packet.h:553
AVCodecParameters::codec_tag
uint32_t codec_tag
Additional information about the codec (corresponds to the AVI FOURCC).
Definition: codec_par.h:59
fixed_key
static const uint8_t fixed_key[]
Definition: aes_ctr.c:40
AV_SPHERICAL_EQUIRECTANGULAR_TILE
@ AV_SPHERICAL_EQUIRECTANGULAR_TILE
Video represents a portion of a sphere mapped on a flat surface using equirectangular projection.
Definition: spherical.h:68
AVStereo3D::baseline
uint32_t baseline
The distance between the centres of the lenses of the camera system, in micrometers.
Definition: stereo3d.h:228
MOVDref::dir
char * dir
Definition: isom.h:88
mov_current_sample_set
static void mov_current_sample_set(MOVStreamContext *sc, int current_sample)
Definition: mov.c:4142
mathematics.h
AVDictionary
Definition: dict.c:32
ffio_init_read_context
void ffio_init_read_context(FFIOContext *s, const uint8_t *buffer, int buffer_size)
Wrap a buffer in an AVIOContext for reading.
Definition: aviobuf.c:99
AV_PKT_FLAG_DISPOSABLE
#define AV_PKT_FLAG_DISPOSABLE
Flag is used to indicate packets that contain frames that can be discarded by the decoder.
Definition: packet.h:609
AVProbeData::buf_size
int buf_size
Size of buf except extra allocated bytes.
Definition: avformat.h:454
AVChannelLayout::order
enum AVChannelOrder order
Channel order used in this layout.
Definition: channel_layout.h:324
FFMAX
#define FFMAX(a, b)
Definition: macros.h:47
MOVAtom
Definition: isom.h:94
AVStreamGroupTileGrid::vertical
int vertical
Offset in pixels from the top edge of the canvas where the tile should be placed.
Definition: avformat.h:1001
iamf_parse.h
mov_read_moov
static int mov_read_moov(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1560
av_sub_q
AVRational av_sub_q(AVRational b, AVRational c)
Subtract one rational from another.
Definition: rational.c:101
cffstream
static const av_always_inline FFStream * cffstream(const AVStream *st)
Definition: internal.h:352
mov_read_esds
static int mov_read_esds(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:846
MOVStreamContext::sample_count
unsigned int sample_count
Definition: isom.h:205
MOVFragmentIndex::allocated_size
int allocated_size
Definition: isom.h:161
MOVTrackExt::flags
unsigned flags
Definition: isom.h:118
AVChannelLayout::nb_channels
int nb_channels
Number of channels in this layout.
Definition: channel_layout.h:329
HEIFItem::height
int height
Definition: isom.h:296
AV_SPHERICAL_EQUIRECTANGULAR
@ AV_SPHERICAL_EQUIRECTANGULAR
Video represents a sphere mapped on a flat surface using equirectangular projection.
Definition: spherical.h:52
intfloat.h
id3v1.h
MOVStreamContext::ctts_data
MOVCtts * ctts_data
Definition: isom.h:192
ff_dvdclut_yuv_to_rgb
int ff_dvdclut_yuv_to_rgb(uint32_t *clut, const size_t clut_size)
Definition: dvdclut.c:50
AV_CODEC_ID_R10K
@ AV_CODEC_ID_R10K
Definition: codec_id.h:197
heif_cur_item
static HEIFItem * heif_cur_item(MOVContext *c)
Get the current item in the parsing process.
Definition: mov.c:193
av_encryption_init_info_get_side_data
AVEncryptionInitInfo * av_encryption_init_info_get_side_data(const uint8_t *side_data, size_t side_data_size)
Creates a copy of the AVEncryptionInitInfo that is contained in the given side data.
Definition: encryption_info.c:231
AV_STEREO3D_VIEW_RIGHT
@ AV_STEREO3D_VIEW_RIGHT
Frame contains only the right view.
Definition: stereo3d.h:163
MOVContext::advanced_editlist_autodisabled
int advanced_editlist_autodisabled
Definition: isom.h:340
avio_size
int64_t avio_size(AVIOContext *s)
Get the filesize.
Definition: aviobuf.c:323
av_strlcatf
size_t av_strlcatf(char *dst, size_t size, const char *fmt,...)
Definition: avstring.c:103
mov_read_stco
static int mov_read_stco(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2555
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:6966
FFIOContext
Definition: avio_internal.h:28
AV_PKT_FLAG_KEY
#define AV_PKT_FLAG_KEY
The packet contains a keyframe.
Definition: packet.h:590
init_get_bits
static int init_get_bits(GetBitContext *s, const uint8_t *buffer, int bit_size)
Initialize GetBitContext.
Definition: get_bits.h:497
MOVStreamContext::aes_ctr
struct AVAESCTR * aes_ctr
Definition: isom.h:278
cenc_filter
static int cenc_filter(MOVContext *mov, AVStream *st, MOVStreamContext *sc, AVPacket *pkt, int current_index)
Definition: mov.c:8236
mov_read_sdtp
static int mov_read_sdtp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:3595
mov_read_jp2h
static int mov_read_jp2h(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2253
AV_STEREO3D_UNSPEC
@ AV_STEREO3D_UNSPEC
Video is stereoscopic but the packing is unspecified.
Definition: stereo3d.h:143
AVIndexEntry
Definition: avformat.h:599
AV_WB64
#define AV_WB64(p, v)
Definition: intreadwrite.h:429
MOVStreamContext::dv_audio_container
int dv_audio_container
Definition: isom.h:219
AV_CODEC_ID_AMR_WB
@ AV_CODEC_ID_AMR_WB
Definition: codec_id.h:431
mov_read_tfhd
static int mov_read_tfhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5583
AV_CODEC_ID_BIN_DATA
@ AV_CODEC_ID_BIN_DATA
Definition: codec_id.h:600
av_malloc
#define av_malloc(s)
Definition: tableprint_vlc.h:31
OPUS_SEEK_PREROLL_MS
#define OPUS_SEEK_PREROLL_MS
Definition: oggparseopus.c:36
AV_CODEC_ID_H261
@ AV_CODEC_ID_H261
Definition: codec_id.h:55
IAMFMixPresentation::cmix
const AVIAMFMixPresentation * cmix
Definition: iamf.h:108
mov_read_wide
static int mov_read_wide(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6162
AVINDEX_KEYFRAME
#define AVINDEX_KEYFRAME
Definition: avformat.h:607
AV_FIELD_BT
@ AV_FIELD_BT
Bottom coded first, top displayed first.
Definition: defs.h:214
MOVStreamContext::stsd_count
int stsd_count
Definition: isom.h:259
ff_mov_lang_to_iso639
int ff_mov_lang_to_iso639(unsigned code, char to[4])
Definition: isom.c:260
ff_generate_avci_extradata
int ff_generate_avci_extradata(AVStream *st)
Generate standard extradata for AVC-Intra based on width/height and field order.
Definition: demux_utils.c:191
ff_get_extradata
int ff_get_extradata(void *logctx, AVCodecParameters *par, AVIOContext *pb, int size)
Allocate extradata with additional AV_INPUT_BUFFER_PADDING_SIZE at end which is always set to 0 and f...
Definition: demux_utils.c:326
AVStereo3D::horizontal_field_of_view
AVRational horizontal_field_of_view
Horizontal field of view, in degrees.
Definition: stereo3d.h:239
skip_bits
static void skip_bits(GetBitContext *s, int n)
Definition: get_bits.h:364
AVCodecParameters::color_primaries
enum AVColorPrimaries color_primaries
Definition: codec_par.h:167
AVEncryptionInfo::scheme
uint32_t scheme
The fourcc encryption scheme, in big-endian byte order.
Definition: encryption_info.h:45
MOVStreamContext::stsc_count
unsigned int stsc_count
Definition: isom.h:193
MOVStreamContext::has_palette
int has_palette
Definition: isom.h:234
AVPROBE_SCORE_MAX
#define AVPROBE_SCORE_MAX
maximum score
Definition: avformat.h:463
AV_STEREO3D_SIDEBYSIDE
@ AV_STEREO3D_SIDEBYSIDE
Views are next to each other.
Definition: stereo3d.h:64
MOVIndexRange::start
int64_t start
Definition: isom.h:169
AVPacketSideData::size
size_t size
Definition: packet.h:388
get_bits
static unsigned int get_bits(GetBitContext *s, int n)
Read 1-25 bits.
Definition: get_bits.h:318
ff_remove_stream
void ff_remove_stream(AVFormatContext *s, AVStream *st)
Remove a stream from its AVFormatContext and free it.
Definition: avformat.c:113
OFFSET
#define OFFSET(x)
Definition: mov.c:11291
HEIFGrid::tile_item_list
HEIFItem ** tile_item_list
Definition: isom.h:308
set_icc_profile_from_item
static int set_icc_profile_from_item(AVPacketSideData **coded_side_data, int *nb_coded_side_data, const HEIFItem *item)
Definition: mov.c:9994
AV_FIELD_TT
@ AV_FIELD_TT
Top coded_first, top displayed first.
Definition: defs.h:211
AV_STEREO3D_VIEW_PACKED
@ AV_STEREO3D_VIEW_PACKED
Frame contains two packed views.
Definition: stereo3d.h:153
MOVStreamContext::nb_frames_for_fps
int nb_frames_for_fps
Definition: isom.h:252
avpriv_dv_produce_packet
int avpriv_dv_produce_packet(DVDemuxContext *c, AVPacket *pkt, uint8_t *buf, int buf_size, int64_t pos)
Definition: dv.c:736
avpriv_set_pts_info
void avpriv_set_pts_info(AVStream *st, int pts_wrap_bits, unsigned int pts_num, unsigned int pts_den)
Set the time base and wrapping info for a given stream.
Definition: avformat.c:777
FF_DVDCLUT_CLUT_LEN
#define FF_DVDCLUT_CLUT_LEN
Definition: dvdclut.h:28
AVEncryptionInfo::skip_byte_block
uint32_t skip_byte_block
Only used for pattern encryption.
Definition: encryption_info.h:57
finish
static void finish(void)
Definition: movenc.c:374
aax_filter
static int aax_filter(uint8_t *input, int size, MOVContext *c)
Definition: mov.c:1498
AV_OPT_TYPE_BINARY
@ AV_OPT_TYPE_BINARY
Underlying C type is a uint8_t* that is either NULL or points to an array allocated with the av_mallo...
Definition: opt.h:286
av_color_space_name
const char * av_color_space_name(enum AVColorSpace space)
Definition: pixdesc.c:3717
av_packet_add_side_data
int av_packet_add_side_data(AVPacket *pkt, enum AVPacketSideDataType type, uint8_t *data, size_t size)
Wrap an existing array as a packet side data.
Definition: packet.c:198
MOVStreamContext::mastering
AVMasteringDisplayMetadata * mastering
Definition: isom.h:267
AV_CODEC_ID_SPEEX
@ AV_CODEC_ID_SPEEX
Definition: codec_id.h:484
AV_FOURCC_MAX_STRING_SIZE
#define AV_FOURCC_MAX_STRING_SIZE
Definition: avutil.h:345
AV_PKT_DATA_PALETTE
@ AV_PKT_DATA_PALETTE
An AV_PKT_DATA_PALETTE side data packet contains exactly AVPALETTE_SIZE bytes worth of palette.
Definition: packet.h:47
ffstream
static av_always_inline FFStream * ffstream(AVStream *st)
Definition: internal.h:347
MOVFragmentIndexItem::current
int current
Definition: isom.h:155
AVFMT_SEEK_TO_PTS
#define AVFMT_SEEK_TO_PTS
Seeking is based on PTS.
Definition: avformat.h:500
AV_CODEC_ID_PCM_S16BE
@ AV_CODEC_ID_PCM_S16BE
Definition: codec_id.h:337
mov_read_mdhd
static int mov_read_mdhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1864
mov_read_ctts
static int mov_read_ctts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:3640
MOVTrackExt
Definition: isom.h:113
MOV_FRAG_SAMPLE_FLAG_IS_NON_SYNC
#define MOV_FRAG_SAMPLE_FLAG_IS_NON_SYNC
Definition: isom.h:412
fail
#define fail()
Definition: checkasm.h:196
mov_read_aclr
static int mov_read_aclr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2328
AVSEEK_FLAG_ANY
#define AVSEEK_FLAG_ANY
seek to any frame, even non-keyframes
Definition: avformat.h:2377
av_int2float
static av_always_inline float av_int2float(uint32_t i)
Reinterpret a 32-bit integer as a float.
Definition: intfloat.h:40
MOVFragment::found_tfhd
int found_tfhd
Definition: isom.h:102
AVStreamGroupTileGrid
AVStreamGroupTileGrid holds information on how to combine several independent images on a single canv...
Definition: avformat.h:952
MOVContext::decryption_key
uint8_t * decryption_key
Definition: isom.h:366
FF_DVDCLUT_CLUT_SIZE
#define FF_DVDCLUT_CLUT_SIZE
Definition: dvdclut.h:29
AV_STEREO3D_2D
@ AV_STEREO3D_2D
Video is not stereoscopic (and metadata has to be there).
Definition: stereo3d.h:52
read_seek
static int read_seek(AVFormatContext *ctx, int stream_index, int64_t timestamp, int flags)
Definition: libcdio.c:151
HEIFItem::item_id
int item_id
Definition: isom.h:292
av_shrink_packet
void av_shrink_packet(AVPacket *pkt, int size)
Reduce packet size, correctly zeroing padding.
Definition: packet.c:114
timecode.h
get_current_frag_stream_info
static MOVFragmentStreamInfo * get_current_frag_stream_info(MOVFragmentIndex *frag_index)
Definition: mov.c:1617
GetBitContext
Definition: get_bits.h:108
MOVStreamContext::mastering_size
size_t mastering_size
Definition: isom.h:268
AVStreamGroupTileGrid::coded_width
int coded_width
Width of the canvas.
Definition: avformat.h:967
av_iamf_audio_element_free
void av_iamf_audio_element_free(AVIAMFAudioElement **paudio_element)
Free an AVIAMFAudioElement and all its contents.
Definition: iamf.c:336
FFStream::index_entries_allocated_size
unsigned int index_entries_allocated_size
Definition: internal.h:187
read_close
static av_cold int read_close(AVFormatContext *ctx)
Definition: libcdio.c:143
mov_read_amve
static int mov_read_amve(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6521
mov_read_enda
static int mov_read_enda(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1978
mov_read_chap
static int mov_read_chap(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5630
MOVParseTableEntry
Definition: mov.c:81
avio_tell
static av_always_inline int64_t avio_tell(AVIOContext *s)
ftell() equivalent for AVIOContext.
Definition: avio.h:494
MOV_TRUN_SAMPLE_DURATION
#define MOV_TRUN_SAMPLE_DURATION
Definition: isom.h:406
val
static double val(void *priv, double ch)
Definition: aeval.c:77
set_display_matrix_from_item
static int set_display_matrix_from_item(AVPacketSideData **coded_side_data, int *nb_coded_side_data, const HEIFItem *item)
Definition: mov.c:10008
type
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf type
Definition: writing_filters.txt:86
MOVContext
Definition: isom.h:314
AV_DISPOSITION_TIMED_THUMBNAILS
#define AV_DISPOSITION_TIMED_THUMBNAILS
The stream is sparse, and contains thumbnail images, often corresponding to chapter markers.
Definition: avformat.h:676
AVStreamGroupTileGrid::coded_height
int coded_height
Width of the canvas.
Definition: avformat.h:973
pts
static int64_t pts
Definition: transcode_aac.c:644
MOVStreamContext::v_spacing
int v_spacing
pasp vSpacing
Definition: isom.h:231
AVEncryptionInfo::iv
uint8_t * iv
The initialization vector.
Definition: encryption_info.h:71
AV_CODEC_ID_MP3
@ AV_CODEC_ID_MP3
preferred ID for decoding MPEG audio layer 1, 2 or 3
Definition: codec_id.h:450
AVStream::duration
int64_t duration
Decoding: duration of the stream, in stream time base.
Definition: avformat.h:804
AVAmbientViewingEnvironment::ambient_illuminance
AVRational ambient_illuminance
Environmental illuminance of the ambient viewing environment in lux.
Definition: ambient_viewing_environment.h:40
ss
#define ss(width, name, subs,...)
Definition: cbs_vp9.c:202
MOVStreamContext::width
int width
tkhd width
Definition: isom.h:228
MOVContext::meta_keys
char ** meta_keys
Definition: isom.h:325
av_reduce
int av_reduce(int *dst_num, int *dst_den, int64_t num, int64_t den, int64_t max)
Reduce a fraction.
Definition: rational.c:35
MOVStreamContext::extradata_size
int * extradata_size
Definition: isom.h:257
AVIAMFAudioElement::audio_element_type
enum AVIAMFAudioElementType audio_element_type
Audio element type as defined in section 3.6 of IAMF.
Definition: iamf.h:388
loop
static int loop
Definition: ffplay.c:335
ff_data_to_hex
char * ff_data_to_hex(char *buf, const uint8_t *src, int size, int lowercase)
Write hexadecimal string corresponding to given binary data.
Definition: utils.c:451
update_frag_index
static int update_frag_index(MOVContext *c, int64_t offset)
Definition: mov.c:1732
AVRational::num
int num
Numerator.
Definition: rational.h:59
MOVStreamContext::keyframes
int * keyframes
Definition: isom.h:209
MOVEncryptionIndex::auxiliary_info_sample_count
size_t auxiliary_info_sample_count
Definition: isom.h:133
AV_FIELD_TB
@ AV_FIELD_TB
Top coded first, bottom displayed first.
Definition: defs.h:213
AVStream::attached_pic
AVPacket attached_pic
For streams with AV_DISPOSITION_ATTACHED_PIC disposition, this packet will contain the attached pictu...
Definition: avformat.h:843
MOVStsc::id
int id
Definition: isom.h:76
mov_read_saiz
static int mov_read_saiz(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:7509
MOV_FRAG_SAMPLE_FLAG_DEPENDS_YES
#define MOV_FRAG_SAMPLE_FLAG_DEPENDS_YES
Definition: isom.h:419
mov_merge_tts_data
static int mov_merge_tts_data(MOVContext *mov, AVStream *st, int flags)
Definition: mov.c:4553
MOVContext::idat_offset
int64_t idat_offset
Definition: isom.h:380
MOV_TRUN_DATA_OFFSET
#define MOV_TRUN_DATA_OFFSET
Definition: isom.h:404
av_encryption_info_clone
AVEncryptionInfo * av_encryption_info_clone(const AVEncryptionInfo *info)
Allocates an AVEncryptionInfo structure with a copy of the given data.
Definition: encryption_info.c:65
av_ambient_viewing_environment_alloc
AVAmbientViewingEnvironment * av_ambient_viewing_environment_alloc(size_t *size)
Allocate an AVAmbientViewingEnvironment structure.
Definition: ambient_viewing_environment.c:31
AV_DICT_DONT_STRDUP_VAL
#define AV_DICT_DONT_STRDUP_VAL
Take ownership of a value that's been allocated with av_malloc() or another memory allocation functio...
Definition: dict.h:79
IAMFAudioElement::element
AVIAMFAudioElement * element
element backs celement iff the AVIAMFAudioElement is owned by this structure.
Definition: iamf.h:95
MOVStreamContext::elst_data
MOVElst * elst_data
Definition: isom.h:199
mov_read_ares
static int mov_read_ares(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2285
mov_read_adrm
static int mov_read_adrm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1374
av_get_bits_per_sample
int av_get_bits_per_sample(enum AVCodecID codec_id)
Return codec bits per sample.
Definition: utils.c:547
AVCodecParameters::color_trc
enum AVColorTransferCharacteristic color_trc
Definition: codec_par.h:168
IAMFContext::audio_elements
IAMFAudioElement ** audio_elements
Definition: iamf.h:131
MOVFragmentIndex::complete
int complete
Definition: isom.h:162
AV_CODEC_ID_PCM_S8
@ AV_CODEC_ID_PCM_S8
Definition: codec_id.h:340
avassert.h
avio_rb32
unsigned int avio_rb32(AVIOContext *s)
Definition: aviobuf.c:761
AV_LOG_TRACE
#define AV_LOG_TRACE
Extremely verbose debugging, useful for libav* development.
Definition: log.h:236
MOVStreamContext::stsc_sample
int stsc_sample
Definition: isom.h:196
pkt
AVPacket * pkt
Definition: movenc.c:60
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:210
AV_CODEC_ID_MACE3
@ AV_CODEC_ID_MACE3
Definition: codec_id.h:458
MOVTrackExt::track_id
unsigned track_id
Definition: isom.h:114
mov_free_encryption_index
static void mov_free_encryption_index(MOVEncryptionIndex **index)
Definition: mov.c:9731
AV_CH_LOW_FREQUENCY
#define AV_CH_LOW_FREQUENCY
Definition: channel_layout.h:178
duration
int64_t duration
Definition: movenc.c:65
MOVEncryptionIndex::auxiliary_offsets
uint64_t * auxiliary_offsets
Absolute seek position.
Definition: isom.h:135
read_packet
static int read_packet(void *opaque, uint8_t *buf, int buf_size)
Definition: avio_read_callback.c:42
AV_FIELD_UNKNOWN
@ AV_FIELD_UNKNOWN
Definition: defs.h:209
MOVStreamContext::dts_shift
int dts_shift
dts shift when ctts is negative
Definition: isom.h:232
av_timecode_init
int av_timecode_init(AVTimecode *tc, AVRational rate, int flags, int frame_start, void *log_ctx)
Init a timecode struct with the passed parameters.
Definition: timecode.c:201
AVCodecParameters::frame_size
int frame_size
Audio only.
Definition: codec_par.h:195
avio_get_str16le
int avio_get_str16le(AVIOContext *pb, int maxlen, char *buf, int buflen)
Read a UTF-16 string from pb and convert it to UTF-8.
mov_metadata_track_or_disc_number
static int mov_metadata_track_or_disc_number(MOVContext *c, AVIOContext *pb, unsigned len, const char *key)
Definition: mov.c:90
av_dict_get
AVDictionaryEntry * av_dict_get(const AVDictionary *m, const char *key, const AVDictionaryEntry *prev, int flags)
Get a dictionary entry with matching key.
Definition: dict.c:60
AES_CTR_KEY_SIZE
#define AES_CTR_KEY_SIZE
Definition: aes_ctr.h:35
MOVStreamContext::stsd_version
int stsd_version
Definition: isom.h:260
AV_STREAM_GROUP_PARAMS_IAMF_MIX_PRESENTATION
@ AV_STREAM_GROUP_PARAMS_IAMF_MIX_PRESENTATION
Definition: avformat.h:1091
ff_add_attached_pic
int ff_add_attached_pic(AVFormatContext *s, AVStream *st, AVIOContext *pb, AVBufferRef **buf, int size)
Add an attached pic to an AVStream.
Definition: demux_utils.c:107
AVStreamGroupTileGrid::offsets
struct AVStreamGroupTileGrid::@392 * offsets
An nb_tiles sized array of offsets in pixels from the topleft edge of the canvas, indicating where ea...
add_tts_entry
static int add_tts_entry(MOVTimeToSample **tts_data, unsigned int *tts_count, unsigned int *allocated_size, int count, int offset, unsigned int duration)
Definition: mov.c:4033
av_fast_realloc
void * av_fast_realloc(void *ptr, unsigned int *size, size_t min_size)
Reallocate the given buffer if it is not large enough, otherwise do nothing.
Definition: mem.c:497
FF_MOV_FLAG_MFRA_PTS
#define FF_MOV_FLAG_MFRA_PTS
Definition: isom.h:456
MOV_MERGE_STTS
#define MOV_MERGE_STTS
Definition: mov.c:4547
MOVStreamContext::iamf_stream_offset
int iamf_stream_offset
Definition: isom.h:286
ff_mov_read_esds
int ff_mov_read_esds(AVFormatContext *fc, AVIOContext *pb)
Definition: mov_esds.c:23
stereo3d.h
AVMasteringDisplayMetadata::white_point
AVRational white_point[2]
CIE 1931 xy chromaticity coords of white point.
Definition: mastering_display_metadata.h:47
intreadwrite.h
mov_read_coll
static int mov_read_coll(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6455
s
#define s(width, name)
Definition: cbs_vp9.c:198
MOVFragmentStreamInfo::encryption_index
MOVEncryptionIndex * encryption_index
Definition: isom.h:148
mov_read_trak
static int mov_read_trak(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5100
IAMFSubStream::audio_substream_id
unsigned int audio_substream_id
Definition: iamf.h:83
MOVContext::fc
AVFormatContext * fc
Definition: isom.h:316
MOV_TFHD_DEFAULT_BASE_IS_MOOF
#define MOV_TFHD_DEFAULT_BASE_IS_MOOF
Definition: isom.h:402
av_new_packet
int av_new_packet(AVPacket *pkt, int size)
Allocate the payload of a packet and initialize its fields with default values.
Definition: packet.c:99
AV_CODEC_ID_BMP
@ AV_CODEC_ID_BMP
Definition: codec_id.h:130
AV_CODEC_ID_EVC
@ AV_CODEC_ID_EVC
Definition: codec_id.h:325
IAMFLayer::substream_count
unsigned int substream_count
Definition: iamf.h:78
MOV_TFHD_DEFAULT_DURATION
#define MOV_TFHD_DEFAULT_DURATION
Definition: isom.h:398
ALAC_EXTRADATA_SIZE
#define ALAC_EXTRADATA_SIZE
DRM_BLOB_SIZE
#define DRM_BLOB_SIZE
Definition: mov.c:1372
MOVStreamContext::sample_offsets_count
int sample_offsets_count
Definition: isom.h:247
MOVCtts::count
unsigned int count
Definition: isom.h:69
MOVStreamContext::drefs
MOVDref * drefs
Definition: isom.h:223
av_realloc_array
void * av_realloc_array(void *ptr, size_t nmemb, size_t size)
Definition: mem.c:217
AVInputFormat::name
const char * name
A comma separated list of short names for the format.
Definition: avformat.h:550
MOVContext::aes_decrypt
struct AVAES * aes_decrypt
Definition: isom.h:365
AVProbeData::buf
unsigned char * buf
Buffer must have AVPROBE_PADDING_SIZE of extra allocated bytes filled with zero.
Definition: avformat.h:453
AVSphericalMapping::bound_top
uint32_t bound_top
Distance from the top edge.
Definition: spherical.h:180
AVMEDIA_TYPE_AUDIO
@ AVMEDIA_TYPE_AUDIO
Definition: avutil.h:201
AV_CODEC_ID_VP9
@ AV_CODEC_ID_VP9
Definition: codec_id.h:222
MOVFragmentIndex::nb_items
int nb_items
Definition: isom.h:164
AVCodecParameters::width
int width
Video only.
Definition: codec_par.h:134
MOVTimeToSample
Definition: isom.h:57
AV_CHANNEL_ORDER_UNSPEC
@ AV_CHANNEL_ORDER_UNSPEC
Only the channel count is specified, without any further information about the channel order.
Definition: channel_layout.h:119
AV_CODEC_ID_MP2
@ AV_CODEC_ID_MP2
Definition: codec_id.h:449
HEIFGrid::tile_idx_list
unsigned * tile_idx_list
Definition: isom.h:310
MOV_TRUN_FIRST_SAMPLE_FLAGS
#define MOV_TRUN_FIRST_SAMPLE_FLAGS
Definition: isom.h:405
av_q2d
static double av_q2d(AVRational a)
Convert an AVRational to a double.
Definition: rational.h:104
AVIndexEntry::size
int size
Definition: avformat.h:610
av_channel_layout_from_mask
int av_channel_layout_from_mask(AVChannelLayout *channel_layout, uint64_t mask)
Initialize a native channel layout from a bitmask indicating which channels are present.
Definition: channel_layout.c:252
MOVStreamContext::keyframe_absent
int keyframe_absent
Definition: isom.h:207
info
MIPS optimizations info
Definition: mips.txt:2
MOVStts::duration
unsigned int duration
Definition: isom.h:65
fc
#define fc(width, name, range_min, range_max)
Definition: cbs_av1.c:493
MOVStreamContext::coll_size
size_t coll_size
Definition: isom.h:270
tile_rows
int tile_rows
Definition: h265_levels.c:217
mov_estimate_video_delay
static void mov_estimate_video_delay(MOVContext *c, AVStream *st)
Definition: mov.c:4062
AVIndexEntry::timestamp
int64_t timestamp
Timestamp in AVStream.time_base units, preferably the time from which on correctly decoded frames are...
Definition: avformat.h:601
av_assert0
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:41
MOVStreamContext::min_corrected_pts
int64_t min_corrected_pts
minimum Composition time shown by the edits excluding empty edits.
Definition: isom.h:212
ffio_read_leb
unsigned int ffio_read_leb(AVIOContext *s)
Read a unsigned integer coded as a variable number of up to eight little-endian bytes,...
Definition: aviobuf.c:927
AVStreamGroup::params
union AVStreamGroup::@393 params
Group type-specific parameters.
tile_cols
int tile_cols
Definition: av1_levels.c:73
MOVStreamContext::sdtp_count
unsigned int sdtp_count
Definition: isom.h:188
dvdclut.h
mov_read_lhvc
static int mov_read_lhvc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:8410
AV_LOG_DEBUG
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:231
AVPacketSideData::data
uint8_t * data
Definition: packet.h:387
ctx
AVFormatContext * ctx
Definition: movenc.c:49
hevc.h
get_bits.h
limits.h
mov_read_sidx
static int mov_read_sidx(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6024
AV_PKT_DATA_STEREO3D
@ AV_PKT_DATA_STEREO3D
This side data should be associated with a video stream and contains Stereoscopic 3D information in f...
Definition: packet.h:111
nb_streams
static int nb_streams
Definition: ffprobe.c:334
av_rescale_q
int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq)
Rescale a 64-bit integer by 2 rational numbers.
Definition: mathematics.c:142
ff_iamfdec_read_descriptors
int ff_iamfdec_read_descriptors(IAMFContext *c, AVIOContext *pb, int max_size, void *log_ctx)
Definition: iamf_parse.c:1095
FFStream::display_aspect_ratio
AVRational display_aspect_ratio
display aspect ratio (0 if unknown)
Definition: internal.h:296
IAMFContext::nb_mix_presentations
int nb_mix_presentations
Definition: iamf.h:134
mov_find_next_sample
static AVIndexEntry * mov_find_next_sample(AVFormatContext *s, AVStream **st)
Definition: mov.c:10691
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:611
mov_read_dvcc_dvvc
static int mov_read_dvcc_dvvc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:8390
MOVParseTableEntry::parse
int(* parse)(MOVContext *ctx, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:83
codec_id
enum AVCodecID codec_id
Definition: vaapi_decode.c:410
AV_CODEC_ID_SVQ3
@ AV_CODEC_ID_SVQ3
Definition: codec_id.h:75
key
const char * key
Definition: hwcontext_opencl.c:189
AVCodecParameters::nb_coded_side_data
int nb_coded_side_data
Amount of entries in coded_side_data.
Definition: codec_par.h:86
MOVStreamContext::sdtp_data
uint8_t * sdtp_data
Definition: isom.h:189
color_range
color_range
Definition: vf_selectivecolor.c:43
AVMEDIA_TYPE_DATA
@ AVMEDIA_TYPE_DATA
Opaque data information usually continuous.
Definition: avutil.h:202
mov_read_udta_string
static int mov_read_udta_string(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:344
mov_read_stss
static int mov_read_stss(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:3327
mov_read_ddts
static int mov_read_ddts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1119
mov_read_uuid
static int mov_read_uuid(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:7112
AVCOL_PRI_UNSPECIFIED
@ AVCOL_PRI_UNSPECIFIED
Definition: pixfmt.h:622
MOVTrackExt::duration
unsigned duration
Definition: isom.h:116
AV_CODEC_ID_H264
@ AV_CODEC_ID_H264
Definition: codec_id.h:79
av_content_light_metadata_alloc
AVContentLightMetadata * av_content_light_metadata_alloc(size_t *size)
Allocate an AVContentLightMetadata structure and set its fields to default values.
Definition: mastering_display_metadata.c:72
av_sha_final
void av_sha_final(AVSHA *ctx, uint8_t *digest)
Finish hashing and output digest value.
Definition: sha.c:347
MOVStreamContext::current_sample
int current_sample
Definition: isom.h:213
MOVFragmentStreamInfo::sidx_pts
int64_t sidx_pts
Definition: isom.h:141
MAX_REORDER_DELAY
#define MAX_REORDER_DELAY
Definition: mov.c:4061
MOVFragmentIndex::current
int current
Definition: isom.h:163
MOVEncryptionIndex::encrypted_samples
AVEncryptionInfo ** encrypted_samples
Definition: isom.h:130
mov_read_close
static int mov_read_close(AVFormatContext *s)
Definition: mov.c:9805
MOVAtom::size
int64_t size
Definition: isom.h:96
MOVStreamContext::refcount
int refcount
Definition: isom.h:175
AVStereo3D::flags
int flags
Additional information about the frame packing.
Definition: stereo3d.h:212
ff_mov_get_lpcm_codec_id
static enum AVCodecID ff_mov_get_lpcm_codec_id(int bps, int flags)
Compute codec id for 'lpcm' tag.
Definition: isom.h:462
AV_CODEC_ID_PNG
@ AV_CODEC_ID_PNG
Definition: codec_id.h:113
AV_CODEC_ID_AVUI
@ AV_CODEC_ID_AVUI
Definition: codec_id.h:257
if
if(ret)
Definition: filter_design.txt:179
mov_read_cmov
static int mov_read_cmov(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6182
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:7337
FFStream::need_parsing
enum AVStreamParseType need_parsing
Definition: internal.h:314
MOVStreamContext::keyframe_count
unsigned int keyframe_count
Definition: isom.h:208
mov_read_SAND
static int mov_read_SAND(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:8638
IAMFAudioElement::audio_element_id
unsigned int audio_element_id
Definition: iamf.h:96
AVDISCARD_ALL
@ AVDISCARD_ALL
discard all
Definition: defs.h:229
AVFormatContext
Format I/O context.
Definition: avformat.h:1265
av_realloc_f
#define av_realloc_f(p, o, n)
Definition: tableprint_vlc.h:33
mov_read_stts
static int mov_read_stts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:3475
MOVStreamContext::index_ranges
MOVIndexRange * index_ranges
Definition: isom.h:215
DDTS_SIZE
#define DDTS_SIZE
internal.h
MOVTrackExt::stsd_id
unsigned stsd_id
Definition: isom.h:115
AVStreamGroupLCEVC::height
int height
Height of the final image for presentation.
Definition: avformat.h:1085
find_prev_closest_index
static int find_prev_closest_index(AVStream *st, AVIndexEntry *e_old, int nb_old, MOVTimeToSample *tts_data, int64_t tts_count, int64_t timestamp_pts, int flag, int64_t *index, int64_t *tts_index, int64_t *tts_sample)
Find the closest previous frame to the timestamp_pts, in e_old index entries.
Definition: mov.c:3884
set_frag_stream
static void set_frag_stream(MOVFragmentIndex *frag_index, int id)
Definition: mov.c:1597
mov_read_free
static int mov_read_free(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:7217
mov_realloc_extradata
static int mov_realloc_extradata(AVCodecParameters *par, MOVAtom atom)
Definition: mov.c:2180
AVStream::codecpar
AVCodecParameters * codecpar
Codec parameters associated with this stream.
Definition: avformat.h:768
LIBAVUTIL_VERSION_INT
#define LIBAVUTIL_VERSION_INT
Definition: version.h:85
AVSEEK_FLAG_BACKWARD
#define AVSEEK_FLAG_BACKWARD
Definition: avformat.h:2375
aes.h
AVClass
Describe the class of an AVClass context structure.
Definition: log.h:76
MOVStreamContext::tts_sample
int tts_sample
Definition: isom.h:202
avpriv_dv_get_packet
int avpriv_dv_get_packet(DVDemuxContext *c, AVPacket *pkt)
Definition: dv.c:731
MOVContext::ignore_editlist
int ignore_editlist
Definition: isom.h:338
result
and forward the result(frame or status change) to the corresponding input. If nothing is possible
fabs
static __device__ float fabs(float a)
Definition: cuda_runtime.h:182
AVStream::time_base
AVRational time_base
This is the fundamental unit of time (in seconds) in terms of which frame timestamps are represented.
Definition: avformat.h:784
NULL
#define NULL
Definition: coverity.c:32
sha.h
truehd_layout
static uint64_t truehd_layout(int chanmap)
Definition: mlp_parse.h:105
MOVDref
Definition: isom.h:85
AVERROR_PATCHWELCOME
#define AVERROR_PATCHWELCOME
Not yet implemented in FFmpeg, patches welcome.
Definition: error.h:64
format
New swscale design to change SwsGraph is what coordinates multiple passes These can include cascaded scaling error diffusion and so on Or we could have separate passes for the vertical and horizontal scaling In between each SwsPass lies a fully allocated image buffer Graph passes may have different levels of e g we can have a single threaded error diffusion pass following a multi threaded scaling pass SwsGraph is internally recreated whenever the image format
Definition: swscale-v2.txt:14
AV_CODEC_ID_AV1
@ AV_CODEC_ID_AV1
Definition: codec_id.h:284
MOVStreamContext::ctts_count
unsigned int ctts_count
Definition: isom.h:190
AVEncryptionInitInfo
This describes info used to initialize an encryption key system.
Definition: encryption_info.h:88
isom.h
tmp
static uint8_t tmp[20]
Definition: aes_ctr.c:47
MP4TrackKindValueMapping::disposition
int disposition
Definition: isom.h:478
mov_read_ftyp
static int mov_read_ftyp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1512
AV_WB16
#define AV_WB16(p, v)
Definition: intreadwrite.h:401
MOVContext::nb_heif_grid
int nb_heif_grid
Definition: isom.h:378
read_image_grid
static int read_image_grid(AVFormatContext *s, const HEIFGrid *grid, AVStreamGroupTileGrid *tile_grid)
Definition: mov.c:10029
MOVElst
Definition: isom.h:79
av_aes_ctr_alloc
struct AVAESCTR * av_aes_ctr_alloc(void)
Allocate an AVAESCTR context.
Definition: aes_ctr.c:40
flac_parse_block_header
static av_always_inline void flac_parse_block_header(const uint8_t *block_header, int *last, int *type, int *size)
Parse the metadata block parameters from the header.
Definition: flac.h:63
AVStreamGroupTileGrid::coded_side_data
AVPacketSideData * coded_side_data
Additional data associated with the grid.
Definition: avformat.h:1055
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:3721
AV_CHANNEL_LAYOUT_RETYPE_FLAG_CANONICAL
#define AV_CHANNEL_LAYOUT_RETYPE_FLAG_CANONICAL
The specified retype target order is ignored and the simplest possible (canonical) order is used for ...
Definition: channel_layout.h:721
mov_probe
static int mov_probe(const AVProbeData *p)
Definition: mov.c:9451
AVPALETTE_SIZE
#define AVPALETTE_SIZE
Definition: pixfmt.h:32
MOVDref::nlvl_to
int16_t nlvl_to
Definition: isom.h:91
get_eia608_packet
static int get_eia608_packet(AVIOContext *pb, AVPacket *pkt, int src_size)
Definition: mov.c:10788
AV_CODEC_ID_DVD_SUBTITLE
@ AV_CODEC_ID_DVD_SUBTITLE
Definition: codec_id.h:559
AVIndexEntry::flags
int flags
Definition: avformat.h:609
MOVStreamContext::time_offset
int64_t time_offset
time offset of the edit list entries
Definition: isom.h:211
mov_read_smdm
static int mov_read_smdm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6364
av_default_item_name
const char * av_default_item_name(void *ptr)
Return the context name.
Definition: log.c:240
AVStereo3D::horizontal_disparity_adjustment
AVRational horizontal_disparity_adjustment
Relative shift of the left and right images, which changes the zero parallax plane.
Definition: stereo3d.h:234
avio_rb64
uint64_t avio_rb64(AVIOContext *s)
Definition: aviobuf.c:908
av_aes_crypt
void av_aes_crypt(AVAES *a, uint8_t *dst, const uint8_t *src, int count, uint8_t *iv, int decrypt)
Encrypt or decrypt a buffer using a previously initialized context.
Definition: aes.c:171
MOVStreamContext::current_index_range
MOVIndexRange * current_index_range
Definition: isom.h:216
mov_open_dref
static int mov_open_dref(MOVContext *c, AVIOContext **pb, const char *src, MOVDref *ref)
Definition: mov.c:4954
FFStream::nb_index_entries
int nb_index_entries
Definition: internal.h:186
AVProbeData
This structure contains the data a format has to probe a file.
Definition: avformat.h:451
av_aes_alloc
struct AVAES * av_aes_alloc(void)
Allocate an AVAES context.
Definition: aes.c:37
TAG_IS_AVCI
#define TAG_IS_AVCI(tag)
Definition: isom.h:432
IAMFSubStream
Definition: iamf.h:82
MOVStreamContext::timecode_track
int timecode_track
Definition: isom.h:227
IAMFAudioElement::layers
IAMFLayer * layers
Definition: iamf.h:103
mov_read_schm
static int mov_read_schm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:7809
AVStream::metadata
AVDictionary * metadata
Definition: avformat.h:825
FLAC_STREAMINFO_SIZE
#define FLAC_STREAMINFO_SIZE
Definition: flac.h:32
av_color_primaries_name
const char * av_color_primaries_name(enum AVColorPrimaries primaries)
Definition: pixdesc.c:3675
FF_MOV_FLAG_MFRA_DTS
#define FF_MOV_FLAG_MFRA_DTS
Definition: isom.h:455
MOV_SAMPLE_DEPENDENCY_NO
#define MOV_SAMPLE_DEPENDENCY_NO
Definition: isom.h:428
mov_read_iref_thmb
static int mov_read_iref_thmb(MOVContext *c, AVIOContext *pb, int version)
Definition: mov.c:8967
AV_DICT_DONT_OVERWRITE
#define AV_DICT_DONT_OVERWRITE
Don't overwrite existing entries.
Definition: dict.h:81
ff_codec_movvideo_tags
const AVCodecTag ff_codec_movvideo_tags[]
Definition: isom_tags.c:29
MOVStreamContext::tts_index
int tts_index
Definition: isom.h:201
AV_DISPOSITION_MULTILAYER
#define AV_DISPOSITION_MULTILAYER
The video stream contains multiple layers, e.g.
Definition: avformat.h:715
MOVFragmentStreamInfo::index_base
int index_base
Definition: isom.h:146
MOVStreamContext::rap_group
MOVSbgp * rap_group
Definition: isom.h:241
AV_CODEC_ID_QDM2
@ AV_CODEC_ID_QDM2
Definition: codec_id.h:468
mov_read_ilst
static int mov_read_ilst(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5259
MOVTimeToSample::duration
unsigned int duration
Definition: isom.h:59
AV_CH_FRONT_CENTER
#define AV_CH_FRONT_CENTER
Definition: channel_layout.h:177
AVCodecParameters::ch_layout
AVChannelLayout ch_layout
Audio only.
Definition: codec_par.h:180
get_frag_stream_info_from_pkt
static MOVFragmentStreamInfo * get_frag_stream_info_from_pkt(MOVFragmentIndex *frag_index, AVPacket *pkt, int id)
Definition: mov.c:8211
get_sgpd_sync_index
static uint32_t get_sgpd_sync_index(const MOVStreamContext *sc, int nal_unit_type)
Definition: mov.c:4475
mov_read_fiel
static int mov_read_fiel(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2146
parse
static int parse(AVCodecParserContext *s, AVCodecContext *avctx, const uint8_t **poutbuf, int *poutbuf_size, const uint8_t *buf, int buf_size)
Definition: apv_parser.c:45
MOV_MP4_TTML_TAG
#define MOV_MP4_TTML_TAG
Definition: isom.h:473
AV_PKT_DATA_CONTENT_LIGHT_LEVEL
@ AV_PKT_DATA_CONTENT_LIGHT_LEVEL
Content light level (based on CTA-861.3).
Definition: packet.h:232
av_encryption_info_add_side_data
uint8_t * av_encryption_info_add_side_data(const AVEncryptionInfo *info, size_t *size)
Allocates and initializes side data that holds a copy of the given encryption info.
Definition: encryption_info.c:127
MOV_TFHD_BASE_DATA_OFFSET
#define MOV_TFHD_BASE_DATA_OFFSET
Definition: isom.h:396
MOVFragmentStreamInfo::stsd_id
int stsd_id
Definition: isom.h:149
MOVStreamContext::open_key_samples_count
int open_key_samples_count
Definition: isom.h:249
HEIFItem
Definition: isom.h:289
ff_codec_movaudio_tags
const AVCodecTag ff_codec_movaudio_tags[]
Definition: isom_tags.c:305
ff_codec_movdata_tags
const AVCodecTag ff_codec_movdata_tags[]
Definition: isom.c:82
mov_read_wfex
static int mov_read_wfex(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1223
av_stereo3d_alloc_size
AVStereo3D * av_stereo3d_alloc_size(size_t *size)
Allocate an AVStereo3D structure and set its fields to default values.
Definition: stereo3d.c:40
index
int index
Definition: gxfenc.c:90
c
Undefined Behavior In the C some operations are like signed integer dereferencing freed accessing outside allocated Undefined Behavior must not occur in a C it is not safe even if the output of undefined operations is unused The unsafety may seem nit picking but Optimizing compilers have in fact optimized code on the assumption that no undefined Behavior occurs Optimizing code based on wrong assumptions can and has in some cases lead to effects beyond the output of computations The signed integer overflow problem in speed critical code Code which is highly optimized and works with signed integers sometimes has the problem that often the output of the computation does not c
Definition: undefined.txt:32
AVPROBE_SCORE_EXTENSION
#define AVPROBE_SCORE_EXTENSION
score for file extension
Definition: avformat.h:461
MOVSbgp::count
unsigned int count
Definition: isom.h:122
AVCodecParameters::sample_rate
int sample_rate
Audio only.
Definition: codec_par.h:184
mov_parse_stsd_subtitle
static void mov_parse_stsd_subtitle(MOVContext *c, AVIOContext *pb, AVStream *st, MOVStreamContext *sc, int64_t size)
Definition: mov.c:2835
cid
uint16_t cid
Definition: mxfenc.c:2286
mov_skip_multiple_stsd
static int mov_skip_multiple_stsd(MOVContext *c, AVIOContext *pb, int codec_tag, int format, int64_t size)
Definition: mov.c:2997
MOVStts
Definition: isom.h:63
AVAudioServiceType
AVAudioServiceType
Definition: defs.h:232
AV_CODEC_ID_MPEG1VIDEO
@ AV_CODEC_ID_MPEG1VIDEO
Definition: codec_id.h:53
AV_CODEC_ID_GSM
@ AV_CODEC_ID_GSM
as in Berlin toast format
Definition: codec_id.h:467
AVStream::nb_frames
int64_t nb_frames
number of frames in this stream if known or 0
Definition: avformat.h:806
AVCodecID
AVCodecID
Identify the syntax and semantics of the bitstream.
Definition: codec_id.h:49
av_packet_side_data_get
const AVPacketSideData * av_packet_side_data_get(const AVPacketSideData *sd, int nb_sd, enum AVPacketSideDataType type)
Get side information from a side data array.
Definition: packet.c:657
AVIAMFSubmixElement::audio_element_id
unsigned int audio_element_id
The id of the Audio Element this submix element references.
Definition: iamf.h:452
AV_CODEC_ID_EAC3
@ AV_CODEC_ID_EAC3
Definition: codec_id.h:489
should_retry
static int should_retry(AVIOContext *pb, int error_code)
Definition: mov.c:10721
avformat_stream_group_add_stream
int avformat_stream_group_add_stream(AVStreamGroup *stg, AVStream *st)
Add an already allocated stream to a stream group.
Definition: options.c:513
AV_PKT_DATA_SPHERICAL
@ AV_PKT_DATA_SPHERICAL
This side data should be associated with a video stream and corresponds to the AVSphericalMapping str...
Definition: packet.h:225
AVCodecParameters::extradata_size
int extradata_size
Size of the extradata content in bytes.
Definition: codec_par.h:73
AVIAMFSubmix
Submix layout as defined in section 3.7 of IAMF.
Definition: iamf.h:556
AV_WB32
#define AV_WB32(p, v)
Definition: intreadwrite.h:415
mov_read_pasp
static int mov_read_pasp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1342
MOVContext::dv_demux
DVDemuxContext * dv_demux
Definition: isom.h:327
AV_CODEC_ID_AAC
@ AV_CODEC_ID_AAC
Definition: codec_id.h:451
AVStereo3D::primary_eye
enum AVStereo3DPrimaryEye primary_eye
Which eye is the primary eye when rendering in 2D.
Definition: stereo3d.h:222
ff_dlog
#define ff_dlog(a,...)
Definition: tableprint_vlc.h:28
color_primaries
static const AVColorPrimariesDesc color_primaries[AVCOL_PRI_NB]
Definition: csp.c:76
mov_read_SA3D
static int mov_read_SA3D(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:8548
mov_read_elst
static int mov_read_elst(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6235
MOVEncryptionIndex::auxiliary_info_default_size
uint8_t auxiliary_info_default_size
Definition: isom.h:134
AV_STREAM_GROUP_PARAMS_TILE_GRID
@ AV_STREAM_GROUP_PARAMS_TILE_GRID
Definition: avformat.h:1092
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:10456
AV_CODEC_ID_QCELP
@ AV_CODEC_ID_QCELP
Definition: codec_id.h:473
AV_SPHERICAL_HALF_EQUIRECTANGULAR
@ AV_SPHERICAL_HALF_EQUIRECTANGULAR
Video frame displays as a 180 degree equirectangular projection.
Definition: spherical.h:73
cbc1_scheme_decrypt
static int cbc1_scheme_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
Definition: mov.c:8004
avio_rl32
unsigned int avio_rl32(AVIOContext *s)
Definition: aviobuf.c:730
MOVStreamContext::tref_flags
unsigned tref_flags
Definition: isom.h:225
AVDISCARD_NONKEY
@ AVDISCARD_NONKEY
discard all frames except keyframes
Definition: defs.h:228
MOVFragment::flags
unsigned flags
Definition: isom.h:110
f
f
Definition: af_crystalizer.c:122
AVIOContext
Bytestream IO Context.
Definition: avio.h:160
AV_CODEC_ID_PCM_S24LE
@ AV_CODEC_ID_PCM_S24LE
Definition: codec_id.h:348
mov_read_wave
static int mov_read_wave(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2376
AV_SPHERICAL_CUBEMAP
@ AV_SPHERICAL_CUBEMAP
Video frame is split into 6 faces of a cube, and arranged on a 3x2 layout.
Definition: spherical.h:61
avio_rb24
unsigned int avio_rb24(AVIOContext *s)
Definition: aviobuf.c:754
ff_mpa_check_header
static int ff_mpa_check_header(uint32_t header)
Definition: mpegaudiodecheader.h:62
MOVStreamContext::aes_ctx
struct AVAES * aes_ctx
Definition: isom.h:279
MOV_TREF_FLAG_ENHANCEMENT
#define MOV_TREF_FLAG_ENHANCEMENT
Definition: isom.h:430
cens_scheme_decrypt
static int cens_scheme_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
Definition: mov.c:8064
MOVContext::handbrake_version
int handbrake_version
Definition: isom.h:334
mov_free_stream_context
static void mov_free_stream_context(AVFormatContext *s, AVStream *st)
Definition: mov.c:9743
AVPacket::size
int size
Definition: packet.h:536
NULL_IF_CONFIG_SMALL
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
Definition: internal.h:94
ff_codec_get_id
enum AVCodecID ff_codec_get_id(const AVCodecTag *tags, unsigned int tag)
Definition: utils.c:136
avformat_alloc_context
AVFormatContext * avformat_alloc_context(void)
Allocate an AVFormatContext.
Definition: options.c:162
MOVFragmentIndexItem
Definition: isom.h:152
get_current_encryption_info
static int get_current_encryption_info(MOVContext *c, MOVEncryptionIndex **encryption_index, MOVStreamContext **sc)
Gets the current encryption info and associated current stream context.
Definition: mov.c:7286
AVIOContext::seekable
int seekable
A combination of AVIO_SEEKABLE_ flags or 0 when the stream is not seekable.
Definition: avio.h:261
av_aes_ctr_init
int av_aes_ctr_init(struct AVAESCTR *a, const uint8_t *key)
Initialize an AVAESCTR context.
Definition: aes_ctr.c:71
height
#define height
Definition: dsp.h:89
qtpalette.h
av_bprint_finalize
int av_bprint_finalize(AVBPrint *buf, char **ret_str)
Finalize a print buffer.
Definition: bprint.c:240
AVChannelLayout
An AVChannelLayout holds information about the channel layout of audio data.
Definition: channel_layout.h:319
FFStream
Definition: internal.h:128
mov_read_dref
static int mov_read_dref(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:636
mov_current_sample_dec
static void mov_current_sample_dec(MOVStreamContext *sc)
Definition: mov.c:4130
AVSphericalMapping::bound_right
uint32_t bound_right
Distance from the right edge.
Definition: spherical.h:181
MOVStsc::first
int first
Definition: isom.h:74
dst
uint8_t ptrdiff_t const uint8_t ptrdiff_t int intptr_t intptr_t int int16_t * dst
Definition: dsp.h:87
av_bswap32
#define av_bswap32
Definition: bswap.h:47
MOVStreamContext::stsz_sample_size
unsigned int stsz_sample_size
always contains sample size from stsz atom
Definition: isom.h:204
FF_MOV_FLAG_MFRA_AUTO
#define FF_MOV_FLAG_MFRA_AUTO
Definition: isom.h:454
ff_dict_set_timestamp
int ff_dict_set_timestamp(AVDictionary **dict, const char *key, int64_t timestamp)
Set a dictionary value to an ISO-8601 compliant timestamp string.
Definition: utils.c:603
av_err2str
#define av_err2str(errnum)
Convenience macro, the return value should be used only directly in function arguments but never stan...
Definition: error.h:122
for
for(k=2;k<=8;++k)
Definition: h264pred_template.c:424
MOVStreamContext::sgpd_sync
uint8_t * sgpd_sync
Definition: isom.h:244
start_time
static int64_t start_time
Definition: ffplay.c:326
uuid.h
ff_dvdclut_palette_extradata_cat
int ff_dvdclut_palette_extradata_cat(const uint32_t *clut, const size_t clut_size, AVCodecParameters *par)
Definition: dvdclut.c:28
mov_read_trun
static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5716
MOVStreamContext::stereo3d_size
size_t stereo3d_size
Definition: isom.h:264
avio_get_str
int avio_get_str(AVIOContext *pb, int maxlen, char *buf, int buflen)
Read a string from pb into buf.
Definition: aviobuf.c:866
mov_read_iprp
static int mov_read_iprp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:9090
av_sha_update
void av_sha_update(struct AVSHA *ctx, const uint8_t *data, size_t len)
Update hash value.
Definition: sha.c:315
sample
#define sample
Definition: flacdsp_template.c:44
hypot
static av_const double hypot(double x, double y)
Definition: libm.h:368
AV_CODEC_ID_H263
@ AV_CODEC_ID_H263
Definition: codec_id.h:56
MOV_TFHD_STSD_ID
#define MOV_TFHD_STSD_ID
Definition: isom.h:397
size
int size
Definition: twinvq_data.h:10344
mov_read_chan
static int mov_read_chan(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1172
av_make_q
static AVRational av_make_q(int num, int den)
Create an AVRational.
Definition: rational.h:71
mov_read_stsc
static int mov_read_stsc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:3185
AV_WL32A
#define AV_WL32A(p, v)
Definition: intreadwrite.h:571
av_reallocp
int av_reallocp(void *ptr, size_t size)
Allocate, reallocate, or free a block of memory through a pointer to a pointer.
Definition: mem.c:188
ff_get_qtpalette
int ff_get_qtpalette(int codec_id, AVIOContext *pb, uint32_t *palette)
Retrieve the palette (or "color table" in QuickTime terms), either from the video sample description,...
Definition: qtpalette.c:323
AV_NOPTS_VALUE
#define AV_NOPTS_VALUE
Undefined timestamp value.
Definition: avutil.h:247
MKBETAG
#define MKBETAG(a, b, c, d)
Definition: macros.h:56
AV_CODEC_ID_QDMC
@ AV_CODEC_ID_QDMC
Definition: codec_id.h:499
av_fourcc_make_string
char * av_fourcc_make_string(char *buf, uint32_t fourcc)
Fill the provided buffer with a string containing a FourCC (four-character code) representation.
Definition: utils.c:75
AV_RB32
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_WL16 uint64_t_TMPL AV_WB64 unsigned int_TMPL AV_RB32
Definition: bytestream.h:96
avpriv_report_missing_feature
void avpriv_report_missing_feature(void *avc, const char *msg,...) av_printf_format(2
Log a generic warning message about a missing feature.
av_aes_ctr_set_full_iv
void av_aes_ctr_set_full_iv(struct AVAESCTR *a, const uint8_t *iv)
Forcefully change the "full" 16-byte iv, including the counter.
Definition: aes_ctr.c:51
AVStreamGroup::iamf_audio_element
struct AVIAMFAudioElement * iamf_audio_element
Definition: avformat.h:1132
MOVStreamContext::coll
AVContentLightMetadata * coll
Definition: isom.h:269
aes_ctr.h
ff_format_io_close
int ff_format_io_close(AVFormatContext *s, AVIOContext **pb)
Definition: avformat.c:868
mov_parse_heif_items
static int mov_parse_heif_items(AVFormatContext *s)
Definition: mov.c:10305
HEIFItem::is_idat_relative
int is_idat_relative
Definition: isom.h:301
IAMFContext
Definition: iamf.h:128
add_index_entry
static int64_t add_index_entry(AVStream *st, int64_t pos, int64_t timestamp, int size, int distance, int flags)
Add index entry with the given values, to the end of ffstream(st)->index_entries.
Definition: mov.c:3980
MOVDref::path
char * path
Definition: isom.h:87
mov_current_sample_inc
static void mov_current_sample_inc(MOVStreamContext *sc)
Definition: mov.c:4118
AVStream::sample_aspect_ratio
AVRational sample_aspect_ratio
sample aspect ratio (0 if unknown)
Definition: avformat.h:823
FFInputFormat::p
AVInputFormat p
The public AVInputFormat.
Definition: demux.h:46
dovi_isom.h
AVPacket::dts
int64_t dts
Decompression timestamp in AVStream->time_base units; the time at which the packet is decompressed.
Definition: packet.h:534
mov_read_vexu_proj
static int mov_read_vexu_proj(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6730
fix_timescale
static void fix_timescale(MOVContext *c, MOVStreamContext *sc)
Definition: mov.c:5026
avio_r8
int avio_r8(AVIOContext *s)
Definition: aviobuf.c:603
IAMFAudioElement::substreams
IAMFSubStream * substreams
Definition: iamf.h:98
AVSphericalMapping::padding
uint32_t padding
Number of pixels to pad from the edge of each cube face.
Definition: spherical.h:194
a
The reader does not expect b to be semantically here and if the code is changed by maybe adding a a division or other the signedness will almost certainly be mistaken To avoid this confusion a new type was SUINT is the C unsigned type but it holds a signed int to use the same example SUINT a
Definition: undefined.txt:41
av_channel_layout_retype
int av_channel_layout_retype(AVChannelLayout *channel_layout, enum AVChannelOrder order, int flags)
Change the AVChannelOrder of a channel layout.
Definition: channel_layout.c:885
av_reallocp_array
int av_reallocp_array(void *ptr, size_t nmemb, size_t size)
Allocate, reallocate an array through a pointer to a pointer.
Definition: mem.c:225
AVIAMFAudioElement
Information on how to combine one or more audio streams, as defined in section 3.6 of IAMF.
Definition: iamf.h:356
AV_PRIMARY_EYE_NONE
@ AV_PRIMARY_EYE_NONE
Neither eye.
Definition: stereo3d.h:178
mov_read_default
static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:9329
AV_TIMECODE_FLAG_24HOURSMAX
@ AV_TIMECODE_FLAG_24HOURSMAX
timecode wraps after 24 hours
Definition: timecode.h:37
MOV_MP4_FPCM_TAG
#define MOV_MP4_FPCM_TAG
Definition: isom.h:474
ffio_ensure_seekback
int ffio_ensure_seekback(AVIOContext *s, int64_t buf_size)
Ensures that the requested seekback buffer size will be available.
Definition: aviobuf.c:1023
AVStreamGroupTileGrid::nb_tiles
unsigned int nb_tiles
Amount of tiles in the grid.
Definition: avformat.h:960
av_packet_side_data_add
AVPacketSideData * av_packet_side_data_add(AVPacketSideData **psd, int *pnb_sd, enum AVPacketSideDataType type, void *data, size_t size, int flags)
Wrap existing data as packet side data.
Definition: packet.c:700
mov_read_packet
static int mov_read_packet(AVFormatContext *s, AVPacket *pkt)
Definition: mov.c:10921
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:1077
AVStreamGroup::lcevc
struct AVStreamGroupLCEVC * lcevc
Definition: avformat.h:1135
attributes.h
AV_CODEC_ID_LCEVC
@ AV_CODEC_ID_LCEVC
Definition: codec_id.h:602
MOVEncryptionIndex::auxiliary_offsets_count
size_t auxiliary_offsets_count
Definition: isom.h:136
HEIFItem::vflip
int vflip
Definition: isom.h:299
AVPacket::flags
int flags
A combination of AV_PKT_FLAG values.
Definition: packet.h:541
av_dict_free
void av_dict_free(AVDictionary **pm)
Free all the memory allocated for an AVDictionary struct and all keys and values.
Definition: dict.c:233
av_encryption_info_free
void av_encryption_info_free(AVEncryptionInfo *info)
Frees the given encryption info object.
Definition: encryption_info.c:82
read_header
static int read_header(FFV1Context *f, RangeCoder *c)
Definition: ffv1dec.c:489
av_strstart
int av_strstart(const char *str, const char *pfx, const char **ptr)
Return non-zero if pfx is a prefix of str.
Definition: avstring.c:36
mov_find_reference_track
static AVStream * mov_find_reference_track(AVFormatContext *s, AVStream *st, int first_index)
Definition: mov.c:10367
AVSubsampleEncryptionInfo
This file is part of FFmpeg.
Definition: encryption_info.h:25
MOVFragmentIndexItem::stream_info
MOVFragmentStreamInfo * stream_info
Definition: isom.h:157
version
version
Definition: libkvazaar.c:315
AV_STREAM_GROUP_PARAMS_IAMF_AUDIO_ELEMENT
@ AV_STREAM_GROUP_PARAMS_IAMF_AUDIO_ELEMENT
Definition: avformat.h:1090
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:1166
ff_rfps_calculate
void ff_rfps_calculate(AVFormatContext *ic)
Definition: demux.c:2338
input
and forward the test the status of outputs and forward it to the corresponding return FFERROR_NOT_READY If the filters stores internally one or a few frame for some input
Definition: filter_design.txt:172
MOV_MP4_IPCM_TAG
#define MOV_MP4_IPCM_TAG
Definition: isom.h:475
mov_read_clli
static int mov_read_clli(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6492
MOVStreamContext::chunk_offsets
int64_t * chunk_offsets
Definition: isom.h:181
AVStreamGroup::iamf_mix_presentation
struct AVIAMFMixPresentation * iamf_mix_presentation
Definition: avformat.h:1133
MOVFragmentIndex::item
MOVFragmentIndexItem * item
Definition: isom.h:165
AV_LOG_INFO
#define AV_LOG_INFO
Standard information.
Definition: log.h:221
MOVStreamContext::iamf
struct IAMFDemuxContext * iamf
Definition: isom.h:285
FFERROR_REDO
#define FFERROR_REDO
Returned by demuxers to indicate that data was consumed but discarded (ignored streams or junk data).
Definition: demux.h:176
av_encryption_init_info_alloc
AVEncryptionInitInfo * av_encryption_init_info_alloc(uint32_t system_id_size, uint32_t num_key_ids, uint32_t key_id_size, uint32_t data_size)
Allocates an AVEncryptionInitInfo structure and sub-pointers to hold the given sizes.
Definition: encryption_info.c:178
av_channel_layout_custom_init
int av_channel_layout_custom_init(AVChannelLayout *channel_layout, int nb_channels)
Initialize a custom channel layout with the specified number of channels.
Definition: channel_layout.c:232
MOVContext::decryption_key_len
int decryption_key_len
Definition: isom.h:367
av_aes_ctr_free
void av_aes_ctr_free(struct AVAESCTR *a)
Release an AVAESCTR context.
Definition: aes_ctr.c:80
av_mastering_display_metadata_alloc_size
AVMasteringDisplayMetadata * av_mastering_display_metadata_alloc_size(size_t *size)
Allocate an AVMasteringDisplayMetadata structure and set its fields to default values.
Definition: mastering_display_metadata.c:44
mov_read_dfla
static int mov_read_dfla(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:7911
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:9201
layout
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel layout
Definition: filter_design.txt:18
MOVDref::nlvl_from
int16_t nlvl_from
Definition: isom.h:91
AVStreamGroupTileGrid::nb_coded_side_data
int nb_coded_side_data
Amount of entries in coded_side_data.
Definition: avformat.h:1060
mov_metadata_creation_time
static void mov_metadata_creation_time(MOVContext *c, AVIOContext *pb, AVDictionary **metadata, int version)
Definition: mov.c:1834
mov_metadata_hmmt
static int mov_metadata_hmmt(MOVContext *c, AVIOContext *pb, unsigned len)
Definition: mov.c:323
AV_CODEC_ID_MJPEG
@ AV_CODEC_ID_MJPEG
Definition: codec_id.h:59
MOVFragmentStreamInfo::next_trun_dts
int64_t next_trun_dts
Definition: isom.h:144
MOVStreamContext::stsc_index
unsigned int stsc_index
Definition: isom.h:195
av_sha_alloc
struct AVSHA * av_sha_alloc(void)
Allocate an AVSHA context.
Definition: sha.c:46
mov_read_tenc
static int mov_read_tenc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:7840
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:3265
mov_finalize_packet
static int mov_finalize_packet(AVFormatContext *s, AVStream *st, AVIndexEntry *sample, int64_t current_index, AVPacket *pkt)
Definition: mov.c:10857
MOVIndexRange
Definition: isom.h:168
mov_read_seek
static int mov_read_seek(AVFormatContext *s, int stream_index, int64_t sample_time, int flags)
Definition: mov.c:11235
bprint.h
MOVContext::advanced_editlist
int advanced_editlist
Definition: isom.h:339
MOVStreamContext::time_scale
int time_scale
Definition: isom.h:210
mlp_parse.h
mac_to_unicode
static const uint32_t mac_to_unicode[128]
Definition: mov.c:149
AVStreamGroupTileGrid::width
int width
Width of the final image for presentation.
Definition: avformat.h:1037
MOVStreamContext::bytes_per_frame
unsigned int bytes_per_frame
Definition: isom.h:217
AVSphericalMapping::roll
int32_t roll
Rotation around the forward vector [-180, 180].
Definition: spherical.h:140
IAMFContext::nb_audio_elements
int nb_audio_elements
Definition: iamf.h:132
MOVIndexRange::end
int64_t end
Definition: isom.h:170
AV_CODEC_ID_NONE
@ AV_CODEC_ID_NONE
Definition: codec_id.h:50
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:256
AVPacket::pts
int64_t pts
Presentation timestamp in AVStream->time_base units; the time at which the decompressed packet will b...
Definition: packet.h:528
avio_internal.h
MOVCtts::offset
int offset
Definition: isom.h:70
mov_read_trex
static int mov_read_trex(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5651
search_frag_timestamp
static int search_frag_timestamp(AVFormatContext *s, MOVFragmentIndex *frag_index, AVStream *st, int64_t timestamp)
Definition: mov.c:1707
HEIFItem::width
int width
Definition: isom.h:295
FLAGS
#define FLAGS
Definition: mov.c:11292
MOVStreamContext::stereo3d
AVStereo3D * stereo3d
Definition: isom.h:263
mov_fix_index
static void mov_fix_index(MOVContext *mov, AVStream *st)
Fix ffstream(st)->index_entries, so that it contains only the entries (and the entries which are need...
Definition: mov.c:4170
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:7688
MOVDref::volume
char volume[28]
Definition: isom.h:89
mov_read_stsd
static int mov_read_stsd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:3120
internal.h
AV_SPHERICAL_FISHEYE
@ AV_SPHERICAL_FISHEYE
Fisheye projection (Apple).
Definition: spherical.h:84
AVCodecParameters::height
int height
Definition: codec_par.h:135
AV_TIME_BASE
#define AV_TIME_BASE
Internal time base represented as integer.
Definition: avutil.h:253
MOVStreamContext::stps_count
unsigned int stps_count
Definition: isom.h:197
AVCodecParameters::block_align
int block_align
Audio only.
Definition: codec_par.h:191
AV_CODEC_ID_TTML
@ AV_CODEC_ID_TTML
Definition: codec_id.h:583
rb_size
static int rb_size(AVIOContext *pb, int64_t *value, int size)
Definition: mov.c:8664
AVStereo3DPrimaryEye
AVStereo3DPrimaryEye
List of possible primary eyes.
Definition: stereo3d.h:174
av_malloc_array
#define av_malloc_array(a, b)
Definition: tableprint_vlc.h:32
AV_CODEC_ID_CAVS
@ AV_CODEC_ID_CAVS
Definition: codec_id.h:139
display.h
ff_mov_read_stsd_entries
int ff_mov_read_stsd_entries(MOVContext *c, AVIOContext *pb, int entries)
Definition: mov.c:3023
AV_FIELD_BB
@ AV_FIELD_BB
Bottom coded first, bottom displayed first.
Definition: defs.h:212
AV_PKT_DATA_ICC_PROFILE
@ AV_PKT_DATA_ICC_PROFILE
ICC profile data consisting of an opaque octet buffer following the format described by ISO 15076-1.
Definition: packet.h:271
AV_STEREO3D_TOPBOTTOM
@ AV_STEREO3D_TOPBOTTOM
Views are on top of each other.
Definition: stereo3d.h:76
MOVFragment::duration
unsigned duration
Definition: isom.h:108
AVIAMFMixPresentation
Information on how to render and mix one or more AVIAMFAudioElement to generate the final audio outpu...
Definition: iamf.h:613
ff_id3v1_genre_str
const char *const ff_id3v1_genre_str[ID3v1_GENRE_MAX+1]
ID3v1 genres.
Definition: id3v1.c:26
MOVStreamContext::sample_sizes
unsigned int * sample_sizes
Definition: isom.h:206
MOVContext::frag_index
MOVFragmentIndex frag_index
Definition: isom.h:352
mov_read_vpcc
static int mov_read_vpcc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6320
AV_CODEC_ID_PCM_F64BE
@ AV_CODEC_ID_PCM_F64BE
Definition: codec_id.h:358
AV_CODEC_ID_HEVC
@ AV_CODEC_ID_HEVC
Definition: codec_id.h:228
value
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf default value
Definition: writing_filters.txt:86
av_url_split
void av_url_split(char *proto, int proto_size, char *authorization, int authorization_size, char *hostname, int hostname_size, int *port_ptr, char *path, int path_size, const char *url)
Split a URL string into components.
Definition: utils.c:354
MOVStreamContext::dref_id
int dref_id
Definition: isom.h:224
FFMIN
#define FFMIN(a, b)
Definition: macros.h:49
av_d2q
AVRational av_d2q(double d, int max)
Convert a double precision floating point number to a rational.
Definition: rational.c:106
fix_frag_index_entries
static void fix_frag_index_entries(MOVFragmentIndex *frag_index, int index, int id, int entries)
Definition: mov.c:1793
mov_finalize_stsd_codec
static int mov_finalize_stsd_codec(MOVContext *c, AVIOContext *pb, AVStream *st, MOVStreamContext *sc)
Definition: mov.c:2897
AV_CH_FRONT_LEFT
#define AV_CH_FRONT_LEFT
Definition: channel_layout.h:175
AV_CODEC_ID_PCM_S32BE
@ AV_CODEC_ID_PCM_S32BE
Definition: codec_id.h:345
mov_read_mdcv
static int mov_read_mdcv(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6411
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:1364
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:706
MOVStreamContext::pb
AVIOContext * pb
Definition: isom.h:174
mov_read_keys
static int mov_read_keys(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5268
AVCodecParameters::color_range
enum AVColorRange color_range
Video only.
Definition: codec_par.h:166
AV_CH_SIDE_RIGHT
#define AV_CH_SIDE_RIGHT
Definition: channel_layout.h:185
len
int len
Definition: vorbis_enc_data.h:426
AV_CODEC_ID_JPEG2000
@ AV_CODEC_ID_JPEG2000
Definition: codec_id.h:140
MOVFragment::size
unsigned size
Definition: isom.h:109
MOV_TFHD_DEFAULT_SIZE
#define MOV_TFHD_DEFAULT_SIZE
Definition: isom.h:399
MOVTimeToSample::count
unsigned int count
Definition: isom.h:58
ff_get_wav_header
int ff_get_wav_header(AVFormatContext *s, AVIOContext *pb, AVCodecParameters *par, int size, int big_endian)
Definition: riffdec.c:95
AVCOL_SPC_UNSPECIFIED
@ AVCOL_SPC_UNSPECIFIED
Definition: pixfmt.h:676
fix_stream_ids
static void fix_stream_ids(AVFormatContext *s)
Definition: mov.c:10432
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:4616
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:2371
AVSHA
hash context
Definition: sha.c:35
AVCOL_RANGE_MPEG
@ AVCOL_RANGE_MPEG
Narrow or limited range content.
Definition: pixfmt.h:733
av_calloc
void * av_calloc(size_t nmemb, size_t size)
Definition: mem.c:264
MOVFragmentStreamInfo::tfdt_dts
int64_t tfdt_dts
Definition: isom.h:143
AVChannelLayout::u
union AVChannelLayout::@459 u
Details about which channels are present in this layout.
AV_IAMF_AUDIO_ELEMENT_TYPE_SCENE
@ AV_IAMF_AUDIO_ELEMENT_TYPE_SCENE
Definition: iamf.h:346
AVCodecParameters::field_order
enum AVFieldOrder field_order
Video only.
Definition: codec_par.h:161
av_get_packet
int av_get_packet(AVIOContext *s, AVPacket *pkt, int size)
Allocate and read the payload of a packet and initialize its fields with default values.
Definition: utils.c:94
mov_read_iinf
static int mov_read_iinf(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:8847
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:996
get_stream_info_time
static int64_t get_stream_info_time(MOVFragmentStreamInfo *frag_stream_info)
Definition: mov.c:1657
MP4TrackKindValueMapping
Definition: isom.h:477
fix_index_entry_timestamps
static void fix_index_entry_timestamps(AVStream *st, int end_index, int64_t end_ts, int64_t *frame_duration_buffer, int frame_duration_buffer_size)
Rewrite timestamps of index entries in the range [end_index - frame_duration_buffer_size,...
Definition: mov.c:4021
AV_WB8
#define AV_WB8(p, d)
Definition: intreadwrite.h:392
MOVStreamContext::chunk_count
unsigned int chunk_count
Definition: isom.h:180
MOVStreamContext::data_size
int64_t data_size
Definition: isom.h:235
AV_TIMECODE_FLAG_DROPFRAME
@ AV_TIMECODE_FLAG_DROPFRAME
timecode is drop frame
Definition: timecode.h:36
language
Undefined Behavior In the C language
Definition: undefined.txt:3
MOVStreamContext::ambient
AVAmbientViewingEnvironment * ambient
Definition: isom.h:271
mov_read_tmcd
static int mov_read_tmcd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6309
mov_chan.h
AVStream::disposition
int disposition
Stream disposition - a combination of AV_DISPOSITION_* flags.
Definition: avformat.h:814
MOVStreamContext::ambient_size
size_t ambient_size
Definition: isom.h:272
tag
uint32_t tag
Definition: movenc.c:1911
AVStream::id
int id
Format-specific stream ID.
Definition: avformat.h:757
ret
ret
Definition: filter_design.txt:187
AVStream
Stream structure.
Definition: avformat.h:745
AV_LOG_FATAL
#define AV_LOG_FATAL
Something went wrong and recovery is not possible.
Definition: log.h:204
HEIFItem::extent_length
int64_t extent_length
Definition: isom.h:293
MOVEncryptionIndex::nb_encrypted_samples
unsigned int nb_encrypted_samples
Definition: isom.h:129
mov_read_senc
static int mov_read_senc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:7391
avio_seek
int64_t avio_seek(AVIOContext *s, int64_t offset, int whence)
fseek() equivalent for AVIOContext.
Definition: aviobuf.c:231
FFSWAP
#define FFSWAP(type, a, b)
Definition: macros.h:52
AVClass::class_name
const char * class_name
The name of the class; usually it is the same name as the context structure type to which the AVClass...
Definition: log.h:81
AVEncryptionInfo::key_id
uint8_t * key_id
The ID of the key used to encrypt the packet.
Definition: encryption_info.h:63
av_strlcat
size_t av_strlcat(char *dst, const char *src, size_t size)
Append the string src to the string dst, but to a total length of no more than size - 1 bytes,...
Definition: avstring.c:95
MOVStreamContext::stts_data
MOVStts * stts_data
Definition: isom.h:187
AVSphericalMapping::pitch
int32_t pitch
Rotation around the right vector [-90, 90].
Definition: spherical.h:139
AVStreamGroup::metadata
AVDictionary * metadata
Metadata that applies to the whole group.
Definition: avformat.h:1146
avio_rb16
unsigned int avio_rb16(AVIOContext *s)
Definition: aviobuf.c:746
AVStereo3D::type
enum AVStereo3DType type
How views are packed within the video.
Definition: stereo3d.h:207
MOVSbgp::index
unsigned int index
Definition: isom.h:123
HEIFItem::icc_profile_size
size_t icc_profile_size
Definition: isom.h:303
MOVContext::chapter_tracks
int * chapter_tracks
Definition: isom.h:335
cdt2
static const int16_t cdt2[8]
Definition: truemotion1data.h:43
AVSTREAM_PARSE_HEADERS
@ AVSTREAM_PARSE_HEADERS
Only parse headers, do not repack.
Definition: avformat.h:591
pos
unsigned int pos
Definition: spdifenc.c:414
avformat.h
MOVFragment::implicit_offset
uint64_t implicit_offset
Definition: isom.h:106
dict.h
av_packet_side_data_new
AVPacketSideData * av_packet_side_data_new(AVPacketSideData **psd, int *pnb_sd, enum AVPacketSideDataType type, size_t size, int flags)
Allocate a new packet side data.
Definition: packet.c:707
AV_AUDIO_SERVICE_TYPE_KARAOKE
@ AV_AUDIO_SERVICE_TYPE_KARAOKE
Definition: defs.h:241
mov_read_dmlp
static int mov_read_dmlp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:8355
flag
#define flag(name)
Definition: cbs_av1.c:495
AV_INPUT_BUFFER_PADDING_SIZE
#define AV_INPUT_BUFFER_PADDING_SIZE
Definition: defs.h:40
MOVStreamContext::pseudo_stream_id
int pseudo_stream_id
-1 means demux all ids
Definition: isom.h:220
MOVContext::time_scale
int time_scale
Definition: isom.h:317
id
enum AVCodecID id
Definition: dts2pts.c:367
mov_read_tfdt
static int mov_read_tfdt(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5677
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:5395
search_frag_moof_offset
static int search_frag_moof_offset(MOVFragmentIndex *frag_index, int64_t offset)
Definition: mov.c:1633
MOVFragment
Definition: isom.h:101
AV_DICT_MATCH_CASE
#define AV_DICT_MATCH_CASE
Only get an entry with exact-case key match.
Definition: dict.h:74
AV_RL32
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_RL32
Definition: bytestream.h:92
U
#define U(x)
Definition: vpx_arith.h:37
mov_switch_root
static int mov_switch_root(AVFormatContext *s, int64_t target, int index)
Definition: mov.c:10728
MOVContext::use_mfra_for
int use_mfra_for
Definition: isom.h:349
AVEncryptionInfo
This describes encryption info for a packet.
Definition: encryption_info.h:43
MOVStreamContext::encryption_index
MOVEncryptionIndex * encryption_index
Definition: isom.h:282
MIN_DATA_ENTRY_BOX_SIZE
#define MIN_DATA_ENTRY_BOX_SIZE
Definition: mov.c:635
AVStreamGroup
Definition: avformat.h:1099
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:751
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:11084
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:2660
ff_codec_bmp_tags
const AVCodecTag ff_codec_bmp_tags[]
Definition: riff.c:36
MOVStreamContext::h_spacing
int h_spacing
pasp hSpacing
Definition: isom.h:230
mov_read_dec3
static int mov_read_dec3(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1076
get_frag_time
static int64_t get_frag_time(AVFormatContext *s, AVStream *dst_st, MOVFragmentIndex *frag_index, int index)
Definition: mov.c:1667
MOVStreamContext::sample_size
unsigned int sample_size
may contain value calculated from stsd or value from stsz atom
Definition: isom.h:203
HEVC_NAL_CRA_NUT
@ HEVC_NAL_CRA_NUT
Definition: hevc.h:50
AVStreamGroup::nb_streams
unsigned int nb_streams
Number of elements in AVStreamGroup.streams.
Definition: avformat.h:1153
mlp_samplerate
static int mlp_samplerate(int in)
Definition: mlp_parse.h:87
channel_layout.h
MOVStreamContext::duration_for_fps
int64_t duration_for_fps
Definition: isom.h:253
ISOM_DVCC_DVVC_SIZE
#define ISOM_DVCC_DVVC_SIZE
Definition: dovi_isom.h:29
mov_read_sbgp
static int mov_read_sbgp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:3777
MOVFragment::moof_offset
uint64_t moof_offset
Definition: isom.h:105
AVIO_SEEKABLE_NORMAL
#define AVIO_SEEKABLE_NORMAL
Seeking works like for a local file.
Definition: avio.h:41
av_packet_new_side_data
uint8_t * av_packet_new_side_data(AVPacket *pkt, enum AVPacketSideDataType type, size_t size)
Allocate new information of a packet.
Definition: packet.c:232
buffer
the frame and frame reference mechanism is intended to as much as expensive copies of that data while still allowing the filters to produce correct results The data is stored in buffers represented by AVFrame structures Several references can point to the same frame buffer
Definition: filter_design.txt:49
mov_read_glbl
static int mov_read_glbl(MOVContext *c, AVIOContext *pb, MOVAtom atom)
This function reads atom content and puts data in extradata without tag nor size unlike mov_read_extr...
Definition: mov.c:2433
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:7049
MOVTrackExt::size
unsigned size
Definition: isom.h:117
ff_remove_stream_group
void ff_remove_stream_group(AVFormatContext *s, AVStreamGroup *stg)
Remove a stream group from its AVFormatContext and free it.
Definition: avformat.c:121
AV_OPT_TYPE_INT
@ AV_OPT_TYPE_INT
Underlying C type is int.
Definition: opt.h:259
MOVContext::dv_fctx
AVFormatContext * dv_fctx
Definition: isom.h:328
av_channel_layout_uninit
void av_channel_layout_uninit(AVChannelLayout *channel_layout)
Free any allocated data in the channel layout and reset the channel count to 0.
Definition: channel_layout.c:442
AV_CODEC_ID_DVAUDIO
@ AV_CODEC_ID_DVAUDIO
Definition: codec_id.h:455
avformat_free_context
void avformat_free_context(AVFormatContext *s)
Free an AVFormatContext and all its streams.
Definition: avformat.c:141
MOVContext::aax_mode
unsigned int aax_mode
'aax' file has been detected
Definition: isom.h:354
mov_read_sv3d
static int mov_read_sv3d(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6593
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:1473
mov_get_skip_samples
static int64_t mov_get_skip_samples(AVStream *st, int sample)
Definition: mov.c:11218
MOVFragmentIndex
Definition: isom.h:160
mov_read_infe
static int mov_read_infe(MOVContext *c, AVIOContext *pb, MOVAtom atom, int idx)
Definition: mov.c:8782
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:879
MOVStreamContext::tts_count
unsigned int tts_count
Definition: isom.h:182
MOVStreamContext::track_end
int64_t track_end
used for dts generation in fragmented movie files
Definition: isom.h:238
MOVStreamContext::sgpd_sync_count
uint32_t sgpd_sync_count
Definition: isom.h:245
MOVContext::fragment
MOVFragment fragment
current fragment in moof atom
Definition: isom.h:330
AVIndexEntry::pos
int64_t pos
Definition: avformat.h:600
AVIOContext::eof_reached
int eof_reached
true if was unable to read due to error or eof
Definition: avio.h:238
mov_metadata_int8_bypass_padding
static int mov_metadata_int8_bypass_padding(MOVContext *c, AVIOContext *pb, unsigned len, const char *key)
Definition: mov.c:110
AVStreamGroupLCEVC::width
int width
Width of the final stream for presentation.
Definition: avformat.h:1081
MOVDref::type
uint32_t type
Definition: isom.h:86
samples
Filter the word “frame” indicates either a video frame or a group of audio samples
Definition: filter_design.txt:8
mean
static float mean(const float *input, int size)
Definition: vf_nnedi.c:861
mov_read_covr
static int mov_read_covr(MOVContext *c, AVIOContext *pb, int type, int len)
Definition: mov.c:230
MOVParseTableEntry::type
uint32_t type
Definition: mov.c:82
AVMasteringDisplayMetadata::min_luminance
AVRational min_luminance
Min luminance of mastering display (cd/m^2).
Definition: mastering_display_metadata.h:52
MOVStreamContext::per_sample_iv_size
unsigned int per_sample_iv_size
Definition: isom.h:280
ff_codec_movsubtitle_tags
const AVCodecTag ff_codec_movsubtitle_tags[]
Definition: isom.c:75
av_mul_q
AVRational av_mul_q(AVRational b, AVRational c)
Multiply two rationals.
Definition: rational.c:80
AVPacket::stream_index
int stream_index
Definition: packet.h:537
MOVFragmentIndexItem::nb_stream_info
int nb_stream_info
Definition: isom.h:156
avio_skip
int64_t avio_skip(AVIOContext *s, int64_t offset)
Skip given number of bytes forward.
Definition: aviobuf.c:318
export_orphan_timecode
static void export_orphan_timecode(AVFormatContext *s)
Definition: mov.c:9875
mov_read_sbas
static int mov_read_sbas(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2504
MOVStreamContext::has_sidx
int has_sidx
Definition: isom.h:276
AV_CH_FRONT_RIGHT
#define AV_CH_FRONT_RIGHT
Definition: channel_layout.h:176
av_aes_ctr_crypt
void av_aes_ctr_crypt(struct AVAESCTR *a, uint8_t *dst, const uint8_t *src, int count)
Process a buffer using a previously initialized context.
Definition: aes_ctr.c:97
mov_metadata_gnre
static int mov_metadata_gnre(MOVContext *c, AVIOContext *pb, unsigned len, const char *key)
Definition: mov.c:133
AV_PKT_DATA_ENCRYPTION_INFO
@ AV_PKT_DATA_ENCRYPTION_INFO
This side data contains encryption info for how to decrypt the packet.
Definition: packet.h:252
MOV_MERGE_CTTS
#define MOV_MERGE_CTTS
Definition: mov.c:4546
FFStream::index_entries
AVIndexEntry * index_entries
Only used if the format does not support seeking natively.
Definition: internal.h:184
av_dict_set_int
int av_dict_set_int(AVDictionary **pm, const char *key, int64_t value, int flags)
Convenience wrapper for av_dict_set() that converts the value to a string and stores it.
Definition: dict.c:177
mov_read_dpxe
static int mov_read_dpxe(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2258
AVIAMFSubmix::nb_elements
unsigned int nb_elements
Number of elements in the submix.
Definition: iamf.h:572
MOVFragmentStreamInfo::id
int id
Definition: isom.h:140
AVIO_FLAG_READ
#define AVIO_FLAG_READ
read-only
Definition: avio.h:617
AV_PKT_DATA_AUDIO_SERVICE_TYPE
@ AV_PKT_DATA_AUDIO_SERVICE_TYPE
This side data should be associated with an audio stream and corresponds to enum AVAudioServiceType.
Definition: packet.h:117
av_spherical_alloc
AVSphericalMapping * av_spherical_alloc(size_t *size)
Allocate a AVSphericalVideo structure and initialize its fields to default values.
Definition: spherical.c:26
AV_OPT_FLAG_DECODING_PARAM
#define AV_OPT_FLAG_DECODING_PARAM
A generic parameter which can be set by the user for demuxing or decoding.
Definition: opt.h:356
MOVContext::thmb_item_id
int thmb_item_id
Definition: isom.h:379
mov_read_rtmd_track
static int mov_read_rtmd_track(AVFormatContext *s, AVStream *st)
Definition: mov.c:9658
AVMEDIA_TYPE_VIDEO
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:200
read_probe
static int read_probe(const AVProbeData *p)
Definition: cdg.c:30
MOVStreamContext::pb_is_copied
int pb_is_copied
Definition: isom.h:176
AV_CODEC_ID_PCM_S32LE
@ AV_CODEC_ID_PCM_S32LE
Definition: codec_id.h:344
AVCodecParameters::bits_per_coded_sample
int bits_per_coded_sample
The number of bits per sample in the codedwords.
Definition: codec_par.h:110
mov_parse_tiles
static int mov_parse_tiles(AVFormatContext *s)
Definition: mov.c:10210
mem.h
AVStreamGroup::type
enum AVStreamGroupParamsType type
Group type.
Definition: avformat.h:1126
MOVElst::time
int64_t time
Definition: isom.h:81
HEIFGrid
Definition: isom.h:306
mov_read_iref_dimg
static int mov_read_iref_dimg(MOVContext *c, AVIOContext *pb, int version)
Definition: mov.c:8907
mov_read_pcmc
static int mov_read_pcmc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1987
build_open_gop_key_points
static int build_open_gop_key_points(AVStream *st)
Definition: mov.c:4483
mov_parse_stsd_audio
static void mov_parse_stsd_audio(MOVContext *c, AVIOContext *pb, AVStream *st, MOVStreamContext *sc)
Definition: mov.c:2718
IAMFContext::mix_presentations
IAMFMixPresentation ** mix_presentations
Definition: iamf.h:133
AV_CODEC_ID_PCM_U8
@ AV_CODEC_ID_PCM_U8
Definition: codec_id.h:341
MOVContext::trak_index
int trak_index
Index of the current 'trak'.
Definition: isom.h:324
mov_read_timecode_track
static int mov_read_timecode_track(AVFormatContext *s, AVStream *st)
Definition: mov.c:9684
HEIFGrid::item
HEIFItem * item
Definition: isom.h:307
AVSphericalMapping::bound_left
uint32_t bound_left
Distance from the left edge.
Definition: spherical.h:179
mov_read_mac_string
static int mov_read_mac_string(MOVContext *c, AVIOContext *pb, int len, char *dst, int dstlen)
Definition: mov.c:168
MOVEncryptionIndex::auxiliary_info_sizes
uint8_t * auxiliary_info_sizes
Definition: isom.h:132
MOVFragment::stsd_id
unsigned stsd_id
Definition: isom.h:107
AVCodecParameters::video_delay
int video_delay
Video only.
Definition: codec_par.h:175
HEIFGrid::tile_id_list
int16_t * tile_id_list
Definition: isom.h:309
avpriv_request_sample
#define avpriv_request_sample(...)
Definition: tableprint_vlc.h:37
MOVStreamContext::tts_data
MOVTimeToSample * tts_data
Definition: isom.h:184
map
const VDPAUPixFmtMap * map
Definition: hwcontext_vdpau.c:71
avformat_stream_group_create
AVStreamGroup * avformat_stream_group_create(AVFormatContext *s, enum AVStreamGroupParamsType type, AVDictionary **options)
Add a new empty stream group to a media file.
Definition: options.c:433
AV_CHANNEL_LAYOUT_MONO
#define AV_CHANNEL_LAYOUT_MONO
Definition: channel_layout.h:394
AV_CODEC_ID_PCM_F64LE
@ AV_CODEC_ID_PCM_F64LE
Definition: codec_id.h:359
AVStreamGroupTileGrid::height
int height
Height of the final image for presentation.
Definition: avformat.h:1047
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:9893
av_free
#define av_free(p)
Definition: tableprint_vlc.h:34
AVDictionaryEntry
Definition: dict.h:90
av_add_q
AVRational av_add_q(AVRational b, AVRational c)
Add two rationals.
Definition: rational.c:93
AVCodecParameters::codec_id
enum AVCodecID codec_id
Specific type of the encoded data (the codec used).
Definition: codec_par.h:55
AVStereo3DView
AVStereo3DView
List of possible view types.
Definition: stereo3d.h:149
AVPacket
This structure stores compressed data.
Definition: packet.h:512
AVContentLightMetadata::MaxFALL
unsigned MaxFALL
Max average light level per frame (cd/m^2).
Definition: mastering_display_metadata.h:116
mov_parse_lcevc_streams
static int mov_parse_lcevc_streams(AVFormatContext *s)
Definition: mov.c:10382
mov_read_hfov
static int mov_read_hfov(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:7020
AV_OPT_TYPE_BOOL
@ AV_OPT_TYPE_BOOL
Underlying C type is int.
Definition: opt.h:327
MOVStreamContext::stps_data
unsigned * stps_data
partial sync sample for mpeg-2 open gop
Definition: isom.h:198
AV_CODEC_ID_ADPCM_IMA_WAV
@ AV_CODEC_ID_ADPCM_IMA_WAV
Definition: codec_id.h:376
MOVContext::nb_heif_item
int nb_heif_item
Definition: isom.h:376
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:35
av_dict_set
int av_dict_set(AVDictionary **pm, const char *key, const char *value, int flags)
Set the given entry in *pm, overwriting an existing entry.
Definition: dict.c:86
riff.h
av_dict_copy
int av_dict_copy(AVDictionary **dst, const AVDictionary *src, int flags)
Copy entries from one AVDictionary struct into another.
Definition: dict.c:247
av_encryption_info_alloc
AVEncryptionInfo * av_encryption_info_alloc(uint32_t subsample_count, uint32_t key_id_size, uint32_t iv_size)
Allocates an AVEncryptionInfo structure and sub-pointers to hold the given number of subsamples.
Definition: encryption_info.c:41
AVPacket::pos
int64_t pos
byte position in stream, -1 if unknown
Definition: packet.h:555
FFInputFormat
Definition: demux.h:42
mov_metadata_loci
static int mov_metadata_loci(MOVContext *c, AVIOContext *pb, unsigned len)
Definition: mov.c:273
mov_read_eyes
static int mov_read_eyes(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6792
AV_CODEC_ID_ILBC
@ AV_CODEC_ID_ILBC
Definition: codec_id.h:508
AV_CHAN_AMBISONIC_BASE
@ AV_CHAN_AMBISONIC_BASE
Range of channels between AV_CHAN_AMBISONIC_BASE and AV_CHAN_AMBISONIC_END represent Ambisonic compon...
Definition: channel_layout.h:108
MOV_TRUN_SAMPLE_SIZE
#define MOV_TRUN_SAMPLE_SIZE
Definition: isom.h:407
MOVStreamContext::tmcd_flags
uint32_t tmcd_flags
tmcd track flags
Definition: isom.h:236
int32_t
int32_t
Definition: audioconvert.c:56
HEIFItem::rotation
int rotation
Definition: isom.h:297
MOVAtom::type
uint32_t type
Definition: isom.h:95
distance
static float distance(float x, float y, int band)
Definition: nellymoserenc.c:231
AVSTREAM_PARSE_FULL
@ AVSTREAM_PARSE_FULL
full parsing and repack
Definition: avformat.h:590
parse_timecode_in_framenum_format
static int parse_timecode_in_framenum_format(AVFormatContext *s, AVStream *st, int64_t value, int flags)
Definition: mov.c:9644
MOVStreamContext::tmcd_nb_frames
uint8_t tmcd_nb_frames
tmcd number of frames per tick / second
Definition: isom.h:237
AVIAMFSubmixElement
Submix element as defined in section 3.7 of IAMF.
Definition: iamf.h:446
replaygain.h
MOVFragmentIndexItem::headers_read
int headers_read
Definition: isom.h:154
AV_CODEC_ID_VP8
@ AV_CODEC_ID_VP8
Definition: codec_id.h:192
AVERROR_BUG
#define AVERROR_BUG
Internal bug, also see AVERROR_BUG2.
Definition: error.h:52
MOVStreamContext::start_pad
int start_pad
amount of samples to skip due to enc-dec delay
Definition: isom.h:239
MP4TrackKindValueMapping::value
const char * value
Definition: isom.h:479
AVStereo3DType
AVStereo3DType
List of possible 3D Types.
Definition: stereo3d.h:48
MOVDref::filename
char filename[64]
Definition: isom.h:90
ff_mov_read_chnl
int ff_mov_read_chnl(AVFormatContext *s, AVIOContext *pb, AVStream *st)
Read 'chnl' tag from the input stream.
Definition: mov_chan.c:729
MOVStsc::count
int count
Definition: isom.h:75
AV_CODEC_ID_PCM_F32LE
@ AV_CODEC_ID_PCM_F32LE
Definition: codec_id.h:357
ff_mov_demuxer
const FFInputFormat ff_mov_demuxer
Definition: mov.c:11353
AVCodecParameters::bit_rate
int64_t bit_rate
The average bitrate of the encoded data (in bits per second).
Definition: codec_par.h:97
MOVStts::count
unsigned int count
Definition: isom.h:64
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
MOVStreamContext::display_matrix
int32_t * display_matrix
Definition: isom.h:262
MOVContext::heif_grid
HEIFGrid * heif_grid
Definition: isom.h:377
MOVStreamContext::min_sample_duration
uint32_t min_sample_duration
Definition: isom.h:250
MOVStreamContext::current_index
int64_t current_index
Definition: isom.h:214
AVERROR_INVALIDDATA
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:61
ff_mov_track_kind_table
const struct MP4TrackKindMapping ff_mov_track_kind_table[]
Definition: isom.c:451
get_curr_st
static AVStream * get_curr_st(MOVContext *c)
Get the current stream in the parsing process.
Definition: mov.c:212
MOVStreamContext::stts_allocated_size
unsigned int stts_allocated_size
Definition: isom.h:186
MOVFragmentStreamInfo::index_entry
int index_entry
Definition: isom.h:147
cenc_decrypt
static int cenc_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
Definition: mov.c:8195
MOVStreamContext::format
uint32_t format
Definition: isom.h:274
MKTAG
#define MKTAG(a, b, c, d)
Definition: macros.h:55
ffio_read_size
int ffio_read_size(AVIOContext *s, unsigned char *buf, int size)
Read size bytes from AVIOContext into buf.
Definition: aviobuf.c:662
MOVStreamContext::sync_group_count
unsigned int sync_group_count
Definition: isom.h:242
MOVContext::bitrates_count
int bitrates_count
Definition: isom.h:347
AV_CODEC_ID_VORBIS
@ AV_CODEC_ID_VORBIS
Definition: codec_id.h:454
AVDictionaryEntry::value
char * value
Definition: dict.h:92
AVStream::start_time
int64_t start_time
Decoding: pts of the first frame of the stream in presentation order, in stream time base.
Definition: avformat.h:794
MOVStreamContext::id
int id
AVStream id.
Definition: isom.h:177
MOVStreamContext::samples_per_frame
unsigned int samples_per_frame
Definition: isom.h:218
MOVStreamContext::tts_allocated_size
unsigned int tts_allocated_size
Definition: isom.h:183
MOVElst::duration
int64_t duration
Definition: isom.h:80
ac3tab.h
avstring.h
mov_read_ispe
static int mov_read_ispe(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:9029
width
#define width
Definition: dsp.h:89
AVAmbientViewingEnvironment::ambient_light_y
AVRational ambient_light_y
Normalized y chromaticity coordinate of the environmental ambient light in the nominal viewing enviro...
Definition: ambient_viewing_environment.h:54
mov_read_iref
static int mov_read_iref(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:8991
IAMFMixPresentation::mix
AVIAMFMixPresentation * mix
mix backs cmix iff the AVIAMFMixPresentation is owned by this structure.
Definition: iamf.h:113
mov_read_clap
static int mov_read_clap(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1238
mov_read_mfra
static int mov_read_mfra(MOVContext *c, AVIOContext *f)
Definition: mov.c:9948
AV_CODEC_ID_FLV1
@ AV_CODEC_ID_FLV1
Definition: codec_id.h:73
mov_metadata_int8_no_padding
static int mov_metadata_int8_no_padding(MOVContext *c, AVIOContext *pb, unsigned len, const char *key)
Definition: mov.c:124
flac.h
AVStreamGroupTileGrid::idx
unsigned int idx
Index of the stream in the group this tile references.
Definition: avformat.h:991
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:1578
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:8459
MOVContext::heif_item
HEIFItem ** heif_item
Definition: isom.h:375
MOVStreamContext::stts_count
unsigned int stts_count
Definition: isom.h:185
MOV_TRUN_SAMPLE_CTS
#define MOV_TRUN_SAMPLE_CTS
Definition: isom.h:409
AV_OPT_TYPE_CONST
@ AV_OPT_TYPE_CONST
Special option type for declaring named constants.
Definition: opt.h:299
MOV_ISMV_TTML_TAG
#define MOV_ISMV_TTML_TAG
Definition: isom.h:472
snprintf
#define snprintf
Definition: snprintf.h:34
IAMFMixPresentation::mix_presentation_id
unsigned int mix_presentation_id
Definition: iamf.h:114
AVCodecParameters::initial_padding
int initial_padding
Audio only.
Definition: codec_par.h:203
AV_CODEC_ID_PCM_S24BE
@ AV_CODEC_ID_PCM_S24BE
Definition: codec_id.h:349
mov_read_st3d
static int mov_read_st3d(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6546
mov_read_imir
static int mov_read_imir(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:9071
is_open_key_sample
static int is_open_key_sample(const MOVStreamContext *sc, int sample)
Definition: mov.c:11103
mov_read_dvc1
static int mov_read_dvc1(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2479
MOVStreamContext::elst_count
unsigned int elst_count
Definition: isom.h:200
av_color_transfer_name
const char * av_color_transfer_name(enum AVColorTransferCharacteristic transfer)
Definition: pixdesc.c:3696
AVChannelCustom::id
enum AVChannel id
Definition: channel_layout.h:284
mov_read_atom_into_extradata
static int64_t mov_read_atom_into_extradata(MOVContext *c, AVIOContext *pb, MOVAtom atom, AVCodecParameters *par, uint8_t *buf)
Definition: mov.c:2195
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:9545
AV_CODEC_ID_DNXHD
@ AV_CODEC_ID_DNXHD
Definition: codec_id.h:151
channel
channel
Definition: ebur128.h:39
MOVStreamContext::default_encrypted_sample
AVEncryptionInfo * default_encrypted_sample
Definition: isom.h:281
MOVContext::cur_item_id
int cur_item_id
Definition: isom.h:374
av_timecode_make_string
char * av_timecode_make_string(const AVTimecode *tc, char *buf, int framenum_arg)
Load timecode string in buf.
Definition: timecode.c:104
AVFMT_EVENT_FLAG_METADATA_UPDATED
#define AVFMT_EVENT_FLAG_METADATA_UPDATED
Definition: avformat.h:1639
AV_DICT_DONT_STRDUP_KEY
#define AV_DICT_DONT_STRDUP_KEY
Take ownership of a key that's been allocated with av_malloc() or another memory allocation function.
Definition: dict.h:77
MOVContext::next_root_atom
int64_t next_root_atom
offset of the next root atom
Definition: isom.h:343
MOVContext::found_iinf
int found_iinf
'iinf' atom has been found
Definition: isom.h:321
MOVContext::meta_keys_count
unsigned meta_keys_count
Definition: isom.h:326
avcodec_parameters_copy
int avcodec_parameters_copy(AVCodecParameters *dst, const AVCodecParameters *src)
Copy the contents of src to dst.
Definition: codec_par.c:106
iamf_reader.h
AVStreamGroupTileGrid::background
uint8_t background[4]
The pixel value per channel in RGBA format used if no pixel of any tile is located at a particular pi...
Definition: avformat.h:1011
MOVStreamContext::palette
uint32_t palette[256]
Definition: isom.h:233
cenc_scheme_decrypt
static int cenc_scheme_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
Definition: mov.c:7951
MOVFragment::track_id
unsigned track_id
Definition: isom.h:103
mov_read_hdlr
static int mov_read_hdlr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:780
mov_parse_stsd_data
static int mov_parse_stsd_data(MOVContext *c, AVIOContext *pb, AVStream *st, MOVStreamContext *sc, int64_t size)
Definition: mov.c:2851
AV_CH_SIDE_LEFT
#define AV_CH_SIDE_LEFT
Definition: channel_layout.h:184
ff_iamf_read_deinit
void ff_iamf_read_deinit(IAMFDemuxContext *c)
Definition: iamf_reader.c:342
AV_RB16
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_WL16 uint64_t_TMPL AV_WB64 unsigned int_TMPL AV_WB32 unsigned int_TMPL AV_WB24 unsigned int_TMPL AV_RB16
Definition: bytestream.h:98
av_realloc
void * av_realloc(void *ptr, size_t size)
Allocate, reallocate, or free a block of memory.
Definition: mem.c:155
av_encryption_init_info_add_side_data
uint8_t * av_encryption_init_info_add_side_data(const AVEncryptionInitInfo *info, size_t *side_data_size)
Allocates and initializes side data that holds a copy of the given encryption init info.
Definition: encryption_info.c:292
av_fourcc2str
#define av_fourcc2str(fourcc)
Definition: avutil.h:347
ff_mov_read_chan
int ff_mov_read_chan(AVFormatContext *s, AVIOContext *pb, AVStream *st, int64_t size)
Read 'chan' tag from the input stream.
Definition: mov_chan.c:524
av_index_search_timestamp
int av_index_search_timestamp(AVStream *st, int64_t timestamp, int flags)
Get the index for a specific timestamp.
Definition: seek.c:245
mov_read_pitm
static int mov_read_pitm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:8683
FLAC_METADATA_TYPE_STREAMINFO
@ FLAC_METADATA_TYPE_STREAMINFO
Definition: flac.h:46
MOVContext::ignore_chapters
int ignore_chapters
Definition: isom.h:341
MOVTimeToSample::offset
int offset
Definition: isom.h:60
mov_read_dac3
static int mov_read_dac3(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:851
MP4TrackKindMapping
Definition: isom.h:482
ff_alloc_extradata
int ff_alloc_extradata(AVCodecParameters *par, int size)
Allocate extradata with additional AV_INPUT_BUFFER_PADDING_SIZE at end which is always set to 0.
Definition: utils.c:230
AV_DISPOSITION_NON_DIEGETIC
#define AV_DISPOSITION_NON_DIEGETIC
The stream is intended to be mixed with a spatial audio track.
Definition: avformat.h:683
avio_feof
int avio_feof(AVIOContext *s)
Similar to feof() but also returns nonzero on read errors.
Definition: aviobuf.c:346
mc
#define mc
Definition: vf_colormatrix.c:100
MOVStreamContext::ffindex
int ffindex
AVStream index.
Definition: isom.h:178
HEIFItem::extent_offset
int64_t extent_offset
Definition: isom.h:294
mov_read_stsz
static int mov_read_stsz(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:3382