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