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 %"PRIu32"\n", key, data_type);
571  av_free(str);
572  return 0;
573  } else {
574  int ret = ffio_read_size(pb, str, str_size);
575  if (ret < 0) {
576  av_free(str);
577  return ret;
578  }
579  str[str_size] = 0;
580  }
581  c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
582  av_dict_set(metadata, key, str, 0);
583  if (*language && strcmp(language, "und")) {
584  snprintf(key2, sizeof(key2), "%s-%s", key, language);
585  av_dict_set(metadata, key2, str, 0);
586  }
587  if (!strcmp(key, "encoder")) {
588  int major, minor, micro;
589  if (sscanf(str, "HandBrake %d.%d.%d", &major, &minor, &micro) == 3) {
590  c->handbrake_version = 1000000*major + 1000*minor + micro;
591  }
592  }
593  }
594 
595  av_freep(&str);
596  return 0;
597 }
598 
600 {
601  int64_t start;
602  int i, nb_chapters, str_len, version;
603  char str[256+1];
604  int ret;
605 
606  if (c->ignore_chapters)
607  return 0;
608 
609  if ((atom.size -= 5) < 0)
610  return 0;
611 
612  version = avio_r8(pb);
613  avio_rb24(pb);
614  if (version)
615  avio_rb32(pb); // ???
616  nb_chapters = avio_r8(pb);
617 
618  for (i = 0; i < nb_chapters; i++) {
619  if (atom.size < 9)
620  return 0;
621 
622  start = avio_rb64(pb);
623  str_len = avio_r8(pb);
624 
625  if ((atom.size -= 9+str_len) < 0)
626  return 0;
627 
628  ret = ffio_read_size(pb, str, str_len);
629  if (ret < 0)
630  return ret;
631  str[str_len] = 0;
632  avpriv_new_chapter(c->fc, i, (AVRational){1,10000000}, start, AV_NOPTS_VALUE, str);
633  }
634  return 0;
635 }
636 
637 #define MIN_DATA_ENTRY_BOX_SIZE 12
639 {
640  AVStream *st;
641  MOVStreamContext *sc;
642  int entries, i, j;
643 
644  if (c->fc->nb_streams < 1)
645  return 0;
646  st = c->fc->streams[c->fc->nb_streams-1];
647  sc = st->priv_data;
648 
649  avio_rb32(pb); // version + flags
650  entries = avio_rb32(pb);
651  if (!entries ||
652  entries > (atom.size - 1) / MIN_DATA_ENTRY_BOX_SIZE + 1 ||
653  entries >= UINT_MAX / sizeof(*sc->drefs))
654  return AVERROR_INVALIDDATA;
655 
656  for (i = 0; i < sc->drefs_count; i++) {
657  MOVDref *dref = &sc->drefs[i];
658  av_freep(&dref->path);
659  av_freep(&dref->dir);
660  }
661  av_free(sc->drefs);
662  sc->drefs_count = 0;
663  sc->drefs = av_mallocz(entries * sizeof(*sc->drefs));
664  if (!sc->drefs)
665  return AVERROR(ENOMEM);
666  sc->drefs_count = entries;
667 
668  for (i = 0; i < entries; i++) {
669  MOVDref *dref = &sc->drefs[i];
670  uint32_t size = avio_rb32(pb);
671  int64_t next = avio_tell(pb);
672 
673  if (size < 12 || next < 0 || next > INT64_MAX - size)
674  return AVERROR_INVALIDDATA;
675 
676  next += size - 4;
677 
678  dref->type = avio_rl32(pb);
679  avio_rb32(pb); // version + flags
680 
681  if (dref->type == MKTAG('a','l','i','s') && size > 150) {
682  /* macintosh alias record */
683  uint16_t volume_len, len;
684  int16_t type;
685  int ret;
686 
687  avio_skip(pb, 10);
688 
689  volume_len = avio_r8(pb);
690  volume_len = FFMIN(volume_len, 27);
691  ret = ffio_read_size(pb, dref->volume, 27);
692  if (ret < 0)
693  return ret;
694  dref->volume[volume_len] = 0;
695  av_log(c->fc, AV_LOG_DEBUG, "volume %s, len %d\n", dref->volume, volume_len);
696 
697  avio_skip(pb, 12);
698 
699  len = avio_r8(pb);
700  len = FFMIN(len, 63);
701  ret = ffio_read_size(pb, dref->filename, 63);
702  if (ret < 0)
703  return ret;
704  dref->filename[len] = 0;
705  av_log(c->fc, AV_LOG_DEBUG, "filename %s, len %d\n", dref->filename, len);
706 
707  avio_skip(pb, 16);
708 
709  /* read next level up_from_alias/down_to_target */
710  dref->nlvl_from = avio_rb16(pb);
711  dref->nlvl_to = avio_rb16(pb);
712  av_log(c->fc, AV_LOG_DEBUG, "nlvl from %d, nlvl to %d\n",
713  dref->nlvl_from, dref->nlvl_to);
714 
715  avio_skip(pb, 16);
716 
717  for (type = 0; type != -1 && avio_tell(pb) < next; ) {
718  if (avio_feof(pb))
719  return AVERROR_EOF;
720  type = avio_rb16(pb);
721  len = avio_rb16(pb);
722  av_log(c->fc, AV_LOG_DEBUG, "type %d, len %d\n", type, len);
723  if (len&1)
724  len += 1;
725  if (type == 2) { // absolute path
726  av_free(dref->path);
727  dref->path = av_mallocz(len+1);
728  if (!dref->path)
729  return AVERROR(ENOMEM);
730 
731  ret = ffio_read_size(pb, dref->path, len);
732  if (ret < 0) {
733  av_freep(&dref->path);
734  return ret;
735  }
736  if (len > volume_len && !strncmp(dref->path, dref->volume, volume_len)) {
737  len -= volume_len;
738  memmove(dref->path, dref->path+volume_len, len);
739  dref->path[len] = 0;
740  }
741  // trim string of any ending zeros
742  for (j = len - 1; j >= 0; j--) {
743  if (dref->path[j] == 0)
744  len--;
745  else
746  break;
747  }
748  for (j = 0; j < len; j++)
749  if (dref->path[j] == ':' || dref->path[j] == 0)
750  dref->path[j] = '/';
751  av_log(c->fc, AV_LOG_DEBUG, "path %s\n", dref->path);
752  } else if (type == 0) { // directory name
753  av_free(dref->dir);
754  dref->dir = av_malloc(len+1);
755  if (!dref->dir)
756  return AVERROR(ENOMEM);
757 
758  ret = ffio_read_size(pb, dref->dir, len);
759  if (ret < 0) {
760  av_freep(&dref->dir);
761  return ret;
762  }
763  dref->dir[len] = 0;
764  for (j = 0; j < len; j++)
765  if (dref->dir[j] == ':')
766  dref->dir[j] = '/';
767  av_log(c->fc, AV_LOG_DEBUG, "dir %s\n", dref->dir);
768  } else
769  avio_skip(pb, len);
770  }
771  } else {
772  av_log(c->fc, AV_LOG_DEBUG, "Unknown dref type 0x%08"PRIx32" size %"PRIu32"\n",
773  dref->type, size);
774  entries--;
775  i--;
776  }
777  avio_seek(pb, next, SEEK_SET);
778  }
779  return 0;
780 }
781 
783 {
784  AVStream *st;
785  uint32_t type;
786  uint32_t ctype;
787  int64_t title_size;
788  char *title_str;
789  int ret;
790 
791  avio_r8(pb); /* version */
792  avio_rb24(pb); /* flags */
793 
794  /* component type */
795  ctype = avio_rl32(pb);
796  type = avio_rl32(pb); /* component subtype */
797 
798  av_log(c->fc, AV_LOG_TRACE, "ctype=%s\n", av_fourcc2str(ctype));
799  av_log(c->fc, AV_LOG_TRACE, "stype=%s\n", av_fourcc2str(type));
800 
801  if (c->trak_index < 0) { // meta not inside a trak
802  if (type == MKTAG('m','d','t','a')) {
803  c->found_hdlr_mdta = 1;
804  }
805  return 0;
806  }
807 
808  st = c->fc->streams[c->fc->nb_streams-1];
809 
810  if (type == MKTAG('v','i','d','e'))
812  else if (type == MKTAG('s','o','u','n'))
814  else if (type == MKTAG('m','1','a',' '))
816  else if ((type == MKTAG('s','u','b','p')) || (type == MKTAG('c','l','c','p')))
818 
819  avio_rb32(pb); /* component manufacture */
820  avio_rb32(pb); /* component flags */
821  avio_rb32(pb); /* component flags mask */
822 
823  title_size = atom.size - 24;
824  if (title_size > 0) {
825  if (title_size > FFMIN(INT_MAX, SIZE_MAX-1))
826  return AVERROR_INVALIDDATA;
827  title_str = av_malloc(title_size + 1); /* Add null terminator */
828  if (!title_str)
829  return AVERROR(ENOMEM);
830 
831  ret = ffio_read_size(pb, title_str, title_size);
832  if (ret < 0) {
833  av_freep(&title_str);
834  return ret;
835  }
836  title_str[title_size] = 0;
837  if (title_str[0]) {
838  int off = (!c->isom && title_str[0] == title_size - 1);
839  // flag added so as to not set stream handler name if already set from mdia->hdlr
840  av_dict_set(&st->metadata, "handler_name", title_str + off, AV_DICT_DONT_OVERWRITE);
841  }
842  av_freep(&title_str);
843  }
844 
845  return 0;
846 }
847 
849 {
850  return ff_mov_read_esds(c->fc, pb);
851 }
852 
854 {
855  AVStream *st;
856  AVPacketSideData *sd;
857  enum AVAudioServiceType *ast;
858  int ac3info, acmod, lfeon, bsmod;
859  uint64_t mask;
860 
861  if (c->fc->nb_streams < 1)
862  return 0;
863  st = c->fc->streams[c->fc->nb_streams-1];
864 
868  sizeof(*ast), 0);
869  if (!sd)
870  return AVERROR(ENOMEM);
871 
872  ast = (enum AVAudioServiceType*)sd->data;
873  ac3info = avio_rb24(pb);
874  bsmod = (ac3info >> 14) & 0x7;
875  acmod = (ac3info >> 11) & 0x7;
876  lfeon = (ac3info >> 10) & 0x1;
877 
879  if (lfeon)
883 
884  *ast = bsmod;
885  if (st->codecpar->ch_layout.nb_channels > 1 && bsmod == 0x7)
887 
888  return 0;
889 }
890 
891 #if CONFIG_IAMFDEC
892 static int mov_read_iacb(MOVContext *c, AVIOContext *pb, MOVAtom atom)
893 {
894  AVStream *st;
895  MOVStreamContext *sc;
896  FFIOContext b;
897  AVIOContext *descriptor_pb;
899  IAMFContext *iamf;
901  unsigned descriptors_size;
902  int nb_frames, disposition;
903  int version, ret;
904 
905  if (atom.size < 5)
906  return AVERROR_INVALIDDATA;
907 
908  if (c->fc->nb_streams < 1)
909  return 0;
910 
911  version = avio_r8(pb);
912  if (version != 1) {
913  av_log(c->fc, AV_LOG_ERROR, "%s configurationVersion %d",
914  version < 1 ? "invalid" : "unsupported", version);
915  return AVERROR_INVALIDDATA;
916  }
917 
918  descriptors_size = ffio_read_leb(pb);
919  if (!descriptors_size || descriptors_size > INT_MAX)
920  return AVERROR_INVALIDDATA;
921 
922  st = c->fc->streams[c->fc->nb_streams - 1];
923  sc = st->priv_data;
924 
925  if (st->codecpar->extradata) {
926  av_log(c->fc, AV_LOG_WARNING, "ignoring iacb\n");
927  return 0;
928  }
929 
930  sc->iamf = av_mallocz(sizeof(*sc->iamf));
931  if (!sc->iamf)
932  return AVERROR(ENOMEM);
933  iamf = &sc->iamf->iamf;
934 
935  ret = ff_alloc_extradata(st->codecpar, descriptors_size);
936  if (ret < 0)
937  return ret;
938 
939  ret = avio_read(pb, st->codecpar->extradata, descriptors_size);
940  if (ret != descriptors_size)
941  return ret < 0 ? ret : AVERROR_INVALIDDATA;
942 
943  ffio_init_read_context(&b, st->codecpar->extradata, descriptors_size);
944  descriptor_pb = &b.pub;
945 
946  ret = ff_iamfdec_read_descriptors(iamf, descriptor_pb, descriptors_size, c->fc);
947  if (ret < 0)
948  return ret;
949 
950  metadata = st->metadata;
951  st->metadata = NULL;
952  start_time = st->start_time;
953  nb_frames = st->nb_frames;
954  duration = st->duration;
955  disposition = st->disposition;
956 
957  for (int i = 0; i < iamf->nb_audio_elements; i++) {
958  IAMFAudioElement *audio_element = iamf->audio_elements[i];
959  const AVIAMFAudioElement *element;
960  AVStreamGroup *stg =
962 
963  if (!stg) {
964  ret = AVERROR(ENOMEM);
965  goto fail;
966  }
967 
969  stg->id = audio_element->audio_element_id;
970  /* Transfer ownership */
971  element = stg->params.iamf_audio_element = audio_element->element;
972  audio_element->element = NULL;
973 
974  for (int j = 0; j < audio_element->nb_substreams; j++) {
975  IAMFSubStream *substream = &audio_element->substreams[j];
976  AVStream *stream;
977 
978  if (!i && !j) {
979  if (audio_element->layers[0].substream_count != 1)
980  disposition &= ~AV_DISPOSITION_DEFAULT;
981  stream = st;
982  } else
983  stream = avformat_new_stream(c->fc, NULL);
984  if (!stream) {
985  ret = AVERROR(ENOMEM);
986  goto fail;
987  }
988 
989  stream->start_time = start_time;
990  stream->nb_frames = nb_frames;
991  stream->duration = duration;
992  stream->disposition = disposition;
993  if (stream != st) {
994  stream->priv_data = sc;
995  sc->refcount++;
996  }
997 
1000  if (i || j) {
1002  if (audio_element->layers[0].substream_count == 1)
1003  stream->disposition &= ~AV_DISPOSITION_DEFAULT;
1004  }
1005 
1006  ret = avcodec_parameters_copy(stream->codecpar, substream->codecpar);
1007  if (ret < 0)
1008  goto fail;
1009 
1010  stream->id = substream->audio_substream_id;
1011 
1012  avpriv_set_pts_info(st, 64, 1, sc->time_scale);
1013 
1014  ret = avformat_stream_group_add_stream(stg, stream);
1015  if (ret < 0)
1016  goto fail;
1017  }
1018 
1019  ret = av_dict_copy(&stg->metadata, metadata, 0);
1020  if (ret < 0)
1021  goto fail;
1022  }
1023 
1024  for (int i = 0; i < iamf->nb_mix_presentations; i++) {
1025  IAMFMixPresentation *mix_presentation = iamf->mix_presentations[i];
1026  const AVIAMFMixPresentation *mix = mix_presentation->cmix;
1027  AVStreamGroup *stg =
1029 
1030  if (!stg) {
1031  ret = AVERROR(ENOMEM);
1032  goto fail;
1033  }
1034 
1036  stg->id = mix_presentation->mix_presentation_id;
1037  /* Transfer ownership */
1038  stg->params.iamf_mix_presentation = mix_presentation->mix;
1039  mix_presentation->mix = NULL;
1040 
1041  for (int j = 0; j < mix->nb_submixes; j++) {
1042  const AVIAMFSubmix *submix = mix->submixes[j];
1043 
1044  for (int k = 0; k < submix->nb_elements; k++) {
1045  const AVIAMFSubmixElement *submix_element = submix->elements[k];
1046  const AVStreamGroup *audio_element = NULL;
1047 
1048  for (int l = 0; l < c->fc->nb_stream_groups; l++)
1049  if (c->fc->stream_groups[l]->type == AV_STREAM_GROUP_PARAMS_IAMF_AUDIO_ELEMENT &&
1050  c->fc->stream_groups[l]->id == submix_element->audio_element_id) {
1051  audio_element = c->fc->stream_groups[l];
1052  break;
1053  }
1054  av_assert0(audio_element);
1055 
1056  for (int l = 0; l < audio_element->nb_streams; l++) {
1057  ret = avformat_stream_group_add_stream(stg, audio_element->streams[l]);
1058  if (ret < 0 && ret != AVERROR(EEXIST))
1059  goto fail;
1060  }
1061  }
1062  }
1063 
1064  ret = av_dict_copy(&stg->metadata, metadata, 0);
1065  if (ret < 0)
1066  goto fail;
1067  }
1068 
1069  ret = 0;
1070 fail:
1072 
1073  return ret;
1074 }
1075 #endif
1076 
1078 {
1079  AVStream *st;
1080  int32_t sample_rate;
1081 
1082  if (atom.size < 8 || c->fc->nb_streams < 1)
1083  return 0;
1084 
1085  st = c->fc->streams[c->fc->nb_streams-1];
1086  if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO) {
1087  av_log(c->fc, AV_LOG_WARNING, "'srat' within non-audio sample entry, skip\n");
1088  return 0;
1089  }
1090 
1091  if (!c->isom) {
1092  av_log(c->fc, AV_LOG_WARNING, "'srat' within non-isom, skip\n");
1093  return 0;
1094  }
1095 
1096  avio_skip(pb, 4); // version+flags
1097  sample_rate = avio_rb32(pb);
1098  if (sample_rate > 0) {
1099  av_log(c->fc, AV_LOG_DEBUG,
1100  "overwrite sample rate from %d to %d by 'srat'\n",
1101  st->codecpar->sample_rate, sample_rate);
1102  st->codecpar->sample_rate = sample_rate;
1103  } else {
1104  av_log(c->fc, AV_LOG_WARNING,
1105  "ignore invalid sample rate %d in 'srat'\n", sample_rate);
1106  }
1107 
1108  return 0;
1109 }
1110 
1112 {
1113  AVStream *st;
1114  AVPacketSideData *sd;
1115  enum AVAudioServiceType *ast;
1116  int eac3info, acmod, lfeon, bsmod;
1117  uint64_t mask;
1118 
1119  if (c->fc->nb_streams < 1)
1120  return 0;
1121  st = c->fc->streams[c->fc->nb_streams-1];
1122 
1126  sizeof(*ast), 0);
1127  if (!sd)
1128  return AVERROR(ENOMEM);
1129 
1130  ast = (enum AVAudioServiceType*)sd->data;
1131 
1132  /* No need to parse fields for additional independent substreams and its
1133  * associated dependent substreams since libavcodec's E-AC-3 decoder
1134  * does not support them yet. */
1135  avio_rb16(pb); /* data_rate and num_ind_sub */
1136  eac3info = avio_rb24(pb);
1137  bsmod = (eac3info >> 12) & 0x1f;
1138  acmod = (eac3info >> 9) & 0x7;
1139  lfeon = (eac3info >> 8) & 0x1;
1140 
1142  if (lfeon)
1146 
1147  *ast = bsmod;
1148  if (st->codecpar->ch_layout.nb_channels > 1 && bsmod == 0x7)
1150 
1151  return 0;
1152 }
1153 
1155 {
1156 #define DDTS_SIZE 20
1157  uint8_t buf[DDTS_SIZE + AV_INPUT_BUFFER_PADDING_SIZE];
1158  AVStream *st = NULL;
1159  uint32_t frame_duration_code = 0;
1160  uint32_t channel_layout_code = 0;
1161  GetBitContext gb;
1162  int ret;
1163 
1164  if ((ret = ffio_read_size(pb, buf, DDTS_SIZE)) < 0)
1165  return ret;
1166 
1167  init_get_bits(&gb, buf, 8 * DDTS_SIZE);
1168 
1169  if (c->fc->nb_streams < 1) {
1170  return 0;
1171  }
1172  st = c->fc->streams[c->fc->nb_streams-1];
1173 
1174  st->codecpar->sample_rate = get_bits_long(&gb, 32);
1175  if (st->codecpar->sample_rate <= 0) {
1176  av_log(c->fc, AV_LOG_ERROR, "Invalid sample rate %d\n", st->codecpar->sample_rate);
1177  return AVERROR_INVALIDDATA;
1178  }
1179  skip_bits_long(&gb, 32); /* max bitrate */
1180  st->codecpar->bit_rate = get_bits_long(&gb, 32);
1181  st->codecpar->bits_per_coded_sample = get_bits(&gb, 8);
1182  frame_duration_code = get_bits(&gb, 2);
1183  skip_bits(&gb, 30); /* various fields */
1184  channel_layout_code = get_bits(&gb, 16);
1185 
1186  st->codecpar->frame_size =
1187  (frame_duration_code == 0) ? 512 :
1188  (frame_duration_code == 1) ? 1024 :
1189  (frame_duration_code == 2) ? 2048 :
1190  (frame_duration_code == 3) ? 4096 : 0;
1191 
1192  if (channel_layout_code > 0xff) {
1193  av_log(c->fc, AV_LOG_WARNING, "Unsupported DTS audio channel layout\n");
1194  }
1197  ((channel_layout_code & 0x1) ? AV_CH_FRONT_CENTER : 0) |
1198  ((channel_layout_code & 0x2) ? AV_CH_FRONT_LEFT : 0) |
1199  ((channel_layout_code & 0x2) ? AV_CH_FRONT_RIGHT : 0) |
1200  ((channel_layout_code & 0x4) ? AV_CH_SIDE_LEFT : 0) |
1201  ((channel_layout_code & 0x4) ? AV_CH_SIDE_RIGHT : 0) |
1202  ((channel_layout_code & 0x8) ? AV_CH_LOW_FREQUENCY : 0));
1203 
1204  return 0;
1205 }
1206 
1208 {
1209  AVStream *st;
1210 
1211  if (c->fc->nb_streams < 1)
1212  return 0;
1213  st = c->fc->streams[c->fc->nb_streams-1];
1214 
1215  if (atom.size < 16)
1216  return 0;
1217 
1218  /* skip version and flags */
1219  avio_skip(pb, 4);
1220 
1221  ff_mov_read_chan(c->fc, pb, st, atom.size - 4);
1222 
1223  return 0;
1224 }
1225 
1227 {
1228  int64_t end = av_sat_add64(avio_tell(pb), atom.size);
1229  int version, flags;
1230  int ret;
1231  AVStream *st;
1232 
1233  if (c->fc->nb_streams < 1)
1234  return 0;
1235  st = c->fc->streams[c->fc->nb_streams-1];
1236 
1237  version = avio_r8(pb);
1238  flags = avio_rb24(pb);
1239  if (version != 0 || flags != 0) {
1240  av_log(c->fc, AV_LOG_ERROR,
1241  "Unsupported 'chnl' box with version %d, flags: %#x",
1242  version, flags);
1243  return AVERROR_INVALIDDATA;
1244  }
1245 
1246  ret = ff_mov_read_chnl(c->fc, pb, st);
1247  if (ret < 0)
1248  return ret;
1249 
1250  if (avio_tell(pb) != end) {
1251  av_log(c->fc, AV_LOG_WARNING, "skip %" PRId64 " bytes of unknown data inside chnl\n",
1252  end - avio_tell(pb));
1253  avio_seek(pb, end, SEEK_SET);
1254  }
1255  return ret;
1256 }
1257 
1259 {
1260  AVStream *st;
1261  int ret;
1262 
1263  if (c->fc->nb_streams < 1)
1264  return 0;
1265  st = c->fc->streams[c->fc->nb_streams-1];
1266 
1267  if ((ret = ff_get_wav_header(c->fc, pb, st->codecpar, atom.size, 0)) < 0)
1268  av_log(c->fc, AV_LOG_WARNING, "get_wav_header failed\n");
1269 
1270  return ret;
1271 }
1272 
1274 {
1275  AVStream *st;
1276  HEIFItem *item;
1277  AVPacketSideData *sd;
1278  int width, height, err = 0;
1279  AVRational aperture_width, aperture_height, horiz_off, vert_off;
1280  AVRational pc_x, pc_y;
1281  uint64_t top, bottom, left, right;
1282 
1283  item = get_heif_item(c, c->cur_item_id);
1284  st = get_curr_st(c);
1285  if (!st)
1286  return 0;
1287 
1288  width = st->codecpar->width;
1289  height = st->codecpar->height;
1290  if ((!width || !height) && item) {
1291  width = item->width;
1292  height = item->height;
1293  }
1294  if (!width || !height) {
1295  err = AVERROR_INVALIDDATA;
1296  goto fail;
1297  }
1298 
1299  aperture_width.num = avio_rb32(pb);
1300  aperture_width.den = avio_rb32(pb);
1301  aperture_height.num = avio_rb32(pb);
1302  aperture_height.den = avio_rb32(pb);
1303 
1304  horiz_off.num = avio_rb32(pb);
1305  horiz_off.den = avio_rb32(pb);
1306  vert_off.num = avio_rb32(pb);
1307  vert_off.den = avio_rb32(pb);
1308 
1309  if (aperture_width.num < 0 || aperture_width.den < 0 ||
1310  aperture_height.num < 0 || aperture_height.den < 0 ||
1311  horiz_off.den < 0 || vert_off.den < 0) {
1312  err = AVERROR_INVALIDDATA;
1313  goto fail;
1314  }
1315  if ((av_cmp_q((AVRational) { width, 1 }, aperture_width) < 0) ||
1316  (av_cmp_q((AVRational) { height, 1 }, aperture_height) < 0)) {
1317  err = AVERROR_INVALIDDATA;
1318  goto fail;
1319  }
1320  av_log(c->fc, AV_LOG_TRACE, "clap: apertureWidth %d/%d, apertureHeight %d/%d "
1321  "horizOff %d/%d vertOff %d/%d\n",
1322  aperture_width.num, aperture_width.den, aperture_height.num, aperture_height.den,
1323  horiz_off.num, horiz_off.den, vert_off.num, vert_off.den);
1324 
1325  pc_x = av_mul_q((AVRational) { width - 1, 1 }, (AVRational) { 1, 2 });
1326  pc_x = av_add_q(pc_x, horiz_off);
1327  pc_y = av_mul_q((AVRational) { height - 1, 1 }, (AVRational) { 1, 2 });
1328  pc_y = av_add_q(pc_y, vert_off);
1329 
1330  aperture_width = av_sub_q(aperture_width, (AVRational) { 1, 1 });
1331  aperture_width = av_mul_q(aperture_width, (AVRational) { 1, 2 });
1332  aperture_height = av_sub_q(aperture_height, (AVRational) { 1, 1 });
1333  aperture_height = av_mul_q(aperture_height, (AVRational) { 1, 2 });
1334 
1335  left = av_q2d(av_sub_q(pc_x, aperture_width));
1336  right = av_q2d(av_add_q(pc_x, aperture_width));
1337  top = av_q2d(av_sub_q(pc_y, aperture_height));
1338  bottom = av_q2d(av_add_q(pc_y, aperture_height));
1339 
1340  if (bottom > (height - 1) ||
1341  right > (width - 1)) {
1342  err = AVERROR_INVALIDDATA;
1343  goto fail;
1344  }
1345 
1346  bottom = height - 1 - bottom;
1347  right = width - 1 - right;
1348 
1349  if (!(left | right | top | bottom))
1350  return 0;
1351 
1352  if ((left + right) >= width ||
1353  (top + bottom) >= height) {
1354  err = AVERROR_INVALIDDATA;
1355  goto fail;
1356  }
1357 
1361  sizeof(uint32_t) * 4, 0);
1362  if (!sd)
1363  return AVERROR(ENOMEM);
1364 
1365  AV_WL32A(sd->data, top);
1366  AV_WL32A(sd->data + 4, bottom);
1367  AV_WL32A(sd->data + 8, left);
1368  AV_WL32A(sd->data + 12, right);
1369 
1370 fail:
1371  if (err < 0) {
1372  int explode = !!(c->fc->error_recognition & AV_EF_EXPLODE);
1373  av_log(c->fc, explode ? AV_LOG_ERROR : AV_LOG_WARNING, "Invalid clap box\n");
1374  if (!explode)
1375  err = 0;
1376  }
1377 
1378  return err;
1379 }
1380 
1381 /* This atom overrides any previously set aspect ratio */
1383 {
1384  const int num = avio_rb32(pb);
1385  const int den = avio_rb32(pb);
1386  AVStream *st;
1387  MOVStreamContext *sc;
1388 
1389  if (c->fc->nb_streams < 1)
1390  return 0;
1391  st = c->fc->streams[c->fc->nb_streams-1];
1392  sc = st->priv_data;
1393 
1394  av_log(c->fc, AV_LOG_TRACE, "pasp: hSpacing %d, vSpacing %d\n", num, den);
1395 
1396  if (den != 0) {
1397  sc->h_spacing = num;
1398  sc->v_spacing = den;
1399  }
1400  return 0;
1401 }
1402 
1403 /* this atom contains actual media data */
1405 {
1406  if (atom.size == 0) /* wrong one (MP4) */
1407  return 0;
1408  c->found_mdat=1;
1409  return 0; /* now go for moov */
1410 }
1411 
1412 #define DRM_BLOB_SIZE 56
1413 
1415 {
1416  uint8_t intermediate_key[20];
1417  uint8_t intermediate_iv[20];
1418  uint8_t input[64];
1419  uint8_t output[64];
1420  uint8_t file_checksum[20];
1421  uint8_t calculated_checksum[20];
1422  char checksum_string[2 * sizeof(file_checksum) + 1];
1423  struct AVSHA *sha;
1424  int i;
1425  int ret = 0;
1426  uint8_t *activation_bytes = c->activation_bytes;
1427  uint8_t *fixed_key = c->audible_fixed_key;
1428 
1429  c->aax_mode = 1;
1430 
1431  sha = av_sha_alloc();
1432  if (!sha)
1433  return AVERROR(ENOMEM);
1434  av_free(c->aes_decrypt);
1435  c->aes_decrypt = av_aes_alloc();
1436  if (!c->aes_decrypt) {
1437  ret = AVERROR(ENOMEM);
1438  goto fail;
1439  }
1440 
1441  /* drm blob processing */
1442  avio_read(pb, output, 8); // go to offset 8, absolute position 0x251
1444  avio_read(pb, output, 4); // go to offset 4, absolute position 0x28d
1445  ret = ffio_read_size(pb, file_checksum, 20);
1446  if (ret < 0)
1447  goto fail;
1448 
1449  // required by external tools
1450  ff_data_to_hex(checksum_string, file_checksum, sizeof(file_checksum), 1);
1451  av_log(c->fc, AV_LOG_INFO, "[aax] file checksum == %s\n", checksum_string);
1452 
1453  /* verify activation data */
1454  if (!activation_bytes) {
1455  av_log(c->fc, AV_LOG_WARNING, "[aax] activation_bytes option is missing!\n");
1456  ret = 0; /* allow ffprobe to continue working on .aax files */
1457  goto fail;
1458  }
1459  if (c->activation_bytes_size != 4) {
1460  av_log(c->fc, AV_LOG_FATAL, "[aax] activation_bytes value needs to be 4 bytes!\n");
1461  ret = AVERROR(EINVAL);
1462  goto fail;
1463  }
1464 
1465  /* verify fixed key */
1466  if (c->audible_fixed_key_size != 16) {
1467  av_log(c->fc, AV_LOG_FATAL, "[aax] audible_fixed_key value needs to be 16 bytes!\n");
1468  ret = AVERROR(EINVAL);
1469  goto fail;
1470  }
1471 
1472  /* AAX (and AAX+) key derivation */
1473  av_sha_init(sha, 160);
1474  av_sha_update(sha, fixed_key, 16);
1475  av_sha_update(sha, activation_bytes, 4);
1476  av_sha_final(sha, intermediate_key);
1477  av_sha_init(sha, 160);
1478  av_sha_update(sha, fixed_key, 16);
1479  av_sha_update(sha, intermediate_key, 20);
1480  av_sha_update(sha, activation_bytes, 4);
1481  av_sha_final(sha, intermediate_iv);
1482  av_sha_init(sha, 160);
1483  av_sha_update(sha, intermediate_key, 16);
1484  av_sha_update(sha, intermediate_iv, 16);
1485  av_sha_final(sha, calculated_checksum);
1486  if (memcmp(calculated_checksum, file_checksum, 20)) { // critical error
1487  av_log(c->fc, AV_LOG_ERROR, "[aax] mismatch in checksums!\n");
1489  goto fail;
1490  }
1491  av_aes_init(c->aes_decrypt, intermediate_key, 128, 1);
1492  av_aes_crypt(c->aes_decrypt, output, input, DRM_BLOB_SIZE >> 4, intermediate_iv, 1);
1493  for (i = 0; i < 4; i++) {
1494  // file data (in output) is stored in big-endian mode
1495  if (activation_bytes[i] != output[3 - i]) { // critical error
1496  av_log(c->fc, AV_LOG_ERROR, "[aax] error in drm blob decryption!\n");
1498  goto fail;
1499  }
1500  }
1501  memcpy(c->file_key, output + 8, 16);
1502  memcpy(input, output + 26, 16);
1503  av_sha_init(sha, 160);
1504  av_sha_update(sha, input, 16);
1505  av_sha_update(sha, c->file_key, 16);
1506  av_sha_update(sha, fixed_key, 16);
1507  av_sha_final(sha, c->file_iv);
1508 
1509 fail:
1510  av_free(sha);
1511 
1512  return ret;
1513 }
1514 
1516 {
1517  if (c->audible_key_size != 16) {
1518  av_log(c->fc, AV_LOG_FATAL, "[aaxc] audible_key value needs to be 16 bytes!\n");
1519  return AVERROR(EINVAL);
1520  }
1521 
1522  if (c->audible_iv_size != 16) {
1523  av_log(c->fc, AV_LOG_FATAL, "[aaxc] audible_iv value needs to be 16 bytes!\n");
1524  return AVERROR(EINVAL);
1525  }
1526 
1527  c->aes_decrypt = av_aes_alloc();
1528  if (!c->aes_decrypt) {
1529  return AVERROR(ENOMEM);
1530  }
1531 
1532  memcpy(c->file_key, c->audible_key, 16);
1533  memcpy(c->file_iv, c->audible_iv, 16);
1534  c->aax_mode = 1;
1535 
1536  return 0;
1537 }
1538 
1539 // Audible AAX (and AAX+) bytestream decryption
1540 static int aax_filter(uint8_t *input, int size, MOVContext *c)
1541 {
1542  int blocks = 0;
1543  unsigned char iv[16];
1544 
1545  memcpy(iv, c->file_iv, 16); // iv is overwritten
1546  blocks = size >> 4; // trailing bytes are not encrypted!
1547  av_aes_init(c->aes_decrypt, c->file_key, 128, 1);
1548  av_aes_crypt(c->aes_decrypt, input, input, blocks, iv, 1);
1549 
1550  return 0;
1551 }
1552 
1553 /* read major brand, minor version and compatible brands and store them as metadata */
1555 {
1556  uint32_t minor_ver;
1557  int comp_brand_size;
1558  char* comp_brands_str;
1559  uint8_t type[5] = {0};
1560  int ret = ffio_read_size(pb, type, 4);
1561  if (ret < 0)
1562  return ret;
1563  if (c->fc->nb_streams) {
1564  if (c->fc->strict_std_compliance >= FF_COMPLIANCE_STRICT)
1565  return AVERROR_INVALIDDATA;
1566  av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate FTYP\n");
1567  return 0;
1568  }
1569 
1570  if (strcmp(type, "qt "))
1571  c->isom = 1;
1572  av_log(c->fc, AV_LOG_DEBUG, "ISO: File Type Major Brand: %.4s\n",(char *)&type);
1573  av_dict_set(&c->fc->metadata, "major_brand", type, 0);
1574  minor_ver = avio_rb32(pb); /* minor version */
1575  av_dict_set_int(&c->fc->metadata, "minor_version", minor_ver, 0);
1576 
1577  comp_brand_size = atom.size - 8;
1578  if (comp_brand_size < 0 || comp_brand_size == INT_MAX)
1579  return AVERROR_INVALIDDATA;
1580  comp_brands_str = av_malloc(comp_brand_size + 1); /* Add null terminator */
1581  if (!comp_brands_str)
1582  return AVERROR(ENOMEM);
1583 
1584  ret = ffio_read_size(pb, comp_brands_str, comp_brand_size);
1585  if (ret < 0) {
1586  av_freep(&comp_brands_str);
1587  return ret;
1588  }
1589  comp_brands_str[comp_brand_size] = 0;
1590  av_dict_set(&c->fc->metadata, "compatible_brands",
1591  comp_brands_str, AV_DICT_DONT_STRDUP_VAL);
1592 
1593  // Logic for handling Audible's .aaxc files
1594  if (!strcmp(type, "aaxc")) {
1595  mov_aaxc_crypto(c);
1596  }
1597 
1598  return 0;
1599 }
1600 
1601 /* this atom should contain all header atoms */
1603 {
1604  int ret;
1605 
1606  if (c->found_moov) {
1607  av_log(c->fc, AV_LOG_WARNING, "Found duplicated MOOV Atom. Skipped it\n");
1608  avio_skip(pb, atom.size);
1609  return 0;
1610  }
1611 
1612  if ((ret = mov_read_default(c, pb, atom)) < 0)
1613  return ret;
1614  /* we parsed the 'moov' atom, we can terminate the parsing as soon as we find the 'mdat' */
1615  /* so we don't parse the whole file if over a network */
1616  c->found_moov=1;
1617  return 0; /* now go for mdat */
1618 }
1619 
1621  MOVFragmentIndex *frag_index,
1622  int index,
1623  int id)
1624 {
1625  int i;
1626  MOVFragmentIndexItem * item;
1627 
1628  if (index < 0 || index >= frag_index->nb_items)
1629  return NULL;
1630  item = &frag_index->item[index];
1631  for (i = 0; i < item->nb_stream_info; i++)
1632  if (item->stream_info[i].id == id)
1633  return &item->stream_info[i];
1634 
1635  // This shouldn't happen
1636  return NULL;
1637 }
1638 
1639 static void set_frag_stream(MOVFragmentIndex *frag_index, int id)
1640 {
1641  int i;
1642  MOVFragmentIndexItem * item;
1643 
1644  if (frag_index->current < 0 ||
1645  frag_index->current >= frag_index->nb_items)
1646  return;
1647 
1648  item = &frag_index->item[frag_index->current];
1649  for (i = 0; i < item->nb_stream_info; i++)
1650  if (item->stream_info[i].id == id) {
1651  item->current = i;
1652  return;
1653  }
1654 
1655  // id not found. This shouldn't happen.
1656  item->current = -1;
1657 }
1658 
1660  MOVFragmentIndex *frag_index)
1661 {
1662  MOVFragmentIndexItem *item;
1663  if (frag_index->current < 0 ||
1664  frag_index->current >= frag_index->nb_items)
1665  return NULL;
1666 
1667  item = &frag_index->item[frag_index->current];
1668  if (item->current >= 0 && item->current < item->nb_stream_info)
1669  return &item->stream_info[item->current];
1670 
1671  // This shouldn't happen
1672  return NULL;
1673 }
1674 
1676 {
1677  int a, b, m;
1678  int64_t moof_offset;
1679 
1680  // Optimize for appending new entries
1681  if (!frag_index->nb_items ||
1682  frag_index->item[frag_index->nb_items - 1].moof_offset < offset)
1683  return frag_index->nb_items;
1684 
1685  a = -1;
1686  b = frag_index->nb_items;
1687 
1688  while (b - a > 1) {
1689  m = (a + b) >> 1;
1690  moof_offset = frag_index->item[m].moof_offset;
1691  if (moof_offset >= offset)
1692  b = m;
1693  if (moof_offset <= offset)
1694  a = m;
1695  }
1696  return b;
1697 }
1698 
1700 {
1701  av_assert0(frag_stream_info);
1702  if (frag_stream_info->sidx_pts != AV_NOPTS_VALUE)
1703  return frag_stream_info->sidx_pts;
1704  if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE)
1705  return frag_stream_info->first_tfra_pts;
1706  return frag_stream_info->tfdt_dts;
1707 }
1708 
1710  MOVFragmentIndex *frag_index, int index)
1711 {
1712  MOVFragmentStreamInfo * frag_stream_info;
1713  MOVStreamContext *sc = dst_st->priv_data;
1714  int64_t timestamp;
1715  int i, j;
1716 
1717  // If the stream is referenced by any sidx, limit the search
1718  // to fragments that referenced this stream in the sidx
1719  if (sc->has_sidx) {
1720  frag_stream_info = get_frag_stream_info(frag_index, index, sc->id);
1721  if (!frag_stream_info)
1722  return AV_NOPTS_VALUE;
1723  if (frag_stream_info->sidx_pts != AV_NOPTS_VALUE)
1724  return frag_stream_info->sidx_pts;
1725  if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE)
1726  return frag_stream_info->first_tfra_pts;
1727  return frag_stream_info->sidx_pts;
1728  }
1729 
1730  for (i = 0; i < frag_index->item[index].nb_stream_info; i++) {
1731  if (dst_st->id != frag_index->item[index].stream_info[i].id)
1732  continue;
1733  AVStream *frag_stream = NULL;
1734  frag_stream_info = &frag_index->item[index].stream_info[i];
1735  for (j = 0; j < s->nb_streams; j++) {
1736  MOVStreamContext *sc2 = s->streams[j]->priv_data;
1737  if (sc2->id == frag_stream_info->id)
1738  frag_stream = s->streams[j];
1739  }
1740  if (!frag_stream) {
1741  av_log(s, AV_LOG_WARNING, "No stream matching sidx ID found.\n");
1742  continue;
1743  }
1744  timestamp = get_stream_info_time(frag_stream_info);
1745  if (timestamp != AV_NOPTS_VALUE)
1746  return av_rescale_q(timestamp, frag_stream->time_base, dst_st->time_base);
1747  }
1748  return AV_NOPTS_VALUE;
1749 }
1750 
1752  AVStream *st, int64_t timestamp)
1753 {
1754  int a, b, m, m0;
1755  int64_t frag_time;
1756 
1757  a = -1;
1758  b = frag_index->nb_items;
1759 
1760  while (b - a > 1) {
1761  m0 = m = (a + b) >> 1;
1762 
1763  while (m < b &&
1764  (frag_time = get_frag_time(s, st, frag_index, m)) == AV_NOPTS_VALUE)
1765  m++;
1766 
1767  if (m < b && frag_time <= timestamp)
1768  a = m;
1769  else
1770  b = m0;
1771  }
1772 
1773  return a;
1774 }
1775 
1777 {
1778  int index, i;
1779  MOVFragmentIndexItem * item;
1780  MOVFragmentStreamInfo * frag_stream_info;
1781 
1782  // If moof_offset already exists in frag_index, return index to it
1783  index = search_frag_moof_offset(&c->frag_index, offset);
1784  if (index < c->frag_index.nb_items &&
1785  c->frag_index.item[index].moof_offset == offset)
1786  return index;
1787 
1788  // offset is not yet in frag index.
1789  // Insert new item at index (sorted by moof offset)
1790  item = av_fast_realloc(c->frag_index.item,
1791  &c->frag_index.allocated_size,
1792  (c->frag_index.nb_items + 1) *
1793  sizeof(*c->frag_index.item));
1794  if (!item)
1795  return -1;
1796  c->frag_index.item = item;
1797 
1798  frag_stream_info = av_realloc_array(NULL, c->fc->nb_streams,
1799  sizeof(*item->stream_info));
1800  if (!frag_stream_info)
1801  return -1;
1802 
1803  for (i = 0; i < c->fc->nb_streams; i++) {
1804  // Avoid building frag index if streams lack track id.
1805  MOVStreamContext *sc = c->fc->streams[i]->priv_data;
1806  if (sc->id < 0) {
1807  av_free(frag_stream_info);
1808  return AVERROR_INVALIDDATA;
1809  }
1810 
1811  frag_stream_info[i].id = sc->id;
1812  frag_stream_info[i].sidx_pts = AV_NOPTS_VALUE;
1813  frag_stream_info[i].tfdt_dts = AV_NOPTS_VALUE;
1814  frag_stream_info[i].next_trun_dts = AV_NOPTS_VALUE;
1815  frag_stream_info[i].first_tfra_pts = AV_NOPTS_VALUE;
1816  frag_stream_info[i].index_base = -1;
1817  frag_stream_info[i].index_entry = -1;
1818  frag_stream_info[i].encryption_index = NULL;
1819  frag_stream_info[i].stsd_id = -1;
1820  }
1821 
1822  if (index < c->frag_index.nb_items)
1823  memmove(c->frag_index.item + index + 1, c->frag_index.item + index,
1824  (c->frag_index.nb_items - index) * sizeof(*c->frag_index.item));
1825 
1826  item = &c->frag_index.item[index];
1827  item->headers_read = 0;
1828  item->current = 0;
1829  item->nb_stream_info = c->fc->nb_streams;
1830  item->moof_offset = offset;
1831  item->stream_info = frag_stream_info;
1832  c->frag_index.nb_items++;
1833 
1834  return index;
1835 }
1836 
1837 static void fix_frag_index_entries(MOVFragmentIndex *frag_index, int index,
1838  int id, int entries)
1839 {
1840  int i;
1841  MOVFragmentStreamInfo * frag_stream_info;
1842 
1843  if (index < 0)
1844  return;
1845  for (i = index; i < frag_index->nb_items; i++) {
1846  frag_stream_info = get_frag_stream_info(frag_index, i, id);
1847  if (frag_stream_info && frag_stream_info->index_entry >= 0)
1848  frag_stream_info->index_entry += entries;
1849  }
1850 }
1851 
1853 {
1854  // Set by mov_read_tfhd(). mov_read_trun() will reject files missing tfhd.
1855  c->fragment.found_tfhd = 0;
1856 
1857  if (!c->has_looked_for_mfra && c->use_mfra_for > 0) {
1858  c->has_looked_for_mfra = 1;
1859  if (pb->seekable & AVIO_SEEKABLE_NORMAL) {
1860  int ret;
1861  av_log(c->fc, AV_LOG_VERBOSE, "stream has moof boxes, will look "
1862  "for a mfra\n");
1863  if ((ret = mov_read_mfra(c, pb)) < 0) {
1864  av_log(c->fc, AV_LOG_VERBOSE, "found a moof box but failed to "
1865  "read the mfra (may be a live ismv)\n");
1866  }
1867  } else {
1868  av_log(c->fc, AV_LOG_VERBOSE, "found a moof box but stream is not "
1869  "seekable, can not look for mfra\n");
1870  }
1871  }
1872  c->fragment.moof_offset = c->fragment.implicit_offset = avio_tell(pb) - 8;
1873  av_log(c->fc, AV_LOG_TRACE, "moof offset %"PRIx64"\n", c->fragment.moof_offset);
1874  c->frag_index.current = update_frag_index(c, c->fragment.moof_offset);
1875  return mov_read_default(c, pb, atom);
1876 }
1877 
1879 {
1880  int64_t time;
1881  if (version == 1) {
1882  time = avio_rb64(pb);
1883  avio_rb64(pb);
1884  if (time < 0) {
1885  av_log(c->fc, AV_LOG_DEBUG, "creation_time is negative\n");
1886  return;
1887  }
1888  } else {
1889  time = avio_rb32(pb);
1890  avio_rb32(pb); /* modification time */
1891  if (time > 0 && time < 2082844800) {
1892  av_log(c->fc, AV_LOG_WARNING, "Detected creation time before 1970, parsing as unix timestamp.\n");
1893  time += 2082844800;
1894  }
1895  }
1896  if (time) {
1897  time -= 2082844800; /* seconds between 1904-01-01 and Epoch */
1898 
1899  if ((int64_t)(time * 1000000ULL) / 1000000 != time) {
1900  av_log(c->fc, AV_LOG_DEBUG, "creation_time is not representable\n");
1901  return;
1902  }
1903 
1904  ff_dict_set_timestamp(metadata, "creation_time", time * 1000000);
1905  }
1906 }
1907 
1909 {
1910  AVStream *st;
1911  MOVStreamContext *sc;
1912  int version;
1913  char language[4] = {0};
1914  unsigned lang;
1915 
1916  if (c->fc->nb_streams < 1)
1917  return 0;
1918  st = c->fc->streams[c->fc->nb_streams-1];
1919  sc = st->priv_data;
1920 
1921  if (sc->time_scale) {
1922  av_log(c->fc, AV_LOG_ERROR, "Multiple mdhd?\n");
1923  return AVERROR_INVALIDDATA;
1924  }
1925 
1926  version = avio_r8(pb);
1927  if (version > 1) {
1928  avpriv_request_sample(c->fc, "Version %d", version);
1929  return AVERROR_PATCHWELCOME;
1930  }
1931  avio_rb24(pb); /* flags */
1933 
1934  sc->time_scale = avio_rb32(pb);
1935  if (sc->time_scale <= 0) {
1936  av_log(c->fc, AV_LOG_ERROR, "Invalid mdhd time scale %d, defaulting to 1\n", sc->time_scale);
1937  sc->time_scale = 1;
1938  }
1939  st->duration = (version == 1) ? avio_rb64(pb) : avio_rb32(pb); /* duration */
1940 
1941  if ((version == 1 && st->duration == UINT64_MAX) ||
1942  (version != 1 && st->duration == UINT32_MAX)) {
1943  st->duration = 0;
1944  }
1945 
1946  lang = avio_rb16(pb); /* language */
1947  if (ff_mov_lang_to_iso639(lang, language))
1948  av_dict_set(&st->metadata, "language", language, 0);
1949  avio_rb16(pb); /* quality */
1950 
1951  return 0;
1952 }
1953 
1955 {
1956  int i;
1957  int version = avio_r8(pb); /* version */
1958  avio_rb24(pb); /* flags */
1959 
1960  mov_metadata_creation_time(c, pb, &c->fc->metadata, version);
1961  c->time_scale = avio_rb32(pb); /* time scale */
1962  if (c->time_scale <= 0) {
1963  av_log(c->fc, AV_LOG_ERROR, "Invalid mvhd time scale %d, defaulting to 1\n", c->time_scale);
1964  c->time_scale = 1;
1965  }
1966  av_log(c->fc, AV_LOG_TRACE, "time scale = %i\n", c->time_scale);
1967 
1968  c->duration = (version == 1) ? avio_rb64(pb) : avio_rb32(pb); /* duration */
1969  avio_rb32(pb); /* preferred scale */
1970 
1971  avio_rb16(pb); /* preferred volume */
1972 
1973  avio_skip(pb, 10); /* reserved */
1974 
1975  /* movie display matrix, store it in main context and use it later on */
1976  for (i = 0; i < 3; i++) {
1977  c->movie_display_matrix[i][0] = avio_rb32(pb); // 16.16 fixed point
1978  c->movie_display_matrix[i][1] = avio_rb32(pb); // 16.16 fixed point
1979  c->movie_display_matrix[i][2] = avio_rb32(pb); // 2.30 fixed point
1980  }
1981 
1982  avio_rb32(pb); /* preview time */
1983  avio_rb32(pb); /* preview duration */
1984  avio_rb32(pb); /* poster time */
1985  avio_rb32(pb); /* selection time */
1986  avio_rb32(pb); /* selection duration */
1987  avio_rb32(pb); /* current time */
1988  avio_rb32(pb); /* next track ID */
1989 
1990  return 0;
1991 }
1992 
1994 {
1995  AVStream *st;
1996 
1997  if (fc->nb_streams < 1)
1998  return;
1999  st = fc->streams[fc->nb_streams-1];
2000 
2001  switch (st->codecpar->codec_id) {
2002  case AV_CODEC_ID_PCM_S16BE:
2004  break;
2005  case AV_CODEC_ID_PCM_S24BE:
2007  break;
2008  case AV_CODEC_ID_PCM_S32BE:
2010  break;
2011  case AV_CODEC_ID_PCM_F32BE:
2013  break;
2014  case AV_CODEC_ID_PCM_F64BE:
2016  break;
2017  default:
2018  break;
2019  }
2020 }
2021 
2023 {
2024  int little_endian = avio_rb16(pb) & 0xFF;
2025  av_log(c->fc, AV_LOG_TRACE, "enda %d\n", little_endian);
2026  if (little_endian == 1)
2028  return 0;
2029 }
2030 
2032 {
2033  int format_flags;
2034  int version, flags;
2035  int pcm_sample_size;
2036  AVFormatContext *fc = c->fc;
2037  AVStream *st;
2038  MOVStreamContext *sc;
2039 
2040  if (atom.size < 6) {
2041  av_log(c->fc, AV_LOG_ERROR, "Empty pcmC box\n");
2042  return AVERROR_INVALIDDATA;
2043  }
2044 
2045  version = avio_r8(pb);
2046  flags = avio_rb24(pb);
2047 
2048  if (version != 0 || flags != 0) {
2049  av_log(c->fc, AV_LOG_ERROR,
2050  "Unsupported 'pcmC' box with version %d, flags: %x",
2051  version, flags);
2052  return AVERROR_INVALIDDATA;
2053  }
2054 
2055  format_flags = avio_r8(pb);
2056  pcm_sample_size = avio_r8(pb);
2057 
2058  if (fc->nb_streams < 1)
2059  return AVERROR_INVALIDDATA;
2060 
2061  st = fc->streams[fc->nb_streams - 1];
2062  sc = st->priv_data;
2063 
2064  if (sc->format == MOV_MP4_FPCM_TAG) {
2065  switch (pcm_sample_size) {
2066  case 32:
2068  break;
2069  case 64:
2071  break;
2072  default:
2073  av_log(fc, AV_LOG_ERROR, "invalid pcm_sample_size %d for %s\n",
2074  pcm_sample_size,
2075  av_fourcc2str(sc->format));
2076  return AVERROR_INVALIDDATA;
2077  }
2078  } else if (sc->format == MOV_MP4_IPCM_TAG) {
2079  switch (pcm_sample_size) {
2080  case 16:
2082  break;
2083  case 24:
2085  break;
2086  case 32:
2088  break;
2089  default:
2090  av_log(fc, AV_LOG_ERROR, "invalid pcm_sample_size %d for %s\n",
2091  pcm_sample_size,
2092  av_fourcc2str(sc->format));
2093  return AVERROR_INVALIDDATA;
2094  }
2095  } else {
2096  av_log(fc, AV_LOG_ERROR, "'pcmC' with invalid sample entry '%s'\n",
2097  av_fourcc2str(sc->format));
2098  return AVERROR_INVALIDDATA;
2099  }
2100 
2101  if (format_flags & 1) // indicates little-endian format. If not present, big-endian format is used
2104 
2105  return 0;
2106 }
2107 
2109 {
2110  AVStream *st;
2111  HEIFItem *item = NULL;
2112  char color_parameter_type[5] = { 0 };
2113  uint16_t color_primaries, color_trc, color_matrix;
2114  int ret;
2115 
2116  st = get_curr_st(c);
2117  if (!st) {
2118  item = get_heif_item(c, c->cur_item_id);
2119  if (!item)
2120  return 0;
2121  }
2122 
2123  ret = ffio_read_size(pb, color_parameter_type, 4);
2124  if (ret < 0)
2125  return ret;
2126  if (strncmp(color_parameter_type, "nclx", 4) &&
2127  strncmp(color_parameter_type, "nclc", 4) &&
2128  strncmp(color_parameter_type, "prof", 4)) {
2129  av_log(c->fc, AV_LOG_WARNING, "unsupported color_parameter_type %s\n",
2130  color_parameter_type);
2131  return 0;
2132  }
2133 
2134  if (!strncmp(color_parameter_type, "prof", 4)) {
2135  AVPacketSideData *sd;
2136  uint8_t *icc_profile;
2137  if (st) {
2141  atom.size - 4, 0);
2142  if (!sd)
2143  return AVERROR(ENOMEM);
2144  icc_profile = sd->data;
2145  } else {
2146  av_freep(&item->icc_profile);
2147  icc_profile = item->icc_profile = av_malloc(atom.size - 4);
2148  if (!icc_profile) {
2149  item->icc_profile_size = 0;
2150  return AVERROR(ENOMEM);
2151  }
2152  item->icc_profile_size = atom.size - 4;
2153  }
2154  ret = ffio_read_size(pb, icc_profile, atom.size - 4);
2155  if (ret < 0)
2156  return ret;
2157  } else if (st) {
2158  color_primaries = avio_rb16(pb);
2159  color_trc = avio_rb16(pb);
2160  color_matrix = avio_rb16(pb);
2161 
2162  av_log(c->fc, AV_LOG_TRACE,
2163  "%s: pri %d trc %d matrix %d",
2164  color_parameter_type, color_primaries, color_trc, color_matrix);
2165 
2166  if (!strncmp(color_parameter_type, "nclx", 4)) {
2167  uint8_t color_range = avio_r8(pb) >> 7;
2168  av_log(c->fc, AV_LOG_TRACE, " full %"PRIu8"", color_range);
2169  if (color_range)
2171  else
2173  }
2174 
2177  if (!av_color_transfer_name(color_trc))
2178  color_trc = AVCOL_TRC_UNSPECIFIED;
2179  if (!av_color_space_name(color_matrix))
2180  color_matrix = AVCOL_SPC_UNSPECIFIED;
2181 
2183  st->codecpar->color_trc = color_trc;
2184  st->codecpar->color_space = color_matrix;
2185  av_log(c->fc, AV_LOG_TRACE, "\n");
2186  }
2187  return 0;
2188 }
2189 
2191 {
2192  AVStream *st;
2193  unsigned mov_field_order;
2194  enum AVFieldOrder decoded_field_order = AV_FIELD_UNKNOWN;
2195 
2196  if (c->fc->nb_streams < 1) // will happen with jp2 files
2197  return 0;
2198  st = c->fc->streams[c->fc->nb_streams-1];
2199  if (atom.size < 2)
2200  return AVERROR_INVALIDDATA;
2201  mov_field_order = avio_rb16(pb);
2202  if ((mov_field_order & 0xFF00) == 0x0100)
2203  decoded_field_order = AV_FIELD_PROGRESSIVE;
2204  else if ((mov_field_order & 0xFF00) == 0x0200) {
2205  switch (mov_field_order & 0xFF) {
2206  case 0x01: decoded_field_order = AV_FIELD_TT;
2207  break;
2208  case 0x06: decoded_field_order = AV_FIELD_BB;
2209  break;
2210  case 0x09: decoded_field_order = AV_FIELD_TB;
2211  break;
2212  case 0x0E: decoded_field_order = AV_FIELD_BT;
2213  break;
2214  }
2215  }
2216  if (decoded_field_order == AV_FIELD_UNKNOWN && mov_field_order) {
2217  av_log(c->fc, AV_LOG_ERROR, "Unknown MOV field order 0x%04x\n", mov_field_order);
2218  }
2219  st->codecpar->field_order = decoded_field_order;
2220 
2221  return 0;
2222 }
2223 
2225 {
2226  int err = 0;
2227  uint64_t size = (uint64_t)par->extradata_size + atom.size + 8 + AV_INPUT_BUFFER_PADDING_SIZE;
2228  if (size > INT_MAX || (uint64_t)atom.size > INT_MAX)
2229  return AVERROR_INVALIDDATA;
2230  if ((err = av_reallocp(&par->extradata, size)) < 0) {
2231  par->extradata_size = 0;
2232  return err;
2233  }
2235  return 0;
2236 }
2237 
2238 /* Read a whole atom into the extradata return the size of the atom read, possibly truncated if != atom.size */
2240  AVCodecParameters *par, uint8_t *buf)
2241 {
2242  int64_t result = atom.size;
2243  int err;
2244 
2245  AV_WB32(buf , atom.size + 8);
2246  AV_WL32(buf + 4, atom.type);
2247  err = ffio_read_size(pb, buf + 8, atom.size);
2248  if (err < 0) {
2249  par->extradata_size -= atom.size;
2250  return err;
2251  } else if (err < atom.size) {
2252  av_log(c->fc, AV_LOG_WARNING, "truncated extradata\n");
2253  par->extradata_size -= atom.size - err;
2254  result = err;
2255  }
2256  memset(buf + 8 + err, 0, AV_INPUT_BUFFER_PADDING_SIZE);
2257  return result;
2258 }
2259 
2260 /* FIXME modify QDM2/SVQ3/H.264 decoders to take full atom as extradata */
2262  enum AVCodecID codec_id)
2263 {
2264  AVStream *st;
2265  uint64_t original_size;
2266  int err;
2267 
2268  if (c->fc->nb_streams < 1) // will happen with jp2 files
2269  return 0;
2270  st = c->fc->streams[c->fc->nb_streams-1];
2271 
2272  if (st->codecpar->codec_id != codec_id)
2273  return 0; /* unexpected codec_id - don't mess with extradata */
2274 
2275  original_size = st->codecpar->extradata_size;
2276  err = mov_realloc_extradata(st->codecpar, atom);
2277  if (err)
2278  return err;
2279 
2280  err = mov_read_atom_into_extradata(c, pb, atom, st->codecpar, st->codecpar->extradata + original_size);
2281  if (err < 0)
2282  return err;
2283  return 0; // Note: this is the original behavior to ignore truncation.
2284 }
2285 
2286 /* wrapper functions for reading ALAC/AVS/MJPEG/MJPEG2000 extradata atoms only for those codecs */
2288 {
2289  return mov_read_extradata(c, pb, atom, AV_CODEC_ID_ALAC);
2290 }
2291 
2293 {
2294  return mov_read_extradata(c, pb, atom, AV_CODEC_ID_CAVS);
2295 }
2296 
2298 {
2299  return mov_read_extradata(c, pb, atom, AV_CODEC_ID_JPEG2000);
2300 }
2301 
2303 {
2304  return mov_read_extradata(c, pb, atom, AV_CODEC_ID_R10K);
2305 }
2306 
2308 {
2309  int ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_AVUI);
2310  if (!ret)
2311  ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_DNXHD);
2312  return ret;
2313 }
2314 
2316 {
2317  int ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_TARGA_Y216);
2318 
2319  if (!ret && c->fc->nb_streams >= 1) {
2320  AVCodecParameters *par = c->fc->streams[c->fc->nb_streams-1]->codecpar;
2321  if (par->extradata_size >= 40) {
2322  par->height = AV_RB16(&par->extradata[36]);
2323  par->width = AV_RB16(&par->extradata[38]);
2324  }
2325  }
2326  return ret;
2327 }
2328 
2330 {
2331  if (c->fc->nb_streams >= 1) {
2332  AVStream *const st = c->fc->streams[c->fc->nb_streams - 1];
2333  FFStream *const sti = ffstream(st);
2334  AVCodecParameters *par = st->codecpar;
2335 
2336  if (par->codec_tag == MKTAG('A', 'V', 'i', 'n') &&
2337  par->codec_id == AV_CODEC_ID_H264 &&
2338  atom.size > 11) {
2339  int cid;
2340  avio_skip(pb, 10);
2341  cid = avio_rb16(pb);
2342  /* For AVID AVCI50, force width of 1440 to be able to select the correct SPS and PPS */
2343  if (cid == 0xd4d || cid == 0xd4e)
2344  par->width = 1440;
2345  return 0;
2346  } else if ((par->codec_tag == MKTAG('A', 'V', 'd', '1') ||
2347  par->codec_tag == MKTAG('A', 'V', 'j', '2') ||
2348  par->codec_tag == MKTAG('A', 'V', 'd', 'n')) &&
2349  atom.size >= 24) {
2350  int num, den;
2351  avio_skip(pb, 12);
2352  num = avio_rb32(pb);
2353  den = avio_rb32(pb);
2354  if (num <= 0 || den <= 0)
2355  return 0;
2356  switch (avio_rb32(pb)) {
2357  case 2:
2358  if (den >= INT_MAX / 2)
2359  return 0;
2360  den *= 2;
2362  case 1:
2363  sti->display_aspect_ratio = (AVRational){ num, den };
2365  default:
2366  return 0;
2367  }
2368  }
2369  }
2370 
2371  return mov_read_avid(c, pb, atom);
2372 }
2373 
2375 {
2376  int ret = 0;
2377  int length = 0;
2378  uint64_t original_size;
2379  if (c->fc->nb_streams >= 1) {
2380  AVCodecParameters *par = c->fc->streams[c->fc->nb_streams-1]->codecpar;
2381  if (par->codec_id == AV_CODEC_ID_H264)
2382  return 0;
2383  if (atom.size == 16) {
2384  original_size = par->extradata_size;
2385  ret = mov_realloc_extradata(par, atom);
2386  if (!ret) {
2387  length = mov_read_atom_into_extradata(c, pb, atom, par, par->extradata + original_size);
2388  if (length == atom.size) {
2389  const uint8_t range_value = par->extradata[original_size + 19];
2390  switch (range_value) {
2391  case 1:
2393  break;
2394  case 2:
2396  break;
2397  default:
2398  av_log(c->fc, AV_LOG_WARNING, "ignored unknown aclr value (%d)\n", range_value);
2399  break;
2400  }
2401  ff_dlog(c->fc, "color_range: %d\n", par->color_range);
2402  } else {
2403  /* For some reason the whole atom was not added to the extradata */
2404  av_log(c->fc, AV_LOG_ERROR, "aclr not decoded - incomplete atom\n");
2405  }
2406  } else {
2407  av_log(c->fc, AV_LOG_ERROR, "aclr not decoded - unable to add atom to extradata\n");
2408  }
2409  } else {
2410  av_log(c->fc, AV_LOG_WARNING, "aclr not decoded - unexpected size %"PRId64"\n", atom.size);
2411  }
2412  }
2413 
2414  return ret;
2415 }
2416 
2418 {
2419  return mov_read_extradata(c, pb, atom, AV_CODEC_ID_SVQ3);
2420 }
2421 
2423 {
2424  AVStream *st;
2425  int ret;
2426 
2427  if (c->fc->nb_streams < 1)
2428  return 0;
2429  st = c->fc->streams[c->fc->nb_streams-1];
2430 
2431  if ((uint64_t)atom.size > (1<<30))
2432  return AVERROR_INVALIDDATA;
2433 
2434  if (st->codecpar->codec_id == AV_CODEC_ID_QDM2 ||
2437  // pass all frma atom to codec, needed at least for QDMC and QDM2
2438  ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size);
2439  if (ret < 0)
2440  return ret;
2441  } else if (atom.size > 8) { /* to read frma, esds atoms */
2442  if (st->codecpar->codec_id == AV_CODEC_ID_ALAC && atom.size >= 24) {
2443  uint64_t buffer;
2444  ret = ffio_ensure_seekback(pb, 8);
2445  if (ret < 0)
2446  return ret;
2447  buffer = avio_rb64(pb);
2448  atom.size -= 8;
2449  if ( (buffer & 0xFFFFFFFF) == MKBETAG('f','r','m','a')
2450  && buffer >> 32 <= atom.size
2451  && buffer >> 32 >= 8) {
2452  avio_skip(pb, -8);
2453  atom.size += 8;
2454  } else if (!st->codecpar->extradata_size) {
2455 #define ALAC_EXTRADATA_SIZE 36
2457  if (!st->codecpar->extradata)
2458  return AVERROR(ENOMEM);
2461  AV_WB32(st->codecpar->extradata + 4, MKTAG('a','l','a','c'));
2462  AV_WB64(st->codecpar->extradata + 12, buffer);
2463  avio_read(pb, st->codecpar->extradata + 20, 16);
2464  avio_skip(pb, atom.size - 24);
2465  return 0;
2466  }
2467  }
2468  if ((ret = mov_read_default(c, pb, atom)) < 0)
2469  return ret;
2470  } else
2471  avio_skip(pb, atom.size);
2472  return 0;
2473 }
2474 
2475 /**
2476  * This function reads atom content and puts data in extradata without tag
2477  * nor size unlike mov_read_extradata.
2478  */
2480 {
2481  AVStream *st;
2482  int ret;
2483 
2484  st = get_curr_st(c);
2485  if (!st)
2486  return 0;
2487 
2488  if ((uint64_t)atom.size > (1<<30))
2489  return AVERROR_INVALIDDATA;
2490 
2491  if (atom.type == MKTAG('v','v','c','C')) {
2492  avio_skip(pb, 4);
2493  atom.size -= 4;
2494  }
2495 
2496  if (atom.size >= 10) {
2497  // Broken files created by legacy versions of libavformat will
2498  // wrap a whole fiel atom inside of a glbl atom.
2499  unsigned size = avio_rb32(pb);
2500  unsigned type = avio_rl32(pb);
2501  if (avio_feof(pb))
2502  return AVERROR_INVALIDDATA;
2503  avio_seek(pb, -8, SEEK_CUR);
2504  if (type == MKTAG('f','i','e','l') && size == atom.size)
2505  return mov_read_default(c, pb, atom);
2506  }
2507  if (st->codecpar->extradata_size > 1 && st->codecpar->extradata) {
2508  av_log(c->fc, AV_LOG_WARNING, "ignoring multiple glbl\n");
2509  return 0;
2510  }
2511  ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size);
2512  if (ret < 0)
2513  return ret;
2514  if (atom.type == MKTAG('h','v','c','C') && st->codecpar->codec_tag == MKTAG('d','v','h','1'))
2515  /* HEVC-based Dolby Vision derived from hvc1.
2516  Happens to match with an identifier
2517  previously utilized for DV. Thus, if we have
2518  the hvcC extradata box available as specified,
2519  set codec to HEVC */
2521 
2522  return 0;
2523 }
2524 
2526 {
2527  AVStream *st;
2528  uint8_t profile_level;
2529  int ret;
2530 
2531  if (c->fc->nb_streams < 1)
2532  return 0;
2533  st = c->fc->streams[c->fc->nb_streams-1];
2534 
2535  if (atom.size >= (1<<28) || atom.size < 7)
2536  return AVERROR_INVALIDDATA;
2537 
2538  profile_level = avio_r8(pb);
2539  if ((profile_level & 0xf0) != 0xc0)
2540  return 0;
2541 
2542  avio_seek(pb, 6, SEEK_CUR);
2543  ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size - 7);
2544  if (ret < 0)
2545  return ret;
2546 
2547  return 0;
2548 }
2549 
2550 static int mov_find_tref_id(const MovTref *tag, uint32_t id)
2551 {
2552  for (int i = 0; i < tag->nb_id; i++) {
2553  if (tag->id[i] == id)
2554  return 1;
2555  }
2556  return 0;
2557 }
2558 
2559 static int mov_add_tref_id(MovTref *tag, uint32_t id)
2560 {
2561  int ret = mov_find_tref_id(tag, id);
2562 
2563  if (!ret) {
2564  uint32_t *tmp = av_realloc_array(tag->id, tag->nb_id + 1, sizeof(*tag->id));
2565  if (!tmp)
2566  return AVERROR(ENOMEM);
2567  tag->id = tmp;
2568  tag->id[tag->nb_id++] = id;
2569  }
2570 
2571  return 0;
2572 }
2573 
2574 static MovTref *mov_find_tref_tag(const MOVStreamContext *sc, uint32_t name)
2575 {
2576  for (int i = 0; i < sc->nb_tref_tags; i++) {
2577  MovTref *entry = &sc->tref_tags[i];
2578 
2579  if (entry->name == name)
2580  return entry;
2581  }
2582  return NULL;
2583 }
2584 
2586 {
2588 
2589  if (!tag) {
2591  sizeof(*sc->tref_tags));
2592  if (!tmp)
2593  return NULL;
2594  sc->tref_tags = tmp;
2595  tag = &sc->tref_tags[sc->nb_tref_tags++];
2596  *tag = (MovTref){ .name = name };
2597  }
2598 
2599  return tag;
2600 }
2601 
2603 {
2604  AVStream* st;
2605  MOVStreamContext* sc;
2606 
2607  if (c->fc->nb_streams < 1)
2608  return 0;
2609 
2610  /* For SBAS this should be fine - though beware if someone implements a
2611  * tref atom processor that doesn't drop down to default then this may
2612  * be lost. */
2613  if (atom.size > 4) {
2614  av_log(c->fc, AV_LOG_ERROR, "Only a single tref of type sbas is supported\n");
2615  return AVERROR_PATCHWELCOME;
2616  }
2617  if (atom.size < 4)
2618  return AVERROR_INVALIDDATA;
2619 
2620  st = c->fc->streams[c->fc->nb_streams - 1];
2621  sc = st->priv_data;
2622 
2623  MovTref *tag = mov_add_tref_tag(sc, atom.type);
2624  if (!tag)
2625  return AVERROR(ENOMEM);
2626 
2627  int ret = mov_add_tref_id(tag, avio_rb32(pb));
2628  if (ret < 0)
2629  return ret;
2630 
2631  return 0;
2632 }
2633 
2634 /**
2635  * An strf atom is a BITMAPINFOHEADER struct. This struct is 40 bytes itself,
2636  * but can have extradata appended at the end after the 40 bytes belonging
2637  * to the struct.
2638  */
2640 {
2641  AVStream *st;
2642  int ret;
2643 
2644  if (c->fc->nb_streams < 1)
2645  return 0;
2646  if (atom.size <= 40)
2647  return 0;
2648  st = c->fc->streams[c->fc->nb_streams-1];
2649 
2650  if ((uint64_t)atom.size > (1<<30))
2651  return AVERROR_INVALIDDATA;
2652 
2653  avio_skip(pb, 40);
2654  ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size - 40);
2655  if (ret < 0)
2656  return ret;
2657 
2658  return 0;
2659 }
2660 
2662 {
2663  AVStream *st;
2664  MOVStreamContext *sc;
2665  unsigned int i, entries;
2666 
2667  if (c->trak_index < 0) {
2668  av_log(c->fc, AV_LOG_WARNING, "STCO outside TRAK\n");
2669  return 0;
2670  }
2671  if (c->fc->nb_streams < 1)
2672  return 0;
2673  st = c->fc->streams[c->fc->nb_streams-1];
2674  sc = st->priv_data;
2675 
2676  avio_r8(pb); /* version */
2677  avio_rb24(pb); /* flags */
2678 
2679  // Clamp allocation size for `chunk_offsets` -- don't throw an error for an
2680  // invalid count since the EOF path doesn't throw either.
2681  entries = avio_rb32(pb);
2682  entries =
2683  FFMIN(entries,
2684  FFMAX(0, (atom.size - 8) /
2685  (atom.type == MKTAG('s', 't', 'c', 'o') ? 4 : 8)));
2686 
2687  if (!entries)
2688  return 0;
2689 
2690  if (sc->chunk_offsets) {
2691  av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicated STCO atom\n");
2692  return 0;
2693  }
2694 
2695  av_free(sc->chunk_offsets);
2696  sc->chunk_count = 0;
2697  sc->chunk_offsets = av_malloc_array(entries, sizeof(*sc->chunk_offsets));
2698  if (!sc->chunk_offsets)
2699  return AVERROR(ENOMEM);
2700  sc->chunk_count = entries;
2701 
2702  if (atom.type == MKTAG('s','t','c','o'))
2703  for (i = 0; i < entries && !pb->eof_reached; i++)
2704  sc->chunk_offsets[i] = avio_rb32(pb);
2705  else if (atom.type == MKTAG('c','o','6','4'))
2706  for (i = 0; i < entries && !pb->eof_reached; i++) {
2707  sc->chunk_offsets[i] = avio_rb64(pb);
2708  if (sc->chunk_offsets[i] < 0) {
2709  av_log(c->fc, AV_LOG_WARNING, "Impossible chunk_offset\n");
2710  sc->chunk_offsets[i] = 0;
2711  }
2712  }
2713  else
2714  return AVERROR_INVALIDDATA;
2715 
2716  sc->chunk_count = i;
2717 
2718  if (pb->eof_reached) {
2719  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STCO atom\n");
2720  return AVERROR_EOF;
2721  }
2722 
2723  return 0;
2724 }
2725 
2726 static int mov_codec_id(AVStream *st, uint32_t format)
2727 {
2729 
2730  if (id <= 0 &&
2731  ((format & 0xFFFF) == 'm' + ('s' << 8) ||
2732  (format & 0xFFFF) == 'T' + ('S' << 8)))
2734 
2735  if (st->codecpar->codec_type != AVMEDIA_TYPE_VIDEO && id > 0) {
2737  } else if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO &&
2738  /* skip old ASF MPEG-4 tag */
2739  format && format != MKTAG('m','p','4','s')) {
2741  if (id <= 0)
2743  if (id > 0)
2745  else if (st->codecpar->codec_type == AVMEDIA_TYPE_DATA ||
2747  st->codecpar->codec_id == AV_CODEC_ID_NONE)) {
2749  if (id <= 0) {
2751  AV_CODEC_ID_TTML : id;
2752  }
2753 
2754  if (id > 0)
2756  else
2758  }
2759  }
2760 
2761  st->codecpar->codec_tag = format;
2762 
2763  return id;
2764 }
2765 
2767  AVStream *st, MOVStreamContext *sc)
2768 {
2769  uint8_t codec_name[32] = { 0 };
2770  int64_t stsd_start;
2771  unsigned int len;
2772  uint32_t id = 0;
2773 
2774  /* The first 16 bytes of the video sample description are already
2775  * read in ff_mov_read_stsd_entries() */
2776  stsd_start = avio_tell(pb) - 16;
2777 
2778  if (c->isom) {
2779  avio_skip(pb, 2); /* pre_defined */
2780  avio_skip(pb, 2); /* reserved */
2781  avio_skip(pb, 12); /* pre_defined */
2782  } else {
2783  avio_rb16(pb); /* version */
2784  avio_rb16(pb); /* revision level */
2785  id = avio_rl32(pb); /* vendor */
2786  av_dict_set(&st->metadata, "vendor_id", av_fourcc2str(id), 0);
2787  avio_rb32(pb); /* temporal quality */
2788  avio_rb32(pb); /* spatial quality */
2789  }
2790 
2791  st->codecpar->width = avio_rb16(pb); /* width */
2792  st->codecpar->height = avio_rb16(pb); /* height */
2793 
2794  avio_rb32(pb); /* horiz resolution */
2795  avio_rb32(pb); /* vert resolution */
2796  avio_rb32(pb); /* data size, always 0 */
2797  avio_rb16(pb); /* frames per samples */
2798 
2799  len = avio_r8(pb); /* codec name, pascal string */
2800  if (len > 31)
2801  len = 31;
2802  mov_read_mac_string(c, pb, len, codec_name, sizeof(codec_name));
2803  if (len < 31)
2804  avio_skip(pb, 31 - len);
2805 
2806  if (codec_name[0])
2807  av_dict_set(&st->metadata, "encoder", codec_name, 0);
2808 
2809  /* codec_tag YV12 triggers an UV swap in rawdec.c */
2810  if (!strncmp(codec_name, "Planar Y'CbCr 8-bit 4:2:0", 25)) {
2811  st->codecpar->codec_tag = MKTAG('I', '4', '2', '0');
2812  st->codecpar->width &= ~1;
2813  st->codecpar->height &= ~1;
2814  }
2815  /* Flash Media Server uses tag H.263 with Sorenson Spark */
2816  if (st->codecpar->codec_tag == MKTAG('H','2','6','3') &&
2817  !strncmp(codec_name, "Sorenson H263", 13))
2819 
2820  st->codecpar->bits_per_coded_sample = avio_rb16(pb); /* depth */
2821 
2822  avio_seek(pb, stsd_start, SEEK_SET);
2823 
2824  if (ff_get_qtpalette(st->codecpar->codec_id, pb, sc->palette)) {
2825  st->codecpar->bits_per_coded_sample &= 0x1F;
2826  sc->has_palette = 1;
2827  }
2828 }
2829 
2831  AVStream *st, MOVStreamContext *sc)
2832 {
2833  int bits_per_sample, flags;
2834  uint16_t version = avio_rb16(pb);
2835  uint32_t id = 0;
2836  AVDictionaryEntry *compatible_brands = av_dict_get(c->fc->metadata, "compatible_brands", NULL, AV_DICT_MATCH_CASE);
2837  int channel_count;
2838 
2839  if (c->isom)
2840  avio_skip(pb, 6); /* reserved */
2841  else {
2842  avio_rb16(pb); /* revision level */
2843  id = avio_rl32(pb); /* vendor */
2844  av_dict_set(&st->metadata, "vendor_id", av_fourcc2str(id), 0);
2845  }
2846 
2847  channel_count = avio_rb16(pb);
2848 
2850  st->codecpar->ch_layout.nb_channels = channel_count;
2851  st->codecpar->bits_per_coded_sample = avio_rb16(pb); /* sample size */
2852  av_log(c->fc, AV_LOG_TRACE, "audio channels %d\n", channel_count);
2853 
2854  sc->audio_cid = avio_rb16(pb);
2855  avio_rb16(pb); /* packet size = 0 */
2856 
2857  st->codecpar->sample_rate = ((avio_rb32(pb) >> 16));
2858 
2859  // Read QT version 1 fields. In version 0 these do not exist.
2860  av_log(c->fc, AV_LOG_TRACE, "version =%d, isom =%d\n", version, c->isom);
2861  if (!c->isom ||
2862  (compatible_brands && strstr(compatible_brands->value, "qt ")) ||
2863  (sc->stsd_version == 0 && version > 0)) {
2864  if (version == 1) {
2865  sc->samples_per_frame = avio_rb32(pb);
2866  avio_rb32(pb); /* bytes per packet */
2867  sc->bytes_per_frame = avio_rb32(pb);
2868  avio_rb32(pb); /* bytes per sample */
2869  } else if (version == 2) {
2870  avio_rb32(pb); /* sizeof struct only */
2872  channel_count = avio_rb32(pb);
2874  st->codecpar->ch_layout.nb_channels = channel_count;
2875  avio_rb32(pb); /* always 0x7F000000 */
2877 
2878  flags = avio_rb32(pb); /* lpcm format specific flag */
2879  sc->bytes_per_frame = avio_rb32(pb);
2880  sc->samples_per_frame = avio_rb32(pb);
2881  if (st->codecpar->codec_tag == MKTAG('l','p','c','m'))
2882  st->codecpar->codec_id =
2884  flags);
2885  }
2886  if (version == 0 || (version == 1 && sc->audio_cid != -2)) {
2887  /* can't correctly handle variable sized packet as audio unit */
2888  switch (st->codecpar->codec_id) {
2889  case AV_CODEC_ID_MP2:
2890  case AV_CODEC_ID_MP3:
2892  break;
2893  }
2894  }
2895  }
2896 
2897  if (sc->format == 0) {
2898  if (st->codecpar->bits_per_coded_sample == 8)
2899  st->codecpar->codec_id = mov_codec_id(st, MKTAG('r','a','w',' '));
2900  else if (st->codecpar->bits_per_coded_sample == 16)
2901  st->codecpar->codec_id = mov_codec_id(st, MKTAG('t','w','o','s'));
2902  }
2903 
2904  switch (st->codecpar->codec_id) {
2905  case AV_CODEC_ID_PCM_S8:
2906  case AV_CODEC_ID_PCM_U8:
2907  if (st->codecpar->bits_per_coded_sample == 16)
2909  break;
2910  case AV_CODEC_ID_PCM_S16LE:
2911  case AV_CODEC_ID_PCM_S16BE:
2912  if (st->codecpar->bits_per_coded_sample == 8)
2914  else if (st->codecpar->bits_per_coded_sample == 24)
2915  st->codecpar->codec_id =
2918  else if (st->codecpar->bits_per_coded_sample == 32)
2919  st->codecpar->codec_id =
2922  break;
2923  /* set values for old format before stsd version 1 appeared */
2924  case AV_CODEC_ID_MACE3:
2925  sc->samples_per_frame = 6;
2927  break;
2928  case AV_CODEC_ID_MACE6:
2929  sc->samples_per_frame = 6;
2931  break;
2933  sc->samples_per_frame = 64;
2935  break;
2936  case AV_CODEC_ID_GSM:
2937  sc->samples_per_frame = 160;
2938  sc->bytes_per_frame = 33;
2939  break;
2940  default:
2941  break;
2942  }
2943 
2944  bits_per_sample = av_get_bits_per_sample(st->codecpar->codec_id);
2945  if (bits_per_sample && (bits_per_sample >> 3) * (uint64_t)st->codecpar->ch_layout.nb_channels <= INT_MAX) {
2946  st->codecpar->bits_per_coded_sample = bits_per_sample;
2947  sc->sample_size = (bits_per_sample >> 3) * st->codecpar->ch_layout.nb_channels;
2948  }
2949 }
2950 
2952  AVStream *st, MOVStreamContext *sc,
2953  int64_t size)
2954 {
2955  // ttxt stsd contains display flags, justification, background
2956  // color, fonts, and default styles, so fake an atom to read it
2957  MOVAtom fake_atom = { .size = size };
2958  // mp4s contains a regular esds atom, dfxp ISMV TTML has no content
2959  // in extradata unlike stpp MP4 TTML.
2960  if (st->codecpar->codec_tag != AV_RL32("mp4s") &&
2962  mov_read_glbl(c, pb, fake_atom);
2963  st->codecpar->width = sc->width;
2964  st->codecpar->height = sc->height;
2965 }
2966 
2968  AVStream *st, MOVStreamContext *sc,
2969  int64_t size)
2970 {
2971  int ret;
2972 
2973  if (st->codecpar->codec_tag == MKTAG('t','m','c','d')) {
2974  if ((int)size != size)
2975  return AVERROR(ENOMEM);
2976 
2977  ret = ff_get_extradata(c->fc, st->codecpar, pb, size);
2978  if (ret < 0)
2979  return ret;
2980  if (size > 16) {
2981  MOVStreamContext *tmcd_ctx = st->priv_data;
2982  int val;
2983  val = AV_RB32(st->codecpar->extradata + 4);
2984  tmcd_ctx->tmcd_flags = val;
2985  st->avg_frame_rate.num = AV_RB32(st->codecpar->extradata + 8); /* timescale */
2986  st->avg_frame_rate.den = AV_RB32(st->codecpar->extradata + 12); /* frameDuration */
2987  tmcd_ctx->tmcd_nb_frames = st->codecpar->extradata[16]; /* number of frames */
2988  if (size > 30) {
2989  uint32_t len = AV_RB32(st->codecpar->extradata + 18); /* name atom length */
2990  uint32_t format = AV_RB32(st->codecpar->extradata + 22);
2991  if (format == AV_RB32("name") && (int64_t)size >= (int64_t)len + 18) {
2992  uint16_t str_size = AV_RB16(st->codecpar->extradata + 26); /* string length */
2993  if (str_size > 0 && size >= (int)str_size + 30 &&
2994  st->codecpar->extradata[30] /* Don't add empty string */) {
2995  char *reel_name = av_malloc(str_size + 1);
2996  if (!reel_name)
2997  return AVERROR(ENOMEM);
2998  memcpy(reel_name, st->codecpar->extradata + 30, str_size);
2999  reel_name[str_size] = 0; /* Add null terminator */
3000  av_dict_set(&st->metadata, "reel_name", reel_name,
3002  }
3003  }
3004  }
3005  }
3006  } else {
3007  /* other codec type, just skip (rtp, mp4s ...) */
3008  avio_skip(pb, size);
3009  }
3010  return 0;
3011 }
3012 
3014  AVStream *st, MOVStreamContext *sc)
3015 {
3016  FFStream *const sti = ffstream(st);
3017 
3018  if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
3019  !st->codecpar->sample_rate && sc->time_scale > 1)
3020  st->codecpar->sample_rate = sc->time_scale;
3021 
3022  /* special codec parameters handling */
3023  switch (st->codecpar->codec_id) {
3024 #if CONFIG_DV_DEMUXER
3025  case AV_CODEC_ID_DVAUDIO:
3026  if (c->dv_fctx) {
3027  avpriv_request_sample(c->fc, "multiple DV audio streams");
3028  return AVERROR(ENOSYS);
3029  }
3030 
3031  c->dv_fctx = avformat_alloc_context();
3032  if (!c->dv_fctx) {
3033  av_log(c->fc, AV_LOG_ERROR, "dv demux context alloc error\n");
3034  return AVERROR(ENOMEM);
3035  }
3036  c->dv_demux = avpriv_dv_init_demux(c->dv_fctx);
3037  if (!c->dv_demux) {
3038  av_log(c->fc, AV_LOG_ERROR, "dv demux context init error\n");
3039  return AVERROR(ENOMEM);
3040  }
3041  sc->dv_audio_container = 1;
3043  break;
3044 #endif
3045  /* no ifdef since parameters are always those */
3046  case AV_CODEC_ID_QCELP:
3049  // force sample rate for qcelp when not stored in mov
3050  if (st->codecpar->codec_tag != MKTAG('Q','c','l','p'))
3051  st->codecpar->sample_rate = 8000;
3052  // FIXME: Why is the following needed for some files?
3053  sc->samples_per_frame = 160;
3054  if (!sc->bytes_per_frame)
3055  sc->bytes_per_frame = 35;
3056  break;
3057  case AV_CODEC_ID_AMR_NB:
3060  /* force sample rate for amr, stsd in 3gp does not store sample rate */
3061  st->codecpar->sample_rate = 8000;
3062  break;
3063  case AV_CODEC_ID_AMR_WB:
3066  st->codecpar->sample_rate = 16000;
3067  break;
3068  case AV_CODEC_ID_MP2:
3069  case AV_CODEC_ID_MP3:
3070  /* force type after stsd for m1a hdlr */
3072  break;
3073  case AV_CODEC_ID_GSM:
3074  case AV_CODEC_ID_ADPCM_MS:
3076  case AV_CODEC_ID_ILBC:
3077  case AV_CODEC_ID_MACE3:
3078  case AV_CODEC_ID_MACE6:
3079  case AV_CODEC_ID_QDM2:
3081  break;
3082  case AV_CODEC_ID_ALAC:
3083  if (st->codecpar->extradata_size == 36) {
3084  int channel_count = AV_RB8(st->codecpar->extradata + 21);
3085  if (st->codecpar->ch_layout.nb_channels != channel_count) {
3088  st->codecpar->ch_layout.nb_channels = channel_count;
3089  }
3090  st->codecpar->sample_rate = AV_RB32(st->codecpar->extradata + 32);
3091  }
3092  break;
3093  case AV_CODEC_ID_AC3:
3094  case AV_CODEC_ID_EAC3:
3096  case AV_CODEC_ID_VC1:
3097  case AV_CODEC_ID_VP8:
3098  case AV_CODEC_ID_VP9:
3100  break;
3102  case AV_CODEC_ID_PRORES:
3103  case AV_CODEC_ID_APV:
3104  case AV_CODEC_ID_EVC:
3105  case AV_CODEC_ID_LCEVC:
3106  case AV_CODEC_ID_AV1:
3107  /* field_order detection of H264 requires parsing */
3108  case AV_CODEC_ID_H264:
3110  break;
3111  default:
3112  break;
3113  }
3114  return 0;
3115 }
3116 
3118  int codec_tag, int format,
3119  int64_t size)
3120 {
3121  if (codec_tag &&
3122  (codec_tag != format &&
3123  // AVID 1:1 samples with differing data format and codec tag exist
3124  (codec_tag != AV_RL32("AV1x") || format != AV_RL32("AVup")) &&
3125  // prores is allowed to have differing data format and codec tag
3126  codec_tag != AV_RL32("apcn") && codec_tag != AV_RL32("apch") &&
3127  // so is dv (sigh)
3128  codec_tag != AV_RL32("dvpp") && codec_tag != AV_RL32("dvcp") &&
3129  (c->fc->video_codec_id ? ff_codec_get_id(ff_codec_movvideo_tags, format) != c->fc->video_codec_id
3130  : codec_tag != MKTAG('j','p','e','g')))) {
3131  /* Multiple fourcc, we skip JPEG. This is not correct, we should
3132  * export it as a separate AVStream but this needs a few changes
3133  * in the MOV demuxer, patch welcome. */
3134 
3135  av_log(c->fc, AV_LOG_WARNING, "multiple fourcc not supported\n");
3136  avio_skip(pb, size);
3137  return 1;
3138  }
3139 
3140  return 0;
3141 }
3142 
3144 {
3145  int ret;
3146 
3147  /* special codec parameters handling */
3148  switch (st->codecpar->codec_id) {
3149  case AV_CODEC_ID_H264:
3150  // done for ai5q, ai52, ai55, ai1q, ai12 and ai15.
3151  if (!st->codecpar->extradata_size && TAG_IS_AVCI(st->codecpar->codec_tag)) {
3153  if (ret < 0)
3154  return ret;
3155  }
3156  break;
3157  default:
3158  break;
3159  }
3160 
3161  return 0;
3162 }
3163 
3165 {
3166  AVStream *st;
3167  MOVStreamContext *sc;
3168  int pseudo_stream_id;
3169 
3170  av_assert0 (c->fc->nb_streams >= 1);
3171  st = c->fc->streams[c->fc->nb_streams-1];
3172  sc = st->priv_data;
3173 
3174  for (pseudo_stream_id = 0;
3175  pseudo_stream_id < entries && !pb->eof_reached;
3176  pseudo_stream_id++) {
3177  //Parsing Sample description table
3178  enum AVCodecID id;
3179  int ret, dref_id = 1;
3180  MOVAtom a = { AV_RL32("stsd") };
3181  int64_t start_pos = avio_tell(pb);
3182  int64_t size = avio_rb32(pb); /* size */
3183  uint32_t format = avio_rl32(pb); /* data format */
3184 
3185  if (size >= 16) {
3186  avio_rb32(pb); /* reserved */
3187  avio_rb16(pb); /* reserved */
3188  dref_id = avio_rb16(pb);
3189  } else if (size <= 7) {
3190  av_log(c->fc, AV_LOG_ERROR,
3191  "invalid size %"PRId64" in stsd\n", size);
3192  return AVERROR_INVALIDDATA;
3193  }
3194 
3196  size - (avio_tell(pb) - start_pos))) {
3197  sc->stsd_count++;
3198  continue;
3199  }
3200 
3201  sc->pseudo_stream_id = st->codecpar->codec_tag ? -1 : pseudo_stream_id;
3202  sc->dref_id= dref_id;
3203  sc->format = format;
3204 
3205  id = mov_codec_id(st, format);
3206 
3207  av_log(c->fc, AV_LOG_TRACE,
3208  "size=%"PRId64" 4CC=%s codec_type=%d\n", size,
3210 
3211  st->codecpar->codec_id = id;
3213  mov_parse_stsd_video(c, pb, st, sc);
3214  } else if (st->codecpar->codec_type==AVMEDIA_TYPE_AUDIO) {
3215  mov_parse_stsd_audio(c, pb, st, sc);
3216  if (st->codecpar->sample_rate < 0) {
3217  av_log(c->fc, AV_LOG_ERROR, "Invalid sample rate %d\n", st->codecpar->sample_rate);
3218  return AVERROR_INVALIDDATA;
3219  }
3220  if (st->codecpar->ch_layout.nb_channels < 0) {
3221  av_log(c->fc, AV_LOG_ERROR, "Invalid channels %d\n", st->codecpar->ch_layout.nb_channels);
3222  return AVERROR_INVALIDDATA;
3223  }
3224  } else if (st->codecpar->codec_type==AVMEDIA_TYPE_SUBTITLE){
3225  mov_parse_stsd_subtitle(c, pb, st, sc,
3226  size - (avio_tell(pb) - start_pos));
3227  } else {
3228  ret = mov_parse_stsd_data(c, pb, st, sc,
3229  size - (avio_tell(pb) - start_pos));
3230  if (ret < 0)
3231  return ret;
3232  }
3233  /* this will read extra atoms at the end (wave, alac, damr, avcC, hvcC, SMI ...) */
3234  a.size = size - (avio_tell(pb) - start_pos);
3235  if (a.size > 8) {
3236  if ((ret = mov_read_default(c, pb, a)) < 0)
3237  return ret;
3238  } else if (a.size > 0)
3239  avio_skip(pb, a.size);
3240 
3241  ret = mov_finalize_stsd_entry(c, st);
3242  if (ret < 0)
3243  return ret;
3244 
3245  if (sc->extradata && st->codecpar->extradata) {
3246  int extra_size = st->codecpar->extradata_size;
3247 
3248  /* Move the current stream extradata to the stream context one. */
3249  sc->extradata_size[pseudo_stream_id] = extra_size;
3250  sc->extradata[pseudo_stream_id] = st->codecpar->extradata;
3251  st->codecpar->extradata = NULL;
3252  st->codecpar->extradata_size = 0;
3253  }
3254  sc->stsd_count++;
3255  }
3256 
3257  if (pb->eof_reached) {
3258  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSD atom\n");
3259  return AVERROR_EOF;
3260  }
3261 
3262  return 0;
3263 }
3264 
3266 {
3267  AVStream *st;
3268  MOVStreamContext *sc;
3269  int ret, entries;
3270 
3271  if (c->fc->nb_streams < 1)
3272  return 0;
3273  st = c->fc->streams[c->fc->nb_streams - 1];
3274  sc = st->priv_data;
3275 
3276  if (sc->extradata) {
3277  av_log(c->fc, AV_LOG_ERROR,
3278  "Duplicate stsd found in this track.\n");
3279  return AVERROR_INVALIDDATA;
3280  }
3281 
3282  sc->stsd_version = avio_r8(pb);
3283  avio_rb24(pb); /* flags */
3284  entries = avio_rb32(pb);
3285 
3286  /* Each entry contains a size (4 bytes) and format (4 bytes). */
3287  if (entries <= 0 || entries > atom.size / 8 || entries > 1024) {
3288  av_log(c->fc, AV_LOG_ERROR, "invalid STSD entries %d\n", entries);
3289  return AVERROR_INVALIDDATA;
3290  }
3291 
3292  /* Prepare space for hosting multiple extradata. */
3293  sc->extradata = av_calloc(entries, sizeof(*sc->extradata));
3294  if (!sc->extradata)
3295  return AVERROR(ENOMEM);
3296 
3297  sc->extradata_size = av_calloc(entries, sizeof(*sc->extradata_size));
3298  if (!sc->extradata_size) {
3299  ret = AVERROR(ENOMEM);
3300  goto fail;
3301  }
3302 
3303  ret = ff_mov_read_stsd_entries(c, pb, entries);
3304  if (ret < 0)
3305  goto fail;
3306 
3307  /* Restore back the primary extradata. */
3308  av_freep(&st->codecpar->extradata);
3309  st->codecpar->extradata_size = sc->extradata_size[0];
3310  if (sc->extradata_size[0]) {
3312  if (!st->codecpar->extradata)
3313  return AVERROR(ENOMEM);
3314  memcpy(st->codecpar->extradata, sc->extradata[0], sc->extradata_size[0]);
3315  }
3316 
3317  return mov_finalize_stsd_codec(c, pb, st, sc);
3318 fail:
3319  if (sc->extradata) {
3320  int j;
3321  for (j = 0; j < sc->stsd_count; j++)
3322  av_freep(&sc->extradata[j]);
3323  }
3324 
3325  sc->stsd_count = 0;
3326  av_freep(&sc->extradata);
3327  av_freep(&sc->extradata_size);
3328  return ret;
3329 }
3330 
3332 {
3333  AVStream *st;
3334  MOVStreamContext *sc;
3335  unsigned int i, entries;
3336 
3337  if (c->trak_index < 0) {
3338  av_log(c->fc, AV_LOG_WARNING, "STSC outside TRAK\n");
3339  return 0;
3340  }
3341 
3342  if (c->fc->nb_streams < 1)
3343  return 0;
3344  st = c->fc->streams[c->fc->nb_streams-1];
3345  sc = st->priv_data;
3346 
3347  avio_r8(pb); /* version */
3348  avio_rb24(pb); /* flags */
3349 
3350  entries = avio_rb32(pb);
3351  if ((uint64_t)entries * 12 + 4 > atom.size)
3352  return AVERROR_INVALIDDATA;
3353 
3354  av_log(c->fc, AV_LOG_TRACE, "track[%u].stsc.entries = %u\n", c->fc->nb_streams - 1, entries);
3355 
3356  if (!entries)
3357  return 0;
3358  if (sc->stsc_data) {
3359  av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicated STSC atom\n");
3360  return 0;
3361  }
3362  av_free(sc->stsc_data);
3363  sc->stsc_count = 0;
3364  sc->stsc_data = av_malloc_array(entries, sizeof(*sc->stsc_data));
3365  if (!sc->stsc_data)
3366  return AVERROR(ENOMEM);
3367 
3368  for (i = 0; i < entries && !pb->eof_reached; i++) {
3369  sc->stsc_data[i].first = avio_rb32(pb);
3370  sc->stsc_data[i].count = avio_rb32(pb);
3371  sc->stsc_data[i].id = avio_rb32(pb);
3372  }
3373 
3374  sc->stsc_count = i;
3375  for (i = sc->stsc_count - 1; i < UINT_MAX; i--) {
3376  int64_t first_min = i + 1;
3377  if ((i+1 < sc->stsc_count && sc->stsc_data[i].first >= sc->stsc_data[i+1].first) ||
3378  (i > 0 && sc->stsc_data[i].first <= sc->stsc_data[i-1].first) ||
3379  sc->stsc_data[i].first < first_min ||
3380  sc->stsc_data[i].count < 1 ||
3381  sc->stsc_data[i].id < 1) {
3382  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);
3383  if (i+1 >= sc->stsc_count) {
3384  if (sc->stsc_data[i].count == 0 && i > 0) {
3385  sc->stsc_count --;
3386  continue;
3387  }
3388  sc->stsc_data[i].first = FFMAX(sc->stsc_data[i].first, first_min);
3389  if (i > 0 && sc->stsc_data[i].first <= sc->stsc_data[i-1].first)
3390  sc->stsc_data[i].first = FFMIN(sc->stsc_data[i-1].first + 1LL, INT_MAX);
3391  sc->stsc_data[i].count = FFMAX(sc->stsc_data[i].count, 1);
3392  sc->stsc_data[i].id = FFMAX(sc->stsc_data[i].id, 1);
3393  continue;
3394  }
3395  av_assert0(sc->stsc_data[i+1].first >= 2);
3396  // We replace this entry by the next valid
3397  sc->stsc_data[i].first = sc->stsc_data[i+1].first - 1;
3398  sc->stsc_data[i].count = sc->stsc_data[i+1].count;
3399  sc->stsc_data[i].id = sc->stsc_data[i+1].id;
3400  }
3401  }
3402 
3403  if (pb->eof_reached) {
3404  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSC atom\n");
3405  return AVERROR_EOF;
3406  }
3407 
3408  return 0;
3409 }
3410 
3411 static inline int mov_stsc_index_valid(unsigned int index, unsigned int count)
3412 {
3413  return index < count - 1;
3414 }
3415 
3416 /* Compute the samples value for the stsc entry at the given index. */
3417 static inline int64_t mov_get_stsc_samples(MOVStreamContext *sc, unsigned int index)
3418 {
3419  int chunk_count;
3420 
3422  chunk_count = sc->stsc_data[index + 1].first - sc->stsc_data[index].first;
3423  else {
3424  // Validation for stsc / stco happens earlier in mov_read_stsc + mov_read_trak.
3426  chunk_count = sc->chunk_count - (sc->stsc_data[index].first - 1);
3427  }
3428 
3429  return sc->stsc_data[index].count * (int64_t)chunk_count;
3430 }
3431 
3433 {
3434  AVStream *st;
3435  MOVStreamContext *sc;
3436  unsigned i, entries;
3437 
3438  if (c->trak_index < 0) {
3439  av_log(c->fc, AV_LOG_WARNING, "STPS outside TRAK\n");
3440  return 0;
3441  }
3442 
3443  if (c->fc->nb_streams < 1)
3444  return 0;
3445  st = c->fc->streams[c->fc->nb_streams-1];
3446  sc = st->priv_data;
3447 
3448  avio_rb32(pb); // version + flags
3449 
3450  entries = avio_rb32(pb);
3451  if (sc->stps_data)
3452  av_log(c->fc, AV_LOG_WARNING, "Duplicated STPS atom\n");
3453  av_free(sc->stps_data);
3454  sc->stps_count = 0;
3455  sc->stps_data = av_malloc_array(entries, sizeof(*sc->stps_data));
3456  if (!sc->stps_data)
3457  return AVERROR(ENOMEM);
3458 
3459  for (i = 0; i < entries && !pb->eof_reached; i++) {
3460  sc->stps_data[i] = avio_rb32(pb);
3461  }
3462 
3463  sc->stps_count = i;
3464 
3465  if (pb->eof_reached) {
3466  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STPS atom\n");
3467  return AVERROR_EOF;
3468  }
3469 
3470  return 0;
3471 }
3472 
3474 {
3475  AVStream *st;
3476  FFStream *sti;
3477  MOVStreamContext *sc;
3478  unsigned int i, entries;
3479 
3480  if (c->trak_index < 0) {
3481  av_log(c->fc, AV_LOG_WARNING, "STSS outside TRAK\n");
3482  return 0;
3483  }
3484 
3485  if (c->fc->nb_streams < 1)
3486  return 0;
3487  st = c->fc->streams[c->fc->nb_streams-1];
3488  sti = ffstream(st);
3489  sc = st->priv_data;
3490 
3491  avio_r8(pb); /* version */
3492  avio_rb24(pb); /* flags */
3493 
3494  entries = avio_rb32(pb);
3495 
3496  av_log(c->fc, AV_LOG_TRACE, "keyframe_count = %u\n", entries);
3497 
3498  if (!entries) {
3499  sc->keyframe_absent = 1;
3500  if (!sti->need_parsing && st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
3502  return 0;
3503  }
3504  if (sc->keyframes)
3505  av_log(c->fc, AV_LOG_WARNING, "Duplicated STSS atom\n");
3506  if (entries >= UINT_MAX / sizeof(int))
3507  return AVERROR_INVALIDDATA;
3508  av_freep(&sc->keyframes);
3509  sc->keyframe_count = 0;
3510  sc->keyframes = av_malloc_array(entries, sizeof(*sc->keyframes));
3511  if (!sc->keyframes)
3512  return AVERROR(ENOMEM);
3513 
3514  for (i = 0; i < entries && !pb->eof_reached; i++) {
3515  sc->keyframes[i] = avio_rb32(pb);
3516  }
3517 
3518  sc->keyframe_count = i;
3519 
3520  if (pb->eof_reached) {
3521  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSS atom\n");
3522  return AVERROR_EOF;
3523  }
3524 
3525  return 0;
3526 }
3527 
3529 {
3530  AVStream *st;
3531  MOVStreamContext *sc;
3532  unsigned int i, entries, sample_size, field_size, num_bytes;
3533  GetBitContext gb;
3534  unsigned char* buf;
3535  int ret;
3536 
3537  if (c->trak_index < 0) {
3538  av_log(c->fc, AV_LOG_WARNING, "STSZ outside TRAK\n");
3539  return 0;
3540  }
3541 
3542  if (c->fc->nb_streams < 1)
3543  return 0;
3544  st = c->fc->streams[c->fc->nb_streams-1];
3545  sc = st->priv_data;
3546 
3547  avio_r8(pb); /* version */
3548  avio_rb24(pb); /* flags */
3549 
3550  if (atom.type == MKTAG('s','t','s','z')) {
3551  sample_size = avio_rb32(pb);
3552  if (!sc->sample_size) /* do not overwrite value computed in stsd */
3553  sc->sample_size = sample_size;
3554  sc->stsz_sample_size = sample_size;
3555  field_size = 32;
3556  } else {
3557  sample_size = 0;
3558  avio_rb24(pb); /* reserved */
3559  field_size = avio_r8(pb);
3560  }
3561  entries = avio_rb32(pb);
3562 
3563  av_log(c->fc, AV_LOG_TRACE, "sample_size = %u sample_count = %u\n", sc->sample_size, entries);
3564 
3565  sc->sample_count = entries;
3566  if (sample_size)
3567  return 0;
3568 
3569  if (field_size != 4 && field_size != 8 && field_size != 16 && field_size != 32) {
3570  av_log(c->fc, AV_LOG_ERROR, "Invalid sample field size %u\n", field_size);
3571  return AVERROR_INVALIDDATA;
3572  }
3573 
3574  if (!entries)
3575  return 0;
3576  if (entries >= (INT_MAX - 4 - 8 * AV_INPUT_BUFFER_PADDING_SIZE) / field_size)
3577  return AVERROR_INVALIDDATA;
3578  if (sc->sample_sizes)
3579  av_log(c->fc, AV_LOG_WARNING, "Duplicated STSZ atom\n");
3580  av_free(sc->sample_sizes);
3581  sc->sample_count = 0;
3582  sc->sample_sizes = av_malloc_array(entries, sizeof(*sc->sample_sizes));
3583  if (!sc->sample_sizes)
3584  return AVERROR(ENOMEM);
3585 
3586  num_bytes = (entries*field_size+4)>>3;
3587 
3588  buf = av_malloc(num_bytes+AV_INPUT_BUFFER_PADDING_SIZE);
3589  if (!buf) {
3590  av_freep(&sc->sample_sizes);
3591  return AVERROR(ENOMEM);
3592  }
3593 
3594  ret = ffio_read_size(pb, buf, num_bytes);
3595  if (ret < 0) {
3596  av_freep(&sc->sample_sizes);
3597  av_free(buf);
3598  av_log(c->fc, AV_LOG_WARNING, "STSZ atom truncated\n");
3599  return 0;
3600  }
3601 
3602  init_get_bits(&gb, buf, 8*num_bytes);
3603 
3604  for (i = 0; i < entries; i++) {
3605  sc->sample_sizes[i] = get_bits_long(&gb, field_size);
3606  if (sc->sample_sizes[i] > INT64_MAX - sc->data_size) {
3607  av_free(buf);
3608  av_log(c->fc, AV_LOG_ERROR, "Sample size overflow in STSZ\n");
3609  return AVERROR_INVALIDDATA;
3610  }
3611  sc->data_size += sc->sample_sizes[i];
3612  }
3613 
3614  sc->sample_count = i;
3615 
3616  av_free(buf);
3617 
3618  return 0;
3619 }
3620 
3622 {
3623  AVStream *st;
3624  MOVStreamContext *sc;
3625  unsigned int i, entries;
3626  int64_t duration = 0;
3627  int64_t total_sample_count = 0;
3628  int64_t current_dts = 0;
3629  int64_t corrected_dts = 0;
3630 
3631  if (c->trak_index < 0) {
3632  av_log(c->fc, AV_LOG_WARNING, "STTS outside TRAK\n");
3633  return 0;
3634  }
3635 
3636  if (c->fc->nb_streams < 1)
3637  return 0;
3638  st = c->fc->streams[c->fc->nb_streams-1];
3639  sc = st->priv_data;
3640 
3641  avio_r8(pb); /* version */
3642  avio_rb24(pb); /* flags */
3643  entries = avio_rb32(pb);
3644 
3645  av_log(c->fc, AV_LOG_TRACE, "track[%u].stts.entries = %u\n",
3646  c->fc->nb_streams-1, entries);
3647 
3648  if (sc->stts_data)
3649  av_log(c->fc, AV_LOG_WARNING, "Duplicated STTS atom\n");
3650  av_freep(&sc->stts_data);
3651  sc->stts_count = 0;
3652  if (entries >= INT_MAX / sizeof(*sc->stts_data))
3653  return AVERROR(ENOMEM);
3654 
3655  for (i = 0; i < entries && !pb->eof_reached; i++) {
3656  unsigned int sample_duration;
3657  unsigned int sample_count;
3658  unsigned int min_entries = FFMIN(FFMAX(i + 1, 1024 * 1024), entries);
3659  MOVStts *stts_data = av_fast_realloc(sc->stts_data, &sc->stts_allocated_size,
3660  min_entries * sizeof(*sc->stts_data));
3661  if (!stts_data) {
3662  av_freep(&sc->stts_data);
3663  sc->stts_count = 0;
3664  return AVERROR(ENOMEM);
3665  }
3666  sc->stts_count = min_entries;
3667  sc->stts_data = stts_data;
3668 
3669  sample_count = avio_rb32(pb);
3670  sample_duration = avio_rb32(pb);
3671 
3672  sc->stts_data[i].count= sample_count;
3673  sc->stts_data[i].duration= sample_duration;
3674 
3675  av_log(c->fc, AV_LOG_TRACE, "sample_count=%u, sample_duration=%u\n",
3676  sample_count, sample_duration);
3677 
3678  /* STTS sample offsets are uint32 but some files store it as int32
3679  * with negative values used to correct DTS delays.
3680  There may be abnormally large values as well. */
3681  if (sample_duration > c->max_stts_delta) {
3682  // assume high delta is a correction if negative when cast as int32
3683  int32_t delta_magnitude = (int32_t)sample_duration;
3684  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",
3685  sample_duration, i, sample_count, st->index);
3686  sc->stts_data[i].duration = 1;
3687  corrected_dts = av_sat_add64(corrected_dts, (delta_magnitude < 0 ? (int64_t)delta_magnitude : 1) * sample_count);
3688  } else {
3689  corrected_dts += sample_duration * (uint64_t)sample_count;
3690  }
3691 
3692  current_dts += sc->stts_data[i].duration * (uint64_t)sample_count;
3693 
3694  if (current_dts > corrected_dts) {
3695  int64_t drift = av_sat_sub64(current_dts, corrected_dts) / FFMAX(sample_count, 1);
3696  uint32_t correction = (sc->stts_data[i].duration > drift) ? drift : sc->stts_data[i].duration - 1;
3697  current_dts -= correction * (uint64_t)sample_count;
3698  sc->stts_data[i].duration -= correction;
3699  }
3700 
3701  duration+=(int64_t)sc->stts_data[i].duration*(uint64_t)sc->stts_data[i].count;
3702  total_sample_count+=sc->stts_data[i].count;
3703  }
3704 
3705  sc->stts_count = i;
3706 
3707  if (duration > 0 &&
3708  duration <= INT64_MAX - sc->duration_for_fps &&
3709  total_sample_count <= INT_MAX - sc->nb_frames_for_fps) {
3710  sc->duration_for_fps += duration;
3711  sc->nb_frames_for_fps += total_sample_count;
3712  }
3713 
3714  if (pb->eof_reached) {
3715  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STTS atom\n");
3716  return AVERROR_EOF;
3717  }
3718 
3719  st->nb_frames= total_sample_count;
3720  if (duration)
3721  st->duration= FFMIN(st->duration, duration);
3722 
3723  // All samples have zero duration. They have higher chance be chose by
3724  // mov_find_next_sample, which leads to seek again and again.
3725  //
3726  // It's AVERROR_INVALIDDATA actually, but such files exist in the wild.
3727  // So only mark data stream as discarded for safety.
3728  if (!duration && sc->stts_count &&
3730  av_log(c->fc, AV_LOG_WARNING,
3731  "All samples in data stream index:id [%d:%d] have zero "
3732  "duration, stream set to be discarded by default. Override "
3733  "using AVStream->discard or -discard for ffmpeg command.\n",
3734  st->index, sc->id);
3735  st->discard = AVDISCARD_ALL;
3736  }
3737  sc->track_end = duration;
3738  return 0;
3739 }
3740 
3742 {
3743  AVStream *st;
3744  MOVStreamContext *sc;
3745  unsigned int i;
3746  int64_t entries;
3747 
3748  if (c->fc->nb_streams < 1)
3749  return 0;
3750  st = c->fc->streams[c->fc->nb_streams - 1];
3751  sc = st->priv_data;
3752 
3753  avio_r8(pb); /* version */
3754  avio_rb24(pb); /* flags */
3755  entries = atom.size - 4;
3756 
3757  av_log(c->fc, AV_LOG_TRACE, "track[%u].sdtp.entries = %" PRId64 "\n",
3758  c->fc->nb_streams - 1, entries);
3759 
3760  if (sc->sdtp_data)
3761  av_log(c->fc, AV_LOG_WARNING, "Duplicated SDTP atom\n");
3762  av_freep(&sc->sdtp_data);
3763  sc->sdtp_count = 0;
3764 
3765  if (entries < 0 || entries > UINT_MAX)
3766  return AVERROR(ERANGE);
3767 
3768  sc->sdtp_data = av_malloc(entries);
3769  if (!sc->sdtp_data)
3770  return AVERROR(ENOMEM);
3771 
3772  for (i = 0; i < entries && !pb->eof_reached; i++)
3773  sc->sdtp_data[i] = avio_r8(pb);
3774  sc->sdtp_count = i;
3775 
3776  return 0;
3777 }
3778 
3779 static void mov_update_dts_shift(MOVStreamContext *sc, int duration, void *logctx)
3780 {
3781  if (duration < 0) {
3782  if (duration == INT_MIN) {
3783  av_log(logctx, AV_LOG_WARNING, "mov_update_dts_shift(): dts_shift set to %d\n", INT_MAX);
3784  duration++;
3785  }
3786  sc->dts_shift = FFMAX(sc->dts_shift, -duration);
3787  }
3788 }
3789 
3791 {
3792  AVStream *st;
3793  MOVStreamContext *sc;
3794  unsigned int i, entries, ctts_count = 0;
3795 
3796  if (c->trak_index < 0) {
3797  av_log(c->fc, AV_LOG_WARNING, "CTTS outside TRAK\n");
3798  return 0;
3799  }
3800 
3801  if (c->fc->nb_streams < 1)
3802  return 0;
3803  st = c->fc->streams[c->fc->nb_streams-1];
3804  sc = st->priv_data;
3805 
3806  avio_r8(pb); /* version */
3807  avio_rb24(pb); /* flags */
3808  entries = avio_rb32(pb);
3809 
3810  av_log(c->fc, AV_LOG_TRACE, "track[%u].ctts.entries = %u\n", c->fc->nb_streams - 1, entries);
3811 
3812  if (!entries)
3813  return 0;
3814  if (entries >= UINT_MAX / sizeof(*sc->ctts_data))
3815  return AVERROR_INVALIDDATA;
3816  av_freep(&sc->ctts_data);
3817  sc->ctts_data = av_fast_realloc(NULL, &sc->ctts_allocated_size, entries * sizeof(*sc->ctts_data));
3818  if (!sc->ctts_data)
3819  return AVERROR(ENOMEM);
3820 
3821  for (i = 0; i < entries && !pb->eof_reached; i++) {
3822  MOVCtts *ctts_data;
3823  const size_t min_size_needed = (ctts_count + 1) * sizeof(MOVCtts);
3824  const size_t requested_size =
3825  min_size_needed > sc->ctts_allocated_size ?
3826  FFMAX(min_size_needed, 2 * sc->ctts_allocated_size) :
3827  min_size_needed;
3828  int count = avio_rb32(pb);
3829  int duration = avio_rb32(pb);
3830 
3831  if (count <= 0) {
3832  av_log(c->fc, AV_LOG_TRACE,
3833  "ignoring CTTS entry with count=%d duration=%d\n",
3834  count, duration);
3835  continue;
3836  }
3837 
3838  if (ctts_count >= UINT_MAX / sizeof(MOVCtts) - 1)
3839  return AVERROR(ENOMEM);
3840 
3841  ctts_data = av_fast_realloc(sc->ctts_data, &sc->ctts_allocated_size, requested_size);
3842 
3843  if (!ctts_data)
3844  return AVERROR(ENOMEM);
3845 
3846  sc->ctts_data = ctts_data;
3847 
3848  ctts_data[ctts_count].count = count;
3849  ctts_data[ctts_count].offset = duration;
3850  ctts_count++;
3851 
3852  av_log(c->fc, AV_LOG_TRACE, "count=%d, duration=%d\n",
3853  count, duration);
3854 
3855  if (i+2<entries)
3856  mov_update_dts_shift(sc, duration, c->fc);
3857  }
3858 
3859  sc->ctts_count = ctts_count;
3860 
3861  if (pb->eof_reached) {
3862  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted CTTS atom\n");
3863  return AVERROR_EOF;
3864  }
3865 
3866  av_log(c->fc, AV_LOG_TRACE, "dts shift %d\n", sc->dts_shift);
3867 
3868  return 0;
3869 }
3870 
3872 {
3873  AVStream *st;
3874  MOVStreamContext *sc;
3875  uint8_t version;
3876  uint32_t grouping_type;
3877  uint32_t default_length;
3878  av_unused uint32_t default_group_description_index;
3879  uint32_t entry_count;
3880 
3881  if (c->fc->nb_streams < 1)
3882  return 0;
3883  st = c->fc->streams[c->fc->nb_streams - 1];
3884  sc = st->priv_data;
3885 
3886  version = avio_r8(pb); /* version */
3887  avio_rb24(pb); /* flags */
3888  grouping_type = avio_rl32(pb);
3889 
3890  /*
3891  * This function only supports "sync" boxes, but the code is able to parse
3892  * other boxes (such as "tscl", "tsas" and "stsa")
3893  */
3894  if (grouping_type != MKTAG('s','y','n','c'))
3895  return 0;
3896 
3897  default_length = version >= 1 ? avio_rb32(pb) : 0;
3898  default_group_description_index = version >= 2 ? avio_rb32(pb) : 0;
3899  entry_count = avio_rb32(pb);
3900 
3901  av_freep(&sc->sgpd_sync);
3902  sc->sgpd_sync_count = entry_count;
3903  sc->sgpd_sync = av_calloc(entry_count, sizeof(*sc->sgpd_sync));
3904  if (!sc->sgpd_sync)
3905  return AVERROR(ENOMEM);
3906 
3907  for (uint32_t i = 0; i < entry_count && !pb->eof_reached; i++) {
3908  uint32_t description_length = default_length;
3909  if (version >= 1 && default_length == 0)
3910  description_length = avio_rb32(pb);
3911  if (grouping_type == MKTAG('s','y','n','c')) {
3912  const uint8_t nal_unit_type = avio_r8(pb) & 0x3f;
3913  sc->sgpd_sync[i] = nal_unit_type;
3914  description_length -= 1;
3915  }
3916  avio_skip(pb, description_length);
3917  }
3918 
3919  if (pb->eof_reached) {
3920  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted SGPD atom\n");
3921  return AVERROR_EOF;
3922  }
3923 
3924  return 0;
3925 }
3926 
3928 {
3929  AVStream *st;
3930  MOVStreamContext *sc;
3931  unsigned int i, entries;
3932  uint8_t version;
3933  uint32_t grouping_type;
3934  MOVSbgp *table, **tablep;
3935  int *table_count;
3936 
3937  if (c->fc->nb_streams < 1)
3938  return 0;
3939  st = c->fc->streams[c->fc->nb_streams-1];
3940  sc = st->priv_data;
3941 
3942  version = avio_r8(pb); /* version */
3943  avio_rb24(pb); /* flags */
3944  grouping_type = avio_rl32(pb);
3945 
3946  if (grouping_type == MKTAG('r','a','p',' ')) {
3947  tablep = &sc->rap_group;
3948  table_count = &sc->rap_group_count;
3949  } else if (grouping_type == MKTAG('s','y','n','c')) {
3950  tablep = &sc->sync_group;
3951  table_count = &sc->sync_group_count;
3952  } else {
3953  return 0;
3954  }
3955 
3956  if (version == 1)
3957  avio_rb32(pb); /* grouping_type_parameter */
3958 
3959  entries = avio_rb32(pb);
3960  if (!entries)
3961  return 0;
3962  if (*tablep)
3963  av_log(c->fc, AV_LOG_WARNING, "Duplicated SBGP %s atom\n", av_fourcc2str(grouping_type));
3964  av_freep(tablep);
3965  table = av_malloc_array(entries, sizeof(*table));
3966  if (!table)
3967  return AVERROR(ENOMEM);
3968  *tablep = table;
3969 
3970  for (i = 0; i < entries && !pb->eof_reached; i++) {
3971  table[i].count = avio_rb32(pb); /* sample_count */
3972  table[i].index = avio_rb32(pb); /* group_description_index */
3973  }
3974 
3975  *table_count = i;
3976 
3977  if (pb->eof_reached) {
3978  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted SBGP atom\n");
3979  return AVERROR_EOF;
3980  }
3981 
3982  return 0;
3983 }
3984 
3985 /**
3986  * Get ith edit list entry (media time, duration).
3987  */
3989  const MOVStreamContext *msc,
3990  unsigned int edit_list_index,
3991  int64_t *edit_list_media_time,
3992  int64_t *edit_list_duration,
3993  int64_t global_timescale)
3994 {
3995  if (edit_list_index == msc->elst_count) {
3996  return 0;
3997  }
3998  *edit_list_media_time = msc->elst_data[edit_list_index].time;
3999  *edit_list_duration = msc->elst_data[edit_list_index].duration;
4000 
4001  /* duration is in global timescale units;convert to msc timescale */
4002  if (global_timescale == 0) {
4003  avpriv_request_sample(mov->fc, "Support for mvhd.timescale = 0 with editlists");
4004  return 0;
4005  }
4006  *edit_list_duration = av_rescale(*edit_list_duration, msc->time_scale,
4007  global_timescale);
4008 
4009  if (*edit_list_duration + (uint64_t)*edit_list_media_time > INT64_MAX)
4010  *edit_list_duration = 0;
4011 
4012  return 1;
4013 }
4014 
4015 /**
4016  * Find the closest previous frame to the timestamp_pts, in e_old index
4017  * entries. Searching for just any frame / just key frames can be controlled by
4018  * last argument 'flag'.
4019  * Note that if ctts_data is not NULL, we will always search for a key frame
4020  * irrespective of the value of 'flag'. If we don't find any keyframe, we will
4021  * return the first frame of the video.
4022  *
4023  * Here the timestamp_pts is considered to be a presentation timestamp and
4024  * the timestamp of index entries are considered to be decoding timestamps.
4025  *
4026  * Returns 0 if successful in finding a frame, else returns -1.
4027  * Places the found index corresponding output arg.
4028  *
4029  * If ctts_old is not NULL, then refines the searched entry by searching
4030  * backwards from the found timestamp, to find the frame with correct PTS.
4031  *
4032  * Places the found ctts_index and ctts_sample in corresponding output args.
4033  */
4035  AVIndexEntry *e_old,
4036  int nb_old,
4037  MOVTimeToSample *tts_data,
4038  int64_t tts_count,
4039  int64_t timestamp_pts,
4040  int flag,
4041  int64_t* index,
4042  int64_t* tts_index,
4043  int64_t* tts_sample)
4044 {
4045  MOVStreamContext *msc = st->priv_data;
4046  FFStream *const sti = ffstream(st);
4047  AVIndexEntry *e_keep = sti->index_entries;
4048  int nb_keep = sti->nb_index_entries;
4049  int64_t i = 0;
4050 
4051  av_assert0(index);
4052 
4053  // If dts_shift > 0, then all the index timestamps will have to be offset by
4054  // at least dts_shift amount to obtain PTS.
4055  // Hence we decrement the searched timestamp_pts by dts_shift to find the closest index element.
4056  if (msc->dts_shift > 0) {
4057  timestamp_pts -= msc->dts_shift;
4058  }
4059 
4060  sti->index_entries = e_old;
4061  sti->nb_index_entries = nb_old;
4062  *index = av_index_search_timestamp(st, timestamp_pts, flag | AVSEEK_FLAG_BACKWARD);
4063 
4064  // Keep going backwards in the index entries until the timestamp is the same.
4065  if (*index >= 0) {
4066  for (i = *index; i > 0 && e_old[i].timestamp == e_old[i - 1].timestamp;
4067  i--) {
4068  if ((flag & AVSEEK_FLAG_ANY) ||
4069  (e_old[i - 1].flags & AVINDEX_KEYFRAME)) {
4070  *index = i - 1;
4071  }
4072  }
4073  }
4074 
4075  // If we have CTTS then refine the search, by searching backwards over PTS
4076  // computed by adding corresponding CTTS durations to index timestamps.
4077  if (msc->ctts_count && *index >= 0) {
4078  av_assert0(tts_index);
4079  av_assert0(tts_sample);
4080  // Find out the ctts_index for the found frame.
4081  *tts_index = 0;
4082  *tts_sample = 0;
4083  for (int64_t index_tts_count = 0; index_tts_count < *index; index_tts_count++) {
4084  if (*tts_index < tts_count) {
4085  (*tts_sample)++;
4086  if (tts_data[*tts_index].count == *tts_sample) {
4087  (*tts_index)++;
4088  *tts_sample = 0;
4089  }
4090  }
4091  }
4092 
4093  while (*index >= 0 && (*tts_index) >= 0 && (*tts_index) < tts_count) {
4094  // Find a "key frame" with PTS <= timestamp_pts (So that we can decode B-frames correctly).
4095  // No need to add dts_shift to the timestamp here because timestamp_pts has already been
4096  // compensated by dts_shift above.
4097  if ((e_old[*index].timestamp + tts_data[*tts_index].offset) <= timestamp_pts &&
4098  (e_old[*index].flags & AVINDEX_KEYFRAME)) {
4099  break;
4100  }
4101 
4102  (*index)--;
4103  if (*tts_sample == 0) {
4104  (*tts_index)--;
4105  if (*tts_index >= 0)
4106  *tts_sample = tts_data[*tts_index].count - 1;
4107  } else {
4108  (*tts_sample)--;
4109  }
4110  }
4111  }
4112 
4113  /* restore AVStream state*/
4114  sti->index_entries = e_keep;
4115  sti->nb_index_entries = nb_keep;
4116  return *index >= 0 ? 0 : -1;
4117 }
4118 
4119 /**
4120  * Add index entry with the given values, to the end of ffstream(st)->index_entries.
4121  * Returns the new size ffstream(st)->index_entries if successful, else returns -1.
4122  *
4123  * This function is similar to ff_add_index_entry in libavformat/utils.c
4124  * except that here we are always unconditionally adding an index entry to
4125  * the end, instead of searching the entries list and skipping the add if
4126  * there is an existing entry with the same timestamp.
4127  * This is needed because the mov_fix_index calls this func with the same
4128  * unincremented timestamp for successive discarded frames.
4129  */
4131  int size, int distance, int flags)
4132 {
4133  FFStream *const sti = ffstream(st);
4134  AVIndexEntry *entries, *ie;
4135  int64_t index = -1;
4136  const size_t min_size_needed = (sti->nb_index_entries + 1) * sizeof(AVIndexEntry);
4137 
4138  // Double the allocation each time, to lower memory fragmentation.
4139  // Another difference from ff_add_index_entry function.
4140  const size_t requested_size =
4141  min_size_needed > sti->index_entries_allocated_size ?
4142  FFMAX(min_size_needed, 2 * sti->index_entries_allocated_size) :
4143  min_size_needed;
4144 
4145  if (sti->nb_index_entries + 1U >= UINT_MAX / sizeof(AVIndexEntry))
4146  return -1;
4147 
4148  entries = av_fast_realloc(sti->index_entries,
4150  requested_size);
4151  if (!entries)
4152  return -1;
4153 
4154  sti->index_entries = entries;
4155 
4156  index = sti->nb_index_entries++;
4157  ie= &entries[index];
4158 
4159  ie->pos = pos;
4160  ie->timestamp = timestamp;
4161  ie->min_distance= distance;
4162  ie->size= size;
4163  ie->flags = flags;
4164  return index;
4165 }
4166 
4167 /**
4168  * Rewrite timestamps of index entries in the range [end_index - frame_duration_buffer_size, end_index)
4169  * by subtracting end_ts successively by the amounts given in frame_duration_buffer.
4170  */
4171 static void fix_index_entry_timestamps(AVStream* st, int end_index, int64_t end_ts,
4172  int64_t* frame_duration_buffer,
4173  int frame_duration_buffer_size) {
4174  FFStream *const sti = ffstream(st);
4175  int i = 0;
4176  av_assert0(end_index >= 0 && end_index <= sti->nb_index_entries);
4177  for (i = 0; i < frame_duration_buffer_size; i++) {
4178  end_ts -= frame_duration_buffer[frame_duration_buffer_size - 1 - i];
4179  sti->index_entries[end_index - 1 - i].timestamp = end_ts;
4180  }
4181 }
4182 
4183 static int add_tts_entry(MOVTimeToSample **tts_data, unsigned int *tts_count, unsigned int *allocated_size,
4184  int count, int offset, unsigned int duration)
4185 {
4186  MOVTimeToSample *tts_buf_new;
4187  const size_t min_size_needed = (*tts_count + 1) * sizeof(MOVTimeToSample);
4188  const size_t requested_size =
4189  min_size_needed > *allocated_size ?
4190  FFMAX(min_size_needed, 2 * (*allocated_size)) :
4191  min_size_needed;
4192 
4193  if ((unsigned)(*tts_count) >= UINT_MAX / sizeof(MOVTimeToSample) - 1)
4194  return -1;
4195 
4196  tts_buf_new = av_fast_realloc(*tts_data, allocated_size, requested_size);
4197 
4198  if (!tts_buf_new)
4199  return -1;
4200 
4201  *tts_data = tts_buf_new;
4202 
4203  tts_buf_new[*tts_count].count = count;
4204  tts_buf_new[*tts_count].offset = offset;
4205  tts_buf_new[*tts_count].duration = duration;
4206 
4207  *tts_count = (*tts_count) + 1;
4208  return 0;
4209 }
4210 
4211 #define MAX_REORDER_DELAY 16
4213 {
4214  MOVStreamContext *msc = st->priv_data;
4215  FFStream *const sti = ffstream(st);
4216  int ctts_ind = 0;
4217  int ctts_sample = 0;
4218  int64_t pts_buf[MAX_REORDER_DELAY + 1]; // Circular buffer to sort pts.
4219  int buf_start = 0;
4220  int j, r, num_swaps;
4221 
4222  for (j = 0; j < MAX_REORDER_DELAY + 1; j++)
4223  pts_buf[j] = INT64_MIN;
4224 
4225  if (st->codecpar->video_delay <= 0 && msc->ctts_count &&
4227  st->codecpar->video_delay = 0;
4228  for (int ind = 0; ind < sti->nb_index_entries && ctts_ind < msc->tts_count; ++ind) {
4229  // Point j to the last elem of the buffer and insert the current pts there.
4230  j = buf_start;
4231  buf_start = (buf_start + 1);
4232  if (buf_start == MAX_REORDER_DELAY + 1)
4233  buf_start = 0;
4234 
4235  pts_buf[j] = sti->index_entries[ind].timestamp + msc->tts_data[ctts_ind].offset;
4236 
4237  // The timestamps that are already in the sorted buffer, and are greater than the
4238  // current pts, are exactly the timestamps that need to be buffered to output PTS
4239  // in correct sorted order.
4240  // Hence the video delay (which is the buffer size used to sort DTS and output PTS),
4241  // can be computed as the maximum no. of swaps any particular timestamp needs to
4242  // go through, to keep this buffer in sorted order.
4243  num_swaps = 0;
4244  while (j != buf_start) {
4245  r = j - 1;
4246  if (r < 0) r = MAX_REORDER_DELAY;
4247  if (pts_buf[j] < pts_buf[r]) {
4248  FFSWAP(int64_t, pts_buf[j], pts_buf[r]);
4249  ++num_swaps;
4250  } else {
4251  break;
4252  }
4253  j = r;
4254  }
4255  st->codecpar->video_delay = FFMAX(st->codecpar->video_delay, num_swaps);
4256 
4257  ctts_sample++;
4258  if (ctts_sample == msc->tts_data[ctts_ind].count) {
4259  ctts_ind++;
4260  ctts_sample = 0;
4261  }
4262  }
4263  av_log(c->fc, AV_LOG_DEBUG, "Setting codecpar->delay to %d for stream st: %d\n",
4264  st->codecpar->video_delay, st->index);
4265  }
4266 }
4267 
4269 {
4270  sc->current_sample++;
4271  sc->current_index++;
4272  if (sc->index_ranges &&
4273  sc->current_index >= sc->current_index_range->end &&
4274  sc->current_index_range->end) {
4275  sc->current_index_range++;
4277  }
4278 }
4279 
4281 {
4282  sc->current_sample--;
4283  sc->current_index--;
4284  if (sc->index_ranges &&
4286  sc->current_index_range > sc->index_ranges) {
4287  sc->current_index_range--;
4288  sc->current_index = sc->current_index_range->end - 1;
4289  }
4290 }
4291 
4292 static void mov_current_sample_set(MOVStreamContext *sc, int current_sample)
4293 {
4294  int64_t range_size;
4295 
4296  sc->current_sample = current_sample;
4297  sc->current_index = current_sample;
4298  if (!sc->index_ranges) {
4299  return;
4300  }
4301 
4302  for (sc->current_index_range = sc->index_ranges;
4303  sc->current_index_range->end;
4304  sc->current_index_range++) {
4305  range_size = sc->current_index_range->end - sc->current_index_range->start;
4306  if (range_size > current_sample) {
4307  sc->current_index = sc->current_index_range->start + current_sample;
4308  break;
4309  }
4310  current_sample -= range_size;
4311  }
4312 }
4313 
4314 /**
4315  * Fix ffstream(st)->index_entries, so that it contains only the entries (and the entries
4316  * which are needed to decode them) that fall in the edit list time ranges.
4317  * Also fixes the timestamps of the index entries to match the timeline
4318  * specified the edit lists.
4319  */
4320 static void mov_fix_index(MOVContext *mov, AVStream *st)
4321 {
4322  MOVStreamContext *msc = st->priv_data;
4323  FFStream *const sti = ffstream(st);
4324  AVIndexEntry *e_old = sti->index_entries;
4325  int nb_old = sti->nb_index_entries;
4326  const AVIndexEntry *e_old_end = e_old + nb_old;
4327  const AVIndexEntry *current = NULL;
4328  MOVTimeToSample *tts_data_old = msc->tts_data;
4329  int64_t tts_index_old = 0;
4330  int64_t tts_sample_old = 0;
4331  int64_t tts_count_old = msc->tts_count;
4332  int64_t edit_list_media_time = 0;
4333  int64_t edit_list_duration = 0;
4334  int64_t frame_duration = 0;
4335  int64_t edit_list_dts_counter = 0;
4336  int64_t edit_list_dts_entry_end = 0;
4337  int64_t edit_list_start_tts_sample = 0;
4338  int64_t curr_cts;
4339  int64_t curr_ctts = 0;
4340  int64_t empty_edits_sum_duration = 0;
4341  int64_t edit_list_index = 0;
4342  int64_t index;
4343  int flags;
4344  int64_t start_dts = 0;
4345  int64_t edit_list_start_encountered = 0;
4346  int64_t search_timestamp = 0;
4347  int64_t* frame_duration_buffer = NULL;
4348  int num_discarded_begin = 0;
4349  int first_non_zero_audio_edit = -1;
4350  int packet_skip_samples = 0;
4351  MOVIndexRange *current_index_range = NULL;
4352  int found_keyframe_after_edit = 0;
4353  int found_non_empty_edit = 0;
4354 
4355  if (!msc->elst_data || msc->elst_count <= 0 || nb_old <= 0) {
4356  return;
4357  }
4358 
4359  // allocate the index ranges array
4360  msc->index_ranges = av_malloc_array(msc->elst_count + 1,
4361  sizeof(msc->index_ranges[0]));
4362  if (!msc->index_ranges) {
4363  av_log(mov->fc, AV_LOG_ERROR, "Cannot allocate index ranges buffer\n");
4364  return;
4365  }
4366  msc->current_index_range = msc->index_ranges;
4367 
4368  // Clean AVStream from traces of old index
4369  sti->index_entries = NULL;
4371  sti->nb_index_entries = 0;
4372 
4373  // Clean time to sample fields of MOVStreamContext
4374  msc->tts_data = NULL;
4375  msc->tts_count = 0;
4376  msc->tts_index = 0;
4377  msc->tts_sample = 0;
4378  msc->tts_allocated_size = 0;
4379 
4380  // Reinitialize min_corrected_pts so that it can be computed again.
4381  msc->min_corrected_pts = -1;
4382 
4383  // If the dts_shift is positive (in case of negative ctts values in mov),
4384  // then negate the DTS by dts_shift
4385  if (msc->dts_shift > 0) {
4386  edit_list_dts_entry_end -= msc->dts_shift;
4387  av_log(mov->fc, AV_LOG_DEBUG, "Shifting DTS by %d because of negative CTTS.\n", msc->dts_shift);
4388  }
4389 
4390  start_dts = edit_list_dts_entry_end;
4391 
4392  while (get_edit_list_entry(mov, msc, edit_list_index, &edit_list_media_time,
4393  &edit_list_duration, mov->time_scale)) {
4394  av_log(mov->fc, AV_LOG_DEBUG, "Processing st: %d, edit list %"PRId64" - media time: %"PRId64", duration: %"PRId64"\n",
4395  st->index, edit_list_index, edit_list_media_time, edit_list_duration);
4396  edit_list_index++;
4397  edit_list_dts_counter = edit_list_dts_entry_end;
4398  edit_list_dts_entry_end = av_sat_add64(edit_list_dts_entry_end, edit_list_duration);
4399  if (edit_list_dts_entry_end == INT64_MAX) {
4400  av_log(mov->fc, AV_LOG_ERROR, "Cannot calculate dts entry length with duration %"PRId64"\n",
4401  edit_list_duration);
4402  break;
4403  }
4404  num_discarded_begin = 0;
4405  if (!found_non_empty_edit && edit_list_media_time == -1) {
4406  empty_edits_sum_duration += edit_list_duration;
4407  continue;
4408  }
4409  found_non_empty_edit = 1;
4410 
4411  // If we encounter a non-negative edit list reset the skip_samples/start_pad fields and set them
4412  // according to the edit list below.
4413  if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
4414  if (first_non_zero_audio_edit < 0) {
4415  first_non_zero_audio_edit = 1;
4416  } else {
4417  first_non_zero_audio_edit = 0;
4418  }
4419 
4420  if (first_non_zero_audio_edit > 0)
4421  sti->skip_samples = msc->start_pad = 0;
4422  }
4423 
4424  // While reordering frame index according to edit list we must handle properly
4425  // the scenario when edit list entry starts from none key frame.
4426  // We find closest previous key frame and preserve it and consequent frames in index.
4427  // All frames which are outside edit list entry time boundaries will be dropped after decoding.
4428  search_timestamp = edit_list_media_time;
4429  if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
4430  // Audio decoders like AAC need need a decoder delay samples previous to the current sample,
4431  // to correctly decode this frame. Hence for audio we seek to a frame 1 sec. before the
4432  // edit_list_media_time to cover the decoder delay.
4433  search_timestamp = FFMAX(search_timestamp - msc->time_scale, e_old[0].timestamp);
4434  }
4435 
4436  if (find_prev_closest_index(st, e_old, nb_old, tts_data_old, tts_count_old, search_timestamp, 0,
4437  &index, &tts_index_old, &tts_sample_old) < 0) {
4438  av_log(mov->fc, AV_LOG_WARNING,
4439  "st: %d edit list: %"PRId64" Missing key frame while searching for timestamp: %"PRId64"\n",
4440  st->index, edit_list_index, search_timestamp);
4441  if (find_prev_closest_index(st, e_old, nb_old, tts_data_old, tts_count_old, search_timestamp, AVSEEK_FLAG_ANY,
4442  &index, &tts_index_old, &tts_sample_old) < 0) {
4443  av_log(mov->fc, AV_LOG_WARNING,
4444  "st: %d edit list %"PRId64" Cannot find an index entry before timestamp: %"PRId64".\n",
4445  st->index, edit_list_index, search_timestamp);
4446  index = 0;
4447  tts_index_old = 0;
4448  tts_sample_old = 0;
4449  }
4450  }
4451  current = e_old + index;
4452  edit_list_start_tts_sample = tts_sample_old;
4453 
4454  // Iterate over index and arrange it according to edit list
4455  edit_list_start_encountered = 0;
4456  found_keyframe_after_edit = 0;
4457  for (; current < e_old_end; current++, index++) {
4458  // check if frame outside edit list mark it for discard
4459  frame_duration = (current + 1 < e_old_end) ?
4460  ((current + 1)->timestamp - current->timestamp) : edit_list_duration;
4461 
4462  flags = current->flags;
4463 
4464  // frames (pts) before or after edit list
4465  curr_cts = current->timestamp + msc->dts_shift;
4466  curr_ctts = 0;
4467 
4468  if (tts_data_old && tts_index_old < tts_count_old) {
4469  curr_ctts = tts_data_old[tts_index_old].offset;
4470  av_log(mov->fc, AV_LOG_TRACE, "stts: %"PRId64" ctts: %"PRId64", tts_index: %"PRId64", tts_count: %"PRId64"\n",
4471  curr_cts, curr_ctts, tts_index_old, tts_count_old);
4472  curr_cts += curr_ctts;
4473  tts_sample_old++;
4474  if (tts_sample_old == tts_data_old[tts_index_old].count) {
4475  if (add_tts_entry(&msc->tts_data, &msc->tts_count,
4476  &msc->tts_allocated_size,
4477  tts_data_old[tts_index_old].count - edit_list_start_tts_sample,
4478  tts_data_old[tts_index_old].offset, tts_data_old[tts_index_old].duration) == -1) {
4479  av_log(mov->fc, AV_LOG_ERROR, "Cannot add Time To Sample entry %"PRId64" - {%"PRId64", %d}\n",
4480  tts_index_old,
4481  tts_data_old[tts_index_old].count - edit_list_start_tts_sample,
4482  tts_data_old[tts_index_old].offset);
4483  break;
4484  }
4485  tts_index_old++;
4486  tts_sample_old = 0;
4487  edit_list_start_tts_sample = 0;
4488  }
4489  }
4490 
4491  if (curr_cts < edit_list_media_time || curr_cts >= (edit_list_duration + edit_list_media_time)) {
4493  curr_cts < edit_list_media_time && curr_cts + frame_duration > edit_list_media_time &&
4494  first_non_zero_audio_edit > 0) {
4495  packet_skip_samples = edit_list_media_time - curr_cts;
4496  sti->skip_samples += packet_skip_samples;
4497 
4498  // Shift the index entry timestamp by packet_skip_samples to be correct.
4499  edit_list_dts_counter -= packet_skip_samples;
4500  if (edit_list_start_encountered == 0) {
4501  edit_list_start_encountered = 1;
4502  // Make timestamps strictly monotonically increasing for audio, by rewriting timestamps for
4503  // discarded packets.
4504  if (frame_duration_buffer) {
4505  fix_index_entry_timestamps(st, sti->nb_index_entries, edit_list_dts_counter,
4506  frame_duration_buffer, num_discarded_begin);
4507  av_freep(&frame_duration_buffer);
4508  }
4509  }
4510 
4511  av_log(mov->fc, AV_LOG_DEBUG, "skip %d audio samples from curr_cts: %"PRId64"\n", packet_skip_samples, curr_cts);
4512  } else {
4514  av_log(mov->fc, AV_LOG_DEBUG, "drop a frame at curr_cts: %"PRId64" @ %"PRId64"\n", curr_cts, index);
4515 
4516  if (edit_list_start_encountered == 0) {
4517  num_discarded_begin++;
4518  frame_duration_buffer = av_realloc(frame_duration_buffer,
4519  num_discarded_begin * sizeof(int64_t));
4520  if (!frame_duration_buffer) {
4521  av_log(mov->fc, AV_LOG_ERROR, "Cannot reallocate frame duration buffer\n");
4522  break;
4523  }
4524  frame_duration_buffer[num_discarded_begin - 1] = frame_duration;
4525 
4526  // Increment skip_samples for the first non-zero audio edit list
4527  if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
4528  first_non_zero_audio_edit > 0 && st->codecpar->codec_id != AV_CODEC_ID_VORBIS) {
4529  sti->skip_samples += frame_duration;
4530  }
4531  }
4532  }
4533  } else {
4534  if (msc->min_corrected_pts < 0) {
4535  msc->min_corrected_pts = edit_list_dts_counter + curr_ctts + msc->dts_shift;
4536  } else {
4537  msc->min_corrected_pts = FFMIN(msc->min_corrected_pts, edit_list_dts_counter + curr_ctts + msc->dts_shift);
4538  }
4539  if (edit_list_start_encountered == 0) {
4540  edit_list_start_encountered = 1;
4541  // Make timestamps strictly monotonically increasing by rewriting timestamps for
4542  // discarded packets.
4543  if (frame_duration_buffer) {
4544  fix_index_entry_timestamps(st, sti->nb_index_entries, edit_list_dts_counter,
4545  frame_duration_buffer, num_discarded_begin);
4546  av_freep(&frame_duration_buffer);
4547  }
4548  }
4549  }
4550 
4551  if (add_index_entry(st, current->pos, edit_list_dts_counter, current->size,
4552  current->min_distance, flags) == -1) {
4553  av_log(mov->fc, AV_LOG_ERROR, "Cannot add index entry\n");
4554  break;
4555  }
4556 
4557  // Update the index ranges array
4558  if (!current_index_range || index != current_index_range->end) {
4559  current_index_range = current_index_range ? current_index_range + 1
4560  : msc->index_ranges;
4561  current_index_range->start = index;
4562  }
4563  current_index_range->end = index + 1;
4564 
4565  // Only start incrementing DTS in frame_duration amounts, when we encounter a frame in edit list.
4566  if (edit_list_start_encountered > 0) {
4567  edit_list_dts_counter = edit_list_dts_counter + frame_duration;
4568  }
4569 
4570  // Break when found first key frame after edit entry completion
4571  if ((curr_cts + frame_duration >= (edit_list_duration + edit_list_media_time)) &&
4573  if (msc->ctts_count) {
4574  // If we have CTTS and this is the first keyframe after edit elist,
4575  // wait for one more, because there might be trailing B-frames after this I-frame
4576  // that do belong to the edit.
4577  if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO && found_keyframe_after_edit == 0) {
4578  found_keyframe_after_edit = 1;
4579  continue;
4580  }
4581  if (tts_sample_old != 0) {
4582  if (add_tts_entry(&msc->tts_data, &msc->tts_count,
4583  &msc->tts_allocated_size,
4584  tts_sample_old - edit_list_start_tts_sample,
4585  tts_data_old[tts_index_old].offset, tts_data_old[tts_index_old].duration) == -1) {
4586  av_log(mov->fc, AV_LOG_ERROR, "Cannot add Time To Sample entry %"PRId64" - {%"PRId64", %d}\n",
4587  tts_index_old, tts_sample_old - edit_list_start_tts_sample,
4588  tts_data_old[tts_index_old].offset);
4589  break;
4590  }
4591  }
4592  }
4593  break;
4594  }
4595  }
4596  }
4597  // If there are empty edits, then msc->min_corrected_pts might be positive
4598  // intentionally. So we subtract the sum duration of empty edits here.
4599  msc->min_corrected_pts -= empty_edits_sum_duration;
4600 
4601  // If the minimum pts turns out to be greater than zero after fixing the index, then we subtract the
4602  // dts by that amount to make the first pts zero.
4603  if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
4604  if (msc->min_corrected_pts > 0) {
4605  av_log(mov->fc, AV_LOG_DEBUG, "Offset DTS by %"PRId64" to make first pts zero.\n", msc->min_corrected_pts);
4606  for (int i = 0; i < sti->nb_index_entries; ++i)
4608  }
4609  }
4610  // Start time should be equal to zero or the duration of any empty edits.
4611  st->start_time = empty_edits_sum_duration;
4612 
4613  // Update av stream length, if it ends up shorter than the track's media duration
4614  st->duration = FFMIN(st->duration, edit_list_dts_entry_end - start_dts);
4615  msc->start_pad = sti->skip_samples;
4616 
4617  // Free the old index and the old CTTS structures
4618  av_free(e_old);
4619  av_free(tts_data_old);
4620  av_freep(&frame_duration_buffer);
4621 
4622  // Null terminate the index ranges array
4623  current_index_range = current_index_range ? current_index_range + 1
4624  : msc->index_ranges;
4625  current_index_range->start = 0;
4626  current_index_range->end = 0;
4627  msc->current_index = msc->index_ranges[0].start;
4628 }
4629 
4630 static uint32_t get_sgpd_sync_index(const MOVStreamContext *sc, int nal_unit_type)
4631 {
4632  for (uint32_t i = 0; i < sc->sgpd_sync_count; i++)
4633  if (sc->sgpd_sync[i] == nal_unit_type)
4634  return i + 1;
4635  return 0;
4636 }
4637 
4639 {
4640  int k;
4641  int sample_id = 0;
4642  uint32_t cra_index;
4643  MOVStreamContext *sc = st->priv_data;
4644 
4645  if (st->codecpar->codec_id != AV_CODEC_ID_HEVC || !sc->sync_group_count)
4646  return 0;
4647 
4648  /* Build an unrolled index of the samples */
4649  sc->sample_offsets_count = 0;
4650  for (uint32_t i = 0; i < sc->ctts_count; i++) {
4651  if (sc->ctts_data[i].count > INT_MAX - sc->sample_offsets_count)
4652  return AVERROR(ENOMEM);
4653  sc->sample_offsets_count += sc->ctts_data[i].count;
4654  }
4655  av_freep(&sc->sample_offsets);
4657  if (!sc->sample_offsets)
4658  return AVERROR(ENOMEM);
4659  k = 0;
4660  for (uint32_t i = 0; i < sc->ctts_count; i++)
4661  for (int j = 0; j < sc->ctts_data[i].count; j++)
4662  sc->sample_offsets[k++] = sc->ctts_data[i].offset;
4663 
4664  /* The following HEVC NAL type reveal the use of open GOP sync points
4665  * (TODO: BLA types may also be concerned) */
4666  cra_index = get_sgpd_sync_index(sc, HEVC_NAL_CRA_NUT); /* Clean Random Access */
4667  if (!cra_index)
4668  return 0;
4669 
4670  /* Build a list of open-GOP key samples */
4671  sc->open_key_samples_count = 0;
4672  for (uint32_t i = 0; i < sc->sync_group_count; i++)
4673  if (sc->sync_group[i].index == cra_index) {
4674  if (sc->sync_group[i].count > INT_MAX - sc->open_key_samples_count)
4675  return AVERROR(ENOMEM);
4677  }
4678  av_freep(&sc->open_key_samples);
4680  if (!sc->open_key_samples)
4681  return AVERROR(ENOMEM);
4682  k = 0;
4683  for (uint32_t i = 0; i < sc->sync_group_count; i++) {
4684  const MOVSbgp *sg = &sc->sync_group[i];
4685  if (sg->index == cra_index)
4686  for (uint32_t j = 0; j < sg->count; j++)
4687  sc->open_key_samples[k++] = sample_id;
4688  if (sg->count > INT_MAX - sample_id)
4689  return AVERROR_PATCHWELCOME;
4690  sample_id += sg->count;
4691  }
4692 
4693  /* Identify the minimal time step between samples */
4694  sc->min_sample_duration = UINT_MAX;
4695  for (uint32_t i = 0; i < sc->stts_count; i++)
4697 
4698  return 0;
4699 }
4700 
4701 #define MOV_MERGE_CTTS 1
4702 #define MOV_MERGE_STTS 2
4703 /*
4704  * Merge stts and ctts arrays into a new combined array.
4705  * stts_count and ctts_count may be left untouched as they will be
4706  * used to check for the presence of either of them.
4707  */
4708 static int mov_merge_tts_data(MOVContext *mov, AVStream *st, int flags)
4709 {
4710  MOVStreamContext *sc = st->priv_data;
4711  int ctts = sc->ctts_data && (flags & MOV_MERGE_CTTS);
4712  int stts = sc->stts_data && (flags & MOV_MERGE_STTS);
4713  int idx = 0;
4714 
4715  if (!sc->ctts_data && !sc->stts_data)
4716  return 0;
4717  // Expand time to sample entries such that we have a 1-1 mapping with samples
4718  if (!sc->sample_count || sc->sample_count >= UINT_MAX / sizeof(*sc->tts_data))
4719  return -1;
4720 
4721  if (ctts) {
4723  sc->sample_count * sizeof(*sc->tts_data));
4724  if (!sc->tts_data)
4725  return -1;
4726 
4727  memset(sc->tts_data, 0, sc->tts_allocated_size);
4728 
4729  for (int i = 0; i < sc->ctts_count &&
4730  idx < sc->sample_count; i++)
4731  for (int j = 0; j < sc->ctts_data[i].count &&
4732  idx < sc->sample_count; j++) {
4733  sc->tts_data[idx].offset = sc->ctts_data[i].offset;
4734  sc->tts_data[idx++].count = 1;
4735  }
4736 
4737  sc->tts_count = idx;
4738  } else
4739  sc->ctts_count = 0;
4740  av_freep(&sc->ctts_data);
4741  sc->ctts_allocated_size = 0;
4742 
4743  idx = 0;
4744  if (stts) {
4746  sc->sample_count * sizeof(*sc->tts_data));
4747  if (!tts_data)
4748  return -1;
4749 
4750  if (!sc->tts_data)
4751  memset(tts_data, 0, sc->tts_allocated_size);
4752  sc->tts_data = tts_data;
4753 
4754  for (int i = 0; i < sc->stts_count &&
4755  idx < sc->sample_count; i++)
4756  for (int j = 0; j < sc->stts_data[i].count &&
4757  idx < sc->sample_count; j++) {
4758  sc->tts_data[idx].duration = sc->stts_data[i].duration;
4759  sc->tts_data[idx++].count = 1;
4760  }
4761 
4762  sc->tts_count = FFMAX(sc->tts_count, idx);
4763  } else
4764  sc->stts_count = 0;
4765  av_freep(&sc->stts_data);
4766  sc->stts_allocated_size = 0;
4767 
4768  return 0;
4769 }
4770 
4771 static void mov_build_index(MOVContext *mov, AVStream *st)
4772 {
4773  MOVStreamContext *sc = st->priv_data;
4774  FFStream *const sti = ffstream(st);
4775  int64_t current_offset;
4776  int64_t current_dts = 0;
4777  unsigned int stts_index = 0;
4778  unsigned int stsc_index = 0;
4779  unsigned int stss_index = 0;
4780  unsigned int stps_index = 0;
4781  unsigned int i, j;
4782  uint64_t stream_size = 0;
4783 
4784  int ret = build_open_gop_key_points(st);
4785  if (ret < 0)
4786  return;
4787 
4788  if (sc->elst_count) {
4789  int i, edit_start_index = 0, multiple_edits = 0;
4790  int64_t empty_duration = 0; // empty duration of the first edit list entry
4791  int64_t start_time = 0; // start time of the media
4792 
4793  for (i = 0; i < sc->elst_count; i++) {
4794  const MOVElst *e = &sc->elst_data[i];
4795  if (i == 0 && e->time == -1) {
4796  /* if empty, the first entry is the start time of the stream
4797  * relative to the presentation itself */
4798  empty_duration = e->duration;
4799  edit_start_index = 1;
4800  } else if (i == edit_start_index && e->time >= 0) {
4801  start_time = e->time;
4802  } else {
4803  multiple_edits = 1;
4804  }
4805  }
4806 
4807  if (multiple_edits && !mov->advanced_editlist) {
4809  av_log(mov->fc, AV_LOG_WARNING, "multiple edit list entries, "
4810  "not supported in fragmented MP4 files\n");
4811  else
4812  av_log(mov->fc, AV_LOG_WARNING, "multiple edit list entries, "
4813  "Use -advanced_editlist to correctly decode otherwise "
4814  "a/v desync might occur\n");
4815  }
4816 
4817  /* adjust first dts according to edit list */
4818  if ((empty_duration || start_time) && mov->time_scale > 0) {
4819  if (empty_duration)
4820  empty_duration = av_rescale(empty_duration, sc->time_scale, mov->time_scale);
4821 
4822  if (av_sat_sub64(start_time, empty_duration) != start_time - (uint64_t)empty_duration)
4823  av_log(mov->fc, AV_LOG_WARNING, "start_time - empty_duration is not representable\n");
4824 
4825  sc->time_offset = start_time - (uint64_t)empty_duration;
4827  if (!mov->advanced_editlist)
4828  current_dts = -sc->time_offset;
4829  }
4830 
4831  if (!multiple_edits && !mov->advanced_editlist &&
4834  (AVRational){1, st->codecpar->sample_rate});
4835  }
4836 
4837  /* only use old uncompressed audio chunk demuxing when stts specifies it */
4838  if (!(st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
4839  sc->stts_count == 1 && sc->stts_data && sc->stts_data[0].duration == 1)) {
4840  unsigned int current_sample = 0;
4841  unsigned int stts_sample = 0;
4842  unsigned int sample_size;
4843  unsigned int distance = 0;
4844  unsigned int rap_group_index = 0;
4845  unsigned int rap_group_sample = 0;
4846  int rap_group_present = sc->rap_group_count && sc->rap_group;
4847  int key_off = (sc->keyframe_count && sc->keyframes[0] > 0) || (sc->stps_count && sc->stps_data[0] > 0);
4848 
4849  current_dts -= sc->dts_shift;
4850 
4851  if (!sc->sample_count || sti->nb_index_entries || sc->tts_count)
4852  return;
4853  if (sc->sample_count >= UINT_MAX / sizeof(*sti->index_entries) - sti->nb_index_entries)
4854  return;
4855  if (av_reallocp_array(&sti->index_entries,
4856  sti->nb_index_entries + sc->sample_count,
4857  sizeof(*sti->index_entries)) < 0) {
4858  sti->nb_index_entries = 0;
4859  return;
4860  }
4861  sti->index_entries_allocated_size = (sti->nb_index_entries + sc->sample_count) * sizeof(*sti->index_entries);
4862 
4864  if (ret < 0)
4865  return;
4866 
4867  for (i = 0; i < sc->chunk_count; i++) {
4868  int64_t next_offset = i+1 < sc->chunk_count ? sc->chunk_offsets[i+1] : INT64_MAX;
4869  current_offset = sc->chunk_offsets[i];
4870  while (mov_stsc_index_valid(stsc_index, sc->stsc_count) &&
4871  i + 1 == sc->stsc_data[stsc_index + 1].first)
4872  stsc_index++;
4873 
4874  if (next_offset > current_offset && sc->sample_size>0 && sc->sample_size < sc->stsz_sample_size &&
4875  sc->stsc_data[stsc_index].count * (int64_t)sc->stsz_sample_size > next_offset - current_offset) {
4876  av_log(mov->fc, AV_LOG_WARNING, "STSZ sample size %d invalid (too large), ignoring\n", sc->stsz_sample_size);
4877  sc->stsz_sample_size = sc->sample_size;
4878  }
4879  if (sc->stsz_sample_size>0 && sc->stsz_sample_size < sc->sample_size) {
4880  av_log(mov->fc, AV_LOG_WARNING, "STSZ sample size %d invalid (too small), ignoring\n", sc->stsz_sample_size);
4881  sc->stsz_sample_size = sc->sample_size;
4882  }
4883 
4884  for (j = 0; j < sc->stsc_data[stsc_index].count; j++) {
4885  int keyframe = 0;
4886  if (current_sample >= sc->sample_count) {
4887  av_log(mov->fc, AV_LOG_ERROR, "wrong sample count\n");
4888  return;
4889  }
4890 
4891  if (!sc->keyframe_absent && (!sc->keyframe_count || current_sample+key_off == sc->keyframes[stss_index])) {
4892  keyframe = 1;
4893  if (stss_index + 1 < sc->keyframe_count)
4894  stss_index++;
4895  } else if (sc->stps_count && current_sample+key_off == sc->stps_data[stps_index]) {
4896  keyframe = 1;
4897  if (stps_index + 1 < sc->stps_count)
4898  stps_index++;
4899  }
4900  if (rap_group_present && rap_group_index < sc->rap_group_count) {
4901  if (sc->rap_group[rap_group_index].index > 0)
4902  keyframe = 1;
4903  if (++rap_group_sample == sc->rap_group[rap_group_index].count) {
4904  rap_group_sample = 0;
4905  rap_group_index++;
4906  }
4907  }
4908  if (sc->keyframe_absent
4909  && !sc->stps_count
4910  && !rap_group_present
4911  && (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO || (i==0 && j==0)))
4912  keyframe = 1;
4913  if (keyframe)
4914  distance = 0;
4915  sample_size = sc->stsz_sample_size > 0 ? sc->stsz_sample_size : sc->sample_sizes[current_sample];
4916  if (current_offset > INT64_MAX - sample_size) {
4917  av_log(mov->fc, AV_LOG_ERROR, "Current offset %"PRId64" or sample size %u is too large\n",
4918  current_offset,
4919  sample_size);
4920  return;
4921  }
4922 
4923  if (sc->pseudo_stream_id == -1 ||
4924  sc->stsc_data[stsc_index].id - 1 == sc->pseudo_stream_id) {
4925  AVIndexEntry *e;
4926  if (sample_size > 0x3FFFFFFF) {
4927  av_log(mov->fc, AV_LOG_ERROR, "Sample size %u is too large\n", sample_size);
4928  return;
4929  }
4930  e = &sti->index_entries[sti->nb_index_entries++];
4931  e->pos = current_offset;
4932  e->timestamp = current_dts;
4933  e->size = sample_size;
4934  e->min_distance = distance;
4935  e->flags = keyframe ? AVINDEX_KEYFRAME : 0;
4936  av_log(mov->fc, AV_LOG_TRACE, "AVIndex stream %d, sample %u, offset %"PRIx64", dts %"PRId64", "
4937  "size %u, distance %u, keyframe %d\n", st->index, current_sample,
4938  current_offset, current_dts, sample_size, distance, keyframe);
4939  if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && sti->nb_index_entries < 100)
4940  ff_rfps_add_frame(mov->fc, st, current_dts);
4941  }
4942 
4943  current_offset += sample_size;
4944  stream_size += sample_size;
4945 
4946  current_dts += sc->tts_data[stts_index].duration;
4947 
4948  distance++;
4949  stts_sample++;
4950  current_sample++;
4951  if (stts_index + 1 < sc->tts_count && stts_sample == sc->tts_data[stts_index].count) {
4952  stts_sample = 0;
4953  stts_index++;
4954  }
4955  }
4956  }
4957  if (st->duration > 0)
4958  st->codecpar->bit_rate = stream_size*8*sc->time_scale/st->duration;
4959  } else {
4960  unsigned chunk_samples, total = 0;
4961 
4962  if (!sc->chunk_count || sc->tts_count)
4963  return;
4964 
4965  // compute total chunk count
4966  for (i = 0; i < sc->stsc_count; i++) {
4967  unsigned count, chunk_count;
4968 
4969  chunk_samples = sc->stsc_data[i].count;
4970  if (i != sc->stsc_count - 1 &&
4971  sc->samples_per_frame && chunk_samples % sc->samples_per_frame) {
4972  av_log(mov->fc, AV_LOG_ERROR, "error unaligned chunk\n");
4973  return;
4974  }
4975 
4976  if (sc->samples_per_frame >= 160) { // gsm
4977  count = chunk_samples / sc->samples_per_frame;
4978  } else if (sc->samples_per_frame > 1) {
4979  unsigned samples = (1024/sc->samples_per_frame)*sc->samples_per_frame;
4980  count = (chunk_samples+samples-1) / samples;
4981  } else {
4982  count = (chunk_samples+1023) / 1024;
4983  }
4984 
4985  if (mov_stsc_index_valid(i, sc->stsc_count))
4986  chunk_count = sc->stsc_data[i+1].first - sc->stsc_data[i].first;
4987  else
4988  chunk_count = sc->chunk_count - (sc->stsc_data[i].first - 1);
4989  total += chunk_count * count;
4990  }
4991 
4992  av_log(mov->fc, AV_LOG_TRACE, "chunk count %u\n", total);
4993  if (total >= UINT_MAX / sizeof(*sti->index_entries) - sti->nb_index_entries)
4994  return;
4995  if (av_reallocp_array(&sti->index_entries,
4996  sti->nb_index_entries + total,
4997  sizeof(*sti->index_entries)) < 0) {
4998  sti->nb_index_entries = 0;
4999  return;
5000  }
5001  sti->index_entries_allocated_size = (sti->nb_index_entries + total) * sizeof(*sti->index_entries);
5002 
5003  // populate index
5004  for (i = 0; i < sc->chunk_count; i++) {
5005  current_offset = sc->chunk_offsets[i];
5006  if (mov_stsc_index_valid(stsc_index, sc->stsc_count) &&
5007  i + 1 == sc->stsc_data[stsc_index + 1].first)
5008  stsc_index++;
5009  chunk_samples = sc->stsc_data[stsc_index].count;
5010 
5011  while (chunk_samples > 0) {
5012  AVIndexEntry *e;
5013  unsigned size, samples;
5014 
5015  if (sc->samples_per_frame > 1 && !sc->bytes_per_frame) {
5017  "Zero bytes per frame, but %d samples per frame",
5018  sc->samples_per_frame);
5019  return;
5020  }
5021 
5022  if (sc->samples_per_frame >= 160) { // gsm
5023  samples = sc->samples_per_frame;
5024  size = sc->bytes_per_frame;
5025  } else {
5026  if (sc->samples_per_frame > 1) {
5027  samples = FFMIN((1024 / sc->samples_per_frame)*
5028  sc->samples_per_frame, chunk_samples);
5030  } else {
5031  samples = FFMIN(1024, chunk_samples);
5032  size = samples * sc->sample_size;
5033  }
5034  }
5035 
5036  if (sti->nb_index_entries >= total) {
5037  av_log(mov->fc, AV_LOG_ERROR, "wrong chunk count %u\n", total);
5038  return;
5039  }
5040  if (size > 0x3FFFFFFF) {
5041  av_log(mov->fc, AV_LOG_ERROR, "Sample size %u is too large\n", size);
5042  return;
5043  }
5044  e = &sti->index_entries[sti->nb_index_entries++];
5045  e->pos = current_offset;
5046  e->timestamp = current_dts;
5047  e->size = size;
5048  e->min_distance = 0;
5049  e->flags = AVINDEX_KEYFRAME;
5050  av_log(mov->fc, AV_LOG_TRACE, "AVIndex stream %d, chunk %u, offset %"PRIx64", dts %"PRId64", "
5051  "size %u, duration %u\n", st->index, i, current_offset, current_dts,
5052  size, samples);
5053 
5054  current_offset += size;
5055  current_dts += samples;
5056  chunk_samples -= samples;
5057  }
5058  }
5059 
5061  if (ret < 0)
5062  return;
5063  }
5064 
5065  if (!mov->ignore_editlist && mov->advanced_editlist) {
5066  // Fix index according to edit lists.
5067  mov_fix_index(mov, st);
5068  }
5069 
5070  // Update start time of the stream.
5072  st->start_time = sti->index_entries[0].timestamp + sc->dts_shift;
5073  if (sc->tts_data) {
5074  st->start_time += sc->tts_data[0].offset;
5075  }
5076  }
5077 
5078  mov_estimate_video_delay(mov, st);
5079 }
5080 
5081 static int test_same_origin(const char *src, const char *ref) {
5082  char src_proto[64];
5083  char ref_proto[64];
5084  char src_auth[256];
5085  char ref_auth[256];
5086  char src_host[256];
5087  char ref_host[256];
5088  int src_port=-1;
5089  int ref_port=-1;
5090 
5091  av_url_split(src_proto, sizeof(src_proto), src_auth, sizeof(src_auth), src_host, sizeof(src_host), &src_port, NULL, 0, src);
5092  av_url_split(ref_proto, sizeof(ref_proto), ref_auth, sizeof(ref_auth), ref_host, sizeof(ref_host), &ref_port, NULL, 0, ref);
5093 
5094  if (strlen(src) == 0) {
5095  return -1;
5096  } else if (strlen(src_auth) + 1 >= sizeof(src_auth) ||
5097  strlen(ref_auth) + 1 >= sizeof(ref_auth) ||
5098  strlen(src_host) + 1 >= sizeof(src_host) ||
5099  strlen(ref_host) + 1 >= sizeof(ref_host)) {
5100  return 0;
5101  } else if (strcmp(src_proto, ref_proto) ||
5102  strcmp(src_auth, ref_auth) ||
5103  strcmp(src_host, ref_host) ||
5104  src_port != ref_port) {
5105  return 0;
5106  } else
5107  return 1;
5108 }
5109 
5110 static int mov_open_dref(MOVContext *c, AVIOContext **pb, const char *src, MOVDref *ref)
5111 {
5112  /* try relative path, we do not try the absolute because it can leak information about our
5113  system to an attacker */
5114  if (ref->nlvl_to > 0 && ref->nlvl_from > 0) {
5115  char filename[1025];
5116  const char *src_path;
5117  int i, l;
5118 
5119  /* find a source dir */
5120  src_path = strrchr(src, '/');
5121  if (src_path)
5122  src_path++;
5123  else
5124  src_path = src;
5125 
5126  /* find a next level down to target */
5127  for (i = 0, l = strlen(ref->path) - 1; l >= 0; l--)
5128  if (ref->path[l] == '/') {
5129  if (i == ref->nlvl_to - 1)
5130  break;
5131  else
5132  i++;
5133  }
5134 
5135  /* compose filename if next level down to target was found */
5136  if (i == ref->nlvl_to - 1 && src_path - src < sizeof(filename)) {
5137  memcpy(filename, src, src_path - src);
5138  filename[src_path - src] = 0;
5139 
5140  for (i = 1; i < ref->nlvl_from; i++)
5141  av_strlcat(filename, "../", sizeof(filename));
5142 
5143  av_strlcat(filename, ref->path + l + 1, sizeof(filename));
5144  if (!c->use_absolute_path) {
5145  int same_origin = test_same_origin(src, filename);
5146 
5147  if (!same_origin) {
5148  av_log(c->fc, AV_LOG_ERROR,
5149  "Reference with mismatching origin, %s not tried for security reasons, "
5150  "set demuxer option use_absolute_path to allow it anyway\n",
5151  ref->path);
5152  return AVERROR(ENOENT);
5153  }
5154 
5155  if (strstr(ref->path + l + 1, "..") ||
5156  strstr(ref->path + l + 1, ":") ||
5157  (ref->nlvl_from > 1 && same_origin < 0) ||
5158  (filename[0] == '/' && src_path == src))
5159  return AVERROR(ENOENT);
5160  }
5161 
5162  if (strlen(filename) + 1 == sizeof(filename))
5163  return AVERROR(ENOENT);
5164  if (!c->fc->io_open(c->fc, pb, filename, AVIO_FLAG_READ, NULL))
5165  return 0;
5166  }
5167  } else if (c->use_absolute_path) {
5168  av_log(c->fc, AV_LOG_WARNING, "Using absolute path on user request, "
5169  "this is a possible security issue\n");
5170  if (!c->fc->io_open(c->fc, pb, ref->path, AVIO_FLAG_READ, NULL))
5171  return 0;
5172  } else {
5173  av_log(c->fc, AV_LOG_ERROR,
5174  "Absolute path %s not tried for security reasons, "
5175  "set demuxer option use_absolute_path to allow absolute paths\n",
5176  ref->path);
5177  }
5178 
5179  return AVERROR(ENOENT);
5180 }
5181 
5183 {
5184  if (sc->time_scale <= 0) {
5185  av_log(c->fc, AV_LOG_WARNING, "stream %d, timescale not set\n", sc->ffindex);
5186  sc->time_scale = c->time_scale;
5187  if (sc->time_scale <= 0)
5188  sc->time_scale = 1;
5189  }
5190 }
5191 
5192 #if CONFIG_IAMFDEC
5193 static int mov_update_iamf_streams(MOVContext *c, const AVStream *st)
5194 {
5195  const MOVStreamContext *sc = st->priv_data;
5196  const IAMFContext *iamf = &sc->iamf->iamf;
5197 
5198  for (int i = 0; i < iamf->nb_audio_elements; i++) {
5199  const AVStreamGroup *stg = NULL;
5200 
5201  for (int j = 0; j < c->fc->nb_stream_groups; j++)
5202  if (c->fc->stream_groups[j]->id == iamf->audio_elements[i]->audio_element_id)
5203  stg = c->fc->stream_groups[j];
5204  av_assert0(stg);
5205 
5206  for (int j = 0; j < stg->nb_streams; j++) {
5207  const FFStream *sti = cffstream(st);
5208  AVStream *out = stg->streams[j];
5209  FFStream *out_sti = ffstream(stg->streams[j]);
5210 
5211  out->codecpar->bit_rate = 0;
5212 
5213  if (out == st)
5214  continue;
5215 
5216  out->time_base = st->time_base;
5217  out->start_time = st->start_time;
5218  out->duration = st->duration;
5219  out->nb_frames = st->nb_frames;
5220  out->discard = st->discard;
5221 
5222  av_assert0(!out_sti->index_entries);
5224  if (!out_sti->index_entries)
5225  return AVERROR(ENOMEM);
5226 
5228  out_sti->nb_index_entries = sti->nb_index_entries;
5229  out_sti->skip_samples = sti->skip_samples;
5230  memcpy(out_sti->index_entries, sti->index_entries, sti->index_entries_allocated_size);
5231  }
5232  }
5233 
5234  return 0;
5235 }
5236 #endif
5237 
5238 static int sanity_checks(void *log_obj, MOVStreamContext *sc, int index)
5239 {
5240  if ((sc->chunk_count && (!sc->stts_count || !sc->stsc_count ||
5241  (!sc->sample_size && !sc->sample_count))) ||
5242  (sc->sample_count && (!sc->chunk_count ||
5243  (!sc->sample_size && !sc->sample_sizes)))) {
5244  av_log(log_obj, AV_LOG_ERROR, "stream %d, missing mandatory atoms, broken header\n",
5245  index);
5246  return 1;
5247  }
5248 
5249  if (sc->stsc_count && sc->stsc_data[ sc->stsc_count - 1 ].first > sc->chunk_count) {
5250  av_log(log_obj, AV_LOG_ERROR, "stream %d, contradictionary STSC and STCO\n",
5251  index);
5252  return 2;
5253  }
5254  return 0;
5255 }
5256 
5258 {
5259  AVStream *st;
5260  MOVStreamContext *sc;
5261  int ret;
5262 
5263  st = avformat_new_stream(c->fc, NULL);
5264  if (!st) return AVERROR(ENOMEM);
5265  st->id = -1;
5266  sc = av_mallocz(sizeof(MOVStreamContext));
5267  if (!sc) return AVERROR(ENOMEM);
5268 
5269  st->priv_data = sc;
5271  sc->ffindex = st->index;
5272  c->trak_index = st->index;
5273  sc->refcount = 1;
5274 
5275  if ((ret = mov_read_default(c, pb, atom)) < 0)
5276  return ret;
5277 
5278  c->trak_index = -1;
5279 
5280  // Here stsc refers to a chunk not described in stco. This is technically invalid,
5281  // but we can overlook it (clearing stsc) whenever stts_count == 0 (indicating no samples).
5282  if (!sc->chunk_count && !sc->stts_count && sc->stsc_count) {
5283  sc->stsc_count = 0;
5284  av_freep(&sc->stsc_data);
5285  }
5286 
5287  ret = sanity_checks(c->fc, sc, st->index);
5288  if (ret)
5289  return ret > 1 ? AVERROR_INVALIDDATA : 0;
5290 
5291  fix_timescale(c, sc);
5292 
5293  avpriv_set_pts_info(st, 64, 1, sc->time_scale);
5294 
5295  /*
5296  * Advanced edit list support does not work with fragemented MP4s, which
5297  * have stsc, stsz, stco, and stts with zero entries in the moov atom.
5298  * In these files, trun atoms may be streamed in.
5299  */
5300  if (!sc->stts_count && c->advanced_editlist) {
5301 
5302  av_log(c->fc, AV_LOG_VERBOSE, "advanced_editlist does not work with fragmented "
5303  "MP4. disabling.\n");
5304  c->advanced_editlist = 0;
5305  c->advanced_editlist_autodisabled = 1;
5306  }
5307 
5308  mov_build_index(c, st);
5309 
5310 #if CONFIG_IAMFDEC
5311  if (sc->iamf) {
5312  ret = mov_update_iamf_streams(c, st);
5313  if (ret < 0)
5314  return ret;
5315  }
5316 #endif
5317 
5318  if (sc->dref_id-1 < sc->drefs_count && sc->drefs[sc->dref_id-1].path) {
5319  MOVDref *dref = &sc->drefs[sc->dref_id - 1];
5320  if (c->enable_drefs) {
5321  if (mov_open_dref(c, &sc->pb, c->fc->url, dref) < 0)
5322  av_log(c->fc, AV_LOG_ERROR,
5323  "stream %d, error opening alias: path='%s', dir='%s', "
5324  "filename='%s', volume='%s', nlvl_from=%d, nlvl_to=%d\n",
5325  st->index, dref->path, dref->dir, dref->filename,
5326  dref->volume, dref->nlvl_from, dref->nlvl_to);
5327  } else {
5328  av_log(c->fc, AV_LOG_WARNING,
5329  "Skipped opening external track: "
5330  "stream %d, alias: path='%s', dir='%s', "
5331  "filename='%s', volume='%s', nlvl_from=%d, nlvl_to=%d."
5332  "Set enable_drefs to allow this.\n",
5333  st->index, dref->path, dref->dir, dref->filename,
5334  dref->volume, dref->nlvl_from, dref->nlvl_to);
5335  }
5336  } else {
5337  sc->pb = c->fc->pb;
5338  sc->pb_is_copied = 1;
5339  }
5340 
5341  if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
5342  int stts_constant = sc->stts_count && sc->tts_count;
5343  if (sc->h_spacing && sc->v_spacing)
5345  sc->h_spacing, sc->v_spacing, INT_MAX);
5346  if (!st->sample_aspect_ratio.num && st->codecpar->width && st->codecpar->height &&
5347  sc->height && sc->width &&
5348  (st->codecpar->width != sc->width || st->codecpar->height != sc->height)) {
5350  (int64_t)st->codecpar->height * sc->width,
5351  (int64_t)st->codecpar->width * sc->height, INT_MAX);
5352  }
5353 
5354 #if FF_API_R_FRAME_RATE
5355  for (unsigned int i = 1; sc->stts_count && i + 1 < sc->tts_count; i++) {
5356  if (sc->tts_data[i].duration == sc->tts_data[0].duration)
5357  continue;
5358  stts_constant = 0;
5359  }
5360  if (stts_constant)
5362  sc->time_scale, sc->tts_data[0].duration, INT_MAX);
5363 #endif
5364  }
5365 
5366 #if CONFIG_H261_DECODER || CONFIG_H263_DECODER || CONFIG_MPEG4_DECODER
5367  switch (st->codecpar->codec_id) {
5368 #if CONFIG_H261_DECODER
5369  case AV_CODEC_ID_H261:
5370 #endif
5371 #if CONFIG_H263_DECODER
5372  case AV_CODEC_ID_H263:
5373 #endif
5374 #if CONFIG_MPEG4_DECODER
5375  case AV_CODEC_ID_MPEG4:
5376 #endif
5377  st->codecpar->width = 0; /* let decoder init width/height */
5378  st->codecpar->height= 0;
5379  break;
5380  }
5381 #endif
5382 
5383  // If the duration of the mp3 packets is not constant, then they could need a parser
5384  if (st->codecpar->codec_id == AV_CODEC_ID_MP3
5385  && sc->time_scale == st->codecpar->sample_rate) {
5386  int stts_constant = 1;
5387  for (int i = 1; sc->stts_count && i < sc->tts_count; i++) {
5388  if (sc->tts_data[i].duration == sc->tts_data[0].duration)
5389  continue;
5390  stts_constant = 0;
5391  }
5392  if (!stts_constant)
5394  }
5395  /* Do not need those anymore. */
5396  av_freep(&sc->chunk_offsets);
5397  av_freep(&sc->sample_sizes);
5398  av_freep(&sc->keyframes);
5399  av_freep(&sc->stps_data);
5400  av_freep(&sc->elst_data);
5401  av_freep(&sc->rap_group);
5402  av_freep(&sc->sync_group);
5403  av_freep(&sc->sgpd_sync);
5404 
5405  return 0;
5406 }
5407 
5409 {
5410  int ret;
5411  c->itunes_metadata = 1;
5412  ret = mov_read_default(c, pb, atom);
5413  c->itunes_metadata = 0;
5414  return ret;
5415 }
5416 
5418 {
5419  uint32_t count;
5420  uint32_t i;
5421 
5422  if (atom.size < 8)
5423  return 0;
5424 
5425  avio_skip(pb, 4);
5426  count = avio_rb32(pb);
5427  atom.size -= 8;
5428  if (count >= UINT_MAX / sizeof(*c->meta_keys)) {
5429  av_log(c->fc, AV_LOG_ERROR,
5430  "The 'keys' atom with the invalid key count: %"PRIu32"\n", count);
5431  return AVERROR_INVALIDDATA;
5432  }
5433 
5434  c->meta_keys_count = count + 1;
5435  c->meta_keys = av_mallocz(c->meta_keys_count * sizeof(*c->meta_keys));
5436  if (!c->meta_keys)
5437  return AVERROR(ENOMEM);
5438 
5439  for (i = 1; i <= count; ++i) {
5440  uint32_t key_size = avio_rb32(pb);
5441  uint32_t type = avio_rl32(pb);
5442  if (key_size < 8 || key_size > atom.size) {
5443  av_log(c->fc, AV_LOG_ERROR,
5444  "The key# %"PRIu32" in meta has invalid size:"
5445  "%"PRIu32"\n", i, key_size);
5446  return AVERROR_INVALIDDATA;
5447  }
5448  atom.size -= key_size;
5449  key_size -= 8;
5450  if (type != MKTAG('m','d','t','a')) {
5451  avio_skip(pb, key_size);
5452  continue;
5453  }
5454  c->meta_keys[i] = av_mallocz(key_size + 1);
5455  if (!c->meta_keys[i])
5456  return AVERROR(ENOMEM);
5457  avio_read(pb, c->meta_keys[i], key_size);
5458  }
5459 
5460  return 0;
5461 }
5462 
5464 {
5465  int64_t end = av_sat_add64(avio_tell(pb), atom.size);
5466  uint8_t *key = NULL, *val = NULL, *mean = NULL;
5467  int i;
5468  int ret = 0;
5469  AVStream *st;
5470  MOVStreamContext *sc;
5471 
5472  if (c->fc->nb_streams < 1)
5473  return 0;
5474  st = c->fc->streams[c->fc->nb_streams-1];
5475  sc = st->priv_data;
5476 
5477  for (i = 0; i < 3; i++) {
5478  uint8_t **p;
5479  uint32_t len, tag;
5480 
5481  if (end - avio_tell(pb) <= 12)
5482  break;
5483 
5484  len = avio_rb32(pb);
5485  tag = avio_rl32(pb);
5486  avio_skip(pb, 4); // flags
5487 
5488  if (len < 12 || len - 12 > end - avio_tell(pb))
5489  break;
5490  len -= 12;
5491 
5492  if (tag == MKTAG('m', 'e', 'a', 'n'))
5493  p = &mean;
5494  else if (tag == MKTAG('n', 'a', 'm', 'e'))
5495  p = &key;
5496  else if (tag == MKTAG('d', 'a', 't', 'a') && len > 4) {
5497  avio_skip(pb, 4);
5498  len -= 4;
5499  p = &val;
5500  } else
5501  break;
5502 
5503  if (*p)
5504  break;
5505 
5506  *p = av_malloc(len + 1);
5507  if (!*p) {
5508  ret = AVERROR(ENOMEM);
5509  break;
5510  }
5511  ret = ffio_read_size(pb, *p, len);
5512  if (ret < 0) {
5513  av_freep(p);
5514  break;
5515  }
5516  (*p)[len] = 0;
5517  }
5518 
5519  if (mean && key && val) {
5520  if (strcmp(key, "iTunSMPB") == 0) {
5521  int priming, remainder, samples;
5522  if(sscanf(val, "%*X %X %X %X", &priming, &remainder, &samples) == 3){
5523  if(priming>0 && priming<16384)
5524  sc->start_pad = priming;
5525  }
5526  }
5527  if (strcmp(mean, "com.apple.iTunes") == 0 &&
5528  strcmp(key, "DISCSUBTITLE") == 0) {
5529  av_dict_set(&c->fc->metadata, "disc_subtitle", val,
5531  val = NULL;
5532  }
5533  if (strcmp(key, "cdec") != 0) {
5534  av_dict_set(&c->fc->metadata, key, val,
5536  key = val = NULL;
5537  }
5538  } else {
5539  av_log(c->fc, AV_LOG_VERBOSE,
5540  "Unhandled or malformed custom metadata of size %"PRId64"\n", atom.size);
5541  }
5542 
5543  avio_seek(pb, end, SEEK_SET);
5544  av_freep(&key);
5545  av_freep(&val);
5546  av_freep(&mean);
5547  return ret;
5548 }
5549 
5551 {
5552  MOVStreamContext *sc;
5553  AVStream *st;
5554 
5555  st = avformat_new_stream(c->fc, NULL);
5556  if (!st)
5557  return AVERROR(ENOMEM);
5558  sc = av_mallocz(sizeof(MOVStreamContext));
5559  if (!sc)
5560  goto fail;
5561 
5562  item->st = st;
5563  st->id = item->item_id;
5564  st->priv_data = sc;
5566  st->codecpar->codec_id = mov_codec_id(st, item->type);
5567  sc->id = st->id;
5568  sc->ffindex = st->index;
5569  st->avg_frame_rate.num = st->avg_frame_rate.den = 1;
5570  st->time_base.num = st->time_base.den = 1;
5571  st->nb_frames = 1;
5572  sc->time_scale = 1;
5573  sc->pb = c->fc->pb;
5574  sc->pb_is_copied = 1;
5575  sc->refcount = 1;
5576 
5577  if (item->name)
5578  av_dict_set(&st->metadata, "title", item->name, 0);
5579 
5580  // Populate the necessary fields used by mov_build_index.
5581  sc->stsc_data = av_malloc_array(1, sizeof(*sc->stsc_data));
5582  if (!sc->stsc_data)
5583  goto fail;
5584  sc->stsc_count = 1;
5585  sc->stsc_data[0].first = 1;
5586  sc->stsc_data[0].count = 1;
5587  sc->stsc_data[0].id = 1;
5588  sc->chunk_offsets = av_malloc_array(1, sizeof(*sc->chunk_offsets));
5589  if (!sc->chunk_offsets)
5590  goto fail;
5591  sc->chunk_count = 1;
5592  sc->stts_data = av_malloc_array(1, sizeof(*sc->stts_data));
5593  if (!sc->stts_data)
5594  goto fail;
5595  sc->stts_count = 1;
5596  sc->stts_data[0].count = 1;
5597  // Not used for still images. But needed by mov_build_index.
5598  sc->stts_data[0].duration = 0;
5599 
5600  return 0;
5601 fail:
5602  mov_free_stream_context(c->fc, st);
5603  ff_remove_stream(c->fc, st);
5604  item->st = NULL;
5605 
5606  return AVERROR(ENOMEM);
5607 }
5608 
5610 {
5611  while (atom.size > 8) {
5612  uint32_t tag;
5613  if (avio_feof(pb))
5614  return AVERROR_EOF;
5615  tag = avio_rl32(pb);
5616  atom.size -= 4;
5617  if (tag == MKTAG('h','d','l','r')) {
5618  avio_seek(pb, -8, SEEK_CUR);
5619  atom.size += 8;
5620  return mov_read_default(c, pb, atom);
5621  }
5622  }
5623  return 0;
5624 }
5625 
5626 // return 1 when matrix is identity, 0 otherwise
5627 #define IS_MATRIX_IDENT(matrix) \
5628  ( (matrix)[0][0] == (1 << 16) && \
5629  (matrix)[1][1] == (1 << 16) && \
5630  (matrix)[2][2] == (1 << 30) && \
5631  !(matrix)[0][1] && !(matrix)[0][2] && \
5632  !(matrix)[1][0] && !(matrix)[1][2] && \
5633  !(matrix)[2][0] && !(matrix)[2][1])
5634 
5636 {
5637  int i, j, e;
5638  int width;
5639  int height;
5640  int display_matrix[3][3];
5641  int res_display_matrix[3][3] = { { 0 } };
5642  AVStream *st;
5643  MOVStreamContext *sc;
5644  int version;
5645  int flags;
5646 
5647  if (c->fc->nb_streams < 1)
5648  return 0;
5649  st = c->fc->streams[c->fc->nb_streams-1];
5650  sc = st->priv_data;
5651 
5652  // Each stream (trak) should have exactly 1 tkhd. This catches bad files and
5653  // avoids corrupting AVStreams mapped to an earlier tkhd.
5654  if (st->id != -1)
5655  return AVERROR_INVALIDDATA;
5656 
5657  version = avio_r8(pb);
5658  flags = avio_rb24(pb);
5660 
5661  if (version == 1) {
5662  avio_rb64(pb);
5663  avio_rb64(pb);
5664  } else {
5665  avio_rb32(pb); /* creation time */
5666  avio_rb32(pb); /* modification time */
5667  }
5668  st->id = (int)avio_rb32(pb); /* track id (NOT 0 !)*/
5669  sc->id = st->id;
5670  avio_rb32(pb); /* reserved */
5671 
5672  /* highlevel (considering edits) duration in movie timebase */
5673  (version == 1) ? avio_rb64(pb) : avio_rb32(pb);
5674  avio_rb32(pb); /* reserved */
5675  avio_rb32(pb); /* reserved */
5676 
5677  avio_rb16(pb); /* layer */
5678  avio_rb16(pb); /* alternate group */
5679  avio_rb16(pb); /* volume */
5680  avio_rb16(pb); /* reserved */
5681 
5682  //read in the display matrix (outlined in ISO 14496-12, Section 6.2.2)
5683  // they're kept in fixed point format through all calculations
5684  // save u,v,z to store the whole matrix in the AV_PKT_DATA_DISPLAYMATRIX
5685  // side data, but the scale factor is not needed to calculate aspect ratio
5686  for (i = 0; i < 3; i++) {
5687  display_matrix[i][0] = avio_rb32(pb); // 16.16 fixed point
5688  display_matrix[i][1] = avio_rb32(pb); // 16.16 fixed point
5689  display_matrix[i][2] = avio_rb32(pb); // 2.30 fixed point
5690  }
5691 
5692  width = avio_rb32(pb); // 16.16 fixed point track width
5693  height = avio_rb32(pb); // 16.16 fixed point track height
5694  sc->width = width >> 16;
5695  sc->height = height >> 16;
5696 
5697  // apply the moov display matrix (after the tkhd one)
5698  for (i = 0; i < 3; i++) {
5699  const int sh[3] = { 16, 16, 30 };
5700  for (j = 0; j < 3; j++) {
5701  for (e = 0; e < 3; e++) {
5702  res_display_matrix[i][j] +=
5703  ((int64_t) display_matrix[i][e] *
5704  c->movie_display_matrix[e][j]) >> sh[e];
5705  }
5706  }
5707  }
5708 
5709  // save the matrix when it is not the default identity
5710  if (!IS_MATRIX_IDENT(res_display_matrix)) {
5711  av_freep(&sc->display_matrix);
5712  sc->display_matrix = av_malloc(sizeof(int32_t) * 9);
5713  if (!sc->display_matrix)
5714  return AVERROR(ENOMEM);
5715 
5716  for (i = 0; i < 3; i++)
5717  for (j = 0; j < 3; j++)
5718  sc->display_matrix[i * 3 + j] = res_display_matrix[i][j];
5719  }
5720 
5721  // transform the display width/height according to the matrix
5722  // to keep the same scale, use [width height 1<<16]
5723  if (width && height && sc->display_matrix) {
5724  double disp_transform[2];
5725 
5726  for (i = 0; i < 2; i++)
5727  disp_transform[i] = hypot(sc->display_matrix[0 + i],
5728  sc->display_matrix[3 + i]);
5729 
5730  if (disp_transform[0] > 1 && disp_transform[1] > 1 &&
5731  disp_transform[0] < (1<<24) && disp_transform[1] < (1<<24) &&
5732  fabs((disp_transform[0] / disp_transform[1]) - 1.0) > 0.01)
5734  disp_transform[0] / disp_transform[1],
5735  INT_MAX);
5736  }
5737  return 0;
5738 }
5739 
5741 {
5742  MOVFragment *frag = &c->fragment;
5743  MOVTrackExt *trex = NULL;
5744  int flags, track_id, i;
5745  MOVFragmentStreamInfo * frag_stream_info;
5746 
5747  avio_r8(pb); /* version */
5748  flags = avio_rb24(pb);
5749 
5750  track_id = avio_rb32(pb);
5751  if (!track_id)
5752  return AVERROR_INVALIDDATA;
5753  for (i = 0; i < c->trex_count; i++)
5754  if (c->trex_data[i].track_id == track_id) {
5755  trex = &c->trex_data[i];
5756  break;
5757  }
5758  if (!trex) {
5759  av_log(c->fc, AV_LOG_WARNING, "could not find corresponding trex (id %u)\n", track_id);
5760  return 0;
5761  }
5762  c->fragment.found_tfhd = 1;
5763  frag->track_id = track_id;
5764  set_frag_stream(&c->frag_index, track_id);
5765 
5768  frag->moof_offset : frag->implicit_offset;
5769  frag->stsd_id = flags & MOV_TFHD_STSD_ID ? avio_rb32(pb) : trex->stsd_id;
5770 
5772  avio_rb32(pb) : trex->duration;
5773  frag->size = flags & MOV_TFHD_DEFAULT_SIZE ?
5774  avio_rb32(pb) : trex->size;
5775  frag->flags = flags & MOV_TFHD_DEFAULT_FLAGS ?
5776  avio_rb32(pb) : trex->flags;
5777  av_log(c->fc, AV_LOG_TRACE, "frag flags 0x%x\n", frag->flags);
5778 
5779  frag_stream_info = get_current_frag_stream_info(&c->frag_index);
5780  if (frag_stream_info) {
5781  frag_stream_info->next_trun_dts = AV_NOPTS_VALUE;
5782  frag_stream_info->stsd_id = frag->stsd_id;
5783  }
5784  return 0;
5785 }
5786 
5788 {
5789  unsigned i, num;
5790  void *new_tracks;
5791 
5792  num = atom.size / 4;
5793  if (!(new_tracks = av_malloc_array(num, sizeof(int))))
5794  return AVERROR(ENOMEM);
5795 
5796  av_free(c->chapter_tracks);
5797  c->chapter_tracks = new_tracks;
5798  c->nb_chapter_tracks = num;
5799 
5800  for (i = 0; i < num && !pb->eof_reached; i++)
5801  c->chapter_tracks[i] = avio_rb32(pb);
5802 
5803  c->nb_chapter_tracks = i;
5804 
5805  return 0;
5806 }
5807 
5809 {
5810  MOVTrackExt *trex;
5811  int err;
5812 
5813  if ((uint64_t)c->trex_count+1 >= UINT_MAX / sizeof(*c->trex_data))
5814  return AVERROR_INVALIDDATA;
5815  if ((err = av_reallocp_array(&c->trex_data, c->trex_count + 1,
5816  sizeof(*c->trex_data))) < 0) {
5817  c->trex_count = 0;
5818  return err;
5819  }
5820 
5821  c->fc->duration = AV_NOPTS_VALUE; // the duration from mvhd is not representing the whole file when fragments are used.
5822 
5823  trex = &c->trex_data[c->trex_count++];
5824  avio_r8(pb); /* version */
5825  avio_rb24(pb); /* flags */
5826  trex->track_id = avio_rb32(pb);
5827  trex->stsd_id = avio_rb32(pb);
5828  trex->duration = avio_rb32(pb);
5829  trex->size = avio_rb32(pb);
5830  trex->flags = avio_rb32(pb);
5831  return 0;
5832 }
5833 
5835 {
5836  MOVFragment *frag = &c->fragment;
5837  AVStream *st = NULL;
5838  MOVStreamContext *sc;
5839  int version, i;
5840  MOVFragmentStreamInfo * frag_stream_info;
5841  int64_t base_media_decode_time;
5842 
5843  for (i = 0; i < c->fc->nb_streams; i++) {
5844  sc = c->fc->streams[i]->priv_data;
5845  if (sc->id == frag->track_id) {
5846  st = c->fc->streams[i];
5847  break;
5848  }
5849  }
5850  if (!st) {
5851  av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %u\n", frag->track_id);
5852  return 0;
5853  }
5854  sc = st->priv_data;
5855  if (sc->pseudo_stream_id + 1 != frag->stsd_id && sc->pseudo_stream_id != -1)
5856  return 0;
5857  version = avio_r8(pb);
5858  avio_rb24(pb); /* flags */
5859  if (version) {
5860  base_media_decode_time = avio_rb64(pb);
5861  } else {
5862  base_media_decode_time = avio_rb32(pb);
5863  }
5864 
5865  frag_stream_info = get_current_frag_stream_info(&c->frag_index);
5866  if (frag_stream_info)
5867  frag_stream_info->tfdt_dts = base_media_decode_time;
5868  sc->track_end = base_media_decode_time;
5869 
5870  return 0;
5871 }
5872 
5874 {
5875  MOVFragment *frag = &c->fragment;
5876  AVStream *st = NULL;
5877  FFStream *sti = NULL;
5878  MOVStreamContext *sc;
5879  MOVTimeToSample *tts_data;
5880  uint64_t offset;
5881  int64_t dts, pts = AV_NOPTS_VALUE;
5882  int data_offset = 0;
5883  unsigned entries, first_sample_flags = frag->flags;
5884  int flags, distance, i;
5885  int64_t prev_dts = AV_NOPTS_VALUE;
5886  int next_frag_index = -1, index_entry_pos;
5887  size_t requested_size;
5888  size_t old_allocated_size;
5889  AVIndexEntry *new_entries;
5890  MOVFragmentStreamInfo * frag_stream_info;
5891 
5892  if (!frag->found_tfhd) {
5893  av_log(c->fc, AV_LOG_ERROR, "trun track id unknown, no tfhd was found\n");
5894  return AVERROR_INVALIDDATA;
5895  }
5896 
5897  for (i = 0; i < c->fc->nb_streams; i++) {
5898  sc = c->fc->streams[i]->priv_data;
5899  if (sc->id == frag->track_id) {
5900  st = c->fc->streams[i];
5901  sti = ffstream(st);
5902  break;
5903  }
5904  }
5905  if (!st) {
5906  av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %u\n", frag->track_id);
5907  return 0;
5908  }
5909  sc = st->priv_data;
5910  if (sc->pseudo_stream_id+1 != frag->stsd_id && sc->pseudo_stream_id != -1)
5911  return 0;
5912 
5913  // Find the next frag_index index that has a valid index_entry for
5914  // the current track_id.
5915  //
5916  // A valid index_entry means the trun for the fragment was read
5917  // and it's samples are in index_entries at the given position.
5918  // New index entries will be inserted before the index_entry found.
5919  index_entry_pos = sti->nb_index_entries;
5920  for (i = c->frag_index.current + 1; i < c->frag_index.nb_items; i++) {
5921  frag_stream_info = get_frag_stream_info(&c->frag_index, i, frag->track_id);
5922  if (frag_stream_info && frag_stream_info->index_entry >= 0) {
5923  next_frag_index = i;
5924  index_entry_pos = frag_stream_info->index_entry;
5925  break;
5926  }
5927  }
5928  av_assert0(index_entry_pos <= sti->nb_index_entries);
5929 
5930  avio_r8(pb); /* version */
5931  flags = avio_rb24(pb);
5932  entries = avio_rb32(pb);
5933  av_log(c->fc, AV_LOG_TRACE, "flags 0x%x entries %u\n", flags, entries);
5934 
5935  if ((uint64_t)entries+sc->tts_count >= UINT_MAX/sizeof(*sc->tts_data))
5936  return AVERROR_INVALIDDATA;
5937  if (flags & MOV_TRUN_DATA_OFFSET) data_offset = avio_rb32(pb);
5938  if (flags & MOV_TRUN_FIRST_SAMPLE_FLAGS) first_sample_flags = avio_rb32(pb);
5939 
5940  frag_stream_info = get_current_frag_stream_info(&c->frag_index);
5941  if (frag_stream_info) {
5942  if (frag_stream_info->next_trun_dts != AV_NOPTS_VALUE) {
5943  dts = frag_stream_info->next_trun_dts - sc->time_offset;
5944  } else if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE &&
5945  c->use_mfra_for == FF_MOV_FLAG_MFRA_PTS) {
5946  pts = frag_stream_info->first_tfra_pts;
5947  av_log(c->fc, AV_LOG_DEBUG, "found mfra time %"PRId64
5948  ", using it for pts\n", pts);
5949  } else if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE &&
5950  c->use_mfra_for == FF_MOV_FLAG_MFRA_DTS) {
5951  dts = frag_stream_info->first_tfra_pts;
5952  av_log(c->fc, AV_LOG_DEBUG, "found mfra time %"PRId64
5953  ", using it for dts\n", pts);
5954  } else {
5955  int has_tfdt = frag_stream_info->tfdt_dts != AV_NOPTS_VALUE;
5956  int has_sidx = frag_stream_info->sidx_pts != AV_NOPTS_VALUE;
5957  int fallback_tfdt = !c->use_tfdt && !has_sidx && has_tfdt;
5958  int fallback_sidx = c->use_tfdt && !has_tfdt && has_sidx;
5959 
5960  if (fallback_sidx) {
5961  av_log(c->fc, AV_LOG_DEBUG, "use_tfdt set but no tfdt found, using sidx instead\n");
5962  }
5963  if (fallback_tfdt) {
5964  av_log(c->fc, AV_LOG_DEBUG, "use_tfdt not set but no sidx found, using tfdt instead\n");
5965  }
5966 
5967  if (has_tfdt && c->use_tfdt || fallback_tfdt) {
5968  dts = frag_stream_info->tfdt_dts - sc->time_offset;
5969  av_log(c->fc, AV_LOG_DEBUG, "found tfdt time %"PRId64
5970  ", using it for dts\n", dts);
5971  } else if (has_sidx && !c->use_tfdt || fallback_sidx) {
5972  // FIXME: sidx earliest_presentation_time is *PTS*, s.b.
5973  // pts = frag_stream_info->sidx_pts;
5974  dts = frag_stream_info->sidx_pts;
5975  av_log(c->fc, AV_LOG_DEBUG, "found sidx time %"PRId64
5976  ", using it for dts\n", frag_stream_info->sidx_pts);
5977  } else {
5978  dts = sc->track_end - sc->time_offset;
5979  av_log(c->fc, AV_LOG_DEBUG, "found track end time %"PRId64
5980  ", using it for dts\n", dts);
5981  }
5982  }
5983  } else {
5984  dts = sc->track_end - sc->time_offset;
5985  av_log(c->fc, AV_LOG_DEBUG, "found track end time %"PRId64
5986  ", using it for dts\n", dts);
5987  }
5988  offset = frag->base_data_offset + data_offset;
5989  distance = 0;
5990  av_log(c->fc, AV_LOG_TRACE, "first sample flags 0x%x\n", first_sample_flags);
5991 
5992  // realloc space for new index entries
5993  if ((uint64_t)sti->nb_index_entries + entries >= UINT_MAX / sizeof(AVIndexEntry)) {
5994  entries = UINT_MAX / sizeof(AVIndexEntry) - sti->nb_index_entries;
5995  av_log(c->fc, AV_LOG_ERROR, "Failed to add index entry\n");
5996  }
5997  if (entries == 0)
5998  return 0;
5999 
6000  requested_size = (sti->nb_index_entries + entries) * sizeof(AVIndexEntry);
6001  new_entries = av_fast_realloc(sti->index_entries,
6003  requested_size);
6004  if (!new_entries)
6005  return AVERROR(ENOMEM);
6006  sti->index_entries= new_entries;
6007 
6008  requested_size = (sti->nb_index_entries + entries) * sizeof(*sc->tts_data);
6009  old_allocated_size = sc->tts_allocated_size;
6010  tts_data = av_fast_realloc(sc->tts_data, &sc->tts_allocated_size,
6011  requested_size);
6012  if (!tts_data)
6013  return AVERROR(ENOMEM);
6014  sc->tts_data = tts_data;
6015 
6016  // In case there were samples without time to sample entries, ensure they get
6017  // zero valued entries. This ensures clips which mix boxes with and
6018  // without time to sample entries don't pickup uninitialized data.
6019  memset((uint8_t*)(sc->tts_data) + old_allocated_size, 0,
6020  sc->tts_allocated_size - old_allocated_size);
6021 
6022  if (index_entry_pos < sti->nb_index_entries) {
6023  // Make hole in index_entries and tts_data for new samples
6024  memmove(sti->index_entries + index_entry_pos + entries,
6025  sti->index_entries + index_entry_pos,
6026  sizeof(*sti->index_entries) *
6027  (sti->nb_index_entries - index_entry_pos));
6028  memmove(sc->tts_data + index_entry_pos + entries,
6029  sc->tts_data + index_entry_pos,
6030  sizeof(*sc->tts_data) * (sc->tts_count - index_entry_pos));
6031  if (index_entry_pos < sc->current_sample) {
6032  sc->current_sample += entries;
6033  }
6034  }
6035 
6036  sti->nb_index_entries += entries;
6037  sc->tts_count = sti->nb_index_entries;
6038  sc->stts_count = sti->nb_index_entries;
6039  if (flags & MOV_TRUN_SAMPLE_CTS)
6040  sc->ctts_count = sti->nb_index_entries;
6041 
6042  // Record the index_entry position in frag_index of this fragment
6043  if (frag_stream_info) {
6044  frag_stream_info->index_entry = index_entry_pos;
6045  if (frag_stream_info->index_base < 0)
6046  frag_stream_info->index_base = index_entry_pos;
6047  }
6048 
6049  if (index_entry_pos > 0)
6050  prev_dts = sti->index_entries[index_entry_pos-1].timestamp;
6051 
6052  for (i = 0; i < entries && !pb->eof_reached; i++) {
6053  unsigned sample_size = frag->size;
6054  int sample_flags = i ? frag->flags : first_sample_flags;
6055  unsigned sample_duration = frag->duration;
6056  unsigned ctts_duration = 0;
6057  int keyframe = 0;
6058  int index_entry_flags = 0;
6059 
6060  if (flags & MOV_TRUN_SAMPLE_DURATION) sample_duration = avio_rb32(pb);
6061  if (flags & MOV_TRUN_SAMPLE_SIZE) sample_size = avio_rb32(pb);
6062  if (flags & MOV_TRUN_SAMPLE_FLAGS) sample_flags = avio_rb32(pb);
6063  if (flags & MOV_TRUN_SAMPLE_CTS) ctts_duration = avio_rb32(pb);
6064 
6065  mov_update_dts_shift(sc, ctts_duration, c->fc);
6066  if (pts != AV_NOPTS_VALUE) {
6067  dts = pts - sc->dts_shift;
6068  if (flags & MOV_TRUN_SAMPLE_CTS) {
6069  dts -= ctts_duration;
6070  } else {
6071  dts -= sc->time_offset;
6072  }
6073  av_log(c->fc, AV_LOG_DEBUG,
6074  "pts %"PRId64" calculated dts %"PRId64
6075  " sc->dts_shift %d ctts.duration %d"
6076  " sc->time_offset %"PRId64
6077  " flags & MOV_TRUN_SAMPLE_CTS %d\n",
6078  pts, dts,
6079  sc->dts_shift, ctts_duration,
6081  pts = AV_NOPTS_VALUE;
6082  }
6083 
6084  keyframe =
6085  !(sample_flags & (MOV_FRAG_SAMPLE_FLAG_IS_NON_SYNC |
6087  if (keyframe) {
6088  distance = 0;
6089  index_entry_flags |= AVINDEX_KEYFRAME;
6090  }
6091  // Fragments can overlap in time. Discard overlapping frames after
6092  // decoding.
6093  if (prev_dts >= dts)
6094  index_entry_flags |= AVINDEX_DISCARD_FRAME;
6095 
6096  sti->index_entries[index_entry_pos].pos = offset;
6097  sti->index_entries[index_entry_pos].timestamp = dts;
6098  sti->index_entries[index_entry_pos].size = sample_size;
6099  sti->index_entries[index_entry_pos].min_distance = distance;
6100  sti->index_entries[index_entry_pos].flags = index_entry_flags;
6101 
6102  sc->tts_data[index_entry_pos].count = 1;
6103  sc->tts_data[index_entry_pos].offset = ctts_duration;
6104  sc->tts_data[index_entry_pos].duration = sample_duration;
6105  index_entry_pos++;
6106 
6107  av_log(c->fc, AV_LOG_TRACE, "AVIndex stream %d, sample %d, offset %"PRIx64", dts %"PRId64", "
6108  "size %u, distance %d, keyframe %d\n", st->index,
6109  index_entry_pos, offset, dts, sample_size, distance, keyframe);
6110  distance++;
6111  if (av_sat_add64(dts, sample_duration) != dts + (uint64_t)sample_duration)
6112  return AVERROR_INVALIDDATA;
6113  if (!sample_size)
6114  return AVERROR_INVALIDDATA;
6115  dts += sample_duration;
6116  offset += sample_size;
6117  sc->data_size += sample_size;
6118 
6119  if (sample_duration <= INT64_MAX - sc->duration_for_fps &&
6120  1 <= INT_MAX - sc->nb_frames_for_fps
6121  ) {
6122  sc->duration_for_fps += sample_duration;
6123  sc->nb_frames_for_fps ++;
6124  }
6125  }
6126  if (frag_stream_info)
6127  frag_stream_info->next_trun_dts = dts + sc->time_offset;
6128  if (i < entries) {
6129  // EOF found before reading all entries. Fix the hole this would
6130  // leave in index_entries and tts_data
6131  int gap = entries - i;
6132  memmove(sti->index_entries + index_entry_pos,
6133  sti->index_entries + index_entry_pos + gap,
6134  sizeof(*sti->index_entries) *
6135  (sti->nb_index_entries - (index_entry_pos + gap)));
6136  memmove(sc->tts_data + index_entry_pos,
6137  sc->tts_data + index_entry_pos + gap,
6138  sizeof(*sc->tts_data) *
6139  (sc->tts_count - (index_entry_pos + gap)));
6140 
6141  sti->nb_index_entries -= gap;
6142  sc->tts_count -= gap;
6143  if (index_entry_pos < sc->current_sample) {
6144  sc->current_sample -= gap;
6145  }
6146  entries = i;
6147  }
6148 
6149  // The end of this new fragment may overlap in time with the start
6150  // of the next fragment in index_entries. Mark the samples in the next
6151  // fragment that overlap with AVINDEX_DISCARD_FRAME
6152  prev_dts = AV_NOPTS_VALUE;
6153  if (index_entry_pos > 0)
6154  prev_dts = sti->index_entries[index_entry_pos-1].timestamp;
6155  for (int i = index_entry_pos; i < sti->nb_index_entries; i++) {
6156  if (prev_dts < sti->index_entries[i].timestamp)
6157  break;
6159  }
6160 
6161  // If a hole was created to insert the new index_entries into,
6162  // the index_entry recorded for all subsequent moof must
6163  // be incremented by the number of entries inserted.
6164  fix_frag_index_entries(&c->frag_index, next_frag_index,
6165  frag->track_id, entries);
6166 
6167  if (pb->eof_reached) {
6168  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted TRUN atom\n");
6169  return AVERROR_EOF;
6170  }
6171 
6172  frag->implicit_offset = offset;
6173 
6174  sc->track_end = dts + sc->time_offset;
6175  if (st->duration < sc->track_end)
6176  st->duration = sc->track_end;
6177 
6178  return 0;
6179 }
6180 
6182 {
6183  int64_t stream_size = avio_size(pb);
6184  int64_t offset = av_sat_add64(avio_tell(pb), atom.size), pts, timestamp;
6185  uint8_t version, is_complete;
6186  int64_t offadd;
6187  unsigned i, j, track_id, item_count;
6188  AVStream *st = NULL;
6189  AVStream *ref_st = NULL;
6190  MOVStreamContext *sc, *ref_sc = NULL;
6191  AVRational timescale;
6192 
6193  version = avio_r8(pb);
6194  if (version > 1) {
6195  avpriv_request_sample(c->fc, "sidx version %u", version);
6196  return 0;
6197  }
6198 
6199  avio_rb24(pb); // flags
6200 
6201  track_id = avio_rb32(pb); // Reference ID
6202  for (i = 0; i < c->fc->nb_streams; i++) {
6203  sc = c->fc->streams[i]->priv_data;
6204  if (sc->id == track_id) {
6205  st = c->fc->streams[i];
6206  break;
6207  }
6208  }
6209  if (!st) {
6210  av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %d\n", track_id);
6211  return 0;
6212  }
6213 
6214  sc = st->priv_data;
6215 
6216  timescale = av_make_q(1, avio_rb32(pb));
6217 
6218  if (timescale.den <= 0) {
6219  av_log(c->fc, AV_LOG_ERROR, "Invalid sidx timescale 1/%d\n", timescale.den);
6220  return AVERROR_INVALIDDATA;
6221  }
6222 
6223  if (version == 0) {
6224  pts = avio_rb32(pb);
6225  offadd= avio_rb32(pb);
6226  } else {
6227  pts = avio_rb64(pb);
6228  offadd= avio_rb64(pb);
6229  }
6230  if (av_sat_add64(offset, offadd) != offset + (uint64_t)offadd)
6231  return AVERROR_INVALIDDATA;
6232 
6233  offset += (uint64_t)offadd;
6234 
6235  avio_rb16(pb); // reserved
6236 
6237  item_count = avio_rb16(pb);
6238  if (item_count == 0)
6239  return AVERROR_INVALIDDATA;
6240 
6241  for (i = 0; i < item_count; i++) {
6242  int index;
6243  MOVFragmentStreamInfo * frag_stream_info;
6244  uint32_t size = avio_rb32(pb);
6245  uint32_t duration = avio_rb32(pb);
6246  if (size & 0x80000000) {
6247  avpriv_request_sample(c->fc, "sidx reference_type 1");
6248  return AVERROR_PATCHWELCOME;
6249  }
6250  avio_rb32(pb); // sap_flags
6251  timestamp = av_rescale_q(pts, timescale, st->time_base);
6252 
6254  frag_stream_info = get_frag_stream_info(&c->frag_index, index, track_id);
6255  if (frag_stream_info)
6256  frag_stream_info->sidx_pts = timestamp;
6257 
6258  if (av_sat_add64(offset, size) != offset + (uint64_t)size ||
6259  av_sat_add64(pts, duration) != pts + (uint64_t)duration
6260  )
6261  return AVERROR_INVALIDDATA;
6262  offset += size;
6263  pts += duration;
6264  }
6265 
6266  st->duration = sc->track_end = pts;
6267 
6268  sc->has_sidx = 1;
6269 
6270  // See if the remaining bytes are just an mfra which we can ignore.
6271  is_complete = offset == stream_size;
6272  if (!is_complete && (pb->seekable & AVIO_SEEKABLE_NORMAL) && stream_size > 0 ) {
6273  int64_t ret;
6274  int64_t original_pos = avio_tell(pb);
6275  if (!c->have_read_mfra_size) {
6276  if ((ret = avio_seek(pb, stream_size - 4, SEEK_SET)) < 0)
6277  return ret;
6278  c->mfra_size = avio_rb32(pb);
6279  c->have_read_mfra_size = 1;
6280  if ((ret = avio_seek(pb, original_pos, SEEK_SET)) < 0)
6281  return ret;
6282  }
6283  if (offset == stream_size - c->mfra_size)
6284  is_complete = 1;
6285  }
6286 
6287  if (is_complete) {
6288  // Find first entry in fragment index that came from an sidx.
6289  // This will pretty much always be the first entry.
6290  for (i = 0; i < c->frag_index.nb_items; i++) {
6291  MOVFragmentIndexItem * item = &c->frag_index.item[i];
6292  for (j = 0; ref_st == NULL && j < item->nb_stream_info; j++) {
6293  MOVFragmentStreamInfo * si;
6294  si = &item->stream_info[j];
6295  if (si->sidx_pts != AV_NOPTS_VALUE) {
6296  ref_st = c->fc->streams[j];
6297  ref_sc = ref_st->priv_data;
6298  break;
6299  }
6300  }
6301  }
6302  if (ref_st) for (i = 0; i < c->fc->nb_streams; i++) {
6303  st = c->fc->streams[i];
6304  sc = st->priv_data;
6305  if (!sc->has_sidx) {
6306  st->duration = sc->track_end = av_rescale(ref_st->duration, sc->time_scale, ref_sc->time_scale);
6307  }
6308  }
6309 
6310  if (offadd == 0)
6311  c->frag_index.complete = 1;
6312  }
6313 
6314  return 0;
6315 }
6316 
6317 /* this atom should be null (from specs), but some buggy files put the 'moov' atom inside it... */
6318 /* like the files created with Adobe Premiere 5.0, for samples see */
6319 /* http://graphics.tudelft.nl/~wouter/publications/soundtests/ */
6321 {
6322  int err;
6323 
6324  if (atom.size < 8)
6325  return 0; /* continue */
6326  if (avio_rb32(pb) != 0) { /* 0 sized mdat atom... use the 'wide' atom size */
6327  avio_skip(pb, atom.size - 4);
6328  return 0;
6329  }
6330  atom.type = avio_rl32(pb);
6331  atom.size -= 8;
6332  if (atom.type != MKTAG('m','d','a','t')) {
6333  avio_skip(pb, atom.size);
6334  return 0;
6335  }
6336  err = mov_read_mdat(c, pb, atom);
6337  return err;
6338 }
6339 
6341 {
6342 #if CONFIG_ZLIB
6343  FFIOContext ctx;
6344  uint8_t *cmov_data;
6345  uint8_t *moov_data; /* uncompressed data */
6346  long cmov_len, moov_len;
6347  int ret = -1;
6348 
6349  avio_rb32(pb); /* dcom atom */
6350  if (avio_rl32(pb) != MKTAG('d','c','o','m'))
6351  return AVERROR_INVALIDDATA;
6352  if (avio_rl32(pb) != MKTAG('z','l','i','b')) {
6353  av_log(c->fc, AV_LOG_ERROR, "unknown compression for cmov atom !\n");
6354  return AVERROR_INVALIDDATA;
6355  }
6356  avio_rb32(pb); /* cmvd atom */
6357  if (avio_rl32(pb) != MKTAG('c','m','v','d'))
6358  return AVERROR_INVALIDDATA;
6359  moov_len = avio_rb32(pb); /* uncompressed size */
6360  cmov_len = atom.size - 6 * 4;
6361 
6362  cmov_data = av_malloc(cmov_len);
6363  if (!cmov_data)
6364  return AVERROR(ENOMEM);
6365  moov_data = av_malloc(moov_len);
6366  if (!moov_data) {
6367  av_free(cmov_data);
6368  return AVERROR(ENOMEM);
6369  }
6370  ret = ffio_read_size(pb, cmov_data, cmov_len);
6371  if (ret < 0)
6372  goto free_and_return;
6373 
6375  if (uncompress (moov_data, (uLongf *) &moov_len, (const Bytef *)cmov_data, cmov_len) != Z_OK)
6376  goto free_and_return;
6377  ffio_init_read_context(&ctx, moov_data, moov_len);
6378  ctx.pub.seekable = AVIO_SEEKABLE_NORMAL;
6379  atom.type = MKTAG('m','o','o','v');
6380  atom.size = moov_len;
6381  ret = mov_read_default(c, &ctx.pub, atom);
6382 free_and_return:
6383  av_free(moov_data);
6384  av_free(cmov_data);
6385  return ret;
6386 #else
6387  av_log(c->fc, AV_LOG_ERROR, "this file requires zlib support compiled in\n");
6388  return AVERROR(ENOSYS);
6389 #endif
6390 }
6391 
6392 /* edit list atom */
6394 {
6395  MOVStreamContext *sc;
6396  int i, edit_count, version;
6397  int64_t elst_entry_size;
6398 
6399  if (c->fc->nb_streams < 1 || c->ignore_editlist)
6400  return 0;
6401  sc = c->fc->streams[c->fc->nb_streams-1]->priv_data;
6402 
6403  version = avio_r8(pb); /* version */
6404  avio_rb24(pb); /* flags */
6405  edit_count = avio_rb32(pb); /* entries */
6406  atom.size -= 8;
6407 
6408  elst_entry_size = version == 1 ? 20 : 12;
6409  if (atom.size != edit_count * elst_entry_size) {
6410  if (c->fc->strict_std_compliance >= FF_COMPLIANCE_STRICT) {
6411  av_log(c->fc, AV_LOG_ERROR, "Invalid edit list entry_count: %d for elst atom of size: %"PRId64" bytes.\n",
6412  edit_count, atom.size + 8);
6413  return AVERROR_INVALIDDATA;
6414  } else {
6415  edit_count = atom.size / elst_entry_size;
6416  if (edit_count * elst_entry_size != atom.size) {
6417  av_log(c->fc, AV_LOG_WARNING, "ELST atom of %"PRId64" bytes, bigger than %d entries.\n", atom.size, edit_count);
6418  }
6419  }
6420  }
6421 
6422  if (!edit_count)
6423  return 0;
6424  if (sc->elst_data)
6425  av_log(c->fc, AV_LOG_WARNING, "Duplicated ELST atom\n");
6426  av_free(sc->elst_data);
6427  sc->elst_count = 0;
6428  sc->elst_data = av_malloc_array(edit_count, sizeof(*sc->elst_data));
6429  if (!sc->elst_data)
6430  return AVERROR(ENOMEM);
6431 
6432  av_log(c->fc, AV_LOG_TRACE, "track[%u].edit_count = %i\n", c->fc->nb_streams - 1, edit_count);
6433  for (i = 0; i < edit_count && atom.size > 0 && !pb->eof_reached; i++) {
6434  MOVElst *e = &sc->elst_data[i];
6435 
6436  if (version == 1) {
6437  e->duration = avio_rb64(pb);
6438  e->time = avio_rb64(pb);
6439  atom.size -= 16;
6440  } else {
6441  e->duration = avio_rb32(pb); /* segment duration */
6442  e->time = (int32_t)avio_rb32(pb); /* media time */
6443  atom.size -= 8;
6444  }
6445  e->rate = avio_rb32(pb) / 65536.0;
6446  atom.size -= 4;
6447  av_log(c->fc, AV_LOG_TRACE, "duration=%"PRId64" time=%"PRId64" rate=%f\n",
6448  e->duration, e->time, e->rate);
6449 
6450  if (e->time < 0 && e->time != -1 &&
6451  c->fc->strict_std_compliance >= FF_COMPLIANCE_STRICT) {
6452  av_log(c->fc, AV_LOG_ERROR, "Track %d, edit %d: Invalid edit list media time=%"PRId64"\n",
6453  c->fc->nb_streams-1, i, e->time);
6454  return AVERROR_INVALIDDATA;
6455  }
6456  if (e->duration < 0) {
6457  av_log(c->fc, AV_LOG_ERROR, "Track %d, edit %d: Invalid edit list duration=%"PRId64"\n",
6458  c->fc->nb_streams-1, i, e->duration);
6459  return AVERROR_INVALIDDATA;
6460  }
6461  }
6462  sc->elst_count = i;
6463 
6464  return 0;
6465 }
6466 
6468 {
6469  MOVStreamContext *sc;
6470  int err;
6471 
6472  if (c->fc->nb_streams < 1)
6473  return AVERROR_INVALIDDATA;
6474  sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
6475 
6476  if (atom.size % sizeof(uint32_t))
6477  return AVERROR_INVALIDDATA;
6478 
6479  MovTref *tag = mov_add_tref_tag(sc, atom.type);
6480  if (!tag)
6481  return AVERROR(ENOMEM);
6482 
6483  int nb_timecode_track = atom.size >> 2;
6484  for (int i = 0; i < nb_timecode_track; i++) {
6485  if (avio_feof(pb))
6486  return AVERROR_INVALIDDATA;
6487  err = mov_add_tref_id(tag, avio_rb32(pb));
6488  if (err < 0)
6489  return err;
6490  }
6491 
6492  return 0;
6493 }
6494 
6496 {
6497  AVStream *st;
6498  int version, color_range, color_primaries, color_trc, color_space;
6499 
6500  if (c->fc->nb_streams < 1)
6501  return 0;
6502  st = c->fc->streams[c->fc->nb_streams - 1];
6503 
6504  if (atom.size < 5) {
6505  av_log(c->fc, AV_LOG_ERROR, "Empty VP Codec Configuration box\n");
6506  return AVERROR_INVALIDDATA;
6507  }
6508 
6509  version = avio_r8(pb);
6510  if (version != 1) {
6511  av_log(c->fc, AV_LOG_WARNING, "Unsupported VP Codec Configuration box version %d\n", version);
6512  return 0;
6513  }
6514  avio_skip(pb, 3); /* flags */
6515 
6516  avio_skip(pb, 2); /* profile + level */
6517  color_range = avio_r8(pb); /* bitDepth, chromaSubsampling, videoFullRangeFlag */
6518  color_primaries = avio_r8(pb);
6519  color_trc = avio_r8(pb);
6520  color_space = avio_r8(pb);
6521  if (avio_rb16(pb)) /* codecIntializationDataSize */
6522  return AVERROR_INVALIDDATA;
6523 
6526  if (!av_color_transfer_name(color_trc))
6527  color_trc = AVCOL_TRC_UNSPECIFIED;
6528  if (!av_color_space_name(color_space))
6529  color_space = AVCOL_SPC_UNSPECIFIED;
6530 
6533  st->codecpar->color_trc = color_trc;
6534  st->codecpar->color_space = color_space;
6535 
6536  return 0;
6537 }
6538 
6540 {
6541  MOVStreamContext *sc;
6542  int i, version;
6543 
6544  if (c->fc->nb_streams < 1)
6545  return AVERROR_INVALIDDATA;
6546 
6547  sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
6548 
6549  if (atom.size < 5) {
6550  av_log(c->fc, AV_LOG_ERROR, "Empty Mastering Display Metadata box\n");
6551  return AVERROR_INVALIDDATA;
6552  }
6553 
6554  version = avio_r8(pb);
6555  if (version) {
6556  av_log(c->fc, AV_LOG_WARNING, "Unsupported Mastering Display Metadata box version %d\n", version);
6557  return 0;
6558  }
6559  if (sc->mastering) {
6560  av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicate Mastering Display Metadata\n");
6561  return 0;
6562  }
6563 
6564  avio_skip(pb, 3); /* flags */
6565 
6567  if (!sc->mastering)
6568  return AVERROR(ENOMEM);
6569 
6570  for (i = 0; i < 3; i++) {
6571  sc->mastering->display_primaries[i][0] = av_make_q(avio_rb16(pb), 1 << 16);
6572  sc->mastering->display_primaries[i][1] = av_make_q(avio_rb16(pb), 1 << 16);
6573  }
6574  sc->mastering->white_point[0] = av_make_q(avio_rb16(pb), 1 << 16);
6575  sc->mastering->white_point[1] = av_make_q(avio_rb16(pb), 1 << 16);
6576 
6577  sc->mastering->max_luminance = av_make_q(avio_rb32(pb), 1 << 8);
6578  sc->mastering->min_luminance = av_make_q(avio_rb32(pb), 1 << 14);
6579 
6580  sc->mastering->has_primaries = 1;
6581  sc->mastering->has_luminance = 1;
6582 
6583  return 0;
6584 }
6585 
6587 {
6588  MOVStreamContext *sc;
6589  const int mapping[3] = {1, 2, 0};
6590  const int chroma_den = 50000;
6591  const int luma_den = 10000;
6592  int i;
6593 
6594  if (c->fc->nb_streams < 1)
6595  return AVERROR_INVALIDDATA;
6596 
6597  sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
6598 
6599  if (atom.size < 24) {
6600  av_log(c->fc, AV_LOG_ERROR, "Invalid Mastering Display Color Volume box\n");
6601  return AVERROR_INVALIDDATA;
6602  }
6603 
6604  if (sc->mastering) {
6605  av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicate Mastering Display Color Volume\n");
6606  return 0;
6607  }
6608 
6610  if (!sc->mastering)
6611  return AVERROR(ENOMEM);
6612 
6613  for (i = 0; i < 3; i++) {
6614  const int j = mapping[i];
6615  sc->mastering->display_primaries[j][0] = av_make_q(avio_rb16(pb), chroma_den);
6616  sc->mastering->display_primaries[j][1] = av_make_q(avio_rb16(pb), chroma_den);
6617  }
6618  sc->mastering->white_point[0] = av_make_q(avio_rb16(pb), chroma_den);
6619  sc->mastering->white_point[1] = av_make_q(avio_rb16(pb), chroma_den);
6620 
6621  sc->mastering->max_luminance = av_make_q(avio_rb32(pb), luma_den);
6622  sc->mastering->min_luminance = av_make_q(avio_rb32(pb), luma_den);
6623 
6624  sc->mastering->has_luminance = 1;
6625  sc->mastering->has_primaries = 1;
6626 
6627  return 0;
6628 }
6629 
6631 {
6632  MOVStreamContext *sc;
6633  int version;
6634 
6635  if (c->fc->nb_streams < 1)
6636  return AVERROR_INVALIDDATA;
6637 
6638  sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
6639 
6640  if (atom.size < 5) {
6641  av_log(c->fc, AV_LOG_ERROR, "Empty Content Light Level box\n");
6642  return AVERROR_INVALIDDATA;
6643  }
6644 
6645  version = avio_r8(pb);
6646  if (version) {
6647  av_log(c->fc, AV_LOG_WARNING, "Unsupported Content Light Level box version %d\n", version);
6648  return 0;
6649  }
6650  avio_skip(pb, 3); /* flags */
6651 
6652  if (sc->coll){
6653  av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicate COLL\n");
6654  return 0;
6655  }
6656 
6658  if (!sc->coll)
6659  return AVERROR(ENOMEM);
6660 
6661  sc->coll->MaxCLL = avio_rb16(pb);
6662  sc->coll->MaxFALL = avio_rb16(pb);
6663 
6664  return 0;
6665 }
6666 
6668 {
6669  MOVStreamContext *sc;
6670 
6671  if (c->fc->nb_streams < 1)
6672  return AVERROR_INVALIDDATA;
6673 
6674  sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
6675 
6676  if (atom.size < 4) {
6677  av_log(c->fc, AV_LOG_ERROR, "Empty Content Light Level Info box\n");
6678  return AVERROR_INVALIDDATA;
6679  }
6680 
6681  if (sc->coll){
6682  av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicate CLLI/COLL\n");
6683  return 0;
6684  }
6685 
6687  if (!sc->coll)
6688  return AVERROR(ENOMEM);
6689 
6690  sc->coll->MaxCLL = avio_rb16(pb);
6691  sc->coll->MaxFALL = avio_rb16(pb);
6692 
6693  return 0;
6694 }
6695 
6697 {
6698  MOVStreamContext *sc;
6699  const int illuminance_den = 10000;
6700  const int ambient_den = 50000;
6701  if (c->fc->nb_streams < 1)
6702  return AVERROR_INVALIDDATA;
6703  sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
6704  if (atom.size < 6) {
6705  av_log(c->fc, AV_LOG_ERROR, "Empty Ambient Viewing Environment Info box\n");
6706  return AVERROR_INVALIDDATA;
6707  }
6708  if (sc->ambient){
6709  av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicate AMVE\n");
6710  return 0;
6711  }
6713  if (!sc->ambient)
6714  return AVERROR(ENOMEM);
6715  sc->ambient->ambient_illuminance = av_make_q(avio_rb32(pb), illuminance_den);
6716  sc->ambient->ambient_light_x = av_make_q(avio_rb16(pb), ambient_den);
6717  sc->ambient->ambient_light_y = av_make_q(avio_rb16(pb), ambient_den);
6718  return 0;
6719 }
6720 
6722 {
6723  AVStream *st;
6724  MOVStreamContext *sc;
6725  enum AVStereo3DType type;
6726  int mode;
6727 
6728  if (c->fc->nb_streams < 1)
6729  return 0;
6730 
6731  st = c->fc->streams[c->fc->nb_streams - 1];
6732  sc = st->priv_data;
6733 
6734  if (atom.size < 5) {
6735  av_log(c->fc, AV_LOG_ERROR, "Empty stereoscopic video box\n");
6736  return AVERROR_INVALIDDATA;
6737  }
6738 
6739  if (sc->stereo3d)
6740  return AVERROR_INVALIDDATA;
6741 
6742  avio_skip(pb, 4); /* version + flags */
6743 
6744  mode = avio_r8(pb);
6745  switch (mode) {
6746  case 0:
6747  type = AV_STEREO3D_2D;
6748  break;
6749  case 1:
6751  break;
6752  case 2:
6754  break;
6755  default:
6756  av_log(c->fc, AV_LOG_WARNING, "Unknown st3d mode value %d\n", mode);
6757  return 0;
6758  }
6759 
6761  if (!sc->stereo3d)
6762  return AVERROR(ENOMEM);
6763 
6764  sc->stereo3d->type = type;
6765  return 0;
6766 }
6767 
6769 {
6770  AVStream *st;
6771  MOVStreamContext *sc;
6772  int size = 0;
6773  int64_t remaining;
6774  uint32_t tag = 0;
6776 
6777  if (c->fc->nb_streams < 1)
6778  return 0;
6779 
6780  st = c->fc->streams[c->fc->nb_streams - 1];
6781  sc = st->priv_data;
6782 
6783  remaining = atom.size;
6784  while (remaining > 0) {
6785  size = avio_rb32(pb);
6786  if (size < 8 || size > remaining ) {
6787  av_log(c->fc, AV_LOG_ERROR, "Invalid child size in pack box\n");
6788  return AVERROR_INVALIDDATA;
6789  }
6790 
6791  tag = avio_rl32(pb);
6792  switch (tag) {
6793  case MKTAG('p','k','i','n'): {
6794  if (size != 16) {
6795  av_log(c->fc, AV_LOG_ERROR, "Invalid size of pkin box: %d\n", size);
6796  return AVERROR_INVALIDDATA;
6797  }
6798  avio_skip(pb, 1); // version
6799  avio_skip(pb, 3); // flags
6800 
6801  tag = avio_rl32(pb);
6802  switch (tag) {
6803  case MKTAG('s','i','d','e'):
6805  break;
6806  case MKTAG('o','v','e','r'):
6808  break;
6809  case 0:
6810  // This means value will be set in another layer
6811  break;
6812  default:
6813  av_log(c->fc, AV_LOG_WARNING, "Unknown tag in pkin: %s\n",
6814  av_fourcc2str(tag));
6815  avio_skip(pb, size - 8);
6816  break;
6817  }
6818 
6819  break;
6820  }
6821  default:
6822  av_log(c->fc, AV_LOG_WARNING, "Unknown tag in pack: %s\n",
6823  av_fourcc2str(tag));
6824  avio_skip(pb, size - 8);
6825  break;
6826  }
6827  remaining -= size;
6828  }
6829 
6830  if (remaining != 0) {
6831  av_log(c->fc, AV_LOG_ERROR, "Broken pack box\n");
6832  return AVERROR_INVALIDDATA;
6833  }
6834 
6835  if (type == AV_STEREO3D_2D)
6836  return 0;
6837 
6838  if (!sc->stereo3d) {
6840  if (!sc->stereo3d)
6841  return AVERROR(ENOMEM);
6842  }
6843 
6844  sc->stereo3d->type = type;
6845 
6846  return 0;
6847 }
6848 
6850 {
6851  AVStream *st;
6852  MOVStreamContext *sc;
6853  int size, version, layout;
6854  int32_t yaw, pitch, roll;
6855  uint32_t l = 0, t = 0, r = 0, b = 0;
6856  uint32_t tag, padding = 0;
6857  enum AVSphericalProjection projection;
6858 
6859  if (c->fc->nb_streams < 1)
6860  return 0;
6861 
6862  st = c->fc->streams[c->fc->nb_streams - 1];
6863  sc = st->priv_data;
6864 
6865  if (atom.size < 8) {
6866  av_log(c->fc, AV_LOG_ERROR, "Empty spherical video box\n");
6867  return AVERROR_INVALIDDATA;
6868  }
6869 
6870  size = avio_rb32(pb);
6871  if (size <= 12 || size > atom.size)
6872  return AVERROR_INVALIDDATA;
6873 
6874  tag = avio_rl32(pb);
6875  if (tag != MKTAG('s','v','h','d')) {
6876  av_log(c->fc, AV_LOG_ERROR, "Missing spherical video header\n");
6877  return 0;
6878  }
6879  version = avio_r8(pb);
6880  if (version != 0) {
6881  av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
6882  version);
6883  return 0;
6884  }
6885  avio_skip(pb, 3); /* flags */
6886  avio_skip(pb, size - 12); /* metadata_source */
6887 
6888  size = avio_rb32(pb);
6889  if (size > atom.size)
6890  return AVERROR_INVALIDDATA;
6891 
6892  tag = avio_rl32(pb);
6893  if (tag != MKTAG('p','r','o','j')) {
6894  av_log(c->fc, AV_LOG_ERROR, "Missing projection box\n");
6895  return 0;
6896  }
6897 
6898  size = avio_rb32(pb);
6899  if (size > atom.size)
6900  return AVERROR_INVALIDDATA;
6901 
6902  tag = avio_rl32(pb);
6903  if (tag != MKTAG('p','r','h','d')) {
6904  av_log(c->fc, AV_LOG_ERROR, "Missing projection header box\n");
6905  return 0;
6906  }
6907  version = avio_r8(pb);
6908  if (version != 0) {
6909  av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
6910  version);
6911  return 0;
6912  }
6913  avio_skip(pb, 3); /* flags */
6914 
6915  /* 16.16 fixed point */
6916  yaw = avio_rb32(pb);
6917  pitch = avio_rb32(pb);
6918  roll = avio_rb32(pb);
6919 
6920  size = avio_rb32(pb);
6921  if (size > atom.size)
6922  return AVERROR_INVALIDDATA;
6923 
6924  tag = avio_rl32(pb);
6925  version = avio_r8(pb);
6926  if (version != 0) {
6927  av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
6928  version);
6929  return 0;
6930  }
6931  avio_skip(pb, 3); /* flags */
6932  switch (tag) {
6933  case MKTAG('c','b','m','p'):
6934  layout = avio_rb32(pb);
6935  if (layout) {
6936  av_log(c->fc, AV_LOG_WARNING,
6937  "Unsupported cubemap layout %d\n", layout);
6938  return 0;
6939  }
6940  projection = AV_SPHERICAL_CUBEMAP;
6941  padding = avio_rb32(pb);
6942  break;
6943  case MKTAG('e','q','u','i'):
6944  t = avio_rb32(pb);
6945  b = avio_rb32(pb);
6946  l = avio_rb32(pb);
6947  r = avio_rb32(pb);
6948 
6949  if (b >= UINT_MAX - t || r >= UINT_MAX - l) {
6950  av_log(c->fc, AV_LOG_ERROR,
6951  "Invalid bounding rectangle coordinates "
6952  "%"PRIu32",%"PRIu32",%"PRIu32",%"PRIu32"\n", l, t, r, b);
6953  return AVERROR_INVALIDDATA;
6954  }
6955 
6956  if (l || t || r || b)
6957  projection = AV_SPHERICAL_EQUIRECTANGULAR_TILE;
6958  else
6959  projection = AV_SPHERICAL_EQUIRECTANGULAR;
6960  break;
6961  default:
6962  av_log(c->fc, AV_LOG_ERROR, "Unknown projection type: %s\n", av_fourcc2str(tag));
6963  return 0;
6964  }
6965 
6967  if (!sc->spherical)
6968  return AVERROR(ENOMEM);
6969 
6970  sc->spherical->projection = projection;
6971 
6972  sc->spherical->yaw = yaw;
6973  sc->spherical->pitch = pitch;
6974  sc->spherical->roll = roll;
6975 
6976  sc->spherical->padding = padding;
6977 
6978  sc->spherical->bound_left = l;
6979  sc->spherical->bound_top = t;
6980  sc->spherical->bound_right = r;
6981  sc->spherical->bound_bottom = b;
6982 
6983  return 0;
6984 }
6985 
6987 {
6988  AVStream *st;
6989  MOVStreamContext *sc;
6990  int size;
6991  uint32_t tag;
6992  enum AVSphericalProjection projection;
6993 
6994  if (c->fc->nb_streams < 1)
6995  return 0;
6996 
6997  st = c->fc->streams[c->fc->nb_streams - 1];
6998  sc = st->priv_data;
6999 
7000  if (atom.size < 16) {
7001  av_log(c->fc, AV_LOG_ERROR, "Invalid size for proj box: %"PRIu64"\n", atom.size);
7002  return AVERROR_INVALIDDATA;
7003  }
7004 
7005  size = avio_rb32(pb);
7006  if (size < 16) {
7007  av_log(c->fc, AV_LOG_ERROR, "Invalid size for prji box: %d\n", size);
7008  return AVERROR_INVALIDDATA;
7009  } else if (size > 16) {
7010  av_log(c->fc, AV_LOG_WARNING, "Box has more bytes (%d) than prji box required (16) \n", size);
7011  }
7012 
7013  tag = avio_rl32(pb);
7014  if (tag != MKTAG('p','r','j','i')) {
7015  av_log(c->fc, AV_LOG_ERROR, "Invalid child box of proj box: %s\n",
7016  av_fourcc2str(tag));
7017  return AVERROR_INVALIDDATA;
7018  }
7019 
7020  // version and flags, only support (0, 0)
7021  unsigned n = avio_rl32(pb);
7022  if (n != 0) {
7023  av_log(c->fc, AV_LOG_ERROR, "prji version %u, flag %u are not supported\n",
7024  n & 0xFF, n >> 8);
7025  return AVERROR_PATCHWELCOME;
7026  }
7027 
7028  tag = avio_rl32(pb);
7029  switch (tag) {
7030  case MKTAG('r','e','c','t'):
7031  projection = AV_SPHERICAL_RECTILINEAR;
7032  break;
7033  case MKTAG('e','q','u','i'):
7034  projection = AV_SPHERICAL_EQUIRECTANGULAR;
7035  break;
7036  case MKTAG('h','e','q','u'):
7037  projection = AV_SPHERICAL_HALF_EQUIRECTANGULAR;
7038  break;
7039  case MKTAG('f','i','s','h'):
7040  projection = AV_SPHERICAL_FISHEYE;
7041  break;
7042  case MKTAG('p','r','i','m'):
7043  projection = AV_SPHERICAL_PARAMETRIC_IMMERSIVE;
7044  break;
7045  default:
7046  av_log(c->fc, AV_LOG_ERROR, "Invalid projection type in prji box: %s\n", av_fourcc2str(tag));
7047  return AVERROR_INVALIDDATA;
7048  }
7049 
7051  if (!sc->spherical)
7052  return AVERROR(ENOMEM);
7053 
7054  sc->spherical->projection = projection;
7055 
7056  return 0;
7057 }
7058 
7060 {
7061  AVStream *st;
7062  MOVStreamContext *sc;
7063  int size, flags = 0;
7064  int64_t remaining;
7065  uint32_t tag, baseline = 0;
7068  enum AVStereo3DPrimaryEye primary_eye = AV_PRIMARY_EYE_NONE;
7069  AVRational horizontal_disparity_adjustment = { 0, 1 };
7070 
7071  if (c->fc->nb_streams < 1)
7072  return 0;
7073 
7074  st = c->fc->streams[c->fc->nb_streams - 1];
7075  sc = st->priv_data;
7076 
7077  remaining = atom.size;
7078  while (remaining > 0) {
7079  size = avio_rb32(pb);
7080  if (size < 8 || size > remaining ) {
7081  av_log(c->fc, AV_LOG_ERROR, "Invalid child size in eyes box\n");
7082  return AVERROR_INVALIDDATA;
7083  }
7084 
7085  tag = avio_rl32(pb);
7086  switch (tag) {
7087  case MKTAG('s','t','r','i'): {
7088  int has_right, has_left;
7089  uint8_t tmp;
7090  if (size != 13) {
7091  av_log(c->fc, AV_LOG_ERROR, "Invalid size of stri box: %d\n", size);
7092  return AVERROR_INVALIDDATA;
7093  }
7094  avio_skip(pb, 1); // version
7095  avio_skip(pb, 3); // flags
7096 
7097  tmp = avio_r8(pb);
7098 
7099  // eye_views_reversed
7100  if (tmp & 8) {
7102  }
7103  // has_additional_views
7104  if (tmp & 4) {
7105  // skip...
7106  }
7107 
7108  has_right = tmp & 2; // has_right_eye_view
7109  has_left = tmp & 1; // has_left_eye_view
7110 
7111  if (has_left && has_right)
7112  view = AV_STEREO3D_VIEW_PACKED;
7113  else if (has_left)
7114  view = AV_STEREO3D_VIEW_LEFT;
7115  else if (has_right)
7116  view = AV_STEREO3D_VIEW_RIGHT;
7117  if (has_left || has_right)
7119 
7120  break;
7121  }
7122  case MKTAG('h','e','r','o'): {
7123  int tmp;
7124  if (size != 13) {
7125  av_log(c->fc, AV_LOG_ERROR, "Invalid size of hero box: %d\n", size);
7126  return AVERROR_INVALIDDATA;
7127  }
7128  avio_skip(pb, 1); // version
7129  avio_skip(pb, 3); // flags
7130 
7131  tmp = avio_r8(pb);
7132  if (tmp == 0)
7133  primary_eye = AV_PRIMARY_EYE_NONE;
7134  else if (tmp == 1)
7135  primary_eye = AV_PRIMARY_EYE_LEFT;
7136  else if (tmp == 2)
7137  primary_eye = AV_PRIMARY_EYE_RIGHT;
7138  else
7139  av_log(c->fc, AV_LOG_WARNING, "Unknown hero eye type: %d\n", tmp);
7140 
7141  break;
7142  }
7143  case MKTAG('c','a','m','s'): {
7144  uint32_t subtag;
7145  int subsize;
7146  if (size != 24) {
7147  av_log(c->fc, AV_LOG_ERROR, "Invalid size of cams box: %d\n", size);
7148  return AVERROR_INVALIDDATA;
7149  }
7150 
7151  subsize = avio_rb32(pb);
7152  if (subsize != 16) {
7153  av_log(c->fc, AV_LOG_ERROR, "Invalid size of blin box: %d\n", size);
7154  return AVERROR_INVALIDDATA;
7155  }
7156 
7157  subtag = avio_rl32(pb);
7158  if (subtag != MKTAG('b','l','i','n')) {
7159  av_log(c->fc, AV_LOG_ERROR, "Expected blin box, got %s\n",
7160  av_fourcc2str(subtag));
7161  return AVERROR_INVALIDDATA;
7162  }
7163 
7164  avio_skip(pb, 1); // version
7165  avio_skip(pb, 3); // flags
7166 
7167  baseline = avio_rb32(pb);
7168 
7169  break;
7170  }
7171  case MKTAG('c','m','f','y'): {
7172  uint32_t subtag;
7173  int subsize;
7174  int32_t adjustment;
7175  if (size != 24) {
7176  av_log(c->fc, AV_LOG_ERROR, "Invalid size of cmfy box: %d\n", size);
7177  return AVERROR_INVALIDDATA;
7178  }
7179 
7180  subsize = avio_rb32(pb);
7181  if (subsize != 16) {
7182  av_log(c->fc, AV_LOG_ERROR, "Invalid size of dadj box: %d\n", size);
7183  return AVERROR_INVALIDDATA;
7184  }
7185 
7186  subtag = avio_rl32(pb);
7187  if (subtag != MKTAG('d','a','d','j')) {
7188  av_log(c->fc, AV_LOG_ERROR, "Expected dadj box, got %s\n",
7189  av_fourcc2str(subtag));
7190  return AVERROR_INVALIDDATA;
7191  }
7192 
7193  avio_skip(pb, 1); // version
7194  avio_skip(pb, 3); // flags
7195 
7196  adjustment = (int32_t) avio_rb32(pb);
7197 
7198  horizontal_disparity_adjustment.num = (int) adjustment;
7199  horizontal_disparity_adjustment.den = 10000;
7200 
7201  break;
7202  }
7203  default:
7204  av_log(c->fc, AV_LOG_WARNING, "Unknown tag in eyes: %s\n",
7205  av_fourcc2str(tag));
7206  avio_skip(pb, size - 8);
7207  break;
7208  }
7209  remaining -= size;
7210  }
7211 
7212  if (remaining != 0) {
7213  av_log(c->fc, AV_LOG_ERROR, "Broken eyes box\n");
7214  return AVERROR_INVALIDDATA;
7215  }
7216 
7217  if (type == AV_STEREO3D_2D)
7218  return 0;
7219 
7220  if (!sc->stereo3d) {
7222  if (!sc->stereo3d)
7223  return AVERROR(ENOMEM);
7224  }
7225 
7226  sc->stereo3d->flags = flags;
7227  sc->stereo3d->type = type;
7228  sc->stereo3d->view = view;
7229  sc->stereo3d->primary_eye = primary_eye;
7230  sc->stereo3d->baseline = baseline;
7231  sc->stereo3d->horizontal_disparity_adjustment = horizontal_disparity_adjustment;
7232 
7233  return 0;
7234 }
7235 
7237 {
7238  int size;
7239  int64_t remaining;
7240  uint32_t tag;
7241 
7242  if (c->fc->nb_streams < 1)
7243  return 0;
7244 
7245  if (atom.size < 8) {
7246  av_log(c->fc, AV_LOG_ERROR, "Empty video extension usage box\n");
7247  return AVERROR_INVALIDDATA;
7248  }
7249 
7250  remaining = atom.size;
7251  while (remaining > 0) {
7252  size = avio_rb32(pb);
7253  if (size < 8 || size > remaining ) {
7254  av_log(c->fc, AV_LOG_ERROR, "Invalid child size in vexu box\n");
7255  return AVERROR_INVALIDDATA;
7256  }
7257 
7258  tag = avio_rl32(pb);
7259  switch (tag) {
7260  case MKTAG('p','r','o','j'): {
7261  MOVAtom proj = { tag, size - 8 };
7262  int ret = mov_read_vexu_proj(c, pb, proj);
7263  if (ret < 0)
7264  return ret;
7265  break;
7266  }
7267  case MKTAG('e','y','e','s'): {
7268  MOVAtom eyes = { tag, size - 8 };
7269  int ret = mov_read_eyes(c, pb, eyes);
7270  if (ret < 0)
7271  return ret;
7272  break;
7273  }
7274  case MKTAG('p','a','c','k'): {
7275  MOVAtom pack = { tag, size - 8 };
7276  int ret = mov_read_pack(c, pb, pack);
7277  if (ret < 0)
7278  return ret;
7279  break;
7280  }
7281  default:
7282  av_log(c->fc, AV_LOG_WARNING, "Unknown tag in vexu: %s\n",
7283  av_fourcc2str(tag));
7284  avio_skip(pb, size - 8);
7285  break;
7286  }
7287  remaining -= size;
7288  }
7289 
7290  if (remaining != 0) {
7291  av_log(c->fc, AV_LOG_ERROR, "Broken vexu box\n");
7292  return AVERROR_INVALIDDATA;
7293  }
7294 
7295  return 0;
7296 }
7297 
7299 {
7300  AVStream *st;
7301  MOVStreamContext *sc;
7302 
7303  if (c->fc->nb_streams < 1)
7304  return 0;
7305 
7306  st = c->fc->streams[c->fc->nb_streams - 1];
7307  sc = st->priv_data;
7308 
7309  if (atom.size != 4) {
7310  av_log(c->fc, AV_LOG_ERROR, "Invalid size of hfov box: %"PRIu64"\n", atom.size);
7311  return AVERROR_INVALIDDATA;
7312  }
7313 
7314 
7315  if (!sc->stereo3d) {
7317  if (!sc->stereo3d)
7318  return AVERROR(ENOMEM);
7319  }
7320 
7322  sc->stereo3d->horizontal_field_of_view.den = 1000; // thousands of a degree
7323 
7324  return 0;
7325 }
7326 
7328 {
7329  int ret = 0;
7330  uint8_t *buffer = av_malloc(len + 1);
7331  const char *val;
7332 
7333  if (!buffer)
7334  return AVERROR(ENOMEM);
7335  buffer[len] = '\0';
7336 
7337  ret = ffio_read_size(pb, buffer, len);
7338  if (ret < 0)
7339  goto out;
7340 
7341  /* Check for mandatory keys and values, try to support XML as best-effort */
7342  if (!sc->spherical &&
7343  av_stristr(buffer, "<GSpherical:StitchingSoftware>") &&
7344  (val = av_stristr(buffer, "<GSpherical:Spherical>")) &&
7345  av_stristr(val, "true") &&
7346  (val = av_stristr(buffer, "<GSpherical:Stitched>")) &&
7347  av_stristr(val, "true") &&
7348  (val = av_stristr(buffer, "<GSpherical:ProjectionType>")) &&
7349  av_stristr(val, "equirectangular")) {
7351  if (!sc->spherical)
7352  goto out;
7353 
7355 
7356  if (av_stristr(buffer, "<GSpherical:StereoMode>") && !sc->stereo3d) {
7357  enum AVStereo3DType mode;
7358 
7359  if (av_stristr(buffer, "left-right"))
7361  else if (av_stristr(buffer, "top-bottom"))
7363  else
7364  mode = AV_STEREO3D_2D;
7365 
7367  if (!sc->stereo3d)
7368  goto out;
7369 
7370  sc->stereo3d->type = mode;
7371  }
7372 
7373  /* orientation */
7374  val = av_stristr(buffer, "<GSpherical:InitialViewHeadingDegrees>");
7375  if (val)
7376  sc->spherical->yaw = strtol(val, NULL, 10) * (1 << 16);
7377  val = av_stristr(buffer, "<GSpherical:InitialViewPitchDegrees>");
7378  if (val)
7379  sc->spherical->pitch = strtol(val, NULL, 10) * (1 << 16);
7380  val = av_stristr(buffer, "<GSpherical:InitialViewRollDegrees>");
7381  if (val)
7382  sc->spherical->roll = strtol(val, NULL, 10) * (1 << 16);
7383  }
7384 
7385 out:
7386  av_free(buffer);
7387  return ret;
7388 }
7389 
7391 {
7392  AVStream *st;
7393  MOVStreamContext *sc;
7394  int64_t ret;
7395  AVUUID uuid;
7396  static const AVUUID uuid_isml_manifest = {
7397  0xa5, 0xd4, 0x0b, 0x30, 0xe8, 0x14, 0x11, 0xdd,
7398  0xba, 0x2f, 0x08, 0x00, 0x20, 0x0c, 0x9a, 0x66
7399  };
7400  static const AVUUID uuid_xmp = {
7401  0xbe, 0x7a, 0xcf, 0xcb, 0x97, 0xa9, 0x42, 0xe8,
7402  0x9c, 0x71, 0x99, 0x94, 0x91, 0xe3, 0xaf, 0xac
7403  };
7404  static const AVUUID uuid_spherical = {
7405  0xff, 0xcc, 0x82, 0x63, 0xf8, 0x55, 0x4a, 0x93,
7406  0x88, 0x14, 0x58, 0x7a, 0x02, 0x52, 0x1f, 0xdd,
7407  };
7408 
7409  if (atom.size < AV_UUID_LEN || atom.size >= FFMIN(INT_MAX, SIZE_MAX))
7410  return AVERROR_INVALIDDATA;
7411 
7412  if (c->fc->nb_streams < 1)
7413  return 0;
7414  st = c->fc->streams[c->fc->nb_streams - 1];
7415  sc = st->priv_data;
7416 
7417  ret = ffio_read_size(pb, uuid, AV_UUID_LEN);
7418  if (ret < 0)
7419  return ret;
7420  if (av_uuid_equal(uuid, uuid_isml_manifest)) {
7421  uint8_t *buffer, *ptr;
7422  char *endptr;
7423  size_t len = atom.size - AV_UUID_LEN;
7424 
7425  if (len < 4) {
7426  return AVERROR_INVALIDDATA;
7427  }
7428  ret = avio_skip(pb, 4); // zeroes
7429  len -= 4;
7430 
7431  buffer = av_mallocz(len + 1);
7432  if (!buffer) {
7433  return AVERROR(ENOMEM);
7434  }
7435  ret = ffio_read_size(pb, buffer, len);
7436  if (ret < 0) {
7437  av_free(buffer);
7438  return ret;
7439  }
7440 
7441  ptr = buffer;
7442  while ((ptr = av_stristr(ptr, "systemBitrate=\""))) {
7443  ptr += sizeof("systemBitrate=\"") - 1;
7444  c->bitrates_count++;
7445  c->bitrates = av_realloc_f(c->bitrates, c->bitrates_count, sizeof(*c->bitrates));
7446  if (!c->bitrates) {
7447  c->bitrates_count = 0;
7448  av_free(buffer);
7449  return AVERROR(ENOMEM);
7450  }
7451  errno = 0;
7452  ret = strtol(ptr, &endptr, 10);
7453  if (ret < 0 || errno || *endptr != '"') {
7454  c->bitrates[c->bitrates_count - 1] = 0;
7455  } else {
7456  c->bitrates[c->bitrates_count - 1] = ret;
7457  }
7458  }
7459 
7460  av_free(buffer);
7461  } else if (av_uuid_equal(uuid, uuid_xmp)) {
7462  uint8_t *buffer;
7463  size_t len = atom.size - AV_UUID_LEN;
7464  if (c->export_xmp) {
7465  buffer = av_mallocz(len + 1);
7466  if (!buffer) {
7467  return AVERROR(ENOMEM);
7468  }
7469  ret = ffio_read_size(pb, buffer, len);
7470  if (ret < 0) {
7471  av_free(buffer);
7472  return ret;
7473  }
7474  buffer[len] = '\0';
7475  av_dict_set(&c->fc->metadata, "xmp",
7477  } else {
7478  // skip all uuid atom, which makes it fast for long uuid-xmp file
7479  ret = avio_skip(pb, len);
7480  if (ret < 0)
7481  return ret;
7482  }
7483  } else if (av_uuid_equal(uuid, uuid_spherical)) {
7484  size_t len = atom.size - AV_UUID_LEN;
7485  ret = mov_parse_uuid_spherical(sc, pb, len);
7486  if (ret < 0)
7487  return ret;
7488  if (!sc->spherical)
7489  av_log(c->fc, AV_LOG_WARNING, "Invalid spherical metadata found\n");
7490  }
7491 
7492  return 0;
7493 }
7494 
7496 {
7497  int ret;
7498  uint8_t content[16];
7499 
7500  if (atom.size < 8)
7501  return 0;
7502 
7503  ret = ffio_read_size(pb, content, FFMIN(sizeof(content), atom.size));
7504  if (ret < 0)
7505  return ret;
7506 
7507  if ( !c->found_moov
7508  && !c->found_mdat
7509  && !memcmp(content, "Anevia\x1A\x1A", 8)
7510  && c->use_mfra_for == FF_MOV_FLAG_MFRA_AUTO) {
7511  c->use_mfra_for = FF_MOV_FLAG_MFRA_PTS;
7512  }
7513 
7514  return 0;
7515 }
7516 
7518 {
7519  uint32_t format = avio_rl32(pb);
7520  MOVStreamContext *sc;
7521  enum AVCodecID id;
7522  AVStream *st;
7523 
7524  if (c->fc->nb_streams < 1)
7525  return 0;
7526  st = c->fc->streams[c->fc->nb_streams - 1];
7527  sc = st->priv_data;
7528 
7529  switch (sc->format)
7530  {
7531  case MKTAG('e','n','c','v'): // encrypted video
7532  case MKTAG('e','n','c','a'): // encrypted audio
7533  id = mov_codec_id(st, format);
7534  if (st->codecpar->codec_id != AV_CODEC_ID_NONE &&
7535  st->codecpar->codec_id != id) {
7536  av_log(c->fc, AV_LOG_WARNING,
7537  "ignoring 'frma' atom of '%.4s', stream has codec id %d\n",
7538  (char*)&format, st->codecpar->codec_id);
7539  break;
7540  }
7541 
7542  st->codecpar->codec_id = id;
7543  sc->format = format;
7544  break;
7545 
7546  default:
7547  if (format != sc->format) {
7548  av_log(c->fc, AV_LOG_WARNING,
7549  "ignoring 'frma' atom of '%.4s', stream format is '%.4s'\n",
7550  (char*)&format, (char*)&sc->format);
7551  }
7552  break;
7553  }
7554 
7555  return 0;
7556 }
7557 
7558 /**
7559  * Gets the current encryption info and associated current stream context. If
7560  * we are parsing a track fragment, this will return the specific encryption
7561  * info for this fragment; otherwise this will return the global encryption
7562  * info for the current stream.
7563  */
7565 {
7566  MOVFragmentStreamInfo *frag_stream_info;
7567  AVStream *st;
7568  int i;
7569 
7570  frag_stream_info = get_current_frag_stream_info(&c->frag_index);
7571  if (frag_stream_info) {
7572  for (i = 0; i < c->fc->nb_streams; i++) {
7573  *sc = c->fc->streams[i]->priv_data;
7574  if ((*sc)->id == frag_stream_info->id) {
7575  st = c->fc->streams[i];
7576  break;
7577  }
7578  }
7579  if (i == c->fc->nb_streams)
7580  return 0;
7581  *sc = st->priv_data;
7582 
7583  if (!frag_stream_info->encryption_index) {
7584  // If this stream isn't encrypted, don't create the index.
7585  if (!(*sc)->cenc.default_encrypted_sample)
7586  return 0;
7587  frag_stream_info->encryption_index = av_mallocz(sizeof(*frag_stream_info->encryption_index));
7588  if (!frag_stream_info->encryption_index)
7589  return AVERROR(ENOMEM);
7590  }
7591  *encryption_index = frag_stream_info->encryption_index;
7592  return 1;
7593  } else {
7594  // No current track fragment, using stream level encryption info.
7595 
7596  if (c->fc->nb_streams < 1)
7597  return 0;
7598  st = c->fc->streams[c->fc->nb_streams - 1];
7599  *sc = st->priv_data;
7600 
7601  if (!(*sc)->cenc.encryption_index) {
7602  // If this stream isn't encrypted, don't create the index.
7603  if (!(*sc)->cenc.default_encrypted_sample)
7604  return 0;
7605  (*sc)->cenc.encryption_index = av_mallocz(sizeof(*frag_stream_info->encryption_index));
7606  if (!(*sc)->cenc.encryption_index)
7607  return AVERROR(ENOMEM);
7608  }
7609 
7610  *encryption_index = (*sc)->cenc.encryption_index;
7611  return 1;
7612  }
7613 }
7614 
7616 {
7617  int i, ret;
7618  unsigned int subsample_count;
7619  AVSubsampleEncryptionInfo *subsamples;
7620 
7621  if (!sc->cenc.default_encrypted_sample) {
7622  av_log(c->fc, AV_LOG_ERROR, "Missing schm or tenc\n");
7623  return AVERROR_INVALIDDATA;
7624  }
7625 
7626  if (sc->cenc.per_sample_iv_size || use_subsamples) {
7628  if (!*sample)
7629  return AVERROR(ENOMEM);
7630  } else
7631  *sample = NULL;
7632 
7633  if (sc->cenc.per_sample_iv_size != 0) {
7634  if ((ret = ffio_read_size(pb, (*sample)->iv, sc->cenc.per_sample_iv_size)) < 0) {
7635  av_log(c->fc, AV_LOG_ERROR, "failed to read the initialization vector\n");
7637  *sample = NULL;
7638  return ret;
7639  }
7640  }
7641 
7642  if (use_subsamples) {
7643  subsample_count = avio_rb16(pb);
7644  av_free((*sample)->subsamples);
7645  (*sample)->subsamples = av_calloc(subsample_count, sizeof(*subsamples));
7646  if (!(*sample)->subsamples) {
7648  *sample = NULL;
7649  return AVERROR(ENOMEM);
7650  }
7651 
7652  for (i = 0; i < subsample_count && !pb->eof_reached; i++) {
7653  (*sample)->subsamples[i].bytes_of_clear_data = avio_rb16(pb);
7654  (*sample)->subsamples[i].bytes_of_protected_data = avio_rb32(pb);
7655  }
7656 
7657  if (pb->eof_reached) {
7658  av_log(c->fc, AV_LOG_ERROR, "hit EOF while reading sub-sample encryption info\n");
7660  *sample = NULL;
7661  return AVERROR_INVALIDDATA;
7662  }
7663  (*sample)->subsample_count = subsample_count;
7664  }
7665 
7666  return 0;
7667 }
7668 
7670 {
7671  AVEncryptionInfo **encrypted_samples;
7672  MOVEncryptionIndex *encryption_index;
7673  MOVStreamContext *sc;
7674  int use_subsamples, ret;
7675  unsigned int sample_count, i, alloc_size = 0;
7676 
7677  ret = get_current_encryption_info(c, &encryption_index, &sc);
7678  if (ret != 1)
7679  return ret;
7680 
7681  if (encryption_index->nb_encrypted_samples) {
7682  // This can happen if we have both saio/saiz and senc atoms.
7683  av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in senc\n");
7684  return 0;
7685  }
7686 
7687  avio_r8(pb); /* version */
7688  use_subsamples = avio_rb24(pb) & 0x02; /* flags */
7689 
7690  sample_count = avio_rb32(pb);
7691  if (sample_count >= INT_MAX / sizeof(*encrypted_samples))
7692  return AVERROR(ENOMEM);
7693 
7694  for (i = 0; i < sample_count; i++) {
7695  unsigned int min_samples = FFMIN(FFMAX(i + 1, 1024 * 1024), sample_count);
7696  encrypted_samples = av_fast_realloc(encryption_index->encrypted_samples, &alloc_size,
7697  min_samples * sizeof(*encrypted_samples));
7698  if (encrypted_samples) {
7699  encryption_index->encrypted_samples = encrypted_samples;
7700 
7702  c, pb, sc, &encryption_index->encrypted_samples[i], use_subsamples);
7703  } else {
7704  ret = AVERROR(ENOMEM);
7705  }
7706  if (pb->eof_reached) {
7707  av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading senc\n");
7708  if (ret >= 0)
7709  av_encryption_info_free(encryption_index->encrypted_samples[i]);
7711  }
7712 
7713  if (ret < 0) {
7714  for (; i > 0; i--)
7715  av_encryption_info_free(encryption_index->encrypted_samples[i - 1]);
7716  av_freep(&encryption_index->encrypted_samples);
7717  return ret;
7718  }
7719  }
7720  encryption_index->nb_encrypted_samples = sample_count;
7721 
7722  return 0;
7723 }
7724 
7726 {
7727  AVEncryptionInfo **sample, **encrypted_samples;
7728  int64_t prev_pos;
7729  size_t sample_count, sample_info_size, i;
7730  int ret = 0;
7731  unsigned int alloc_size = 0;
7732 
7733  if (encryption_index->nb_encrypted_samples)
7734  return 0;
7735  sample_count = encryption_index->auxiliary_info_sample_count;
7736  if (encryption_index->auxiliary_offsets_count != 1) {
7737  av_log(c->fc, AV_LOG_ERROR, "Multiple auxiliary info chunks are not supported\n");
7738  return AVERROR_PATCHWELCOME;
7739  }
7740  if (sample_count >= INT_MAX / sizeof(*encrypted_samples))
7741  return AVERROR(ENOMEM);
7742 
7743  prev_pos = avio_tell(pb);
7744  if (!(pb->seekable & AVIO_SEEKABLE_NORMAL) ||
7745  avio_seek(pb, encryption_index->auxiliary_offsets[0], SEEK_SET) != encryption_index->auxiliary_offsets[0]) {
7746  av_log(c->fc, AV_LOG_INFO, "Failed to seek for auxiliary info, will only parse senc atoms for encryption info\n");
7747  goto finish;
7748  }
7749 
7750  for (i = 0; i < sample_count && !pb->eof_reached; i++) {
7751  unsigned int min_samples = FFMIN(FFMAX(i + 1, 1024 * 1024), sample_count);
7752  encrypted_samples = av_fast_realloc(encryption_index->encrypted_samples, &alloc_size,
7753  min_samples * sizeof(*encrypted_samples));
7754  if (!encrypted_samples) {
7755  ret = AVERROR(ENOMEM);
7756  goto finish;
7757  }
7758  encryption_index->encrypted_samples = encrypted_samples;
7759 
7760  sample = &encryption_index->encrypted_samples[i];
7761  sample_info_size = encryption_index->auxiliary_info_default_size
7762  ? encryption_index->auxiliary_info_default_size
7763  : encryption_index->auxiliary_info_sizes[i];
7764 
7765  ret = mov_read_sample_encryption_info(c, pb, sc, sample, sample_info_size > sc->cenc.per_sample_iv_size);
7766  if (ret < 0)
7767  goto finish;
7768  }
7769  if (pb->eof_reached) {
7770  av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading auxiliary info\n");
7772  } else {
7773  encryption_index->nb_encrypted_samples = sample_count;
7774  }
7775 
7776 finish:
7777  avio_seek(pb, prev_pos, SEEK_SET);
7778  if (ret < 0) {
7779  for (; i > 0; i--) {
7780  av_encryption_info_free(encryption_index->encrypted_samples[i - 1]);
7781  }
7782  av_freep(&encryption_index->encrypted_samples);
7783  }
7784  return ret;
7785 }
7786 
7788 {
7789  MOVEncryptionIndex *encryption_index;
7790  MOVStreamContext *sc;
7791  int ret;
7792  unsigned int sample_count, aux_info_type, aux_info_param;
7793 
7794  ret = get_current_encryption_info(c, &encryption_index, &sc);
7795  if (ret != 1)
7796  return ret;
7797 
7798  if (encryption_index->nb_encrypted_samples) {
7799  // This can happen if we have both saio/saiz and senc atoms.
7800  av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in saiz\n");
7801  return 0;
7802  }
7803 
7804  if (encryption_index->auxiliary_info_sample_count) {
7805  av_log(c->fc, AV_LOG_ERROR, "Duplicate saiz atom\n");
7806  return AVERROR_INVALIDDATA;
7807  }
7808 
7809  avio_r8(pb); /* version */
7810  if (avio_rb24(pb) & 0x01) { /* flags */
7811  aux_info_type = avio_rb32(pb);
7812  aux_info_param = avio_rb32(pb);
7813  if (sc->cenc.default_encrypted_sample) {
7814  if (aux_info_type != sc->cenc.default_encrypted_sample->scheme) {
7815  av_log(c->fc, AV_LOG_DEBUG, "Ignoring saiz box with non-zero aux_info_type\n");
7816  return 0;
7817  }
7818  if (aux_info_param != 0) {
7819  av_log(c->fc, AV_LOG_DEBUG, "Ignoring saiz box with non-zero aux_info_type_parameter\n");
7820  return 0;
7821  }
7822  } else {
7823  // Didn't see 'schm' or 'tenc', so this isn't encrypted.
7824  if ((aux_info_type == MKBETAG('c','e','n','c') ||
7825  aux_info_type == MKBETAG('c','e','n','s') ||
7826  aux_info_type == MKBETAG('c','b','c','1') ||
7827  aux_info_type == MKBETAG('c','b','c','s')) &&
7828  aux_info_param == 0) {
7829  av_log(c->fc, AV_LOG_ERROR, "Saw encrypted saiz without schm/tenc\n");
7830  return AVERROR_INVALIDDATA;
7831  } else {
7832  return 0;
7833  }
7834  }
7835  } else if (!sc->cenc.default_encrypted_sample) {
7836  // Didn't see 'schm' or 'tenc', so this isn't encrypted.
7837  return 0;
7838  }
7839 
7840  encryption_index->auxiliary_info_default_size = avio_r8(pb);
7841  sample_count = avio_rb32(pb);
7842 
7843  if (encryption_index->auxiliary_info_default_size == 0) {
7844  if (sample_count == 0)
7845  return AVERROR_INVALIDDATA;
7846 
7847  encryption_index->auxiliary_info_sizes = av_malloc(sample_count);
7848  if (!encryption_index->auxiliary_info_sizes)
7849  return AVERROR(ENOMEM);
7850 
7851  ret = avio_read(pb, encryption_index->auxiliary_info_sizes, sample_count);
7852  if (ret != sample_count) {
7853  av_freep(&encryption_index->auxiliary_info_sizes);
7854 
7855  if (ret >= 0)
7857  av_log(c->fc, AV_LOG_ERROR, "Failed to read the auxiliary info, %s\n",
7858  av_err2str(ret));
7859  return ret;
7860  }
7861  }
7862  encryption_index->auxiliary_info_sample_count = sample_count;
7863 
7864  if (encryption_index->auxiliary_offsets_count) {
7865  return mov_parse_auxiliary_info(c, sc, pb, encryption_index);
7866  }
7867 
7868  return 0;
7869 }
7870 
7872 {
7873  uint64_t *auxiliary_offsets;
7874  MOVEncryptionIndex *encryption_index;
7875  MOVStreamContext *sc;
7876  int i, ret;
7877  unsigned int version, entry_count, aux_info_type, aux_info_param;
7878  unsigned int alloc_size = 0;
7879 
7880  ret = get_current_encryption_info(c, &encryption_index, &sc);
7881  if (ret != 1)
7882  return ret;
7883 
7884  if (encryption_index->nb_encrypted_samples) {
7885  // This can happen if we have both saio/saiz and senc atoms.
7886  av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in saio\n");
7887  return 0;
7888  }
7889 
7890  if (encryption_index->auxiliary_offsets_count) {
7891  av_log(c->fc, AV_LOG_ERROR, "Duplicate saio atom\n");
7892  return AVERROR_INVALIDDATA;
7893  }
7894 
7895  version = avio_r8(pb); /* version */
7896  if (avio_rb24(pb) & 0x01) { /* flags */
7897  aux_info_type = avio_rb32(pb);
7898  aux_info_param = avio_rb32(pb);
7899  if (sc->cenc.default_encrypted_sample) {
7900  if (aux_info_type != sc->cenc.default_encrypted_sample->scheme) {
7901  av_log(c->fc, AV_LOG_DEBUG, "Ignoring saio box with non-zero aux_info_type\n");
7902  return 0;
7903  }
7904  if (aux_info_param != 0) {
7905  av_log(c->fc, AV_LOG_DEBUG, "Ignoring saio box with non-zero aux_info_type_parameter\n");
7906  return 0;
7907  }
7908  } else {
7909  // Didn't see 'schm' or 'tenc', so this isn't encrypted.
7910  if ((aux_info_type == MKBETAG('c','e','n','c') ||
7911  aux_info_type == MKBETAG('c','e','n','s') ||
7912  aux_info_type == MKBETAG('c','b','c','1') ||
7913  aux_info_type == MKBETAG('c','b','c','s')) &&
7914  aux_info_param == 0) {
7915  av_log(c->fc, AV_LOG_ERROR, "Saw encrypted saio without schm/tenc\n");
7916  return AVERROR_INVALIDDATA;
7917  } else {
7918  return 0;
7919  }
7920  }
7921  } else if (!sc->cenc.default_encrypted_sample) {
7922  // Didn't see 'schm' or 'tenc', so this isn't encrypted.
7923  return 0;
7924  }
7925 
7926  entry_count = avio_rb32(pb);
7927  if (entry_count >= INT_MAX / sizeof(*auxiliary_offsets))
7928  return AVERROR(ENOMEM);
7929 
7930  for (i = 0; i < entry_count && !pb->eof_reached; i++) {
7931  unsigned int min_offsets = FFMIN(FFMAX(i + 1, 1024), entry_count);
7932  auxiliary_offsets = av_fast_realloc(
7933  encryption_index->auxiliary_offsets, &alloc_size,
7934  min_offsets * sizeof(*auxiliary_offsets));
7935  if (!auxiliary_offsets) {
7936  av_freep(&encryption_index->auxiliary_offsets);
7937  return AVERROR(ENOMEM);
7938  }
7939  encryption_index->auxiliary_offsets = auxiliary_offsets;
7940 
7941  if (version == 0) {
7942  encryption_index->auxiliary_offsets[i] = avio_rb32(pb);
7943  } else {
7944  encryption_index->auxiliary_offsets[i] = avio_rb64(pb);
7945  }
7946  if (c->frag_index.current >= 0) {
7947  encryption_index->auxiliary_offsets[i] += c->fragment.base_data_offset;
7948  }
7949  }
7950 
7951  if (pb->eof_reached) {
7952  av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading saio\n");
7953  av_freep(&encryption_index->auxiliary_offsets);
7954  return AVERROR_INVALIDDATA;
7955  }
7956 
7957  encryption_index->auxiliary_offsets_count = entry_count;
7958 
7959  if (encryption_index->auxiliary_info_sample_count) {
7960  return mov_parse_auxiliary_info(c, sc, pb, encryption_index);
7961  }
7962 
7963  return 0;
7964 }
7965 
7967 {
7968  AVEncryptionInitInfo *info, *old_init_info;
7969  uint8_t **key_ids;
7970  AVStream *st;
7971  const AVPacketSideData *old_side_data;
7972  uint8_t *side_data, *extra_data;
7973  size_t side_data_size;
7974  int ret = 0;
7975  unsigned int version, kid_count, extra_data_size, alloc_size = 0;
7976 
7977  if (c->fc->nb_streams < 1)
7978  return 0;
7979  st = c->fc->streams[c->fc->nb_streams-1];
7980 
7981  version = avio_r8(pb); /* version */
7982  avio_rb24(pb); /* flags */
7983 
7984  info = av_encryption_init_info_alloc(/* system_id_size */ 16, /* num_key_ids */ 0,
7985  /* key_id_size */ 16, /* data_size */ 0);
7986  if (!info)
7987  return AVERROR(ENOMEM);
7988 
7989  if ((ret = ffio_read_size(pb, info->system_id, 16)) < 0) {
7990  av_log(c->fc, AV_LOG_ERROR, "Failed to read the system id\n");
7991  goto finish;
7992  }
7993 
7994  if (version > 0) {
7995  kid_count = avio_rb32(pb);
7996  if (kid_count >= INT_MAX / sizeof(*key_ids)) {
7997  ret = AVERROR(ENOMEM);
7998  goto finish;
7999  }
8000 
8001  for (unsigned int i = 0; i < kid_count && !pb->eof_reached; i++) {
8002  unsigned int min_kid_count = FFMIN(FFMAX(i + 1, 1024), kid_count);
8003  key_ids = av_fast_realloc(info->key_ids, &alloc_size,
8004  min_kid_count * sizeof(*key_ids));
8005  if (!key_ids) {
8006  ret = AVERROR(ENOMEM);
8007  goto finish;
8008  }
8009  info->key_ids = key_ids;
8010 
8011  info->key_ids[i] = av_mallocz(16);
8012  if (!info->key_ids[i]) {
8013  ret = AVERROR(ENOMEM);
8014  goto finish;
8015  }
8016  info->num_key_ids = i + 1;
8017 
8018  if ((ret = ffio_read_size(pb, info->key_ids[i], 16)) < 0) {
8019  av_log(c->fc, AV_LOG_ERROR, "Failed to read the key id\n");
8020  goto finish;
8021  }
8022  }
8023 
8024  if (pb->eof_reached) {
8025  av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading pssh\n");
8027  goto finish;
8028  }
8029  }
8030 
8031  extra_data_size = avio_rb32(pb);
8032  extra_data = av_malloc(extra_data_size);
8033  if (!extra_data) {
8034  ret = AVERROR(ENOMEM);
8035  goto finish;
8036  }
8037  ret = avio_read(pb, extra_data, extra_data_size);
8038  if (ret != extra_data_size) {
8039  av_free(extra_data);
8040 
8041  if (ret >= 0)
8043  goto finish;
8044  }
8045 
8046  av_freep(&info->data); // malloc(0) may still allocate something.
8047  info->data = extra_data;
8048  info->data_size = extra_data_size;
8049 
8050  // If there is existing initialization data, append to the list.
8053  if (old_side_data) {
8054  old_init_info = av_encryption_init_info_get_side_data(old_side_data->data, old_side_data->size);
8055  if (old_init_info) {
8056  // Append to the end of the list.
8057  for (AVEncryptionInitInfo *cur = old_init_info;; cur = cur->next) {
8058  if (!cur->next) {
8059  cur->next = info;
8060  break;
8061  }
8062  }
8063  info = old_init_info;
8064  } else {
8065  // Assume existing side-data will be valid, so the only error we could get is OOM.
8066  ret = AVERROR(ENOMEM);
8067  goto finish;
8068  }
8069  }
8070 
8071  side_data = av_encryption_init_info_add_side_data(info, &side_data_size);
8072  if (!side_data) {
8073  ret = AVERROR(ENOMEM);
8074  goto finish;
8075  }
8079  side_data, side_data_size, 0))
8080  av_free(side_data);
8081 
8082 finish:
8084  return ret;
8085 }
8086 
8088 {
8089  AVStream *st;
8090  MOVStreamContext *sc;
8091 
8092  if (c->fc->nb_streams < 1)
8093  return 0;
8094  st = c->fc->streams[c->fc->nb_streams-1];
8095  sc = st->priv_data;
8096 
8097  if (sc->pseudo_stream_id != 0) {
8098  av_log(c->fc, AV_LOG_ERROR, "schm boxes are only supported in first sample descriptor\n");
8099  return AVERROR_PATCHWELCOME;
8100  }
8101 
8102  if (atom.size < 8)
8103  return AVERROR_INVALIDDATA;
8104 
8105  avio_rb32(pb); /* version and flags */
8106 
8107  if (!sc->cenc.default_encrypted_sample) {
8109  if (!sc->cenc.default_encrypted_sample) {
8110  return AVERROR(ENOMEM);
8111  }
8112  }
8113 
8115  return 0;
8116 }
8117 
8119 {
8120  AVStream *st;
8121  MOVStreamContext *sc;
8122  unsigned int version, pattern, is_protected, iv_size;
8123 
8124  if (c->fc->nb_streams < 1)
8125  return 0;
8126  st = c->fc->streams[c->fc->nb_streams-1];
8127  sc = st->priv_data;
8128 
8129  if (sc->pseudo_stream_id != 0) {
8130  av_log(c->fc, AV_LOG_ERROR, "tenc atom are only supported in first sample descriptor\n");
8131  return AVERROR_PATCHWELCOME;
8132  }
8133 
8134  if (!sc->cenc.default_encrypted_sample) {
8136  if (!sc->cenc.default_encrypted_sample) {
8137  return AVERROR(ENOMEM);
8138  }
8139  }
8140 
8141  if (atom.size < 20)
8142  return AVERROR_INVALIDDATA;
8143 
8144  version = avio_r8(pb); /* version */
8145  avio_rb24(pb); /* flags */
8146 
8147  avio_r8(pb); /* reserved */
8148  pattern = avio_r8(pb);
8149 
8150  if (version > 0) {
8151  sc->cenc.default_encrypted_sample->crypt_byte_block = pattern >> 4;
8152  sc->cenc.default_encrypted_sample->skip_byte_block = pattern & 0xf;
8153  }
8154 
8155  is_protected = avio_r8(pb);
8156  if (is_protected && !sc->cenc.encryption_index) {
8157  // The whole stream should be by-default encrypted.
8159  if (!sc->cenc.encryption_index)
8160  return AVERROR(ENOMEM);
8161  }
8162  sc->cenc.per_sample_iv_size = avio_r8(pb);
8163  if (sc->cenc.per_sample_iv_size != 0 && sc->cenc.per_sample_iv_size != 8 &&
8164  sc->cenc.per_sample_iv_size != 16) {
8165  av_log(c->fc, AV_LOG_ERROR, "invalid per-sample IV size value\n");
8166  return AVERROR_INVALIDDATA;
8167  }
8168  if (avio_read(pb, sc->cenc.default_encrypted_sample->key_id, 16) != 16) {
8169  av_log(c->fc, AV_LOG_ERROR, "failed to read the default key ID\n");
8170  return AVERROR_INVALIDDATA;
8171  }
8172 
8173  if (is_protected && !sc->cenc.per_sample_iv_size) {
8174  iv_size = avio_r8(pb);
8175  if (iv_size != 8 && iv_size != 16) {
8176  av_log(c->fc, AV_LOG_ERROR, "invalid default_constant_IV_size in tenc atom\n");
8177  return AVERROR_INVALIDDATA;
8178  }
8179 
8180  if (avio_read(pb, sc->cenc.default_encrypted_sample->iv, iv_size) != iv_size) {
8181  av_log(c->fc, AV_LOG_ERROR, "failed to read the default IV\n");
8182  return AVERROR_INVALIDDATA;
8183  }
8184  }
8185 
8186  return 0;
8187 }
8188 
8190 {
8191  AVStream *st;
8192  int last, type, size, ret;
8193  uint8_t buf[4];
8194 
8195  if (c->fc->nb_streams < 1)
8196  return 0;
8197  st = c->fc->streams[c->fc->nb_streams-1];
8198 
8199  if ((uint64_t)atom.size > (1<<30) || atom.size < 42)
8200  return AVERROR_INVALIDDATA;
8201 
8202  /* Check FlacSpecificBox version. */
8203  if (avio_r8(pb) != 0)
8204  return AVERROR_INVALIDDATA;
8205 
8206  avio_rb24(pb); /* Flags */
8207 
8208  if (avio_read(pb, buf, sizeof(buf)) != sizeof(buf)) {
8209  av_log(c->fc, AV_LOG_ERROR, "failed to read FLAC metadata block header\n");
8210  return pb->error < 0 ? pb->error : AVERROR_INVALIDDATA;
8211  }
8212  flac_parse_block_header(buf, &last, &type, &size);
8213 
8215  av_log(c->fc, AV_LOG_ERROR, "STREAMINFO must be first FLACMetadataBlock\n");
8216  return AVERROR_INVALIDDATA;
8217  }
8218 
8219  ret = ff_get_extradata(c->fc, st->codecpar, pb, size);
8220  if (ret < 0)
8221  return ret;
8222 
8223  if (!last)
8224  av_log(c->fc, AV_LOG_WARNING, "non-STREAMINFO FLACMetadataBlock(s) ignored\n");
8225 
8226  return 0;
8227 }
8228 
8229 static int get_key_from_kid(uint8_t* out, int len, MOVContext *c, AVEncryptionInfo *sample) {
8230  AVDictionaryEntry *key_entry_hex;
8231  char kid_hex[16*2+1];
8232 
8233  if (c->decryption_default_key && c->decryption_default_key_len != len) {
8234  av_log(c->fc, AV_LOG_ERROR, "invalid default decryption key length: got %d, expected %d\n", c->decryption_default_key_len, len);
8235  return -1;
8236  }
8237 
8238  if (!c->decryption_keys) {
8239  av_assert0(c->decryption_default_key);
8240  memcpy(out, c->decryption_default_key, len);
8241  return 0;
8242  }
8243 
8244  if (sample->key_id_size != 16) {
8245  av_log(c->fc, AV_LOG_ERROR, "invalid key ID size: got %u, expected 16\n", sample->key_id_size);
8246  return -1;
8247  }
8248 
8249  ff_data_to_hex(kid_hex, sample->key_id, 16, 1);
8250  key_entry_hex = av_dict_get(c->decryption_keys, kid_hex, NULL, AV_DICT_DONT_STRDUP_KEY|AV_DICT_DONT_STRDUP_VAL);
8251  if (!key_entry_hex) {
8252  if (!c->decryption_default_key) {
8253  av_log(c->fc, AV_LOG_ERROR, "unable to find KID %s\n", kid_hex);
8254  return -1;
8255  }
8256  memcpy(out, c->decryption_default_key, len);
8257  return 0;
8258  }
8259  if (strlen(key_entry_hex->value) != len*2) {
8260  return -1;
8261  }
8262  ff_hex_to_data(out, key_entry_hex->value);
8263  return 0;
8264 }
8265 
8267 {
8268  int i, ret;
8269  int bytes_of_protected_data;
8270  uint8_t decryption_key[AES_CTR_KEY_SIZE];
8271 
8272  if (!sc->cenc.aes_ctr) {
8273  ret = get_key_from_kid(decryption_key, sizeof(decryption_key), c, sample);
8274  if (ret < 0) {
8275  return ret;
8276  }
8277 
8278  /* initialize the cipher */
8279  sc->cenc.aes_ctr = av_aes_ctr_alloc();
8280  if (!sc->cenc.aes_ctr) {
8281  return AVERROR(ENOMEM);
8282  }
8283 
8284  ret = av_aes_ctr_init(sc->cenc.aes_ctr, decryption_key);
8285  if (ret < 0) {
8286  return ret;
8287  }
8288  }
8289 
8291 
8292  if (!sample->subsample_count) {
8293  /* decrypt the whole packet */
8295  return 0;
8296  }
8297 
8298  for (i = 0; i < sample->subsample_count; i++) {
8299  if (sample->subsamples[i].bytes_of_clear_data + (int64_t)sample->subsamples[i].bytes_of_protected_data > size) {
8300  av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n");
8301  return AVERROR_INVALIDDATA;
8302  }
8303 
8304  /* skip the clear bytes */
8305  input += sample->subsamples[i].bytes_of_clear_data;
8306  size -= sample->subsamples[i].bytes_of_clear_data;
8307 
8308  /* decrypt the encrypted bytes */
8309 
8310  bytes_of_protected_data = sample->subsamples[i].bytes_of_protected_data;
8311  av_aes_ctr_crypt(sc->cenc.aes_ctr, input, input, bytes_of_protected_data);
8312 
8313  input += bytes_of_protected_data;
8314  size -= bytes_of_protected_data;
8315  }
8316 
8317  if (size > 0) {
8318  av_log(c->fc, AV_LOG_ERROR, "leftover packet bytes after subsample processing\n");
8319  return AVERROR_INVALIDDATA;
8320  }
8321 
8322  return 0;
8323 }
8324 
8326 {
8327  int i, ret;
8328  int num_of_encrypted_blocks;
8329  uint8_t iv[16];
8330  uint8_t decryption_key[16];
8331 
8332  if (!sc->cenc.aes_ctx) {
8333  ret = get_key_from_kid(decryption_key, sizeof(decryption_key), c, sample);
8334  if (ret < 0) {
8335  return ret;
8336  }
8337 
8338  /* initialize the cipher */
8339  sc->cenc.aes_ctx = av_aes_alloc();
8340  if (!sc->cenc.aes_ctx) {
8341  return AVERROR(ENOMEM);
8342  }
8343 
8344  ret = av_aes_init(sc->cenc.aes_ctx, decryption_key, 16 * 8, 1);
8345  if (ret < 0) {
8346  return ret;
8347  }
8348  }
8349 
8350  memcpy(iv, sample->iv, 16);
8351 
8352  /* whole-block full sample encryption */
8353  if (!sample->subsample_count) {
8354  /* decrypt the whole packet */
8355  av_aes_crypt(sc->cenc.aes_ctx, input, input, size/16, iv, 1);
8356  return 0;
8357  }
8358 
8359  for (i = 0; i < sample->subsample_count; i++) {
8360  if (sample->subsamples[i].bytes_of_clear_data + (int64_t)sample->subsamples[i].bytes_of_protected_data > size) {
8361  av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n");
8362  return AVERROR_INVALIDDATA;
8363  }
8364 
8365  if (sample->subsamples[i].bytes_of_protected_data % 16) {
8366  av_log(c->fc, AV_LOG_ERROR, "subsample BytesOfProtectedData is not a multiple of 16\n");
8367  return AVERROR_INVALIDDATA;
8368  }
8369 
8370  /* skip the clear bytes */
8371  input += sample->subsamples[i].bytes_of_clear_data;
8372  size -= sample->subsamples[i].bytes_of_clear_data;
8373 
8374  /* decrypt the encrypted bytes */
8375  num_of_encrypted_blocks = sample->subsamples[i].bytes_of_protected_data/16;
8376  if (num_of_encrypted_blocks > 0) {
8377  av_aes_crypt(sc->cenc.aes_ctx, input, input, num_of_encrypted_blocks, iv, 1);
8378  }
8379  input += sample->subsamples[i].bytes_of_protected_data;
8380  size -= sample->subsamples[i].bytes_of_protected_data;
8381  }
8382 
8383  if (size > 0) {
8384  av_log(c->fc, AV_LOG_ERROR, "leftover packet bytes after subsample processing\n");
8385  return AVERROR_INVALIDDATA;
8386  }
8387 
8388  return 0;
8389 }
8390 
8392 {
8393  int i, ret, rem_bytes;
8394  uint8_t *data;
8395  uint8_t decryption_key[AES_CTR_KEY_SIZE];
8396 
8397  if (!sc->cenc.aes_ctr) {
8398  ret = get_key_from_kid(decryption_key, sizeof(decryption_key), c, sample);
8399  if (ret < 0) {
8400  return ret;
8401  }
8402 
8403  /* initialize the cipher */
8404  sc->cenc.aes_ctr = av_aes_ctr_alloc();
8405  if (!sc->cenc.aes_ctr) {
8406  return AVERROR(ENOMEM);
8407  }
8408 
8409  ret = av_aes_ctr_init(sc->cenc.aes_ctr, decryption_key);
8410  if (ret < 0) {
8411  return ret;
8412  }
8413  }
8414 
8416 
8417  /* whole-block full sample encryption */
8418  if (!sample->subsample_count) {
8419  /* decrypt the whole packet */
8421  return 0;
8422  } else if (!sample->crypt_byte_block && !sample->skip_byte_block) {
8423  av_log(c->fc, AV_LOG_ERROR, "pattern encryption is not present in 'cens' scheme\n");
8424  return AVERROR_INVALIDDATA;
8425  }
8426 
8427  for (i = 0; i < sample->subsample_count; i++) {
8428  if (sample->subsamples[i].bytes_of_clear_data + (int64_t)sample->subsamples[i].bytes_of_protected_data > size) {
8429  av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n");
8430  return AVERROR_INVALIDDATA;
8431  }
8432 
8433  /* skip the clear bytes */
8434  input += sample->subsamples[i].bytes_of_clear_data;
8435  size -= sample->subsamples[i].bytes_of_clear_data;
8436 
8437  /* decrypt the encrypted bytes */
8438  data = input;
8439  rem_bytes = sample->subsamples[i].bytes_of_protected_data;
8440  while (rem_bytes > 0) {
8441  if (rem_bytes < 16*sample->crypt_byte_block) {
8442  break;
8443  }
8444  av_aes_ctr_crypt(sc->cenc.aes_ctr, data, data, 16*sample->crypt_byte_block);
8445  data += 16*sample->crypt_byte_block;
8446  rem_bytes -= 16*sample->crypt_byte_block;
8447  data += FFMIN(16*sample->skip_byte_block, rem_bytes);
8448  rem_bytes -= FFMIN(16*sample->skip_byte_block, rem_bytes);
8449  }
8450  input += sample->subsamples[i].bytes_of_protected_data;
8451  size -= sample->subsamples[i].bytes_of_protected_data;
8452  }
8453 
8454  if (size > 0) {
8455  av_log(c->fc, AV_LOG_ERROR, "leftover packet bytes after subsample processing\n");
8456  return AVERROR_INVALIDDATA;
8457  }
8458 
8459  return 0;
8460 }
8461 
8463 {
8464  int i, ret, rem_bytes;
8465  uint8_t iv[16];
8466  uint8_t *data;
8467  uint8_t decryption_key[16];
8468 
8469  if (!sc->cenc.aes_ctx) {
8470  ret = get_key_from_kid(decryption_key, sizeof(decryption_key), c, sample);
8471  if (ret < 0) {
8472  return ret;
8473  }
8474 
8475  /* initialize the cipher */
8476  sc->cenc.aes_ctx = av_aes_alloc();
8477  if (!sc->cenc.aes_ctx) {
8478  return AVERROR(ENOMEM);
8479  }
8480 
8481  ret = av_aes_init(sc->cenc.aes_ctx, decryption_key, 16 * 8, 1);
8482  if (ret < 0) {
8483  return ret;
8484  }
8485  }
8486 
8487  /* whole-block full sample encryption */
8488  if (!sample->subsample_count) {
8489  /* decrypt the whole packet */
8490  memcpy(iv, sample->iv, 16);
8491  av_aes_crypt(sc->cenc.aes_ctx, input, input, size/16, iv, 1);
8492  return 0;
8493  } else if (!sample->crypt_byte_block && !sample->skip_byte_block) {
8494  av_log(c->fc, AV_LOG_ERROR, "pattern encryption is not present in 'cbcs' scheme\n");
8495  return AVERROR_INVALIDDATA;
8496  }
8497 
8498  for (i = 0; i < sample->subsample_count; i++) {
8499  if (sample->subsamples[i].bytes_of_clear_data + (int64_t)sample->subsamples[i].bytes_of_protected_data > size) {
8500  av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n");
8501  return AVERROR_INVALIDDATA;
8502  }
8503 
8504  /* skip the clear bytes */
8505  input += sample->subsamples[i].bytes_of_clear_data;
8506  size -= sample->subsamples[i].bytes_of_clear_data;
8507 
8508  /* decrypt the encrypted bytes */
8509  memcpy(iv, sample->iv, 16);
8510  data = input;
8511  rem_bytes = sample->subsamples[i].bytes_of_protected_data;
8512  while (rem_bytes > 0) {
8513  if (rem_bytes < 16*sample->crypt_byte_block) {
8514  break;
8515  }
8516  av_aes_crypt(sc->cenc.aes_ctx, data, data, sample->crypt_byte_block, iv, 1);
8517  data += 16*sample->crypt_byte_block;
8518  rem_bytes -= 16*sample->crypt_byte_block;
8519  data += FFMIN(16*sample->skip_byte_block, rem_bytes);
8520  rem_bytes -= FFMIN(16*sample->skip_byte_block, rem_bytes);
8521  }
8522  input += sample->subsamples[i].bytes_of_protected_data;
8523  size -= sample->subsamples[i].bytes_of_protected_data;
8524  }
8525 
8526  if (size > 0) {
8527  av_log(c->fc, AV_LOG_ERROR, "leftover packet bytes after subsample processing\n");
8528  return AVERROR_INVALIDDATA;
8529  }
8530 
8531  return 0;
8532 }
8533 
8535 {
8536  if (sample->scheme == MKBETAG('c','e','n','c') && !sample->crypt_byte_block && !sample->skip_byte_block) {
8537  return cenc_scheme_decrypt(c, sc, sample, input, size);
8538  } else if (sample->scheme == MKBETAG('c','b','c','1') && !sample->crypt_byte_block && !sample->skip_byte_block) {
8539  return cbc1_scheme_decrypt(c, sc, sample, input, size);
8540  } else if (sample->scheme == MKBETAG('c','e','n','s')) {
8541  return cens_scheme_decrypt(c, sc, sample, input, size);
8542  } else if (sample->scheme == MKBETAG('c','b','c','s')) {
8543  return cbcs_scheme_decrypt(c, sc, sample, input, size);
8544  } else {
8545  av_log(c->fc, AV_LOG_ERROR, "invalid encryption scheme\n");
8546  return AVERROR_INVALIDDATA;
8547  }
8548 }
8549 
8551 {
8552  int current = frag_index->current;
8553 
8554  if (!frag_index->nb_items)
8555  return NULL;
8556 
8557  // Check frag_index->current is the right one for pkt. It can out of sync.
8558  if (current >= 0 && current < frag_index->nb_items) {
8559  if (frag_index->item[current].moof_offset < pkt->pos &&
8560  (current + 1 == frag_index->nb_items ||
8561  frag_index->item[current + 1].moof_offset > pkt->pos))
8562  return get_frag_stream_info(frag_index, current, id);
8563  }
8564 
8565 
8566  for (int i = 0; i < frag_index->nb_items; i++) {
8567  if (frag_index->item[i].moof_offset > pkt->pos)
8568  break;
8569  current = i;
8570  }
8571  frag_index->current = current;
8572  return get_frag_stream_info(frag_index, current, id);
8573 }
8574 
8575 static int cenc_filter(MOVContext *mov, AVStream* st, MOVStreamContext *sc, AVPacket *pkt, int current_index)
8576 {
8577  MOVFragmentStreamInfo *frag_stream_info;
8578  MOVEncryptionIndex *encryption_index;
8579  AVEncryptionInfo *encrypted_sample;
8580  int encrypted_index, ret;
8581 
8582  frag_stream_info = get_frag_stream_info_from_pkt(&mov->frag_index, pkt, sc->id);
8583  encrypted_index = current_index;
8584  encryption_index = NULL;
8585  if (frag_stream_info) {
8586  // Note this only supports encryption info in the first sample descriptor.
8587  if (frag_stream_info->stsd_id == 1) {
8588  if (frag_stream_info->encryption_index) {
8589  encrypted_index = current_index - frag_stream_info->index_base;
8590  encryption_index = frag_stream_info->encryption_index;
8591  } else {
8592  encryption_index = sc->cenc.encryption_index;
8593  }
8594  }
8595  } else {
8596  encryption_index = sc->cenc.encryption_index;
8597  }
8598 
8599  if (encryption_index) {
8600  if (encryption_index->auxiliary_info_sample_count &&
8601  !encryption_index->nb_encrypted_samples) {
8602  av_log(mov->fc, AV_LOG_ERROR, "saiz atom found without saio\n");
8603  return AVERROR_INVALIDDATA;
8604  }
8605  if (encryption_index->auxiliary_offsets_count &&
8606  !encryption_index->nb_encrypted_samples) {
8607  av_log(mov->fc, AV_LOG_ERROR, "saio atom found without saiz\n");
8608  return AVERROR_INVALIDDATA;
8609  }
8610 
8611  encrypted_sample = NULL;
8612  if (!encryption_index->nb_encrypted_samples) {
8613  // Full-sample encryption with default settings.
8614  encrypted_sample = sc->cenc.default_encrypted_sample;
8615  } else if (encrypted_index >= 0 && encrypted_index < encryption_index->nb_encrypted_samples) {
8616  // Per-sample setting override.
8617  encrypted_sample = encryption_index->encrypted_samples[encrypted_index];
8618  if (!encrypted_sample) {
8619  encrypted_sample = sc->cenc.default_encrypted_sample;
8620  }
8621  }
8622 
8623  if (!encrypted_sample) {
8624  av_log(mov->fc, AV_LOG_ERROR, "Incorrect number of samples in encryption info\n");
8625  return AVERROR_INVALIDDATA;
8626  }
8627 
8628  if (mov->decryption_keys || mov->decryption_default_key) {
8629  return cenc_decrypt(mov, sc, encrypted_sample, pkt->data, pkt->size);
8630  } else {
8631  size_t size;
8632  uint8_t *side_data = av_encryption_info_add_side_data(encrypted_sample, &size);
8633  if (!side_data)
8634  return AVERROR(ENOMEM);
8636  if (ret < 0)
8637  av_free(side_data);
8638  return ret;
8639  }
8640  }
8641 
8642  return 0;
8643 }
8644 
8646 {
8647  const int OPUS_SEEK_PREROLL_MS = 80;
8648  int ret;
8649  AVStream *st;
8650  size_t size;
8651  uint16_t pre_skip;
8652 
8653  if (c->fc->nb_streams < 1)
8654  return 0;
8655  st = c->fc->streams[c->fc->nb_streams-1];
8656 
8657  if ((uint64_t)atom.size > (1<<30) || atom.size < 11 || st->codecpar->extradata)
8658  return AVERROR_INVALIDDATA;
8659 
8660  /* Check OpusSpecificBox version. */
8661  if (avio_r8(pb) != 0) {
8662  av_log(c->fc, AV_LOG_ERROR, "unsupported OpusSpecificBox version\n");
8663  return AVERROR_INVALIDDATA;
8664  }
8665 
8666  /* OpusSpecificBox size plus magic for Ogg OpusHead header. */
8667  size = atom.size + 8;
8668 
8669  if ((ret = ff_alloc_extradata(st->codecpar, size)) < 0)
8670  return ret;
8671 
8672  AV_WL32A(st->codecpar->extradata, MKTAG('O','p','u','s'));
8673  AV_WL32A(st->codecpar->extradata + 4, MKTAG('H','e','a','d'));
8674  AV_WB8(st->codecpar->extradata + 8, 1); /* OpusHead version */
8675  if ((ret = ffio_read_size(pb, st->codecpar->extradata + 9, size - 9)) < 0) {
8676  av_freep(&st->codecpar->extradata);
8677  st->codecpar->extradata_size = 0;
8678  return ret;
8679  }
8680 
8681  /* OpusSpecificBox is stored in big-endian, but OpusHead is
8682  little-endian; aside from the preceding magic and version they're
8683  otherwise currently identical. Data after output gain at offset 16
8684  doesn't need to be bytewapped. */
8685  pre_skip = AV_RB16A(st->codecpar->extradata + 10);
8686  AV_WL16A(st->codecpar->extradata + 10, pre_skip);
8687  AV_WL32A(st->codecpar->extradata + 12, AV_RB32A(st->codecpar->extradata + 12));
8688  AV_WL16A(st->codecpar->extradata + 16, AV_RB16A(st->codecpar->extradata + 16));
8689 
8690  st->codecpar->initial_padding = pre_skip;
8692  (AVRational){1, 1000},
8693  (AVRational){1, 48000});
8694 
8695  return 0;
8696 }
8697 
8699 {
8700  AVStream *st;
8701  unsigned format_info;
8702  int channel_assignment, channel_assignment1, channel_assignment2;
8703  int ratebits;
8704  uint64_t chmask;
8705 
8706  if (c->fc->nb_streams < 1)
8707  return 0;
8708  st = c->fc->streams[c->fc->nb_streams-1];
8709 
8710  if (atom.size < 10)
8711  return AVERROR_INVALIDDATA;
8712 
8713  format_info = avio_rb32(pb);
8714 
8715  ratebits = (format_info >> 28) & 0xF;
8716  channel_assignment1 = (format_info >> 15) & 0x1F;
8717  channel_assignment2 = format_info & 0x1FFF;
8718  if (channel_assignment2)
8719  channel_assignment = channel_assignment2;
8720  else
8721  channel_assignment = channel_assignment1;
8722 
8723  st->codecpar->frame_size = 40 << (ratebits & 0x7);
8724  st->codecpar->sample_rate = mlp_samplerate(ratebits);
8725 
8727  chmask = truehd_layout(channel_assignment);
8729 
8730  return 0;
8731 }
8732 
8734 {
8735  AVStream *st;
8736  uint8_t buf[ISOM_DVCC_DVVC_SIZE];
8737  int ret;
8738  int64_t read_size = atom.size;
8739 
8740  if (c->fc->nb_streams < 1)
8741  return 0;
8742  st = c->fc->streams[c->fc->nb_streams-1];
8743 
8744  // At most 24 bytes
8745  read_size = FFMIN(read_size, ISOM_DVCC_DVVC_SIZE);
8746 
8747  if ((ret = ffio_read_size(pb, buf, read_size)) < 0)
8748  return ret;
8749 
8750  return ff_isom_parse_dvcc_dvvc(c->fc, st, buf, read_size);
8751 }
8752 
8754 {
8755  AVStream *st;
8756  uint8_t *buf;
8757  int ret, old_size, num_arrays;
8758 
8759  if (c->fc->nb_streams < 1)
8760  return 0;
8761  st = c->fc->streams[c->fc->nb_streams-1];
8762 
8763  if (!st->codecpar->extradata_size)
8764  // TODO: handle lhvC when present before hvcC
8765  return 0;
8766 
8767  if (atom.size < 6 || st->codecpar->extradata_size < 23 ||
8768  atom.size > INT_MAX - AV_INPUT_BUFFER_PADDING_SIZE) {
8769  return AVERROR_INVALIDDATA;
8770  }
8771 
8773  if (!buf)
8774  return AVERROR(ENOMEM);
8775  memset(buf + atom.size, 0, AV_INPUT_BUFFER_PADDING_SIZE);
8776 
8777  ret = ffio_read_size(pb, buf, atom.size);
8778  if (ret < 0) {
8779  av_free(buf);
8780  av_log(c->fc, AV_LOG_WARNING, "lhvC atom truncated\n");
8781  return 0;
8782  }
8783 
8784  num_arrays = buf[5];
8785  old_size = st->codecpar->extradata_size;
8786  atom.size -= 8 /* account for mov_realloc_extradata offsetting */
8787  + 6 /* lhvC bytes before the arrays*/;
8788 
8789  ret = mov_realloc_extradata(st->codecpar, atom);
8790  if (ret < 0) {
8791  av_free(buf);
8792  return ret;
8793  }
8794 
8795  st->codecpar->extradata[22] += num_arrays;
8796  memcpy(st->codecpar->extradata + old_size, buf + 6, atom.size + 8);
8797 
8799 
8800  av_free(buf);
8801  return 0;
8802 }
8803 
8805 {
8806  AVFormatContext *ctx = c->fc;
8807  AVStream *st = NULL;
8808  AVBPrint scheme_buf, value_buf;
8809  int64_t scheme_str_len = 0, value_str_len = 0;
8810  int version, flags, ret = AVERROR_BUG;
8811  int64_t size = atom.size;
8812 
8813  if (atom.size < 6)
8814  // 4 bytes for version + flags, 2x 1 byte for null
8815  return AVERROR_INVALIDDATA;
8816 
8817  if (c->fc->nb_streams < 1)
8818  return 0;
8819  st = c->fc->streams[c->fc->nb_streams-1];
8820 
8821  version = avio_r8(pb);
8822  flags = avio_rb24(pb);
8823  size -= 4;
8824 
8825  if (version != 0 || flags != 0) {
8827  "Unsupported 'kind' box with version %d, flags: %x",
8828  version, flags);
8829  return AVERROR_INVALIDDATA;
8830  }
8831 
8832  av_bprint_init(&scheme_buf, 0, AV_BPRINT_SIZE_UNLIMITED);
8833  av_bprint_init(&value_buf, 0, AV_BPRINT_SIZE_UNLIMITED);
8834 
8835  if ((scheme_str_len = ff_read_string_to_bprint_overwrite(pb, &scheme_buf,
8836  size)) < 0) {
8837  ret = scheme_str_len;
8838  goto cleanup;
8839  }
8840 
8841  if (scheme_str_len + 1 >= size) {
8842  // we need to have another string, even if nullptr.
8843  // we check with + 1 since we expect that if size was not hit,
8844  // an additional null was read.
8846  goto cleanup;
8847  }
8848 
8849  size -= scheme_str_len + 1;
8850 
8851  if ((value_str_len = ff_read_string_to_bprint_overwrite(pb, &value_buf,
8852  size)) < 0) {
8853  ret = value_str_len;
8854  goto cleanup;
8855  }
8856 
8857  if (value_str_len == size) {
8858  // in case of no trailing null, box is not valid.
8860  goto cleanup;
8861  }
8862 
8864  "%s stream %d KindBox(scheme: %s, value: %s)\n",
8866  st->index,
8867  scheme_buf.str, value_buf.str);
8868 
8869  for (int i = 0; ff_mov_track_kind_table[i].scheme_uri; i++) {
8871  if (!av_strstart(scheme_buf.str, map.scheme_uri, NULL))
8872  continue;
8873 
8874  for (int j = 0; map.value_maps[j].disposition; j++) {
8875  const struct MP4TrackKindValueMapping value_map = map.value_maps[j];
8876  if (!av_strstart(value_buf.str, value_map.value, NULL))
8877  continue;
8878 
8879  st->disposition |= value_map.disposition;
8880  }
8881  }
8882 
8883  ret = 0;
8884 
8885 cleanup:
8886 
8887  av_bprint_finalize(&scheme_buf, NULL);
8888  av_bprint_finalize(&value_buf, NULL);
8889 
8890  return ret;
8891 }
8892 
8894 {
8895  AVStream *st;
8896  AVChannelLayout ch_layout = { 0 };
8897  int ret, i, version, type;
8898  int ambisonic_order, channel_order, normalization, channel_count;
8899  int ambi_channels, non_diegetic_channels;
8900 
8901  if (c->fc->nb_streams < 1)
8902  return 0;
8903 
8904  st = c->fc->streams[c->fc->nb_streams - 1];
8905 
8906  if (atom.size < 16) {
8907  av_log(c->fc, AV_LOG_ERROR, "SA3D audio box too small\n");
8908  return AVERROR_INVALIDDATA;
8909  }
8910 
8911  version = avio_r8(pb);
8912  if (version) {
8913  av_log(c->fc, AV_LOG_WARNING, "Unsupported SA3D box version %d\n", version);
8914  return 0;
8915  }
8916 
8917  type = avio_r8(pb);
8918  if (type & 0x7f) {
8919  av_log(c->fc, AV_LOG_WARNING,
8920  "Unsupported ambisonic type %d\n", type & 0x7f);
8921  return 0;
8922  }
8923  non_diegetic_channels = (type >> 7) * 2; // head_locked_stereo
8924 
8925  ambisonic_order = avio_rb32(pb);
8926 
8927  channel_order = avio_r8(pb);
8928  if (channel_order) {
8929  av_log(c->fc, AV_LOG_WARNING,
8930  "Unsupported channel_order %d\n", channel_order);
8931  return 0;
8932  }
8933 
8934  normalization = avio_r8(pb);
8935  if (normalization) {
8936  av_log(c->fc, AV_LOG_WARNING,
8937  "Unsupported normalization %d\n", normalization);
8938  return 0;
8939  }
8940 
8941  channel_count = avio_rb32(pb);
8942  if (ambisonic_order < 0 || ambisonic_order > 31 ||
8943  channel_count != ((ambisonic_order + 1LL) * (ambisonic_order + 1LL) +
8944  non_diegetic_channels)) {
8945  av_log(c->fc, AV_LOG_ERROR,
8946  "Invalid number of channels (%d / %d)\n",
8947  channel_count, ambisonic_order);
8948  return 0;
8949  }
8950  ambi_channels = channel_count - non_diegetic_channels;
8951 
8952  ret = av_channel_layout_custom_init(&ch_layout, channel_count);
8953  if (ret < 0)
8954  return 0;
8955 
8956  for (i = 0; i < channel_count; i++) {
8957  unsigned channel = avio_rb32(pb);
8958 
8959  if (channel >= channel_count) {
8960  av_log(c->fc, AV_LOG_ERROR, "Invalid channel index (%d / %d)\n",
8961  channel, ambisonic_order);
8962  av_channel_layout_uninit(&ch_layout);
8963  return 0;
8964  }
8965  if (channel >= ambi_channels)
8966  ch_layout.u.map[i].id = channel - ambi_channels;
8967  else
8968  ch_layout.u.map[i].id = AV_CHAN_AMBISONIC_BASE + channel;
8969  }
8970 
8972  if (ret < 0) {
8973  av_channel_layout_uninit(&ch_layout);
8974  return 0;
8975  }
8976 
8978  st->codecpar->ch_layout = ch_layout;
8979 
8980  return 0;
8981 }
8982 
8984 {
8985  AVStream *st;
8986  int version;
8987 
8988  if (c->fc->nb_streams < 1)
8989  return 0;
8990 
8991  st = c->fc->streams[c->fc->nb_streams - 1];
8992 
8993  if (atom.size < 5) {
8994  av_log(c->fc, AV_LOG_ERROR, "Empty SAND audio box\n");
8995  return AVERROR_INVALIDDATA;
8996  }
8997 
8998  version = avio_r8(pb);
8999  if (version) {
9000  av_log(c->fc, AV_LOG_WARNING, "Unsupported SAND box version %d\n", version);
9001  return 0;
9002  }
9003 
9005 
9006  return 0;
9007 }
9008 
9009 static int rb_size(AVIOContext *pb, int64_t *value, int size)
9010 {
9011  if (size == 0)
9012  *value = 0;
9013  else if (size == 1)
9014  *value = avio_r8(pb);
9015  else if (size == 2)
9016  *value = avio_rb16(pb);
9017  else if (size == 4)
9018  *value = avio_rb32(pb);
9019  else if (size == 8) {
9020  *value = avio_rb64(pb);
9021  if (*value < 0)
9022  return -1;
9023  } else
9024  return -1;
9025  return size;
9026 }
9027 
9029 {
9030  avio_rb32(pb); // version & flags.
9031  c->primary_item_id = avio_rb16(pb);
9032  av_log(c->fc, AV_LOG_TRACE, "pitm: primary_item_id %d\n", c->primary_item_id);
9033  return atom.size;
9034 }
9035 
9037 {
9038  c->idat_offset = avio_tell(pb);
9039  return 0;
9040 }
9041 
9043 {
9044  HEIFItem **heif_item;
9045  int version, offset_size, length_size, base_offset_size, index_size;
9046  int item_count, extent_count;
9047  int64_t base_offset, extent_offset, extent_length;
9048  uint8_t value;
9049 
9050  if (c->found_iloc) {
9051  av_log(c->fc, AV_LOG_INFO, "Duplicate iloc box found\n");
9052  return 0;
9053  }
9054 
9055  version = avio_r8(pb);
9056  avio_rb24(pb); // flags.
9057 
9058  value = avio_r8(pb);
9059  offset_size = (value >> 4) & 0xF;
9060  length_size = value & 0xF;
9061  value = avio_r8(pb);
9062  base_offset_size = (value >> 4) & 0xF;
9063  index_size = !version ? 0 : (value & 0xF);
9064  if (index_size) {
9065  avpriv_report_missing_feature(c->fc, "iloc: index_size != 0");
9066  return AVERROR_PATCHWELCOME;
9067  }
9068  item_count = (version < 2) ? avio_rb16(pb) : avio_rb32(pb);
9069 
9070  heif_item = av_realloc_array(c->heif_item, FFMAX(item_count, c->nb_heif_item), sizeof(*c->heif_item));
9071  if (!heif_item)
9072  return AVERROR(ENOMEM);
9073  c->heif_item = heif_item;
9074  if (item_count > c->nb_heif_item)
9075  memset(&c->heif_item[c->nb_heif_item], 0,
9076  sizeof(*c->heif_item) * (item_count - c->nb_heif_item));
9077  c->nb_heif_item = FFMAX(c->nb_heif_item, item_count);
9078 
9079  av_log(c->fc, AV_LOG_TRACE, "iloc: item_count %d\n", item_count);
9080  for (int i = 0; i < item_count; i++) {
9081  HEIFItem *item = NULL;
9082  int item_id = (version < 2) ? avio_rb16(pb) : avio_rb32(pb);
9083  int offset_type = (version > 0) ? avio_rb16(pb) & 0xf : 0;
9084  int j;
9085 
9086  if (avio_feof(pb))
9087  return AVERROR_INVALIDDATA;
9088  if (offset_type > 1) {
9089  avpriv_report_missing_feature(c->fc, "iloc offset type %d", offset_type);
9090  return AVERROR_PATCHWELCOME;
9091  }
9092 
9093  avio_rb16(pb); // data_reference_index.
9094  if (rb_size(pb, &base_offset, base_offset_size) < 0)
9095  return AVERROR_INVALIDDATA;
9096  extent_count = avio_rb16(pb);
9097  if (extent_count > 1) {
9098  // For still AVIF images, we only support one extent item.
9099  avpriv_report_missing_feature(c->fc, "iloc: extent_count > 1");
9100  return AVERROR_PATCHWELCOME;
9101  }
9102 
9103  if (rb_size(pb, &extent_offset, offset_size) < 0 ||
9104  rb_size(pb, &extent_length, length_size) < 0 ||
9105  base_offset > INT64_MAX - extent_offset)
9106  return AVERROR_INVALIDDATA;
9107 
9108  for (j = 0; j < c->nb_heif_item; j++) {
9109  item = c->heif_item[j];
9110  if (!item)
9111  item = c->heif_item[j] = av_mallocz(sizeof(*item));
9112  else if (item->item_id != item_id)
9113  continue;
9114  break;
9115  }
9116  if (!item)
9117  return AVERROR(ENOMEM);
9118  if (j == c->nb_heif_item)
9119  return AVERROR_INVALIDDATA;
9120 
9121  item->item_id = item_id;
9122 
9123  if (offset_type == 1)
9124  item->is_idat_relative = 1;
9125  item->extent_length = extent_length;
9126  item->extent_offset = base_offset + extent_offset;
9127  av_log(c->fc, AV_LOG_TRACE, "iloc: item_idx %d, item->item_id %d, offset_type %d, "
9128  "extent_offset %"PRId64", extent_length %"PRId64"\n",
9129  i, item->item_id, offset_type, item->extent_offset, item->extent_length);
9130  }
9131 
9132  c->found_iloc = 1;
9133  return atom.size;
9134 }
9135 
9137 {
9138  HEIFItem *item = NULL;
9139  AVBPrint item_name;
9140  int64_t size = atom.size;
9141  uint32_t item_type;
9142  int item_id;
9143  int i, version, ret;
9144 
9145  version = avio_r8(pb);
9146  avio_rb24(pb); // flags.
9147  size -= 4;
9148  if (size < 0)
9149  return AVERROR_INVALIDDATA;
9150 
9151  if (version < 2) {
9152  avpriv_report_missing_feature(c->fc, "infe version < 2");
9153  avio_skip(pb, size);
9154  return 1;
9155  }
9156 
9157  item_id = version > 2 ? avio_rb32(pb) : avio_rb16(pb);
9158  avio_rb16(pb); // item_protection_index
9159  item_type = avio_rl32(pb);
9160  size -= 8;
9161  if (size < 1)
9162  return AVERROR_INVALIDDATA;
9163 
9166  if (ret < 0) {
9168  return ret;
9169  }
9170 
9171  av_log(c->fc, AV_LOG_TRACE, "infe: item_id %d, item_type %s, item_name %s\n",
9172  item_id, av_fourcc2str(item_type), item_name.str);
9173 
9174  size -= ret + 1;
9175  if (size > 0)
9176  avio_skip(pb, size);
9177 
9178  for (i = 0; i < c->nb_heif_item; i++) {
9179  item = c->heif_item[i];
9180  if (!item)
9181  item = c->heif_item[i] = av_mallocz(sizeof(*item));
9182  else if (item->item_id != item_id)
9183  continue;
9184  break;
9185  }
9186  if (!item) {
9188  return AVERROR(ENOMEM);
9189  }
9190  if (i == c->nb_heif_item) {
9192  return AVERROR_INVALIDDATA;
9193  }
9194 
9195  av_freep(&item->name);
9196  av_bprint_finalize(&item_name, ret ? &item->name : NULL);
9197  item->item_id = item_id;
9198  item->type = item_type;
9199 
9200  switch (item_type) {
9201  case MKTAG('a','v','0','1'):
9202  case MKTAG('j','p','e','g'):
9203  case MKTAG('h','v','c','1'):
9204  ret = heif_add_stream(c, item);
9205  if (ret < 0)
9206  return ret;
9207  break;
9208  }
9209 
9210  return 0;
9211 }
9212 
9214 {
9215  HEIFItem **heif_item;
9216  int entry_count;
9217  int version, got_stream = 0, ret, i;
9218 
9219  if (c->found_iinf) {
9220  av_log(c->fc, AV_LOG_WARNING, "Duplicate iinf box found\n");
9221  return 0;
9222  }
9223 
9224  version = avio_r8(pb);
9225  avio_rb24(pb); // flags.
9226  entry_count = version ? avio_rb32(pb) : avio_rb16(pb);
9227 
9228  heif_item = av_realloc_array(c->heif_item, FFMAX(entry_count, c->nb_heif_item), sizeof(*c->heif_item));
9229  if (!heif_item)
9230  return AVERROR(ENOMEM);
9231  c->heif_item = heif_item;
9232  if (entry_count > c->nb_heif_item)
9233  memset(&c->heif_item[c->nb_heif_item], 0,
9234  sizeof(*c->heif_item) * (entry_count - c->nb_heif_item));
9235  c->nb_heif_item = FFMAX(c->nb_heif_item, entry_count);
9236 
9237  for (i = 0; i < entry_count; i++) {
9238  MOVAtom infe;
9239 
9240  infe.size = avio_rb32(pb) - 8;
9241  infe.type = avio_rl32(pb);
9242  if (avio_feof(pb)) {
9244  goto fail;
9245  }
9246  ret = mov_read_infe(c, pb, infe);
9247  if (ret < 0)
9248  goto fail;
9249  if (!ret)
9250  got_stream = 1;
9251  }
9252 
9253  c->found_iinf = got_stream;
9254  return 0;
9255 fail:
9256  for (; i >= 0; i--) {
9257  HEIFItem *item = c->heif_item[i];
9258 
9259  if (!item)
9260  continue;
9261 
9262  av_freep(&item->name);
9263  }
9264  return ret;
9265 }
9266 
9268 {
9269  HEIFItem *item = NULL;
9270  HEIFGrid *grid;
9271  int entries, i;
9272  int from_item_id = version ? avio_rb32(pb) : avio_rb16(pb);
9273  int ret = 0;
9274 
9275  for (int i = 0; i < c->nb_heif_grid; i++) {
9276  if (c->heif_grid[i].item->item_id == from_item_id) {
9277  av_log(c->fc, AV_LOG_ERROR, "More than one 'dimg' box "
9278  "referencing the same Derived Image item\n");
9279  return AVERROR_INVALIDDATA;
9280  }
9281  }
9282  for (int i = 0; i < c->nb_heif_item; i++) {
9283  if (!c->heif_item[i] || c->heif_item[i]->item_id != from_item_id)
9284  continue;
9285  item = c->heif_item[i];
9286 
9287  switch (item->type) {
9288  case MKTAG('g','r','i','d'):
9289  case MKTAG('i','o','v','l'):
9290  break;
9291  default:
9292  avpriv_report_missing_feature(c->fc, "Derived Image item of type %s",
9293  av_fourcc2str(item->type));
9294  return 0;
9295  }
9296  break;
9297  }
9298  if (!item) {
9299  av_log(c->fc, AV_LOG_ERROR, "Missing grid information\n");
9300  return AVERROR_INVALIDDATA;
9301  }
9302 
9303  entries = avio_rb16(pb);
9304  if (!entries) {
9305  av_log(c->fc, AV_LOG_ERROR,
9306  "Derived image item references no input images\n");
9307  return AVERROR_INVALIDDATA;
9308  }
9309 
9310  grid = av_realloc_array(c->heif_grid, c->nb_heif_grid + 1U,
9311  sizeof(*c->heif_grid));
9312  if (!grid)
9313  return AVERROR(ENOMEM);
9314  c->heif_grid = grid;
9315  grid = &grid[c->nb_heif_grid];
9316 
9317  grid->tile_id_list = av_malloc_array(entries, sizeof(*grid->tile_id_list));
9318  grid->tile_idx_list = av_calloc(entries, sizeof(*grid->tile_idx_list));
9319  grid->tile_item_list = av_calloc(entries, sizeof(*grid->tile_item_list));
9320  if (!grid->tile_id_list || !grid->tile_item_list || !grid->tile_idx_list) {
9321  ret = AVERROR(ENOMEM);
9322  goto fail;
9323  }
9324  /* 'to' item ids */
9325  for (i = 0; i < entries; i++) {
9326  grid->tile_id_list[i] = version ? avio_rb32(pb) : avio_rb16(pb);
9327 
9328  if (avio_feof(pb)) {
9330  goto fail;
9331  }
9332  }
9333 
9334  grid->nb_tiles = entries;
9335  grid->item = item;
9336  ++c->nb_heif_grid;
9337 
9338  av_log(c->fc, AV_LOG_TRACE, "dimg: from_item_id %d, entries %d\n",
9339  from_item_id, entries);
9340 
9341  return 0;
9342 fail:
9343  av_freep(&grid->tile_id_list);
9344  av_freep(&grid->tile_idx_list);
9345  av_freep(&grid->tile_item_list);
9346 
9347  return ret;
9348 }
9349 
9350 static int mov_read_iref_cdsc(MOVContext *c, AVIOContext *pb, uint32_t type, int version)
9351 {
9352  HEIFItem *from_item = NULL;
9353  int entries;
9354  int from_item_id = version ? avio_rb32(pb) : avio_rb16(pb);
9355  const HEIFItemRef ref = { type, from_item_id };
9356 
9357  from_item = get_heif_item(c, from_item_id);
9358  if (!from_item) {
9359  av_log(c->fc, AV_LOG_ERROR, "Missing stream referenced by thmb item\n");
9360  return AVERROR_INVALIDDATA;
9361  }
9362 
9363  entries = avio_rb16(pb);
9364  /* 'to' item ids */
9365  for (int i = 0; i < entries; i++) {
9366  HEIFItem *item = get_heif_item(c, version ? avio_rb32(pb) : avio_rb16(pb));
9367 
9368  if (avio_feof(pb))
9369  return AVERROR_INVALIDDATA;
9370 
9371  if (!item) {
9372  av_log(c->fc, AV_LOG_WARNING, "Missing stream referenced by %s item\n",
9373  av_fourcc2str(type));
9374  continue;
9375  }
9376 
9377  if (!av_dynarray2_add((void **)&item->iref_list, &item->nb_iref_list,
9378  sizeof(*item->iref_list), (const uint8_t *)&ref))
9379  return AVERROR(ENOMEM);
9380  }
9381 
9382  av_log(c->fc, AV_LOG_TRACE, "%s: from_item_id %d, entries %d\n",
9383  av_fourcc2str(type), from_item_id, entries);
9384 
9385  return 0;
9386 }
9387 
9389 {
9390  int version = avio_r8(pb);
9391  int ret;
9392 
9393  avio_rb24(pb); // flags
9394  atom.size -= 4;
9395 
9396  if (version > 1) {
9397  av_log(c->fc, AV_LOG_WARNING, "Unknown iref box version %d\n", version);
9398  return 0;
9399  }
9400 
9401  while (atom.size) {
9402  uint32_t type, size = avio_rb32(pb);
9403  int64_t next = avio_tell(pb);
9404 
9405  if (size < 14 || next < 0 || next > INT64_MAX - size)
9406  return AVERROR_INVALIDDATA;
9407 
9408  next += size - 4;
9409  type = avio_rl32(pb);
9410  switch (type) {
9411  case MKTAG('d','i','m','g'):
9412  ret = mov_read_iref_dimg(c, pb, version);
9413  if (ret < 0)
9414  return ret;
9415  break;
9416  case MKTAG('c','d','s','c'):
9417  case MKTAG('t','h','m','b'):
9418  ret = mov_read_iref_cdsc(c, pb, type, version);
9419  if (ret < 0)
9420  return ret;
9421  break;
9422  default:
9423  av_log(c->fc, AV_LOG_DEBUG, "Unknown iref type %s size %"PRIu32"\n",
9424  av_fourcc2str(type), size);
9425  }
9426 
9427  atom.size -= size;
9428  avio_seek(pb, next, SEEK_SET);
9429  }
9430  return 0;
9431 }
9432 
9434 {
9435  HEIFItem *item;
9436  uint32_t width, height;
9437 
9438  avio_r8(pb); /* version */
9439  avio_rb24(pb); /* flags */
9440  width = avio_rb32(pb);
9441  height = avio_rb32(pb);
9442 
9443  av_log(c->fc, AV_LOG_TRACE, "ispe: item_id %d, width %"PRIu32", height %"PRIu32"\n",
9444  c->cur_item_id, width, height);
9445 
9446  item = get_heif_item(c, c->cur_item_id);
9447  if (item) {
9448  item->width = width;
9449  item->height = height;
9450  }
9451 
9452  return 0;
9453 }
9454 
9456 {
9457  HEIFItem *item;
9458  int angle;
9459 
9460  angle = avio_r8(pb) & 0x3;
9461 
9462  av_log(c->fc, AV_LOG_TRACE, "irot: item_id %d, angle %u\n",
9463  c->cur_item_id, angle);
9464 
9465  item = get_heif_item(c, c->cur_item_id);
9466  if (item) {
9467  // angle * 90 specifies the angle (in anti-clockwise direction)
9468  // in units of degrees.
9469  item->rotation = angle * 90;
9470  }
9471 
9472  return 0;
9473 }
9474 
9476 {
9477  HEIFItem *item;
9478  int axis;
9479 
9480  axis = avio_r8(pb) & 0x1;
9481 
9482  av_log(c->fc, AV_LOG_TRACE, "imir: item_id %d, axis %u\n",
9483  c->cur_item_id, axis);
9484 
9485  item = get_heif_item(c, c->cur_item_id);
9486  if (item) {
9487  item->hflip = axis;
9488  item->vflip = !axis;
9489  }
9490 
9491  return 0;
9492 }
9493 
9495 {
9496  typedef struct MOVAtoms {
9497  FFIOContext b;
9498  uint32_t type;
9499  int64_t size;
9500  uint8_t *data;
9501  } MOVAtoms;
9502  MOVAtoms *atoms = NULL;
9503  MOVAtom a;
9504  unsigned count;
9505  int nb_atoms = 0;
9506  int version, flags;
9507  int ret;
9508 
9509  a.size = avio_rb32(pb);
9510  a.type = avio_rl32(pb);
9511 
9512  if (a.size < 8 || a.type != MKTAG('i','p','c','o'))
9513  return AVERROR_INVALIDDATA;
9514 
9515  a.size -= 8;
9516  while (a.size >= 8) {
9517  MOVAtoms *ref = av_dynarray2_add((void**)&atoms, &nb_atoms, sizeof(MOVAtoms), NULL);
9518  if (!ref) {
9519  ret = AVERROR(ENOMEM);
9520  goto fail;
9521  }
9522  ref->data = NULL;
9523  ref->size = avio_rb32(pb);
9524  ref->type = avio_rl32(pb);
9525  if (ref->size > a.size || ref->size < 8)
9526  break;
9527  ref->data = av_malloc(ref->size);
9528  if (!ref->data) {
9530  goto fail;
9531  }
9532  av_log(c->fc, AV_LOG_TRACE, "ipco: index %d, box type %s\n", nb_atoms, av_fourcc2str(ref->type));
9533  avio_seek(pb, -8, SEEK_CUR);
9534  if (avio_read(pb, ref->data, ref->size) != ref->size) {
9536  goto fail;
9537  }
9538  ffio_init_read_context(&ref->b, ref->data, ref->size);
9539  a.size -= ref->size;
9540  }
9541 
9542  if (a.size) {
9544  goto fail;
9545  }
9546 
9547  a.size = avio_rb32(pb);
9548  a.type = avio_rl32(pb);
9549 
9550  if (a.size < 8 || a.type != MKTAG('i','p','m','a')) {
9552  goto fail;
9553  }
9554 
9555  version = avio_r8(pb);
9556  flags = avio_rb24(pb);
9557  count = avio_rb32(pb);
9558 
9559  for (int i = 0; i < count; i++) {
9560  int item_id = version ? avio_rb32(pb) : avio_rb16(pb);
9561  int assoc_count = avio_r8(pb);
9562 
9563  if (avio_feof(pb)) {
9565  goto fail;
9566  }
9567 
9568  for (int j = 0; j < assoc_count; j++) {
9569  MOVAtoms *ref;
9570  int index = avio_r8(pb) & 0x7f;
9571  if (flags & 1) {
9572  index <<= 8;
9573  index |= avio_r8(pb);
9574  }
9575  if (index > nb_atoms || index <= 0) {
9577  goto fail;
9578  }
9579  ref = &atoms[--index];
9580 
9581  av_log(c->fc, AV_LOG_TRACE, "ipma: property_index %d, item_id %d, item_type %s\n",
9582  index + 1, item_id, av_fourcc2str(ref->type));
9583 
9584  c->cur_item_id = item_id;
9585 
9586  ret = mov_read_default(c, &ref->b.pub,
9587  (MOVAtom) { .size = ref->size,
9588  .type = MKTAG('i','p','c','o') });
9589  if (ret < 0)
9590  goto fail;
9591  ffio_init_read_context(&ref->b, ref->data, ref->size);
9592  }
9593  }
9594 
9595  ret = 0;
9596 fail:
9597  c->cur_item_id = -1;
9598  for (int i = 0; i < nb_atoms; i++)
9599  av_free(atoms[i].data);
9600  av_free(atoms);
9601 
9602  return ret;
9603 }
9604 
9606 { MKTAG('A','C','L','R'), mov_read_aclr },
9607 { MKTAG('A','P','R','G'), mov_read_avid },
9608 { MKTAG('A','A','L','P'), mov_read_avid },
9609 { MKTAG('A','R','E','S'), mov_read_ares },
9610 { MKTAG('a','v','s','s'), mov_read_avss },
9611 { MKTAG('a','v','1','C'), mov_read_glbl },
9612 { MKTAG('c','h','p','l'), mov_read_chpl },
9613 { MKTAG('c','o','6','4'), mov_read_stco },
9614 { MKTAG('c','o','l','r'), mov_read_colr },
9615 { MKTAG('c','t','t','s'), mov_read_ctts }, /* composition time to sample */
9616 { MKTAG('d','i','n','f'), mov_read_default },
9617 { MKTAG('D','p','x','E'), mov_read_dpxe },
9618 { MKTAG('d','r','e','f'), mov_read_dref },
9619 { MKTAG('e','d','t','s'), mov_read_default },
9620 { MKTAG('e','l','s','t'), mov_read_elst },
9621 { MKTAG('e','n','d','a'), mov_read_enda },
9622 { MKTAG('f','i','e','l'), mov_read_fiel },
9623 { MKTAG('a','d','r','m'), mov_read_adrm },
9624 { MKTAG('f','t','y','p'), mov_read_ftyp },
9625 { MKTAG('g','l','b','l'), mov_read_glbl },
9626 { MKTAG('h','d','l','r'), mov_read_hdlr },
9627 { MKTAG('i','l','s','t'), mov_read_ilst },
9628 { MKTAG('j','p','2','h'), mov_read_jp2h },
9629 { MKTAG('m','d','a','t'), mov_read_mdat },
9630 { MKTAG('m','d','h','d'), mov_read_mdhd },
9631 { MKTAG('m','d','i','a'), mov_read_default },
9632 { MKTAG('m','e','t','a'), mov_read_meta },
9633 { MKTAG('m','i','n','f'), mov_read_default },
9634 { MKTAG('m','o','o','f'), mov_read_moof },
9635 { MKTAG('m','o','o','v'), mov_read_moov },
9636 { MKTAG('m','v','e','x'), mov_read_default },
9637 { MKTAG('m','v','h','d'), mov_read_mvhd },
9638 { MKTAG('S','M','I',' '), mov_read_svq3 },
9639 { MKTAG('a','l','a','c'), mov_read_alac }, /* alac specific atom */
9640 { MKTAG('a','v','c','C'), mov_read_glbl },
9641 { MKTAG('p','a','s','p'), mov_read_pasp },
9642 { MKTAG('c','l','a','p'), mov_read_clap },
9643 { MKTAG('s','b','a','s'), mov_read_sbas },
9644 { MKTAG('s','i','d','x'), mov_read_sidx },
9645 { MKTAG('s','t','b','l'), mov_read_default },
9646 { MKTAG('s','t','c','o'), mov_read_stco },
9647 { MKTAG('s','t','p','s'), mov_read_stps },
9648 { MKTAG('s','t','r','f'), mov_read_strf },
9649 { MKTAG('s','t','s','c'), mov_read_stsc },
9650 { MKTAG('s','t','s','d'), mov_read_stsd }, /* sample description */
9651 { MKTAG('s','t','s','s'), mov_read_stss }, /* sync sample */
9652 { MKTAG('s','t','s','z'), mov_read_stsz }, /* sample size */
9653 { MKTAG('s','t','t','s'), mov_read_stts },
9654 { MKTAG('s','t','z','2'), mov_read_stsz }, /* compact sample size */
9655 { MKTAG('s','d','t','p'), mov_read_sdtp }, /* independent and disposable samples */
9656 { MKTAG('t','k','h','d'), mov_read_tkhd }, /* track header */
9657 { MKTAG('t','f','d','t'), mov_read_tfdt },
9658 { MKTAG('t','f','h','d'), mov_read_tfhd }, /* track fragment header */
9659 { MKTAG('t','r','a','k'), mov_read_trak },
9660 { MKTAG('t','r','a','f'), mov_read_default },
9661 { MKTAG('t','r','e','f'), mov_read_default },
9662 { MKTAG('t','m','c','d'), mov_read_tmcd },
9663 { MKTAG('c','h','a','p'), mov_read_chap },
9664 { MKTAG('t','r','e','x'), mov_read_trex },
9665 { MKTAG('t','r','u','n'), mov_read_trun },
9666 { MKTAG('u','d','t','a'), mov_read_default },
9667 { MKTAG('w','a','v','e'), mov_read_wave },
9668 { MKTAG('e','s','d','s'), mov_read_esds },
9669 { MKTAG('d','a','c','3'), mov_read_dac3 }, /* AC-3 info */
9670 { MKTAG('d','e','c','3'), mov_read_dec3 }, /* EAC-3 info */
9671 { MKTAG('d','d','t','s'), mov_read_ddts }, /* DTS audio descriptor */
9672 { MKTAG('w','i','d','e'), mov_read_wide }, /* place holder */
9673 { MKTAG('w','f','e','x'), mov_read_wfex },
9674 { MKTAG('c','m','o','v'), mov_read_cmov },
9675 { MKTAG('c','h','a','n'), mov_read_chan }, /* channel layout from quicktime */
9676 { MKTAG('c','h','n','l'), mov_read_chnl }, /* channel layout from ISO-14496-12 */
9677 { MKTAG('d','v','c','1'), mov_read_dvc1 },
9678 { MKTAG('s','g','p','d'), mov_read_sgpd },
9679 { MKTAG('s','b','g','p'), mov_read_sbgp },
9680 { MKTAG('h','v','c','C'), mov_read_glbl },
9681 { MKTAG('v','v','c','C'), mov_read_glbl },
9682 { MKTAG('u','u','i','d'), mov_read_uuid },
9683 { MKTAG('C','i','n', 0x8e), mov_read_targa_y216 },
9684 { MKTAG('f','r','e','e'), mov_read_free },
9685 { MKTAG('-','-','-','-'), mov_read_custom },
9686 { MKTAG('s','i','n','f'), mov_read_default },
9687 { MKTAG('f','r','m','a'), mov_read_frma },
9688 { MKTAG('s','e','n','c'), mov_read_senc },
9689 { MKTAG('s','a','i','z'), mov_read_saiz },
9690 { MKTAG('s','a','i','o'), mov_read_saio },
9691 { MKTAG('p','s','s','h'), mov_read_pssh },
9692 { MKTAG('s','c','h','m'), mov_read_schm },
9693 { MKTAG('s','c','h','i'), mov_read_default },
9694 { MKTAG('t','e','n','c'), mov_read_tenc },
9695 { MKTAG('d','f','L','a'), mov_read_dfla },
9696 { MKTAG('s','t','3','d'), mov_read_st3d }, /* stereoscopic 3D video box */
9697 { MKTAG('s','v','3','d'), mov_read_sv3d }, /* spherical video box */
9698 { MKTAG('v','e','x','u'), mov_read_vexu }, /* video extension usage */
9699 { MKTAG('h','f','o','v'), mov_read_hfov },
9700 { MKTAG('d','O','p','s'), mov_read_dops },
9701 { MKTAG('d','m','l','p'), mov_read_dmlp },
9702 { MKTAG('S','m','D','m'), mov_read_smdm },
9703 { MKTAG('C','o','L','L'), mov_read_coll },
9704 { MKTAG('v','p','c','C'), mov_read_vpcc },
9705 { MKTAG('m','d','c','v'), mov_read_mdcv },
9706 { MKTAG('c','l','l','i'), mov_read_clli },
9707 { MKTAG('d','v','c','C'), mov_read_dvcc_dvvc },
9708 { MKTAG('d','v','v','C'), mov_read_dvcc_dvvc },
9709 { MKTAG('d','v','w','C'), mov_read_dvcc_dvvc },
9710 { MKTAG('k','i','n','d'), mov_read_kind },
9711 { MKTAG('S','A','3','D'), mov_read_SA3D }, /* ambisonic audio box */
9712 { MKTAG('S','A','N','D'), mov_read_SAND }, /* non diegetic audio box */
9713 { MKTAG('i','l','o','c'), mov_read_iloc },
9714 { MKTAG('p','c','m','C'), mov_read_pcmc }, /* PCM configuration box */
9715 { MKTAG('p','i','t','m'), mov_read_pitm },
9716 { MKTAG('e','v','c','C'), mov_read_glbl },
9717 { MKTAG('i','d','a','t'), mov_read_idat },
9718 { MKTAG('i','m','i','r'), mov_read_imir },
9719 { MKTAG('i','r','e','f'), mov_read_iref },
9720 { MKTAG('i','s','p','e'), mov_read_ispe },
9721 { MKTAG('i','r','o','t'), mov_read_irot },
9722 { MKTAG('i','p','r','p'), mov_read_iprp },
9723 { MKTAG('i','i','n','f'), mov_read_iinf },
9724 { MKTAG('a','m','v','e'), mov_read_amve }, /* ambient viewing environment box */
9725 { MKTAG('l','h','v','C'), mov_read_lhvc },
9726 { MKTAG('l','v','c','C'), mov_read_glbl },
9727 { MKTAG('a','p','v','C'), mov_read_glbl },
9728 #if CONFIG_IAMFDEC
9729 { MKTAG('i','a','c','b'), mov_read_iacb },
9730 #endif
9731 { MKTAG('s','r','a','t'), mov_read_srat },
9732 { 0, NULL }
9733 };
9734 
9736 {
9737  int64_t total_size = 0;
9738  MOVAtom a;
9739  int i;
9740 
9741  if (c->atom_depth > 10) {
9742  av_log(c->fc, AV_LOG_ERROR, "Atoms too deeply nested\n");
9743  return AVERROR_INVALIDDATA;
9744  }
9745  c->atom_depth ++;
9746 
9747  if (atom.size < 0)
9748  atom.size = INT64_MAX;
9749  while (total_size <= atom.size - 8) {
9750  int (*parse)(MOVContext*, AVIOContext*, MOVAtom) = NULL;
9751  a.size = avio_rb32(pb);
9752  a.type = avio_rl32(pb);
9753  if (avio_feof(pb))
9754  break;
9755  if (((a.type == MKTAG('f','r','e','e') && c->moov_retry) ||
9756  a.type == MKTAG('h','o','o','v')) &&
9757  a.size >= 8 &&
9758  c->fc->strict_std_compliance < FF_COMPLIANCE_STRICT) {
9759  uint32_t type;
9760  avio_skip(pb, 4);
9761  type = avio_rl32(pb);
9762  if (avio_feof(pb))
9763  break;
9764  avio_seek(pb, -8, SEEK_CUR);
9765  if (type == MKTAG('m','v','h','d') ||
9766  type == MKTAG('c','m','o','v')) {
9767  av_log(c->fc, AV_LOG_ERROR, "Detected moov in a free or hoov atom.\n");
9768  a.type = MKTAG('m','o','o','v');
9769  }
9770  }
9771  if (atom.type != MKTAG('r','o','o','t') &&
9772  atom.type != MKTAG('m','o','o','v')) {
9773  if (a.type == MKTAG('t','r','a','k') ||
9774  a.type == MKTAG('m','d','a','t')) {
9775  av_log(c->fc, AV_LOG_ERROR, "Broken file, trak/mdat not at top-level\n");
9776  avio_skip(pb, -8);
9777  c->atom_depth --;
9778  return 0;
9779  }
9780  }
9781  total_size += 8;
9782  if (a.size == 1 && total_size + 8 <= atom.size) { /* 64 bit extended size */
9783  a.size = avio_rb64(pb) - 8;
9784  total_size += 8;
9785  }
9786  av_log(c->fc, AV_LOG_TRACE, "type:'%s' parent:'%s' sz: %"PRId64" %"PRId64" %"PRId64"\n",
9787  av_fourcc2str(a.type), av_fourcc2str(atom.type), a.size, total_size, atom.size);
9788  if (a.size == 0) {
9789  a.size = atom.size - total_size + 8;
9790  }
9791  if (a.size < 0)
9792  break;
9793  a.size -= 8;
9794  if (a.size < 0)
9795  break;
9796  a.size = FFMIN(a.size, atom.size - total_size);
9797 
9798  for (i = 0; mov_default_parse_table[i].type; i++)
9799  if (mov_default_parse_table[i].type == a.type) {
9801  break;
9802  }
9803 
9804  // container is user data
9805  if (!parse && (atom.type == MKTAG('u','d','t','a') ||
9806  atom.type == MKTAG('i','l','s','t')))
9808 
9809  // Supports parsing the QuickTime Metadata Keys.
9810  // https://developer.apple.com/library/mac/documentation/QuickTime/QTFF/Metadata/Metadata.html
9811  if (!parse && c->found_hdlr_mdta &&
9812  atom.type == MKTAG('m','e','t','a') &&
9813  a.type == MKTAG('k','e','y','s') &&
9814  c->meta_keys_count == 0) {
9815  parse = mov_read_keys;
9816  }
9817 
9818  if (!parse) { /* skip leaf atoms data */
9819  avio_skip(pb, a.size);
9820  } else {
9821  int64_t start_pos = avio_tell(pb);
9822  int64_t left;
9823  int err = parse(c, pb, a);
9824  if (err < 0) {
9825  c->atom_depth --;
9826  return err;
9827  }
9828  if (c->found_moov && c->found_mdat && a.size <= INT64_MAX - start_pos &&
9829  ((!(pb->seekable & AVIO_SEEKABLE_NORMAL) || c->fc->flags & AVFMT_FLAG_IGNIDX || c->frag_index.complete) ||
9830  start_pos + a.size == avio_size(pb))) {
9831  if (!(pb->seekable & AVIO_SEEKABLE_NORMAL) || c->fc->flags & AVFMT_FLAG_IGNIDX || c->frag_index.complete)
9832  c->next_root_atom = start_pos + a.size;
9833  c->atom_depth --;
9834  return 0;
9835  }
9836  left = a.size - avio_tell(pb) + start_pos;
9837  if (left > 0) /* skip garbage at atom end */
9838  avio_skip(pb, left);
9839  else if (left < 0) {
9840  av_log(c->fc, AV_LOG_WARNING,
9841  "overread end of atom '%s' by %"PRId64" bytes\n",
9842  av_fourcc2str(a.type), -left);
9843  avio_seek(pb, left, SEEK_CUR);
9844  }
9845  }
9846 
9847  total_size += a.size;
9848  }
9849 
9850  if (total_size < atom.size && atom.size < 0x7ffff)
9851  avio_skip(pb, atom.size - total_size);
9852 
9853  c->atom_depth --;
9854  return 0;
9855 }
9856 
9857 static int mov_probe(const AVProbeData *p)
9858 {
9859  int64_t offset;
9860  uint32_t tag;
9861  int score = 0;
9862  int moov_offset = -1;
9863 
9864  /* check file header */
9865  offset = 0;
9866  for (;;) {
9867  int64_t size;
9868  int minsize = 8;
9869  /* ignore invalid offset */
9870  if ((offset + 8ULL) > (unsigned int)p->buf_size)
9871  break;
9872  size = AV_RB32(p->buf + offset);
9873  if (size == 1 && offset + 16 <= (unsigned int)p->buf_size) {
9874  size = AV_RB64(p->buf+offset + 8);
9875  minsize = 16;
9876  } else if (size == 0) {
9877  size = p->buf_size - offset;
9878  }
9879  if (size < minsize) {
9880  offset += 4;
9881  continue;
9882  }
9883  tag = AV_RL32(p->buf + offset + 4);
9884  switch(tag) {
9885  /* check for obvious tags */
9886  case MKTAG('m','o','o','v'):
9887  moov_offset = offset + 4;
9889  case MKTAG('m','d','a','t'):
9890  case MKTAG('p','n','o','t'): /* detect movs with preview pics like ew.mov and april.mov */
9891  case MKTAG('u','d','t','a'): /* Packet Video PVAuthor adds this and a lot of more junk */
9892  case MKTAG('f','t','y','p'):
9893  if (tag == MKTAG('f','t','y','p') &&
9894  ( AV_RL32(p->buf + offset + 8) == MKTAG('j','p','2',' ')
9895  || AV_RL32(p->buf + offset + 8) == MKTAG('j','p','x',' ')
9896  || AV_RL32(p->buf + offset + 8) == MKTAG('j','x','l',' ')
9897  )) {
9898  score = FFMAX(score, 5);
9899  } else {
9900  score = AVPROBE_SCORE_MAX;
9901  }
9902  break;
9903  /* those are more common words, so rate then a bit less */
9904  case MKTAG('e','d','i','w'): /* xdcam files have reverted first tags */
9905  case MKTAG('w','i','d','e'):
9906  case MKTAG('f','r','e','e'):
9907  case MKTAG('j','u','n','k'):
9908  case MKTAG('p','i','c','t'):
9909  score = FFMAX(score, AVPROBE_SCORE_MAX - 5);
9910  break;
9911  case MKTAG(0x82,0x82,0x7f,0x7d):
9912  score = FFMAX(score, AVPROBE_SCORE_EXTENSION - 5);
9913  break;
9914  case MKTAG('s','k','i','p'):
9915  case MKTAG('u','u','i','d'):
9916  case MKTAG('p','r','f','l'):
9917  /* if we only find those cause probedata is too small at least rate them */
9918  score = FFMAX(score, AVPROBE_SCORE_EXTENSION);
9919  break;
9920  }
9921  if (size > INT64_MAX - offset)
9922  break;
9923  offset += size;
9924  }
9925  if (score > AVPROBE_SCORE_MAX - 50 && moov_offset != -1) {
9926  /* moov atom in the header - we should make sure that this is not a
9927  * MOV-packed MPEG-PS */
9928  offset = moov_offset;
9929 
9930  while (offset < (p->buf_size - 16)) { /* Sufficient space */
9931  /* We found an actual hdlr atom */
9932  if (AV_RL32(p->buf + offset ) == MKTAG('h','d','l','r') &&
9933  AV_RL32(p->buf + offset + 8) == MKTAG('m','h','l','r') &&
9934  AV_RL32(p->buf + offset + 12) == MKTAG('M','P','E','G')) {
9935  av_log(NULL, AV_LOG_WARNING, "Found media data tag MPEG indicating this is a MOV-packed MPEG-PS.\n");
9936  /* We found a media handler reference atom describing an
9937  * MPEG-PS-in-MOV, return a
9938  * low score to force expanding the probe window until
9939  * mpegps_probe finds what it needs */
9940  return 5;
9941  } else {
9942  /* Keep looking */
9943  offset += 2;
9944  }
9945  }
9946  }
9947 
9948  return score;
9949 }
9950 
9951 // must be done after parsing all trak because there's no order requirement
9953 {
9954  MOVContext *mov = s->priv_data;
9955  MOVStreamContext *sc;
9956  int64_t cur_pos;
9957  int i, j;
9958  int chapter_track;
9959 
9960  for (j = 0; j < mov->nb_chapter_tracks; j++) {
9961  AVStream *st = NULL;
9962  FFStream *sti = NULL;
9963  chapter_track = mov->chapter_tracks[j];
9964  for (i = 0; i < s->nb_streams; i++) {
9965  sc = mov->fc->streams[i]->priv_data;
9966  if (sc->id == chapter_track) {
9967  st = s->streams[i];
9968  break;
9969  }
9970  }
9971  if (!st) {
9972  av_log(s, AV_LOG_ERROR, "Referenced QT chapter track not found\n");
9973  continue;
9974  }
9975  sti = ffstream(st);
9976 
9977  sc = st->priv_data;
9978  cur_pos = avio_tell(sc->pb);
9979 
9980  if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
9982  if (!st->attached_pic.data && sti->nb_index_entries) {
9983  // Retrieve the first frame, if possible
9984  AVIndexEntry *sample = &sti->index_entries[0];
9985  if (avio_seek(sc->pb, sample->pos, SEEK_SET) != sample->pos) {
9986  av_log(s, AV_LOG_ERROR, "Failed to retrieve first frame\n");
9987  goto finish;
9988  }
9989 
9990  if (ff_add_attached_pic(s, st, sc->pb, NULL, sample->size) < 0)
9991  goto finish;
9992  }
9993  } else {
9996  st->discard = AVDISCARD_ALL;
9997  for (int i = 0; i < sti->nb_index_entries; i++) {
9998  AVIndexEntry *sample = &sti->index_entries[i];
9999  int64_t end = i+1 < sti->nb_index_entries ? sti->index_entries[i+1].timestamp : st->duration;
10000  uint8_t *title;
10001  uint16_t ch;
10002  int len, title_len;
10003 
10004  if (end < sample->timestamp) {
10005  av_log(s, AV_LOG_WARNING, "ignoring stream duration which is shorter than chapters\n");
10006  end = AV_NOPTS_VALUE;
10007  }
10008 
10009  if (avio_seek(sc->pb, sample->pos, SEEK_SET) != sample->pos) {
10010  av_log(s, AV_LOG_ERROR, "Chapter %d not found in file\n", i);
10011  goto finish;
10012  }
10013 
10014  // the first two bytes are the length of the title
10015  len = avio_rb16(sc->pb);
10016  if (len > sample->size-2)
10017  continue;
10018  title_len = 2*len + 1;
10019  if (!(title = av_mallocz(title_len)))
10020  goto finish;
10021 
10022  // The samples could theoretically be in any encoding if there's an encd
10023  // atom following, but in practice are only utf-8 or utf-16, distinguished
10024  // instead by the presence of a BOM
10025  if (!len) {
10026  title[0] = 0;
10027  } else {
10028  ch = avio_rb16(sc->pb);
10029  if (ch == 0xfeff)
10030  avio_get_str16be(sc->pb, len, title, title_len);
10031  else if (ch == 0xfffe)
10032  avio_get_str16le(sc->pb, len, title, title_len);
10033  else {
10034  AV_WB16(title, ch);
10035  if (len == 1 || len == 2)
10036  title[len] = 0;
10037  else
10038  avio_get_str(sc->pb, INT_MAX, title + 2, len - 1);
10039  }
10040  }
10041 
10042  avpriv_new_chapter(s, i, st->time_base, sample->timestamp, end, title);
10043  av_freep(&title);
10044  }
10045  }
10046 finish:
10047  avio_seek(sc->pb, cur_pos, SEEK_SET);
10048  }
10049 }
10050 
10052  int64_t value, int flags)
10053 {
10054  AVTimecode tc;
10055  char buf[AV_TIMECODE_STR_SIZE];
10056  AVRational rate = st->avg_frame_rate;
10057  int ret = av_timecode_init(&tc, rate, flags, 0, s);
10058  if (ret < 0)
10059  return ret;
10060  av_dict_set(&st->metadata, "timecode",
10061  av_timecode_make_string(&tc, buf, value), 0);
10062  return 0;
10063 }
10064 
10066 {
10067  MOVStreamContext *sc = st->priv_data;
10068  FFStream *const sti = ffstream(st);
10069  char buf[AV_TIMECODE_STR_SIZE];
10070  int64_t cur_pos = avio_tell(sc->pb);
10071  int hh, mm, ss, ff, drop;
10072 
10073  if (!sti->nb_index_entries)
10074  return -1;
10075 
10076  avio_seek(sc->pb, sti->index_entries->pos, SEEK_SET);
10077  avio_skip(s->pb, 13);
10078  hh = avio_r8(s->pb);
10079  mm = avio_r8(s->pb);
10080  ss = avio_r8(s->pb);
10081  drop = avio_r8(s->pb);
10082  ff = avio_r8(s->pb);
10083  snprintf(buf, AV_TIMECODE_STR_SIZE, "%02d:%02d:%02d%c%02d",
10084  hh, mm, ss, drop ? ';' : ':', ff);
10085  av_dict_set(&st->metadata, "timecode", buf, 0);
10086 
10087  avio_seek(sc->pb, cur_pos, SEEK_SET);
10088  return 0;
10089 }
10090 
10092 {
10093  MOVStreamContext *sc = st->priv_data;
10094  FFStream *const sti = ffstream(st);
10095  int flags = 0;
10096  int64_t cur_pos = avio_tell(sc->pb);
10097  int64_t value;
10098  AVRational tc_rate = st->avg_frame_rate;
10099  int tmcd_nb_frames = sc->tmcd_nb_frames;
10100  int rounded_tc_rate;
10101 
10102  if (!sti->nb_index_entries)
10103  return -1;
10104 
10105  if (!tc_rate.num || !tc_rate.den || !tmcd_nb_frames)
10106  return -1;
10107 
10108  avio_seek(sc->pb, sti->index_entries->pos, SEEK_SET);
10109  value = avio_rb32(s->pb);
10110 
10111  if (sc->tmcd_flags & 0x0001) flags |= AV_TIMECODE_FLAG_DROPFRAME;
10112  if (sc->tmcd_flags & 0x0002) flags |= AV_TIMECODE_FLAG_24HOURSMAX;
10113  if (sc->tmcd_flags & 0x0004) flags |= AV_TIMECODE_FLAG_ALLOWNEGATIVE;
10114 
10115  /* Assume Counter flag is set to 1 in tmcd track (even though it is likely
10116  * not the case) and thus assume "frame number format" instead of QT one.
10117  * No sample with tmcd track can be found with a QT timecode at the moment,
10118  * despite what the tmcd track "suggests" (Counter flag set to 0 means QT
10119  * format). */
10120 
10121  /* 60 fps content have tmcd_nb_frames set to 30 but tc_rate set to 60, so
10122  * we multiply the frame number with the quotient.
10123  * See tickets #9492, #9710. */
10124  rounded_tc_rate = (tc_rate.num + tc_rate.den / 2LL) / tc_rate.den;
10125  /* Work around files where tmcd_nb_frames is rounded down from frame rate
10126  * instead of up. See ticket #5978. */
10127  if (tmcd_nb_frames == tc_rate.num / tc_rate.den &&
10128  s->strict_std_compliance < FF_COMPLIANCE_STRICT)
10129  tmcd_nb_frames = rounded_tc_rate;
10130  value = av_rescale(value, rounded_tc_rate, tmcd_nb_frames);
10131 
10133 
10134  avio_seek(sc->pb, cur_pos, SEEK_SET);
10135  return 0;
10136 }
10137 
10139  int i;
10140  if (!index || !*index) return;
10141  for (i = 0; i < (*index)->nb_encrypted_samples; i++) {
10142  av_encryption_info_free((*index)->encrypted_samples[i]);
10143  }
10144  av_freep(&(*index)->encrypted_samples);
10145  av_freep(&(*index)->auxiliary_info_sizes);
10146  av_freep(&(*index)->auxiliary_offsets);
10147  av_freep(index);
10148 }
10149 
10151 {
10152  MOVStreamContext *sc = st->priv_data;
10153 
10154  if (!sc || --sc->refcount) {
10155  st->priv_data = NULL;
10156  return;
10157  }
10158 
10159  av_freep(&sc->tts_data);
10160  for (int i = 0; i < sc->drefs_count; i++) {
10161  av_freep(&sc->drefs[i].path);
10162  av_freep(&sc->drefs[i].dir);
10163  }
10164  av_freep(&sc->drefs);
10165 
10166  sc->drefs_count = 0;
10167 
10168  if (!sc->pb_is_copied)
10169  ff_format_io_close(s, &sc->pb);
10170 
10171  sc->pb = NULL;
10172  av_freep(&sc->chunk_offsets);
10173  av_freep(&sc->stsc_data);
10174  av_freep(&sc->sample_sizes);
10175  av_freep(&sc->keyframes);
10176  av_freep(&sc->ctts_data);
10177  av_freep(&sc->stts_data);
10178  av_freep(&sc->sdtp_data);
10179  av_freep(&sc->stps_data);
10180  av_freep(&sc->elst_data);
10181  av_freep(&sc->rap_group);
10182  av_freep(&sc->sync_group);
10183  av_freep(&sc->sgpd_sync);
10184  av_freep(&sc->sample_offsets);
10185  av_freep(&sc->open_key_samples);
10186  av_freep(&sc->display_matrix);
10187  av_freep(&sc->index_ranges);
10188  for (int i = 0; i < sc->nb_tref_tags; i++)
10189  av_freep(&sc->tref_tags[i].id);
10190  av_freep(&sc->tref_tags);
10191 
10192  if (sc->extradata)
10193  for (int i = 0; i < sc->stsd_count; i++)
10194  av_free(sc->extradata[i]);
10195  av_freep(&sc->extradata);
10196  av_freep(&sc->extradata_size);
10197 
10201 
10202  av_freep(&sc->stereo3d);
10203  av_freep(&sc->spherical);
10204  av_freep(&sc->mastering);
10205  av_freep(&sc->coll);
10206  av_freep(&sc->ambient);
10207 
10208 #if CONFIG_IAMFDEC
10209  if (sc->iamf)
10211 #endif
10212  av_freep(&sc->iamf);
10213 }
10214 
10216 {
10217  MOVContext *mov = s->priv_data;
10218  int i, j;
10219 
10220  for (i = 0; i < s->nb_streams; i++) {
10221  AVStream *st = s->streams[i];
10222 
10224  }
10225 
10226  av_freep(&mov->dv_demux);
10228  mov->dv_fctx = NULL;
10229 
10230  if (mov->meta_keys) {
10231  for (i = 1; i < mov->meta_keys_count; i++) {
10232  av_freep(&mov->meta_keys[i]);
10233  }
10234  av_freep(&mov->meta_keys);
10235  }
10236 
10237  av_freep(&mov->trex_data);
10238  av_freep(&mov->bitrates);
10239 
10240  for (i = 0; i < mov->frag_index.nb_items; i++) {
10242  for (j = 0; j < mov->frag_index.item[i].nb_stream_info; j++) {
10243  mov_free_encryption_index(&frag[j].encryption_index);
10244  }
10246  }
10247  av_freep(&mov->frag_index.item);
10248 
10249  av_freep(&mov->aes_decrypt);
10250  av_freep(&mov->chapter_tracks);
10251  for (i = 0; i < mov->nb_heif_item; i++) {
10252  if (!mov->heif_item[i])
10253  continue;
10254  av_freep(&mov->heif_item[i]->name);
10255  av_freep(&mov->heif_item[i]->iref_list);
10256  av_freep(&mov->heif_item[i]->icc_profile);
10257  av_freep(&mov->heif_item[i]);
10258  }
10259  av_freep(&mov->heif_item);
10260  for (i = 0; i < mov->nb_heif_grid; i++) {
10261  av_freep(&mov->heif_grid[i].tile_id_list);
10264  }
10265  av_freep(&mov->heif_grid);
10266 
10267  return 0;
10268 }
10269 
10270 static int tmcd_is_referenced(AVFormatContext *s, int tmcd_id)
10271 {
10272  int i;
10273 
10274  for (i = 0; i < s->nb_streams; i++) {
10275  AVStream *st = s->streams[i];
10276  MOVStreamContext *sc = st->priv_data;
10277  MovTref *tag = mov_find_tref_tag(sc, MKTAG('t','m','c','d'));
10278 
10279  if (!tag)
10280  continue;
10281  if (mov_find_tref_id(tag, tmcd_id))
10282  return 1;
10283  }
10284  return 0;
10285 }
10286 
10287 /* look for a tmcd track not referenced by any video track, and export it globally */
10289 {
10290  int i;
10291 
10292  for (i = 0; i < s->nb_streams; i++) {
10293  AVStream *st = s->streams[i];
10294 
10295  if (st->codecpar->codec_tag == MKTAG('t','m','c','d') &&
10296  !tmcd_is_referenced(s, st->id)) {
10297  AVDictionaryEntry *tcr = av_dict_get(st->metadata, "timecode", NULL, 0);
10298  if (tcr) {
10299  av_dict_set(&s->metadata, "timecode", tcr->value, 0);
10300  break;
10301  }
10302  }
10303  }
10304 }
10305 
10306 static int read_tfra(MOVContext *mov, AVIOContext *f)
10307 {
10308  int version, fieldlength, i, j;
10309  int64_t pos = avio_tell(f);
10310  uint32_t size = avio_rb32(f);
10311  unsigned track_id, item_count;
10312 
10313  if (avio_rb32(f) != MKBETAG('t', 'f', 'r', 'a')) {
10314  return 1;
10315  }
10316  av_log(mov->fc, AV_LOG_VERBOSE, "found tfra\n");
10317 
10318  version = avio_r8(f);
10319  avio_rb24(f);
10320  track_id = avio_rb32(f);
10321  fieldlength = avio_rb32(f);
10322  item_count = avio_rb32(f);
10323  for (i = 0; i < item_count; i++) {
10324  int64_t time, offset;
10325  int index;
10326  MOVFragmentStreamInfo * frag_stream_info;
10327 
10328  if (avio_feof(f)) {
10329  return AVERROR_INVALIDDATA;
10330  }
10331 
10332  if (version == 1) {
10333  time = avio_rb64(f);
10334  offset = avio_rb64(f);
10335  } else {
10336  time = avio_rb32(f);
10337  offset = avio_rb32(f);
10338  }
10339 
10340  // The first sample of each stream in a fragment is always a random
10341  // access sample. So it's entry in the tfra can be used as the
10342  // initial PTS of the fragment.
10343  index = update_frag_index(mov, offset);
10344  frag_stream_info = get_frag_stream_info(&mov->frag_index, index, track_id);
10345  if (frag_stream_info &&
10346  frag_stream_info->first_tfra_pts == AV_NOPTS_VALUE)
10347  frag_stream_info->first_tfra_pts = time;
10348 
10349  for (j = 0; j < ((fieldlength >> 4) & 3) + 1; j++)
10350  avio_r8(f);
10351  for (j = 0; j < ((fieldlength >> 2) & 3) + 1; j++)
10352  avio_r8(f);
10353  for (j = 0; j < ((fieldlength >> 0) & 3) + 1; j++)
10354  avio_r8(f);
10355  }
10356 
10357  avio_seek(f, pos + size, SEEK_SET);
10358  return 0;
10359 }
10360 
10362 {
10363  int64_t stream_size = avio_size(f);
10364  int64_t original_pos = avio_tell(f);
10365  int64_t seek_ret;
10366  int ret = -1;
10367  if ((seek_ret = avio_seek(f, stream_size - 4, SEEK_SET)) < 0) {
10368  ret = seek_ret;
10369  goto fail;
10370  }
10371  c->mfra_size = avio_rb32(f);
10372  c->have_read_mfra_size = 1;
10373  if (!c->mfra_size || c->mfra_size > stream_size) {
10374  av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (unreasonable size)\n");
10375  goto fail;
10376  }
10377  if ((seek_ret = avio_seek(f, -((int64_t) c->mfra_size), SEEK_CUR)) < 0) {
10378  ret = seek_ret;
10379  goto fail;
10380  }
10381  if (avio_rb32(f) != c->mfra_size) {
10382  av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (size mismatch)\n");
10383  goto fail;
10384  }
10385  if (avio_rb32(f) != MKBETAG('m', 'f', 'r', 'a')) {
10386  av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (tag mismatch)\n");
10387  goto fail;
10388  }
10389  av_log(c->fc, AV_LOG_VERBOSE, "stream has mfra\n");
10390  do {
10391  ret = read_tfra(c, f);
10392  if (ret < 0)
10393  goto fail;
10394  } while (!ret);
10395  ret = 0;
10396  c->frag_index.complete = 1;
10397 fail:
10398  seek_ret = avio_seek(f, original_pos, SEEK_SET);
10399  if (seek_ret < 0) {
10400  av_log(c->fc, AV_LOG_ERROR,
10401  "failed to seek back after looking for mfra\n");
10402  ret = seek_ret;
10403  }
10404  return ret;
10405 }
10406 
10407 static int set_icc_profile_from_item(AVPacketSideData **coded_side_data, int *nb_coded_side_data,
10408  const HEIFItem *item)
10409 {
10410  AVPacketSideData *sd = av_packet_side_data_new(coded_side_data, nb_coded_side_data,
10412  item->icc_profile_size, 0);
10413  if (!sd)
10414  return AVERROR(ENOMEM);
10415 
10416  memcpy(sd->data, item->icc_profile, item->icc_profile_size);
10417 
10418  return 0;
10419 }
10420 
10421 static int set_display_matrix_from_item(AVPacketSideData **coded_side_data, int *nb_coded_side_data,
10422  const HEIFItem *item)
10423 {
10424  int32_t *matrix;
10425  AVPacketSideData *sd = av_packet_side_data_new(coded_side_data,
10426  nb_coded_side_data,
10428  9 * sizeof(*matrix), 0);
10429  if (!sd)
10430  return AVERROR(ENOMEM);
10431 
10432  matrix = (int32_t*)sd->data;
10433  /* rotation is in the counter-clockwise direction whereas
10434  * av_display_rotation_set() expects its argument to be
10435  * oriented clockwise, so we need to negate it. */
10437  av_display_matrix_flip(matrix, item->hflip, item->vflip);
10438 
10439  return 0;
10440 }
10441 
10442 static int read_image_grid(AVFormatContext *s, const HEIFGrid *grid,
10443  AVStreamGroupTileGrid *tile_grid)
10444 {
10445  MOVContext *c = s->priv_data;
10446  const HEIFItem *item = grid->item;
10447  int64_t offset = 0, pos = avio_tell(s->pb);
10448  int x = 0, y = 0, i = 0;
10449  int tile_rows, tile_cols;
10450  int flags, size;
10451 
10452  if (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL)) {
10453  av_log(c->fc, AV_LOG_INFO, "grid box with non seekable input\n");
10454  return AVERROR_PATCHWELCOME;
10455  }
10456  if (item->is_idat_relative) {
10457  if (!c->idat_offset) {
10458  av_log(c->fc, AV_LOG_ERROR, "missing idat box required by the image grid\n");
10459  return AVERROR_INVALIDDATA;
10460  }
10461  offset = c->idat_offset;
10462  }
10463 
10464  if (offset > INT64_MAX - item->extent_offset)
10465  return AVERROR_INVALIDDATA;
10466 
10467  avio_seek(s->pb, item->extent_offset + offset, SEEK_SET);
10468 
10469  avio_r8(s->pb); /* version */
10470  flags = avio_r8(s->pb);
10471 
10472  tile_rows = avio_r8(s->pb) + 1;
10473  tile_cols = avio_r8(s->pb) + 1;
10474  /* actual width and height of output image */
10475  tile_grid->width = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
10476  tile_grid->height = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
10477 
10478  av_log(c->fc, AV_LOG_TRACE, "grid: grid_rows %d grid_cols %d output_width %d output_height %d\n",
10479  tile_rows, tile_cols, tile_grid->width, tile_grid->height);
10480 
10481  avio_seek(s->pb, pos, SEEK_SET);
10482 
10483  size = tile_rows * tile_cols;
10484  tile_grid->nb_tiles = grid->nb_tiles;
10485 
10486  if (tile_grid->nb_tiles != size)
10487  return AVERROR_INVALIDDATA;
10488 
10489  for (int i = 0; i < tile_cols; i++)
10490  tile_grid->coded_width += grid->tile_item_list[i]->width;
10491  for (int i = 0; i < size; i += tile_cols)
10492  tile_grid->coded_height += grid->tile_item_list[i]->height;
10493 
10494  tile_grid->offsets = av_calloc(tile_grid->nb_tiles, sizeof(*tile_grid->offsets));
10495  if (!tile_grid->offsets)
10496  return AVERROR(ENOMEM);
10497 
10498  while (y < tile_grid->coded_height) {
10499  int left_col = i;
10500 
10501  while (x < tile_grid->coded_width) {
10502  if (i == tile_grid->nb_tiles)
10503  return AVERROR_INVALIDDATA;
10504 
10505  tile_grid->offsets[i].idx = grid->tile_idx_list[i];
10506  tile_grid->offsets[i].horizontal = x;
10507  tile_grid->offsets[i].vertical = y;
10508 
10509  x += grid->tile_item_list[i++]->width;
10510  }
10511 
10512  if (x > tile_grid->coded_width) {
10513  av_log(c->fc, AV_LOG_ERROR, "Non uniform HEIF tiles\n");
10514  return AVERROR_INVALIDDATA;
10515  }
10516 
10517  x = 0;
10518  y += grid->tile_item_list[left_col]->height;
10519  }
10520 
10521  if (y > tile_grid->coded_height || i != tile_grid->nb_tiles) {
10522  av_log(c->fc, AV_LOG_ERROR, "Non uniform HEIF tiles\n");
10523  return AVERROR_INVALIDDATA;
10524  }
10525 
10526  return 0;
10527 }
10528 
10529 static int read_image_iovl(AVFormatContext *s, const HEIFGrid *grid,
10530  AVStreamGroupTileGrid *tile_grid)
10531 {
10532  MOVContext *c = s->priv_data;
10533  const HEIFItem *item = grid->item;
10534  uint16_t canvas_fill_value[4];
10535  int64_t offset = 0, pos = avio_tell(s->pb);
10536  int ret = 0, flags;
10537 
10538  if (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL)) {
10539  av_log(c->fc, AV_LOG_INFO, "iovl box with non seekable input\n");
10540  return AVERROR_PATCHWELCOME;
10541  }
10542  if (item->is_idat_relative) {
10543  if (!c->idat_offset) {
10544  av_log(c->fc, AV_LOG_ERROR, "missing idat box required by the image overlay\n");
10545  return AVERROR_INVALIDDATA;
10546  }
10547  offset = c->idat_offset;
10548  }
10549 
10550  if (offset > INT64_MAX - item->extent_offset)
10551  return AVERROR_INVALIDDATA;
10552 
10553  avio_seek(s->pb, item->extent_offset + offset, SEEK_SET);
10554 
10555  avio_r8(s->pb); /* version */
10556  flags = avio_r8(s->pb);
10557 
10558  for (int i = 0; i < 4; i++)
10559  canvas_fill_value[i] = avio_rb16(s->pb);
10560  av_log(c->fc, AV_LOG_TRACE, "iovl: canvas_fill_value { %u, %u, %u, %u }\n",
10561  canvas_fill_value[0], canvas_fill_value[1],
10562  canvas_fill_value[2], canvas_fill_value[3]);
10563  for (int i = 0; i < 4; i++)
10564  tile_grid->background[i] = canvas_fill_value[i];
10565 
10566  /* actual width and height of output image */
10567  tile_grid->width =
10568  tile_grid->coded_width = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
10569  tile_grid->height =
10570  tile_grid->coded_height = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
10571 
10572  av_log(c->fc, AV_LOG_TRACE, "iovl: output_width %d, output_height %d\n",
10573  tile_grid->width, tile_grid->height);
10574 
10575  tile_grid->nb_tiles = grid->nb_tiles;
10576  tile_grid->offsets = av_malloc_array(tile_grid->nb_tiles, sizeof(*tile_grid->offsets));
10577  if (!tile_grid->offsets) {
10578  ret = AVERROR(ENOMEM);
10579  goto fail;
10580  }
10581 
10582  for (int i = 0; i < tile_grid->nb_tiles; i++) {
10583  tile_grid->offsets[i].idx = grid->tile_idx_list[i];
10584  tile_grid->offsets[i].horizontal = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
10585  tile_grid->offsets[i].vertical = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
10586  av_log(c->fc, AV_LOG_TRACE, "iovl: stream_idx[%d] %u, "
10587  "horizontal_offset[%d] %d, vertical_offset[%d] %d\n",
10588  i, tile_grid->offsets[i].idx,
10589  i, tile_grid->offsets[i].horizontal, i, tile_grid->offsets[i].vertical);
10590  }
10591 
10592 fail:
10593  avio_seek(s->pb, pos, SEEK_SET);
10594 
10595  return ret;
10596 }
10597 
10599  AVPacketSideData **coded_side_data, int *nb_coded_side_data,
10600  const HEIFItem *ref)
10601 {
10602  MOVContext *c = s->priv_data;
10603  AVPacketSideData *sd;
10604  AVExifMetadata ifd = { 0 };
10605  AVBufferRef *buf;
10606  int64_t offset = 0, pos = avio_tell(s->pb);
10607  unsigned orientation_id = av_exif_get_tag_id("Orientation");
10608  int err;
10609 
10610  if (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL)) {
10611  av_log(c->fc, AV_LOG_WARNING, "Exif metadata with non seekable input\n");
10612  return AVERROR_PATCHWELCOME;
10613  }
10614  if (ref->is_idat_relative) {
10615  if (!c->idat_offset) {
10616  av_log(c->fc, AV_LOG_ERROR, "missing idat box required by the Exif metadata\n");
10617  return AVERROR_INVALIDDATA;
10618  }
10619  offset = c->idat_offset;
10620  }
10621 
10622  buf = av_buffer_alloc(ref->extent_length);
10623  if (!buf)
10624  return AVERROR(ENOMEM);
10625 
10626  if (offset > INT64_MAX - ref->extent_offset) {
10627  err = AVERROR(ENOMEM);
10628  goto fail;
10629  }
10630 
10631  avio_seek(s->pb, ref->extent_offset + offset, SEEK_SET);
10632  err = avio_read(s->pb, buf->data, ref->extent_length);
10633  if (err != ref->extent_length) {
10634  if (err > 0)
10635  err = AVERROR_INVALIDDATA;
10636  goto fail;
10637  }
10638 
10639  // HEIF spec states that Exif metadata is informative. The irot item property is
10640  // the normative source of rotation information. So we remove any Orientation tag
10641  // present in the Exif buffer.
10642  err = av_exif_parse_buffer(s, buf->data, ref->extent_length, &ifd, AV_EXIF_T_OFF);
10643  if (err < 0) {
10644  av_log(s, AV_LOG_ERROR, "Unable to parse Exif metadata\n");
10645  goto fail;
10646  }
10647 
10648  err = av_exif_remove_entry(s, &ifd, orientation_id, 0);
10649  if (err < 0)
10650  goto fail;
10651  else if (!err)
10652  goto finish;
10653 
10654  av_buffer_unref(&buf);
10655  err = av_exif_write(s, &ifd, &buf, AV_EXIF_T_OFF);
10656  if (err < 0)
10657  goto fail;
10658 
10659 finish:
10660  offset = AV_RB32(buf->data) + 4;
10661  if (offset >= buf->size) {
10662  err = AVERROR_INVALIDDATA;
10663  goto fail;
10664  }
10665  sd = av_packet_side_data_new(coded_side_data, nb_coded_side_data,
10666  AV_PKT_DATA_EXIF, buf->size - offset, 0);
10667  if (!sd) {
10668  err = AVERROR(ENOMEM);
10669  goto fail;
10670  }
10671  memcpy(sd->data, buf->data + offset, buf->size - offset);
10672 
10673  err = 0;
10674 fail:
10675  av_buffer_unref(&buf);
10676  av_exif_free(&ifd);
10677  avio_seek(s->pb, pos, SEEK_SET);
10678 
10679  return err;
10680 }
10681 
10683 {
10684  MOVContext *mov = s->priv_data;
10685 
10686  for (int i = 0; i < mov->nb_heif_grid; i++) {
10688  AVStreamGroupTileGrid *tile_grid;
10689  const HEIFGrid *grid = &mov->heif_grid[i];
10690  int err, loop = 1;
10691 
10692  if (!stg)
10693  return AVERROR(ENOMEM);
10694 
10695  stg->id = grid->item->item_id;
10696  tile_grid = stg->params.tile_grid;
10697 
10698  for (int j = 0; j < grid->nb_tiles; j++) {
10699  int tile_id = grid->tile_id_list[j];
10700  int k;
10701 
10702  for (k = 0; k < mov->nb_heif_item; k++) {
10703  HEIFItem *item = mov->heif_item[k];
10704  AVStream *st;
10705 
10706  if (!item || item->item_id != tile_id)
10707  continue;
10708  st = item->st;
10709  if (!st) {
10710  av_log(s, AV_LOG_WARNING, "HEIF item id %d from grid id %d doesn't "
10711  "reference a stream\n",
10712  tile_id, grid->item->item_id);
10713  ff_remove_stream_group(s, stg);
10714  loop = 0;
10715  break;
10716  }
10717 
10718  grid->tile_item_list[j] = item;
10719  grid->tile_idx_list[j] = stg->nb_streams;
10720 
10721  err = avformat_stream_group_add_stream(stg, st);
10722  if (err < 0) {
10723  int l;
10724  if (err != AVERROR(EEXIST))
10725  return err;
10726 
10727  for (l = 0; l < stg->nb_streams; l++)
10728  if (stg->streams[l]->index == st->index)
10729  break;
10730  av_assert0(l < stg->nb_streams);
10731  grid->tile_idx_list[j] = l;
10732  }
10733 
10734  if (item->item_id != mov->primary_item_id)
10736  break;
10737  }
10738 
10739  if (k == mov->nb_heif_item) {
10740  av_assert0(loop);
10741  av_log(s, AV_LOG_WARNING, "HEIF item id %d referenced by grid id %d doesn't "
10742  "exist\n",
10743  tile_id, grid->item->item_id);
10744  ff_remove_stream_group(s, stg);
10745  loop = 0;
10746  }
10747  if (!loop)
10748  break;
10749  }
10750 
10751  if (!loop)
10752  continue;
10753 
10754  switch (grid->item->type) {
10755  case MKTAG('g','r','i','d'):
10756  err = read_image_grid(s, grid, tile_grid);
10757  break;
10758  case MKTAG('i','o','v','l'):
10759  err = read_image_iovl(s, grid, tile_grid);
10760  break;
10761  default:
10762  av_assert0(0);
10763  }
10764  if (err < 0)
10765  return err;
10766 
10767  for (int j = 0; j < grid->item->nb_iref_list; j++) {
10768  HEIFItem *ref = get_heif_item(mov, grid->item->iref_list[j].item_id);
10769 
10770  av_assert0(ref);
10771  switch(ref->type) {
10772  case MKTAG('E','x','i','f'):
10773  err = mov_parse_exif_item(s, &tile_grid->coded_side_data,
10774  &tile_grid->nb_coded_side_data, ref);
10775  if (err < 0 && (s->error_recognition & AV_EF_EXPLODE))
10776  return err;
10777  break;
10778  default:
10779  break;
10780  }
10781  }
10782 
10783  /* rotation */
10784  if (grid->item->rotation || grid->item->hflip || grid->item->vflip) {
10786  &tile_grid->nb_coded_side_data, grid->item);
10787  if (err < 0)
10788  return err;
10789  }
10790 
10791  /* ICC profile */
10792  if (grid->item->icc_profile_size) {
10793  err = set_icc_profile_from_item(&tile_grid->coded_side_data,
10794  &tile_grid->nb_coded_side_data, grid->item);
10795  if (err < 0)
10796  return err;
10797  }
10798 
10799  if (grid->item->name)
10800  av_dict_set(&stg->metadata, "title", grid->item->name, 0);
10801  if (grid->item->item_id == mov->primary_item_id)
10803  }
10804 
10805  return 0;
10806 }
10807 
10809 {
10810  MOVContext *mov = s->priv_data;
10811  int err;
10812 
10813  for (int i = 0; i < mov->nb_heif_item; i++) {
10814  HEIFItem *item = mov->heif_item[i];
10815  MOVStreamContext *sc;
10816  AVStream *st;
10817  int64_t offset = 0;
10818 
10819  if (!item)
10820  continue;
10821  if (!item->st) {
10822  continue;
10823  }
10824  if (item->is_idat_relative) {
10825  if (!mov->idat_offset) {
10826  av_log(s, AV_LOG_ERROR, "Missing idat box for item %d\n", item->item_id);
10827  return AVERROR_INVALIDDATA;
10828  }
10829  offset = mov->idat_offset;
10830  }
10831 
10832  st = item->st;
10833  sc = st->priv_data;
10834  st->codecpar->width = item->width;
10835  st->codecpar->height = item->height;
10836 
10837  sc->sample_size = sc->stsz_sample_size = item->extent_length;
10838  sc->sample_count = 1;
10839 
10840  err = sanity_checks(s, sc, st->index);
10841  if (err)
10842  return AVERROR_INVALIDDATA;
10843 
10844  if (offset > INT64_MAX - item->extent_offset)
10845  return AVERROR_INVALIDDATA;
10846 
10847  sc->chunk_offsets[0] = item->extent_offset + offset;
10848 
10849  if (item->item_id == mov->primary_item_id)
10851 
10852  for (int j = 0; j < item->nb_iref_list; j++) {
10853  HEIFItem *ref = get_heif_item(mov, item->iref_list[j].item_id);
10854 
10855  av_assert0(ref);
10856  switch(ref->type) {
10857  case MKTAG('E','x','i','f'):
10860  if (err < 0 && (s->error_recognition & AV_EF_EXPLODE))
10861  return err;
10862  break;
10863  default:
10864  break;
10865  }
10866  }
10867 
10868  if (item->rotation || item->hflip || item->vflip) {
10870  &st->codecpar->nb_coded_side_data, item);
10871  if (err < 0)
10872  return err;
10873  }
10874 
10875  mov_build_index(mov, st);
10876  }
10877 
10878  if (mov->nb_heif_grid) {
10879  err = mov_parse_tiles(s);
10880  if (err < 0)
10881  return err;
10882  }
10883 
10884  return 0;
10885 }
10886 
10888 {
10889  int err;
10890 
10891  for (int i = 0; i < s->nb_streams; i++) {
10892  AVStreamGroup *stg;
10893  const AVDictionaryEntry *tcr;
10894  AVStream *st = s->streams[i];
10895 
10896  if (st->codecpar->codec_tag != MKTAG('t','m','c','d'))
10897  continue;
10898 
10900  if (!stg)
10901  return AVERROR(ENOMEM);
10902 
10903  stg->id = st->id;
10904  tcr = av_dict_get(st->metadata, "timecode", NULL, 0);
10905 
10906  for (int j = 0; j < s->nb_streams; j++) {
10907  AVStream *st2 = s->streams[j];
10908  MOVStreamContext *sc2 = st2->priv_data;
10909  MovTref *tag = mov_find_tref_tag(sc2, MKTAG('t','m','c','d'));
10910 
10911  if (!tag)
10912  continue;
10913 
10914  for (int k = 0; k < tag->nb_id; k++) {
10915  if (tag->id[k] != st->id)
10916  continue;
10917 
10918  err = avformat_stream_group_add_stream(stg, st2);
10919  if (err < 0)
10920  return err;
10921 
10922  if (tcr)
10923  av_dict_set(&st2->metadata, "timecode", tcr->value, AV_DICT_DONT_OVERWRITE);
10924  }
10925  }
10926 
10927  if (!stg->nb_streams) {
10928  ff_remove_stream_group(s, stg);
10929  continue;
10930  }
10931 
10932  err = avformat_stream_group_add_stream(stg, st);
10933  if (err < 0)
10934  return err;
10935 
10936  stg->params.tref->metadata_index = stg->nb_streams - 1;
10937  }
10939 
10940  return 0;
10941 }
10942 
10944  uint32_t *tref_id, int nb_tref_id, int first_index)
10945 {
10946  if (!nb_tref_id)
10947  return NULL;
10948 
10949  for (int i = first_index; i < s->nb_streams; i++)
10950  for (int j = 0; j < nb_tref_id; j++)
10951  if (s->streams[i]->index != st->index &&
10952  s->streams[i]->id == tref_id[j])
10953  return s->streams[i];
10954 
10955  return NULL;
10956 }
10957 
10959 {
10960  int err;
10961 
10962  // Don't try to add a group if there's only one track
10963  if (s->nb_streams <= 1)
10964  return 0;
10965 
10966  for (int i = 0; i < s->nb_streams; i++) {
10967  AVStreamGroup *stg;
10968  AVStream *st = s->streams[i];
10969  AVStream *st_base;
10970  MOVStreamContext *sc = st->priv_data;
10971  MovTref *tag = mov_find_tref_tag(sc, MKTAG('s','b','a','s'));
10972  int j = 0;
10973 
10974  /* Find an enhancement stream. */
10975  if (st->codecpar->codec_id != AV_CODEC_ID_LCEVC || !tag)
10976  continue;
10977 
10979  if (!stg)
10980  return AVERROR(ENOMEM);
10981 
10982  stg->id = st->id;
10983  stg->params.lcevc->width = st->codecpar->width;
10984  stg->params.lcevc->height = st->codecpar->height;
10985 
10986  while (st_base = mov_find_reference_track(s, st, tag->id, tag->nb_id, j)) {
10987  err = avformat_stream_group_add_stream(stg, st_base);
10988  if (err < 0)
10989  return err;
10990 
10991  j = st_base->index + 1;
10992  }
10993  if (!j) {
10994  int loglevel = (s->error_recognition & AV_EF_EXPLODE) ? AV_LOG_ERROR : AV_LOG_WARNING;
10995  av_log(s, loglevel, "Failed to find base stream for LCEVC stream\n");
10996  ff_remove_stream_group(s, stg);
10997  if (s->error_recognition & AV_EF_EXPLODE)
10998  return AVERROR_INVALIDDATA;
10999  continue;
11000  }
11001 
11002  err = avformat_stream_group_add_stream(stg, st);
11003  if (err < 0)
11004  return err;
11005 
11006  stg->params.lcevc->lcevc_index = stg->nb_streams - 1;
11007  }
11008 
11009  return 0;
11010 }
11011 
11013 {
11014  int highest_id = 0, lowest_iamf_id = INT_MAX;
11015 
11016  for (int i = 0; i < s->nb_streams; i++) {
11017  const AVStream *st = s->streams[i];
11018  const MOVStreamContext *sc = st->priv_data;
11019  if (!sc->iamf)
11020  highest_id = FFMAX(highest_id, st->id);
11021  }
11022 
11023  for (int i = 0; i < s->nb_stream_groups; i++) {
11024  AVStreamGroup *stg = s->stream_groups[i];
11026  continue;
11027  for (int j = 0; j < stg->nb_streams; j++) {
11028  AVStream *st = stg->streams[j];
11029  lowest_iamf_id = FFMIN(lowest_iamf_id, st->id);
11030  }
11031  }
11032 
11033  if (highest_id < lowest_iamf_id)
11034  return;
11035 
11036  highest_id += !lowest_iamf_id;
11037  for (int i = 0; highest_id > 1 && i < s->nb_stream_groups; i++) {
11038  AVStreamGroup *stg = s->stream_groups[i];
11040  continue;
11041  for (int j = 0; j < stg->nb_streams; j++) {
11042  AVStream *st = stg->streams[j];
11043  MOVStreamContext *sc = st->priv_data;
11044  st->id += highest_id;
11045  sc->iamf_stream_offset = highest_id;
11046  }
11047  }
11048 }
11049 
11051 {
11052  MOVContext *mov = s->priv_data;
11053  AVIOContext *pb = s->pb;
11054  int j, err;
11055  MOVAtom atom = { AV_RL32("root") };
11056  int i;
11057 
11058  mov->fc = s;
11059  mov->trak_index = -1;
11060  mov->primary_item_id = -1;
11061  mov->cur_item_id = -1;
11062  /* .mov and .mp4 aren't streamable anyway (only progressive download if moov is before mdat) */
11063  if (pb->seekable & AVIO_SEEKABLE_NORMAL)
11064  atom.size = avio_size(pb);
11065  else
11066  atom.size = INT64_MAX;
11067 
11068  /* check MOV header */
11069  do {
11070  if (mov->moov_retry)
11071  avio_seek(pb, 0, SEEK_SET);
11072  if ((err = mov_read_default(mov, pb, atom)) < 0) {
11073  av_log(s, AV_LOG_ERROR, "error reading header\n");
11074  return err;
11075  }
11076  } while ((pb->seekable & AVIO_SEEKABLE_NORMAL) &&
11077  !mov->found_moov && (!mov->found_iloc || !mov->found_iinf) && !mov->moov_retry++);
11078  if (!mov->found_moov && !mov->found_iloc && !mov->found_iinf) {
11079  av_log(s, AV_LOG_ERROR, "moov atom not found\n");
11080  return AVERROR_INVALIDDATA;
11081  }
11082  av_log(mov->fc, AV_LOG_TRACE, "on_parse_exit_offset=%"PRId64"\n", avio_tell(pb));
11083 
11084  if (mov->found_iloc && mov->found_iinf) {
11085  err = mov_parse_heif_items(s);
11086  if (err < 0)
11087  return err;
11088  }
11089  // prevent iloc and iinf boxes from being parsed while reading packets.
11090  // this is needed because an iinf box may have been parsed but ignored
11091  // for having old infe boxes which create no streams.
11092  mov->found_iloc = mov->found_iinf = 1;
11093 
11094  if (pb->seekable & AVIO_SEEKABLE_NORMAL) {
11095  if (mov->nb_chapter_tracks > 0 && !mov->ignore_chapters)
11097  for (i = 0; i < s->nb_streams; i++)
11098  if (s->streams[i]->codecpar->codec_tag == AV_RL32("tmcd")) {
11099  mov_read_timecode_track(s, s->streams[i]);
11100  } else if (s->streams[i]->codecpar->codec_tag == AV_RL32("rtmd")) {
11101  mov_read_rtmd_track(s, s->streams[i]);
11102  }
11103  }
11104 
11105  /* copy timecode metadata from tmcd tracks to the related video streams */
11106  err = mov_parse_tmcd_streams(s);
11107  if (err < 0)
11108  return err;
11109 
11110  /* Create LCEVC stream groups. */
11111  err = mov_parse_lcevc_streams(s);
11112  if (err < 0)
11113  return err;
11114 
11115  for (i = 0; i < s->nb_streams; i++) {
11116  AVStream *st = s->streams[i];
11117  FFStream *const sti = ffstream(st);
11118  MOVStreamContext *sc = st->priv_data;
11119  uint32_t dvdsub_clut[FF_DVDCLUT_CLUT_LEN] = {0};
11120  fix_timescale(mov, sc);
11121 
11122  /* Set the primary extradata based on the first Sample if it doesn't reference the first stsd entry. */
11123  if (sc->stsc_count && sc->extradata_size && !sc->iamf &&
11124  sc->stsc_data[0].id > 1 && sc->stsc_data[0].id <= sc->stsd_count) {
11125  sc->last_stsd_index = sc->stsc_data[0].id - 1;
11126  av_freep(&st->codecpar->extradata);
11128  if (sc->extradata_size[sc->last_stsd_index]) {
11130  if (!st->codecpar->extradata)
11131  return AVERROR(ENOMEM);
11132  memcpy(st->codecpar->extradata, sc->extradata[sc->last_stsd_index], sc->extradata_size[sc->last_stsd_index]);
11133  }
11134  }
11135 
11136  if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
11137  st->codecpar->codec_id == AV_CODEC_ID_AAC) {
11138  sti->skip_samples = sc->start_pad;
11139  }
11140  if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && sc->nb_frames_for_fps > 0 && sc->duration_for_fps > 0)
11142  sc->time_scale*(int64_t)sc->nb_frames_for_fps, sc->duration_for_fps, INT_MAX);
11144  if (st->codecpar->width <= 0 || st->codecpar->height <= 0) {
11145  st->codecpar->width = sc->width;
11146  st->codecpar->height = sc->height;
11147  }
11150 
11151  for (j = 0; j < FF_DVDCLUT_CLUT_LEN; j++)
11152  dvdsub_clut[j] = AV_RB32(st->codecpar->extradata + j * 4);
11153 
11154  err = ff_dvdclut_yuv_to_rgb(dvdsub_clut, FF_DVDCLUT_CLUT_SIZE);
11155  if (err < 0)
11156  return err;
11157 
11158  av_freep(&st->codecpar->extradata);
11159  st->codecpar->extradata_size = 0;
11160 
11162  st->codecpar);
11163  if (err < 0)
11164  return err;
11165  }
11166  }
11167  if (mov->handbrake_version &&
11168  mov->handbrake_version <= 1000000*0 + 1000*10 + 2 && // 0.10.2
11169  st->codecpar->codec_id == AV_CODEC_ID_MP3) {
11170  av_log(s, AV_LOG_VERBOSE, "Forcing full parsing for mp3 stream\n");
11172  }
11173  }
11174 
11175  if (mov->trex_data || mov->use_mfra_for > 0) {
11176  for (i = 0; i < s->nb_streams; i++) {
11177  AVStream *st = s->streams[i];
11178  MOVStreamContext *sc = st->priv_data;
11179  if (sc->duration_for_fps > 0) {
11180  /* Akin to sc->data_size * 8 * sc->time_scale / sc->duration_for_fps but accounting for overflows. */
11182  if (st->codecpar->bit_rate == INT64_MIN) {
11183  av_log(s, AV_LOG_WARNING, "Overflow during bit rate calculation %"PRId64" * 8 * %d\n",
11184  sc->data_size, sc->time_scale);
11185  st->codecpar->bit_rate = 0;
11186  if (s->error_recognition & AV_EF_EXPLODE)
11187  return AVERROR_INVALIDDATA;
11188  }
11189  }
11190  }
11191  }
11192 
11193  for (i = 0; i < mov->bitrates_count && i < s->nb_streams; i++) {
11194  if (mov->bitrates[i]) {
11195  s->streams[i]->codecpar->bit_rate = mov->bitrates[i];
11196  }
11197  }
11198 
11200 
11201  for (i = 0; i < s->nb_streams; i++) {
11202  AVStream *st = s->streams[i];
11203  MOVStreamContext *sc = st->priv_data;
11204 
11205  switch (st->codecpar->codec_type) {
11206  case AVMEDIA_TYPE_AUDIO:
11207  err = ff_replaygain_export(st, s->metadata);
11208  if (err < 0)
11209  return err;
11210  break;
11211  case AVMEDIA_TYPE_VIDEO:
11212  if (sc->display_matrix) {
11215  (uint8_t*)sc->display_matrix, sizeof(int32_t) * 9, 0))
11216  return AVERROR(ENOMEM);
11217 
11218  sc->display_matrix = NULL;
11219  }
11220  if (sc->stereo3d) {
11223  (uint8_t *)sc->stereo3d, sc->stereo3d_size, 0))
11224  return AVERROR(ENOMEM);
11225 
11226  sc->stereo3d = NULL;
11227  }
11228  if (sc->spherical) {
11231  (uint8_t *)sc->spherical, sc->spherical_size, 0))
11232  return AVERROR(ENOMEM);
11233 
11234  sc->spherical = NULL;
11235  }
11236  if (sc->mastering) {
11239  (uint8_t *)sc->mastering, sc->mastering_size, 0))
11240  return AVERROR(ENOMEM);
11241 
11242  sc->mastering = NULL;
11243  }
11244  if (sc->coll) {
11247  (uint8_t *)sc->coll, sc->coll_size, 0))
11248  return AVERROR(ENOMEM);
11249 
11250  sc->coll = NULL;
11251  }
11252  if (sc->ambient) {
11255  (uint8_t *) sc->ambient, sc->ambient_size, 0))
11256  return AVERROR(ENOMEM);
11257 
11258  sc->ambient = NULL;
11259  }
11260  break;
11261  }
11262  }
11263 
11264  fix_stream_ids(s);
11265 
11267 
11268  for (i = 0; i < mov->frag_index.nb_items; i++)
11269  if (mov->frag_index.item[i].moof_offset <= mov->fragment.moof_offset)
11270  mov->frag_index.item[i].headers_read = 1;
11271 
11272  return 0;
11273 }
11274 
11276 {
11278  int64_t best_dts = INT64_MAX;
11279  int i;
11280  MOVContext *mov = s->priv_data;
11281  int no_interleave = !mov->interleaved_read || !(s->pb->seekable & AVIO_SEEKABLE_NORMAL);
11282  for (i = 0; i < s->nb_streams; i++) {
11283  AVStream *avst = s->streams[i];
11284  FFStream *const avsti = ffstream(avst);
11285  MOVStreamContext *msc = avst->priv_data;
11286  if (msc->pb && msc->current_sample < avsti->nb_index_entries) {
11287  AVIndexEntry *current_sample = &avsti->index_entries[msc->current_sample];
11288  int64_t dts = av_rescale(current_sample->timestamp, AV_TIME_BASE, msc->time_scale);
11289  uint64_t dtsdiff = best_dts > dts ? best_dts - (uint64_t)dts : ((uint64_t)dts - best_dts);
11290  av_log(s, AV_LOG_TRACE, "stream %d, sample %d, dts %"PRId64"\n", i, msc->current_sample, dts);
11291  if (!sample || (no_interleave && current_sample->pos < sample->pos) ||
11292  ((s->pb->seekable & AVIO_SEEKABLE_NORMAL) &&
11293  ((msc->pb != s->pb && dts < best_dts) || (msc->pb == s->pb && dts != AV_NOPTS_VALUE &&
11294  ((dtsdiff <= AV_TIME_BASE && current_sample->pos < sample->pos) ||
11295  (dtsdiff > AV_TIME_BASE && dts < best_dts && mov->interleaved_read)))))) {
11296  sample = current_sample;
11297  best_dts = dts;
11298  *st = avst;
11299  }
11300  }
11301  }
11302  return sample;
11303 }
11304 
11305 static int should_retry(AVIOContext *pb, int error_code) {
11306  if (error_code == AVERROR_EOF || avio_feof(pb))
11307  return 0;
11308 
11309  return 1;
11310 }
11311 
11312 static int mov_switch_root(AVFormatContext *s, int64_t target, int index)
11313 {
11314  int ret;
11315  MOVContext *mov = s->priv_data;
11316 
11317  if (index >= 0 && index < mov->frag_index.nb_items)
11318  target = mov->frag_index.item[index].moof_offset;
11319  if (target >= 0 && avio_seek(s->pb, target, SEEK_SET) != target) {
11320  av_log(mov->fc, AV_LOG_ERROR, "root atom offset 0x%"PRIx64": partial file\n", target);
11321  return AVERROR_INVALIDDATA;
11322  }
11323 
11324  mov->next_root_atom = 0;
11325  if ((index < 0 && target >= 0) || index >= mov->frag_index.nb_items)
11326  index = search_frag_moof_offset(&mov->frag_index, target);
11327  if (index >= 0 && index < mov->frag_index.nb_items &&
11328  mov->frag_index.item[index].moof_offset == target) {
11329  if (index + 1 < mov->frag_index.nb_items)
11330  mov->next_root_atom = mov->frag_index.item[index + 1].moof_offset;
11331  if (mov->frag_index.item[index].headers_read)
11332  return 0;
11333  mov->frag_index.item[index].headers_read = 1;
11334  }
11335 
11336  mov->found_mdat = 0;
11337 
11338  ret = mov_read_default(mov, s->pb, (MOVAtom){ AV_RL32("root"), INT64_MAX });
11339  if (ret < 0)
11340  return ret;
11341  if (avio_feof(s->pb))
11342  return AVERROR_EOF;
11343  av_log(s, AV_LOG_TRACE, "read fragments, offset 0x%"PRIx64"\n", avio_tell(s->pb));
11344 
11345  return 1;
11346 }
11347 
11349 {
11350  MOVStreamContext *sc = st->priv_data;
11351  uint8_t *side, *extradata;
11352  int extradata_size;
11353 
11354  /* Save the current index. */
11355  sc->last_stsd_index = sc->stsc_data[sc->stsc_index].id - 1;
11356 
11357  /* Notify the decoder that extradata changed. */
11358  extradata_size = sc->extradata_size[sc->last_stsd_index];
11359  extradata = sc->extradata[sc->last_stsd_index];
11360  if (st->discard != AVDISCARD_ALL && extradata_size > 0 && extradata) {
11363  extradata_size);
11364  if (!side)
11365  return AVERROR(ENOMEM);
11366  memcpy(side, extradata, extradata_size);
11367  }
11368 
11369  return 0;
11370 }
11371 
11372 static int get_eia608_packet(AVIOContext *pb, AVPacket *pkt, int src_size)
11373 {
11374  /* We can't make assumptions about the structure of the payload,
11375  because it may include multiple cdat and cdt2 samples. */
11376  const uint32_t cdat = AV_RB32("cdat");
11377  const uint32_t cdt2 = AV_RB32("cdt2");
11378  int ret, out_size = 0;
11379 
11380  /* a valid payload must have size, 4cc, and at least 1 byte pair: */
11381  if (src_size < 10)
11382  return AVERROR_INVALIDDATA;
11383 
11384  /* avoid an int overflow: */
11385  if ((src_size - 8) / 2 >= INT_MAX / 3)
11386  return AVERROR_INVALIDDATA;
11387 
11388  ret = av_new_packet(pkt, ((src_size - 8) / 2) * 3);
11389  if (ret < 0)
11390  return ret;
11391 
11392  /* parse and re-format the c608 payload in one pass. */
11393  while (src_size >= 10) {
11394  const uint32_t atom_size = avio_rb32(pb);
11395  const uint32_t atom_type = avio_rb32(pb);
11396  const uint32_t data_size = atom_size - 8;
11397  const uint8_t cc_field =
11398  atom_type == cdat ? 1 :
11399  atom_type == cdt2 ? 2 :
11400  0;
11401 
11402  /* account for bytes consumed for atom size and type. */
11403  src_size -= 8;
11404 
11405  /* make sure the data size stays within the buffer boundaries. */
11406  if (data_size < 2 || data_size > src_size) {
11408  break;
11409  }
11410 
11411  /* make sure the data size is consistent with N byte pairs. */
11412  if (data_size % 2 != 0) {
11414  break;
11415  }
11416 
11417  if (!cc_field) {
11418  /* neither cdat or cdt2 ... skip it */
11419  avio_skip(pb, data_size);
11420  src_size -= data_size;
11421  continue;
11422  }
11423 
11424  for (uint32_t i = 0; i < data_size; i += 2) {
11425  pkt->data[out_size] = (0x1F << 3) | (1 << 2) | (cc_field - 1);
11426  pkt->data[out_size + 1] = avio_r8(pb);
11427  pkt->data[out_size + 2] = avio_r8(pb);
11428  out_size += 3;
11429  src_size -= 2;
11430  }
11431  }
11432 
11433  if (src_size > 0)
11434  /* skip any remaining unread portion of the input payload */
11435  avio_skip(pb, src_size);
11436 
11438  return ret;
11439 }
11440 
11442  int64_t current_index, AVPacket *pkt)
11443 {
11444  MOVStreamContext *sc = st->priv_data;
11445 
11446  pkt->stream_index = sc->ffindex;
11447  pkt->dts = sample->timestamp;
11448  if (sample->flags & AVINDEX_DISCARD_FRAME) {
11450  }
11451  if (sc->stts_count && sc->tts_index < sc->tts_count)
11452  pkt->duration = sc->tts_data[sc->tts_index].duration;
11453  if (sc->ctts_count && sc->tts_index < sc->tts_count) {
11455  } else {
11456  if (pkt->duration == 0) {
11457  int64_t next_dts = (sc->current_sample < ffstream(st)->nb_index_entries) ?
11459  if (next_dts >= pkt->dts)
11460  pkt->duration = next_dts - pkt->dts;
11461  }
11462  pkt->pts = pkt->dts;
11463  }
11464 
11465  if (sc->tts_data && sc->tts_index < sc->tts_count) {
11466  /* update tts context */
11467  sc->tts_sample++;
11468  if (sc->tts_index < sc->tts_count &&
11469  sc->tts_data[sc->tts_index].count == sc->tts_sample) {
11470  sc->tts_index++;
11471  sc->tts_sample = 0;
11472  }
11473  }
11474 
11475  if (sc->sdtp_data && sc->current_sample <= sc->sdtp_count) {
11476  uint8_t sample_flags = sc->sdtp_data[sc->current_sample - 1];
11477  uint8_t sample_is_depended_on = (sample_flags >> 2) & 0x3;
11478  pkt->flags |= sample_is_depended_on == MOV_SAMPLE_DEPENDENCY_NO ? AV_PKT_FLAG_DISPOSABLE : 0;
11479  }
11480  pkt->flags |= sample->flags & AVINDEX_KEYFRAME ? AV_PKT_FLAG_KEY : 0;
11481  pkt->pos = sample->pos;
11482 
11483  /* Multiple stsd handling. */
11484  if (sc->stsc_data) {
11485  if (sc->stsc_data[sc->stsc_index].id > 0 &&
11486  sc->stsc_data[sc->stsc_index].id - 1 < sc->stsd_count &&
11487  sc->stsc_data[sc->stsc_index].id - 1 != sc->last_stsd_index) {
11488  int ret = mov_change_extradata(st, pkt);
11489  if (ret < 0)
11490  return ret;
11491  }
11492 
11493  /* Update the stsc index for the next sample */
11494  sc->stsc_sample++;
11495  if (mov_stsc_index_valid(sc->stsc_index, sc->stsc_count) &&
11496  mov_get_stsc_samples(sc, sc->stsc_index) == sc->stsc_sample) {
11497  sc->stsc_index++;
11498  sc->stsc_sample = 0;
11499  }
11500  }
11501 
11502  return 0;
11503 }
11504 
11506 {
11507  MOVContext *mov = s->priv_data;
11508  MOVStreamContext *sc;
11510  AVStream *st = NULL;
11511  FFStream *avsti = NULL;
11512  int64_t current_index;
11513  int ret;
11514  int i;
11515  mov->fc = s;
11516  retry:
11517  if (s->pb->pos == 0) {
11518 
11519  // Discard current fragment index
11520  if (mov->frag_index.allocated_size > 0) {
11521  for(int i = 0; i < mov->frag_index.nb_items; i++) {
11523  }
11524  av_freep(&mov->frag_index.item);
11525  mov->frag_index.nb_items = 0;
11526  mov->frag_index.allocated_size = 0;
11527  mov->frag_index.current = -1;
11528  mov->frag_index.complete = 0;
11529  }
11530 
11531  for (i = 0; i < s->nb_streams; i++) {
11532  AVStream *avst = s->streams[i];
11533  MOVStreamContext *msc = avst->priv_data;
11534 
11535  // Clear current sample
11536  mov_current_sample_set(msc, 0);
11537  msc->tts_index = 0;
11538 
11539  // Discard current index entries
11540  avsti = ffstream(avst);
11541  if (avsti->index_entries_allocated_size > 0) {
11542  av_freep(&avsti->index_entries);
11543  avsti->index_entries_allocated_size = 0;
11544  avsti->nb_index_entries = 0;
11545  }
11546  }
11547 
11548  if ((ret = mov_switch_root(s, -1, -1)) < 0)
11549  return ret;
11550  }
11551  sample = mov_find_next_sample(s, &st);
11552  if (!sample || (mov->next_root_atom && sample->pos > mov->next_root_atom)) {
11553  if (!mov->next_root_atom)
11554  return AVERROR_EOF;
11555  if ((ret = mov_switch_root(s, mov->next_root_atom, -1)) < 0)
11556  return ret;
11557  goto retry;
11558  }
11559  sc = st->priv_data;
11560  /* must be done just before reading, to avoid infinite loop on sample */
11561  current_index = sc->current_index;
11563 
11564  if (mov->next_root_atom) {
11565  sample->pos = FFMIN(sample->pos, mov->next_root_atom);
11566  sample->size = FFMIN(sample->size, (mov->next_root_atom - sample->pos));
11567  }
11568 
11569  if (st->discard != AVDISCARD_ALL || sc->iamf) {
11570  int64_t ret64 = avio_seek(sc->pb, sample->pos, SEEK_SET);
11571  if (ret64 != sample->pos) {
11572  av_log(mov->fc, AV_LOG_ERROR, "stream %d, offset 0x%"PRIx64": partial file\n",
11573  sc->ffindex, sample->pos);
11574  if (should_retry(sc->pb, ret64)) {
11576  } else if (ret64 < 0) {
11577  return (int)ret64;
11578  }
11579  return AVERROR_INVALIDDATA;
11580  }
11581 
11582  if (st->discard == AVDISCARD_NONKEY && !(sample->flags & AVINDEX_KEYFRAME)) {
11583  av_log(mov->fc, AV_LOG_DEBUG, "Nonkey frame from stream %d discarded due to AVDISCARD_NONKEY\n", sc->ffindex);
11584  goto retry;
11585  }
11586 
11587  if (st->codecpar->codec_id == AV_CODEC_ID_EIA_608 && sample->size > 8)
11588  ret = get_eia608_packet(sc->pb, pkt, sample->size);
11589 #if CONFIG_IAMFDEC
11590  else if (sc->iamf) {
11591  int64_t pts, dts, pos, duration;
11592  int flags, size = sample->size;
11593  ret = mov_finalize_packet(s, st, sample, current_index, pkt);
11594  pts = pkt->pts; dts = pkt->dts;
11595  pos = pkt->pos; flags = pkt->flags;
11596  duration = pkt->duration;
11597  while (!ret && size > 0) {
11598  ret = ff_iamf_read_packet(s, sc->iamf, sc->pb, size, sc->iamf_stream_offset, pkt);
11599  if (ret < 0) {
11600  if (should_retry(sc->pb, ret))
11602  return ret;
11603  }
11604  size -= ret;
11605 
11606  if (pkt->flags & AV_PKT_FLAG_DISCARD) {
11608  ret = 0;
11609  continue;
11610  }
11611  pkt->pts = pts; pkt->dts = dts;
11612  pkt->pos = pos; pkt->flags |= flags;
11613  pkt->duration = duration;
11614  ret = ff_buffer_packet(s, pkt);
11615  }
11616  if (!ret)
11617  return FFERROR_REDO;
11618  }
11619 #endif
11620  else if (st->codecpar->codec_id == AV_CODEC_ID_APV && sample->size > 4) {
11621  const uint32_t au_size = avio_rb32(sc->pb);
11622  ret = av_get_packet(sc->pb, pkt, au_size);
11623  } else
11624  ret = av_get_packet(sc->pb, pkt, sample->size);
11625  if (ret < 0) {
11626  if (should_retry(sc->pb, ret)) {
11628  }
11629  return ret;
11630  }
11631 #if CONFIG_DV_DEMUXER
11632  if (mov->dv_demux && sc->dv_audio_container) {
11635  if (ret < 0)
11636  return ret;
11638  if (ret < 0)
11639  return ret;
11640  }
11641 #endif
11642  if (sc->has_palette) {
11643  uint8_t *pal;
11644 
11646  if (!pal) {
11647  av_log(mov->fc, AV_LOG_ERROR, "Cannot append palette to packet\n");
11648  } else {
11649  memcpy(pal, sc->palette, AVPALETTE_SIZE);
11650  sc->has_palette = 0;
11651  }
11652  }
11653  if (st->codecpar->codec_id == AV_CODEC_ID_MP3 && !ffstream(st)->need_parsing && pkt->size > 4) {
11654  if (ff_mpa_check_header(AV_RB32(pkt->data)) < 0)
11656  }
11657  }
11658 
11659  ret = mov_finalize_packet(s, st, sample, current_index, pkt);
11660  if (ret < 0)
11661  return ret;
11662 
11663  if (st->discard == AVDISCARD_ALL)
11664  goto retry;
11665 
11666  if (mov->aax_mode)
11667  aax_filter(pkt->data, pkt->size, mov);
11668 
11669  ret = cenc_filter(mov, st, sc, pkt, current_index);
11670  if (ret < 0) {
11671  return ret;
11672  }
11673 
11674  return 0;
11675 }
11676 
11678 {
11679  MOVContext *mov = s->priv_data;
11680  int index;
11681 
11682  if (!mov->frag_index.complete)
11683  return 0;
11684 
11685  index = search_frag_timestamp(s, &mov->frag_index, st, timestamp);
11686  if (index < 0)
11687  index = 0;
11688  if (!mov->frag_index.item[index].headers_read)
11689  return mov_switch_root(s, -1, index);
11690  if (index + 1 < mov->frag_index.nb_items)
11691  mov->next_root_atom = mov->frag_index.item[index + 1].moof_offset;
11692 
11693  return 0;
11694 }
11695 
11696 static int is_open_key_sample(const MOVStreamContext *sc, int sample)
11697 {
11698  // TODO: a bisect search would scale much better
11699  for (int i = 0; i < sc->open_key_samples_count; i++) {
11700  const int oks = sc->open_key_samples[i];
11701  if (oks == sample)
11702  return 1;
11703  if (oks > sample) /* list is monotically increasing so we can stop early */
11704  break;
11705  }
11706  return 0;
11707 }
11708 
11709 /*
11710  * Some key sample may be key frames but not IDR frames, so a random access to
11711  * them may not be allowed.
11712  */
11713 static int can_seek_to_key_sample(AVStream *st, int sample, int64_t requested_pts)
11714 {
11715  MOVStreamContext *sc = st->priv_data;
11716  FFStream *const sti = ffstream(st);
11717  int64_t key_sample_dts, key_sample_pts;
11718 
11719  if (st->codecpar->codec_id != AV_CODEC_ID_HEVC)
11720  return 1;
11721 
11722  if (sample >= sc->sample_offsets_count)
11723  return 1;
11724 
11725  av_assert0(sample >= 0);
11726  key_sample_dts = sti->index_entries[sample].timestamp;
11727  key_sample_pts = key_sample_dts + sc->sample_offsets[sample] + sc->dts_shift;
11728 
11729  /*
11730  * If the sample needs to be presented before an open key sample, they may
11731  * not be decodable properly, even though they come after in decoding
11732  * order.
11733  */
11734  if (is_open_key_sample(sc, sample) && key_sample_pts > requested_pts)
11735  return 0;
11736 
11737  return 1;
11738 }
11739 
11740 static int mov_seek_stream(AVFormatContext *s, AVStream *st, int64_t timestamp, int flags)
11741 {
11742  MOVStreamContext *sc = st->priv_data;
11743  FFStream *const sti = ffstream(st);
11744  int sample, time_sample, ret, requested_sample;
11745  int64_t next_ts;
11746  unsigned int i;
11747 
11748  // Here we consider timestamp to be PTS, hence try to offset it so that we
11749  // can search over the DTS timeline.
11750  timestamp -= (sc->min_corrected_pts + sc->dts_shift);
11751 
11752  ret = mov_seek_fragment(s, st, timestamp);
11753  if (ret < 0)
11754  return ret;
11755 
11756  for (;;) {
11757  sample = av_index_search_timestamp(st, timestamp, flags);
11758  av_log(s, AV_LOG_TRACE, "stream %d, timestamp %"PRId64", sample %d\n", st->index, timestamp, sample);
11759  if (sample < 0 && sti->nb_index_entries && timestamp < sti->index_entries[0].timestamp)
11760  sample = 0;
11761  if (sample < 0) /* not sure what to do */
11762  return AVERROR_INVALIDDATA;
11763 
11764  if (!sample || can_seek_to_key_sample(st, sample, timestamp))
11765  break;
11766 
11767  next_ts = timestamp - FFMAX(sc->min_sample_duration, 1);
11768  requested_sample = av_index_search_timestamp(st, next_ts, flags);
11769  if (requested_sample < 0)
11770  return AVERROR_INVALIDDATA;
11771 
11772  // If we've reached a different sample trying to find a good pts to
11773  // seek to, give up searching because we'll end up seeking back to
11774  // sample 0 on every seek.
11775  if (sample != requested_sample && !can_seek_to_key_sample(st, requested_sample, next_ts))
11776  break;
11777 
11778  timestamp = next_ts;
11779  }
11780 
11782  av_log(s, AV_LOG_TRACE, "stream %d, found sample %d\n", st->index, sc->current_sample);
11783  /* adjust time to sample index */
11784  if (sc->tts_data) {
11785  time_sample = 0;
11786  for (i = 0; i < sc->tts_count; i++) {
11787  int next = time_sample + sc->tts_data[i].count;
11788  if (next > sc->current_sample) {
11789  sc->tts_index = i;
11790  sc->tts_sample = sc->current_sample - time_sample;
11791  break;
11792  }
11793  time_sample = next;
11794  }
11795  }
11796 
11797  /* adjust stsd index */
11798  if (sc->chunk_count) {
11799  time_sample = 0;
11800  for (i = 0; i < sc->stsc_count; i++) {
11801  int64_t next = time_sample + mov_get_stsc_samples(sc, i);
11802  if (next > sc->current_sample) {
11803  sc->stsc_index = i;
11804  sc->stsc_sample = sc->current_sample - time_sample;
11805  break;
11806  }
11807  av_assert0(next == (int)next);
11808  time_sample = next;
11809  }
11810  }
11811 
11812  return sample;
11813 }
11814 
11816 {
11817  MOVStreamContext *sc = st->priv_data;
11818  FFStream *const sti = ffstream(st);
11819  int64_t first_ts = sti->index_entries[0].timestamp;
11821  int64_t off;
11822 
11824  return 0;
11825 
11826  /* compute skip samples according to stream start_pad, seek ts and first ts */
11827  off = av_rescale_q(ts - first_ts, st->time_base,
11828  (AVRational){1, st->codecpar->sample_rate});
11829  return FFMAX(sc->start_pad - off, 0);
11830 }
11831 
11832 static int mov_read_seek(AVFormatContext *s, int stream_index, int64_t sample_time, int flags)
11833 {
11834  MOVContext *mc = s->priv_data;
11835  AVStream *st;
11836  FFStream *sti;
11837  int sample;
11838  int i;
11839 
11840  if (stream_index >= s->nb_streams)
11841  return AVERROR_INVALIDDATA;
11842 
11843  st = s->streams[stream_index];
11844  sti = ffstream(st);
11845  sample = mov_seek_stream(s, st, sample_time, flags);
11846  if (sample < 0)
11847  return sample;
11848 
11849  if (mc->seek_individually) {
11850  /* adjust seek timestamp to found sample timestamp */
11851  int64_t seek_timestamp = sti->index_entries[sample].timestamp;
11853 
11854  for (i = 0; i < s->nb_streams; i++) {
11855  AVStream *const st = s->streams[i];
11856  FFStream *const sti = ffstream(st);
11857  int64_t timestamp;
11858 
11859  if (stream_index == i)
11860  continue;
11861 
11862  timestamp = av_rescale_q(seek_timestamp, s->streams[stream_index]->time_base, st->time_base);
11863  sample = mov_seek_stream(s, st, timestamp, flags);
11864  if (sample >= 0)
11866  }
11867  } else {
11868  for (i = 0; i < s->nb_streams; i++) {
11869  MOVStreamContext *sc;
11870  st = s->streams[i];
11871  sc = st->priv_data;
11872  mov_current_sample_set(sc, 0);
11873  }
11874  while (1) {
11875  MOVStreamContext *sc;
11877  if (!entry)
11878  return AVERROR_INVALIDDATA;
11879  sc = st->priv_data;
11880  if (sc->ffindex == stream_index && sc->current_sample == sample)
11881  break;
11883  }
11884  }
11885  return 0;
11886 }
11887 
11888 #define OFFSET(x) offsetof(MOVContext, x)
11889 #define FLAGS AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM
11890 static const AVOption mov_options[] = {
11891  {"use_absolute_path",
11892  "allow using absolute path when opening alias, this is a possible security issue",
11893  OFFSET(use_absolute_path), AV_OPT_TYPE_BOOL, {.i64 = 0},
11894  0, 1, FLAGS},
11895  {"seek_streams_individually",
11896  "Seek each stream individually to the closest point",
11897  OFFSET(seek_individually), AV_OPT_TYPE_BOOL, { .i64 = 1 },
11898  0, 1, FLAGS},
11899  {"ignore_editlist", "Ignore the edit list atom.", OFFSET(ignore_editlist), AV_OPT_TYPE_BOOL, {.i64 = 0},
11900  0, 1, FLAGS},
11901  {"advanced_editlist",
11902  "Modify the AVIndex according to the editlists. Use this option to decode in the order specified by the edits.",
11903  OFFSET(advanced_editlist), AV_OPT_TYPE_BOOL, {.i64 = 1},
11904  0, 1, FLAGS},
11905  {"ignore_chapters", "", OFFSET(ignore_chapters), AV_OPT_TYPE_BOOL, {.i64 = 0},
11906  0, 1, FLAGS},
11907  {"use_mfra_for",
11908  "use mfra for fragment timestamps",
11909  OFFSET(use_mfra_for), AV_OPT_TYPE_INT, {.i64 = FF_MOV_FLAG_MFRA_AUTO},
11911  .unit = "use_mfra_for"},
11912  {"auto", "auto", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_AUTO}, 0, 0,
11913  FLAGS, .unit = "use_mfra_for" },
11914  {"dts", "dts", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_DTS}, 0, 0,
11915  FLAGS, .unit = "use_mfra_for" },
11916  {"pts", "pts", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_PTS}, 0, 0,
11917  FLAGS, .unit = "use_mfra_for" },
11918  {"use_tfdt", "use tfdt for fragment timestamps", OFFSET(use_tfdt), AV_OPT_TYPE_BOOL, {.i64 = 1},
11919  0, 1, FLAGS},
11920  { "export_all", "Export unrecognized metadata entries", OFFSET(export_all),
11921  AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = FLAGS },
11922  { "export_xmp", "Export full XMP metadata", OFFSET(export_xmp),
11923  AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = FLAGS },
11924  { "activation_bytes", "Secret bytes for Audible AAX files", OFFSET(activation_bytes),
11926  { "audible_key", "AES-128 Key for Audible AAXC files", OFFSET(audible_key),
11928  { "audible_iv", "AES-128 IV for Audible AAXC files", OFFSET(audible_iv),
11930  { "audible_fixed_key", // extracted from libAAX_SDK.so and AAXSDKWin.dll files!
11931  "Fixed key used for handling Audible AAX files", OFFSET(audible_fixed_key),
11932  AV_OPT_TYPE_BINARY, {.str="77214d4b196a87cd520045fd20a51d67"},
11933  .flags = AV_OPT_FLAG_DECODING_PARAM },
11934  { "decryption_key", "The default media decryption key (hex)", OFFSET(decryption_default_key), AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM },
11935  { "decryption_keys", "The media decryption keys by KID (hex)", OFFSET(decryption_keys), AV_OPT_TYPE_DICT, .flags = AV_OPT_FLAG_DECODING_PARAM },
11936  { "enable_drefs", "Enable external track support.", OFFSET(enable_drefs), AV_OPT_TYPE_BOOL,
11937  {.i64 = 0}, 0, 1, FLAGS },
11938  { "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 },
11939  { "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 },
11940 
11941  { NULL },
11942 };
11943 
11944 static const AVClass mov_class = {
11945  .class_name = "mov,mp4,m4a,3gp,3g2,mj2",
11946  .item_name = av_default_item_name,
11947  .option = mov_options,
11948  .version = LIBAVUTIL_VERSION_INT,
11949 };
11950 
11952  .p.name = "mov,mp4,m4a,3gp,3g2,mj2",
11953  .p.long_name = NULL_IF_CONFIG_SMALL("QuickTime / MOV"),
11954  .p.priv_class = &mov_class,
11955  .p.extensions = "mov,mp4,m4a,3gp,3g2,mj2,psp,m4v,m4b,ism,ismv,isma,f4v,avif,heic,heif",
11957  .priv_data_size = sizeof(MOVContext),
11958  .flags_internal = FF_INFMT_FLAG_INIT_CLEANUP,
11959  .read_probe = mov_probe,
11964 };
HEIFItemRef::item_id
int item_id
Definition: isom.h:296
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:197
item_name
item_name
Definition: libkvazaar.c:311
AV_CODEC_ID_PCM_S16LE
@ AV_CODEC_ID_PCM_S16LE
Definition: codec_id.h:339
flags
const SwsFlags flags[]
Definition: swscale.c:72
AV_EXIF_T_OFF
@ AV_EXIF_T_OFF
The first four bytes point to the actual start, then it's AV_EXIF_TIFF_HEADER.
Definition: exif.h:69
mov_finalize_stsd_entry
static int mov_finalize_stsd_entry(MOVContext *c, AVStream *st)
Definition: mov.c:3143
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:7517
mov_read_meta
static int mov_read_meta(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5609
AV_CODEC_ID_EIA_608
@ AV_CODEC_ID_EIA_608
Definition: codec_id.h:583
AV_PKT_DATA_DISPLAYMATRIX
@ AV_PKT_DATA_DISPLAYMATRIX
This side data contains a 3x3 transformation matrix describing an affine transformation that needs to...
Definition: packet.h:105
av_packet_unref
void av_packet_unref(AVPacket *pkt)
Wipe the packet.
Definition: packet.c:433
MOVContext::found_iloc
int found_iloc
'iloc' atom has been found
Definition: isom.h:332
AV_CODEC_ID_MACE6
@ AV_CODEC_ID_MACE6
Definition: codec_id.h:471
MOVFragmentStreamInfo::first_tfra_pts
int64_t first_tfra_pts
Definition: isom.h:148
ff_rfps_add_frame
int ff_rfps_add_frame(AVFormatContext *ic, AVStream *st, int64_t ts)
add frame for rfps calculation.
Definition: demux.c:2336
read_image_iovl
static int read_image_iovl(AVFormatContext *s, const HEIFGrid *grid, AVStreamGroupTileGrid *tile_grid)
Definition: mov.c:10529
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:9455
AVMEDIA_TYPE_SUBTITLE
@ AVMEDIA_TYPE_SUBTITLE
Definition: avutil.h:203
AVIAMFSubmix::elements
AVIAMFSubmixElement ** elements
Array of submix elements.
Definition: iamf.h:568
skip_bits_long
static void skip_bits_long(GetBitContext *s, int n)
Skips the specified number of bits.
Definition: get_bits.h:280
AV_LOG_WARNING
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:216
AV_BPRINT_SIZE_UNLIMITED
#define AV_BPRINT_SIZE_UNLIMITED
MOV_TFHD_DEFAULT_FLAGS
#define MOV_TFHD_DEFAULT_FLAGS
Definition: isom.h:412
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:359
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:227
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:384
AVCodecParameters::extradata
uint8_t * extradata
Extra binary data needed for initializing the decoder, codec-dependent.
Definition: codec_par.h:71
mov_read_dops
static int mov_read_dops(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:8645
can_seek_to_key_sample
static int can_seek_to_key_sample(AVStream *st, int sample, int64_t requested_pts)
Definition: mov.c:11713
name
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 minimum maximum flags name is the option name
Definition: writing_filters.txt:88
AV_CODEC_ID_ADPCM_IMA_QT
@ AV_CODEC_ID_ADPCM_IMA_QT
Definition: codec_id.h:378
entry
#define entry
Definition: aom_film_grain_template.c:66
AVFMT_NO_BYTE_SEEK
#define AVFMT_NO_BYTE_SEEK
Format does not allow seeking by bytes.
Definition: avformat.h:487
AV_EF_EXPLODE
#define AV_EF_EXPLODE
abort decoding on minor error detection
Definition: defs.h:51
AVStreamGroup::id
int64_t id
Group type-specific group ID.
Definition: avformat.h:1136
AV_CODEC_ID_AC3
@ AV_CODEC_ID_AC3
Definition: codec_id.h:464
HEIFItem::name
char * name
Definition: isom.h:303
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:248
MOVStreamContext::height
int height
tkhd height
Definition: isom.h:234
MOVContext::moov_retry
int moov_retry
Definition: isom.h:360
MOV_TRUN_SAMPLE_FLAGS
#define MOV_TRUN_SAMPLE_FLAGS
Definition: isom.h:420
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:348
mix
static int mix(int c0, int c1)
Definition: 4xm.c:717
MOVStreamContext::last_stsd_index
int last_stsd_index
Definition: isom.h:263
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:433
AVCodecParameters::codec_type
enum AVMediaType codec_type
General type of the encoded data.
Definition: codec_par.h:53
AVStreamGroup::tile_grid
struct AVStreamGroupTileGrid * tile_grid
Definition: avformat.h:1152
AVFMT_SHOW_IDS
#define AVFMT_SHOW_IDS
Show format stream IDs numbers.
Definition: avformat.h:477
AVSphericalMapping::projection
enum AVSphericalProjection projection
Projection type.
Definition: spherical.h:104
AV_WL32
#define AV_WL32(p, v)
Definition: intreadwrite.h:422
av_exif_parse_buffer
int av_exif_parse_buffer(void *logctx, const uint8_t *buf, size_t size, AVExifMetadata *ifd, enum AVExifHeaderMode header_mode)
Decodes the EXIF data provided in the buffer and writes it into the struct *ifd.
Definition: exif.c:882
AV_STREAM_GROUP_PARAMS_LCEVC
@ AV_STREAM_GROUP_PARAMS_LCEVC
Definition: avformat.h:1110
MOVStreamContext::extradata
uint8_t ** extradata
extradata array (and size) for multiple stsd
Definition: isom.h:261
mov_class
static const AVClass mov_class
Definition: mov.c:11944
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:253
AVUUID
uint8_t AVUUID[AV_UUID_LEN]
Definition: uuid.h:60
MovTref
Definition: isom.h:94
mov_parse_tmcd_streams
static int mov_parse_tmcd_streams(AVFormatContext *s)
Definition: mov.c:10887
out
static FILE * out
Definition: movenc.c:55
MOVFragmentStreamInfo
Definition: isom.h:145
AVFieldOrder
AVFieldOrder
Definition: defs.h:211
mov_read_targa_y216
static int mov_read_targa_y216(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2315
mov_read_chnl
static int mov_read_chnl(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1226
mov_read_moof
static int mov_read_moof(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1852
av_bprint_init
void av_bprint_init(AVBPrint *buf, unsigned size_init, unsigned size_max)
Definition: bprint.c:69
ctype
#define ctype
Definition: afir_template.c:46
AV_PKT_DATA_FRAME_CROPPING
@ AV_PKT_DATA_FRAME_CROPPING
The number of pixels to discard from the top/bottom/left/right border of the decoded frame to obtain ...
Definition: packet.h:340
av_exif_write
int av_exif_write(void *logctx, const AVExifMetadata *ifd, AVBufferRef **buffer, enum AVExifHeaderMode header_mode)
Allocates a buffer using av_malloc of an appropriate size and writes the EXIF data represented by ifd...
Definition: exif.c:753
AVCodecParameters
This struct describes the properties of an encoded stream.
Definition: codec_par.h:49
HEIFItem::icc_profile
uint8_t * icc_profile
Definition: isom.h:314
AVFMT_FLAG_IGNIDX
#define AVFMT_FLAG_IGNIDX
Ignore index.
Definition: avformat.h:1437
AVExifMetadata
Definition: exif.h:76
sanity_checks
static int sanity_checks(void *log_obj, MOVStreamContext *sc, int index)
Definition: mov.c:5238
av_stristr
char * av_stristr(const char *s1, const char *s2)
Locate the first case-independent occurrence in the string haystack of the string needle.
Definition: avstring.c:58
AVCodecParameters::color_space
enum AVColorSpace color_space
Definition: codec_par.h:192
avformat_new_stream
AVStream * avformat_new_stream(AVFormatContext *s, const struct AVCodec *c)
Add a new stream to a media file.
ff_replaygain_export
int ff_replaygain_export(AVStream *st, AVDictionary *metadata)
Parse replaygain tags and export them as per-stream side data.
Definition: replaygain.c:94
tmcd_is_referenced
static int tmcd_is_referenced(AVFormatContext *s, int tmcd_id)
Definition: mov.c:10270
HEIFItem::hflip
int hflip
Definition: isom.h:310
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:772
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:673
AVStream::discard
enum AVDiscard discard
Selects which packets can be discarded at will and do not need to be demuxed.
Definition: avformat.h:818
AV_FIELD_PROGRESSIVE
@ AV_FIELD_PROGRESSIVE
Definition: defs.h:213
mov_options
static const AVOption mov_options[]
Definition: mov.c:11890
mov_codec_id
static int mov_codec_id(AVStream *st, uint32_t format)
Definition: mov.c:2726
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:251
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:9042
matrix
Definition: vc1dsp.c:43
AVMasteringDisplayMetadata::display_primaries
AVRational display_primaries[3][2]
CIE 1931 xy chromaticity coords of color primaries (r, g, b order).
Definition: mastering_display_metadata.h:42
AV_PKT_FLAG_DISCARD
#define AV_PKT_FLAG_DISCARD
Flag is used to discard packets which are required to maintain valid decoder state but are not requir...
Definition: packet.h:657
AVMasteringDisplayMetadata::has_luminance
int has_luminance
Flag indicating whether the luminance (min_ and max_) have been set.
Definition: mastering_display_metadata.h:67
get_bits_long
static unsigned int get_bits_long(GetBitContext *s, int n)
Read 0-32 bits.
Definition: get_bits.h:424
int64_t
long long int64_t
Definition: coverity.c:34
output
filter_frame For filters that do not use the this method is called when a frame is pushed to the filter s input It can be called at any time except in a reentrant way If the input frame is enough to produce output
Definition: filter_design.txt:226
mov_read_alac
static int mov_read_alac(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2287
test_same_origin
static int test_same_origin(const char *src, const char *ref)
Definition: mov.c:5081
cbcs_scheme_decrypt
static int cbcs_scheme_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
Definition: mov.c:8462
MOVFragment::base_data_offset
uint64_t base_data_offset
Definition: isom.h:110
MOVStreamContext
Definition: isom.h:179
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:200
ff_buffer_packet
int ff_buffer_packet(AVFormatContext *s, AVPacket *pkt)
Definition: demux.c:622
IS_MATRIX_IDENT
#define IS_MATRIX_IDENT(matrix)
Definition: mov.c:5627
AVStreamGroup::disposition
int disposition
Stream group disposition - a combination of AV_DISPOSITION_* flags.
Definition: avformat.h:1195
av_unused
#define av_unused
Definition: attributes.h:164
AV_DISPOSITION_DEFAULT
#define AV_DISPOSITION_DEFAULT
The stream should be chosen by default among other streams of the same type, unless the user has expl...
Definition: avformat.h:620
mov_update_dts_shift
static void mov_update_dts_shift(MOVStreamContext *sc, int duration, void *logctx)
Definition: mov.c:3779
MOVStreamContext::spherical
AVSphericalMapping * spherical
Definition: isom.h:270
mask
int mask
Definition: mediacodecdec_common.c:154
out_size
static int out_size
Definition: movenc.c:56
MOVStreamContext::cenc
struct MOVStreamContext::@479 cenc
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:132
av_encryption_init_info_free
void av_encryption_init_info_free(AVEncryptionInitInfo *info)
Frees the given encryption init info object.
Definition: encryption_info.c:216
mov_read_avss
static int mov_read_avss(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2292
AV_RB32A
#define AV_RB32A(p)
Definition: intreadwrite.h:575
MOVContext::primary_item_id
int primary_item_id
Definition: isom.h:385
mode
Definition: swscale.c:60
MOVContext::found_moov
int found_moov
'moov' atom has been found
Definition: isom.h:331
ff_iamf_read_packet
int ff_iamf_read_packet(AVFormatContext *s, IAMFDemuxContext *c, AVIOContext *pb, int max_size, int stream_id_offset, AVPacket *pkt)
Definition: iamf_reader.c:308
mov_read_custom
static int mov_read_custom(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5463
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:1352
HEIFGrid::nb_tiles
int nb_tiles
Definition: isom.h:323
ID3v1_GENRE_MAX
#define ID3v1_GENRE_MAX
Definition: id3v1.h:29
MOVSbgp
Definition: isom.h:127
MOVCtts
Definition: isom.h:68
AVPacketSideData
This structure stores auxiliary information for decoding, presenting, or otherwise processing the cod...
Definition: packet.h:416
mov_read_extradata
static int mov_read_extradata(MOVContext *c, AVIOContext *pb, MOVAtom atom, enum AVCodecID codec_id)
Definition: mov.c:2261
AVCOL_RANGE_JPEG
@ AVCOL_RANGE_JPEG
Full range content.
Definition: pixfmt.h:777
mpegaudiodecheader.h
MOVStreamContext::rap_group_count
unsigned int rap_group_count
Definition: isom.h:245
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:312
mov_read_mvhd
static int mov_read_mvhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1954
mov_read_idat
static int mov_read_idat(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:9036
AVPacket::data
uint8_t * data
Definition: packet.h:595
MOVContext::found_mdat
int found_mdat
'mdat' atom has been found
Definition: isom.h:334
MOVStreamContext::drefs_count
unsigned drefs_count
Definition: isom.h:228
AVEncryptionInfo::crypt_byte_block
uint32_t crypt_byte_block
Only used for pattern encryption.
Definition: encryption_info.h:51
AV_PKT_DATA_ENCRYPTION_INIT_INFO
@ AV_PKT_DATA_ENCRYPTION_INIT_INFO
This side data is encryption initialization data.
Definition: packet.h:246
mov_read_avid
static int mov_read_avid(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2307
AVAmbientViewingEnvironment::ambient_light_x
AVRational ambient_light_x
Normalized x chromaticity coordinate of the environmental ambient light in the nominal viewing enviro...
Definition: ambient_viewing_environment.h:47
AVCodecParameters::seek_preroll
int seek_preroll
Number of audio samples to skip after a discontinuity.
Definition: codec_par.h:256
av_dynarray2_add
void * av_dynarray2_add(void **tab_ptr, int *nb_ptr, size_t elem_size, const uint8_t *elem_data)
Add an element of size elem_size to a dynamic array.
Definition: mem.c:343
AVOption
AVOption.
Definition: opt.h:429
MOVContext::trex_data
MOVTrackExt * trex_data
Definition: isom.h:343
mov_read_stps
static int mov_read_stps(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:3432
MOVContext::bitrates
int * bitrates
bitrates read before streams creation
Definition: isom.h:358
b
#define b
Definition: input.c:43
AVCOL_TRC_UNSPECIFIED
@ AVCOL_TRC_UNSPECIFIED
Definition: pixfmt.h:669
MOVContext::interleaved_read
int interleaved_read
Definition: isom.h:392
mov_read_tkhd
static int mov_read_tkhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5635
MOVElst::rate
float rate
Definition: isom.h:82
AVStream::avg_frame_rate
AVRational avg_frame_rate
Average framerate.
Definition: avformat.h:836
table
static const uint16_t table[]
Definition: prosumer.c:203
spherical.h
mov_read_colr
static int mov_read_colr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2108
data
const char data[16]
Definition: mxf.c:149
set_last_stream_little_endian
static void set_last_stream_little_endian(AVFormatContext *fc)
Definition: mov.c:1993
mov_read_strf
static int mov_read_strf(MOVContext *c, AVIOContext *pb, MOVAtom atom)
An strf atom is a BITMAPINFOHEADER struct.
Definition: mov.c:2639
AV_CODEC_ID_ALAC
@ AV_CODEC_ID_ALAC
Definition: codec_id.h:477
HEIFItem::st
AVStream * st
Definition: isom.h:300
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:442
av_iamf_mix_presentation_free
void av_iamf_mix_presentation_free(AVIAMFMixPresentation **pmix_presentation)
Free an AVIAMFMixPresentation and all its contents.
Definition: iamf.c:536
AVStreamGroupTREF::metadata_index
unsigned int metadata_index
Index of the metadata stream in the AVStreamGroup.
Definition: avformat.h:1102
mov_parse_auxiliary_info
static int mov_parse_auxiliary_info(MOVContext *c, MOVStreamContext *sc, AVIOContext *pb, MOVEncryptionIndex *encryption_index)
Definition: mov.c:7725
mov_seek_stream
static int mov_seek_stream(AVFormatContext *s, AVStream *st, int64_t timestamp, int flags)
Definition: mov.c:11740
mov_read_saio
static int mov_read_saio(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:7871
mov_get_stsc_samples
static int64_t mov_get_stsc_samples(MOVStreamContext *sc, unsigned int index)
Definition: mov.c:3417
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:3988
MOVFragmentIndexItem::moof_offset
int64_t moof_offset
Definition: isom.h:159
MOVStreamContext::spherical_size
size_t spherical_size
Definition: isom.h:271
mov_change_extradata
static int mov_change_extradata(AVStream *st, AVPacket *pkt)
Definition: mov.c:11348
nb_streams
static unsigned int nb_streams
Definition: ffprobe.c:352
HEIFItemRef
Definition: isom.h:294
MP4TrackKindMapping::scheme_uri
const char * scheme_uri
Definition: isom.h:493
AVINDEX_DISCARD_FRAME
#define AVINDEX_DISCARD_FRAME
Definition: avformat.h:610
av_display_rotation_set
void av_display_rotation_set(int32_t matrix[9], double angle)
Initialize a transformation matrix describing a pure clockwise rotation by the specified angle (in de...
Definition: display.c:51
AVPacket::duration
int64_t duration
Duration of this packet in AVStream->time_base units, 0 if unknown.
Definition: packet.h:613
AVStreamGroup::tref
struct AVStreamGroupTREF * tref
Definition: avformat.h:1154
AVCodecParameters::codec_tag
uint32_t codec_tag
Additional information about the codec (corresponds to the AVI FOURCC).
Definition: codec_par.h:61
fixed_key
static const uint8_t fixed_key[]
Definition: aes_ctr.c:45
AV_SPHERICAL_EQUIRECTANGULAR_TILE
@ AV_SPHERICAL_EQUIRECTANGULAR_TILE
Video represents a portion of a sphere mapped on a flat surface using equirectangular projection.
Definition: spherical.h:68
AVStereo3D::baseline
uint32_t baseline
The distance between the centres of the lenses of the camera system, in micrometers.
Definition: stereo3d.h:228
MOVDref::dir
char * dir
Definition: isom.h:88
mov_current_sample_set
static void mov_current_sample_set(MOVStreamContext *sc, int current_sample)
Definition: mov.c:4292
mathematics.h
AVChannelLayout::u
union AVChannelLayout::@516 u
Details about which channels are present in this layout.
AVDictionary
Definition: dict.c:32
ffio_init_read_context
void ffio_init_read_context(FFIOContext *s, const uint8_t *buffer, int buffer_size)
Wrap a buffer in an AVIOContext for reading.
Definition: aviobuf.c:99
AV_PKT_FLAG_DISPOSABLE
#define AV_PKT_FLAG_DISPOSABLE
Flag is used to indicate packets that contain frames that can be discarded by the decoder.
Definition: packet.h:669
AVChannelLayout::order
enum AVChannelOrder order
Channel order used in this layout.
Definition: channel_layout.h:324
FFMAX
#define FFMAX(a, b)
Definition: macros.h:47
MOVAtom
Definition: isom.h:100
AVStreamGroupTileGrid::vertical
int vertical
Offset in pixels from the top edge of the canvas where the tile should be placed.
Definition: avformat.h:1003
iamf_parse.h
mov_read_moov
static int mov_read_moov(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1602
av_sub_q
AVRational av_sub_q(AVRational b, AVRational c)
Subtract one rational from another.
Definition: rational.c:101
cffstream
static const av_always_inline FFStream * cffstream(const AVStream *st)
Definition: internal.h:367
mov_read_esds
static int mov_read_esds(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:848
MOVStreamContext::sample_count
unsigned int sample_count
Definition: isom.h:211
MOVFragmentIndex::allocated_size
int allocated_size
Definition: isom.h:167
MOVTrackExt::flags
unsigned flags
Definition: isom.h:124
AVChannelLayout::nb_channels
int nb_channels
Number of channels in this layout.
Definition: channel_layout.h:329
HEIFItem::height
int height
Definition: isom.h:308
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:198
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:352
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:2661
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:7236
FFIOContext
Definition: avio_internal.h:28
AV_PKT_FLAG_KEY
#define AV_PKT_FLAG_KEY
The packet contains a keyframe.
Definition: packet.h:650
init_get_bits
static int init_get_bits(GetBitContext *s, const uint8_t *buffer, int bit_size)
Initialize GetBitContext.
Definition: get_bits.h:517
MOVStreamContext::aes_ctr
struct AVAESCTR * aes_ctr
Definition: isom.h:283
cenc_filter
static int cenc_filter(MOVContext *mov, AVStream *st, MOVStreamContext *sc, AVPacket *pkt, int current_index)
Definition: mov.c:8575
mov_read_sdtp
static int mov_read_sdtp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:3741
mov_read_jp2h
static int mov_read_jp2h(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2297
AV_STEREO3D_UNSPEC
@ AV_STEREO3D_UNSPEC
Video is stereoscopic but the packing is unspecified.
Definition: stereo3d.h:143
AVIndexEntry
Definition: avformat.h:601
AV_WB64
#define AV_WB64(p, v)
Definition: intreadwrite.h:429
MOVStreamContext::dv_audio_container
int dv_audio_container
Definition: isom.h:225
AV_CODEC_ID_AMR_WB
@ AV_CODEC_ID_AMR_WB
Definition: codec_id.h:443
mov_read_tfhd
static int mov_read_tfhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5740
AV_CODEC_ID_BIN_DATA
@ AV_CODEC_ID_BIN_DATA
Definition: codec_id.h:614
OPUS_SEEK_PREROLL_MS
#define OPUS_SEEK_PREROLL_MS
Definition: oggparseopus.c:36
AV_CODEC_ID_H261
@ AV_CODEC_ID_H261
Definition: codec_id.h:55
IAMFMixPresentation::cmix
const AVIAMFMixPresentation * cmix
Definition: iamf.h:108
MOVContext::decryption_default_key
uint8_t * decryption_default_key
Definition: isom.h:378
mov_read_wide
static int mov_read_wide(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6320
AVINDEX_KEYFRAME
#define AVINDEX_KEYFRAME
Definition: avformat.h:609
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:264
ff_mov_lang_to_iso639
int ff_mov_lang_to_iso639(unsigned code, char to[4])
Definition: isom.c:260
ff_generate_avci_extradata
int ff_generate_avci_extradata(AVStream *st)
Generate standard extradata for AVC-Intra based on width/height and field order.
Definition: demux_utils.c:205
ff_get_extradata
int ff_get_extradata(void *logctx, AVCodecParameters *par, AVIOContext *pb, int size)
Allocate extradata with additional AV_INPUT_BUFFER_PADDING_SIZE at end which is always set to 0 and f...
Definition: demux_utils.c:340
mov_add_tref_id
static int mov_add_tref_id(MovTref *tag, uint32_t id)
Definition: mov.c:2559
AVStereo3D::horizontal_field_of_view
AVRational horizontal_field_of_view
Horizontal field of view, in degrees.
Definition: stereo3d.h:239
skip_bits
static void skip_bits(GetBitContext *s, int n)
Definition: get_bits.h:383
AVCodecParameters::color_primaries
enum AVColorPrimaries color_primaries
Definition: codec_par.h:190
AVEncryptionInfo::scheme
uint32_t scheme
The fourcc encryption scheme, in big-endian byte order.
Definition: encryption_info.h:45
MOVStreamContext::stsc_count
unsigned int stsc_count
Definition: isom.h:199
MOVStreamContext::has_palette
int has_palette
Definition: isom.h:239
AVPROBE_SCORE_MAX
#define AVPROBE_SCORE_MAX
maximum score
Definition: avformat.h:464
AV_STEREO3D_SIDEBYSIDE
@ AV_STEREO3D_SIDEBYSIDE
Views are next to each other.
Definition: stereo3d.h:64
MOVIndexRange::start
int64_t start
Definition: isom.h:175
AVPacketSideData::size
size_t size
Definition: packet.h:418
get_bits
static unsigned int get_bits(GetBitContext *s, int n)
Read 1-25 bits.
Definition: get_bits.h:337
ff_remove_stream
void ff_remove_stream(AVFormatContext *s, AVStream *st)
Remove a stream from its AVFormatContext and free it.
Definition: avformat.c:120
OFFSET
#define OFFSET(x)
Definition: mov.c:11888
HEIFGrid::tile_item_list
HEIFItem ** tile_item_list
Definition: isom.h:320
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:10407
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:257
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:900
FF_DVDCLUT_CLUT_LEN
#define FF_DVDCLUT_CLUT_LEN
Definition: dvdclut.h:28
AVEncryptionInfo::skip_byte_block
uint32_t skip_byte_block
Only used for pattern encryption.
Definition: encryption_info.h:57
finish
static void finish(void)
Definition: movenc.c:374
aax_filter
static int aax_filter(uint8_t *input, int size, MOVContext *c)
Definition: mov.c:1540
AV_OPT_TYPE_BINARY
@ AV_OPT_TYPE_BINARY
Underlying C type is a uint8_t* that is either NULL or points to an array allocated with the av_mallo...
Definition: opt.h:286
av_color_space_name
const char * av_color_space_name(enum AVColorSpace space)
Definition: pixdesc.c:3856
av_packet_add_side_data
int av_packet_add_side_data(AVPacket *pkt, enum AVPacketSideDataType type, uint8_t *data, size_t size)
Wrap an existing array as a packet side data.
Definition: packet.c:197
MOVStreamContext::mastering
AVMasteringDisplayMetadata * mastering
Definition: isom.h:272
AV_CODEC_ID_SPEEX
@ AV_CODEC_ID_SPEEX
Definition: codec_id.h:496
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
mov_find_tref_id
static int mov_find_tref_id(const MovTref *tag, uint32_t id)
Definition: mov.c:2550
ffstream
static av_always_inline FFStream * ffstream(AVStream *st)
Definition: internal.h:362
MOVFragmentIndexItem::current
int current
Definition: isom.h:161
mov_add_tref_tag
static MovTref * mov_add_tref_tag(MOVStreamContext *sc, uint32_t name)
Definition: mov.c:2585
AVFMT_SEEK_TO_PTS
#define AVFMT_SEEK_TO_PTS
Seeking is based on PTS.
Definition: avformat.h:501
AV_CODEC_ID_PCM_S16BE
@ AV_CODEC_ID_PCM_S16BE
Definition: codec_id.h:340
mov_read_mdhd
static int mov_read_mdhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1908
mov_read_ctts
static int mov_read_ctts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:3790
MOVTrackExt
Definition: isom.h:119
MOV_FRAG_SAMPLE_FLAG_IS_NON_SYNC
#define MOV_FRAG_SAMPLE_FLAG_IS_NON_SYNC
Definition: isom.h:424
fail
#define fail()
Definition: checkasm.h:225
mov_read_aclr
static int mov_read_aclr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2374
AVSEEK_FLAG_ANY
#define AVSEEK_FLAG_ANY
seek to any frame, even non-keyframes
Definition: avformat.h:2545
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:108
AVStreamGroupTileGrid
AVStreamGroupTileGrid holds information on how to combine several independent images on a single canv...
Definition: avformat.h:954
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:304
av_shrink_packet
void av_shrink_packet(AVPacket *pkt, int size)
Reduce packet size, correctly zeroing padding.
Definition: packet.c:113
timecode.h
get_current_frag_stream_info
static MOVFragmentStreamInfo * get_current_frag_stream_info(MOVFragmentIndex *frag_index)
Definition: mov.c:1659
GetBitContext
Definition: get_bits.h:109
MOVStreamContext::mastering_size
size_t mastering_size
Definition: isom.h:273
AVStreamGroupTileGrid::coded_width
int coded_width
Width of the canvas.
Definition: avformat.h:969
av_iamf_audio_element_free
void av_iamf_audio_element_free(AVIAMFAudioElement **paudio_element)
Free an AVIAMFAudioElement and all its contents.
Definition: iamf.c:338
FFStream::index_entries_allocated_size
unsigned int index_entries_allocated_size
Definition: internal.h:187
read_close
static av_cold int read_close(AVFormatContext *ctx)
Definition: libcdio.c:143
mov_read_amve
static int mov_read_amve(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6696
mov_read_enda
static int mov_read_enda(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2022
mov_read_chap
static int mov_read_chap(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5787
MOVParseTableEntry
Definition: mov.c:82
avio_tell
static av_always_inline int64_t avio_tell(AVIOContext *s)
ftell() equivalent for AVIOContext.
Definition: avio.h:494
av_exif_free
void av_exif_free(AVExifMetadata *ifd)
Frees all resources associated with the given EXIF metadata struct.
Definition: exif.c:659
MOV_TRUN_SAMPLE_DURATION
#define MOV_TRUN_SAMPLE_DURATION
Definition: isom.h:418
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:10421
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:326
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:678
AVStreamGroupTileGrid::coded_height
int coded_height
Width of the canvas.
Definition: avformat.h:975
pts
static int64_t pts
Definition: transcode_aac.c:644
MOVStreamContext::v_spacing
int v_spacing
pasp vSpacing
Definition: isom.h:236
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:462
AVStream::duration
int64_t duration
Decoding: duration of the stream, in stream time base.
Definition: avformat.h:806
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:233
MOVContext::meta_keys
char ** meta_keys
Definition: isom.h:337
get_key_from_kid
static int get_key_from_kid(uint8_t *out, int len, MOVContext *c, AVEncryptionInfo *sample)
Definition: mov.c:8229
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:262
AVIAMFAudioElement::audio_element_type
enum AVIAMFAudioElementType audio_element_type
Audio element type as defined in section 3.6 of IAMF.
Definition: iamf.h:391
loop
static int loop
Definition: ffplay.c:337
ff_data_to_hex
char * ff_data_to_hex(char *buf, const uint8_t *src, int size, int lowercase)
Write hexadecimal string corresponding to given binary data.
Definition: utils.c:458
update_frag_index
static int update_frag_index(MOVContext *c, int64_t offset)
Definition: mov.c:1776
AV_CODEC_ID_PRORES_RAW
@ AV_CODEC_ID_PRORES_RAW
Definition: codec_id.h:333
AVRational::num
int num
Numerator.
Definition: rational.h:59
MOVStreamContext::keyframes
int * keyframes
Definition: isom.h:215
MOVEncryptionIndex::auxiliary_info_sample_count
size_t auxiliary_info_sample_count
Definition: isom.h:139
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:6768
AVStream::attached_pic
AVPacket attached_pic
For streams with AV_DISPOSITION_ATTACHED_PIC disposition, this packet will contain the attached pictu...
Definition: avformat.h:845
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:7787
MOV_FRAG_SAMPLE_FLAG_DEPENDS_YES
#define MOV_FRAG_SAMPLE_FLAG_DEPENDS_YES
Definition: isom.h:431
mov_merge_tts_data
static int mov_merge_tts_data(MOVContext *mov, AVStream *st, int flags)
Definition: mov.c:4708
MOVContext::idat_offset
int64_t idat_offset
Definition: isom.h:391
MOV_TRUN_DATA_OFFSET
#define MOV_TRUN_DATA_OFFSET
Definition: isom.h:416
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:205
mov_read_ares
static int mov_read_ares(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2329
mov_read_adrm
static int mov_read_adrm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1414
av_get_bits_per_sample
int av_get_bits_per_sample(enum AVCodecID codec_id)
Return codec bits per sample.
Definition: utils.c:549
AVCodecParameters::color_trc
enum AVColorTransferCharacteristic color_trc
Definition: codec_par.h:191
IAMFContext::audio_elements
IAMFAudioElement ** audio_elements
Definition: iamf.h:131
MOVFragmentIndex::complete
int complete
Definition: isom.h:168
AV_CODEC_ID_PCM_S8
@ AV_CODEC_ID_PCM_S8
Definition: codec_id.h:343
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:202
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:470
AVStreamGroup::params
union AVStreamGroup::@448 params
Group type-specific parameters.
MOVTrackExt::track_id
unsigned track_id
Definition: isom.h:120
mov_free_encryption_index
static void mov_free_encryption_index(MOVEncryptionIndex **index)
Definition: mov.c:10138
AV_CH_LOW_FREQUENCY
#define AV_CH_LOW_FREQUENCY
Definition: channel_layout.h:178
MOVEncryptionIndex::auxiliary_offsets
uint64_t * auxiliary_offsets
Absolute seek position.
Definition: isom.h:141
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:237
av_timecode_init
int av_timecode_init(AVTimecode *tc, AVRational rate, int flags, int frame_start, void *log_ctx)
Init a timecode struct with the passed parameters.
Definition: timecode.c:201
AVCodecParameters::frame_size
int frame_size
Audio frame size, if known.
Definition: codec_par.h:227
mov_read_srat
static int mov_read_srat(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1077
avio_get_str16le
int avio_get_str16le(AVIOContext *pb, int maxlen, char *buf, int buflen)
Read a UTF-16 string from pb and convert it to UTF-8.
mov_metadata_track_or_disc_number
static int mov_metadata_track_or_disc_number(MOVContext *c, AVIOContext *pb, unsigned len, const char *key)
Definition: mov.c:91
av_dict_get
AVDictionaryEntry * av_dict_get(const AVDictionary *m, const char *key, const AVDictionaryEntry *prev, int flags)
Get a dictionary entry with matching key.
Definition: dict.c:60
AES_CTR_KEY_SIZE
#define AES_CTR_KEY_SIZE
Definition: aes_ctr.h:35
MOVStreamContext::stsd_version
int stsd_version
Definition: isom.h:265
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:10598
AV_STREAM_GROUP_PARAMS_IAMF_MIX_PRESENTATION
@ AV_STREAM_GROUP_PARAMS_IAMF_MIX_PRESENTATION
Definition: avformat.h:1108
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:4183
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:466
MOV_MERGE_STTS
#define MOV_MERGE_STTS
Definition: mov.c:4702
MOVStreamContext::iamf_stream_offset
int iamf_stream_offset
Definition: isom.h:291
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:6630
s
#define s(width, name)
Definition: cbs_vp9.c:198
MOVFragmentStreamInfo::encryption_index
MOVEncryptionIndex * encryption_index
Definition: isom.h:154
mov_read_trak
static int mov_read_trak(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5257
IAMFSubStream::audio_substream_id
unsigned int audio_substream_id
Definition: iamf.h:83
MOVContext::fc
AVFormatContext * fc
Definition: isom.h:328
MOV_TFHD_DEFAULT_BASE_IS_MOOF
#define MOV_TFHD_DEFAULT_BASE_IS_MOOF
Definition: isom.h:414
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:410
ALAC_EXTRADATA_SIZE
#define ALAC_EXTRADATA_SIZE
DRM_BLOB_SIZE
#define DRM_BLOB_SIZE
Definition: mov.c:1412
MOVStreamContext::sample_offsets_count
int sample_offsets_count
Definition: isom.h:252
MOVCtts::count
unsigned int count
Definition: isom.h:69
MOVStreamContext::drefs
MOVDref * drefs
Definition: isom.h:229
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:551
MOVContext::aes_decrypt
struct AVAES * aes_decrypt
Definition: isom.h:377
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:170
AVCodecParameters::width
int width
The width of the video frame in pixels.
Definition: codec_par.h:143
MOVTimeToSample
Definition: isom.h:57
AV_CHANNEL_ORDER_UNSPEC
@ AV_CHANNEL_ORDER_UNSPEC
Only the channel count is specified, without any further information about the channel order.
Definition: channel_layout.h:119
AV_CODEC_ID_MP2
@ AV_CODEC_ID_MP2
Definition: codec_id.h:461
HEIFGrid::tile_idx_list
unsigned * tile_idx_list
Definition: isom.h:322
MOV_TRUN_FIRST_SAMPLE_FLAGS
#define MOV_TRUN_FIRST_SAMPLE_FLAGS
Definition: isom.h:417
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:612
av_channel_layout_from_mask
int av_channel_layout_from_mask(AVChannelLayout *channel_layout, uint64_t mask)
Initialize a native channel layout from a bitmask indicating which channels are present.
Definition: channel_layout.c:253
MOVStreamContext::keyframe_absent
int keyframe_absent
Definition: isom.h:213
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:275
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:4212
AVIndexEntry::timestamp
int64_t timestamp
Timestamp in AVStream.time_base units, preferably the time from which on correctly decoded frames are...
Definition: avformat.h:603
av_assert0
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:42
MOVStreamContext::min_corrected_pts
int64_t min_corrected_pts
minimum Composition time shown by the edits excluding empty edits.
Definition: isom.h:218
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:194
dvdclut.h
MOVStreamContext::nb_tref_tags
int nb_tref_tags
Definition: isom.h:231
mov_read_lhvc
static int mov_read_lhvc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:8753
AV_LOG_DEBUG
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:231
AVPacketSideData::data
uint8_t * data
Definition: packet.h:417
ctx
static AVFormatContext * ctx
Definition: movenc.c:49
hevc.h
get_bits.h
limits.h
mov_read_sidx
static int mov_read_sidx(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6181
AV_PKT_DATA_STEREO3D
@ AV_PKT_DATA_STEREO3D
This side data should be associated with a video stream and contains Stereoscopic 3D information in f...
Definition: packet.h:111
av_rescale_q
int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq)
Rescale a 64-bit integer by 2 rational numbers.
Definition: mathematics.c:142
ff_iamfdec_read_descriptors
int ff_iamfdec_read_descriptors(IAMFContext *c, AVIOContext *pb, int max_size, void *log_ctx)
Definition: iamf_parse.c:1225
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:11275
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:613
mov_read_dvcc_dvvc
static int mov_read_dvcc_dvvc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:8733
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
MOVStreamContext::tref_tags
MovTref * tref_tags
Definition: isom.h:232
AV_CODEC_ID_SVQ3
@ AV_CODEC_ID_SVQ3
Definition: codec_id.h:75
key
const char * key
Definition: hwcontext_opencl.c:189
AVCodecParameters::nb_coded_side_data
int nb_coded_side_data
Amount of entries in coded_side_data.
Definition: codec_par.h:88
MOVStreamContext::sdtp_data
uint8_t * sdtp_data
Definition: isom.h:195
color_range
color_range
Definition: vf_selectivecolor.c:43
AVMEDIA_TYPE_DATA
@ AVMEDIA_TYPE_DATA
Opaque data information usually continuous.
Definition: avutil.h:202
mov_read_udta_string
static int mov_read_udta_string(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:345
av_mallocz
#define av_mallocz(s)
Definition: tableprint_vlc.h:31
mov_read_stss
static int mov_read_stss(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:3473
mov_read_ddts
static int mov_read_ddts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1154
mov_read_uuid
static int mov_read_uuid(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:7390
AVCOL_PRI_UNSPECIFIED
@ AVCOL_PRI_UNSPECIFIED
Definition: pixfmt.h:639
MOVTrackExt::duration
unsigned duration
Definition: isom.h:122
av_fallthrough
#define av_fallthrough
Definition: attributes.h:67
AV_CODEC_ID_H264
@ AV_CODEC_ID_H264
Definition: codec_id.h:79
av_content_light_metadata_alloc
AVContentLightMetadata * av_content_light_metadata_alloc(size_t *size)
Allocate an AVContentLightMetadata structure and set its fields to default values.
Definition: mastering_display_metadata.c:72
tmp
static uint8_t tmp[40]
Definition: aes_ctr.c:52
av_sha_final
void av_sha_final(AVSHA *ctx, uint8_t *digest)
Finish hashing and output digest value.
Definition: sha.c:347
MOVStreamContext::current_sample
int current_sample
Definition: isom.h:219
MOVFragmentStreamInfo::sidx_pts
int64_t sidx_pts
Definition: isom.h:147
MAX_REORDER_DELAY
#define MAX_REORDER_DELAY
Definition: mov.c:4211
MOVFragmentIndex::current
int current
Definition: isom.h:169
MOVEncryptionIndex::encrypted_samples
AVEncryptionInfo ** encrypted_samples
Definition: isom.h:136
mov_read_close
static int mov_read_close(AVFormatContext *s)
Definition: mov.c:10215
ff_hex_to_data
int ff_hex_to_data(uint8_t *data, const char *p)
Parse a string of hexadecimal strings.
Definition: utils.c:479
MOVAtom::size
int64_t size
Definition: isom.h:102
MOVStreamContext::refcount
int refcount
Definition: isom.h:181
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:472
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:6340
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:7615
FFStream::need_parsing
enum AVStreamParseType need_parsing
Definition: internal.h:314
MOVStreamContext::keyframe_count
unsigned int keyframe_count
Definition: isom.h:214
mov_read_SAND
static int mov_read_SAND(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:8983
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:1284
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:3621
MOVStreamContext::index_ranges
MOVIndexRange * index_ranges
Definition: isom.h:221
DDTS_SIZE
#define DDTS_SIZE
internal.h
MOVTrackExt::stsd_id
unsigned stsd_id
Definition: isom.h:121
AVStreamGroupLCEVC::height
int height
Height of the final image for presentation.
Definition: avformat.h:1086
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:4034
set_frag_stream
static void set_frag_stream(MOVFragmentIndex *frag_index, int id)
Definition: mov.c:1639
mov_read_free
static int mov_read_free(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:7495
mov_realloc_extradata
static int mov_realloc_extradata(AVCodecParameters *par, MOVAtom atom)
Definition: mov.c:2224
AVStream::codecpar
AVCodecParameters * codecpar
Codec parameters associated with this stream.
Definition: avformat.h:770
LIBAVUTIL_VERSION_INT
#define LIBAVUTIL_VERSION_INT
Definition: version.h:85
av_exif_get_tag_id
int32_t av_exif_get_tag_id(const char *name)
Retrieves the tag ID associated with the provided tag string name.
Definition: exif.c:244
AV_PKT_DATA_EXIF
@ AV_PKT_DATA_EXIF
Extensible image file format metadata.
Definition: packet.h:369
AVSEEK_FLAG_BACKWARD
#define AVSEEK_FLAG_BACKWARD
Definition: avformat.h:2543
aes.h
AVClass
Describe the class of an AVClass context structure.
Definition: log.h:76
MOVStreamContext::tts_sample
int tts_sample
Definition: isom.h:208
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:350
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:786
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:196
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:488
mov_read_ftyp
static int mov_read_ftyp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1554
AV_WB16
#define AV_WB16(p, v)
Definition: intreadwrite.h:401
MOVContext::nb_heif_grid
int nb_heif_grid
Definition: isom.h:390
read_image_grid
static int read_image_grid(AVFormatContext *s, const HEIFGrid *grid, AVStreamGroupTileGrid *tile_grid)
Definition: mov.c:10442
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:1057
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:3871
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:9857
AVPALETTE_SIZE
#define AVPALETTE_SIZE
Definition: pixfmt.h:32
AV_OPT_TYPE_DICT
@ AV_OPT_TYPE_DICT
Underlying C type is AVDictionary*.
Definition: opt.h:290
MOVDref::nlvl_to
int16_t nlvl_to
Definition: isom.h:91
get_eia608_packet
static int get_eia608_packet(AVIOContext *pb, AVPacket *pkt, int src_size)
Definition: mov.c:11372
AV_CODEC_ID_DVD_SUBTITLE
@ AV_CODEC_ID_DVD_SUBTITLE
Definition: codec_id.h:573
AVIndexEntry::flags
int flags
Definition: avformat.h:611
MOVStreamContext::time_offset
int64_t time_offset
time offset of the edit list entries
Definition: isom.h:217
mov_read_smdm
static int mov_read_smdm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6539
av_default_item_name
const char * av_default_item_name(void *ptr)
Return the context name.
Definition: log.c:242
AVStereo3D::horizontal_disparity_adjustment
AVRational horizontal_disparity_adjustment
Relative shift of the left and right images, which changes the zero parallax plane.
Definition: stereo3d.h:234
avio_rb64
uint64_t avio_rb64(AVIOContext *s)
Definition: aviobuf.c:911
av_aes_crypt
void av_aes_crypt(AVAES *a, uint8_t *dst, const uint8_t *src, int count, uint8_t *iv, int decrypt)
Encrypt or decrypt a buffer using a previously initialized context.
Definition: aes.c:171
MOVStreamContext::current_index_range
MOVIndexRange * current_index_range
Definition: isom.h:222
mov_open_dref
static int mov_open_dref(MOVContext *c, AVIOContext **pb, const char *src, MOVDref *ref)
Definition: mov.c:5110
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:452
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:442
IAMFSubStream
Definition: iamf.h:82
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:8087
AVStream::metadata
AVDictionary * metadata
Definition: avformat.h:827
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:465
MOV_SAMPLE_DEPENDENCY_NO
#define MOV_SAMPLE_DEPENDENCY_NO
Definition: isom.h:440
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:207
AV_DISPOSITION_MULTILAYER
#define AV_DISPOSITION_MULTILAYER
The video stream contains multiple layers, e.g.
Definition: avformat.h:717
MOVFragmentStreamInfo::index_base
int index_base
Definition: isom.h:152
MOVStreamContext::rap_group
MOVSbgp * rap_group
Definition: isom.h:246
AV_CODEC_ID_QDM2
@ AV_CODEC_ID_QDM2
Definition: codec_id.h:480
mov_read_ilst
static int mov_read_ilst(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5408
MOVTimeToSample::duration
unsigned int duration
Definition: isom.h:59
AV_CH_FRONT_CENTER
#define AV_CH_FRONT_CENTER
Definition: channel_layout.h:177
AVCodecParameters::ch_layout
AVChannelLayout ch_layout
The channel layout and number of channels.
Definition: codec_par.h:207
get_frag_stream_info_from_pkt
static MOVFragmentStreamInfo * get_frag_stream_info_from_pkt(MOVFragmentIndex *frag_index, AVPacket *pkt, int id)
Definition: mov.c:8550
get_sgpd_sync_index
static uint32_t get_sgpd_sync_index(const MOVStreamContext *sc, int nal_unit_type)
Definition: mov.c:4630
mov_read_fiel
static int mov_read_fiel(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2190
parse
static int parse(AVCodecParserContext *s, AVCodecContext *avctx, const uint8_t **poutbuf, int *poutbuf_size, const uint8_t *buf, int buf_size)
Definition: apv_parser.c:92
MOV_MP4_TTML_TAG
#define MOV_MP4_TTML_TAG
Definition: isom.h:483
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:408
MOVFragmentStreamInfo::stsd_id
int stsd_id
Definition: isom.h:155
av_exif_remove_entry
int av_exif_remove_entry(void *logctx, AVExifMetadata *ifd, uint16_t id, int flags)
Remove an entry from the provided EXIF metadata struct.
Definition: exif.c:1289
MOVStreamContext::open_key_samples_count
int open_key_samples_count
Definition: isom.h:254
HEIFItem
Definition: isom.h:299
ff_codec_movaudio_tags
const AVCodecTag ff_codec_movaudio_tags[]
Definition: isom_tags.c:311
ff_codec_movdata_tags
const AVCodecTag ff_codec_movdata_tags[]
Definition: isom.c:82
mov_read_wfex
static int mov_read_wfex(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1258
av_stereo3d_alloc_size
AVStereo3D * av_stereo3d_alloc_size(size_t *size)
Allocate an AVStereo3D structure and set its fields to default values.
Definition: stereo3d.c:39
index
int index
Definition: gxfenc.c:90
c
Undefined Behavior In the C some operations are like signed integer dereferencing freed accessing outside allocated Undefined Behavior must not occur in a C it is not safe even if the output of undefined operations is unused The unsafety may seem nit picking but Optimizing compilers have in fact optimized code on the assumption that no undefined Behavior occurs Optimizing code based on wrong assumptions can and has in some cases lead to effects beyond the output of computations The signed integer overflow problem in speed critical code Code which is highly optimized and works with signed integers sometimes has the problem that often the output of the computation does not c
Definition: undefined.txt:32
AVPROBE_SCORE_EXTENSION
#define AVPROBE_SCORE_EXTENSION
score for file extension
Definition: avformat.h:462
MOVSbgp::count
unsigned int count
Definition: isom.h:128
AVCodecParameters::sample_rate
int sample_rate
The number of audio samples per second.
Definition: codec_par.h:213
mov_parse_stsd_subtitle
static void mov_parse_stsd_subtitle(MOVContext *c, AVIOContext *pb, AVStream *st, MOVStreamContext *sc, int64_t size)
Definition: mov.c:2951
cid
uint16_t cid
Definition: mxfenc.c:2335
mov_skip_multiple_stsd
static int mov_skip_multiple_stsd(MOVContext *c, AVIOContext *pb, int codec_tag, int format, int64_t size)
Definition: mov.c:3117
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:479
AVStream::nb_frames
int64_t nb_frames
number of frames in this stream if known or 0
Definition: avformat.h:808
AVCodecID
AVCodecID
Identify the syntax and semantics of the bitstream.
Definition: codec_id.h:49
av_packet_side_data_get
const AVPacketSideData * av_packet_side_data_get(const AVPacketSideData *sd, int nb_sd, enum AVPacketSideDataType type)
Get side information from a side data array.
Definition: packet.c:645
AVIAMFSubmixElement::audio_element_id
unsigned int audio_element_id
The id of the Audio Element this submix element references.
Definition: iamf.h:455
AV_CODEC_ID_EAC3
@ AV_CODEC_ID_EAC3
Definition: codec_id.h:501
should_retry
static int should_retry(AVIOContext *pb, int error_code)
Definition: mov.c:11305
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:547
AV_PKT_DATA_SPHERICAL
@ AV_PKT_DATA_SPHERICAL
This side data should be associated with a video stream and corresponds to the AVSphericalMapping str...
Definition: packet.h:225
AVCodecParameters::extradata_size
int extradata_size
Size of the extradata content in bytes.
Definition: codec_par.h:75
AVIAMFSubmix
Submix layout as defined in section 3.7 of IAMF.
Definition: iamf.h:559
AV_WB32
#define AV_WB32(p, v)
Definition: intreadwrite.h:415
mov_read_pasp
static int mov_read_pasp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1382
MOVContext::dv_demux
DVDemuxContext * dv_demux
Definition: isom.h:339
AV_CODEC_ID_AAC
@ AV_CODEC_ID_AAC
Definition: codec_id.h:463
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:8893
mov_read_elst
static int mov_read_elst(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6393
MOVEncryptionIndex::auxiliary_info_default_size
uint8_t auxiliary_info_default_size
Definition: isom.h:140
AV_STREAM_GROUP_PARAMS_TILE_GRID
@ AV_STREAM_GROUP_PARAMS_TILE_GRID
Definition: avformat.h:1109
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:11050
AV_CODEC_ID_QCELP
@ AV_CODEC_ID_QCELP
Definition: codec_id.h:485
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:8325
avio_rl32
unsigned int avio_rl32(AVIOContext *s)
Definition: aviobuf.c:733
AVDISCARD_NONKEY
@ AVDISCARD_NONKEY
discard all frames except keyframes
Definition: defs.h:231
MOVFragment::flags
unsigned flags
Definition: isom.h:116
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:351
mov_read_wave
static int mov_read_wave(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2422
AV_SPHERICAL_CUBEMAP
@ AV_SPHERICAL_CUBEMAP
Video frame is split into 6 faces of a cube, and arranged on a 3x2 layout.
Definition: spherical.h:61
avio_rb24
unsigned int avio_rb24(AVIOContext *s)
Definition: aviobuf.c:757
ff_mpa_check_header
static int ff_mpa_check_header(uint32_t header)
Definition: mpegaudiodecheader.h:62
MOVStreamContext::aes_ctx
struct AVAES * aes_ctx
Definition: isom.h:284
cens_scheme_decrypt
static int cens_scheme_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
Definition: mov.c:8391
MOVContext::handbrake_version
int handbrake_version
Definition: isom.h:346
mov_free_stream_context
static void mov_free_stream_context(AVFormatContext *s, AVStream *st)
Definition: mov.c:10150
AVPacket::size
int size
Definition: packet.h:596
NULL_IF_CONFIG_SMALL
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
Definition: internal.h:94
AV_STREAM_GROUP_PARAMS_TREF
@ AV_STREAM_GROUP_PARAMS_TREF
Definition: avformat.h:1111
ff_codec_get_id
enum AVCodecID ff_codec_get_id(const AVCodecTag *tags, unsigned int tag)
Definition: utils.c:143
avformat_alloc_context
AVFormatContext * avformat_alloc_context(void)
Allocate an AVFormatContext.
Definition: options.c:164
MOVFragmentIndexItem
Definition: isom.h:158
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:7564
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:4280
AVSphericalMapping::bound_right
uint32_t bound_right
Distance from the right edge.
Definition: spherical.h:187
MOVStsc::first
int first
Definition: isom.h:74
dst
uint8_t ptrdiff_t const uint8_t ptrdiff_t int intptr_t intptr_t int int16_t * dst
Definition: dsp.h:87
av_bswap32
#define av_bswap32
Definition: bswap.h:47
i
#define i(width, name, range_min, range_max)
Definition: cbs_h264.c:63
MOVStreamContext::stsz_sample_size
unsigned int stsz_sample_size
always contains sample size from stsz atom
Definition: isom.h:210
FF_MOV_FLAG_MFRA_AUTO
#define FF_MOV_FLAG_MFRA_AUTO
Definition: isom.h:464
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:249
start_time
static int64_t start_time
Definition: ffplay.c:328
uuid.h
ff_dvdclut_palette_extradata_cat
int ff_dvdclut_palette_extradata_cat(const uint32_t *clut, const size_t clut_size, AVCodecParameters *par)
Definition: dvdclut.c:28
mov_read_trun
static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5873
MOVStreamContext::stereo3d_size
size_t stereo3d_size
Definition: isom.h:269
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:9494
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:409
size
int size
Definition: twinvq_data.h:10344
mov_read_chan
static int mov_read_chan(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1207
av_make_q
static AVRational av_make_q(int num, int den)
Create an AVRational.
Definition: rational.h:71
mov_read_stsc
static int mov_read_stsc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:3331
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:511
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:1150
MOVStreamContext::coll
AVContentLightMetadata * coll
Definition: isom.h:274
aes_ctr.h
ff_format_io_close
int ff_format_io_close(AVFormatContext *s, AVIOContext **pb)
Definition: avformat.c:1022
mov_parse_heif_items
static int mov_parse_heif_items(AVFormatContext *s)
Definition: mov.c:10808
HEIFItem::is_idat_relative
int is_idat_relative
Definition: isom.h:313
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:4130
MOVDref::path
char * path
Definition: isom.h:87
mov_current_sample_inc
static void mov_current_sample_inc(MOVStreamContext *sc)
Definition: mov.c:4268
AVStream::sample_aspect_ratio
AVRational sample_aspect_ratio
sample aspect ratio (0 if unknown)
Definition: avformat.h:825
FFInputFormat::p
AVInputFormat p
The public AVInputFormat.
Definition: demux.h:70
dovi_isom.h
AVPacket::dts
int64_t dts
Decompression timestamp in AVStream->time_base units; the time at which the packet is decompressed.
Definition: packet.h:594
mov_read_vexu_proj
static int mov_read_vexu_proj(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6986
fix_timescale
static void fix_timescale(MOVContext *c, MOVStreamContext *sc)
Definition: mov.c:5182
avio_r8
int avio_r8(AVIOContext *s)
Definition: aviobuf.c:606
IAMFAudioElement::substreams
IAMFSubStream * substreams
Definition: iamf.h:98
AVSphericalMapping::padding
uint32_t padding
Number of pixels to pad from the edge of each cube face.
Definition: spherical.h:200
a
The reader does not expect b to be semantically here and if the code is changed by maybe adding a a division or other the signedness will almost certainly be mistaken To avoid this confusion a new type was SUINT is the C unsigned type but it holds a signed int to use the same example SUINT a
Definition: undefined.txt:41
av_channel_layout_retype
int av_channel_layout_retype(AVChannelLayout *channel_layout, enum AVChannelOrder order, int flags)
Change the AVChannelOrder of a channel layout.
Definition: channel_layout.c:887
av_reallocp_array
int av_reallocp_array(void *ptr, size_t nmemb, size_t size)
Allocate, reallocate an array through a pointer to a pointer.
Definition: mem.c:225
AVIAMFAudioElement
Information on how to combine one or more audio streams, as defined in section 3.6 of IAMF.
Definition: iamf.h:359
AV_PRIMARY_EYE_NONE
@ AV_PRIMARY_EYE_NONE
Neither eye.
Definition: stereo3d.h:178
mov_read_default
static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:9735
AV_TIMECODE_FLAG_24HOURSMAX
@ AV_TIMECODE_FLAG_24HOURSMAX
timecode wraps after 24 hours
Definition: timecode.h:37
mov_find_reference_track
static AVStream * mov_find_reference_track(AVFormatContext *s, AVStream *st, uint32_t *tref_id, int nb_tref_id, int first_index)
Definition: mov.c:10943
MOV_MP4_FPCM_TAG
#define MOV_MP4_FPCM_TAG
Definition: isom.h:484
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:962
av_packet_side_data_add
AVPacketSideData * av_packet_side_data_add(AVPacketSideData **psd, int *pnb_sd, enum AVPacketSideDataType type, void *data, size_t size, int flags)
Wrap existing data as packet side data.
Definition: packet.c:688
mov_read_packet
static int mov_read_packet(AVFormatContext *s, AVPacket *pkt)
Definition: mov.c:11505
mov_read_infe
static int mov_read_infe(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:9136
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:1078
AVStreamGroup::lcevc
struct AVStreamGroupLCEVC * lcevc
Definition: avformat.h:1153
attributes.h
AV_CODEC_ID_LCEVC
@ AV_CODEC_ID_LCEVC
Definition: codec_id.h:616
MOVEncryptionIndex::auxiliary_offsets_count
size_t auxiliary_offsets_count
Definition: isom.h:142
HEIFItem::vflip
int vflip
Definition: isom.h:311
AVPacket::flags
int flags
A combination of AV_PKT_FLAG values.
Definition: packet.h:601
av_dict_free
void av_dict_free(AVDictionary **pm)
Free all the memory allocated for an AVDictionary struct and all keys and values.
Definition: dict.c:233
av_encryption_info_free
void av_encryption_info_free(AVEncryptionInfo *info)
Frees the given encryption info object.
Definition: encryption_info.c:82
read_header
static int read_header(FFV1Context *f, RangeCoder *c)
Definition: ffv1dec.c:501
av_strstart
int av_strstart(const char *str, const char *pfx, const char **ptr)
Return non-zero if pfx is a prefix of str.
Definition: avstring.c:36
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:163
version
version
Definition: libkvazaar.c:313
AV_STREAM_GROUP_PARAMS_IAMF_AUDIO_ELEMENT
@ AV_STREAM_GROUP_PARAMS_IAMF_AUDIO_ELEMENT
Definition: avformat.h:1107
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:1185
ff_rfps_calculate
void ff_rfps_calculate(AVFormatContext *ic)
Definition: demux.c:2397
input
and forward the test the status of outputs and forward it to the corresponding return FFERROR_NOT_READY If the filters stores internally one or a few frame for some input
Definition: filter_design.txt:172
MOV_MP4_IPCM_TAG
#define MOV_MP4_IPCM_TAG
Definition: isom.h:485
mov_read_clli
static int mov_read_clli(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6667
MOVStreamContext::chunk_offsets
int64_t * chunk_offsets
Definition: isom.h:187
MovTref::id
uint32_t * id
trackID of the referenced track
Definition: isom.h:97
AVStreamGroup::iamf_mix_presentation
struct AVIAMFMixPresentation * iamf_mix_presentation
Definition: avformat.h:1151
AVBufferRef::size
size_t size
Size of data in bytes.
Definition: buffer.h:94
MOVFragmentIndex::item
MOVFragmentIndexItem * item
Definition: isom.h:171
AV_LOG_INFO
#define AV_LOG_INFO
Standard information.
Definition: log.h:221
MOVStreamContext::iamf
struct IAMFDemuxContext * iamf
Definition: isom.h:290
FFERROR_REDO
#define FFERROR_REDO
Returned by demuxers to indicate that data was consumed but discarded (ignored streams or junk data).
Definition: demux.h:224
av_encryption_init_info_alloc
AVEncryptionInitInfo * av_encryption_init_info_alloc(uint32_t system_id_size, uint32_t num_key_ids, uint32_t key_id_size, uint32_t data_size)
Allocates an AVEncryptionInitInfo structure and sub-pointers to hold the given sizes.
Definition: encryption_info.c:178
av_channel_layout_custom_init
int av_channel_layout_custom_init(AVChannelLayout *channel_layout, int nb_channels)
Initialize a custom channel layout with the specified number of channels.
Definition: channel_layout.c:233
av_aes_ctr_free
void av_aes_ctr_free(struct AVAESCTR *a)
Release an AVAESCTR context.
Definition: aes_ctr.c:84
av_mastering_display_metadata_alloc_size
AVMasteringDisplayMetadata * av_mastering_display_metadata_alloc_size(size_t *size)
Allocate an AVMasteringDisplayMetadata structure and set its fields to default values.
Definition: mastering_display_metadata.c:44
mov_read_dfla
static int mov_read_dfla(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:8189
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:9605
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:1062
mov_metadata_creation_time
static void mov_metadata_creation_time(MOVContext *c, AVIOContext *pb, AVDictionary **metadata, int version)
Definition: mov.c:1878
mov_metadata_hmmt
static int mov_metadata_hmmt(MOVContext *c, AVIOContext *pb, unsigned len)
Definition: mov.c:324
AV_CODEC_ID_MJPEG
@ AV_CODEC_ID_MJPEG
Definition: codec_id.h:59
MOVFragmentStreamInfo::next_trun_dts
int64_t next_trun_dts
Definition: isom.h:150
MOVStreamContext::stsc_index
unsigned int stsc_index
Definition: isom.h:201
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:8118
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:3411
mov_finalize_packet
static int mov_finalize_packet(AVFormatContext *s, AVStream *st, AVIndexEntry *sample, int64_t current_index, AVPacket *pkt)
Definition: mov.c:11441
MOVIndexRange
Definition: isom.h:174
mov_read_seek
static int mov_read_seek(AVFormatContext *s, int stream_index, int64_t sample_time, int flags)
Definition: mov.c:11832
bprint.h
MOVContext::advanced_editlist
int advanced_editlist
Definition: isom.h:351
MOVStreamContext::time_scale
int time_scale
Definition: isom.h:216
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:1039
MOVStreamContext::bytes_per_frame
unsigned int bytes_per_frame
Definition: isom.h:223
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:176
av_malloc
#define av_malloc(s)
Definition: ops_asmgen.c:44
AV_CODEC_ID_NONE
@ AV_CODEC_ID_NONE
Definition: codec_id.h:50
AVPacket::pts
int64_t pts
Presentation timestamp in AVStream->time_base units; the time at which the decompressed packet will b...
Definition: packet.h:588
avio_internal.h
MOVCtts::offset
int offset
Definition: isom.h:70
mov_read_trex
static int mov_read_trex(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5808
search_frag_timestamp
static int search_frag_timestamp(AVFormatContext *s, MOVFragmentIndex *frag_index, AVStream *st, int64_t timestamp)
Definition: mov.c:1751
HEIFItem::width
int width
Definition: isom.h:307
FLAGS
#define FLAGS
Definition: mov.c:11889
MOVStreamContext::stereo3d
AVStereo3D * stereo3d
Definition: isom.h:268
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:4320
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:7966
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:3265
internal.h
AV_SPHERICAL_FISHEYE
@ AV_SPHERICAL_FISHEYE
Fisheye projection (Apple).
Definition: spherical.h:84
AVCodecParameters::height
int height
The height of the video frame in pixels.
Definition: codec_par.h:150
AV_TIME_BASE
#define AV_TIME_BASE
Internal time base represented as integer.
Definition: avutil.h:253
MOVStreamContext::stps_count
unsigned int stps_count
Definition: isom.h:203
AVCodecParameters::block_align
int block_align
The number of bytes per coded audio frame, required by some formats.
Definition: codec_par.h:221
AV_CODEC_ID_TTML
@ AV_CODEC_ID_TTML
Definition: codec_id.h:597
rb_size
static int rb_size(AVIOContext *pb, int64_t *value, int size)
Definition: mov.c:9009
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:3164
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:114
AVIAMFMixPresentation
Information on how to render and mix one or more AVIAMFAudioElement to generate the final audio outpu...
Definition: iamf.h:616
ff_id3v1_genre_str
const char *const ff_id3v1_genre_str[ID3v1_GENRE_MAX+1]
ID3v1 genres.
Definition: id3v1.c:26
MOVStreamContext::sample_sizes
unsigned int * sample_sizes
Definition: isom.h:212
MOVContext::frag_index
MOVFragmentIndex frag_index
Definition: isom.h:364
mov_read_vpcc
static int mov_read_vpcc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6495
AV_CODEC_ID_PCM_F64BE
@ AV_CODEC_ID_PCM_F64BE
Definition: codec_id.h:361
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:230
FFMIN
#define FFMIN(a, b)
Definition: macros.h:49
av_d2q
AVRational av_d2q(double d, int max)
Convert a double precision floating point number to a rational.
Definition: rational.c:106
fix_frag_index_entries
static void fix_frag_index_entries(MOVFragmentIndex *frag_index, int index, int id, int entries)
Definition: mov.c:1837
mov_finalize_stsd_codec
static int mov_finalize_stsd_codec(MOVContext *c, AVIOContext *pb, AVStream *st, MOVStreamContext *sc)
Definition: mov.c:3013
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:348
mov_read_mdcv
static int mov_read_mdcv(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6586
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:1404
AV_CODEC_ID_VC1
@ AV_CODEC_ID_VC1
Definition: codec_id.h:122
demux.h
AV_DISPOSITION_DEPENDENT
#define AV_DISPOSITION_DEPENDENT
The stream is intended to be mixed with another stream before presentation.
Definition: avformat.h:708
MOVStreamContext::pb
AVIOContext * pb
Definition: isom.h:180
mov_read_keys
static int mov_read_keys(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5417
mov_read_iref_cdsc
static int mov_read_iref_cdsc(MOVContext *c, AVIOContext *pb, uint32_t type, int version)
Definition: mov.c:9350
AVCodecParameters::color_range
enum AVColorRange color_range
Additional colorspace characteristics.
Definition: codec_par.h:189
AV_CH_SIDE_RIGHT
#define AV_CH_SIDE_RIGHT
Definition: channel_layout.h:185
len
int len
Definition: vorbis_enc_data.h:426
AV_CODEC_ID_JPEG2000
@ AV_CODEC_ID_JPEG2000
Definition: codec_id.h:140
exif.h
MOVFragment::size
unsigned size
Definition: isom.h:115
MOV_TFHD_DEFAULT_SIZE
#define MOV_TFHD_DEFAULT_SIZE
Definition: isom.h:411
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:11012
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:4771
AVCodecParameters::coded_side_data
AVPacketSideData * coded_side_data
Additional data associated with the entire stream.
Definition: codec_par.h:83
mov_read_svq3
static int mov_read_svq3(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2417
mov_find_tref_tag
static MovTref * mov_find_tref_tag(const MOVStreamContext *sc, uint32_t name)
Definition: mov.c:2574
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:149
AV_IAMF_AUDIO_ELEMENT_TYPE_SCENE
@ AV_IAMF_AUDIO_ELEMENT_TYPE_SCENE
Definition: iamf.h:349
AVCodecParameters::field_order
enum AVFieldOrder field_order
The order of the fields in interlaced video.
Definition: codec_par.h:182
av_get_packet
int av_get_packet(AVIOContext *s, AVPacket *pkt, int size)
Allocate and read the payload of a packet and initialize its fields with default values.
Definition: utils.c:98
mov_read_iinf
static int mov_read_iinf(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:9213
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:998
get_stream_info_time
static int64_t get_stream_info_time(MOVFragmentStreamInfo *frag_stream_info)
Definition: mov.c:1699
MP4TrackKindValueMapping
Definition: isom.h:487
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:4171
AV_WB8
#define AV_WB8(p, d)
Definition: intreadwrite.h:392
MOVStreamContext::chunk_count
unsigned int chunk_count
Definition: isom.h:186
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:240
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:276
AVCodecParameters::avcodec_parameters_copy
int avcodec_parameters_copy(AVCodecParameters *dst, const AVCodecParameters *src)
Copy the contents of src to dst.
Definition: codec_par.c:107
mov_read_tmcd
static int mov_read_tmcd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6467
mov_chan.h
AVStream::disposition
int disposition
Stream disposition - a combination of AV_DISPOSITION_* flags.
Definition: avformat.h:816
MOVStreamContext::ambient_size
size_t ambient_size
Definition: isom.h:277
tag
uint32_t tag
Definition: movenc.c:2049
AVStream::id
int id
Format-specific stream ID.
Definition: avformat.h:759
ret
ret
Definition: filter_design.txt:187
AVStream
Stream structure.
Definition: avformat.h:747
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:305
MOVEncryptionIndex::nb_encrypted_samples
unsigned int nb_encrypted_samples
Definition: isom.h:135
mov_read_senc
static int mov_read_senc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:7669
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:193
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:1165
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:129
HEIFItem::icc_profile_size
size_t icc_profile_size
Definition: isom.h:315
MOVContext::chapter_tracks
int * chapter_tracks
Definition: isom.h:347
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:593
pos
unsigned int pos
Definition: spdifenc.c:414
avformat.h
MOVFragment::implicit_offset
uint64_t implicit_offset
Definition: isom.h:112
dict.h
av_packet_side_data_new
AVPacketSideData * av_packet_side_data_new(AVPacketSideData **psd, int *pnb_sd, enum AVPacketSideDataType type, size_t size, int flags)
Allocate a new packet side data.
Definition: packet.c:695
AV_AUDIO_SERVICE_TYPE_KARAOKE
@ AV_AUDIO_SERVICE_TYPE_KARAOKE
Definition: defs.h:244
mov_read_dmlp
static int mov_read_dmlp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:8698
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:226
MOVContext::time_scale
int time_scale
Definition: isom.h:329
id
enum AVCodecID id
Definition: dts2pts.c:550
mov_read_tfdt
static int mov_read_tfdt(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5834
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:5550
search_frag_moof_offset
static int search_frag_moof_offset(MOVFragmentIndex *frag_index, int64_t offset)
Definition: mov.c:1675
MOVFragment
Definition: isom.h:107
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:11312
MOVContext::use_mfra_for
int use_mfra_for
Definition: isom.h:361
AVEncryptionInfo
This describes encryption info for a packet.
Definition: encryption_info.h:43
MOVStreamContext::encryption_index
MOVEncryptionIndex * encryption_index
Definition: isom.h:287
MIN_DATA_ENTRY_BOX_SIZE
#define MIN_DATA_ENTRY_BOX_SIZE
Definition: mov.c:637
AVStreamGroup
Definition: avformat.h:1117
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:753
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:11677
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:2766
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:235
mov_read_dec3
static int mov_read_dec3(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1111
get_frag_time
static int64_t get_frag_time(AVFormatContext *s, AVStream *dst_st, MOVFragmentIndex *frag_index, int index)
Definition: mov.c:1709
MOVStreamContext::sample_size
unsigned int sample_size
may contain value calculated from stsd or value from stsz atom
Definition: isom.h:209
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:1172
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:258
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:3927
MOVFragment::moof_offset
uint64_t moof_offset
Definition: isom.h:111
AVIO_SEEKABLE_NORMAL
#define AVIO_SEEKABLE_NORMAL
Seeking works like for a local file.
Definition: avio.h:41
av_packet_new_side_data
uint8_t * av_packet_new_side_data(AVPacket *pkt, enum AVPacketSideDataType type, size_t size)
Allocate new information of a packet.
Definition: packet.c:231
buffer
the frame and frame reference mechanism is intended to as much as expensive copies of that data while still allowing the filters to produce correct results The data is stored in buffers represented by AVFrame structures Several references can point to the same frame buffer
Definition: filter_design.txt:49
mov_read_glbl
static int mov_read_glbl(MOVContext *c, AVIOContext *pb, MOVAtom atom)
This function reads atom content and puts data in extradata without tag nor size unlike mov_read_extr...
Definition: mov.c:2479
AVRational::den
int den
Denominator.
Definition: rational.h:60
mode
mode
Definition: ebur128.h:83
mov_parse_uuid_spherical
static int mov_parse_uuid_spherical(MOVStreamContext *sc, AVIOContext *pb, size_t len)
Definition: mov.c:7327
MOVTrackExt::size
unsigned size
Definition: isom.h:123
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:128
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:340
av_channel_layout_uninit
void av_channel_layout_uninit(AVChannelLayout *channel_layout)
Free any allocated data in the channel layout and reset the channel count to 0.
Definition: channel_layout.c:443
AV_CODEC_ID_DVAUDIO
@ AV_CODEC_ID_DVAUDIO
Definition: codec_id.h:467
avformat_free_context
void avformat_free_context(AVFormatContext *s)
Free an AVFormatContext and all its streams.
Definition: avformat.c:148
MOVContext::aax_mode
unsigned int aax_mode
'aax' file has been detected
Definition: isom.h:366
mov_read_sv3d
static int mov_read_sv3d(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6849
avio_read
int avio_read(AVIOContext *s, unsigned char *buf, int size)
Read size bytes from AVIOContext into buf.
Definition: aviobuf.c:615
mov_aaxc_crypto
static int mov_aaxc_crypto(MOVContext *c)
Definition: mov.c:1515
mov_get_skip_samples
static int64_t mov_get_skip_samples(AVStream *st, int sample)
Definition: mov.c:11815
MOVFragmentIndex
Definition: isom.h:166
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:881
MOVStreamContext::tts_count
unsigned int tts_count
Definition: isom.h:188
MOVStreamContext::track_end
int64_t track_end
used for dts generation in fragmented movie files
Definition: isom.h:243
MOVStreamContext::sgpd_sync_count
uint32_t sgpd_sync_count
Definition: isom.h:250
MOVContext::fragment
MOVFragment fragment
current fragment in moof atom
Definition: isom.h:342
AVIndexEntry::pos
int64_t pos
Definition: avformat.h:602
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:1082
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:285
ff_codec_movsubtitle_tags
const AVCodecTag ff_codec_movsubtitle_tags[]
Definition: isom.c:75
av_mul_q
AVRational av_mul_q(AVRational b, AVRational c)
Multiply two rationals.
Definition: rational.c:80
AVPacket::stream_index
int stream_index
Definition: packet.h:597
MOVFragmentIndexItem::nb_stream_info
int nb_stream_info
Definition: isom.h:162
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:10288
mov_read_sbas
static int mov_read_sbas(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2602
MOVStreamContext::has_sidx
int has_sidx
Definition: isom.h:281
AV_CH_FRONT_RIGHT
#define AV_CH_FRONT_RIGHT
Definition: channel_layout.h:176
av_aes_ctr_crypt
void av_aes_ctr_crypt(struct AVAESCTR *a, uint8_t *dst, const uint8_t *src, int count)
Process a buffer using a previously initialized context.
Definition: aes_ctr.c:102
mov_metadata_gnre
static int mov_metadata_gnre(MOVContext *c, AVIOContext *pb, unsigned len, const char *key)
Definition: mov.c:134
AV_PKT_DATA_ENCRYPTION_INFO
@ AV_PKT_DATA_ENCRYPTION_INFO
This side data contains encryption info for how to decrypt the packet.
Definition: packet.h:252
av_realloc
#define av_realloc(p, s)
Definition: ops_asmgen.c:46
MOV_MERGE_CTTS
#define MOV_MERGE_CTTS
Definition: mov.c:4701
FFStream::index_entries
AVIndexEntry * index_entries
Only used if the format does not support seeking natively.
Definition: internal.h:184
av_dict_set_int
int av_dict_set_int(AVDictionary **pm, const char *key, int64_t value, int flags)
Convenience wrapper for av_dict_set() that converts the value to a string and stores it.
Definition: dict.c:177
mov_read_dpxe
static int mov_read_dpxe(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2302
AVIAMFSubmix::nb_elements
unsigned int nb_elements
Number of elements in the submix.
Definition: iamf.h:575
MOVFragmentStreamInfo::id
int id
Definition: isom.h:146
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:10065
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:182
AV_CODEC_ID_PCM_S32LE
@ AV_CODEC_ID_PCM_S32LE
Definition: codec_id.h:347
AVCodecParameters::bits_per_coded_sample
int bits_per_coded_sample
The number of bits per sample in the codedwords.
Definition: codec_par.h:113
mov_parse_tiles
static int mov_parse_tiles(AVFormatContext *s)
Definition: mov.c:10682
mem.h
AVStreamGroup::type
enum AVStreamGroupParamsType type
Group type.
Definition: avformat.h:1144
MOVElst::time
int64_t time
Definition: isom.h:81
AVBufferRef
A reference to a data buffer.
Definition: buffer.h:82
HEIFGrid
Definition: isom.h:318
mov_read_iref_dimg
static int mov_read_iref_dimg(MOVContext *c, AVIOContext *pb, int version)
Definition: mov.c:9267
mov_read_pcmc
static int mov_read_pcmc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2031
build_open_gop_key_points
static int build_open_gop_key_points(AVStream *st)
Definition: mov.c:4638
mov_parse_stsd_audio
static void mov_parse_stsd_audio(MOVContext *c, AVIOContext *pb, AVStream *st, MOVStreamContext *sc)
Definition: mov.c:2830
IAMFContext::mix_presentations
IAMFMixPresentation ** mix_presentations
Definition: iamf.h:133
AV_CODEC_ID_PCM_U8
@ AV_CODEC_ID_PCM_U8
Definition: codec_id.h:344
MOVContext::trak_index
int trak_index
Index of the current 'trak'.
Definition: isom.h:336
mov_read_timecode_track
static int mov_read_timecode_track(AVFormatContext *s, AVStream *st)
Definition: mov.c:10091
HEIFGrid::item
HEIFItem * item
Definition: isom.h:319
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:138
MOVFragment::stsd_id
unsigned stsd_id
Definition: isom.h:113
AVCodecParameters::video_delay
int video_delay
Number of delayed frames.
Definition: codec_par.h:200
HEIFGrid::tile_id_list
int16_t * tile_id_list
Definition: isom.h:321
avpriv_request_sample
#define avpriv_request_sample(...)
Definition: tableprint_vlc.h:37
MOVStreamContext::tts_data
MOVTimeToSample * tts_data
Definition: isom.h:190
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:460
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:362
AVStreamGroupTileGrid::height
int height
Height of the final image for presentation.
Definition: avformat.h:1049
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:10306
av_free
#define av_free(p)
Definition: tableprint_vlc.h:34
AVDictionaryEntry
Definition: dict.h:90
av_add_q
AVRational av_add_q(AVRational b, AVRational c)
Add two rationals.
Definition: rational.c:93
AVCodecParameters::codec_id
enum AVCodecID codec_id
Specific type of the encoded data (the codec used).
Definition: codec_par.h:57
AVStereo3DView
AVStereo3DView
List of possible view types.
Definition: stereo3d.h:149
AVPacket
This structure stores compressed data.
Definition: packet.h:572
AVContentLightMetadata::MaxFALL
unsigned MaxFALL
Max average light level per frame (cd/m^2).
Definition: mastering_display_metadata.h:116
mov_parse_lcevc_streams
static int mov_parse_lcevc_streams(AVFormatContext *s)
Definition: mov.c:10958
mov_read_hfov
static int mov_read_hfov(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:7298
AV_OPT_TYPE_BOOL
@ AV_OPT_TYPE_BOOL
Underlying C type is int.
Definition: opt.h:327
AVStreamGroupTileGrid::offsets
struct AVStreamGroupTileGrid::@447 * offsets
An nb_tiles sized array of offsets in pixels from the topleft edge of the canvas, indicating where ea...
MOVStreamContext::stps_data
unsigned * stps_data
partial sync sample for mpeg-2 open gop
Definition: isom.h:204
AV_CODEC_ID_ADPCM_IMA_WAV
@ AV_CODEC_ID_ADPCM_IMA_WAV
Definition: codec_id.h:379
MOVContext::nb_heif_item
int nb_heif_item
Definition: isom.h:388
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:35
av_dict_set
int av_dict_set(AVDictionary **pm, const char *key, const char *value, int flags)
Set the given entry in *pm, overwriting an existing entry.
Definition: dict.c:86
riff.h
av_dict_copy
int av_dict_copy(AVDictionary **dst, const AVDictionary *src, int flags)
Copy entries from one AVDictionary struct into another.
Definition: dict.c:247
av_encryption_info_alloc
AVEncryptionInfo * av_encryption_info_alloc(uint32_t subsample_count, uint32_t key_id_size, uint32_t iv_size)
Allocates an AVEncryptionInfo structure and sub-pointers to hold the given number of subsamples.
Definition: encryption_info.c:41
AVPacket::pos
int64_t pos
byte position in stream, -1 if unknown
Definition: packet.h:615
FFInputFormat
Definition: demux.h:66
MOVContext::decryption_keys
AVDictionary * decryption_keys
Definition: isom.h:393
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:7059
AV_CODEC_ID_ILBC
@ AV_CODEC_ID_ILBC
Definition: codec_id.h:520
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:419
MOVStreamContext::tmcd_flags
uint32_t tmcd_flags
tmcd track flags
Definition: isom.h:241
int32_t
int32_t
Definition: audioconvert.c:56
HEIFItem::rotation
int rotation
Definition: isom.h:309
MOVAtom::type
uint32_t type
Definition: isom.h:101
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:592
parse_timecode_in_framenum_format
static int parse_timecode_in_framenum_format(AVFormatContext *s, AVStream *st, int64_t value, int flags)
Definition: mov.c:10051
MOVStreamContext::tmcd_nb_frames
uint8_t tmcd_nb_frames
tmcd number of frames per tick / second
Definition: isom.h:242
AVIAMFSubmixElement
Submix element as defined in section 3.7 of IAMF.
Definition: iamf.h:449
replaygain.h
MOVFragmentIndexItem::headers_read
int headers_read
Definition: isom.h:160
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:244
MP4TrackKindValueMapping::value
const char * value
Definition: isom.h:489
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:736
MOVStsc::count
int count
Definition: isom.h:75
AV_CODEC_ID_PCM_F32LE
@ AV_CODEC_ID_PCM_F32LE
Definition: codec_id.h:360
ff_mov_demuxer
const FFInputFormat ff_mov_demuxer
Definition: mov.c:11951
AVCodecParameters::bit_rate
int64_t bit_rate
The average bitrate of the encoded data (in bits per second).
Definition: codec_par.h:99
MOVStts::count
unsigned int count
Definition: isom.h:64
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
MOVStreamContext::display_matrix
int32_t * display_matrix
Definition: isom.h:267
MOVContext::heif_grid
HEIFGrid * heif_grid
Definition: isom.h:389
MOVStreamContext::min_sample_duration
uint32_t min_sample_duration
Definition: isom.h:255
MOVStreamContext::current_index
int64_t current_index
Definition: isom.h:220
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:192
MOVFragmentStreamInfo::index_entry
int index_entry
Definition: isom.h:153
cenc_decrypt
static int cenc_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
Definition: mov.c:8534
MOVStreamContext::format
uint32_t format
Definition: isom.h:279
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:247
MOVContext::bitrates_count
int bitrates_count
Definition: isom.h:359
AV_CODEC_ID_VORBIS
@ AV_CODEC_ID_VORBIS
Definition: codec_id.h:466
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:796
MOVStreamContext::id
int id
AVStream id.
Definition: isom.h:183
MOVStreamContext::samples_per_frame
unsigned int samples_per_frame
Definition: isom.h:224
MOVStreamContext::tts_allocated_size
unsigned int tts_allocated_size
Definition: isom.h:189
pkt
static AVPacket * pkt
Definition: demux_decode.c:55
MOVElst::duration
int64_t duration
Definition: isom.h:80
ac3tab.h
avstring.h
mov_read_ispe
static int mov_read_ispe(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:9433
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:9388
IAMFMixPresentation::mix
AVIAMFMixPresentation * mix
mix backs cmix iff the AVIAMFMixPresentation is owned by this structure.
Definition: iamf.h:113
mov_read_clap
static int mov_read_clap(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1273
mov_read_mfra
static int mov_read_mfra(MOVContext *c, AVIOContext *f)
Definition: mov.c:10361
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:993
AVTimecode
Definition: timecode.h:41
get_frag_stream_info
static MOVFragmentStreamInfo * get_frag_stream_info(MOVFragmentIndex *frag_index, int index, int id)
Definition: mov.c:1620
IAMFDemuxContext::iamf
IAMFContext iamf
Definition: iamf_reader.h:33
IAMFSubStream::codecpar
AVCodecParameters * codecpar
Definition: iamf.h:86
mov_read_kind
static int mov_read_kind(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:8804
MOVContext::heif_item
HEIFItem ** heif_item
Definition: isom.h:387
MOVStreamContext::stts_count
unsigned int stts_count
Definition: isom.h:191
MOV_TRUN_SAMPLE_CTS
#define MOV_TRUN_SAMPLE_CTS
Definition: isom.h:421
HEIFItem::iref_list
HEIFItemRef * iref_list
Definition: isom.h:301
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:482
snprintf
#define snprintf
Definition: snprintf.h:34
IAMFMixPresentation::mix_presentation_id
unsigned int mix_presentation_id
Definition: iamf.h:114
AVCodecParameters::initial_padding
int initial_padding
Number of padding audio samples at the start.
Definition: codec_par.h:239
AV_CODEC_ID_PCM_S24BE
@ AV_CODEC_ID_PCM_S24BE
Definition: codec_id.h:352
mov_read_st3d
static int mov_read_st3d(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6721
mov_read_imir
static int mov_read_imir(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:9475
is_open_key_sample
static int is_open_key_sample(const MOVStreamContext *sc, int sample)
Definition: mov.c:11696
mov_read_dvc1
static int mov_read_dvc1(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2525
MOVStreamContext::elst_count
unsigned int elst_count
Definition: isom.h:206
av_color_transfer_name
const char * av_color_transfer_name(enum AVColorTransferCharacteristic transfer)
Definition: pixdesc.c:3823
AVChannelCustom::id
enum AVChannel id
Definition: channel_layout.h:284
mov_read_atom_into_extradata
static int64_t mov_read_atom_into_extradata(MOVContext *c, AVIOContext *pb, MOVAtom atom, AVCodecParameters *par, uint8_t *buf)
Definition: mov.c:2239
FLAC_METADATA_TYPE_STREAMINFO
@ FLAC_METADATA_TYPE_STREAMINFO
Definition: flac.h:46
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:9952
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:286
duration
static int64_t duration
Definition: ffplay.c:329
MOVContext::cur_item_id
int cur_item_id
Definition: isom.h:386
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:1663
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:355
MOVContext::found_iinf
int found_iinf
'iinf' atom has been found
Definition: isom.h:333
MOVContext::meta_keys_count
unsigned meta_keys_count
Definition: isom.h:338
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:1013
MOVStreamContext::palette
uint32_t palette[256]
Definition: isom.h:238
cenc_scheme_decrypt
static int cenc_scheme_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
Definition: mov.c:8266
MOVFragment::track_id
unsigned track_id
Definition: isom.h:109
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:2967
AV_CH_SIDE_LEFT
#define AV_CH_SIDE_LEFT
Definition: channel_layout.h:184
ff_iamf_read_deinit
void ff_iamf_read_deinit(IAMFDemuxContext *c)
Definition: iamf_reader.c:371
AV_CODEC_ID_PRORES
@ AV_CODEC_ID_PRORES
Definition: codec_id.h:200
AV_RB16
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_WL16 uint64_t_TMPL AV_WB64 unsigned int_TMPL AV_WB32 unsigned int_TMPL AV_WB24 unsigned int_TMPL AV_RB16
Definition: bytestream.h:98
av_encryption_init_info_add_side_data
uint8_t * av_encryption_init_info_add_side_data(const AVEncryptionInitInfo *info, size_t *side_data_size)
Allocates and initializes side data that holds a copy of the given encryption init info.
Definition: encryption_info.c:292
av_fourcc2str
#define av_fourcc2str(fourcc)
Definition: avutil.h:347
ff_mov_read_chan
int ff_mov_read_chan(AVFormatContext *s, AVIOContext *pb, AVStream *st, int64_t size)
Read 'chan' tag from the input stream.
Definition: mov_chan.c:524
av_index_search_timestamp
int av_index_search_timestamp(AVStream *st, int64_t timestamp, int flags)
Get the index for a specific timestamp.
Definition: seek.c:245
mov_read_pitm
static int mov_read_pitm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:9028
MOVContext::ignore_chapters
int ignore_chapters
Definition: isom.h:353
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:492
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:302
AV_DISPOSITION_NON_DIEGETIC
#define AV_DISPOSITION_NON_DIEGETIC
The stream is intended to be mixed with a spatial audio track.
Definition: avformat.h:685
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:184
HEIFItem::extent_offset
int64_t extent_offset
Definition: isom.h:306
mov_read_stsz
static int mov_read_stsz(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:3528