Thanks to visit codestin.com
Credit goes to www.ffmpeg.org

FFmpeg
mov.c
Go to the documentation of this file.
1 /*
2  * MOV demuxer
3  * Copyright (c) 2001 Fabrice Bellard
4  * Copyright (c) 2009 Baptiste Coudurier <baptiste dot coudurier at gmail dot com>
5  *
6  * first version by Francois Revol <[email protected]>
7  * seek function by Gael Chardon <[email protected]>
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/exif.h"
55 #include "libavcodec/flac.h"
56 #include "libavcodec/hevc/hevc.h"
58 #include "libavcodec/mlp_parse.h"
59 #include "avformat.h"
60 #include "internal.h"
61 #include "avio_internal.h"
62 #include "demux.h"
63 #include "dvdclut.h"
64 #include "iamf_parse.h"
65 #include "iamf_reader.h"
66 #include "dovi_isom.h"
67 #include "riff.h"
68 #include "isom.h"
69 #include "libavcodec/get_bits.h"
70 #include "id3v1.h"
71 #include "mov_chan.h"
72 #include "replaygain.h"
73 
74 #if CONFIG_ZLIB
75 #include <zlib.h>
76 #endif
77 
78 #include "qtpalette.h"
79 
80 /* those functions parse an atom */
81 /* links atom IDs to parse functions */
82 typedef struct MOVParseTableEntry {
83  uint32_t type;
84  int (*parse)(MOVContext *ctx, AVIOContext *pb, MOVAtom atom);
86 
87 static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom);
88 static int mov_read_mfra(MOVContext *c, AVIOContext *f);
90 
92  unsigned len, const char *key)
93 {
94  char buf[16];
95 
96  short current, total = 0;
97  avio_rb16(pb); // unknown
98  current = avio_rb16(pb);
99  if (len >= 6)
100  total = avio_rb16(pb);
101  if (!total)
102  snprintf(buf, sizeof(buf), "%d", current);
103  else
104  snprintf(buf, sizeof(buf), "%d/%d", current, total);
105  c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
106  av_dict_set(&c->fc->metadata, key, buf, 0);
107 
108  return 0;
109 }
110 
112  unsigned len, const char *key)
113 {
114  /* bypass padding bytes */
115  avio_r8(pb);
116  avio_r8(pb);
117  avio_r8(pb);
118 
119  c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
120  av_dict_set_int(&c->fc->metadata, key, avio_r8(pb), 0);
121 
122  return 0;
123 }
124 
126  unsigned len, const char *key)
127 {
128  c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
129  av_dict_set_int(&c->fc->metadata, key, avio_r8(pb), 0);
130 
131  return 0;
132 }
133 
135  unsigned len, const char *key)
136 {
137  short genre;
138 
139  avio_r8(pb); // unknown
140 
141  genre = avio_r8(pb);
142  if (genre < 1 || genre > ID3v1_GENRE_MAX)
143  return 0;
144  c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
145  av_dict_set(&c->fc->metadata, key, ff_id3v1_genre_str[genre-1], 0);
146 
147  return 0;
148 }
149 
150 static const uint32_t mac_to_unicode[128] = {
151  0x00C4,0x00C5,0x00C7,0x00C9,0x00D1,0x00D6,0x00DC,0x00E1,
152  0x00E0,0x00E2,0x00E4,0x00E3,0x00E5,0x00E7,0x00E9,0x00E8,
153  0x00EA,0x00EB,0x00ED,0x00EC,0x00EE,0x00EF,0x00F1,0x00F3,
154  0x00F2,0x00F4,0x00F6,0x00F5,0x00FA,0x00F9,0x00FB,0x00FC,
155  0x2020,0x00B0,0x00A2,0x00A3,0x00A7,0x2022,0x00B6,0x00DF,
156  0x00AE,0x00A9,0x2122,0x00B4,0x00A8,0x2260,0x00C6,0x00D8,
157  0x221E,0x00B1,0x2264,0x2265,0x00A5,0x00B5,0x2202,0x2211,
158  0x220F,0x03C0,0x222B,0x00AA,0x00BA,0x03A9,0x00E6,0x00F8,
159  0x00BF,0x00A1,0x00AC,0x221A,0x0192,0x2248,0x2206,0x00AB,
160  0x00BB,0x2026,0x00A0,0x00C0,0x00C3,0x00D5,0x0152,0x0153,
161  0x2013,0x2014,0x201C,0x201D,0x2018,0x2019,0x00F7,0x25CA,
162  0x00FF,0x0178,0x2044,0x20AC,0x2039,0x203A,0xFB01,0xFB02,
163  0x2021,0x00B7,0x201A,0x201E,0x2030,0x00C2,0x00CA,0x00C1,
164  0x00CB,0x00C8,0x00CD,0x00CE,0x00CF,0x00CC,0x00D3,0x00D4,
165  0xF8FF,0x00D2,0x00DA,0x00DB,0x00D9,0x0131,0x02C6,0x02DC,
166  0x00AF,0x02D8,0x02D9,0x02DA,0x00B8,0x02DD,0x02DB,0x02C7,
167 };
168 
170  char *dst, int dstlen)
171 {
172  char *p = dst;
173  char *end = dst+dstlen-1;
174  int i;
175 
176  for (i = 0; i < len; i++) {
177  uint8_t t, c = avio_r8(pb);
178 
179  if (p >= end)
180  continue;
181 
182  if (c < 0x80)
183  *p++ = c;
184  else if (p < end)
185  PUT_UTF8(mac_to_unicode[c-0x80], t, if (p < end) *p++ = t;);
186  }
187  *p = 0;
188  return p - dst;
189 }
190 
191 /**
192  * Get the requested item.
193  */
194 static HEIFItem *get_heif_item(MOVContext *c, unsigned id)
195 {
196  HEIFItem *item = NULL;
197 
198  for (int i = 0; i < c->nb_heif_item; i++) {
199  if (!c->heif_item[i] || c->heif_item[i]->item_id != id)
200  continue;
201 
202  item = c->heif_item[i];
203  break;
204  }
205 
206  return item;
207 }
208 
209 /**
210  * Get the current stream in the parsing process. This can either be the
211  * latest stream added to the context, or the stream referenced by an item.
212  */
214 {
215  AVStream *st = NULL;
216  HEIFItem *item;
217 
218  if (c->fc->nb_streams < 1)
219  return NULL;
220 
221  if (c->cur_item_id == -1)
222  return c->fc->streams[c->fc->nb_streams-1];
223 
224  item = get_heif_item(c, c->cur_item_id);
225  if (item)
226  st = item->st;
227 
228  return st;
229 }
230 
231 static int mov_read_covr(MOVContext *c, AVIOContext *pb, int type, int len)
232 {
233  AVStream *st;
234  MOVStreamContext *sc;
235  enum AVCodecID id;
236  int ret;
237 
238  switch (type) {
239  case 0xd: id = AV_CODEC_ID_MJPEG; break;
240  case 0xe: id = AV_CODEC_ID_PNG; break;
241  case 0x1b: id = AV_CODEC_ID_BMP; break;
242  default:
243  av_log(c->fc, AV_LOG_WARNING, "Unknown cover type: 0x%x.\n", type);
244  avio_skip(pb, len);
245  return 0;
246  }
247 
248  sc = av_mallocz(sizeof(*sc));
249  if (!sc)
250  return AVERROR(ENOMEM);
251  ret = ff_add_attached_pic(c->fc, NULL, pb, NULL, len);
252  if (ret < 0) {
253  av_free(sc);
254  return ret;
255  }
256  st = c->fc->streams[c->fc->nb_streams - 1];
257  st->priv_data = sc;
258  sc->id = st->id;
259  sc->refcount = 1;
260 
261  if (st->attached_pic.size >= 8 && id != AV_CODEC_ID_BMP) {
262  if (AV_RB64(st->attached_pic.data) == 0x89504e470d0a1a0a) {
263  id = AV_CODEC_ID_PNG;
264  } else {
265  id = AV_CODEC_ID_MJPEG;
266  }
267  }
268  st->codecpar->codec_id = id;
269 
270  return 0;
271 }
272 
273 // 3GPP TS 26.244
274 static int mov_metadata_loci(MOVContext *c, AVIOContext *pb, unsigned len)
275 {
276  char language[4] = { 0 };
277  char buf[200], place[100];
278  uint16_t langcode = 0;
279  double longitude, latitude, altitude;
280  const char *key = "location";
281 
282  if (len < 4 + 2 + 1 + 1 + 4 + 4 + 4) {
283  av_log(c->fc, AV_LOG_ERROR, "loci too short\n");
284  return AVERROR_INVALIDDATA;
285  }
286 
287  avio_skip(pb, 4); // version+flags
288  langcode = avio_rb16(pb);
289  ff_mov_lang_to_iso639(langcode, language);
290  len -= 6;
291 
292  len -= avio_get_str(pb, len, place, sizeof(place));
293  if (len < 1) {
294  av_log(c->fc, AV_LOG_ERROR, "place name too long\n");
295  return AVERROR_INVALIDDATA;
296  }
297  avio_skip(pb, 1); // role
298  len -= 1;
299 
300  if (len < 12) {
301  av_log(c->fc, AV_LOG_ERROR,
302  "loci too short (%u bytes left, need at least %d)\n", len, 12);
303  return AVERROR_INVALIDDATA;
304  }
305  longitude = ((int32_t) avio_rb32(pb)) / (float) (1 << 16);
306  latitude = ((int32_t) avio_rb32(pb)) / (float) (1 << 16);
307  altitude = ((int32_t) avio_rb32(pb)) / (float) (1 << 16);
308 
309  // Try to output in the same format as the ?xyz field
310  snprintf(buf, sizeof(buf), "%+08.4f%+09.4f", latitude, longitude);
311  if (altitude)
312  av_strlcatf(buf, sizeof(buf), "%+f", altitude);
313  av_strlcatf(buf, sizeof(buf), "/%s", place);
314 
315  if (*language && strcmp(language, "und")) {
316  char key2[16];
317  snprintf(key2, sizeof(key2), "%s-%s", key, language);
318  av_dict_set(&c->fc->metadata, key2, buf, 0);
319  }
320  c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
321  return av_dict_set(&c->fc->metadata, key, buf, 0);
322 }
323 
324 static int mov_metadata_hmmt(MOVContext *c, AVIOContext *pb, unsigned len)
325 {
326  int i, n_hmmt;
327 
328  if (len < 2)
329  return 0;
330  if (c->ignore_chapters)
331  return 0;
332 
333  n_hmmt = avio_rb32(pb);
334  if (n_hmmt > len / 4)
335  return AVERROR_INVALIDDATA;
336  for (i = 0; i < n_hmmt && !pb->eof_reached; i++) {
337  int moment_time = avio_rb32(pb);
338  avpriv_new_chapter(c->fc, i, av_make_q(1, 1000), moment_time, AV_NOPTS_VALUE, NULL);
339  }
340  if (avio_feof(pb))
341  return AVERROR_INVALIDDATA;
342  return 0;
343 }
344 
346 {
347  char tmp_key[AV_FOURCC_MAX_STRING_SIZE] = {0};
348  char key2[32], language[4] = {0};
349  char *str = NULL;
350  const char *key = NULL;
351  uint16_t langcode = 0;
352  uint32_t data_type = 0, str_size_alloc;
353  uint64_t str_size;
354  int (*parse)(MOVContext*, AVIOContext*, unsigned, const char*) = NULL;
355  int raw = 0;
356  int num = 0;
358 
359  if (c->trak_index >= 0 && c->trak_index < c->fc->nb_streams)
360  metadata = &c->fc->streams[c->trak_index]->metadata;
361  else
362  metadata = &c->fc->metadata;
363 
364  switch (atom.type) {
365  case MKTAG( '@','P','R','M'): key = "premiere_version"; raw = 1; break;
366  case MKTAG( '@','P','R','Q'): key = "quicktime_version"; raw = 1; break;
367  case MKTAG( 'X','M','P','_'):
368  if (c->export_xmp) { key = "xmp"; raw = 1; } break;
369  case MKTAG( 'a','A','R','T'): key = "album_artist"; break;
370  case MKTAG( 'a','k','I','D'): key = "account_type";
372  case MKTAG( 'a','p','I','D'): key = "account_id"; break;
373  case MKTAG( 'c','a','t','g'): key = "category"; break;
374  case MKTAG( 'c','p','i','l'): key = "compilation";
376  case MKTAG( 'c','p','r','t'): key = "copyright"; break;
377  case MKTAG( 'd','e','s','c'): key = "description"; break;
378  case MKTAG( 'd','i','s','k'): key = "disc";
380  case MKTAG( 'e','g','i','d'): key = "episode_uid";
382  case MKTAG( 'F','I','R','M'): key = "firmware"; raw = 1; break;
383  case MKTAG( 'g','n','r','e'): key = "genre";
384  parse = mov_metadata_gnre; break;
385  case MKTAG( 'h','d','v','d'): key = "hd_video";
387  case MKTAG( 'H','M','M','T'):
388  return mov_metadata_hmmt(c, pb, atom.size);
389  case MKTAG( 'k','e','y','w'): key = "keywords"; break;
390  case MKTAG( 'l','d','e','s'): key = "synopsis"; break;
391  case MKTAG( 'l','o','c','i'):
392  return mov_metadata_loci(c, pb, atom.size);
393  case MKTAG( 'm','a','n','u'): key = "make"; break;
394  case MKTAG( 'm','o','d','l'): key = "model"; break;
395  case MKTAG( 'n','a','m','e'): key = "name"; break;
396  case MKTAG( 'p','c','s','t'): key = "podcast";
398  case MKTAG( 'p','g','a','p'): key = "gapless_playback";
400  case MKTAG( 'p','u','r','d'): key = "purchase_date"; break;
401  case MKTAG( 'r','t','n','g'): key = "rating";
403  case MKTAG( 's','o','a','a'): key = "sort_album_artist"; break;
404  case MKTAG( 's','o','a','l'): key = "sort_album"; break;
405  case MKTAG( 's','o','a','r'): key = "sort_artist"; break;
406  case MKTAG( 's','o','c','o'): key = "sort_composer"; break;
407  case MKTAG( 's','o','n','m'): key = "sort_name"; break;
408  case MKTAG( 's','o','s','n'): key = "sort_show"; break;
409  case MKTAG( 's','t','i','k'): key = "media_type";
411  case MKTAG( 't','r','k','n'): key = "track";
413  case MKTAG( 't','v','e','n'): key = "episode_id"; break;
414  case MKTAG( 't','v','e','s'): key = "episode_sort";
416  case MKTAG( 't','v','n','n'): key = "network"; break;
417  case MKTAG( 't','v','s','h'): key = "show"; break;
418  case MKTAG( 't','v','s','n'): key = "season_number";
420  case MKTAG(0xa9,'A','R','T'): key = "artist"; break;
421  case MKTAG(0xa9,'P','R','D'): key = "producer"; break;
422  case MKTAG(0xa9,'a','l','b'): key = "album"; break;
423  case MKTAG(0xa9,'a','u','t'): key = "artist"; break;
424  case MKTAG(0xa9,'c','h','p'): key = "chapter"; break;
425  case MKTAG(0xa9,'c','m','t'): key = "comment"; break;
426  case MKTAG(0xa9,'c','o','m'): key = "composer"; break;
427  case MKTAG(0xa9,'c','p','y'): key = "copyright"; break;
428  case MKTAG(0xa9,'d','a','y'): key = "date"; break;
429  case MKTAG(0xa9,'d','i','r'): key = "director"; break;
430  case MKTAG(0xa9,'d','i','s'): key = "disclaimer"; break;
431  case MKTAG(0xa9,'e','d','1'): key = "edit_date"; break;
432  case MKTAG(0xa9,'e','n','c'): key = "encoder"; break;
433  case MKTAG(0xa9,'f','m','t'): key = "original_format"; break;
434  case MKTAG(0xa9,'g','e','n'): key = "genre"; break;
435  case MKTAG(0xa9,'g','r','p'): key = "grouping"; break;
436  case MKTAG(0xa9,'h','s','t'): key = "host_computer"; break;
437  case MKTAG(0xa9,'i','n','f'): key = "comment"; break;
438  case MKTAG(0xa9,'l','y','r'): key = "lyrics"; break;
439  case MKTAG(0xa9,'m','a','k'): key = "make"; break;
440  case MKTAG(0xa9,'m','o','d'): key = "model"; break;
441  case MKTAG(0xa9,'n','a','m'): key = "title"; break;
442  case MKTAG(0xa9,'o','p','e'): key = "original_artist"; break;
443  case MKTAG(0xa9,'p','r','d'): key = "producer"; break;
444  case MKTAG(0xa9,'p','r','f'): key = "performers"; break;
445  case MKTAG(0xa9,'r','e','q'): key = "playback_requirements"; break;
446  case MKTAG(0xa9,'s','r','c'): key = "original_source"; break;
447  case MKTAG(0xa9,'s','t','3'): key = "subtitle"; break;
448  case MKTAG(0xa9,'s','w','r'): key = "encoder"; break;
449  case MKTAG(0xa9,'t','o','o'): key = "encoder"; break;
450  case MKTAG(0xa9,'t','r','k'): key = "track"; break;
451  case MKTAG(0xa9,'u','r','l'): key = "URL"; break;
452  case MKTAG(0xa9,'w','r','n'): key = "warning"; break;
453  case MKTAG(0xa9,'w','r','t'): key = "composer"; break;
454  case MKTAG(0xa9,'x','y','z'): key = "location"; break;
455  }
456 retry:
457  if (c->itunes_metadata && atom.size > 8) {
458  int data_size = avio_rb32(pb);
459  int tag = avio_rl32(pb);
460  if (tag == MKTAG('d','a','t','a') && data_size <= atom.size && data_size >= 16) {
461  data_type = avio_rb32(pb); // type
462  avio_rb32(pb); // unknown
463  str_size = data_size - 16;
464  atom.size -= 16;
465 
466  if (!key && c->found_hdlr_mdta && c->meta_keys) {
467  uint32_t index = av_bswap32(atom.type); // BE number has been read as LE
468  if (index < c->meta_keys_count && index > 0) {
469  key = c->meta_keys[index];
470  } else if (atom.type != MKTAG('c', 'o', 'v', 'r')) {
471  av_log(c->fc, AV_LOG_WARNING,
472  "The index of 'data' is out of range: %"PRId32" < 1 or >= %d.\n",
473  index, c->meta_keys_count);
474  }
475  }
476  if (atom.type == MKTAG('c', 'o', 'v', 'r') ||
477  (key && !strcmp(key, "com.apple.quicktime.artwork"))) {
478  int ret = mov_read_covr(c, pb, data_type, str_size);
479  if (ret < 0) {
480  av_log(c->fc, AV_LOG_ERROR, "Error parsing cover art.\n");
481  return ret;
482  }
483  atom.size -= str_size;
484  if (atom.size > 8)
485  goto retry;
486  return ret;
487  }
488  } else return 0;
489  } else if (atom.size > 4 && (key || c->export_all) && !c->itunes_metadata && !raw) {
490  str_size = avio_rb16(pb); // string length
491  if (str_size > atom.size) {
492  raw = 1;
493  avio_seek(pb, -2, SEEK_CUR);
494  av_log(c->fc, AV_LOG_WARNING, "UDTA parsing failed retrying raw\n");
495  goto retry;
496  }
497  langcode = avio_rb16(pb);
498  ff_mov_lang_to_iso639(langcode, language);
499  atom.size -= 4;
500  } else
501  str_size = atom.size;
502 
503  if (c->export_all && !key) {
504  key = av_fourcc_make_string(tmp_key, atom.type);
505  }
506 
507  if (!key)
508  return 0;
509  if (atom.size < 0 || str_size >= INT_MAX/2)
510  return AVERROR_INVALIDDATA;
511 
512  // Allocates enough space if data_type is a int32 or float32 number, otherwise
513  // worst-case requirement for output string in case of utf8 coded input
514  num = (data_type >= 21 && data_type <= 23);
515  str_size_alloc = (num ? 512 : (raw ? str_size : str_size * 2)) + 1;
516  str = av_mallocz(str_size_alloc);
517  if (!str)
518  return AVERROR(ENOMEM);
519 
520  if (parse)
521  parse(c, pb, str_size, key);
522  else {
523  if (!raw && (data_type == 3 || (data_type == 0 && (langcode < 0x400 || langcode == 0x7fff)))) { // MAC Encoded
524  mov_read_mac_string(c, pb, str_size, str, str_size_alloc);
525  } else if (data_type == 21) { // BE signed integer, variable size
526  int val = 0;
527  if (str_size == 1)
528  val = (int8_t)avio_r8(pb);
529  else if (str_size == 2)
530  val = (int16_t)avio_rb16(pb);
531  else if (str_size == 3)
532  val = ((int32_t)(avio_rb24(pb)<<8))>>8;
533  else if (str_size == 4)
534  val = (int32_t)avio_rb32(pb);
535  if (snprintf(str, str_size_alloc, "%d", val) >= str_size_alloc) {
536  av_log(c->fc, AV_LOG_ERROR,
537  "Failed to store the number (%d) in string.\n", val);
538  av_free(str);
539  return AVERROR_INVALIDDATA;
540  }
541  } else if (data_type == 22) { // BE unsigned integer, variable size
542  unsigned int val = 0;
543  if (str_size == 1)
544  val = avio_r8(pb);
545  else if (str_size == 2)
546  val = avio_rb16(pb);
547  else if (str_size == 3)
548  val = avio_rb24(pb);
549  else if (str_size == 4)
550  val = avio_rb32(pb);
551  if (snprintf(str, str_size_alloc, "%u", val) >= str_size_alloc) {
552  av_log(c->fc, AV_LOG_ERROR,
553  "Failed to store the number (%u) in string.\n", val);
554  av_free(str);
555  return AVERROR_INVALIDDATA;
556  }
557  } else if (data_type == 23 && str_size >= 4) { // BE float32
558  float val = av_int2float(avio_rb32(pb));
559  if (snprintf(str, str_size_alloc, "%f", val) >= str_size_alloc) {
560  av_log(c->fc, AV_LOG_ERROR,
561  "Failed to store the float32 number (%f) in string.\n", val);
562  av_free(str);
563  return AVERROR_INVALIDDATA;
564  }
565  } else if (data_type > 1 && data_type != 4) {
566  // data_type can be 0 if not set at all above. data_type 1 means
567  // UTF8 and 4 means "UTF8 sort". For any other type (UTF16 or e.g.
568  // a picture), don't return it blindly in a string that is supposed
569  // to be UTF8 text.
570  av_log(c->fc, AV_LOG_WARNING, "Skipping unhandled metadata %s of type %"PRIu32"\n", key, data_type);
571  av_free(str);
572  return 0;
573  } else {
574  int ret = ffio_read_size(pb, str, str_size);
575  if (ret < 0) {
576  av_free(str);
577  return ret;
578  }
579  str[str_size] = 0;
580  }
581  c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
582  av_dict_set(metadata, key, str, 0);
583  if (*language && strcmp(language, "und")) {
584  snprintf(key2, sizeof(key2), "%s-%s", key, language);
585  av_dict_set(metadata, key2, str, 0);
586  }
587  if (!strcmp(key, "encoder")) {
588  int major, minor, micro;
589  if (sscanf(str, "HandBrake %d.%d.%d", &major, &minor, &micro) == 3) {
590  c->handbrake_version = 1000000*major + 1000*minor + micro;
591  }
592  }
593  }
594 
595  av_freep(&str);
596  return 0;
597 }
598 
600 {
601  int64_t start;
602  int i, nb_chapters, str_len, version;
603  char str[256+1];
604  int ret;
605 
606  if (c->ignore_chapters)
607  return 0;
608 
609  if ((atom.size -= 5) < 0)
610  return 0;
611 
612  version = avio_r8(pb);
613  avio_rb24(pb);
614  if (version)
615  avio_rb32(pb); // ???
616  nb_chapters = avio_r8(pb);
617 
618  for (i = 0; i < nb_chapters; i++) {
619  if (atom.size < 9)
620  return 0;
621 
622  start = avio_rb64(pb);
623  str_len = avio_r8(pb);
624 
625  if ((atom.size -= 9+str_len) < 0)
626  return 0;
627 
628  ret = ffio_read_size(pb, str, str_len);
629  if (ret < 0)
630  return ret;
631  str[str_len] = 0;
632  avpriv_new_chapter(c->fc, i, (AVRational){1,10000000}, start, AV_NOPTS_VALUE, str);
633  }
634  return 0;
635 }
636 
637 #define MIN_DATA_ENTRY_BOX_SIZE 12
639 {
640  AVStream *st;
641  MOVStreamContext *sc;
642  int entries, i, j;
643 
644  if (c->fc->nb_streams < 1)
645  return 0;
646  st = c->fc->streams[c->fc->nb_streams-1];
647  sc = st->priv_data;
648 
649  avio_rb32(pb); // version + flags
650  entries = avio_rb32(pb);
651  if (!entries ||
652  entries > (atom.size - 1) / MIN_DATA_ENTRY_BOX_SIZE + 1 ||
653  entries >= UINT_MAX / sizeof(*sc->drefs))
654  return AVERROR_INVALIDDATA;
655 
656  for (i = 0; i < sc->drefs_count; i++) {
657  MOVDref *dref = &sc->drefs[i];
658  av_freep(&dref->path);
659  av_freep(&dref->dir);
660  }
661  av_free(sc->drefs);
662  sc->drefs_count = 0;
663  sc->drefs = av_mallocz(entries * sizeof(*sc->drefs));
664  if (!sc->drefs)
665  return AVERROR(ENOMEM);
666  sc->drefs_count = entries;
667 
668  for (i = 0; i < entries; i++) {
669  MOVDref *dref = &sc->drefs[i];
670  uint32_t size = avio_rb32(pb);
671  int64_t next = avio_tell(pb);
672 
673  if (size < 12 || next < 0 || next > INT64_MAX - size)
674  return AVERROR_INVALIDDATA;
675 
676  next += size - 4;
677 
678  dref->type = avio_rl32(pb);
679  avio_rb32(pb); // version + flags
680 
681  if (dref->type == MKTAG('a','l','i','s') && size > 150) {
682  /* macintosh alias record */
683  uint16_t volume_len, len;
684  int16_t type;
685  int ret;
686 
687  avio_skip(pb, 10);
688 
689  volume_len = avio_r8(pb);
690  volume_len = FFMIN(volume_len, 27);
691  ret = ffio_read_size(pb, dref->volume, 27);
692  if (ret < 0)
693  return ret;
694  dref->volume[volume_len] = 0;
695  av_log(c->fc, AV_LOG_DEBUG, "volume %s, len %d\n", dref->volume, volume_len);
696 
697  avio_skip(pb, 12);
698 
699  len = avio_r8(pb);
700  len = FFMIN(len, 63);
701  ret = ffio_read_size(pb, dref->filename, 63);
702  if (ret < 0)
703  return ret;
704  dref->filename[len] = 0;
705  av_log(c->fc, AV_LOG_DEBUG, "filename %s, len %d\n", dref->filename, len);
706 
707  avio_skip(pb, 16);
708 
709  /* read next level up_from_alias/down_to_target */
710  dref->nlvl_from = avio_rb16(pb);
711  dref->nlvl_to = avio_rb16(pb);
712  av_log(c->fc, AV_LOG_DEBUG, "nlvl from %d, nlvl to %d\n",
713  dref->nlvl_from, dref->nlvl_to);
714 
715  avio_skip(pb, 16);
716 
717  for (type = 0; type != -1 && avio_tell(pb) < next; ) {
718  if (avio_feof(pb))
719  return AVERROR_EOF;
720  type = avio_rb16(pb);
721  len = avio_rb16(pb);
722  av_log(c->fc, AV_LOG_DEBUG, "type %d, len %d\n", type, len);
723  if (len&1)
724  len += 1;
725  if (type == 2) { // absolute path
726  av_free(dref->path);
727  dref->path = av_mallocz(len+1);
728  if (!dref->path)
729  return AVERROR(ENOMEM);
730 
731  ret = ffio_read_size(pb, dref->path, len);
732  if (ret < 0) {
733  av_freep(&dref->path);
734  return ret;
735  }
736  if (len > volume_len && !strncmp(dref->path, dref->volume, volume_len)) {
737  len -= volume_len;
738  memmove(dref->path, dref->path+volume_len, len);
739  dref->path[len] = 0;
740  }
741  // trim string of any ending zeros
742  for (j = len - 1; j >= 0; j--) {
743  if (dref->path[j] == 0)
744  len--;
745  else
746  break;
747  }
748  for (j = 0; j < len; j++)
749  if (dref->path[j] == ':' || dref->path[j] == 0)
750  dref->path[j] = '/';
751  av_log(c->fc, AV_LOG_DEBUG, "path %s\n", dref->path);
752  } else if (type == 0) { // directory name
753  av_free(dref->dir);
754  dref->dir = av_malloc(len+1);
755  if (!dref->dir)
756  return AVERROR(ENOMEM);
757 
758  ret = ffio_read_size(pb, dref->dir, len);
759  if (ret < 0) {
760  av_freep(&dref->dir);
761  return ret;
762  }
763  dref->dir[len] = 0;
764  for (j = 0; j < len; j++)
765  if (dref->dir[j] == ':')
766  dref->dir[j] = '/';
767  av_log(c->fc, AV_LOG_DEBUG, "dir %s\n", dref->dir);
768  } else
769  avio_skip(pb, len);
770  }
771  } else {
772  av_log(c->fc, AV_LOG_DEBUG, "Unknown dref type 0x%08"PRIx32" size %"PRIu32"\n",
773  dref->type, size);
774  entries--;
775  i--;
776  }
777  avio_seek(pb, next, SEEK_SET);
778  }
779  return 0;
780 }
781 
783 {
784  AVStream *st;
785  uint32_t type;
786  uint32_t ctype;
787  int64_t title_size;
788  char *title_str;
789  int ret;
790 
791  avio_r8(pb); /* version */
792  avio_rb24(pb); /* flags */
793 
794  /* component type */
795  ctype = avio_rl32(pb);
796  type = avio_rl32(pb); /* component subtype */
797 
798  av_log(c->fc, AV_LOG_TRACE, "ctype=%s\n", av_fourcc2str(ctype));
799  av_log(c->fc, AV_LOG_TRACE, "stype=%s\n", av_fourcc2str(type));
800 
801  if (c->trak_index < 0) { // meta not inside a trak
802  if (type == MKTAG('m','d','t','a')) {
803  c->found_hdlr_mdta = 1;
804  }
805  return 0;
806  }
807 
808  st = c->fc->streams[c->fc->nb_streams-1];
809 
810  if (type == MKTAG('v','i','d','e'))
812  else if (type == MKTAG('s','o','u','n'))
814  else if (type == MKTAG('m','1','a',' '))
816  else if ((type == MKTAG('s','u','b','p')) || (type == MKTAG('c','l','c','p')))
818 
819  avio_rb32(pb); /* component manufacture */
820  avio_rb32(pb); /* component flags */
821  avio_rb32(pb); /* component flags mask */
822 
823  title_size = atom.size - 24;
824  if (title_size > 0) {
825  if (title_size > FFMIN(INT_MAX, SIZE_MAX-1))
826  return AVERROR_INVALIDDATA;
827  title_str = av_malloc(title_size + 1); /* Add null terminator */
828  if (!title_str)
829  return AVERROR(ENOMEM);
830 
831  ret = ffio_read_size(pb, title_str, title_size);
832  if (ret < 0) {
833  av_freep(&title_str);
834  return ret;
835  }
836  title_str[title_size] = 0;
837  if (title_str[0]) {
838  int off = (!c->isom && title_str[0] == title_size - 1);
839  // flag added so as to not set stream handler name if already set from mdia->hdlr
840  av_dict_set(&st->metadata, "handler_name", title_str + off, AV_DICT_DONT_OVERWRITE);
841  }
842  av_freep(&title_str);
843  }
844 
845  return 0;
846 }
847 
849 {
850  return ff_mov_read_esds(c->fc, pb);
851 }
852 
854 {
855  AVStream *st;
856  AVPacketSideData *sd;
857  enum AVAudioServiceType *ast;
858  int ac3info, acmod, lfeon, bsmod;
859  uint64_t mask;
860 
861  if (c->fc->nb_streams < 1)
862  return 0;
863  st = c->fc->streams[c->fc->nb_streams-1];
864 
868  sizeof(*ast), 0);
869  if (!sd)
870  return AVERROR(ENOMEM);
871 
872  ast = (enum AVAudioServiceType*)sd->data;
873  ac3info = avio_rb24(pb);
874  bsmod = (ac3info >> 14) & 0x7;
875  acmod = (ac3info >> 11) & 0x7;
876  lfeon = (ac3info >> 10) & 0x1;
877 
879  if (lfeon)
883 
884  *ast = bsmod;
885  if (st->codecpar->ch_layout.nb_channels > 1 && bsmod == 0x7)
887 
888  return 0;
889 }
890 
891 #if CONFIG_IAMFDEC
892 static int mov_read_iacb(MOVContext *c, AVIOContext *pb, MOVAtom atom)
893 {
894  AVStream *st;
895  MOVStreamContext *sc;
896  FFIOContext b;
897  AVIOContext *descriptor_pb;
899  IAMFContext *iamf;
901  unsigned descriptors_size;
902  int nb_frames, disposition;
903  int version, ret;
904 
905  if (atom.size < 5)
906  return AVERROR_INVALIDDATA;
907 
908  if (c->fc->nb_streams < 1)
909  return 0;
910 
911  version = avio_r8(pb);
912  if (version != 1) {
913  av_log(c->fc, AV_LOG_ERROR, "%s configurationVersion %d",
914  version < 1 ? "invalid" : "unsupported", version);
915  return AVERROR_INVALIDDATA;
916  }
917 
918  descriptors_size = ffio_read_leb(pb);
919  if (!descriptors_size || descriptors_size > INT_MAX)
920  return AVERROR_INVALIDDATA;
921 
922  st = c->fc->streams[c->fc->nb_streams - 1];
923  sc = st->priv_data;
924 
925  if (st->codecpar->extradata) {
926  av_log(c->fc, AV_LOG_WARNING, "ignoring iacb\n");
927  return 0;
928  }
929 
930  sc->iamf = av_mallocz(sizeof(*sc->iamf));
931  if (!sc->iamf)
932  return AVERROR(ENOMEM);
933  iamf = &sc->iamf->iamf;
934 
935  ret = ff_alloc_extradata(st->codecpar, descriptors_size);
936  if (ret < 0)
937  return ret;
938 
939  ret = avio_read(pb, st->codecpar->extradata, descriptors_size);
940  if (ret != descriptors_size)
941  return ret < 0 ? ret : AVERROR_INVALIDDATA;
942 
943  ffio_init_read_context(&b, st->codecpar->extradata, descriptors_size);
944  descriptor_pb = &b.pub;
945 
946  ret = ff_iamfdec_read_descriptors(iamf, descriptor_pb, descriptors_size, c->fc);
947  if (ret < 0)
948  return ret;
949 
950  metadata = st->metadata;
951  st->metadata = NULL;
952  start_time = st->start_time;
953  nb_frames = st->nb_frames;
954  duration = st->duration;
955  disposition = st->disposition;
956 
957  for (int i = 0; i < iamf->nb_audio_elements; i++) {
958  IAMFAudioElement *audio_element = iamf->audio_elements[i];
959  const AVIAMFAudioElement *element;
960  AVStreamGroup *stg =
962 
963  if (!stg) {
964  ret = AVERROR(ENOMEM);
965  goto fail;
966  }
967 
969  stg->id = audio_element->audio_element_id;
970  /* Transfer ownership */
971  element = stg->params.iamf_audio_element = audio_element->element;
972  audio_element->element = NULL;
973 
974  for (int j = 0; j < audio_element->nb_substreams; j++) {
975  IAMFSubStream *substream = &audio_element->substreams[j];
976  AVStream *stream;
977 
978  if (!i && !j) {
979  if (audio_element->layers[0].substream_count != 1)
980  disposition &= ~AV_DISPOSITION_DEFAULT;
981  stream = st;
982  } else
983  stream = avformat_new_stream(c->fc, NULL);
984  if (!stream) {
985  ret = AVERROR(ENOMEM);
986  goto fail;
987  }
988 
989  stream->start_time = start_time;
990  stream->nb_frames = nb_frames;
991  stream->duration = duration;
992  stream->disposition = disposition;
993  if (stream != st) {
994  stream->priv_data = sc;
995  sc->refcount++;
996  }
997 
1000  if (i || j) {
1002  if (audio_element->layers[0].substream_count == 1)
1003  stream->disposition &= ~AV_DISPOSITION_DEFAULT;
1004  }
1005 
1006  ret = avcodec_parameters_copy(stream->codecpar, substream->codecpar);
1007  if (ret < 0)
1008  goto fail;
1009 
1010  stream->id = substream->audio_substream_id;
1011 
1012  avpriv_set_pts_info(st, 64, 1, sc->time_scale);
1013 
1014  ret = avformat_stream_group_add_stream(stg, stream);
1015  if (ret < 0)
1016  goto fail;
1017  }
1018 
1019  ret = av_dict_copy(&stg->metadata, metadata, 0);
1020  if (ret < 0)
1021  goto fail;
1022  }
1023 
1024  for (int i = 0; i < iamf->nb_mix_presentations; i++) {
1025  IAMFMixPresentation *mix_presentation = iamf->mix_presentations[i];
1026  const AVIAMFMixPresentation *mix = mix_presentation->cmix;
1027  AVStreamGroup *stg =
1029 
1030  if (!stg) {
1031  ret = AVERROR(ENOMEM);
1032  goto fail;
1033  }
1034 
1036  stg->id = mix_presentation->mix_presentation_id;
1037  /* Transfer ownership */
1038  stg->params.iamf_mix_presentation = mix_presentation->mix;
1039  mix_presentation->mix = NULL;
1040 
1041  for (int j = 0; j < mix->nb_submixes; j++) {
1042  const AVIAMFSubmix *submix = mix->submixes[j];
1043 
1044  for (int k = 0; k < submix->nb_elements; k++) {
1045  const AVIAMFSubmixElement *submix_element = submix->elements[k];
1046  const AVStreamGroup *audio_element = NULL;
1047 
1048  for (int l = 0; l < c->fc->nb_stream_groups; l++)
1049  if (c->fc->stream_groups[l]->type == AV_STREAM_GROUP_PARAMS_IAMF_AUDIO_ELEMENT &&
1050  c->fc->stream_groups[l]->id == submix_element->audio_element_id) {
1051  audio_element = c->fc->stream_groups[l];
1052  break;
1053  }
1054  av_assert0(audio_element);
1055 
1056  for (int l = 0; l < audio_element->nb_streams; l++) {
1057  ret = avformat_stream_group_add_stream(stg, audio_element->streams[l]);
1058  if (ret < 0 && ret != AVERROR(EEXIST))
1059  goto fail;
1060  }
1061  }
1062  }
1063 
1064  ret = av_dict_copy(&stg->metadata, metadata, 0);
1065  if (ret < 0)
1066  goto fail;
1067  }
1068 
1069  ret = 0;
1070 fail:
1072 
1073  return ret;
1074 }
1075 #endif
1076 
1078 {
1079  AVStream *st;
1080  int32_t sample_rate;
1081 
1082  if (atom.size < 8 || c->fc->nb_streams < 1)
1083  return 0;
1084 
1085  st = c->fc->streams[c->fc->nb_streams-1];
1086  if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO) {
1087  av_log(c->fc, AV_LOG_WARNING, "'srat' within non-audio sample entry, skip\n");
1088  return 0;
1089  }
1090 
1091  if (!c->isom) {
1092  av_log(c->fc, AV_LOG_WARNING, "'srat' within non-isom, skip\n");
1093  return 0;
1094  }
1095 
1096  avio_skip(pb, 4); // version+flags
1097  sample_rate = avio_rb32(pb);
1098  if (sample_rate > 0) {
1099  av_log(c->fc, AV_LOG_DEBUG,
1100  "overwrite sample rate from %d to %d by 'srat'\n",
1101  st->codecpar->sample_rate, sample_rate);
1102  st->codecpar->sample_rate = sample_rate;
1103  } else {
1104  av_log(c->fc, AV_LOG_WARNING,
1105  "ignore invalid sample rate %d in 'srat'\n", sample_rate);
1106  }
1107 
1108  return 0;
1109 }
1110 
1112 {
1113  AVStream *st;
1114  AVPacketSideData *sd;
1115  enum AVAudioServiceType *ast;
1116  int eac3info, acmod, lfeon, bsmod;
1117  uint64_t mask;
1118 
1119  if (c->fc->nb_streams < 1)
1120  return 0;
1121  st = c->fc->streams[c->fc->nb_streams-1];
1122 
1126  sizeof(*ast), 0);
1127  if (!sd)
1128  return AVERROR(ENOMEM);
1129 
1130  ast = (enum AVAudioServiceType*)sd->data;
1131 
1132  /* No need to parse fields for additional independent substreams and its
1133  * associated dependent substreams since libavcodec's E-AC-3 decoder
1134  * does not support them yet. */
1135  avio_rb16(pb); /* data_rate and num_ind_sub */
1136  eac3info = avio_rb24(pb);
1137  bsmod = (eac3info >> 12) & 0x1f;
1138  acmod = (eac3info >> 9) & 0x7;
1139  lfeon = (eac3info >> 8) & 0x1;
1140 
1142  if (lfeon)
1146 
1147  *ast = bsmod;
1148  if (st->codecpar->ch_layout.nb_channels > 1 && bsmod == 0x7)
1150 
1151  return 0;
1152 }
1153 
1155 {
1156 #define DDTS_SIZE 20
1157  uint8_t buf[DDTS_SIZE + AV_INPUT_BUFFER_PADDING_SIZE];
1158  AVStream *st = NULL;
1159  uint32_t frame_duration_code = 0;
1160  uint32_t channel_layout_code = 0;
1161  GetBitContext gb;
1162  int ret;
1163 
1164  if ((ret = ffio_read_size(pb, buf, DDTS_SIZE)) < 0)
1165  return ret;
1166 
1167  init_get_bits(&gb, buf, 8 * DDTS_SIZE);
1168 
1169  if (c->fc->nb_streams < 1) {
1170  return 0;
1171  }
1172  st = c->fc->streams[c->fc->nb_streams-1];
1173 
1174  st->codecpar->sample_rate = get_bits_long(&gb, 32);
1175  if (st->codecpar->sample_rate <= 0) {
1176  av_log(c->fc, AV_LOG_ERROR, "Invalid sample rate %d\n", st->codecpar->sample_rate);
1177  return AVERROR_INVALIDDATA;
1178  }
1179  skip_bits_long(&gb, 32); /* max bitrate */
1180  st->codecpar->bit_rate = get_bits_long(&gb, 32);
1181  st->codecpar->bits_per_coded_sample = get_bits(&gb, 8);
1182  frame_duration_code = get_bits(&gb, 2);
1183  skip_bits(&gb, 30); /* various fields */
1184  channel_layout_code = get_bits(&gb, 16);
1185 
1186  st->codecpar->frame_size =
1187  (frame_duration_code == 0) ? 512 :
1188  (frame_duration_code == 1) ? 1024 :
1189  (frame_duration_code == 2) ? 2048 :
1190  (frame_duration_code == 3) ? 4096 : 0;
1191 
1192  if (channel_layout_code > 0xff) {
1193  av_log(c->fc, AV_LOG_WARNING, "Unsupported DTS audio channel layout\n");
1194  }
1197  ((channel_layout_code & 0x1) ? AV_CH_FRONT_CENTER : 0) |
1198  ((channel_layout_code & 0x2) ? AV_CH_FRONT_LEFT : 0) |
1199  ((channel_layout_code & 0x2) ? AV_CH_FRONT_RIGHT : 0) |
1200  ((channel_layout_code & 0x4) ? AV_CH_SIDE_LEFT : 0) |
1201  ((channel_layout_code & 0x4) ? AV_CH_SIDE_RIGHT : 0) |
1202  ((channel_layout_code & 0x8) ? AV_CH_LOW_FREQUENCY : 0));
1203 
1204  return 0;
1205 }
1206 
1208 {
1209  AVStream *st;
1210 
1211  if (c->fc->nb_streams < 1)
1212  return 0;
1213  st = c->fc->streams[c->fc->nb_streams-1];
1214 
1215  if (atom.size < 16)
1216  return 0;
1217 
1218  /* skip version and flags */
1219  avio_skip(pb, 4);
1220 
1221  ff_mov_read_chan(c->fc, pb, st, atom.size - 4);
1222 
1223  return 0;
1224 }
1225 
1227 {
1228  int64_t end = av_sat_add64(avio_tell(pb), atom.size);
1229  int version, flags;
1230  int ret;
1231  AVStream *st;
1232 
1233  if (c->fc->nb_streams < 1)
1234  return 0;
1235  st = c->fc->streams[c->fc->nb_streams-1];
1236 
1237  version = avio_r8(pb);
1238  flags = avio_rb24(pb);
1239  if (version != 0 || flags != 0) {
1240  av_log(c->fc, AV_LOG_ERROR,
1241  "Unsupported 'chnl' box with version %d, flags: %#x",
1242  version, flags);
1243  return AVERROR_INVALIDDATA;
1244  }
1245 
1246  ret = ff_mov_read_chnl(c->fc, pb, st);
1247  if (ret < 0)
1248  return ret;
1249 
1250  if (avio_tell(pb) != end) {
1251  av_log(c->fc, AV_LOG_WARNING, "skip %" PRId64 " bytes of unknown data inside chnl\n",
1252  end - avio_tell(pb));
1253  avio_seek(pb, end, SEEK_SET);
1254  }
1255  return ret;
1256 }
1257 
1259 {
1260  AVStream *st;
1261  int ret;
1262 
1263  if (c->fc->nb_streams < 1)
1264  return 0;
1265  st = c->fc->streams[c->fc->nb_streams-1];
1266 
1267  if ((ret = ff_get_wav_header(c->fc, pb, st->codecpar, atom.size, 0)) < 0)
1268  av_log(c->fc, AV_LOG_WARNING, "get_wav_header failed\n");
1269 
1270  return ret;
1271 }
1272 
1274 {
1275  AVStream *st;
1276  HEIFItem *item;
1277  AVPacketSideData *sd;
1278  int width, height, err = 0;
1279  AVRational aperture_width, aperture_height, horiz_off, vert_off;
1280  AVRational pc_x, pc_y;
1281  uint64_t top, bottom, left, right;
1282 
1283  item = get_heif_item(c, c->cur_item_id);
1284  st = get_curr_st(c);
1285  if (!st)
1286  return 0;
1287 
1288  width = st->codecpar->width;
1289  height = st->codecpar->height;
1290  if ((!width || !height) && item) {
1291  width = item->width;
1292  height = item->height;
1293  }
1294  if (!width || !height) {
1295  err = AVERROR_INVALIDDATA;
1296  goto fail;
1297  }
1298 
1299  aperture_width.num = avio_rb32(pb);
1300  aperture_width.den = avio_rb32(pb);
1301  aperture_height.num = avio_rb32(pb);
1302  aperture_height.den = avio_rb32(pb);
1303 
1304  horiz_off.num = avio_rb32(pb);
1305  horiz_off.den = avio_rb32(pb);
1306  vert_off.num = avio_rb32(pb);
1307  vert_off.den = avio_rb32(pb);
1308 
1309  if (aperture_width.num < 0 || aperture_width.den < 0 ||
1310  aperture_height.num < 0 || aperture_height.den < 0 ||
1311  horiz_off.den < 0 || vert_off.den < 0) {
1312  err = AVERROR_INVALIDDATA;
1313  goto fail;
1314  }
1315  if ((av_cmp_q((AVRational) { width, 1 }, aperture_width) < 0) ||
1316  (av_cmp_q((AVRational) { height, 1 }, aperture_height) < 0)) {
1317  err = AVERROR_INVALIDDATA;
1318  goto fail;
1319  }
1320  av_log(c->fc, AV_LOG_TRACE, "clap: apertureWidth %d/%d, apertureHeight %d/%d "
1321  "horizOff %d/%d vertOff %d/%d\n",
1322  aperture_width.num, aperture_width.den, aperture_height.num, aperture_height.den,
1323  horiz_off.num, horiz_off.den, vert_off.num, vert_off.den);
1324 
1325  pc_x = av_mul_q((AVRational) { width - 1, 1 }, (AVRational) { 1, 2 });
1326  pc_x = av_add_q(pc_x, horiz_off);
1327  pc_y = av_mul_q((AVRational) { height - 1, 1 }, (AVRational) { 1, 2 });
1328  pc_y = av_add_q(pc_y, vert_off);
1329 
1330  aperture_width = av_sub_q(aperture_width, (AVRational) { 1, 1 });
1331  aperture_width = av_mul_q(aperture_width, (AVRational) { 1, 2 });
1332  aperture_height = av_sub_q(aperture_height, (AVRational) { 1, 1 });
1333  aperture_height = av_mul_q(aperture_height, (AVRational) { 1, 2 });
1334 
1335  left = av_q2d(av_sub_q(pc_x, aperture_width));
1336  right = av_q2d(av_add_q(pc_x, aperture_width));
1337  top = av_q2d(av_sub_q(pc_y, aperture_height));
1338  bottom = av_q2d(av_add_q(pc_y, aperture_height));
1339 
1340  if (bottom > (height - 1) ||
1341  right > (width - 1)) {
1342  err = AVERROR_INVALIDDATA;
1343  goto fail;
1344  }
1345 
1346  bottom = height - 1 - bottom;
1347  right = width - 1 - right;
1348 
1349  if (!(left | right | top | bottom))
1350  return 0;
1351 
1352  if ((left + right) >= width ||
1353  (top + bottom) >= height) {
1354  err = AVERROR_INVALIDDATA;
1355  goto fail;
1356  }
1357 
1361  sizeof(uint32_t) * 4, 0);
1362  if (!sd)
1363  return AVERROR(ENOMEM);
1364 
1365  AV_WL32A(sd->data, top);
1366  AV_WL32A(sd->data + 4, bottom);
1367  AV_WL32A(sd->data + 8, left);
1368  AV_WL32A(sd->data + 12, right);
1369 
1370 fail:
1371  if (err < 0) {
1372  int explode = !!(c->fc->error_recognition & AV_EF_EXPLODE);
1373  av_log(c->fc, explode ? AV_LOG_ERROR : AV_LOG_WARNING, "Invalid clap box\n");
1374  if (!explode)
1375  err = 0;
1376  }
1377 
1378  return err;
1379 }
1380 
1381 /* This atom overrides any previously set aspect ratio */
1383 {
1384  const int num = avio_rb32(pb);
1385  const int den = avio_rb32(pb);
1386  AVStream *st;
1387  MOVStreamContext *sc;
1388 
1389  if (c->fc->nb_streams < 1)
1390  return 0;
1391  st = c->fc->streams[c->fc->nb_streams-1];
1392  sc = st->priv_data;
1393 
1394  av_log(c->fc, AV_LOG_TRACE, "pasp: hSpacing %d, vSpacing %d\n", num, den);
1395 
1396  if (den != 0) {
1397  sc->h_spacing = num;
1398  sc->v_spacing = den;
1399  }
1400  return 0;
1401 }
1402 
1403 /* this atom contains actual media data */
1405 {
1406  if (atom.size == 0) /* wrong one (MP4) */
1407  return 0;
1408  c->found_mdat=1;
1409  return 0; /* now go for moov */
1410 }
1411 
1412 #define DRM_BLOB_SIZE 56
1413 
1415 {
1416  uint8_t intermediate_key[20];
1417  uint8_t intermediate_iv[20];
1418  uint8_t input[64];
1419  uint8_t output[64];
1420  uint8_t file_checksum[20];
1421  uint8_t calculated_checksum[20];
1422  char checksum_string[2 * sizeof(file_checksum) + 1];
1423  struct AVSHA *sha;
1424  int i;
1425  int ret = 0;
1426  uint8_t *activation_bytes = c->activation_bytes;
1427  uint8_t *fixed_key = c->audible_fixed_key;
1428 
1429  c->aax_mode = 1;
1430 
1431  sha = av_sha_alloc();
1432  if (!sha)
1433  return AVERROR(ENOMEM);
1434  av_free(c->aes_decrypt);
1435  c->aes_decrypt = av_aes_alloc();
1436  if (!c->aes_decrypt) {
1437  ret = AVERROR(ENOMEM);
1438  goto fail;
1439  }
1440 
1441  /* drm blob processing */
1442  avio_read(pb, output, 8); // go to offset 8, absolute position 0x251
1444  avio_read(pb, output, 4); // go to offset 4, absolute position 0x28d
1445  ret = ffio_read_size(pb, file_checksum, 20);
1446  if (ret < 0)
1447  goto fail;
1448 
1449  // required by external tools
1450  ff_data_to_hex(checksum_string, file_checksum, sizeof(file_checksum), 1);
1451  av_log(c->fc, AV_LOG_INFO, "[aax] file checksum == %s\n", checksum_string);
1452 
1453  /* verify activation data */
1454  if (!activation_bytes) {
1455  av_log(c->fc, AV_LOG_WARNING, "[aax] activation_bytes option is missing!\n");
1456  ret = 0; /* allow ffprobe to continue working on .aax files */
1457  goto fail;
1458  }
1459  if (c->activation_bytes_size != 4) {
1460  av_log(c->fc, AV_LOG_FATAL, "[aax] activation_bytes value needs to be 4 bytes!\n");
1461  ret = AVERROR(EINVAL);
1462  goto fail;
1463  }
1464 
1465  /* verify fixed key */
1466  if (c->audible_fixed_key_size != 16) {
1467  av_log(c->fc, AV_LOG_FATAL, "[aax] audible_fixed_key value needs to be 16 bytes!\n");
1468  ret = AVERROR(EINVAL);
1469  goto fail;
1470  }
1471 
1472  /* AAX (and AAX+) key derivation */
1473  av_sha_init(sha, 160);
1474  av_sha_update(sha, fixed_key, 16);
1475  av_sha_update(sha, activation_bytes, 4);
1476  av_sha_final(sha, intermediate_key);
1477  av_sha_init(sha, 160);
1478  av_sha_update(sha, fixed_key, 16);
1479  av_sha_update(sha, intermediate_key, 20);
1480  av_sha_update(sha, activation_bytes, 4);
1481  av_sha_final(sha, intermediate_iv);
1482  av_sha_init(sha, 160);
1483  av_sha_update(sha, intermediate_key, 16);
1484  av_sha_update(sha, intermediate_iv, 16);
1485  av_sha_final(sha, calculated_checksum);
1486  if (memcmp(calculated_checksum, file_checksum, 20)) { // critical error
1487  av_log(c->fc, AV_LOG_ERROR, "[aax] mismatch in checksums!\n");
1489  goto fail;
1490  }
1491  av_aes_init(c->aes_decrypt, intermediate_key, 128, 1);
1492  av_aes_crypt(c->aes_decrypt, output, input, DRM_BLOB_SIZE >> 4, intermediate_iv, 1);
1493  for (i = 0; i < 4; i++) {
1494  // file data (in output) is stored in big-endian mode
1495  if (activation_bytes[i] != output[3 - i]) { // critical error
1496  av_log(c->fc, AV_LOG_ERROR, "[aax] error in drm blob decryption!\n");
1498  goto fail;
1499  }
1500  }
1501  memcpy(c->file_key, output + 8, 16);
1502  memcpy(input, output + 26, 16);
1503  av_sha_init(sha, 160);
1504  av_sha_update(sha, input, 16);
1505  av_sha_update(sha, c->file_key, 16);
1506  av_sha_update(sha, fixed_key, 16);
1507  av_sha_final(sha, c->file_iv);
1508 
1509 fail:
1510  av_free(sha);
1511 
1512  return ret;
1513 }
1514 
1516 {
1517  if (c->audible_key_size != 16) {
1518  av_log(c->fc, AV_LOG_FATAL, "[aaxc] audible_key value needs to be 16 bytes!\n");
1519  return AVERROR(EINVAL);
1520  }
1521 
1522  if (c->audible_iv_size != 16) {
1523  av_log(c->fc, AV_LOG_FATAL, "[aaxc] audible_iv value needs to be 16 bytes!\n");
1524  return AVERROR(EINVAL);
1525  }
1526 
1527  c->aes_decrypt = av_aes_alloc();
1528  if (!c->aes_decrypt) {
1529  return AVERROR(ENOMEM);
1530  }
1531 
1532  memcpy(c->file_key, c->audible_key, 16);
1533  memcpy(c->file_iv, c->audible_iv, 16);
1534  c->aax_mode = 1;
1535 
1536  return 0;
1537 }
1538 
1539 // Audible AAX (and AAX+) bytestream decryption
1540 static int aax_filter(uint8_t *input, int size, MOVContext *c)
1541 {
1542  int blocks = 0;
1543  unsigned char iv[16];
1544 
1545  memcpy(iv, c->file_iv, 16); // iv is overwritten
1546  blocks = size >> 4; // trailing bytes are not encrypted!
1547  av_aes_init(c->aes_decrypt, c->file_key, 128, 1);
1548  av_aes_crypt(c->aes_decrypt, input, input, blocks, iv, 1);
1549 
1550  return 0;
1551 }
1552 
1553 /* read major brand, minor version and compatible brands and store them as metadata */
1555 {
1556  uint32_t minor_ver;
1557  int comp_brand_size;
1558  char* comp_brands_str;
1559  uint8_t type[5] = {0};
1560  int ret = ffio_read_size(pb, type, 4);
1561  if (ret < 0)
1562  return ret;
1563  if (c->fc->nb_streams) {
1564  if (c->fc->strict_std_compliance >= FF_COMPLIANCE_STRICT)
1565  return AVERROR_INVALIDDATA;
1566  av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate FTYP\n");
1567  return 0;
1568  }
1569 
1570  if (strcmp(type, "qt "))
1571  c->isom = 1;
1572  av_log(c->fc, AV_LOG_DEBUG, "ISO: File Type Major Brand: %.4s\n",(char *)&type);
1573  av_dict_set(&c->fc->metadata, "major_brand", type, 0);
1574  minor_ver = avio_rb32(pb); /* minor version */
1575  av_dict_set_int(&c->fc->metadata, "minor_version", minor_ver, 0);
1576 
1577  comp_brand_size = atom.size - 8;
1578  if (comp_brand_size < 0 || comp_brand_size == INT_MAX)
1579  return AVERROR_INVALIDDATA;
1580  comp_brands_str = av_malloc(comp_brand_size + 1); /* Add null terminator */
1581  if (!comp_brands_str)
1582  return AVERROR(ENOMEM);
1583 
1584  ret = ffio_read_size(pb, comp_brands_str, comp_brand_size);
1585  if (ret < 0) {
1586  av_freep(&comp_brands_str);
1587  return ret;
1588  }
1589  comp_brands_str[comp_brand_size] = 0;
1590  av_dict_set(&c->fc->metadata, "compatible_brands",
1591  comp_brands_str, AV_DICT_DONT_STRDUP_VAL);
1592 
1593  // Logic for handling Audible's .aaxc files
1594  if (!strcmp(type, "aaxc")) {
1595  mov_aaxc_crypto(c);
1596  }
1597 
1598  return 0;
1599 }
1600 
1601 /* this atom should contain all header atoms */
1603 {
1604  int ret;
1605 
1606  if (c->found_moov) {
1607  av_log(c->fc, AV_LOG_WARNING, "Found duplicated MOOV Atom. Skipped it\n");
1608  avio_skip(pb, atom.size);
1609  return 0;
1610  }
1611 
1612  if ((ret = mov_read_default(c, pb, atom)) < 0)
1613  return ret;
1614  /* we parsed the 'moov' atom, we can terminate the parsing as soon as we find the 'mdat' */
1615  /* so we don't parse the whole file if over a network */
1616  c->found_moov=1;
1617  return 0; /* now go for mdat */
1618 }
1619 
1621  MOVFragmentIndex *frag_index,
1622  int index,
1623  int id)
1624 {
1625  int i;
1626  MOVFragmentIndexItem * item;
1627 
1628  if (index < 0 || index >= frag_index->nb_items)
1629  return NULL;
1630  item = &frag_index->item[index];
1631  for (i = 0; i < item->nb_stream_info; i++)
1632  if (item->stream_info[i].id == id)
1633  return &item->stream_info[i];
1634 
1635  // This shouldn't happen
1636  return NULL;
1637 }
1638 
1639 static void set_frag_stream(MOVFragmentIndex *frag_index, int id)
1640 {
1641  int i;
1642  MOVFragmentIndexItem * item;
1643 
1644  if (frag_index->current < 0 ||
1645  frag_index->current >= frag_index->nb_items)
1646  return;
1647 
1648  item = &frag_index->item[frag_index->current];
1649  for (i = 0; i < item->nb_stream_info; i++)
1650  if (item->stream_info[i].id == id) {
1651  item->current = i;
1652  return;
1653  }
1654 
1655  // id not found. This shouldn't happen.
1656  item->current = -1;
1657 }
1658 
1660  MOVFragmentIndex *frag_index)
1661 {
1662  MOVFragmentIndexItem *item;
1663  if (frag_index->current < 0 ||
1664  frag_index->current >= frag_index->nb_items)
1665  return NULL;
1666 
1667  item = &frag_index->item[frag_index->current];
1668  if (item->current >= 0 && item->current < item->nb_stream_info)
1669  return &item->stream_info[item->current];
1670 
1671  // This shouldn't happen
1672  return NULL;
1673 }
1674 
1676 {
1677  int a, b, m;
1678  int64_t moof_offset;
1679 
1680  // Optimize for appending new entries
1681  if (!frag_index->nb_items ||
1682  frag_index->item[frag_index->nb_items - 1].moof_offset < offset)
1683  return frag_index->nb_items;
1684 
1685  a = -1;
1686  b = frag_index->nb_items;
1687 
1688  while (b - a > 1) {
1689  m = (a + b) >> 1;
1690  moof_offset = frag_index->item[m].moof_offset;
1691  if (moof_offset >= offset)
1692  b = m;
1693  if (moof_offset <= offset)
1694  a = m;
1695  }
1696  return b;
1697 }
1698 
1700 {
1701  av_assert0(frag_stream_info);
1702  if (frag_stream_info->sidx_pts != AV_NOPTS_VALUE)
1703  return frag_stream_info->sidx_pts;
1704  if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE)
1705  return frag_stream_info->first_tfra_pts;
1706  return frag_stream_info->tfdt_dts;
1707 }
1708 
1710  MOVFragmentIndex *frag_index, int index)
1711 {
1712  MOVFragmentStreamInfo * frag_stream_info;
1713  MOVStreamContext *sc = dst_st->priv_data;
1714  int64_t timestamp;
1715  int i, j;
1716 
1717  // If the stream is referenced by any sidx, limit the search
1718  // to fragments that referenced this stream in the sidx
1719  if (sc->has_sidx) {
1720  frag_stream_info = get_frag_stream_info(frag_index, index, sc->id);
1721  if (!frag_stream_info)
1722  return AV_NOPTS_VALUE;
1723  if (frag_stream_info->sidx_pts != AV_NOPTS_VALUE)
1724  return frag_stream_info->sidx_pts;
1725  if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE)
1726  return frag_stream_info->first_tfra_pts;
1727  return frag_stream_info->sidx_pts;
1728  }
1729 
1730  for (i = 0; i < frag_index->item[index].nb_stream_info; i++) {
1731  if (dst_st->id != frag_index->item[index].stream_info[i].id)
1732  continue;
1733  AVStream *frag_stream = NULL;
1734  frag_stream_info = &frag_index->item[index].stream_info[i];
1735  for (j = 0; j < s->nb_streams; j++) {
1736  MOVStreamContext *sc2 = s->streams[j]->priv_data;
1737  if (sc2->id == frag_stream_info->id)
1738  frag_stream = s->streams[j];
1739  }
1740  if (!frag_stream) {
1741  av_log(s, AV_LOG_WARNING, "No stream matching sidx ID found.\n");
1742  continue;
1743  }
1744  timestamp = get_stream_info_time(frag_stream_info);
1745  if (timestamp != AV_NOPTS_VALUE)
1746  return av_rescale_q(timestamp, frag_stream->time_base, dst_st->time_base);
1747  }
1748  return AV_NOPTS_VALUE;
1749 }
1750 
1752  AVStream *st, int64_t timestamp)
1753 {
1754  int a, b, m, m0;
1755  int64_t frag_time;
1756 
1757  a = -1;
1758  b = frag_index->nb_items;
1759 
1760  while (b - a > 1) {
1761  m0 = m = (a + b) >> 1;
1762 
1763  while (m < b &&
1764  (frag_time = get_frag_time(s, st, frag_index, m)) == AV_NOPTS_VALUE)
1765  m++;
1766 
1767  if (m < b && frag_time <= timestamp)
1768  a = m;
1769  else
1770  b = m0;
1771  }
1772 
1773  return a;
1774 }
1775 
1777 {
1778  int index, i;
1779  MOVFragmentIndexItem * item;
1780  MOVFragmentStreamInfo * frag_stream_info;
1781 
1782  // If moof_offset already exists in frag_index, return index to it
1783  index = search_frag_moof_offset(&c->frag_index, offset);
1784  if (index < c->frag_index.nb_items &&
1785  c->frag_index.item[index].moof_offset == offset)
1786  return index;
1787 
1788  // offset is not yet in frag index.
1789  // Insert new item at index (sorted by moof offset)
1790  item = av_fast_realloc(c->frag_index.item,
1791  &c->frag_index.allocated_size,
1792  (c->frag_index.nb_items + 1) *
1793  sizeof(*c->frag_index.item));
1794  if (!item)
1795  return -1;
1796  c->frag_index.item = item;
1797 
1798  frag_stream_info = av_realloc_array(NULL, c->fc->nb_streams,
1799  sizeof(*item->stream_info));
1800  if (!frag_stream_info)
1801  return -1;
1802 
1803  for (i = 0; i < c->fc->nb_streams; i++) {
1804  // Avoid building frag index if streams lack track id.
1805  MOVStreamContext *sc = c->fc->streams[i]->priv_data;
1806  if (sc->id < 0) {
1807  av_free(frag_stream_info);
1808  return AVERROR_INVALIDDATA;
1809  }
1810 
1811  frag_stream_info[i].id = sc->id;
1812  frag_stream_info[i].sidx_pts = AV_NOPTS_VALUE;
1813  frag_stream_info[i].tfdt_dts = AV_NOPTS_VALUE;
1814  frag_stream_info[i].next_trun_dts = AV_NOPTS_VALUE;
1815  frag_stream_info[i].first_tfra_pts = AV_NOPTS_VALUE;
1816  frag_stream_info[i].index_base = -1;
1817  frag_stream_info[i].index_entry = -1;
1818  frag_stream_info[i].encryption_index = NULL;
1819  frag_stream_info[i].stsd_id = -1;
1820  }
1821 
1822  if (index < c->frag_index.nb_items)
1823  memmove(c->frag_index.item + index + 1, c->frag_index.item + index,
1824  (c->frag_index.nb_items - index) * sizeof(*c->frag_index.item));
1825 
1826  item = &c->frag_index.item[index];
1827  item->headers_read = 0;
1828  item->current = 0;
1829  item->nb_stream_info = c->fc->nb_streams;
1830  item->moof_offset = offset;
1831  item->stream_info = frag_stream_info;
1832  c->frag_index.nb_items++;
1833 
1834  return index;
1835 }
1836 
1837 static void fix_frag_index_entries(MOVFragmentIndex *frag_index, int index,
1838  int id, int entries)
1839 {
1840  int i;
1841  MOVFragmentStreamInfo * frag_stream_info;
1842 
1843  if (index < 0)
1844  return;
1845  for (i = index; i < frag_index->nb_items; i++) {
1846  frag_stream_info = get_frag_stream_info(frag_index, i, id);
1847  if (frag_stream_info && frag_stream_info->index_entry >= 0)
1848  frag_stream_info->index_entry += entries;
1849  }
1850 }
1851 
1853 {
1854  // Set by mov_read_tfhd(). mov_read_trun() will reject files missing tfhd.
1855  c->fragment.found_tfhd = 0;
1856 
1857  if (!c->has_looked_for_mfra && c->use_mfra_for > 0) {
1858  c->has_looked_for_mfra = 1;
1859  if (pb->seekable & AVIO_SEEKABLE_NORMAL) {
1860  int ret;
1861  av_log(c->fc, AV_LOG_VERBOSE, "stream has moof boxes, will look "
1862  "for a mfra\n");
1863  if ((ret = mov_read_mfra(c, pb)) < 0) {
1864  av_log(c->fc, AV_LOG_VERBOSE, "found a moof box but failed to "
1865  "read the mfra (may be a live ismv)\n");
1866  }
1867  } else {
1868  av_log(c->fc, AV_LOG_VERBOSE, "found a moof box but stream is not "
1869  "seekable, can not look for mfra\n");
1870  }
1871  }
1872  c->fragment.moof_offset = c->fragment.implicit_offset = avio_tell(pb) - 8;
1873  av_log(c->fc, AV_LOG_TRACE, "moof offset %"PRIx64"\n", c->fragment.moof_offset);
1874  c->frag_index.current = update_frag_index(c, c->fragment.moof_offset);
1875  return mov_read_default(c, pb, atom);
1876 }
1877 
1879 {
1880  int64_t time;
1881  if (version == 1) {
1882  time = avio_rb64(pb);
1883  avio_rb64(pb);
1884  if (time < 0) {
1885  av_log(c->fc, AV_LOG_DEBUG, "creation_time is negative\n");
1886  return;
1887  }
1888  } else {
1889  time = avio_rb32(pb);
1890  avio_rb32(pb); /* modification time */
1891  if (time > 0 && time < 2082844800) {
1892  av_log(c->fc, AV_LOG_WARNING, "Detected creation time before 1970, parsing as unix timestamp.\n");
1893  time += 2082844800;
1894  }
1895  }
1896  if (time) {
1897  time -= 2082844800; /* seconds between 1904-01-01 and Epoch */
1898 
1899  if ((int64_t)(time * 1000000ULL) / 1000000 != time) {
1900  av_log(c->fc, AV_LOG_DEBUG, "creation_time is not representable\n");
1901  return;
1902  }
1903 
1904  ff_dict_set_timestamp(metadata, "creation_time", time * 1000000);
1905  }
1906 }
1907 
1909 {
1910  AVStream *st;
1911  MOVStreamContext *sc;
1912  int version;
1913  char language[4] = {0};
1914  unsigned lang;
1915 
1916  if (c->fc->nb_streams < 1)
1917  return 0;
1918  st = c->fc->streams[c->fc->nb_streams-1];
1919  sc = st->priv_data;
1920 
1921  if (sc->time_scale) {
1922  av_log(c->fc, AV_LOG_ERROR, "Multiple mdhd?\n");
1923  return AVERROR_INVALIDDATA;
1924  }
1925 
1926  version = avio_r8(pb);
1927  if (version > 1) {
1928  avpriv_request_sample(c->fc, "Version %d", version);
1929  return AVERROR_PATCHWELCOME;
1930  }
1931  avio_rb24(pb); /* flags */
1933 
1934  sc->time_scale = avio_rb32(pb);
1935  if (sc->time_scale <= 0) {
1936  av_log(c->fc, AV_LOG_ERROR, "Invalid mdhd time scale %d, defaulting to 1\n", sc->time_scale);
1937  sc->time_scale = 1;
1938  }
1939  st->duration = (version == 1) ? avio_rb64(pb) : avio_rb32(pb); /* duration */
1940 
1941  if ((version == 1 && st->duration == UINT64_MAX) ||
1942  (version != 1 && st->duration == UINT32_MAX)) {
1943  st->duration = 0;
1944  }
1945 
1946  lang = avio_rb16(pb); /* language */
1947  if (ff_mov_lang_to_iso639(lang, language))
1948  av_dict_set(&st->metadata, "language", language, 0);
1949  avio_rb16(pb); /* quality */
1950 
1951  return 0;
1952 }
1953 
1955 {
1956  int i;
1957  int version = avio_r8(pb); /* version */
1958  avio_rb24(pb); /* flags */
1959 
1960  mov_metadata_creation_time(c, pb, &c->fc->metadata, version);
1961  c->time_scale = avio_rb32(pb); /* time scale */
1962  if (c->time_scale <= 0) {
1963  av_log(c->fc, AV_LOG_ERROR, "Invalid mvhd time scale %d, defaulting to 1\n", c->time_scale);
1964  c->time_scale = 1;
1965  }
1966  av_log(c->fc, AV_LOG_TRACE, "time scale = %i\n", c->time_scale);
1967 
1968  c->duration = (version == 1) ? avio_rb64(pb) : avio_rb32(pb); /* duration */
1969  avio_rb32(pb); /* preferred scale */
1970 
1971  avio_rb16(pb); /* preferred volume */
1972 
1973  avio_skip(pb, 10); /* reserved */
1974 
1975  /* movie display matrix, store it in main context and use it later on */
1976  for (i = 0; i < 3; i++) {
1977  c->movie_display_matrix[i][0] = avio_rb32(pb); // 16.16 fixed point
1978  c->movie_display_matrix[i][1] = avio_rb32(pb); // 16.16 fixed point
1979  c->movie_display_matrix[i][2] = avio_rb32(pb); // 2.30 fixed point
1980  }
1981 
1982  avio_rb32(pb); /* preview time */
1983  avio_rb32(pb); /* preview duration */
1984  avio_rb32(pb); /* poster time */
1985  avio_rb32(pb); /* selection time */
1986  avio_rb32(pb); /* selection duration */
1987  avio_rb32(pb); /* current time */
1988  avio_rb32(pb); /* next track ID */
1989 
1990  return 0;
1991 }
1992 
1994 {
1995  AVStream *st;
1996 
1997  if (fc->nb_streams < 1)
1998  return;
1999  st = fc->streams[fc->nb_streams-1];
2000 
2001  switch (st->codecpar->codec_id) {
2002  case AV_CODEC_ID_PCM_S16BE:
2004  break;
2005  case AV_CODEC_ID_PCM_S24BE:
2007  break;
2008  case AV_CODEC_ID_PCM_S32BE:
2010  break;
2011  case AV_CODEC_ID_PCM_F32BE:
2013  break;
2014  case AV_CODEC_ID_PCM_F64BE:
2016  break;
2017  default:
2018  break;
2019  }
2020 }
2021 
2023 {
2024  int little_endian = avio_rb16(pb) & 0xFF;
2025  av_log(c->fc, AV_LOG_TRACE, "enda %d\n", little_endian);
2026  if (little_endian == 1)
2028  return 0;
2029 }
2030 
2032 {
2033  int format_flags;
2034  int version, flags;
2035  int pcm_sample_size;
2036  AVFormatContext *fc = c->fc;
2037  AVStream *st;
2038  MOVStreamContext *sc;
2039 
2040  if (atom.size < 6) {
2041  av_log(c->fc, AV_LOG_ERROR, "Empty pcmC box\n");
2042  return AVERROR_INVALIDDATA;
2043  }
2044 
2045  version = avio_r8(pb);
2046  flags = avio_rb24(pb);
2047 
2048  if (version != 0 || flags != 0) {
2049  av_log(c->fc, AV_LOG_ERROR,
2050  "Unsupported 'pcmC' box with version %d, flags: %x",
2051  version, flags);
2052  return AVERROR_INVALIDDATA;
2053  }
2054 
2055  format_flags = avio_r8(pb);
2056  pcm_sample_size = avio_r8(pb);
2057 
2058  if (fc->nb_streams < 1)
2059  return AVERROR_INVALIDDATA;
2060 
2061  st = fc->streams[fc->nb_streams - 1];
2062  sc = st->priv_data;
2063 
2064  if (sc->format == MOV_MP4_FPCM_TAG) {
2065  switch (pcm_sample_size) {
2066  case 32:
2068  break;
2069  case 64:
2071  break;
2072  default:
2073  av_log(fc, AV_LOG_ERROR, "invalid pcm_sample_size %d for %s\n",
2074  pcm_sample_size,
2075  av_fourcc2str(sc->format));
2076  return AVERROR_INVALIDDATA;
2077  }
2078  } else if (sc->format == MOV_MP4_IPCM_TAG) {
2079  switch (pcm_sample_size) {
2080  case 16:
2082  break;
2083  case 24:
2085  break;
2086  case 32:
2088  break;
2089  default:
2090  av_log(fc, AV_LOG_ERROR, "invalid pcm_sample_size %d for %s\n",
2091  pcm_sample_size,
2092  av_fourcc2str(sc->format));
2093  return AVERROR_INVALIDDATA;
2094  }
2095  } else {
2096  av_log(fc, AV_LOG_ERROR, "'pcmC' with invalid sample entry '%s'\n",
2097  av_fourcc2str(sc->format));
2098  return AVERROR_INVALIDDATA;
2099  }
2100 
2101  if (format_flags & 1) // indicates little-endian format. If not present, big-endian format is used
2104 
2105  return 0;
2106 }
2107 
2109 {
2110  AVStream *st;
2111  HEIFItem *item = NULL;
2112  char color_parameter_type[5] = { 0 };
2113  uint16_t color_primaries, color_trc, color_matrix;
2114  int ret;
2115 
2116  st = get_curr_st(c);
2117  if (!st) {
2118  item = get_heif_item(c, c->cur_item_id);
2119  if (!item)
2120  return 0;
2121  }
2122 
2123  ret = ffio_read_size(pb, color_parameter_type, 4);
2124  if (ret < 0)
2125  return ret;
2126  if (strncmp(color_parameter_type, "nclx", 4) &&
2127  strncmp(color_parameter_type, "nclc", 4) &&
2128  strncmp(color_parameter_type, "prof", 4)) {
2129  av_log(c->fc, AV_LOG_WARNING, "unsupported color_parameter_type %s\n",
2130  color_parameter_type);
2131  return 0;
2132  }
2133 
2134  if (!strncmp(color_parameter_type, "prof", 4)) {
2135  AVPacketSideData *sd;
2136  uint8_t *icc_profile;
2137  if (st) {
2141  atom.size - 4, 0);
2142  if (!sd)
2143  return AVERROR(ENOMEM);
2144  icc_profile = sd->data;
2145  } else {
2146  av_freep(&item->icc_profile);
2147  icc_profile = item->icc_profile = av_malloc(atom.size - 4);
2148  if (!icc_profile) {
2149  item->icc_profile_size = 0;
2150  return AVERROR(ENOMEM);
2151  }
2152  item->icc_profile_size = atom.size - 4;
2153  }
2154  ret = ffio_read_size(pb, icc_profile, atom.size - 4);
2155  if (ret < 0)
2156  return ret;
2157  } else if (st) {
2158  color_primaries = avio_rb16(pb);
2159  color_trc = avio_rb16(pb);
2160  color_matrix = avio_rb16(pb);
2161 
2162  av_log(c->fc, AV_LOG_TRACE,
2163  "%s: pri %d trc %d matrix %d",
2164  color_parameter_type, color_primaries, color_trc, color_matrix);
2165 
2166  if (!strncmp(color_parameter_type, "nclx", 4)) {
2167  uint8_t color_range = avio_r8(pb) >> 7;
2168  av_log(c->fc, AV_LOG_TRACE, " full %"PRIu8"", color_range);
2169  if (color_range)
2171  else
2173  }
2174 
2177  if (!av_color_transfer_name(color_trc))
2178  color_trc = AVCOL_TRC_UNSPECIFIED;
2179  if (!av_color_space_name(color_matrix))
2180  color_matrix = AVCOL_SPC_UNSPECIFIED;
2181 
2183  st->codecpar->color_trc = color_trc;
2184  st->codecpar->color_space = color_matrix;
2185  av_log(c->fc, AV_LOG_TRACE, "\n");
2186  }
2187  return 0;
2188 }
2189 
2191 {
2192  AVStream *st;
2193  unsigned mov_field_order;
2194  enum AVFieldOrder decoded_field_order = AV_FIELD_UNKNOWN;
2195 
2196  if (c->fc->nb_streams < 1) // will happen with jp2 files
2197  return 0;
2198  st = c->fc->streams[c->fc->nb_streams-1];
2199  if (atom.size < 2)
2200  return AVERROR_INVALIDDATA;
2201  mov_field_order = avio_rb16(pb);
2202  if ((mov_field_order & 0xFF00) == 0x0100)
2203  decoded_field_order = AV_FIELD_PROGRESSIVE;
2204  else if ((mov_field_order & 0xFF00) == 0x0200) {
2205  switch (mov_field_order & 0xFF) {
2206  case 0x01: decoded_field_order = AV_FIELD_TT;
2207  break;
2208  case 0x06: decoded_field_order = AV_FIELD_BB;
2209  break;
2210  case 0x09: decoded_field_order = AV_FIELD_TB;
2211  break;
2212  case 0x0E: decoded_field_order = AV_FIELD_BT;
2213  break;
2214  }
2215  }
2216  if (decoded_field_order == AV_FIELD_UNKNOWN && mov_field_order) {
2217  av_log(c->fc, AV_LOG_ERROR, "Unknown MOV field order 0x%04x\n", mov_field_order);
2218  }
2219  st->codecpar->field_order = decoded_field_order;
2220 
2221  return 0;
2222 }
2223 
2225 {
2226  int err = 0;
2227  uint64_t size = (uint64_t)par->extradata_size + atom.size + 8 + AV_INPUT_BUFFER_PADDING_SIZE;
2228  if (size > INT_MAX || (uint64_t)atom.size > INT_MAX)
2229  return AVERROR_INVALIDDATA;
2230  if ((err = av_reallocp(&par->extradata, size)) < 0) {
2231  par->extradata_size = 0;
2232  return err;
2233  }
2235  return 0;
2236 }
2237 
2238 /* Read a whole atom into the extradata return the size of the atom read, possibly truncated if != atom.size */
2240  AVCodecParameters *par, uint8_t *buf)
2241 {
2242  int64_t result = atom.size;
2243  int err;
2244 
2245  AV_WB32(buf , atom.size + 8);
2246  AV_WL32(buf + 4, atom.type);
2247  err = ffio_read_size(pb, buf + 8, atom.size);
2248  if (err < 0) {
2249  par->extradata_size -= atom.size;
2250  return err;
2251  } else if (err < atom.size) {
2252  av_log(c->fc, AV_LOG_WARNING, "truncated extradata\n");
2253  par->extradata_size -= atom.size - err;
2254  result = err;
2255  }
2256  memset(buf + 8 + err, 0, AV_INPUT_BUFFER_PADDING_SIZE);
2257  return result;
2258 }
2259 
2260 /* FIXME modify QDM2/SVQ3/H.264 decoders to take full atom as extradata */
2262  enum AVCodecID codec_id)
2263 {
2264  AVStream *st;
2265  uint64_t original_size;
2266  int err;
2267 
2268  if (c->fc->nb_streams < 1) // will happen with jp2 files
2269  return 0;
2270  st = c->fc->streams[c->fc->nb_streams-1];
2271 
2272  if (st->codecpar->codec_id != codec_id)
2273  return 0; /* unexpected codec_id - don't mess with extradata */
2274 
2275  original_size = st->codecpar->extradata_size;
2276  err = mov_realloc_extradata(st->codecpar, atom);
2277  if (err)
2278  return err;
2279 
2280  err = mov_read_atom_into_extradata(c, pb, atom, st->codecpar, st->codecpar->extradata + original_size);
2281  if (err < 0)
2282  return err;
2283  return 0; // Note: this is the original behavior to ignore truncation.
2284 }
2285 
2286 /* wrapper functions for reading ALAC/AVS/MJPEG/MJPEG2000 extradata atoms only for those codecs */
2288 {
2289  return mov_read_extradata(c, pb, atom, AV_CODEC_ID_ALAC);
2290 }
2291 
2293 {
2294  return mov_read_extradata(c, pb, atom, AV_CODEC_ID_CAVS);
2295 }
2296 
2298 {
2299  return mov_read_extradata(c, pb, atom, AV_CODEC_ID_JPEG2000);
2300 }
2301 
2303 {
2304  return mov_read_extradata(c, pb, atom, AV_CODEC_ID_R10K);
2305 }
2306 
2308 {
2309  int ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_AVUI);
2310  if (!ret)
2311  ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_DNXHD);
2312  return ret;
2313 }
2314 
2316 {
2317  int ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_TARGA_Y216);
2318 
2319  if (!ret && c->fc->nb_streams >= 1) {
2320  AVCodecParameters *par = c->fc->streams[c->fc->nb_streams-1]->codecpar;
2321  if (par->extradata_size >= 40) {
2322  par->height = AV_RB16(&par->extradata[36]);
2323  par->width = AV_RB16(&par->extradata[38]);
2324  }
2325  }
2326  return ret;
2327 }
2328 
2330 {
2331  if (c->fc->nb_streams >= 1) {
2332  AVStream *const st = c->fc->streams[c->fc->nb_streams - 1];
2333  FFStream *const sti = ffstream(st);
2334  AVCodecParameters *par = st->codecpar;
2335 
2336  if (par->codec_tag == MKTAG('A', 'V', 'i', 'n') &&
2337  par->codec_id == AV_CODEC_ID_H264 &&
2338  atom.size > 11) {
2339  int cid;
2340  avio_skip(pb, 10);
2341  cid = avio_rb16(pb);
2342  /* For AVID AVCI50, force width of 1440 to be able to select the correct SPS and PPS */
2343  if (cid == 0xd4d || cid == 0xd4e)
2344  par->width = 1440;
2345  return 0;
2346  } else if ((par->codec_tag == MKTAG('A', 'V', 'd', '1') ||
2347  par->codec_tag == MKTAG('A', 'V', 'j', '2') ||
2348  par->codec_tag == MKTAG('A', 'V', 'd', 'n')) &&
2349  atom.size >= 24) {
2350  int num, den;
2351  avio_skip(pb, 12);
2352  num = avio_rb32(pb);
2353  den = avio_rb32(pb);
2354  if (num <= 0 || den <= 0)
2355  return 0;
2356  switch (avio_rb32(pb)) {
2357  case 2:
2358  if (den >= INT_MAX / 2)
2359  return 0;
2360  den *= 2;
2362  case 1:
2363  sti->display_aspect_ratio = (AVRational){ num, den };
2365  default:
2366  return 0;
2367  }
2368  }
2369  }
2370 
2371  return mov_read_avid(c, pb, atom);
2372 }
2373 
2375 {
2376  int ret = 0;
2377  int length = 0;
2378  uint64_t original_size;
2379  if (c->fc->nb_streams >= 1) {
2380  AVCodecParameters *par = c->fc->streams[c->fc->nb_streams-1]->codecpar;
2381  if (par->codec_id == AV_CODEC_ID_H264)
2382  return 0;
2383  if (atom.size == 16) {
2384  original_size = par->extradata_size;
2385  ret = mov_realloc_extradata(par, atom);
2386  if (!ret) {
2387  length = mov_read_atom_into_extradata(c, pb, atom, par, par->extradata + original_size);
2388  if (length == atom.size) {
2389  const uint8_t range_value = par->extradata[original_size + 19];
2390  switch (range_value) {
2391  case 1:
2393  break;
2394  case 2:
2396  break;
2397  default:
2398  av_log(c->fc, AV_LOG_WARNING, "ignored unknown aclr value (%d)\n", range_value);
2399  break;
2400  }
2401  ff_dlog(c->fc, "color_range: %d\n", par->color_range);
2402  } else {
2403  /* For some reason the whole atom was not added to the extradata */
2404  av_log(c->fc, AV_LOG_ERROR, "aclr not decoded - incomplete atom\n");
2405  }
2406  } else {
2407  av_log(c->fc, AV_LOG_ERROR, "aclr not decoded - unable to add atom to extradata\n");
2408  }
2409  } else {
2410  av_log(c->fc, AV_LOG_WARNING, "aclr not decoded - unexpected size %"PRId64"\n", atom.size);
2411  }
2412  }
2413 
2414  return ret;
2415 }
2416 
2418 {
2419  return mov_read_extradata(c, pb, atom, AV_CODEC_ID_SVQ3);
2420 }
2421 
2423 {
2424  AVStream *st;
2425  int ret;
2426 
2427  if (c->fc->nb_streams < 1)
2428  return 0;
2429  st = c->fc->streams[c->fc->nb_streams-1];
2430 
2431  if ((uint64_t)atom.size > (1<<30))
2432  return AVERROR_INVALIDDATA;
2433 
2434  if (st->codecpar->codec_id == AV_CODEC_ID_QDM2 ||
2437  // pass all frma atom to codec, needed at least for QDMC and QDM2
2438  ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size);
2439  if (ret < 0)
2440  return ret;
2441  } else if (atom.size > 8) { /* to read frma, esds atoms */
2442  if (st->codecpar->codec_id == AV_CODEC_ID_ALAC && atom.size >= 24) {
2443  uint64_t buffer;
2444  ret = ffio_ensure_seekback(pb, 8);
2445  if (ret < 0)
2446  return ret;
2447  buffer = avio_rb64(pb);
2448  atom.size -= 8;
2449  if ( (buffer & 0xFFFFFFFF) == MKBETAG('f','r','m','a')
2450  && buffer >> 32 <= atom.size
2451  && buffer >> 32 >= 8) {
2452  avio_skip(pb, -8);
2453  atom.size += 8;
2454  } else if (!st->codecpar->extradata_size) {
2455 #define ALAC_EXTRADATA_SIZE 36
2457  if (!st->codecpar->extradata)
2458  return AVERROR(ENOMEM);
2461  AV_WB32(st->codecpar->extradata + 4, MKTAG('a','l','a','c'));
2462  AV_WB64(st->codecpar->extradata + 12, buffer);
2463  avio_read(pb, st->codecpar->extradata + 20, 16);
2464  avio_skip(pb, atom.size - 24);
2465  return 0;
2466  }
2467  }
2468  if ((ret = mov_read_default(c, pb, atom)) < 0)
2469  return ret;
2470  } else
2471  avio_skip(pb, atom.size);
2472  return 0;
2473 }
2474 
2475 /**
2476  * This function reads atom content and puts data in extradata without tag
2477  * nor size unlike mov_read_extradata.
2478  */
2480 {
2481  AVStream *st;
2482  int ret;
2483 
2484  st = get_curr_st(c);
2485  if (!st)
2486  return 0;
2487 
2488  if ((uint64_t)atom.size > (1<<30))
2489  return AVERROR_INVALIDDATA;
2490 
2491  if (atom.type == MKTAG('v','v','c','C')) {
2492  avio_skip(pb, 4);
2493  atom.size -= 4;
2494  }
2495 
2496  if (atom.size >= 10) {
2497  // Broken files created by legacy versions of libavformat will
2498  // wrap a whole fiel atom inside of a glbl atom.
2499  unsigned size = avio_rb32(pb);
2500  unsigned type = avio_rl32(pb);
2501  if (avio_feof(pb))
2502  return AVERROR_INVALIDDATA;
2503  avio_seek(pb, -8, SEEK_CUR);
2504  if (type == MKTAG('f','i','e','l') && size == atom.size)
2505  return mov_read_default(c, pb, atom);
2506  }
2507  if (st->codecpar->extradata_size > 1 && st->codecpar->extradata) {
2508  av_log(c->fc, AV_LOG_WARNING, "ignoring multiple glbl\n");
2509  return 0;
2510  }
2511  ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size);
2512  if (ret < 0)
2513  return ret;
2514  if (atom.type == MKTAG('h','v','c','C') && st->codecpar->codec_tag == MKTAG('d','v','h','1'))
2515  /* HEVC-based Dolby Vision derived from hvc1.
2516  Happens to match with an identifier
2517  previously utilized for DV. Thus, if we have
2518  the hvcC extradata box available as specified,
2519  set codec to HEVC */
2521 
2522  return 0;
2523 }
2524 
2526 {
2527  AVStream *st;
2528  uint8_t profile_level;
2529  int ret;
2530 
2531  if (c->fc->nb_streams < 1)
2532  return 0;
2533  st = c->fc->streams[c->fc->nb_streams-1];
2534 
2535  if (atom.size >= (1<<28) || atom.size < 7)
2536  return AVERROR_INVALIDDATA;
2537 
2538  profile_level = avio_r8(pb);
2539  if ((profile_level & 0xf0) != 0xc0)
2540  return 0;
2541 
2542  avio_seek(pb, 6, SEEK_CUR);
2543  ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size - 7);
2544  if (ret < 0)
2545  return ret;
2546 
2547  return 0;
2548 }
2549 
2551 {
2552  AVStream* st;
2553  MOVStreamContext* sc;
2554 
2555  if (c->fc->nb_streams < 1)
2556  return 0;
2557 
2558  /* For SBAS this should be fine - though beware if someone implements a
2559  * tref atom processor that doesn't drop down to default then this may
2560  * be lost. */
2561  if (atom.size > 4) {
2562  av_log(c->fc, AV_LOG_ERROR, "Only a single tref of type sbas is supported\n");
2563  return AVERROR_PATCHWELCOME;
2564  }
2565 
2566  st = c->fc->streams[c->fc->nb_streams - 1];
2567  sc = st->priv_data;
2568  sc->tref_id = avio_rb32(pb);
2570 
2571  return 0;
2572 }
2573 
2574 /**
2575  * An strf atom is a BITMAPINFOHEADER struct. This struct is 40 bytes itself,
2576  * but can have extradata appended at the end after the 40 bytes belonging
2577  * to the struct.
2578  */
2580 {
2581  AVStream *st;
2582  int ret;
2583 
2584  if (c->fc->nb_streams < 1)
2585  return 0;
2586  if (atom.size <= 40)
2587  return 0;
2588  st = c->fc->streams[c->fc->nb_streams-1];
2589 
2590  if ((uint64_t)atom.size > (1<<30))
2591  return AVERROR_INVALIDDATA;
2592 
2593  avio_skip(pb, 40);
2594  ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size - 40);
2595  if (ret < 0)
2596  return ret;
2597 
2598  return 0;
2599 }
2600 
2602 {
2603  AVStream *st;
2604  MOVStreamContext *sc;
2605  unsigned int i, entries;
2606 
2607  if (c->trak_index < 0) {
2608  av_log(c->fc, AV_LOG_WARNING, "STCO outside TRAK\n");
2609  return 0;
2610  }
2611  if (c->fc->nb_streams < 1)
2612  return 0;
2613  st = c->fc->streams[c->fc->nb_streams-1];
2614  sc = st->priv_data;
2615 
2616  avio_r8(pb); /* version */
2617  avio_rb24(pb); /* flags */
2618 
2619  // Clamp allocation size for `chunk_offsets` -- don't throw an error for an
2620  // invalid count since the EOF path doesn't throw either.
2621  entries = avio_rb32(pb);
2622  entries =
2623  FFMIN(entries,
2624  FFMAX(0, (atom.size - 8) /
2625  (atom.type == MKTAG('s', 't', 'c', 'o') ? 4 : 8)));
2626 
2627  if (!entries)
2628  return 0;
2629 
2630  if (sc->chunk_offsets) {
2631  av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicated STCO atom\n");
2632  return 0;
2633  }
2634 
2635  av_free(sc->chunk_offsets);
2636  sc->chunk_count = 0;
2637  sc->chunk_offsets = av_malloc_array(entries, sizeof(*sc->chunk_offsets));
2638  if (!sc->chunk_offsets)
2639  return AVERROR(ENOMEM);
2640  sc->chunk_count = entries;
2641 
2642  if (atom.type == MKTAG('s','t','c','o'))
2643  for (i = 0; i < entries && !pb->eof_reached; i++)
2644  sc->chunk_offsets[i] = avio_rb32(pb);
2645  else if (atom.type == MKTAG('c','o','6','4'))
2646  for (i = 0; i < entries && !pb->eof_reached; i++) {
2647  sc->chunk_offsets[i] = avio_rb64(pb);
2648  if (sc->chunk_offsets[i] < 0) {
2649  av_log(c->fc, AV_LOG_WARNING, "Impossible chunk_offset\n");
2650  sc->chunk_offsets[i] = 0;
2651  }
2652  }
2653  else
2654  return AVERROR_INVALIDDATA;
2655 
2656  sc->chunk_count = i;
2657 
2658  if (pb->eof_reached) {
2659  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STCO atom\n");
2660  return AVERROR_EOF;
2661  }
2662 
2663  return 0;
2664 }
2665 
2666 static int mov_codec_id(AVStream *st, uint32_t format)
2667 {
2669 
2670  if (id <= 0 &&
2671  ((format & 0xFFFF) == 'm' + ('s' << 8) ||
2672  (format & 0xFFFF) == 'T' + ('S' << 8)))
2674 
2675  if (st->codecpar->codec_type != AVMEDIA_TYPE_VIDEO && id > 0) {
2677  } else if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO &&
2678  /* skip old ASF MPEG-4 tag */
2679  format && format != MKTAG('m','p','4','s')) {
2681  if (id <= 0)
2683  if (id > 0)
2685  else if (st->codecpar->codec_type == AVMEDIA_TYPE_DATA ||
2687  st->codecpar->codec_id == AV_CODEC_ID_NONE)) {
2689  if (id <= 0) {
2691  AV_CODEC_ID_TTML : id;
2692  }
2693 
2694  if (id > 0)
2696  else
2698  }
2699  }
2700 
2701  st->codecpar->codec_tag = format;
2702 
2703  return id;
2704 }
2705 
2707  AVStream *st, MOVStreamContext *sc)
2708 {
2709  uint8_t codec_name[32] = { 0 };
2710  int64_t stsd_start;
2711  unsigned int len;
2712  uint32_t id = 0;
2713 
2714  /* The first 16 bytes of the video sample description are already
2715  * read in ff_mov_read_stsd_entries() */
2716  stsd_start = avio_tell(pb) - 16;
2717 
2718  if (c->isom) {
2719  avio_skip(pb, 2); /* pre_defined */
2720  avio_skip(pb, 2); /* reserved */
2721  avio_skip(pb, 12); /* pre_defined */
2722  } else {
2723  avio_rb16(pb); /* version */
2724  avio_rb16(pb); /* revision level */
2725  id = avio_rl32(pb); /* vendor */
2726  av_dict_set(&st->metadata, "vendor_id", av_fourcc2str(id), 0);
2727  avio_rb32(pb); /* temporal quality */
2728  avio_rb32(pb); /* spatial quality */
2729  }
2730 
2731  st->codecpar->width = avio_rb16(pb); /* width */
2732  st->codecpar->height = avio_rb16(pb); /* height */
2733 
2734  avio_rb32(pb); /* horiz resolution */
2735  avio_rb32(pb); /* vert resolution */
2736  avio_rb32(pb); /* data size, always 0 */
2737  avio_rb16(pb); /* frames per samples */
2738 
2739  len = avio_r8(pb); /* codec name, pascal string */
2740  if (len > 31)
2741  len = 31;
2742  mov_read_mac_string(c, pb, len, codec_name, sizeof(codec_name));
2743  if (len < 31)
2744  avio_skip(pb, 31 - len);
2745 
2746  if (codec_name[0])
2747  av_dict_set(&st->metadata, "encoder", codec_name, 0);
2748 
2749  /* codec_tag YV12 triggers an UV swap in rawdec.c */
2750  if (!strncmp(codec_name, "Planar Y'CbCr 8-bit 4:2:0", 25)) {
2751  st->codecpar->codec_tag = MKTAG('I', '4', '2', '0');
2752  st->codecpar->width &= ~1;
2753  st->codecpar->height &= ~1;
2754  }
2755  /* Flash Media Server uses tag H.263 with Sorenson Spark */
2756  if (st->codecpar->codec_tag == MKTAG('H','2','6','3') &&
2757  !strncmp(codec_name, "Sorenson H263", 13))
2759 
2760  st->codecpar->bits_per_coded_sample = avio_rb16(pb); /* depth */
2761 
2762  avio_seek(pb, stsd_start, SEEK_SET);
2763 
2764  if (ff_get_qtpalette(st->codecpar->codec_id, pb, sc->palette)) {
2765  st->codecpar->bits_per_coded_sample &= 0x1F;
2766  sc->has_palette = 1;
2767  }
2768 }
2769 
2771  AVStream *st, MOVStreamContext *sc)
2772 {
2773  int bits_per_sample, flags;
2774  uint16_t version = avio_rb16(pb);
2775  uint32_t id = 0;
2776  AVDictionaryEntry *compatible_brands = av_dict_get(c->fc->metadata, "compatible_brands", NULL, AV_DICT_MATCH_CASE);
2777  int channel_count;
2778 
2779  if (c->isom)
2780  avio_skip(pb, 6); /* reserved */
2781  else {
2782  avio_rb16(pb); /* revision level */
2783  id = avio_rl32(pb); /* vendor */
2784  av_dict_set(&st->metadata, "vendor_id", av_fourcc2str(id), 0);
2785  }
2786 
2787  channel_count = avio_rb16(pb);
2788 
2790  st->codecpar->ch_layout.nb_channels = channel_count;
2791  st->codecpar->bits_per_coded_sample = avio_rb16(pb); /* sample size */
2792  av_log(c->fc, AV_LOG_TRACE, "audio channels %d\n", channel_count);
2793 
2794  sc->audio_cid = avio_rb16(pb);
2795  avio_rb16(pb); /* packet size = 0 */
2796 
2797  st->codecpar->sample_rate = ((avio_rb32(pb) >> 16));
2798 
2799  // Read QT version 1 fields. In version 0 these do not exist.
2800  av_log(c->fc, AV_LOG_TRACE, "version =%d, isom =%d\n", version, c->isom);
2801  if (!c->isom ||
2802  (compatible_brands && strstr(compatible_brands->value, "qt ")) ||
2803  (sc->stsd_version == 0 && version > 0)) {
2804  if (version == 1) {
2805  sc->samples_per_frame = avio_rb32(pb);
2806  avio_rb32(pb); /* bytes per packet */
2807  sc->bytes_per_frame = avio_rb32(pb);
2808  avio_rb32(pb); /* bytes per sample */
2809  } else if (version == 2) {
2810  avio_rb32(pb); /* sizeof struct only */
2812  channel_count = avio_rb32(pb);
2814  st->codecpar->ch_layout.nb_channels = channel_count;
2815  avio_rb32(pb); /* always 0x7F000000 */
2817 
2818  flags = avio_rb32(pb); /* lpcm format specific flag */
2819  sc->bytes_per_frame = avio_rb32(pb);
2820  sc->samples_per_frame = avio_rb32(pb);
2821  if (st->codecpar->codec_tag == MKTAG('l','p','c','m'))
2822  st->codecpar->codec_id =
2824  flags);
2825  }
2826  if (version == 0 || (version == 1 && sc->audio_cid != -2)) {
2827  /* can't correctly handle variable sized packet as audio unit */
2828  switch (st->codecpar->codec_id) {
2829  case AV_CODEC_ID_MP2:
2830  case AV_CODEC_ID_MP3:
2832  break;
2833  }
2834  }
2835  }
2836 
2837  if (sc->format == 0) {
2838  if (st->codecpar->bits_per_coded_sample == 8)
2839  st->codecpar->codec_id = mov_codec_id(st, MKTAG('r','a','w',' '));
2840  else if (st->codecpar->bits_per_coded_sample == 16)
2841  st->codecpar->codec_id = mov_codec_id(st, MKTAG('t','w','o','s'));
2842  }
2843 
2844  switch (st->codecpar->codec_id) {
2845  case AV_CODEC_ID_PCM_S8:
2846  case AV_CODEC_ID_PCM_U8:
2847  if (st->codecpar->bits_per_coded_sample == 16)
2849  break;
2850  case AV_CODEC_ID_PCM_S16LE:
2851  case AV_CODEC_ID_PCM_S16BE:
2852  if (st->codecpar->bits_per_coded_sample == 8)
2854  else if (st->codecpar->bits_per_coded_sample == 24)
2855  st->codecpar->codec_id =
2858  else if (st->codecpar->bits_per_coded_sample == 32)
2859  st->codecpar->codec_id =
2862  break;
2863  /* set values for old format before stsd version 1 appeared */
2864  case AV_CODEC_ID_MACE3:
2865  sc->samples_per_frame = 6;
2867  break;
2868  case AV_CODEC_ID_MACE6:
2869  sc->samples_per_frame = 6;
2871  break;
2873  sc->samples_per_frame = 64;
2875  break;
2876  case AV_CODEC_ID_GSM:
2877  sc->samples_per_frame = 160;
2878  sc->bytes_per_frame = 33;
2879  break;
2880  default:
2881  break;
2882  }
2883 
2884  bits_per_sample = av_get_bits_per_sample(st->codecpar->codec_id);
2885  if (bits_per_sample && (bits_per_sample >> 3) * (uint64_t)st->codecpar->ch_layout.nb_channels <= INT_MAX) {
2886  st->codecpar->bits_per_coded_sample = bits_per_sample;
2887  sc->sample_size = (bits_per_sample >> 3) * st->codecpar->ch_layout.nb_channels;
2888  }
2889 }
2890 
2892  AVStream *st, MOVStreamContext *sc,
2893  int64_t size)
2894 {
2895  // ttxt stsd contains display flags, justification, background
2896  // color, fonts, and default styles, so fake an atom to read it
2897  MOVAtom fake_atom = { .size = size };
2898  // mp4s contains a regular esds atom, dfxp ISMV TTML has no content
2899  // in extradata unlike stpp MP4 TTML.
2900  if (st->codecpar->codec_tag != AV_RL32("mp4s") &&
2902  mov_read_glbl(c, pb, fake_atom);
2903  st->codecpar->width = sc->width;
2904  st->codecpar->height = sc->height;
2905 }
2906 
2908  AVStream *st, MOVStreamContext *sc,
2909  int64_t size)
2910 {
2911  int ret;
2912 
2913  if (st->codecpar->codec_tag == MKTAG('t','m','c','d')) {
2914  if ((int)size != size)
2915  return AVERROR(ENOMEM);
2916 
2917  ret = ff_get_extradata(c->fc, st->codecpar, pb, size);
2918  if (ret < 0)
2919  return ret;
2920  if (size > 16) {
2921  MOVStreamContext *tmcd_ctx = st->priv_data;
2922  int val;
2923  val = AV_RB32(st->codecpar->extradata + 4);
2924  tmcd_ctx->tmcd_flags = val;
2925  st->avg_frame_rate.num = AV_RB32(st->codecpar->extradata + 8); /* timescale */
2926  st->avg_frame_rate.den = AV_RB32(st->codecpar->extradata + 12); /* frameDuration */
2927  tmcd_ctx->tmcd_nb_frames = st->codecpar->extradata[16]; /* number of frames */
2928  if (size > 30) {
2929  uint32_t len = AV_RB32(st->codecpar->extradata + 18); /* name atom length */
2930  uint32_t format = AV_RB32(st->codecpar->extradata + 22);
2931  if (format == AV_RB32("name") && (int64_t)size >= (int64_t)len + 18) {
2932  uint16_t str_size = AV_RB16(st->codecpar->extradata + 26); /* string length */
2933  if (str_size > 0 && size >= (int)str_size + 30 &&
2934  st->codecpar->extradata[30] /* Don't add empty string */) {
2935  char *reel_name = av_malloc(str_size + 1);
2936  if (!reel_name)
2937  return AVERROR(ENOMEM);
2938  memcpy(reel_name, st->codecpar->extradata + 30, str_size);
2939  reel_name[str_size] = 0; /* Add null terminator */
2940  av_dict_set(&st->metadata, "reel_name", reel_name,
2942  }
2943  }
2944  }
2945  }
2946  } else {
2947  /* other codec type, just skip (rtp, mp4s ...) */
2948  avio_skip(pb, size);
2949  }
2950  return 0;
2951 }
2952 
2954  AVStream *st, MOVStreamContext *sc)
2955 {
2956  FFStream *const sti = ffstream(st);
2957 
2958  if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
2959  !st->codecpar->sample_rate && sc->time_scale > 1)
2960  st->codecpar->sample_rate = sc->time_scale;
2961 
2962  /* special codec parameters handling */
2963  switch (st->codecpar->codec_id) {
2964 #if CONFIG_DV_DEMUXER
2965  case AV_CODEC_ID_DVAUDIO:
2966  if (c->dv_fctx) {
2967  avpriv_request_sample(c->fc, "multiple DV audio streams");
2968  return AVERROR(ENOSYS);
2969  }
2970 
2971  c->dv_fctx = avformat_alloc_context();
2972  if (!c->dv_fctx) {
2973  av_log(c->fc, AV_LOG_ERROR, "dv demux context alloc error\n");
2974  return AVERROR(ENOMEM);
2975  }
2976  c->dv_demux = avpriv_dv_init_demux(c->dv_fctx);
2977  if (!c->dv_demux) {
2978  av_log(c->fc, AV_LOG_ERROR, "dv demux context init error\n");
2979  return AVERROR(ENOMEM);
2980  }
2981  sc->dv_audio_container = 1;
2983  break;
2984 #endif
2985  /* no ifdef since parameters are always those */
2986  case AV_CODEC_ID_QCELP:
2989  // force sample rate for qcelp when not stored in mov
2990  if (st->codecpar->codec_tag != MKTAG('Q','c','l','p'))
2991  st->codecpar->sample_rate = 8000;
2992  // FIXME: Why is the following needed for some files?
2993  sc->samples_per_frame = 160;
2994  if (!sc->bytes_per_frame)
2995  sc->bytes_per_frame = 35;
2996  break;
2997  case AV_CODEC_ID_AMR_NB:
3000  /* force sample rate for amr, stsd in 3gp does not store sample rate */
3001  st->codecpar->sample_rate = 8000;
3002  break;
3003  case AV_CODEC_ID_AMR_WB:
3006  st->codecpar->sample_rate = 16000;
3007  break;
3008  case AV_CODEC_ID_MP2:
3009  case AV_CODEC_ID_MP3:
3010  /* force type after stsd for m1a hdlr */
3012  break;
3013  case AV_CODEC_ID_GSM:
3014  case AV_CODEC_ID_ADPCM_MS:
3016  case AV_CODEC_ID_ILBC:
3017  case AV_CODEC_ID_MACE3:
3018  case AV_CODEC_ID_MACE6:
3019  case AV_CODEC_ID_QDM2:
3021  break;
3022  case AV_CODEC_ID_ALAC:
3023  if (st->codecpar->extradata_size == 36) {
3024  int channel_count = AV_RB8(st->codecpar->extradata + 21);
3025  if (st->codecpar->ch_layout.nb_channels != channel_count) {
3028  st->codecpar->ch_layout.nb_channels = channel_count;
3029  }
3030  st->codecpar->sample_rate = AV_RB32(st->codecpar->extradata + 32);
3031  }
3032  break;
3033  case AV_CODEC_ID_AC3:
3034  case AV_CODEC_ID_EAC3:
3036  case AV_CODEC_ID_VC1:
3037  case AV_CODEC_ID_VP8:
3038  case AV_CODEC_ID_VP9:
3040  break;
3042  case AV_CODEC_ID_PRORES:
3043  case AV_CODEC_ID_APV:
3044  case AV_CODEC_ID_EVC:
3045  case AV_CODEC_ID_LCEVC:
3046  case AV_CODEC_ID_AV1:
3047  /* field_order detection of H264 requires parsing */
3048  case AV_CODEC_ID_H264:
3050  break;
3051  default:
3052  break;
3053  }
3054  return 0;
3055 }
3056 
3058  int codec_tag, int format,
3059  int64_t size)
3060 {
3061  if (codec_tag &&
3062  (codec_tag != format &&
3063  // AVID 1:1 samples with differing data format and codec tag exist
3064  (codec_tag != AV_RL32("AV1x") || format != AV_RL32("AVup")) &&
3065  // prores is allowed to have differing data format and codec tag
3066  codec_tag != AV_RL32("apcn") && codec_tag != AV_RL32("apch") &&
3067  // so is dv (sigh)
3068  codec_tag != AV_RL32("dvpp") && codec_tag != AV_RL32("dvcp") &&
3069  (c->fc->video_codec_id ? ff_codec_get_id(ff_codec_movvideo_tags, format) != c->fc->video_codec_id
3070  : codec_tag != MKTAG('j','p','e','g')))) {
3071  /* Multiple fourcc, we skip JPEG. This is not correct, we should
3072  * export it as a separate AVStream but this needs a few changes
3073  * in the MOV demuxer, patch welcome. */
3074 
3075  av_log(c->fc, AV_LOG_WARNING, "multiple fourcc not supported\n");
3076  avio_skip(pb, size);
3077  return 1;
3078  }
3079 
3080  return 0;
3081 }
3082 
3084 {
3085  int ret;
3086 
3087  /* special codec parameters handling */
3088  switch (st->codecpar->codec_id) {
3089  case AV_CODEC_ID_H264:
3090  // done for ai5q, ai52, ai55, ai1q, ai12 and ai15.
3091  if (!st->codecpar->extradata_size && TAG_IS_AVCI(st->codecpar->codec_tag)) {
3093  if (ret < 0)
3094  return ret;
3095  }
3096  break;
3097  default:
3098  break;
3099  }
3100 
3101  return 0;
3102 }
3103 
3105 {
3106  AVStream *st;
3107  MOVStreamContext *sc;
3108  int pseudo_stream_id;
3109 
3110  av_assert0 (c->fc->nb_streams >= 1);
3111  st = c->fc->streams[c->fc->nb_streams-1];
3112  sc = st->priv_data;
3113 
3114  for (pseudo_stream_id = 0;
3115  pseudo_stream_id < entries && !pb->eof_reached;
3116  pseudo_stream_id++) {
3117  //Parsing Sample description table
3118  enum AVCodecID id;
3119  int ret, dref_id = 1;
3120  MOVAtom a = { AV_RL32("stsd") };
3121  int64_t start_pos = avio_tell(pb);
3122  int64_t size = avio_rb32(pb); /* size */
3123  uint32_t format = avio_rl32(pb); /* data format */
3124 
3125  if (size >= 16) {
3126  avio_rb32(pb); /* reserved */
3127  avio_rb16(pb); /* reserved */
3128  dref_id = avio_rb16(pb);
3129  } else if (size <= 7) {
3130  av_log(c->fc, AV_LOG_ERROR,
3131  "invalid size %"PRId64" in stsd\n", size);
3132  return AVERROR_INVALIDDATA;
3133  }
3134 
3136  size - (avio_tell(pb) - start_pos))) {
3137  sc->stsd_count++;
3138  continue;
3139  }
3140 
3141  sc->pseudo_stream_id = st->codecpar->codec_tag ? -1 : pseudo_stream_id;
3142  sc->dref_id= dref_id;
3143  sc->format = format;
3144 
3145  id = mov_codec_id(st, format);
3146 
3147  av_log(c->fc, AV_LOG_TRACE,
3148  "size=%"PRId64" 4CC=%s codec_type=%d\n", size,
3150 
3151  st->codecpar->codec_id = id;
3153  mov_parse_stsd_video(c, pb, st, sc);
3154  } else if (st->codecpar->codec_type==AVMEDIA_TYPE_AUDIO) {
3155  mov_parse_stsd_audio(c, pb, st, sc);
3156  if (st->codecpar->sample_rate < 0) {
3157  av_log(c->fc, AV_LOG_ERROR, "Invalid sample rate %d\n", st->codecpar->sample_rate);
3158  return AVERROR_INVALIDDATA;
3159  }
3160  if (st->codecpar->ch_layout.nb_channels < 0) {
3161  av_log(c->fc, AV_LOG_ERROR, "Invalid channels %d\n", st->codecpar->ch_layout.nb_channels);
3162  return AVERROR_INVALIDDATA;
3163  }
3164  } else if (st->codecpar->codec_type==AVMEDIA_TYPE_SUBTITLE){
3165  mov_parse_stsd_subtitle(c, pb, st, sc,
3166  size - (avio_tell(pb) - start_pos));
3167  } else {
3168  ret = mov_parse_stsd_data(c, pb, st, sc,
3169  size - (avio_tell(pb) - start_pos));
3170  if (ret < 0)
3171  return ret;
3172  }
3173  /* this will read extra atoms at the end (wave, alac, damr, avcC, hvcC, SMI ...) */
3174  a.size = size - (avio_tell(pb) - start_pos);
3175  if (a.size > 8) {
3176  if ((ret = mov_read_default(c, pb, a)) < 0)
3177  return ret;
3178  } else if (a.size > 0)
3179  avio_skip(pb, a.size);
3180 
3181  ret = mov_finalize_stsd_entry(c, st);
3182  if (ret < 0)
3183  return ret;
3184 
3185  if (sc->extradata && st->codecpar->extradata) {
3186  int extra_size = st->codecpar->extradata_size;
3187 
3188  /* Move the current stream extradata to the stream context one. */
3189  sc->extradata_size[pseudo_stream_id] = extra_size;
3190  sc->extradata[pseudo_stream_id] = st->codecpar->extradata;
3191  st->codecpar->extradata = NULL;
3192  st->codecpar->extradata_size = 0;
3193  }
3194  sc->stsd_count++;
3195  }
3196 
3197  if (pb->eof_reached) {
3198  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSD atom\n");
3199  return AVERROR_EOF;
3200  }
3201 
3202  return 0;
3203 }
3204 
3206 {
3207  AVStream *st;
3208  MOVStreamContext *sc;
3209  int ret, entries;
3210 
3211  if (c->fc->nb_streams < 1)
3212  return 0;
3213  st = c->fc->streams[c->fc->nb_streams - 1];
3214  sc = st->priv_data;
3215 
3216  if (sc->extradata) {
3217  av_log(c->fc, AV_LOG_ERROR,
3218  "Duplicate stsd found in this track.\n");
3219  return AVERROR_INVALIDDATA;
3220  }
3221 
3222  sc->stsd_version = avio_r8(pb);
3223  avio_rb24(pb); /* flags */
3224  entries = avio_rb32(pb);
3225 
3226  /* Each entry contains a size (4 bytes) and format (4 bytes). */
3227  if (entries <= 0 || entries > atom.size / 8 || entries > 1024) {
3228  av_log(c->fc, AV_LOG_ERROR, "invalid STSD entries %d\n", entries);
3229  return AVERROR_INVALIDDATA;
3230  }
3231 
3232  /* Prepare space for hosting multiple extradata. */
3233  sc->extradata = av_calloc(entries, sizeof(*sc->extradata));
3234  if (!sc->extradata)
3235  return AVERROR(ENOMEM);
3236 
3237  sc->extradata_size = av_calloc(entries, sizeof(*sc->extradata_size));
3238  if (!sc->extradata_size) {
3239  ret = AVERROR(ENOMEM);
3240  goto fail;
3241  }
3242 
3243  ret = ff_mov_read_stsd_entries(c, pb, entries);
3244  if (ret < 0)
3245  goto fail;
3246 
3247  /* Restore back the primary extradata. */
3248  av_freep(&st->codecpar->extradata);
3249  st->codecpar->extradata_size = sc->extradata_size[0];
3250  if (sc->extradata_size[0]) {
3252  if (!st->codecpar->extradata)
3253  return AVERROR(ENOMEM);
3254  memcpy(st->codecpar->extradata, sc->extradata[0], sc->extradata_size[0]);
3255  }
3256 
3257  return mov_finalize_stsd_codec(c, pb, st, sc);
3258 fail:
3259  if (sc->extradata) {
3260  int j;
3261  for (j = 0; j < sc->stsd_count; j++)
3262  av_freep(&sc->extradata[j]);
3263  }
3264 
3265  sc->stsd_count = 0;
3266  av_freep(&sc->extradata);
3267  av_freep(&sc->extradata_size);
3268  return ret;
3269 }
3270 
3272 {
3273  AVStream *st;
3274  MOVStreamContext *sc;
3275  unsigned int i, entries;
3276 
3277  if (c->trak_index < 0) {
3278  av_log(c->fc, AV_LOG_WARNING, "STSC outside TRAK\n");
3279  return 0;
3280  }
3281 
3282  if (c->fc->nb_streams < 1)
3283  return 0;
3284  st = c->fc->streams[c->fc->nb_streams-1];
3285  sc = st->priv_data;
3286 
3287  avio_r8(pb); /* version */
3288  avio_rb24(pb); /* flags */
3289 
3290  entries = avio_rb32(pb);
3291  if ((uint64_t)entries * 12 + 4 > atom.size)
3292  return AVERROR_INVALIDDATA;
3293 
3294  av_log(c->fc, AV_LOG_TRACE, "track[%u].stsc.entries = %u\n", c->fc->nb_streams - 1, entries);
3295 
3296  if (!entries)
3297  return 0;
3298  if (sc->stsc_data) {
3299  av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicated STSC atom\n");
3300  return 0;
3301  }
3302  av_free(sc->stsc_data);
3303  sc->stsc_count = 0;
3304  sc->stsc_data = av_malloc_array(entries, sizeof(*sc->stsc_data));
3305  if (!sc->stsc_data)
3306  return AVERROR(ENOMEM);
3307 
3308  for (i = 0; i < entries && !pb->eof_reached; i++) {
3309  sc->stsc_data[i].first = avio_rb32(pb);
3310  sc->stsc_data[i].count = avio_rb32(pb);
3311  sc->stsc_data[i].id = avio_rb32(pb);
3312  }
3313 
3314  sc->stsc_count = i;
3315  for (i = sc->stsc_count - 1; i < UINT_MAX; i--) {
3316  int64_t first_min = i + 1;
3317  if ((i+1 < sc->stsc_count && sc->stsc_data[i].first >= sc->stsc_data[i+1].first) ||
3318  (i > 0 && sc->stsc_data[i].first <= sc->stsc_data[i-1].first) ||
3319  sc->stsc_data[i].first < first_min ||
3320  sc->stsc_data[i].count < 1 ||
3321  sc->stsc_data[i].id < 1) {
3322  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);
3323  if (i+1 >= sc->stsc_count) {
3324  if (sc->stsc_data[i].count == 0 && i > 0) {
3325  sc->stsc_count --;
3326  continue;
3327  }
3328  sc->stsc_data[i].first = FFMAX(sc->stsc_data[i].first, first_min);
3329  if (i > 0 && sc->stsc_data[i].first <= sc->stsc_data[i-1].first)
3330  sc->stsc_data[i].first = FFMIN(sc->stsc_data[i-1].first + 1LL, INT_MAX);
3331  sc->stsc_data[i].count = FFMAX(sc->stsc_data[i].count, 1);
3332  sc->stsc_data[i].id = FFMAX(sc->stsc_data[i].id, 1);
3333  continue;
3334  }
3335  av_assert0(sc->stsc_data[i+1].first >= 2);
3336  // We replace this entry by the next valid
3337  sc->stsc_data[i].first = sc->stsc_data[i+1].first - 1;
3338  sc->stsc_data[i].count = sc->stsc_data[i+1].count;
3339  sc->stsc_data[i].id = sc->stsc_data[i+1].id;
3340  }
3341  }
3342 
3343  if (pb->eof_reached) {
3344  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSC atom\n");
3345  return AVERROR_EOF;
3346  }
3347 
3348  return 0;
3349 }
3350 
3351 static inline int mov_stsc_index_valid(unsigned int index, unsigned int count)
3352 {
3353  return index < count - 1;
3354 }
3355 
3356 /* Compute the samples value for the stsc entry at the given index. */
3357 static inline int64_t mov_get_stsc_samples(MOVStreamContext *sc, unsigned int index)
3358 {
3359  int chunk_count;
3360 
3362  chunk_count = sc->stsc_data[index + 1].first - sc->stsc_data[index].first;
3363  else {
3364  // Validation for stsc / stco happens earlier in mov_read_stsc + mov_read_trak.
3366  chunk_count = sc->chunk_count - (sc->stsc_data[index].first - 1);
3367  }
3368 
3369  return sc->stsc_data[index].count * (int64_t)chunk_count;
3370 }
3371 
3373 {
3374  AVStream *st;
3375  MOVStreamContext *sc;
3376  unsigned i, entries;
3377 
3378  if (c->trak_index < 0) {
3379  av_log(c->fc, AV_LOG_WARNING, "STPS outside TRAK\n");
3380  return 0;
3381  }
3382 
3383  if (c->fc->nb_streams < 1)
3384  return 0;
3385  st = c->fc->streams[c->fc->nb_streams-1];
3386  sc = st->priv_data;
3387 
3388  avio_rb32(pb); // version + flags
3389 
3390  entries = avio_rb32(pb);
3391  if (sc->stps_data)
3392  av_log(c->fc, AV_LOG_WARNING, "Duplicated STPS atom\n");
3393  av_free(sc->stps_data);
3394  sc->stps_count = 0;
3395  sc->stps_data = av_malloc_array(entries, sizeof(*sc->stps_data));
3396  if (!sc->stps_data)
3397  return AVERROR(ENOMEM);
3398 
3399  for (i = 0; i < entries && !pb->eof_reached; i++) {
3400  sc->stps_data[i] = avio_rb32(pb);
3401  }
3402 
3403  sc->stps_count = i;
3404 
3405  if (pb->eof_reached) {
3406  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STPS atom\n");
3407  return AVERROR_EOF;
3408  }
3409 
3410  return 0;
3411 }
3412 
3414 {
3415  AVStream *st;
3416  FFStream *sti;
3417  MOVStreamContext *sc;
3418  unsigned int i, entries;
3419 
3420  if (c->trak_index < 0) {
3421  av_log(c->fc, AV_LOG_WARNING, "STSS outside TRAK\n");
3422  return 0;
3423  }
3424 
3425  if (c->fc->nb_streams < 1)
3426  return 0;
3427  st = c->fc->streams[c->fc->nb_streams-1];
3428  sti = ffstream(st);
3429  sc = st->priv_data;
3430 
3431  avio_r8(pb); /* version */
3432  avio_rb24(pb); /* flags */
3433 
3434  entries = avio_rb32(pb);
3435 
3436  av_log(c->fc, AV_LOG_TRACE, "keyframe_count = %u\n", entries);
3437 
3438  if (!entries) {
3439  sc->keyframe_absent = 1;
3440  if (!sti->need_parsing && st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
3442  return 0;
3443  }
3444  if (sc->keyframes)
3445  av_log(c->fc, AV_LOG_WARNING, "Duplicated STSS atom\n");
3446  if (entries >= UINT_MAX / sizeof(int))
3447  return AVERROR_INVALIDDATA;
3448  av_freep(&sc->keyframes);
3449  sc->keyframe_count = 0;
3450  sc->keyframes = av_malloc_array(entries, sizeof(*sc->keyframes));
3451  if (!sc->keyframes)
3452  return AVERROR(ENOMEM);
3453 
3454  for (i = 0; i < entries && !pb->eof_reached; i++) {
3455  sc->keyframes[i] = avio_rb32(pb);
3456  }
3457 
3458  sc->keyframe_count = i;
3459 
3460  if (pb->eof_reached) {
3461  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSS atom\n");
3462  return AVERROR_EOF;
3463  }
3464 
3465  return 0;
3466 }
3467 
3469 {
3470  AVStream *st;
3471  MOVStreamContext *sc;
3472  unsigned int i, entries, sample_size, field_size, num_bytes;
3473  GetBitContext gb;
3474  unsigned char* buf;
3475  int ret;
3476 
3477  if (c->trak_index < 0) {
3478  av_log(c->fc, AV_LOG_WARNING, "STSZ outside TRAK\n");
3479  return 0;
3480  }
3481 
3482  if (c->fc->nb_streams < 1)
3483  return 0;
3484  st = c->fc->streams[c->fc->nb_streams-1];
3485  sc = st->priv_data;
3486 
3487  avio_r8(pb); /* version */
3488  avio_rb24(pb); /* flags */
3489 
3490  if (atom.type == MKTAG('s','t','s','z')) {
3491  sample_size = avio_rb32(pb);
3492  if (!sc->sample_size) /* do not overwrite value computed in stsd */
3493  sc->sample_size = sample_size;
3494  sc->stsz_sample_size = sample_size;
3495  field_size = 32;
3496  } else {
3497  sample_size = 0;
3498  avio_rb24(pb); /* reserved */
3499  field_size = avio_r8(pb);
3500  }
3501  entries = avio_rb32(pb);
3502 
3503  av_log(c->fc, AV_LOG_TRACE, "sample_size = %u sample_count = %u\n", sc->sample_size, entries);
3504 
3505  sc->sample_count = entries;
3506  if (sample_size)
3507  return 0;
3508 
3509  if (field_size != 4 && field_size != 8 && field_size != 16 && field_size != 32) {
3510  av_log(c->fc, AV_LOG_ERROR, "Invalid sample field size %u\n", field_size);
3511  return AVERROR_INVALIDDATA;
3512  }
3513 
3514  if (!entries)
3515  return 0;
3516  if (entries >= (INT_MAX - 4 - 8 * AV_INPUT_BUFFER_PADDING_SIZE) / field_size)
3517  return AVERROR_INVALIDDATA;
3518  if (sc->sample_sizes)
3519  av_log(c->fc, AV_LOG_WARNING, "Duplicated STSZ atom\n");
3520  av_free(sc->sample_sizes);
3521  sc->sample_count = 0;
3522  sc->sample_sizes = av_malloc_array(entries, sizeof(*sc->sample_sizes));
3523  if (!sc->sample_sizes)
3524  return AVERROR(ENOMEM);
3525 
3526  num_bytes = (entries*field_size+4)>>3;
3527 
3528  buf = av_malloc(num_bytes+AV_INPUT_BUFFER_PADDING_SIZE);
3529  if (!buf) {
3530  av_freep(&sc->sample_sizes);
3531  return AVERROR(ENOMEM);
3532  }
3533 
3534  ret = ffio_read_size(pb, buf, num_bytes);
3535  if (ret < 0) {
3536  av_freep(&sc->sample_sizes);
3537  av_free(buf);
3538  av_log(c->fc, AV_LOG_WARNING, "STSZ atom truncated\n");
3539  return 0;
3540  }
3541 
3542  init_get_bits(&gb, buf, 8*num_bytes);
3543 
3544  for (i = 0; i < entries; i++) {
3545  sc->sample_sizes[i] = get_bits_long(&gb, field_size);
3546  if (sc->sample_sizes[i] > INT64_MAX - sc->data_size) {
3547  av_free(buf);
3548  av_log(c->fc, AV_LOG_ERROR, "Sample size overflow in STSZ\n");
3549  return AVERROR_INVALIDDATA;
3550  }
3551  sc->data_size += sc->sample_sizes[i];
3552  }
3553 
3554  sc->sample_count = i;
3555 
3556  av_free(buf);
3557 
3558  return 0;
3559 }
3560 
3562 {
3563  AVStream *st;
3564  MOVStreamContext *sc;
3565  unsigned int i, entries;
3566  int64_t duration = 0;
3567  int64_t total_sample_count = 0;
3568  int64_t current_dts = 0;
3569  int64_t corrected_dts = 0;
3570 
3571  if (c->trak_index < 0) {
3572  av_log(c->fc, AV_LOG_WARNING, "STTS outside TRAK\n");
3573  return 0;
3574  }
3575 
3576  if (c->fc->nb_streams < 1)
3577  return 0;
3578  st = c->fc->streams[c->fc->nb_streams-1];
3579  sc = st->priv_data;
3580 
3581  avio_r8(pb); /* version */
3582  avio_rb24(pb); /* flags */
3583  entries = avio_rb32(pb);
3584 
3585  av_log(c->fc, AV_LOG_TRACE, "track[%u].stts.entries = %u\n",
3586  c->fc->nb_streams-1, entries);
3587 
3588  if (sc->stts_data)
3589  av_log(c->fc, AV_LOG_WARNING, "Duplicated STTS atom\n");
3590  av_freep(&sc->stts_data);
3591  sc->stts_count = 0;
3592  if (entries >= INT_MAX / sizeof(*sc->stts_data))
3593  return AVERROR(ENOMEM);
3594 
3595  for (i = 0; i < entries && !pb->eof_reached; i++) {
3596  unsigned int sample_duration;
3597  unsigned int sample_count;
3598  unsigned int min_entries = FFMIN(FFMAX(i + 1, 1024 * 1024), entries);
3599  MOVStts *stts_data = av_fast_realloc(sc->stts_data, &sc->stts_allocated_size,
3600  min_entries * sizeof(*sc->stts_data));
3601  if (!stts_data) {
3602  av_freep(&sc->stts_data);
3603  sc->stts_count = 0;
3604  return AVERROR(ENOMEM);
3605  }
3606  sc->stts_count = min_entries;
3607  sc->stts_data = stts_data;
3608 
3609  sample_count = avio_rb32(pb);
3610  sample_duration = avio_rb32(pb);
3611 
3612  sc->stts_data[i].count= sample_count;
3613  sc->stts_data[i].duration= sample_duration;
3614 
3615  av_log(c->fc, AV_LOG_TRACE, "sample_count=%u, sample_duration=%u\n",
3616  sample_count, sample_duration);
3617 
3618  /* STTS sample offsets are uint32 but some files store it as int32
3619  * with negative values used to correct DTS delays.
3620  There may be abnormally large values as well. */
3621  if (sample_duration > c->max_stts_delta) {
3622  // assume high delta is a correction if negative when cast as int32
3623  int32_t delta_magnitude = (int32_t)sample_duration;
3624  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",
3625  sample_duration, i, sample_count, st->index);
3626  sc->stts_data[i].duration = 1;
3627  corrected_dts = av_sat_add64(corrected_dts, (delta_magnitude < 0 ? (int64_t)delta_magnitude : 1) * sample_count);
3628  } else {
3629  corrected_dts += sample_duration * (uint64_t)sample_count;
3630  }
3631 
3632  current_dts += sc->stts_data[i].duration * (uint64_t)sample_count;
3633 
3634  if (current_dts > corrected_dts) {
3635  int64_t drift = av_sat_sub64(current_dts, corrected_dts) / FFMAX(sample_count, 1);
3636  uint32_t correction = (sc->stts_data[i].duration > drift) ? drift : sc->stts_data[i].duration - 1;
3637  current_dts -= correction * (uint64_t)sample_count;
3638  sc->stts_data[i].duration -= correction;
3639  }
3640 
3641  duration+=(int64_t)sc->stts_data[i].duration*(uint64_t)sc->stts_data[i].count;
3642  total_sample_count+=sc->stts_data[i].count;
3643  }
3644 
3645  sc->stts_count = i;
3646 
3647  if (duration > 0 &&
3648  duration <= INT64_MAX - sc->duration_for_fps &&
3649  total_sample_count <= INT_MAX - sc->nb_frames_for_fps) {
3650  sc->duration_for_fps += duration;
3651  sc->nb_frames_for_fps += total_sample_count;
3652  }
3653 
3654  if (pb->eof_reached) {
3655  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STTS atom\n");
3656  return AVERROR_EOF;
3657  }
3658 
3659  st->nb_frames= total_sample_count;
3660  if (duration)
3661  st->duration= FFMIN(st->duration, duration);
3662 
3663  // All samples have zero duration. They have higher chance be chose by
3664  // mov_find_next_sample, which leads to seek again and again.
3665  //
3666  // It's AVERROR_INVALIDDATA actually, but such files exist in the wild.
3667  // So only mark data stream as discarded for safety.
3668  if (!duration && sc->stts_count &&
3670  av_log(c->fc, AV_LOG_WARNING,
3671  "All samples in data stream index:id [%d:%d] have zero "
3672  "duration, stream set to be discarded by default. Override "
3673  "using AVStream->discard or -discard for ffmpeg command.\n",
3674  st->index, sc->id);
3675  st->discard = AVDISCARD_ALL;
3676  }
3677  sc->track_end = duration;
3678  return 0;
3679 }
3680 
3682 {
3683  AVStream *st;
3684  MOVStreamContext *sc;
3685  unsigned int i;
3686  int64_t entries;
3687 
3688  if (c->fc->nb_streams < 1)
3689  return 0;
3690  st = c->fc->streams[c->fc->nb_streams - 1];
3691  sc = st->priv_data;
3692 
3693  avio_r8(pb); /* version */
3694  avio_rb24(pb); /* flags */
3695  entries = atom.size - 4;
3696 
3697  av_log(c->fc, AV_LOG_TRACE, "track[%u].sdtp.entries = %" PRId64 "\n",
3698  c->fc->nb_streams - 1, entries);
3699 
3700  if (sc->sdtp_data)
3701  av_log(c->fc, AV_LOG_WARNING, "Duplicated SDTP atom\n");
3702  av_freep(&sc->sdtp_data);
3703  sc->sdtp_count = 0;
3704 
3705  if (entries < 0 || entries > UINT_MAX)
3706  return AVERROR(ERANGE);
3707 
3708  sc->sdtp_data = av_malloc(entries);
3709  if (!sc->sdtp_data)
3710  return AVERROR(ENOMEM);
3711 
3712  for (i = 0; i < entries && !pb->eof_reached; i++)
3713  sc->sdtp_data[i] = avio_r8(pb);
3714  sc->sdtp_count = i;
3715 
3716  return 0;
3717 }
3718 
3719 static void mov_update_dts_shift(MOVStreamContext *sc, int duration, void *logctx)
3720 {
3721  if (duration < 0) {
3722  if (duration == INT_MIN) {
3723  av_log(logctx, AV_LOG_WARNING, "mov_update_dts_shift(): dts_shift set to %d\n", INT_MAX);
3724  duration++;
3725  }
3726  sc->dts_shift = FFMAX(sc->dts_shift, -duration);
3727  }
3728 }
3729 
3731 {
3732  AVStream *st;
3733  MOVStreamContext *sc;
3734  unsigned int i, entries, ctts_count = 0;
3735 
3736  if (c->trak_index < 0) {
3737  av_log(c->fc, AV_LOG_WARNING, "CTTS outside TRAK\n");
3738  return 0;
3739  }
3740 
3741  if (c->fc->nb_streams < 1)
3742  return 0;
3743  st = c->fc->streams[c->fc->nb_streams-1];
3744  sc = st->priv_data;
3745 
3746  avio_r8(pb); /* version */
3747  avio_rb24(pb); /* flags */
3748  entries = avio_rb32(pb);
3749 
3750  av_log(c->fc, AV_LOG_TRACE, "track[%u].ctts.entries = %u\n", c->fc->nb_streams - 1, entries);
3751 
3752  if (!entries)
3753  return 0;
3754  if (entries >= UINT_MAX / sizeof(*sc->ctts_data))
3755  return AVERROR_INVALIDDATA;
3756  av_freep(&sc->ctts_data);
3757  sc->ctts_data = av_fast_realloc(NULL, &sc->ctts_allocated_size, entries * sizeof(*sc->ctts_data));
3758  if (!sc->ctts_data)
3759  return AVERROR(ENOMEM);
3760 
3761  for (i = 0; i < entries && !pb->eof_reached; i++) {
3762  MOVCtts *ctts_data;
3763  const size_t min_size_needed = (ctts_count + 1) * sizeof(MOVCtts);
3764  const size_t requested_size =
3765  min_size_needed > sc->ctts_allocated_size ?
3766  FFMAX(min_size_needed, 2 * sc->ctts_allocated_size) :
3767  min_size_needed;
3768  int count = avio_rb32(pb);
3769  int duration = avio_rb32(pb);
3770 
3771  if (count <= 0) {
3772  av_log(c->fc, AV_LOG_TRACE,
3773  "ignoring CTTS entry with count=%d duration=%d\n",
3774  count, duration);
3775  continue;
3776  }
3777 
3778  if (ctts_count >= UINT_MAX / sizeof(MOVCtts) - 1)
3779  return AVERROR(ENOMEM);
3780 
3781  ctts_data = av_fast_realloc(sc->ctts_data, &sc->ctts_allocated_size, requested_size);
3782 
3783  if (!ctts_data)
3784  return AVERROR(ENOMEM);
3785 
3786  sc->ctts_data = ctts_data;
3787 
3788  ctts_data[ctts_count].count = count;
3789  ctts_data[ctts_count].offset = duration;
3790  ctts_count++;
3791 
3792  av_log(c->fc, AV_LOG_TRACE, "count=%d, duration=%d\n",
3793  count, duration);
3794 
3795  if (i+2<entries)
3796  mov_update_dts_shift(sc, duration, c->fc);
3797  }
3798 
3799  sc->ctts_count = ctts_count;
3800 
3801  if (pb->eof_reached) {
3802  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted CTTS atom\n");
3803  return AVERROR_EOF;
3804  }
3805 
3806  av_log(c->fc, AV_LOG_TRACE, "dts shift %d\n", sc->dts_shift);
3807 
3808  return 0;
3809 }
3810 
3812 {
3813  AVStream *st;
3814  MOVStreamContext *sc;
3815  uint8_t version;
3816  uint32_t grouping_type;
3817  uint32_t default_length;
3818  av_unused uint32_t default_group_description_index;
3819  uint32_t entry_count;
3820 
3821  if (c->fc->nb_streams < 1)
3822  return 0;
3823  st = c->fc->streams[c->fc->nb_streams - 1];
3824  sc = st->priv_data;
3825 
3826  version = avio_r8(pb); /* version */
3827  avio_rb24(pb); /* flags */
3828  grouping_type = avio_rl32(pb);
3829 
3830  /*
3831  * This function only supports "sync" boxes, but the code is able to parse
3832  * other boxes (such as "tscl", "tsas" and "stsa")
3833  */
3834  if (grouping_type != MKTAG('s','y','n','c'))
3835  return 0;
3836 
3837  default_length = version >= 1 ? avio_rb32(pb) : 0;
3838  default_group_description_index = version >= 2 ? avio_rb32(pb) : 0;
3839  entry_count = avio_rb32(pb);
3840 
3841  av_freep(&sc->sgpd_sync);
3842  sc->sgpd_sync_count = entry_count;
3843  sc->sgpd_sync = av_calloc(entry_count, sizeof(*sc->sgpd_sync));
3844  if (!sc->sgpd_sync)
3845  return AVERROR(ENOMEM);
3846 
3847  for (uint32_t i = 0; i < entry_count && !pb->eof_reached; i++) {
3848  uint32_t description_length = default_length;
3849  if (version >= 1 && default_length == 0)
3850  description_length = avio_rb32(pb);
3851  if (grouping_type == MKTAG('s','y','n','c')) {
3852  const uint8_t nal_unit_type = avio_r8(pb) & 0x3f;
3853  sc->sgpd_sync[i] = nal_unit_type;
3854  description_length -= 1;
3855  }
3856  avio_skip(pb, description_length);
3857  }
3858 
3859  if (pb->eof_reached) {
3860  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted SGPD atom\n");
3861  return AVERROR_EOF;
3862  }
3863 
3864  return 0;
3865 }
3866 
3868 {
3869  AVStream *st;
3870  MOVStreamContext *sc;
3871  unsigned int i, entries;
3872  uint8_t version;
3873  uint32_t grouping_type;
3874  MOVSbgp *table, **tablep;
3875  int *table_count;
3876 
3877  if (c->fc->nb_streams < 1)
3878  return 0;
3879  st = c->fc->streams[c->fc->nb_streams-1];
3880  sc = st->priv_data;
3881 
3882  version = avio_r8(pb); /* version */
3883  avio_rb24(pb); /* flags */
3884  grouping_type = avio_rl32(pb);
3885 
3886  if (grouping_type == MKTAG('r','a','p',' ')) {
3887  tablep = &sc->rap_group;
3888  table_count = &sc->rap_group_count;
3889  } else if (grouping_type == MKTAG('s','y','n','c')) {
3890  tablep = &sc->sync_group;
3891  table_count = &sc->sync_group_count;
3892  } else {
3893  return 0;
3894  }
3895 
3896  if (version == 1)
3897  avio_rb32(pb); /* grouping_type_parameter */
3898 
3899  entries = avio_rb32(pb);
3900  if (!entries)
3901  return 0;
3902  if (*tablep)
3903  av_log(c->fc, AV_LOG_WARNING, "Duplicated SBGP %s atom\n", av_fourcc2str(grouping_type));
3904  av_freep(tablep);
3905  table = av_malloc_array(entries, sizeof(*table));
3906  if (!table)
3907  return AVERROR(ENOMEM);
3908  *tablep = table;
3909 
3910  for (i = 0; i < entries && !pb->eof_reached; i++) {
3911  table[i].count = avio_rb32(pb); /* sample_count */
3912  table[i].index = avio_rb32(pb); /* group_description_index */
3913  }
3914 
3915  *table_count = i;
3916 
3917  if (pb->eof_reached) {
3918  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted SBGP atom\n");
3919  return AVERROR_EOF;
3920  }
3921 
3922  return 0;
3923 }
3924 
3925 /**
3926  * Get ith edit list entry (media time, duration).
3927  */
3929  const MOVStreamContext *msc,
3930  unsigned int edit_list_index,
3931  int64_t *edit_list_media_time,
3932  int64_t *edit_list_duration,
3933  int64_t global_timescale)
3934 {
3935  if (edit_list_index == msc->elst_count) {
3936  return 0;
3937  }
3938  *edit_list_media_time = msc->elst_data[edit_list_index].time;
3939  *edit_list_duration = msc->elst_data[edit_list_index].duration;
3940 
3941  /* duration is in global timescale units;convert to msc timescale */
3942  if (global_timescale == 0) {
3943  avpriv_request_sample(mov->fc, "Support for mvhd.timescale = 0 with editlists");
3944  return 0;
3945  }
3946  *edit_list_duration = av_rescale(*edit_list_duration, msc->time_scale,
3947  global_timescale);
3948 
3949  if (*edit_list_duration + (uint64_t)*edit_list_media_time > INT64_MAX)
3950  *edit_list_duration = 0;
3951 
3952  return 1;
3953 }
3954 
3955 /**
3956  * Find the closest previous frame to the timestamp_pts, in e_old index
3957  * entries. Searching for just any frame / just key frames can be controlled by
3958  * last argument 'flag'.
3959  * Note that if ctts_data is not NULL, we will always search for a key frame
3960  * irrespective of the value of 'flag'. If we don't find any keyframe, we will
3961  * return the first frame of the video.
3962  *
3963  * Here the timestamp_pts is considered to be a presentation timestamp and
3964  * the timestamp of index entries are considered to be decoding timestamps.
3965  *
3966  * Returns 0 if successful in finding a frame, else returns -1.
3967  * Places the found index corresponding output arg.
3968  *
3969  * If ctts_old is not NULL, then refines the searched entry by searching
3970  * backwards from the found timestamp, to find the frame with correct PTS.
3971  *
3972  * Places the found ctts_index and ctts_sample in corresponding output args.
3973  */
3975  AVIndexEntry *e_old,
3976  int nb_old,
3977  MOVTimeToSample *tts_data,
3978  int64_t tts_count,
3979  int64_t timestamp_pts,
3980  int flag,
3981  int64_t* index,
3982  int64_t* tts_index,
3983  int64_t* tts_sample)
3984 {
3985  MOVStreamContext *msc = st->priv_data;
3986  FFStream *const sti = ffstream(st);
3987  AVIndexEntry *e_keep = sti->index_entries;
3988  int nb_keep = sti->nb_index_entries;
3989  int64_t i = 0;
3990 
3991  av_assert0(index);
3992 
3993  // If dts_shift > 0, then all the index timestamps will have to be offset by
3994  // at least dts_shift amount to obtain PTS.
3995  // Hence we decrement the searched timestamp_pts by dts_shift to find the closest index element.
3996  if (msc->dts_shift > 0) {
3997  timestamp_pts -= msc->dts_shift;
3998  }
3999 
4000  sti->index_entries = e_old;
4001  sti->nb_index_entries = nb_old;
4002  *index = av_index_search_timestamp(st, timestamp_pts, flag | AVSEEK_FLAG_BACKWARD);
4003 
4004  // Keep going backwards in the index entries until the timestamp is the same.
4005  if (*index >= 0) {
4006  for (i = *index; i > 0 && e_old[i].timestamp == e_old[i - 1].timestamp;
4007  i--) {
4008  if ((flag & AVSEEK_FLAG_ANY) ||
4009  (e_old[i - 1].flags & AVINDEX_KEYFRAME)) {
4010  *index = i - 1;
4011  }
4012  }
4013  }
4014 
4015  // If we have CTTS then refine the search, by searching backwards over PTS
4016  // computed by adding corresponding CTTS durations to index timestamps.
4017  if (msc->ctts_count && *index >= 0) {
4018  av_assert0(tts_index);
4019  av_assert0(tts_sample);
4020  // Find out the ctts_index for the found frame.
4021  *tts_index = 0;
4022  *tts_sample = 0;
4023  for (int64_t index_tts_count = 0; index_tts_count < *index; index_tts_count++) {
4024  if (*tts_index < tts_count) {
4025  (*tts_sample)++;
4026  if (tts_data[*tts_index].count == *tts_sample) {
4027  (*tts_index)++;
4028  *tts_sample = 0;
4029  }
4030  }
4031  }
4032 
4033  while (*index >= 0 && (*tts_index) >= 0 && (*tts_index) < tts_count) {
4034  // Find a "key frame" with PTS <= timestamp_pts (So that we can decode B-frames correctly).
4035  // No need to add dts_shift to the timestamp here because timestamp_pts has already been
4036  // compensated by dts_shift above.
4037  if ((e_old[*index].timestamp + tts_data[*tts_index].offset) <= timestamp_pts &&
4038  (e_old[*index].flags & AVINDEX_KEYFRAME)) {
4039  break;
4040  }
4041 
4042  (*index)--;
4043  if (*tts_sample == 0) {
4044  (*tts_index)--;
4045  if (*tts_index >= 0)
4046  *tts_sample = tts_data[*tts_index].count - 1;
4047  } else {
4048  (*tts_sample)--;
4049  }
4050  }
4051  }
4052 
4053  /* restore AVStream state*/
4054  sti->index_entries = e_keep;
4055  sti->nb_index_entries = nb_keep;
4056  return *index >= 0 ? 0 : -1;
4057 }
4058 
4059 /**
4060  * Add index entry with the given values, to the end of ffstream(st)->index_entries.
4061  * Returns the new size ffstream(st)->index_entries if successful, else returns -1.
4062  *
4063  * This function is similar to ff_add_index_entry in libavformat/utils.c
4064  * except that here we are always unconditionally adding an index entry to
4065  * the end, instead of searching the entries list and skipping the add if
4066  * there is an existing entry with the same timestamp.
4067  * This is needed because the mov_fix_index calls this func with the same
4068  * unincremented timestamp for successive discarded frames.
4069  */
4071  int size, int distance, int flags)
4072 {
4073  FFStream *const sti = ffstream(st);
4074  AVIndexEntry *entries, *ie;
4075  int64_t index = -1;
4076  const size_t min_size_needed = (sti->nb_index_entries + 1) * sizeof(AVIndexEntry);
4077 
4078  // Double the allocation each time, to lower memory fragmentation.
4079  // Another difference from ff_add_index_entry function.
4080  const size_t requested_size =
4081  min_size_needed > sti->index_entries_allocated_size ?
4082  FFMAX(min_size_needed, 2 * sti->index_entries_allocated_size) :
4083  min_size_needed;
4084 
4085  if (sti->nb_index_entries + 1U >= UINT_MAX / sizeof(AVIndexEntry))
4086  return -1;
4087 
4088  entries = av_fast_realloc(sti->index_entries,
4090  requested_size);
4091  if (!entries)
4092  return -1;
4093 
4094  sti->index_entries = entries;
4095 
4096  index = sti->nb_index_entries++;
4097  ie= &entries[index];
4098 
4099  ie->pos = pos;
4100  ie->timestamp = timestamp;
4101  ie->min_distance= distance;
4102  ie->size= size;
4103  ie->flags = flags;
4104  return index;
4105 }
4106 
4107 /**
4108  * Rewrite timestamps of index entries in the range [end_index - frame_duration_buffer_size, end_index)
4109  * by subtracting end_ts successively by the amounts given in frame_duration_buffer.
4110  */
4111 static void fix_index_entry_timestamps(AVStream* st, int end_index, int64_t end_ts,
4112  int64_t* frame_duration_buffer,
4113  int frame_duration_buffer_size) {
4114  FFStream *const sti = ffstream(st);
4115  int i = 0;
4116  av_assert0(end_index >= 0 && end_index <= sti->nb_index_entries);
4117  for (i = 0; i < frame_duration_buffer_size; i++) {
4118  end_ts -= frame_duration_buffer[frame_duration_buffer_size - 1 - i];
4119  sti->index_entries[end_index - 1 - i].timestamp = end_ts;
4120  }
4121 }
4122 
4123 static int add_tts_entry(MOVTimeToSample **tts_data, unsigned int *tts_count, unsigned int *allocated_size,
4124  int count, int offset, unsigned int duration)
4125 {
4126  MOVTimeToSample *tts_buf_new;
4127  const size_t min_size_needed = (*tts_count + 1) * sizeof(MOVTimeToSample);
4128  const size_t requested_size =
4129  min_size_needed > *allocated_size ?
4130  FFMAX(min_size_needed, 2 * (*allocated_size)) :
4131  min_size_needed;
4132 
4133  if ((unsigned)(*tts_count) >= UINT_MAX / sizeof(MOVTimeToSample) - 1)
4134  return -1;
4135 
4136  tts_buf_new = av_fast_realloc(*tts_data, allocated_size, requested_size);
4137 
4138  if (!tts_buf_new)
4139  return -1;
4140 
4141  *tts_data = tts_buf_new;
4142 
4143  tts_buf_new[*tts_count].count = count;
4144  tts_buf_new[*tts_count].offset = offset;
4145  tts_buf_new[*tts_count].duration = duration;
4146 
4147  *tts_count = (*tts_count) + 1;
4148  return 0;
4149 }
4150 
4151 #define MAX_REORDER_DELAY 16
4153 {
4154  MOVStreamContext *msc = st->priv_data;
4155  FFStream *const sti = ffstream(st);
4156  int ctts_ind = 0;
4157  int ctts_sample = 0;
4158  int64_t pts_buf[MAX_REORDER_DELAY + 1]; // Circular buffer to sort pts.
4159  int buf_start = 0;
4160  int j, r, num_swaps;
4161 
4162  for (j = 0; j < MAX_REORDER_DELAY + 1; j++)
4163  pts_buf[j] = INT64_MIN;
4164 
4165  if (st->codecpar->video_delay <= 0 && msc->ctts_count &&
4167  st->codecpar->video_delay = 0;
4168  for (int ind = 0; ind < sti->nb_index_entries && ctts_ind < msc->tts_count; ++ind) {
4169  // Point j to the last elem of the buffer and insert the current pts there.
4170  j = buf_start;
4171  buf_start = (buf_start + 1);
4172  if (buf_start == MAX_REORDER_DELAY + 1)
4173  buf_start = 0;
4174 
4175  pts_buf[j] = sti->index_entries[ind].timestamp + msc->tts_data[ctts_ind].offset;
4176 
4177  // The timestamps that are already in the sorted buffer, and are greater than the
4178  // current pts, are exactly the timestamps that need to be buffered to output PTS
4179  // in correct sorted order.
4180  // Hence the video delay (which is the buffer size used to sort DTS and output PTS),
4181  // can be computed as the maximum no. of swaps any particular timestamp needs to
4182  // go through, to keep this buffer in sorted order.
4183  num_swaps = 0;
4184  while (j != buf_start) {
4185  r = j - 1;
4186  if (r < 0) r = MAX_REORDER_DELAY;
4187  if (pts_buf[j] < pts_buf[r]) {
4188  FFSWAP(int64_t, pts_buf[j], pts_buf[r]);
4189  ++num_swaps;
4190  } else {
4191  break;
4192  }
4193  j = r;
4194  }
4195  st->codecpar->video_delay = FFMAX(st->codecpar->video_delay, num_swaps);
4196 
4197  ctts_sample++;
4198  if (ctts_sample == msc->tts_data[ctts_ind].count) {
4199  ctts_ind++;
4200  ctts_sample = 0;
4201  }
4202  }
4203  av_log(c->fc, AV_LOG_DEBUG, "Setting codecpar->delay to %d for stream st: %d\n",
4204  st->codecpar->video_delay, st->index);
4205  }
4206 }
4207 
4209 {
4210  sc->current_sample++;
4211  sc->current_index++;
4212  if (sc->index_ranges &&
4213  sc->current_index >= sc->current_index_range->end &&
4214  sc->current_index_range->end) {
4215  sc->current_index_range++;
4217  }
4218 }
4219 
4221 {
4222  sc->current_sample--;
4223  sc->current_index--;
4224  if (sc->index_ranges &&
4226  sc->current_index_range > sc->index_ranges) {
4227  sc->current_index_range--;
4228  sc->current_index = sc->current_index_range->end - 1;
4229  }
4230 }
4231 
4232 static void mov_current_sample_set(MOVStreamContext *sc, int current_sample)
4233 {
4234  int64_t range_size;
4235 
4236  sc->current_sample = current_sample;
4237  sc->current_index = current_sample;
4238  if (!sc->index_ranges) {
4239  return;
4240  }
4241 
4242  for (sc->current_index_range = sc->index_ranges;
4243  sc->current_index_range->end;
4244  sc->current_index_range++) {
4245  range_size = sc->current_index_range->end - sc->current_index_range->start;
4246  if (range_size > current_sample) {
4247  sc->current_index = sc->current_index_range->start + current_sample;
4248  break;
4249  }
4250  current_sample -= range_size;
4251  }
4252 }
4253 
4254 /**
4255  * Fix ffstream(st)->index_entries, so that it contains only the entries (and the entries
4256  * which are needed to decode them) that fall in the edit list time ranges.
4257  * Also fixes the timestamps of the index entries to match the timeline
4258  * specified the edit lists.
4259  */
4260 static void mov_fix_index(MOVContext *mov, AVStream *st)
4261 {
4262  MOVStreamContext *msc = st->priv_data;
4263  FFStream *const sti = ffstream(st);
4264  AVIndexEntry *e_old = sti->index_entries;
4265  int nb_old = sti->nb_index_entries;
4266  const AVIndexEntry *e_old_end = e_old + nb_old;
4267  const AVIndexEntry *current = NULL;
4268  MOVTimeToSample *tts_data_old = msc->tts_data;
4269  int64_t tts_index_old = 0;
4270  int64_t tts_sample_old = 0;
4271  int64_t tts_count_old = msc->tts_count;
4272  int64_t edit_list_media_time = 0;
4273  int64_t edit_list_duration = 0;
4274  int64_t frame_duration = 0;
4275  int64_t edit_list_dts_counter = 0;
4276  int64_t edit_list_dts_entry_end = 0;
4277  int64_t edit_list_start_tts_sample = 0;
4278  int64_t curr_cts;
4279  int64_t curr_ctts = 0;
4280  int64_t empty_edits_sum_duration = 0;
4281  int64_t edit_list_index = 0;
4282  int64_t index;
4283  int flags;
4284  int64_t start_dts = 0;
4285  int64_t edit_list_start_encountered = 0;
4286  int64_t search_timestamp = 0;
4287  int64_t* frame_duration_buffer = NULL;
4288  int num_discarded_begin = 0;
4289  int first_non_zero_audio_edit = -1;
4290  int packet_skip_samples = 0;
4291  MOVIndexRange *current_index_range = NULL;
4292  int found_keyframe_after_edit = 0;
4293  int found_non_empty_edit = 0;
4294 
4295  if (!msc->elst_data || msc->elst_count <= 0 || nb_old <= 0) {
4296  return;
4297  }
4298 
4299  // allocate the index ranges array
4300  msc->index_ranges = av_malloc_array(msc->elst_count + 1,
4301  sizeof(msc->index_ranges[0]));
4302  if (!msc->index_ranges) {
4303  av_log(mov->fc, AV_LOG_ERROR, "Cannot allocate index ranges buffer\n");
4304  return;
4305  }
4306  msc->current_index_range = msc->index_ranges;
4307 
4308  // Clean AVStream from traces of old index
4309  sti->index_entries = NULL;
4311  sti->nb_index_entries = 0;
4312 
4313  // Clean time to sample fields of MOVStreamContext
4314  msc->tts_data = NULL;
4315  msc->tts_count = 0;
4316  msc->tts_index = 0;
4317  msc->tts_sample = 0;
4318  msc->tts_allocated_size = 0;
4319 
4320  // Reinitialize min_corrected_pts so that it can be computed again.
4321  msc->min_corrected_pts = -1;
4322 
4323  // If the dts_shift is positive (in case of negative ctts values in mov),
4324  // then negate the DTS by dts_shift
4325  if (msc->dts_shift > 0) {
4326  edit_list_dts_entry_end -= msc->dts_shift;
4327  av_log(mov->fc, AV_LOG_DEBUG, "Shifting DTS by %d because of negative CTTS.\n", msc->dts_shift);
4328  }
4329 
4330  start_dts = edit_list_dts_entry_end;
4331 
4332  while (get_edit_list_entry(mov, msc, edit_list_index, &edit_list_media_time,
4333  &edit_list_duration, mov->time_scale)) {
4334  av_log(mov->fc, AV_LOG_DEBUG, "Processing st: %d, edit list %"PRId64" - media time: %"PRId64", duration: %"PRId64"\n",
4335  st->index, edit_list_index, edit_list_media_time, edit_list_duration);
4336  edit_list_index++;
4337  edit_list_dts_counter = edit_list_dts_entry_end;
4338  edit_list_dts_entry_end = av_sat_add64(edit_list_dts_entry_end, edit_list_duration);
4339  if (edit_list_dts_entry_end == INT64_MAX) {
4340  av_log(mov->fc, AV_LOG_ERROR, "Cannot calculate dts entry length with duration %"PRId64"\n",
4341  edit_list_duration);
4342  break;
4343  }
4344  num_discarded_begin = 0;
4345  if (!found_non_empty_edit && edit_list_media_time == -1) {
4346  empty_edits_sum_duration += edit_list_duration;
4347  continue;
4348  }
4349  found_non_empty_edit = 1;
4350 
4351  // If we encounter a non-negative edit list reset the skip_samples/start_pad fields and set them
4352  // according to the edit list below.
4353  if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
4354  if (first_non_zero_audio_edit < 0) {
4355  first_non_zero_audio_edit = 1;
4356  } else {
4357  first_non_zero_audio_edit = 0;
4358  }
4359 
4360  if (first_non_zero_audio_edit > 0)
4361  sti->skip_samples = msc->start_pad = 0;
4362  }
4363 
4364  // While reordering frame index according to edit list we must handle properly
4365  // the scenario when edit list entry starts from none key frame.
4366  // We find closest previous key frame and preserve it and consequent frames in index.
4367  // All frames which are outside edit list entry time boundaries will be dropped after decoding.
4368  search_timestamp = edit_list_media_time;
4369  if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
4370  // Audio decoders like AAC need need a decoder delay samples previous to the current sample,
4371  // to correctly decode this frame. Hence for audio we seek to a frame 1 sec. before the
4372  // edit_list_media_time to cover the decoder delay.
4373  search_timestamp = FFMAX(search_timestamp - msc->time_scale, e_old[0].timestamp);
4374  }
4375 
4376  if (find_prev_closest_index(st, e_old, nb_old, tts_data_old, tts_count_old, search_timestamp, 0,
4377  &index, &tts_index_old, &tts_sample_old) < 0) {
4378  av_log(mov->fc, AV_LOG_WARNING,
4379  "st: %d edit list: %"PRId64" Missing key frame while searching for timestamp: %"PRId64"\n",
4380  st->index, edit_list_index, search_timestamp);
4381  if (find_prev_closest_index(st, e_old, nb_old, tts_data_old, tts_count_old, search_timestamp, AVSEEK_FLAG_ANY,
4382  &index, &tts_index_old, &tts_sample_old) < 0) {
4383  av_log(mov->fc, AV_LOG_WARNING,
4384  "st: %d edit list %"PRId64" Cannot find an index entry before timestamp: %"PRId64".\n",
4385  st->index, edit_list_index, search_timestamp);
4386  index = 0;
4387  tts_index_old = 0;
4388  tts_sample_old = 0;
4389  }
4390  }
4391  current = e_old + index;
4392  edit_list_start_tts_sample = tts_sample_old;
4393 
4394  // Iterate over index and arrange it according to edit list
4395  edit_list_start_encountered = 0;
4396  found_keyframe_after_edit = 0;
4397  for (; current < e_old_end; current++, index++) {
4398  // check if frame outside edit list mark it for discard
4399  frame_duration = (current + 1 < e_old_end) ?
4400  ((current + 1)->timestamp - current->timestamp) : edit_list_duration;
4401 
4402  flags = current->flags;
4403 
4404  // frames (pts) before or after edit list
4405  curr_cts = current->timestamp + msc->dts_shift;
4406  curr_ctts = 0;
4407 
4408  if (tts_data_old && tts_index_old < tts_count_old) {
4409  curr_ctts = tts_data_old[tts_index_old].offset;
4410  av_log(mov->fc, AV_LOG_TRACE, "stts: %"PRId64" ctts: %"PRId64", tts_index: %"PRId64", tts_count: %"PRId64"\n",
4411  curr_cts, curr_ctts, tts_index_old, tts_count_old);
4412  curr_cts += curr_ctts;
4413  tts_sample_old++;
4414  if (tts_sample_old == tts_data_old[tts_index_old].count) {
4415  if (add_tts_entry(&msc->tts_data, &msc->tts_count,
4416  &msc->tts_allocated_size,
4417  tts_data_old[tts_index_old].count - edit_list_start_tts_sample,
4418  tts_data_old[tts_index_old].offset, tts_data_old[tts_index_old].duration) == -1) {
4419  av_log(mov->fc, AV_LOG_ERROR, "Cannot add Time To Sample entry %"PRId64" - {%"PRId64", %d}\n",
4420  tts_index_old,
4421  tts_data_old[tts_index_old].count - edit_list_start_tts_sample,
4422  tts_data_old[tts_index_old].offset);
4423  break;
4424  }
4425  tts_index_old++;
4426  tts_sample_old = 0;
4427  edit_list_start_tts_sample = 0;
4428  }
4429  }
4430 
4431  if (curr_cts < edit_list_media_time || curr_cts >= (edit_list_duration + edit_list_media_time)) {
4433  curr_cts < edit_list_media_time && curr_cts + frame_duration > edit_list_media_time &&
4434  first_non_zero_audio_edit > 0) {
4435  packet_skip_samples = edit_list_media_time - curr_cts;
4436  sti->skip_samples += packet_skip_samples;
4437 
4438  // Shift the index entry timestamp by packet_skip_samples to be correct.
4439  edit_list_dts_counter -= packet_skip_samples;
4440  if (edit_list_start_encountered == 0) {
4441  edit_list_start_encountered = 1;
4442  // Make timestamps strictly monotonically increasing for audio, by rewriting timestamps for
4443  // discarded packets.
4444  if (frame_duration_buffer) {
4445  fix_index_entry_timestamps(st, sti->nb_index_entries, edit_list_dts_counter,
4446  frame_duration_buffer, num_discarded_begin);
4447  av_freep(&frame_duration_buffer);
4448  }
4449  }
4450 
4451  av_log(mov->fc, AV_LOG_DEBUG, "skip %d audio samples from curr_cts: %"PRId64"\n", packet_skip_samples, curr_cts);
4452  } else {
4454  av_log(mov->fc, AV_LOG_DEBUG, "drop a frame at curr_cts: %"PRId64" @ %"PRId64"\n", curr_cts, index);
4455 
4456  if (edit_list_start_encountered == 0) {
4457  num_discarded_begin++;
4458  frame_duration_buffer = av_realloc(frame_duration_buffer,
4459  num_discarded_begin * sizeof(int64_t));
4460  if (!frame_duration_buffer) {
4461  av_log(mov->fc, AV_LOG_ERROR, "Cannot reallocate frame duration buffer\n");
4462  break;
4463  }
4464  frame_duration_buffer[num_discarded_begin - 1] = frame_duration;
4465 
4466  // Increment skip_samples for the first non-zero audio edit list
4467  if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
4468  first_non_zero_audio_edit > 0 && st->codecpar->codec_id != AV_CODEC_ID_VORBIS) {
4469  sti->skip_samples += frame_duration;
4470  }
4471  }
4472  }
4473  } else {
4474  if (msc->min_corrected_pts < 0) {
4475  msc->min_corrected_pts = edit_list_dts_counter + curr_ctts + msc->dts_shift;
4476  } else {
4477  msc->min_corrected_pts = FFMIN(msc->min_corrected_pts, edit_list_dts_counter + curr_ctts + msc->dts_shift);
4478  }
4479  if (edit_list_start_encountered == 0) {
4480  edit_list_start_encountered = 1;
4481  // Make timestamps strictly monotonically increasing by rewriting timestamps for
4482  // discarded packets.
4483  if (frame_duration_buffer) {
4484  fix_index_entry_timestamps(st, sti->nb_index_entries, edit_list_dts_counter,
4485  frame_duration_buffer, num_discarded_begin);
4486  av_freep(&frame_duration_buffer);
4487  }
4488  }
4489  }
4490 
4491  if (add_index_entry(st, current->pos, edit_list_dts_counter, current->size,
4492  current->min_distance, flags) == -1) {
4493  av_log(mov->fc, AV_LOG_ERROR, "Cannot add index entry\n");
4494  break;
4495  }
4496 
4497  // Update the index ranges array
4498  if (!current_index_range || index != current_index_range->end) {
4499  current_index_range = current_index_range ? current_index_range + 1
4500  : msc->index_ranges;
4501  current_index_range->start = index;
4502  }
4503  current_index_range->end = index + 1;
4504 
4505  // Only start incrementing DTS in frame_duration amounts, when we encounter a frame in edit list.
4506  if (edit_list_start_encountered > 0) {
4507  edit_list_dts_counter = edit_list_dts_counter + frame_duration;
4508  }
4509 
4510  // Break when found first key frame after edit entry completion
4511  if ((curr_cts + frame_duration >= (edit_list_duration + edit_list_media_time)) &&
4513  if (msc->ctts_count) {
4514  // If we have CTTS and this is the first keyframe after edit elist,
4515  // wait for one more, because there might be trailing B-frames after this I-frame
4516  // that do belong to the edit.
4517  if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO && found_keyframe_after_edit == 0) {
4518  found_keyframe_after_edit = 1;
4519  continue;
4520  }
4521  if (tts_sample_old != 0) {
4522  if (add_tts_entry(&msc->tts_data, &msc->tts_count,
4523  &msc->tts_allocated_size,
4524  tts_sample_old - edit_list_start_tts_sample,
4525  tts_data_old[tts_index_old].offset, tts_data_old[tts_index_old].duration) == -1) {
4526  av_log(mov->fc, AV_LOG_ERROR, "Cannot add Time To Sample entry %"PRId64" - {%"PRId64", %d}\n",
4527  tts_index_old, tts_sample_old - edit_list_start_tts_sample,
4528  tts_data_old[tts_index_old].offset);
4529  break;
4530  }
4531  }
4532  }
4533  break;
4534  }
4535  }
4536  }
4537  // If there are empty edits, then msc->min_corrected_pts might be positive
4538  // intentionally. So we subtract the sum duration of empty edits here.
4539  msc->min_corrected_pts -= empty_edits_sum_duration;
4540 
4541  // If the minimum pts turns out to be greater than zero after fixing the index, then we subtract the
4542  // dts by that amount to make the first pts zero.
4543  if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
4544  if (msc->min_corrected_pts > 0) {
4545  av_log(mov->fc, AV_LOG_DEBUG, "Offset DTS by %"PRId64" to make first pts zero.\n", msc->min_corrected_pts);
4546  for (int i = 0; i < sti->nb_index_entries; ++i)
4548  }
4549  }
4550  // Start time should be equal to zero or the duration of any empty edits.
4551  st->start_time = empty_edits_sum_duration;
4552 
4553  // Update av stream length, if it ends up shorter than the track's media duration
4554  st->duration = FFMIN(st->duration, edit_list_dts_entry_end - start_dts);
4555  msc->start_pad = sti->skip_samples;
4556 
4557  // Free the old index and the old CTTS structures
4558  av_free(e_old);
4559  av_free(tts_data_old);
4560  av_freep(&frame_duration_buffer);
4561 
4562  // Null terminate the index ranges array
4563  current_index_range = current_index_range ? current_index_range + 1
4564  : msc->index_ranges;
4565  current_index_range->start = 0;
4566  current_index_range->end = 0;
4567  msc->current_index = msc->index_ranges[0].start;
4568 }
4569 
4570 static uint32_t get_sgpd_sync_index(const MOVStreamContext *sc, int nal_unit_type)
4571 {
4572  for (uint32_t i = 0; i < sc->sgpd_sync_count; i++)
4573  if (sc->sgpd_sync[i] == nal_unit_type)
4574  return i + 1;
4575  return 0;
4576 }
4577 
4579 {
4580  int k;
4581  int sample_id = 0;
4582  uint32_t cra_index;
4583  MOVStreamContext *sc = st->priv_data;
4584 
4585  if (st->codecpar->codec_id != AV_CODEC_ID_HEVC || !sc->sync_group_count)
4586  return 0;
4587 
4588  /* Build an unrolled index of the samples */
4589  sc->sample_offsets_count = 0;
4590  for (uint32_t i = 0; i < sc->ctts_count; i++) {
4591  if (sc->ctts_data[i].count > INT_MAX - sc->sample_offsets_count)
4592  return AVERROR(ENOMEM);
4593  sc->sample_offsets_count += sc->ctts_data[i].count;
4594  }
4595  av_freep(&sc->sample_offsets);
4597  if (!sc->sample_offsets)
4598  return AVERROR(ENOMEM);
4599  k = 0;
4600  for (uint32_t i = 0; i < sc->ctts_count; i++)
4601  for (int j = 0; j < sc->ctts_data[i].count; j++)
4602  sc->sample_offsets[k++] = sc->ctts_data[i].offset;
4603 
4604  /* The following HEVC NAL type reveal the use of open GOP sync points
4605  * (TODO: BLA types may also be concerned) */
4606  cra_index = get_sgpd_sync_index(sc, HEVC_NAL_CRA_NUT); /* Clean Random Access */
4607  if (!cra_index)
4608  return 0;
4609 
4610  /* Build a list of open-GOP key samples */
4611  sc->open_key_samples_count = 0;
4612  for (uint32_t i = 0; i < sc->sync_group_count; i++)
4613  if (sc->sync_group[i].index == cra_index) {
4614  if (sc->sync_group[i].count > INT_MAX - sc->open_key_samples_count)
4615  return AVERROR(ENOMEM);
4617  }
4618  av_freep(&sc->open_key_samples);
4620  if (!sc->open_key_samples)
4621  return AVERROR(ENOMEM);
4622  k = 0;
4623  for (uint32_t i = 0; i < sc->sync_group_count; i++) {
4624  const MOVSbgp *sg = &sc->sync_group[i];
4625  if (sg->index == cra_index)
4626  for (uint32_t j = 0; j < sg->count; j++)
4627  sc->open_key_samples[k++] = sample_id;
4628  if (sg->count > INT_MAX - sample_id)
4629  return AVERROR_PATCHWELCOME;
4630  sample_id += sg->count;
4631  }
4632 
4633  /* Identify the minimal time step between samples */
4634  sc->min_sample_duration = UINT_MAX;
4635  for (uint32_t i = 0; i < sc->stts_count; i++)
4637 
4638  return 0;
4639 }
4640 
4641 #define MOV_MERGE_CTTS 1
4642 #define MOV_MERGE_STTS 2
4643 /*
4644  * Merge stts and ctts arrays into a new combined array.
4645  * stts_count and ctts_count may be left untouched as they will be
4646  * used to check for the presence of either of them.
4647  */
4648 static int mov_merge_tts_data(MOVContext *mov, AVStream *st, int flags)
4649 {
4650  MOVStreamContext *sc = st->priv_data;
4651  int ctts = sc->ctts_data && (flags & MOV_MERGE_CTTS);
4652  int stts = sc->stts_data && (flags & MOV_MERGE_STTS);
4653  int idx = 0;
4654 
4655  if (!sc->ctts_data && !sc->stts_data)
4656  return 0;
4657  // Expand time to sample entries such that we have a 1-1 mapping with samples
4658  if (!sc->sample_count || sc->sample_count >= UINT_MAX / sizeof(*sc->tts_data))
4659  return -1;
4660 
4661  if (ctts) {
4663  sc->sample_count * sizeof(*sc->tts_data));
4664  if (!sc->tts_data)
4665  return -1;
4666 
4667  memset(sc->tts_data, 0, sc->tts_allocated_size);
4668 
4669  for (int i = 0; i < sc->ctts_count &&
4670  idx < sc->sample_count; i++)
4671  for (int j = 0; j < sc->ctts_data[i].count &&
4672  idx < sc->sample_count; j++) {
4673  sc->tts_data[idx].offset = sc->ctts_data[i].offset;
4674  sc->tts_data[idx++].count = 1;
4675  }
4676 
4677  sc->tts_count = idx;
4678  } else
4679  sc->ctts_count = 0;
4680  av_freep(&sc->ctts_data);
4681  sc->ctts_allocated_size = 0;
4682 
4683  idx = 0;
4684  if (stts) {
4686  sc->sample_count * sizeof(*sc->tts_data));
4687  if (!tts_data)
4688  return -1;
4689 
4690  if (!sc->tts_data)
4691  memset(tts_data, 0, sc->tts_allocated_size);
4692  sc->tts_data = tts_data;
4693 
4694  for (int i = 0; i < sc->stts_count &&
4695  idx < sc->sample_count; i++)
4696  for (int j = 0; j < sc->stts_data[i].count &&
4697  idx < sc->sample_count; j++) {
4698  sc->tts_data[idx].duration = sc->stts_data[i].duration;
4699  sc->tts_data[idx++].count = 1;
4700  }
4701 
4702  sc->tts_count = FFMAX(sc->tts_count, idx);
4703  } else
4704  sc->stts_count = 0;
4705  av_freep(&sc->stts_data);
4706  sc->stts_allocated_size = 0;
4707 
4708  return 0;
4709 }
4710 
4711 static void mov_build_index(MOVContext *mov, AVStream *st)
4712 {
4713  MOVStreamContext *sc = st->priv_data;
4714  FFStream *const sti = ffstream(st);
4715  int64_t current_offset;
4716  int64_t current_dts = 0;
4717  unsigned int stts_index = 0;
4718  unsigned int stsc_index = 0;
4719  unsigned int stss_index = 0;
4720  unsigned int stps_index = 0;
4721  unsigned int i, j;
4722  uint64_t stream_size = 0;
4723 
4724  int ret = build_open_gop_key_points(st);
4725  if (ret < 0)
4726  return;
4727 
4728  if (sc->elst_count) {
4729  int i, edit_start_index = 0, multiple_edits = 0;
4730  int64_t empty_duration = 0; // empty duration of the first edit list entry
4731  int64_t start_time = 0; // start time of the media
4732 
4733  for (i = 0; i < sc->elst_count; i++) {
4734  const MOVElst *e = &sc->elst_data[i];
4735  if (i == 0 && e->time == -1) {
4736  /* if empty, the first entry is the start time of the stream
4737  * relative to the presentation itself */
4738  empty_duration = e->duration;
4739  edit_start_index = 1;
4740  } else if (i == edit_start_index && e->time >= 0) {
4741  start_time = e->time;
4742  } else {
4743  multiple_edits = 1;
4744  }
4745  }
4746 
4747  if (multiple_edits && !mov->advanced_editlist) {
4749  av_log(mov->fc, AV_LOG_WARNING, "multiple edit list entries, "
4750  "not supported in fragmented MP4 files\n");
4751  else
4752  av_log(mov->fc, AV_LOG_WARNING, "multiple edit list entries, "
4753  "Use -advanced_editlist to correctly decode otherwise "
4754  "a/v desync might occur\n");
4755  }
4756 
4757  /* adjust first dts according to edit list */
4758  if ((empty_duration || start_time) && mov->time_scale > 0) {
4759  if (empty_duration)
4760  empty_duration = av_rescale(empty_duration, sc->time_scale, mov->time_scale);
4761 
4762  if (av_sat_sub64(start_time, empty_duration) != start_time - (uint64_t)empty_duration)
4763  av_log(mov->fc, AV_LOG_WARNING, "start_time - empty_duration is not representable\n");
4764 
4765  sc->time_offset = start_time - (uint64_t)empty_duration;
4767  if (!mov->advanced_editlist)
4768  current_dts = -sc->time_offset;
4769  }
4770 
4771  if (!multiple_edits && !mov->advanced_editlist &&
4774  (AVRational){1, st->codecpar->sample_rate});
4775  }
4776 
4777  /* only use old uncompressed audio chunk demuxing when stts specifies it */
4778  if (!(st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
4779  sc->stts_count == 1 && sc->stts_data && sc->stts_data[0].duration == 1)) {
4780  unsigned int current_sample = 0;
4781  unsigned int stts_sample = 0;
4782  unsigned int sample_size;
4783  unsigned int distance = 0;
4784  unsigned int rap_group_index = 0;
4785  unsigned int rap_group_sample = 0;
4786  int rap_group_present = sc->rap_group_count && sc->rap_group;
4787  int key_off = (sc->keyframe_count && sc->keyframes[0] > 0) || (sc->stps_count && sc->stps_data[0] > 0);
4788 
4789  current_dts -= sc->dts_shift;
4790 
4791  if (!sc->sample_count || sti->nb_index_entries || sc->tts_count)
4792  return;
4793  if (sc->sample_count >= UINT_MAX / sizeof(*sti->index_entries) - sti->nb_index_entries)
4794  return;
4795  if (av_reallocp_array(&sti->index_entries,
4796  sti->nb_index_entries + sc->sample_count,
4797  sizeof(*sti->index_entries)) < 0) {
4798  sti->nb_index_entries = 0;
4799  return;
4800  }
4801  sti->index_entries_allocated_size = (sti->nb_index_entries + sc->sample_count) * sizeof(*sti->index_entries);
4802 
4804  if (ret < 0)
4805  return;
4806 
4807  for (i = 0; i < sc->chunk_count; i++) {
4808  int64_t next_offset = i+1 < sc->chunk_count ? sc->chunk_offsets[i+1] : INT64_MAX;
4809  current_offset = sc->chunk_offsets[i];
4810  while (mov_stsc_index_valid(stsc_index, sc->stsc_count) &&
4811  i + 1 == sc->stsc_data[stsc_index + 1].first)
4812  stsc_index++;
4813 
4814  if (next_offset > current_offset && sc->sample_size>0 && sc->sample_size < sc->stsz_sample_size &&
4815  sc->stsc_data[stsc_index].count * (int64_t)sc->stsz_sample_size > next_offset - current_offset) {
4816  av_log(mov->fc, AV_LOG_WARNING, "STSZ sample size %d invalid (too large), ignoring\n", sc->stsz_sample_size);
4817  sc->stsz_sample_size = sc->sample_size;
4818  }
4819  if (sc->stsz_sample_size>0 && sc->stsz_sample_size < sc->sample_size) {
4820  av_log(mov->fc, AV_LOG_WARNING, "STSZ sample size %d invalid (too small), ignoring\n", sc->stsz_sample_size);
4821  sc->stsz_sample_size = sc->sample_size;
4822  }
4823 
4824  for (j = 0; j < sc->stsc_data[stsc_index].count; j++) {
4825  int keyframe = 0;
4826  if (current_sample >= sc->sample_count) {
4827  av_log(mov->fc, AV_LOG_ERROR, "wrong sample count\n");
4828  return;
4829  }
4830 
4831  if (!sc->keyframe_absent && (!sc->keyframe_count || current_sample+key_off == sc->keyframes[stss_index])) {
4832  keyframe = 1;
4833  if (stss_index + 1 < sc->keyframe_count)
4834  stss_index++;
4835  } else if (sc->stps_count && current_sample+key_off == sc->stps_data[stps_index]) {
4836  keyframe = 1;
4837  if (stps_index + 1 < sc->stps_count)
4838  stps_index++;
4839  }
4840  if (rap_group_present && rap_group_index < sc->rap_group_count) {
4841  if (sc->rap_group[rap_group_index].index > 0)
4842  keyframe = 1;
4843  if (++rap_group_sample == sc->rap_group[rap_group_index].count) {
4844  rap_group_sample = 0;
4845  rap_group_index++;
4846  }
4847  }
4848  if (sc->keyframe_absent
4849  && !sc->stps_count
4850  && !rap_group_present
4851  && (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO || (i==0 && j==0)))
4852  keyframe = 1;
4853  if (keyframe)
4854  distance = 0;
4855  sample_size = sc->stsz_sample_size > 0 ? sc->stsz_sample_size : sc->sample_sizes[current_sample];
4856  if (current_offset > INT64_MAX - sample_size) {
4857  av_log(mov->fc, AV_LOG_ERROR, "Current offset %"PRId64" or sample size %u is too large\n",
4858  current_offset,
4859  sample_size);
4860  return;
4861  }
4862 
4863  if (sc->pseudo_stream_id == -1 ||
4864  sc->stsc_data[stsc_index].id - 1 == sc->pseudo_stream_id) {
4865  AVIndexEntry *e;
4866  if (sample_size > 0x3FFFFFFF) {
4867  av_log(mov->fc, AV_LOG_ERROR, "Sample size %u is too large\n", sample_size);
4868  return;
4869  }
4870  e = &sti->index_entries[sti->nb_index_entries++];
4871  e->pos = current_offset;
4872  e->timestamp = current_dts;
4873  e->size = sample_size;
4874  e->min_distance = distance;
4875  e->flags = keyframe ? AVINDEX_KEYFRAME : 0;
4876  av_log(mov->fc, AV_LOG_TRACE, "AVIndex stream %d, sample %u, offset %"PRIx64", dts %"PRId64", "
4877  "size %u, distance %u, keyframe %d\n", st->index, current_sample,
4878  current_offset, current_dts, sample_size, distance, keyframe);
4879  if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && sti->nb_index_entries < 100)
4880  ff_rfps_add_frame(mov->fc, st, current_dts);
4881  }
4882 
4883  current_offset += sample_size;
4884  stream_size += sample_size;
4885 
4886  current_dts += sc->tts_data[stts_index].duration;
4887 
4888  distance++;
4889  stts_sample++;
4890  current_sample++;
4891  if (stts_index + 1 < sc->tts_count && stts_sample == sc->tts_data[stts_index].count) {
4892  stts_sample = 0;
4893  stts_index++;
4894  }
4895  }
4896  }
4897  if (st->duration > 0)
4898  st->codecpar->bit_rate = stream_size*8*sc->time_scale/st->duration;
4899  } else {
4900  unsigned chunk_samples, total = 0;
4901 
4902  if (!sc->chunk_count || sc->tts_count)
4903  return;
4904 
4905  // compute total chunk count
4906  for (i = 0; i < sc->stsc_count; i++) {
4907  unsigned count, chunk_count;
4908 
4909  chunk_samples = sc->stsc_data[i].count;
4910  if (i != sc->stsc_count - 1 &&
4911  sc->samples_per_frame && chunk_samples % sc->samples_per_frame) {
4912  av_log(mov->fc, AV_LOG_ERROR, "error unaligned chunk\n");
4913  return;
4914  }
4915 
4916  if (sc->samples_per_frame >= 160) { // gsm
4917  count = chunk_samples / sc->samples_per_frame;
4918  } else if (sc->samples_per_frame > 1) {
4919  unsigned samples = (1024/sc->samples_per_frame)*sc->samples_per_frame;
4920  count = (chunk_samples+samples-1) / samples;
4921  } else {
4922  count = (chunk_samples+1023) / 1024;
4923  }
4924 
4925  if (mov_stsc_index_valid(i, sc->stsc_count))
4926  chunk_count = sc->stsc_data[i+1].first - sc->stsc_data[i].first;
4927  else
4928  chunk_count = sc->chunk_count - (sc->stsc_data[i].first - 1);
4929  total += chunk_count * count;
4930  }
4931 
4932  av_log(mov->fc, AV_LOG_TRACE, "chunk count %u\n", total);
4933  if (total >= UINT_MAX / sizeof(*sti->index_entries) - sti->nb_index_entries)
4934  return;
4935  if (av_reallocp_array(&sti->index_entries,
4936  sti->nb_index_entries + total,
4937  sizeof(*sti->index_entries)) < 0) {
4938  sti->nb_index_entries = 0;
4939  return;
4940  }
4941  sti->index_entries_allocated_size = (sti->nb_index_entries + total) * sizeof(*sti->index_entries);
4942 
4943  // populate index
4944  for (i = 0; i < sc->chunk_count; i++) {
4945  current_offset = sc->chunk_offsets[i];
4946  if (mov_stsc_index_valid(stsc_index, sc->stsc_count) &&
4947  i + 1 == sc->stsc_data[stsc_index + 1].first)
4948  stsc_index++;
4949  chunk_samples = sc->stsc_data[stsc_index].count;
4950 
4951  while (chunk_samples > 0) {
4952  AVIndexEntry *e;
4953  unsigned size, samples;
4954 
4955  if (sc->samples_per_frame > 1 && !sc->bytes_per_frame) {
4957  "Zero bytes per frame, but %d samples per frame",
4958  sc->samples_per_frame);
4959  return;
4960  }
4961 
4962  if (sc->samples_per_frame >= 160) { // gsm
4963  samples = sc->samples_per_frame;
4964  size = sc->bytes_per_frame;
4965  } else {
4966  if (sc->samples_per_frame > 1) {
4967  samples = FFMIN((1024 / sc->samples_per_frame)*
4968  sc->samples_per_frame, chunk_samples);
4970  } else {
4971  samples = FFMIN(1024, chunk_samples);
4972  size = samples * sc->sample_size;
4973  }
4974  }
4975 
4976  if (sti->nb_index_entries >= total) {
4977  av_log(mov->fc, AV_LOG_ERROR, "wrong chunk count %u\n", total);
4978  return;
4979  }
4980  if (size > 0x3FFFFFFF) {
4981  av_log(mov->fc, AV_LOG_ERROR, "Sample size %u is too large\n", size);
4982  return;
4983  }
4984  e = &sti->index_entries[sti->nb_index_entries++];
4985  e->pos = current_offset;
4986  e->timestamp = current_dts;
4987  e->size = size;
4988  e->min_distance = 0;
4989  e->flags = AVINDEX_KEYFRAME;
4990  av_log(mov->fc, AV_LOG_TRACE, "AVIndex stream %d, chunk %u, offset %"PRIx64", dts %"PRId64", "
4991  "size %u, duration %u\n", st->index, i, current_offset, current_dts,
4992  size, samples);
4993 
4994  current_offset += size;
4995  current_dts += samples;
4996  chunk_samples -= samples;
4997  }
4998  }
4999 
5001  if (ret < 0)
5002  return;
5003  }
5004 
5005  if (!mov->ignore_editlist && mov->advanced_editlist) {
5006  // Fix index according to edit lists.
5007  mov_fix_index(mov, st);
5008  }
5009 
5010  // Update start time of the stream.
5012  st->start_time = sti->index_entries[0].timestamp + sc->dts_shift;
5013  if (sc->tts_data) {
5014  st->start_time += sc->tts_data[0].offset;
5015  }
5016  }
5017 
5018  mov_estimate_video_delay(mov, st);
5019 }
5020 
5021 static int test_same_origin(const char *src, const char *ref) {
5022  char src_proto[64];
5023  char ref_proto[64];
5024  char src_auth[256];
5025  char ref_auth[256];
5026  char src_host[256];
5027  char ref_host[256];
5028  int src_port=-1;
5029  int ref_port=-1;
5030 
5031  av_url_split(src_proto, sizeof(src_proto), src_auth, sizeof(src_auth), src_host, sizeof(src_host), &src_port, NULL, 0, src);
5032  av_url_split(ref_proto, sizeof(ref_proto), ref_auth, sizeof(ref_auth), ref_host, sizeof(ref_host), &ref_port, NULL, 0, ref);
5033 
5034  if (strlen(src) == 0) {
5035  return -1;
5036  } else if (strlen(src_auth) + 1 >= sizeof(src_auth) ||
5037  strlen(ref_auth) + 1 >= sizeof(ref_auth) ||
5038  strlen(src_host) + 1 >= sizeof(src_host) ||
5039  strlen(ref_host) + 1 >= sizeof(ref_host)) {
5040  return 0;
5041  } else if (strcmp(src_proto, ref_proto) ||
5042  strcmp(src_auth, ref_auth) ||
5043  strcmp(src_host, ref_host) ||
5044  src_port != ref_port) {
5045  return 0;
5046  } else
5047  return 1;
5048 }
5049 
5050 static int mov_open_dref(MOVContext *c, AVIOContext **pb, const char *src, MOVDref *ref)
5051 {
5052  /* try relative path, we do not try the absolute because it can leak information about our
5053  system to an attacker */
5054  if (ref->nlvl_to > 0 && ref->nlvl_from > 0) {
5055  char filename[1025];
5056  const char *src_path;
5057  int i, l;
5058 
5059  /* find a source dir */
5060  src_path = strrchr(src, '/');
5061  if (src_path)
5062  src_path++;
5063  else
5064  src_path = src;
5065 
5066  /* find a next level down to target */
5067  for (i = 0, l = strlen(ref->path) - 1; l >= 0; l--)
5068  if (ref->path[l] == '/') {
5069  if (i == ref->nlvl_to - 1)
5070  break;
5071  else
5072  i++;
5073  }
5074 
5075  /* compose filename if next level down to target was found */
5076  if (i == ref->nlvl_to - 1 && src_path - src < sizeof(filename)) {
5077  memcpy(filename, src, src_path - src);
5078  filename[src_path - src] = 0;
5079 
5080  for (i = 1; i < ref->nlvl_from; i++)
5081  av_strlcat(filename, "../", sizeof(filename));
5082 
5083  av_strlcat(filename, ref->path + l + 1, sizeof(filename));
5084  if (!c->use_absolute_path) {
5085  int same_origin = test_same_origin(src, filename);
5086 
5087  if (!same_origin) {
5088  av_log(c->fc, AV_LOG_ERROR,
5089  "Reference with mismatching origin, %s not tried for security reasons, "
5090  "set demuxer option use_absolute_path to allow it anyway\n",
5091  ref->path);
5092  return AVERROR(ENOENT);
5093  }
5094 
5095  if (strstr(ref->path + l + 1, "..") ||
5096  strstr(ref->path + l + 1, ":") ||
5097  (ref->nlvl_from > 1 && same_origin < 0) ||
5098  (filename[0] == '/' && src_path == src))
5099  return AVERROR(ENOENT);
5100  }
5101 
5102  if (strlen(filename) + 1 == sizeof(filename))
5103  return AVERROR(ENOENT);
5104  if (!c->fc->io_open(c->fc, pb, filename, AVIO_FLAG_READ, NULL))
5105  return 0;
5106  }
5107  } else if (c->use_absolute_path) {
5108  av_log(c->fc, AV_LOG_WARNING, "Using absolute path on user request, "
5109  "this is a possible security issue\n");
5110  if (!c->fc->io_open(c->fc, pb, ref->path, AVIO_FLAG_READ, NULL))
5111  return 0;
5112  } else {
5113  av_log(c->fc, AV_LOG_ERROR,
5114  "Absolute path %s not tried for security reasons, "
5115  "set demuxer option use_absolute_path to allow absolute paths\n",
5116  ref->path);
5117  }
5118 
5119  return AVERROR(ENOENT);
5120 }
5121 
5123 {
5124  if (sc->time_scale <= 0) {
5125  av_log(c->fc, AV_LOG_WARNING, "stream %d, timescale not set\n", sc->ffindex);
5126  sc->time_scale = c->time_scale;
5127  if (sc->time_scale <= 0)
5128  sc->time_scale = 1;
5129  }
5130 }
5131 
5132 #if CONFIG_IAMFDEC
5133 static int mov_update_iamf_streams(MOVContext *c, const AVStream *st)
5134 {
5135  const MOVStreamContext *sc = st->priv_data;
5136  const IAMFContext *iamf = &sc->iamf->iamf;
5137 
5138  for (int i = 0; i < iamf->nb_audio_elements; i++) {
5139  const AVStreamGroup *stg = NULL;
5140 
5141  for (int j = 0; j < c->fc->nb_stream_groups; j++)
5142  if (c->fc->stream_groups[j]->id == iamf->audio_elements[i]->audio_element_id)
5143  stg = c->fc->stream_groups[j];
5144  av_assert0(stg);
5145 
5146  for (int j = 0; j < stg->nb_streams; j++) {
5147  const FFStream *sti = cffstream(st);
5148  AVStream *out = stg->streams[j];
5149  FFStream *out_sti = ffstream(stg->streams[j]);
5150 
5151  out->codecpar->bit_rate = 0;
5152 
5153  if (out == st)
5154  continue;
5155 
5156  out->time_base = st->time_base;
5157  out->start_time = st->start_time;
5158  out->duration = st->duration;
5159  out->nb_frames = st->nb_frames;
5160  out->discard = st->discard;
5161 
5162  av_assert0(!out_sti->index_entries);
5164  if (!out_sti->index_entries)
5165  return AVERROR(ENOMEM);
5166 
5168  out_sti->nb_index_entries = sti->nb_index_entries;
5169  out_sti->skip_samples = sti->skip_samples;
5170  memcpy(out_sti->index_entries, sti->index_entries, sti->index_entries_allocated_size);
5171  }
5172  }
5173 
5174  return 0;
5175 }
5176 #endif
5177 
5178 static int sanity_checks(void *log_obj, MOVStreamContext *sc, int index)
5179 {
5180  if ((sc->chunk_count && (!sc->stts_count || !sc->stsc_count ||
5181  (!sc->sample_size && !sc->sample_count))) ||
5182  (sc->sample_count && (!sc->chunk_count ||
5183  (!sc->sample_size && !sc->sample_sizes)))) {
5184  av_log(log_obj, AV_LOG_ERROR, "stream %d, missing mandatory atoms, broken header\n",
5185  index);
5186  return 1;
5187  }
5188 
5189  if (sc->stsc_count && sc->stsc_data[ sc->stsc_count - 1 ].first > sc->chunk_count) {
5190  av_log(log_obj, AV_LOG_ERROR, "stream %d, contradictionary STSC and STCO\n",
5191  index);
5192  return 2;
5193  }
5194  return 0;
5195 }
5196 
5198 {
5199  AVStream *st;
5200  MOVStreamContext *sc;
5201  int ret;
5202 
5203  st = avformat_new_stream(c->fc, NULL);
5204  if (!st) return AVERROR(ENOMEM);
5205  st->id = -1;
5206  sc = av_mallocz(sizeof(MOVStreamContext));
5207  if (!sc) return AVERROR(ENOMEM);
5208 
5209  st->priv_data = sc;
5211  sc->ffindex = st->index;
5212  c->trak_index = st->index;
5213  sc->tref_flags = 0;
5214  sc->tref_id = -1;
5215  sc->refcount = 1;
5216 
5217  if ((ret = mov_read_default(c, pb, atom)) < 0)
5218  return ret;
5219 
5220  c->trak_index = -1;
5221 
5222  // Here stsc refers to a chunk not described in stco. This is technically invalid,
5223  // but we can overlook it (clearing stsc) whenever stts_count == 0 (indicating no samples).
5224  if (!sc->chunk_count && !sc->stts_count && sc->stsc_count) {
5225  sc->stsc_count = 0;
5226  av_freep(&sc->stsc_data);
5227  }
5228 
5229  ret = sanity_checks(c->fc, sc, st->index);
5230  if (ret)
5231  return ret > 1 ? AVERROR_INVALIDDATA : 0;
5232 
5233  fix_timescale(c, sc);
5234 
5235  avpriv_set_pts_info(st, 64, 1, sc->time_scale);
5236 
5237  /*
5238  * Advanced edit list support does not work with fragemented MP4s, which
5239  * have stsc, stsz, stco, and stts with zero entries in the moov atom.
5240  * In these files, trun atoms may be streamed in.
5241  */
5242  if (!sc->stts_count && c->advanced_editlist) {
5243 
5244  av_log(c->fc, AV_LOG_VERBOSE, "advanced_editlist does not work with fragmented "
5245  "MP4. disabling.\n");
5246  c->advanced_editlist = 0;
5247  c->advanced_editlist_autodisabled = 1;
5248  }
5249 
5250  mov_build_index(c, st);
5251 
5252 #if CONFIG_IAMFDEC
5253  if (sc->iamf) {
5254  ret = mov_update_iamf_streams(c, st);
5255  if (ret < 0)
5256  return ret;
5257  }
5258 #endif
5259 
5260  if (sc->dref_id-1 < sc->drefs_count && sc->drefs[sc->dref_id-1].path) {
5261  MOVDref *dref = &sc->drefs[sc->dref_id - 1];
5262  if (c->enable_drefs) {
5263  if (mov_open_dref(c, &sc->pb, c->fc->url, dref) < 0)
5264  av_log(c->fc, AV_LOG_ERROR,
5265  "stream %d, error opening alias: path='%s', dir='%s', "
5266  "filename='%s', volume='%s', nlvl_from=%d, nlvl_to=%d\n",
5267  st->index, dref->path, dref->dir, dref->filename,
5268  dref->volume, dref->nlvl_from, dref->nlvl_to);
5269  } else {
5270  av_log(c->fc, AV_LOG_WARNING,
5271  "Skipped opening external track: "
5272  "stream %d, alias: path='%s', dir='%s', "
5273  "filename='%s', volume='%s', nlvl_from=%d, nlvl_to=%d."
5274  "Set enable_drefs to allow this.\n",
5275  st->index, dref->path, dref->dir, dref->filename,
5276  dref->volume, dref->nlvl_from, dref->nlvl_to);
5277  }
5278  } else {
5279  sc->pb = c->fc->pb;
5280  sc->pb_is_copied = 1;
5281  }
5282 
5283  if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
5284  int stts_constant = sc->stts_count && sc->tts_count;
5285  if (sc->h_spacing && sc->v_spacing)
5287  sc->h_spacing, sc->v_spacing, INT_MAX);
5288  if (!st->sample_aspect_ratio.num && st->codecpar->width && st->codecpar->height &&
5289  sc->height && sc->width &&
5290  (st->codecpar->width != sc->width || st->codecpar->height != sc->height)) {
5292  (int64_t)st->codecpar->height * sc->width,
5293  (int64_t)st->codecpar->width * sc->height, INT_MAX);
5294  }
5295 
5296 #if FF_API_R_FRAME_RATE
5297  for (unsigned int i = 1; sc->stts_count && i + 1 < sc->tts_count; i++) {
5298  if (sc->tts_data[i].duration == sc->tts_data[0].duration)
5299  continue;
5300  stts_constant = 0;
5301  }
5302  if (stts_constant)
5304  sc->time_scale, sc->tts_data[0].duration, INT_MAX);
5305 #endif
5306  }
5307 
5308 #if CONFIG_H261_DECODER || CONFIG_H263_DECODER || CONFIG_MPEG4_DECODER
5309  switch (st->codecpar->codec_id) {
5310 #if CONFIG_H261_DECODER
5311  case AV_CODEC_ID_H261:
5312 #endif
5313 #if CONFIG_H263_DECODER
5314  case AV_CODEC_ID_H263:
5315 #endif
5316 #if CONFIG_MPEG4_DECODER
5317  case AV_CODEC_ID_MPEG4:
5318 #endif
5319  st->codecpar->width = 0; /* let decoder init width/height */
5320  st->codecpar->height= 0;
5321  break;
5322  }
5323 #endif
5324 
5325  // If the duration of the mp3 packets is not constant, then they could need a parser
5326  if (st->codecpar->codec_id == AV_CODEC_ID_MP3
5327  && sc->time_scale == st->codecpar->sample_rate) {
5328  int stts_constant = 1;
5329  for (int i = 1; sc->stts_count && i < sc->tts_count; i++) {
5330  if (sc->tts_data[i].duration == sc->tts_data[0].duration)
5331  continue;
5332  stts_constant = 0;
5333  }
5334  if (!stts_constant)
5336  }
5337  /* Do not need those anymore. */
5338  av_freep(&sc->chunk_offsets);
5339  av_freep(&sc->sample_sizes);
5340  av_freep(&sc->keyframes);
5341  av_freep(&sc->stps_data);
5342  av_freep(&sc->elst_data);
5343  av_freep(&sc->rap_group);
5344  av_freep(&sc->sync_group);
5345  av_freep(&sc->sgpd_sync);
5346 
5347  return 0;
5348 }
5349 
5351 {
5352  int ret;
5353  c->itunes_metadata = 1;
5354  ret = mov_read_default(c, pb, atom);
5355  c->itunes_metadata = 0;
5356  return ret;
5357 }
5358 
5360 {
5361  uint32_t count;
5362  uint32_t i;
5363 
5364  if (atom.size < 8)
5365  return 0;
5366 
5367  avio_skip(pb, 4);
5368  count = avio_rb32(pb);
5369  atom.size -= 8;
5370  if (count >= UINT_MAX / sizeof(*c->meta_keys)) {
5371  av_log(c->fc, AV_LOG_ERROR,
5372  "The 'keys' atom with the invalid key count: %"PRIu32"\n", count);
5373  return AVERROR_INVALIDDATA;
5374  }
5375 
5376  c->meta_keys_count = count + 1;
5377  c->meta_keys = av_mallocz(c->meta_keys_count * sizeof(*c->meta_keys));
5378  if (!c->meta_keys)
5379  return AVERROR(ENOMEM);
5380 
5381  for (i = 1; i <= count; ++i) {
5382  uint32_t key_size = avio_rb32(pb);
5383  uint32_t type = avio_rl32(pb);
5384  if (key_size < 8 || key_size > atom.size) {
5385  av_log(c->fc, AV_LOG_ERROR,
5386  "The key# %"PRIu32" in meta has invalid size:"
5387  "%"PRIu32"\n", i, key_size);
5388  return AVERROR_INVALIDDATA;
5389  }
5390  atom.size -= key_size;
5391  key_size -= 8;
5392  if (type != MKTAG('m','d','t','a')) {
5393  avio_skip(pb, key_size);
5394  continue;
5395  }
5396  c->meta_keys[i] = av_mallocz(key_size + 1);
5397  if (!c->meta_keys[i])
5398  return AVERROR(ENOMEM);
5399  avio_read(pb, c->meta_keys[i], key_size);
5400  }
5401 
5402  return 0;
5403 }
5404 
5406 {
5407  int64_t end = av_sat_add64(avio_tell(pb), atom.size);
5408  uint8_t *key = NULL, *val = NULL, *mean = NULL;
5409  int i;
5410  int ret = 0;
5411  AVStream *st;
5412  MOVStreamContext *sc;
5413 
5414  if (c->fc->nb_streams < 1)
5415  return 0;
5416  st = c->fc->streams[c->fc->nb_streams-1];
5417  sc = st->priv_data;
5418 
5419  for (i = 0; i < 3; i++) {
5420  uint8_t **p;
5421  uint32_t len, tag;
5422 
5423  if (end - avio_tell(pb) <= 12)
5424  break;
5425 
5426  len = avio_rb32(pb);
5427  tag = avio_rl32(pb);
5428  avio_skip(pb, 4); // flags
5429 
5430  if (len < 12 || len - 12 > end - avio_tell(pb))
5431  break;
5432  len -= 12;
5433 
5434  if (tag == MKTAG('m', 'e', 'a', 'n'))
5435  p = &mean;
5436  else if (tag == MKTAG('n', 'a', 'm', 'e'))
5437  p = &key;
5438  else if (tag == MKTAG('d', 'a', 't', 'a') && len > 4) {
5439  avio_skip(pb, 4);
5440  len -= 4;
5441  p = &val;
5442  } else
5443  break;
5444 
5445  if (*p)
5446  break;
5447 
5448  *p = av_malloc(len + 1);
5449  if (!*p) {
5450  ret = AVERROR(ENOMEM);
5451  break;
5452  }
5453  ret = ffio_read_size(pb, *p, len);
5454  if (ret < 0) {
5455  av_freep(p);
5456  break;
5457  }
5458  (*p)[len] = 0;
5459  }
5460 
5461  if (mean && key && val) {
5462  if (strcmp(key, "iTunSMPB") == 0) {
5463  int priming, remainder, samples;
5464  if(sscanf(val, "%*X %X %X %X", &priming, &remainder, &samples) == 3){
5465  if(priming>0 && priming<16384)
5466  sc->start_pad = priming;
5467  }
5468  }
5469  if (strcmp(key, "cdec") != 0) {
5470  av_dict_set(&c->fc->metadata, key, val,
5472  key = val = NULL;
5473  }
5474  } else {
5475  av_log(c->fc, AV_LOG_VERBOSE,
5476  "Unhandled or malformed custom metadata of size %"PRId64"\n", atom.size);
5477  }
5478 
5479  avio_seek(pb, end, SEEK_SET);
5480  av_freep(&key);
5481  av_freep(&val);
5482  av_freep(&mean);
5483  return ret;
5484 }
5485 
5487 {
5488  MOVStreamContext *sc;
5489  AVStream *st;
5490 
5491  st = avformat_new_stream(c->fc, NULL);
5492  if (!st)
5493  return AVERROR(ENOMEM);
5494  sc = av_mallocz(sizeof(MOVStreamContext));
5495  if (!sc)
5496  goto fail;
5497 
5498  item->st = st;
5499  st->id = item->item_id;
5500  st->priv_data = sc;
5502  st->codecpar->codec_id = mov_codec_id(st, item->type);
5503  sc->id = st->id;
5504  sc->ffindex = st->index;
5505  st->avg_frame_rate.num = st->avg_frame_rate.den = 1;
5506  st->time_base.num = st->time_base.den = 1;
5507  st->nb_frames = 1;
5508  sc->time_scale = 1;
5509  sc->pb = c->fc->pb;
5510  sc->pb_is_copied = 1;
5511  sc->refcount = 1;
5512 
5513  if (item->name)
5514  av_dict_set(&st->metadata, "title", item->name, 0);
5515 
5516  // Populate the necessary fields used by mov_build_index.
5517  sc->stsc_data = av_malloc_array(1, sizeof(*sc->stsc_data));
5518  if (!sc->stsc_data)
5519  goto fail;
5520  sc->stsc_count = 1;
5521  sc->stsc_data[0].first = 1;
5522  sc->stsc_data[0].count = 1;
5523  sc->stsc_data[0].id = 1;
5524  sc->chunk_offsets = av_malloc_array(1, sizeof(*sc->chunk_offsets));
5525  if (!sc->chunk_offsets)
5526  goto fail;
5527  sc->chunk_count = 1;
5528  sc->stts_data = av_malloc_array(1, sizeof(*sc->stts_data));
5529  if (!sc->stts_data)
5530  goto fail;
5531  sc->stts_count = 1;
5532  sc->stts_data[0].count = 1;
5533  // Not used for still images. But needed by mov_build_index.
5534  sc->stts_data[0].duration = 0;
5535 
5536  return 0;
5537 fail:
5538  mov_free_stream_context(c->fc, st);
5539  ff_remove_stream(c->fc, st);
5540  item->st = NULL;
5541 
5542  return AVERROR(ENOMEM);
5543 }
5544 
5546 {
5547  while (atom.size > 8) {
5548  uint32_t tag;
5549  if (avio_feof(pb))
5550  return AVERROR_EOF;
5551  tag = avio_rl32(pb);
5552  atom.size -= 4;
5553  if (tag == MKTAG('h','d','l','r')) {
5554  avio_seek(pb, -8, SEEK_CUR);
5555  atom.size += 8;
5556  return mov_read_default(c, pb, atom);
5557  }
5558  }
5559  return 0;
5560 }
5561 
5562 // return 1 when matrix is identity, 0 otherwise
5563 #define IS_MATRIX_IDENT(matrix) \
5564  ( (matrix)[0][0] == (1 << 16) && \
5565  (matrix)[1][1] == (1 << 16) && \
5566  (matrix)[2][2] == (1 << 30) && \
5567  !(matrix)[0][1] && !(matrix)[0][2] && \
5568  !(matrix)[1][0] && !(matrix)[1][2] && \
5569  !(matrix)[2][0] && !(matrix)[2][1])
5570 
5572 {
5573  int i, j, e;
5574  int width;
5575  int height;
5576  int display_matrix[3][3];
5577  int res_display_matrix[3][3] = { { 0 } };
5578  AVStream *st;
5579  MOVStreamContext *sc;
5580  int version;
5581  int flags;
5582 
5583  if (c->fc->nb_streams < 1)
5584  return 0;
5585  st = c->fc->streams[c->fc->nb_streams-1];
5586  sc = st->priv_data;
5587 
5588  // Each stream (trak) should have exactly 1 tkhd. This catches bad files and
5589  // avoids corrupting AVStreams mapped to an earlier tkhd.
5590  if (st->id != -1)
5591  return AVERROR_INVALIDDATA;
5592 
5593  version = avio_r8(pb);
5594  flags = avio_rb24(pb);
5596 
5597  if (version == 1) {
5598  avio_rb64(pb);
5599  avio_rb64(pb);
5600  } else {
5601  avio_rb32(pb); /* creation time */
5602  avio_rb32(pb); /* modification time */
5603  }
5604  st->id = (int)avio_rb32(pb); /* track id (NOT 0 !)*/
5605  sc->id = st->id;
5606  avio_rb32(pb); /* reserved */
5607 
5608  /* highlevel (considering edits) duration in movie timebase */
5609  (version == 1) ? avio_rb64(pb) : avio_rb32(pb);
5610  avio_rb32(pb); /* reserved */
5611  avio_rb32(pb); /* reserved */
5612 
5613  avio_rb16(pb); /* layer */
5614  avio_rb16(pb); /* alternate group */
5615  avio_rb16(pb); /* volume */
5616  avio_rb16(pb); /* reserved */
5617 
5618  //read in the display matrix (outlined in ISO 14496-12, Section 6.2.2)
5619  // they're kept in fixed point format through all calculations
5620  // save u,v,z to store the whole matrix in the AV_PKT_DATA_DISPLAYMATRIX
5621  // side data, but the scale factor is not needed to calculate aspect ratio
5622  for (i = 0; i < 3; i++) {
5623  display_matrix[i][0] = avio_rb32(pb); // 16.16 fixed point
5624  display_matrix[i][1] = avio_rb32(pb); // 16.16 fixed point
5625  display_matrix[i][2] = avio_rb32(pb); // 2.30 fixed point
5626  }
5627 
5628  width = avio_rb32(pb); // 16.16 fixed point track width
5629  height = avio_rb32(pb); // 16.16 fixed point track height
5630  sc->width = width >> 16;
5631  sc->height = height >> 16;
5632 
5633  // apply the moov display matrix (after the tkhd one)
5634  for (i = 0; i < 3; i++) {
5635  const int sh[3] = { 16, 16, 30 };
5636  for (j = 0; j < 3; j++) {
5637  for (e = 0; e < 3; e++) {
5638  res_display_matrix[i][j] +=
5639  ((int64_t) display_matrix[i][e] *
5640  c->movie_display_matrix[e][j]) >> sh[e];
5641  }
5642  }
5643  }
5644 
5645  // save the matrix when it is not the default identity
5646  if (!IS_MATRIX_IDENT(res_display_matrix)) {
5647  av_freep(&sc->display_matrix);
5648  sc->display_matrix = av_malloc(sizeof(int32_t) * 9);
5649  if (!sc->display_matrix)
5650  return AVERROR(ENOMEM);
5651 
5652  for (i = 0; i < 3; i++)
5653  for (j = 0; j < 3; j++)
5654  sc->display_matrix[i * 3 + j] = res_display_matrix[i][j];
5655  }
5656 
5657  // transform the display width/height according to the matrix
5658  // to keep the same scale, use [width height 1<<16]
5659  if (width && height && sc->display_matrix) {
5660  double disp_transform[2];
5661 
5662  for (i = 0; i < 2; i++)
5663  disp_transform[i] = hypot(sc->display_matrix[0 + i],
5664  sc->display_matrix[3 + i]);
5665 
5666  if (disp_transform[0] > 1 && disp_transform[1] > 1 &&
5667  disp_transform[0] < (1<<24) && disp_transform[1] < (1<<24) &&
5668  fabs((disp_transform[0] / disp_transform[1]) - 1.0) > 0.01)
5670  disp_transform[0] / disp_transform[1],
5671  INT_MAX);
5672  }
5673  return 0;
5674 }
5675 
5677 {
5678  MOVFragment *frag = &c->fragment;
5679  MOVTrackExt *trex = NULL;
5680  int flags, track_id, i;
5681  MOVFragmentStreamInfo * frag_stream_info;
5682 
5683  avio_r8(pb); /* version */
5684  flags = avio_rb24(pb);
5685 
5686  track_id = avio_rb32(pb);
5687  if (!track_id)
5688  return AVERROR_INVALIDDATA;
5689  for (i = 0; i < c->trex_count; i++)
5690  if (c->trex_data[i].track_id == track_id) {
5691  trex = &c->trex_data[i];
5692  break;
5693  }
5694  if (!trex) {
5695  av_log(c->fc, AV_LOG_WARNING, "could not find corresponding trex (id %u)\n", track_id);
5696  return 0;
5697  }
5698  c->fragment.found_tfhd = 1;
5699  frag->track_id = track_id;
5700  set_frag_stream(&c->frag_index, track_id);
5701 
5704  frag->moof_offset : frag->implicit_offset;
5705  frag->stsd_id = flags & MOV_TFHD_STSD_ID ? avio_rb32(pb) : trex->stsd_id;
5706 
5708  avio_rb32(pb) : trex->duration;
5709  frag->size = flags & MOV_TFHD_DEFAULT_SIZE ?
5710  avio_rb32(pb) : trex->size;
5711  frag->flags = flags & MOV_TFHD_DEFAULT_FLAGS ?
5712  avio_rb32(pb) : trex->flags;
5713  av_log(c->fc, AV_LOG_TRACE, "frag flags 0x%x\n", frag->flags);
5714 
5715  frag_stream_info = get_current_frag_stream_info(&c->frag_index);
5716  if (frag_stream_info) {
5717  frag_stream_info->next_trun_dts = AV_NOPTS_VALUE;
5718  frag_stream_info->stsd_id = frag->stsd_id;
5719  }
5720  return 0;
5721 }
5722 
5724 {
5725  unsigned i, num;
5726  void *new_tracks;
5727 
5728  num = atom.size / 4;
5729  if (!(new_tracks = av_malloc_array(num, sizeof(int))))
5730  return AVERROR(ENOMEM);
5731 
5732  av_free(c->chapter_tracks);
5733  c->chapter_tracks = new_tracks;
5734  c->nb_chapter_tracks = num;
5735 
5736  for (i = 0; i < num && !pb->eof_reached; i++)
5737  c->chapter_tracks[i] = avio_rb32(pb);
5738 
5739  c->nb_chapter_tracks = i;
5740 
5741  return 0;
5742 }
5743 
5745 {
5746  MOVTrackExt *trex;
5747  int err;
5748 
5749  if ((uint64_t)c->trex_count+1 >= UINT_MAX / sizeof(*c->trex_data))
5750  return AVERROR_INVALIDDATA;
5751  if ((err = av_reallocp_array(&c->trex_data, c->trex_count + 1,
5752  sizeof(*c->trex_data))) < 0) {
5753  c->trex_count = 0;
5754  return err;
5755  }
5756 
5757  c->fc->duration = AV_NOPTS_VALUE; // the duration from mvhd is not representing the whole file when fragments are used.
5758 
5759  trex = &c->trex_data[c->trex_count++];
5760  avio_r8(pb); /* version */
5761  avio_rb24(pb); /* flags */
5762  trex->track_id = avio_rb32(pb);
5763  trex->stsd_id = avio_rb32(pb);
5764  trex->duration = avio_rb32(pb);
5765  trex->size = avio_rb32(pb);
5766  trex->flags = avio_rb32(pb);
5767  return 0;
5768 }
5769 
5771 {
5772  MOVFragment *frag = &c->fragment;
5773  AVStream *st = NULL;
5774  MOVStreamContext *sc;
5775  int version, i;
5776  MOVFragmentStreamInfo * frag_stream_info;
5777  int64_t base_media_decode_time;
5778 
5779  for (i = 0; i < c->fc->nb_streams; i++) {
5780  sc = c->fc->streams[i]->priv_data;
5781  if (sc->id == frag->track_id) {
5782  st = c->fc->streams[i];
5783  break;
5784  }
5785  }
5786  if (!st) {
5787  av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %u\n", frag->track_id);
5788  return 0;
5789  }
5790  sc = st->priv_data;
5791  if (sc->pseudo_stream_id + 1 != frag->stsd_id && sc->pseudo_stream_id != -1)
5792  return 0;
5793  version = avio_r8(pb);
5794  avio_rb24(pb); /* flags */
5795  if (version) {
5796  base_media_decode_time = avio_rb64(pb);
5797  } else {
5798  base_media_decode_time = avio_rb32(pb);
5799  }
5800 
5801  frag_stream_info = get_current_frag_stream_info(&c->frag_index);
5802  if (frag_stream_info)
5803  frag_stream_info->tfdt_dts = base_media_decode_time;
5804  sc->track_end = base_media_decode_time;
5805 
5806  return 0;
5807 }
5808 
5810 {
5811  MOVFragment *frag = &c->fragment;
5812  AVStream *st = NULL;
5813  FFStream *sti = NULL;
5814  MOVStreamContext *sc;
5815  MOVTimeToSample *tts_data;
5816  uint64_t offset;
5817  int64_t dts, pts = AV_NOPTS_VALUE;
5818  int data_offset = 0;
5819  unsigned entries, first_sample_flags = frag->flags;
5820  int flags, distance, i;
5821  int64_t prev_dts = AV_NOPTS_VALUE;
5822  int next_frag_index = -1, index_entry_pos;
5823  size_t requested_size;
5824  size_t old_allocated_size;
5825  AVIndexEntry *new_entries;
5826  MOVFragmentStreamInfo * frag_stream_info;
5827 
5828  if (!frag->found_tfhd) {
5829  av_log(c->fc, AV_LOG_ERROR, "trun track id unknown, no tfhd was found\n");
5830  return AVERROR_INVALIDDATA;
5831  }
5832 
5833  for (i = 0; i < c->fc->nb_streams; i++) {
5834  sc = c->fc->streams[i]->priv_data;
5835  if (sc->id == frag->track_id) {
5836  st = c->fc->streams[i];
5837  sti = ffstream(st);
5838  break;
5839  }
5840  }
5841  if (!st) {
5842  av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %u\n", frag->track_id);
5843  return 0;
5844  }
5845  sc = st->priv_data;
5846  if (sc->pseudo_stream_id+1 != frag->stsd_id && sc->pseudo_stream_id != -1)
5847  return 0;
5848 
5849  // Find the next frag_index index that has a valid index_entry for
5850  // the current track_id.
5851  //
5852  // A valid index_entry means the trun for the fragment was read
5853  // and it's samples are in index_entries at the given position.
5854  // New index entries will be inserted before the index_entry found.
5855  index_entry_pos = sti->nb_index_entries;
5856  for (i = c->frag_index.current + 1; i < c->frag_index.nb_items; i++) {
5857  frag_stream_info = get_frag_stream_info(&c->frag_index, i, frag->track_id);
5858  if (frag_stream_info && frag_stream_info->index_entry >= 0) {
5859  next_frag_index = i;
5860  index_entry_pos = frag_stream_info->index_entry;
5861  break;
5862  }
5863  }
5864  av_assert0(index_entry_pos <= sti->nb_index_entries);
5865 
5866  avio_r8(pb); /* version */
5867  flags = avio_rb24(pb);
5868  entries = avio_rb32(pb);
5869  av_log(c->fc, AV_LOG_TRACE, "flags 0x%x entries %u\n", flags, entries);
5870 
5871  if ((uint64_t)entries+sc->tts_count >= UINT_MAX/sizeof(*sc->tts_data))
5872  return AVERROR_INVALIDDATA;
5873  if (flags & MOV_TRUN_DATA_OFFSET) data_offset = avio_rb32(pb);
5874  if (flags & MOV_TRUN_FIRST_SAMPLE_FLAGS) first_sample_flags = avio_rb32(pb);
5875 
5876  frag_stream_info = get_current_frag_stream_info(&c->frag_index);
5877  if (frag_stream_info) {
5878  if (frag_stream_info->next_trun_dts != AV_NOPTS_VALUE) {
5879  dts = frag_stream_info->next_trun_dts - sc->time_offset;
5880  } else if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE &&
5881  c->use_mfra_for == FF_MOV_FLAG_MFRA_PTS) {
5882  pts = frag_stream_info->first_tfra_pts;
5883  av_log(c->fc, AV_LOG_DEBUG, "found mfra time %"PRId64
5884  ", using it for pts\n", pts);
5885  } else if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE &&
5886  c->use_mfra_for == FF_MOV_FLAG_MFRA_DTS) {
5887  dts = frag_stream_info->first_tfra_pts;
5888  av_log(c->fc, AV_LOG_DEBUG, "found mfra time %"PRId64
5889  ", using it for dts\n", pts);
5890  } else {
5891  int has_tfdt = frag_stream_info->tfdt_dts != AV_NOPTS_VALUE;
5892  int has_sidx = frag_stream_info->sidx_pts != AV_NOPTS_VALUE;
5893  int fallback_tfdt = !c->use_tfdt && !has_sidx && has_tfdt;
5894  int fallback_sidx = c->use_tfdt && !has_tfdt && has_sidx;
5895 
5896  if (fallback_sidx) {
5897  av_log(c->fc, AV_LOG_DEBUG, "use_tfdt set but no tfdt found, using sidx instead\n");
5898  }
5899  if (fallback_tfdt) {
5900  av_log(c->fc, AV_LOG_DEBUG, "use_tfdt not set but no sidx found, using tfdt instead\n");
5901  }
5902 
5903  if (has_tfdt && c->use_tfdt || fallback_tfdt) {
5904  dts = frag_stream_info->tfdt_dts - sc->time_offset;
5905  av_log(c->fc, AV_LOG_DEBUG, "found tfdt time %"PRId64
5906  ", using it for dts\n", dts);
5907  } else if (has_sidx && !c->use_tfdt || fallback_sidx) {
5908  // FIXME: sidx earliest_presentation_time is *PTS*, s.b.
5909  // pts = frag_stream_info->sidx_pts;
5910  dts = frag_stream_info->sidx_pts;
5911  av_log(c->fc, AV_LOG_DEBUG, "found sidx time %"PRId64
5912  ", using it for dts\n", frag_stream_info->sidx_pts);
5913  } else {
5914  dts = sc->track_end - sc->time_offset;
5915  av_log(c->fc, AV_LOG_DEBUG, "found track end time %"PRId64
5916  ", using it for dts\n", dts);
5917  }
5918  }
5919  } else {
5920  dts = sc->track_end - sc->time_offset;
5921  av_log(c->fc, AV_LOG_DEBUG, "found track end time %"PRId64
5922  ", using it for dts\n", dts);
5923  }
5924  offset = frag->base_data_offset + data_offset;
5925  distance = 0;
5926  av_log(c->fc, AV_LOG_TRACE, "first sample flags 0x%x\n", first_sample_flags);
5927 
5928  // realloc space for new index entries
5929  if ((uint64_t)sti->nb_index_entries + entries >= UINT_MAX / sizeof(AVIndexEntry)) {
5930  entries = UINT_MAX / sizeof(AVIndexEntry) - sti->nb_index_entries;
5931  av_log(c->fc, AV_LOG_ERROR, "Failed to add index entry\n");
5932  }
5933  if (entries == 0)
5934  return 0;
5935 
5936  requested_size = (sti->nb_index_entries + entries) * sizeof(AVIndexEntry);
5937  new_entries = av_fast_realloc(sti->index_entries,
5939  requested_size);
5940  if (!new_entries)
5941  return AVERROR(ENOMEM);
5942  sti->index_entries= new_entries;
5943 
5944  requested_size = (sti->nb_index_entries + entries) * sizeof(*sc->tts_data);
5945  old_allocated_size = sc->tts_allocated_size;
5946  tts_data = av_fast_realloc(sc->tts_data, &sc->tts_allocated_size,
5947  requested_size);
5948  if (!tts_data)
5949  return AVERROR(ENOMEM);
5950  sc->tts_data = tts_data;
5951 
5952  // In case there were samples without time to sample entries, ensure they get
5953  // zero valued entries. This ensures clips which mix boxes with and
5954  // without time to sample entries don't pickup uninitialized data.
5955  memset((uint8_t*)(sc->tts_data) + old_allocated_size, 0,
5956  sc->tts_allocated_size - old_allocated_size);
5957 
5958  if (index_entry_pos < sti->nb_index_entries) {
5959  // Make hole in index_entries and tts_data for new samples
5960  memmove(sti->index_entries + index_entry_pos + entries,
5961  sti->index_entries + index_entry_pos,
5962  sizeof(*sti->index_entries) *
5963  (sti->nb_index_entries - index_entry_pos));
5964  memmove(sc->tts_data + index_entry_pos + entries,
5965  sc->tts_data + index_entry_pos,
5966  sizeof(*sc->tts_data) * (sc->tts_count - index_entry_pos));
5967  if (index_entry_pos < sc->current_sample) {
5968  sc->current_sample += entries;
5969  }
5970  }
5971 
5972  sti->nb_index_entries += entries;
5973  sc->tts_count = sti->nb_index_entries;
5974  sc->stts_count = sti->nb_index_entries;
5975  if (flags & MOV_TRUN_SAMPLE_CTS)
5976  sc->ctts_count = sti->nb_index_entries;
5977 
5978  // Record the index_entry position in frag_index of this fragment
5979  if (frag_stream_info) {
5980  frag_stream_info->index_entry = index_entry_pos;
5981  if (frag_stream_info->index_base < 0)
5982  frag_stream_info->index_base = index_entry_pos;
5983  }
5984 
5985  if (index_entry_pos > 0)
5986  prev_dts = sti->index_entries[index_entry_pos-1].timestamp;
5987 
5988  for (i = 0; i < entries && !pb->eof_reached; i++) {
5989  unsigned sample_size = frag->size;
5990  int sample_flags = i ? frag->flags : first_sample_flags;
5991  unsigned sample_duration = frag->duration;
5992  unsigned ctts_duration = 0;
5993  int keyframe = 0;
5994  int index_entry_flags = 0;
5995 
5996  if (flags & MOV_TRUN_SAMPLE_DURATION) sample_duration = avio_rb32(pb);
5997  if (flags & MOV_TRUN_SAMPLE_SIZE) sample_size = avio_rb32(pb);
5998  if (flags & MOV_TRUN_SAMPLE_FLAGS) sample_flags = avio_rb32(pb);
5999  if (flags & MOV_TRUN_SAMPLE_CTS) ctts_duration = avio_rb32(pb);
6000 
6001  mov_update_dts_shift(sc, ctts_duration, c->fc);
6002  if (pts != AV_NOPTS_VALUE) {
6003  dts = pts - sc->dts_shift;
6004  if (flags & MOV_TRUN_SAMPLE_CTS) {
6005  dts -= ctts_duration;
6006  } else {
6007  dts -= sc->time_offset;
6008  }
6009  av_log(c->fc, AV_LOG_DEBUG,
6010  "pts %"PRId64" calculated dts %"PRId64
6011  " sc->dts_shift %d ctts.duration %d"
6012  " sc->time_offset %"PRId64
6013  " flags & MOV_TRUN_SAMPLE_CTS %d\n",
6014  pts, dts,
6015  sc->dts_shift, ctts_duration,
6017  pts = AV_NOPTS_VALUE;
6018  }
6019 
6020  keyframe =
6021  !(sample_flags & (MOV_FRAG_SAMPLE_FLAG_IS_NON_SYNC |
6023  if (keyframe) {
6024  distance = 0;
6025  index_entry_flags |= AVINDEX_KEYFRAME;
6026  }
6027  // Fragments can overlap in time. Discard overlapping frames after
6028  // decoding.
6029  if (prev_dts >= dts)
6030  index_entry_flags |= AVINDEX_DISCARD_FRAME;
6031 
6032  sti->index_entries[index_entry_pos].pos = offset;
6033  sti->index_entries[index_entry_pos].timestamp = dts;
6034  sti->index_entries[index_entry_pos].size = sample_size;
6035  sti->index_entries[index_entry_pos].min_distance = distance;
6036  sti->index_entries[index_entry_pos].flags = index_entry_flags;
6037 
6038  sc->tts_data[index_entry_pos].count = 1;
6039  sc->tts_data[index_entry_pos].offset = ctts_duration;
6040  sc->tts_data[index_entry_pos].duration = sample_duration;
6041  index_entry_pos++;
6042 
6043  av_log(c->fc, AV_LOG_TRACE, "AVIndex stream %d, sample %d, offset %"PRIx64", dts %"PRId64", "
6044  "size %u, distance %d, keyframe %d\n", st->index,
6045  index_entry_pos, offset, dts, sample_size, distance, keyframe);
6046  distance++;
6047  if (av_sat_add64(dts, sample_duration) != dts + (uint64_t)sample_duration)
6048  return AVERROR_INVALIDDATA;
6049  if (!sample_size)
6050  return AVERROR_INVALIDDATA;
6051  dts += sample_duration;
6052  offset += sample_size;
6053  sc->data_size += sample_size;
6054 
6055  if (sample_duration <= INT64_MAX - sc->duration_for_fps &&
6056  1 <= INT_MAX - sc->nb_frames_for_fps
6057  ) {
6058  sc->duration_for_fps += sample_duration;
6059  sc->nb_frames_for_fps ++;
6060  }
6061  }
6062  if (frag_stream_info)
6063  frag_stream_info->next_trun_dts = dts + sc->time_offset;
6064  if (i < entries) {
6065  // EOF found before reading all entries. Fix the hole this would
6066  // leave in index_entries and tts_data
6067  int gap = entries - i;
6068  memmove(sti->index_entries + index_entry_pos,
6069  sti->index_entries + index_entry_pos + gap,
6070  sizeof(*sti->index_entries) *
6071  (sti->nb_index_entries - (index_entry_pos + gap)));
6072  memmove(sc->tts_data + index_entry_pos,
6073  sc->tts_data + index_entry_pos + gap,
6074  sizeof(*sc->tts_data) *
6075  (sc->tts_count - (index_entry_pos + gap)));
6076 
6077  sti->nb_index_entries -= gap;
6078  sc->tts_count -= gap;
6079  if (index_entry_pos < sc->current_sample) {
6080  sc->current_sample -= gap;
6081  }
6082  entries = i;
6083  }
6084 
6085  // The end of this new fragment may overlap in time with the start
6086  // of the next fragment in index_entries. Mark the samples in the next
6087  // fragment that overlap with AVINDEX_DISCARD_FRAME
6088  prev_dts = AV_NOPTS_VALUE;
6089  if (index_entry_pos > 0)
6090  prev_dts = sti->index_entries[index_entry_pos-1].timestamp;
6091  for (int i = index_entry_pos; i < sti->nb_index_entries; i++) {
6092  if (prev_dts < sti->index_entries[i].timestamp)
6093  break;
6095  }
6096 
6097  // If a hole was created to insert the new index_entries into,
6098  // the index_entry recorded for all subsequent moof must
6099  // be incremented by the number of entries inserted.
6100  fix_frag_index_entries(&c->frag_index, next_frag_index,
6101  frag->track_id, entries);
6102 
6103  if (pb->eof_reached) {
6104  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted TRUN atom\n");
6105  return AVERROR_EOF;
6106  }
6107 
6108  frag->implicit_offset = offset;
6109 
6110  sc->track_end = dts + sc->time_offset;
6111  if (st->duration < sc->track_end)
6112  st->duration = sc->track_end;
6113 
6114  return 0;
6115 }
6116 
6118 {
6119  int64_t stream_size = avio_size(pb);
6120  int64_t offset = av_sat_add64(avio_tell(pb), atom.size), pts, timestamp;
6121  uint8_t version, is_complete;
6122  int64_t offadd;
6123  unsigned i, j, track_id, item_count;
6124  AVStream *st = NULL;
6125  AVStream *ref_st = NULL;
6126  MOVStreamContext *sc, *ref_sc = NULL;
6127  AVRational timescale;
6128 
6129  version = avio_r8(pb);
6130  if (version > 1) {
6131  avpriv_request_sample(c->fc, "sidx version %u", version);
6132  return 0;
6133  }
6134 
6135  avio_rb24(pb); // flags
6136 
6137  track_id = avio_rb32(pb); // Reference ID
6138  for (i = 0; i < c->fc->nb_streams; i++) {
6139  sc = c->fc->streams[i]->priv_data;
6140  if (sc->id == track_id) {
6141  st = c->fc->streams[i];
6142  break;
6143  }
6144  }
6145  if (!st) {
6146  av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %d\n", track_id);
6147  return 0;
6148  }
6149 
6150  sc = st->priv_data;
6151 
6152  timescale = av_make_q(1, avio_rb32(pb));
6153 
6154  if (timescale.den <= 0) {
6155  av_log(c->fc, AV_LOG_ERROR, "Invalid sidx timescale 1/%d\n", timescale.den);
6156  return AVERROR_INVALIDDATA;
6157  }
6158 
6159  if (version == 0) {
6160  pts = avio_rb32(pb);
6161  offadd= avio_rb32(pb);
6162  } else {
6163  pts = avio_rb64(pb);
6164  offadd= avio_rb64(pb);
6165  }
6166  if (av_sat_add64(offset, offadd) != offset + (uint64_t)offadd)
6167  return AVERROR_INVALIDDATA;
6168 
6169  offset += (uint64_t)offadd;
6170 
6171  avio_rb16(pb); // reserved
6172 
6173  item_count = avio_rb16(pb);
6174  if (item_count == 0)
6175  return AVERROR_INVALIDDATA;
6176 
6177  for (i = 0; i < item_count; i++) {
6178  int index;
6179  MOVFragmentStreamInfo * frag_stream_info;
6180  uint32_t size = avio_rb32(pb);
6181  uint32_t duration = avio_rb32(pb);
6182  if (size & 0x80000000) {
6183  avpriv_request_sample(c->fc, "sidx reference_type 1");
6184  return AVERROR_PATCHWELCOME;
6185  }
6186  avio_rb32(pb); // sap_flags
6187  timestamp = av_rescale_q(pts, timescale, st->time_base);
6188 
6190  frag_stream_info = get_frag_stream_info(&c->frag_index, index, track_id);
6191  if (frag_stream_info)
6192  frag_stream_info->sidx_pts = timestamp;
6193 
6194  if (av_sat_add64(offset, size) != offset + (uint64_t)size ||
6195  av_sat_add64(pts, duration) != pts + (uint64_t)duration
6196  )
6197  return AVERROR_INVALIDDATA;
6198  offset += size;
6199  pts += duration;
6200  }
6201 
6202  st->duration = sc->track_end = pts;
6203 
6204  sc->has_sidx = 1;
6205 
6206  // See if the remaining bytes are just an mfra which we can ignore.
6207  is_complete = offset == stream_size;
6208  if (!is_complete && (pb->seekable & AVIO_SEEKABLE_NORMAL) && stream_size > 0 ) {
6209  int64_t ret;
6210  int64_t original_pos = avio_tell(pb);
6211  if (!c->have_read_mfra_size) {
6212  if ((ret = avio_seek(pb, stream_size - 4, SEEK_SET)) < 0)
6213  return ret;
6214  c->mfra_size = avio_rb32(pb);
6215  c->have_read_mfra_size = 1;
6216  if ((ret = avio_seek(pb, original_pos, SEEK_SET)) < 0)
6217  return ret;
6218  }
6219  if (offset == stream_size - c->mfra_size)
6220  is_complete = 1;
6221  }
6222 
6223  if (is_complete) {
6224  // Find first entry in fragment index that came from an sidx.
6225  // This will pretty much always be the first entry.
6226  for (i = 0; i < c->frag_index.nb_items; i++) {
6227  MOVFragmentIndexItem * item = &c->frag_index.item[i];
6228  for (j = 0; ref_st == NULL && j < item->nb_stream_info; j++) {
6229  MOVFragmentStreamInfo * si;
6230  si = &item->stream_info[j];
6231  if (si->sidx_pts != AV_NOPTS_VALUE) {
6232  ref_st = c->fc->streams[j];
6233  ref_sc = ref_st->priv_data;
6234  break;
6235  }
6236  }
6237  }
6238  if (ref_st) for (i = 0; i < c->fc->nb_streams; i++) {
6239  st = c->fc->streams[i];
6240  sc = st->priv_data;
6241  if (!sc->has_sidx) {
6242  st->duration = sc->track_end = av_rescale(ref_st->duration, sc->time_scale, ref_sc->time_scale);
6243  }
6244  }
6245 
6246  if (offadd == 0)
6247  c->frag_index.complete = 1;
6248  }
6249 
6250  return 0;
6251 }
6252 
6253 /* this atom should be null (from specs), but some buggy files put the 'moov' atom inside it... */
6254 /* like the files created with Adobe Premiere 5.0, for samples see */
6255 /* http://graphics.tudelft.nl/~wouter/publications/soundtests/ */
6257 {
6258  int err;
6259 
6260  if (atom.size < 8)
6261  return 0; /* continue */
6262  if (avio_rb32(pb) != 0) { /* 0 sized mdat atom... use the 'wide' atom size */
6263  avio_skip(pb, atom.size - 4);
6264  return 0;
6265  }
6266  atom.type = avio_rl32(pb);
6267  atom.size -= 8;
6268  if (atom.type != MKTAG('m','d','a','t')) {
6269  avio_skip(pb, atom.size);
6270  return 0;
6271  }
6272  err = mov_read_mdat(c, pb, atom);
6273  return err;
6274 }
6275 
6277 {
6278 #if CONFIG_ZLIB
6279  FFIOContext ctx;
6280  uint8_t *cmov_data;
6281  uint8_t *moov_data; /* uncompressed data */
6282  long cmov_len, moov_len;
6283  int ret = -1;
6284 
6285  avio_rb32(pb); /* dcom atom */
6286  if (avio_rl32(pb) != MKTAG('d','c','o','m'))
6287  return AVERROR_INVALIDDATA;
6288  if (avio_rl32(pb) != MKTAG('z','l','i','b')) {
6289  av_log(c->fc, AV_LOG_ERROR, "unknown compression for cmov atom !\n");
6290  return AVERROR_INVALIDDATA;
6291  }
6292  avio_rb32(pb); /* cmvd atom */
6293  if (avio_rl32(pb) != MKTAG('c','m','v','d'))
6294  return AVERROR_INVALIDDATA;
6295  moov_len = avio_rb32(pb); /* uncompressed size */
6296  cmov_len = atom.size - 6 * 4;
6297 
6298  cmov_data = av_malloc(cmov_len);
6299  if (!cmov_data)
6300  return AVERROR(ENOMEM);
6301  moov_data = av_malloc(moov_len);
6302  if (!moov_data) {
6303  av_free(cmov_data);
6304  return AVERROR(ENOMEM);
6305  }
6306  ret = ffio_read_size(pb, cmov_data, cmov_len);
6307  if (ret < 0)
6308  goto free_and_return;
6309 
6311  if (uncompress (moov_data, (uLongf *) &moov_len, (const Bytef *)cmov_data, cmov_len) != Z_OK)
6312  goto free_and_return;
6313  ffio_init_read_context(&ctx, moov_data, moov_len);
6314  ctx.pub.seekable = AVIO_SEEKABLE_NORMAL;
6315  atom.type = MKTAG('m','o','o','v');
6316  atom.size = moov_len;
6317  ret = mov_read_default(c, &ctx.pub, atom);
6318 free_and_return:
6319  av_free(moov_data);
6320  av_free(cmov_data);
6321  return ret;
6322 #else
6323  av_log(c->fc, AV_LOG_ERROR, "this file requires zlib support compiled in\n");
6324  return AVERROR(ENOSYS);
6325 #endif
6326 }
6327 
6328 /* edit list atom */
6330 {
6331  MOVStreamContext *sc;
6332  int i, edit_count, version;
6333  int64_t elst_entry_size;
6334 
6335  if (c->fc->nb_streams < 1 || c->ignore_editlist)
6336  return 0;
6337  sc = c->fc->streams[c->fc->nb_streams-1]->priv_data;
6338 
6339  version = avio_r8(pb); /* version */
6340  avio_rb24(pb); /* flags */
6341  edit_count = avio_rb32(pb); /* entries */
6342  atom.size -= 8;
6343 
6344  elst_entry_size = version == 1 ? 20 : 12;
6345  if (atom.size != edit_count * elst_entry_size) {
6346  if (c->fc->strict_std_compliance >= FF_COMPLIANCE_STRICT) {
6347  av_log(c->fc, AV_LOG_ERROR, "Invalid edit list entry_count: %d for elst atom of size: %"PRId64" bytes.\n",
6348  edit_count, atom.size + 8);
6349  return AVERROR_INVALIDDATA;
6350  } else {
6351  edit_count = atom.size / elst_entry_size;
6352  if (edit_count * elst_entry_size != atom.size) {
6353  av_log(c->fc, AV_LOG_WARNING, "ELST atom of %"PRId64" bytes, bigger than %d entries.\n", atom.size, edit_count);
6354  }
6355  }
6356  }
6357 
6358  if (!edit_count)
6359  return 0;
6360  if (sc->elst_data)
6361  av_log(c->fc, AV_LOG_WARNING, "Duplicated ELST atom\n");
6362  av_free(sc->elst_data);
6363  sc->elst_count = 0;
6364  sc->elst_data = av_malloc_array(edit_count, sizeof(*sc->elst_data));
6365  if (!sc->elst_data)
6366  return AVERROR(ENOMEM);
6367 
6368  av_log(c->fc, AV_LOG_TRACE, "track[%u].edit_count = %i\n", c->fc->nb_streams - 1, edit_count);
6369  for (i = 0; i < edit_count && atom.size > 0 && !pb->eof_reached; i++) {
6370  MOVElst *e = &sc->elst_data[i];
6371 
6372  if (version == 1) {
6373  e->duration = avio_rb64(pb);
6374  e->time = avio_rb64(pb);
6375  atom.size -= 16;
6376  } else {
6377  e->duration = avio_rb32(pb); /* segment duration */
6378  e->time = (int32_t)avio_rb32(pb); /* media time */
6379  atom.size -= 8;
6380  }
6381  e->rate = avio_rb32(pb) / 65536.0;
6382  atom.size -= 4;
6383  av_log(c->fc, AV_LOG_TRACE, "duration=%"PRId64" time=%"PRId64" rate=%f\n",
6384  e->duration, e->time, e->rate);
6385 
6386  if (e->time < 0 && e->time != -1 &&
6387  c->fc->strict_std_compliance >= FF_COMPLIANCE_STRICT) {
6388  av_log(c->fc, AV_LOG_ERROR, "Track %d, edit %d: Invalid edit list media time=%"PRId64"\n",
6389  c->fc->nb_streams-1, i, e->time);
6390  return AVERROR_INVALIDDATA;
6391  }
6392  if (e->duration < 0) {
6393  av_log(c->fc, AV_LOG_ERROR, "Track %d, edit %d: Invalid edit list duration=%"PRId64"\n",
6394  c->fc->nb_streams-1, i, e->duration);
6395  return AVERROR_INVALIDDATA;
6396  }
6397  }
6398  sc->elst_count = i;
6399 
6400  return 0;
6401 }
6402 
6404 {
6405  MOVStreamContext *sc;
6406 
6407  if (c->fc->nb_streams < 1)
6408  return AVERROR_INVALIDDATA;
6409  sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
6410  sc->timecode_track = avio_rb32(pb);
6411  return 0;
6412 }
6413 
6415 {
6416  AVStream *st;
6417  int version, color_range, color_primaries, color_trc, color_space;
6418 
6419  if (c->fc->nb_streams < 1)
6420  return 0;
6421  st = c->fc->streams[c->fc->nb_streams - 1];
6422 
6423  if (atom.size < 5) {
6424  av_log(c->fc, AV_LOG_ERROR, "Empty VP Codec Configuration box\n");
6425  return AVERROR_INVALIDDATA;
6426  }
6427 
6428  version = avio_r8(pb);
6429  if (version != 1) {
6430  av_log(c->fc, AV_LOG_WARNING, "Unsupported VP Codec Configuration box version %d\n", version);
6431  return 0;
6432  }
6433  avio_skip(pb, 3); /* flags */
6434 
6435  avio_skip(pb, 2); /* profile + level */
6436  color_range = avio_r8(pb); /* bitDepth, chromaSubsampling, videoFullRangeFlag */
6437  color_primaries = avio_r8(pb);
6438  color_trc = avio_r8(pb);
6439  color_space = avio_r8(pb);
6440  if (avio_rb16(pb)) /* codecIntializationDataSize */
6441  return AVERROR_INVALIDDATA;
6442 
6445  if (!av_color_transfer_name(color_trc))
6446  color_trc = AVCOL_TRC_UNSPECIFIED;
6447  if (!av_color_space_name(color_space))
6448  color_space = AVCOL_SPC_UNSPECIFIED;
6449 
6452  st->codecpar->color_trc = color_trc;
6453  st->codecpar->color_space = color_space;
6454 
6455  return 0;
6456 }
6457 
6459 {
6460  MOVStreamContext *sc;
6461  int i, version;
6462 
6463  if (c->fc->nb_streams < 1)
6464  return AVERROR_INVALIDDATA;
6465 
6466  sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
6467 
6468  if (atom.size < 5) {
6469  av_log(c->fc, AV_LOG_ERROR, "Empty Mastering Display Metadata box\n");
6470  return AVERROR_INVALIDDATA;
6471  }
6472 
6473  version = avio_r8(pb);
6474  if (version) {
6475  av_log(c->fc, AV_LOG_WARNING, "Unsupported Mastering Display Metadata box version %d\n", version);
6476  return 0;
6477  }
6478  if (sc->mastering) {
6479  av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicate Mastering Display Metadata\n");
6480  return 0;
6481  }
6482 
6483  avio_skip(pb, 3); /* flags */
6484 
6486  if (!sc->mastering)
6487  return AVERROR(ENOMEM);
6488 
6489  for (i = 0; i < 3; i++) {
6490  sc->mastering->display_primaries[i][0] = av_make_q(avio_rb16(pb), 1 << 16);
6491  sc->mastering->display_primaries[i][1] = av_make_q(avio_rb16(pb), 1 << 16);
6492  }
6493  sc->mastering->white_point[0] = av_make_q(avio_rb16(pb), 1 << 16);
6494  sc->mastering->white_point[1] = av_make_q(avio_rb16(pb), 1 << 16);
6495 
6496  sc->mastering->max_luminance = av_make_q(avio_rb32(pb), 1 << 8);
6497  sc->mastering->min_luminance = av_make_q(avio_rb32(pb), 1 << 14);
6498 
6499  sc->mastering->has_primaries = 1;
6500  sc->mastering->has_luminance = 1;
6501 
6502  return 0;
6503 }
6504 
6506 {
6507  MOVStreamContext *sc;
6508  const int mapping[3] = {1, 2, 0};
6509  const int chroma_den = 50000;
6510  const int luma_den = 10000;
6511  int i;
6512 
6513  if (c->fc->nb_streams < 1)
6514  return AVERROR_INVALIDDATA;
6515 
6516  sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
6517 
6518  if (atom.size < 24) {
6519  av_log(c->fc, AV_LOG_ERROR, "Invalid Mastering Display Color Volume box\n");
6520  return AVERROR_INVALIDDATA;
6521  }
6522 
6523  if (sc->mastering) {
6524  av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicate Mastering Display Color Volume\n");
6525  return 0;
6526  }
6527 
6529  if (!sc->mastering)
6530  return AVERROR(ENOMEM);
6531 
6532  for (i = 0; i < 3; i++) {
6533  const int j = mapping[i];
6534  sc->mastering->display_primaries[j][0] = av_make_q(avio_rb16(pb), chroma_den);
6535  sc->mastering->display_primaries[j][1] = av_make_q(avio_rb16(pb), chroma_den);
6536  }
6537  sc->mastering->white_point[0] = av_make_q(avio_rb16(pb), chroma_den);
6538  sc->mastering->white_point[1] = av_make_q(avio_rb16(pb), chroma_den);
6539 
6540  sc->mastering->max_luminance = av_make_q(avio_rb32(pb), luma_den);
6541  sc->mastering->min_luminance = av_make_q(avio_rb32(pb), luma_den);
6542 
6543  sc->mastering->has_luminance = 1;
6544  sc->mastering->has_primaries = 1;
6545 
6546  return 0;
6547 }
6548 
6550 {
6551  MOVStreamContext *sc;
6552  int version;
6553 
6554  if (c->fc->nb_streams < 1)
6555  return AVERROR_INVALIDDATA;
6556 
6557  sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
6558 
6559  if (atom.size < 5) {
6560  av_log(c->fc, AV_LOG_ERROR, "Empty Content Light Level box\n");
6561  return AVERROR_INVALIDDATA;
6562  }
6563 
6564  version = avio_r8(pb);
6565  if (version) {
6566  av_log(c->fc, AV_LOG_WARNING, "Unsupported Content Light Level box version %d\n", version);
6567  return 0;
6568  }
6569  avio_skip(pb, 3); /* flags */
6570 
6571  if (sc->coll){
6572  av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicate COLL\n");
6573  return 0;
6574  }
6575 
6577  if (!sc->coll)
6578  return AVERROR(ENOMEM);
6579 
6580  sc->coll->MaxCLL = avio_rb16(pb);
6581  sc->coll->MaxFALL = avio_rb16(pb);
6582 
6583  return 0;
6584 }
6585 
6587 {
6588  MOVStreamContext *sc;
6589 
6590  if (c->fc->nb_streams < 1)
6591  return AVERROR_INVALIDDATA;
6592 
6593  sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
6594 
6595  if (atom.size < 4) {
6596  av_log(c->fc, AV_LOG_ERROR, "Empty Content Light Level Info box\n");
6597  return AVERROR_INVALIDDATA;
6598  }
6599 
6600  if (sc->coll){
6601  av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicate CLLI/COLL\n");
6602  return 0;
6603  }
6604 
6606  if (!sc->coll)
6607  return AVERROR(ENOMEM);
6608 
6609  sc->coll->MaxCLL = avio_rb16(pb);
6610  sc->coll->MaxFALL = avio_rb16(pb);
6611 
6612  return 0;
6613 }
6614 
6616 {
6617  MOVStreamContext *sc;
6618  const int illuminance_den = 10000;
6619  const int ambient_den = 50000;
6620  if (c->fc->nb_streams < 1)
6621  return AVERROR_INVALIDDATA;
6622  sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
6623  if (atom.size < 6) {
6624  av_log(c->fc, AV_LOG_ERROR, "Empty Ambient Viewing Environment Info box\n");
6625  return AVERROR_INVALIDDATA;
6626  }
6627  if (sc->ambient){
6628  av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicate AMVE\n");
6629  return 0;
6630  }
6632  if (!sc->ambient)
6633  return AVERROR(ENOMEM);
6634  sc->ambient->ambient_illuminance = av_make_q(avio_rb32(pb), illuminance_den);
6635  sc->ambient->ambient_light_x = av_make_q(avio_rb16(pb), ambient_den);
6636  sc->ambient->ambient_light_y = av_make_q(avio_rb16(pb), ambient_den);
6637  return 0;
6638 }
6639 
6641 {
6642  AVStream *st;
6643  MOVStreamContext *sc;
6644  enum AVStereo3DType type;
6645  int mode;
6646 
6647  if (c->fc->nb_streams < 1)
6648  return 0;
6649 
6650  st = c->fc->streams[c->fc->nb_streams - 1];
6651  sc = st->priv_data;
6652 
6653  if (atom.size < 5) {
6654  av_log(c->fc, AV_LOG_ERROR, "Empty stereoscopic video box\n");
6655  return AVERROR_INVALIDDATA;
6656  }
6657 
6658  if (sc->stereo3d)
6659  return AVERROR_INVALIDDATA;
6660 
6661  avio_skip(pb, 4); /* version + flags */
6662 
6663  mode = avio_r8(pb);
6664  switch (mode) {
6665  case 0:
6666  type = AV_STEREO3D_2D;
6667  break;
6668  case 1:
6670  break;
6671  case 2:
6673  break;
6674  default:
6675  av_log(c->fc, AV_LOG_WARNING, "Unknown st3d mode value %d\n", mode);
6676  return 0;
6677  }
6678 
6680  if (!sc->stereo3d)
6681  return AVERROR(ENOMEM);
6682 
6683  sc->stereo3d->type = type;
6684  return 0;
6685 }
6686 
6688 {
6689  AVStream *st;
6690  MOVStreamContext *sc;
6691  int size = 0;
6692  int64_t remaining;
6693  uint32_t tag = 0;
6695 
6696  if (c->fc->nb_streams < 1)
6697  return 0;
6698 
6699  st = c->fc->streams[c->fc->nb_streams - 1];
6700  sc = st->priv_data;
6701 
6702  remaining = atom.size;
6703  while (remaining > 0) {
6704  size = avio_rb32(pb);
6705  if (size < 8 || size > remaining ) {
6706  av_log(c->fc, AV_LOG_ERROR, "Invalid child size in pack box\n");
6707  return AVERROR_INVALIDDATA;
6708  }
6709 
6710  tag = avio_rl32(pb);
6711  switch (tag) {
6712  case MKTAG('p','k','i','n'): {
6713  if (size != 16) {
6714  av_log(c->fc, AV_LOG_ERROR, "Invalid size of pkin box: %d\n", size);
6715  return AVERROR_INVALIDDATA;
6716  }
6717  avio_skip(pb, 1); // version
6718  avio_skip(pb, 3); // flags
6719 
6720  tag = avio_rl32(pb);
6721  switch (tag) {
6722  case MKTAG('s','i','d','e'):
6724  break;
6725  case MKTAG('o','v','e','r'):
6727  break;
6728  case 0:
6729  // This means value will be set in another layer
6730  break;
6731  default:
6732  av_log(c->fc, AV_LOG_WARNING, "Unknown tag in pkin: %s\n",
6733  av_fourcc2str(tag));
6734  avio_skip(pb, size - 8);
6735  break;
6736  }
6737 
6738  break;
6739  }
6740  default:
6741  av_log(c->fc, AV_LOG_WARNING, "Unknown tag in pack: %s\n",
6742  av_fourcc2str(tag));
6743  avio_skip(pb, size - 8);
6744  break;
6745  }
6746  remaining -= size;
6747  }
6748 
6749  if (remaining != 0) {
6750  av_log(c->fc, AV_LOG_ERROR, "Broken pack box\n");
6751  return AVERROR_INVALIDDATA;
6752  }
6753 
6754  if (type == AV_STEREO3D_2D)
6755  return 0;
6756 
6757  if (!sc->stereo3d) {
6759  if (!sc->stereo3d)
6760  return AVERROR(ENOMEM);
6761  }
6762 
6763  sc->stereo3d->type = type;
6764 
6765  return 0;
6766 }
6767 
6769 {
6770  AVStream *st;
6771  MOVStreamContext *sc;
6772  int size, version, layout;
6773  int32_t yaw, pitch, roll;
6774  uint32_t l = 0, t = 0, r = 0, b = 0;
6775  uint32_t tag, padding = 0;
6776  enum AVSphericalProjection projection;
6777 
6778  if (c->fc->nb_streams < 1)
6779  return 0;
6780 
6781  st = c->fc->streams[c->fc->nb_streams - 1];
6782  sc = st->priv_data;
6783 
6784  if (atom.size < 8) {
6785  av_log(c->fc, AV_LOG_ERROR, "Empty spherical video box\n");
6786  return AVERROR_INVALIDDATA;
6787  }
6788 
6789  size = avio_rb32(pb);
6790  if (size <= 12 || size > atom.size)
6791  return AVERROR_INVALIDDATA;
6792 
6793  tag = avio_rl32(pb);
6794  if (tag != MKTAG('s','v','h','d')) {
6795  av_log(c->fc, AV_LOG_ERROR, "Missing spherical video header\n");
6796  return 0;
6797  }
6798  version = avio_r8(pb);
6799  if (version != 0) {
6800  av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
6801  version);
6802  return 0;
6803  }
6804  avio_skip(pb, 3); /* flags */
6805  avio_skip(pb, size - 12); /* metadata_source */
6806 
6807  size = avio_rb32(pb);
6808  if (size > atom.size)
6809  return AVERROR_INVALIDDATA;
6810 
6811  tag = avio_rl32(pb);
6812  if (tag != MKTAG('p','r','o','j')) {
6813  av_log(c->fc, AV_LOG_ERROR, "Missing projection box\n");
6814  return 0;
6815  }
6816 
6817  size = avio_rb32(pb);
6818  if (size > atom.size)
6819  return AVERROR_INVALIDDATA;
6820 
6821  tag = avio_rl32(pb);
6822  if (tag != MKTAG('p','r','h','d')) {
6823  av_log(c->fc, AV_LOG_ERROR, "Missing projection header box\n");
6824  return 0;
6825  }
6826  version = avio_r8(pb);
6827  if (version != 0) {
6828  av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
6829  version);
6830  return 0;
6831  }
6832  avio_skip(pb, 3); /* flags */
6833 
6834  /* 16.16 fixed point */
6835  yaw = avio_rb32(pb);
6836  pitch = avio_rb32(pb);
6837  roll = avio_rb32(pb);
6838 
6839  size = avio_rb32(pb);
6840  if (size > atom.size)
6841  return AVERROR_INVALIDDATA;
6842 
6843  tag = avio_rl32(pb);
6844  version = avio_r8(pb);
6845  if (version != 0) {
6846  av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
6847  version);
6848  return 0;
6849  }
6850  avio_skip(pb, 3); /* flags */
6851  switch (tag) {
6852  case MKTAG('c','b','m','p'):
6853  layout = avio_rb32(pb);
6854  if (layout) {
6855  av_log(c->fc, AV_LOG_WARNING,
6856  "Unsupported cubemap layout %d\n", layout);
6857  return 0;
6858  }
6859  projection = AV_SPHERICAL_CUBEMAP;
6860  padding = avio_rb32(pb);
6861  break;
6862  case MKTAG('e','q','u','i'):
6863  t = avio_rb32(pb);
6864  b = avio_rb32(pb);
6865  l = avio_rb32(pb);
6866  r = avio_rb32(pb);
6867 
6868  if (b >= UINT_MAX - t || r >= UINT_MAX - l) {
6869  av_log(c->fc, AV_LOG_ERROR,
6870  "Invalid bounding rectangle coordinates "
6871  "%"PRIu32",%"PRIu32",%"PRIu32",%"PRIu32"\n", l, t, r, b);
6872  return AVERROR_INVALIDDATA;
6873  }
6874 
6875  if (l || t || r || b)
6876  projection = AV_SPHERICAL_EQUIRECTANGULAR_TILE;
6877  else
6878  projection = AV_SPHERICAL_EQUIRECTANGULAR;
6879  break;
6880  default:
6881  av_log(c->fc, AV_LOG_ERROR, "Unknown projection type: %s\n", av_fourcc2str(tag));
6882  return 0;
6883  }
6884 
6886  if (!sc->spherical)
6887  return AVERROR(ENOMEM);
6888 
6889  sc->spherical->projection = projection;
6890 
6891  sc->spherical->yaw = yaw;
6892  sc->spherical->pitch = pitch;
6893  sc->spherical->roll = roll;
6894 
6895  sc->spherical->padding = padding;
6896 
6897  sc->spherical->bound_left = l;
6898  sc->spherical->bound_top = t;
6899  sc->spherical->bound_right = r;
6900  sc->spherical->bound_bottom = b;
6901 
6902  return 0;
6903 }
6904 
6906 {
6907  AVStream *st;
6908  MOVStreamContext *sc;
6909  int size;
6910  uint32_t tag;
6911  enum AVSphericalProjection projection;
6912 
6913  if (c->fc->nb_streams < 1)
6914  return 0;
6915 
6916  st = c->fc->streams[c->fc->nb_streams - 1];
6917  sc = st->priv_data;
6918 
6919  if (atom.size < 16) {
6920  av_log(c->fc, AV_LOG_ERROR, "Invalid size for proj box: %"PRIu64"\n", atom.size);
6921  return AVERROR_INVALIDDATA;
6922  }
6923 
6924  size = avio_rb32(pb);
6925  if (size < 16) {
6926  av_log(c->fc, AV_LOG_ERROR, "Invalid size for prji box: %d\n", size);
6927  return AVERROR_INVALIDDATA;
6928  } else if (size > 16) {
6929  av_log(c->fc, AV_LOG_WARNING, "Box has more bytes (%d) than prji box required (16) \n", size);
6930  }
6931 
6932  tag = avio_rl32(pb);
6933  if (tag != MKTAG('p','r','j','i')) {
6934  av_log(c->fc, AV_LOG_ERROR, "Invalid child box of proj box: %s\n",
6935  av_fourcc2str(tag));
6936  return AVERROR_INVALIDDATA;
6937  }
6938 
6939  // version and flags, only support (0, 0)
6940  unsigned n = avio_rl32(pb);
6941  if (n != 0) {
6942  av_log(c->fc, AV_LOG_ERROR, "prji version %u, flag %u are not supported\n",
6943  n & 0xFF, n >> 8);
6944  return AVERROR_PATCHWELCOME;
6945  }
6946 
6947  tag = avio_rl32(pb);
6948  switch (tag) {
6949  case MKTAG('r','e','c','t'):
6950  projection = AV_SPHERICAL_RECTILINEAR;
6951  break;
6952  case MKTAG('e','q','u','i'):
6953  projection = AV_SPHERICAL_EQUIRECTANGULAR;
6954  break;
6955  case MKTAG('h','e','q','u'):
6956  projection = AV_SPHERICAL_HALF_EQUIRECTANGULAR;
6957  break;
6958  case MKTAG('f','i','s','h'):
6959  projection = AV_SPHERICAL_FISHEYE;
6960  break;
6961  case MKTAG('p','r','i','m'):
6962  projection = AV_SPHERICAL_PARAMETRIC_IMMERSIVE;
6963  break;
6964  default:
6965  av_log(c->fc, AV_LOG_ERROR, "Invalid projection type in prji box: %s\n", av_fourcc2str(tag));
6966  return AVERROR_INVALIDDATA;
6967  }
6968 
6970  if (!sc->spherical)
6971  return AVERROR(ENOMEM);
6972 
6973  sc->spherical->projection = projection;
6974 
6975  return 0;
6976 }
6977 
6979 {
6980  AVStream *st;
6981  MOVStreamContext *sc;
6982  int size, flags = 0;
6983  int64_t remaining;
6984  uint32_t tag, baseline = 0;
6987  enum AVStereo3DPrimaryEye primary_eye = AV_PRIMARY_EYE_NONE;
6988  AVRational horizontal_disparity_adjustment = { 0, 1 };
6989 
6990  if (c->fc->nb_streams < 1)
6991  return 0;
6992 
6993  st = c->fc->streams[c->fc->nb_streams - 1];
6994  sc = st->priv_data;
6995 
6996  remaining = atom.size;
6997  while (remaining > 0) {
6998  size = avio_rb32(pb);
6999  if (size < 8 || size > remaining ) {
7000  av_log(c->fc, AV_LOG_ERROR, "Invalid child size in eyes box\n");
7001  return AVERROR_INVALIDDATA;
7002  }
7003 
7004  tag = avio_rl32(pb);
7005  switch (tag) {
7006  case MKTAG('s','t','r','i'): {
7007  int has_right, has_left;
7008  uint8_t tmp;
7009  if (size != 13) {
7010  av_log(c->fc, AV_LOG_ERROR, "Invalid size of stri box: %d\n", size);
7011  return AVERROR_INVALIDDATA;
7012  }
7013  avio_skip(pb, 1); // version
7014  avio_skip(pb, 3); // flags
7015 
7016  tmp = avio_r8(pb);
7017 
7018  // eye_views_reversed
7019  if (tmp & 8) {
7021  }
7022  // has_additional_views
7023  if (tmp & 4) {
7024  // skip...
7025  }
7026 
7027  has_right = tmp & 2; // has_right_eye_view
7028  has_left = tmp & 1; // has_left_eye_view
7029 
7030  if (has_left && has_right)
7031  view = AV_STEREO3D_VIEW_PACKED;
7032  else if (has_left)
7033  view = AV_STEREO3D_VIEW_LEFT;
7034  else if (has_right)
7035  view = AV_STEREO3D_VIEW_RIGHT;
7036  if (has_left || has_right)
7038 
7039  break;
7040  }
7041  case MKTAG('h','e','r','o'): {
7042  int tmp;
7043  if (size != 13) {
7044  av_log(c->fc, AV_LOG_ERROR, "Invalid size of hero box: %d\n", size);
7045  return AVERROR_INVALIDDATA;
7046  }
7047  avio_skip(pb, 1); // version
7048  avio_skip(pb, 3); // flags
7049 
7050  tmp = avio_r8(pb);
7051  if (tmp == 0)
7052  primary_eye = AV_PRIMARY_EYE_NONE;
7053  else if (tmp == 1)
7054  primary_eye = AV_PRIMARY_EYE_LEFT;
7055  else if (tmp == 2)
7056  primary_eye = AV_PRIMARY_EYE_RIGHT;
7057  else
7058  av_log(c->fc, AV_LOG_WARNING, "Unknown hero eye type: %d\n", tmp);
7059 
7060  break;
7061  }
7062  case MKTAG('c','a','m','s'): {
7063  uint32_t subtag;
7064  int subsize;
7065  if (size != 24) {
7066  av_log(c->fc, AV_LOG_ERROR, "Invalid size of cams box: %d\n", size);
7067  return AVERROR_INVALIDDATA;
7068  }
7069 
7070  subsize = avio_rb32(pb);
7071  if (subsize != 16) {
7072  av_log(c->fc, AV_LOG_ERROR, "Invalid size of blin box: %d\n", size);
7073  return AVERROR_INVALIDDATA;
7074  }
7075 
7076  subtag = avio_rl32(pb);
7077  if (subtag != MKTAG('b','l','i','n')) {
7078  av_log(c->fc, AV_LOG_ERROR, "Expected blin box, got %s\n",
7079  av_fourcc2str(subtag));
7080  return AVERROR_INVALIDDATA;
7081  }
7082 
7083  avio_skip(pb, 1); // version
7084  avio_skip(pb, 3); // flags
7085 
7086  baseline = avio_rb32(pb);
7087 
7088  break;
7089  }
7090  case MKTAG('c','m','f','y'): {
7091  uint32_t subtag;
7092  int subsize;
7093  int32_t adjustment;
7094  if (size != 24) {
7095  av_log(c->fc, AV_LOG_ERROR, "Invalid size of cmfy box: %d\n", size);
7096  return AVERROR_INVALIDDATA;
7097  }
7098 
7099  subsize = avio_rb32(pb);
7100  if (subsize != 16) {
7101  av_log(c->fc, AV_LOG_ERROR, "Invalid size of dadj box: %d\n", size);
7102  return AVERROR_INVALIDDATA;
7103  }
7104 
7105  subtag = avio_rl32(pb);
7106  if (subtag != MKTAG('d','a','d','j')) {
7107  av_log(c->fc, AV_LOG_ERROR, "Expected dadj box, got %s\n",
7108  av_fourcc2str(subtag));
7109  return AVERROR_INVALIDDATA;
7110  }
7111 
7112  avio_skip(pb, 1); // version
7113  avio_skip(pb, 3); // flags
7114 
7115  adjustment = (int32_t) avio_rb32(pb);
7116 
7117  horizontal_disparity_adjustment.num = (int) adjustment;
7118  horizontal_disparity_adjustment.den = 10000;
7119 
7120  break;
7121  }
7122  default:
7123  av_log(c->fc, AV_LOG_WARNING, "Unknown tag in eyes: %s\n",
7124  av_fourcc2str(tag));
7125  avio_skip(pb, size - 8);
7126  break;
7127  }
7128  remaining -= size;
7129  }
7130 
7131  if (remaining != 0) {
7132  av_log(c->fc, AV_LOG_ERROR, "Broken eyes box\n");
7133  return AVERROR_INVALIDDATA;
7134  }
7135 
7136  if (type == AV_STEREO3D_2D)
7137  return 0;
7138 
7139  if (!sc->stereo3d) {
7141  if (!sc->stereo3d)
7142  return AVERROR(ENOMEM);
7143  }
7144 
7145  sc->stereo3d->flags = flags;
7146  sc->stereo3d->type = type;
7147  sc->stereo3d->view = view;
7148  sc->stereo3d->primary_eye = primary_eye;
7149  sc->stereo3d->baseline = baseline;
7150  sc->stereo3d->horizontal_disparity_adjustment = horizontal_disparity_adjustment;
7151 
7152  return 0;
7153 }
7154 
7156 {
7157  int size;
7158  int64_t remaining;
7159  uint32_t tag;
7160 
7161  if (c->fc->nb_streams < 1)
7162  return 0;
7163 
7164  if (atom.size < 8) {
7165  av_log(c->fc, AV_LOG_ERROR, "Empty video extension usage box\n");
7166  return AVERROR_INVALIDDATA;
7167  }
7168 
7169  remaining = atom.size;
7170  while (remaining > 0) {
7171  size = avio_rb32(pb);
7172  if (size < 8 || size > remaining ) {
7173  av_log(c->fc, AV_LOG_ERROR, "Invalid child size in vexu box\n");
7174  return AVERROR_INVALIDDATA;
7175  }
7176 
7177  tag = avio_rl32(pb);
7178  switch (tag) {
7179  case MKTAG('p','r','o','j'): {
7180  MOVAtom proj = { tag, size - 8 };
7181  int ret = mov_read_vexu_proj(c, pb, proj);
7182  if (ret < 0)
7183  return ret;
7184  break;
7185  }
7186  case MKTAG('e','y','e','s'): {
7187  MOVAtom eyes = { tag, size - 8 };
7188  int ret = mov_read_eyes(c, pb, eyes);
7189  if (ret < 0)
7190  return ret;
7191  break;
7192  }
7193  case MKTAG('p','a','c','k'): {
7194  MOVAtom pack = { tag, size - 8 };
7195  int ret = mov_read_pack(c, pb, pack);
7196  if (ret < 0)
7197  return ret;
7198  break;
7199  }
7200  default:
7201  av_log(c->fc, AV_LOG_WARNING, "Unknown tag in vexu: %s\n",
7202  av_fourcc2str(tag));
7203  avio_skip(pb, size - 8);
7204  break;
7205  }
7206  remaining -= size;
7207  }
7208 
7209  if (remaining != 0) {
7210  av_log(c->fc, AV_LOG_ERROR, "Broken vexu box\n");
7211  return AVERROR_INVALIDDATA;
7212  }
7213 
7214  return 0;
7215 }
7216 
7218 {
7219  AVStream *st;
7220  MOVStreamContext *sc;
7221 
7222  if (c->fc->nb_streams < 1)
7223  return 0;
7224 
7225  st = c->fc->streams[c->fc->nb_streams - 1];
7226  sc = st->priv_data;
7227 
7228  if (atom.size != 4) {
7229  av_log(c->fc, AV_LOG_ERROR, "Invalid size of hfov box: %"PRIu64"\n", atom.size);
7230  return AVERROR_INVALIDDATA;
7231  }
7232 
7233 
7234  if (!sc->stereo3d) {
7236  if (!sc->stereo3d)
7237  return AVERROR(ENOMEM);
7238  }
7239 
7241  sc->stereo3d->horizontal_field_of_view.den = 1000; // thousands of a degree
7242 
7243  return 0;
7244 }
7245 
7247 {
7248  int ret = 0;
7249  uint8_t *buffer = av_malloc(len + 1);
7250  const char *val;
7251 
7252  if (!buffer)
7253  return AVERROR(ENOMEM);
7254  buffer[len] = '\0';
7255 
7256  ret = ffio_read_size(pb, buffer, len);
7257  if (ret < 0)
7258  goto out;
7259 
7260  /* Check for mandatory keys and values, try to support XML as best-effort */
7261  if (!sc->spherical &&
7262  av_stristr(buffer, "<GSpherical:StitchingSoftware>") &&
7263  (val = av_stristr(buffer, "<GSpherical:Spherical>")) &&
7264  av_stristr(val, "true") &&
7265  (val = av_stristr(buffer, "<GSpherical:Stitched>")) &&
7266  av_stristr(val, "true") &&
7267  (val = av_stristr(buffer, "<GSpherical:ProjectionType>")) &&
7268  av_stristr(val, "equirectangular")) {
7270  if (!sc->spherical)
7271  goto out;
7272 
7274 
7275  if (av_stristr(buffer, "<GSpherical:StereoMode>") && !sc->stereo3d) {
7276  enum AVStereo3DType mode;
7277 
7278  if (av_stristr(buffer, "left-right"))
7280  else if (av_stristr(buffer, "top-bottom"))
7282  else
7283  mode = AV_STEREO3D_2D;
7284 
7286  if (!sc->stereo3d)
7287  goto out;
7288 
7289  sc->stereo3d->type = mode;
7290  }
7291 
7292  /* orientation */
7293  val = av_stristr(buffer, "<GSpherical:InitialViewHeadingDegrees>");
7294  if (val)
7295  sc->spherical->yaw = strtol(val, NULL, 10) * (1 << 16);
7296  val = av_stristr(buffer, "<GSpherical:InitialViewPitchDegrees>");
7297  if (val)
7298  sc->spherical->pitch = strtol(val, NULL, 10) * (1 << 16);
7299  val = av_stristr(buffer, "<GSpherical:InitialViewRollDegrees>");
7300  if (val)
7301  sc->spherical->roll = strtol(val, NULL, 10) * (1 << 16);
7302  }
7303 
7304 out:
7305  av_free(buffer);
7306  return ret;
7307 }
7308 
7310 {
7311  AVStream *st;
7312  MOVStreamContext *sc;
7313  int64_t ret;
7314  AVUUID uuid;
7315  static const AVUUID uuid_isml_manifest = {
7316  0xa5, 0xd4, 0x0b, 0x30, 0xe8, 0x14, 0x11, 0xdd,
7317  0xba, 0x2f, 0x08, 0x00, 0x20, 0x0c, 0x9a, 0x66
7318  };
7319  static const AVUUID uuid_xmp = {
7320  0xbe, 0x7a, 0xcf, 0xcb, 0x97, 0xa9, 0x42, 0xe8,
7321  0x9c, 0x71, 0x99, 0x94, 0x91, 0xe3, 0xaf, 0xac
7322  };
7323  static const AVUUID uuid_spherical = {
7324  0xff, 0xcc, 0x82, 0x63, 0xf8, 0x55, 0x4a, 0x93,
7325  0x88, 0x14, 0x58, 0x7a, 0x02, 0x52, 0x1f, 0xdd,
7326  };
7327 
7328  if (atom.size < AV_UUID_LEN || atom.size >= FFMIN(INT_MAX, SIZE_MAX))
7329  return AVERROR_INVALIDDATA;
7330 
7331  if (c->fc->nb_streams < 1)
7332  return 0;
7333  st = c->fc->streams[c->fc->nb_streams - 1];
7334  sc = st->priv_data;
7335 
7336  ret = ffio_read_size(pb, uuid, AV_UUID_LEN);
7337  if (ret < 0)
7338  return ret;
7339  if (av_uuid_equal(uuid, uuid_isml_manifest)) {
7340  uint8_t *buffer, *ptr;
7341  char *endptr;
7342  size_t len = atom.size - AV_UUID_LEN;
7343 
7344  if (len < 4) {
7345  return AVERROR_INVALIDDATA;
7346  }
7347  ret = avio_skip(pb, 4); // zeroes
7348  len -= 4;
7349 
7350  buffer = av_mallocz(len + 1);
7351  if (!buffer) {
7352  return AVERROR(ENOMEM);
7353  }
7354  ret = ffio_read_size(pb, buffer, len);
7355  if (ret < 0) {
7356  av_free(buffer);
7357  return ret;
7358  }
7359 
7360  ptr = buffer;
7361  while ((ptr = av_stristr(ptr, "systemBitrate=\""))) {
7362  ptr += sizeof("systemBitrate=\"") - 1;
7363  c->bitrates_count++;
7364  c->bitrates = av_realloc_f(c->bitrates, c->bitrates_count, sizeof(*c->bitrates));
7365  if (!c->bitrates) {
7366  c->bitrates_count = 0;
7367  av_free(buffer);
7368  return AVERROR(ENOMEM);
7369  }
7370  errno = 0;
7371  ret = strtol(ptr, &endptr, 10);
7372  if (ret < 0 || errno || *endptr != '"') {
7373  c->bitrates[c->bitrates_count - 1] = 0;
7374  } else {
7375  c->bitrates[c->bitrates_count - 1] = ret;
7376  }
7377  }
7378 
7379  av_free(buffer);
7380  } else if (av_uuid_equal(uuid, uuid_xmp)) {
7381  uint8_t *buffer;
7382  size_t len = atom.size - AV_UUID_LEN;
7383  if (c->export_xmp) {
7384  buffer = av_mallocz(len + 1);
7385  if (!buffer) {
7386  return AVERROR(ENOMEM);
7387  }
7388  ret = ffio_read_size(pb, buffer, len);
7389  if (ret < 0) {
7390  av_free(buffer);
7391  return ret;
7392  }
7393  buffer[len] = '\0';
7394  av_dict_set(&c->fc->metadata, "xmp",
7396  } else {
7397  // skip all uuid atom, which makes it fast for long uuid-xmp file
7398  ret = avio_skip(pb, len);
7399  if (ret < 0)
7400  return ret;
7401  }
7402  } else if (av_uuid_equal(uuid, uuid_spherical)) {
7403  size_t len = atom.size - AV_UUID_LEN;
7404  ret = mov_parse_uuid_spherical(sc, pb, len);
7405  if (ret < 0)
7406  return ret;
7407  if (!sc->spherical)
7408  av_log(c->fc, AV_LOG_WARNING, "Invalid spherical metadata found\n");
7409  }
7410 
7411  return 0;
7412 }
7413 
7415 {
7416  int ret;
7417  uint8_t content[16];
7418 
7419  if (atom.size < 8)
7420  return 0;
7421 
7422  ret = ffio_read_size(pb, content, FFMIN(sizeof(content), atom.size));
7423  if (ret < 0)
7424  return ret;
7425 
7426  if ( !c->found_moov
7427  && !c->found_mdat
7428  && !memcmp(content, "Anevia\x1A\x1A", 8)
7429  && c->use_mfra_for == FF_MOV_FLAG_MFRA_AUTO) {
7430  c->use_mfra_for = FF_MOV_FLAG_MFRA_PTS;
7431  }
7432 
7433  return 0;
7434 }
7435 
7437 {
7438  uint32_t format = avio_rl32(pb);
7439  MOVStreamContext *sc;
7440  enum AVCodecID id;
7441  AVStream *st;
7442 
7443  if (c->fc->nb_streams < 1)
7444  return 0;
7445  st = c->fc->streams[c->fc->nb_streams - 1];
7446  sc = st->priv_data;
7447 
7448  switch (sc->format)
7449  {
7450  case MKTAG('e','n','c','v'): // encrypted video
7451  case MKTAG('e','n','c','a'): // encrypted audio
7452  id = mov_codec_id(st, format);
7453  if (st->codecpar->codec_id != AV_CODEC_ID_NONE &&
7454  st->codecpar->codec_id != id) {
7455  av_log(c->fc, AV_LOG_WARNING,
7456  "ignoring 'frma' atom of '%.4s', stream has codec id %d\n",
7457  (char*)&format, st->codecpar->codec_id);
7458  break;
7459  }
7460 
7461  st->codecpar->codec_id = id;
7462  sc->format = format;
7463  break;
7464 
7465  default:
7466  if (format != sc->format) {
7467  av_log(c->fc, AV_LOG_WARNING,
7468  "ignoring 'frma' atom of '%.4s', stream format is '%.4s'\n",
7469  (char*)&format, (char*)&sc->format);
7470  }
7471  break;
7472  }
7473 
7474  return 0;
7475 }
7476 
7477 /**
7478  * Gets the current encryption info and associated current stream context. If
7479  * we are parsing a track fragment, this will return the specific encryption
7480  * info for this fragment; otherwise this will return the global encryption
7481  * info for the current stream.
7482  */
7484 {
7485  MOVFragmentStreamInfo *frag_stream_info;
7486  AVStream *st;
7487  int i;
7488 
7489  frag_stream_info = get_current_frag_stream_info(&c->frag_index);
7490  if (frag_stream_info) {
7491  for (i = 0; i < c->fc->nb_streams; i++) {
7492  *sc = c->fc->streams[i]->priv_data;
7493  if ((*sc)->id == frag_stream_info->id) {
7494  st = c->fc->streams[i];
7495  break;
7496  }
7497  }
7498  if (i == c->fc->nb_streams)
7499  return 0;
7500  *sc = st->priv_data;
7501 
7502  if (!frag_stream_info->encryption_index) {
7503  // If this stream isn't encrypted, don't create the index.
7504  if (!(*sc)->cenc.default_encrypted_sample)
7505  return 0;
7506  frag_stream_info->encryption_index = av_mallocz(sizeof(*frag_stream_info->encryption_index));
7507  if (!frag_stream_info->encryption_index)
7508  return AVERROR(ENOMEM);
7509  }
7510  *encryption_index = frag_stream_info->encryption_index;
7511  return 1;
7512  } else {
7513  // No current track fragment, using stream level encryption info.
7514 
7515  if (c->fc->nb_streams < 1)
7516  return 0;
7517  st = c->fc->streams[c->fc->nb_streams - 1];
7518  *sc = st->priv_data;
7519 
7520  if (!(*sc)->cenc.encryption_index) {
7521  // If this stream isn't encrypted, don't create the index.
7522  if (!(*sc)->cenc.default_encrypted_sample)
7523  return 0;
7524  (*sc)->cenc.encryption_index = av_mallocz(sizeof(*frag_stream_info->encryption_index));
7525  if (!(*sc)->cenc.encryption_index)
7526  return AVERROR(ENOMEM);
7527  }
7528 
7529  *encryption_index = (*sc)->cenc.encryption_index;
7530  return 1;
7531  }
7532 }
7533 
7535 {
7536  int i, ret;
7537  unsigned int subsample_count;
7538  AVSubsampleEncryptionInfo *subsamples;
7539 
7540  if (!sc->cenc.default_encrypted_sample) {
7541  av_log(c->fc, AV_LOG_ERROR, "Missing schm or tenc\n");
7542  return AVERROR_INVALIDDATA;
7543  }
7544 
7545  if (sc->cenc.per_sample_iv_size || use_subsamples) {
7547  if (!*sample)
7548  return AVERROR(ENOMEM);
7549  } else
7550  *sample = NULL;
7551 
7552  if (sc->cenc.per_sample_iv_size != 0) {
7553  if ((ret = ffio_read_size(pb, (*sample)->iv, sc->cenc.per_sample_iv_size)) < 0) {
7554  av_log(c->fc, AV_LOG_ERROR, "failed to read the initialization vector\n");
7556  *sample = NULL;
7557  return ret;
7558  }
7559  }
7560 
7561  if (use_subsamples) {
7562  subsample_count = avio_rb16(pb);
7563  av_free((*sample)->subsamples);
7564  (*sample)->subsamples = av_calloc(subsample_count, sizeof(*subsamples));
7565  if (!(*sample)->subsamples) {
7567  *sample = NULL;
7568  return AVERROR(ENOMEM);
7569  }
7570 
7571  for (i = 0; i < subsample_count && !pb->eof_reached; i++) {
7572  (*sample)->subsamples[i].bytes_of_clear_data = avio_rb16(pb);
7573  (*sample)->subsamples[i].bytes_of_protected_data = avio_rb32(pb);
7574  }
7575 
7576  if (pb->eof_reached) {
7577  av_log(c->fc, AV_LOG_ERROR, "hit EOF while reading sub-sample encryption info\n");
7579  *sample = NULL;
7580  return AVERROR_INVALIDDATA;
7581  }
7582  (*sample)->subsample_count = subsample_count;
7583  }
7584 
7585  return 0;
7586 }
7587 
7589 {
7590  AVEncryptionInfo **encrypted_samples;
7591  MOVEncryptionIndex *encryption_index;
7592  MOVStreamContext *sc;
7593  int use_subsamples, ret;
7594  unsigned int sample_count, i, alloc_size = 0;
7595 
7596  ret = get_current_encryption_info(c, &encryption_index, &sc);
7597  if (ret != 1)
7598  return ret;
7599 
7600  if (encryption_index->nb_encrypted_samples) {
7601  // This can happen if we have both saio/saiz and senc atoms.
7602  av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in senc\n");
7603  return 0;
7604  }
7605 
7606  avio_r8(pb); /* version */
7607  use_subsamples = avio_rb24(pb) & 0x02; /* flags */
7608 
7609  sample_count = avio_rb32(pb);
7610  if (sample_count >= INT_MAX / sizeof(*encrypted_samples))
7611  return AVERROR(ENOMEM);
7612 
7613  for (i = 0; i < sample_count; i++) {
7614  unsigned int min_samples = FFMIN(FFMAX(i + 1, 1024 * 1024), sample_count);
7615  encrypted_samples = av_fast_realloc(encryption_index->encrypted_samples, &alloc_size,
7616  min_samples * sizeof(*encrypted_samples));
7617  if (encrypted_samples) {
7618  encryption_index->encrypted_samples = encrypted_samples;
7619 
7621  c, pb, sc, &encryption_index->encrypted_samples[i], use_subsamples);
7622  } else {
7623  ret = AVERROR(ENOMEM);
7624  }
7625  if (pb->eof_reached) {
7626  av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading senc\n");
7627  if (ret >= 0)
7628  av_encryption_info_free(encryption_index->encrypted_samples[i]);
7630  }
7631 
7632  if (ret < 0) {
7633  for (; i > 0; i--)
7634  av_encryption_info_free(encryption_index->encrypted_samples[i - 1]);
7635  av_freep(&encryption_index->encrypted_samples);
7636  return ret;
7637  }
7638  }
7639  encryption_index->nb_encrypted_samples = sample_count;
7640 
7641  return 0;
7642 }
7643 
7645 {
7646  AVEncryptionInfo **sample, **encrypted_samples;
7647  int64_t prev_pos;
7648  size_t sample_count, sample_info_size, i;
7649  int ret = 0;
7650  unsigned int alloc_size = 0;
7651 
7652  if (encryption_index->nb_encrypted_samples)
7653  return 0;
7654  sample_count = encryption_index->auxiliary_info_sample_count;
7655  if (encryption_index->auxiliary_offsets_count != 1) {
7656  av_log(c->fc, AV_LOG_ERROR, "Multiple auxiliary info chunks are not supported\n");
7657  return AVERROR_PATCHWELCOME;
7658  }
7659  if (sample_count >= INT_MAX / sizeof(*encrypted_samples))
7660  return AVERROR(ENOMEM);
7661 
7662  prev_pos = avio_tell(pb);
7663  if (!(pb->seekable & AVIO_SEEKABLE_NORMAL) ||
7664  avio_seek(pb, encryption_index->auxiliary_offsets[0], SEEK_SET) != encryption_index->auxiliary_offsets[0]) {
7665  av_log(c->fc, AV_LOG_INFO, "Failed to seek for auxiliary info, will only parse senc atoms for encryption info\n");
7666  goto finish;
7667  }
7668 
7669  for (i = 0; i < sample_count && !pb->eof_reached; i++) {
7670  unsigned int min_samples = FFMIN(FFMAX(i + 1, 1024 * 1024), sample_count);
7671  encrypted_samples = av_fast_realloc(encryption_index->encrypted_samples, &alloc_size,
7672  min_samples * sizeof(*encrypted_samples));
7673  if (!encrypted_samples) {
7674  ret = AVERROR(ENOMEM);
7675  goto finish;
7676  }
7677  encryption_index->encrypted_samples = encrypted_samples;
7678 
7679  sample = &encryption_index->encrypted_samples[i];
7680  sample_info_size = encryption_index->auxiliary_info_default_size
7681  ? encryption_index->auxiliary_info_default_size
7682  : encryption_index->auxiliary_info_sizes[i];
7683 
7684  ret = mov_read_sample_encryption_info(c, pb, sc, sample, sample_info_size > sc->cenc.per_sample_iv_size);
7685  if (ret < 0)
7686  goto finish;
7687  }
7688  if (pb->eof_reached) {
7689  av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading auxiliary info\n");
7691  } else {
7692  encryption_index->nb_encrypted_samples = sample_count;
7693  }
7694 
7695 finish:
7696  avio_seek(pb, prev_pos, SEEK_SET);
7697  if (ret < 0) {
7698  for (; i > 0; i--) {
7699  av_encryption_info_free(encryption_index->encrypted_samples[i - 1]);
7700  }
7701  av_freep(&encryption_index->encrypted_samples);
7702  }
7703  return ret;
7704 }
7705 
7707 {
7708  MOVEncryptionIndex *encryption_index;
7709  MOVStreamContext *sc;
7710  int ret;
7711  unsigned int sample_count, aux_info_type, aux_info_param;
7712 
7713  ret = get_current_encryption_info(c, &encryption_index, &sc);
7714  if (ret != 1)
7715  return ret;
7716 
7717  if (encryption_index->nb_encrypted_samples) {
7718  // This can happen if we have both saio/saiz and senc atoms.
7719  av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in saiz\n");
7720  return 0;
7721  }
7722 
7723  if (encryption_index->auxiliary_info_sample_count) {
7724  av_log(c->fc, AV_LOG_ERROR, "Duplicate saiz atom\n");
7725  return AVERROR_INVALIDDATA;
7726  }
7727 
7728  avio_r8(pb); /* version */
7729  if (avio_rb24(pb) & 0x01) { /* flags */
7730  aux_info_type = avio_rb32(pb);
7731  aux_info_param = avio_rb32(pb);
7732  if (sc->cenc.default_encrypted_sample) {
7733  if (aux_info_type != sc->cenc.default_encrypted_sample->scheme) {
7734  av_log(c->fc, AV_LOG_DEBUG, "Ignoring saiz box with non-zero aux_info_type\n");
7735  return 0;
7736  }
7737  if (aux_info_param != 0) {
7738  av_log(c->fc, AV_LOG_DEBUG, "Ignoring saiz box with non-zero aux_info_type_parameter\n");
7739  return 0;
7740  }
7741  } else {
7742  // Didn't see 'schm' or 'tenc', so this isn't encrypted.
7743  if ((aux_info_type == MKBETAG('c','e','n','c') ||
7744  aux_info_type == MKBETAG('c','e','n','s') ||
7745  aux_info_type == MKBETAG('c','b','c','1') ||
7746  aux_info_type == MKBETAG('c','b','c','s')) &&
7747  aux_info_param == 0) {
7748  av_log(c->fc, AV_LOG_ERROR, "Saw encrypted saiz without schm/tenc\n");
7749  return AVERROR_INVALIDDATA;
7750  } else {
7751  return 0;
7752  }
7753  }
7754  } else if (!sc->cenc.default_encrypted_sample) {
7755  // Didn't see 'schm' or 'tenc', so this isn't encrypted.
7756  return 0;
7757  }
7758 
7759  encryption_index->auxiliary_info_default_size = avio_r8(pb);
7760  sample_count = avio_rb32(pb);
7761 
7762  if (encryption_index->auxiliary_info_default_size == 0) {
7763  if (sample_count == 0)
7764  return AVERROR_INVALIDDATA;
7765 
7766  encryption_index->auxiliary_info_sizes = av_malloc(sample_count);
7767  if (!encryption_index->auxiliary_info_sizes)
7768  return AVERROR(ENOMEM);
7769 
7770  ret = avio_read(pb, encryption_index->auxiliary_info_sizes, sample_count);
7771  if (ret != sample_count) {
7772  av_freep(&encryption_index->auxiliary_info_sizes);
7773 
7774  if (ret >= 0)
7776  av_log(c->fc, AV_LOG_ERROR, "Failed to read the auxiliary info, %s\n",
7777  av_err2str(ret));
7778  return ret;
7779  }
7780  }
7781  encryption_index->auxiliary_info_sample_count = sample_count;
7782 
7783  if (encryption_index->auxiliary_offsets_count) {
7784  return mov_parse_auxiliary_info(c, sc, pb, encryption_index);
7785  }
7786 
7787  return 0;
7788 }
7789 
7791 {
7792  uint64_t *auxiliary_offsets;
7793  MOVEncryptionIndex *encryption_index;
7794  MOVStreamContext *sc;
7795  int i, ret;
7796  unsigned int version, entry_count, aux_info_type, aux_info_param;
7797  unsigned int alloc_size = 0;
7798 
7799  ret = get_current_encryption_info(c, &encryption_index, &sc);
7800  if (ret != 1)
7801  return ret;
7802 
7803  if (encryption_index->nb_encrypted_samples) {
7804  // This can happen if we have both saio/saiz and senc atoms.
7805  av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in saio\n");
7806  return 0;
7807  }
7808 
7809  if (encryption_index->auxiliary_offsets_count) {
7810  av_log(c->fc, AV_LOG_ERROR, "Duplicate saio atom\n");
7811  return AVERROR_INVALIDDATA;
7812  }
7813 
7814  version = avio_r8(pb); /* version */
7815  if (avio_rb24(pb) & 0x01) { /* flags */
7816  aux_info_type = avio_rb32(pb);
7817  aux_info_param = avio_rb32(pb);
7818  if (sc->cenc.default_encrypted_sample) {
7819  if (aux_info_type != sc->cenc.default_encrypted_sample->scheme) {
7820  av_log(c->fc, AV_LOG_DEBUG, "Ignoring saio box with non-zero aux_info_type\n");
7821  return 0;
7822  }
7823  if (aux_info_param != 0) {
7824  av_log(c->fc, AV_LOG_DEBUG, "Ignoring saio box with non-zero aux_info_type_parameter\n");
7825  return 0;
7826  }
7827  } else {
7828  // Didn't see 'schm' or 'tenc', so this isn't encrypted.
7829  if ((aux_info_type == MKBETAG('c','e','n','c') ||
7830  aux_info_type == MKBETAG('c','e','n','s') ||
7831  aux_info_type == MKBETAG('c','b','c','1') ||
7832  aux_info_type == MKBETAG('c','b','c','s')) &&
7833  aux_info_param == 0) {
7834  av_log(c->fc, AV_LOG_ERROR, "Saw encrypted saio without schm/tenc\n");
7835  return AVERROR_INVALIDDATA;
7836  } else {
7837  return 0;
7838  }
7839  }
7840  } else if (!sc->cenc.default_encrypted_sample) {
7841  // Didn't see 'schm' or 'tenc', so this isn't encrypted.
7842  return 0;
7843  }
7844 
7845  entry_count = avio_rb32(pb);
7846  if (entry_count >= INT_MAX / sizeof(*auxiliary_offsets))
7847  return AVERROR(ENOMEM);
7848 
7849  for (i = 0; i < entry_count && !pb->eof_reached; i++) {
7850  unsigned int min_offsets = FFMIN(FFMAX(i + 1, 1024), entry_count);
7851  auxiliary_offsets = av_fast_realloc(
7852  encryption_index->auxiliary_offsets, &alloc_size,
7853  min_offsets * sizeof(*auxiliary_offsets));
7854  if (!auxiliary_offsets) {
7855  av_freep(&encryption_index->auxiliary_offsets);
7856  return AVERROR(ENOMEM);
7857  }
7858  encryption_index->auxiliary_offsets = auxiliary_offsets;
7859 
7860  if (version == 0) {
7861  encryption_index->auxiliary_offsets[i] = avio_rb32(pb);
7862  } else {
7863  encryption_index->auxiliary_offsets[i] = avio_rb64(pb);
7864  }
7865  if (c->frag_index.current >= 0) {
7866  encryption_index->auxiliary_offsets[i] += c->fragment.base_data_offset;
7867  }
7868  }
7869 
7870  if (pb->eof_reached) {
7871  av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading saio\n");
7872  av_freep(&encryption_index->auxiliary_offsets);
7873  return AVERROR_INVALIDDATA;
7874  }
7875 
7876  encryption_index->auxiliary_offsets_count = entry_count;
7877 
7878  if (encryption_index->auxiliary_info_sample_count) {
7879  return mov_parse_auxiliary_info(c, sc, pb, encryption_index);
7880  }
7881 
7882  return 0;
7883 }
7884 
7886 {
7887  AVEncryptionInitInfo *info, *old_init_info;
7888  uint8_t **key_ids;
7889  AVStream *st;
7890  const AVPacketSideData *old_side_data;
7891  uint8_t *side_data, *extra_data;
7892  size_t side_data_size;
7893  int ret = 0;
7894  unsigned int version, kid_count, extra_data_size, alloc_size = 0;
7895 
7896  if (c->fc->nb_streams < 1)
7897  return 0;
7898  st = c->fc->streams[c->fc->nb_streams-1];
7899 
7900  version = avio_r8(pb); /* version */
7901  avio_rb24(pb); /* flags */
7902 
7903  info = av_encryption_init_info_alloc(/* system_id_size */ 16, /* num_key_ids */ 0,
7904  /* key_id_size */ 16, /* data_size */ 0);
7905  if (!info)
7906  return AVERROR(ENOMEM);
7907 
7908  if ((ret = ffio_read_size(pb, info->system_id, 16)) < 0) {
7909  av_log(c->fc, AV_LOG_ERROR, "Failed to read the system id\n");
7910  goto finish;
7911  }
7912 
7913  if (version > 0) {
7914  kid_count = avio_rb32(pb);
7915  if (kid_count >= INT_MAX / sizeof(*key_ids)) {
7916  ret = AVERROR(ENOMEM);
7917  goto finish;
7918  }
7919 
7920  for (unsigned int i = 0; i < kid_count && !pb->eof_reached; i++) {
7921  unsigned int min_kid_count = FFMIN(FFMAX(i + 1, 1024), kid_count);
7922  key_ids = av_fast_realloc(info->key_ids, &alloc_size,
7923  min_kid_count * sizeof(*key_ids));
7924  if (!key_ids) {
7925  ret = AVERROR(ENOMEM);
7926  goto finish;
7927  }
7928  info->key_ids = key_ids;
7929 
7930  info->key_ids[i] = av_mallocz(16);
7931  if (!info->key_ids[i]) {
7932  ret = AVERROR(ENOMEM);
7933  goto finish;
7934  }
7935  info->num_key_ids = i + 1;
7936 
7937  if ((ret = ffio_read_size(pb, info->key_ids[i], 16)) < 0) {
7938  av_log(c->fc, AV_LOG_ERROR, "Failed to read the key id\n");
7939  goto finish;
7940  }
7941  }
7942 
7943  if (pb->eof_reached) {
7944  av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading pssh\n");
7946  goto finish;
7947  }
7948  }
7949 
7950  extra_data_size = avio_rb32(pb);
7951  extra_data = av_malloc(extra_data_size);
7952  if (!extra_data) {
7953  ret = AVERROR(ENOMEM);
7954  goto finish;
7955  }
7956  ret = avio_read(pb, extra_data, extra_data_size);
7957  if (ret != extra_data_size) {
7958  av_free(extra_data);
7959 
7960  if (ret >= 0)
7962  goto finish;
7963  }
7964 
7965  av_freep(&info->data); // malloc(0) may still allocate something.
7966  info->data = extra_data;
7967  info->data_size = extra_data_size;
7968 
7969  // If there is existing initialization data, append to the list.
7972  if (old_side_data) {
7973  old_init_info = av_encryption_init_info_get_side_data(old_side_data->data, old_side_data->size);
7974  if (old_init_info) {
7975  // Append to the end of the list.
7976  for (AVEncryptionInitInfo *cur = old_init_info;; cur = cur->next) {
7977  if (!cur->next) {
7978  cur->next = info;
7979  break;
7980  }
7981  }
7982  info = old_init_info;
7983  } else {
7984  // Assume existing side-data will be valid, so the only error we could get is OOM.
7985  ret = AVERROR(ENOMEM);
7986  goto finish;
7987  }
7988  }
7989 
7990  side_data = av_encryption_init_info_add_side_data(info, &side_data_size);
7991  if (!side_data) {
7992  ret = AVERROR(ENOMEM);
7993  goto finish;
7994  }
7998  side_data, side_data_size, 0))
7999  av_free(side_data);
8000 
8001 finish:
8003  return ret;
8004 }
8005 
8007 {
8008  AVStream *st;
8009  MOVStreamContext *sc;
8010 
8011  if (c->fc->nb_streams < 1)
8012  return 0;
8013  st = c->fc->streams[c->fc->nb_streams-1];
8014  sc = st->priv_data;
8015 
8016  if (sc->pseudo_stream_id != 0) {
8017  av_log(c->fc, AV_LOG_ERROR, "schm boxes are only supported in first sample descriptor\n");
8018  return AVERROR_PATCHWELCOME;
8019  }
8020 
8021  if (atom.size < 8)
8022  return AVERROR_INVALIDDATA;
8023 
8024  avio_rb32(pb); /* version and flags */
8025 
8026  if (!sc->cenc.default_encrypted_sample) {
8028  if (!sc->cenc.default_encrypted_sample) {
8029  return AVERROR(ENOMEM);
8030  }
8031  }
8032 
8034  return 0;
8035 }
8036 
8038 {
8039  AVStream *st;
8040  MOVStreamContext *sc;
8041  unsigned int version, pattern, is_protected, iv_size;
8042 
8043  if (c->fc->nb_streams < 1)
8044  return 0;
8045  st = c->fc->streams[c->fc->nb_streams-1];
8046  sc = st->priv_data;
8047 
8048  if (sc->pseudo_stream_id != 0) {
8049  av_log(c->fc, AV_LOG_ERROR, "tenc atom are only supported in first sample descriptor\n");
8050  return AVERROR_PATCHWELCOME;
8051  }
8052 
8053  if (!sc->cenc.default_encrypted_sample) {
8055  if (!sc->cenc.default_encrypted_sample) {
8056  return AVERROR(ENOMEM);
8057  }
8058  }
8059 
8060  if (atom.size < 20)
8061  return AVERROR_INVALIDDATA;
8062 
8063  version = avio_r8(pb); /* version */
8064  avio_rb24(pb); /* flags */
8065 
8066  avio_r8(pb); /* reserved */
8067  pattern = avio_r8(pb);
8068 
8069  if (version > 0) {
8070  sc->cenc.default_encrypted_sample->crypt_byte_block = pattern >> 4;
8071  sc->cenc.default_encrypted_sample->skip_byte_block = pattern & 0xf;
8072  }
8073 
8074  is_protected = avio_r8(pb);
8075  if (is_protected && !sc->cenc.encryption_index) {
8076  // The whole stream should be by-default encrypted.
8078  if (!sc->cenc.encryption_index)
8079  return AVERROR(ENOMEM);
8080  }
8081  sc->cenc.per_sample_iv_size = avio_r8(pb);
8082  if (sc->cenc.per_sample_iv_size != 0 && sc->cenc.per_sample_iv_size != 8 &&
8083  sc->cenc.per_sample_iv_size != 16) {
8084  av_log(c->fc, AV_LOG_ERROR, "invalid per-sample IV size value\n");
8085  return AVERROR_INVALIDDATA;
8086  }
8087  if (avio_read(pb, sc->cenc.default_encrypted_sample->key_id, 16) != 16) {
8088  av_log(c->fc, AV_LOG_ERROR, "failed to read the default key ID\n");
8089  return AVERROR_INVALIDDATA;
8090  }
8091 
8092  if (is_protected && !sc->cenc.per_sample_iv_size) {
8093  iv_size = avio_r8(pb);
8094  if (iv_size != 8 && iv_size != 16) {
8095  av_log(c->fc, AV_LOG_ERROR, "invalid default_constant_IV_size in tenc atom\n");
8096  return AVERROR_INVALIDDATA;
8097  }
8098 
8099  if (avio_read(pb, sc->cenc.default_encrypted_sample->iv, iv_size) != iv_size) {
8100  av_log(c->fc, AV_LOG_ERROR, "failed to read the default IV\n");
8101  return AVERROR_INVALIDDATA;
8102  }
8103  }
8104 
8105  return 0;
8106 }
8107 
8109 {
8110  AVStream *st;
8111  int last, type, size, ret;
8112  uint8_t buf[4];
8113 
8114  if (c->fc->nb_streams < 1)
8115  return 0;
8116  st = c->fc->streams[c->fc->nb_streams-1];
8117 
8118  if ((uint64_t)atom.size > (1<<30) || atom.size < 42)
8119  return AVERROR_INVALIDDATA;
8120 
8121  /* Check FlacSpecificBox version. */
8122  if (avio_r8(pb) != 0)
8123  return AVERROR_INVALIDDATA;
8124 
8125  avio_rb24(pb); /* Flags */
8126 
8127  if (avio_read(pb, buf, sizeof(buf)) != sizeof(buf)) {
8128  av_log(c->fc, AV_LOG_ERROR, "failed to read FLAC metadata block header\n");
8129  return pb->error < 0 ? pb->error : AVERROR_INVALIDDATA;
8130  }
8131  flac_parse_block_header(buf, &last, &type, &size);
8132 
8134  av_log(c->fc, AV_LOG_ERROR, "STREAMINFO must be first FLACMetadataBlock\n");
8135  return AVERROR_INVALIDDATA;
8136  }
8137 
8138  ret = ff_get_extradata(c->fc, st->codecpar, pb, size);
8139  if (ret < 0)
8140  return ret;
8141 
8142  if (!last)
8143  av_log(c->fc, AV_LOG_WARNING, "non-STREAMINFO FLACMetadataBlock(s) ignored\n");
8144 
8145  return 0;
8146 }
8147 
8148 static int get_key_from_kid(uint8_t* out, int len, MOVContext *c, AVEncryptionInfo *sample) {
8149  AVDictionaryEntry *key_entry_hex;
8150  char kid_hex[16*2+1];
8151 
8152  if (c->decryption_default_key && c->decryption_default_key_len != len) {
8153  av_log(c->fc, AV_LOG_ERROR, "invalid default decryption key length: got %d, expected %d\n", c->decryption_default_key_len, len);
8154  return -1;
8155  }
8156 
8157  if (!c->decryption_keys) {
8158  av_assert0(c->decryption_default_key);
8159  memcpy(out, c->decryption_default_key, len);
8160  return 0;
8161  }
8162 
8163  if (sample->key_id_size != 16) {
8164  av_log(c->fc, AV_LOG_ERROR, "invalid key ID size: got %u, expected 16\n", sample->key_id_size);
8165  return -1;
8166  }
8167 
8168  ff_data_to_hex(kid_hex, sample->key_id, 16, 1);
8169  key_entry_hex = av_dict_get(c->decryption_keys, kid_hex, NULL, AV_DICT_DONT_STRDUP_KEY|AV_DICT_DONT_STRDUP_VAL);
8170  if (!key_entry_hex) {
8171  if (!c->decryption_default_key) {
8172  av_log(c->fc, AV_LOG_ERROR, "unable to find KID %s\n", kid_hex);
8173  return -1;
8174  }
8175  memcpy(out, c->decryption_default_key, len);
8176  return 0;
8177  }
8178  if (strlen(key_entry_hex->value) != len*2) {
8179  return -1;
8180  }
8181  ff_hex_to_data(out, key_entry_hex->value);
8182  return 0;
8183 }
8184 
8186 {
8187  int i, ret;
8188  int bytes_of_protected_data;
8189  uint8_t decryption_key[AES_CTR_KEY_SIZE];
8190 
8191  if (!sc->cenc.aes_ctr) {
8192  ret = get_key_from_kid(decryption_key, sizeof(decryption_key), c, sample);
8193  if (ret < 0) {
8194  return ret;
8195  }
8196 
8197  /* initialize the cipher */
8198  sc->cenc.aes_ctr = av_aes_ctr_alloc();
8199  if (!sc->cenc.aes_ctr) {
8200  return AVERROR(ENOMEM);
8201  }
8202 
8203  ret = av_aes_ctr_init(sc->cenc.aes_ctr, decryption_key);
8204  if (ret < 0) {
8205  return ret;
8206  }
8207  }
8208 
8210 
8211  if (!sample->subsample_count) {
8212  /* decrypt the whole packet */
8214  return 0;
8215  }
8216 
8217  for (i = 0; i < sample->subsample_count; i++) {
8218  if (sample->subsamples[i].bytes_of_clear_data + (int64_t)sample->subsamples[i].bytes_of_protected_data > size) {
8219  av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n");
8220  return AVERROR_INVALIDDATA;
8221  }
8222 
8223  /* skip the clear bytes */
8224  input += sample->subsamples[i].bytes_of_clear_data;
8225  size -= sample->subsamples[i].bytes_of_clear_data;
8226 
8227  /* decrypt the encrypted bytes */
8228 
8229  bytes_of_protected_data = sample->subsamples[i].bytes_of_protected_data;
8230  av_aes_ctr_crypt(sc->cenc.aes_ctr, input, input, bytes_of_protected_data);
8231 
8232  input += bytes_of_protected_data;
8233  size -= bytes_of_protected_data;
8234  }
8235 
8236  if (size > 0) {
8237  av_log(c->fc, AV_LOG_ERROR, "leftover packet bytes after subsample processing\n");
8238  return AVERROR_INVALIDDATA;
8239  }
8240 
8241  return 0;
8242 }
8243 
8245 {
8246  int i, ret;
8247  int num_of_encrypted_blocks;
8248  uint8_t iv[16];
8249  uint8_t decryption_key[16];
8250 
8251  if (!sc->cenc.aes_ctx) {
8252  ret = get_key_from_kid(decryption_key, sizeof(decryption_key), c, sample);
8253  if (ret < 0) {
8254  return ret;
8255  }
8256 
8257  /* initialize the cipher */
8258  sc->cenc.aes_ctx = av_aes_alloc();
8259  if (!sc->cenc.aes_ctx) {
8260  return AVERROR(ENOMEM);
8261  }
8262 
8263  ret = av_aes_init(sc->cenc.aes_ctx, decryption_key, 16 * 8, 1);
8264  if (ret < 0) {
8265  return ret;
8266  }
8267  }
8268 
8269  memcpy(iv, sample->iv, 16);
8270 
8271  /* whole-block full sample encryption */
8272  if (!sample->subsample_count) {
8273  /* decrypt the whole packet */
8274  av_aes_crypt(sc->cenc.aes_ctx, input, input, size/16, iv, 1);
8275  return 0;
8276  }
8277 
8278  for (i = 0; i < sample->subsample_count; i++) {
8279  if (sample->subsamples[i].bytes_of_clear_data + (int64_t)sample->subsamples[i].bytes_of_protected_data > size) {
8280  av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n");
8281  return AVERROR_INVALIDDATA;
8282  }
8283 
8284  if (sample->subsamples[i].bytes_of_protected_data % 16) {
8285  av_log(c->fc, AV_LOG_ERROR, "subsample BytesOfProtectedData is not a multiple of 16\n");
8286  return AVERROR_INVALIDDATA;
8287  }
8288 
8289  /* skip the clear bytes */
8290  input += sample->subsamples[i].bytes_of_clear_data;
8291  size -= sample->subsamples[i].bytes_of_clear_data;
8292 
8293  /* decrypt the encrypted bytes */
8294  num_of_encrypted_blocks = sample->subsamples[i].bytes_of_protected_data/16;
8295  if (num_of_encrypted_blocks > 0) {
8296  av_aes_crypt(sc->cenc.aes_ctx, input, input, num_of_encrypted_blocks, iv, 1);
8297  }
8298  input += sample->subsamples[i].bytes_of_protected_data;
8299  size -= sample->subsamples[i].bytes_of_protected_data;
8300  }
8301 
8302  if (size > 0) {
8303  av_log(c->fc, AV_LOG_ERROR, "leftover packet bytes after subsample processing\n");
8304  return AVERROR_INVALIDDATA;
8305  }
8306 
8307  return 0;
8308 }
8309 
8311 {
8312  int i, ret, rem_bytes;
8313  uint8_t *data;
8314  uint8_t decryption_key[AES_CTR_KEY_SIZE];
8315 
8316  if (!sc->cenc.aes_ctr) {
8317  ret = get_key_from_kid(decryption_key, sizeof(decryption_key), c, sample);
8318  if (ret < 0) {
8319  return ret;
8320  }
8321 
8322  /* initialize the cipher */
8323  sc->cenc.aes_ctr = av_aes_ctr_alloc();
8324  if (!sc->cenc.aes_ctr) {
8325  return AVERROR(ENOMEM);
8326  }
8327 
8328  ret = av_aes_ctr_init(sc->cenc.aes_ctr, decryption_key);
8329  if (ret < 0) {
8330  return ret;
8331  }
8332  }
8333 
8335 
8336  /* whole-block full sample encryption */
8337  if (!sample->subsample_count) {
8338  /* decrypt the whole packet */
8340  return 0;
8341  } else if (!sample->crypt_byte_block && !sample->skip_byte_block) {
8342  av_log(c->fc, AV_LOG_ERROR, "pattern encryption is not present in 'cens' scheme\n");
8343  return AVERROR_INVALIDDATA;
8344  }
8345 
8346  for (i = 0; i < sample->subsample_count; i++) {
8347  if (sample->subsamples[i].bytes_of_clear_data + (int64_t)sample->subsamples[i].bytes_of_protected_data > size) {
8348  av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n");
8349  return AVERROR_INVALIDDATA;
8350  }
8351 
8352  /* skip the clear bytes */
8353  input += sample->subsamples[i].bytes_of_clear_data;
8354  size -= sample->subsamples[i].bytes_of_clear_data;
8355 
8356  /* decrypt the encrypted bytes */
8357  data = input;
8358  rem_bytes = sample->subsamples[i].bytes_of_protected_data;
8359  while (rem_bytes > 0) {
8360  if (rem_bytes < 16*sample->crypt_byte_block) {
8361  break;
8362  }
8363  av_aes_ctr_crypt(sc->cenc.aes_ctr, data, data, 16*sample->crypt_byte_block);
8364  data += 16*sample->crypt_byte_block;
8365  rem_bytes -= 16*sample->crypt_byte_block;
8366  data += FFMIN(16*sample->skip_byte_block, rem_bytes);
8367  rem_bytes -= FFMIN(16*sample->skip_byte_block, rem_bytes);
8368  }
8369  input += sample->subsamples[i].bytes_of_protected_data;
8370  size -= sample->subsamples[i].bytes_of_protected_data;
8371  }
8372 
8373  if (size > 0) {
8374  av_log(c->fc, AV_LOG_ERROR, "leftover packet bytes after subsample processing\n");
8375  return AVERROR_INVALIDDATA;
8376  }
8377 
8378  return 0;
8379 }
8380 
8382 {
8383  int i, ret, rem_bytes;
8384  uint8_t iv[16];
8385  uint8_t *data;
8386  uint8_t decryption_key[16];
8387 
8388  if (!sc->cenc.aes_ctx) {
8389  ret = get_key_from_kid(decryption_key, sizeof(decryption_key), c, sample);
8390  if (ret < 0) {
8391  return ret;
8392  }
8393 
8394  /* initialize the cipher */
8395  sc->cenc.aes_ctx = av_aes_alloc();
8396  if (!sc->cenc.aes_ctx) {
8397  return AVERROR(ENOMEM);
8398  }
8399 
8400  ret = av_aes_init(sc->cenc.aes_ctx, decryption_key, 16 * 8, 1);
8401  if (ret < 0) {
8402  return ret;
8403  }
8404  }
8405 
8406  /* whole-block full sample encryption */
8407  if (!sample->subsample_count) {
8408  /* decrypt the whole packet */
8409  memcpy(iv, sample->iv, 16);
8410  av_aes_crypt(sc->cenc.aes_ctx, input, input, size/16, iv, 1);
8411  return 0;
8412  } else if (!sample->crypt_byte_block && !sample->skip_byte_block) {
8413  av_log(c->fc, AV_LOG_ERROR, "pattern encryption is not present in 'cbcs' scheme\n");
8414  return AVERROR_INVALIDDATA;
8415  }
8416 
8417  for (i = 0; i < sample->subsample_count; i++) {
8418  if (sample->subsamples[i].bytes_of_clear_data + (int64_t)sample->subsamples[i].bytes_of_protected_data > size) {
8419  av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n");
8420  return AVERROR_INVALIDDATA;
8421  }
8422 
8423  /* skip the clear bytes */
8424  input += sample->subsamples[i].bytes_of_clear_data;
8425  size -= sample->subsamples[i].bytes_of_clear_data;
8426 
8427  /* decrypt the encrypted bytes */
8428  memcpy(iv, sample->iv, 16);
8429  data = input;
8430  rem_bytes = sample->subsamples[i].bytes_of_protected_data;
8431  while (rem_bytes > 0) {
8432  if (rem_bytes < 16*sample->crypt_byte_block) {
8433  break;
8434  }
8435  av_aes_crypt(sc->cenc.aes_ctx, data, data, sample->crypt_byte_block, iv, 1);
8436  data += 16*sample->crypt_byte_block;
8437  rem_bytes -= 16*sample->crypt_byte_block;
8438  data += FFMIN(16*sample->skip_byte_block, rem_bytes);
8439  rem_bytes -= FFMIN(16*sample->skip_byte_block, rem_bytes);
8440  }
8441  input += sample->subsamples[i].bytes_of_protected_data;
8442  size -= sample->subsamples[i].bytes_of_protected_data;
8443  }
8444 
8445  if (size > 0) {
8446  av_log(c->fc, AV_LOG_ERROR, "leftover packet bytes after subsample processing\n");
8447  return AVERROR_INVALIDDATA;
8448  }
8449 
8450  return 0;
8451 }
8452 
8454 {
8455  if (sample->scheme == MKBETAG('c','e','n','c') && !sample->crypt_byte_block && !sample->skip_byte_block) {
8456  return cenc_scheme_decrypt(c, sc, sample, input, size);
8457  } else if (sample->scheme == MKBETAG('c','b','c','1') && !sample->crypt_byte_block && !sample->skip_byte_block) {
8458  return cbc1_scheme_decrypt(c, sc, sample, input, size);
8459  } else if (sample->scheme == MKBETAG('c','e','n','s')) {
8460  return cens_scheme_decrypt(c, sc, sample, input, size);
8461  } else if (sample->scheme == MKBETAG('c','b','c','s')) {
8462  return cbcs_scheme_decrypt(c, sc, sample, input, size);
8463  } else {
8464  av_log(c->fc, AV_LOG_ERROR, "invalid encryption scheme\n");
8465  return AVERROR_INVALIDDATA;
8466  }
8467 }
8468 
8470 {
8471  int current = frag_index->current;
8472 
8473  if (!frag_index->nb_items)
8474  return NULL;
8475 
8476  // Check frag_index->current is the right one for pkt. It can out of sync.
8477  if (current >= 0 && current < frag_index->nb_items) {
8478  if (frag_index->item[current].moof_offset < pkt->pos &&
8479  (current + 1 == frag_index->nb_items ||
8480  frag_index->item[current + 1].moof_offset > pkt->pos))
8481  return get_frag_stream_info(frag_index, current, id);
8482  }
8483 
8484 
8485  for (int i = 0; i < frag_index->nb_items; i++) {
8486  if (frag_index->item[i].moof_offset > pkt->pos)
8487  break;
8488  current = i;
8489  }
8490  frag_index->current = current;
8491  return get_frag_stream_info(frag_index, current, id);
8492 }
8493 
8494 static int cenc_filter(MOVContext *mov, AVStream* st, MOVStreamContext *sc, AVPacket *pkt, int current_index)
8495 {
8496  MOVFragmentStreamInfo *frag_stream_info;
8497  MOVEncryptionIndex *encryption_index;
8498  AVEncryptionInfo *encrypted_sample;
8499  int encrypted_index, ret;
8500 
8501  frag_stream_info = get_frag_stream_info_from_pkt(&mov->frag_index, pkt, sc->id);
8502  encrypted_index = current_index;
8503  encryption_index = NULL;
8504  if (frag_stream_info) {
8505  // Note this only supports encryption info in the first sample descriptor.
8506  if (frag_stream_info->stsd_id == 1) {
8507  if (frag_stream_info->encryption_index) {
8508  encrypted_index = current_index - frag_stream_info->index_base;
8509  encryption_index = frag_stream_info->encryption_index;
8510  } else {
8511  encryption_index = sc->cenc.encryption_index;
8512  }
8513  }
8514  } else {
8515  encryption_index = sc->cenc.encryption_index;
8516  }
8517 
8518  if (encryption_index) {
8519  if (encryption_index->auxiliary_info_sample_count &&
8520  !encryption_index->nb_encrypted_samples) {
8521  av_log(mov->fc, AV_LOG_ERROR, "saiz atom found without saio\n");
8522  return AVERROR_INVALIDDATA;
8523  }
8524  if (encryption_index->auxiliary_offsets_count &&
8525  !encryption_index->nb_encrypted_samples) {
8526  av_log(mov->fc, AV_LOG_ERROR, "saio atom found without saiz\n");
8527  return AVERROR_INVALIDDATA;
8528  }
8529 
8530  encrypted_sample = NULL;
8531  if (!encryption_index->nb_encrypted_samples) {
8532  // Full-sample encryption with default settings.
8533  encrypted_sample = sc->cenc.default_encrypted_sample;
8534  } else if (encrypted_index >= 0 && encrypted_index < encryption_index->nb_encrypted_samples) {
8535  // Per-sample setting override.
8536  encrypted_sample = encryption_index->encrypted_samples[encrypted_index];
8537  if (!encrypted_sample) {
8538  encrypted_sample = sc->cenc.default_encrypted_sample;
8539  }
8540  }
8541 
8542  if (!encrypted_sample) {
8543  av_log(mov->fc, AV_LOG_ERROR, "Incorrect number of samples in encryption info\n");
8544  return AVERROR_INVALIDDATA;
8545  }
8546 
8547  if (mov->decryption_keys || mov->decryption_default_key) {
8548  return cenc_decrypt(mov, sc, encrypted_sample, pkt->data, pkt->size);
8549  } else {
8550  size_t size;
8551  uint8_t *side_data = av_encryption_info_add_side_data(encrypted_sample, &size);
8552  if (!side_data)
8553  return AVERROR(ENOMEM);
8555  if (ret < 0)
8556  av_free(side_data);
8557  return ret;
8558  }
8559  }
8560 
8561  return 0;
8562 }
8563 
8565 {
8566  const int OPUS_SEEK_PREROLL_MS = 80;
8567  int ret;
8568  AVStream *st;
8569  size_t size;
8570  uint16_t pre_skip;
8571 
8572  if (c->fc->nb_streams < 1)
8573  return 0;
8574  st = c->fc->streams[c->fc->nb_streams-1];
8575 
8576  if ((uint64_t)atom.size > (1<<30) || atom.size < 11 || st->codecpar->extradata)
8577  return AVERROR_INVALIDDATA;
8578 
8579  /* Check OpusSpecificBox version. */
8580  if (avio_r8(pb) != 0) {
8581  av_log(c->fc, AV_LOG_ERROR, "unsupported OpusSpecificBox version\n");
8582  return AVERROR_INVALIDDATA;
8583  }
8584 
8585  /* OpusSpecificBox size plus magic for Ogg OpusHead header. */
8586  size = atom.size + 8;
8587 
8588  if ((ret = ff_alloc_extradata(st->codecpar, size)) < 0)
8589  return ret;
8590 
8591  AV_WL32A(st->codecpar->extradata, MKTAG('O','p','u','s'));
8592  AV_WL32A(st->codecpar->extradata + 4, MKTAG('H','e','a','d'));
8593  AV_WB8(st->codecpar->extradata + 8, 1); /* OpusHead version */
8594  if ((ret = ffio_read_size(pb, st->codecpar->extradata + 9, size - 9)) < 0) {
8595  av_freep(&st->codecpar->extradata);
8596  st->codecpar->extradata_size = 0;
8597  return ret;
8598  }
8599 
8600  /* OpusSpecificBox is stored in big-endian, but OpusHead is
8601  little-endian; aside from the preceding magic and version they're
8602  otherwise currently identical. Data after output gain at offset 16
8603  doesn't need to be bytewapped. */
8604  pre_skip = AV_RB16A(st->codecpar->extradata + 10);
8605  AV_WL16A(st->codecpar->extradata + 10, pre_skip);
8606  AV_WL32A(st->codecpar->extradata + 12, AV_RB32A(st->codecpar->extradata + 12));
8607  AV_WL16A(st->codecpar->extradata + 16, AV_RB16A(st->codecpar->extradata + 16));
8608 
8609  st->codecpar->initial_padding = pre_skip;
8611  (AVRational){1, 1000},
8612  (AVRational){1, 48000});
8613 
8614  return 0;
8615 }
8616 
8618 {
8619  AVStream *st;
8620  unsigned format_info;
8621  int channel_assignment, channel_assignment1, channel_assignment2;
8622  int ratebits;
8623  uint64_t chmask;
8624 
8625  if (c->fc->nb_streams < 1)
8626  return 0;
8627  st = c->fc->streams[c->fc->nb_streams-1];
8628 
8629  if (atom.size < 10)
8630  return AVERROR_INVALIDDATA;
8631 
8632  format_info = avio_rb32(pb);
8633 
8634  ratebits = (format_info >> 28) & 0xF;
8635  channel_assignment1 = (format_info >> 15) & 0x1F;
8636  channel_assignment2 = format_info & 0x1FFF;
8637  if (channel_assignment2)
8638  channel_assignment = channel_assignment2;
8639  else
8640  channel_assignment = channel_assignment1;
8641 
8642  st->codecpar->frame_size = 40 << (ratebits & 0x7);
8643  st->codecpar->sample_rate = mlp_samplerate(ratebits);
8644 
8646  chmask = truehd_layout(channel_assignment);
8648 
8649  return 0;
8650 }
8651 
8653 {
8654  AVStream *st;
8655  uint8_t buf[ISOM_DVCC_DVVC_SIZE];
8656  int ret;
8657  int64_t read_size = atom.size;
8658 
8659  if (c->fc->nb_streams < 1)
8660  return 0;
8661  st = c->fc->streams[c->fc->nb_streams-1];
8662 
8663  // At most 24 bytes
8664  read_size = FFMIN(read_size, ISOM_DVCC_DVVC_SIZE);
8665 
8666  if ((ret = ffio_read_size(pb, buf, read_size)) < 0)
8667  return ret;
8668 
8669  return ff_isom_parse_dvcc_dvvc(c->fc, st, buf, read_size);
8670 }
8671 
8673 {
8674  AVStream *st;
8675  uint8_t *buf;
8676  int ret, old_size, num_arrays;
8677 
8678  if (c->fc->nb_streams < 1)
8679  return 0;
8680  st = c->fc->streams[c->fc->nb_streams-1];
8681 
8682  if (!st->codecpar->extradata_size)
8683  // TODO: handle lhvC when present before hvcC
8684  return 0;
8685 
8686  if (atom.size < 6 || st->codecpar->extradata_size < 23 ||
8687  atom.size > INT_MAX - AV_INPUT_BUFFER_PADDING_SIZE) {
8688  return AVERROR_INVALIDDATA;
8689  }
8690 
8692  if (!buf)
8693  return AVERROR(ENOMEM);
8694  memset(buf + atom.size, 0, AV_INPUT_BUFFER_PADDING_SIZE);
8695 
8696  ret = ffio_read_size(pb, buf, atom.size);
8697  if (ret < 0) {
8698  av_free(buf);
8699  av_log(c->fc, AV_LOG_WARNING, "lhvC atom truncated\n");
8700  return 0;
8701  }
8702 
8703  num_arrays = buf[5];
8704  old_size = st->codecpar->extradata_size;
8705  atom.size -= 8 /* account for mov_realloc_extradata offsetting */
8706  + 6 /* lhvC bytes before the arrays*/;
8707 
8708  ret = mov_realloc_extradata(st->codecpar, atom);
8709  if (ret < 0) {
8710  av_free(buf);
8711  return ret;
8712  }
8713 
8714  st->codecpar->extradata[22] += num_arrays;
8715  memcpy(st->codecpar->extradata + old_size, buf + 6, atom.size + 8);
8716 
8718 
8719  av_free(buf);
8720  return 0;
8721 }
8722 
8724 {
8725  AVFormatContext *ctx = c->fc;
8726  AVStream *st = NULL;
8727  AVBPrint scheme_buf, value_buf;
8728  int64_t scheme_str_len = 0, value_str_len = 0;
8729  int version, flags, ret = AVERROR_BUG;
8730  int64_t size = atom.size;
8731 
8732  if (atom.size < 6)
8733  // 4 bytes for version + flags, 2x 1 byte for null
8734  return AVERROR_INVALIDDATA;
8735 
8736  if (c->fc->nb_streams < 1)
8737  return 0;
8738  st = c->fc->streams[c->fc->nb_streams-1];
8739 
8740  version = avio_r8(pb);
8741  flags = avio_rb24(pb);
8742  size -= 4;
8743 
8744  if (version != 0 || flags != 0) {
8746  "Unsupported 'kind' box with version %d, flags: %x",
8747  version, flags);
8748  return AVERROR_INVALIDDATA;
8749  }
8750 
8751  av_bprint_init(&scheme_buf, 0, AV_BPRINT_SIZE_UNLIMITED);
8752  av_bprint_init(&value_buf, 0, AV_BPRINT_SIZE_UNLIMITED);
8753 
8754  if ((scheme_str_len = ff_read_string_to_bprint_overwrite(pb, &scheme_buf,
8755  size)) < 0) {
8756  ret = scheme_str_len;
8757  goto cleanup;
8758  }
8759 
8760  if (scheme_str_len + 1 >= size) {
8761  // we need to have another string, even if nullptr.
8762  // we check with + 1 since we expect that if size was not hit,
8763  // an additional null was read.
8765  goto cleanup;
8766  }
8767 
8768  size -= scheme_str_len + 1;
8769 
8770  if ((value_str_len = ff_read_string_to_bprint_overwrite(pb, &value_buf,
8771  size)) < 0) {
8772  ret = value_str_len;
8773  goto cleanup;
8774  }
8775 
8776  if (value_str_len == size) {
8777  // in case of no trailing null, box is not valid.
8779  goto cleanup;
8780  }
8781 
8783  "%s stream %d KindBox(scheme: %s, value: %s)\n",
8785  st->index,
8786  scheme_buf.str, value_buf.str);
8787 
8788  for (int i = 0; ff_mov_track_kind_table[i].scheme_uri; i++) {
8790  if (!av_strstart(scheme_buf.str, map.scheme_uri, NULL))
8791  continue;
8792 
8793  for (int j = 0; map.value_maps[j].disposition; j++) {
8794  const struct MP4TrackKindValueMapping value_map = map.value_maps[j];
8795  if (!av_strstart(value_buf.str, value_map.value, NULL))
8796  continue;
8797 
8798  st->disposition |= value_map.disposition;
8799  }
8800  }
8801 
8802  ret = 0;
8803 
8804 cleanup:
8805 
8806  av_bprint_finalize(&scheme_buf, NULL);
8807  av_bprint_finalize(&value_buf, NULL);
8808 
8809  return ret;
8810 }
8811 
8813 {
8814  AVStream *st;
8815  AVChannelLayout ch_layout = { 0 };
8816  int ret, i, version, type;
8817  int ambisonic_order, channel_order, normalization, channel_count;
8818  int ambi_channels, non_diegetic_channels;
8819 
8820  if (c->fc->nb_streams < 1)
8821  return 0;
8822 
8823  st = c->fc->streams[c->fc->nb_streams - 1];
8824 
8825  if (atom.size < 16) {
8826  av_log(c->fc, AV_LOG_ERROR, "SA3D audio box too small\n");
8827  return AVERROR_INVALIDDATA;
8828  }
8829 
8830  version = avio_r8(pb);
8831  if (version) {
8832  av_log(c->fc, AV_LOG_WARNING, "Unsupported SA3D box version %d\n", version);
8833  return 0;
8834  }
8835 
8836  type = avio_r8(pb);
8837  if (type & 0x7f) {
8838  av_log(c->fc, AV_LOG_WARNING,
8839  "Unsupported ambisonic type %d\n", type & 0x7f);
8840  return 0;
8841  }
8842  non_diegetic_channels = (type >> 7) * 2; // head_locked_stereo
8843 
8844  ambisonic_order = avio_rb32(pb);
8845 
8846  channel_order = avio_r8(pb);
8847  if (channel_order) {
8848  av_log(c->fc, AV_LOG_WARNING,
8849  "Unsupported channel_order %d\n", channel_order);
8850  return 0;
8851  }
8852 
8853  normalization = avio_r8(pb);
8854  if (normalization) {
8855  av_log(c->fc, AV_LOG_WARNING,
8856  "Unsupported normalization %d\n", normalization);
8857  return 0;
8858  }
8859 
8860  channel_count = avio_rb32(pb);
8861  if (ambisonic_order < 0 || ambisonic_order > 31 ||
8862  channel_count != ((ambisonic_order + 1LL) * (ambisonic_order + 1LL) +
8863  non_diegetic_channels)) {
8864  av_log(c->fc, AV_LOG_ERROR,
8865  "Invalid number of channels (%d / %d)\n",
8866  channel_count, ambisonic_order);
8867  return 0;
8868  }
8869  ambi_channels = channel_count - non_diegetic_channels;
8870 
8871  ret = av_channel_layout_custom_init(&ch_layout, channel_count);
8872  if (ret < 0)
8873  return 0;
8874 
8875  for (i = 0; i < channel_count; i++) {
8876  unsigned channel = avio_rb32(pb);
8877 
8878  if (channel >= channel_count) {
8879  av_log(c->fc, AV_LOG_ERROR, "Invalid channel index (%d / %d)\n",
8880  channel, ambisonic_order);
8881  av_channel_layout_uninit(&ch_layout);
8882  return 0;
8883  }
8884  if (channel >= ambi_channels)
8885  ch_layout.u.map[i].id = channel - ambi_channels;
8886  else
8887  ch_layout.u.map[i].id = AV_CHAN_AMBISONIC_BASE + channel;
8888  }
8889 
8891  if (ret < 0) {
8892  av_channel_layout_uninit(&ch_layout);
8893  return 0;
8894  }
8895 
8897  st->codecpar->ch_layout = ch_layout;
8898 
8899  return 0;
8900 }
8901 
8903 {
8904  AVStream *st;
8905  int version;
8906 
8907  if (c->fc->nb_streams < 1)
8908  return 0;
8909 
8910  st = c->fc->streams[c->fc->nb_streams - 1];
8911 
8912  if (atom.size < 5) {
8913  av_log(c->fc, AV_LOG_ERROR, "Empty SAND audio box\n");
8914  return AVERROR_INVALIDDATA;
8915  }
8916 
8917  version = avio_r8(pb);
8918  if (version) {
8919  av_log(c->fc, AV_LOG_WARNING, "Unsupported SAND box version %d\n", version);
8920  return 0;
8921  }
8922 
8924 
8925  return 0;
8926 }
8927 
8928 static int rb_size(AVIOContext *pb, int64_t *value, int size)
8929 {
8930  if (size == 0)
8931  *value = 0;
8932  else if (size == 1)
8933  *value = avio_r8(pb);
8934  else if (size == 2)
8935  *value = avio_rb16(pb);
8936  else if (size == 4)
8937  *value = avio_rb32(pb);
8938  else if (size == 8) {
8939  *value = avio_rb64(pb);
8940  if (*value < 0)
8941  return -1;
8942  } else
8943  return -1;
8944  return size;
8945 }
8946 
8948 {
8949  avio_rb32(pb); // version & flags.
8950  c->primary_item_id = avio_rb16(pb);
8951  av_log(c->fc, AV_LOG_TRACE, "pitm: primary_item_id %d\n", c->primary_item_id);
8952  return atom.size;
8953 }
8954 
8956 {
8957  c->idat_offset = avio_tell(pb);
8958  return 0;
8959 }
8960 
8962 {
8963  HEIFItem **heif_item;
8964  int version, offset_size, length_size, base_offset_size, index_size;
8965  int item_count, extent_count;
8966  int64_t base_offset, extent_offset, extent_length;
8967  uint8_t value;
8968 
8969  if (c->found_iloc) {
8970  av_log(c->fc, AV_LOG_INFO, "Duplicate iloc box found\n");
8971  return 0;
8972  }
8973 
8974  version = avio_r8(pb);
8975  avio_rb24(pb); // flags.
8976 
8977  value = avio_r8(pb);
8978  offset_size = (value >> 4) & 0xF;
8979  length_size = value & 0xF;
8980  value = avio_r8(pb);
8981  base_offset_size = (value >> 4) & 0xF;
8982  index_size = !version ? 0 : (value & 0xF);
8983  if (index_size) {
8984  avpriv_report_missing_feature(c->fc, "iloc: index_size != 0");
8985  return AVERROR_PATCHWELCOME;
8986  }
8987  item_count = (version < 2) ? avio_rb16(pb) : avio_rb32(pb);
8988 
8989  heif_item = av_realloc_array(c->heif_item, FFMAX(item_count, c->nb_heif_item), sizeof(*c->heif_item));
8990  if (!heif_item)
8991  return AVERROR(ENOMEM);
8992  c->heif_item = heif_item;
8993  if (item_count > c->nb_heif_item)
8994  memset(&c->heif_item[c->nb_heif_item], 0,
8995  sizeof(*c->heif_item) * (item_count - c->nb_heif_item));
8996  c->nb_heif_item = FFMAX(c->nb_heif_item, item_count);
8997 
8998  av_log(c->fc, AV_LOG_TRACE, "iloc: item_count %d\n", item_count);
8999  for (int i = 0; i < item_count; i++) {
9000  HEIFItem *item = NULL;
9001  int item_id = (version < 2) ? avio_rb16(pb) : avio_rb32(pb);
9002  int offset_type = (version > 0) ? avio_rb16(pb) & 0xf : 0;
9003  int j;
9004 
9005  if (avio_feof(pb))
9006  return AVERROR_INVALIDDATA;
9007  if (offset_type > 1) {
9008  avpriv_report_missing_feature(c->fc, "iloc offset type %d", offset_type);
9009  return AVERROR_PATCHWELCOME;
9010  }
9011 
9012  avio_rb16(pb); // data_reference_index.
9013  if (rb_size(pb, &base_offset, base_offset_size) < 0)
9014  return AVERROR_INVALIDDATA;
9015  extent_count = avio_rb16(pb);
9016  if (extent_count > 1) {
9017  // For still AVIF images, we only support one extent item.
9018  avpriv_report_missing_feature(c->fc, "iloc: extent_count > 1");
9019  return AVERROR_PATCHWELCOME;
9020  }
9021 
9022  if (rb_size(pb, &extent_offset, offset_size) < 0 ||
9023  rb_size(pb, &extent_length, length_size) < 0 ||
9024  base_offset > INT64_MAX - extent_offset)
9025  return AVERROR_INVALIDDATA;
9026 
9027  for (j = 0; j < c->nb_heif_item; j++) {
9028  item = c->heif_item[j];
9029  if (!item)
9030  item = c->heif_item[j] = av_mallocz(sizeof(*item));
9031  else if (item->item_id != item_id)
9032  continue;
9033  break;
9034  }
9035  if (!item)
9036  return AVERROR(ENOMEM);
9037  if (j == c->nb_heif_item)
9038  return AVERROR_INVALIDDATA;
9039 
9040  item->item_id = item_id;
9041 
9042  if (offset_type == 1)
9043  item->is_idat_relative = 1;
9044  item->extent_length = extent_length;
9045  item->extent_offset = base_offset + extent_offset;
9046  av_log(c->fc, AV_LOG_TRACE, "iloc: item_idx %d, item->item_id %d, offset_type %d, "
9047  "extent_offset %"PRId64", extent_length %"PRId64"\n",
9048  i, item->item_id, offset_type, item->extent_offset, item->extent_length);
9049  }
9050 
9051  c->found_iloc = 1;
9052  return atom.size;
9053 }
9054 
9056 {
9057  HEIFItem *item = NULL;
9058  AVBPrint item_name;
9059  int64_t size = atom.size;
9060  uint32_t item_type;
9061  int item_id;
9062  int i, version, ret;
9063 
9064  version = avio_r8(pb);
9065  avio_rb24(pb); // flags.
9066  size -= 4;
9067  if (size < 0)
9068  return AVERROR_INVALIDDATA;
9069 
9070  if (version < 2) {
9071  avpriv_report_missing_feature(c->fc, "infe version < 2");
9072  avio_skip(pb, size);
9073  return 1;
9074  }
9075 
9076  item_id = version > 2 ? avio_rb32(pb) : avio_rb16(pb);
9077  avio_rb16(pb); // item_protection_index
9078  item_type = avio_rl32(pb);
9079  size -= 8;
9080  if (size < 1)
9081  return AVERROR_INVALIDDATA;
9082 
9085  if (ret < 0) {
9087  return ret;
9088  }
9089 
9090  av_log(c->fc, AV_LOG_TRACE, "infe: item_id %d, item_type %s, item_name %s\n",
9091  item_id, av_fourcc2str(item_type), item_name.str);
9092 
9093  size -= ret + 1;
9094  if (size > 0)
9095  avio_skip(pb, size);
9096 
9097  for (i = 0; i < c->nb_heif_item; i++) {
9098  item = c->heif_item[i];
9099  if (!item)
9100  item = c->heif_item[i] = av_mallocz(sizeof(*item));
9101  else if (item->item_id != item_id)
9102  continue;
9103  break;
9104  }
9105  if (!item) {
9107  return AVERROR(ENOMEM);
9108  }
9109  if (i == c->nb_heif_item) {
9111  return AVERROR_INVALIDDATA;
9112  }
9113 
9114  av_freep(&item->name);
9115  av_bprint_finalize(&item_name, ret ? &item->name : NULL);
9116  item->item_id = item_id;
9117  item->type = item_type;
9118 
9119  switch (item_type) {
9120  case MKTAG('a','v','0','1'):
9121  case MKTAG('j','p','e','g'):
9122  case MKTAG('h','v','c','1'):
9123  ret = heif_add_stream(c, item);
9124  if (ret < 0)
9125  return ret;
9126  break;
9127  }
9128 
9129  return 0;
9130 }
9131 
9133 {
9134  HEIFItem **heif_item;
9135  int entry_count;
9136  int version, got_stream = 0, ret, i;
9137 
9138  if (c->found_iinf) {
9139  av_log(c->fc, AV_LOG_WARNING, "Duplicate iinf box found\n");
9140  return 0;
9141  }
9142 
9143  version = avio_r8(pb);
9144  avio_rb24(pb); // flags.
9145  entry_count = version ? avio_rb32(pb) : avio_rb16(pb);
9146 
9147  heif_item = av_realloc_array(c->heif_item, FFMAX(entry_count, c->nb_heif_item), sizeof(*c->heif_item));
9148  if (!heif_item)
9149  return AVERROR(ENOMEM);
9150  c->heif_item = heif_item;
9151  if (entry_count > c->nb_heif_item)
9152  memset(&c->heif_item[c->nb_heif_item], 0,
9153  sizeof(*c->heif_item) * (entry_count - c->nb_heif_item));
9154  c->nb_heif_item = FFMAX(c->nb_heif_item, entry_count);
9155 
9156  for (i = 0; i < entry_count; i++) {
9157  MOVAtom infe;
9158 
9159  infe.size = avio_rb32(pb) - 8;
9160  infe.type = avio_rl32(pb);
9161  if (avio_feof(pb)) {
9163  goto fail;
9164  }
9165  ret = mov_read_infe(c, pb, infe);
9166  if (ret < 0)
9167  goto fail;
9168  if (!ret)
9169  got_stream = 1;
9170  }
9171 
9172  c->found_iinf = got_stream;
9173  return 0;
9174 fail:
9175  for (; i >= 0; i--) {
9176  HEIFItem *item = c->heif_item[i];
9177 
9178  if (!item)
9179  continue;
9180 
9181  av_freep(&item->name);
9182  }
9183  return ret;
9184 }
9185 
9187 {
9188  HEIFItem *item = NULL;
9189  HEIFGrid *grid;
9190  int entries, i;
9191  int from_item_id = version ? avio_rb32(pb) : avio_rb16(pb);
9192  int ret = 0;
9193 
9194  for (int i = 0; i < c->nb_heif_grid; i++) {
9195  if (c->heif_grid[i].item->item_id == from_item_id) {
9196  av_log(c->fc, AV_LOG_ERROR, "More than one 'dimg' box "
9197  "referencing the same Derived Image item\n");
9198  return AVERROR_INVALIDDATA;
9199  }
9200  }
9201  for (int i = 0; i < c->nb_heif_item; i++) {
9202  if (!c->heif_item[i] || c->heif_item[i]->item_id != from_item_id)
9203  continue;
9204  item = c->heif_item[i];
9205 
9206  switch (item->type) {
9207  case MKTAG('g','r','i','d'):
9208  case MKTAG('i','o','v','l'):
9209  break;
9210  default:
9211  avpriv_report_missing_feature(c->fc, "Derived Image item of type %s",
9212  av_fourcc2str(item->type));
9213  return 0;
9214  }
9215  break;
9216  }
9217  if (!item) {
9218  av_log(c->fc, AV_LOG_ERROR, "Missing grid information\n");
9219  return AVERROR_INVALIDDATA;
9220  }
9221 
9222  entries = avio_rb16(pb);
9223  if (!entries) {
9224  av_log(c->fc, AV_LOG_ERROR,
9225  "Derived image item references no input images\n");
9226  return AVERROR_INVALIDDATA;
9227  }
9228 
9229  grid = av_realloc_array(c->heif_grid, c->nb_heif_grid + 1U,
9230  sizeof(*c->heif_grid));
9231  if (!grid)
9232  return AVERROR(ENOMEM);
9233  c->heif_grid = grid;
9234  grid = &grid[c->nb_heif_grid];
9235 
9236  grid->tile_id_list = av_malloc_array(entries, sizeof(*grid->tile_id_list));
9237  grid->tile_idx_list = av_calloc(entries, sizeof(*grid->tile_idx_list));
9238  grid->tile_item_list = av_calloc(entries, sizeof(*grid->tile_item_list));
9239  if (!grid->tile_id_list || !grid->tile_item_list || !grid->tile_idx_list) {
9240  ret = AVERROR(ENOMEM);
9241  goto fail;
9242  }
9243  /* 'to' item ids */
9244  for (i = 0; i < entries; i++) {
9245  grid->tile_id_list[i] = version ? avio_rb32(pb) : avio_rb16(pb);
9246 
9247  if (avio_feof(pb)) {
9249  goto fail;
9250  }
9251  }
9252 
9253  grid->nb_tiles = entries;
9254  grid->item = item;
9255  ++c->nb_heif_grid;
9256 
9257  av_log(c->fc, AV_LOG_TRACE, "dimg: from_item_id %d, entries %d\n",
9258  from_item_id, entries);
9259 
9260  return 0;
9261 fail:
9262  av_freep(&grid->tile_id_list);
9263  av_freep(&grid->tile_idx_list);
9264  av_freep(&grid->tile_item_list);
9265 
9266  return ret;
9267 }
9268 
9269 static int mov_read_iref_cdsc(MOVContext *c, AVIOContext *pb, uint32_t type, int version)
9270 {
9271  HEIFItem *from_item = NULL;
9272  int entries;
9273  int from_item_id = version ? avio_rb32(pb) : avio_rb16(pb);
9274  const HEIFItemRef ref = { type, from_item_id };
9275 
9276  from_item = get_heif_item(c, from_item_id);
9277  if (!from_item) {
9278  av_log(c->fc, AV_LOG_ERROR, "Missing stream referenced by thmb item\n");
9279  return AVERROR_INVALIDDATA;
9280  }
9281 
9282  entries = avio_rb16(pb);
9283  /* 'to' item ids */
9284  for (int i = 0; i < entries; i++) {
9285  HEIFItem *item = get_heif_item(c, version ? avio_rb32(pb) : avio_rb16(pb));
9286 
9287  if (avio_feof(pb))
9288  return AVERROR_INVALIDDATA;
9289 
9290  if (!item) {
9291  av_log(c->fc, AV_LOG_WARNING, "Missing stream referenced by %s item\n",
9292  av_fourcc2str(type));
9293  continue;
9294  }
9295 
9296  if (!av_dynarray2_add((void **)&item->iref_list, &item->nb_iref_list,
9297  sizeof(*item->iref_list), (const uint8_t *)&ref))
9298  return AVERROR(ENOMEM);
9299  }
9300 
9301  av_log(c->fc, AV_LOG_TRACE, "%s: from_item_id %d, entries %d\n",
9302  av_fourcc2str(type), from_item_id, entries);
9303 
9304  return 0;
9305 }
9306 
9308 {
9309  int version = avio_r8(pb);
9310  int ret;
9311 
9312  avio_rb24(pb); // flags
9313  atom.size -= 4;
9314 
9315  if (version > 1) {
9316  av_log(c->fc, AV_LOG_WARNING, "Unknown iref box version %d\n", version);
9317  return 0;
9318  }
9319 
9320  while (atom.size) {
9321  uint32_t type, size = avio_rb32(pb);
9322  int64_t next = avio_tell(pb);
9323 
9324  if (size < 14 || next < 0 || next > INT64_MAX - size)
9325  return AVERROR_INVALIDDATA;
9326 
9327  next += size - 4;
9328  type = avio_rl32(pb);
9329  switch (type) {
9330  case MKTAG('d','i','m','g'):
9331  ret = mov_read_iref_dimg(c, pb, version);
9332  if (ret < 0)
9333  return ret;
9334  break;
9335  case MKTAG('c','d','s','c'):
9336  case MKTAG('t','h','m','b'):
9337  ret = mov_read_iref_cdsc(c, pb, type, version);
9338  if (ret < 0)
9339  return ret;
9340  break;
9341  default:
9342  av_log(c->fc, AV_LOG_DEBUG, "Unknown iref type %s size %"PRIu32"\n",
9343  av_fourcc2str(type), size);
9344  }
9345 
9346  atom.size -= size;
9347  avio_seek(pb, next, SEEK_SET);
9348  }
9349  return 0;
9350 }
9351 
9353 {
9354  HEIFItem *item;
9355  uint32_t width, height;
9356 
9357  avio_r8(pb); /* version */
9358  avio_rb24(pb); /* flags */
9359  width = avio_rb32(pb);
9360  height = avio_rb32(pb);
9361 
9362  av_log(c->fc, AV_LOG_TRACE, "ispe: item_id %d, width %"PRIu32", height %"PRIu32"\n",
9363  c->cur_item_id, width, height);
9364 
9365  item = get_heif_item(c, c->cur_item_id);
9366  if (item) {
9367  item->width = width;
9368  item->height = height;
9369  }
9370 
9371  return 0;
9372 }
9373 
9375 {
9376  HEIFItem *item;
9377  int angle;
9378 
9379  angle = avio_r8(pb) & 0x3;
9380 
9381  av_log(c->fc, AV_LOG_TRACE, "irot: item_id %d, angle %u\n",
9382  c->cur_item_id, angle);
9383 
9384  item = get_heif_item(c, c->cur_item_id);
9385  if (item) {
9386  // angle * 90 specifies the angle (in anti-clockwise direction)
9387  // in units of degrees.
9388  item->rotation = angle * 90;
9389  }
9390 
9391  return 0;
9392 }
9393 
9395 {
9396  HEIFItem *item;
9397  int axis;
9398 
9399  axis = avio_r8(pb) & 0x1;
9400 
9401  av_log(c->fc, AV_LOG_TRACE, "imir: item_id %d, axis %u\n",
9402  c->cur_item_id, axis);
9403 
9404  item = get_heif_item(c, c->cur_item_id);
9405  if (item) {
9406  item->hflip = axis;
9407  item->vflip = !axis;
9408  }
9409 
9410  return 0;
9411 }
9412 
9414 {
9415  typedef struct MOVAtoms {
9416  FFIOContext b;
9417  uint32_t type;
9418  int64_t size;
9419  uint8_t *data;
9420  } MOVAtoms;
9421  MOVAtoms *atoms = NULL;
9422  MOVAtom a;
9423  unsigned count;
9424  int nb_atoms = 0;
9425  int version, flags;
9426  int ret;
9427 
9428  a.size = avio_rb32(pb);
9429  a.type = avio_rl32(pb);
9430 
9431  if (a.size < 8 || a.type != MKTAG('i','p','c','o'))
9432  return AVERROR_INVALIDDATA;
9433 
9434  a.size -= 8;
9435  while (a.size >= 8) {
9436  MOVAtoms *ref = av_dynarray2_add((void**)&atoms, &nb_atoms, sizeof(MOVAtoms), NULL);
9437  if (!ref) {
9438  ret = AVERROR(ENOMEM);
9439  goto fail;
9440  }
9441  ref->data = NULL;
9442  ref->size = avio_rb32(pb);
9443  ref->type = avio_rl32(pb);
9444  if (ref->size > a.size || ref->size < 8)
9445  break;
9446  ref->data = av_malloc(ref->size);
9447  if (!ref->data) {
9449  goto fail;
9450  }
9451  av_log(c->fc, AV_LOG_TRACE, "ipco: index %d, box type %s\n", nb_atoms, av_fourcc2str(ref->type));
9452  avio_seek(pb, -8, SEEK_CUR);
9453  if (avio_read(pb, ref->data, ref->size) != ref->size) {
9455  goto fail;
9456  }
9457  ffio_init_read_context(&ref->b, ref->data, ref->size);
9458  a.size -= ref->size;
9459  }
9460 
9461  if (a.size) {
9463  goto fail;
9464  }
9465 
9466  a.size = avio_rb32(pb);
9467  a.type = avio_rl32(pb);
9468 
9469  if (a.size < 8 || a.type != MKTAG('i','p','m','a')) {
9471  goto fail;
9472  }
9473 
9474  version = avio_r8(pb);
9475  flags = avio_rb24(pb);
9476  count = avio_rb32(pb);
9477 
9478  for (int i = 0; i < count; i++) {
9479  int item_id = version ? avio_rb32(pb) : avio_rb16(pb);
9480  int assoc_count = avio_r8(pb);
9481 
9482  if (avio_feof(pb)) {
9484  goto fail;
9485  }
9486 
9487  for (int j = 0; j < assoc_count; j++) {
9488  MOVAtoms *ref;
9489  int index = avio_r8(pb) & 0x7f;
9490  if (flags & 1) {
9491  index <<= 8;
9492  index |= avio_r8(pb);
9493  }
9494  if (index > nb_atoms || index <= 0) {
9496  goto fail;
9497  }
9498  ref = &atoms[--index];
9499 
9500  av_log(c->fc, AV_LOG_TRACE, "ipma: property_index %d, item_id %d, item_type %s\n",
9501  index + 1, item_id, av_fourcc2str(ref->type));
9502 
9503  c->cur_item_id = item_id;
9504 
9505  ret = mov_read_default(c, &ref->b.pub,
9506  (MOVAtom) { .size = ref->size,
9507  .type = MKTAG('i','p','c','o') });
9508  if (ret < 0)
9509  goto fail;
9510  ffio_init_read_context(&ref->b, ref->data, ref->size);
9511  }
9512  }
9513 
9514  ret = 0;
9515 fail:
9516  c->cur_item_id = -1;
9517  for (int i = 0; i < nb_atoms; i++)
9518  av_free(atoms[i].data);
9519  av_free(atoms);
9520 
9521  return ret;
9522 }
9523 
9525 { MKTAG('A','C','L','R'), mov_read_aclr },
9526 { MKTAG('A','P','R','G'), mov_read_avid },
9527 { MKTAG('A','A','L','P'), mov_read_avid },
9528 { MKTAG('A','R','E','S'), mov_read_ares },
9529 { MKTAG('a','v','s','s'), mov_read_avss },
9530 { MKTAG('a','v','1','C'), mov_read_glbl },
9531 { MKTAG('c','h','p','l'), mov_read_chpl },
9532 { MKTAG('c','o','6','4'), mov_read_stco },
9533 { MKTAG('c','o','l','r'), mov_read_colr },
9534 { MKTAG('c','t','t','s'), mov_read_ctts }, /* composition time to sample */
9535 { MKTAG('d','i','n','f'), mov_read_default },
9536 { MKTAG('D','p','x','E'), mov_read_dpxe },
9537 { MKTAG('d','r','e','f'), mov_read_dref },
9538 { MKTAG('e','d','t','s'), mov_read_default },
9539 { MKTAG('e','l','s','t'), mov_read_elst },
9540 { MKTAG('e','n','d','a'), mov_read_enda },
9541 { MKTAG('f','i','e','l'), mov_read_fiel },
9542 { MKTAG('a','d','r','m'), mov_read_adrm },
9543 { MKTAG('f','t','y','p'), mov_read_ftyp },
9544 { MKTAG('g','l','b','l'), mov_read_glbl },
9545 { MKTAG('h','d','l','r'), mov_read_hdlr },
9546 { MKTAG('i','l','s','t'), mov_read_ilst },
9547 { MKTAG('j','p','2','h'), mov_read_jp2h },
9548 { MKTAG('m','d','a','t'), mov_read_mdat },
9549 { MKTAG('m','d','h','d'), mov_read_mdhd },
9550 { MKTAG('m','d','i','a'), mov_read_default },
9551 { MKTAG('m','e','t','a'), mov_read_meta },
9552 { MKTAG('m','i','n','f'), mov_read_default },
9553 { MKTAG('m','o','o','f'), mov_read_moof },
9554 { MKTAG('m','o','o','v'), mov_read_moov },
9555 { MKTAG('m','v','e','x'), mov_read_default },
9556 { MKTAG('m','v','h','d'), mov_read_mvhd },
9557 { MKTAG('S','M','I',' '), mov_read_svq3 },
9558 { MKTAG('a','l','a','c'), mov_read_alac }, /* alac specific atom */
9559 { MKTAG('a','v','c','C'), mov_read_glbl },
9560 { MKTAG('p','a','s','p'), mov_read_pasp },
9561 { MKTAG('c','l','a','p'), mov_read_clap },
9562 { MKTAG('s','b','a','s'), mov_read_sbas },
9563 { MKTAG('s','i','d','x'), mov_read_sidx },
9564 { MKTAG('s','t','b','l'), mov_read_default },
9565 { MKTAG('s','t','c','o'), mov_read_stco },
9566 { MKTAG('s','t','p','s'), mov_read_stps },
9567 { MKTAG('s','t','r','f'), mov_read_strf },
9568 { MKTAG('s','t','s','c'), mov_read_stsc },
9569 { MKTAG('s','t','s','d'), mov_read_stsd }, /* sample description */
9570 { MKTAG('s','t','s','s'), mov_read_stss }, /* sync sample */
9571 { MKTAG('s','t','s','z'), mov_read_stsz }, /* sample size */
9572 { MKTAG('s','t','t','s'), mov_read_stts },
9573 { MKTAG('s','t','z','2'), mov_read_stsz }, /* compact sample size */
9574 { MKTAG('s','d','t','p'), mov_read_sdtp }, /* independent and disposable samples */
9575 { MKTAG('t','k','h','d'), mov_read_tkhd }, /* track header */
9576 { MKTAG('t','f','d','t'), mov_read_tfdt },
9577 { MKTAG('t','f','h','d'), mov_read_tfhd }, /* track fragment header */
9578 { MKTAG('t','r','a','k'), mov_read_trak },
9579 { MKTAG('t','r','a','f'), mov_read_default },
9580 { MKTAG('t','r','e','f'), mov_read_default },
9581 { MKTAG('t','m','c','d'), mov_read_tmcd },
9582 { MKTAG('c','h','a','p'), mov_read_chap },
9583 { MKTAG('t','r','e','x'), mov_read_trex },
9584 { MKTAG('t','r','u','n'), mov_read_trun },
9585 { MKTAG('u','d','t','a'), mov_read_default },
9586 { MKTAG('w','a','v','e'), mov_read_wave },
9587 { MKTAG('e','s','d','s'), mov_read_esds },
9588 { MKTAG('d','a','c','3'), mov_read_dac3 }, /* AC-3 info */
9589 { MKTAG('d','e','c','3'), mov_read_dec3 }, /* EAC-3 info */
9590 { MKTAG('d','d','t','s'), mov_read_ddts }, /* DTS audio descriptor */
9591 { MKTAG('w','i','d','e'), mov_read_wide }, /* place holder */
9592 { MKTAG('w','f','e','x'), mov_read_wfex },
9593 { MKTAG('c','m','o','v'), mov_read_cmov },
9594 { MKTAG('c','h','a','n'), mov_read_chan }, /* channel layout from quicktime */
9595 { MKTAG('c','h','n','l'), mov_read_chnl }, /* channel layout from ISO-14496-12 */
9596 { MKTAG('d','v','c','1'), mov_read_dvc1 },
9597 { MKTAG('s','g','p','d'), mov_read_sgpd },
9598 { MKTAG('s','b','g','p'), mov_read_sbgp },
9599 { MKTAG('h','v','c','C'), mov_read_glbl },
9600 { MKTAG('v','v','c','C'), mov_read_glbl },
9601 { MKTAG('u','u','i','d'), mov_read_uuid },
9602 { MKTAG('C','i','n', 0x8e), mov_read_targa_y216 },
9603 { MKTAG('f','r','e','e'), mov_read_free },
9604 { MKTAG('-','-','-','-'), mov_read_custom },
9605 { MKTAG('s','i','n','f'), mov_read_default },
9606 { MKTAG('f','r','m','a'), mov_read_frma },
9607 { MKTAG('s','e','n','c'), mov_read_senc },
9608 { MKTAG('s','a','i','z'), mov_read_saiz },
9609 { MKTAG('s','a','i','o'), mov_read_saio },
9610 { MKTAG('p','s','s','h'), mov_read_pssh },
9611 { MKTAG('s','c','h','m'), mov_read_schm },
9612 { MKTAG('s','c','h','i'), mov_read_default },
9613 { MKTAG('t','e','n','c'), mov_read_tenc },
9614 { MKTAG('d','f','L','a'), mov_read_dfla },
9615 { MKTAG('s','t','3','d'), mov_read_st3d }, /* stereoscopic 3D video box */
9616 { MKTAG('s','v','3','d'), mov_read_sv3d }, /* spherical video box */
9617 { MKTAG('v','e','x','u'), mov_read_vexu }, /* video extension usage */
9618 { MKTAG('h','f','o','v'), mov_read_hfov },
9619 { MKTAG('d','O','p','s'), mov_read_dops },
9620 { MKTAG('d','m','l','p'), mov_read_dmlp },
9621 { MKTAG('S','m','D','m'), mov_read_smdm },
9622 { MKTAG('C','o','L','L'), mov_read_coll },
9623 { MKTAG('v','p','c','C'), mov_read_vpcc },
9624 { MKTAG('m','d','c','v'), mov_read_mdcv },
9625 { MKTAG('c','l','l','i'), mov_read_clli },
9626 { MKTAG('d','v','c','C'), mov_read_dvcc_dvvc },
9627 { MKTAG('d','v','v','C'), mov_read_dvcc_dvvc },
9628 { MKTAG('d','v','w','C'), mov_read_dvcc_dvvc },
9629 { MKTAG('k','i','n','d'), mov_read_kind },
9630 { MKTAG('S','A','3','D'), mov_read_SA3D }, /* ambisonic audio box */
9631 { MKTAG('S','A','N','D'), mov_read_SAND }, /* non diegetic audio box */
9632 { MKTAG('i','l','o','c'), mov_read_iloc },
9633 { MKTAG('p','c','m','C'), mov_read_pcmc }, /* PCM configuration box */
9634 { MKTAG('p','i','t','m'), mov_read_pitm },
9635 { MKTAG('e','v','c','C'), mov_read_glbl },
9636 { MKTAG('i','d','a','t'), mov_read_idat },
9637 { MKTAG('i','m','i','r'), mov_read_imir },
9638 { MKTAG('i','r','e','f'), mov_read_iref },
9639 { MKTAG('i','s','p','e'), mov_read_ispe },
9640 { MKTAG('i','r','o','t'), mov_read_irot },
9641 { MKTAG('i','p','r','p'), mov_read_iprp },
9642 { MKTAG('i','i','n','f'), mov_read_iinf },
9643 { MKTAG('a','m','v','e'), mov_read_amve }, /* ambient viewing environment box */
9644 { MKTAG('l','h','v','C'), mov_read_lhvc },
9645 { MKTAG('l','v','c','C'), mov_read_glbl },
9646 { MKTAG('a','p','v','C'), mov_read_glbl },
9647 #if CONFIG_IAMFDEC
9648 { MKTAG('i','a','c','b'), mov_read_iacb },
9649 #endif
9650 { MKTAG('s','r','a','t'), mov_read_srat },
9651 { 0, NULL }
9652 };
9653 
9655 {
9656  int64_t total_size = 0;
9657  MOVAtom a;
9658  int i;
9659 
9660  if (c->atom_depth > 10) {
9661  av_log(c->fc, AV_LOG_ERROR, "Atoms too deeply nested\n");
9662  return AVERROR_INVALIDDATA;
9663  }
9664  c->atom_depth ++;
9665 
9666  if (atom.size < 0)
9667  atom.size = INT64_MAX;
9668  while (total_size <= atom.size - 8) {
9669  int (*parse)(MOVContext*, AVIOContext*, MOVAtom) = NULL;
9670  a.size = avio_rb32(pb);
9671  a.type = avio_rl32(pb);
9672  if (avio_feof(pb))
9673  break;
9674  if (((a.type == MKTAG('f','r','e','e') && c->moov_retry) ||
9675  a.type == MKTAG('h','o','o','v')) &&
9676  a.size >= 8 &&
9677  c->fc->strict_std_compliance < FF_COMPLIANCE_STRICT) {
9678  uint32_t type;
9679  avio_skip(pb, 4);
9680  type = avio_rl32(pb);
9681  if (avio_feof(pb))
9682  break;
9683  avio_seek(pb, -8, SEEK_CUR);
9684  if (type == MKTAG('m','v','h','d') ||
9685  type == MKTAG('c','m','o','v')) {
9686  av_log(c->fc, AV_LOG_ERROR, "Detected moov in a free or hoov atom.\n");
9687  a.type = MKTAG('m','o','o','v');
9688  }
9689  }
9690  if (atom.type != MKTAG('r','o','o','t') &&
9691  atom.type != MKTAG('m','o','o','v')) {
9692  if (a.type == MKTAG('t','r','a','k') ||
9693  a.type == MKTAG('m','d','a','t')) {
9694  av_log(c->fc, AV_LOG_ERROR, "Broken file, trak/mdat not at top-level\n");
9695  avio_skip(pb, -8);
9696  c->atom_depth --;
9697  return 0;
9698  }
9699  }
9700  total_size += 8;
9701  if (a.size == 1 && total_size + 8 <= atom.size) { /* 64 bit extended size */
9702  a.size = avio_rb64(pb) - 8;
9703  total_size += 8;
9704  }
9705  av_log(c->fc, AV_LOG_TRACE, "type:'%s' parent:'%s' sz: %"PRId64" %"PRId64" %"PRId64"\n",
9706  av_fourcc2str(a.type), av_fourcc2str(atom.type), a.size, total_size, atom.size);
9707  if (a.size == 0) {
9708  a.size = atom.size - total_size + 8;
9709  }
9710  if (a.size < 0)
9711  break;
9712  a.size -= 8;
9713  if (a.size < 0)
9714  break;
9715  a.size = FFMIN(a.size, atom.size - total_size);
9716 
9717  for (i = 0; mov_default_parse_table[i].type; i++)
9718  if (mov_default_parse_table[i].type == a.type) {
9720  break;
9721  }
9722 
9723  // container is user data
9724  if (!parse && (atom.type == MKTAG('u','d','t','a') ||
9725  atom.type == MKTAG('i','l','s','t')))
9727 
9728  // Supports parsing the QuickTime Metadata Keys.
9729  // https://developer.apple.com/library/mac/documentation/QuickTime/QTFF/Metadata/Metadata.html
9730  if (!parse && c->found_hdlr_mdta &&
9731  atom.type == MKTAG('m','e','t','a') &&
9732  a.type == MKTAG('k','e','y','s') &&
9733  c->meta_keys_count == 0) {
9734  parse = mov_read_keys;
9735  }
9736 
9737  if (!parse) { /* skip leaf atoms data */
9738  avio_skip(pb, a.size);
9739  } else {
9740  int64_t start_pos = avio_tell(pb);
9741  int64_t left;
9742  int err = parse(c, pb, a);
9743  if (err < 0) {
9744  c->atom_depth --;
9745  return err;
9746  }
9747  if (c->found_moov && c->found_mdat && a.size <= INT64_MAX - start_pos &&
9748  ((!(pb->seekable & AVIO_SEEKABLE_NORMAL) || c->fc->flags & AVFMT_FLAG_IGNIDX || c->frag_index.complete) ||
9749  start_pos + a.size == avio_size(pb))) {
9750  if (!(pb->seekable & AVIO_SEEKABLE_NORMAL) || c->fc->flags & AVFMT_FLAG_IGNIDX || c->frag_index.complete)
9751  c->next_root_atom = start_pos + a.size;
9752  c->atom_depth --;
9753  return 0;
9754  }
9755  left = a.size - avio_tell(pb) + start_pos;
9756  if (left > 0) /* skip garbage at atom end */
9757  avio_skip(pb, left);
9758  else if (left < 0) {
9759  av_log(c->fc, AV_LOG_WARNING,
9760  "overread end of atom '%s' by %"PRId64" bytes\n",
9761  av_fourcc2str(a.type), -left);
9762  avio_seek(pb, left, SEEK_CUR);
9763  }
9764  }
9765 
9766  total_size += a.size;
9767  }
9768 
9769  if (total_size < atom.size && atom.size < 0x7ffff)
9770  avio_skip(pb, atom.size - total_size);
9771 
9772  c->atom_depth --;
9773  return 0;
9774 }
9775 
9776 static int mov_probe(const AVProbeData *p)
9777 {
9778  int64_t offset;
9779  uint32_t tag;
9780  int score = 0;
9781  int moov_offset = -1;
9782 
9783  /* check file header */
9784  offset = 0;
9785  for (;;) {
9786  int64_t size;
9787  int minsize = 8;
9788  /* ignore invalid offset */
9789  if ((offset + 8ULL) > (unsigned int)p->buf_size)
9790  break;
9791  size = AV_RB32(p->buf + offset);
9792  if (size == 1 && offset + 16 <= (unsigned int)p->buf_size) {
9793  size = AV_RB64(p->buf+offset + 8);
9794  minsize = 16;
9795  } else if (size == 0) {
9796  size = p->buf_size - offset;
9797  }
9798  if (size < minsize) {
9799  offset += 4;
9800  continue;
9801  }
9802  tag = AV_RL32(p->buf + offset + 4);
9803  switch(tag) {
9804  /* check for obvious tags */
9805  case MKTAG('m','o','o','v'):
9806  moov_offset = offset + 4;
9808  case MKTAG('m','d','a','t'):
9809  case MKTAG('p','n','o','t'): /* detect movs with preview pics like ew.mov and april.mov */
9810  case MKTAG('u','d','t','a'): /* Packet Video PVAuthor adds this and a lot of more junk */
9811  case MKTAG('f','t','y','p'):
9812  if (tag == MKTAG('f','t','y','p') &&
9813  ( AV_RL32(p->buf + offset + 8) == MKTAG('j','p','2',' ')
9814  || AV_RL32(p->buf + offset + 8) == MKTAG('j','p','x',' ')
9815  || AV_RL32(p->buf + offset + 8) == MKTAG('j','x','l',' ')
9816  )) {
9817  score = FFMAX(score, 5);
9818  } else {
9819  score = AVPROBE_SCORE_MAX;
9820  }
9821  break;
9822  /* those are more common words, so rate then a bit less */
9823  case MKTAG('e','d','i','w'): /* xdcam files have reverted first tags */
9824  case MKTAG('w','i','d','e'):
9825  case MKTAG('f','r','e','e'):
9826  case MKTAG('j','u','n','k'):
9827  case MKTAG('p','i','c','t'):
9828  score = FFMAX(score, AVPROBE_SCORE_MAX - 5);
9829  break;
9830  case MKTAG(0x82,0x82,0x7f,0x7d):
9831  score = FFMAX(score, AVPROBE_SCORE_EXTENSION - 5);
9832  break;
9833  case MKTAG('s','k','i','p'):
9834  case MKTAG('u','u','i','d'):
9835  case MKTAG('p','r','f','l'):
9836  /* if we only find those cause probedata is too small at least rate them */
9837  score = FFMAX(score, AVPROBE_SCORE_EXTENSION);
9838  break;
9839  }
9840  if (size > INT64_MAX - offset)
9841  break;
9842  offset += size;
9843  }
9844  if (score > AVPROBE_SCORE_MAX - 50 && moov_offset != -1) {
9845  /* moov atom in the header - we should make sure that this is not a
9846  * MOV-packed MPEG-PS */
9847  offset = moov_offset;
9848 
9849  while (offset < (p->buf_size - 16)) { /* Sufficient space */
9850  /* We found an actual hdlr atom */
9851  if (AV_RL32(p->buf + offset ) == MKTAG('h','d','l','r') &&
9852  AV_RL32(p->buf + offset + 8) == MKTAG('m','h','l','r') &&
9853  AV_RL32(p->buf + offset + 12) == MKTAG('M','P','E','G')) {
9854  av_log(NULL, AV_LOG_WARNING, "Found media data tag MPEG indicating this is a MOV-packed MPEG-PS.\n");
9855  /* We found a media handler reference atom describing an
9856  * MPEG-PS-in-MOV, return a
9857  * low score to force expanding the probe window until
9858  * mpegps_probe finds what it needs */
9859  return 5;
9860  } else {
9861  /* Keep looking */
9862  offset += 2;
9863  }
9864  }
9865  }
9866 
9867  return score;
9868 }
9869 
9870 // must be done after parsing all trak because there's no order requirement
9872 {
9873  MOVContext *mov = s->priv_data;
9874  MOVStreamContext *sc;
9875  int64_t cur_pos;
9876  int i, j;
9877  int chapter_track;
9878 
9879  for (j = 0; j < mov->nb_chapter_tracks; j++) {
9880  AVStream *st = NULL;
9881  FFStream *sti = NULL;
9882  chapter_track = mov->chapter_tracks[j];
9883  for (i = 0; i < s->nb_streams; i++) {
9884  sc = mov->fc->streams[i]->priv_data;
9885  if (sc->id == chapter_track) {
9886  st = s->streams[i];
9887  break;
9888  }
9889  }
9890  if (!st) {
9891  av_log(s, AV_LOG_ERROR, "Referenced QT chapter track not found\n");
9892  continue;
9893  }
9894  sti = ffstream(st);
9895 
9896  sc = st->priv_data;
9897  cur_pos = avio_tell(sc->pb);
9898 
9899  if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
9901  if (!st->attached_pic.data && sti->nb_index_entries) {
9902  // Retrieve the first frame, if possible
9903  AVIndexEntry *sample = &sti->index_entries[0];
9904  if (avio_seek(sc->pb, sample->pos, SEEK_SET) != sample->pos) {
9905  av_log(s, AV_LOG_ERROR, "Failed to retrieve first frame\n");
9906  goto finish;
9907  }
9908 
9909  if (ff_add_attached_pic(s, st, sc->pb, NULL, sample->size) < 0)
9910  goto finish;
9911  }
9912  } else {
9915  st->discard = AVDISCARD_ALL;
9916  for (int i = 0; i < sti->nb_index_entries; i++) {
9917  AVIndexEntry *sample = &sti->index_entries[i];
9918  int64_t end = i+1 < sti->nb_index_entries ? sti->index_entries[i+1].timestamp : st->duration;
9919  uint8_t *title;
9920  uint16_t ch;
9921  int len, title_len;
9922 
9923  if (end < sample->timestamp) {
9924  av_log(s, AV_LOG_WARNING, "ignoring stream duration which is shorter than chapters\n");
9925  end = AV_NOPTS_VALUE;
9926  }
9927 
9928  if (avio_seek(sc->pb, sample->pos, SEEK_SET) != sample->pos) {
9929  av_log(s, AV_LOG_ERROR, "Chapter %d not found in file\n", i);
9930  goto finish;
9931  }
9932 
9933  // the first two bytes are the length of the title
9934  len = avio_rb16(sc->pb);
9935  if (len > sample->size-2)
9936  continue;
9937  title_len = 2*len + 1;
9938  if (!(title = av_mallocz(title_len)))
9939  goto finish;
9940 
9941  // The samples could theoretically be in any encoding if there's an encd
9942  // atom following, but in practice are only utf-8 or utf-16, distinguished
9943  // instead by the presence of a BOM
9944  if (!len) {
9945  title[0] = 0;
9946  } else {
9947  ch = avio_rb16(sc->pb);
9948  if (ch == 0xfeff)
9949  avio_get_str16be(sc->pb, len, title, title_len);
9950  else if (ch == 0xfffe)
9951  avio_get_str16le(sc->pb, len, title, title_len);
9952  else {
9953  AV_WB16(title, ch);
9954  if (len == 1 || len == 2)
9955  title[len] = 0;
9956  else
9957  avio_get_str(sc->pb, INT_MAX, title + 2, len - 1);
9958  }
9959  }
9960 
9961  avpriv_new_chapter(s, i, st->time_base, sample->timestamp, end, title);
9962  av_freep(&title);
9963  }
9964  }
9965 finish:
9966  avio_seek(sc->pb, cur_pos, SEEK_SET);
9967  }
9968 }
9969 
9971  int64_t value, int flags)
9972 {
9973  AVTimecode tc;
9974  char buf[AV_TIMECODE_STR_SIZE];
9975  AVRational rate = st->avg_frame_rate;
9976  int ret = av_timecode_init(&tc, rate, flags, 0, s);
9977  if (ret < 0)
9978  return ret;
9979  av_dict_set(&st->metadata, "timecode",
9980  av_timecode_make_string(&tc, buf, value), 0);
9981  return 0;
9982 }
9983 
9985 {
9986  MOVStreamContext *sc = st->priv_data;
9987  FFStream *const sti = ffstream(st);
9988  char buf[AV_TIMECODE_STR_SIZE];
9989  int64_t cur_pos = avio_tell(sc->pb);
9990  int hh, mm, ss, ff, drop;
9991 
9992  if (!sti->nb_index_entries)
9993  return -1;
9994 
9995  avio_seek(sc->pb, sti->index_entries->pos, SEEK_SET);
9996  avio_skip(s->pb, 13);
9997  hh = avio_r8(s->pb);
9998  mm = avio_r8(s->pb);
9999  ss = avio_r8(s->pb);
10000  drop = avio_r8(s->pb);
10001  ff = avio_r8(s->pb);
10002  snprintf(buf, AV_TIMECODE_STR_SIZE, "%02d:%02d:%02d%c%02d",
10003  hh, mm, ss, drop ? ';' : ':', ff);
10004  av_dict_set(&st->metadata, "timecode", buf, 0);
10005 
10006  avio_seek(sc->pb, cur_pos, SEEK_SET);
10007  return 0;
10008 }
10009 
10011 {
10012  MOVStreamContext *sc = st->priv_data;
10013  FFStream *const sti = ffstream(st);
10014  int flags = 0;
10015  int64_t cur_pos = avio_tell(sc->pb);
10016  int64_t value;
10017  AVRational tc_rate = st->avg_frame_rate;
10018  int tmcd_nb_frames = sc->tmcd_nb_frames;
10019  int rounded_tc_rate;
10020 
10021  if (!sti->nb_index_entries)
10022  return -1;
10023 
10024  if (!tc_rate.num || !tc_rate.den || !tmcd_nb_frames)
10025  return -1;
10026 
10027  avio_seek(sc->pb, sti->index_entries->pos, SEEK_SET);
10028  value = avio_rb32(s->pb);
10029 
10030  if (sc->tmcd_flags & 0x0001) flags |= AV_TIMECODE_FLAG_DROPFRAME;
10031  if (sc->tmcd_flags & 0x0002) flags |= AV_TIMECODE_FLAG_24HOURSMAX;
10032  if (sc->tmcd_flags & 0x0004) flags |= AV_TIMECODE_FLAG_ALLOWNEGATIVE;
10033 
10034  /* Assume Counter flag is set to 1 in tmcd track (even though it is likely
10035  * not the case) and thus assume "frame number format" instead of QT one.
10036  * No sample with tmcd track can be found with a QT timecode at the moment,
10037  * despite what the tmcd track "suggests" (Counter flag set to 0 means QT
10038  * format). */
10039 
10040  /* 60 fps content have tmcd_nb_frames set to 30 but tc_rate set to 60, so
10041  * we multiply the frame number with the quotient.
10042  * See tickets #9492, #9710. */
10043  rounded_tc_rate = (tc_rate.num + tc_rate.den / 2LL) / tc_rate.den;
10044  /* Work around files where tmcd_nb_frames is rounded down from frame rate
10045  * instead of up. See ticket #5978. */
10046  if (tmcd_nb_frames == tc_rate.num / tc_rate.den &&
10047  s->strict_std_compliance < FF_COMPLIANCE_STRICT)
10048  tmcd_nb_frames = rounded_tc_rate;
10049  value = av_rescale(value, rounded_tc_rate, tmcd_nb_frames);
10050 
10052 
10053  avio_seek(sc->pb, cur_pos, SEEK_SET);
10054  return 0;
10055 }
10056 
10058  int i;
10059  if (!index || !*index) return;
10060  for (i = 0; i < (*index)->nb_encrypted_samples; i++) {
10061  av_encryption_info_free((*index)->encrypted_samples[i]);
10062  }
10063  av_freep(&(*index)->encrypted_samples);
10064  av_freep(&(*index)->auxiliary_info_sizes);
10065  av_freep(&(*index)->auxiliary_offsets);
10066  av_freep(index);
10067 }
10068 
10070 {
10071  MOVStreamContext *sc = st->priv_data;
10072 
10073  if (!sc || --sc->refcount) {
10074  st->priv_data = NULL;
10075  return;
10076  }
10077 
10078  av_freep(&sc->tts_data);
10079  for (int i = 0; i < sc->drefs_count; i++) {
10080  av_freep(&sc->drefs[i].path);
10081  av_freep(&sc->drefs[i].dir);
10082  }
10083  av_freep(&sc->drefs);
10084 
10085  sc->drefs_count = 0;
10086 
10087  if (!sc->pb_is_copied)
10088  ff_format_io_close(s, &sc->pb);
10089 
10090  sc->pb = NULL;
10091  av_freep(&sc->chunk_offsets);
10092  av_freep(&sc->stsc_data);
10093  av_freep(&sc->sample_sizes);
10094  av_freep(&sc->keyframes);
10095  av_freep(&sc->ctts_data);
10096  av_freep(&sc->stts_data);
10097  av_freep(&sc->sdtp_data);
10098  av_freep(&sc->stps_data);
10099  av_freep(&sc->elst_data);
10100  av_freep(&sc->rap_group);
10101  av_freep(&sc->sync_group);
10102  av_freep(&sc->sgpd_sync);
10103  av_freep(&sc->sample_offsets);
10104  av_freep(&sc->open_key_samples);
10105  av_freep(&sc->display_matrix);
10106  av_freep(&sc->index_ranges);
10107 
10108  if (sc->extradata)
10109  for (int i = 0; i < sc->stsd_count; i++)
10110  av_free(sc->extradata[i]);
10111  av_freep(&sc->extradata);
10112  av_freep(&sc->extradata_size);
10113 
10117 
10118  av_freep(&sc->stereo3d);
10119  av_freep(&sc->spherical);
10120  av_freep(&sc->mastering);
10121  av_freep(&sc->coll);
10122  av_freep(&sc->ambient);
10123 
10124 #if CONFIG_IAMFDEC
10125  if (sc->iamf)
10127 #endif
10128  av_freep(&sc->iamf);
10129 }
10130 
10132 {
10133  MOVContext *mov = s->priv_data;
10134  int i, j;
10135 
10136  for (i = 0; i < s->nb_streams; i++) {
10137  AVStream *st = s->streams[i];
10138 
10140  }
10141 
10142  av_freep(&mov->dv_demux);
10144  mov->dv_fctx = NULL;
10145 
10146  if (mov->meta_keys) {
10147  for (i = 1; i < mov->meta_keys_count; i++) {
10148  av_freep(&mov->meta_keys[i]);
10149  }
10150  av_freep(&mov->meta_keys);
10151  }
10152 
10153  av_freep(&mov->trex_data);
10154  av_freep(&mov->bitrates);
10155 
10156  for (i = 0; i < mov->frag_index.nb_items; i++) {
10158  for (j = 0; j < mov->frag_index.item[i].nb_stream_info; j++) {
10159  mov_free_encryption_index(&frag[j].encryption_index);
10160  }
10162  }
10163  av_freep(&mov->frag_index.item);
10164 
10165  av_freep(&mov->aes_decrypt);
10166  av_freep(&mov->chapter_tracks);
10167  for (i = 0; i < mov->nb_heif_item; i++) {
10168  if (!mov->heif_item[i])
10169  continue;
10170  av_freep(&mov->heif_item[i]->name);
10171  av_freep(&mov->heif_item[i]->iref_list);
10172  av_freep(&mov->heif_item[i]->icc_profile);
10173  av_freep(&mov->heif_item[i]);
10174  }
10175  av_freep(&mov->heif_item);
10176  for (i = 0; i < mov->nb_heif_grid; i++) {
10177  av_freep(&mov->heif_grid[i].tile_id_list);
10180  }
10181  av_freep(&mov->heif_grid);
10182 
10183  return 0;
10184 }
10185 
10186 static int tmcd_is_referenced(AVFormatContext *s, int tmcd_id)
10187 {
10188  int i;
10189 
10190  for (i = 0; i < s->nb_streams; i++) {
10191  AVStream *st = s->streams[i];
10192  MOVStreamContext *sc = st->priv_data;
10193 
10194  if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO &&
10195  sc->timecode_track == tmcd_id)
10196  return 1;
10197  }
10198  return 0;
10199 }
10200 
10201 /* look for a tmcd track not referenced by any video track, and export it globally */
10203 {
10204  int i;
10205 
10206  for (i = 0; i < s->nb_streams; i++) {
10207  AVStream *st = s->streams[i];
10208 
10209  if (st->codecpar->codec_tag == MKTAG('t','m','c','d') &&
10210  !tmcd_is_referenced(s, i + 1)) {
10211  AVDictionaryEntry *tcr = av_dict_get(st->metadata, "timecode", NULL, 0);
10212  if (tcr) {
10213  av_dict_set(&s->metadata, "timecode", tcr->value, 0);
10214  break;
10215  }
10216  }
10217  }
10218 }
10219 
10220 static int read_tfra(MOVContext *mov, AVIOContext *f)
10221 {
10222  int version, fieldlength, i, j;
10223  int64_t pos = avio_tell(f);
10224  uint32_t size = avio_rb32(f);
10225  unsigned track_id, item_count;
10226 
10227  if (avio_rb32(f) != MKBETAG('t', 'f', 'r', 'a')) {
10228  return 1;
10229  }
10230  av_log(mov->fc, AV_LOG_VERBOSE, "found tfra\n");
10231 
10232  version = avio_r8(f);
10233  avio_rb24(f);
10234  track_id = avio_rb32(f);
10235  fieldlength = avio_rb32(f);
10236  item_count = avio_rb32(f);
10237  for (i = 0; i < item_count; i++) {
10238  int64_t time, offset;
10239  int index;
10240  MOVFragmentStreamInfo * frag_stream_info;
10241 
10242  if (avio_feof(f)) {
10243  return AVERROR_INVALIDDATA;
10244  }
10245 
10246  if (version == 1) {
10247  time = avio_rb64(f);
10248  offset = avio_rb64(f);
10249  } else {
10250  time = avio_rb32(f);
10251  offset = avio_rb32(f);
10252  }
10253 
10254  // The first sample of each stream in a fragment is always a random
10255  // access sample. So it's entry in the tfra can be used as the
10256  // initial PTS of the fragment.
10257  index = update_frag_index(mov, offset);
10258  frag_stream_info = get_frag_stream_info(&mov->frag_index, index, track_id);
10259  if (frag_stream_info &&
10260  frag_stream_info->first_tfra_pts == AV_NOPTS_VALUE)
10261  frag_stream_info->first_tfra_pts = time;
10262 
10263  for (j = 0; j < ((fieldlength >> 4) & 3) + 1; j++)
10264  avio_r8(f);
10265  for (j = 0; j < ((fieldlength >> 2) & 3) + 1; j++)
10266  avio_r8(f);
10267  for (j = 0; j < ((fieldlength >> 0) & 3) + 1; j++)
10268  avio_r8(f);
10269  }
10270 
10271  avio_seek(f, pos + size, SEEK_SET);
10272  return 0;
10273 }
10274 
10276 {
10277  int64_t stream_size = avio_size(f);
10278  int64_t original_pos = avio_tell(f);
10279  int64_t seek_ret;
10280  int ret = -1;
10281  if ((seek_ret = avio_seek(f, stream_size - 4, SEEK_SET)) < 0) {
10282  ret = seek_ret;
10283  goto fail;
10284  }
10285  c->mfra_size = avio_rb32(f);
10286  c->have_read_mfra_size = 1;
10287  if (!c->mfra_size || c->mfra_size > stream_size) {
10288  av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (unreasonable size)\n");
10289  goto fail;
10290  }
10291  if ((seek_ret = avio_seek(f, -((int64_t) c->mfra_size), SEEK_CUR)) < 0) {
10292  ret = seek_ret;
10293  goto fail;
10294  }
10295  if (avio_rb32(f) != c->mfra_size) {
10296  av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (size mismatch)\n");
10297  goto fail;
10298  }
10299  if (avio_rb32(f) != MKBETAG('m', 'f', 'r', 'a')) {
10300  av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (tag mismatch)\n");
10301  goto fail;
10302  }
10303  av_log(c->fc, AV_LOG_VERBOSE, "stream has mfra\n");
10304  do {
10305  ret = read_tfra(c, f);
10306  if (ret < 0)
10307  goto fail;
10308  } while (!ret);
10309  ret = 0;
10310  c->frag_index.complete = 1;
10311 fail:
10312  seek_ret = avio_seek(f, original_pos, SEEK_SET);
10313  if (seek_ret < 0) {
10314  av_log(c->fc, AV_LOG_ERROR,
10315  "failed to seek back after looking for mfra\n");
10316  ret = seek_ret;
10317  }
10318  return ret;
10319 }
10320 
10321 static int set_icc_profile_from_item(AVPacketSideData **coded_side_data, int *nb_coded_side_data,
10322  const HEIFItem *item)
10323 {
10324  AVPacketSideData *sd = av_packet_side_data_new(coded_side_data, nb_coded_side_data,
10326  item->icc_profile_size, 0);
10327  if (!sd)
10328  return AVERROR(ENOMEM);
10329 
10330  memcpy(sd->data, item->icc_profile, item->icc_profile_size);
10331 
10332  return 0;
10333 }
10334 
10335 static int set_display_matrix_from_item(AVPacketSideData **coded_side_data, int *nb_coded_side_data,
10336  const HEIFItem *item)
10337 {
10338  int32_t *matrix;
10339  AVPacketSideData *sd = av_packet_side_data_new(coded_side_data,
10340  nb_coded_side_data,
10342  9 * sizeof(*matrix), 0);
10343  if (!sd)
10344  return AVERROR(ENOMEM);
10345 
10346  matrix = (int32_t*)sd->data;
10347  /* rotation is in the counter-clockwise direction whereas
10348  * av_display_rotation_set() expects its argument to be
10349  * oriented clockwise, so we need to negate it. */
10351  av_display_matrix_flip(matrix, item->hflip, item->vflip);
10352 
10353  return 0;
10354 }
10355 
10356 static int read_image_grid(AVFormatContext *s, const HEIFGrid *grid,
10357  AVStreamGroupTileGrid *tile_grid)
10358 {
10359  MOVContext *c = s->priv_data;
10360  const HEIFItem *item = grid->item;
10361  int64_t offset = 0, pos = avio_tell(s->pb);
10362  int x = 0, y = 0, i = 0;
10363  int tile_rows, tile_cols;
10364  int flags, size;
10365 
10366  if (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL)) {
10367  av_log(c->fc, AV_LOG_INFO, "grid box with non seekable input\n");
10368  return AVERROR_PATCHWELCOME;
10369  }
10370  if (item->is_idat_relative) {
10371  if (!c->idat_offset) {
10372  av_log(c->fc, AV_LOG_ERROR, "missing idat box required by the image grid\n");
10373  return AVERROR_INVALIDDATA;
10374  }
10375  offset = c->idat_offset;
10376  }
10377 
10378  if (offset > INT64_MAX - item->extent_offset)
10379  return AVERROR_INVALIDDATA;
10380 
10381  avio_seek(s->pb, item->extent_offset + offset, SEEK_SET);
10382 
10383  avio_r8(s->pb); /* version */
10384  flags = avio_r8(s->pb);
10385 
10386  tile_rows = avio_r8(s->pb) + 1;
10387  tile_cols = avio_r8(s->pb) + 1;
10388  /* actual width and height of output image */
10389  tile_grid->width = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
10390  tile_grid->height = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
10391 
10392  av_log(c->fc, AV_LOG_TRACE, "grid: grid_rows %d grid_cols %d output_width %d output_height %d\n",
10393  tile_rows, tile_cols, tile_grid->width, tile_grid->height);
10394 
10395  avio_seek(s->pb, pos, SEEK_SET);
10396 
10397  size = tile_rows * tile_cols;
10398  tile_grid->nb_tiles = grid->nb_tiles;
10399 
10400  if (tile_grid->nb_tiles != size)
10401  return AVERROR_INVALIDDATA;
10402 
10403  for (int i = 0; i < tile_cols; i++)
10404  tile_grid->coded_width += grid->tile_item_list[i]->width;
10405  for (int i = 0; i < size; i += tile_cols)
10406  tile_grid->coded_height += grid->tile_item_list[i]->height;
10407 
10408  tile_grid->offsets = av_calloc(tile_grid->nb_tiles, sizeof(*tile_grid->offsets));
10409  if (!tile_grid->offsets)
10410  return AVERROR(ENOMEM);
10411 
10412  while (y < tile_grid->coded_height) {
10413  int left_col = i;
10414 
10415  while (x < tile_grid->coded_width) {
10416  if (i == tile_grid->nb_tiles)
10417  return AVERROR_INVALIDDATA;
10418 
10419  tile_grid->offsets[i].idx = grid->tile_idx_list[i];
10420  tile_grid->offsets[i].horizontal = x;
10421  tile_grid->offsets[i].vertical = y;
10422 
10423  x += grid->tile_item_list[i++]->width;
10424  }
10425 
10426  if (x > tile_grid->coded_width) {
10427  av_log(c->fc, AV_LOG_ERROR, "Non uniform HEIF tiles\n");
10428  return AVERROR_INVALIDDATA;
10429  }
10430 
10431  x = 0;
10432  y += grid->tile_item_list[left_col]->height;
10433  }
10434 
10435  if (y > tile_grid->coded_height || i != tile_grid->nb_tiles) {
10436  av_log(c->fc, AV_LOG_ERROR, "Non uniform HEIF tiles\n");
10437  return AVERROR_INVALIDDATA;
10438  }
10439 
10440  return 0;
10441 }
10442 
10443 static int read_image_iovl(AVFormatContext *s, const HEIFGrid *grid,
10444  AVStreamGroupTileGrid *tile_grid)
10445 {
10446  MOVContext *c = s->priv_data;
10447  const HEIFItem *item = grid->item;
10448  uint16_t canvas_fill_value[4];
10449  int64_t offset = 0, pos = avio_tell(s->pb);
10450  int ret = 0, flags;
10451 
10452  if (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL)) {
10453  av_log(c->fc, AV_LOG_INFO, "iovl box with non seekable input\n");
10454  return AVERROR_PATCHWELCOME;
10455  }
10456  if (item->is_idat_relative) {
10457  if (!c->idat_offset) {
10458  av_log(c->fc, AV_LOG_ERROR, "missing idat box required by the image overlay\n");
10459  return AVERROR_INVALIDDATA;
10460  }
10461  offset = c->idat_offset;
10462  }
10463 
10464  if (offset > INT64_MAX - item->extent_offset)
10465  return AVERROR_INVALIDDATA;
10466 
10467  avio_seek(s->pb, item->extent_offset + offset, SEEK_SET);
10468 
10469  avio_r8(s->pb); /* version */
10470  flags = avio_r8(s->pb);
10471 
10472  for (int i = 0; i < 4; i++)
10473  canvas_fill_value[i] = avio_rb16(s->pb);
10474  av_log(c->fc, AV_LOG_TRACE, "iovl: canvas_fill_value { %u, %u, %u, %u }\n",
10475  canvas_fill_value[0], canvas_fill_value[1],
10476  canvas_fill_value[2], canvas_fill_value[3]);
10477  for (int i = 0; i < 4; i++)
10478  tile_grid->background[i] = canvas_fill_value[i];
10479 
10480  /* actual width and height of output image */
10481  tile_grid->width =
10482  tile_grid->coded_width = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
10483  tile_grid->height =
10484  tile_grid->coded_height = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
10485 
10486  av_log(c->fc, AV_LOG_TRACE, "iovl: output_width %d, output_height %d\n",
10487  tile_grid->width, tile_grid->height);
10488 
10489  tile_grid->nb_tiles = grid->nb_tiles;
10490  tile_grid->offsets = av_malloc_array(tile_grid->nb_tiles, sizeof(*tile_grid->offsets));
10491  if (!tile_grid->offsets) {
10492  ret = AVERROR(ENOMEM);
10493  goto fail;
10494  }
10495 
10496  for (int i = 0; i < tile_grid->nb_tiles; i++) {
10497  tile_grid->offsets[i].idx = grid->tile_idx_list[i];
10498  tile_grid->offsets[i].horizontal = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
10499  tile_grid->offsets[i].vertical = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
10500  av_log(c->fc, AV_LOG_TRACE, "iovl: stream_idx[%d] %u, "
10501  "horizontal_offset[%d] %d, vertical_offset[%d] %d\n",
10502  i, tile_grid->offsets[i].idx,
10503  i, tile_grid->offsets[i].horizontal, i, tile_grid->offsets[i].vertical);
10504  }
10505 
10506 fail:
10507  avio_seek(s->pb, pos, SEEK_SET);
10508 
10509  return ret;
10510 }
10511 
10513  AVPacketSideData **coded_side_data, int *nb_coded_side_data,
10514  const HEIFItem *ref)
10515 {
10516  MOVContext *c = s->priv_data;
10517  AVPacketSideData *sd;
10518  AVExifMetadata ifd = { 0 };
10519  AVBufferRef *buf;
10520  int64_t offset = 0, pos = avio_tell(s->pb);
10521  unsigned orientation_id = av_exif_get_tag_id("Orientation");
10522  int err;
10523 
10524  if (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL)) {
10525  av_log(c->fc, AV_LOG_WARNING, "Exif metadata with non seekable input\n");
10526  return AVERROR_PATCHWELCOME;
10527  }
10528  if (ref->is_idat_relative) {
10529  if (!c->idat_offset) {
10530  av_log(c->fc, AV_LOG_ERROR, "missing idat box required by the Exif metadata\n");
10531  return AVERROR_INVALIDDATA;
10532  }
10533  offset = c->idat_offset;
10534  }
10535 
10536  buf = av_buffer_alloc(ref->extent_length);
10537  if (!buf)
10538  return AVERROR(ENOMEM);
10539 
10540  if (offset > INT64_MAX - ref->extent_offset) {
10541  err = AVERROR(ENOMEM);
10542  goto fail;
10543  }
10544 
10545  avio_seek(s->pb, ref->extent_offset + offset, SEEK_SET);
10546  err = avio_read(s->pb, buf->data, ref->extent_length);
10547  if (err != ref->extent_length) {
10548  if (err > 0)
10549  err = AVERROR_INVALIDDATA;
10550  goto fail;
10551  }
10552 
10553  // HEIF spec states that Exif metadata is informative. The irot item property is
10554  // the normative source of rotation information. So we remove any Orientation tag
10555  // present in the Exif buffer.
10556  err = av_exif_parse_buffer(s, buf->data, ref->extent_length, &ifd, AV_EXIF_T_OFF);
10557  if (err < 0) {
10558  av_log(s, AV_LOG_ERROR, "Unable to parse Exif metadata\n");
10559  goto fail;
10560  }
10561 
10562  err = av_exif_remove_entry(s, &ifd, orientation_id, 0);
10563  if (err < 0)
10564  goto fail;
10565  else if (!err)
10566  goto finish;
10567 
10568  av_buffer_unref(&buf);
10569  err = av_exif_write(s, &ifd, &buf, AV_EXIF_T_OFF);
10570  if (err < 0)
10571  goto fail;
10572 
10573 finish:
10574  offset = AV_RB32(buf->data) + 4;
10575  if (offset >= buf->size) {
10576  err = AVERROR_INVALIDDATA;
10577  goto fail;
10578  }
10579  sd = av_packet_side_data_new(coded_side_data, nb_coded_side_data,
10580  AV_PKT_DATA_EXIF, buf->size - offset, 0);
10581  if (!sd) {
10582  err = AVERROR(ENOMEM);
10583  goto fail;
10584  }
10585  memcpy(sd->data, buf->data + offset, buf->size - offset);
10586 
10587  err = 0;
10588 fail:
10589  av_buffer_unref(&buf);
10590  av_exif_free(&ifd);
10591  avio_seek(s->pb, pos, SEEK_SET);
10592 
10593  return err;
10594 }
10595 
10597 {
10598  MOVContext *mov = s->priv_data;
10599 
10600  for (int i = 0; i < mov->nb_heif_grid; i++) {
10602  AVStreamGroupTileGrid *tile_grid;
10603  const HEIFGrid *grid = &mov->heif_grid[i];
10604  int err, loop = 1;
10605 
10606  if (!stg)
10607  return AVERROR(ENOMEM);
10608 
10609  stg->id = grid->item->item_id;
10610  tile_grid = stg->params.tile_grid;
10611 
10612  for (int j = 0; j < grid->nb_tiles; j++) {
10613  int tile_id = grid->tile_id_list[j];
10614  int k;
10615 
10616  for (k = 0; k < mov->nb_heif_item; k++) {
10617  HEIFItem *item = mov->heif_item[k];
10618  AVStream *st;
10619 
10620  if (!item || item->item_id != tile_id)
10621  continue;
10622  st = item->st;
10623  if (!st) {
10624  av_log(s, AV_LOG_WARNING, "HEIF item id %d from grid id %d doesn't "
10625  "reference a stream\n",
10626  tile_id, grid->item->item_id);
10627  ff_remove_stream_group(s, stg);
10628  loop = 0;
10629  break;
10630  }
10631 
10632  grid->tile_item_list[j] = item;
10633  grid->tile_idx_list[j] = stg->nb_streams;
10634 
10635  err = avformat_stream_group_add_stream(stg, st);
10636  if (err < 0) {
10637  int l;
10638  if (err != AVERROR(EEXIST))
10639  return err;
10640 
10641  for (l = 0; l < stg->nb_streams; l++)
10642  if (stg->streams[l]->index == st->index)
10643  break;
10644  av_assert0(l < stg->nb_streams);
10645  grid->tile_idx_list[j] = l;
10646  }
10647 
10648  if (item->item_id != mov->primary_item_id)
10650  break;
10651  }
10652 
10653  if (k == mov->nb_heif_item) {
10654  av_assert0(loop);
10655  av_log(s, AV_LOG_WARNING, "HEIF item id %d referenced by grid id %d doesn't "
10656  "exist\n",
10657  tile_id, grid->item->item_id);
10658  ff_remove_stream_group(s, stg);
10659  loop = 0;
10660  }
10661  if (!loop)
10662  break;
10663  }
10664 
10665  if (!loop)
10666  continue;
10667 
10668  switch (grid->item->type) {
10669  case MKTAG('g','r','i','d'):
10670  err = read_image_grid(s, grid, tile_grid);
10671  break;
10672  case MKTAG('i','o','v','l'):
10673  err = read_image_iovl(s, grid, tile_grid);
10674  break;
10675  default:
10676  av_assert0(0);
10677  }
10678  if (err < 0)
10679  return err;
10680 
10681  for (int j = 0; j < grid->item->nb_iref_list; j++) {
10682  HEIFItem *ref = get_heif_item(mov, grid->item->iref_list[j].item_id);
10683 
10684  av_assert0(ref);
10685  switch(ref->type) {
10686  case MKTAG('E','x','i','f'):
10687  err = mov_parse_exif_item(s, &tile_grid->coded_side_data,
10688  &tile_grid->nb_coded_side_data, ref);
10689  if (err < 0 && (s->error_recognition & AV_EF_EXPLODE))
10690  return err;
10691  break;
10692  default:
10693  break;
10694  }
10695  }
10696 
10697  /* rotation */
10698  if (grid->item->rotation || grid->item->hflip || grid->item->vflip) {
10700  &tile_grid->nb_coded_side_data, grid->item);
10701  if (err < 0)
10702  return err;
10703  }
10704 
10705  /* ICC profile */
10706  if (grid->item->icc_profile_size) {
10707  err = set_icc_profile_from_item(&tile_grid->coded_side_data,
10708  &tile_grid->nb_coded_side_data, grid->item);
10709  if (err < 0)
10710  return err;
10711  }
10712 
10713  if (grid->item->name)
10714  av_dict_set(&stg->metadata, "title", grid->item->name, 0);
10715  if (grid->item->item_id == mov->primary_item_id)
10717  }
10718 
10719  return 0;
10720 }
10721 
10723 {
10724  MOVContext *mov = s->priv_data;
10725  int err;
10726 
10727  for (int i = 0; i < mov->nb_heif_item; i++) {
10728  HEIFItem *item = mov->heif_item[i];
10729  MOVStreamContext *sc;
10730  AVStream *st;
10731  int64_t offset = 0;
10732 
10733  if (!item)
10734  continue;
10735  if (!item->st) {
10736  continue;
10737  }
10738  if (item->is_idat_relative) {
10739  if (!mov->idat_offset) {
10740  av_log(s, AV_LOG_ERROR, "Missing idat box for item %d\n", item->item_id);
10741  return AVERROR_INVALIDDATA;
10742  }
10743  offset = mov->idat_offset;
10744  }
10745 
10746  st = item->st;
10747  sc = st->priv_data;
10748  st->codecpar->width = item->width;
10749  st->codecpar->height = item->height;
10750 
10751  sc->sample_size = sc->stsz_sample_size = item->extent_length;
10752  sc->sample_count = 1;
10753 
10754  err = sanity_checks(s, sc, st->index);
10755  if (err)
10756  return AVERROR_INVALIDDATA;
10757 
10758  if (offset > INT64_MAX - item->extent_offset)
10759  return AVERROR_INVALIDDATA;
10760 
10761  sc->chunk_offsets[0] = item->extent_offset + offset;
10762 
10763  if (item->item_id == mov->primary_item_id)
10765 
10766  for (int j = 0; j < item->nb_iref_list; j++) {
10767  HEIFItem *ref = get_heif_item(mov, item->iref_list[j].item_id);
10768 
10769  av_assert0(ref);
10770  switch(ref->type) {
10771  case MKTAG('E','x','i','f'):
10774  if (err < 0 && (s->error_recognition & AV_EF_EXPLODE))
10775  return err;
10776  break;
10777  default:
10778  break;
10779  }
10780  }
10781 
10782  if (item->rotation || item->hflip || item->vflip) {
10784  &st->codecpar->nb_coded_side_data, item);
10785  if (err < 0)
10786  return err;
10787  }
10788 
10789  mov_build_index(mov, st);
10790  }
10791 
10792  if (mov->nb_heif_grid) {
10793  err = mov_parse_tiles(s);
10794  if (err < 0)
10795  return err;
10796  }
10797 
10798  return 0;
10799 }
10800 
10802  int first_index)
10803 {
10804  MOVStreamContext *sc = st->priv_data;
10805 
10806  if (sc->tref_id < 0)
10807  return NULL;
10808 
10809  for (int i = first_index; i < s->nb_streams; i++)
10810  if (s->streams[i]->index != st->index &&
10811  s->streams[i]->id == sc->tref_id)
10812  return s->streams[i];
10813 
10814  return NULL;
10815 }
10816 
10818 {
10819  int err;
10820 
10821  // Don't try to add a group if there's only one track
10822  if (s->nb_streams <= 1)
10823  return 0;
10824 
10825  for (int i = 0; i < s->nb_streams; i++) {
10826  AVStreamGroup *stg;
10827  AVStream *st = s->streams[i];
10828  AVStream *st_base;
10829  MOVStreamContext *sc = st->priv_data;
10830  int j = 0;
10831 
10832  /* Find an enhancement stream. */
10833  if (st->codecpar->codec_id != AV_CODEC_ID_LCEVC ||
10835  continue;
10836 
10838  if (!stg)
10839  return AVERROR(ENOMEM);
10840 
10841  stg->id = st->id;
10842  stg->params.lcevc->width = st->codecpar->width;
10843  stg->params.lcevc->height = st->codecpar->height;
10844 
10845  while (st_base = mov_find_reference_track(s, st, j)) {
10846  err = avformat_stream_group_add_stream(stg, st_base);
10847  if (err < 0)
10848  return err;
10849 
10850  j = st_base->index + 1;
10851  }
10852  if (!j) {
10853  int loglevel = (s->error_recognition & AV_EF_EXPLODE) ? AV_LOG_ERROR : AV_LOG_WARNING;
10854  av_log(s, loglevel, "Failed to find base stream for LCEVC stream\n");
10855  ff_remove_stream_group(s, stg);
10856  if (s->error_recognition & AV_EF_EXPLODE)
10857  return AVERROR_INVALIDDATA;
10858  continue;
10859  }
10860 
10861  err = avformat_stream_group_add_stream(stg, st);
10862  if (err < 0)
10863  return err;
10864 
10865  stg->params.lcevc->lcevc_index = stg->nb_streams - 1;
10866  }
10867 
10868  return 0;
10869 }
10870 
10872 {
10873  int highest_id = 0, lowest_iamf_id = INT_MAX;
10874 
10875  for (int i = 0; i < s->nb_streams; i++) {
10876  const AVStream *st = s->streams[i];
10877  const MOVStreamContext *sc = st->priv_data;
10878  if (!sc->iamf)
10879  highest_id = FFMAX(highest_id, st->id);
10880  }
10881 
10882  for (int i = 0; i < s->nb_stream_groups; i++) {
10883  AVStreamGroup *stg = s->stream_groups[i];
10885  continue;
10886  for (int j = 0; j < stg->nb_streams; j++) {
10887  AVStream *st = stg->streams[j];
10888  lowest_iamf_id = FFMIN(lowest_iamf_id, st->id);
10889  }
10890  }
10891 
10892  if (highest_id < lowest_iamf_id)
10893  return;
10894 
10895  highest_id += !lowest_iamf_id;
10896  for (int i = 0; highest_id > 1 && i < s->nb_stream_groups; i++) {
10897  AVStreamGroup *stg = s->stream_groups[i];
10899  continue;
10900  for (int j = 0; j < stg->nb_streams; j++) {
10901  AVStream *st = stg->streams[j];
10902  MOVStreamContext *sc = st->priv_data;
10903  st->id += highest_id;
10904  sc->iamf_stream_offset = highest_id;
10905  }
10906  }
10907 }
10908 
10910 {
10911  MOVContext *mov = s->priv_data;
10912  AVIOContext *pb = s->pb;
10913  int j, err;
10914  MOVAtom atom = { AV_RL32("root") };
10915  int i;
10916 
10917  mov->fc = s;
10918  mov->trak_index = -1;
10919  mov->primary_item_id = -1;
10920  mov->cur_item_id = -1;
10921  /* .mov and .mp4 aren't streamable anyway (only progressive download if moov is before mdat) */
10922  if (pb->seekable & AVIO_SEEKABLE_NORMAL)
10923  atom.size = avio_size(pb);
10924  else
10925  atom.size = INT64_MAX;
10926 
10927  /* check MOV header */
10928  do {
10929  if (mov->moov_retry)
10930  avio_seek(pb, 0, SEEK_SET);
10931  if ((err = mov_read_default(mov, pb, atom)) < 0) {
10932  av_log(s, AV_LOG_ERROR, "error reading header\n");
10933  return err;
10934  }
10935  } while ((pb->seekable & AVIO_SEEKABLE_NORMAL) &&
10936  !mov->found_moov && (!mov->found_iloc || !mov->found_iinf) && !mov->moov_retry++);
10937  if (!mov->found_moov && !mov->found_iloc && !mov->found_iinf) {
10938  av_log(s, AV_LOG_ERROR, "moov atom not found\n");
10939  return AVERROR_INVALIDDATA;
10940  }
10941  av_log(mov->fc, AV_LOG_TRACE, "on_parse_exit_offset=%"PRId64"\n", avio_tell(pb));
10942 
10943  if (mov->found_iloc && mov->found_iinf) {
10944  err = mov_parse_heif_items(s);
10945  if (err < 0)
10946  return err;
10947  }
10948  // prevent iloc and iinf boxes from being parsed while reading packets.
10949  // this is needed because an iinf box may have been parsed but ignored
10950  // for having old infe boxes which create no streams.
10951  mov->found_iloc = mov->found_iinf = 1;
10952 
10953  if (pb->seekable & AVIO_SEEKABLE_NORMAL) {
10954  if (mov->nb_chapter_tracks > 0 && !mov->ignore_chapters)
10956  for (i = 0; i < s->nb_streams; i++)
10957  if (s->streams[i]->codecpar->codec_tag == AV_RL32("tmcd")) {
10958  mov_read_timecode_track(s, s->streams[i]);
10959  } else if (s->streams[i]->codecpar->codec_tag == AV_RL32("rtmd")) {
10960  mov_read_rtmd_track(s, s->streams[i]);
10961  }
10962  }
10963 
10964  /* copy timecode metadata from tmcd tracks to the related video streams */
10965  for (i = 0; i < s->nb_streams; i++) {
10966  AVStream *st = s->streams[i];
10967  MOVStreamContext *sc = st->priv_data;
10968  if (sc->timecode_track > 0) {
10969  AVDictionaryEntry *tcr;
10970  int tmcd_st_id = -1;
10971 
10972  for (j = 0; j < s->nb_streams; j++) {
10973  MOVStreamContext *sc2 = s->streams[j]->priv_data;
10974  if (sc2->id == sc->timecode_track)
10975  tmcd_st_id = j;
10976  }
10977 
10978  if (tmcd_st_id < 0 || tmcd_st_id == i)
10979  continue;
10980  tcr = av_dict_get(s->streams[tmcd_st_id]->metadata, "timecode", NULL, 0);
10981  if (tcr)
10982  av_dict_set(&st->metadata, "timecode", tcr->value, 0);
10983  }
10984  }
10986 
10987  /* Create LCEVC stream groups. */
10988  err = mov_parse_lcevc_streams(s);
10989  if (err < 0)
10990  return err;
10991 
10992  for (i = 0; i < s->nb_streams; i++) {
10993  AVStream *st = s->streams[i];
10994  FFStream *const sti = ffstream(st);
10995  MOVStreamContext *sc = st->priv_data;
10996  uint32_t dvdsub_clut[FF_DVDCLUT_CLUT_LEN] = {0};
10997  fix_timescale(mov, sc);
10998 
10999  /* Set the primary extradata based on the first Sample if it doesn't reference the first stsd entry. */
11000  if (sc->stsc_count && sc->extradata_size && !sc->iamf &&
11001  sc->stsc_data[0].id > 1 && sc->stsc_data[0].id <= sc->stsd_count) {
11002  sc->last_stsd_index = sc->stsc_data[0].id - 1;
11003  av_freep(&st->codecpar->extradata);
11005  if (sc->extradata_size[sc->last_stsd_index]) {
11007  if (!st->codecpar->extradata)
11008  return AVERROR(ENOMEM);
11009  memcpy(st->codecpar->extradata, sc->extradata[sc->last_stsd_index], sc->extradata_size[sc->last_stsd_index]);
11010  }
11011  }
11012 
11013  if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
11014  st->codecpar->codec_id == AV_CODEC_ID_AAC) {
11015  sti->skip_samples = sc->start_pad;
11016  }
11017  if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && sc->nb_frames_for_fps > 0 && sc->duration_for_fps > 0)
11019  sc->time_scale*(int64_t)sc->nb_frames_for_fps, sc->duration_for_fps, INT_MAX);
11021  if (st->codecpar->width <= 0 || st->codecpar->height <= 0) {
11022  st->codecpar->width = sc->width;
11023  st->codecpar->height = sc->height;
11024  }
11027 
11028  for (j = 0; j < FF_DVDCLUT_CLUT_LEN; j++)
11029  dvdsub_clut[j] = AV_RB32(st->codecpar->extradata + j * 4);
11030 
11031  err = ff_dvdclut_yuv_to_rgb(dvdsub_clut, FF_DVDCLUT_CLUT_SIZE);
11032  if (err < 0)
11033  return err;
11034 
11035  av_freep(&st->codecpar->extradata);
11036  st->codecpar->extradata_size = 0;
11037 
11039  st->codecpar);
11040  if (err < 0)
11041  return err;
11042  }
11043  }
11044  if (mov->handbrake_version &&
11045  mov->handbrake_version <= 1000000*0 + 1000*10 + 2 && // 0.10.2
11046  st->codecpar->codec_id == AV_CODEC_ID_MP3) {
11047  av_log(s, AV_LOG_VERBOSE, "Forcing full parsing for mp3 stream\n");
11049  }
11050  }
11051 
11052  if (mov->trex_data || mov->use_mfra_for > 0) {
11053  for (i = 0; i < s->nb_streams; i++) {
11054  AVStream *st = s->streams[i];
11055  MOVStreamContext *sc = st->priv_data;
11056  if (sc->duration_for_fps > 0) {
11057  /* Akin to sc->data_size * 8 * sc->time_scale / sc->duration_for_fps but accounting for overflows. */
11059  if (st->codecpar->bit_rate == INT64_MIN) {
11060  av_log(s, AV_LOG_WARNING, "Overflow during bit rate calculation %"PRId64" * 8 * %d\n",
11061  sc->data_size, sc->time_scale);
11062  st->codecpar->bit_rate = 0;
11063  if (s->error_recognition & AV_EF_EXPLODE)
11064  return AVERROR_INVALIDDATA;
11065  }
11066  }
11067  }
11068  }
11069 
11070  for (i = 0; i < mov->bitrates_count && i < s->nb_streams; i++) {
11071  if (mov->bitrates[i]) {
11072  s->streams[i]->codecpar->bit_rate = mov->bitrates[i];
11073  }
11074  }
11075 
11077 
11078  for (i = 0; i < s->nb_streams; i++) {
11079  AVStream *st = s->streams[i];
11080  MOVStreamContext *sc = st->priv_data;
11081 
11082  switch (st->codecpar->codec_type) {
11083  case AVMEDIA_TYPE_AUDIO:
11084  err = ff_replaygain_export(st, s->metadata);
11085  if (err < 0)
11086  return err;
11087  break;
11088  case AVMEDIA_TYPE_VIDEO:
11089  if (sc->display_matrix) {
11092  (uint8_t*)sc->display_matrix, sizeof(int32_t) * 9, 0))
11093  return AVERROR(ENOMEM);
11094 
11095  sc->display_matrix = NULL;
11096  }
11097  if (sc->stereo3d) {
11100  (uint8_t *)sc->stereo3d, sc->stereo3d_size, 0))
11101  return AVERROR(ENOMEM);
11102 
11103  sc->stereo3d = NULL;
11104  }
11105  if (sc->spherical) {
11108  (uint8_t *)sc->spherical, sc->spherical_size, 0))
11109  return AVERROR(ENOMEM);
11110 
11111  sc->spherical = NULL;
11112  }
11113  if (sc->mastering) {
11116  (uint8_t *)sc->mastering, sc->mastering_size, 0))
11117  return AVERROR(ENOMEM);
11118 
11119  sc->mastering = NULL;
11120  }
11121  if (sc->coll) {
11124  (uint8_t *)sc->coll, sc->coll_size, 0))
11125  return AVERROR(ENOMEM);
11126 
11127  sc->coll = NULL;
11128  }
11129  if (sc->ambient) {
11132  (uint8_t *) sc->ambient, sc->ambient_size, 0))
11133  return AVERROR(ENOMEM);
11134 
11135  sc->ambient = NULL;
11136  }
11137  break;
11138  }
11139  }
11140 
11141  fix_stream_ids(s);
11142 
11144 
11145  for (i = 0; i < mov->frag_index.nb_items; i++)
11146  if (mov->frag_index.item[i].moof_offset <= mov->fragment.moof_offset)
11147  mov->frag_index.item[i].headers_read = 1;
11148 
11149  return 0;
11150 }
11151 
11153 {
11155  int64_t best_dts = INT64_MAX;
11156  int i;
11157  MOVContext *mov = s->priv_data;
11158  int no_interleave = !mov->interleaved_read || !(s->pb->seekable & AVIO_SEEKABLE_NORMAL);
11159  for (i = 0; i < s->nb_streams; i++) {
11160  AVStream *avst = s->streams[i];
11161  FFStream *const avsti = ffstream(avst);
11162  MOVStreamContext *msc = avst->priv_data;
11163  if (msc->pb && msc->current_sample < avsti->nb_index_entries) {
11164  AVIndexEntry *current_sample = &avsti->index_entries[msc->current_sample];
11165  int64_t dts = av_rescale(current_sample->timestamp, AV_TIME_BASE, msc->time_scale);
11166  uint64_t dtsdiff = best_dts > dts ? best_dts - (uint64_t)dts : ((uint64_t)dts - best_dts);
11167  av_log(s, AV_LOG_TRACE, "stream %d, sample %d, dts %"PRId64"\n", i, msc->current_sample, dts);
11168  if (!sample || (no_interleave && current_sample->pos < sample->pos) ||
11169  ((s->pb->seekable & AVIO_SEEKABLE_NORMAL) &&
11170  ((msc->pb != s->pb && dts < best_dts) || (msc->pb == s->pb && dts != AV_NOPTS_VALUE &&
11171  ((dtsdiff <= AV_TIME_BASE && current_sample->pos < sample->pos) ||
11172  (dtsdiff > AV_TIME_BASE && dts < best_dts && mov->interleaved_read)))))) {
11173  sample = current_sample;
11174  best_dts = dts;
11175  *st = avst;
11176  }
11177  }
11178  }
11179  return sample;
11180 }
11181 
11182 static int should_retry(AVIOContext *pb, int error_code) {
11183  if (error_code == AVERROR_EOF || avio_feof(pb))
11184  return 0;
11185 
11186  return 1;
11187 }
11188 
11189 static int mov_switch_root(AVFormatContext *s, int64_t target, int index)
11190 {
11191  int ret;
11192  MOVContext *mov = s->priv_data;
11193 
11194  if (index >= 0 && index < mov->frag_index.nb_items)
11195  target = mov->frag_index.item[index].moof_offset;
11196  if (target >= 0 && avio_seek(s->pb, target, SEEK_SET) != target) {
11197  av_log(mov->fc, AV_LOG_ERROR, "root atom offset 0x%"PRIx64": partial file\n", target);
11198  return AVERROR_INVALIDDATA;
11199  }
11200 
11201  mov->next_root_atom = 0;
11202  if ((index < 0 && target >= 0) || index >= mov->frag_index.nb_items)
11203  index = search_frag_moof_offset(&mov->frag_index, target);
11204  if (index >= 0 && index < mov->frag_index.nb_items &&
11205  mov->frag_index.item[index].moof_offset == target) {
11206  if (index + 1 < mov->frag_index.nb_items)
11207  mov->next_root_atom = mov->frag_index.item[index + 1].moof_offset;
11208  if (mov->frag_index.item[index].headers_read)
11209  return 0;
11210  mov->frag_index.item[index].headers_read = 1;
11211  }
11212 
11213  mov->found_mdat = 0;
11214 
11215  ret = mov_read_default(mov, s->pb, (MOVAtom){ AV_RL32("root"), INT64_MAX });
11216  if (ret < 0)
11217  return ret;
11218  if (avio_feof(s->pb))
11219  return AVERROR_EOF;
11220  av_log(s, AV_LOG_TRACE, "read fragments, offset 0x%"PRIx64"\n", avio_tell(s->pb));
11221 
11222  return 1;
11223 }
11224 
11226 {
11227  MOVStreamContext *sc = st->priv_data;
11228  uint8_t *side, *extradata;
11229  int extradata_size;
11230 
11231  /* Save the current index. */
11232  sc->last_stsd_index = sc->stsc_data[sc->stsc_index].id - 1;
11233 
11234  /* Notify the decoder that extradata changed. */
11235  extradata_size = sc->extradata_size[sc->last_stsd_index];
11236  extradata = sc->extradata[sc->last_stsd_index];
11237  if (st->discard != AVDISCARD_ALL && extradata_size > 0 && extradata) {
11240  extradata_size);
11241  if (!side)
11242  return AVERROR(ENOMEM);
11243  memcpy(side, extradata, extradata_size);
11244  }
11245 
11246  return 0;
11247 }
11248 
11249 static int get_eia608_packet(AVIOContext *pb, AVPacket *pkt, int src_size)
11250 {
11251  /* We can't make assumptions about the structure of the payload,
11252  because it may include multiple cdat and cdt2 samples. */
11253  const uint32_t cdat = AV_RB32("cdat");
11254  const uint32_t cdt2 = AV_RB32("cdt2");
11255  int ret, out_size = 0;
11256 
11257  /* a valid payload must have size, 4cc, and at least 1 byte pair: */
11258  if (src_size < 10)
11259  return AVERROR_INVALIDDATA;
11260 
11261  /* avoid an int overflow: */
11262  if ((src_size - 8) / 2 >= INT_MAX / 3)
11263  return AVERROR_INVALIDDATA;
11264 
11265  ret = av_new_packet(pkt, ((src_size - 8) / 2) * 3);
11266  if (ret < 0)
11267  return ret;
11268 
11269  /* parse and re-format the c608 payload in one pass. */
11270  while (src_size >= 10) {
11271  const uint32_t atom_size = avio_rb32(pb);
11272  const uint32_t atom_type = avio_rb32(pb);
11273  const uint32_t data_size = atom_size - 8;
11274  const uint8_t cc_field =
11275  atom_type == cdat ? 1 :
11276  atom_type == cdt2 ? 2 :
11277  0;
11278 
11279  /* account for bytes consumed for atom size and type. */
11280  src_size -= 8;
11281 
11282  /* make sure the data size stays within the buffer boundaries. */
11283  if (data_size < 2 || data_size > src_size) {
11285  break;
11286  }
11287 
11288  /* make sure the data size is consistent with N byte pairs. */
11289  if (data_size % 2 != 0) {
11291  break;
11292  }
11293 
11294  if (!cc_field) {
11295  /* neither cdat or cdt2 ... skip it */
11296  avio_skip(pb, data_size);
11297  src_size -= data_size;
11298  continue;
11299  }
11300 
11301  for (uint32_t i = 0; i < data_size; i += 2) {
11302  pkt->data[out_size] = (0x1F << 3) | (1 << 2) | (cc_field - 1);
11303  pkt->data[out_size + 1] = avio_r8(pb);
11304  pkt->data[out_size + 2] = avio_r8(pb);
11305  out_size += 3;
11306  src_size -= 2;
11307  }
11308  }
11309 
11310  if (src_size > 0)
11311  /* skip any remaining unread portion of the input payload */
11312  avio_skip(pb, src_size);
11313 
11315  return ret;
11316 }
11317 
11319  int64_t current_index, AVPacket *pkt)
11320 {
11321  MOVStreamContext *sc = st->priv_data;
11322 
11323  pkt->stream_index = sc->ffindex;
11324  pkt->dts = sample->timestamp;
11325  if (sample->flags & AVINDEX_DISCARD_FRAME) {
11327  }
11328  if (sc->stts_count && sc->tts_index < sc->tts_count)
11329  pkt->duration = sc->tts_data[sc->tts_index].duration;
11330  if (sc->ctts_count && sc->tts_index < sc->tts_count) {
11332  } else {
11333  if (pkt->duration == 0) {
11334  int64_t next_dts = (sc->current_sample < ffstream(st)->nb_index_entries) ?
11336  if (next_dts >= pkt->dts)
11337  pkt->duration = next_dts - pkt->dts;
11338  }
11339  pkt->pts = pkt->dts;
11340  }
11341 
11342  if (sc->tts_data && sc->tts_index < sc->tts_count) {
11343  /* update tts context */
11344  sc->tts_sample++;
11345  if (sc->tts_index < sc->tts_count &&
11346  sc->tts_data[sc->tts_index].count == sc->tts_sample) {
11347  sc->tts_index++;
11348  sc->tts_sample = 0;
11349  }
11350  }
11351 
11352  if (sc->sdtp_data && sc->current_sample <= sc->sdtp_count) {
11353  uint8_t sample_flags = sc->sdtp_data[sc->current_sample - 1];
11354  uint8_t sample_is_depended_on = (sample_flags >> 2) & 0x3;
11355  pkt->flags |= sample_is_depended_on == MOV_SAMPLE_DEPENDENCY_NO ? AV_PKT_FLAG_DISPOSABLE : 0;
11356  }
11357  pkt->flags |= sample->flags & AVINDEX_KEYFRAME ? AV_PKT_FLAG_KEY : 0;
11358  pkt->pos = sample->pos;
11359 
11360  /* Multiple stsd handling. */
11361  if (sc->stsc_data) {
11362  if (sc->stsc_data[sc->stsc_index].id > 0 &&
11363  sc->stsc_data[sc->stsc_index].id - 1 < sc->stsd_count &&
11364  sc->stsc_data[sc->stsc_index].id - 1 != sc->last_stsd_index) {
11365  int ret = mov_change_extradata(st, pkt);
11366  if (ret < 0)
11367  return ret;
11368  }
11369 
11370  /* Update the stsc index for the next sample */
11371  sc->stsc_sample++;
11372  if (mov_stsc_index_valid(sc->stsc_index, sc->stsc_count) &&
11373  mov_get_stsc_samples(sc, sc->stsc_index) == sc->stsc_sample) {
11374  sc->stsc_index++;
11375  sc->stsc_sample = 0;
11376  }
11377  }
11378 
11379  return 0;
11380 }
11381 
11383 {
11384  MOVContext *mov = s->priv_data;
11385  MOVStreamContext *sc;
11387  AVStream *st = NULL;
11388  FFStream *avsti = NULL;
11389  int64_t current_index;
11390  int ret;
11391  int i;
11392  mov->fc = s;
11393  retry:
11394  if (s->pb->pos == 0) {
11395 
11396  // Discard current fragment index
11397  if (mov->frag_index.allocated_size > 0) {
11398  for(int i = 0; i < mov->frag_index.nb_items; i++) {
11400  }
11401  av_freep(&mov->frag_index.item);
11402  mov->frag_index.nb_items = 0;
11403  mov->frag_index.allocated_size = 0;
11404  mov->frag_index.current = -1;
11405  mov->frag_index.complete = 0;
11406  }
11407 
11408  for (i = 0; i < s->nb_streams; i++) {
11409  AVStream *avst = s->streams[i];
11410  MOVStreamContext *msc = avst->priv_data;
11411 
11412  // Clear current sample
11413  mov_current_sample_set(msc, 0);
11414  msc->tts_index = 0;
11415 
11416  // Discard current index entries
11417  avsti = ffstream(avst);
11418  if (avsti->index_entries_allocated_size > 0) {
11419  av_freep(&avsti->index_entries);
11420  avsti->index_entries_allocated_size = 0;
11421  avsti->nb_index_entries = 0;
11422  }
11423  }
11424 
11425  if ((ret = mov_switch_root(s, -1, -1)) < 0)
11426  return ret;
11427  }
11428  sample = mov_find_next_sample(s, &st);
11429  if (!sample || (mov->next_root_atom && sample->pos > mov->next_root_atom)) {
11430  if (!mov->next_root_atom)
11431  return AVERROR_EOF;
11432  if ((ret = mov_switch_root(s, mov->next_root_atom, -1)) < 0)
11433  return ret;
11434  goto retry;
11435  }
11436  sc = st->priv_data;
11437  /* must be done just before reading, to avoid infinite loop on sample */
11438  current_index = sc->current_index;
11440 
11441  if (mov->next_root_atom) {
11442  sample->pos = FFMIN(sample->pos, mov->next_root_atom);
11443  sample->size = FFMIN(sample->size, (mov->next_root_atom - sample->pos));
11444  }
11445 
11446  if (st->discard != AVDISCARD_ALL || sc->iamf) {
11447  int64_t ret64 = avio_seek(sc->pb, sample->pos, SEEK_SET);
11448  if (ret64 != sample->pos) {
11449  av_log(mov->fc, AV_LOG_ERROR, "stream %d, offset 0x%"PRIx64": partial file\n",
11450  sc->ffindex, sample->pos);
11451  if (should_retry(sc->pb, ret64)) {
11453  } else if (ret64 < 0) {
11454  return (int)ret64;
11455  }
11456  return AVERROR_INVALIDDATA;
11457  }
11458 
11459  if (st->discard == AVDISCARD_NONKEY && !(sample->flags & AVINDEX_KEYFRAME)) {
11460  av_log(mov->fc, AV_LOG_DEBUG, "Nonkey frame from stream %d discarded due to AVDISCARD_NONKEY\n", sc->ffindex);
11461  goto retry;
11462  }
11463 
11464  if (st->codecpar->codec_id == AV_CODEC_ID_EIA_608 && sample->size > 8)
11465  ret = get_eia608_packet(sc->pb, pkt, sample->size);
11466 #if CONFIG_IAMFDEC
11467  else if (sc->iamf) {
11468  int64_t pts, dts, pos, duration;
11469  int flags, size = sample->size;
11470  ret = mov_finalize_packet(s, st, sample, current_index, pkt);
11471  pts = pkt->pts; dts = pkt->dts;
11472  pos = pkt->pos; flags = pkt->flags;
11473  duration = pkt->duration;
11474  while (!ret && size > 0) {
11475  ret = ff_iamf_read_packet(s, sc->iamf, sc->pb, size, sc->iamf_stream_offset, pkt);
11476  if (ret < 0) {
11477  if (should_retry(sc->pb, ret))
11479  return ret;
11480  }
11481  size -= ret;
11482 
11483  if (pkt->flags & AV_PKT_FLAG_DISCARD) {
11485  ret = 0;
11486  continue;
11487  }
11488  pkt->pts = pts; pkt->dts = dts;
11489  pkt->pos = pos; pkt->flags |= flags;
11490  pkt->duration = duration;
11491  ret = ff_buffer_packet(s, pkt);
11492  }
11493  if (!ret)
11494  return FFERROR_REDO;
11495  }
11496 #endif
11497  else if (st->codecpar->codec_id == AV_CODEC_ID_APV && sample->size > 4) {
11498  const uint32_t au_size = avio_rb32(sc->pb);
11499  ret = av_get_packet(sc->pb, pkt, au_size);
11500  } else
11501  ret = av_get_packet(sc->pb, pkt, sample->size);
11502  if (ret < 0) {
11503  if (should_retry(sc->pb, ret)) {
11505  }
11506  return ret;
11507  }
11508 #if CONFIG_DV_DEMUXER
11509  if (mov->dv_demux && sc->dv_audio_container) {
11512  if (ret < 0)
11513  return ret;
11515  if (ret < 0)
11516  return ret;
11517  }
11518 #endif
11519  if (sc->has_palette) {
11520  uint8_t *pal;
11521 
11523  if (!pal) {
11524  av_log(mov->fc, AV_LOG_ERROR, "Cannot append palette to packet\n");
11525  } else {
11526  memcpy(pal, sc->palette, AVPALETTE_SIZE);
11527  sc->has_palette = 0;
11528  }
11529  }
11530  if (st->codecpar->codec_id == AV_CODEC_ID_MP3 && !ffstream(st)->need_parsing && pkt->size > 4) {
11531  if (ff_mpa_check_header(AV_RB32(pkt->data)) < 0)
11533  }
11534  }
11535 
11536  ret = mov_finalize_packet(s, st, sample, current_index, pkt);
11537  if (ret < 0)
11538  return ret;
11539 
11540  if (st->discard == AVDISCARD_ALL)
11541  goto retry;
11542 
11543  if (mov->aax_mode)
11544  aax_filter(pkt->data, pkt->size, mov);
11545 
11546  ret = cenc_filter(mov, st, sc, pkt, current_index);
11547  if (ret < 0) {
11548  return ret;
11549  }
11550 
11551  return 0;
11552 }
11553 
11555 {
11556  MOVContext *mov = s->priv_data;
11557  int index;
11558 
11559  if (!mov->frag_index.complete)
11560  return 0;
11561 
11562  index = search_frag_timestamp(s, &mov->frag_index, st, timestamp);
11563  if (index < 0)
11564  index = 0;
11565  if (!mov->frag_index.item[index].headers_read)
11566  return mov_switch_root(s, -1, index);
11567  if (index + 1 < mov->frag_index.nb_items)
11568  mov->next_root_atom = mov->frag_index.item[index + 1].moof_offset;
11569 
11570  return 0;
11571 }
11572 
11573 static int is_open_key_sample(const MOVStreamContext *sc, int sample)
11574 {
11575  // TODO: a bisect search would scale much better
11576  for (int i = 0; i < sc->open_key_samples_count; i++) {
11577  const int oks = sc->open_key_samples[i];
11578  if (oks == sample)
11579  return 1;
11580  if (oks > sample) /* list is monotically increasing so we can stop early */
11581  break;
11582  }
11583  return 0;
11584 }
11585 
11586 /*
11587  * Some key sample may be key frames but not IDR frames, so a random access to
11588  * them may not be allowed.
11589  */
11590 static int can_seek_to_key_sample(AVStream *st, int sample, int64_t requested_pts)
11591 {
11592  MOVStreamContext *sc = st->priv_data;
11593  FFStream *const sti = ffstream(st);
11594  int64_t key_sample_dts, key_sample_pts;
11595 
11596  if (st->codecpar->codec_id != AV_CODEC_ID_HEVC)
11597  return 1;
11598 
11599  if (sample >= sc->sample_offsets_count)
11600  return 1;
11601 
11602  av_assert0(sample >= 0);
11603  key_sample_dts = sti->index_entries[sample].timestamp;
11604  key_sample_pts = key_sample_dts + sc->sample_offsets[sample] + sc->dts_shift;
11605 
11606  /*
11607  * If the sample needs to be presented before an open key sample, they may
11608  * not be decodable properly, even though they come after in decoding
11609  * order.
11610  */
11611  if (is_open_key_sample(sc, sample) && key_sample_pts > requested_pts)
11612  return 0;
11613 
11614  return 1;
11615 }
11616 
11617 static int mov_seek_stream(AVFormatContext *s, AVStream *st, int64_t timestamp, int flags)
11618 {
11619  MOVStreamContext *sc = st->priv_data;
11620  FFStream *const sti = ffstream(st);
11621  int sample, time_sample, ret, requested_sample;
11622  int64_t next_ts;
11623  unsigned int i;
11624 
11625  // Here we consider timestamp to be PTS, hence try to offset it so that we
11626  // can search over the DTS timeline.
11627  timestamp -= (sc->min_corrected_pts + sc->dts_shift);
11628 
11629  ret = mov_seek_fragment(s, st, timestamp);
11630  if (ret < 0)
11631  return ret;
11632 
11633  for (;;) {
11634  sample = av_index_search_timestamp(st, timestamp, flags);
11635  av_log(s, AV_LOG_TRACE, "stream %d, timestamp %"PRId64", sample %d\n", st->index, timestamp, sample);
11636  if (sample < 0 && sti->nb_index_entries && timestamp < sti->index_entries[0].timestamp)
11637  sample = 0;
11638  if (sample < 0) /* not sure what to do */
11639  return AVERROR_INVALIDDATA;
11640 
11641  if (!sample || can_seek_to_key_sample(st, sample, timestamp))
11642  break;
11643 
11644  next_ts = timestamp - FFMAX(sc->min_sample_duration, 1);
11645  requested_sample = av_index_search_timestamp(st, next_ts, flags);
11646  if (requested_sample < 0)
11647  return AVERROR_INVALIDDATA;
11648 
11649  // If we've reached a different sample trying to find a good pts to
11650  // seek to, give up searching because we'll end up seeking back to
11651  // sample 0 on every seek.
11652  if (sample != requested_sample && !can_seek_to_key_sample(st, requested_sample, next_ts))
11653  break;
11654 
11655  timestamp = next_ts;
11656  }
11657 
11659  av_log(s, AV_LOG_TRACE, "stream %d, found sample %d\n", st->index, sc->current_sample);
11660  /* adjust time to sample index */
11661  if (sc->tts_data) {
11662  time_sample = 0;
11663  for (i = 0; i < sc->tts_count; i++) {
11664  int next = time_sample + sc->tts_data[i].count;
11665  if (next > sc->current_sample) {
11666  sc->tts_index = i;
11667  sc->tts_sample = sc->current_sample - time_sample;
11668  break;
11669  }
11670  time_sample = next;
11671  }
11672  }
11673 
11674  /* adjust stsd index */
11675  if (sc->chunk_count) {
11676  time_sample = 0;
11677  for (i = 0; i < sc->stsc_count; i++) {
11678  int64_t next = time_sample + mov_get_stsc_samples(sc, i);
11679  if (next > sc->current_sample) {
11680  sc->stsc_index = i;
11681  sc->stsc_sample = sc->current_sample - time_sample;
11682  break;
11683  }
11684  av_assert0(next == (int)next);
11685  time_sample = next;
11686  }
11687  }
11688 
11689  return sample;
11690 }
11691 
11693 {
11694  MOVStreamContext *sc = st->priv_data;
11695  FFStream *const sti = ffstream(st);
11696  int64_t first_ts = sti->index_entries[0].timestamp;
11698  int64_t off;
11699 
11701  return 0;
11702 
11703  /* compute skip samples according to stream start_pad, seek ts and first ts */
11704  off = av_rescale_q(ts - first_ts, st->time_base,
11705  (AVRational){1, st->codecpar->sample_rate});
11706  return FFMAX(sc->start_pad - off, 0);
11707 }
11708 
11709 static int mov_read_seek(AVFormatContext *s, int stream_index, int64_t sample_time, int flags)
11710 {
11711  MOVContext *mc = s->priv_data;
11712  AVStream *st;
11713  FFStream *sti;
11714  int sample;
11715  int i;
11716 
11717  if (stream_index >= s->nb_streams)
11718  return AVERROR_INVALIDDATA;
11719 
11720  st = s->streams[stream_index];
11721  sti = ffstream(st);
11722  sample = mov_seek_stream(s, st, sample_time, flags);
11723  if (sample < 0)
11724  return sample;
11725 
11726  if (mc->seek_individually) {
11727  /* adjust seek timestamp to found sample timestamp */
11728  int64_t seek_timestamp = sti->index_entries[sample].timestamp;
11730 
11731  for (i = 0; i < s->nb_streams; i++) {
11732  AVStream *const st = s->streams[i];
11733  FFStream *const sti = ffstream(st);
11734  int64_t timestamp;
11735 
11736  if (stream_index == i)
11737  continue;
11738 
11739  timestamp = av_rescale_q(seek_timestamp, s->streams[stream_index]->time_base, st->time_base);
11740  sample = mov_seek_stream(s, st, timestamp, flags);
11741  if (sample >= 0)
11743  }
11744  } else {
11745  for (i = 0; i < s->nb_streams; i++) {
11746  MOVStreamContext *sc;
11747  st = s->streams[i];
11748  sc = st->priv_data;
11749  mov_current_sample_set(sc, 0);
11750  }
11751  while (1) {
11752  MOVStreamContext *sc;
11754  if (!entry)
11755  return AVERROR_INVALIDDATA;
11756  sc = st->priv_data;
11757  if (sc->ffindex == stream_index && sc->current_sample == sample)
11758  break;
11760  }
11761  }
11762  return 0;
11763 }
11764 
11765 #define OFFSET(x) offsetof(MOVContext, x)
11766 #define FLAGS AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM
11767 static const AVOption mov_options[] = {
11768  {"use_absolute_path",
11769  "allow using absolute path when opening alias, this is a possible security issue",
11770  OFFSET(use_absolute_path), AV_OPT_TYPE_BOOL, {.i64 = 0},
11771  0, 1, FLAGS},
11772  {"seek_streams_individually",
11773  "Seek each stream individually to the closest point",
11774  OFFSET(seek_individually), AV_OPT_TYPE_BOOL, { .i64 = 1 },
11775  0, 1, FLAGS},
11776  {"ignore_editlist", "Ignore the edit list atom.", OFFSET(ignore_editlist), AV_OPT_TYPE_BOOL, {.i64 = 0},
11777  0, 1, FLAGS},
11778  {"advanced_editlist",
11779  "Modify the AVIndex according to the editlists. Use this option to decode in the order specified by the edits.",
11780  OFFSET(advanced_editlist), AV_OPT_TYPE_BOOL, {.i64 = 1},
11781  0, 1, FLAGS},
11782  {"ignore_chapters", "", OFFSET(ignore_chapters), AV_OPT_TYPE_BOOL, {.i64 = 0},
11783  0, 1, FLAGS},
11784  {"use_mfra_for",
11785  "use mfra for fragment timestamps",
11786  OFFSET(use_mfra_for), AV_OPT_TYPE_INT, {.i64 = FF_MOV_FLAG_MFRA_AUTO},
11788  .unit = "use_mfra_for"},
11789  {"auto", "auto", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_AUTO}, 0, 0,
11790  FLAGS, .unit = "use_mfra_for" },
11791  {"dts", "dts", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_DTS}, 0, 0,
11792  FLAGS, .unit = "use_mfra_for" },
11793  {"pts", "pts", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_PTS}, 0, 0,
11794  FLAGS, .unit = "use_mfra_for" },
11795  {"use_tfdt", "use tfdt for fragment timestamps", OFFSET(use_tfdt), AV_OPT_TYPE_BOOL, {.i64 = 1},
11796  0, 1, FLAGS},
11797  { "export_all", "Export unrecognized metadata entries", OFFSET(export_all),
11798  AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = FLAGS },
11799  { "export_xmp", "Export full XMP metadata", OFFSET(export_xmp),
11800  AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = FLAGS },
11801  { "activation_bytes", "Secret bytes for Audible AAX files", OFFSET(activation_bytes),
11803  { "audible_key", "AES-128 Key for Audible AAXC files", OFFSET(audible_key),
11805  { "audible_iv", "AES-128 IV for Audible AAXC files", OFFSET(audible_iv),
11807  { "audible_fixed_key", // extracted from libAAX_SDK.so and AAXSDKWin.dll files!
11808  "Fixed key used for handling Audible AAX files", OFFSET(audible_fixed_key),
11809  AV_OPT_TYPE_BINARY, {.str="77214d4b196a87cd520045fd20a51d67"},
11810  .flags = AV_OPT_FLAG_DECODING_PARAM },
11811  { "decryption_key", "The default media decryption key (hex)", OFFSET(decryption_default_key), AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM },
11812  { "decryption_keys", "The media decryption keys by KID (hex)", OFFSET(decryption_keys), AV_OPT_TYPE_DICT, .flags = AV_OPT_FLAG_DECODING_PARAM },
11813  { "enable_drefs", "Enable external track support.", OFFSET(enable_drefs), AV_OPT_TYPE_BOOL,
11814  {.i64 = 0}, 0, 1, FLAGS },
11815  { "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 },
11816  { "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 },
11817 
11818  { NULL },
11819 };
11820 
11821 static const AVClass mov_class = {
11822  .class_name = "mov,mp4,m4a,3gp,3g2,mj2",
11823  .item_name = av_default_item_name,
11824  .option = mov_options,
11825  .version = LIBAVUTIL_VERSION_INT,
11826 };
11827 
11829  .p.name = "mov,mp4,m4a,3gp,3g2,mj2",
11830  .p.long_name = NULL_IF_CONFIG_SMALL("QuickTime / MOV"),
11831  .p.priv_class = &mov_class,
11832  .p.extensions = "mov,mp4,m4a,3gp,3g2,mj2,psp,m4v,m4b,ism,ismv,isma,f4v,avif,heic,heif",
11834  .priv_data_size = sizeof(MOVContext),
11835  .flags_internal = FF_INFMT_FLAG_INIT_CLEANUP,
11836  .read_probe = mov_probe,
11841 };
HEIFItemRef::item_id
int item_id
Definition: isom.h:291
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:311
AV_CODEC_ID_PCM_S16LE
@ AV_CODEC_ID_PCM_S16LE
Definition: codec_id.h:338
flags
const SwsFlags flags[]
Definition: swscale.c:72
AV_EXIF_T_OFF
@ AV_EXIF_T_OFF
The first four bytes point to the actual start, then it's AV_EXIF_TIFF_HEADER.
Definition: exif.h:69
mov_finalize_stsd_entry
static int mov_finalize_stsd_entry(MOVContext *c, AVStream *st)
Definition: mov.c:3083
mov_read_chpl
static int mov_read_chpl(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:599
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:7436
mov_read_meta
static int mov_read_meta(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5545
AV_CODEC_ID_EIA_608
@ AV_CODEC_ID_EIA_608
Definition: codec_id.h:582
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:433
MOVContext::found_iloc
int found_iloc
'iloc' atom has been found
Definition: isom.h:327
AV_CODEC_ID_MACE6
@ AV_CODEC_ID_MACE6
Definition: codec_id.h:470
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:2336
read_image_iovl
static int read_image_iovl(AVFormatContext *s, const HEIFGrid *grid, AVStreamGroupTileGrid *tile_grid)
Definition: mov.c:10443
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:9374
AVMEDIA_TYPE_SUBTITLE
@ AVMEDIA_TYPE_SUBTITLE
Definition: avutil.h:203
AVIAMFSubmix::elements
AVIAMFSubmixElement ** elements
Array of submix elements.
Definition: iamf.h:568
skip_bits_long
static void skip_bits_long(GetBitContext *s, int n)
Skips the specified number of bits.
Definition: get_bits.h:280
AV_LOG_WARNING
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:216
AV_BPRINT_SIZE_UNLIMITED
#define AV_BPRINT_SIZE_UNLIMITED
MOV_TFHD_DEFAULT_FLAGS
#define MOV_TFHD_DEFAULT_FLAGS
Definition: isom.h:407
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:358
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:383
AVCodecParameters::extradata
uint8_t * extradata
Extra binary data needed for initializing the decoder, codec-dependent.
Definition: codec_par.h:71
mov_read_dops
static int mov_read_dops(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:8564
can_seek_to_key_sample
static int can_seek_to_key_sample(AVStream *st, int sample, int64_t requested_pts)
Definition: mov.c:11590
AV_CODEC_ID_ADPCM_IMA_QT
@ AV_CODEC_ID_ADPCM_IMA_QT
Definition: codec_id.h:377
entry
#define entry
Definition: aom_film_grain_template.c:66
AVFMT_NO_BYTE_SEEK
#define AVFMT_NO_BYTE_SEEK
Format does not allow seeking by bytes.
Definition: avformat.h:486
AV_EF_EXPLODE
#define AV_EF_EXPLODE
abort decoding on minor error detection
Definition: defs.h:51
AVStreamGroup::id
int64_t id
Group type-specific group ID.
Definition: avformat.h:1116
AV_CODEC_ID_AC3
@ AV_CODEC_ID_AC3
Definition: codec_id.h:463
HEIFItem::name
char * name
Definition: isom.h:298
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:355
MOV_TRUN_SAMPLE_FLAGS
#define MOV_TRUN_SAMPLE_FLAGS
Definition: isom.h:415
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:343
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
get_heif_item
static HEIFItem * get_heif_item(MOVContext *c, unsigned id)
Get the requested item.
Definition: mov.c:194
MOV_TKHD_FLAG_ENABLED
#define MOV_TKHD_FLAG_ENABLED
Definition: isom.h:428
AVCodecParameters::codec_type
enum AVMediaType codec_type
General type of the encoded data.
Definition: codec_par.h:53
AVStreamGroup::tile_grid
struct AVStreamGroupTileGrid * tile_grid
Definition: avformat.h:1132
AVFMT_SHOW_IDS
#define AVFMT_SHOW_IDS
Show format stream IDs numbers.
Definition: avformat.h:476
AVSphericalMapping::projection
enum AVSphericalProjection projection
Projection type.
Definition: spherical.h:104
AV_WL32
#define AV_WL32(p, v)
Definition: intreadwrite.h:422
av_exif_parse_buffer
int av_exif_parse_buffer(void *logctx, const uint8_t *buf, size_t size, AVExifMetadata *ifd, enum AVExifHeaderMode header_mode)
Decodes the EXIF data provided in the buffer and writes it into the struct *ifd.
Definition: exif.c:882
AV_STREAM_GROUP_PARAMS_LCEVC
@ AV_STREAM_GROUP_PARAMS_LCEVC
Definition: avformat.h:1091
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:11821
AVSphericalMapping::bound_bottom
uint32_t bound_bottom
Distance from the bottom edge.
Definition: spherical.h:188
MOVStreamContext::open_key_samples
int * open_key_samples
Definition: isom.h:248
AVUUID
uint8_t AVUUID[AV_UUID_LEN]
Definition: uuid.h:60
AVStreamGroupTileGrid::offsets
struct AVStreamGroupTileGrid::@446 * offsets
An nb_tiles sized array of offsets in pixels from the topleft edge of the canvas, indicating where ea...
out
static FILE * out
Definition: movenc.c:55
MOVFragmentStreamInfo
Definition: isom.h:139
AVFieldOrder
AVFieldOrder
Definition: defs.h:211
mov_read_targa_y216
static int mov_read_targa_y216(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2315
mov_read_chnl
static int mov_read_chnl(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1226
mov_read_moof
static int mov_read_moof(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1852
av_bprint_init
void av_bprint_init(AVBPrint *buf, unsigned size_init, unsigned size_max)
Definition: bprint.c:69
ctype
#define ctype
Definition: afir_template.c:46
AV_PKT_DATA_FRAME_CROPPING
@ AV_PKT_DATA_FRAME_CROPPING
The number of pixels to discard from the top/bottom/left/right border of the decoded frame to obtain ...
Definition: packet.h:340
av_exif_write
int av_exif_write(void *logctx, const AVExifMetadata *ifd, AVBufferRef **buffer, enum AVExifHeaderMode header_mode)
Allocates a buffer using av_malloc of an appropriate size and writes the EXIF data represented by ifd...
Definition: exif.c:753
AVCodecParameters
This struct describes the properties of an encoded stream.
Definition: codec_par.h:49
HEIFItem::icc_profile
uint8_t * icc_profile
Definition: isom.h:309
AVFMT_FLAG_IGNIDX
#define AVFMT_FLAG_IGNIDX
Ignore index.
Definition: avformat.h:1416
AVExifMetadata
Definition: exif.h:76
sanity_checks
static int sanity_checks(void *log_obj, MOVStreamContext *sc, int index)
Definition: mov.c:5178
av_stristr
char * av_stristr(const char *s1, const char *s2)
Locate the first case-independent occurrence in the string haystack of the string needle.
Definition: avstring.c:58
AVCodecParameters::color_space
enum AVColorSpace color_space
Definition: codec_par.h:192
avformat_new_stream
AVStream * avformat_new_stream(AVFormatContext *s, const struct AVCodec *c)
Add a new stream to a media file.
ff_replaygain_export
int ff_replaygain_export(AVStream *st, AVDictionary *metadata)
Parse replaygain tags and export them as per-stream side data.
Definition: replaygain.c:94
tmcd_is_referenced
static int tmcd_is_referenced(AVFormatContext *s, int tmcd_id)
Definition: mov.c:10186
HEIFItem::hflip
int hflip
Definition: isom.h:305
AV_PKT_DATA_NEW_EXTRADATA
@ AV_PKT_DATA_NEW_EXTRADATA
The AV_PKT_DATA_NEW_EXTRADATA is used to notify the codec or the format that the extradata buffer was...
Definition: packet.h:56
IAMFAudioElement::nb_substreams
unsigned int nb_substreams
Definition: iamf.h:99
AVStream::priv_data
void * priv_data
Definition: avformat.h:769
AVERROR_EOF
#define AVERROR_EOF
End of file.
Definition: error.h:57
AVBufferRef::data
uint8_t * data
The data buffer.
Definition: buffer.h:90
AV_DISPOSITION_ATTACHED_PIC
#define AV_DISPOSITION_ATTACHED_PIC
The stream is stored in the file as an attached picture/"cover art" (e.g.
Definition: avformat.h:670
AVStream::discard
enum AVDiscard discard
Selects which packets can be discarded at will and do not need to be demuxed.
Definition: avformat.h:815
AV_FIELD_PROGRESSIVE
@ AV_FIELD_PROGRESSIVE
Definition: defs.h:213
mov_options
static const AVOption mov_options[]
Definition: mov.c:11767
mov_codec_id
static int mov_codec_id(AVStream *st, uint32_t format)
Definition: mov.c:2666
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:8961
matrix
Definition: vc1dsp.c:43
AVMasteringDisplayMetadata::display_primaries
AVRational display_primaries[3][2]
CIE 1931 xy chromaticity coords of color primaries (r, g, b order).
Definition: mastering_display_metadata.h:42
AV_PKT_FLAG_DISCARD
#define AV_PKT_FLAG_DISCARD
Flag is used to discard packets which are required to maintain valid decoder state but are not requir...
Definition: packet.h:657
AVMasteringDisplayMetadata::has_luminance
int has_luminance
Flag indicating whether the luminance (min_ and max_) have been set.
Definition: mastering_display_metadata.h:67
get_bits_long
static unsigned int get_bits_long(GetBitContext *s, int n)
Read 0-32 bits.
Definition: get_bits.h:424
int64_t
long long int64_t
Definition: coverity.c:34
output
filter_frame For filters that do not use the this method is called when a frame is pushed to the filter s input It can be called at any time except in a reentrant way If the input frame is enough to produce output
Definition: filter_design.txt:226
mov_read_alac
static int mov_read_alac(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2287
test_same_origin
static int test_same_origin(const char *src, const char *ref)
Definition: mov.c:5021
cbcs_scheme_decrypt
static int cbcs_scheme_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
Definition: mov.c:8381
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:622
IS_MATRIX_IDENT
#define IS_MATRIX_IDENT(matrix)
Definition: mov.c:5563
AVStreamGroup::disposition
int disposition
Stream group disposition - a combination of AV_DISPOSITION_* flags.
Definition: avformat.h:1174
av_unused
#define av_unused
Definition: attributes.h:164
AV_DISPOSITION_DEFAULT
#define AV_DISPOSITION_DEFAULT
The stream should be chosen by default among other streams of the same type, unless the user has expl...
Definition: avformat.h:617
mov_update_dts_shift
static void mov_update_dts_shift(MOVStreamContext *sc, int duration, void *logctx)
Definition: mov.c:3719
MOVStreamContext::spherical
AVSphericalMapping * spherical
Definition: isom.h:265
mask
int mask
Definition: mediacodecdec_common.c:154
out_size
static int out_size
Definition: movenc.c:56
AV_CODEC_ID_MPEG4
@ AV_CODEC_ID_MPEG4
Definition: codec_id.h: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:2292
AV_RB32A
#define AV_RB32A(p)
Definition: intreadwrite.h:575
MOVContext::primary_item_id
int primary_item_id
Definition: isom.h:380
mode
Definition: swscale.c:60
MOVContext::found_moov
int found_moov
'moov' atom has been found
Definition: isom.h:326
ff_iamf_read_packet
int ff_iamf_read_packet(AVFormatContext *s, IAMFDemuxContext *c, AVIOContext *pb, int max_size, int stream_id_offset, AVPacket *pkt)
Definition: iamf_reader.c:308
mov_read_custom
static int mov_read_custom(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5405
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:1331
HEIFGrid::nb_tiles
int nb_tiles
Definition: isom.h:318
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:416
mov_read_extradata
static int mov_read_extradata(MOVContext *c, AVIOContext *pb, MOVAtom atom, enum AVCodecID codec_id)
Definition: mov.c:2261
AVCOL_RANGE_JPEG
@ AVCOL_RANGE_JPEG
Full range content.
Definition: pixfmt.h:777
mpegaudiodecheader.h
MOVStreamContext::rap_group_count
unsigned int rap_group_count
Definition: isom.h: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:307
mov_read_mvhd
static int mov_read_mvhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1954
mov_read_idat
static int mov_read_idat(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:8955
AVPacket::data
uint8_t * data
Definition: packet.h:595
MOVContext::found_mdat
int found_mdat
'mdat' atom has been found
Definition: isom.h:329
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:2307
AVAmbientViewingEnvironment::ambient_light_x
AVRational ambient_light_x
Normalized x chromaticity coordinate of the environmental ambient light in the nominal viewing enviro...
Definition: ambient_viewing_environment.h:47
AVCodecParameters::seek_preroll
int seek_preroll
Number of audio samples to skip after a discontinuity.
Definition: codec_par.h:256
av_dynarray2_add
void * av_dynarray2_add(void **tab_ptr, int *nb_ptr, size_t elem_size, const uint8_t *elem_data)
Add an element of size elem_size to a dynamic array.
Definition: mem.c:343
AVOption
AVOption.
Definition: opt.h:429
MOVContext::trex_data
MOVTrackExt * trex_data
Definition: isom.h:338
mov_read_stps
static int mov_read_stps(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:3372
MOVContext::bitrates
int * bitrates
bitrates read before streams creation
Definition: isom.h:353
b
#define b
Definition: input.c:43
AVCOL_TRC_UNSPECIFIED
@ AVCOL_TRC_UNSPECIFIED
Definition: pixfmt.h:669
MOVContext::interleaved_read
int interleaved_read
Definition: isom.h:387
mov_read_tkhd
static int mov_read_tkhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5571
MOVElst::rate
float rate
Definition: isom.h:82
AVStream::avg_frame_rate
AVRational avg_frame_rate
Average framerate.
Definition: avformat.h:833
table
static const uint16_t table[]
Definition: prosumer.c:203
spherical.h
mov_read_colr
static int mov_read_colr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2108
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:1993
mov_read_strf
static int mov_read_strf(MOVContext *c, AVIOContext *pb, MOVAtom atom)
An strf atom is a BITMAPINFOHEADER struct.
Definition: mov.c:2579
AV_CODEC_ID_ALAC
@ AV_CODEC_ID_ALAC
Definition: codec_id.h:476
HEIFItem::st
AVStream * st
Definition: isom.h:295
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:441
av_iamf_mix_presentation_free
void av_iamf_mix_presentation_free(AVIAMFMixPresentation **pmix_presentation)
Free an AVIAMFMixPresentation and all its contents.
Definition: iamf.c:536
mov_parse_auxiliary_info
static int mov_parse_auxiliary_info(MOVContext *c, MOVStreamContext *sc, AVIOContext *pb, MOVEncryptionIndex *encryption_index)
Definition: mov.c:7644
mov_seek_stream
static int mov_seek_stream(AVFormatContext *s, AVStream *st, int64_t timestamp, int flags)
Definition: mov.c:11617
mov_read_saio
static int mov_read_saio(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:7790
mov_get_stsc_samples
static int64_t mov_get_stsc_samples(MOVStreamContext *sc, unsigned int index)
Definition: mov.c:3357
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:3928
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:11225
nb_streams
static unsigned int nb_streams
Definition: ffprobe.c:352
HEIFItemRef
Definition: isom.h:289
MOVStreamContext::tref_id
int tref_id
Definition: isom.h:226
MP4TrackKindMapping::scheme_uri
const char * scheme_uri
Definition: isom.h:490
AVINDEX_DISCARD_FRAME
#define AVINDEX_DISCARD_FRAME
Definition: avformat.h:607
av_display_rotation_set
void av_display_rotation_set(int32_t matrix[9], double angle)
Initialize a transformation matrix describing a pure clockwise rotation by the specified angle (in de...
Definition: display.c:51
AVPacket::duration
int64_t duration
Duration of this packet in AVStream->time_base units, 0 if unknown.
Definition: packet.h:613
AVCodecParameters::codec_tag
uint32_t codec_tag
Additional information about the codec (corresponds to the AVI FOURCC).
Definition: codec_par.h:61
fixed_key
static const uint8_t fixed_key[]
Definition: aes_ctr.c:45
AV_SPHERICAL_EQUIRECTANGULAR_TILE
@ AV_SPHERICAL_EQUIRECTANGULAR_TILE
Video represents a portion of a sphere mapped on a flat surface using equirectangular projection.
Definition: spherical.h:68
AVStereo3D::baseline
uint32_t baseline
The distance between the centres of the lenses of the camera system, in micrometers.
Definition: stereo3d.h:228
MOVDref::dir
char * dir
Definition: isom.h:88
mov_current_sample_set
static void mov_current_sample_set(MOVStreamContext *sc, int current_sample)
Definition: mov.c:4232
mathematics.h
AVDictionary
Definition: dict.c:32
ffio_init_read_context
void ffio_init_read_context(FFIOContext *s, const uint8_t *buffer, int buffer_size)
Wrap a buffer in an AVIOContext for reading.
Definition: aviobuf.c:99
AV_PKT_FLAG_DISPOSABLE
#define AV_PKT_FLAG_DISPOSABLE
Flag is used to indicate packets that contain frames that can be discarded by the decoder.
Definition: packet.h:669
AVChannelLayout::order
enum AVChannelOrder order
Channel order used in this layout.
Definition: channel_layout.h:324
FFMAX
#define FFMAX(a, b)
Definition: macros.h:47
MOVAtom
Definition: isom.h:94
AVStreamGroupTileGrid::vertical
int vertical
Offset in pixels from the top edge of the canvas where the tile should be placed.
Definition: avformat.h:1000
iamf_parse.h
mov_read_moov
static int mov_read_moov(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1602
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:367
mov_read_esds
static int mov_read_esds(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:848
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:303
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
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:347
avio_size
int64_t avio_size(AVIOContext *s)
Get the filesize.
Definition: aviobuf.c:326
av_strlcatf
size_t av_strlcatf(char *dst, size_t size, const char *fmt,...)
Definition: avstring.c:103
mov_read_stco
static int mov_read_stco(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2601
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:7155
FFIOContext
Definition: avio_internal.h:28
AV_PKT_FLAG_KEY
#define AV_PKT_FLAG_KEY
The packet contains a keyframe.
Definition: packet.h:650
init_get_bits
static int init_get_bits(GetBitContext *s, const uint8_t *buffer, int bit_size)
Initialize GetBitContext.
Definition: get_bits.h:517
MOVStreamContext::aes_ctr
struct AVAESCTR * aes_ctr
Definition: isom.h:278
cenc_filter
static int cenc_filter(MOVContext *mov, AVStream *st, MOVStreamContext *sc, AVPacket *pkt, int current_index)
Definition: mov.c:8494
mov_read_sdtp
static int mov_read_sdtp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:3681
mov_read_jp2h
static int mov_read_jp2h(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2297
AV_STEREO3D_UNSPEC
@ AV_STEREO3D_UNSPEC
Video is stereoscopic but the packing is unspecified.
Definition: stereo3d.h:143
AVIndexEntry
Definition: avformat.h:598
AV_WB64
#define AV_WB64(p, v)
Definition: intreadwrite.h:429
MOVStreamContext::dv_audio_container
int dv_audio_container
Definition: isom.h:219
AV_CODEC_ID_AMR_WB
@ AV_CODEC_ID_AMR_WB
Definition: codec_id.h:442
mov_read_tfhd
static int mov_read_tfhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5676
AV_CODEC_ID_BIN_DATA
@ AV_CODEC_ID_BIN_DATA
Definition: codec_id.h:613
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
MOVContext::decryption_default_key
uint8_t * decryption_default_key
Definition: isom.h:373
mov_read_wide
static int mov_read_wide(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6256
AVINDEX_KEYFRAME
#define AVINDEX_KEYFRAME
Definition: avformat.h:606
AV_FIELD_BT
@ AV_FIELD_BT
Bottom coded first, top displayed first.
Definition: defs.h:217
MOVStreamContext::stsd_count
int stsd_count
Definition: isom.h: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:205
ff_get_extradata
int ff_get_extradata(void *logctx, AVCodecParameters *par, AVIOContext *pb, int size)
Allocate extradata with additional AV_INPUT_BUFFER_PADDING_SIZE at end which is always set to 0 and f...
Definition: demux_utils.c:340
AVStereo3D::horizontal_field_of_view
AVRational horizontal_field_of_view
Horizontal field of view, in degrees.
Definition: stereo3d.h:239
skip_bits
static void skip_bits(GetBitContext *s, int n)
Definition: get_bits.h:383
AVCodecParameters::color_primaries
enum AVColorPrimaries color_primaries
Definition: codec_par.h:190
AVEncryptionInfo::scheme
uint32_t scheme
The fourcc encryption scheme, in big-endian byte order.
Definition: encryption_info.h:45
MOVStreamContext::stsc_count
unsigned int stsc_count
Definition: isom.h: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:418
get_bits
static unsigned int get_bits(GetBitContext *s, int n)
Read 1-25 bits.
Definition: get_bits.h:337
ff_remove_stream
void ff_remove_stream(AVFormatContext *s, AVStream *st)
Remove a stream from its AVFormatContext and free it.
Definition: avformat.c:116
OFFSET
#define OFFSET(x)
Definition: mov.c:11765
HEIFGrid::tile_item_list
HEIFItem ** tile_item_list
Definition: isom.h:315
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:10321
AV_FIELD_TT
@ AV_FIELD_TT
Top coded_first, top displayed first.
Definition: defs.h:214
AV_STEREO3D_VIEW_PACKED
@ AV_STEREO3D_VIEW_PACKED
Frame contains two packed views.
Definition: stereo3d.h:153
AV_SPHERICAL_PARAMETRIC_IMMERSIVE
@ AV_SPHERICAL_PARAMETRIC_IMMERSIVE
Parametric Immersive projection (Apple).
Definition: spherical.h:90
MOVStreamContext::nb_frames_for_fps
int nb_frames_for_fps
Definition: isom.h: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:738
avpriv_set_pts_info
void avpriv_set_pts_info(AVStream *st, int pts_wrap_bits, unsigned int pts_num, unsigned int pts_den)
Set the time base and wrapping info for a given stream.
Definition: avformat.c:895
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:1540
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:3856
av_packet_add_side_data
int av_packet_add_side_data(AVPacket *pkt, enum AVPacketSideDataType type, uint8_t *data, size_t size)
Wrap an existing array as a packet side data.
Definition: packet.c:197
MOVStreamContext::mastering
AVMasteringDisplayMetadata * mastering
Definition: isom.h:267
AV_CODEC_ID_SPEEX
@ AV_CODEC_ID_SPEEX
Definition: codec_id.h:495
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:362
MOVFragmentIndexItem::current
int current
Definition: isom.h:155
AVFMT_SEEK_TO_PTS
#define AVFMT_SEEK_TO_PTS
Seeking is based on PTS.
Definition: avformat.h:499
AV_CODEC_ID_PCM_S16BE
@ AV_CODEC_ID_PCM_S16BE
Definition: codec_id.h:339
mov_read_mdhd
static int mov_read_mdhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1908
mov_read_ctts
static int mov_read_ctts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:3730
MOVTrackExt
Definition: isom.h:113
MOV_FRAG_SAMPLE_FLAG_IS_NON_SYNC
#define MOV_FRAG_SAMPLE_FLAG_IS_NON_SYNC
Definition: isom.h:419
fail
#define fail()
Definition: checkasm.h:224
mov_read_aclr
static int mov_read_aclr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2374
AVSEEK_FLAG_ANY
#define AVSEEK_FLAG_ANY
seek to any frame, even non-keyframes
Definition: avformat.h:2520
av_int2float
static av_always_inline float av_int2float(uint32_t i)
Reinterpret a 32-bit integer as a float.
Definition: intfloat.h:40
MOVFragment::found_tfhd
int found_tfhd
Definition: isom.h:102
AVStreamGroupTileGrid
AVStreamGroupTileGrid holds information on how to combine several independent images on a single canv...
Definition: avformat.h:951
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:299
av_shrink_packet
void av_shrink_packet(AVPacket *pkt, int size)
Reduce packet size, correctly zeroing padding.
Definition: packet.c:113
timecode.h
get_current_frag_stream_info
static MOVFragmentStreamInfo * get_current_frag_stream_info(MOVFragmentIndex *frag_index)
Definition: mov.c:1659
GetBitContext
Definition: get_bits.h:109
MOVStreamContext::mastering_size
size_t mastering_size
Definition: isom.h:268
AVStreamGroupTileGrid::coded_width
int coded_width
Width of the canvas.
Definition: avformat.h:966
av_iamf_audio_element_free
void av_iamf_audio_element_free(AVIAMFAudioElement **paudio_element)
Free an AVIAMFAudioElement and all its contents.
Definition: iamf.c:338
FFStream::index_entries_allocated_size
unsigned int index_entries_allocated_size
Definition: internal.h:187
read_close
static av_cold int read_close(AVFormatContext *ctx)
Definition: libcdio.c:143
mov_read_amve
static int mov_read_amve(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6615
mov_read_enda
static int mov_read_enda(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2022
mov_read_chap
static int mov_read_chap(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5723
MOVParseTableEntry
Definition: mov.c:82
avio_tell
static av_always_inline int64_t avio_tell(AVIOContext *s)
ftell() equivalent for AVIOContext.
Definition: avio.h:494
av_exif_free
void av_exif_free(AVExifMetadata *ifd)
Frees all resources associated with the given EXIF metadata struct.
Definition: exif.c:659
MOV_TRUN_SAMPLE_DURATION
#define MOV_TRUN_SAMPLE_DURATION
Definition: isom.h:413
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:10335
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:321
AV_DISPOSITION_TIMED_THUMBNAILS
#define AV_DISPOSITION_TIMED_THUMBNAILS
The stream is sparse, and contains thumbnail images, often corresponding to chapter markers.
Definition: avformat.h:675
AVStreamGroupTileGrid::coded_height
int coded_height
Width of the canvas.
Definition: avformat.h:972
pts
static int64_t pts
Definition: transcode_aac.c:644
MOVStreamContext::v_spacing
int v_spacing
pasp vSpacing
Definition: isom.h:231
AVEncryptionInfo::iv
uint8_t * iv
The initialization vector.
Definition: encryption_info.h:71
AV_CODEC_ID_MP3
@ AV_CODEC_ID_MP3
preferred ID for decoding MPEG audio layer 1, 2 or 3
Definition: codec_id.h:461
AVStream::duration
int64_t duration
Decoding: duration of the stream, in stream time base.
Definition: avformat.h:803
AVAmbientViewingEnvironment::ambient_illuminance
AVRational ambient_illuminance
Environmental illuminance of the ambient viewing environment in lux.
Definition: ambient_viewing_environment.h:40
ss
#define ss(width, name, subs,...)
Definition: cbs_vp9.c:202
MOVStreamContext::width
int width
tkhd width
Definition: isom.h:228
MOVContext::meta_keys
char ** meta_keys
Definition: isom.h:332
get_key_from_kid
static int get_key_from_kid(uint8_t *out, int len, MOVContext *c, AVEncryptionInfo *sample)
Definition: mov.c:8148
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:391
loop
static int loop
Definition: ffplay.c:337
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:458
update_frag_index
static int update_frag_index(MOVContext *c, int64_t offset)
Definition: mov.c:1776
AV_CODEC_ID_PRORES_RAW
@ AV_CODEC_ID_PRORES_RAW
Definition: codec_id.h:333
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:216
mov_read_pack
static int mov_read_pack(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6687
AVStream::attached_pic
AVPacket attached_pic
For streams with AV_DISPOSITION_ATTACHED_PIC disposition, this packet will contain the attached pictu...
Definition: avformat.h:842
MOVStsc::id
int id
Definition: isom.h:76
mov_read_saiz
static int mov_read_saiz(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:7706
MOV_FRAG_SAMPLE_FLAG_DEPENDS_YES
#define MOV_FRAG_SAMPLE_FLAG_DEPENDS_YES
Definition: isom.h:426
mov_merge_tts_data
static int mov_merge_tts_data(MOVContext *mov, AVStream *st, int flags)
Definition: mov.c:4648
MOVContext::idat_offset
int64_t idat_offset
Definition: isom.h:386
MOV_TRUN_DATA_OFFSET
#define MOV_TRUN_DATA_OFFSET
Definition: isom.h:411
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:2329
mov_read_adrm
static int mov_read_adrm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1414
av_get_bits_per_sample
int av_get_bits_per_sample(enum AVCodecID codec_id)
Return codec bits per sample.
Definition: utils.c:549
AVCodecParameters::color_trc
enum AVColorTransferCharacteristic color_trc
Definition: codec_par.h:191
IAMFContext::audio_elements
IAMFAudioElement ** audio_elements
Definition: iamf.h:131
MOVFragmentIndex::complete
int complete
Definition: isom.h:162
AV_CODEC_ID_PCM_S8
@ AV_CODEC_ID_PCM_S8
Definition: codec_id.h:342
avassert.h
avio_rb32
unsigned int avio_rb32(AVIOContext *s)
Definition: aviobuf.c:764
AV_LOG_TRACE
#define AV_LOG_TRACE
Extremely verbose debugging, useful for libav* development.
Definition: log.h:236
MOVStreamContext::stsc_sample
int stsc_sample
Definition: isom.h:196
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:469
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:10057
AV_CH_LOW_FREQUENCY
#define AV_CH_LOW_FREQUENCY
Definition: channel_layout.h:178
MOVEncryptionIndex::auxiliary_offsets
uint64_t * auxiliary_offsets
Absolute seek position.
Definition: isom.h: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:212
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 frame size, if known.
Definition: codec_par.h:227
mov_read_srat
static int mov_read_srat(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1077
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:91
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
mov_parse_exif_item
static int mov_parse_exif_item(AVFormatContext *s, AVPacketSideData **coded_side_data, int *nb_coded_side_data, const HEIFItem *ref)
Definition: mov.c:10512
AV_STREAM_GROUP_PARAMS_IAMF_MIX_PRESENTATION
@ AV_STREAM_GROUP_PARAMS_IAMF_MIX_PRESENTATION
Definition: avformat.h:1089
ff_add_attached_pic
int ff_add_attached_pic(AVFormatContext *s, AVStream *st, AVIOContext *pb, AVBufferRef **buf, int size)
Add an attached pic to an AVStream.
Definition: demux_utils.c:107
add_tts_entry
static int add_tts_entry(MOVTimeToSample **tts_data, unsigned int *tts_count, unsigned int *allocated_size, int count, int offset, unsigned int duration)
Definition: mov.c:4123
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:463
MOV_MERGE_STTS
#define MOV_MERGE_STTS
Definition: mov.c:4642
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:6549
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:5197
IAMFSubStream::audio_substream_id
unsigned int audio_substream_id
Definition: iamf.h:83
MOVContext::fc
AVFormatContext * fc
Definition: isom.h:323
MOV_TFHD_DEFAULT_BASE_IS_MOOF
#define MOV_TFHD_DEFAULT_BASE_IS_MOOF
Definition: isom.h:409
av_new_packet
int av_new_packet(AVPacket *pkt, int size)
Allocate the payload of a packet and initialize its fields with default values.
Definition: packet.c:98
AV_CODEC_ID_BMP
@ AV_CODEC_ID_BMP
Definition: codec_id.h:130
AV_CODEC_ID_EVC
@ AV_CODEC_ID_EVC
Definition: codec_id.h:325
IAMFLayer::substream_count
unsigned int substream_count
Definition: iamf.h:78
MOV_TFHD_DEFAULT_DURATION
#define MOV_TFHD_DEFAULT_DURATION
Definition: isom.h:405
ALAC_EXTRADATA_SIZE
#define ALAC_EXTRADATA_SIZE
DRM_BLOB_SIZE
#define DRM_BLOB_SIZE
Definition: mov.c:1412
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
MOVStreamContext::cenc
struct MOVStreamContext::@478 cenc
AVInputFormat::name
const char * name
A comma separated list of short names for the format.
Definition: avformat.h:549
MOVContext::aes_decrypt
struct AVAES * aes_decrypt
Definition: isom.h:372
AVSphericalMapping::bound_top
uint32_t bound_top
Distance from the top edge.
Definition: spherical.h:186
AVMEDIA_TYPE_AUDIO
@ AVMEDIA_TYPE_AUDIO
Definition: avutil.h:201
AV_CODEC_ID_VP9
@ AV_CODEC_ID_VP9
Definition: codec_id.h:222
MOVFragmentIndex::nb_items
int nb_items
Definition: isom.h:164
AVCodecParameters::width
int width
The width of the video frame in pixels.
Definition: codec_par.h:143
MOVTimeToSample
Definition: isom.h:57
AV_CHANNEL_ORDER_UNSPEC
@ AV_CHANNEL_ORDER_UNSPEC
Only the channel count is specified, without any further information about the channel order.
Definition: channel_layout.h:119
AV_CODEC_ID_MP2
@ AV_CODEC_ID_MP2
Definition: codec_id.h:460
HEIFGrid::tile_idx_list
unsigned * tile_idx_list
Definition: isom.h:317
MOV_TRUN_FIRST_SAMPLE_FLAGS
#define MOV_TRUN_FIRST_SAMPLE_FLAGS
Definition: isom.h:412
av_q2d
static double av_q2d(AVRational a)
Convert an AVRational to a double.
Definition: rational.h:104
AVIndexEntry::size
int size
Definition: avformat.h:609
av_channel_layout_from_mask
int av_channel_layout_from_mask(AVChannelLayout *channel_layout, uint64_t mask)
Initialize a native channel layout from a bitmask indicating which channels are present.
Definition: channel_layout.c:253
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:494
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:4152
AVIndexEntry::timestamp
int64_t timestamp
Timestamp in AVStream.time_base units, preferably the time from which on correctly decoded frames are...
Definition: avformat.h:600
av_assert0
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:42
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:930
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:8672
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:417
ctx
static AVFormatContext * ctx
Definition: movenc.c:49
hevc.h
get_bits.h
limits.h
mov_read_sidx
static int mov_read_sidx(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6117
AV_PKT_DATA_STEREO3D
@ AV_PKT_DATA_STEREO3D
This side data should be associated with a video stream and contains Stereoscopic 3D information in f...
Definition: packet.h:111
av_rescale_q
int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq)
Rescale a 64-bit integer by 2 rational numbers.
Definition: mathematics.c:142
ff_iamfdec_read_descriptors
int ff_iamfdec_read_descriptors(IAMFContext *c, AVIOContext *pb, int max_size, void *log_ctx)
Definition: iamf_parse.c:1225
FLAC_METADATA_TYPE_STREAMINFO
@ FLAC_METADATA_TYPE_STREAMINFO
Definition: flac.h:46
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:11152
AV_CODEC_ID_TARGA_Y216
@ AV_CODEC_ID_TARGA_Y216
Definition: codec_id.h:258
AVIndexEntry::min_distance
int min_distance
Minimum distance between this and the previous keyframe, used to avoid unneeded searching.
Definition: avformat.h:610
mov_read_dvcc_dvvc
static int mov_read_dvcc_dvvc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:8652
MOVParseTableEntry::parse
int(* parse)(MOVContext *ctx, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:84
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:88
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:345
av_mallocz
#define av_mallocz(s)
Definition: tableprint_vlc.h:31
mov_read_stss
static int mov_read_stss(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:3413
mov_read_ddts
static int mov_read_ddts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1154
mov_read_uuid
static int mov_read_uuid(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:7309
AVCOL_PRI_UNSPECIFIED
@ AVCOL_PRI_UNSPECIFIED
Definition: pixfmt.h:639
MOVTrackExt::duration
unsigned duration
Definition: isom.h:116
av_fallthrough
#define av_fallthrough
Definition: attributes.h:67
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
tmp
static uint8_t tmp[40]
Definition: aes_ctr.c:52
av_sha_final
void av_sha_final(AVSHA *ctx, uint8_t *digest)
Finish hashing and output digest value.
Definition: sha.c:347
MOVStreamContext::current_sample
int current_sample
Definition: isom.h:213
MOVFragmentStreamInfo::sidx_pts
int64_t sidx_pts
Definition: isom.h:141
MAX_REORDER_DELAY
#define MAX_REORDER_DELAY
Definition: mov.c:4151
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:10131
ff_hex_to_data
int ff_hex_to_data(uint8_t *data, const char *p)
Parse a string of hexadecimal strings.
Definition: utils.c:479
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:469
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:6276
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:7534
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:8902
IAMFAudioElement::audio_element_id
unsigned int audio_element_id
Definition: iamf.h:96
AVDISCARD_ALL
@ AVDISCARD_ALL
discard all
Definition: defs.h:232
AVFormatContext
Format I/O context.
Definition: avformat.h:1263
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:3561
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:1083
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:3974
set_frag_stream
static void set_frag_stream(MOVFragmentIndex *frag_index, int id)
Definition: mov.c:1639
mov_read_free
static int mov_read_free(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:7414
mov_realloc_extradata
static int mov_realloc_extradata(AVCodecParameters *par, MOVAtom atom)
Definition: mov.c:2224
AVStream::codecpar
AVCodecParameters * codecpar
Codec parameters associated with this stream.
Definition: avformat.h:767
LIBAVUTIL_VERSION_INT
#define LIBAVUTIL_VERSION_INT
Definition: version.h:85
av_exif_get_tag_id
int32_t av_exif_get_tag_id(const char *name)
Retrieves the tag ID associated with the provided tag string name.
Definition: exif.c:244
AV_PKT_DATA_EXIF
@ AV_PKT_DATA_EXIF
Extensible image file format metadata.
Definition: packet.h:369
AVSEEK_FLAG_BACKWARD
#define AVSEEK_FLAG_BACKWARD
Definition: avformat.h:2518
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:733
MOVContext::ignore_editlist
int ignore_editlist
Definition: isom.h:345
result
and forward the result(frame or status change) to the corresponding input. If nothing is possible
fabs
static __device__ float fabs(float a)
Definition: cuda_runtime.h:182
metadata
Stream codec metadata
Definition: ogg-flac-chained-meta.txt:2
AVStream::time_base
AVRational time_base
This is the fundamental unit of time (in seconds) in terms of which frame timestamps are represented.
Definition: avformat.h:783
NULL
#define NULL
Definition: coverity.c:32
sha.h
truehd_layout
static uint64_t truehd_layout(int chanmap)
Definition: mlp_parse.h:105
MOVDref
Definition: isom.h:85
AVERROR_PATCHWELCOME
#define AVERROR_PATCHWELCOME
Not yet implemented in FFmpeg, patches welcome.
Definition: error.h:64
format
New swscale design to change SwsGraph is what coordinates multiple passes These can include cascaded scaling error diffusion and so on Or we could have separate passes for the vertical and horizontal scaling In between each SwsPass lies a fully allocated image buffer Graph passes may have different levels of e g we can have a single threaded error diffusion pass following a multi threaded scaling pass SwsGraph is internally recreated whenever the image format
Definition: swscale-v2.txt:14
av_buffer_unref
void av_buffer_unref(AVBufferRef **buf)
Free a given reference and automatically free the buffer if there are no more references to it.
Definition: buffer.c:139
AV_CODEC_ID_AV1
@ AV_CODEC_ID_AV1
Definition: codec_id.h: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
MP4TrackKindValueMapping::disposition
int disposition
Definition: isom.h:485
mov_read_ftyp
static int mov_read_ftyp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1554
AV_WB16
#define AV_WB16(p, v)
Definition: intreadwrite.h:401
MOVContext::nb_heif_grid
int nb_heif_grid
Definition: isom.h:385
read_image_grid
static int read_image_grid(AVFormatContext *s, const HEIFGrid *grid, AVStreamGroupTileGrid *tile_grid)
Definition: mov.c:10356
MOVElst
Definition: isom.h:79
av_aes_ctr_alloc
struct AVAESCTR * av_aes_ctr_alloc(void)
Allocate an AVAESCTR context.
Definition: aes_ctr.c:41
flac_parse_block_header
static av_always_inline void flac_parse_block_header(const uint8_t *block_header, int *last, int *type, int *size)
Parse the metadata block parameters from the header.
Definition: flac.h:63
AVStreamGroupTileGrid::coded_side_data
AVPacketSideData * coded_side_data
Additional data associated with the grid.
Definition: avformat.h:1054
AVRational
Rational number (pair of numerator and denominator).
Definition: rational.h:58
AV_PRIMARY_EYE_LEFT
@ AV_PRIMARY_EYE_LEFT
Left eye.
Definition: stereo3d.h:183
mov_read_sgpd
static int mov_read_sgpd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:3811
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:9776
AVPALETTE_SIZE
#define AVPALETTE_SIZE
Definition: pixfmt.h:32
AV_OPT_TYPE_DICT
@ AV_OPT_TYPE_DICT
Underlying C type is AVDictionary*.
Definition: opt.h:290
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:11249
AV_CODEC_ID_DVD_SUBTITLE
@ AV_CODEC_ID_DVD_SUBTITLE
Definition: codec_id.h:572
AVIndexEntry::flags
int flags
Definition: avformat.h:608
MOVStreamContext::time_offset
int64_t time_offset
time offset of the edit list entries
Definition: isom.h:211
mov_read_smdm
static int mov_read_smdm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6458
av_default_item_name
const char * av_default_item_name(void *ptr)
Return the context name.
Definition: log.c:242
AVStereo3D::horizontal_disparity_adjustment
AVRational horizontal_disparity_adjustment
Relative shift of the left and right images, which changes the zero parallax plane.
Definition: stereo3d.h:234
avio_rb64
uint64_t avio_rb64(AVIOContext *s)
Definition: aviobuf.c:911
av_aes_crypt
void av_aes_crypt(AVAES *a, uint8_t *dst, const uint8_t *src, int count, uint8_t *iv, int decrypt)
Encrypt or decrypt a buffer using a previously initialized context.
Definition: aes.c:171
MOVStreamContext::current_index_range
MOVIndexRange * current_index_range
Definition: isom.h:216
mov_open_dref
static int mov_open_dref(MOVContext *c, AVIOContext **pb, const char *src, MOVDref *ref)
Definition: mov.c:5050
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:439
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:8006
AVStream::metadata
AVDictionary * metadata
Definition: avformat.h:824
FLAC_STREAMINFO_SIZE
#define FLAC_STREAMINFO_SIZE
Definition: flac.h:32
av_color_primaries_name
const char * av_color_primaries_name(enum AVColorPrimaries primaries)
Definition: pixdesc.c:3790
FF_MOV_FLAG_MFRA_DTS
#define FF_MOV_FLAG_MFRA_DTS
Definition: isom.h:462
MOV_SAMPLE_DEPENDENCY_NO
#define MOV_SAMPLE_DEPENDENCY_NO
Definition: isom.h:435
AV_DICT_DONT_OVERWRITE
#define AV_DICT_DONT_OVERWRITE
Don't overwrite existing entries.
Definition: dict.h:81
ff_codec_movvideo_tags
const AVCodecTag ff_codec_movvideo_tags[]
Definition: isom_tags.c:29
MOVStreamContext::tts_index
int tts_index
Definition: isom.h:201
AV_DISPOSITION_MULTILAYER
#define AV_DISPOSITION_MULTILAYER
The video stream contains multiple layers, e.g.
Definition: avformat.h:714
MOVFragmentStreamInfo::index_base
int index_base
Definition: isom.h:146
MOVStreamContext::rap_group
MOVSbgp * rap_group
Definition: isom.h:241
AV_CODEC_ID_QDM2
@ AV_CODEC_ID_QDM2
Definition: codec_id.h:479
mov_read_ilst
static int mov_read_ilst(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5350
MOVTimeToSample::duration
unsigned int duration
Definition: isom.h:59
AV_CH_FRONT_CENTER
#define AV_CH_FRONT_CENTER
Definition: channel_layout.h:177
AVCodecParameters::ch_layout
AVChannelLayout ch_layout
The channel layout and number of channels.
Definition: codec_par.h:207
get_frag_stream_info_from_pkt
static MOVFragmentStreamInfo * get_frag_stream_info_from_pkt(MOVFragmentIndex *frag_index, AVPacket *pkt, int id)
Definition: mov.c:8469
get_sgpd_sync_index
static uint32_t get_sgpd_sync_index(const MOVStreamContext *sc, int nal_unit_type)
Definition: mov.c:4570
mov_read_fiel
static int mov_read_fiel(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2190
parse
static int parse(AVCodecParserContext *s, AVCodecContext *avctx, const uint8_t **poutbuf, int *poutbuf_size, const uint8_t *buf, int buf_size)
Definition: apv_parser.c:92
MOV_MP4_TTML_TAG
#define MOV_MP4_TTML_TAG
Definition: isom.h:480
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:403
MOVFragmentStreamInfo::stsd_id
int stsd_id
Definition: isom.h:149
av_exif_remove_entry
int av_exif_remove_entry(void *logctx, AVExifMetadata *ifd, uint16_t id, int flags)
Remove an entry from the provided EXIF metadata struct.
Definition: exif.c:1289
MOVStreamContext::open_key_samples_count
int open_key_samples_count
Definition: isom.h:249
HEIFItem
Definition: isom.h:294
ff_codec_movaudio_tags
const AVCodecTag ff_codec_movaudio_tags[]
Definition: isom_tags.c:311
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:1258
av_stereo3d_alloc_size
AVStereo3D * av_stereo3d_alloc_size(size_t *size)
Allocate an AVStereo3D structure and set its fields to default values.
Definition: stereo3d.c:39
index
int index
Definition: gxfenc.c:90
c
Undefined Behavior In the C some operations are like signed integer dereferencing freed accessing outside allocated Undefined Behavior must not occur in a C it is not safe even if the output of undefined operations is unused The unsafety may seem nit picking but Optimizing compilers have in fact optimized code on the assumption that no undefined Behavior occurs Optimizing code based on wrong assumptions can and has in some cases lead to effects beyond the output of computations The signed integer overflow problem in speed critical code Code which is highly optimized and works with signed integers sometimes has the problem that often the output of the computation does not c
Definition: undefined.txt:32
AVPROBE_SCORE_EXTENSION
#define AVPROBE_SCORE_EXTENSION
score for file extension
Definition: avformat.h:461
MOVSbgp::count
unsigned int count
Definition: isom.h:122
AVCodecParameters::sample_rate
int sample_rate
The number of audio samples per second.
Definition: codec_par.h:213
mov_parse_stsd_subtitle
static void mov_parse_stsd_subtitle(MOVContext *c, AVIOContext *pb, AVStream *st, MOVStreamContext *sc, int64_t size)
Definition: mov.c:2891
cid
uint16_t cid
Definition: mxfenc.c:2335
mov_skip_multiple_stsd
static int mov_skip_multiple_stsd(MOVContext *c, AVIOContext *pb, int codec_tag, int format, int64_t size)
Definition: mov.c:3057
MOVStts
Definition: isom.h:63
AVAudioServiceType
AVAudioServiceType
Definition: defs.h:235
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:478
AVStream::nb_frames
int64_t nb_frames
number of frames in this stream if known or 0
Definition: avformat.h:805
AVCodecID
AVCodecID
Identify the syntax and semantics of the bitstream.
Definition: codec_id.h:49
av_packet_side_data_get
const AVPacketSideData * av_packet_side_data_get(const AVPacketSideData *sd, int nb_sd, enum AVPacketSideDataType type)
Get side information from a side data array.
Definition: packet.c:645
AVIAMFSubmixElement::audio_element_id
unsigned int audio_element_id
The id of the Audio Element this submix element references.
Definition: iamf.h:455
AV_CODEC_ID_EAC3
@ AV_CODEC_ID_EAC3
Definition: codec_id.h:500
should_retry
static int should_retry(AVIOContext *pb, int error_code)
Definition: mov.c:11182
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:521
AV_PKT_DATA_SPHERICAL
@ AV_PKT_DATA_SPHERICAL
This side data should be associated with a video stream and corresponds to the AVSphericalMapping str...
Definition: packet.h:225
AVCodecParameters::extradata_size
int extradata_size
Size of the extradata content in bytes.
Definition: codec_par.h:75
AVIAMFSubmix
Submix layout as defined in section 3.7 of IAMF.
Definition: iamf.h:559
AV_WB32
#define AV_WB32(p, v)
Definition: intreadwrite.h:415
mov_read_pasp
static int mov_read_pasp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1382
MOVContext::dv_demux
DVDemuxContext * dv_demux
Definition: isom.h:334
AV_CODEC_ID_AAC
@ AV_CODEC_ID_AAC
Definition: codec_id.h:462
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:8812
mov_read_elst
static int mov_read_elst(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6329
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:1090
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:10909
AV_CODEC_ID_QCELP
@ AV_CODEC_ID_QCELP
Definition: codec_id.h:484
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:8244
avio_rl32
unsigned int avio_rl32(AVIOContext *s)
Definition: aviobuf.c:733
MOVStreamContext::tref_flags
unsigned tref_flags
Definition: isom.h:225
AVDISCARD_NONKEY
@ AVDISCARD_NONKEY
discard all frames except keyframes
Definition: defs.h:231
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:350
mov_read_wave
static int mov_read_wave(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2422
AV_SPHERICAL_CUBEMAP
@ AV_SPHERICAL_CUBEMAP
Video frame is split into 6 faces of a cube, and arranged on a 3x2 layout.
Definition: spherical.h:61
avio_rb24
unsigned int avio_rb24(AVIOContext *s)
Definition: aviobuf.c:757
ff_mpa_check_header
static int ff_mpa_check_header(uint32_t header)
Definition: mpegaudiodecheader.h:62
MOVStreamContext::aes_ctx
struct AVAES * aes_ctx
Definition: isom.h:279
MOV_TREF_FLAG_ENHANCEMENT
#define MOV_TREF_FLAG_ENHANCEMENT
Definition: isom.h:437
cens_scheme_decrypt
static int cens_scheme_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
Definition: mov.c:8310
MOVContext::handbrake_version
int handbrake_version
Definition: isom.h:341
mov_free_stream_context
static void mov_free_stream_context(AVFormatContext *s, AVStream *st)
Definition: mov.c:10069
AVPacket::size
int size
Definition: packet.h:596
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:143
avformat_alloc_context
AVFormatContext * avformat_alloc_context(void)
Allocate an AVFormatContext.
Definition: options.c:164
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:7483
AVIOContext::seekable
int seekable
A combination of AVIO_SEEKABLE_ flags or 0 when the stream is not seekable.
Definition: avio.h:261
av_aes_ctr_init
int av_aes_ctr_init(struct AVAESCTR *a, const uint8_t *key)
Initialize an AVAESCTR context.
Definition: aes_ctr.c:74
height
#define height
Definition: dsp.h:89
qtpalette.h
av_bprint_finalize
int av_bprint_finalize(AVBPrint *buf, char **ret_str)
Finalize a print buffer.
Definition: bprint.c:235
AVChannelLayout
An AVChannelLayout holds information about the channel layout of audio data.
Definition: channel_layout.h:319
FFStream
Definition: internal.h:128
mov_read_dref
static int mov_read_dref(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:638
mov_current_sample_dec
static void mov_current_sample_dec(MOVStreamContext *sc)
Definition: mov.c:4220
AVSphericalMapping::bound_right
uint32_t bound_right
Distance from the right edge.
Definition: spherical.h:187
MOVStsc::first
int first
Definition: isom.h:74
dst
uint8_t ptrdiff_t const uint8_t ptrdiff_t int intptr_t intptr_t int int16_t * dst
Definition: dsp.h:87
av_bswap32
#define av_bswap32
Definition: bswap.h:47
i
#define i(width, name, range_min, range_max)
Definition: cbs_h264.c:63
MOVStreamContext::stsz_sample_size
unsigned int stsz_sample_size
always contains sample size from stsz atom
Definition: isom.h:204
FF_MOV_FLAG_MFRA_AUTO
#define FF_MOV_FLAG_MFRA_AUTO
Definition: isom.h:461
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:610
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:328
uuid.h
ff_dvdclut_palette_extradata_cat
int ff_dvdclut_palette_extradata_cat(const uint32_t *clut, const size_t clut_size, AVCodecParameters *par)
Definition: dvdclut.c:28
mov_read_trun
static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5809
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:869
mov_read_iprp
static int mov_read_iprp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:9413
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:404
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:1207
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:3271
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:510
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:53
AVStreamGroup::iamf_audio_element
struct AVIAMFAudioElement * iamf_audio_element
Definition: avformat.h:1130
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:1017
mov_parse_heif_items
static int mov_parse_heif_items(AVFormatContext *s)
Definition: mov.c:10722
HEIFItem::is_idat_relative
int is_idat_relative
Definition: isom.h:308
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:4070
MOVDref::path
char * path
Definition: isom.h:87
mov_current_sample_inc
static void mov_current_sample_inc(MOVStreamContext *sc)
Definition: mov.c:4208
AVStream::sample_aspect_ratio
AVRational sample_aspect_ratio
sample aspect ratio (0 if unknown)
Definition: avformat.h:822
FFInputFormat::p
AVInputFormat p
The public AVInputFormat.
Definition: demux.h:70
dovi_isom.h
AVPacket::dts
int64_t dts
Decompression timestamp in AVStream->time_base units; the time at which the packet is decompressed.
Definition: packet.h:594
mov_read_vexu_proj
static int mov_read_vexu_proj(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6905
fix_timescale
static void fix_timescale(MOVContext *c, MOVStreamContext *sc)
Definition: mov.c:5122
avio_r8
int avio_r8(AVIOContext *s)
Definition: aviobuf.c:606
IAMFAudioElement::substreams
IAMFSubStream * substreams
Definition: iamf.h:98
AVSphericalMapping::padding
uint32_t padding
Number of pixels to pad from the edge of each cube face.
Definition: spherical.h:200
a
The reader does not expect b to be semantically here and if the code is changed by maybe adding a a division or other the signedness will almost certainly be mistaken To avoid this confusion a new type was SUINT is the C unsigned type but it holds a signed int to use the same example SUINT a
Definition: undefined.txt:41
av_channel_layout_retype
int av_channel_layout_retype(AVChannelLayout *channel_layout, enum AVChannelOrder order, int flags)
Change the AVChannelOrder of a channel layout.
Definition: channel_layout.c:887
av_reallocp_array
int av_reallocp_array(void *ptr, size_t nmemb, size_t size)
Allocate, reallocate an array through a pointer to a pointer.
Definition: mem.c:225
AVIAMFAudioElement
Information on how to combine one or more audio streams, as defined in section 3.6 of IAMF.
Definition: iamf.h:359
AV_PRIMARY_EYE_NONE
@ AV_PRIMARY_EYE_NONE
Neither eye.
Definition: stereo3d.h:178
mov_read_default
static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:9654
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:481
ffio_ensure_seekback
int ffio_ensure_seekback(AVIOContext *s, int64_t buf_size)
Ensures that the requested seekback buffer size will be available.
Definition: aviobuf.c:1026
AVStreamGroupTileGrid::nb_tiles
unsigned int nb_tiles
Amount of tiles in the grid.
Definition: avformat.h:959
av_packet_side_data_add
AVPacketSideData * av_packet_side_data_add(AVPacketSideData **psd, int *pnb_sd, enum AVPacketSideDataType type, void *data, size_t size, int flags)
Wrap existing data as packet side data.
Definition: packet.c:688
mov_read_packet
static int mov_read_packet(AVFormatContext *s, AVPacket *pkt)
Definition: mov.c:11382
mov_read_infe
static int mov_read_infe(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:9055
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:1075
AVStreamGroup::lcevc
struct AVStreamGroupLCEVC * lcevc
Definition: avformat.h:1133
attributes.h
AV_CODEC_ID_LCEVC
@ AV_CODEC_ID_LCEVC
Definition: codec_id.h:615
MOVEncryptionIndex::auxiliary_offsets_count
size_t auxiliary_offsets_count
Definition: isom.h:136
HEIFItem::vflip
int vflip
Definition: isom.h:306
AVPacket::flags
int flags
A combination of AV_PKT_FLAG values.
Definition: packet.h:601
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:501
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:10801
AVSubsampleEncryptionInfo
This file is part of FFmpeg.
Definition: encryption_info.h:25
av_buffer_alloc
AVBufferRef * av_buffer_alloc(size_t size)
Allocate an AVBuffer of the given size using av_malloc().
Definition: buffer.c:77
MOVFragmentIndexItem::stream_info
MOVFragmentStreamInfo * stream_info
Definition: isom.h:157
version
version
Definition: libkvazaar.c:313
AV_STREAM_GROUP_PARAMS_IAMF_AUDIO_ELEMENT
@ AV_STREAM_GROUP_PARAMS_IAMF_AUDIO_ELEMENT
Definition: avformat.h:1088
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:1164
ff_rfps_calculate
void ff_rfps_calculate(AVFormatContext *ic)
Definition: demux.c:2397
input
and forward the test the status of outputs and forward it to the corresponding return FFERROR_NOT_READY If the filters stores internally one or a few frame for some input
Definition: filter_design.txt:172
MOV_MP4_IPCM_TAG
#define MOV_MP4_IPCM_TAG
Definition: isom.h:482
mov_read_clli
static int mov_read_clli(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6586
MOVStreamContext::chunk_offsets
int64_t * chunk_offsets
Definition: isom.h:181
AVStreamGroup::iamf_mix_presentation
struct AVIAMFMixPresentation * iamf_mix_presentation
Definition: avformat.h:1131
AVBufferRef::size
size_t size
Size of data in bytes.
Definition: buffer.h:94
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:224
av_encryption_init_info_alloc
AVEncryptionInitInfo * av_encryption_init_info_alloc(uint32_t system_id_size, uint32_t num_key_ids, uint32_t key_id_size, uint32_t data_size)
Allocates an AVEncryptionInitInfo structure and sub-pointers to hold the given sizes.
Definition: encryption_info.c:178
av_channel_layout_custom_init
int av_channel_layout_custom_init(AVChannelLayout *channel_layout, int nb_channels)
Initialize a custom channel layout with the specified number of channels.
Definition: channel_layout.c:233
av_aes_ctr_free
void av_aes_ctr_free(struct AVAESCTR *a)
Release an AVAESCTR context.
Definition: aes_ctr.c:84
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:8108
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:9524
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
AVChannelLayout::u
union AVChannelLayout::@515 u
Details about which channels are present in this layout.
MOVDref::nlvl_from
int16_t nlvl_from
Definition: isom.h:91
AVStreamGroupTileGrid::nb_coded_side_data
int nb_coded_side_data
Amount of entries in coded_side_data.
Definition: avformat.h:1059
mov_metadata_creation_time
static void mov_metadata_creation_time(MOVContext *c, AVIOContext *pb, AVDictionary **metadata, int version)
Definition: mov.c:1878
mov_metadata_hmmt
static int mov_metadata_hmmt(MOVContext *c, AVIOContext *pb, unsigned len)
Definition: mov.c:324
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:8037
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:3351
mov_finalize_packet
static int mov_finalize_packet(AVFormatContext *s, AVStream *st, AVIndexEntry *sample, int64_t current_index, AVPacket *pkt)
Definition: mov.c:11318
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:11709
bprint.h
MOVContext::advanced_editlist
int advanced_editlist
Definition: isom.h:346
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:150
AVStreamGroupTileGrid::width
int width
Width of the final image for presentation.
Definition: avformat.h:1036
MOVStreamContext::bytes_per_frame
unsigned int bytes_per_frame
Definition: isom.h:217
AVSphericalMapping::roll
int32_t roll
Rotation around the forward vector [-180, 180].
Definition: spherical.h:146
IAMFContext::nb_audio_elements
int nb_audio_elements
Definition: iamf.h:132
MOVIndexRange::end
int64_t end
Definition: isom.h:170
av_malloc
#define av_malloc(s)
Definition: ops_asmgen.c:44
AV_CODEC_ID_NONE
@ AV_CODEC_ID_NONE
Definition: codec_id.h:50
AVPacket::pts
int64_t pts
Presentation timestamp in AVStream->time_base units; the time at which the decompressed packet will b...
Definition: packet.h:588
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:5744
search_frag_timestamp
static int search_frag_timestamp(AVFormatContext *s, MOVFragmentIndex *frag_index, AVStream *st, int64_t timestamp)
Definition: mov.c:1751
HEIFItem::width
int width
Definition: isom.h:302
FLAGS
#define FLAGS
Definition: mov.c:11766
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:4260
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:7885
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:3205
internal.h
AV_SPHERICAL_FISHEYE
@ AV_SPHERICAL_FISHEYE
Fisheye projection (Apple).
Definition: spherical.h:84
AVCodecParameters::height
int height
The height of the video frame in pixels.
Definition: codec_par.h:150
AV_TIME_BASE
#define AV_TIME_BASE
Internal time base represented as integer.
Definition: avutil.h:253
MOVStreamContext::stps_count
unsigned int stps_count
Definition: isom.h:197
AVCodecParameters::block_align
int block_align
The number of bytes per coded audio frame, required by some formats.
Definition: codec_par.h:221
AV_CODEC_ID_TTML
@ AV_CODEC_ID_TTML
Definition: codec_id.h:596
rb_size
static int rb_size(AVIOContext *pb, int64_t *value, int size)
Definition: mov.c:8928
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:3104
AV_FIELD_BB
@ AV_FIELD_BB
Bottom coded first, bottom displayed first.
Definition: defs.h:215
AV_PKT_DATA_ICC_PROFILE
@ AV_PKT_DATA_ICC_PROFILE
ICC profile data consisting of an opaque octet buffer following the format described by ISO 15076-1.
Definition: packet.h:271
AV_STEREO3D_TOPBOTTOM
@ AV_STEREO3D_TOPBOTTOM
Views are on top of each other.
Definition: stereo3d.h:76
MOVFragment::duration
unsigned duration
Definition: isom.h:108
AVIAMFMixPresentation
Information on how to render and mix one or more AVIAMFAudioElement to generate the final audio outpu...
Definition: iamf.h:616
ff_id3v1_genre_str
const char *const ff_id3v1_genre_str[ID3v1_GENRE_MAX+1]
ID3v1 genres.
Definition: id3v1.c:26
MOVStreamContext::sample_sizes
unsigned int * sample_sizes
Definition: isom.h:206
MOVContext::frag_index
MOVFragmentIndex frag_index
Definition: isom.h:359
mov_read_vpcc
static int mov_read_vpcc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6414
AV_CODEC_ID_PCM_F64BE
@ AV_CODEC_ID_PCM_F64BE
Definition: codec_id.h:360
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:361
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:1837
mov_finalize_stsd_codec
static int mov_finalize_stsd_codec(MOVContext *c, AVIOContext *pb, AVStream *st, MOVStreamContext *sc)
Definition: mov.c:2953
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:347
mov_read_mdcv
static int mov_read_mdcv(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6505
AV_TIMECODE_FLAG_ALLOWNEGATIVE
@ AV_TIMECODE_FLAG_ALLOWNEGATIVE
negative time values are allowed
Definition: timecode.h:38
AVStreamGroup::params
union AVStreamGroup::@447 params
Group type-specific parameters.
mov_read_mdat
static int mov_read_mdat(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1404
AV_CODEC_ID_VC1
@ AV_CODEC_ID_VC1
Definition: codec_id.h:122
demux.h
AV_DISPOSITION_DEPENDENT
#define AV_DISPOSITION_DEPENDENT
The stream is intended to be mixed with another stream before presentation.
Definition: avformat.h:705
MOVStreamContext::pb
AVIOContext * pb
Definition: isom.h:174
mov_read_keys
static int mov_read_keys(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5359
mov_read_iref_cdsc
static int mov_read_iref_cdsc(MOVContext *c, AVIOContext *pb, uint32_t type, int version)
Definition: mov.c:9269
AVCodecParameters::color_range
enum AVColorRange color_range
Additional colorspace characteristics.
Definition: codec_par.h:189
AV_CH_SIDE_RIGHT
#define AV_CH_SIDE_RIGHT
Definition: channel_layout.h:185
len
int len
Definition: vorbis_enc_data.h:426
AV_CODEC_ID_JPEG2000
@ AV_CODEC_ID_JPEG2000
Definition: codec_id.h:140
exif.h
MOVFragment::size
unsigned size
Definition: isom.h:109
MOV_TFHD_DEFAULT_SIZE
#define MOV_TFHD_DEFAULT_SIZE
Definition: isom.h:406
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:703
fix_stream_ids
static void fix_stream_ids(AVFormatContext *s)
Definition: mov.c:10871
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:4711
AVCodecParameters::coded_side_data
AVPacketSideData * coded_side_data
Additional data associated with the entire stream.
Definition: codec_par.h:83
mov_read_svq3
static int mov_read_svq3(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2417
AVSHA
hash context
Definition: sha.c:35
AVCOL_RANGE_MPEG
@ AVCOL_RANGE_MPEG
Narrow or limited range content.
Definition: pixfmt.h:760
av_calloc
void * av_calloc(size_t nmemb, size_t size)
Definition: mem.c:264
MOVFragmentStreamInfo::tfdt_dts
int64_t tfdt_dts
Definition: isom.h:143
AV_IAMF_AUDIO_ELEMENT_TYPE_SCENE
@ AV_IAMF_AUDIO_ELEMENT_TYPE_SCENE
Definition: iamf.h:349
AVCodecParameters::field_order
enum AVFieldOrder field_order
The order of the fields in interlaced video.
Definition: codec_par.h:182
av_get_packet
int av_get_packet(AVIOContext *s, AVPacket *pkt, int size)
Allocate and read the payload of a packet and initialize its fields with default values.
Definition: utils.c:98
mov_read_iinf
static int mov_read_iinf(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:9132
ff_read_string_to_bprint_overwrite
int64_t ff_read_string_to_bprint_overwrite(AVIOContext *s, struct AVBPrint *bp, int64_t max_len)
Read a whole null-terminated string of text from AVIOContext to an AVBPrint buffer overwriting its co...
Definition: aviobuf.c:863
AVStreamGroupTileGrid::horizontal
int horizontal
Offset in pixels from the left edge of the canvas where the tile should be placed.
Definition: avformat.h:995
get_stream_info_time
static int64_t get_stream_info_time(MOVFragmentStreamInfo *frag_stream_info)
Definition: mov.c:1699
MP4TrackKindValueMapping
Definition: isom.h:484
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:4111
AV_WB8
#define AV_WB8(p, d)
Definition: intreadwrite.h:392
MOVStreamContext::chunk_count
unsigned int chunk_count
Definition: isom.h:180
av_cmp_q
static int av_cmp_q(AVRational a, AVRational b)
Compare two rationals.
Definition: rational.h:89
MOVStreamContext::data_size
int64_t data_size
Definition: isom.h:235
AV_TIMECODE_FLAG_DROPFRAME
@ AV_TIMECODE_FLAG_DROPFRAME
timecode is drop frame
Definition: timecode.h:36
language
Undefined Behavior In the C language
Definition: undefined.txt:3
MOVStreamContext::ambient
AVAmbientViewingEnvironment * ambient
Definition: isom.h:271
AVCodecParameters::avcodec_parameters_copy
int avcodec_parameters_copy(AVCodecParameters *dst, const AVCodecParameters *src)
Copy the contents of src to dst.
Definition: codec_par.c:107
mov_read_tmcd
static int mov_read_tmcd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6403
mov_chan.h
AVStream::disposition
int disposition
Stream disposition - a combination of AV_DISPOSITION_* flags.
Definition: avformat.h:813
MOVStreamContext::ambient_size
size_t ambient_size
Definition: isom.h:272
tag
uint32_t tag
Definition: movenc.c:2048
AVStream::id
int id
Format-specific stream ID.
Definition: avformat.h:756
ret
ret
Definition: filter_design.txt:187
AVStream
Stream structure.
Definition: avformat.h:744
AV_CODEC_ID_APV
@ AV_CODEC_ID_APV
Definition: codec_id.h:332
AV_LOG_FATAL
#define AV_LOG_FATAL
Something went wrong and recovery is not possible.
Definition: log.h:204
HEIFItem::extent_length
int64_t extent_length
Definition: isom.h:300
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:7588
avio_seek
int64_t avio_seek(AVIOContext *s, int64_t offset, int whence)
fseek() equivalent for AVIOContext.
Definition: aviobuf.c:236
FFSWAP
#define FFSWAP(type, a, b)
Definition: macros.h:52
AVClass::class_name
const char * class_name
The name of the class; usually it is the same name as the context structure type to which the AVClass...
Definition: log.h:81
AVEncryptionInfo::key_id
uint8_t * key_id
The ID of the key used to encrypt the packet.
Definition: encryption_info.h:63
av_strlcat
size_t av_strlcat(char *dst, const char *src, size_t size)
Append the string src to the string dst, but to a total length of no more than size - 1 bytes,...
Definition: avstring.c:95
MOVStreamContext::stts_data
MOVStts * stts_data
Definition: isom.h:187
AVSphericalMapping::pitch
int32_t pitch
Rotation around the right vector [-90, 90].
Definition: spherical.h:145
AVStreamGroup::metadata
AVDictionary * metadata
Metadata that applies to the whole group.
Definition: avformat.h:1144
avio_rb16
unsigned int avio_rb16(AVIOContext *s)
Definition: aviobuf.c:749
AVStereo3D::type
enum AVStereo3DType type
How views are packed within the video.
Definition: stereo3d.h:207
MOVSbgp::index
unsigned int index
Definition: isom.h:123
HEIFItem::icc_profile_size
size_t icc_profile_size
Definition: isom.h:310
MOVContext::chapter_tracks
int * chapter_tracks
Definition: isom.h:342
cdt2
static const int16_t cdt2[8]
Definition: truemotion1data.h:43
AVSTREAM_PARSE_HEADERS
@ AVSTREAM_PARSE_HEADERS
Only parse headers, do not repack.
Definition: avformat.h:590
pos
unsigned int pos
Definition: spdifenc.c:414
avformat.h
MOVFragment::implicit_offset
uint64_t implicit_offset
Definition: isom.h:106
dict.h
av_packet_side_data_new
AVPacketSideData * av_packet_side_data_new(AVPacketSideData **psd, int *pnb_sd, enum AVPacketSideDataType type, size_t size, int flags)
Allocate a new packet side data.
Definition: packet.c:695
AV_AUDIO_SERVICE_TYPE_KARAOKE
@ AV_AUDIO_SERVICE_TYPE_KARAOKE
Definition: defs.h:244
mov_read_dmlp
static int mov_read_dmlp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:8617
flag
#define flag(name)
Definition: cbs_av1.c:496
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:324
id
enum AVCodecID id
Definition: dts2pts.c:550
mov_read_tfdt
static int mov_read_tfdt(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5770
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:5486
search_frag_moof_offset
static int search_frag_moof_offset(MOVFragmentIndex *frag_index, int64_t offset)
Definition: mov.c:1675
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:11189
MOVContext::use_mfra_for
int use_mfra_for
Definition: isom.h:356
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:637
AVStreamGroup
Definition: avformat.h:1097
av_get_media_type_string
const char * av_get_media_type_string(enum AVMediaType media_type)
Return a string describing the media_type enum, NULL if media_type is unknown.
Definition: utils.c:28
IAMFMixPresentation
Definition: iamf.h:107
AVStream::index
int index
stream index in AVFormatContext
Definition: avformat.h:750
avpriv_dv_init_demux
DVDemuxContext * avpriv_dv_init_demux(AVFormatContext *s)
Definition: dv.c:728
mov_seek_fragment
static int mov_seek_fragment(AVFormatContext *s, AVStream *st, int64_t timestamp)
Definition: mov.c:11554
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:2706
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:1111
get_frag_time
static int64_t get_frag_time(AVFormatContext *s, AVStream *dst_st, MOVFragmentIndex *frag_index, int index)
Definition: mov.c:1709
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:1151
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:3867
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:231
buffer
the frame and frame reference mechanism is intended to as much as expensive copies of that data while still allowing the filters to produce correct results The data is stored in buffers represented by AVFrame structures Several references can point to the same frame buffer
Definition: filter_design.txt:49
mov_read_glbl
static int mov_read_glbl(MOVContext *c, AVIOContext *pb, MOVAtom atom)
This function reads atom content and puts data in extradata without tag nor size unlike mov_read_extr...
Definition: mov.c:2479
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:7246
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:124
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:335
av_channel_layout_uninit
void av_channel_layout_uninit(AVChannelLayout *channel_layout)
Free any allocated data in the channel layout and reset the channel count to 0.
Definition: channel_layout.c:443
AV_CODEC_ID_DVAUDIO
@ AV_CODEC_ID_DVAUDIO
Definition: codec_id.h:466
avformat_free_context
void avformat_free_context(AVFormatContext *s)
Free an AVFormatContext and all its streams.
Definition: avformat.c:144
MOVContext::aax_mode
unsigned int aax_mode
'aax' file has been detected
Definition: isom.h:361
mov_read_sv3d
static int mov_read_sv3d(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6768
avio_read
int avio_read(AVIOContext *s, unsigned char *buf, int size)
Read size bytes from AVIOContext into buf.
Definition: aviobuf.c:615
mov_aaxc_crypto
static int mov_aaxc_crypto(MOVContext *c)
Definition: mov.c:1515
mov_get_skip_samples
static int64_t mov_get_skip_samples(AVStream *st, int sample)
Definition: mov.c:11692
MOVFragmentIndex
Definition: isom.h:160
AV_RB8
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_WL16 uint64_t_TMPL AV_WB64 unsigned int_TMPL AV_WB32 unsigned int_TMPL AV_WB24 unsigned int_TMPL AV_WB16 unsigned int_TMPL AV_RB8
Definition: bytestream.h:99
ref
static int ref[MAX_W *MAX_W]
Definition: jpeg2000dwt.c:117
AVStream::r_frame_rate
AVRational r_frame_rate
Real base framerate of the stream.
Definition: avformat.h:878
MOVStreamContext::tts_count
unsigned int tts_count
Definition: isom.h:182
MOVStreamContext::track_end
int64_t track_end
used for dts generation in fragmented movie files
Definition: isom.h:238
MOVStreamContext::sgpd_sync_count
uint32_t sgpd_sync_count
Definition: isom.h:245
MOVContext::fragment
MOVFragment fragment
current fragment in moof atom
Definition: isom.h:337
AVIndexEntry::pos
int64_t pos
Definition: avformat.h:599
AVIOContext::eof_reached
int eof_reached
true if was unable to read due to error or eof
Definition: avio.h:238
mov_metadata_int8_bypass_padding
static int mov_metadata_int8_bypass_padding(MOVContext *c, AVIOContext *pb, unsigned len, const char *key)
Definition: mov.c:111
AVStreamGroupLCEVC::width
int width
Width of the final stream for presentation.
Definition: avformat.h:1079
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:231
MOVParseTableEntry::type
uint32_t type
Definition: mov.c:83
Windows::Graphics::DirectX::Direct3D11::p
IDirect3DDxgiInterfaceAccess _COM_Outptr_ void ** p
Definition: vsrc_gfxcapture_winrt.hpp:53
AVMasteringDisplayMetadata::min_luminance
AVRational min_luminance
Min luminance of mastering display (cd/m^2).
Definition: mastering_display_metadata.h:52
MOVStreamContext::per_sample_iv_size
unsigned int per_sample_iv_size
Definition: isom.h: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:597
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:321
export_orphan_timecode
static void export_orphan_timecode(AVFormatContext *s)
Definition: mov.c:10202
mov_read_sbas
static int mov_read_sbas(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2550
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:102
mov_metadata_gnre
static int mov_metadata_gnre(MOVContext *c, AVIOContext *pb, unsigned len, const char *key)
Definition: mov.c:134
AV_PKT_DATA_ENCRYPTION_INFO
@ AV_PKT_DATA_ENCRYPTION_INFO
This side data contains encryption info for how to decrypt the packet.
Definition: packet.h:252
av_realloc
#define av_realloc(p, s)
Definition: ops_asmgen.c:46
MOV_MERGE_CTTS
#define MOV_MERGE_CTTS
Definition: mov.c:4641
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:2302
AVIAMFSubmix::nb_elements
unsigned int nb_elements
Number of elements in the submix.
Definition: iamf.h:575
MOVFragmentStreamInfo::id
int id
Definition: isom.h:140
AVIO_FLAG_READ
#define AVIO_FLAG_READ
read-only
Definition: avio.h:617
AV_PKT_DATA_AUDIO_SERVICE_TYPE
@ AV_PKT_DATA_AUDIO_SERVICE_TYPE
This side data should be associated with an audio stream and corresponds to enum AVAudioServiceType.
Definition: packet.h:117
av_spherical_alloc
AVSphericalMapping * av_spherical_alloc(size_t *size)
Allocate a AVSphericalVideo structure and initialize its fields to default values.
Definition: spherical.c:26
AV_OPT_FLAG_DECODING_PARAM
#define AV_OPT_FLAG_DECODING_PARAM
A generic parameter which can be set by the user for demuxing or decoding.
Definition: opt.h:356
mov_read_rtmd_track
static int mov_read_rtmd_track(AVFormatContext *s, AVStream *st)
Definition: mov.c:9984
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:346
AVCodecParameters::bits_per_coded_sample
int bits_per_coded_sample
The number of bits per sample in the codedwords.
Definition: codec_par.h:113
mov_parse_tiles
static int mov_parse_tiles(AVFormatContext *s)
Definition: mov.c:10596
mem.h
AVStreamGroup::type
enum AVStreamGroupParamsType type
Group type.
Definition: avformat.h:1124
MOVElst::time
int64_t time
Definition: isom.h:81
AVBufferRef
A reference to a data buffer.
Definition: buffer.h:82
HEIFGrid
Definition: isom.h:313
mov_read_iref_dimg
static int mov_read_iref_dimg(MOVContext *c, AVIOContext *pb, int version)
Definition: mov.c:9186
mov_read_pcmc
static int mov_read_pcmc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2031
build_open_gop_key_points
static int build_open_gop_key_points(AVStream *st)
Definition: mov.c:4578
mov_parse_stsd_audio
static void mov_parse_stsd_audio(MOVContext *c, AVIOContext *pb, AVStream *st, MOVStreamContext *sc)
Definition: mov.c:2770
IAMFContext::mix_presentations
IAMFMixPresentation ** mix_presentations
Definition: iamf.h:133
AV_CODEC_ID_PCM_U8
@ AV_CODEC_ID_PCM_U8
Definition: codec_id.h:343
MOVContext::trak_index
int trak_index
Index of the current 'trak'.
Definition: isom.h:331
mov_read_timecode_track
static int mov_read_timecode_track(AVFormatContext *s, AVStream *st)
Definition: mov.c:10010
HEIFGrid::item
HEIFItem * item
Definition: isom.h:314
AVSphericalMapping::bound_left
uint32_t bound_left
Distance from the left edge.
Definition: spherical.h:185
mov_read_mac_string
static int mov_read_mac_string(MOVContext *c, AVIOContext *pb, int len, char *dst, int dstlen)
Definition: mov.c:169
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
Number of delayed frames.
Definition: codec_par.h:200
HEIFGrid::tile_id_list
int16_t * tile_id_list
Definition: isom.h:316
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:441
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:361
AVStreamGroupTileGrid::height
int height
Height of the final image for presentation.
Definition: avformat.h:1046
AVStereo3D::view
enum AVStereo3DView view
Determines which views are packed.
Definition: stereo3d.h:217
read_tfra
static int read_tfra(MOVContext *mov, AVIOContext *f)
Definition: mov.c:10220
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:57
AVStereo3DView
AVStereo3DView
List of possible view types.
Definition: stereo3d.h:149
AVPacket
This structure stores compressed data.
Definition: packet.h:572
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:10817
mov_read_hfov
static int mov_read_hfov(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:7217
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:378
MOVContext::nb_heif_item
int nb_heif_item
Definition: isom.h:383
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:615
FFInputFormat
Definition: demux.h:66
MOVContext::decryption_keys
AVDictionary * decryption_keys
Definition: isom.h:388
mov_metadata_loci
static int mov_metadata_loci(MOVContext *c, AVIOContext *pb, unsigned len)
Definition: mov.c:274
mov_read_eyes
static int mov_read_eyes(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6978
AV_CODEC_ID_ILBC
@ AV_CODEC_ID_ILBC
Definition: codec_id.h:519
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:414
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:304
MOVAtom::type
uint32_t type
Definition: isom.h:95
distance
static float distance(float x, float y, int band)
Definition: nellymoserenc.c:231
AVSTREAM_PARSE_FULL
@ AVSTREAM_PARSE_FULL
full parsing and repack
Definition: avformat.h:589
parse_timecode_in_framenum_format
static int parse_timecode_in_framenum_format(AVFormatContext *s, AVStream *st, int64_t value, int flags)
Definition: mov.c:9970
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:449
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:486
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:359
ff_mov_demuxer
const FFInputFormat ff_mov_demuxer
Definition: mov.c:11828
AVCodecParameters::bit_rate
int64_t bit_rate
The average bitrate of the encoded data (in bits per second).
Definition: codec_par.h:99
MOVStts::count
unsigned int count
Definition: isom.h:64
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
MOVStreamContext::display_matrix
int32_t * display_matrix
Definition: isom.h:262
MOVContext::heif_grid
HEIFGrid * heif_grid
Definition: isom.h:384
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:213
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:8453
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:665
MOVStreamContext::sync_group_count
unsigned int sync_group_count
Definition: isom.h:242
MOVContext::bitrates_count
int bitrates_count
Definition: isom.h:354
AV_CODEC_ID_VORBIS
@ AV_CODEC_ID_VORBIS
Definition: codec_id.h:465
AVDictionaryEntry::value
char * value
Definition: dict.h:92
AVStream::start_time
int64_t start_time
Decoding: pts of the first frame of the stream in presentation order, in stream time base.
Definition: avformat.h:793
MOVStreamContext::id
int id
AVStream id.
Definition: isom.h:177
MOVStreamContext::samples_per_frame
unsigned int samples_per_frame
Definition: isom.h:218
MOVStreamContext::tts_allocated_size
unsigned int tts_allocated_size
Definition: isom.h:183
pkt
static AVPacket * pkt
Definition: demux_decode.c:55
MOVElst::duration
int64_t duration
Definition: isom.h:80
ac3tab.h
avstring.h
mov_read_ispe
static int mov_read_ispe(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:9352
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:9307
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:1273
mov_read_mfra
static int mov_read_mfra(MOVContext *c, AVIOContext *f)
Definition: mov.c:10275
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:125
flac.h
AVStreamGroupTileGrid::idx
unsigned int idx
Index of the stream in the group this tile references.
Definition: avformat.h:990
AVTimecode
Definition: timecode.h:41
get_frag_stream_info
static MOVFragmentStreamInfo * get_frag_stream_info(MOVFragmentIndex *frag_index, int index, int id)
Definition: mov.c:1620
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:8723
MOVContext::heif_item
HEIFItem ** heif_item
Definition: isom.h:382
MOVStreamContext::stts_count
unsigned int stts_count
Definition: isom.h:185
MOV_TRUN_SAMPLE_CTS
#define MOV_TRUN_SAMPLE_CTS
Definition: isom.h:416
HEIFItem::iref_list
HEIFItemRef * iref_list
Definition: isom.h:296
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:479
snprintf
#define snprintf
Definition: snprintf.h:34
IAMFMixPresentation::mix_presentation_id
unsigned int mix_presentation_id
Definition: iamf.h:114
AVCodecParameters::initial_padding
int initial_padding
Number of padding audio samples at the start.
Definition: codec_par.h:239
AV_CODEC_ID_PCM_S24BE
@ AV_CODEC_ID_PCM_S24BE
Definition: codec_id.h:351
mov_read_st3d
static int mov_read_st3d(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6640
mov_read_imir
static int mov_read_imir(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:9394
is_open_key_sample
static int is_open_key_sample(const MOVStreamContext *sc, int sample)
Definition: mov.c:11573
mov_read_dvc1
static int mov_read_dvc1(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2525
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:3823
AVChannelCustom::id
enum AVChannel id
Definition: channel_layout.h:284
mov_read_atom_into_extradata
static int64_t mov_read_atom_into_extradata(MOVContext *c, AVIOContext *pb, MOVAtom atom, AVCodecParameters *par, uint8_t *buf)
Definition: mov.c:2239
AV_WL16A
#define AV_WL16A(p, v)
Definition: intreadwrite.h:557
AV_RB64
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_WL16 uint64_t_TMPL AV_RB64
Definition: bytestream.h:95
AVSphericalMapping::yaw
int32_t yaw
Rotation around the up vector [-180, 180].
Definition: spherical.h:144
src
#define src
Definition: vp8dsp.c:248
mov_read_chapters
static void mov_read_chapters(AVFormatContext *s)
Definition: mov.c:9871
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
duration
static int64_t duration
Definition: ffplay.c:329
MOVContext::cur_item_id
int cur_item_id
Definition: isom.h:381
av_timecode_make_string
char * av_timecode_make_string(const AVTimecode *tc, char *buf, int framenum_arg)
Load timecode string in buf.
Definition: timecode.c:104
AVFMT_EVENT_FLAG_METADATA_UPDATED
#define AVFMT_EVENT_FLAG_METADATA_UPDATED
Definition: avformat.h:1638
AV_DICT_DONT_STRDUP_KEY
#define AV_DICT_DONT_STRDUP_KEY
Take ownership of a key that's been allocated with av_malloc() or another memory allocation function.
Definition: dict.h:77
MOVContext::next_root_atom
int64_t next_root_atom
offset of the next root atom
Definition: isom.h:350
MOVContext::found_iinf
int found_iinf
'iinf' atom has been found
Definition: isom.h:328
MOVContext::meta_keys_count
unsigned meta_keys_count
Definition: isom.h:333
iamf_reader.h
AVStreamGroupTileGrid::background
uint8_t background[4]
The pixel value per channel in RGBA format used if no pixel of any tile is located at a particular pi...
Definition: avformat.h:1010
MOVStreamContext::palette
uint32_t palette[256]
Definition: isom.h:233
cenc_scheme_decrypt
static int cenc_scheme_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
Definition: mov.c:8185
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:782
mov_parse_stsd_data
static int mov_parse_stsd_data(MOVContext *c, AVIOContext *pb, AVStream *st, MOVStreamContext *sc, int64_t size)
Definition: mov.c:2907
AV_CH_SIDE_LEFT
#define AV_CH_SIDE_LEFT
Definition: channel_layout.h:184
ff_iamf_read_deinit
void ff_iamf_read_deinit(IAMFDemuxContext *c)
Definition: iamf_reader.c:371
AV_CODEC_ID_PRORES
@ AV_CODEC_ID_PRORES
Definition: codec_id.h:200
AV_RB16
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_WL16 uint64_t_TMPL AV_WB64 unsigned int_TMPL AV_WB32 unsigned int_TMPL AV_WB24 unsigned int_TMPL AV_RB16
Definition: bytestream.h:98
av_encryption_init_info_add_side_data
uint8_t * av_encryption_init_info_add_side_data(const AVEncryptionInitInfo *info, size_t *side_data_size)
Allocates and initializes side data that holds a copy of the given encryption init info.
Definition: encryption_info.c:292
av_fourcc2str
#define av_fourcc2str(fourcc)
Definition: avutil.h: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:8947
MOVContext::ignore_chapters
int ignore_chapters
Definition: isom.h:348
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:853
MP4TrackKindMapping
Definition: isom.h:489
ff_alloc_extradata
int ff_alloc_extradata(AVCodecParameters *par, int size)
Allocate extradata with additional AV_INPUT_BUFFER_PADDING_SIZE at end which is always set to 0.
Definition: utils.c:237
HEIFItem::nb_iref_list
int nb_iref_list
Definition: isom.h:297
AV_DISPOSITION_NON_DIEGETIC
#define AV_DISPOSITION_NON_DIEGETIC
The stream is intended to be mixed with a spatial audio track.
Definition: avformat.h:682
avio_feof
int avio_feof(AVIOContext *s)
Similar to feof() but also returns nonzero on read errors.
Definition: aviobuf.c:349
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:301
mov_read_stsz
static int mov_read_stsz(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:3468