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  av_freep(&sc->extradata);
3262  av_freep(&sc->extradata_size);
3263  return ret;
3264 }
3265 
3267 {
3268  AVStream *st;
3269  MOVStreamContext *sc;
3270  unsigned int i, entries;
3271 
3272  if (c->trak_index < 0) {
3273  av_log(c->fc, AV_LOG_WARNING, "STSC outside TRAK\n");
3274  return 0;
3275  }
3276 
3277  if (c->fc->nb_streams < 1)
3278  return 0;
3279  st = c->fc->streams[c->fc->nb_streams-1];
3280  sc = st->priv_data;
3281 
3282  avio_r8(pb); /* version */
3283  avio_rb24(pb); /* flags */
3284 
3285  entries = avio_rb32(pb);
3286  if ((uint64_t)entries * 12 + 4 > atom.size)
3287  return AVERROR_INVALIDDATA;
3288 
3289  av_log(c->fc, AV_LOG_TRACE, "track[%u].stsc.entries = %u\n", c->fc->nb_streams - 1, entries);
3290 
3291  if (!entries)
3292  return 0;
3293  if (sc->stsc_data) {
3294  av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicated STSC atom\n");
3295  return 0;
3296  }
3297  av_free(sc->stsc_data);
3298  sc->stsc_count = 0;
3299  sc->stsc_data = av_malloc_array(entries, sizeof(*sc->stsc_data));
3300  if (!sc->stsc_data)
3301  return AVERROR(ENOMEM);
3302 
3303  for (i = 0; i < entries && !pb->eof_reached; i++) {
3304  sc->stsc_data[i].first = avio_rb32(pb);
3305  sc->stsc_data[i].count = avio_rb32(pb);
3306  sc->stsc_data[i].id = avio_rb32(pb);
3307  }
3308 
3309  sc->stsc_count = i;
3310  for (i = sc->stsc_count - 1; i < UINT_MAX; i--) {
3311  int64_t first_min = i + 1;
3312  if ((i+1 < sc->stsc_count && sc->stsc_data[i].first >= sc->stsc_data[i+1].first) ||
3313  (i > 0 && sc->stsc_data[i].first <= sc->stsc_data[i-1].first) ||
3314  sc->stsc_data[i].first < first_min ||
3315  sc->stsc_data[i].count < 1 ||
3316  sc->stsc_data[i].id < 1) {
3317  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);
3318  if (i+1 >= sc->stsc_count) {
3319  if (sc->stsc_data[i].count == 0 && i > 0) {
3320  sc->stsc_count --;
3321  continue;
3322  }
3323  sc->stsc_data[i].first = FFMAX(sc->stsc_data[i].first, first_min);
3324  if (i > 0 && sc->stsc_data[i].first <= sc->stsc_data[i-1].first)
3325  sc->stsc_data[i].first = FFMIN(sc->stsc_data[i-1].first + 1LL, INT_MAX);
3326  sc->stsc_data[i].count = FFMAX(sc->stsc_data[i].count, 1);
3327  sc->stsc_data[i].id = FFMAX(sc->stsc_data[i].id, 1);
3328  continue;
3329  }
3330  av_assert0(sc->stsc_data[i+1].first >= 2);
3331  // We replace this entry by the next valid
3332  sc->stsc_data[i].first = sc->stsc_data[i+1].first - 1;
3333  sc->stsc_data[i].count = sc->stsc_data[i+1].count;
3334  sc->stsc_data[i].id = sc->stsc_data[i+1].id;
3335  }
3336  }
3337 
3338  if (pb->eof_reached) {
3339  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSC atom\n");
3340  return AVERROR_EOF;
3341  }
3342 
3343  return 0;
3344 }
3345 
3346 static inline int mov_stsc_index_valid(unsigned int index, unsigned int count)
3347 {
3348  return index < count - 1;
3349 }
3350 
3351 /* Compute the samples value for the stsc entry at the given index. */
3352 static inline int64_t mov_get_stsc_samples(MOVStreamContext *sc, unsigned int index)
3353 {
3354  int chunk_count;
3355 
3357  chunk_count = sc->stsc_data[index + 1].first - sc->stsc_data[index].first;
3358  else {
3359  // Validation for stsc / stco happens earlier in mov_read_stsc + mov_read_trak.
3361  chunk_count = sc->chunk_count - (sc->stsc_data[index].first - 1);
3362  }
3363 
3364  return sc->stsc_data[index].count * (int64_t)chunk_count;
3365 }
3366 
3368 {
3369  AVStream *st;
3370  MOVStreamContext *sc;
3371  unsigned i, entries;
3372 
3373  if (c->trak_index < 0) {
3374  av_log(c->fc, AV_LOG_WARNING, "STPS outside TRAK\n");
3375  return 0;
3376  }
3377 
3378  if (c->fc->nb_streams < 1)
3379  return 0;
3380  st = c->fc->streams[c->fc->nb_streams-1];
3381  sc = st->priv_data;
3382 
3383  avio_rb32(pb); // version + flags
3384 
3385  entries = avio_rb32(pb);
3386  if (sc->stps_data)
3387  av_log(c->fc, AV_LOG_WARNING, "Duplicated STPS atom\n");
3388  av_free(sc->stps_data);
3389  sc->stps_count = 0;
3390  sc->stps_data = av_malloc_array(entries, sizeof(*sc->stps_data));
3391  if (!sc->stps_data)
3392  return AVERROR(ENOMEM);
3393 
3394  for (i = 0; i < entries && !pb->eof_reached; i++) {
3395  sc->stps_data[i] = avio_rb32(pb);
3396  }
3397 
3398  sc->stps_count = i;
3399 
3400  if (pb->eof_reached) {
3401  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STPS atom\n");
3402  return AVERROR_EOF;
3403  }
3404 
3405  return 0;
3406 }
3407 
3409 {
3410  AVStream *st;
3411  FFStream *sti;
3412  MOVStreamContext *sc;
3413  unsigned int i, entries;
3414 
3415  if (c->trak_index < 0) {
3416  av_log(c->fc, AV_LOG_WARNING, "STSS outside TRAK\n");
3417  return 0;
3418  }
3419 
3420  if (c->fc->nb_streams < 1)
3421  return 0;
3422  st = c->fc->streams[c->fc->nb_streams-1];
3423  sti = ffstream(st);
3424  sc = st->priv_data;
3425 
3426  avio_r8(pb); /* version */
3427  avio_rb24(pb); /* flags */
3428 
3429  entries = avio_rb32(pb);
3430 
3431  av_log(c->fc, AV_LOG_TRACE, "keyframe_count = %u\n", entries);
3432 
3433  if (!entries) {
3434  sc->keyframe_absent = 1;
3435  if (!sti->need_parsing && st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
3437  return 0;
3438  }
3439  if (sc->keyframes)
3440  av_log(c->fc, AV_LOG_WARNING, "Duplicated STSS atom\n");
3441  if (entries >= UINT_MAX / sizeof(int))
3442  return AVERROR_INVALIDDATA;
3443  av_freep(&sc->keyframes);
3444  sc->keyframe_count = 0;
3445  sc->keyframes = av_malloc_array(entries, sizeof(*sc->keyframes));
3446  if (!sc->keyframes)
3447  return AVERROR(ENOMEM);
3448 
3449  for (i = 0; i < entries && !pb->eof_reached; i++) {
3450  sc->keyframes[i] = avio_rb32(pb);
3451  }
3452 
3453  sc->keyframe_count = i;
3454 
3455  if (pb->eof_reached) {
3456  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSS atom\n");
3457  return AVERROR_EOF;
3458  }
3459 
3460  return 0;
3461 }
3462 
3464 {
3465  AVStream *st;
3466  MOVStreamContext *sc;
3467  unsigned int i, entries, sample_size, field_size, num_bytes;
3468  GetBitContext gb;
3469  unsigned char* buf;
3470  int ret;
3471 
3472  if (c->trak_index < 0) {
3473  av_log(c->fc, AV_LOG_WARNING, "STSZ outside TRAK\n");
3474  return 0;
3475  }
3476 
3477  if (c->fc->nb_streams < 1)
3478  return 0;
3479  st = c->fc->streams[c->fc->nb_streams-1];
3480  sc = st->priv_data;
3481 
3482  avio_r8(pb); /* version */
3483  avio_rb24(pb); /* flags */
3484 
3485  if (atom.type == MKTAG('s','t','s','z')) {
3486  sample_size = avio_rb32(pb);
3487  if (!sc->sample_size) /* do not overwrite value computed in stsd */
3488  sc->sample_size = sample_size;
3489  sc->stsz_sample_size = sample_size;
3490  field_size = 32;
3491  } else {
3492  sample_size = 0;
3493  avio_rb24(pb); /* reserved */
3494  field_size = avio_r8(pb);
3495  }
3496  entries = avio_rb32(pb);
3497 
3498  av_log(c->fc, AV_LOG_TRACE, "sample_size = %u sample_count = %u\n", sc->sample_size, entries);
3499 
3500  sc->sample_count = entries;
3501  if (sample_size)
3502  return 0;
3503 
3504  if (field_size != 4 && field_size != 8 && field_size != 16 && field_size != 32) {
3505  av_log(c->fc, AV_LOG_ERROR, "Invalid sample field size %u\n", field_size);
3506  return AVERROR_INVALIDDATA;
3507  }
3508 
3509  if (!entries)
3510  return 0;
3511  if (entries >= (INT_MAX - 4 - 8 * AV_INPUT_BUFFER_PADDING_SIZE) / field_size)
3512  return AVERROR_INVALIDDATA;
3513  if (sc->sample_sizes)
3514  av_log(c->fc, AV_LOG_WARNING, "Duplicated STSZ atom\n");
3515  av_free(sc->sample_sizes);
3516  sc->sample_count = 0;
3517  sc->sample_sizes = av_malloc_array(entries, sizeof(*sc->sample_sizes));
3518  if (!sc->sample_sizes)
3519  return AVERROR(ENOMEM);
3520 
3521  num_bytes = (entries*field_size+4)>>3;
3522 
3523  buf = av_malloc(num_bytes+AV_INPUT_BUFFER_PADDING_SIZE);
3524  if (!buf) {
3525  av_freep(&sc->sample_sizes);
3526  return AVERROR(ENOMEM);
3527  }
3528 
3529  ret = ffio_read_size(pb, buf, num_bytes);
3530  if (ret < 0) {
3531  av_freep(&sc->sample_sizes);
3532  av_free(buf);
3533  av_log(c->fc, AV_LOG_WARNING, "STSZ atom truncated\n");
3534  return 0;
3535  }
3536 
3537  init_get_bits(&gb, buf, 8*num_bytes);
3538 
3539  for (i = 0; i < entries; i++) {
3540  sc->sample_sizes[i] = get_bits_long(&gb, field_size);
3541  if (sc->sample_sizes[i] > INT64_MAX - sc->data_size) {
3542  av_free(buf);
3543  av_log(c->fc, AV_LOG_ERROR, "Sample size overflow in STSZ\n");
3544  return AVERROR_INVALIDDATA;
3545  }
3546  sc->data_size += sc->sample_sizes[i];
3547  }
3548 
3549  sc->sample_count = i;
3550 
3551  av_free(buf);
3552 
3553  return 0;
3554 }
3555 
3557 {
3558  AVStream *st;
3559  MOVStreamContext *sc;
3560  unsigned int i, entries;
3561  int64_t duration = 0;
3562  int64_t total_sample_count = 0;
3563  int64_t current_dts = 0;
3564  int64_t corrected_dts = 0;
3565 
3566  if (c->trak_index < 0) {
3567  av_log(c->fc, AV_LOG_WARNING, "STTS outside TRAK\n");
3568  return 0;
3569  }
3570 
3571  if (c->fc->nb_streams < 1)
3572  return 0;
3573  st = c->fc->streams[c->fc->nb_streams-1];
3574  sc = st->priv_data;
3575 
3576  avio_r8(pb); /* version */
3577  avio_rb24(pb); /* flags */
3578  entries = avio_rb32(pb);
3579 
3580  av_log(c->fc, AV_LOG_TRACE, "track[%u].stts.entries = %u\n",
3581  c->fc->nb_streams-1, entries);
3582 
3583  if (sc->stts_data)
3584  av_log(c->fc, AV_LOG_WARNING, "Duplicated STTS atom\n");
3585  av_freep(&sc->stts_data);
3586  sc->stts_count = 0;
3587  if (entries >= INT_MAX / sizeof(*sc->stts_data))
3588  return AVERROR(ENOMEM);
3589 
3590  for (i = 0; i < entries && !pb->eof_reached; i++) {
3591  unsigned int sample_duration;
3592  unsigned int sample_count;
3593  unsigned int min_entries = FFMIN(FFMAX(i + 1, 1024 * 1024), entries);
3594  MOVStts *stts_data = av_fast_realloc(sc->stts_data, &sc->stts_allocated_size,
3595  min_entries * sizeof(*sc->stts_data));
3596  if (!stts_data) {
3597  av_freep(&sc->stts_data);
3598  sc->stts_count = 0;
3599  return AVERROR(ENOMEM);
3600  }
3601  sc->stts_count = min_entries;
3602  sc->stts_data = stts_data;
3603 
3604  sample_count = avio_rb32(pb);
3605  sample_duration = avio_rb32(pb);
3606 
3607  sc->stts_data[i].count= sample_count;
3608  sc->stts_data[i].duration= sample_duration;
3609 
3610  av_log(c->fc, AV_LOG_TRACE, "sample_count=%u, sample_duration=%u\n",
3611  sample_count, sample_duration);
3612 
3613  /* STTS sample offsets are uint32 but some files store it as int32
3614  * with negative values used to correct DTS delays.
3615  There may be abnormally large values as well. */
3616  if (sample_duration > c->max_stts_delta) {
3617  // assume high delta is a correction if negative when cast as int32
3618  int32_t delta_magnitude = (int32_t)sample_duration;
3619  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",
3620  sample_duration, i, sample_count, st->index);
3621  sc->stts_data[i].duration = 1;
3622  corrected_dts = av_sat_add64(corrected_dts, (delta_magnitude < 0 ? (int64_t)delta_magnitude : 1) * sample_count);
3623  } else {
3624  corrected_dts += sample_duration * (uint64_t)sample_count;
3625  }
3626 
3627  current_dts += sc->stts_data[i].duration * (uint64_t)sample_count;
3628 
3629  if (current_dts > corrected_dts) {
3630  int64_t drift = av_sat_sub64(current_dts, corrected_dts) / FFMAX(sample_count, 1);
3631  uint32_t correction = (sc->stts_data[i].duration > drift) ? drift : sc->stts_data[i].duration - 1;
3632  current_dts -= correction * (uint64_t)sample_count;
3633  sc->stts_data[i].duration -= correction;
3634  }
3635 
3636  duration+=(int64_t)sc->stts_data[i].duration*(uint64_t)sc->stts_data[i].count;
3637  total_sample_count+=sc->stts_data[i].count;
3638  }
3639 
3640  sc->stts_count = i;
3641 
3642  if (duration > 0 &&
3643  duration <= INT64_MAX - sc->duration_for_fps &&
3644  total_sample_count <= INT_MAX - sc->nb_frames_for_fps) {
3645  sc->duration_for_fps += duration;
3646  sc->nb_frames_for_fps += total_sample_count;
3647  }
3648 
3649  if (pb->eof_reached) {
3650  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STTS atom\n");
3651  return AVERROR_EOF;
3652  }
3653 
3654  st->nb_frames= total_sample_count;
3655  if (duration)
3656  st->duration= FFMIN(st->duration, duration);
3657 
3658  // All samples have zero duration. They have higher chance be chose by
3659  // mov_find_next_sample, which leads to seek again and again.
3660  //
3661  // It's AVERROR_INVALIDDATA actually, but such files exist in the wild.
3662  // So only mark data stream as discarded for safety.
3663  if (!duration && sc->stts_count &&
3665  av_log(c->fc, AV_LOG_WARNING,
3666  "All samples in data stream index:id [%d:%d] have zero "
3667  "duration, stream set to be discarded by default. Override "
3668  "using AVStream->discard or -discard for ffmpeg command.\n",
3669  st->index, sc->id);
3670  st->discard = AVDISCARD_ALL;
3671  }
3672  sc->track_end = duration;
3673  return 0;
3674 }
3675 
3677 {
3678  AVStream *st;
3679  MOVStreamContext *sc;
3680  int64_t i, entries;
3681 
3682  if (c->fc->nb_streams < 1)
3683  return 0;
3684  st = c->fc->streams[c->fc->nb_streams - 1];
3685  sc = st->priv_data;
3686 
3687  avio_r8(pb); /* version */
3688  avio_rb24(pb); /* flags */
3689  entries = atom.size - 4;
3690 
3691  av_log(c->fc, AV_LOG_TRACE, "track[%u].sdtp.entries = %" PRId64 "\n",
3692  c->fc->nb_streams - 1, entries);
3693 
3694  if (sc->sdtp_data)
3695  av_log(c->fc, AV_LOG_WARNING, "Duplicated SDTP atom\n");
3696  av_freep(&sc->sdtp_data);
3697  sc->sdtp_count = 0;
3698 
3699  sc->sdtp_data = av_malloc(entries);
3700  if (!sc->sdtp_data)
3701  return AVERROR(ENOMEM);
3702 
3703  for (i = 0; i < entries && !pb->eof_reached; i++)
3704  sc->sdtp_data[i] = avio_r8(pb);
3705  sc->sdtp_count = i;
3706 
3707  return 0;
3708 }
3709 
3710 static void mov_update_dts_shift(MOVStreamContext *sc, int duration, void *logctx)
3711 {
3712  if (duration < 0) {
3713  if (duration == INT_MIN) {
3714  av_log(logctx, AV_LOG_WARNING, "mov_update_dts_shift(): dts_shift set to %d\n", INT_MAX);
3715  duration++;
3716  }
3717  sc->dts_shift = FFMAX(sc->dts_shift, -duration);
3718  }
3719 }
3720 
3722 {
3723  AVStream *st;
3724  MOVStreamContext *sc;
3725  unsigned int i, entries, ctts_count = 0;
3726 
3727  if (c->trak_index < 0) {
3728  av_log(c->fc, AV_LOG_WARNING, "CTTS outside TRAK\n");
3729  return 0;
3730  }
3731 
3732  if (c->fc->nb_streams < 1)
3733  return 0;
3734  st = c->fc->streams[c->fc->nb_streams-1];
3735  sc = st->priv_data;
3736 
3737  avio_r8(pb); /* version */
3738  avio_rb24(pb); /* flags */
3739  entries = avio_rb32(pb);
3740 
3741  av_log(c->fc, AV_LOG_TRACE, "track[%u].ctts.entries = %u\n", c->fc->nb_streams - 1, entries);
3742 
3743  if (!entries)
3744  return 0;
3745  if (entries >= UINT_MAX / sizeof(*sc->ctts_data))
3746  return AVERROR_INVALIDDATA;
3747  av_freep(&sc->ctts_data);
3748  sc->ctts_data = av_fast_realloc(NULL, &sc->ctts_allocated_size, entries * sizeof(*sc->ctts_data));
3749  if (!sc->ctts_data)
3750  return AVERROR(ENOMEM);
3751 
3752  for (i = 0; i < entries && !pb->eof_reached; i++) {
3753  MOVCtts *ctts_data;
3754  const size_t min_size_needed = (ctts_count + 1) * sizeof(MOVCtts);
3755  const size_t requested_size =
3756  min_size_needed > sc->ctts_allocated_size ?
3757  FFMAX(min_size_needed, 2 * sc->ctts_allocated_size) :
3758  min_size_needed;
3759  int count = avio_rb32(pb);
3760  int duration = avio_rb32(pb);
3761 
3762  if (count <= 0) {
3763  av_log(c->fc, AV_LOG_TRACE,
3764  "ignoring CTTS entry with count=%d duration=%d\n",
3765  count, duration);
3766  continue;
3767  }
3768 
3769  if (ctts_count >= UINT_MAX / sizeof(MOVCtts) - 1)
3770  return AVERROR(ENOMEM);
3771 
3772  ctts_data = av_fast_realloc(sc->ctts_data, &sc->ctts_allocated_size, requested_size);
3773 
3774  if (!ctts_data)
3775  return AVERROR(ENOMEM);
3776 
3777  sc->ctts_data = ctts_data;
3778 
3779  ctts_data[ctts_count].count = count;
3780  ctts_data[ctts_count].offset = duration;
3781  ctts_count++;
3782 
3783  av_log(c->fc, AV_LOG_TRACE, "count=%d, duration=%d\n",
3784  count, duration);
3785 
3786  if (i+2<entries)
3787  mov_update_dts_shift(sc, duration, c->fc);
3788  }
3789 
3790  sc->ctts_count = ctts_count;
3791 
3792  if (pb->eof_reached) {
3793  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted CTTS atom\n");
3794  return AVERROR_EOF;
3795  }
3796 
3797  av_log(c->fc, AV_LOG_TRACE, "dts shift %d\n", sc->dts_shift);
3798 
3799  return 0;
3800 }
3801 
3803 {
3804  AVStream *st;
3805  MOVStreamContext *sc;
3806  uint8_t version;
3807  uint32_t grouping_type;
3808  uint32_t default_length;
3809  av_unused uint32_t default_group_description_index;
3810  uint32_t entry_count;
3811 
3812  if (c->fc->nb_streams < 1)
3813  return 0;
3814  st = c->fc->streams[c->fc->nb_streams - 1];
3815  sc = st->priv_data;
3816 
3817  version = avio_r8(pb); /* version */
3818  avio_rb24(pb); /* flags */
3819  grouping_type = avio_rl32(pb);
3820 
3821  /*
3822  * This function only supports "sync" boxes, but the code is able to parse
3823  * other boxes (such as "tscl", "tsas" and "stsa")
3824  */
3825  if (grouping_type != MKTAG('s','y','n','c'))
3826  return 0;
3827 
3828  default_length = version >= 1 ? avio_rb32(pb) : 0;
3829  default_group_description_index = version >= 2 ? avio_rb32(pb) : 0;
3830  entry_count = avio_rb32(pb);
3831 
3832  av_freep(&sc->sgpd_sync);
3833  sc->sgpd_sync_count = entry_count;
3834  sc->sgpd_sync = av_calloc(entry_count, sizeof(*sc->sgpd_sync));
3835  if (!sc->sgpd_sync)
3836  return AVERROR(ENOMEM);
3837 
3838  for (uint32_t i = 0; i < entry_count && !pb->eof_reached; i++) {
3839  uint32_t description_length = default_length;
3840  if (version >= 1 && default_length == 0)
3841  description_length = avio_rb32(pb);
3842  if (grouping_type == MKTAG('s','y','n','c')) {
3843  const uint8_t nal_unit_type = avio_r8(pb) & 0x3f;
3844  sc->sgpd_sync[i] = nal_unit_type;
3845  description_length -= 1;
3846  }
3847  avio_skip(pb, description_length);
3848  }
3849 
3850  if (pb->eof_reached) {
3851  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted SGPD atom\n");
3852  return AVERROR_EOF;
3853  }
3854 
3855  return 0;
3856 }
3857 
3859 {
3860  AVStream *st;
3861  MOVStreamContext *sc;
3862  unsigned int i, entries;
3863  uint8_t version;
3864  uint32_t grouping_type;
3865  MOVSbgp *table, **tablep;
3866  int *table_count;
3867 
3868  if (c->fc->nb_streams < 1)
3869  return 0;
3870  st = c->fc->streams[c->fc->nb_streams-1];
3871  sc = st->priv_data;
3872 
3873  version = avio_r8(pb); /* version */
3874  avio_rb24(pb); /* flags */
3875  grouping_type = avio_rl32(pb);
3876 
3877  if (grouping_type == MKTAG('r','a','p',' ')) {
3878  tablep = &sc->rap_group;
3879  table_count = &sc->rap_group_count;
3880  } else if (grouping_type == MKTAG('s','y','n','c')) {
3881  tablep = &sc->sync_group;
3882  table_count = &sc->sync_group_count;
3883  } else {
3884  return 0;
3885  }
3886 
3887  if (version == 1)
3888  avio_rb32(pb); /* grouping_type_parameter */
3889 
3890  entries = avio_rb32(pb);
3891  if (!entries)
3892  return 0;
3893  if (*tablep)
3894  av_log(c->fc, AV_LOG_WARNING, "Duplicated SBGP %s atom\n", av_fourcc2str(grouping_type));
3895  av_freep(tablep);
3896  table = av_malloc_array(entries, sizeof(*table));
3897  if (!table)
3898  return AVERROR(ENOMEM);
3899  *tablep = table;
3900 
3901  for (i = 0; i < entries && !pb->eof_reached; i++) {
3902  table[i].count = avio_rb32(pb); /* sample_count */
3903  table[i].index = avio_rb32(pb); /* group_description_index */
3904  }
3905 
3906  *table_count = i;
3907 
3908  if (pb->eof_reached) {
3909  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted SBGP atom\n");
3910  return AVERROR_EOF;
3911  }
3912 
3913  return 0;
3914 }
3915 
3916 /**
3917  * Get ith edit list entry (media time, duration).
3918  */
3920  const MOVStreamContext *msc,
3921  unsigned int edit_list_index,
3922  int64_t *edit_list_media_time,
3923  int64_t *edit_list_duration,
3924  int64_t global_timescale)
3925 {
3926  if (edit_list_index == msc->elst_count) {
3927  return 0;
3928  }
3929  *edit_list_media_time = msc->elst_data[edit_list_index].time;
3930  *edit_list_duration = msc->elst_data[edit_list_index].duration;
3931 
3932  /* duration is in global timescale units;convert to msc timescale */
3933  if (global_timescale == 0) {
3934  avpriv_request_sample(mov->fc, "Support for mvhd.timescale = 0 with editlists");
3935  return 0;
3936  }
3937  *edit_list_duration = av_rescale(*edit_list_duration, msc->time_scale,
3938  global_timescale);
3939 
3940  if (*edit_list_duration + (uint64_t)*edit_list_media_time > INT64_MAX)
3941  *edit_list_duration = 0;
3942 
3943  return 1;
3944 }
3945 
3946 /**
3947  * Find the closest previous frame to the timestamp_pts, in e_old index
3948  * entries. Searching for just any frame / just key frames can be controlled by
3949  * last argument 'flag'.
3950  * Note that if ctts_data is not NULL, we will always search for a key frame
3951  * irrespective of the value of 'flag'. If we don't find any keyframe, we will
3952  * return the first frame of the video.
3953  *
3954  * Here the timestamp_pts is considered to be a presentation timestamp and
3955  * the timestamp of index entries are considered to be decoding timestamps.
3956  *
3957  * Returns 0 if successful in finding a frame, else returns -1.
3958  * Places the found index corresponding output arg.
3959  *
3960  * If ctts_old is not NULL, then refines the searched entry by searching
3961  * backwards from the found timestamp, to find the frame with correct PTS.
3962  *
3963  * Places the found ctts_index and ctts_sample in corresponding output args.
3964  */
3966  AVIndexEntry *e_old,
3967  int nb_old,
3968  MOVTimeToSample *tts_data,
3969  int64_t tts_count,
3970  int64_t timestamp_pts,
3971  int flag,
3972  int64_t* index,
3973  int64_t* tts_index,
3974  int64_t* tts_sample)
3975 {
3976  MOVStreamContext *msc = st->priv_data;
3977  FFStream *const sti = ffstream(st);
3978  AVIndexEntry *e_keep = sti->index_entries;
3979  int nb_keep = sti->nb_index_entries;
3980  int64_t i = 0;
3981 
3982  av_assert0(index);
3983 
3984  // If dts_shift > 0, then all the index timestamps will have to be offset by
3985  // at least dts_shift amount to obtain PTS.
3986  // Hence we decrement the searched timestamp_pts by dts_shift to find the closest index element.
3987  if (msc->dts_shift > 0) {
3988  timestamp_pts -= msc->dts_shift;
3989  }
3990 
3991  sti->index_entries = e_old;
3992  sti->nb_index_entries = nb_old;
3993  *index = av_index_search_timestamp(st, timestamp_pts, flag | AVSEEK_FLAG_BACKWARD);
3994 
3995  // Keep going backwards in the index entries until the timestamp is the same.
3996  if (*index >= 0) {
3997  for (i = *index; i > 0 && e_old[i].timestamp == e_old[i - 1].timestamp;
3998  i--) {
3999  if ((flag & AVSEEK_FLAG_ANY) ||
4000  (e_old[i - 1].flags & AVINDEX_KEYFRAME)) {
4001  *index = i - 1;
4002  }
4003  }
4004  }
4005 
4006  // If we have CTTS then refine the search, by searching backwards over PTS
4007  // computed by adding corresponding CTTS durations to index timestamps.
4008  if (msc->ctts_count && *index >= 0) {
4009  av_assert0(tts_index);
4010  av_assert0(tts_sample);
4011  // Find out the ctts_index for the found frame.
4012  *tts_index = 0;
4013  *tts_sample = 0;
4014  for (int64_t index_tts_count = 0; index_tts_count < *index; index_tts_count++) {
4015  if (*tts_index < tts_count) {
4016  (*tts_sample)++;
4017  if (tts_data[*tts_index].count == *tts_sample) {
4018  (*tts_index)++;
4019  *tts_sample = 0;
4020  }
4021  }
4022  }
4023 
4024  while (*index >= 0 && (*tts_index) >= 0 && (*tts_index) < tts_count) {
4025  // Find a "key frame" with PTS <= timestamp_pts (So that we can decode B-frames correctly).
4026  // No need to add dts_shift to the timestamp here because timestamp_pts has already been
4027  // compensated by dts_shift above.
4028  if ((e_old[*index].timestamp + tts_data[*tts_index].offset) <= timestamp_pts &&
4029  (e_old[*index].flags & AVINDEX_KEYFRAME)) {
4030  break;
4031  }
4032 
4033  (*index)--;
4034  if (*tts_sample == 0) {
4035  (*tts_index)--;
4036  if (*tts_index >= 0)
4037  *tts_sample = tts_data[*tts_index].count - 1;
4038  } else {
4039  (*tts_sample)--;
4040  }
4041  }
4042  }
4043 
4044  /* restore AVStream state*/
4045  sti->index_entries = e_keep;
4046  sti->nb_index_entries = nb_keep;
4047  return *index >= 0 ? 0 : -1;
4048 }
4049 
4050 /**
4051  * Add index entry with the given values, to the end of ffstream(st)->index_entries.
4052  * Returns the new size ffstream(st)->index_entries if successful, else returns -1.
4053  *
4054  * This function is similar to ff_add_index_entry in libavformat/utils.c
4055  * except that here we are always unconditionally adding an index entry to
4056  * the end, instead of searching the entries list and skipping the add if
4057  * there is an existing entry with the same timestamp.
4058  * This is needed because the mov_fix_index calls this func with the same
4059  * unincremented timestamp for successive discarded frames.
4060  */
4062  int size, int distance, int flags)
4063 {
4064  FFStream *const sti = ffstream(st);
4065  AVIndexEntry *entries, *ie;
4066  int64_t index = -1;
4067  const size_t min_size_needed = (sti->nb_index_entries + 1) * sizeof(AVIndexEntry);
4068 
4069  // Double the allocation each time, to lower memory fragmentation.
4070  // Another difference from ff_add_index_entry function.
4071  const size_t requested_size =
4072  min_size_needed > sti->index_entries_allocated_size ?
4073  FFMAX(min_size_needed, 2 * sti->index_entries_allocated_size) :
4074  min_size_needed;
4075 
4076  if (sti->nb_index_entries + 1U >= UINT_MAX / sizeof(AVIndexEntry))
4077  return -1;
4078 
4079  entries = av_fast_realloc(sti->index_entries,
4081  requested_size);
4082  if (!entries)
4083  return -1;
4084 
4085  sti->index_entries = entries;
4086 
4087  index = sti->nb_index_entries++;
4088  ie= &entries[index];
4089 
4090  ie->pos = pos;
4091  ie->timestamp = timestamp;
4092  ie->min_distance= distance;
4093  ie->size= size;
4094  ie->flags = flags;
4095  return index;
4096 }
4097 
4098 /**
4099  * Rewrite timestamps of index entries in the range [end_index - frame_duration_buffer_size, end_index)
4100  * by subtracting end_ts successively by the amounts given in frame_duration_buffer.
4101  */
4102 static void fix_index_entry_timestamps(AVStream* st, int end_index, int64_t end_ts,
4103  int64_t* frame_duration_buffer,
4104  int frame_duration_buffer_size) {
4105  FFStream *const sti = ffstream(st);
4106  int i = 0;
4107  av_assert0(end_index >= 0 && end_index <= sti->nb_index_entries);
4108  for (i = 0; i < frame_duration_buffer_size; i++) {
4109  end_ts -= frame_duration_buffer[frame_duration_buffer_size - 1 - i];
4110  sti->index_entries[end_index - 1 - i].timestamp = end_ts;
4111  }
4112 }
4113 
4114 static int add_tts_entry(MOVTimeToSample **tts_data, unsigned int *tts_count, unsigned int *allocated_size,
4115  int count, int offset, unsigned int duration)
4116 {
4117  MOVTimeToSample *tts_buf_new;
4118  const size_t min_size_needed = (*tts_count + 1) * sizeof(MOVTimeToSample);
4119  const size_t requested_size =
4120  min_size_needed > *allocated_size ?
4121  FFMAX(min_size_needed, 2 * (*allocated_size)) :
4122  min_size_needed;
4123 
4124  if ((unsigned)(*tts_count) >= UINT_MAX / sizeof(MOVTimeToSample) - 1)
4125  return -1;
4126 
4127  tts_buf_new = av_fast_realloc(*tts_data, allocated_size, requested_size);
4128 
4129  if (!tts_buf_new)
4130  return -1;
4131 
4132  *tts_data = tts_buf_new;
4133 
4134  tts_buf_new[*tts_count].count = count;
4135  tts_buf_new[*tts_count].offset = offset;
4136  tts_buf_new[*tts_count].duration = duration;
4137 
4138  *tts_count = (*tts_count) + 1;
4139  return 0;
4140 }
4141 
4142 #define MAX_REORDER_DELAY 16
4144 {
4145  MOVStreamContext *msc = st->priv_data;
4146  FFStream *const sti = ffstream(st);
4147  int ctts_ind = 0;
4148  int ctts_sample = 0;
4149  int64_t pts_buf[MAX_REORDER_DELAY + 1]; // Circular buffer to sort pts.
4150  int buf_start = 0;
4151  int j, r, num_swaps;
4152 
4153  for (j = 0; j < MAX_REORDER_DELAY + 1; j++)
4154  pts_buf[j] = INT64_MIN;
4155 
4156  if (st->codecpar->video_delay <= 0 && msc->ctts_count &&
4158  st->codecpar->video_delay = 0;
4159  for (int ind = 0; ind < sti->nb_index_entries && ctts_ind < msc->tts_count; ++ind) {
4160  // Point j to the last elem of the buffer and insert the current pts there.
4161  j = buf_start;
4162  buf_start = (buf_start + 1);
4163  if (buf_start == MAX_REORDER_DELAY + 1)
4164  buf_start = 0;
4165 
4166  pts_buf[j] = sti->index_entries[ind].timestamp + msc->tts_data[ctts_ind].offset;
4167 
4168  // The timestamps that are already in the sorted buffer, and are greater than the
4169  // current pts, are exactly the timestamps that need to be buffered to output PTS
4170  // in correct sorted order.
4171  // Hence the video delay (which is the buffer size used to sort DTS and output PTS),
4172  // can be computed as the maximum no. of swaps any particular timestamp needs to
4173  // go through, to keep this buffer in sorted order.
4174  num_swaps = 0;
4175  while (j != buf_start) {
4176  r = j - 1;
4177  if (r < 0) r = MAX_REORDER_DELAY;
4178  if (pts_buf[j] < pts_buf[r]) {
4179  FFSWAP(int64_t, pts_buf[j], pts_buf[r]);
4180  ++num_swaps;
4181  } else {
4182  break;
4183  }
4184  j = r;
4185  }
4186  st->codecpar->video_delay = FFMAX(st->codecpar->video_delay, num_swaps);
4187 
4188  ctts_sample++;
4189  if (ctts_sample == msc->tts_data[ctts_ind].count) {
4190  ctts_ind++;
4191  ctts_sample = 0;
4192  }
4193  }
4194  av_log(c->fc, AV_LOG_DEBUG, "Setting codecpar->delay to %d for stream st: %d\n",
4195  st->codecpar->video_delay, st->index);
4196  }
4197 }
4198 
4200 {
4201  sc->current_sample++;
4202  sc->current_index++;
4203  if (sc->index_ranges &&
4204  sc->current_index >= sc->current_index_range->end &&
4205  sc->current_index_range->end) {
4206  sc->current_index_range++;
4208  }
4209 }
4210 
4212 {
4213  sc->current_sample--;
4214  sc->current_index--;
4215  if (sc->index_ranges &&
4217  sc->current_index_range > sc->index_ranges) {
4218  sc->current_index_range--;
4219  sc->current_index = sc->current_index_range->end - 1;
4220  }
4221 }
4222 
4223 static void mov_current_sample_set(MOVStreamContext *sc, int current_sample)
4224 {
4225  int64_t range_size;
4226 
4227  sc->current_sample = current_sample;
4228  sc->current_index = current_sample;
4229  if (!sc->index_ranges) {
4230  return;
4231  }
4232 
4233  for (sc->current_index_range = sc->index_ranges;
4234  sc->current_index_range->end;
4235  sc->current_index_range++) {
4236  range_size = sc->current_index_range->end - sc->current_index_range->start;
4237  if (range_size > current_sample) {
4238  sc->current_index = sc->current_index_range->start + current_sample;
4239  break;
4240  }
4241  current_sample -= range_size;
4242  }
4243 }
4244 
4245 /**
4246  * Fix ffstream(st)->index_entries, so that it contains only the entries (and the entries
4247  * which are needed to decode them) that fall in the edit list time ranges.
4248  * Also fixes the timestamps of the index entries to match the timeline
4249  * specified the edit lists.
4250  */
4251 static void mov_fix_index(MOVContext *mov, AVStream *st)
4252 {
4253  MOVStreamContext *msc = st->priv_data;
4254  FFStream *const sti = ffstream(st);
4255  AVIndexEntry *e_old = sti->index_entries;
4256  int nb_old = sti->nb_index_entries;
4257  const AVIndexEntry *e_old_end = e_old + nb_old;
4258  const AVIndexEntry *current = NULL;
4259  MOVTimeToSample *tts_data_old = msc->tts_data;
4260  int64_t tts_index_old = 0;
4261  int64_t tts_sample_old = 0;
4262  int64_t tts_count_old = msc->tts_count;
4263  int64_t edit_list_media_time = 0;
4264  int64_t edit_list_duration = 0;
4265  int64_t frame_duration = 0;
4266  int64_t edit_list_dts_counter = 0;
4267  int64_t edit_list_dts_entry_end = 0;
4268  int64_t edit_list_start_tts_sample = 0;
4269  int64_t curr_cts;
4270  int64_t curr_ctts = 0;
4271  int64_t empty_edits_sum_duration = 0;
4272  int64_t edit_list_index = 0;
4273  int64_t index;
4274  int flags;
4275  int64_t start_dts = 0;
4276  int64_t edit_list_start_encountered = 0;
4277  int64_t search_timestamp = 0;
4278  int64_t* frame_duration_buffer = NULL;
4279  int num_discarded_begin = 0;
4280  int first_non_zero_audio_edit = -1;
4281  int packet_skip_samples = 0;
4282  MOVIndexRange *current_index_range = NULL;
4283  int found_keyframe_after_edit = 0;
4284  int found_non_empty_edit = 0;
4285 
4286  if (!msc->elst_data || msc->elst_count <= 0 || nb_old <= 0) {
4287  return;
4288  }
4289 
4290  // allocate the index ranges array
4291  msc->index_ranges = av_malloc_array(msc->elst_count + 1,
4292  sizeof(msc->index_ranges[0]));
4293  if (!msc->index_ranges) {
4294  av_log(mov->fc, AV_LOG_ERROR, "Cannot allocate index ranges buffer\n");
4295  return;
4296  }
4297  msc->current_index_range = msc->index_ranges;
4298 
4299  // Clean AVStream from traces of old index
4300  sti->index_entries = NULL;
4302  sti->nb_index_entries = 0;
4303 
4304  // Clean time to sample fields of MOVStreamContext
4305  msc->tts_data = NULL;
4306  msc->tts_count = 0;
4307  msc->tts_index = 0;
4308  msc->tts_sample = 0;
4309  msc->tts_allocated_size = 0;
4310 
4311  // Reinitialize min_corrected_pts so that it can be computed again.
4312  msc->min_corrected_pts = -1;
4313 
4314  // If the dts_shift is positive (in case of negative ctts values in mov),
4315  // then negate the DTS by dts_shift
4316  if (msc->dts_shift > 0) {
4317  edit_list_dts_entry_end -= msc->dts_shift;
4318  av_log(mov->fc, AV_LOG_DEBUG, "Shifting DTS by %d because of negative CTTS.\n", msc->dts_shift);
4319  }
4320 
4321  start_dts = edit_list_dts_entry_end;
4322 
4323  while (get_edit_list_entry(mov, msc, edit_list_index, &edit_list_media_time,
4324  &edit_list_duration, mov->time_scale)) {
4325  av_log(mov->fc, AV_LOG_DEBUG, "Processing st: %d, edit list %"PRId64" - media time: %"PRId64", duration: %"PRId64"\n",
4326  st->index, edit_list_index, edit_list_media_time, edit_list_duration);
4327  edit_list_index++;
4328  edit_list_dts_counter = edit_list_dts_entry_end;
4329  edit_list_dts_entry_end += edit_list_duration;
4330  num_discarded_begin = 0;
4331  if (!found_non_empty_edit && edit_list_media_time == -1) {
4332  empty_edits_sum_duration += edit_list_duration;
4333  continue;
4334  }
4335  found_non_empty_edit = 1;
4336 
4337  // If we encounter a non-negative edit list reset the skip_samples/start_pad fields and set them
4338  // according to the edit list below.
4339  if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
4340  if (first_non_zero_audio_edit < 0) {
4341  first_non_zero_audio_edit = 1;
4342  } else {
4343  first_non_zero_audio_edit = 0;
4344  }
4345 
4346  if (first_non_zero_audio_edit > 0)
4347  sti->skip_samples = msc->start_pad = 0;
4348  }
4349 
4350  // While reordering frame index according to edit list we must handle properly
4351  // the scenario when edit list entry starts from none key frame.
4352  // We find closest previous key frame and preserve it and consequent frames in index.
4353  // All frames which are outside edit list entry time boundaries will be dropped after decoding.
4354  search_timestamp = edit_list_media_time;
4355  if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
4356  // Audio decoders like AAC need need a decoder delay samples previous to the current sample,
4357  // to correctly decode this frame. Hence for audio we seek to a frame 1 sec. before the
4358  // edit_list_media_time to cover the decoder delay.
4359  search_timestamp = FFMAX(search_timestamp - msc->time_scale, e_old[0].timestamp);
4360  }
4361 
4362  if (find_prev_closest_index(st, e_old, nb_old, tts_data_old, tts_count_old, search_timestamp, 0,
4363  &index, &tts_index_old, &tts_sample_old) < 0) {
4364  av_log(mov->fc, AV_LOG_WARNING,
4365  "st: %d edit list: %"PRId64" Missing key frame while searching for timestamp: %"PRId64"\n",
4366  st->index, edit_list_index, search_timestamp);
4367  if (find_prev_closest_index(st, e_old, nb_old, tts_data_old, tts_count_old, search_timestamp, AVSEEK_FLAG_ANY,
4368  &index, &tts_index_old, &tts_sample_old) < 0) {
4369  av_log(mov->fc, AV_LOG_WARNING,
4370  "st: %d edit list %"PRId64" Cannot find an index entry before timestamp: %"PRId64".\n",
4371  st->index, edit_list_index, search_timestamp);
4372  index = 0;
4373  tts_index_old = 0;
4374  tts_sample_old = 0;
4375  }
4376  }
4377  current = e_old + index;
4378  edit_list_start_tts_sample = tts_sample_old;
4379 
4380  // Iterate over index and arrange it according to edit list
4381  edit_list_start_encountered = 0;
4382  found_keyframe_after_edit = 0;
4383  for (; current < e_old_end; current++, index++) {
4384  // check if frame outside edit list mark it for discard
4385  frame_duration = (current + 1 < e_old_end) ?
4386  ((current + 1)->timestamp - current->timestamp) : edit_list_duration;
4387 
4388  flags = current->flags;
4389 
4390  // frames (pts) before or after edit list
4391  curr_cts = current->timestamp + msc->dts_shift;
4392  curr_ctts = 0;
4393 
4394  if (tts_data_old && tts_index_old < tts_count_old) {
4395  curr_ctts = tts_data_old[tts_index_old].offset;
4396  av_log(mov->fc, AV_LOG_TRACE, "stts: %"PRId64" ctts: %"PRId64", tts_index: %"PRId64", tts_count: %"PRId64"\n",
4397  curr_cts, curr_ctts, tts_index_old, tts_count_old);
4398  curr_cts += curr_ctts;
4399  tts_sample_old++;
4400  if (tts_sample_old == tts_data_old[tts_index_old].count) {
4401  if (add_tts_entry(&msc->tts_data, &msc->tts_count,
4402  &msc->tts_allocated_size,
4403  tts_data_old[tts_index_old].count - edit_list_start_tts_sample,
4404  tts_data_old[tts_index_old].offset, tts_data_old[tts_index_old].duration) == -1) {
4405  av_log(mov->fc, AV_LOG_ERROR, "Cannot add Time To Sample entry %"PRId64" - {%"PRId64", %d}\n",
4406  tts_index_old,
4407  tts_data_old[tts_index_old].count - edit_list_start_tts_sample,
4408  tts_data_old[tts_index_old].offset);
4409  break;
4410  }
4411  tts_index_old++;
4412  tts_sample_old = 0;
4413  edit_list_start_tts_sample = 0;
4414  }
4415  }
4416 
4417  if (curr_cts < edit_list_media_time || curr_cts >= (edit_list_duration + edit_list_media_time)) {
4419  curr_cts < edit_list_media_time && curr_cts + frame_duration > edit_list_media_time &&
4420  first_non_zero_audio_edit > 0) {
4421  packet_skip_samples = edit_list_media_time - curr_cts;
4422  sti->skip_samples += packet_skip_samples;
4423 
4424  // Shift the index entry timestamp by packet_skip_samples to be correct.
4425  edit_list_dts_counter -= packet_skip_samples;
4426  if (edit_list_start_encountered == 0) {
4427  edit_list_start_encountered = 1;
4428  // Make timestamps strictly monotonically increasing for audio, by rewriting timestamps for
4429  // discarded packets.
4430  if (frame_duration_buffer) {
4431  fix_index_entry_timestamps(st, sti->nb_index_entries, edit_list_dts_counter,
4432  frame_duration_buffer, num_discarded_begin);
4433  av_freep(&frame_duration_buffer);
4434  }
4435  }
4436 
4437  av_log(mov->fc, AV_LOG_DEBUG, "skip %d audio samples from curr_cts: %"PRId64"\n", packet_skip_samples, curr_cts);
4438  } else {
4440  av_log(mov->fc, AV_LOG_DEBUG, "drop a frame at curr_cts: %"PRId64" @ %"PRId64"\n", curr_cts, index);
4441 
4442  if (edit_list_start_encountered == 0) {
4443  num_discarded_begin++;
4444  frame_duration_buffer = av_realloc(frame_duration_buffer,
4445  num_discarded_begin * sizeof(int64_t));
4446  if (!frame_duration_buffer) {
4447  av_log(mov->fc, AV_LOG_ERROR, "Cannot reallocate frame duration buffer\n");
4448  break;
4449  }
4450  frame_duration_buffer[num_discarded_begin - 1] = frame_duration;
4451 
4452  // Increment skip_samples for the first non-zero audio edit list
4453  if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
4454  first_non_zero_audio_edit > 0 && st->codecpar->codec_id != AV_CODEC_ID_VORBIS) {
4455  sti->skip_samples += frame_duration;
4456  }
4457  }
4458  }
4459  } else {
4460  if (msc->min_corrected_pts < 0) {
4461  msc->min_corrected_pts = edit_list_dts_counter + curr_ctts + msc->dts_shift;
4462  } else {
4463  msc->min_corrected_pts = FFMIN(msc->min_corrected_pts, edit_list_dts_counter + curr_ctts + msc->dts_shift);
4464  }
4465  if (edit_list_start_encountered == 0) {
4466  edit_list_start_encountered = 1;
4467  // Make timestamps strictly monotonically increasing by rewriting timestamps for
4468  // discarded packets.
4469  if (frame_duration_buffer) {
4470  fix_index_entry_timestamps(st, sti->nb_index_entries, edit_list_dts_counter,
4471  frame_duration_buffer, num_discarded_begin);
4472  av_freep(&frame_duration_buffer);
4473  }
4474  }
4475  }
4476 
4477  if (add_index_entry(st, current->pos, edit_list_dts_counter, current->size,
4478  current->min_distance, flags) == -1) {
4479  av_log(mov->fc, AV_LOG_ERROR, "Cannot add index entry\n");
4480  break;
4481  }
4482 
4483  // Update the index ranges array
4484  if (!current_index_range || index != current_index_range->end) {
4485  current_index_range = current_index_range ? current_index_range + 1
4486  : msc->index_ranges;
4487  current_index_range->start = index;
4488  }
4489  current_index_range->end = index + 1;
4490 
4491  // Only start incrementing DTS in frame_duration amounts, when we encounter a frame in edit list.
4492  if (edit_list_start_encountered > 0) {
4493  edit_list_dts_counter = edit_list_dts_counter + frame_duration;
4494  }
4495 
4496  // Break when found first key frame after edit entry completion
4497  if ((curr_cts + frame_duration >= (edit_list_duration + edit_list_media_time)) &&
4499  if (msc->ctts_count) {
4500  // If we have CTTS and this is the first keyframe after edit elist,
4501  // wait for one more, because there might be trailing B-frames after this I-frame
4502  // that do belong to the edit.
4503  if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO && found_keyframe_after_edit == 0) {
4504  found_keyframe_after_edit = 1;
4505  continue;
4506  }
4507  if (tts_sample_old != 0) {
4508  if (add_tts_entry(&msc->tts_data, &msc->tts_count,
4509  &msc->tts_allocated_size,
4510  tts_sample_old - edit_list_start_tts_sample,
4511  tts_data_old[tts_index_old].offset, tts_data_old[tts_index_old].duration) == -1) {
4512  av_log(mov->fc, AV_LOG_ERROR, "Cannot add Time To Sample entry %"PRId64" - {%"PRId64", %d}\n",
4513  tts_index_old, tts_sample_old - edit_list_start_tts_sample,
4514  tts_data_old[tts_index_old].offset);
4515  break;
4516  }
4517  }
4518  }
4519  break;
4520  }
4521  }
4522  }
4523  // If there are empty edits, then msc->min_corrected_pts might be positive
4524  // intentionally. So we subtract the sum duration of empty edits here.
4525  msc->min_corrected_pts -= empty_edits_sum_duration;
4526 
4527  // If the minimum pts turns out to be greater than zero after fixing the index, then we subtract the
4528  // dts by that amount to make the first pts zero.
4529  if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
4530  if (msc->min_corrected_pts > 0) {
4531  av_log(mov->fc, AV_LOG_DEBUG, "Offset DTS by %"PRId64" to make first pts zero.\n", msc->min_corrected_pts);
4532  for (int i = 0; i < sti->nb_index_entries; ++i)
4534  }
4535  }
4536  // Start time should be equal to zero or the duration of any empty edits.
4537  st->start_time = empty_edits_sum_duration;
4538 
4539  // Update av stream length, if it ends up shorter than the track's media duration
4540  st->duration = FFMIN(st->duration, edit_list_dts_entry_end - start_dts);
4541  msc->start_pad = sti->skip_samples;
4542 
4543  // Free the old index and the old CTTS structures
4544  av_free(e_old);
4545  av_free(tts_data_old);
4546  av_freep(&frame_duration_buffer);
4547 
4548  // Null terminate the index ranges array
4549  current_index_range = current_index_range ? current_index_range + 1
4550  : msc->index_ranges;
4551  current_index_range->start = 0;
4552  current_index_range->end = 0;
4553  msc->current_index = msc->index_ranges[0].start;
4554 }
4555 
4556 static uint32_t get_sgpd_sync_index(const MOVStreamContext *sc, int nal_unit_type)
4557 {
4558  for (uint32_t i = 0; i < sc->sgpd_sync_count; i++)
4559  if (sc->sgpd_sync[i] == nal_unit_type)
4560  return i + 1;
4561  return 0;
4562 }
4563 
4565 {
4566  int k;
4567  int sample_id = 0;
4568  uint32_t cra_index;
4569  MOVStreamContext *sc = st->priv_data;
4570 
4571  if (st->codecpar->codec_id != AV_CODEC_ID_HEVC || !sc->sync_group_count)
4572  return 0;
4573 
4574  /* Build an unrolled index of the samples */
4575  sc->sample_offsets_count = 0;
4576  for (uint32_t i = 0; i < sc->ctts_count; i++) {
4577  if (sc->ctts_data[i].count > INT_MAX - sc->sample_offsets_count)
4578  return AVERROR(ENOMEM);
4579  sc->sample_offsets_count += sc->ctts_data[i].count;
4580  }
4581  av_freep(&sc->sample_offsets);
4583  if (!sc->sample_offsets)
4584  return AVERROR(ENOMEM);
4585  k = 0;
4586  for (uint32_t i = 0; i < sc->ctts_count; i++)
4587  for (int j = 0; j < sc->ctts_data[i].count; j++)
4588  sc->sample_offsets[k++] = sc->ctts_data[i].offset;
4589 
4590  /* The following HEVC NAL type reveal the use of open GOP sync points
4591  * (TODO: BLA types may also be concerned) */
4592  cra_index = get_sgpd_sync_index(sc, HEVC_NAL_CRA_NUT); /* Clean Random Access */
4593  if (!cra_index)
4594  return 0;
4595 
4596  /* Build a list of open-GOP key samples */
4597  sc->open_key_samples_count = 0;
4598  for (uint32_t i = 0; i < sc->sync_group_count; i++)
4599  if (sc->sync_group[i].index == cra_index) {
4600  if (sc->sync_group[i].count > INT_MAX - sc->open_key_samples_count)
4601  return AVERROR(ENOMEM);
4603  }
4604  av_freep(&sc->open_key_samples);
4606  if (!sc->open_key_samples)
4607  return AVERROR(ENOMEM);
4608  k = 0;
4609  for (uint32_t i = 0; i < sc->sync_group_count; i++) {
4610  const MOVSbgp *sg = &sc->sync_group[i];
4611  if (sg->index == cra_index)
4612  for (uint32_t j = 0; j < sg->count; j++)
4613  sc->open_key_samples[k++] = sample_id;
4614  if (sg->count > INT_MAX - sample_id)
4615  return AVERROR_PATCHWELCOME;
4616  sample_id += sg->count;
4617  }
4618 
4619  /* Identify the minimal time step between samples */
4620  sc->min_sample_duration = UINT_MAX;
4621  for (uint32_t i = 0; i < sc->stts_count; i++)
4623 
4624  return 0;
4625 }
4626 
4627 #define MOV_MERGE_CTTS 1
4628 #define MOV_MERGE_STTS 2
4629 /*
4630  * Merge stts and ctts arrays into a new combined array.
4631  * stts_count and ctts_count may be left untouched as they will be
4632  * used to check for the presence of either of them.
4633  */
4634 static int mov_merge_tts_data(MOVContext *mov, AVStream *st, int flags)
4635 {
4636  MOVStreamContext *sc = st->priv_data;
4637  int ctts = sc->ctts_data && (flags & MOV_MERGE_CTTS);
4638  int stts = sc->stts_data && (flags & MOV_MERGE_STTS);
4639  int idx = 0;
4640 
4641  if (!sc->ctts_data && !sc->stts_data)
4642  return 0;
4643  // Expand time to sample entries such that we have a 1-1 mapping with samples
4644  if (!sc->sample_count || sc->sample_count >= UINT_MAX / sizeof(*sc->tts_data))
4645  return -1;
4646 
4647  if (ctts) {
4649  sc->sample_count * sizeof(*sc->tts_data));
4650  if (!sc->tts_data)
4651  return -1;
4652 
4653  memset(sc->tts_data, 0, sc->tts_allocated_size);
4654 
4655  for (int i = 0; i < sc->ctts_count &&
4656  idx < sc->sample_count; i++)
4657  for (int j = 0; j < sc->ctts_data[i].count &&
4658  idx < sc->sample_count; j++) {
4659  sc->tts_data[idx].offset = sc->ctts_data[i].offset;
4660  sc->tts_data[idx++].count = 1;
4661  }
4662 
4663  sc->tts_count = idx;
4664  } else
4665  sc->ctts_count = 0;
4666  av_freep(&sc->ctts_data);
4667  sc->ctts_allocated_size = 0;
4668 
4669  idx = 0;
4670  if (stts) {
4672  sc->sample_count * sizeof(*sc->tts_data));
4673  if (!tts_data)
4674  return -1;
4675 
4676  if (!sc->tts_data)
4677  memset(tts_data, 0, sc->tts_allocated_size);
4678  sc->tts_data = tts_data;
4679 
4680  for (int i = 0; i < sc->stts_count &&
4681  idx < sc->sample_count; i++)
4682  for (int j = 0; j < sc->stts_data[i].count &&
4683  idx < sc->sample_count; j++) {
4684  sc->tts_data[idx].duration = sc->stts_data[i].duration;
4685  sc->tts_data[idx++].count = 1;
4686  }
4687 
4688  sc->tts_count = FFMAX(sc->tts_count, idx);
4689  } else
4690  sc->stts_count = 0;
4691  av_freep(&sc->stts_data);
4692  sc->stts_allocated_size = 0;
4693 
4694  return 0;
4695 }
4696 
4697 static void mov_build_index(MOVContext *mov, AVStream *st)
4698 {
4699  MOVStreamContext *sc = st->priv_data;
4700  FFStream *const sti = ffstream(st);
4701  int64_t current_offset;
4702  int64_t current_dts = 0;
4703  unsigned int stts_index = 0;
4704  unsigned int stsc_index = 0;
4705  unsigned int stss_index = 0;
4706  unsigned int stps_index = 0;
4707  unsigned int i, j;
4708  uint64_t stream_size = 0;
4709 
4710  int ret = build_open_gop_key_points(st);
4711  if (ret < 0)
4712  return;
4713 
4714  if (sc->elst_count) {
4715  int i, edit_start_index = 0, multiple_edits = 0;
4716  int64_t empty_duration = 0; // empty duration of the first edit list entry
4717  int64_t start_time = 0; // start time of the media
4718 
4719  for (i = 0; i < sc->elst_count; i++) {
4720  const MOVElst *e = &sc->elst_data[i];
4721  if (i == 0 && e->time == -1) {
4722  /* if empty, the first entry is the start time of the stream
4723  * relative to the presentation itself */
4724  empty_duration = e->duration;
4725  edit_start_index = 1;
4726  } else if (i == edit_start_index && e->time >= 0) {
4727  start_time = e->time;
4728  } else {
4729  multiple_edits = 1;
4730  }
4731  }
4732 
4733  if (multiple_edits && !mov->advanced_editlist) {
4735  av_log(mov->fc, AV_LOG_WARNING, "multiple edit list entries, "
4736  "not supported in fragmented MP4 files\n");
4737  else
4738  av_log(mov->fc, AV_LOG_WARNING, "multiple edit list entries, "
4739  "Use -advanced_editlist to correctly decode otherwise "
4740  "a/v desync might occur\n");
4741  }
4742 
4743  /* adjust first dts according to edit list */
4744  if ((empty_duration || start_time) && mov->time_scale > 0) {
4745  if (empty_duration)
4746  empty_duration = av_rescale(empty_duration, sc->time_scale, mov->time_scale);
4747 
4748  if (av_sat_sub64(start_time, empty_duration) != start_time - (uint64_t)empty_duration)
4749  av_log(mov->fc, AV_LOG_WARNING, "start_time - empty_duration is not representable\n");
4750 
4751  sc->time_offset = start_time - (uint64_t)empty_duration;
4753  if (!mov->advanced_editlist)
4754  current_dts = -sc->time_offset;
4755  }
4756 
4757  if (!multiple_edits && !mov->advanced_editlist &&
4759  sc->start_pad = start_time;
4760  }
4761 
4762  /* only use old uncompressed audio chunk demuxing when stts specifies it */
4763  if (!(st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
4764  sc->stts_count == 1 && sc->stts_data && sc->stts_data[0].duration == 1)) {
4765  unsigned int current_sample = 0;
4766  unsigned int stts_sample = 0;
4767  unsigned int sample_size;
4768  unsigned int distance = 0;
4769  unsigned int rap_group_index = 0;
4770  unsigned int rap_group_sample = 0;
4771  int rap_group_present = sc->rap_group_count && sc->rap_group;
4772  int key_off = (sc->keyframe_count && sc->keyframes[0] > 0) || (sc->stps_count && sc->stps_data[0] > 0);
4773 
4774  current_dts -= sc->dts_shift;
4775 
4776  if (!sc->sample_count || sti->nb_index_entries || sc->tts_count)
4777  return;
4778  if (sc->sample_count >= UINT_MAX / sizeof(*sti->index_entries) - sti->nb_index_entries)
4779  return;
4780  if (av_reallocp_array(&sti->index_entries,
4781  sti->nb_index_entries + sc->sample_count,
4782  sizeof(*sti->index_entries)) < 0) {
4783  sti->nb_index_entries = 0;
4784  return;
4785  }
4786  sti->index_entries_allocated_size = (sti->nb_index_entries + sc->sample_count) * sizeof(*sti->index_entries);
4787 
4789  if (ret < 0)
4790  return;
4791 
4792  for (i = 0; i < sc->chunk_count; i++) {
4793  int64_t next_offset = i+1 < sc->chunk_count ? sc->chunk_offsets[i+1] : INT64_MAX;
4794  current_offset = sc->chunk_offsets[i];
4795  while (mov_stsc_index_valid(stsc_index, sc->stsc_count) &&
4796  i + 1 == sc->stsc_data[stsc_index + 1].first)
4797  stsc_index++;
4798 
4799  if (next_offset > current_offset && sc->sample_size>0 && sc->sample_size < sc->stsz_sample_size &&
4800  sc->stsc_data[stsc_index].count * (int64_t)sc->stsz_sample_size > next_offset - current_offset) {
4801  av_log(mov->fc, AV_LOG_WARNING, "STSZ sample size %d invalid (too large), ignoring\n", sc->stsz_sample_size);
4802  sc->stsz_sample_size = sc->sample_size;
4803  }
4804  if (sc->stsz_sample_size>0 && sc->stsz_sample_size < sc->sample_size) {
4805  av_log(mov->fc, AV_LOG_WARNING, "STSZ sample size %d invalid (too small), ignoring\n", sc->stsz_sample_size);
4806  sc->stsz_sample_size = sc->sample_size;
4807  }
4808 
4809  for (j = 0; j < sc->stsc_data[stsc_index].count; j++) {
4810  int keyframe = 0;
4811  if (current_sample >= sc->sample_count) {
4812  av_log(mov->fc, AV_LOG_ERROR, "wrong sample count\n");
4813  return;
4814  }
4815 
4816  if (!sc->keyframe_absent && (!sc->keyframe_count || current_sample+key_off == sc->keyframes[stss_index])) {
4817  keyframe = 1;
4818  if (stss_index + 1 < sc->keyframe_count)
4819  stss_index++;
4820  } else if (sc->stps_count && current_sample+key_off == sc->stps_data[stps_index]) {
4821  keyframe = 1;
4822  if (stps_index + 1 < sc->stps_count)
4823  stps_index++;
4824  }
4825  if (rap_group_present && rap_group_index < sc->rap_group_count) {
4826  if (sc->rap_group[rap_group_index].index > 0)
4827  keyframe = 1;
4828  if (++rap_group_sample == sc->rap_group[rap_group_index].count) {
4829  rap_group_sample = 0;
4830  rap_group_index++;
4831  }
4832  }
4833  if (sc->keyframe_absent
4834  && !sc->stps_count
4835  && !rap_group_present
4836  && (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO || (i==0 && j==0)))
4837  keyframe = 1;
4838  if (keyframe)
4839  distance = 0;
4840  sample_size = sc->stsz_sample_size > 0 ? sc->stsz_sample_size : sc->sample_sizes[current_sample];
4841  if (current_offset > INT64_MAX - sample_size) {
4842  av_log(mov->fc, AV_LOG_ERROR, "Current offset %"PRId64" or sample size %u is too large\n",
4843  current_offset,
4844  sample_size);
4845  return;
4846  }
4847 
4848  if (sc->pseudo_stream_id == -1 ||
4849  sc->stsc_data[stsc_index].id - 1 == sc->pseudo_stream_id) {
4850  AVIndexEntry *e;
4851  if (sample_size > 0x3FFFFFFF) {
4852  av_log(mov->fc, AV_LOG_ERROR, "Sample size %u is too large\n", sample_size);
4853  return;
4854  }
4855  e = &sti->index_entries[sti->nb_index_entries++];
4856  e->pos = current_offset;
4857  e->timestamp = current_dts;
4858  e->size = sample_size;
4859  e->min_distance = distance;
4860  e->flags = keyframe ? AVINDEX_KEYFRAME : 0;
4861  av_log(mov->fc, AV_LOG_TRACE, "AVIndex stream %d, sample %u, offset %"PRIx64", dts %"PRId64", "
4862  "size %u, distance %u, keyframe %d\n", st->index, current_sample,
4863  current_offset, current_dts, sample_size, distance, keyframe);
4864  if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && sti->nb_index_entries < 100)
4865  ff_rfps_add_frame(mov->fc, st, current_dts);
4866  }
4867 
4868  current_offset += sample_size;
4869  stream_size += sample_size;
4870 
4871  current_dts += sc->tts_data[stts_index].duration;
4872 
4873  distance++;
4874  stts_sample++;
4875  current_sample++;
4876  if (stts_index + 1 < sc->tts_count && stts_sample == sc->tts_data[stts_index].count) {
4877  stts_sample = 0;
4878  stts_index++;
4879  }
4880  }
4881  }
4882  if (st->duration > 0)
4883  st->codecpar->bit_rate = stream_size*8*sc->time_scale/st->duration;
4884  } else {
4885  unsigned chunk_samples, total = 0;
4886 
4887  if (!sc->chunk_count || sc->tts_count)
4888  return;
4889 
4890  // compute total chunk count
4891  for (i = 0; i < sc->stsc_count; i++) {
4892  unsigned count, chunk_count;
4893 
4894  chunk_samples = sc->stsc_data[i].count;
4895  if (i != sc->stsc_count - 1 &&
4896  sc->samples_per_frame && chunk_samples % sc->samples_per_frame) {
4897  av_log(mov->fc, AV_LOG_ERROR, "error unaligned chunk\n");
4898  return;
4899  }
4900 
4901  if (sc->samples_per_frame >= 160) { // gsm
4902  count = chunk_samples / sc->samples_per_frame;
4903  } else if (sc->samples_per_frame > 1) {
4904  unsigned samples = (1024/sc->samples_per_frame)*sc->samples_per_frame;
4905  count = (chunk_samples+samples-1) / samples;
4906  } else {
4907  count = (chunk_samples+1023) / 1024;
4908  }
4909 
4910  if (mov_stsc_index_valid(i, sc->stsc_count))
4911  chunk_count = sc->stsc_data[i+1].first - sc->stsc_data[i].first;
4912  else
4913  chunk_count = sc->chunk_count - (sc->stsc_data[i].first - 1);
4914  total += chunk_count * count;
4915  }
4916 
4917  av_log(mov->fc, AV_LOG_TRACE, "chunk count %u\n", total);
4918  if (total >= UINT_MAX / sizeof(*sti->index_entries) - sti->nb_index_entries)
4919  return;
4920  if (av_reallocp_array(&sti->index_entries,
4921  sti->nb_index_entries + total,
4922  sizeof(*sti->index_entries)) < 0) {
4923  sti->nb_index_entries = 0;
4924  return;
4925  }
4926  sti->index_entries_allocated_size = (sti->nb_index_entries + total) * sizeof(*sti->index_entries);
4927 
4928  // populate index
4929  for (i = 0; i < sc->chunk_count; i++) {
4930  current_offset = sc->chunk_offsets[i];
4931  if (mov_stsc_index_valid(stsc_index, sc->stsc_count) &&
4932  i + 1 == sc->stsc_data[stsc_index + 1].first)
4933  stsc_index++;
4934  chunk_samples = sc->stsc_data[stsc_index].count;
4935 
4936  while (chunk_samples > 0) {
4937  AVIndexEntry *e;
4938  unsigned size, samples;
4939 
4940  if (sc->samples_per_frame > 1 && !sc->bytes_per_frame) {
4942  "Zero bytes per frame, but %d samples per frame",
4943  sc->samples_per_frame);
4944  return;
4945  }
4946 
4947  if (sc->samples_per_frame >= 160) { // gsm
4948  samples = sc->samples_per_frame;
4949  size = sc->bytes_per_frame;
4950  } else {
4951  if (sc->samples_per_frame > 1) {
4952  samples = FFMIN((1024 / sc->samples_per_frame)*
4953  sc->samples_per_frame, chunk_samples);
4955  } else {
4956  samples = FFMIN(1024, chunk_samples);
4957  size = samples * sc->sample_size;
4958  }
4959  }
4960 
4961  if (sti->nb_index_entries >= total) {
4962  av_log(mov->fc, AV_LOG_ERROR, "wrong chunk count %u\n", total);
4963  return;
4964  }
4965  if (size > 0x3FFFFFFF) {
4966  av_log(mov->fc, AV_LOG_ERROR, "Sample size %u is too large\n", size);
4967  return;
4968  }
4969  e = &sti->index_entries[sti->nb_index_entries++];
4970  e->pos = current_offset;
4971  e->timestamp = current_dts;
4972  e->size = size;
4973  e->min_distance = 0;
4974  e->flags = AVINDEX_KEYFRAME;
4975  av_log(mov->fc, AV_LOG_TRACE, "AVIndex stream %d, chunk %u, offset %"PRIx64", dts %"PRId64", "
4976  "size %u, duration %u\n", st->index, i, current_offset, current_dts,
4977  size, samples);
4978 
4979  current_offset += size;
4980  current_dts += samples;
4981  chunk_samples -= samples;
4982  }
4983  }
4984 
4986  if (ret < 0)
4987  return;
4988  }
4989 
4990  if (!mov->ignore_editlist && mov->advanced_editlist) {
4991  // Fix index according to edit lists.
4992  mov_fix_index(mov, st);
4993  }
4994 
4995  // Update start time of the stream.
4997  st->start_time = sti->index_entries[0].timestamp + sc->dts_shift;
4998  if (sc->tts_data) {
4999  st->start_time += sc->tts_data[0].offset;
5000  }
5001  }
5002 
5003  mov_estimate_video_delay(mov, st);
5004 }
5005 
5006 static int test_same_origin(const char *src, const char *ref) {
5007  char src_proto[64];
5008  char ref_proto[64];
5009  char src_auth[256];
5010  char ref_auth[256];
5011  char src_host[256];
5012  char ref_host[256];
5013  int src_port=-1;
5014  int ref_port=-1;
5015 
5016  av_url_split(src_proto, sizeof(src_proto), src_auth, sizeof(src_auth), src_host, sizeof(src_host), &src_port, NULL, 0, src);
5017  av_url_split(ref_proto, sizeof(ref_proto), ref_auth, sizeof(ref_auth), ref_host, sizeof(ref_host), &ref_port, NULL, 0, ref);
5018 
5019  if (strlen(src) == 0) {
5020  return -1;
5021  } else if (strlen(src_auth) + 1 >= sizeof(src_auth) ||
5022  strlen(ref_auth) + 1 >= sizeof(ref_auth) ||
5023  strlen(src_host) + 1 >= sizeof(src_host) ||
5024  strlen(ref_host) + 1 >= sizeof(ref_host)) {
5025  return 0;
5026  } else if (strcmp(src_proto, ref_proto) ||
5027  strcmp(src_auth, ref_auth) ||
5028  strcmp(src_host, ref_host) ||
5029  src_port != ref_port) {
5030  return 0;
5031  } else
5032  return 1;
5033 }
5034 
5035 static int mov_open_dref(MOVContext *c, AVIOContext **pb, const char *src, MOVDref *ref)
5036 {
5037  /* try relative path, we do not try the absolute because it can leak information about our
5038  system to an attacker */
5039  if (ref->nlvl_to > 0 && ref->nlvl_from > 0) {
5040  char filename[1025];
5041  const char *src_path;
5042  int i, l;
5043 
5044  /* find a source dir */
5045  src_path = strrchr(src, '/');
5046  if (src_path)
5047  src_path++;
5048  else
5049  src_path = src;
5050 
5051  /* find a next level down to target */
5052  for (i = 0, l = strlen(ref->path) - 1; l >= 0; l--)
5053  if (ref->path[l] == '/') {
5054  if (i == ref->nlvl_to - 1)
5055  break;
5056  else
5057  i++;
5058  }
5059 
5060  /* compose filename if next level down to target was found */
5061  if (i == ref->nlvl_to - 1 && src_path - src < sizeof(filename)) {
5062  memcpy(filename, src, src_path - src);
5063  filename[src_path - src] = 0;
5064 
5065  for (i = 1; i < ref->nlvl_from; i++)
5066  av_strlcat(filename, "../", sizeof(filename));
5067 
5068  av_strlcat(filename, ref->path + l + 1, sizeof(filename));
5069  if (!c->use_absolute_path) {
5070  int same_origin = test_same_origin(src, filename);
5071 
5072  if (!same_origin) {
5073  av_log(c->fc, AV_LOG_ERROR,
5074  "Reference with mismatching origin, %s not tried for security reasons, "
5075  "set demuxer option use_absolute_path to allow it anyway\n",
5076  ref->path);
5077  return AVERROR(ENOENT);
5078  }
5079 
5080  if (strstr(ref->path + l + 1, "..") ||
5081  strstr(ref->path + l + 1, ":") ||
5082  (ref->nlvl_from > 1 && same_origin < 0) ||
5083  (filename[0] == '/' && src_path == src))
5084  return AVERROR(ENOENT);
5085  }
5086 
5087  if (strlen(filename) + 1 == sizeof(filename))
5088  return AVERROR(ENOENT);
5089  if (!c->fc->io_open(c->fc, pb, filename, AVIO_FLAG_READ, NULL))
5090  return 0;
5091  }
5092  } else if (c->use_absolute_path) {
5093  av_log(c->fc, AV_LOG_WARNING, "Using absolute path on user request, "
5094  "this is a possible security issue\n");
5095  if (!c->fc->io_open(c->fc, pb, ref->path, AVIO_FLAG_READ, NULL))
5096  return 0;
5097  } else {
5098  av_log(c->fc, AV_LOG_ERROR,
5099  "Absolute path %s not tried for security reasons, "
5100  "set demuxer option use_absolute_path to allow absolute paths\n",
5101  ref->path);
5102  }
5103 
5104  return AVERROR(ENOENT);
5105 }
5106 
5108 {
5109  if (sc->time_scale <= 0) {
5110  av_log(c->fc, AV_LOG_WARNING, "stream %d, timescale not set\n", sc->ffindex);
5111  sc->time_scale = c->time_scale;
5112  if (sc->time_scale <= 0)
5113  sc->time_scale = 1;
5114  }
5115 }
5116 
5117 #if CONFIG_IAMFDEC
5118 static int mov_update_iamf_streams(MOVContext *c, const AVStream *st)
5119 {
5120  const MOVStreamContext *sc = st->priv_data;
5121  const IAMFContext *iamf = &sc->iamf->iamf;
5122 
5123  for (int i = 0; i < iamf->nb_audio_elements; i++) {
5124  const AVStreamGroup *stg = NULL;
5125 
5126  for (int j = 0; j < c->fc->nb_stream_groups; j++)
5127  if (c->fc->stream_groups[j]->id == iamf->audio_elements[i]->audio_element_id)
5128  stg = c->fc->stream_groups[j];
5129  av_assert0(stg);
5130 
5131  for (int j = 0; j < stg->nb_streams; j++) {
5132  const FFStream *sti = cffstream(st);
5133  AVStream *out = stg->streams[j];
5134  FFStream *out_sti = ffstream(stg->streams[j]);
5135 
5136  out->codecpar->bit_rate = 0;
5137 
5138  if (out == st)
5139  continue;
5140 
5141  out->time_base = st->time_base;
5142  out->start_time = st->start_time;
5143  out->duration = st->duration;
5144  out->nb_frames = st->nb_frames;
5145  out->discard = st->discard;
5146 
5147  av_assert0(!out_sti->index_entries);
5149  if (!out_sti->index_entries)
5150  return AVERROR(ENOMEM);
5151 
5153  out_sti->nb_index_entries = sti->nb_index_entries;
5154  out_sti->skip_samples = sti->skip_samples;
5155  memcpy(out_sti->index_entries, sti->index_entries, sti->index_entries_allocated_size);
5156  }
5157  }
5158 
5159  return 0;
5160 }
5161 #endif
5162 
5163 static int sanity_checks(void *log_obj, MOVStreamContext *sc, int index)
5164 {
5165  if ((sc->chunk_count && (!sc->stts_count || !sc->stsc_count ||
5166  (!sc->sample_size && !sc->sample_count))) ||
5167  (sc->sample_count && (!sc->chunk_count ||
5168  (!sc->sample_size && !sc->sample_sizes)))) {
5169  av_log(log_obj, AV_LOG_ERROR, "stream %d, missing mandatory atoms, broken header\n",
5170  index);
5171  return 1;
5172  }
5173 
5174  if (sc->stsc_count && sc->stsc_data[ sc->stsc_count - 1 ].first > sc->chunk_count) {
5175  av_log(log_obj, AV_LOG_ERROR, "stream %d, contradictionary STSC and STCO\n",
5176  index);
5177  return 2;
5178  }
5179  return 0;
5180 }
5181 
5183 {
5184  AVStream *st;
5185  MOVStreamContext *sc;
5186  int ret;
5187 
5188  st = avformat_new_stream(c->fc, NULL);
5189  if (!st) return AVERROR(ENOMEM);
5190  st->id = -1;
5191  sc = av_mallocz(sizeof(MOVStreamContext));
5192  if (!sc) return AVERROR(ENOMEM);
5193 
5194  st->priv_data = sc;
5196  sc->ffindex = st->index;
5197  c->trak_index = st->index;
5198  sc->tref_flags = 0;
5199  sc->tref_id = -1;
5200  sc->refcount = 1;
5201 
5202  if ((ret = mov_read_default(c, pb, atom)) < 0)
5203  return ret;
5204 
5205  c->trak_index = -1;
5206 
5207  // Here stsc refers to a chunk not described in stco. This is technically invalid,
5208  // but we can overlook it (clearing stsc) whenever stts_count == 0 (indicating no samples).
5209  if (!sc->chunk_count && !sc->stts_count && sc->stsc_count) {
5210  sc->stsc_count = 0;
5211  av_freep(&sc->stsc_data);
5212  }
5213 
5214  ret = sanity_checks(c->fc, sc, st->index);
5215  if (ret)
5216  return ret > 1 ? AVERROR_INVALIDDATA : 0;
5217 
5218  fix_timescale(c, sc);
5219 
5220  avpriv_set_pts_info(st, 64, 1, sc->time_scale);
5221 
5222  /*
5223  * Advanced edit list support does not work with fragemented MP4s, which
5224  * have stsc, stsz, stco, and stts with zero entries in the moov atom.
5225  * In these files, trun atoms may be streamed in.
5226  */
5227  if (!sc->stts_count && c->advanced_editlist) {
5228 
5229  av_log(c->fc, AV_LOG_VERBOSE, "advanced_editlist does not work with fragmented "
5230  "MP4. disabling.\n");
5231  c->advanced_editlist = 0;
5232  c->advanced_editlist_autodisabled = 1;
5233  }
5234 
5235  mov_build_index(c, st);
5236 
5237 #if CONFIG_IAMFDEC
5238  if (sc->iamf) {
5239  ret = mov_update_iamf_streams(c, st);
5240  if (ret < 0)
5241  return ret;
5242  }
5243 #endif
5244 
5245  if (sc->dref_id-1 < sc->drefs_count && sc->drefs[sc->dref_id-1].path) {
5246  MOVDref *dref = &sc->drefs[sc->dref_id - 1];
5247  if (c->enable_drefs) {
5248  if (mov_open_dref(c, &sc->pb, c->fc->url, dref) < 0)
5249  av_log(c->fc, AV_LOG_ERROR,
5250  "stream %d, error opening alias: path='%s', dir='%s', "
5251  "filename='%s', volume='%s', nlvl_from=%d, nlvl_to=%d\n",
5252  st->index, dref->path, dref->dir, dref->filename,
5253  dref->volume, dref->nlvl_from, dref->nlvl_to);
5254  } else {
5255  av_log(c->fc, AV_LOG_WARNING,
5256  "Skipped opening external track: "
5257  "stream %d, alias: path='%s', dir='%s', "
5258  "filename='%s', volume='%s', nlvl_from=%d, nlvl_to=%d."
5259  "Set enable_drefs to allow this.\n",
5260  st->index, dref->path, dref->dir, dref->filename,
5261  dref->volume, dref->nlvl_from, dref->nlvl_to);
5262  }
5263  } else {
5264  sc->pb = c->fc->pb;
5265  sc->pb_is_copied = 1;
5266  }
5267 
5268  if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
5269  int stts_constant = sc->stts_count && sc->tts_count;
5270  if (sc->h_spacing && sc->v_spacing)
5272  sc->h_spacing, sc->v_spacing, INT_MAX);
5273  if (!st->sample_aspect_ratio.num && st->codecpar->width && st->codecpar->height &&
5274  sc->height && sc->width &&
5275  (st->codecpar->width != sc->width || st->codecpar->height != sc->height)) {
5277  (int64_t)st->codecpar->height * sc->width,
5278  (int64_t)st->codecpar->width * sc->height, INT_MAX);
5279  }
5280 
5281 #if FF_API_R_FRAME_RATE
5282  for (unsigned int i = 1; sc->stts_count && i + 1 < sc->tts_count; i++) {
5283  if (sc->tts_data[i].duration == sc->tts_data[0].duration)
5284  continue;
5285  stts_constant = 0;
5286  }
5287  if (stts_constant)
5289  sc->time_scale, sc->tts_data[0].duration, INT_MAX);
5290 #endif
5291  }
5292 
5293 #if CONFIG_H261_DECODER || CONFIG_H263_DECODER || CONFIG_MPEG4_DECODER
5294  switch (st->codecpar->codec_id) {
5295 #if CONFIG_H261_DECODER
5296  case AV_CODEC_ID_H261:
5297 #endif
5298 #if CONFIG_H263_DECODER
5299  case AV_CODEC_ID_H263:
5300 #endif
5301 #if CONFIG_MPEG4_DECODER
5302  case AV_CODEC_ID_MPEG4:
5303 #endif
5304  st->codecpar->width = 0; /* let decoder init width/height */
5305  st->codecpar->height= 0;
5306  break;
5307  }
5308 #endif
5309 
5310  // If the duration of the mp3 packets is not constant, then they could need a parser
5311  if (st->codecpar->codec_id == AV_CODEC_ID_MP3
5312  && sc->time_scale == st->codecpar->sample_rate) {
5313  int stts_constant = 1;
5314  for (int i = 1; sc->stts_count && i < sc->tts_count; i++) {
5315  if (sc->tts_data[i].duration == sc->tts_data[0].duration)
5316  continue;
5317  stts_constant = 0;
5318  }
5319  if (!stts_constant)
5321  }
5322  /* Do not need those anymore. */
5323  av_freep(&sc->chunk_offsets);
5324  av_freep(&sc->sample_sizes);
5325  av_freep(&sc->keyframes);
5326  av_freep(&sc->stps_data);
5327  av_freep(&sc->elst_data);
5328  av_freep(&sc->rap_group);
5329  av_freep(&sc->sync_group);
5330  av_freep(&sc->sgpd_sync);
5331 
5332  return 0;
5333 }
5334 
5336 {
5337  int ret;
5338  c->itunes_metadata = 1;
5339  ret = mov_read_default(c, pb, atom);
5340  c->itunes_metadata = 0;
5341  return ret;
5342 }
5343 
5345 {
5346  uint32_t count;
5347  uint32_t i;
5348 
5349  if (atom.size < 8)
5350  return 0;
5351 
5352  avio_skip(pb, 4);
5353  count = avio_rb32(pb);
5354  atom.size -= 8;
5355  if (count >= UINT_MAX / sizeof(*c->meta_keys)) {
5356  av_log(c->fc, AV_LOG_ERROR,
5357  "The 'keys' atom with the invalid key count: %"PRIu32"\n", count);
5358  return AVERROR_INVALIDDATA;
5359  }
5360 
5361  c->meta_keys_count = count + 1;
5362  c->meta_keys = av_mallocz(c->meta_keys_count * sizeof(*c->meta_keys));
5363  if (!c->meta_keys)
5364  return AVERROR(ENOMEM);
5365 
5366  for (i = 1; i <= count; ++i) {
5367  uint32_t key_size = avio_rb32(pb);
5368  uint32_t type = avio_rl32(pb);
5369  if (key_size < 8 || key_size > atom.size) {
5370  av_log(c->fc, AV_LOG_ERROR,
5371  "The key# %"PRIu32" in meta has invalid size:"
5372  "%"PRIu32"\n", i, key_size);
5373  return AVERROR_INVALIDDATA;
5374  }
5375  atom.size -= key_size;
5376  key_size -= 8;
5377  if (type != MKTAG('m','d','t','a')) {
5378  avio_skip(pb, key_size);
5379  continue;
5380  }
5381  c->meta_keys[i] = av_mallocz(key_size + 1);
5382  if (!c->meta_keys[i])
5383  return AVERROR(ENOMEM);
5384  avio_read(pb, c->meta_keys[i], key_size);
5385  }
5386 
5387  return 0;
5388 }
5389 
5391 {
5392  int64_t end = av_sat_add64(avio_tell(pb), atom.size);
5393  uint8_t *key = NULL, *val = NULL, *mean = NULL;
5394  int i;
5395  int ret = 0;
5396  AVStream *st;
5397  MOVStreamContext *sc;
5398 
5399  if (c->fc->nb_streams < 1)
5400  return 0;
5401  st = c->fc->streams[c->fc->nb_streams-1];
5402  sc = st->priv_data;
5403 
5404  for (i = 0; i < 3; i++) {
5405  uint8_t **p;
5406  uint32_t len, tag;
5407 
5408  if (end - avio_tell(pb) <= 12)
5409  break;
5410 
5411  len = avio_rb32(pb);
5412  tag = avio_rl32(pb);
5413  avio_skip(pb, 4); // flags
5414 
5415  if (len < 12 || len - 12 > end - avio_tell(pb))
5416  break;
5417  len -= 12;
5418 
5419  if (tag == MKTAG('m', 'e', 'a', 'n'))
5420  p = &mean;
5421  else if (tag == MKTAG('n', 'a', 'm', 'e'))
5422  p = &key;
5423  else if (tag == MKTAG('d', 'a', 't', 'a') && len > 4) {
5424  avio_skip(pb, 4);
5425  len -= 4;
5426  p = &val;
5427  } else
5428  break;
5429 
5430  if (*p)
5431  break;
5432 
5433  *p = av_malloc(len + 1);
5434  if (!*p) {
5435  ret = AVERROR(ENOMEM);
5436  break;
5437  }
5438  ret = ffio_read_size(pb, *p, len);
5439  if (ret < 0) {
5440  av_freep(p);
5441  break;
5442  }
5443  (*p)[len] = 0;
5444  }
5445 
5446  if (mean && key && val) {
5447  if (strcmp(key, "iTunSMPB") == 0) {
5448  int priming, remainder, samples;
5449  if(sscanf(val, "%*X %X %X %X", &priming, &remainder, &samples) == 3){
5450  if(priming>0 && priming<16384)
5451  sc->start_pad = priming;
5452  }
5453  }
5454  if (strcmp(key, "cdec") != 0) {
5455  av_dict_set(&c->fc->metadata, key, val,
5457  key = val = NULL;
5458  }
5459  } else {
5460  av_log(c->fc, AV_LOG_VERBOSE,
5461  "Unhandled or malformed custom metadata of size %"PRId64"\n", atom.size);
5462  }
5463 
5464  avio_seek(pb, end, SEEK_SET);
5465  av_freep(&key);
5466  av_freep(&val);
5467  av_freep(&mean);
5468  return ret;
5469 }
5470 
5472 {
5473  MOVStreamContext *sc;
5474  AVStream *st;
5475 
5476  st = avformat_new_stream(c->fc, NULL);
5477  if (!st)
5478  return AVERROR(ENOMEM);
5479  sc = av_mallocz(sizeof(MOVStreamContext));
5480  if (!sc)
5481  goto fail;
5482 
5483  item->st = st;
5484  st->id = item->item_id;
5485  st->priv_data = sc;
5487  st->codecpar->codec_id = mov_codec_id(st, item->type);
5488  sc->id = st->id;
5489  sc->ffindex = st->index;
5490  st->avg_frame_rate.num = st->avg_frame_rate.den = 1;
5491  st->time_base.num = st->time_base.den = 1;
5492  st->nb_frames = 1;
5493  sc->time_scale = 1;
5494  sc->pb = c->fc->pb;
5495  sc->pb_is_copied = 1;
5496  sc->refcount = 1;
5497 
5498  if (item->name)
5499  av_dict_set(&st->metadata, "title", item->name, 0);
5500 
5501  // Populate the necessary fields used by mov_build_index.
5502  sc->stsc_data = av_malloc_array(1, sizeof(*sc->stsc_data));
5503  if (!sc->stsc_data)
5504  goto fail;
5505  sc->stsc_count = 1;
5506  sc->stsc_data[0].first = 1;
5507  sc->stsc_data[0].count = 1;
5508  sc->stsc_data[0].id = 1;
5509  sc->chunk_offsets = av_malloc_array(1, sizeof(*sc->chunk_offsets));
5510  if (!sc->chunk_offsets)
5511  goto fail;
5512  sc->chunk_count = 1;
5513  sc->stts_data = av_malloc_array(1, sizeof(*sc->stts_data));
5514  if (!sc->stts_data)
5515  goto fail;
5516  sc->stts_count = 1;
5517  sc->stts_data[0].count = 1;
5518  // Not used for still images. But needed by mov_build_index.
5519  sc->stts_data[0].duration = 0;
5520 
5521  return 0;
5522 fail:
5523  mov_free_stream_context(c->fc, st);
5524  ff_remove_stream(c->fc, st);
5525  item->st = NULL;
5526 
5527  return AVERROR(ENOMEM);
5528 }
5529 
5531 {
5532  while (atom.size > 8) {
5533  uint32_t tag;
5534  if (avio_feof(pb))
5535  return AVERROR_EOF;
5536  tag = avio_rl32(pb);
5537  atom.size -= 4;
5538  if (tag == MKTAG('h','d','l','r')) {
5539  avio_seek(pb, -8, SEEK_CUR);
5540  atom.size += 8;
5541  return mov_read_default(c, pb, atom);
5542  }
5543  }
5544  return 0;
5545 }
5546 
5547 // return 1 when matrix is identity, 0 otherwise
5548 #define IS_MATRIX_IDENT(matrix) \
5549  ( (matrix)[0][0] == (1 << 16) && \
5550  (matrix)[1][1] == (1 << 16) && \
5551  (matrix)[2][2] == (1 << 30) && \
5552  !(matrix)[0][1] && !(matrix)[0][2] && \
5553  !(matrix)[1][0] && !(matrix)[1][2] && \
5554  !(matrix)[2][0] && !(matrix)[2][1])
5555 
5557 {
5558  int i, j, e;
5559  int width;
5560  int height;
5561  int display_matrix[3][3];
5562  int res_display_matrix[3][3] = { { 0 } };
5563  AVStream *st;
5564  MOVStreamContext *sc;
5565  int version;
5566  int flags;
5567 
5568  if (c->fc->nb_streams < 1)
5569  return 0;
5570  st = c->fc->streams[c->fc->nb_streams-1];
5571  sc = st->priv_data;
5572 
5573  // Each stream (trak) should have exactly 1 tkhd. This catches bad files and
5574  // avoids corrupting AVStreams mapped to an earlier tkhd.
5575  if (st->id != -1)
5576  return AVERROR_INVALIDDATA;
5577 
5578  version = avio_r8(pb);
5579  flags = avio_rb24(pb);
5581 
5582  if (version == 1) {
5583  avio_rb64(pb);
5584  avio_rb64(pb);
5585  } else {
5586  avio_rb32(pb); /* creation time */
5587  avio_rb32(pb); /* modification time */
5588  }
5589  st->id = (int)avio_rb32(pb); /* track id (NOT 0 !)*/
5590  sc->id = st->id;
5591  avio_rb32(pb); /* reserved */
5592 
5593  /* highlevel (considering edits) duration in movie timebase */
5594  (version == 1) ? avio_rb64(pb) : avio_rb32(pb);
5595  avio_rb32(pb); /* reserved */
5596  avio_rb32(pb); /* reserved */
5597 
5598  avio_rb16(pb); /* layer */
5599  avio_rb16(pb); /* alternate group */
5600  avio_rb16(pb); /* volume */
5601  avio_rb16(pb); /* reserved */
5602 
5603  //read in the display matrix (outlined in ISO 14496-12, Section 6.2.2)
5604  // they're kept in fixed point format through all calculations
5605  // save u,v,z to store the whole matrix in the AV_PKT_DATA_DISPLAYMATRIX
5606  // side data, but the scale factor is not needed to calculate aspect ratio
5607  for (i = 0; i < 3; i++) {
5608  display_matrix[i][0] = avio_rb32(pb); // 16.16 fixed point
5609  display_matrix[i][1] = avio_rb32(pb); // 16.16 fixed point
5610  display_matrix[i][2] = avio_rb32(pb); // 2.30 fixed point
5611  }
5612 
5613  width = avio_rb32(pb); // 16.16 fixed point track width
5614  height = avio_rb32(pb); // 16.16 fixed point track height
5615  sc->width = width >> 16;
5616  sc->height = height >> 16;
5617 
5618  // apply the moov display matrix (after the tkhd one)
5619  for (i = 0; i < 3; i++) {
5620  const int sh[3] = { 16, 16, 30 };
5621  for (j = 0; j < 3; j++) {
5622  for (e = 0; e < 3; e++) {
5623  res_display_matrix[i][j] +=
5624  ((int64_t) display_matrix[i][e] *
5625  c->movie_display_matrix[e][j]) >> sh[e];
5626  }
5627  }
5628  }
5629 
5630  // save the matrix when it is not the default identity
5631  if (!IS_MATRIX_IDENT(res_display_matrix)) {
5632  av_freep(&sc->display_matrix);
5633  sc->display_matrix = av_malloc(sizeof(int32_t) * 9);
5634  if (!sc->display_matrix)
5635  return AVERROR(ENOMEM);
5636 
5637  for (i = 0; i < 3; i++)
5638  for (j = 0; j < 3; j++)
5639  sc->display_matrix[i * 3 + j] = res_display_matrix[i][j];
5640  }
5641 
5642  // transform the display width/height according to the matrix
5643  // to keep the same scale, use [width height 1<<16]
5644  if (width && height && sc->display_matrix) {
5645  double disp_transform[2];
5646 
5647  for (i = 0; i < 2; i++)
5648  disp_transform[i] = hypot(sc->display_matrix[0 + i],
5649  sc->display_matrix[3 + i]);
5650 
5651  if (disp_transform[0] > 1 && disp_transform[1] > 1 &&
5652  disp_transform[0] < (1<<24) && disp_transform[1] < (1<<24) &&
5653  fabs((disp_transform[0] / disp_transform[1]) - 1.0) > 0.01)
5655  disp_transform[0] / disp_transform[1],
5656  INT_MAX);
5657  }
5658  return 0;
5659 }
5660 
5662 {
5663  MOVFragment *frag = &c->fragment;
5664  MOVTrackExt *trex = NULL;
5665  int flags, track_id, i;
5666  MOVFragmentStreamInfo * frag_stream_info;
5667 
5668  avio_r8(pb); /* version */
5669  flags = avio_rb24(pb);
5670 
5671  track_id = avio_rb32(pb);
5672  if (!track_id)
5673  return AVERROR_INVALIDDATA;
5674  for (i = 0; i < c->trex_count; i++)
5675  if (c->trex_data[i].track_id == track_id) {
5676  trex = &c->trex_data[i];
5677  break;
5678  }
5679  if (!trex) {
5680  av_log(c->fc, AV_LOG_WARNING, "could not find corresponding trex (id %u)\n", track_id);
5681  return 0;
5682  }
5683  c->fragment.found_tfhd = 1;
5684  frag->track_id = track_id;
5685  set_frag_stream(&c->frag_index, track_id);
5686 
5689  frag->moof_offset : frag->implicit_offset;
5690  frag->stsd_id = flags & MOV_TFHD_STSD_ID ? avio_rb32(pb) : trex->stsd_id;
5691 
5693  avio_rb32(pb) : trex->duration;
5694  frag->size = flags & MOV_TFHD_DEFAULT_SIZE ?
5695  avio_rb32(pb) : trex->size;
5696  frag->flags = flags & MOV_TFHD_DEFAULT_FLAGS ?
5697  avio_rb32(pb) : trex->flags;
5698  av_log(c->fc, AV_LOG_TRACE, "frag flags 0x%x\n", frag->flags);
5699 
5700  frag_stream_info = get_current_frag_stream_info(&c->frag_index);
5701  if (frag_stream_info) {
5702  frag_stream_info->next_trun_dts = AV_NOPTS_VALUE;
5703  frag_stream_info->stsd_id = frag->stsd_id;
5704  }
5705  return 0;
5706 }
5707 
5709 {
5710  unsigned i, num;
5711  void *new_tracks;
5712 
5713  num = atom.size / 4;
5714  if (!(new_tracks = av_malloc_array(num, sizeof(int))))
5715  return AVERROR(ENOMEM);
5716 
5717  av_free(c->chapter_tracks);
5718  c->chapter_tracks = new_tracks;
5719  c->nb_chapter_tracks = num;
5720 
5721  for (i = 0; i < num && !pb->eof_reached; i++)
5722  c->chapter_tracks[i] = avio_rb32(pb);
5723 
5724  c->nb_chapter_tracks = i;
5725 
5726  return 0;
5727 }
5728 
5730 {
5731  MOVTrackExt *trex;
5732  int err;
5733 
5734  if ((uint64_t)c->trex_count+1 >= UINT_MAX / sizeof(*c->trex_data))
5735  return AVERROR_INVALIDDATA;
5736  if ((err = av_reallocp_array(&c->trex_data, c->trex_count + 1,
5737  sizeof(*c->trex_data))) < 0) {
5738  c->trex_count = 0;
5739  return err;
5740  }
5741 
5742  c->fc->duration = AV_NOPTS_VALUE; // the duration from mvhd is not representing the whole file when fragments are used.
5743 
5744  trex = &c->trex_data[c->trex_count++];
5745  avio_r8(pb); /* version */
5746  avio_rb24(pb); /* flags */
5747  trex->track_id = avio_rb32(pb);
5748  trex->stsd_id = avio_rb32(pb);
5749  trex->duration = avio_rb32(pb);
5750  trex->size = avio_rb32(pb);
5751  trex->flags = avio_rb32(pb);
5752  return 0;
5753 }
5754 
5756 {
5757  MOVFragment *frag = &c->fragment;
5758  AVStream *st = NULL;
5759  MOVStreamContext *sc;
5760  int version, i;
5761  MOVFragmentStreamInfo * frag_stream_info;
5762  int64_t base_media_decode_time;
5763 
5764  for (i = 0; i < c->fc->nb_streams; i++) {
5765  sc = c->fc->streams[i]->priv_data;
5766  if (sc->id == frag->track_id) {
5767  st = c->fc->streams[i];
5768  break;
5769  }
5770  }
5771  if (!st) {
5772  av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %u\n", frag->track_id);
5773  return 0;
5774  }
5775  sc = st->priv_data;
5776  if (sc->pseudo_stream_id + 1 != frag->stsd_id && sc->pseudo_stream_id != -1)
5777  return 0;
5778  version = avio_r8(pb);
5779  avio_rb24(pb); /* flags */
5780  if (version) {
5781  base_media_decode_time = avio_rb64(pb);
5782  } else {
5783  base_media_decode_time = avio_rb32(pb);
5784  }
5785 
5786  frag_stream_info = get_current_frag_stream_info(&c->frag_index);
5787  if (frag_stream_info)
5788  frag_stream_info->tfdt_dts = base_media_decode_time;
5789  sc->track_end = base_media_decode_time;
5790 
5791  return 0;
5792 }
5793 
5795 {
5796  MOVFragment *frag = &c->fragment;
5797  AVStream *st = NULL;
5798  FFStream *sti = NULL;
5799  MOVStreamContext *sc;
5800  MOVTimeToSample *tts_data;
5801  uint64_t offset;
5802  int64_t dts, pts = AV_NOPTS_VALUE;
5803  int data_offset = 0;
5804  unsigned entries, first_sample_flags = frag->flags;
5805  int flags, distance, i;
5806  int64_t prev_dts = AV_NOPTS_VALUE;
5807  int next_frag_index = -1, index_entry_pos;
5808  size_t requested_size;
5809  size_t old_allocated_size;
5810  AVIndexEntry *new_entries;
5811  MOVFragmentStreamInfo * frag_stream_info;
5812 
5813  if (!frag->found_tfhd) {
5814  av_log(c->fc, AV_LOG_ERROR, "trun track id unknown, no tfhd was found\n");
5815  return AVERROR_INVALIDDATA;
5816  }
5817 
5818  for (i = 0; i < c->fc->nb_streams; i++) {
5819  sc = c->fc->streams[i]->priv_data;
5820  if (sc->id == frag->track_id) {
5821  st = c->fc->streams[i];
5822  sti = ffstream(st);
5823  break;
5824  }
5825  }
5826  if (!st) {
5827  av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %u\n", frag->track_id);
5828  return 0;
5829  }
5830  sc = st->priv_data;
5831  if (sc->pseudo_stream_id+1 != frag->stsd_id && sc->pseudo_stream_id != -1)
5832  return 0;
5833 
5834  // Find the next frag_index index that has a valid index_entry for
5835  // the current track_id.
5836  //
5837  // A valid index_entry means the trun for the fragment was read
5838  // and it's samples are in index_entries at the given position.
5839  // New index entries will be inserted before the index_entry found.
5840  index_entry_pos = sti->nb_index_entries;
5841  for (i = c->frag_index.current + 1; i < c->frag_index.nb_items; i++) {
5842  frag_stream_info = get_frag_stream_info(&c->frag_index, i, frag->track_id);
5843  if (frag_stream_info && frag_stream_info->index_entry >= 0) {
5844  next_frag_index = i;
5845  index_entry_pos = frag_stream_info->index_entry;
5846  break;
5847  }
5848  }
5849  av_assert0(index_entry_pos <= sti->nb_index_entries);
5850 
5851  avio_r8(pb); /* version */
5852  flags = avio_rb24(pb);
5853  entries = avio_rb32(pb);
5854  av_log(c->fc, AV_LOG_TRACE, "flags 0x%x entries %u\n", flags, entries);
5855 
5856  if ((uint64_t)entries+sc->tts_count >= UINT_MAX/sizeof(*sc->tts_data))
5857  return AVERROR_INVALIDDATA;
5858  if (flags & MOV_TRUN_DATA_OFFSET) data_offset = avio_rb32(pb);
5859  if (flags & MOV_TRUN_FIRST_SAMPLE_FLAGS) first_sample_flags = avio_rb32(pb);
5860 
5861  frag_stream_info = get_current_frag_stream_info(&c->frag_index);
5862  if (frag_stream_info) {
5863  if (frag_stream_info->next_trun_dts != AV_NOPTS_VALUE) {
5864  dts = frag_stream_info->next_trun_dts - sc->time_offset;
5865  } else if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE &&
5866  c->use_mfra_for == FF_MOV_FLAG_MFRA_PTS) {
5867  pts = frag_stream_info->first_tfra_pts;
5868  av_log(c->fc, AV_LOG_DEBUG, "found mfra time %"PRId64
5869  ", using it for pts\n", pts);
5870  } else if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE &&
5871  c->use_mfra_for == FF_MOV_FLAG_MFRA_DTS) {
5872  dts = frag_stream_info->first_tfra_pts;
5873  av_log(c->fc, AV_LOG_DEBUG, "found mfra time %"PRId64
5874  ", using it for dts\n", pts);
5875  } else {
5876  int has_tfdt = frag_stream_info->tfdt_dts != AV_NOPTS_VALUE;
5877  int has_sidx = frag_stream_info->sidx_pts != AV_NOPTS_VALUE;
5878  int fallback_tfdt = !c->use_tfdt && !has_sidx && has_tfdt;
5879  int fallback_sidx = c->use_tfdt && !has_tfdt && has_sidx;
5880 
5881  if (fallback_sidx) {
5882  av_log(c->fc, AV_LOG_DEBUG, "use_tfdt set but no tfdt found, using sidx instead\n");
5883  }
5884  if (fallback_tfdt) {
5885  av_log(c->fc, AV_LOG_DEBUG, "use_tfdt not set but no sidx found, using tfdt instead\n");
5886  }
5887 
5888  if (has_tfdt && c->use_tfdt || fallback_tfdt) {
5889  dts = frag_stream_info->tfdt_dts - sc->time_offset;
5890  av_log(c->fc, AV_LOG_DEBUG, "found tfdt time %"PRId64
5891  ", using it for dts\n", dts);
5892  } else if (has_sidx && !c->use_tfdt || fallback_sidx) {
5893  // FIXME: sidx earliest_presentation_time is *PTS*, s.b.
5894  // pts = frag_stream_info->sidx_pts;
5895  dts = frag_stream_info->sidx_pts;
5896  av_log(c->fc, AV_LOG_DEBUG, "found sidx time %"PRId64
5897  ", using it for dts\n", frag_stream_info->sidx_pts);
5898  } else {
5899  dts = sc->track_end - sc->time_offset;
5900  av_log(c->fc, AV_LOG_DEBUG, "found track end time %"PRId64
5901  ", using it for dts\n", dts);
5902  }
5903  }
5904  } else {
5905  dts = sc->track_end - sc->time_offset;
5906  av_log(c->fc, AV_LOG_DEBUG, "found track end time %"PRId64
5907  ", using it for dts\n", dts);
5908  }
5909  offset = frag->base_data_offset + data_offset;
5910  distance = 0;
5911  av_log(c->fc, AV_LOG_TRACE, "first sample flags 0x%x\n", first_sample_flags);
5912 
5913  // realloc space for new index entries
5914  if ((uint64_t)sti->nb_index_entries + entries >= UINT_MAX / sizeof(AVIndexEntry)) {
5915  entries = UINT_MAX / sizeof(AVIndexEntry) - sti->nb_index_entries;
5916  av_log(c->fc, AV_LOG_ERROR, "Failed to add index entry\n");
5917  }
5918  if (entries == 0)
5919  return 0;
5920 
5921  requested_size = (sti->nb_index_entries + entries) * sizeof(AVIndexEntry);
5922  new_entries = av_fast_realloc(sti->index_entries,
5924  requested_size);
5925  if (!new_entries)
5926  return AVERROR(ENOMEM);
5927  sti->index_entries= new_entries;
5928 
5929  requested_size = (sti->nb_index_entries + entries) * sizeof(*sc->tts_data);
5930  old_allocated_size = sc->tts_allocated_size;
5931  tts_data = av_fast_realloc(sc->tts_data, &sc->tts_allocated_size,
5932  requested_size);
5933  if (!tts_data)
5934  return AVERROR(ENOMEM);
5935  sc->tts_data = tts_data;
5936 
5937  // In case there were samples without time to sample entries, ensure they get
5938  // zero valued entries. This ensures clips which mix boxes with and
5939  // without time to sample entries don't pickup uninitialized data.
5940  memset((uint8_t*)(sc->tts_data) + old_allocated_size, 0,
5941  sc->tts_allocated_size - old_allocated_size);
5942 
5943  if (index_entry_pos < sti->nb_index_entries) {
5944  // Make hole in index_entries and tts_data for new samples
5945  memmove(sti->index_entries + index_entry_pos + entries,
5946  sti->index_entries + index_entry_pos,
5947  sizeof(*sti->index_entries) *
5948  (sti->nb_index_entries - index_entry_pos));
5949  memmove(sc->tts_data + index_entry_pos + entries,
5950  sc->tts_data + index_entry_pos,
5951  sizeof(*sc->tts_data) * (sc->tts_count - index_entry_pos));
5952  if (index_entry_pos < sc->current_sample) {
5953  sc->current_sample += entries;
5954  }
5955  }
5956 
5957  sti->nb_index_entries += entries;
5958  sc->tts_count = sti->nb_index_entries;
5959  sc->stts_count = sti->nb_index_entries;
5960  if (flags & MOV_TRUN_SAMPLE_CTS)
5961  sc->ctts_count = sti->nb_index_entries;
5962 
5963  // Record the index_entry position in frag_index of this fragment
5964  if (frag_stream_info) {
5965  frag_stream_info->index_entry = index_entry_pos;
5966  if (frag_stream_info->index_base < 0)
5967  frag_stream_info->index_base = index_entry_pos;
5968  }
5969 
5970  if (index_entry_pos > 0)
5971  prev_dts = sti->index_entries[index_entry_pos-1].timestamp;
5972 
5973  for (i = 0; i < entries && !pb->eof_reached; i++) {
5974  unsigned sample_size = frag->size;
5975  int sample_flags = i ? frag->flags : first_sample_flags;
5976  unsigned sample_duration = frag->duration;
5977  unsigned ctts_duration = 0;
5978  int keyframe = 0;
5979  int index_entry_flags = 0;
5980 
5981  if (flags & MOV_TRUN_SAMPLE_DURATION) sample_duration = avio_rb32(pb);
5982  if (flags & MOV_TRUN_SAMPLE_SIZE) sample_size = avio_rb32(pb);
5983  if (flags & MOV_TRUN_SAMPLE_FLAGS) sample_flags = avio_rb32(pb);
5984  if (flags & MOV_TRUN_SAMPLE_CTS) ctts_duration = avio_rb32(pb);
5985 
5986  mov_update_dts_shift(sc, ctts_duration, c->fc);
5987  if (pts != AV_NOPTS_VALUE) {
5988  dts = pts - sc->dts_shift;
5989  if (flags & MOV_TRUN_SAMPLE_CTS) {
5990  dts -= ctts_duration;
5991  } else {
5992  dts -= sc->time_offset;
5993  }
5994  av_log(c->fc, AV_LOG_DEBUG,
5995  "pts %"PRId64" calculated dts %"PRId64
5996  " sc->dts_shift %d ctts.duration %d"
5997  " sc->time_offset %"PRId64
5998  " flags & MOV_TRUN_SAMPLE_CTS %d\n",
5999  pts, dts,
6000  sc->dts_shift, ctts_duration,
6002  pts = AV_NOPTS_VALUE;
6003  }
6004 
6005  keyframe =
6006  !(sample_flags & (MOV_FRAG_SAMPLE_FLAG_IS_NON_SYNC |
6008  if (keyframe) {
6009  distance = 0;
6010  index_entry_flags |= AVINDEX_KEYFRAME;
6011  }
6012  // Fragments can overlap in time. Discard overlapping frames after
6013  // decoding.
6014  if (prev_dts >= dts)
6015  index_entry_flags |= AVINDEX_DISCARD_FRAME;
6016 
6017  sti->index_entries[index_entry_pos].pos = offset;
6018  sti->index_entries[index_entry_pos].timestamp = dts;
6019  sti->index_entries[index_entry_pos].size = sample_size;
6020  sti->index_entries[index_entry_pos].min_distance = distance;
6021  sti->index_entries[index_entry_pos].flags = index_entry_flags;
6022 
6023  sc->tts_data[index_entry_pos].count = 1;
6024  sc->tts_data[index_entry_pos].offset = ctts_duration;
6025  sc->tts_data[index_entry_pos].duration = sample_duration;
6026  index_entry_pos++;
6027 
6028  av_log(c->fc, AV_LOG_TRACE, "AVIndex stream %d, sample %d, offset %"PRIx64", dts %"PRId64", "
6029  "size %u, distance %d, keyframe %d\n", st->index,
6030  index_entry_pos, offset, dts, sample_size, distance, keyframe);
6031  distance++;
6032  if (av_sat_add64(dts, sample_duration) != dts + (uint64_t)sample_duration)
6033  return AVERROR_INVALIDDATA;
6034  if (!sample_size)
6035  return AVERROR_INVALIDDATA;
6036  dts += sample_duration;
6037  offset += sample_size;
6038  sc->data_size += sample_size;
6039 
6040  if (sample_duration <= INT64_MAX - sc->duration_for_fps &&
6041  1 <= INT_MAX - sc->nb_frames_for_fps
6042  ) {
6043  sc->duration_for_fps += sample_duration;
6044  sc->nb_frames_for_fps ++;
6045  }
6046  }
6047  if (frag_stream_info)
6048  frag_stream_info->next_trun_dts = dts + sc->time_offset;
6049  if (i < entries) {
6050  // EOF found before reading all entries. Fix the hole this would
6051  // leave in index_entries and tts_data
6052  int gap = entries - i;
6053  memmove(sti->index_entries + index_entry_pos,
6054  sti->index_entries + index_entry_pos + gap,
6055  sizeof(*sti->index_entries) *
6056  (sti->nb_index_entries - (index_entry_pos + gap)));
6057  memmove(sc->tts_data + index_entry_pos,
6058  sc->tts_data + index_entry_pos + gap,
6059  sizeof(*sc->tts_data) *
6060  (sc->tts_count - (index_entry_pos + gap)));
6061 
6062  sti->nb_index_entries -= gap;
6063  sc->tts_count -= gap;
6064  if (index_entry_pos < sc->current_sample) {
6065  sc->current_sample -= gap;
6066  }
6067  entries = i;
6068  }
6069 
6070  // The end of this new fragment may overlap in time with the start
6071  // of the next fragment in index_entries. Mark the samples in the next
6072  // fragment that overlap with AVINDEX_DISCARD_FRAME
6073  prev_dts = AV_NOPTS_VALUE;
6074  if (index_entry_pos > 0)
6075  prev_dts = sti->index_entries[index_entry_pos-1].timestamp;
6076  for (int i = index_entry_pos; i < sti->nb_index_entries; i++) {
6077  if (prev_dts < sti->index_entries[i].timestamp)
6078  break;
6080  }
6081 
6082  // If a hole was created to insert the new index_entries into,
6083  // the index_entry recorded for all subsequent moof must
6084  // be incremented by the number of entries inserted.
6085  fix_frag_index_entries(&c->frag_index, next_frag_index,
6086  frag->track_id, entries);
6087 
6088  if (pb->eof_reached) {
6089  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted TRUN atom\n");
6090  return AVERROR_EOF;
6091  }
6092 
6093  frag->implicit_offset = offset;
6094 
6095  sc->track_end = dts + sc->time_offset;
6096  if (st->duration < sc->track_end)
6097  st->duration = sc->track_end;
6098 
6099  return 0;
6100 }
6101 
6103 {
6104  int64_t stream_size = avio_size(pb);
6105  int64_t offset = av_sat_add64(avio_tell(pb), atom.size), pts, timestamp;
6106  uint8_t version, is_complete;
6107  int64_t offadd;
6108  unsigned i, j, track_id, item_count;
6109  AVStream *st = NULL;
6110  AVStream *ref_st = NULL;
6111  MOVStreamContext *sc, *ref_sc = NULL;
6112  AVRational timescale;
6113 
6114  version = avio_r8(pb);
6115  if (version > 1) {
6116  avpriv_request_sample(c->fc, "sidx version %u", version);
6117  return 0;
6118  }
6119 
6120  avio_rb24(pb); // flags
6121 
6122  track_id = avio_rb32(pb); // Reference ID
6123  for (i = 0; i < c->fc->nb_streams; i++) {
6124  sc = c->fc->streams[i]->priv_data;
6125  if (sc->id == track_id) {
6126  st = c->fc->streams[i];
6127  break;
6128  }
6129  }
6130  if (!st) {
6131  av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %d\n", track_id);
6132  return 0;
6133  }
6134 
6135  sc = st->priv_data;
6136 
6137  timescale = av_make_q(1, avio_rb32(pb));
6138 
6139  if (timescale.den <= 0) {
6140  av_log(c->fc, AV_LOG_ERROR, "Invalid sidx timescale 1/%d\n", timescale.den);
6141  return AVERROR_INVALIDDATA;
6142  }
6143 
6144  if (version == 0) {
6145  pts = avio_rb32(pb);
6146  offadd= avio_rb32(pb);
6147  } else {
6148  pts = avio_rb64(pb);
6149  offadd= avio_rb64(pb);
6150  }
6151  if (av_sat_add64(offset, offadd) != offset + (uint64_t)offadd)
6152  return AVERROR_INVALIDDATA;
6153 
6154  offset += (uint64_t)offadd;
6155 
6156  avio_rb16(pb); // reserved
6157 
6158  item_count = avio_rb16(pb);
6159  if (item_count == 0)
6160  return AVERROR_INVALIDDATA;
6161 
6162  for (i = 0; i < item_count; i++) {
6163  int index;
6164  MOVFragmentStreamInfo * frag_stream_info;
6165  uint32_t size = avio_rb32(pb);
6166  uint32_t duration = avio_rb32(pb);
6167  if (size & 0x80000000) {
6168  avpriv_request_sample(c->fc, "sidx reference_type 1");
6169  return AVERROR_PATCHWELCOME;
6170  }
6171  avio_rb32(pb); // sap_flags
6172  timestamp = av_rescale_q(pts, timescale, st->time_base);
6173 
6175  frag_stream_info = get_frag_stream_info(&c->frag_index, index, track_id);
6176  if (frag_stream_info)
6177  frag_stream_info->sidx_pts = timestamp;
6178 
6179  if (av_sat_add64(offset, size) != offset + (uint64_t)size ||
6180  av_sat_add64(pts, duration) != pts + (uint64_t)duration
6181  )
6182  return AVERROR_INVALIDDATA;
6183  offset += size;
6184  pts += duration;
6185  }
6186 
6187  st->duration = sc->track_end = pts;
6188 
6189  sc->has_sidx = 1;
6190 
6191  // See if the remaining bytes are just an mfra which we can ignore.
6192  is_complete = offset == stream_size;
6193  if (!is_complete && (pb->seekable & AVIO_SEEKABLE_NORMAL) && stream_size > 0 ) {
6194  int64_t ret;
6195  int64_t original_pos = avio_tell(pb);
6196  if (!c->have_read_mfra_size) {
6197  if ((ret = avio_seek(pb, stream_size - 4, SEEK_SET)) < 0)
6198  return ret;
6199  c->mfra_size = avio_rb32(pb);
6200  c->have_read_mfra_size = 1;
6201  if ((ret = avio_seek(pb, original_pos, SEEK_SET)) < 0)
6202  return ret;
6203  }
6204  if (offset == stream_size - c->mfra_size)
6205  is_complete = 1;
6206  }
6207 
6208  if (is_complete) {
6209  // Find first entry in fragment index that came from an sidx.
6210  // This will pretty much always be the first entry.
6211  for (i = 0; i < c->frag_index.nb_items; i++) {
6212  MOVFragmentIndexItem * item = &c->frag_index.item[i];
6213  for (j = 0; ref_st == NULL && j < item->nb_stream_info; j++) {
6214  MOVFragmentStreamInfo * si;
6215  si = &item->stream_info[j];
6216  if (si->sidx_pts != AV_NOPTS_VALUE) {
6217  ref_st = c->fc->streams[j];
6218  ref_sc = ref_st->priv_data;
6219  break;
6220  }
6221  }
6222  }
6223  if (ref_st) for (i = 0; i < c->fc->nb_streams; i++) {
6224  st = c->fc->streams[i];
6225  sc = st->priv_data;
6226  if (!sc->has_sidx) {
6227  st->duration = sc->track_end = av_rescale(ref_st->duration, sc->time_scale, ref_sc->time_scale);
6228  }
6229  }
6230 
6231  if (offadd == 0)
6232  c->frag_index.complete = 1;
6233  }
6234 
6235  return 0;
6236 }
6237 
6238 /* this atom should be null (from specs), but some buggy files put the 'moov' atom inside it... */
6239 /* like the files created with Adobe Premiere 5.0, for samples see */
6240 /* http://graphics.tudelft.nl/~wouter/publications/soundtests/ */
6242 {
6243  int err;
6244 
6245  if (atom.size < 8)
6246  return 0; /* continue */
6247  if (avio_rb32(pb) != 0) { /* 0 sized mdat atom... use the 'wide' atom size */
6248  avio_skip(pb, atom.size - 4);
6249  return 0;
6250  }
6251  atom.type = avio_rl32(pb);
6252  atom.size -= 8;
6253  if (atom.type != MKTAG('m','d','a','t')) {
6254  avio_skip(pb, atom.size);
6255  return 0;
6256  }
6257  err = mov_read_mdat(c, pb, atom);
6258  return err;
6259 }
6260 
6262 {
6263 #if CONFIG_ZLIB
6264  FFIOContext ctx;
6265  uint8_t *cmov_data;
6266  uint8_t *moov_data; /* uncompressed data */
6267  long cmov_len, moov_len;
6268  int ret = -1;
6269 
6270  avio_rb32(pb); /* dcom atom */
6271  if (avio_rl32(pb) != MKTAG('d','c','o','m'))
6272  return AVERROR_INVALIDDATA;
6273  if (avio_rl32(pb) != MKTAG('z','l','i','b')) {
6274  av_log(c->fc, AV_LOG_ERROR, "unknown compression for cmov atom !\n");
6275  return AVERROR_INVALIDDATA;
6276  }
6277  avio_rb32(pb); /* cmvd atom */
6278  if (avio_rl32(pb) != MKTAG('c','m','v','d'))
6279  return AVERROR_INVALIDDATA;
6280  moov_len = avio_rb32(pb); /* uncompressed size */
6281  cmov_len = atom.size - 6 * 4;
6282 
6283  cmov_data = av_malloc(cmov_len);
6284  if (!cmov_data)
6285  return AVERROR(ENOMEM);
6286  moov_data = av_malloc(moov_len);
6287  if (!moov_data) {
6288  av_free(cmov_data);
6289  return AVERROR(ENOMEM);
6290  }
6291  ret = ffio_read_size(pb, cmov_data, cmov_len);
6292  if (ret < 0)
6293  goto free_and_return;
6294 
6296  if (uncompress (moov_data, (uLongf *) &moov_len, (const Bytef *)cmov_data, cmov_len) != Z_OK)
6297  goto free_and_return;
6298  ffio_init_read_context(&ctx, moov_data, moov_len);
6299  ctx.pub.seekable = AVIO_SEEKABLE_NORMAL;
6300  atom.type = MKTAG('m','o','o','v');
6301  atom.size = moov_len;
6302  ret = mov_read_default(c, &ctx.pub, atom);
6303 free_and_return:
6304  av_free(moov_data);
6305  av_free(cmov_data);
6306  return ret;
6307 #else
6308  av_log(c->fc, AV_LOG_ERROR, "this file requires zlib support compiled in\n");
6309  return AVERROR(ENOSYS);
6310 #endif
6311 }
6312 
6313 /* edit list atom */
6315 {
6316  MOVStreamContext *sc;
6317  int i, edit_count, version;
6318  int64_t elst_entry_size;
6319 
6320  if (c->fc->nb_streams < 1 || c->ignore_editlist)
6321  return 0;
6322  sc = c->fc->streams[c->fc->nb_streams-1]->priv_data;
6323 
6324  version = avio_r8(pb); /* version */
6325  avio_rb24(pb); /* flags */
6326  edit_count = avio_rb32(pb); /* entries */
6327  atom.size -= 8;
6328 
6329  elst_entry_size = version == 1 ? 20 : 12;
6330  if (atom.size != edit_count * elst_entry_size) {
6331  if (c->fc->strict_std_compliance >= FF_COMPLIANCE_STRICT) {
6332  av_log(c->fc, AV_LOG_ERROR, "Invalid edit list entry_count: %d for elst atom of size: %"PRId64" bytes.\n",
6333  edit_count, atom.size + 8);
6334  return AVERROR_INVALIDDATA;
6335  } else {
6336  edit_count = atom.size / elst_entry_size;
6337  if (edit_count * elst_entry_size != atom.size) {
6338  av_log(c->fc, AV_LOG_WARNING, "ELST atom of %"PRId64" bytes, bigger than %d entries.\n", atom.size, edit_count);
6339  }
6340  }
6341  }
6342 
6343  if (!edit_count)
6344  return 0;
6345  if (sc->elst_data)
6346  av_log(c->fc, AV_LOG_WARNING, "Duplicated ELST atom\n");
6347  av_free(sc->elst_data);
6348  sc->elst_count = 0;
6349  sc->elst_data = av_malloc_array(edit_count, sizeof(*sc->elst_data));
6350  if (!sc->elst_data)
6351  return AVERROR(ENOMEM);
6352 
6353  av_log(c->fc, AV_LOG_TRACE, "track[%u].edit_count = %i\n", c->fc->nb_streams - 1, edit_count);
6354  for (i = 0; i < edit_count && atom.size > 0 && !pb->eof_reached; i++) {
6355  MOVElst *e = &sc->elst_data[i];
6356 
6357  if (version == 1) {
6358  e->duration = avio_rb64(pb);
6359  e->time = avio_rb64(pb);
6360  atom.size -= 16;
6361  } else {
6362  e->duration = avio_rb32(pb); /* segment duration */
6363  e->time = (int32_t)avio_rb32(pb); /* media time */
6364  atom.size -= 8;
6365  }
6366  e->rate = avio_rb32(pb) / 65536.0;
6367  atom.size -= 4;
6368  av_log(c->fc, AV_LOG_TRACE, "duration=%"PRId64" time=%"PRId64" rate=%f\n",
6369  e->duration, e->time, e->rate);
6370 
6371  if (e->time < 0 && e->time != -1 &&
6372  c->fc->strict_std_compliance >= FF_COMPLIANCE_STRICT) {
6373  av_log(c->fc, AV_LOG_ERROR, "Track %d, edit %d: Invalid edit list media time=%"PRId64"\n",
6374  c->fc->nb_streams-1, i, e->time);
6375  return AVERROR_INVALIDDATA;
6376  }
6377  if (e->duration < 0) {
6378  av_log(c->fc, AV_LOG_ERROR, "Track %d, edit %d: Invalid edit list duration=%"PRId64"\n",
6379  c->fc->nb_streams-1, i, e->duration);
6380  return AVERROR_INVALIDDATA;
6381  }
6382  }
6383  sc->elst_count = i;
6384 
6385  return 0;
6386 }
6387 
6389 {
6390  MOVStreamContext *sc;
6391 
6392  if (c->fc->nb_streams < 1)
6393  return AVERROR_INVALIDDATA;
6394  sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
6395  sc->timecode_track = avio_rb32(pb);
6396  return 0;
6397 }
6398 
6400 {
6401  AVStream *st;
6402  int version, color_range, color_primaries, color_trc, color_space;
6403 
6404  if (c->fc->nb_streams < 1)
6405  return 0;
6406  st = c->fc->streams[c->fc->nb_streams - 1];
6407 
6408  if (atom.size < 5) {
6409  av_log(c->fc, AV_LOG_ERROR, "Empty VP Codec Configuration box\n");
6410  return AVERROR_INVALIDDATA;
6411  }
6412 
6413  version = avio_r8(pb);
6414  if (version != 1) {
6415  av_log(c->fc, AV_LOG_WARNING, "Unsupported VP Codec Configuration box version %d\n", version);
6416  return 0;
6417  }
6418  avio_skip(pb, 3); /* flags */
6419 
6420  avio_skip(pb, 2); /* profile + level */
6421  color_range = avio_r8(pb); /* bitDepth, chromaSubsampling, videoFullRangeFlag */
6422  color_primaries = avio_r8(pb);
6423  color_trc = avio_r8(pb);
6424  color_space = avio_r8(pb);
6425  if (avio_rb16(pb)) /* codecIntializationDataSize */
6426  return AVERROR_INVALIDDATA;
6427 
6430  if (!av_color_transfer_name(color_trc))
6431  color_trc = AVCOL_TRC_UNSPECIFIED;
6432  if (!av_color_space_name(color_space))
6433  color_space = AVCOL_SPC_UNSPECIFIED;
6434 
6437  st->codecpar->color_trc = color_trc;
6438  st->codecpar->color_space = color_space;
6439 
6440  return 0;
6441 }
6442 
6444 {
6445  MOVStreamContext *sc;
6446  int i, version;
6447 
6448  if (c->fc->nb_streams < 1)
6449  return AVERROR_INVALIDDATA;
6450 
6451  sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
6452 
6453  if (atom.size < 5) {
6454  av_log(c->fc, AV_LOG_ERROR, "Empty Mastering Display Metadata box\n");
6455  return AVERROR_INVALIDDATA;
6456  }
6457 
6458  version = avio_r8(pb);
6459  if (version) {
6460  av_log(c->fc, AV_LOG_WARNING, "Unsupported Mastering Display Metadata box version %d\n", version);
6461  return 0;
6462  }
6463  if (sc->mastering) {
6464  av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicate Mastering Display Metadata\n");
6465  return 0;
6466  }
6467 
6468  avio_skip(pb, 3); /* flags */
6469 
6471  if (!sc->mastering)
6472  return AVERROR(ENOMEM);
6473 
6474  for (i = 0; i < 3; i++) {
6475  sc->mastering->display_primaries[i][0] = av_make_q(avio_rb16(pb), 1 << 16);
6476  sc->mastering->display_primaries[i][1] = av_make_q(avio_rb16(pb), 1 << 16);
6477  }
6478  sc->mastering->white_point[0] = av_make_q(avio_rb16(pb), 1 << 16);
6479  sc->mastering->white_point[1] = av_make_q(avio_rb16(pb), 1 << 16);
6480 
6481  sc->mastering->max_luminance = av_make_q(avio_rb32(pb), 1 << 8);
6482  sc->mastering->min_luminance = av_make_q(avio_rb32(pb), 1 << 14);
6483 
6484  sc->mastering->has_primaries = 1;
6485  sc->mastering->has_luminance = 1;
6486 
6487  return 0;
6488 }
6489 
6491 {
6492  MOVStreamContext *sc;
6493  const int mapping[3] = {1, 2, 0};
6494  const int chroma_den = 50000;
6495  const int luma_den = 10000;
6496  int i;
6497 
6498  if (c->fc->nb_streams < 1)
6499  return AVERROR_INVALIDDATA;
6500 
6501  sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
6502 
6503  if (atom.size < 24) {
6504  av_log(c->fc, AV_LOG_ERROR, "Invalid Mastering Display Color Volume box\n");
6505  return AVERROR_INVALIDDATA;
6506  }
6507 
6508  if (sc->mastering) {
6509  av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicate Mastering Display Color Volume\n");
6510  return 0;
6511  }
6512 
6514  if (!sc->mastering)
6515  return AVERROR(ENOMEM);
6516 
6517  for (i = 0; i < 3; i++) {
6518  const int j = mapping[i];
6519  sc->mastering->display_primaries[j][0] = av_make_q(avio_rb16(pb), chroma_den);
6520  sc->mastering->display_primaries[j][1] = av_make_q(avio_rb16(pb), chroma_den);
6521  }
6522  sc->mastering->white_point[0] = av_make_q(avio_rb16(pb), chroma_den);
6523  sc->mastering->white_point[1] = av_make_q(avio_rb16(pb), chroma_den);
6524 
6525  sc->mastering->max_luminance = av_make_q(avio_rb32(pb), luma_den);
6526  sc->mastering->min_luminance = av_make_q(avio_rb32(pb), luma_den);
6527 
6528  sc->mastering->has_luminance = 1;
6529  sc->mastering->has_primaries = 1;
6530 
6531  return 0;
6532 }
6533 
6535 {
6536  MOVStreamContext *sc;
6537  int version;
6538 
6539  if (c->fc->nb_streams < 1)
6540  return AVERROR_INVALIDDATA;
6541 
6542  sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
6543 
6544  if (atom.size < 5) {
6545  av_log(c->fc, AV_LOG_ERROR, "Empty Content Light Level box\n");
6546  return AVERROR_INVALIDDATA;
6547  }
6548 
6549  version = avio_r8(pb);
6550  if (version) {
6551  av_log(c->fc, AV_LOG_WARNING, "Unsupported Content Light Level box version %d\n", version);
6552  return 0;
6553  }
6554  avio_skip(pb, 3); /* flags */
6555 
6556  if (sc->coll){
6557  av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicate COLL\n");
6558  return 0;
6559  }
6560 
6562  if (!sc->coll)
6563  return AVERROR(ENOMEM);
6564 
6565  sc->coll->MaxCLL = avio_rb16(pb);
6566  sc->coll->MaxFALL = avio_rb16(pb);
6567 
6568  return 0;
6569 }
6570 
6572 {
6573  MOVStreamContext *sc;
6574 
6575  if (c->fc->nb_streams < 1)
6576  return AVERROR_INVALIDDATA;
6577 
6578  sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
6579 
6580  if (atom.size < 4) {
6581  av_log(c->fc, AV_LOG_ERROR, "Empty Content Light Level Info box\n");
6582  return AVERROR_INVALIDDATA;
6583  }
6584 
6585  if (sc->coll){
6586  av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicate CLLI/COLL\n");
6587  return 0;
6588  }
6589 
6591  if (!sc->coll)
6592  return AVERROR(ENOMEM);
6593 
6594  sc->coll->MaxCLL = avio_rb16(pb);
6595  sc->coll->MaxFALL = avio_rb16(pb);
6596 
6597  return 0;
6598 }
6599 
6601 {
6602  MOVStreamContext *sc;
6603  const int illuminance_den = 10000;
6604  const int ambient_den = 50000;
6605  if (c->fc->nb_streams < 1)
6606  return AVERROR_INVALIDDATA;
6607  sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
6608  if (atom.size < 6) {
6609  av_log(c->fc, AV_LOG_ERROR, "Empty Ambient Viewing Environment Info box\n");
6610  return AVERROR_INVALIDDATA;
6611  }
6612  if (sc->ambient){
6613  av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicate AMVE\n");
6614  return 0;
6615  }
6617  if (!sc->ambient)
6618  return AVERROR(ENOMEM);
6619  sc->ambient->ambient_illuminance = av_make_q(avio_rb32(pb), illuminance_den);
6620  sc->ambient->ambient_light_x = av_make_q(avio_rb16(pb), ambient_den);
6621  sc->ambient->ambient_light_y = av_make_q(avio_rb16(pb), ambient_den);
6622  return 0;
6623 }
6624 
6626 {
6627  AVStream *st;
6628  MOVStreamContext *sc;
6629  enum AVStereo3DType type;
6630  int mode;
6631 
6632  if (c->fc->nb_streams < 1)
6633  return 0;
6634 
6635  st = c->fc->streams[c->fc->nb_streams - 1];
6636  sc = st->priv_data;
6637 
6638  if (atom.size < 5) {
6639  av_log(c->fc, AV_LOG_ERROR, "Empty stereoscopic video box\n");
6640  return AVERROR_INVALIDDATA;
6641  }
6642 
6643  if (sc->stereo3d)
6644  return AVERROR_INVALIDDATA;
6645 
6646  avio_skip(pb, 4); /* version + flags */
6647 
6648  mode = avio_r8(pb);
6649  switch (mode) {
6650  case 0:
6651  type = AV_STEREO3D_2D;
6652  break;
6653  case 1:
6655  break;
6656  case 2:
6658  break;
6659  default:
6660  av_log(c->fc, AV_LOG_WARNING, "Unknown st3d mode value %d\n", mode);
6661  return 0;
6662  }
6663 
6665  if (!sc->stereo3d)
6666  return AVERROR(ENOMEM);
6667 
6668  sc->stereo3d->type = type;
6669  return 0;
6670 }
6671 
6673 {
6674  AVStream *st;
6675  MOVStreamContext *sc;
6676  int size = 0;
6677  int64_t remaining;
6678  uint32_t tag = 0;
6680 
6681  if (c->fc->nb_streams < 1)
6682  return 0;
6683 
6684  st = c->fc->streams[c->fc->nb_streams - 1];
6685  sc = st->priv_data;
6686 
6687  remaining = atom.size;
6688  while (remaining > 0) {
6689  size = avio_rb32(pb);
6690  if (size < 8 || size > remaining ) {
6691  av_log(c->fc, AV_LOG_ERROR, "Invalid child size in pack box\n");
6692  return AVERROR_INVALIDDATA;
6693  }
6694 
6695  tag = avio_rl32(pb);
6696  switch (tag) {
6697  case MKTAG('p','k','i','n'): {
6698  if (size != 16) {
6699  av_log(c->fc, AV_LOG_ERROR, "Invalid size of pkin box: %d\n", size);
6700  return AVERROR_INVALIDDATA;
6701  }
6702  avio_skip(pb, 1); // version
6703  avio_skip(pb, 3); // flags
6704 
6705  tag = avio_rl32(pb);
6706  switch (tag) {
6707  case MKTAG('s','i','d','e'):
6709  break;
6710  case MKTAG('o','v','e','r'):
6712  break;
6713  case 0:
6714  // This means value will be set in another layer
6715  break;
6716  default:
6717  av_log(c->fc, AV_LOG_WARNING, "Unknown tag in pkin: %s\n",
6718  av_fourcc2str(tag));
6719  avio_skip(pb, size - 8);
6720  break;
6721  }
6722 
6723  break;
6724  }
6725  default:
6726  av_log(c->fc, AV_LOG_WARNING, "Unknown tag in pack: %s\n",
6727  av_fourcc2str(tag));
6728  avio_skip(pb, size - 8);
6729  break;
6730  }
6731  remaining -= size;
6732  }
6733 
6734  if (remaining != 0) {
6735  av_log(c->fc, AV_LOG_ERROR, "Broken pack box\n");
6736  return AVERROR_INVALIDDATA;
6737  }
6738 
6739  if (type == AV_STEREO3D_2D)
6740  return 0;
6741 
6742  if (!sc->stereo3d) {
6744  if (!sc->stereo3d)
6745  return AVERROR(ENOMEM);
6746  }
6747 
6748  sc->stereo3d->type = type;
6749 
6750  return 0;
6751 }
6752 
6754 {
6755  AVStream *st;
6756  MOVStreamContext *sc;
6757  int size, version, layout;
6758  int32_t yaw, pitch, roll;
6759  uint32_t l = 0, t = 0, r = 0, b = 0;
6760  uint32_t tag, padding = 0;
6761  enum AVSphericalProjection projection;
6762 
6763  if (c->fc->nb_streams < 1)
6764  return 0;
6765 
6766  st = c->fc->streams[c->fc->nb_streams - 1];
6767  sc = st->priv_data;
6768 
6769  if (atom.size < 8) {
6770  av_log(c->fc, AV_LOG_ERROR, "Empty spherical video box\n");
6771  return AVERROR_INVALIDDATA;
6772  }
6773 
6774  size = avio_rb32(pb);
6775  if (size <= 12 || size > atom.size)
6776  return AVERROR_INVALIDDATA;
6777 
6778  tag = avio_rl32(pb);
6779  if (tag != MKTAG('s','v','h','d')) {
6780  av_log(c->fc, AV_LOG_ERROR, "Missing spherical video header\n");
6781  return 0;
6782  }
6783  version = avio_r8(pb);
6784  if (version != 0) {
6785  av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
6786  version);
6787  return 0;
6788  }
6789  avio_skip(pb, 3); /* flags */
6790  avio_skip(pb, size - 12); /* metadata_source */
6791 
6792  size = avio_rb32(pb);
6793  if (size > atom.size)
6794  return AVERROR_INVALIDDATA;
6795 
6796  tag = avio_rl32(pb);
6797  if (tag != MKTAG('p','r','o','j')) {
6798  av_log(c->fc, AV_LOG_ERROR, "Missing projection box\n");
6799  return 0;
6800  }
6801 
6802  size = avio_rb32(pb);
6803  if (size > atom.size)
6804  return AVERROR_INVALIDDATA;
6805 
6806  tag = avio_rl32(pb);
6807  if (tag != MKTAG('p','r','h','d')) {
6808  av_log(c->fc, AV_LOG_ERROR, "Missing projection header box\n");
6809  return 0;
6810  }
6811  version = avio_r8(pb);
6812  if (version != 0) {
6813  av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
6814  version);
6815  return 0;
6816  }
6817  avio_skip(pb, 3); /* flags */
6818 
6819  /* 16.16 fixed point */
6820  yaw = avio_rb32(pb);
6821  pitch = avio_rb32(pb);
6822  roll = avio_rb32(pb);
6823 
6824  size = avio_rb32(pb);
6825  if (size > atom.size)
6826  return AVERROR_INVALIDDATA;
6827 
6828  tag = avio_rl32(pb);
6829  version = avio_r8(pb);
6830  if (version != 0) {
6831  av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
6832  version);
6833  return 0;
6834  }
6835  avio_skip(pb, 3); /* flags */
6836  switch (tag) {
6837  case MKTAG('c','b','m','p'):
6838  layout = avio_rb32(pb);
6839  if (layout) {
6840  av_log(c->fc, AV_LOG_WARNING,
6841  "Unsupported cubemap layout %d\n", layout);
6842  return 0;
6843  }
6844  projection = AV_SPHERICAL_CUBEMAP;
6845  padding = avio_rb32(pb);
6846  break;
6847  case MKTAG('e','q','u','i'):
6848  t = avio_rb32(pb);
6849  b = avio_rb32(pb);
6850  l = avio_rb32(pb);
6851  r = avio_rb32(pb);
6852 
6853  if (b >= UINT_MAX - t || r >= UINT_MAX - l) {
6854  av_log(c->fc, AV_LOG_ERROR,
6855  "Invalid bounding rectangle coordinates "
6856  "%"PRIu32",%"PRIu32",%"PRIu32",%"PRIu32"\n", l, t, r, b);
6857  return AVERROR_INVALIDDATA;
6858  }
6859 
6860  if (l || t || r || b)
6861  projection = AV_SPHERICAL_EQUIRECTANGULAR_TILE;
6862  else
6863  projection = AV_SPHERICAL_EQUIRECTANGULAR;
6864  break;
6865  default:
6866  av_log(c->fc, AV_LOG_ERROR, "Unknown projection type: %s\n", av_fourcc2str(tag));
6867  return 0;
6868  }
6869 
6871  if (!sc->spherical)
6872  return AVERROR(ENOMEM);
6873 
6874  sc->spherical->projection = projection;
6875 
6876  sc->spherical->yaw = yaw;
6877  sc->spherical->pitch = pitch;
6878  sc->spherical->roll = roll;
6879 
6880  sc->spherical->padding = padding;
6881 
6882  sc->spherical->bound_left = l;
6883  sc->spherical->bound_top = t;
6884  sc->spherical->bound_right = r;
6885  sc->spherical->bound_bottom = b;
6886 
6887  return 0;
6888 }
6889 
6891 {
6892  AVStream *st;
6893  MOVStreamContext *sc;
6894  int size;
6895  uint32_t tag;
6896  enum AVSphericalProjection projection;
6897 
6898  if (c->fc->nb_streams < 1)
6899  return 0;
6900 
6901  st = c->fc->streams[c->fc->nb_streams - 1];
6902  sc = st->priv_data;
6903 
6904  if (atom.size < 16) {
6905  av_log(c->fc, AV_LOG_ERROR, "Invalid size for proj box: %"PRIu64"\n", atom.size);
6906  return AVERROR_INVALIDDATA;
6907  }
6908 
6909  size = avio_rb32(pb);
6910  if (size < 16) {
6911  av_log(c->fc, AV_LOG_ERROR, "Invalid size for prji box: %d\n", size);
6912  return AVERROR_INVALIDDATA;
6913  } else if (size > 16) {
6914  av_log(c->fc, AV_LOG_WARNING, "Box has more bytes (%d) than prji box required (16) \n", size);
6915  }
6916 
6917  tag = avio_rl32(pb);
6918  if (tag != MKTAG('p','r','j','i')) {
6919  av_log(c->fc, AV_LOG_ERROR, "Invalid child box of proj box: %s\n",
6920  av_fourcc2str(tag));
6921  return AVERROR_INVALIDDATA;
6922  }
6923 
6924  // version and flags, only support (0, 0)
6925  unsigned n = avio_rl32(pb);
6926  if (n != 0) {
6927  av_log(c->fc, AV_LOG_ERROR, "prji version %u, flag %u are not supported\n",
6928  n & 0xFF, n >> 8);
6929  return AVERROR_PATCHWELCOME;
6930  }
6931 
6932  tag = avio_rl32(pb);
6933  switch (tag) {
6934  case MKTAG('r','e','c','t'):
6935  projection = AV_SPHERICAL_RECTILINEAR;
6936  break;
6937  case MKTAG('e','q','u','i'):
6938  projection = AV_SPHERICAL_EQUIRECTANGULAR;
6939  break;
6940  case MKTAG('h','e','q','u'):
6941  projection = AV_SPHERICAL_HALF_EQUIRECTANGULAR;
6942  break;
6943  case MKTAG('f','i','s','h'):
6944  projection = AV_SPHERICAL_FISHEYE;
6945  break;
6946  case MKTAG('p','r','i','m'):
6947  projection = AV_SPHERICAL_PARAMETRIC_IMMERSIVE;
6948  break;
6949  default:
6950  av_log(c->fc, AV_LOG_ERROR, "Invalid projection type in prji box: %s\n", av_fourcc2str(tag));
6951  return AVERROR_INVALIDDATA;
6952  }
6953 
6955  if (!sc->spherical)
6956  return AVERROR(ENOMEM);
6957 
6958  sc->spherical->projection = projection;
6959 
6960  return 0;
6961 }
6962 
6964 {
6965  AVStream *st;
6966  MOVStreamContext *sc;
6967  int size, flags = 0;
6968  int64_t remaining;
6969  uint32_t tag, baseline = 0;
6972  enum AVStereo3DPrimaryEye primary_eye = AV_PRIMARY_EYE_NONE;
6973  AVRational horizontal_disparity_adjustment = { 0, 1 };
6974 
6975  if (c->fc->nb_streams < 1)
6976  return 0;
6977 
6978  st = c->fc->streams[c->fc->nb_streams - 1];
6979  sc = st->priv_data;
6980 
6981  remaining = atom.size;
6982  while (remaining > 0) {
6983  size = avio_rb32(pb);
6984  if (size < 8 || size > remaining ) {
6985  av_log(c->fc, AV_LOG_ERROR, "Invalid child size in eyes box\n");
6986  return AVERROR_INVALIDDATA;
6987  }
6988 
6989  tag = avio_rl32(pb);
6990  switch (tag) {
6991  case MKTAG('s','t','r','i'): {
6992  int has_right, has_left;
6993  uint8_t tmp;
6994  if (size != 13) {
6995  av_log(c->fc, AV_LOG_ERROR, "Invalid size of stri box: %d\n", size);
6996  return AVERROR_INVALIDDATA;
6997  }
6998  avio_skip(pb, 1); // version
6999  avio_skip(pb, 3); // flags
7000 
7001  tmp = avio_r8(pb);
7002 
7003  // eye_views_reversed
7004  if (tmp & 8) {
7006  }
7007  // has_additional_views
7008  if (tmp & 4) {
7009  // skip...
7010  }
7011 
7012  has_right = tmp & 2; // has_right_eye_view
7013  has_left = tmp & 1; // has_left_eye_view
7014 
7015  if (has_left && has_right)
7016  view = AV_STEREO3D_VIEW_PACKED;
7017  else if (has_left)
7018  view = AV_STEREO3D_VIEW_LEFT;
7019  else if (has_right)
7020  view = AV_STEREO3D_VIEW_RIGHT;
7021  if (has_left || has_right)
7023 
7024  break;
7025  }
7026  case MKTAG('h','e','r','o'): {
7027  int tmp;
7028  if (size != 13) {
7029  av_log(c->fc, AV_LOG_ERROR, "Invalid size of hero box: %d\n", size);
7030  return AVERROR_INVALIDDATA;
7031  }
7032  avio_skip(pb, 1); // version
7033  avio_skip(pb, 3); // flags
7034 
7035  tmp = avio_r8(pb);
7036  if (tmp == 0)
7037  primary_eye = AV_PRIMARY_EYE_NONE;
7038  else if (tmp == 1)
7039  primary_eye = AV_PRIMARY_EYE_LEFT;
7040  else if (tmp == 2)
7041  primary_eye = AV_PRIMARY_EYE_RIGHT;
7042  else
7043  av_log(c->fc, AV_LOG_WARNING, "Unknown hero eye type: %d\n", tmp);
7044 
7045  break;
7046  }
7047  case MKTAG('c','a','m','s'): {
7048  uint32_t subtag;
7049  int subsize;
7050  if (size != 24) {
7051  av_log(c->fc, AV_LOG_ERROR, "Invalid size of cams box: %d\n", size);
7052  return AVERROR_INVALIDDATA;
7053  }
7054 
7055  subsize = avio_rb32(pb);
7056  if (subsize != 16) {
7057  av_log(c->fc, AV_LOG_ERROR, "Invalid size of blin box: %d\n", size);
7058  return AVERROR_INVALIDDATA;
7059  }
7060 
7061  subtag = avio_rl32(pb);
7062  if (subtag != MKTAG('b','l','i','n')) {
7063  av_log(c->fc, AV_LOG_ERROR, "Expected blin box, got %s\n",
7064  av_fourcc2str(subtag));
7065  return AVERROR_INVALIDDATA;
7066  }
7067 
7068  avio_skip(pb, 1); // version
7069  avio_skip(pb, 3); // flags
7070 
7071  baseline = avio_rb32(pb);
7072 
7073  break;
7074  }
7075  case MKTAG('c','m','f','y'): {
7076  uint32_t subtag;
7077  int subsize;
7078  int32_t adjustment;
7079  if (size != 24) {
7080  av_log(c->fc, AV_LOG_ERROR, "Invalid size of cmfy box: %d\n", size);
7081  return AVERROR_INVALIDDATA;
7082  }
7083 
7084  subsize = avio_rb32(pb);
7085  if (subsize != 16) {
7086  av_log(c->fc, AV_LOG_ERROR, "Invalid size of dadj box: %d\n", size);
7087  return AVERROR_INVALIDDATA;
7088  }
7089 
7090  subtag = avio_rl32(pb);
7091  if (subtag != MKTAG('d','a','d','j')) {
7092  av_log(c->fc, AV_LOG_ERROR, "Expected dadj box, got %s\n",
7093  av_fourcc2str(subtag));
7094  return AVERROR_INVALIDDATA;
7095  }
7096 
7097  avio_skip(pb, 1); // version
7098  avio_skip(pb, 3); // flags
7099 
7100  adjustment = (int32_t) avio_rb32(pb);
7101 
7102  horizontal_disparity_adjustment.num = (int) adjustment;
7103  horizontal_disparity_adjustment.den = 10000;
7104 
7105  break;
7106  }
7107  default:
7108  av_log(c->fc, AV_LOG_WARNING, "Unknown tag in eyes: %s\n",
7109  av_fourcc2str(tag));
7110  avio_skip(pb, size - 8);
7111  break;
7112  }
7113  remaining -= size;
7114  }
7115 
7116  if (remaining != 0) {
7117  av_log(c->fc, AV_LOG_ERROR, "Broken eyes box\n");
7118  return AVERROR_INVALIDDATA;
7119  }
7120 
7121  if (type == AV_STEREO3D_2D)
7122  return 0;
7123 
7124  if (!sc->stereo3d) {
7126  if (!sc->stereo3d)
7127  return AVERROR(ENOMEM);
7128  }
7129 
7130  sc->stereo3d->flags = flags;
7131  sc->stereo3d->type = type;
7132  sc->stereo3d->view = view;
7133  sc->stereo3d->primary_eye = primary_eye;
7134  sc->stereo3d->baseline = baseline;
7135  sc->stereo3d->horizontal_disparity_adjustment = horizontal_disparity_adjustment;
7136 
7137  return 0;
7138 }
7139 
7141 {
7142  int size;
7143  int64_t remaining;
7144  uint32_t tag;
7145 
7146  if (c->fc->nb_streams < 1)
7147  return 0;
7148 
7149  if (atom.size < 8) {
7150  av_log(c->fc, AV_LOG_ERROR, "Empty video extension usage box\n");
7151  return AVERROR_INVALIDDATA;
7152  }
7153 
7154  remaining = atom.size;
7155  while (remaining > 0) {
7156  size = avio_rb32(pb);
7157  if (size < 8 || size > remaining ) {
7158  av_log(c->fc, AV_LOG_ERROR, "Invalid child size in vexu box\n");
7159  return AVERROR_INVALIDDATA;
7160  }
7161 
7162  tag = avio_rl32(pb);
7163  switch (tag) {
7164  case MKTAG('p','r','o','j'): {
7165  MOVAtom proj = { tag, size - 8 };
7166  int ret = mov_read_vexu_proj(c, pb, proj);
7167  if (ret < 0)
7168  return ret;
7169  break;
7170  }
7171  case MKTAG('e','y','e','s'): {
7172  MOVAtom eyes = { tag, size - 8 };
7173  int ret = mov_read_eyes(c, pb, eyes);
7174  if (ret < 0)
7175  return ret;
7176  break;
7177  }
7178  case MKTAG('p','a','c','k'): {
7179  MOVAtom pack = { tag, size - 8 };
7180  int ret = mov_read_pack(c, pb, pack);
7181  if (ret < 0)
7182  return ret;
7183  break;
7184  }
7185  default:
7186  av_log(c->fc, AV_LOG_WARNING, "Unknown tag in vexu: %s\n",
7187  av_fourcc2str(tag));
7188  avio_skip(pb, size - 8);
7189  break;
7190  }
7191  remaining -= size;
7192  }
7193 
7194  if (remaining != 0) {
7195  av_log(c->fc, AV_LOG_ERROR, "Broken vexu box\n");
7196  return AVERROR_INVALIDDATA;
7197  }
7198 
7199  return 0;
7200 }
7201 
7203 {
7204  AVStream *st;
7205  MOVStreamContext *sc;
7206 
7207  if (c->fc->nb_streams < 1)
7208  return 0;
7209 
7210  st = c->fc->streams[c->fc->nb_streams - 1];
7211  sc = st->priv_data;
7212 
7213  if (atom.size != 4) {
7214  av_log(c->fc, AV_LOG_ERROR, "Invalid size of hfov box: %"PRIu64"\n", atom.size);
7215  return AVERROR_INVALIDDATA;
7216  }
7217 
7218 
7219  if (!sc->stereo3d) {
7221  if (!sc->stereo3d)
7222  return AVERROR(ENOMEM);
7223  }
7224 
7226  sc->stereo3d->horizontal_field_of_view.den = 1000; // thousands of a degree
7227 
7228  return 0;
7229 }
7230 
7232 {
7233  int ret = 0;
7234  uint8_t *buffer = av_malloc(len + 1);
7235  const char *val;
7236 
7237  if (!buffer)
7238  return AVERROR(ENOMEM);
7239  buffer[len] = '\0';
7240 
7241  ret = ffio_read_size(pb, buffer, len);
7242  if (ret < 0)
7243  goto out;
7244 
7245  /* Check for mandatory keys and values, try to support XML as best-effort */
7246  if (!sc->spherical &&
7247  av_stristr(buffer, "<GSpherical:StitchingSoftware>") &&
7248  (val = av_stristr(buffer, "<GSpherical:Spherical>")) &&
7249  av_stristr(val, "true") &&
7250  (val = av_stristr(buffer, "<GSpherical:Stitched>")) &&
7251  av_stristr(val, "true") &&
7252  (val = av_stristr(buffer, "<GSpherical:ProjectionType>")) &&
7253  av_stristr(val, "equirectangular")) {
7255  if (!sc->spherical)
7256  goto out;
7257 
7259 
7260  if (av_stristr(buffer, "<GSpherical:StereoMode>") && !sc->stereo3d) {
7261  enum AVStereo3DType mode;
7262 
7263  if (av_stristr(buffer, "left-right"))
7265  else if (av_stristr(buffer, "top-bottom"))
7267  else
7268  mode = AV_STEREO3D_2D;
7269 
7271  if (!sc->stereo3d)
7272  goto out;
7273 
7274  sc->stereo3d->type = mode;
7275  }
7276 
7277  /* orientation */
7278  val = av_stristr(buffer, "<GSpherical:InitialViewHeadingDegrees>");
7279  if (val)
7280  sc->spherical->yaw = strtol(val, NULL, 10) * (1 << 16);
7281  val = av_stristr(buffer, "<GSpherical:InitialViewPitchDegrees>");
7282  if (val)
7283  sc->spherical->pitch = strtol(val, NULL, 10) * (1 << 16);
7284  val = av_stristr(buffer, "<GSpherical:InitialViewRollDegrees>");
7285  if (val)
7286  sc->spherical->roll = strtol(val, NULL, 10) * (1 << 16);
7287  }
7288 
7289 out:
7290  av_free(buffer);
7291  return ret;
7292 }
7293 
7295 {
7296  AVStream *st;
7297  MOVStreamContext *sc;
7298  int64_t ret;
7299  AVUUID uuid;
7300  static const AVUUID uuid_isml_manifest = {
7301  0xa5, 0xd4, 0x0b, 0x30, 0xe8, 0x14, 0x11, 0xdd,
7302  0xba, 0x2f, 0x08, 0x00, 0x20, 0x0c, 0x9a, 0x66
7303  };
7304  static const AVUUID uuid_xmp = {
7305  0xbe, 0x7a, 0xcf, 0xcb, 0x97, 0xa9, 0x42, 0xe8,
7306  0x9c, 0x71, 0x99, 0x94, 0x91, 0xe3, 0xaf, 0xac
7307  };
7308  static const AVUUID uuid_spherical = {
7309  0xff, 0xcc, 0x82, 0x63, 0xf8, 0x55, 0x4a, 0x93,
7310  0x88, 0x14, 0x58, 0x7a, 0x02, 0x52, 0x1f, 0xdd,
7311  };
7312 
7313  if (atom.size < AV_UUID_LEN || atom.size >= FFMIN(INT_MAX, SIZE_MAX))
7314  return AVERROR_INVALIDDATA;
7315 
7316  if (c->fc->nb_streams < 1)
7317  return 0;
7318  st = c->fc->streams[c->fc->nb_streams - 1];
7319  sc = st->priv_data;
7320 
7321  ret = ffio_read_size(pb, uuid, AV_UUID_LEN);
7322  if (ret < 0)
7323  return ret;
7324  if (av_uuid_equal(uuid, uuid_isml_manifest)) {
7325  uint8_t *buffer, *ptr;
7326  char *endptr;
7327  size_t len = atom.size - AV_UUID_LEN;
7328 
7329  if (len < 4) {
7330  return AVERROR_INVALIDDATA;
7331  }
7332  ret = avio_skip(pb, 4); // zeroes
7333  len -= 4;
7334 
7335  buffer = av_mallocz(len + 1);
7336  if (!buffer) {
7337  return AVERROR(ENOMEM);
7338  }
7339  ret = ffio_read_size(pb, buffer, len);
7340  if (ret < 0) {
7341  av_free(buffer);
7342  return ret;
7343  }
7344 
7345  ptr = buffer;
7346  while ((ptr = av_stristr(ptr, "systemBitrate=\""))) {
7347  ptr += sizeof("systemBitrate=\"") - 1;
7348  c->bitrates_count++;
7349  c->bitrates = av_realloc_f(c->bitrates, c->bitrates_count, sizeof(*c->bitrates));
7350  if (!c->bitrates) {
7351  c->bitrates_count = 0;
7352  av_free(buffer);
7353  return AVERROR(ENOMEM);
7354  }
7355  errno = 0;
7356  ret = strtol(ptr, &endptr, 10);
7357  if (ret < 0 || errno || *endptr != '"') {
7358  c->bitrates[c->bitrates_count - 1] = 0;
7359  } else {
7360  c->bitrates[c->bitrates_count - 1] = ret;
7361  }
7362  }
7363 
7364  av_free(buffer);
7365  } else if (av_uuid_equal(uuid, uuid_xmp)) {
7366  uint8_t *buffer;
7367  size_t len = atom.size - AV_UUID_LEN;
7368  if (c->export_xmp) {
7369  buffer = av_mallocz(len + 1);
7370  if (!buffer) {
7371  return AVERROR(ENOMEM);
7372  }
7373  ret = ffio_read_size(pb, buffer, len);
7374  if (ret < 0) {
7375  av_free(buffer);
7376  return ret;
7377  }
7378  buffer[len] = '\0';
7379  av_dict_set(&c->fc->metadata, "xmp",
7381  } else {
7382  // skip all uuid atom, which makes it fast for long uuid-xmp file
7383  ret = avio_skip(pb, len);
7384  if (ret < 0)
7385  return ret;
7386  }
7387  } else if (av_uuid_equal(uuid, uuid_spherical)) {
7388  size_t len = atom.size - AV_UUID_LEN;
7389  ret = mov_parse_uuid_spherical(sc, pb, len);
7390  if (ret < 0)
7391  return ret;
7392  if (!sc->spherical)
7393  av_log(c->fc, AV_LOG_WARNING, "Invalid spherical metadata found\n");
7394  }
7395 
7396  return 0;
7397 }
7398 
7400 {
7401  int ret;
7402  uint8_t content[16];
7403 
7404  if (atom.size < 8)
7405  return 0;
7406 
7407  ret = ffio_read_size(pb, content, FFMIN(sizeof(content), atom.size));
7408  if (ret < 0)
7409  return ret;
7410 
7411  if ( !c->found_moov
7412  && !c->found_mdat
7413  && !memcmp(content, "Anevia\x1A\x1A", 8)
7414  && c->use_mfra_for == FF_MOV_FLAG_MFRA_AUTO) {
7415  c->use_mfra_for = FF_MOV_FLAG_MFRA_PTS;
7416  }
7417 
7418  return 0;
7419 }
7420 
7422 {
7423  uint32_t format = avio_rl32(pb);
7424  MOVStreamContext *sc;
7425  enum AVCodecID id;
7426  AVStream *st;
7427 
7428  if (c->fc->nb_streams < 1)
7429  return 0;
7430  st = c->fc->streams[c->fc->nb_streams - 1];
7431  sc = st->priv_data;
7432 
7433  switch (sc->format)
7434  {
7435  case MKTAG('e','n','c','v'): // encrypted video
7436  case MKTAG('e','n','c','a'): // encrypted audio
7437  id = mov_codec_id(st, format);
7438  if (st->codecpar->codec_id != AV_CODEC_ID_NONE &&
7439  st->codecpar->codec_id != id) {
7440  av_log(c->fc, AV_LOG_WARNING,
7441  "ignoring 'frma' atom of '%.4s', stream has codec id %d\n",
7442  (char*)&format, st->codecpar->codec_id);
7443  break;
7444  }
7445 
7446  st->codecpar->codec_id = id;
7447  sc->format = format;
7448  break;
7449 
7450  default:
7451  if (format != sc->format) {
7452  av_log(c->fc, AV_LOG_WARNING,
7453  "ignoring 'frma' atom of '%.4s', stream format is '%.4s'\n",
7454  (char*)&format, (char*)&sc->format);
7455  }
7456  break;
7457  }
7458 
7459  return 0;
7460 }
7461 
7462 /**
7463  * Gets the current encryption info and associated current stream context. If
7464  * we are parsing a track fragment, this will return the specific encryption
7465  * info for this fragment; otherwise this will return the global encryption
7466  * info for the current stream.
7467  */
7469 {
7470  MOVFragmentStreamInfo *frag_stream_info;
7471  AVStream *st;
7472  int i;
7473 
7474  frag_stream_info = get_current_frag_stream_info(&c->frag_index);
7475  if (frag_stream_info) {
7476  for (i = 0; i < c->fc->nb_streams; i++) {
7477  *sc = c->fc->streams[i]->priv_data;
7478  if ((*sc)->id == frag_stream_info->id) {
7479  st = c->fc->streams[i];
7480  break;
7481  }
7482  }
7483  if (i == c->fc->nb_streams)
7484  return 0;
7485  *sc = st->priv_data;
7486 
7487  if (!frag_stream_info->encryption_index) {
7488  // If this stream isn't encrypted, don't create the index.
7489  if (!(*sc)->cenc.default_encrypted_sample)
7490  return 0;
7491  frag_stream_info->encryption_index = av_mallocz(sizeof(*frag_stream_info->encryption_index));
7492  if (!frag_stream_info->encryption_index)
7493  return AVERROR(ENOMEM);
7494  }
7495  *encryption_index = frag_stream_info->encryption_index;
7496  return 1;
7497  } else {
7498  // No current track fragment, using stream level encryption info.
7499 
7500  if (c->fc->nb_streams < 1)
7501  return 0;
7502  st = c->fc->streams[c->fc->nb_streams - 1];
7503  *sc = st->priv_data;
7504 
7505  if (!(*sc)->cenc.encryption_index) {
7506  // If this stream isn't encrypted, don't create the index.
7507  if (!(*sc)->cenc.default_encrypted_sample)
7508  return 0;
7509  (*sc)->cenc.encryption_index = av_mallocz(sizeof(*frag_stream_info->encryption_index));
7510  if (!(*sc)->cenc.encryption_index)
7511  return AVERROR(ENOMEM);
7512  }
7513 
7514  *encryption_index = (*sc)->cenc.encryption_index;
7515  return 1;
7516  }
7517 }
7518 
7520 {
7521  int i, ret;
7522  unsigned int subsample_count;
7523  AVSubsampleEncryptionInfo *subsamples;
7524 
7525  if (!sc->cenc.default_encrypted_sample) {
7526  av_log(c->fc, AV_LOG_ERROR, "Missing schm or tenc\n");
7527  return AVERROR_INVALIDDATA;
7528  }
7529 
7530  if (sc->cenc.per_sample_iv_size || use_subsamples) {
7532  if (!*sample)
7533  return AVERROR(ENOMEM);
7534  } else
7535  *sample = NULL;
7536 
7537  if (sc->cenc.per_sample_iv_size != 0) {
7538  if ((ret = ffio_read_size(pb, (*sample)->iv, sc->cenc.per_sample_iv_size)) < 0) {
7539  av_log(c->fc, AV_LOG_ERROR, "failed to read the initialization vector\n");
7541  *sample = NULL;
7542  return ret;
7543  }
7544  }
7545 
7546  if (use_subsamples) {
7547  subsample_count = avio_rb16(pb);
7548  av_free((*sample)->subsamples);
7549  (*sample)->subsamples = av_calloc(subsample_count, sizeof(*subsamples));
7550  if (!(*sample)->subsamples) {
7552  *sample = NULL;
7553  return AVERROR(ENOMEM);
7554  }
7555 
7556  for (i = 0; i < subsample_count && !pb->eof_reached; i++) {
7557  (*sample)->subsamples[i].bytes_of_clear_data = avio_rb16(pb);
7558  (*sample)->subsamples[i].bytes_of_protected_data = avio_rb32(pb);
7559  }
7560 
7561  if (pb->eof_reached) {
7562  av_log(c->fc, AV_LOG_ERROR, "hit EOF while reading sub-sample encryption info\n");
7564  *sample = NULL;
7565  return AVERROR_INVALIDDATA;
7566  }
7567  (*sample)->subsample_count = subsample_count;
7568  }
7569 
7570  return 0;
7571 }
7572 
7574 {
7575  AVEncryptionInfo **encrypted_samples;
7576  MOVEncryptionIndex *encryption_index;
7577  MOVStreamContext *sc;
7578  int use_subsamples, ret;
7579  unsigned int sample_count, i, alloc_size = 0;
7580 
7581  ret = get_current_encryption_info(c, &encryption_index, &sc);
7582  if (ret != 1)
7583  return ret;
7584 
7585  if (encryption_index->nb_encrypted_samples) {
7586  // This can happen if we have both saio/saiz and senc atoms.
7587  av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in senc\n");
7588  return 0;
7589  }
7590 
7591  avio_r8(pb); /* version */
7592  use_subsamples = avio_rb24(pb) & 0x02; /* flags */
7593 
7594  sample_count = avio_rb32(pb);
7595  if (sample_count >= INT_MAX / sizeof(*encrypted_samples))
7596  return AVERROR(ENOMEM);
7597 
7598  for (i = 0; i < sample_count; i++) {
7599  unsigned int min_samples = FFMIN(FFMAX(i + 1, 1024 * 1024), sample_count);
7600  encrypted_samples = av_fast_realloc(encryption_index->encrypted_samples, &alloc_size,
7601  min_samples * sizeof(*encrypted_samples));
7602  if (encrypted_samples) {
7603  encryption_index->encrypted_samples = encrypted_samples;
7604 
7606  c, pb, sc, &encryption_index->encrypted_samples[i], use_subsamples);
7607  } else {
7608  ret = AVERROR(ENOMEM);
7609  }
7610  if (pb->eof_reached) {
7611  av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading senc\n");
7612  if (ret >= 0)
7613  av_encryption_info_free(encryption_index->encrypted_samples[i]);
7615  }
7616 
7617  if (ret < 0) {
7618  for (; i > 0; i--)
7619  av_encryption_info_free(encryption_index->encrypted_samples[i - 1]);
7620  av_freep(&encryption_index->encrypted_samples);
7621  return ret;
7622  }
7623  }
7624  encryption_index->nb_encrypted_samples = sample_count;
7625 
7626  return 0;
7627 }
7628 
7630 {
7631  AVEncryptionInfo **sample, **encrypted_samples;
7632  int64_t prev_pos;
7633  size_t sample_count, sample_info_size, i;
7634  int ret = 0;
7635  unsigned int alloc_size = 0;
7636 
7637  if (encryption_index->nb_encrypted_samples)
7638  return 0;
7639  sample_count = encryption_index->auxiliary_info_sample_count;
7640  if (encryption_index->auxiliary_offsets_count != 1) {
7641  av_log(c->fc, AV_LOG_ERROR, "Multiple auxiliary info chunks are not supported\n");
7642  return AVERROR_PATCHWELCOME;
7643  }
7644  if (sample_count >= INT_MAX / sizeof(*encrypted_samples))
7645  return AVERROR(ENOMEM);
7646 
7647  prev_pos = avio_tell(pb);
7648  if (!(pb->seekable & AVIO_SEEKABLE_NORMAL) ||
7649  avio_seek(pb, encryption_index->auxiliary_offsets[0], SEEK_SET) != encryption_index->auxiliary_offsets[0]) {
7650  av_log(c->fc, AV_LOG_INFO, "Failed to seek for auxiliary info, will only parse senc atoms for encryption info\n");
7651  goto finish;
7652  }
7653 
7654  for (i = 0; i < sample_count && !pb->eof_reached; i++) {
7655  unsigned int min_samples = FFMIN(FFMAX(i + 1, 1024 * 1024), sample_count);
7656  encrypted_samples = av_fast_realloc(encryption_index->encrypted_samples, &alloc_size,
7657  min_samples * sizeof(*encrypted_samples));
7658  if (!encrypted_samples) {
7659  ret = AVERROR(ENOMEM);
7660  goto finish;
7661  }
7662  encryption_index->encrypted_samples = encrypted_samples;
7663 
7664  sample = &encryption_index->encrypted_samples[i];
7665  sample_info_size = encryption_index->auxiliary_info_default_size
7666  ? encryption_index->auxiliary_info_default_size
7667  : encryption_index->auxiliary_info_sizes[i];
7668 
7669  ret = mov_read_sample_encryption_info(c, pb, sc, sample, sample_info_size > sc->cenc.per_sample_iv_size);
7670  if (ret < 0)
7671  goto finish;
7672  }
7673  if (pb->eof_reached) {
7674  av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading auxiliary info\n");
7676  } else {
7677  encryption_index->nb_encrypted_samples = sample_count;
7678  }
7679 
7680 finish:
7681  avio_seek(pb, prev_pos, SEEK_SET);
7682  if (ret < 0) {
7683  for (; i > 0; i--) {
7684  av_encryption_info_free(encryption_index->encrypted_samples[i - 1]);
7685  }
7686  av_freep(&encryption_index->encrypted_samples);
7687  }
7688  return ret;
7689 }
7690 
7692 {
7693  MOVEncryptionIndex *encryption_index;
7694  MOVStreamContext *sc;
7695  int ret;
7696  unsigned int sample_count, aux_info_type, aux_info_param;
7697 
7698  ret = get_current_encryption_info(c, &encryption_index, &sc);
7699  if (ret != 1)
7700  return ret;
7701 
7702  if (encryption_index->nb_encrypted_samples) {
7703  // This can happen if we have both saio/saiz and senc atoms.
7704  av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in saiz\n");
7705  return 0;
7706  }
7707 
7708  if (encryption_index->auxiliary_info_sample_count) {
7709  av_log(c->fc, AV_LOG_ERROR, "Duplicate saiz atom\n");
7710  return AVERROR_INVALIDDATA;
7711  }
7712 
7713  avio_r8(pb); /* version */
7714  if (avio_rb24(pb) & 0x01) { /* flags */
7715  aux_info_type = avio_rb32(pb);
7716  aux_info_param = avio_rb32(pb);
7717  if (sc->cenc.default_encrypted_sample) {
7718  if (aux_info_type != sc->cenc.default_encrypted_sample->scheme) {
7719  av_log(c->fc, AV_LOG_DEBUG, "Ignoring saiz box with non-zero aux_info_type\n");
7720  return 0;
7721  }
7722  if (aux_info_param != 0) {
7723  av_log(c->fc, AV_LOG_DEBUG, "Ignoring saiz box with non-zero aux_info_type_parameter\n");
7724  return 0;
7725  }
7726  } else {
7727  // Didn't see 'schm' or 'tenc', so this isn't encrypted.
7728  if ((aux_info_type == MKBETAG('c','e','n','c') ||
7729  aux_info_type == MKBETAG('c','e','n','s') ||
7730  aux_info_type == MKBETAG('c','b','c','1') ||
7731  aux_info_type == MKBETAG('c','b','c','s')) &&
7732  aux_info_param == 0) {
7733  av_log(c->fc, AV_LOG_ERROR, "Saw encrypted saiz without schm/tenc\n");
7734  return AVERROR_INVALIDDATA;
7735  } else {
7736  return 0;
7737  }
7738  }
7739  } else if (!sc->cenc.default_encrypted_sample) {
7740  // Didn't see 'schm' or 'tenc', so this isn't encrypted.
7741  return 0;
7742  }
7743 
7744  encryption_index->auxiliary_info_default_size = avio_r8(pb);
7745  sample_count = avio_rb32(pb);
7746 
7747  if (encryption_index->auxiliary_info_default_size == 0) {
7748  if (sample_count == 0)
7749  return AVERROR_INVALIDDATA;
7750 
7751  encryption_index->auxiliary_info_sizes = av_malloc(sample_count);
7752  if (!encryption_index->auxiliary_info_sizes)
7753  return AVERROR(ENOMEM);
7754 
7755  ret = avio_read(pb, encryption_index->auxiliary_info_sizes, sample_count);
7756  if (ret != sample_count) {
7757  av_freep(&encryption_index->auxiliary_info_sizes);
7758 
7759  if (ret >= 0)
7761  av_log(c->fc, AV_LOG_ERROR, "Failed to read the auxiliary info, %s\n",
7762  av_err2str(ret));
7763  return ret;
7764  }
7765  }
7766  encryption_index->auxiliary_info_sample_count = sample_count;
7767 
7768  if (encryption_index->auxiliary_offsets_count) {
7769  return mov_parse_auxiliary_info(c, sc, pb, encryption_index);
7770  }
7771 
7772  return 0;
7773 }
7774 
7776 {
7777  uint64_t *auxiliary_offsets;
7778  MOVEncryptionIndex *encryption_index;
7779  MOVStreamContext *sc;
7780  int i, ret;
7781  unsigned int version, entry_count, aux_info_type, aux_info_param;
7782  unsigned int alloc_size = 0;
7783 
7784  ret = get_current_encryption_info(c, &encryption_index, &sc);
7785  if (ret != 1)
7786  return ret;
7787 
7788  if (encryption_index->nb_encrypted_samples) {
7789  // This can happen if we have both saio/saiz and senc atoms.
7790  av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in saio\n");
7791  return 0;
7792  }
7793 
7794  if (encryption_index->auxiliary_offsets_count) {
7795  av_log(c->fc, AV_LOG_ERROR, "Duplicate saio atom\n");
7796  return AVERROR_INVALIDDATA;
7797  }
7798 
7799  version = avio_r8(pb); /* version */
7800  if (avio_rb24(pb) & 0x01) { /* flags */
7801  aux_info_type = avio_rb32(pb);
7802  aux_info_param = avio_rb32(pb);
7803  if (sc->cenc.default_encrypted_sample) {
7804  if (aux_info_type != sc->cenc.default_encrypted_sample->scheme) {
7805  av_log(c->fc, AV_LOG_DEBUG, "Ignoring saio box with non-zero aux_info_type\n");
7806  return 0;
7807  }
7808  if (aux_info_param != 0) {
7809  av_log(c->fc, AV_LOG_DEBUG, "Ignoring saio box with non-zero aux_info_type_parameter\n");
7810  return 0;
7811  }
7812  } else {
7813  // Didn't see 'schm' or 'tenc', so this isn't encrypted.
7814  if ((aux_info_type == MKBETAG('c','e','n','c') ||
7815  aux_info_type == MKBETAG('c','e','n','s') ||
7816  aux_info_type == MKBETAG('c','b','c','1') ||
7817  aux_info_type == MKBETAG('c','b','c','s')) &&
7818  aux_info_param == 0) {
7819  av_log(c->fc, AV_LOG_ERROR, "Saw encrypted saio without schm/tenc\n");
7820  return AVERROR_INVALIDDATA;
7821  } else {
7822  return 0;
7823  }
7824  }
7825  } else if (!sc->cenc.default_encrypted_sample) {
7826  // Didn't see 'schm' or 'tenc', so this isn't encrypted.
7827  return 0;
7828  }
7829 
7830  entry_count = avio_rb32(pb);
7831  if (entry_count >= INT_MAX / sizeof(*auxiliary_offsets))
7832  return AVERROR(ENOMEM);
7833 
7834  for (i = 0; i < entry_count && !pb->eof_reached; i++) {
7835  unsigned int min_offsets = FFMIN(FFMAX(i + 1, 1024), entry_count);
7836  auxiliary_offsets = av_fast_realloc(
7837  encryption_index->auxiliary_offsets, &alloc_size,
7838  min_offsets * sizeof(*auxiliary_offsets));
7839  if (!auxiliary_offsets) {
7840  av_freep(&encryption_index->auxiliary_offsets);
7841  return AVERROR(ENOMEM);
7842  }
7843  encryption_index->auxiliary_offsets = auxiliary_offsets;
7844 
7845  if (version == 0) {
7846  encryption_index->auxiliary_offsets[i] = avio_rb32(pb);
7847  } else {
7848  encryption_index->auxiliary_offsets[i] = avio_rb64(pb);
7849  }
7850  if (c->frag_index.current >= 0) {
7851  encryption_index->auxiliary_offsets[i] += c->fragment.base_data_offset;
7852  }
7853  }
7854 
7855  if (pb->eof_reached) {
7856  av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading saio\n");
7857  av_freep(&encryption_index->auxiliary_offsets);
7858  return AVERROR_INVALIDDATA;
7859  }
7860 
7861  encryption_index->auxiliary_offsets_count = entry_count;
7862 
7863  if (encryption_index->auxiliary_info_sample_count) {
7864  return mov_parse_auxiliary_info(c, sc, pb, encryption_index);
7865  }
7866 
7867  return 0;
7868 }
7869 
7871 {
7872  AVEncryptionInitInfo *info, *old_init_info;
7873  uint8_t **key_ids;
7874  AVStream *st;
7875  const AVPacketSideData *old_side_data;
7876  uint8_t *side_data, *extra_data;
7877  size_t side_data_size;
7878  int ret = 0;
7879  unsigned int version, kid_count, extra_data_size, alloc_size = 0;
7880 
7881  if (c->fc->nb_streams < 1)
7882  return 0;
7883  st = c->fc->streams[c->fc->nb_streams-1];
7884 
7885  version = avio_r8(pb); /* version */
7886  avio_rb24(pb); /* flags */
7887 
7888  info = av_encryption_init_info_alloc(/* system_id_size */ 16, /* num_key_ids */ 0,
7889  /* key_id_size */ 16, /* data_size */ 0);
7890  if (!info)
7891  return AVERROR(ENOMEM);
7892 
7893  if ((ret = ffio_read_size(pb, info->system_id, 16)) < 0) {
7894  av_log(c->fc, AV_LOG_ERROR, "Failed to read the system id\n");
7895  goto finish;
7896  }
7897 
7898  if (version > 0) {
7899  kid_count = avio_rb32(pb);
7900  if (kid_count >= INT_MAX / sizeof(*key_ids)) {
7901  ret = AVERROR(ENOMEM);
7902  goto finish;
7903  }
7904 
7905  for (unsigned int i = 0; i < kid_count && !pb->eof_reached; i++) {
7906  unsigned int min_kid_count = FFMIN(FFMAX(i + 1, 1024), kid_count);
7907  key_ids = av_fast_realloc(info->key_ids, &alloc_size,
7908  min_kid_count * sizeof(*key_ids));
7909  if (!key_ids) {
7910  ret = AVERROR(ENOMEM);
7911  goto finish;
7912  }
7913  info->key_ids = key_ids;
7914 
7915  info->key_ids[i] = av_mallocz(16);
7916  if (!info->key_ids[i]) {
7917  ret = AVERROR(ENOMEM);
7918  goto finish;
7919  }
7920  info->num_key_ids = i + 1;
7921 
7922  if ((ret = ffio_read_size(pb, info->key_ids[i], 16)) < 0) {
7923  av_log(c->fc, AV_LOG_ERROR, "Failed to read the key id\n");
7924  goto finish;
7925  }
7926  }
7927 
7928  if (pb->eof_reached) {
7929  av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading pssh\n");
7931  goto finish;
7932  }
7933  }
7934 
7935  extra_data_size = avio_rb32(pb);
7936  extra_data = av_malloc(extra_data_size);
7937  if (!extra_data) {
7938  ret = AVERROR(ENOMEM);
7939  goto finish;
7940  }
7941  ret = avio_read(pb, extra_data, extra_data_size);
7942  if (ret != extra_data_size) {
7943  av_free(extra_data);
7944 
7945  if (ret >= 0)
7947  goto finish;
7948  }
7949 
7950  av_freep(&info->data); // malloc(0) may still allocate something.
7951  info->data = extra_data;
7952  info->data_size = extra_data_size;
7953 
7954  // If there is existing initialization data, append to the list.
7957  if (old_side_data) {
7958  old_init_info = av_encryption_init_info_get_side_data(old_side_data->data, old_side_data->size);
7959  if (old_init_info) {
7960  // Append to the end of the list.
7961  for (AVEncryptionInitInfo *cur = old_init_info;; cur = cur->next) {
7962  if (!cur->next) {
7963  cur->next = info;
7964  break;
7965  }
7966  }
7967  info = old_init_info;
7968  } else {
7969  // Assume existing side-data will be valid, so the only error we could get is OOM.
7970  ret = AVERROR(ENOMEM);
7971  goto finish;
7972  }
7973  }
7974 
7975  side_data = av_encryption_init_info_add_side_data(info, &side_data_size);
7976  if (!side_data) {
7977  ret = AVERROR(ENOMEM);
7978  goto finish;
7979  }
7983  side_data, side_data_size, 0))
7984  av_free(side_data);
7985 
7986 finish:
7988  return ret;
7989 }
7990 
7992 {
7993  AVStream *st;
7994  MOVStreamContext *sc;
7995 
7996  if (c->fc->nb_streams < 1)
7997  return 0;
7998  st = c->fc->streams[c->fc->nb_streams-1];
7999  sc = st->priv_data;
8000 
8001  if (sc->pseudo_stream_id != 0) {
8002  av_log(c->fc, AV_LOG_ERROR, "schm boxes are only supported in first sample descriptor\n");
8003  return AVERROR_PATCHWELCOME;
8004  }
8005 
8006  if (atom.size < 8)
8007  return AVERROR_INVALIDDATA;
8008 
8009  avio_rb32(pb); /* version and flags */
8010 
8011  if (!sc->cenc.default_encrypted_sample) {
8013  if (!sc->cenc.default_encrypted_sample) {
8014  return AVERROR(ENOMEM);
8015  }
8016  }
8017 
8019  return 0;
8020 }
8021 
8023 {
8024  AVStream *st;
8025  MOVStreamContext *sc;
8026  unsigned int version, pattern, is_protected, iv_size;
8027 
8028  if (c->fc->nb_streams < 1)
8029  return 0;
8030  st = c->fc->streams[c->fc->nb_streams-1];
8031  sc = st->priv_data;
8032 
8033  if (sc->pseudo_stream_id != 0) {
8034  av_log(c->fc, AV_LOG_ERROR, "tenc atom are only supported in first sample descriptor\n");
8035  return AVERROR_PATCHWELCOME;
8036  }
8037 
8038  if (!sc->cenc.default_encrypted_sample) {
8040  if (!sc->cenc.default_encrypted_sample) {
8041  return AVERROR(ENOMEM);
8042  }
8043  }
8044 
8045  if (atom.size < 20)
8046  return AVERROR_INVALIDDATA;
8047 
8048  version = avio_r8(pb); /* version */
8049  avio_rb24(pb); /* flags */
8050 
8051  avio_r8(pb); /* reserved */
8052  pattern = avio_r8(pb);
8053 
8054  if (version > 0) {
8055  sc->cenc.default_encrypted_sample->crypt_byte_block = pattern >> 4;
8056  sc->cenc.default_encrypted_sample->skip_byte_block = pattern & 0xf;
8057  }
8058 
8059  is_protected = avio_r8(pb);
8060  if (is_protected && !sc->cenc.encryption_index) {
8061  // The whole stream should be by-default encrypted.
8063  if (!sc->cenc.encryption_index)
8064  return AVERROR(ENOMEM);
8065  }
8066  sc->cenc.per_sample_iv_size = avio_r8(pb);
8067  if (sc->cenc.per_sample_iv_size != 0 && sc->cenc.per_sample_iv_size != 8 &&
8068  sc->cenc.per_sample_iv_size != 16) {
8069  av_log(c->fc, AV_LOG_ERROR, "invalid per-sample IV size value\n");
8070  return AVERROR_INVALIDDATA;
8071  }
8072  if (avio_read(pb, sc->cenc.default_encrypted_sample->key_id, 16) != 16) {
8073  av_log(c->fc, AV_LOG_ERROR, "failed to read the default key ID\n");
8074  return AVERROR_INVALIDDATA;
8075  }
8076 
8077  if (is_protected && !sc->cenc.per_sample_iv_size) {
8078  iv_size = avio_r8(pb);
8079  if (iv_size != 8 && iv_size != 16) {
8080  av_log(c->fc, AV_LOG_ERROR, "invalid default_constant_IV_size in tenc atom\n");
8081  return AVERROR_INVALIDDATA;
8082  }
8083 
8084  if (avio_read(pb, sc->cenc.default_encrypted_sample->iv, iv_size) != iv_size) {
8085  av_log(c->fc, AV_LOG_ERROR, "failed to read the default IV\n");
8086  return AVERROR_INVALIDDATA;
8087  }
8088  }
8089 
8090  return 0;
8091 }
8092 
8094 {
8095  AVStream *st;
8096  int last, type, size, ret;
8097  uint8_t buf[4];
8098 
8099  if (c->fc->nb_streams < 1)
8100  return 0;
8101  st = c->fc->streams[c->fc->nb_streams-1];
8102 
8103  if ((uint64_t)atom.size > (1<<30) || atom.size < 42)
8104  return AVERROR_INVALIDDATA;
8105 
8106  /* Check FlacSpecificBox version. */
8107  if (avio_r8(pb) != 0)
8108  return AVERROR_INVALIDDATA;
8109 
8110  avio_rb24(pb); /* Flags */
8111 
8112  if (avio_read(pb, buf, sizeof(buf)) != sizeof(buf)) {
8113  av_log(c->fc, AV_LOG_ERROR, "failed to read FLAC metadata block header\n");
8114  return pb->error < 0 ? pb->error : AVERROR_INVALIDDATA;
8115  }
8116  flac_parse_block_header(buf, &last, &type, &size);
8117 
8119  av_log(c->fc, AV_LOG_ERROR, "STREAMINFO must be first FLACMetadataBlock\n");
8120  return AVERROR_INVALIDDATA;
8121  }
8122 
8123  ret = ff_get_extradata(c->fc, st->codecpar, pb, size);
8124  if (ret < 0)
8125  return ret;
8126 
8127  if (!last)
8128  av_log(c->fc, AV_LOG_WARNING, "non-STREAMINFO FLACMetadataBlock(s) ignored\n");
8129 
8130  return 0;
8131 }
8132 
8134 {
8135  int i, ret;
8136  int bytes_of_protected_data;
8137 
8138  if (!sc->cenc.aes_ctr) {
8139  /* initialize the cipher */
8140  sc->cenc.aes_ctr = av_aes_ctr_alloc();
8141  if (!sc->cenc.aes_ctr) {
8142  return AVERROR(ENOMEM);
8143  }
8144 
8145  ret = av_aes_ctr_init(sc->cenc.aes_ctr, c->decryption_key);
8146  if (ret < 0) {
8147  return ret;
8148  }
8149  }
8150 
8152 
8153  if (!sample->subsample_count) {
8154  /* decrypt the whole packet */
8156  return 0;
8157  }
8158 
8159  for (i = 0; i < sample->subsample_count; i++) {
8160  if (sample->subsamples[i].bytes_of_clear_data + sample->subsamples[i].bytes_of_protected_data > size) {
8161  av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n");
8162  return AVERROR_INVALIDDATA;
8163  }
8164 
8165  /* skip the clear bytes */
8166  input += sample->subsamples[i].bytes_of_clear_data;
8167  size -= sample->subsamples[i].bytes_of_clear_data;
8168 
8169  /* decrypt the encrypted bytes */
8170 
8171  bytes_of_protected_data = sample->subsamples[i].bytes_of_protected_data;
8172  av_aes_ctr_crypt(sc->cenc.aes_ctr, input, input, bytes_of_protected_data);
8173 
8174  input += bytes_of_protected_data;
8175  size -= bytes_of_protected_data;
8176  }
8177 
8178  if (size > 0) {
8179  av_log(c->fc, AV_LOG_ERROR, "leftover packet bytes after subsample processing\n");
8180  return AVERROR_INVALIDDATA;
8181  }
8182 
8183  return 0;
8184 }
8185 
8187 {
8188  int i, ret;
8189  int num_of_encrypted_blocks;
8190  uint8_t iv[16];
8191 
8192  if (!sc->cenc.aes_ctx) {
8193  /* initialize the cipher */
8194  sc->cenc.aes_ctx = av_aes_alloc();
8195  if (!sc->cenc.aes_ctx) {
8196  return AVERROR(ENOMEM);
8197  }
8198 
8199  ret = av_aes_init(sc->cenc.aes_ctx, c->decryption_key, 16 * 8, 1);
8200  if (ret < 0) {
8201  return ret;
8202  }
8203  }
8204 
8205  memcpy(iv, sample->iv, 16);
8206 
8207  /* whole-block full sample encryption */
8208  if (!sample->subsample_count) {
8209  /* decrypt the whole packet */
8210  av_aes_crypt(sc->cenc.aes_ctx, input, input, size/16, iv, 1);
8211  return 0;
8212  }
8213 
8214  for (i = 0; i < sample->subsample_count; i++) {
8215  if (sample->subsamples[i].bytes_of_clear_data + sample->subsamples[i].bytes_of_protected_data > size) {
8216  av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n");
8217  return AVERROR_INVALIDDATA;
8218  }
8219 
8220  if (sample->subsamples[i].bytes_of_protected_data % 16) {
8221  av_log(c->fc, AV_LOG_ERROR, "subsample BytesOfProtectedData is not a multiple of 16\n");
8222  return AVERROR_INVALIDDATA;
8223  }
8224 
8225  /* skip the clear bytes */
8226  input += sample->subsamples[i].bytes_of_clear_data;
8227  size -= sample->subsamples[i].bytes_of_clear_data;
8228 
8229  /* decrypt the encrypted bytes */
8230  num_of_encrypted_blocks = sample->subsamples[i].bytes_of_protected_data/16;
8231  if (num_of_encrypted_blocks > 0) {
8232  av_aes_crypt(sc->cenc.aes_ctx, input, input, num_of_encrypted_blocks, iv, 1);
8233  }
8234  input += sample->subsamples[i].bytes_of_protected_data;
8235  size -= sample->subsamples[i].bytes_of_protected_data;
8236  }
8237 
8238  if (size > 0) {
8239  av_log(c->fc, AV_LOG_ERROR, "leftover packet bytes after subsample processing\n");
8240  return AVERROR_INVALIDDATA;
8241  }
8242 
8243  return 0;
8244 }
8245 
8247 {
8248  int i, ret, rem_bytes;
8249  uint8_t *data;
8250 
8251  if (!sc->cenc.aes_ctr) {
8252  /* initialize the cipher */
8253  sc->cenc.aes_ctr = av_aes_ctr_alloc();
8254  if (!sc->cenc.aes_ctr) {
8255  return AVERROR(ENOMEM);
8256  }
8257 
8258  ret = av_aes_ctr_init(sc->cenc.aes_ctr, c->decryption_key);
8259  if (ret < 0) {
8260  return ret;
8261  }
8262  }
8263 
8265 
8266  /* whole-block full sample encryption */
8267  if (!sample->subsample_count) {
8268  /* decrypt the whole packet */
8270  return 0;
8271  } else if (!sample->crypt_byte_block && !sample->skip_byte_block) {
8272  av_log(c->fc, AV_LOG_ERROR, "pattern encryption is not present in 'cens' scheme\n");
8273  return AVERROR_INVALIDDATA;
8274  }
8275 
8276  for (i = 0; i < sample->subsample_count; i++) {
8277  if (sample->subsamples[i].bytes_of_clear_data + sample->subsamples[i].bytes_of_protected_data > size) {
8278  av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n");
8279  return AVERROR_INVALIDDATA;
8280  }
8281 
8282  /* skip the clear bytes */
8283  input += sample->subsamples[i].bytes_of_clear_data;
8284  size -= sample->subsamples[i].bytes_of_clear_data;
8285 
8286  /* decrypt the encrypted bytes */
8287  data = input;
8288  rem_bytes = sample->subsamples[i].bytes_of_protected_data;
8289  while (rem_bytes > 0) {
8290  if (rem_bytes < 16*sample->crypt_byte_block) {
8291  break;
8292  }
8293  av_aes_ctr_crypt(sc->cenc.aes_ctr, data, data, 16*sample->crypt_byte_block);
8294  data += 16*sample->crypt_byte_block;
8295  rem_bytes -= 16*sample->crypt_byte_block;
8296  data += FFMIN(16*sample->skip_byte_block, rem_bytes);
8297  rem_bytes -= FFMIN(16*sample->skip_byte_block, rem_bytes);
8298  }
8299  input += sample->subsamples[i].bytes_of_protected_data;
8300  size -= sample->subsamples[i].bytes_of_protected_data;
8301  }
8302 
8303  if (size > 0) {
8304  av_log(c->fc, AV_LOG_ERROR, "leftover packet bytes after subsample processing\n");
8305  return AVERROR_INVALIDDATA;
8306  }
8307 
8308  return 0;
8309 }
8310 
8312 {
8313  int i, ret, rem_bytes;
8314  uint8_t iv[16];
8315  uint8_t *data;
8316 
8317  if (!sc->cenc.aes_ctx) {
8318  /* initialize the cipher */
8319  sc->cenc.aes_ctx = av_aes_alloc();
8320  if (!sc->cenc.aes_ctx) {
8321  return AVERROR(ENOMEM);
8322  }
8323 
8324  ret = av_aes_init(sc->cenc.aes_ctx, c->decryption_key, 16 * 8, 1);
8325  if (ret < 0) {
8326  return ret;
8327  }
8328  }
8329 
8330  /* whole-block full sample encryption */
8331  if (!sample->subsample_count) {
8332  /* decrypt the whole packet */
8333  memcpy(iv, sample->iv, 16);
8334  av_aes_crypt(sc->cenc.aes_ctx, input, input, size/16, iv, 1);
8335  return 0;
8336  } else if (!sample->crypt_byte_block && !sample->skip_byte_block) {
8337  av_log(c->fc, AV_LOG_ERROR, "pattern encryption is not present in 'cbcs' scheme\n");
8338  return AVERROR_INVALIDDATA;
8339  }
8340 
8341  for (i = 0; i < sample->subsample_count; i++) {
8342  if (sample->subsamples[i].bytes_of_clear_data + sample->subsamples[i].bytes_of_protected_data > size) {
8343  av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n");
8344  return AVERROR_INVALIDDATA;
8345  }
8346 
8347  /* skip the clear bytes */
8348  input += sample->subsamples[i].bytes_of_clear_data;
8349  size -= sample->subsamples[i].bytes_of_clear_data;
8350 
8351  /* decrypt the encrypted bytes */
8352  memcpy(iv, sample->iv, 16);
8353  data = input;
8354  rem_bytes = sample->subsamples[i].bytes_of_protected_data;
8355  while (rem_bytes > 0) {
8356  if (rem_bytes < 16*sample->crypt_byte_block) {
8357  break;
8358  }
8359  av_aes_crypt(sc->cenc.aes_ctx, data, data, sample->crypt_byte_block, iv, 1);
8360  data += 16*sample->crypt_byte_block;
8361  rem_bytes -= 16*sample->crypt_byte_block;
8362  data += FFMIN(16*sample->skip_byte_block, rem_bytes);
8363  rem_bytes -= FFMIN(16*sample->skip_byte_block, rem_bytes);
8364  }
8365  input += sample->subsamples[i].bytes_of_protected_data;
8366  size -= sample->subsamples[i].bytes_of_protected_data;
8367  }
8368 
8369  if (size > 0) {
8370  av_log(c->fc, AV_LOG_ERROR, "leftover packet bytes after subsample processing\n");
8371  return AVERROR_INVALIDDATA;
8372  }
8373 
8374  return 0;
8375 }
8376 
8378 {
8379  if (sample->scheme == MKBETAG('c','e','n','c') && !sample->crypt_byte_block && !sample->skip_byte_block) {
8380  return cenc_scheme_decrypt(c, sc, sample, input, size);
8381  } else if (sample->scheme == MKBETAG('c','b','c','1') && !sample->crypt_byte_block && !sample->skip_byte_block) {
8382  return cbc1_scheme_decrypt(c, sc, sample, input, size);
8383  } else if (sample->scheme == MKBETAG('c','e','n','s')) {
8384  return cens_scheme_decrypt(c, sc, sample, input, size);
8385  } else if (sample->scheme == MKBETAG('c','b','c','s')) {
8386  return cbcs_scheme_decrypt(c, sc, sample, input, size);
8387  } else {
8388  av_log(c->fc, AV_LOG_ERROR, "invalid encryption scheme\n");
8389  return AVERROR_INVALIDDATA;
8390  }
8391 }
8392 
8394 {
8395  int current = frag_index->current;
8396 
8397  if (!frag_index->nb_items)
8398  return NULL;
8399 
8400  // Check frag_index->current is the right one for pkt. It can out of sync.
8401  if (current >= 0 && current < frag_index->nb_items) {
8402  if (frag_index->item[current].moof_offset < pkt->pos &&
8403  (current + 1 == frag_index->nb_items ||
8404  frag_index->item[current + 1].moof_offset > pkt->pos))
8405  return get_frag_stream_info(frag_index, current, id);
8406  }
8407 
8408 
8409  for (int i = 0; i < frag_index->nb_items; i++) {
8410  if (frag_index->item[i].moof_offset > pkt->pos)
8411  break;
8412  current = i;
8413  }
8414  frag_index->current = current;
8415  return get_frag_stream_info(frag_index, current, id);
8416 }
8417 
8418 static int cenc_filter(MOVContext *mov, AVStream* st, MOVStreamContext *sc, AVPacket *pkt, int current_index)
8419 {
8420  MOVFragmentStreamInfo *frag_stream_info;
8421  MOVEncryptionIndex *encryption_index;
8422  AVEncryptionInfo *encrypted_sample;
8423  int encrypted_index, ret;
8424 
8425  frag_stream_info = get_frag_stream_info_from_pkt(&mov->frag_index, pkt, sc->id);
8426  encrypted_index = current_index;
8427  encryption_index = NULL;
8428  if (frag_stream_info) {
8429  // Note this only supports encryption info in the first sample descriptor.
8430  if (frag_stream_info->stsd_id == 1) {
8431  if (frag_stream_info->encryption_index) {
8432  encrypted_index = current_index - frag_stream_info->index_base;
8433  encryption_index = frag_stream_info->encryption_index;
8434  } else {
8435  encryption_index = sc->cenc.encryption_index;
8436  }
8437  }
8438  } else {
8439  encryption_index = sc->cenc.encryption_index;
8440  }
8441 
8442  if (encryption_index) {
8443  if (encryption_index->auxiliary_info_sample_count &&
8444  !encryption_index->nb_encrypted_samples) {
8445  av_log(mov->fc, AV_LOG_ERROR, "saiz atom found without saio\n");
8446  return AVERROR_INVALIDDATA;
8447  }
8448  if (encryption_index->auxiliary_offsets_count &&
8449  !encryption_index->nb_encrypted_samples) {
8450  av_log(mov->fc, AV_LOG_ERROR, "saio atom found without saiz\n");
8451  return AVERROR_INVALIDDATA;
8452  }
8453 
8454  encrypted_sample = NULL;
8455  if (!encryption_index->nb_encrypted_samples) {
8456  // Full-sample encryption with default settings.
8457  encrypted_sample = sc->cenc.default_encrypted_sample;
8458  } else if (encrypted_index >= 0 && encrypted_index < encryption_index->nb_encrypted_samples) {
8459  // Per-sample setting override.
8460  encrypted_sample = encryption_index->encrypted_samples[encrypted_index];
8461  if (!encrypted_sample) {
8462  encrypted_sample = sc->cenc.default_encrypted_sample;
8463  }
8464  }
8465 
8466  if (!encrypted_sample) {
8467  av_log(mov->fc, AV_LOG_ERROR, "Incorrect number of samples in encryption info\n");
8468  return AVERROR_INVALIDDATA;
8469  }
8470 
8471  if (mov->decryption_key) {
8472  return cenc_decrypt(mov, sc, encrypted_sample, pkt->data, pkt->size);
8473  } else {
8474  size_t size;
8475  uint8_t *side_data = av_encryption_info_add_side_data(encrypted_sample, &size);
8476  if (!side_data)
8477  return AVERROR(ENOMEM);
8479  if (ret < 0)
8480  av_free(side_data);
8481  return ret;
8482  }
8483  }
8484 
8485  return 0;
8486 }
8487 
8489 {
8490  const int OPUS_SEEK_PREROLL_MS = 80;
8491  int ret;
8492  AVStream *st;
8493  size_t size;
8494  uint16_t pre_skip;
8495 
8496  if (c->fc->nb_streams < 1)
8497  return 0;
8498  st = c->fc->streams[c->fc->nb_streams-1];
8499 
8500  if ((uint64_t)atom.size > (1<<30) || atom.size < 11)
8501  return AVERROR_INVALIDDATA;
8502 
8503  /* Check OpusSpecificBox version. */
8504  if (avio_r8(pb) != 0) {
8505  av_log(c->fc, AV_LOG_ERROR, "unsupported OpusSpecificBox version\n");
8506  return AVERROR_INVALIDDATA;
8507  }
8508 
8509  /* OpusSpecificBox size plus magic for Ogg OpusHead header. */
8510  size = atom.size + 8;
8511 
8512  if ((ret = ff_alloc_extradata(st->codecpar, size)) < 0)
8513  return ret;
8514 
8515  AV_WL32A(st->codecpar->extradata, MKTAG('O','p','u','s'));
8516  AV_WL32A(st->codecpar->extradata + 4, MKTAG('H','e','a','d'));
8517  AV_WB8(st->codecpar->extradata + 8, 1); /* OpusHead version */
8518  avio_read(pb, st->codecpar->extradata + 9, size - 9);
8519 
8520  /* OpusSpecificBox is stored in big-endian, but OpusHead is
8521  little-endian; aside from the preceding magic and version they're
8522  otherwise currently identical. Data after output gain at offset 16
8523  doesn't need to be bytewapped. */
8524  pre_skip = AV_RB16A(st->codecpar->extradata + 10);
8525  AV_WL16A(st->codecpar->extradata + 10, pre_skip);
8526  AV_WL32A(st->codecpar->extradata + 12, AV_RB32A(st->codecpar->extradata + 12));
8527  AV_WL16A(st->codecpar->extradata + 16, AV_RB16A(st->codecpar->extradata + 16));
8528 
8529  st->codecpar->initial_padding = pre_skip;
8531  (AVRational){1, 1000},
8532  (AVRational){1, 48000});
8533 
8534  return 0;
8535 }
8536 
8538 {
8539  AVStream *st;
8540  unsigned format_info;
8541  int channel_assignment, channel_assignment1, channel_assignment2;
8542  int ratebits;
8543  uint64_t chmask;
8544 
8545  if (c->fc->nb_streams < 1)
8546  return 0;
8547  st = c->fc->streams[c->fc->nb_streams-1];
8548 
8549  if (atom.size < 10)
8550  return AVERROR_INVALIDDATA;
8551 
8552  format_info = avio_rb32(pb);
8553 
8554  ratebits = (format_info >> 28) & 0xF;
8555  channel_assignment1 = (format_info >> 15) & 0x1F;
8556  channel_assignment2 = format_info & 0x1FFF;
8557  if (channel_assignment2)
8558  channel_assignment = channel_assignment2;
8559  else
8560  channel_assignment = channel_assignment1;
8561 
8562  st->codecpar->frame_size = 40 << (ratebits & 0x7);
8563  st->codecpar->sample_rate = mlp_samplerate(ratebits);
8564 
8566  chmask = truehd_layout(channel_assignment);
8568 
8569  return 0;
8570 }
8571 
8573 {
8574  AVStream *st;
8575  uint8_t buf[ISOM_DVCC_DVVC_SIZE];
8576  int ret;
8577  int64_t read_size = atom.size;
8578 
8579  if (c->fc->nb_streams < 1)
8580  return 0;
8581  st = c->fc->streams[c->fc->nb_streams-1];
8582 
8583  // At most 24 bytes
8584  read_size = FFMIN(read_size, ISOM_DVCC_DVVC_SIZE);
8585 
8586  if ((ret = ffio_read_size(pb, buf, read_size)) < 0)
8587  return ret;
8588 
8589  return ff_isom_parse_dvcc_dvvc(c->fc, st, buf, read_size);
8590 }
8591 
8593 {
8594  AVStream *st;
8595  uint8_t *buf;
8596  int ret, old_size, num_arrays;
8597 
8598  if (c->fc->nb_streams < 1)
8599  return 0;
8600  st = c->fc->streams[c->fc->nb_streams-1];
8601 
8602  if (!st->codecpar->extradata_size)
8603  // TODO: handle lhvC when present before hvcC
8604  return 0;
8605 
8606  if (atom.size < 6 || st->codecpar->extradata_size < 23)
8607  return AVERROR_INVALIDDATA;
8608 
8610  if (!buf)
8611  return AVERROR(ENOMEM);
8612  memset(buf + atom.size, 0, AV_INPUT_BUFFER_PADDING_SIZE);
8613 
8614  ret = ffio_read_size(pb, buf, atom.size);
8615  if (ret < 0) {
8616  av_free(buf);
8617  av_log(c->fc, AV_LOG_WARNING, "lhvC atom truncated\n");
8618  return 0;
8619  }
8620 
8621  num_arrays = buf[5];
8622  old_size = st->codecpar->extradata_size;
8623  atom.size -= 8 /* account for mov_realloc_extradata offsetting */
8624  + 6 /* lhvC bytes before the arrays*/;
8625 
8626  ret = mov_realloc_extradata(st->codecpar, atom);
8627  if (ret < 0) {
8628  av_free(buf);
8629  return ret;
8630  }
8631 
8632  st->codecpar->extradata[22] += num_arrays;
8633  memcpy(st->codecpar->extradata + old_size, buf + 6, atom.size + 8);
8634 
8636 
8637  av_free(buf);
8638  return 0;
8639 }
8640 
8642 {
8643  AVFormatContext *ctx = c->fc;
8644  AVStream *st = NULL;
8645  AVBPrint scheme_buf, value_buf;
8646  int64_t scheme_str_len = 0, value_str_len = 0;
8647  int version, flags, ret = AVERROR_BUG;
8648  int64_t size = atom.size;
8649 
8650  if (atom.size < 6)
8651  // 4 bytes for version + flags, 2x 1 byte for null
8652  return AVERROR_INVALIDDATA;
8653 
8654  if (c->fc->nb_streams < 1)
8655  return 0;
8656  st = c->fc->streams[c->fc->nb_streams-1];
8657 
8658  version = avio_r8(pb);
8659  flags = avio_rb24(pb);
8660  size -= 4;
8661 
8662  if (version != 0 || flags != 0) {
8664  "Unsupported 'kind' box with version %d, flags: %x",
8665  version, flags);
8666  return AVERROR_INVALIDDATA;
8667  }
8668 
8669  av_bprint_init(&scheme_buf, 0, AV_BPRINT_SIZE_UNLIMITED);
8670  av_bprint_init(&value_buf, 0, AV_BPRINT_SIZE_UNLIMITED);
8671 
8672  if ((scheme_str_len = ff_read_string_to_bprint_overwrite(pb, &scheme_buf,
8673  size)) < 0) {
8674  ret = scheme_str_len;
8675  goto cleanup;
8676  }
8677 
8678  if (scheme_str_len + 1 >= size) {
8679  // we need to have another string, even if nullptr.
8680  // we check with + 1 since we expect that if size was not hit,
8681  // an additional null was read.
8683  goto cleanup;
8684  }
8685 
8686  size -= scheme_str_len + 1;
8687 
8688  if ((value_str_len = ff_read_string_to_bprint_overwrite(pb, &value_buf,
8689  size)) < 0) {
8690  ret = value_str_len;
8691  goto cleanup;
8692  }
8693 
8694  if (value_str_len == size) {
8695  // in case of no trailing null, box is not valid.
8697  goto cleanup;
8698  }
8699 
8701  "%s stream %d KindBox(scheme: %s, value: %s)\n",
8703  st->index,
8704  scheme_buf.str, value_buf.str);
8705 
8706  for (int i = 0; ff_mov_track_kind_table[i].scheme_uri; i++) {
8708  if (!av_strstart(scheme_buf.str, map.scheme_uri, NULL))
8709  continue;
8710 
8711  for (int j = 0; map.value_maps[j].disposition; j++) {
8712  const struct MP4TrackKindValueMapping value_map = map.value_maps[j];
8713  if (!av_strstart(value_buf.str, value_map.value, NULL))
8714  continue;
8715 
8716  st->disposition |= value_map.disposition;
8717  }
8718  }
8719 
8720  ret = 0;
8721 
8722 cleanup:
8723 
8724  av_bprint_finalize(&scheme_buf, NULL);
8725  av_bprint_finalize(&value_buf, NULL);
8726 
8727  return ret;
8728 }
8729 
8731 {
8732  AVStream *st;
8733  AVChannelLayout ch_layout = { 0 };
8734  int ret, i, version, type;
8735  int ambisonic_order, channel_order, normalization, channel_count;
8736  int ambi_channels, non_diegetic_channels;
8737 
8738  if (c->fc->nb_streams < 1)
8739  return 0;
8740 
8741  st = c->fc->streams[c->fc->nb_streams - 1];
8742 
8743  if (atom.size < 16) {
8744  av_log(c->fc, AV_LOG_ERROR, "SA3D audio box too small\n");
8745  return AVERROR_INVALIDDATA;
8746  }
8747 
8748  version = avio_r8(pb);
8749  if (version) {
8750  av_log(c->fc, AV_LOG_WARNING, "Unsupported SA3D box version %d\n", version);
8751  return 0;
8752  }
8753 
8754  type = avio_r8(pb);
8755  if (type & 0x7f) {
8756  av_log(c->fc, AV_LOG_WARNING,
8757  "Unsupported ambisonic type %d\n", type & 0x7f);
8758  return 0;
8759  }
8760  non_diegetic_channels = (type >> 7) * 2; // head_locked_stereo
8761 
8762  ambisonic_order = avio_rb32(pb);
8763 
8764  channel_order = avio_r8(pb);
8765  if (channel_order) {
8766  av_log(c->fc, AV_LOG_WARNING,
8767  "Unsupported channel_order %d\n", channel_order);
8768  return 0;
8769  }
8770 
8771  normalization = avio_r8(pb);
8772  if (normalization) {
8773  av_log(c->fc, AV_LOG_WARNING,
8774  "Unsupported normalization %d\n", normalization);
8775  return 0;
8776  }
8777 
8778  channel_count = avio_rb32(pb);
8779  if (ambisonic_order < 0 || ambisonic_order > 31 ||
8780  channel_count != ((ambisonic_order + 1LL) * (ambisonic_order + 1LL) +
8781  non_diegetic_channels)) {
8782  av_log(c->fc, AV_LOG_ERROR,
8783  "Invalid number of channels (%d / %d)\n",
8784  channel_count, ambisonic_order);
8785  return 0;
8786  }
8787  ambi_channels = channel_count - non_diegetic_channels;
8788 
8789  ret = av_channel_layout_custom_init(&ch_layout, channel_count);
8790  if (ret < 0)
8791  return 0;
8792 
8793  for (i = 0; i < channel_count; i++) {
8794  unsigned channel = avio_rb32(pb);
8795 
8796  if (channel >= channel_count) {
8797  av_log(c->fc, AV_LOG_ERROR, "Invalid channel index (%d / %d)\n",
8798  channel, ambisonic_order);
8799  av_channel_layout_uninit(&ch_layout);
8800  return 0;
8801  }
8802  if (channel >= ambi_channels)
8803  ch_layout.u.map[i].id = channel - ambi_channels;
8804  else
8805  ch_layout.u.map[i].id = AV_CHAN_AMBISONIC_BASE + channel;
8806  }
8807 
8809  if (ret < 0) {
8810  av_channel_layout_uninit(&ch_layout);
8811  return 0;
8812  }
8813 
8815  st->codecpar->ch_layout = ch_layout;
8816 
8817  return 0;
8818 }
8819 
8821 {
8822  AVStream *st;
8823  int version;
8824 
8825  if (c->fc->nb_streams < 1)
8826  return 0;
8827 
8828  st = c->fc->streams[c->fc->nb_streams - 1];
8829 
8830  if (atom.size < 5) {
8831  av_log(c->fc, AV_LOG_ERROR, "Empty SAND audio box\n");
8832  return AVERROR_INVALIDDATA;
8833  }
8834 
8835  version = avio_r8(pb);
8836  if (version) {
8837  av_log(c->fc, AV_LOG_WARNING, "Unsupported SAND box version %d\n", version);
8838  return 0;
8839  }
8840 
8842 
8843  return 0;
8844 }
8845 
8846 static int rb_size(AVIOContext *pb, int64_t *value, int size)
8847 {
8848  if (size == 0)
8849  *value = 0;
8850  else if (size == 1)
8851  *value = avio_r8(pb);
8852  else if (size == 2)
8853  *value = avio_rb16(pb);
8854  else if (size == 4)
8855  *value = avio_rb32(pb);
8856  else if (size == 8) {
8857  *value = avio_rb64(pb);
8858  if (*value < 0)
8859  return -1;
8860  } else
8861  return -1;
8862  return size;
8863 }
8864 
8866 {
8867  avio_rb32(pb); // version & flags.
8868  c->primary_item_id = avio_rb16(pb);
8869  av_log(c->fc, AV_LOG_TRACE, "pitm: primary_item_id %d\n", c->primary_item_id);
8870  return atom.size;
8871 }
8872 
8874 {
8875  c->idat_offset = avio_tell(pb);
8876  return 0;
8877 }
8878 
8880 {
8881  HEIFItem **heif_item;
8882  int version, offset_size, length_size, base_offset_size, index_size;
8883  int item_count, extent_count;
8884  int64_t base_offset, extent_offset, extent_length;
8885  uint8_t value;
8886 
8887  if (c->found_iloc) {
8888  av_log(c->fc, AV_LOG_INFO, "Duplicate iloc box found\n");
8889  return 0;
8890  }
8891 
8892  version = avio_r8(pb);
8893  avio_rb24(pb); // flags.
8894 
8895  value = avio_r8(pb);
8896  offset_size = (value >> 4) & 0xF;
8897  length_size = value & 0xF;
8898  value = avio_r8(pb);
8899  base_offset_size = (value >> 4) & 0xF;
8900  index_size = !version ? 0 : (value & 0xF);
8901  if (index_size) {
8902  avpriv_report_missing_feature(c->fc, "iloc: index_size != 0");
8903  return AVERROR_PATCHWELCOME;
8904  }
8905  item_count = (version < 2) ? avio_rb16(pb) : avio_rb32(pb);
8906 
8907  heif_item = av_realloc_array(c->heif_item, FFMAX(item_count, c->nb_heif_item), sizeof(*c->heif_item));
8908  if (!heif_item)
8909  return AVERROR(ENOMEM);
8910  c->heif_item = heif_item;
8911  if (item_count > c->nb_heif_item)
8912  memset(&c->heif_item[c->nb_heif_item], 0,
8913  sizeof(*c->heif_item) * (item_count - c->nb_heif_item));
8914  c->nb_heif_item = FFMAX(c->nb_heif_item, item_count);
8915 
8916  av_log(c->fc, AV_LOG_TRACE, "iloc: item_count %d\n", item_count);
8917  for (int i = 0; i < item_count; i++) {
8918  HEIFItem *item = NULL;
8919  int item_id = (version < 2) ? avio_rb16(pb) : avio_rb32(pb);
8920  int offset_type = (version > 0) ? avio_rb16(pb) & 0xf : 0;
8921 
8922  if (avio_feof(pb))
8923  return AVERROR_INVALIDDATA;
8924  if (offset_type > 1) {
8925  avpriv_report_missing_feature(c->fc, "iloc offset type %d", offset_type);
8926  return AVERROR_PATCHWELCOME;
8927  }
8928 
8929  avio_rb16(pb); // data_reference_index.
8930  if (rb_size(pb, &base_offset, base_offset_size) < 0)
8931  return AVERROR_INVALIDDATA;
8932  extent_count = avio_rb16(pb);
8933  if (extent_count > 1) {
8934  // For still AVIF images, we only support one extent item.
8935  avpriv_report_missing_feature(c->fc, "iloc: extent_count > 1");
8936  return AVERROR_PATCHWELCOME;
8937  }
8938 
8939  if (rb_size(pb, &extent_offset, offset_size) < 0 ||
8940  rb_size(pb, &extent_length, length_size) < 0 ||
8941  base_offset > INT64_MAX - extent_offset)
8942  return AVERROR_INVALIDDATA;
8943 
8944  for (int j = 0; j < c->nb_heif_item; j++) {
8945  item = c->heif_item[j];
8946  if (!item)
8947  item = c->heif_item[j] = av_mallocz(sizeof(*item));
8948  else if (item->item_id != item_id)
8949  continue;
8950  break;
8951  }
8952  if (!item)
8953  return AVERROR(ENOMEM);
8954 
8955  item->item_id = item_id;
8956 
8957  if (offset_type == 1)
8958  item->is_idat_relative = 1;
8959  item->extent_length = extent_length;
8960  item->extent_offset = base_offset + extent_offset;
8961  av_log(c->fc, AV_LOG_TRACE, "iloc: item_idx %d, item->item_id %d, offset_type %d, "
8962  "extent_offset %"PRId64", extent_length %"PRId64"\n",
8963  i, item->item_id, offset_type, item->extent_offset, item->extent_length);
8964  }
8965 
8966  c->found_iloc = 1;
8967  return atom.size;
8968 }
8969 
8971 {
8972  HEIFItem *item = NULL;
8973  AVBPrint item_name;
8974  int64_t size = atom.size;
8975  uint32_t item_type;
8976  int item_id;
8977  int version, ret;
8978 
8979  version = avio_r8(pb);
8980  avio_rb24(pb); // flags.
8981  size -= 4;
8982  if (size < 0)
8983  return AVERROR_INVALIDDATA;
8984 
8985  if (version < 2) {
8986  avpriv_report_missing_feature(c->fc, "infe version < 2");
8987  avio_skip(pb, size);
8988  return 1;
8989  }
8990 
8991  item_id = version > 2 ? avio_rb32(pb) : avio_rb16(pb);
8992  avio_rb16(pb); // item_protection_index
8993  item_type = avio_rl32(pb);
8994  size -= 8;
8995  if (size < 1)
8996  return AVERROR_INVALIDDATA;
8997 
9000  if (ret < 0) {
9002  return ret;
9003  }
9004 
9005  av_log(c->fc, AV_LOG_TRACE, "infe: item_id %d, item_type %s, item_name %s\n",
9006  item_id, av_fourcc2str(item_type), item_name.str);
9007 
9008  size -= ret + 1;
9009  if (size > 0)
9010  avio_skip(pb, size);
9011 
9012  for (int i = 0; i < c->nb_heif_item; i++) {
9013  item = c->heif_item[i];
9014  if (!item)
9015  item = c->heif_item[i] = av_mallocz(sizeof(*item));
9016  else if (item->item_id != item_id)
9017  continue;
9018  break;
9019  }
9020  if (!item) {
9022  return AVERROR(ENOMEM);
9023  }
9024 
9025  av_freep(&item->name);
9026  av_bprint_finalize(&item_name, ret ? &item->name : NULL);
9027  item->item_id = item_id;
9028  item->type = item_type;
9029 
9030  switch (item_type) {
9031  case MKTAG('a','v','0','1'):
9032  case MKTAG('j','p','e','g'):
9033  case MKTAG('h','v','c','1'):
9034  ret = heif_add_stream(c, item);
9035  if (ret < 0)
9036  return ret;
9037  break;
9038  }
9039 
9040  return 0;
9041 }
9042 
9044 {
9045  HEIFItem **heif_item;
9046  int entry_count;
9047  int version, got_stream = 0, ret, i;
9048 
9049  if (c->found_iinf) {
9050  av_log(c->fc, AV_LOG_WARNING, "Duplicate iinf box found\n");
9051  return 0;
9052  }
9053 
9054  version = avio_r8(pb);
9055  avio_rb24(pb); // flags.
9056  entry_count = version ? avio_rb32(pb) : avio_rb16(pb);
9057 
9058  heif_item = av_realloc_array(c->heif_item, FFMAX(entry_count, c->nb_heif_item), sizeof(*c->heif_item));
9059  if (!heif_item)
9060  return AVERROR(ENOMEM);
9061  c->heif_item = heif_item;
9062  if (entry_count > c->nb_heif_item)
9063  memset(&c->heif_item[c->nb_heif_item], 0,
9064  sizeof(*c->heif_item) * (entry_count - c->nb_heif_item));
9065  c->nb_heif_item = FFMAX(c->nb_heif_item, entry_count);
9066 
9067  for (i = 0; i < entry_count; i++) {
9068  MOVAtom infe;
9069 
9070  infe.size = avio_rb32(pb) - 8;
9071  infe.type = avio_rl32(pb);
9072  if (avio_feof(pb)) {
9074  goto fail;
9075  }
9076  ret = mov_read_infe(c, pb, infe);
9077  if (ret < 0)
9078  goto fail;
9079  if (!ret)
9080  got_stream = 1;
9081  }
9082 
9083  c->found_iinf = got_stream;
9084  return 0;
9085 fail:
9086  for (; i >= 0; i--) {
9087  HEIFItem *item = c->heif_item[i];
9088 
9089  if (!item)
9090  continue;
9091 
9092  av_freep(&item->name);
9093  }
9094  return ret;
9095 }
9096 
9098 {
9099  HEIFItem *item = NULL;
9100  HEIFGrid *grid;
9101  int entries, i;
9102  int from_item_id = version ? avio_rb32(pb) : avio_rb16(pb);
9103 
9104  for (int i = 0; i < c->nb_heif_grid; i++) {
9105  if (c->heif_grid[i].item->item_id == from_item_id) {
9106  av_log(c->fc, AV_LOG_ERROR, "More than one 'dimg' box "
9107  "referencing the same Derived Image item\n");
9108  return AVERROR_INVALIDDATA;
9109  }
9110  }
9111  for (int i = 0; i < c->nb_heif_item; i++) {
9112  if (!c->heif_item[i] || c->heif_item[i]->item_id != from_item_id)
9113  continue;
9114  item = c->heif_item[i];
9115 
9116  switch (item->type) {
9117  case MKTAG('g','r','i','d'):
9118  case MKTAG('i','o','v','l'):
9119  break;
9120  default:
9121  avpriv_report_missing_feature(c->fc, "Derived Image item of type %s",
9122  av_fourcc2str(item->type));
9123  return 0;
9124  }
9125  break;
9126  }
9127  if (!item) {
9128  av_log(c->fc, AV_LOG_ERROR, "Missing grid information\n");
9129  return AVERROR_INVALIDDATA;
9130  }
9131 
9132  grid = av_realloc_array(c->heif_grid, c->nb_heif_grid + 1U,
9133  sizeof(*c->heif_grid));
9134  if (!grid)
9135  return AVERROR(ENOMEM);
9136  c->heif_grid = grid;
9137  grid = &grid[c->nb_heif_grid++];
9138 
9139  entries = avio_rb16(pb);
9140  grid->tile_id_list = av_malloc_array(entries, sizeof(*grid->tile_id_list));
9141  grid->tile_idx_list = av_calloc(entries, sizeof(*grid->tile_idx_list));
9142  grid->tile_item_list = av_calloc(entries, sizeof(*grid->tile_item_list));
9143  if (!grid->tile_id_list || !grid->tile_item_list || !grid->tile_idx_list)
9144  return AVERROR(ENOMEM);
9145  /* 'to' item ids */
9146  for (i = 0; i < entries; i++)
9147  grid->tile_id_list[i] = version ? avio_rb32(pb) : avio_rb16(pb);
9148  grid->nb_tiles = entries;
9149  grid->item = item;
9150 
9151  av_log(c->fc, AV_LOG_TRACE, "dimg: from_item_id %d, entries %d\n",
9152  from_item_id, entries);
9153 
9154  return 0;
9155 }
9156 
9157 static int mov_read_iref_cdsc(MOVContext *c, AVIOContext *pb, uint32_t type, int version)
9158 {
9159  HEIFItem *from_item = NULL;
9160  int entries;
9161  int from_item_id = version ? avio_rb32(pb) : avio_rb16(pb);
9162  const HEIFItemRef ref = { type, from_item_id };
9163 
9164  from_item = get_heif_item(c, from_item_id);
9165  if (!from_item) {
9166  av_log(c->fc, AV_LOG_ERROR, "Missing stream referenced by thmb item\n");
9167  return AVERROR_INVALIDDATA;
9168  }
9169 
9170  entries = avio_rb16(pb);
9171  /* 'to' item ids */
9172  for (int i = 0; i < entries; i++) {
9173  HEIFItem *item = get_heif_item(c, version ? avio_rb32(pb) : avio_rb16(pb));
9174  if (!item) {
9175  av_log(c->fc, AV_LOG_WARNING, "Missing stream referenced by %s item\n",
9176  av_fourcc2str(type));
9177  continue;
9178  }
9179 
9180  if (!av_dynarray2_add((void **)&item->iref_list, &item->nb_iref_list,
9181  sizeof(*item->iref_list), (const uint8_t *)&ref))
9182  return AVERROR(ENOMEM);
9183  }
9184 
9185  av_log(c->fc, AV_LOG_TRACE, "%s: from_item_id %d, entries %d\n",
9186  av_fourcc2str(type), from_item_id, entries);
9187 
9188  return 0;
9189 }
9190 
9192 {
9193  int version = avio_r8(pb);
9194  avio_rb24(pb); // flags
9195  atom.size -= 4;
9196 
9197  if (version > 1) {
9198  av_log(c->fc, AV_LOG_WARNING, "Unknown iref box version %d\n", version);
9199  return 0;
9200  }
9201 
9202  while (atom.size) {
9203  uint32_t type, size = avio_rb32(pb);
9204  int64_t next = avio_tell(pb);
9205 
9206  if (size < 14 || next < 0 || next > INT64_MAX - size)
9207  return AVERROR_INVALIDDATA;
9208 
9209  next += size - 4;
9210  type = avio_rl32(pb);
9211  switch (type) {
9212  case MKTAG('d','i','m','g'):
9214  break;
9215  case MKTAG('c','d','s','c'):
9216  case MKTAG('t','h','m','b'):
9218  break;
9219  default:
9220  av_log(c->fc, AV_LOG_DEBUG, "Unknown iref type %s size %"PRIu32"\n",
9221  av_fourcc2str(type), size);
9222  }
9223 
9224  atom.size -= size;
9225  avio_seek(pb, next, SEEK_SET);
9226  }
9227  return 0;
9228 }
9229 
9231 {
9232  HEIFItem *item;
9233  uint32_t width, height;
9234 
9235  avio_r8(pb); /* version */
9236  avio_rb24(pb); /* flags */
9237  width = avio_rb32(pb);
9238  height = avio_rb32(pb);
9239 
9240  av_log(c->fc, AV_LOG_TRACE, "ispe: item_id %d, width %u, height %u\n",
9241  c->cur_item_id, width, height);
9242 
9243  item = get_heif_item(c, c->cur_item_id);
9244  if (item) {
9245  item->width = width;
9246  item->height = height;
9247  }
9248 
9249  return 0;
9250 }
9251 
9253 {
9254  HEIFItem *item;
9255  int angle;
9256 
9257  angle = avio_r8(pb) & 0x3;
9258 
9259  av_log(c->fc, AV_LOG_TRACE, "irot: item_id %d, angle %u\n",
9260  c->cur_item_id, angle);
9261 
9262  item = get_heif_item(c, c->cur_item_id);
9263  if (item) {
9264  // angle * 90 specifies the angle (in anti-clockwise direction)
9265  // in units of degrees.
9266  item->rotation = angle * 90;
9267  }
9268 
9269  return 0;
9270 }
9271 
9273 {
9274  HEIFItem *item;
9275  int axis;
9276 
9277  axis = avio_r8(pb) & 0x1;
9278 
9279  av_log(c->fc, AV_LOG_TRACE, "imir: item_id %d, axis %u\n",
9280  c->cur_item_id, axis);
9281 
9282  item = get_heif_item(c, c->cur_item_id);
9283  if (item) {
9284  item->hflip = axis;
9285  item->vflip = !axis;
9286  }
9287 
9288  return 0;
9289 }
9290 
9292 {
9293  typedef struct MOVAtoms {
9294  FFIOContext b;
9295  uint32_t type;
9296  int64_t size;
9297  uint8_t *data;
9298  } MOVAtoms;
9299  MOVAtoms *atoms = NULL;
9300  MOVAtom a;
9301  unsigned count;
9302  int nb_atoms = 0;
9303  int version, flags;
9304  int ret;
9305 
9306  a.size = avio_rb32(pb);
9307  a.type = avio_rl32(pb);
9308 
9309  if (a.size < 8 || a.type != MKTAG('i','p','c','o'))
9310  return AVERROR_INVALIDDATA;
9311 
9312  a.size -= 8;
9313  while (a.size >= 8) {
9314  MOVAtoms *ref = av_dynarray2_add((void**)&atoms, &nb_atoms, sizeof(MOVAtoms), NULL);
9315  if (!ref) {
9316  ret = AVERROR(ENOMEM);
9317  goto fail;
9318  }
9319  ref->data = NULL;
9320  ref->size = avio_rb32(pb);
9321  ref->type = avio_rl32(pb);
9322  if (ref->size > a.size || ref->size < 8)
9323  break;
9324  ref->data = av_malloc(ref->size);
9325  if (!ref->data) {
9327  goto fail;
9328  }
9329  av_log(c->fc, AV_LOG_TRACE, "ipco: index %d, box type %s\n", nb_atoms, av_fourcc2str(ref->type));
9330  avio_seek(pb, -8, SEEK_CUR);
9331  if (avio_read(pb, ref->data, ref->size) != ref->size) {
9333  goto fail;
9334  }
9335  ffio_init_read_context(&ref->b, ref->data, ref->size);
9336  a.size -= ref->size;
9337  }
9338 
9339  if (a.size) {
9341  goto fail;
9342  }
9343 
9344  a.size = avio_rb32(pb);
9345  a.type = avio_rl32(pb);
9346 
9347  if (a.size < 8 || a.type != MKTAG('i','p','m','a')) {
9349  goto fail;
9350  }
9351 
9352  version = avio_r8(pb);
9353  flags = avio_rb24(pb);
9354  count = avio_rb32(pb);
9355 
9356  for (int i = 0; i < count; i++) {
9357  int item_id = version ? avio_rb32(pb) : avio_rb16(pb);
9358  int assoc_count = avio_r8(pb);
9359 
9360  if (avio_feof(pb)) {
9362  goto fail;
9363  }
9364 
9365  for (int j = 0; j < assoc_count; j++) {
9366  MOVAtoms *ref;
9367  int index = avio_r8(pb) & 0x7f;
9368  if (flags & 1) {
9369  index <<= 8;
9370  index |= avio_r8(pb);
9371  }
9372  if (index > nb_atoms || index <= 0) {
9374  goto fail;
9375  }
9376  ref = &atoms[--index];
9377 
9378  av_log(c->fc, AV_LOG_TRACE, "ipma: property_index %d, item_id %d, item_type %s\n",
9379  index + 1, item_id, av_fourcc2str(ref->type));
9380 
9381  c->cur_item_id = item_id;
9382 
9383  ret = mov_read_default(c, &ref->b.pub,
9384  (MOVAtom) { .size = ref->size,
9385  .type = MKTAG('i','p','c','o') });
9386  if (ret < 0)
9387  goto fail;
9388  ffio_init_read_context(&ref->b, ref->data, ref->size);
9389  }
9390  }
9391 
9392  ret = 0;
9393 fail:
9394  c->cur_item_id = -1;
9395  for (int i = 0; i < nb_atoms; i++)
9396  av_free(atoms[i].data);
9397  av_free(atoms);
9398 
9399  return ret;
9400 }
9401 
9403 { MKTAG('A','C','L','R'), mov_read_aclr },
9404 { MKTAG('A','P','R','G'), mov_read_avid },
9405 { MKTAG('A','A','L','P'), mov_read_avid },
9406 { MKTAG('A','R','E','S'), mov_read_ares },
9407 { MKTAG('a','v','s','s'), mov_read_avss },
9408 { MKTAG('a','v','1','C'), mov_read_glbl },
9409 { MKTAG('c','h','p','l'), mov_read_chpl },
9410 { MKTAG('c','o','6','4'), mov_read_stco },
9411 { MKTAG('c','o','l','r'), mov_read_colr },
9412 { MKTAG('c','t','t','s'), mov_read_ctts }, /* composition time to sample */
9413 { MKTAG('d','i','n','f'), mov_read_default },
9414 { MKTAG('D','p','x','E'), mov_read_dpxe },
9415 { MKTAG('d','r','e','f'), mov_read_dref },
9416 { MKTAG('e','d','t','s'), mov_read_default },
9417 { MKTAG('e','l','s','t'), mov_read_elst },
9418 { MKTAG('e','n','d','a'), mov_read_enda },
9419 { MKTAG('f','i','e','l'), mov_read_fiel },
9420 { MKTAG('a','d','r','m'), mov_read_adrm },
9421 { MKTAG('f','t','y','p'), mov_read_ftyp },
9422 { MKTAG('g','l','b','l'), mov_read_glbl },
9423 { MKTAG('h','d','l','r'), mov_read_hdlr },
9424 { MKTAG('i','l','s','t'), mov_read_ilst },
9425 { MKTAG('j','p','2','h'), mov_read_jp2h },
9426 { MKTAG('m','d','a','t'), mov_read_mdat },
9427 { MKTAG('m','d','h','d'), mov_read_mdhd },
9428 { MKTAG('m','d','i','a'), mov_read_default },
9429 { MKTAG('m','e','t','a'), mov_read_meta },
9430 { MKTAG('m','i','n','f'), mov_read_default },
9431 { MKTAG('m','o','o','f'), mov_read_moof },
9432 { MKTAG('m','o','o','v'), mov_read_moov },
9433 { MKTAG('m','v','e','x'), mov_read_default },
9434 { MKTAG('m','v','h','d'), mov_read_mvhd },
9435 { MKTAG('S','M','I',' '), mov_read_svq3 },
9436 { MKTAG('a','l','a','c'), mov_read_alac }, /* alac specific atom */
9437 { MKTAG('a','v','c','C'), mov_read_glbl },
9438 { MKTAG('p','a','s','p'), mov_read_pasp },
9439 { MKTAG('c','l','a','p'), mov_read_clap },
9440 { MKTAG('s','b','a','s'), mov_read_sbas },
9441 { MKTAG('s','i','d','x'), mov_read_sidx },
9442 { MKTAG('s','t','b','l'), mov_read_default },
9443 { MKTAG('s','t','c','o'), mov_read_stco },
9444 { MKTAG('s','t','p','s'), mov_read_stps },
9445 { MKTAG('s','t','r','f'), mov_read_strf },
9446 { MKTAG('s','t','s','c'), mov_read_stsc },
9447 { MKTAG('s','t','s','d'), mov_read_stsd }, /* sample description */
9448 { MKTAG('s','t','s','s'), mov_read_stss }, /* sync sample */
9449 { MKTAG('s','t','s','z'), mov_read_stsz }, /* sample size */
9450 { MKTAG('s','t','t','s'), mov_read_stts },
9451 { MKTAG('s','t','z','2'), mov_read_stsz }, /* compact sample size */
9452 { MKTAG('s','d','t','p'), mov_read_sdtp }, /* independent and disposable samples */
9453 { MKTAG('t','k','h','d'), mov_read_tkhd }, /* track header */
9454 { MKTAG('t','f','d','t'), mov_read_tfdt },
9455 { MKTAG('t','f','h','d'), mov_read_tfhd }, /* track fragment header */
9456 { MKTAG('t','r','a','k'), mov_read_trak },
9457 { MKTAG('t','r','a','f'), mov_read_default },
9458 { MKTAG('t','r','e','f'), mov_read_default },
9459 { MKTAG('t','m','c','d'), mov_read_tmcd },
9460 { MKTAG('c','h','a','p'), mov_read_chap },
9461 { MKTAG('t','r','e','x'), mov_read_trex },
9462 { MKTAG('t','r','u','n'), mov_read_trun },
9463 { MKTAG('u','d','t','a'), mov_read_default },
9464 { MKTAG('w','a','v','e'), mov_read_wave },
9465 { MKTAG('e','s','d','s'), mov_read_esds },
9466 { MKTAG('d','a','c','3'), mov_read_dac3 }, /* AC-3 info */
9467 { MKTAG('d','e','c','3'), mov_read_dec3 }, /* EAC-3 info */
9468 { MKTAG('d','d','t','s'), mov_read_ddts }, /* DTS audio descriptor */
9469 { MKTAG('w','i','d','e'), mov_read_wide }, /* place holder */
9470 { MKTAG('w','f','e','x'), mov_read_wfex },
9471 { MKTAG('c','m','o','v'), mov_read_cmov },
9472 { MKTAG('c','h','a','n'), mov_read_chan }, /* channel layout from quicktime */
9473 { MKTAG('c','h','n','l'), mov_read_chnl }, /* channel layout from ISO-14496-12 */
9474 { MKTAG('d','v','c','1'), mov_read_dvc1 },
9475 { MKTAG('s','g','p','d'), mov_read_sgpd },
9476 { MKTAG('s','b','g','p'), mov_read_sbgp },
9477 { MKTAG('h','v','c','C'), mov_read_glbl },
9478 { MKTAG('v','v','c','C'), mov_read_glbl },
9479 { MKTAG('u','u','i','d'), mov_read_uuid },
9480 { MKTAG('C','i','n', 0x8e), mov_read_targa_y216 },
9481 { MKTAG('f','r','e','e'), mov_read_free },
9482 { MKTAG('-','-','-','-'), mov_read_custom },
9483 { MKTAG('s','i','n','f'), mov_read_default },
9484 { MKTAG('f','r','m','a'), mov_read_frma },
9485 { MKTAG('s','e','n','c'), mov_read_senc },
9486 { MKTAG('s','a','i','z'), mov_read_saiz },
9487 { MKTAG('s','a','i','o'), mov_read_saio },
9488 { MKTAG('p','s','s','h'), mov_read_pssh },
9489 { MKTAG('s','c','h','m'), mov_read_schm },
9490 { MKTAG('s','c','h','i'), mov_read_default },
9491 { MKTAG('t','e','n','c'), mov_read_tenc },
9492 { MKTAG('d','f','L','a'), mov_read_dfla },
9493 { MKTAG('s','t','3','d'), mov_read_st3d }, /* stereoscopic 3D video box */
9494 { MKTAG('s','v','3','d'), mov_read_sv3d }, /* spherical video box */
9495 { MKTAG('v','e','x','u'), mov_read_vexu }, /* video extension usage */
9496 { MKTAG('h','f','o','v'), mov_read_hfov },
9497 { MKTAG('d','O','p','s'), mov_read_dops },
9498 { MKTAG('d','m','l','p'), mov_read_dmlp },
9499 { MKTAG('S','m','D','m'), mov_read_smdm },
9500 { MKTAG('C','o','L','L'), mov_read_coll },
9501 { MKTAG('v','p','c','C'), mov_read_vpcc },
9502 { MKTAG('m','d','c','v'), mov_read_mdcv },
9503 { MKTAG('c','l','l','i'), mov_read_clli },
9504 { MKTAG('d','v','c','C'), mov_read_dvcc_dvvc },
9505 { MKTAG('d','v','v','C'), mov_read_dvcc_dvvc },
9506 { MKTAG('d','v','w','C'), mov_read_dvcc_dvvc },
9507 { MKTAG('k','i','n','d'), mov_read_kind },
9508 { MKTAG('S','A','3','D'), mov_read_SA3D }, /* ambisonic audio box */
9509 { MKTAG('S','A','N','D'), mov_read_SAND }, /* non diegetic audio box */
9510 { MKTAG('i','l','o','c'), mov_read_iloc },
9511 { MKTAG('p','c','m','C'), mov_read_pcmc }, /* PCM configuration box */
9512 { MKTAG('p','i','t','m'), mov_read_pitm },
9513 { MKTAG('e','v','c','C'), mov_read_glbl },
9514 { MKTAG('i','d','a','t'), mov_read_idat },
9515 { MKTAG('i','m','i','r'), mov_read_imir },
9516 { MKTAG('i','r','e','f'), mov_read_iref },
9517 { MKTAG('i','s','p','e'), mov_read_ispe },
9518 { MKTAG('i','r','o','t'), mov_read_irot },
9519 { MKTAG('i','p','r','p'), mov_read_iprp },
9520 { MKTAG('i','i','n','f'), mov_read_iinf },
9521 { MKTAG('a','m','v','e'), mov_read_amve }, /* ambient viewing environment box */
9522 { MKTAG('l','h','v','C'), mov_read_lhvc },
9523 { MKTAG('l','v','c','C'), mov_read_glbl },
9524 { MKTAG('a','p','v','C'), mov_read_glbl },
9525 #if CONFIG_IAMFDEC
9526 { MKTAG('i','a','c','b'), mov_read_iacb },
9527 #endif
9528 { MKTAG('s','r','a','t'), mov_read_srat },
9529 { 0, NULL }
9530 };
9531 
9533 {
9534  int64_t total_size = 0;
9535  MOVAtom a;
9536  int i;
9537 
9538  if (c->atom_depth > 10) {
9539  av_log(c->fc, AV_LOG_ERROR, "Atoms too deeply nested\n");
9540  return AVERROR_INVALIDDATA;
9541  }
9542  c->atom_depth ++;
9543 
9544  if (atom.size < 0)
9545  atom.size = INT64_MAX;
9546  while (total_size <= atom.size - 8) {
9547  int (*parse)(MOVContext*, AVIOContext*, MOVAtom) = NULL;
9548  a.size = avio_rb32(pb);
9549  a.type = avio_rl32(pb);
9550  if (avio_feof(pb))
9551  break;
9552  if (((a.type == MKTAG('f','r','e','e') && c->moov_retry) ||
9553  a.type == MKTAG('h','o','o','v')) &&
9554  a.size >= 8 &&
9555  c->fc->strict_std_compliance < FF_COMPLIANCE_STRICT) {
9556  uint32_t type;
9557  avio_skip(pb, 4);
9558  type = avio_rl32(pb);
9559  if (avio_feof(pb))
9560  break;
9561  avio_seek(pb, -8, SEEK_CUR);
9562  if (type == MKTAG('m','v','h','d') ||
9563  type == MKTAG('c','m','o','v')) {
9564  av_log(c->fc, AV_LOG_ERROR, "Detected moov in a free or hoov atom.\n");
9565  a.type = MKTAG('m','o','o','v');
9566  }
9567  }
9568  if (atom.type != MKTAG('r','o','o','t') &&
9569  atom.type != MKTAG('m','o','o','v')) {
9570  if (a.type == MKTAG('t','r','a','k') ||
9571  a.type == MKTAG('m','d','a','t')) {
9572  av_log(c->fc, AV_LOG_ERROR, "Broken file, trak/mdat not at top-level\n");
9573  avio_skip(pb, -8);
9574  c->atom_depth --;
9575  return 0;
9576  }
9577  }
9578  total_size += 8;
9579  if (a.size == 1 && total_size + 8 <= atom.size) { /* 64 bit extended size */
9580  a.size = avio_rb64(pb) - 8;
9581  total_size += 8;
9582  }
9583  av_log(c->fc, AV_LOG_TRACE, "type:'%s' parent:'%s' sz: %"PRId64" %"PRId64" %"PRId64"\n",
9584  av_fourcc2str(a.type), av_fourcc2str(atom.type), a.size, total_size, atom.size);
9585  if (a.size == 0) {
9586  a.size = atom.size - total_size + 8;
9587  }
9588  if (a.size < 0)
9589  break;
9590  a.size -= 8;
9591  if (a.size < 0)
9592  break;
9593  a.size = FFMIN(a.size, atom.size - total_size);
9594 
9595  for (i = 0; mov_default_parse_table[i].type; i++)
9596  if (mov_default_parse_table[i].type == a.type) {
9598  break;
9599  }
9600 
9601  // container is user data
9602  if (!parse && (atom.type == MKTAG('u','d','t','a') ||
9603  atom.type == MKTAG('i','l','s','t')))
9605 
9606  // Supports parsing the QuickTime Metadata Keys.
9607  // https://developer.apple.com/library/mac/documentation/QuickTime/QTFF/Metadata/Metadata.html
9608  if (!parse && c->found_hdlr_mdta &&
9609  atom.type == MKTAG('m','e','t','a') &&
9610  a.type == MKTAG('k','e','y','s') &&
9611  c->meta_keys_count == 0) {
9612  parse = mov_read_keys;
9613  }
9614 
9615  if (!parse) { /* skip leaf atoms data */
9616  avio_skip(pb, a.size);
9617  } else {
9618  int64_t start_pos = avio_tell(pb);
9619  int64_t left;
9620  int err = parse(c, pb, a);
9621  if (err < 0) {
9622  c->atom_depth --;
9623  return err;
9624  }
9625  if (c->found_moov && c->found_mdat && a.size <= INT64_MAX - start_pos &&
9626  ((!(pb->seekable & AVIO_SEEKABLE_NORMAL) || c->fc->flags & AVFMT_FLAG_IGNIDX || c->frag_index.complete) ||
9627  start_pos + a.size == avio_size(pb))) {
9628  if (!(pb->seekable & AVIO_SEEKABLE_NORMAL) || c->fc->flags & AVFMT_FLAG_IGNIDX || c->frag_index.complete)
9629  c->next_root_atom = start_pos + a.size;
9630  c->atom_depth --;
9631  return 0;
9632  }
9633  left = a.size - avio_tell(pb) + start_pos;
9634  if (left > 0) /* skip garbage at atom end */
9635  avio_skip(pb, left);
9636  else if (left < 0) {
9637  av_log(c->fc, AV_LOG_WARNING,
9638  "overread end of atom '%s' by %"PRId64" bytes\n",
9639  av_fourcc2str(a.type), -left);
9640  avio_seek(pb, left, SEEK_CUR);
9641  }
9642  }
9643 
9644  total_size += a.size;
9645  }
9646 
9647  if (total_size < atom.size && atom.size < 0x7ffff)
9648  avio_skip(pb, atom.size - total_size);
9649 
9650  c->atom_depth --;
9651  return 0;
9652 }
9653 
9654 static int mov_probe(const AVProbeData *p)
9655 {
9656  int64_t offset;
9657  uint32_t tag;
9658  int score = 0;
9659  int moov_offset = -1;
9660 
9661  /* check file header */
9662  offset = 0;
9663  for (;;) {
9664  int64_t size;
9665  int minsize = 8;
9666  /* ignore invalid offset */
9667  if ((offset + 8ULL) > (unsigned int)p->buf_size)
9668  break;
9669  size = AV_RB32(p->buf + offset);
9670  if (size == 1 && offset + 16 <= (unsigned int)p->buf_size) {
9671  size = AV_RB64(p->buf+offset + 8);
9672  minsize = 16;
9673  } else if (size == 0) {
9674  size = p->buf_size - offset;
9675  }
9676  if (size < minsize) {
9677  offset += 4;
9678  continue;
9679  }
9680  tag = AV_RL32(p->buf + offset + 4);
9681  switch(tag) {
9682  /* check for obvious tags */
9683  case MKTAG('m','o','o','v'):
9684  moov_offset = offset + 4;
9685  case MKTAG('m','d','a','t'):
9686  case MKTAG('p','n','o','t'): /* detect movs with preview pics like ew.mov and april.mov */
9687  case MKTAG('u','d','t','a'): /* Packet Video PVAuthor adds this and a lot of more junk */
9688  case MKTAG('f','t','y','p'):
9689  if (tag == MKTAG('f','t','y','p') &&
9690  ( AV_RL32(p->buf + offset + 8) == MKTAG('j','p','2',' ')
9691  || AV_RL32(p->buf + offset + 8) == MKTAG('j','p','x',' ')
9692  || AV_RL32(p->buf + offset + 8) == MKTAG('j','x','l',' ')
9693  )) {
9694  score = FFMAX(score, 5);
9695  } else {
9696  score = AVPROBE_SCORE_MAX;
9697  }
9698  break;
9699  /* those are more common words, so rate then a bit less */
9700  case MKTAG('e','d','i','w'): /* xdcam files have reverted first tags */
9701  case MKTAG('w','i','d','e'):
9702  case MKTAG('f','r','e','e'):
9703  case MKTAG('j','u','n','k'):
9704  case MKTAG('p','i','c','t'):
9705  score = FFMAX(score, AVPROBE_SCORE_MAX - 5);
9706  break;
9707  case MKTAG(0x82,0x82,0x7f,0x7d):
9708  score = FFMAX(score, AVPROBE_SCORE_EXTENSION - 5);
9709  break;
9710  case MKTAG('s','k','i','p'):
9711  case MKTAG('u','u','i','d'):
9712  case MKTAG('p','r','f','l'):
9713  /* if we only find those cause probedata is too small at least rate them */
9714  score = FFMAX(score, AVPROBE_SCORE_EXTENSION);
9715  break;
9716  }
9717  if (size > INT64_MAX - offset)
9718  break;
9719  offset += size;
9720  }
9721  if (score > AVPROBE_SCORE_MAX - 50 && moov_offset != -1) {
9722  /* moov atom in the header - we should make sure that this is not a
9723  * MOV-packed MPEG-PS */
9724  offset = moov_offset;
9725 
9726  while (offset < (p->buf_size - 16)) { /* Sufficient space */
9727  /* We found an actual hdlr atom */
9728  if (AV_RL32(p->buf + offset ) == MKTAG('h','d','l','r') &&
9729  AV_RL32(p->buf + offset + 8) == MKTAG('m','h','l','r') &&
9730  AV_RL32(p->buf + offset + 12) == MKTAG('M','P','E','G')) {
9731  av_log(NULL, AV_LOG_WARNING, "Found media data tag MPEG indicating this is a MOV-packed MPEG-PS.\n");
9732  /* We found a media handler reference atom describing an
9733  * MPEG-PS-in-MOV, return a
9734  * low score to force expanding the probe window until
9735  * mpegps_probe finds what it needs */
9736  return 5;
9737  } else {
9738  /* Keep looking */
9739  offset += 2;
9740  }
9741  }
9742  }
9743 
9744  return score;
9745 }
9746 
9747 // must be done after parsing all trak because there's no order requirement
9749 {
9750  MOVContext *mov = s->priv_data;
9751  MOVStreamContext *sc;
9752  int64_t cur_pos;
9753  int i, j;
9754  int chapter_track;
9755 
9756  for (j = 0; j < mov->nb_chapter_tracks; j++) {
9757  AVStream *st = NULL;
9758  FFStream *sti = NULL;
9759  chapter_track = mov->chapter_tracks[j];
9760  for (i = 0; i < s->nb_streams; i++) {
9761  sc = mov->fc->streams[i]->priv_data;
9762  if (sc->id == chapter_track) {
9763  st = s->streams[i];
9764  break;
9765  }
9766  }
9767  if (!st) {
9768  av_log(s, AV_LOG_ERROR, "Referenced QT chapter track not found\n");
9769  continue;
9770  }
9771  sti = ffstream(st);
9772 
9773  sc = st->priv_data;
9774  cur_pos = avio_tell(sc->pb);
9775 
9776  if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
9778  if (!st->attached_pic.data && sti->nb_index_entries) {
9779  // Retrieve the first frame, if possible
9780  AVIndexEntry *sample = &sti->index_entries[0];
9781  if (avio_seek(sc->pb, sample->pos, SEEK_SET) != sample->pos) {
9782  av_log(s, AV_LOG_ERROR, "Failed to retrieve first frame\n");
9783  goto finish;
9784  }
9785 
9786  if (ff_add_attached_pic(s, st, sc->pb, NULL, sample->size) < 0)
9787  goto finish;
9788  }
9789  } else {
9792  st->discard = AVDISCARD_ALL;
9793  for (int i = 0; i < sti->nb_index_entries; i++) {
9794  AVIndexEntry *sample = &sti->index_entries[i];
9795  int64_t end = i+1 < sti->nb_index_entries ? sti->index_entries[i+1].timestamp : st->duration;
9796  uint8_t *title;
9797  uint16_t ch;
9798  int len, title_len;
9799 
9800  if (end < sample->timestamp) {
9801  av_log(s, AV_LOG_WARNING, "ignoring stream duration which is shorter than chapters\n");
9802  end = AV_NOPTS_VALUE;
9803  }
9804 
9805  if (avio_seek(sc->pb, sample->pos, SEEK_SET) != sample->pos) {
9806  av_log(s, AV_LOG_ERROR, "Chapter %d not found in file\n", i);
9807  goto finish;
9808  }
9809 
9810  // the first two bytes are the length of the title
9811  len = avio_rb16(sc->pb);
9812  if (len > sample->size-2)
9813  continue;
9814  title_len = 2*len + 1;
9815  if (!(title = av_mallocz(title_len)))
9816  goto finish;
9817 
9818  // The samples could theoretically be in any encoding if there's an encd
9819  // atom following, but in practice are only utf-8 or utf-16, distinguished
9820  // instead by the presence of a BOM
9821  if (!len) {
9822  title[0] = 0;
9823  } else {
9824  ch = avio_rb16(sc->pb);
9825  if (ch == 0xfeff)
9826  avio_get_str16be(sc->pb, len, title, title_len);
9827  else if (ch == 0xfffe)
9828  avio_get_str16le(sc->pb, len, title, title_len);
9829  else {
9830  AV_WB16(title, ch);
9831  if (len == 1 || len == 2)
9832  title[len] = 0;
9833  else
9834  avio_get_str(sc->pb, INT_MAX, title + 2, len - 1);
9835  }
9836  }
9837 
9838  avpriv_new_chapter(s, i, st->time_base, sample->timestamp, end, title);
9839  av_freep(&title);
9840  }
9841  }
9842 finish:
9843  avio_seek(sc->pb, cur_pos, SEEK_SET);
9844  }
9845 }
9846 
9848  int64_t value, int flags)
9849 {
9850  AVTimecode tc;
9851  char buf[AV_TIMECODE_STR_SIZE];
9852  AVRational rate = st->avg_frame_rate;
9853  int ret = av_timecode_init(&tc, rate, flags, 0, s);
9854  if (ret < 0)
9855  return ret;
9856  av_dict_set(&st->metadata, "timecode",
9857  av_timecode_make_string(&tc, buf, value), 0);
9858  return 0;
9859 }
9860 
9862 {
9863  MOVStreamContext *sc = st->priv_data;
9864  FFStream *const sti = ffstream(st);
9865  char buf[AV_TIMECODE_STR_SIZE];
9866  int64_t cur_pos = avio_tell(sc->pb);
9867  int hh, mm, ss, ff, drop;
9868 
9869  if (!sti->nb_index_entries)
9870  return -1;
9871 
9872  avio_seek(sc->pb, sti->index_entries->pos, SEEK_SET);
9873  avio_skip(s->pb, 13);
9874  hh = avio_r8(s->pb);
9875  mm = avio_r8(s->pb);
9876  ss = avio_r8(s->pb);
9877  drop = avio_r8(s->pb);
9878  ff = avio_r8(s->pb);
9879  snprintf(buf, AV_TIMECODE_STR_SIZE, "%02d:%02d:%02d%c%02d",
9880  hh, mm, ss, drop ? ';' : ':', ff);
9881  av_dict_set(&st->metadata, "timecode", buf, 0);
9882 
9883  avio_seek(sc->pb, cur_pos, SEEK_SET);
9884  return 0;
9885 }
9886 
9888 {
9889  MOVStreamContext *sc = st->priv_data;
9890  FFStream *const sti = ffstream(st);
9891  int flags = 0;
9892  int64_t cur_pos = avio_tell(sc->pb);
9893  int64_t value;
9894  AVRational tc_rate = st->avg_frame_rate;
9895  int tmcd_nb_frames = sc->tmcd_nb_frames;
9896  int rounded_tc_rate;
9897 
9898  if (!sti->nb_index_entries)
9899  return -1;
9900 
9901  if (!tc_rate.num || !tc_rate.den || !tmcd_nb_frames)
9902  return -1;
9903 
9904  avio_seek(sc->pb, sti->index_entries->pos, SEEK_SET);
9905  value = avio_rb32(s->pb);
9906 
9907  if (sc->tmcd_flags & 0x0001) flags |= AV_TIMECODE_FLAG_DROPFRAME;
9908  if (sc->tmcd_flags & 0x0002) flags |= AV_TIMECODE_FLAG_24HOURSMAX;
9909  if (sc->tmcd_flags & 0x0004) flags |= AV_TIMECODE_FLAG_ALLOWNEGATIVE;
9910 
9911  /* Assume Counter flag is set to 1 in tmcd track (even though it is likely
9912  * not the case) and thus assume "frame number format" instead of QT one.
9913  * No sample with tmcd track can be found with a QT timecode at the moment,
9914  * despite what the tmcd track "suggests" (Counter flag set to 0 means QT
9915  * format). */
9916 
9917  /* 60 fps content have tmcd_nb_frames set to 30 but tc_rate set to 60, so
9918  * we multiply the frame number with the quotient.
9919  * See tickets #9492, #9710. */
9920  rounded_tc_rate = (tc_rate.num + tc_rate.den / 2LL) / tc_rate.den;
9921  /* Work around files where tmcd_nb_frames is rounded down from frame rate
9922  * instead of up. See ticket #5978. */
9923  if (tmcd_nb_frames == tc_rate.num / tc_rate.den &&
9924  s->strict_std_compliance < FF_COMPLIANCE_STRICT)
9925  tmcd_nb_frames = rounded_tc_rate;
9926  value = av_rescale(value, rounded_tc_rate, tmcd_nb_frames);
9927 
9929 
9930  avio_seek(sc->pb, cur_pos, SEEK_SET);
9931  return 0;
9932 }
9933 
9935  int i;
9936  if (!index || !*index) return;
9937  for (i = 0; i < (*index)->nb_encrypted_samples; i++) {
9938  av_encryption_info_free((*index)->encrypted_samples[i]);
9939  }
9940  av_freep(&(*index)->encrypted_samples);
9941  av_freep(&(*index)->auxiliary_info_sizes);
9942  av_freep(&(*index)->auxiliary_offsets);
9943  av_freep(index);
9944 }
9945 
9947 {
9948  MOVStreamContext *sc = st->priv_data;
9949 
9950  if (!sc || --sc->refcount) {
9951  st->priv_data = NULL;
9952  return;
9953  }
9954 
9955  av_freep(&sc->tts_data);
9956  for (int i = 0; i < sc->drefs_count; i++) {
9957  av_freep(&sc->drefs[i].path);
9958  av_freep(&sc->drefs[i].dir);
9959  }
9960  av_freep(&sc->drefs);
9961 
9962  sc->drefs_count = 0;
9963 
9964  if (!sc->pb_is_copied)
9965  ff_format_io_close(s, &sc->pb);
9966 
9967  sc->pb = NULL;
9968  av_freep(&sc->chunk_offsets);
9969  av_freep(&sc->stsc_data);
9970  av_freep(&sc->sample_sizes);
9971  av_freep(&sc->keyframes);
9972  av_freep(&sc->ctts_data);
9973  av_freep(&sc->stts_data);
9974  av_freep(&sc->sdtp_data);
9975  av_freep(&sc->stps_data);
9976  av_freep(&sc->elst_data);
9977  av_freep(&sc->rap_group);
9978  av_freep(&sc->sync_group);
9979  av_freep(&sc->sgpd_sync);
9980  av_freep(&sc->sample_offsets);
9981  av_freep(&sc->open_key_samples);
9982  av_freep(&sc->display_matrix);
9983  av_freep(&sc->index_ranges);
9984 
9985  if (sc->extradata)
9986  for (int i = 0; i < sc->stsd_count; i++)
9987  av_free(sc->extradata[i]);
9988  av_freep(&sc->extradata);
9989  av_freep(&sc->extradata_size);
9990 
9994 
9995  av_freep(&sc->stereo3d);
9996  av_freep(&sc->spherical);
9997  av_freep(&sc->mastering);
9998  av_freep(&sc->coll);
9999  av_freep(&sc->ambient);
10000 
10001 #if CONFIG_IAMFDEC
10002  if (sc->iamf)
10004 #endif
10005  av_freep(&sc->iamf);
10006 }
10007 
10009 {
10010  MOVContext *mov = s->priv_data;
10011  int i, j;
10012 
10013  for (i = 0; i < s->nb_streams; i++) {
10014  AVStream *st = s->streams[i];
10015 
10017  }
10018 
10019  av_freep(&mov->dv_demux);
10021  mov->dv_fctx = NULL;
10022 
10023  if (mov->meta_keys) {
10024  for (i = 1; i < mov->meta_keys_count; i++) {
10025  av_freep(&mov->meta_keys[i]);
10026  }
10027  av_freep(&mov->meta_keys);
10028  }
10029 
10030  av_freep(&mov->trex_data);
10031  av_freep(&mov->bitrates);
10032 
10033  for (i = 0; i < mov->frag_index.nb_items; i++) {
10035  for (j = 0; j < mov->frag_index.item[i].nb_stream_info; j++) {
10036  mov_free_encryption_index(&frag[j].encryption_index);
10037  }
10039  }
10040  av_freep(&mov->frag_index.item);
10041 
10042  av_freep(&mov->aes_decrypt);
10043  av_freep(&mov->chapter_tracks);
10044  for (i = 0; i < mov->nb_heif_item; i++) {
10045  if (!mov->heif_item[i])
10046  continue;
10047  av_freep(&mov->heif_item[i]->name);
10048  av_freep(&mov->heif_item[i]->iref_list);
10049  av_freep(&mov->heif_item[i]->icc_profile);
10050  av_freep(&mov->heif_item[i]);
10051  }
10052  av_freep(&mov->heif_item);
10053  for (i = 0; i < mov->nb_heif_grid; i++) {
10054  av_freep(&mov->heif_grid[i].tile_id_list);
10057  }
10058  av_freep(&mov->heif_grid);
10059 
10060  return 0;
10061 }
10062 
10063 static int tmcd_is_referenced(AVFormatContext *s, int tmcd_id)
10064 {
10065  int i;
10066 
10067  for (i = 0; i < s->nb_streams; i++) {
10068  AVStream *st = s->streams[i];
10069  MOVStreamContext *sc = st->priv_data;
10070 
10071  if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO &&
10072  sc->timecode_track == tmcd_id)
10073  return 1;
10074  }
10075  return 0;
10076 }
10077 
10078 /* look for a tmcd track not referenced by any video track, and export it globally */
10080 {
10081  int i;
10082 
10083  for (i = 0; i < s->nb_streams; i++) {
10084  AVStream *st = s->streams[i];
10085 
10086  if (st->codecpar->codec_tag == MKTAG('t','m','c','d') &&
10087  !tmcd_is_referenced(s, i + 1)) {
10088  AVDictionaryEntry *tcr = av_dict_get(st->metadata, "timecode", NULL, 0);
10089  if (tcr) {
10090  av_dict_set(&s->metadata, "timecode", tcr->value, 0);
10091  break;
10092  }
10093  }
10094  }
10095 }
10096 
10097 static int read_tfra(MOVContext *mov, AVIOContext *f)
10098 {
10099  int version, fieldlength, i, j;
10100  int64_t pos = avio_tell(f);
10101  uint32_t size = avio_rb32(f);
10102  unsigned track_id, item_count;
10103 
10104  if (avio_rb32(f) != MKBETAG('t', 'f', 'r', 'a')) {
10105  return 1;
10106  }
10107  av_log(mov->fc, AV_LOG_VERBOSE, "found tfra\n");
10108 
10109  version = avio_r8(f);
10110  avio_rb24(f);
10111  track_id = avio_rb32(f);
10112  fieldlength = avio_rb32(f);
10113  item_count = avio_rb32(f);
10114  for (i = 0; i < item_count; i++) {
10115  int64_t time, offset;
10116  int index;
10117  MOVFragmentStreamInfo * frag_stream_info;
10118 
10119  if (avio_feof(f)) {
10120  return AVERROR_INVALIDDATA;
10121  }
10122 
10123  if (version == 1) {
10124  time = avio_rb64(f);
10125  offset = avio_rb64(f);
10126  } else {
10127  time = avio_rb32(f);
10128  offset = avio_rb32(f);
10129  }
10130 
10131  // The first sample of each stream in a fragment is always a random
10132  // access sample. So it's entry in the tfra can be used as the
10133  // initial PTS of the fragment.
10134  index = update_frag_index(mov, offset);
10135  frag_stream_info = get_frag_stream_info(&mov->frag_index, index, track_id);
10136  if (frag_stream_info &&
10137  frag_stream_info->first_tfra_pts == AV_NOPTS_VALUE)
10138  frag_stream_info->first_tfra_pts = time;
10139 
10140  for (j = 0; j < ((fieldlength >> 4) & 3) + 1; j++)
10141  avio_r8(f);
10142  for (j = 0; j < ((fieldlength >> 2) & 3) + 1; j++)
10143  avio_r8(f);
10144  for (j = 0; j < ((fieldlength >> 0) & 3) + 1; j++)
10145  avio_r8(f);
10146  }
10147 
10148  avio_seek(f, pos + size, SEEK_SET);
10149  return 0;
10150 }
10151 
10153 {
10154  int64_t stream_size = avio_size(f);
10155  int64_t original_pos = avio_tell(f);
10156  int64_t seek_ret;
10157  int ret = -1;
10158  if ((seek_ret = avio_seek(f, stream_size - 4, SEEK_SET)) < 0) {
10159  ret = seek_ret;
10160  goto fail;
10161  }
10162  c->mfra_size = avio_rb32(f);
10163  c->have_read_mfra_size = 1;
10164  if (!c->mfra_size || c->mfra_size > stream_size) {
10165  av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (unreasonable size)\n");
10166  goto fail;
10167  }
10168  if ((seek_ret = avio_seek(f, -((int64_t) c->mfra_size), SEEK_CUR)) < 0) {
10169  ret = seek_ret;
10170  goto fail;
10171  }
10172  if (avio_rb32(f) != c->mfra_size) {
10173  av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (size mismatch)\n");
10174  goto fail;
10175  }
10176  if (avio_rb32(f) != MKBETAG('m', 'f', 'r', 'a')) {
10177  av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (tag mismatch)\n");
10178  goto fail;
10179  }
10180  av_log(c->fc, AV_LOG_VERBOSE, "stream has mfra\n");
10181  do {
10182  ret = read_tfra(c, f);
10183  if (ret < 0)
10184  goto fail;
10185  } while (!ret);
10186  ret = 0;
10187  c->frag_index.complete = 1;
10188 fail:
10189  seek_ret = avio_seek(f, original_pos, SEEK_SET);
10190  if (seek_ret < 0) {
10191  av_log(c->fc, AV_LOG_ERROR,
10192  "failed to seek back after looking for mfra\n");
10193  ret = seek_ret;
10194  }
10195  return ret;
10196 }
10197 
10198 static int set_icc_profile_from_item(AVPacketSideData **coded_side_data, int *nb_coded_side_data,
10199  const HEIFItem *item)
10200 {
10201  AVPacketSideData *sd = av_packet_side_data_new(coded_side_data, nb_coded_side_data,
10203  item->icc_profile_size, 0);
10204  if (!sd)
10205  return AVERROR(ENOMEM);
10206 
10207  memcpy(sd->data, item->icc_profile, item->icc_profile_size);
10208 
10209  return 0;
10210 }
10211 
10212 static int set_display_matrix_from_item(AVPacketSideData **coded_side_data, int *nb_coded_side_data,
10213  const HEIFItem *item)
10214 {
10215  int32_t *matrix;
10216  AVPacketSideData *sd = av_packet_side_data_new(coded_side_data,
10217  nb_coded_side_data,
10219  9 * sizeof(*matrix), 0);
10220  if (!sd)
10221  return AVERROR(ENOMEM);
10222 
10223  matrix = (int32_t*)sd->data;
10224  /* rotation is in the counter-clockwise direction whereas
10225  * av_display_rotation_set() expects its argument to be
10226  * oriented clockwise, so we need to negate it. */
10228  av_display_matrix_flip(matrix, item->hflip, item->vflip);
10229 
10230  return 0;
10231 }
10232 
10233 static int read_image_grid(AVFormatContext *s, const HEIFGrid *grid,
10234  AVStreamGroupTileGrid *tile_grid)
10235 {
10236  MOVContext *c = s->priv_data;
10237  const HEIFItem *item = grid->item;
10238  int64_t offset = 0, pos = avio_tell(s->pb);
10239  int x = 0, y = 0, i = 0;
10240  int tile_rows, tile_cols;
10241  int flags, size;
10242 
10243  if (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL)) {
10244  av_log(c->fc, AV_LOG_INFO, "grid box with non seekable input\n");
10245  return AVERROR_PATCHWELCOME;
10246  }
10247  if (item->is_idat_relative) {
10248  if (!c->idat_offset) {
10249  av_log(c->fc, AV_LOG_ERROR, "missing idat box required by the image grid\n");
10250  return AVERROR_INVALIDDATA;
10251  }
10252  offset = c->idat_offset;
10253  }
10254 
10255  avio_seek(s->pb, item->extent_offset + offset, SEEK_SET);
10256 
10257  avio_r8(s->pb); /* version */
10258  flags = avio_r8(s->pb);
10259 
10260  tile_rows = avio_r8(s->pb) + 1;
10261  tile_cols = avio_r8(s->pb) + 1;
10262  /* actual width and height of output image */
10263  tile_grid->width = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
10264  tile_grid->height = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
10265 
10266  av_log(c->fc, AV_LOG_TRACE, "grid: grid_rows %d grid_cols %d output_width %d output_height %d\n",
10267  tile_rows, tile_cols, tile_grid->width, tile_grid->height);
10268 
10269  avio_seek(s->pb, pos, SEEK_SET);
10270 
10271  size = tile_rows * tile_cols;
10272  tile_grid->nb_tiles = grid->nb_tiles;
10273 
10274  if (tile_grid->nb_tiles != size)
10275  return AVERROR_INVALIDDATA;
10276 
10277  for (int i = 0; i < tile_cols; i++)
10278  tile_grid->coded_width += grid->tile_item_list[i]->width;
10279  for (int i = 0; i < size; i += tile_cols)
10280  tile_grid->coded_height += grid->tile_item_list[i]->height;
10281 
10282  tile_grid->offsets = av_calloc(tile_grid->nb_tiles, sizeof(*tile_grid->offsets));
10283  if (!tile_grid->offsets)
10284  return AVERROR(ENOMEM);
10285 
10286  while (y < tile_grid->coded_height) {
10287  int left_col = i;
10288 
10289  while (x < tile_grid->coded_width) {
10290  if (i == tile_grid->nb_tiles)
10291  return AVERROR_INVALIDDATA;
10292 
10293  tile_grid->offsets[i].idx = grid->tile_idx_list[i];
10294  tile_grid->offsets[i].horizontal = x;
10295  tile_grid->offsets[i].vertical = y;
10296 
10297  x += grid->tile_item_list[i++]->width;
10298  }
10299 
10300  if (x > tile_grid->coded_width) {
10301  av_log(c->fc, AV_LOG_ERROR, "Non uniform HEIF tiles\n");
10302  return AVERROR_INVALIDDATA;
10303  }
10304 
10305  x = 0;
10306  y += grid->tile_item_list[left_col]->height;
10307  }
10308 
10309  if (y > tile_grid->coded_height || i != tile_grid->nb_tiles) {
10310  av_log(c->fc, AV_LOG_ERROR, "Non uniform HEIF tiles\n");
10311  return AVERROR_INVALIDDATA;
10312  }
10313 
10314  return 0;
10315 }
10316 
10317 static int read_image_iovl(AVFormatContext *s, const HEIFGrid *grid,
10318  AVStreamGroupTileGrid *tile_grid)
10319 {
10320  MOVContext *c = s->priv_data;
10321  const HEIFItem *item = grid->item;
10322  uint16_t canvas_fill_value[4];
10323  int64_t offset = 0, pos = avio_tell(s->pb);
10324  int ret = 0, flags;
10325 
10326  if (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL)) {
10327  av_log(c->fc, AV_LOG_INFO, "iovl box with non seekable input\n");
10328  return AVERROR_PATCHWELCOME;
10329  }
10330  if (item->is_idat_relative) {
10331  if (!c->idat_offset) {
10332  av_log(c->fc, AV_LOG_ERROR, "missing idat box required by the image overlay\n");
10333  return AVERROR_INVALIDDATA;
10334  }
10335  offset = c->idat_offset;
10336  }
10337 
10338  avio_seek(s->pb, item->extent_offset + offset, SEEK_SET);
10339 
10340  avio_r8(s->pb); /* version */
10341  flags = avio_r8(s->pb);
10342 
10343  for (int i = 0; i < 4; i++)
10344  canvas_fill_value[i] = avio_rb16(s->pb);
10345  av_log(c->fc, AV_LOG_TRACE, "iovl: canvas_fill_value { %u, %u, %u, %u }\n",
10346  canvas_fill_value[0], canvas_fill_value[1],
10347  canvas_fill_value[2], canvas_fill_value[3]);
10348  for (int i = 0; i < 4; i++)
10349  tile_grid->background[i] = canvas_fill_value[i];
10350 
10351  /* actual width and height of output image */
10352  tile_grid->width =
10353  tile_grid->coded_width = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
10354  tile_grid->height =
10355  tile_grid->coded_height = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
10356 
10357  av_log(c->fc, AV_LOG_TRACE, "iovl: output_width %d, output_height %d\n",
10358  tile_grid->width, tile_grid->height);
10359 
10360  tile_grid->nb_tiles = grid->nb_tiles;
10361  tile_grid->offsets = av_malloc_array(tile_grid->nb_tiles, sizeof(*tile_grid->offsets));
10362  if (!tile_grid->offsets) {
10363  ret = AVERROR(ENOMEM);
10364  goto fail;
10365  }
10366 
10367  for (int i = 0; i < tile_grid->nb_tiles; i++) {
10368  tile_grid->offsets[i].idx = grid->tile_idx_list[i];
10369  tile_grid->offsets[i].horizontal = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
10370  tile_grid->offsets[i].vertical = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
10371  av_log(c->fc, AV_LOG_TRACE, "iovl: stream_idx[%d] %u, "
10372  "horizontal_offset[%d] %d, vertical_offset[%d] %d\n",
10373  i, tile_grid->offsets[i].idx,
10374  i, tile_grid->offsets[i].horizontal, i, tile_grid->offsets[i].vertical);
10375  }
10376 
10377 fail:
10378  avio_seek(s->pb, pos, SEEK_SET);
10379 
10380  return ret;
10381 }
10382 
10384  AVPacketSideData **coded_side_data, int *nb_coded_side_data,
10385  const HEIFItem *ref)
10386 {
10387  MOVContext *c = s->priv_data;
10388  AVPacketSideData *sd;
10389  AVExifMetadata ifd = { 0 };
10390  AVBufferRef *buf;
10391  int64_t offset = 0, pos = avio_tell(s->pb);
10392  unsigned orientation_id = av_exif_get_tag_id("Orientation");
10393  int err;
10394 
10395  if (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL)) {
10396  av_log(c->fc, AV_LOG_WARNING, "Exif metadata with non seekable input\n");
10397  return AVERROR_PATCHWELCOME;
10398  }
10399  if (ref->is_idat_relative) {
10400  if (!c->idat_offset) {
10401  av_log(c->fc, AV_LOG_ERROR, "missing idat box required by the Exif metadata\n");
10402  return AVERROR_INVALIDDATA;
10403  }
10404  offset = c->idat_offset;
10405  }
10406 
10407  buf = av_buffer_alloc(ref->extent_length);
10408  if (!buf)
10409  return AVERROR(ENOMEM);
10410 
10411  avio_seek(s->pb, ref->extent_offset + offset, SEEK_SET);
10412  err = avio_read(s->pb, buf->data, ref->extent_length);
10413  if (err != ref->extent_length) {
10414  if (err > 0)
10415  err = AVERROR_INVALIDDATA;
10416  goto fail;
10417  }
10418 
10419  // HEIF spec states that Exif metadata is informative. The irot item property is
10420  // the normative source of rotation information. So we remove any Orientation tag
10421  // present in the Exif buffer.
10422  err = av_exif_parse_buffer(s, buf->data, ref->extent_length, &ifd, AV_EXIF_T_OFF);
10423  if (err < 0) {
10424  av_log(s, AV_LOG_ERROR, "Unable to parse Exif metadata\n");
10425  goto fail;
10426  }
10427 
10428  err = av_exif_remove_entry(s, &ifd, orientation_id, 0);
10429  if (err < 0)
10430  goto fail;
10431  else if (!err)
10432  goto finish;
10433 
10434  av_buffer_unref(&buf);
10435  err = av_exif_write(s, &ifd, &buf, AV_EXIF_T_OFF);
10436  if (err < 0)
10437  goto fail;
10438 
10439 finish:
10440  offset = AV_RB32(buf->data) + 4;
10441  if (offset >= buf->size) {
10442  err = AVERROR_INVALIDDATA;
10443  goto fail;
10444  }
10445  sd = av_packet_side_data_new(coded_side_data, nb_coded_side_data,
10446  AV_PKT_DATA_EXIF, buf->size - offset, 0);
10447  if (!sd) {
10448  err = AVERROR(ENOMEM);
10449  goto fail;
10450  }
10451  memcpy(sd->data, buf->data + offset, buf->size - offset);
10452 
10453  err = 0;
10454 fail:
10455  av_buffer_unref(&buf);
10456  av_exif_free(&ifd);
10457  avio_seek(s->pb, pos, SEEK_SET);
10458 
10459  return err;
10460 }
10461 
10463 {
10464  MOVContext *mov = s->priv_data;
10465 
10466  for (int i = 0; i < mov->nb_heif_grid; i++) {
10468  AVStreamGroupTileGrid *tile_grid;
10469  const HEIFGrid *grid = &mov->heif_grid[i];
10470  int err, loop = 1;
10471 
10472  if (!stg)
10473  return AVERROR(ENOMEM);
10474 
10475  stg->id = grid->item->item_id;
10476  tile_grid = stg->params.tile_grid;
10477 
10478  for (int j = 0; j < grid->nb_tiles; j++) {
10479  int tile_id = grid->tile_id_list[j];
10480  int k;
10481 
10482  for (k = 0; k < mov->nb_heif_item; k++) {
10483  HEIFItem *item = mov->heif_item[k];
10484  AVStream *st;
10485 
10486  if (!item || item->item_id != tile_id)
10487  continue;
10488  st = item->st;
10489  if (!st) {
10490  av_log(s, AV_LOG_WARNING, "HEIF item id %d from grid id %d doesn't "
10491  "reference a stream\n",
10492  tile_id, grid->item->item_id);
10493  ff_remove_stream_group(s, stg);
10494  loop = 0;
10495  break;
10496  }
10497 
10498  grid->tile_item_list[j] = item;
10499  grid->tile_idx_list[j] = stg->nb_streams;
10500 
10501  err = avformat_stream_group_add_stream(stg, st);
10502  if (err < 0) {
10503  int l;
10504  if (err != AVERROR(EEXIST))
10505  return err;
10506 
10507  for (l = 0; l < stg->nb_streams; l++)
10508  if (stg->streams[l]->index == st->index)
10509  break;
10510  av_assert0(l < stg->nb_streams);
10511  grid->tile_idx_list[j] = l;
10512  }
10513 
10514  if (item->item_id != mov->primary_item_id)
10516  break;
10517  }
10518 
10519  if (k == mov->nb_heif_item) {
10520  av_assert0(loop);
10521  av_log(s, AV_LOG_WARNING, "HEIF item id %d referenced by grid id %d doesn't "
10522  "exist\n",
10523  tile_id, grid->item->item_id);
10524  ff_remove_stream_group(s, stg);
10525  loop = 0;
10526  }
10527  if (!loop)
10528  break;
10529  }
10530 
10531  if (!loop)
10532  continue;
10533 
10534  switch (grid->item->type) {
10535  case MKTAG('g','r','i','d'):
10536  err = read_image_grid(s, grid, tile_grid);
10537  break;
10538  case MKTAG('i','o','v','l'):
10539  err = read_image_iovl(s, grid, tile_grid);
10540  break;
10541  default:
10542  av_assert0(0);
10543  }
10544  if (err < 0)
10545  return err;
10546 
10547  for (int j = 0; j < grid->item->nb_iref_list; j++) {
10548  HEIFItem *ref = get_heif_item(mov, grid->item->iref_list[j].item_id);
10549 
10550  av_assert0(ref);
10551  switch(ref->type) {
10552  case MKTAG('E','x','i','f'):
10553  err = mov_parse_exif_item(s, &tile_grid->coded_side_data,
10554  &tile_grid->nb_coded_side_data, ref);
10555  if (err < 0 && (s->error_recognition & AV_EF_EXPLODE))
10556  return err;
10557  break;
10558  default:
10559  break;
10560  }
10561  }
10562 
10563  /* rotation */
10564  if (grid->item->rotation || grid->item->hflip || grid->item->vflip) {
10566  &tile_grid->nb_coded_side_data, grid->item);
10567  if (err < 0)
10568  return err;
10569  }
10570 
10571  /* ICC profile */
10572  if (grid->item->icc_profile_size) {
10573  err = set_icc_profile_from_item(&tile_grid->coded_side_data,
10574  &tile_grid->nb_coded_side_data, grid->item);
10575  if (err < 0)
10576  return err;
10577  }
10578 
10579  if (grid->item->name)
10580  av_dict_set(&stg->metadata, "title", grid->item->name, 0);
10581  if (grid->item->item_id == mov->primary_item_id)
10583  }
10584 
10585  return 0;
10586 }
10587 
10589 {
10590  MOVContext *mov = s->priv_data;
10591  int err;
10592 
10593  for (int i = 0; i < mov->nb_heif_item; i++) {
10594  HEIFItem *item = mov->heif_item[i];
10595  MOVStreamContext *sc;
10596  AVStream *st;
10597  int64_t offset = 0;
10598 
10599  if (!item)
10600  continue;
10601  if (!item->st) {
10602  continue;
10603  }
10604  if (item->is_idat_relative) {
10605  if (!mov->idat_offset) {
10606  av_log(s, AV_LOG_ERROR, "Missing idat box for item %d\n", item->item_id);
10607  return AVERROR_INVALIDDATA;
10608  }
10609  offset = mov->idat_offset;
10610  }
10611 
10612  st = item->st;
10613  sc = st->priv_data;
10614  st->codecpar->width = item->width;
10615  st->codecpar->height = item->height;
10616 
10617  sc->sample_size = sc->stsz_sample_size = item->extent_length;
10618  sc->sample_count = 1;
10619 
10620  err = sanity_checks(s, sc, st->index);
10621  if (err)
10622  return AVERROR_INVALIDDATA;
10623 
10624  sc->chunk_offsets[0] = item->extent_offset + offset;
10625 
10626  if (item->item_id == mov->primary_item_id)
10628 
10629  for (int j = 0; j < item->nb_iref_list; j++) {
10630  HEIFItem *ref = get_heif_item(mov, item->iref_list[j].item_id);
10631 
10632  av_assert0(ref);
10633  switch(ref->type) {
10634  case MKTAG('E','x','i','f'):
10637  if (err < 0 && (s->error_recognition & AV_EF_EXPLODE))
10638  return err;
10639  break;
10640  default:
10641  break;
10642  }
10643  }
10644 
10645  if (item->rotation || item->hflip || item->vflip) {
10647  &st->codecpar->nb_coded_side_data, item);
10648  if (err < 0)
10649  return err;
10650  }
10651 
10652  mov_build_index(mov, st);
10653  }
10654 
10655  if (mov->nb_heif_grid) {
10656  err = mov_parse_tiles(s);
10657  if (err < 0)
10658  return err;
10659  }
10660 
10661  return 0;
10662 }
10663 
10665  int first_index)
10666 {
10667  MOVStreamContext *sc = st->priv_data;
10668 
10669  if (sc->tref_id < 0)
10670  return NULL;
10671 
10672  for (int i = first_index; i < s->nb_streams; i++)
10673  if (s->streams[i]->id == sc->tref_id)
10674  return s->streams[i];
10675 
10676  return NULL;
10677 }
10678 
10680 {
10681  int err;
10682 
10683  for (int i = 0; i < s->nb_streams; i++) {
10684  AVStreamGroup *stg;
10685  AVStream *st = s->streams[i];
10686  AVStream *st_base;
10687  MOVStreamContext *sc = st->priv_data;
10688  int j = 0;
10689 
10690  /* Find an enhancement stream. */
10691  if (st->codecpar->codec_id != AV_CODEC_ID_LCEVC ||
10693  continue;
10694 
10696 
10698  if (!stg)
10699  return AVERROR(ENOMEM);
10700 
10701  stg->id = st->id;
10702  stg->params.lcevc->width = st->codecpar->width;
10703  stg->params.lcevc->height = st->codecpar->height;
10704  st->codecpar->width = 0;
10705  st->codecpar->height = 0;
10706 
10707  while (st_base = mov_find_reference_track(s, st, j)) {
10708  err = avformat_stream_group_add_stream(stg, st_base);
10709  if (err < 0)
10710  return err;
10711 
10712  j = st_base->index + 1;
10713  }
10714  if (!j) {
10715  av_log(s, AV_LOG_ERROR, "Failed to find base stream for enhancement stream\n");
10716  return AVERROR_INVALIDDATA;
10717  }
10718 
10719  err = avformat_stream_group_add_stream(stg, st);
10720  if (err < 0)
10721  return err;
10722 
10723  stg->params.lcevc->lcevc_index = stg->nb_streams - 1;
10724  }
10725 
10726  return 0;
10727 }
10728 
10730 {
10731  int highest_id = 0;
10732 
10733  for (int i = 0; i < s->nb_streams; i++) {
10734  const AVStream *st = s->streams[i];
10735  const MOVStreamContext *sc = st->priv_data;
10736  if (!sc->iamf)
10737  highest_id = FFMAX(highest_id, st->id);
10738  }
10739  highest_id += !highest_id;
10740  for (int i = 0; highest_id > 1 && i < s->nb_stream_groups; i++) {
10741  AVStreamGroup *stg = s->stream_groups[i];
10743  continue;
10744  for (int j = 0; j < stg->nb_streams; j++) {
10745  AVStream *st = stg->streams[j];
10746  MOVStreamContext *sc = st->priv_data;
10747  st->id += highest_id;
10748  sc->iamf_stream_offset = highest_id;
10749  }
10750  }
10751 }
10752 
10754 {
10755  MOVContext *mov = s->priv_data;
10756  AVIOContext *pb = s->pb;
10757  int j, err;
10758  MOVAtom atom = { AV_RL32("root") };
10759  int i;
10760 
10761  if (mov->decryption_key_len != 0 && mov->decryption_key_len != AES_CTR_KEY_SIZE) {
10762  av_log(s, AV_LOG_ERROR, "Invalid decryption key len %d expected %d\n",
10764  return AVERROR(EINVAL);
10765  }
10766 
10767  mov->fc = s;
10768  mov->trak_index = -1;
10769  mov->primary_item_id = -1;
10770  mov->cur_item_id = -1;
10771  /* .mov and .mp4 aren't streamable anyway (only progressive download if moov is before mdat) */
10772  if (pb->seekable & AVIO_SEEKABLE_NORMAL)
10773  atom.size = avio_size(pb);
10774  else
10775  atom.size = INT64_MAX;
10776 
10777  /* check MOV header */
10778  do {
10779  if (mov->moov_retry)
10780  avio_seek(pb, 0, SEEK_SET);
10781  if ((err = mov_read_default(mov, pb, atom)) < 0) {
10782  av_log(s, AV_LOG_ERROR, "error reading header\n");
10783  return err;
10784  }
10785  } while ((pb->seekable & AVIO_SEEKABLE_NORMAL) &&
10786  !mov->found_moov && (!mov->found_iloc || !mov->found_iinf) && !mov->moov_retry++);
10787  if (!mov->found_moov && !mov->found_iloc && !mov->found_iinf) {
10788  av_log(s, AV_LOG_ERROR, "moov atom not found\n");
10789  return AVERROR_INVALIDDATA;
10790  }
10791  av_log(mov->fc, AV_LOG_TRACE, "on_parse_exit_offset=%"PRId64"\n", avio_tell(pb));
10792 
10793  if (mov->found_iloc && mov->found_iinf) {
10794  err = mov_parse_heif_items(s);
10795  if (err < 0)
10796  return err;
10797  }
10798  // prevent iloc and iinf boxes from being parsed while reading packets.
10799  // this is needed because an iinf box may have been parsed but ignored
10800  // for having old infe boxes which create no streams.
10801  mov->found_iloc = mov->found_iinf = 1;
10802 
10803  if (pb->seekable & AVIO_SEEKABLE_NORMAL) {
10804  if (mov->nb_chapter_tracks > 0 && !mov->ignore_chapters)
10806  for (i = 0; i < s->nb_streams; i++)
10807  if (s->streams[i]->codecpar->codec_tag == AV_RL32("tmcd")) {
10808  mov_read_timecode_track(s, s->streams[i]);
10809  } else if (s->streams[i]->codecpar->codec_tag == AV_RL32("rtmd")) {
10810  mov_read_rtmd_track(s, s->streams[i]);
10811  }
10812  }
10813 
10814  /* copy timecode metadata from tmcd tracks to the related video streams */
10815  for (i = 0; i < s->nb_streams; i++) {
10816  AVStream *st = s->streams[i];
10817  MOVStreamContext *sc = st->priv_data;
10818  if (sc->timecode_track > 0) {
10819  AVDictionaryEntry *tcr;
10820  int tmcd_st_id = -1;
10821 
10822  for (j = 0; j < s->nb_streams; j++) {
10823  MOVStreamContext *sc2 = s->streams[j]->priv_data;
10824  if (sc2->id == sc->timecode_track)
10825  tmcd_st_id = j;
10826  }
10827 
10828  if (tmcd_st_id < 0 || tmcd_st_id == i)
10829  continue;
10830  tcr = av_dict_get(s->streams[tmcd_st_id]->metadata, "timecode", NULL, 0);
10831  if (tcr)
10832  av_dict_set(&st->metadata, "timecode", tcr->value, 0);
10833  }
10834  }
10836 
10837  /* Create LCEVC stream groups. */
10838  err = mov_parse_lcevc_streams(s);
10839  if (err < 0)
10840  return err;
10841 
10842  for (i = 0; i < s->nb_streams; i++) {
10843  AVStream *st = s->streams[i];
10844  FFStream *const sti = ffstream(st);
10845  MOVStreamContext *sc = st->priv_data;
10846  uint32_t dvdsub_clut[FF_DVDCLUT_CLUT_LEN] = {0};
10847  fix_timescale(mov, sc);
10848 
10849  /* Set the primary extradata based on the first Sample if it doesn't reference the first stsd entry. */
10850  if (sc->stsc_count && sc->extradata_size && !sc->iamf &&
10851  sc->stsc_data[0].id > 1 && sc->stsc_data[0].id <= sc->stsd_count) {
10852  sc->last_stsd_index = sc->stsc_data[0].id - 1;
10853  av_freep(&st->codecpar->extradata);
10855  if (sc->extradata_size[sc->last_stsd_index]) {
10857  if (!st->codecpar->extradata)
10858  return AVERROR(ENOMEM);
10859  memcpy(st->codecpar->extradata, sc->extradata[sc->last_stsd_index], sc->extradata_size[sc->last_stsd_index]);
10860  }
10861  }
10862 
10863  if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
10864  st->codecpar->codec_id == AV_CODEC_ID_AAC) {
10865  sti->skip_samples = sc->start_pad;
10866  }
10867  if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && sc->nb_frames_for_fps > 0 && sc->duration_for_fps > 0)
10869  sc->time_scale*(int64_t)sc->nb_frames_for_fps, sc->duration_for_fps, INT_MAX);
10871  if (st->codecpar->width <= 0 || st->codecpar->height <= 0) {
10872  st->codecpar->width = sc->width;
10873  st->codecpar->height = sc->height;
10874  }
10877 
10878  for (j = 0; j < FF_DVDCLUT_CLUT_LEN; j++)
10879  dvdsub_clut[j] = AV_RB32(st->codecpar->extradata + j * 4);
10880 
10881  err = ff_dvdclut_yuv_to_rgb(dvdsub_clut, FF_DVDCLUT_CLUT_SIZE);
10882  if (err < 0)
10883  return err;
10884 
10885  av_freep(&st->codecpar->extradata);
10886  st->codecpar->extradata_size = 0;
10887 
10889  st->codecpar);
10890  if (err < 0)
10891  return err;
10892  }
10893  }
10894  if (mov->handbrake_version &&
10895  mov->handbrake_version <= 1000000*0 + 1000*10 + 2 && // 0.10.2
10896  st->codecpar->codec_id == AV_CODEC_ID_MP3) {
10897  av_log(s, AV_LOG_VERBOSE, "Forcing full parsing for mp3 stream\n");
10899  }
10900  }
10901 
10902  if (mov->trex_data || mov->use_mfra_for > 0) {
10903  for (i = 0; i < s->nb_streams; i++) {
10904  AVStream *st = s->streams[i];
10905  MOVStreamContext *sc = st->priv_data;
10906  if (sc->duration_for_fps > 0) {
10907  /* Akin to sc->data_size * 8 * sc->time_scale / sc->duration_for_fps but accounting for overflows. */
10909  if (st->codecpar->bit_rate == INT64_MIN) {
10910  av_log(s, AV_LOG_WARNING, "Overflow during bit rate calculation %"PRId64" * 8 * %d\n",
10911  sc->data_size, sc->time_scale);
10912  st->codecpar->bit_rate = 0;
10913  if (s->error_recognition & AV_EF_EXPLODE)
10914  return AVERROR_INVALIDDATA;
10915  }
10916  }
10917  }
10918  }
10919 
10920  for (i = 0; i < mov->bitrates_count && i < s->nb_streams; i++) {
10921  if (mov->bitrates[i]) {
10922  s->streams[i]->codecpar->bit_rate = mov->bitrates[i];
10923  }
10924  }
10925 
10927 
10928  for (i = 0; i < s->nb_streams; i++) {
10929  AVStream *st = s->streams[i];
10930  MOVStreamContext *sc = st->priv_data;
10931 
10932  switch (st->codecpar->codec_type) {
10933  case AVMEDIA_TYPE_AUDIO:
10934  err = ff_replaygain_export(st, s->metadata);
10935  if (err < 0)
10936  return err;
10937  break;
10938  case AVMEDIA_TYPE_VIDEO:
10939  if (sc->display_matrix) {
10942  (uint8_t*)sc->display_matrix, sizeof(int32_t) * 9, 0))
10943  return AVERROR(ENOMEM);
10944 
10945  sc->display_matrix = NULL;
10946  }
10947  if (sc->stereo3d) {
10950  (uint8_t *)sc->stereo3d, sc->stereo3d_size, 0))
10951  return AVERROR(ENOMEM);
10952 
10953  sc->stereo3d = NULL;
10954  }
10955  if (sc->spherical) {
10958  (uint8_t *)sc->spherical, sc->spherical_size, 0))
10959  return AVERROR(ENOMEM);
10960 
10961  sc->spherical = NULL;
10962  }
10963  if (sc->mastering) {
10966  (uint8_t *)sc->mastering, sc->mastering_size, 0))
10967  return AVERROR(ENOMEM);
10968 
10969  sc->mastering = NULL;
10970  }
10971  if (sc->coll) {
10974  (uint8_t *)sc->coll, sc->coll_size, 0))
10975  return AVERROR(ENOMEM);
10976 
10977  sc->coll = NULL;
10978  }
10979  if (sc->ambient) {
10982  (uint8_t *) sc->ambient, sc->ambient_size, 0))
10983  return AVERROR(ENOMEM);
10984 
10985  sc->ambient = NULL;
10986  }
10987  break;
10988  }
10989  }
10990 
10991  fix_stream_ids(s);
10992 
10994 
10995  for (i = 0; i < mov->frag_index.nb_items; i++)
10996  if (mov->frag_index.item[i].moof_offset <= mov->fragment.moof_offset)
10997  mov->frag_index.item[i].headers_read = 1;
10998 
10999  return 0;
11000 }
11001 
11003 {
11005  int64_t best_dts = INT64_MAX;
11006  int i;
11007  MOVContext *mov = s->priv_data;
11008  int no_interleave = !mov->interleaved_read || !(s->pb->seekable & AVIO_SEEKABLE_NORMAL);
11009  for (i = 0; i < s->nb_streams; i++) {
11010  AVStream *avst = s->streams[i];
11011  FFStream *const avsti = ffstream(avst);
11012  MOVStreamContext *msc = avst->priv_data;
11013  if (msc->pb && msc->current_sample < avsti->nb_index_entries) {
11014  AVIndexEntry *current_sample = &avsti->index_entries[msc->current_sample];
11015  int64_t dts = av_rescale(current_sample->timestamp, AV_TIME_BASE, msc->time_scale);
11016  uint64_t dtsdiff = best_dts > dts ? best_dts - (uint64_t)dts : ((uint64_t)dts - best_dts);
11017  av_log(s, AV_LOG_TRACE, "stream %d, sample %d, dts %"PRId64"\n", i, msc->current_sample, dts);
11018  if (!sample || (no_interleave && current_sample->pos < sample->pos) ||
11019  ((s->pb->seekable & AVIO_SEEKABLE_NORMAL) &&
11020  ((msc->pb != s->pb && dts < best_dts) || (msc->pb == s->pb && dts != AV_NOPTS_VALUE &&
11021  ((dtsdiff <= AV_TIME_BASE && current_sample->pos < sample->pos) ||
11022  (dtsdiff > AV_TIME_BASE && dts < best_dts && mov->interleaved_read)))))) {
11023  sample = current_sample;
11024  best_dts = dts;
11025  *st = avst;
11026  }
11027  }
11028  }
11029  return sample;
11030 }
11031 
11032 static int should_retry(AVIOContext *pb, int error_code) {
11033  if (error_code == AVERROR_EOF || avio_feof(pb))
11034  return 0;
11035 
11036  return 1;
11037 }
11038 
11039 static int mov_switch_root(AVFormatContext *s, int64_t target, int index)
11040 {
11041  int ret;
11042  MOVContext *mov = s->priv_data;
11043 
11044  if (index >= 0 && index < mov->frag_index.nb_items)
11045  target = mov->frag_index.item[index].moof_offset;
11046  if (target >= 0 && avio_seek(s->pb, target, SEEK_SET) != target) {
11047  av_log(mov->fc, AV_LOG_ERROR, "root atom offset 0x%"PRIx64": partial file\n", target);
11048  return AVERROR_INVALIDDATA;
11049  }
11050 
11051  mov->next_root_atom = 0;
11052  if ((index < 0 && target >= 0) || index >= mov->frag_index.nb_items)
11053  index = search_frag_moof_offset(&mov->frag_index, target);
11054  if (index >= 0 && index < mov->frag_index.nb_items &&
11055  mov->frag_index.item[index].moof_offset == target) {
11056  if (index + 1 < mov->frag_index.nb_items)
11057  mov->next_root_atom = mov->frag_index.item[index + 1].moof_offset;
11058  if (mov->frag_index.item[index].headers_read)
11059  return 0;
11060  mov->frag_index.item[index].headers_read = 1;
11061  }
11062 
11063  mov->found_mdat = 0;
11064 
11065  ret = mov_read_default(mov, s->pb, (MOVAtom){ AV_RL32("root"), INT64_MAX });
11066  if (ret < 0)
11067  return ret;
11068  if (avio_feof(s->pb))
11069  return AVERROR_EOF;
11070  av_log(s, AV_LOG_TRACE, "read fragments, offset 0x%"PRIx64"\n", avio_tell(s->pb));
11071 
11072  return 1;
11073 }
11074 
11076 {
11077  MOVStreamContext *sc = st->priv_data;
11078  uint8_t *side, *extradata;
11079  int extradata_size;
11080 
11081  /* Save the current index. */
11082  sc->last_stsd_index = sc->stsc_data[sc->stsc_index].id - 1;
11083 
11084  /* Notify the decoder that extradata changed. */
11085  extradata_size = sc->extradata_size[sc->last_stsd_index];
11086  extradata = sc->extradata[sc->last_stsd_index];
11087  if (st->discard != AVDISCARD_ALL && extradata_size > 0 && extradata) {
11090  extradata_size);
11091  if (!side)
11092  return AVERROR(ENOMEM);
11093  memcpy(side, extradata, extradata_size);
11094  }
11095 
11096  return 0;
11097 }
11098 
11099 static int get_eia608_packet(AVIOContext *pb, AVPacket *pkt, int src_size)
11100 {
11101  /* We can't make assumptions about the structure of the payload,
11102  because it may include multiple cdat and cdt2 samples. */
11103  const uint32_t cdat = AV_RB32("cdat");
11104  const uint32_t cdt2 = AV_RB32("cdt2");
11105  int ret, out_size = 0;
11106 
11107  /* a valid payload must have size, 4cc, and at least 1 byte pair: */
11108  if (src_size < 10)
11109  return AVERROR_INVALIDDATA;
11110 
11111  /* avoid an int overflow: */
11112  if ((src_size - 8) / 2 >= INT_MAX / 3)
11113  return AVERROR_INVALIDDATA;
11114 
11115  ret = av_new_packet(pkt, ((src_size - 8) / 2) * 3);
11116  if (ret < 0)
11117  return ret;
11118 
11119  /* parse and re-format the c608 payload in one pass. */
11120  while (src_size >= 10) {
11121  const uint32_t atom_size = avio_rb32(pb);
11122  const uint32_t atom_type = avio_rb32(pb);
11123  const uint32_t data_size = atom_size - 8;
11124  const uint8_t cc_field =
11125  atom_type == cdat ? 1 :
11126  atom_type == cdt2 ? 2 :
11127  0;
11128 
11129  /* account for bytes consumed for atom size and type. */
11130  src_size -= 8;
11131 
11132  /* make sure the data size stays within the buffer boundaries. */
11133  if (data_size < 2 || data_size > src_size) {
11135  break;
11136  }
11137 
11138  /* make sure the data size is consistent with N byte pairs. */
11139  if (data_size % 2 != 0) {
11141  break;
11142  }
11143 
11144  if (!cc_field) {
11145  /* neither cdat or cdt2 ... skip it */
11146  avio_skip(pb, data_size);
11147  src_size -= data_size;
11148  continue;
11149  }
11150 
11151  for (uint32_t i = 0; i < data_size; i += 2) {
11152  pkt->data[out_size] = (0x1F << 3) | (1 << 2) | (cc_field - 1);
11153  pkt->data[out_size + 1] = avio_r8(pb);
11154  pkt->data[out_size + 2] = avio_r8(pb);
11155  out_size += 3;
11156  src_size -= 2;
11157  }
11158  }
11159 
11160  if (src_size > 0)
11161  /* skip any remaining unread portion of the input payload */
11162  avio_skip(pb, src_size);
11163 
11165  return ret;
11166 }
11167 
11169  int64_t current_index, AVPacket *pkt)
11170 {
11171  MOVStreamContext *sc = st->priv_data;
11172 
11173  pkt->stream_index = sc->ffindex;
11174  pkt->dts = sample->timestamp;
11175  if (sample->flags & AVINDEX_DISCARD_FRAME) {
11177  }
11178  if (sc->stts_count && sc->tts_index < sc->tts_count)
11179  pkt->duration = sc->tts_data[sc->tts_index].duration;
11180  if (sc->ctts_count && sc->tts_index < sc->tts_count) {
11182  } else {
11183  if (pkt->duration == 0) {
11184  int64_t next_dts = (sc->current_sample < ffstream(st)->nb_index_entries) ?
11186  if (next_dts >= pkt->dts)
11187  pkt->duration = next_dts - pkt->dts;
11188  }
11189  pkt->pts = pkt->dts;
11190  }
11191 
11192  if (sc->tts_data && sc->tts_index < sc->tts_count) {
11193  /* update tts context */
11194  sc->tts_sample++;
11195  if (sc->tts_index < sc->tts_count &&
11196  sc->tts_data[sc->tts_index].count == sc->tts_sample) {
11197  sc->tts_index++;
11198  sc->tts_sample = 0;
11199  }
11200  }
11201 
11202  if (sc->sdtp_data && sc->current_sample <= sc->sdtp_count) {
11203  uint8_t sample_flags = sc->sdtp_data[sc->current_sample - 1];
11204  uint8_t sample_is_depended_on = (sample_flags >> 2) & 0x3;
11205  pkt->flags |= sample_is_depended_on == MOV_SAMPLE_DEPENDENCY_NO ? AV_PKT_FLAG_DISPOSABLE : 0;
11206  }
11207  pkt->flags |= sample->flags & AVINDEX_KEYFRAME ? AV_PKT_FLAG_KEY : 0;
11208  pkt->pos = sample->pos;
11209 
11210  /* Multiple stsd handling. */
11211  if (sc->stsc_data) {
11212  if (sc->stsc_data[sc->stsc_index].id > 0 &&
11213  sc->stsc_data[sc->stsc_index].id - 1 < sc->stsd_count &&
11214  sc->stsc_data[sc->stsc_index].id - 1 != sc->last_stsd_index) {
11215  int ret = mov_change_extradata(st, pkt);
11216  if (ret < 0)
11217  return ret;
11218  }
11219 
11220  /* Update the stsc index for the next sample */
11221  sc->stsc_sample++;
11222  if (mov_stsc_index_valid(sc->stsc_index, sc->stsc_count) &&
11223  mov_get_stsc_samples(sc, sc->stsc_index) == sc->stsc_sample) {
11224  sc->stsc_index++;
11225  sc->stsc_sample = 0;
11226  }
11227  }
11228 
11229  return 0;
11230 }
11231 
11233 {
11234  MOVContext *mov = s->priv_data;
11235  MOVStreamContext *sc;
11237  AVStream *st = NULL;
11238  FFStream *avsti = NULL;
11239  int64_t current_index;
11240  int ret;
11241  int i;
11242  mov->fc = s;
11243  retry:
11244  if (s->pb->pos == 0) {
11245 
11246  // Discard current fragment index
11247  if (mov->frag_index.allocated_size > 0) {
11248  for(int i = 0; i < mov->frag_index.nb_items; i++) {
11250  }
11251  av_freep(&mov->frag_index.item);
11252  mov->frag_index.nb_items = 0;
11253  mov->frag_index.allocated_size = 0;
11254  mov->frag_index.current = -1;
11255  mov->frag_index.complete = 0;
11256  }
11257 
11258  for (i = 0; i < s->nb_streams; i++) {
11259  AVStream *avst = s->streams[i];
11260  MOVStreamContext *msc = avst->priv_data;
11261 
11262  // Clear current sample
11263  mov_current_sample_set(msc, 0);
11264  msc->tts_index = 0;
11265 
11266  // Discard current index entries
11267  avsti = ffstream(avst);
11268  if (avsti->index_entries_allocated_size > 0) {
11269  av_freep(&avsti->index_entries);
11270  avsti->index_entries_allocated_size = 0;
11271  avsti->nb_index_entries = 0;
11272  }
11273  }
11274 
11275  if ((ret = mov_switch_root(s, -1, -1)) < 0)
11276  return ret;
11277  }
11278  sample = mov_find_next_sample(s, &st);
11279  if (!sample || (mov->next_root_atom && sample->pos > mov->next_root_atom)) {
11280  if (!mov->next_root_atom)
11281  return AVERROR_EOF;
11282  if ((ret = mov_switch_root(s, mov->next_root_atom, -1)) < 0)
11283  return ret;
11284  goto retry;
11285  }
11286  sc = st->priv_data;
11287  /* must be done just before reading, to avoid infinite loop on sample */
11288  current_index = sc->current_index;
11290 
11291  if (mov->next_root_atom) {
11292  sample->pos = FFMIN(sample->pos, mov->next_root_atom);
11293  sample->size = FFMIN(sample->size, (mov->next_root_atom - sample->pos));
11294  }
11295 
11296  if (st->discard != AVDISCARD_ALL) {
11297  int64_t ret64 = avio_seek(sc->pb, sample->pos, SEEK_SET);
11298  if (ret64 != sample->pos) {
11299  av_log(mov->fc, AV_LOG_ERROR, "stream %d, offset 0x%"PRIx64": partial file\n",
11300  sc->ffindex, sample->pos);
11301  if (should_retry(sc->pb, ret64)) {
11303  } else if (ret64 < 0) {
11304  return (int)ret64;
11305  }
11306  return AVERROR_INVALIDDATA;
11307  }
11308 
11309  if (st->discard == AVDISCARD_NONKEY && !(sample->flags & AVINDEX_KEYFRAME)) {
11310  av_log(mov->fc, AV_LOG_DEBUG, "Nonkey frame from stream %d discarded due to AVDISCARD_NONKEY\n", sc->ffindex);
11311  goto retry;
11312  }
11313 
11314  if (st->codecpar->codec_id == AV_CODEC_ID_EIA_608 && sample->size > 8)
11315  ret = get_eia608_packet(sc->pb, pkt, sample->size);
11316 #if CONFIG_IAMFDEC
11317  else if (sc->iamf) {
11318  int64_t pts, dts, pos, duration;
11319  int flags, size = sample->size;
11320  ret = mov_finalize_packet(s, st, sample, current_index, pkt);
11321  pts = pkt->pts; dts = pkt->dts;
11322  pos = pkt->pos; flags = pkt->flags;
11323  duration = pkt->duration;
11324  while (!ret && size > 0) {
11325  ret = ff_iamf_read_packet(s, sc->iamf, sc->pb, size, sc->iamf_stream_offset, pkt);
11326  if (ret < 0) {
11327  if (should_retry(sc->pb, ret))
11329  return ret;
11330  }
11331  size -= ret;
11332  pkt->pts = pts; pkt->dts = dts;
11333  pkt->pos = pos; pkt->flags |= flags;
11334  pkt->duration = duration;
11335  ret = ff_buffer_packet(s, pkt);
11336  }
11337  if (!ret)
11338  return FFERROR_REDO;
11339  }
11340 #endif
11341  else if (st->codecpar->codec_id == AV_CODEC_ID_APV && sample->size > 4) {
11342  const uint32_t au_size = avio_rb32(sc->pb);
11343  ret = av_get_packet(sc->pb, pkt, au_size);
11344  } else
11345  ret = av_get_packet(sc->pb, pkt, sample->size);
11346  if (ret < 0) {
11347  if (should_retry(sc->pb, ret)) {
11349  }
11350  return ret;
11351  }
11352 #if CONFIG_DV_DEMUXER
11353  if (mov->dv_demux && sc->dv_audio_container) {
11356  if (ret < 0)
11357  return ret;
11359  if (ret < 0)
11360  return ret;
11361  }
11362 #endif
11363  if (sc->has_palette) {
11364  uint8_t *pal;
11365 
11367  if (!pal) {
11368  av_log(mov->fc, AV_LOG_ERROR, "Cannot append palette to packet\n");
11369  } else {
11370  memcpy(pal, sc->palette, AVPALETTE_SIZE);
11371  sc->has_palette = 0;
11372  }
11373  }
11374  if (st->codecpar->codec_id == AV_CODEC_ID_MP3 && !ffstream(st)->need_parsing && pkt->size > 4) {
11375  if (ff_mpa_check_header(AV_RB32(pkt->data)) < 0)
11377  }
11378  }
11379 
11380  ret = mov_finalize_packet(s, st, sample, current_index, pkt);
11381  if (ret < 0)
11382  return ret;
11383 
11384  if (st->discard == AVDISCARD_ALL)
11385  goto retry;
11386 
11387  if (mov->aax_mode)
11388  aax_filter(pkt->data, pkt->size, mov);
11389 
11390  ret = cenc_filter(mov, st, sc, pkt, current_index);
11391  if (ret < 0) {
11392  return ret;
11393  }
11394 
11395  return 0;
11396 }
11397 
11399 {
11400  MOVContext *mov = s->priv_data;
11401  int index;
11402 
11403  if (!mov->frag_index.complete)
11404  return 0;
11405 
11406  index = search_frag_timestamp(s, &mov->frag_index, st, timestamp);
11407  if (index < 0)
11408  index = 0;
11409  if (!mov->frag_index.item[index].headers_read)
11410  return mov_switch_root(s, -1, index);
11411  if (index + 1 < mov->frag_index.nb_items)
11412  mov->next_root_atom = mov->frag_index.item[index + 1].moof_offset;
11413 
11414  return 0;
11415 }
11416 
11417 static int is_open_key_sample(const MOVStreamContext *sc, int sample)
11418 {
11419  // TODO: a bisect search would scale much better
11420  for (int i = 0; i < sc->open_key_samples_count; i++) {
11421  const int oks = sc->open_key_samples[i];
11422  if (oks == sample)
11423  return 1;
11424  if (oks > sample) /* list is monotically increasing so we can stop early */
11425  break;
11426  }
11427  return 0;
11428 }
11429 
11430 /*
11431  * Some key sample may be key frames but not IDR frames, so a random access to
11432  * them may not be allowed.
11433  */
11434 static int can_seek_to_key_sample(AVStream *st, int sample, int64_t requested_pts)
11435 {
11436  MOVStreamContext *sc = st->priv_data;
11437  FFStream *const sti = ffstream(st);
11438  int64_t key_sample_dts, key_sample_pts;
11439 
11440  if (st->codecpar->codec_id != AV_CODEC_ID_HEVC)
11441  return 1;
11442 
11443  if (sample >= sc->sample_offsets_count)
11444  return 1;
11445 
11446  key_sample_dts = sti->index_entries[sample].timestamp;
11447  key_sample_pts = key_sample_dts + sc->sample_offsets[sample] + sc->dts_shift;
11448 
11449  /*
11450  * If the sample needs to be presented before an open key sample, they may
11451  * not be decodable properly, even though they come after in decoding
11452  * order.
11453  */
11454  if (is_open_key_sample(sc, sample) && key_sample_pts > requested_pts)
11455  return 0;
11456 
11457  return 1;
11458 }
11459 
11460 static int mov_seek_stream(AVFormatContext *s, AVStream *st, int64_t timestamp, int flags)
11461 {
11462  MOVStreamContext *sc = st->priv_data;
11463  FFStream *const sti = ffstream(st);
11464  int sample, time_sample, ret, requested_sample;
11465  int64_t next_ts;
11466  unsigned int i;
11467 
11468  // Here we consider timestamp to be PTS, hence try to offset it so that we
11469  // can search over the DTS timeline.
11470  timestamp -= (sc->min_corrected_pts + sc->dts_shift);
11471 
11472  ret = mov_seek_fragment(s, st, timestamp);
11473  if (ret < 0)
11474  return ret;
11475 
11476  for (;;) {
11477  sample = av_index_search_timestamp(st, timestamp, flags);
11478  av_log(s, AV_LOG_TRACE, "stream %d, timestamp %"PRId64", sample %d\n", st->index, timestamp, sample);
11479  if (sample < 0 && sti->nb_index_entries && timestamp < sti->index_entries[0].timestamp)
11480  sample = 0;
11481  if (sample < 0) /* not sure what to do */
11482  return AVERROR_INVALIDDATA;
11483 
11484  if (!sample || can_seek_to_key_sample(st, sample, timestamp))
11485  break;
11486 
11487  next_ts = timestamp - FFMAX(sc->min_sample_duration, 1);
11488  requested_sample = av_index_search_timestamp(st, next_ts, flags);
11489 
11490  // If we've reached a different sample trying to find a good pts to
11491  // seek to, give up searching because we'll end up seeking back to
11492  // sample 0 on every seek.
11493  if (sample != requested_sample && !can_seek_to_key_sample(st, requested_sample, next_ts))
11494  break;
11495 
11496  timestamp = next_ts;
11497  }
11498 
11500  av_log(s, AV_LOG_TRACE, "stream %d, found sample %d\n", st->index, sc->current_sample);
11501  /* adjust time to sample index */
11502  if (sc->tts_data) {
11503  time_sample = 0;
11504  for (i = 0; i < sc->tts_count; i++) {
11505  int next = time_sample + sc->tts_data[i].count;
11506  if (next > sc->current_sample) {
11507  sc->tts_index = i;
11508  sc->tts_sample = sc->current_sample - time_sample;
11509  break;
11510  }
11511  time_sample = next;
11512  }
11513  }
11514 
11515  /* adjust stsd index */
11516  if (sc->chunk_count) {
11517  time_sample = 0;
11518  for (i = 0; i < sc->stsc_count; i++) {
11519  int64_t next = time_sample + mov_get_stsc_samples(sc, i);
11520  if (next > sc->current_sample) {
11521  sc->stsc_index = i;
11522  sc->stsc_sample = sc->current_sample - time_sample;
11523  break;
11524  }
11525  av_assert0(next == (int)next);
11526  time_sample = next;
11527  }
11528  }
11529 
11530  return sample;
11531 }
11532 
11534 {
11535  MOVStreamContext *sc = st->priv_data;
11536  FFStream *const sti = ffstream(st);
11537  int64_t first_ts = sti->index_entries[0].timestamp;
11539  int64_t off;
11540 
11542  return 0;
11543 
11544  /* compute skip samples according to stream start_pad, seek ts and first ts */
11545  off = av_rescale_q(ts - first_ts, st->time_base,
11546  (AVRational){1, st->codecpar->sample_rate});
11547  return FFMAX(sc->start_pad - off, 0);
11548 }
11549 
11550 static int mov_read_seek(AVFormatContext *s, int stream_index, int64_t sample_time, int flags)
11551 {
11552  MOVContext *mc = s->priv_data;
11553  AVStream *st;
11554  FFStream *sti;
11555  int sample;
11556  int i;
11557 
11558  if (stream_index >= s->nb_streams)
11559  return AVERROR_INVALIDDATA;
11560 
11561  st = s->streams[stream_index];
11562  sti = ffstream(st);
11563  sample = mov_seek_stream(s, st, sample_time, flags);
11564  if (sample < 0)
11565  return sample;
11566 
11567  if (mc->seek_individually) {
11568  /* adjust seek timestamp to found sample timestamp */
11569  int64_t seek_timestamp = sti->index_entries[sample].timestamp;
11571 
11572  for (i = 0; i < s->nb_streams; i++) {
11573  AVStream *const st = s->streams[i];
11574  FFStream *const sti = ffstream(st);
11575  int64_t timestamp;
11576 
11577  if (stream_index == i)
11578  continue;
11579 
11580  timestamp = av_rescale_q(seek_timestamp, s->streams[stream_index]->time_base, st->time_base);
11581  sample = mov_seek_stream(s, st, timestamp, flags);
11582  if (sample >= 0)
11584  }
11585  } else {
11586  for (i = 0; i < s->nb_streams; i++) {
11587  MOVStreamContext *sc;
11588  st = s->streams[i];
11589  sc = st->priv_data;
11590  mov_current_sample_set(sc, 0);
11591  }
11592  while (1) {
11593  MOVStreamContext *sc;
11595  if (!entry)
11596  return AVERROR_INVALIDDATA;
11597  sc = st->priv_data;
11598  if (sc->ffindex == stream_index && sc->current_sample == sample)
11599  break;
11601  }
11602  }
11603  return 0;
11604 }
11605 
11606 #define OFFSET(x) offsetof(MOVContext, x)
11607 #define FLAGS AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM
11608 static const AVOption mov_options[] = {
11609  {"use_absolute_path",
11610  "allow using absolute path when opening alias, this is a possible security issue",
11611  OFFSET(use_absolute_path), AV_OPT_TYPE_BOOL, {.i64 = 0},
11612  0, 1, FLAGS},
11613  {"seek_streams_individually",
11614  "Seek each stream individually to the closest point",
11615  OFFSET(seek_individually), AV_OPT_TYPE_BOOL, { .i64 = 1 },
11616  0, 1, FLAGS},
11617  {"ignore_editlist", "Ignore the edit list atom.", OFFSET(ignore_editlist), AV_OPT_TYPE_BOOL, {.i64 = 0},
11618  0, 1, FLAGS},
11619  {"advanced_editlist",
11620  "Modify the AVIndex according to the editlists. Use this option to decode in the order specified by the edits.",
11621  OFFSET(advanced_editlist), AV_OPT_TYPE_BOOL, {.i64 = 1},
11622  0, 1, FLAGS},
11623  {"ignore_chapters", "", OFFSET(ignore_chapters), AV_OPT_TYPE_BOOL, {.i64 = 0},
11624  0, 1, FLAGS},
11625  {"use_mfra_for",
11626  "use mfra for fragment timestamps",
11627  OFFSET(use_mfra_for), AV_OPT_TYPE_INT, {.i64 = FF_MOV_FLAG_MFRA_AUTO},
11629  .unit = "use_mfra_for"},
11630  {"auto", "auto", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_AUTO}, 0, 0,
11631  FLAGS, .unit = "use_mfra_for" },
11632  {"dts", "dts", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_DTS}, 0, 0,
11633  FLAGS, .unit = "use_mfra_for" },
11634  {"pts", "pts", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_PTS}, 0, 0,
11635  FLAGS, .unit = "use_mfra_for" },
11636  {"use_tfdt", "use tfdt for fragment timestamps", OFFSET(use_tfdt), AV_OPT_TYPE_BOOL, {.i64 = 1},
11637  0, 1, FLAGS},
11638  { "export_all", "Export unrecognized metadata entries", OFFSET(export_all),
11639  AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = FLAGS },
11640  { "export_xmp", "Export full XMP metadata", OFFSET(export_xmp),
11641  AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = FLAGS },
11642  { "activation_bytes", "Secret bytes for Audible AAX files", OFFSET(activation_bytes),
11644  { "audible_key", "AES-128 Key for Audible AAXC files", OFFSET(audible_key),
11646  { "audible_iv", "AES-128 IV for Audible AAXC files", OFFSET(audible_iv),
11648  { "audible_fixed_key", // extracted from libAAX_SDK.so and AAXSDKWin.dll files!
11649  "Fixed key used for handling Audible AAX files", OFFSET(audible_fixed_key),
11650  AV_OPT_TYPE_BINARY, {.str="77214d4b196a87cd520045fd20a51d67"},
11651  .flags = AV_OPT_FLAG_DECODING_PARAM },
11652  { "decryption_key", "The media decryption key (hex)", OFFSET(decryption_key), AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM },
11653  { "enable_drefs", "Enable external track support.", OFFSET(enable_drefs), AV_OPT_TYPE_BOOL,
11654  {.i64 = 0}, 0, 1, FLAGS },
11655  { "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 },
11656  { "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 },
11657 
11658  { NULL },
11659 };
11660 
11661 static const AVClass mov_class = {
11662  .class_name = "mov,mp4,m4a,3gp,3g2,mj2",
11663  .item_name = av_default_item_name,
11664  .option = mov_options,
11665  .version = LIBAVUTIL_VERSION_INT,
11666 };
11667 
11669  .p.name = "mov,mp4,m4a,3gp,3g2,mj2",
11670  .p.long_name = NULL_IF_CONFIG_SMALL("QuickTime / MOV"),
11671  .p.priv_class = &mov_class,
11672  .p.extensions = "mov,mp4,m4a,3gp,3g2,mj2,psp,m4b,ism,ismv,isma,f4v,avif,heic,heif",
11674  .priv_data_size = sizeof(MOVContext),
11675  .flags_internal = FF_INFMT_FLAG_INIT_CLEANUP,
11676  .read_probe = mov_probe,
11681 };
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:337
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:7421
mov_read_meta
static int mov_read_meta(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5530
AV_CODEC_ID_EIA_608
@ AV_CODEC_ID_EIA_608
Definition: codec_id.h:581
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:469
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:2306
read_image_iovl
static int read_image_iovl(AVFormatContext *s, const HEIFGrid *grid, AVStreamGroupTileGrid *tile_grid)
Definition: mov.c:10317
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:9252
AVMEDIA_TYPE_SUBTITLE
@ AVMEDIA_TYPE_SUBTITLE
Definition: avutil.h:203
AVIAMFSubmix::elements
AVIAMFSubmixElement ** elements
Array of submix elements.
Definition: iamf.h:565
skip_bits_long
static void skip_bits_long(GetBitContext *s, int n)
Skips the specified number of bits.
Definition: get_bits.h: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:357
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:382
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:8488
can_seek_to_key_sample
static int can_seek_to_key_sample(AVStream *st, int sample, int64_t requested_pts)
Definition: mov.c:11434
AV_CODEC_ID_ADPCM_IMA_QT
@ AV_CODEC_ID_ADPCM_IMA_QT
Definition: codec_id.h:376
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:462
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:767
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:11661
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
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:706
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:5163
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:10063
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:11608
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:8879
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
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:5006
cbcs_scheme_decrypt
static int cbcs_scheme_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
Definition: mov.c:8311
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:612
IS_MATRIX_IDENT
#define IS_MATRIX_IDENT(matrix)
Definition: mov.c:5548
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:3710
MOVStreamContext::spherical
AVSphericalMapping * spherical
Definition: isom.h:265
mask
int mask
Definition: mediacodecdec_common.c:154
out_size
int out_size
Definition: movenc.c:56
AV_CODEC_ID_MPEG4
@ AV_CODEC_ID_MPEG4
Definition: codec_id.h:64
AVContentLightMetadata::MaxCLL
unsigned MaxCLL
Max content light level (cd/m^2).
Definition: mastering_display_metadata.h:111
avio_get_str16be
int avio_get_str16be(AVIOContext *pb, int maxlen, char *buf, int buflen)
MOVEncryptionIndex
Definition: isom.h:126
av_encryption_init_info_free
void av_encryption_init_info_free(AVEncryptionInitInfo *info)
Frees the given encryption init info object.
Definition: encryption_info.c:216
mov_read_avss
static int mov_read_avss(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c: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:279
mov_read_custom
static int mov_read_custom(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5390
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:8873
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:3367
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:5556
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:475
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:440
av_iamf_mix_presentation_free
void av_iamf_mix_presentation_free(AVIAMFMixPresentation **pmix_presentation)
Free an AVIAMFMixPresentation and all its contents.
Definition: iamf.c:534
mov_parse_auxiliary_info
static int mov_parse_auxiliary_info(MOVContext *c, MOVStreamContext *sc, AVIOContext *pb, MOVEncryptionIndex *encryption_index)
Definition: mov.c:7629
mov_seek_stream
static int mov_seek_stream(AVFormatContext *s, AVStream *st, int64_t timestamp, int flags)
Definition: mov.c:11460
mov_read_saio
static int mov_read_saio(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:7775
mov_get_stsc_samples
static int64_t mov_get_stsc_samples(MOVStreamContext *sc, unsigned int index)
Definition: mov.c:3352
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:3919
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:11075
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:4223
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:352
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:7140
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:8418
mov_read_sdtp
static int mov_read_sdtp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:3676
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:441
mov_read_tfhd
static int mov_read_tfhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5661
AV_CODEC_ID_BIN_DATA
@ AV_CODEC_ID_BIN_DATA
Definition: codec_id.h:612
av_malloc
#define av_malloc(s)
Definition: tableprint_vlc.h:31
OPUS_SEEK_PREROLL_MS
#define OPUS_SEEK_PREROLL_MS
Definition: oggparseopus.c:36
AV_CODEC_ID_H261
@ AV_CODEC_ID_H261
Definition: codec_id.h:55
IAMFMixPresentation::cmix
const AVIAMFMixPresentation * cmix
Definition: iamf.h:108
mov_read_wide
static int mov_read_wide(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6241
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:191
ff_get_extradata
int ff_get_extradata(void *logctx, AVCodecParameters *par, AVIOContext *pb, int size)
Allocate extradata with additional AV_INPUT_BUFFER_PADDING_SIZE at end which is always set to 0 and f...
Definition: demux_utils.c:326
AVStereo3D::horizontal_field_of_view
AVRational horizontal_field_of_view
Horizontal field of view, in degrees.
Definition: stereo3d.h:239
skip_bits
static void skip_bits(GetBitContext *s, int n)
Definition: get_bits.h: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:113
OFFSET
#define OFFSET(x)
Definition: mov.c:11606
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:10198
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:777
FF_DVDCLUT_CLUT_LEN
#define FF_DVDCLUT_CLUT_LEN
Definition: dvdclut.h:28
AVEncryptionInfo::skip_byte_block
uint32_t skip_byte_block
Only used for pattern encryption.
Definition: encryption_info.h:57
finish
static void finish(void)
Definition: movenc.c:374
AVStreamGroup::params
union AVStreamGroup::@423 params
Group type-specific parameters.
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:494
AV_FOURCC_MAX_STRING_SIZE
#define AV_FOURCC_MAX_STRING_SIZE
Definition: avutil.h:345
AV_PKT_DATA_PALETTE
@ AV_PKT_DATA_PALETTE
An AV_PKT_DATA_PALETTE side data packet contains exactly AVPALETTE_SIZE bytes worth of palette.
Definition: packet.h:47
ffstream
static av_always_inline FFStream * ffstream(AVStream *st)
Definition: internal.h:347
MOVFragmentIndexItem::current
int current
Definition: isom.h:155
AVFMT_SEEK_TO_PTS
#define AVFMT_SEEK_TO_PTS
Seeking is based on PTS.
Definition: avformat.h:499
AV_CODEC_ID_PCM_S16BE
@ AV_CODEC_ID_PCM_S16BE
Definition: codec_id.h:338
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:3721
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:208
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:2376
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:336
FFStream::index_entries_allocated_size
unsigned int index_entries_allocated_size
Definition: internal.h:187
read_close
static av_cold int read_close(AVFormatContext *ctx)
Definition: libcdio.c:143
mov_read_amve
static int mov_read_amve(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6600
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:5708
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:612
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:10212
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:460
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:388
loop
static int loop
Definition: ffplay.c:335
ff_data_to_hex
char * ff_data_to_hex(char *buf, const uint8_t *src, int size, int lowercase)
Write hexadecimal string corresponding to given binary data.
Definition: utils.c: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:6672
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:7691
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:4634
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:341
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
pkt
AVPacket * pkt
Definition: movenc.c:60
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:210
AV_CODEC_ID_MACE3
@ AV_CODEC_ID_MACE3
Definition: codec_id.h:468
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:9934
AV_CH_LOW_FREQUENCY
#define AV_CH_LOW_FREQUENCY
Definition: channel_layout.h:178
duration
int64_t duration
Definition: movenc.c:65
MOVEncryptionIndex::auxiliary_offsets
uint64_t * auxiliary_offsets
Absolute seek position.
Definition: isom.h:135
read_packet
static int read_packet(void *opaque, uint8_t *buf, int buf_size)
Definition: avio_read_callback.c:42
AV_FIELD_UNKNOWN
@ AV_FIELD_UNKNOWN
Definition: defs.h: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:10383
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:4114
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:4628
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:6534
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:5182
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:459
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:4143
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:41
MOVStreamContext::min_corrected_pts
int64_t min_corrected_pts
minimum Composition time shown by the edits excluding empty edits.
Definition: isom.h:212
ffio_read_leb
unsigned int ffio_read_leb(AVIOContext *s)
Read a unsigned integer coded as a variable number of up to eight little-endian bytes,...
Definition: aviobuf.c: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:8592
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
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:6102
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:340
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:1171
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:11002
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:8572
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
mov_read_stss
static int mov_read_stss(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:3408
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:7294
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:4142
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:10008
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:6261
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:7519
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:8820
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:3556
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:3965
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:7399
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:225
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:2374
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
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:10233
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:3802
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:9654
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:11099
AV_CODEC_ID_DVD_SUBTITLE
@ AV_CODEC_ID_DVD_SUBTITLE
Definition: codec_id.h:571
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:6443
av_default_item_name
const char * av_default_item_name(void *ptr)
Return the context name.
Definition: log.c:241
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:5035
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:7991
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:478
mov_read_ilst
static int mov_read_ilst(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5335
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:8393
get_sgpd_sync_index
static uint32_t get_sgpd_sync_index(const MOVStreamContext *sc, int nal_unit_type)
Definition: mov.c:4556
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:46
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:1143
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:477
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:452
AV_CODEC_ID_EAC3
@ AV_CODEC_ID_EAC3
Definition: codec_id.h:499
should_retry
static int should_retry(AVIOContext *pb, int error_code)
Definition: mov.c:11032
avformat_stream_group_add_stream
int avformat_stream_group_add_stream(AVStreamGroup *stg, AVStream *st)
Add an already allocated stream to a stream group.
Definition: options.c:513
AV_PKT_DATA_SPHERICAL
@ AV_PKT_DATA_SPHERICAL
This side data should be associated with a video stream and corresponds to the AVSphericalMapping str...
Definition: packet.h:225
AVCodecParameters::extradata_size
int extradata_size
Size of the extradata content in bytes.
Definition: codec_par.h:73
AVIAMFSubmix
Submix layout as defined in section 3.7 of IAMF.
Definition: iamf.h:556
AV_WB32
#define AV_WB32(p, v)
Definition: intreadwrite.h:415
mov_read_pasp
static int mov_read_pasp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1383
MOVContext::dv_demux
DVDemuxContext * dv_demux
Definition: isom.h:334
AV_CODEC_ID_AAC
@ AV_CODEC_ID_AAC
Definition: codec_id.h:461
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:8730
mov_read_elst
static int mov_read_elst(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6314
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:10753
AV_CODEC_ID_QCELP
@ AV_CODEC_ID_QCELP
Definition: codec_id.h:483
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:8186
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:349
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:8246
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:9946
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
FLAC_METADATA_TYPE_STREAMINFO
@ FLAC_METADATA_TYPE_STREAMINFO
Definition: flac.h:46
avformat_alloc_context
AVFormatContext * avformat_alloc_context(void)
Allocate an AVFormatContext.
Definition: options.c:162
MOVFragmentIndexItem
Definition: isom.h:152
get_current_encryption_info
static int get_current_encryption_info(MOVContext *c, MOVEncryptionIndex **encryption_index, MOVStreamContext **sc)
Gets the current encryption info and associated current stream context.
Definition: mov.c:7468
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:4211
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:326
uuid.h
ff_dvdclut_palette_extradata_cat
int ff_dvdclut_palette_extradata_cat(const uint32_t *clut, const size_t clut_size, AVCodecParameters *par)
Definition: dvdclut.c:28
mov_read_trun
static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5794
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:9291
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:3266
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:509
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
AVStreamGroupTileGrid::offsets
struct AVStreamGroupTileGrid::@422 * offsets
An nb_tiles sized array of offsets in pixels from the topleft edge of the canvas, indicating where ea...
ff_format_io_close
int ff_format_io_close(AVFormatContext *s, AVIOContext **pb)
Definition: avformat.c:868
mov_parse_heif_items
static int mov_parse_heif_items(AVFormatContext *s)
Definition: mov.c:10588
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:4061
MOVDref::path
char * path
Definition: isom.h:87
mov_current_sample_inc
static void mov_current_sample_inc(MOVStreamContext *sc)
Definition: mov.c:4199
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:51
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:6890
fix_timescale
static void fix_timescale(MOVContext *c, MOVStreamContext *sc)
Definition: mov.c:5107
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:356
AV_PRIMARY_EYE_NONE
@ AV_PRIMARY_EYE_NONE
Neither eye.
Definition: stereo3d.h:178
mov_read_default
static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:9532
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:11232
mov_read_infe
static int mov_read_infe(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:8970
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:614
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:10664
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:2367
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:6571
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:181
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:8093
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:9402
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:8022
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:3346
mov_finalize_packet
static int mov_finalize_packet(AVFormatContext *s, AVStream *st, AVIndexEntry *sample, int64_t current_index, AVPacket *pkt)
Definition: mov.c:11168
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:11550
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:5729
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:11607
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:4251
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:7870
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:595
rb_size
static int rb_size(AVIOContext *pb, int64_t *value, int size)
Definition: mov.c:8846
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:613
ff_id3v1_genre_str
const char *const ff_id3v1_genre_str[ID3v1_GENRE_MAX+1]
ID3v1 genres.
Definition: id3v1.c:26
MOVStreamContext::sample_sizes
unsigned int * sample_sizes
Definition: isom.h:206
MOVContext::frag_index
MOVFragmentIndex frag_index
Definition: isom.h:359
mov_read_vpcc
static int mov_read_vpcc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6399
AV_CODEC_ID_PCM_F64BE
@ AV_CODEC_ID_PCM_F64BE
Definition: codec_id.h:359
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:346
mov_read_mdcv
static int mov_read_mdcv(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6490
av_mallocz
void * av_mallocz(size_t size)
Allocate a memory block with alignment suitable for all memory accesses (including vectors if availab...
Definition: mem.c:256
AV_TIMECODE_FLAG_ALLOWNEGATIVE
@ AV_TIMECODE_FLAG_ALLOWNEGATIVE
negative time values are allowed
Definition: timecode.h:38
mov_read_mdat
static int mov_read_mdat(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c: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:5344
mov_read_iref_cdsc
static int mov_read_iref_cdsc(MOVContext *c, AVIOContext *pb, uint32_t type, int version)
Definition: mov.c:9157
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:10729
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:4697
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:346
AVCodecParameters::field_order
enum AVFieldOrder field_order
Video only.
Definition: codec_par.h:161
av_get_packet
int av_get_packet(AVIOContext *s, AVPacket *pkt, int size)
Allocate and read the payload of a packet and initialize its fields with default values.
Definition: utils.c:98
mov_read_iinf
static int mov_read_iinf(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:9043
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:4102
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:6388
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:7573
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
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:8537
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:5755
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:5471
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:11039
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:11398
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:3858
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:7231
MOVTrackExt::size
unsigned size
Definition: isom.h:117
ff_remove_stream_group
void ff_remove_stream_group(AVFormatContext *s, AVStreamGroup *stg)
Remove a stream group from its AVFormatContext and free it.
Definition: avformat.c:121
AV_OPT_TYPE_INT
@ AV_OPT_TYPE_INT
Underlying C type is int.
Definition: opt.h:259
MOVContext::dv_fctx
AVFormatContext * dv_fctx
Definition: isom.h: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:465
avformat_free_context
void avformat_free_context(AVFormatContext *s)
Free an AVFormatContext and all its streams.
Definition: avformat.c:141
MOVContext::aax_mode
unsigned int aax_mode
'aax' file has been detected
Definition: isom.h:361
mov_read_sv3d
static int mov_read_sv3d(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6753
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:11533
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:10079
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:4627
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:572
AVChannelLayout::u
union AVChannelLayout::@490 u
Details about which channels are present in this layout.
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:9861
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:345
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:10462
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:9097
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:4564
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:342
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:9887
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:433
AV_CHANNEL_LAYOUT_MONO
#define AV_CHANNEL_LAYOUT_MONO
Definition: channel_layout.h:394
AV_CODEC_ID_PCM_F64LE
@ AV_CODEC_ID_PCM_F64LE
Definition: codec_id.h:360
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:10097
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:10679
mov_read_hfov
static int mov_read_hfov(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:7202
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:377
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:47
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:6963
AV_CODEC_ID_ILBC
@ AV_CODEC_ID_ILBC
Definition: codec_id.h:518
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:9847
MOVStreamContext::tmcd_nb_frames
uint8_t tmcd_nb_frames
tmcd number of frames per tick / second
Definition: isom.h:237
AVIAMFSubmixElement
Submix element as defined in section 3.7 of IAMF.
Definition: iamf.h:446
replaygain.h
MOVFragmentIndexItem::headers_read
int headers_read
Definition: isom.h:154
AV_CODEC_ID_VP8
@ AV_CODEC_ID_VP8
Definition: codec_id.h:192
AVERROR_BUG
#define AVERROR_BUG
Internal bug, also see AVERROR_BUG2.
Definition: error.h:52
MOVStreamContext::start_pad
int start_pad
amount of samples to skip due to enc-dec delay
Definition: isom.h:239
MP4TrackKindValueMapping::value
const char * value
Definition: isom.h: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:358
ff_mov_demuxer
const FFInputFormat ff_mov_demuxer
Definition: mov.c:11668
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:8377
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:464
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
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:9230
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:9191
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:10152
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:8641
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:350
MOVStreamContext::cenc
struct MOVStreamContext::@454 cenc
mov_read_st3d
static int mov_read_st3d(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6625
mov_read_imir
static int mov_read_imir(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:9272
is_open_key_sample
static int is_open_key_sample(const MOVStreamContext *sc, int sample)
Definition: mov.c:11417
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:9748
AV_CODEC_ID_DNXHD
@ AV_CODEC_ID_DNXHD
Definition: codec_id.h:151
channel
channel
Definition: ebur128.h:39
MOVStreamContext::default_encrypted_sample
AVEncryptionInfo * default_encrypted_sample
Definition: isom.h:281
MOVContext::cur_item_id
int cur_item_id
Definition: isom.h: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:8133
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:342
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:8865
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:3463