FFmpeg
mov.c
Go to the documentation of this file.
1 /*
2  * MOV demuxer
3  * Copyright (c) 2001 Fabrice Bellard
4  * Copyright (c) 2009 Baptiste Coudurier <baptiste dot coudurier at gmail dot com>
5  *
6  * first version by Francois Revol <revol@free.fr>
7  * seek function by Gael Chardon <gael.dev@4now.net>
8  *
9  * This file is part of FFmpeg.
10  *
11  * FFmpeg is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU Lesser General Public
13  * License as published by the Free Software Foundation; either
14  * version 2.1 of the License, or (at your option) any later version.
15  *
16  * FFmpeg is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19  * Lesser General Public License for more details.
20  *
21  * You should have received a copy of the GNU Lesser General Public
22  * License along with FFmpeg; if not, write to the Free Software
23  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
24  */
25 
26 #include "config_components.h"
27 
28 #include <inttypes.h>
29 #include <limits.h>
30 #include <stdint.h>
31 
32 #include "libavutil/attributes.h"
33 #include "libavutil/bprint.h"
35 #include "libavutil/internal.h"
36 #include "libavutil/intreadwrite.h"
37 #include "libavutil/intfloat.h"
38 #include "libavutil/mathematics.h"
39 #include "libavutil/avassert.h"
40 #include "libavutil/avstring.h"
41 #include "libavutil/dict.h"
42 #include "libavutil/display.h"
43 #include "libavutil/mem.h"
44 #include "libavutil/opt.h"
45 #include "libavutil/aes.h"
46 #include "libavutil/aes_ctr.h"
47 #include "libavutil/pixdesc.h"
48 #include "libavutil/sha.h"
49 #include "libavutil/spherical.h"
50 #include "libavutil/stereo3d.h"
51 #include "libavutil/timecode.h"
52 #include "libavutil/uuid.h"
53 #include "libavcodec/ac3tab.h"
54 #include "libavcodec/exif.h"
55 #include "libavcodec/flac.h"
56 #include "libavcodec/hevc/hevc.h"
58 #include "libavcodec/mlp_parse.h"
59 #include "avformat.h"
60 #include "internal.h"
61 #include "avio_internal.h"
62 #include "demux.h"
63 #include "dvdclut.h"
64 #include "iamf_parse.h"
65 #include "iamf_reader.h"
66 #include "dovi_isom.h"
67 #include "riff.h"
68 #include "isom.h"
69 #include "libavcodec/get_bits.h"
70 #include "id3v1.h"
71 #include "mov_chan.h"
72 #include "replaygain.h"
73 
74 #if CONFIG_ZLIB
75 #include <zlib.h>
76 #endif
77 
78 #include "qtpalette.h"
79 
80 /* those functions parse an atom */
81 /* links atom IDs to parse functions */
82 typedef struct MOVParseTableEntry {
83  uint32_t type;
84  int (*parse)(MOVContext *ctx, AVIOContext *pb, MOVAtom atom);
86 
87 static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom);
88 static int mov_read_mfra(MOVContext *c, AVIOContext *f);
90 
92  unsigned len, const char *key)
93 {
94  char buf[16];
95 
96  short current, total = 0;
97  avio_rb16(pb); // unknown
98  current = avio_rb16(pb);
99  if (len >= 6)
100  total = avio_rb16(pb);
101  if (!total)
102  snprintf(buf, sizeof(buf), "%d", current);
103  else
104  snprintf(buf, sizeof(buf), "%d/%d", current, total);
105  c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
106  av_dict_set(&c->fc->metadata, key, buf, 0);
107 
108  return 0;
109 }
110 
112  unsigned len, const char *key)
113 {
114  /* bypass padding bytes */
115  avio_r8(pb);
116  avio_r8(pb);
117  avio_r8(pb);
118 
119  c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
120  av_dict_set_int(&c->fc->metadata, key, avio_r8(pb), 0);
121 
122  return 0;
123 }
124 
126  unsigned len, const char *key)
127 {
128  c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
129  av_dict_set_int(&c->fc->metadata, key, avio_r8(pb), 0);
130 
131  return 0;
132 }
133 
135  unsigned len, const char *key)
136 {
137  short genre;
138 
139  avio_r8(pb); // unknown
140 
141  genre = avio_r8(pb);
142  if (genre < 1 || genre > ID3v1_GENRE_MAX)
143  return 0;
144  c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
145  av_dict_set(&c->fc->metadata, key, ff_id3v1_genre_str[genre-1], 0);
146 
147  return 0;
148 }
149 
150 static const uint32_t mac_to_unicode[128] = {
151  0x00C4,0x00C5,0x00C7,0x00C9,0x00D1,0x00D6,0x00DC,0x00E1,
152  0x00E0,0x00E2,0x00E4,0x00E3,0x00E5,0x00E7,0x00E9,0x00E8,
153  0x00EA,0x00EB,0x00ED,0x00EC,0x00EE,0x00EF,0x00F1,0x00F3,
154  0x00F2,0x00F4,0x00F6,0x00F5,0x00FA,0x00F9,0x00FB,0x00FC,
155  0x2020,0x00B0,0x00A2,0x00A3,0x00A7,0x2022,0x00B6,0x00DF,
156  0x00AE,0x00A9,0x2122,0x00B4,0x00A8,0x2260,0x00C6,0x00D8,
157  0x221E,0x00B1,0x2264,0x2265,0x00A5,0x00B5,0x2202,0x2211,
158  0x220F,0x03C0,0x222B,0x00AA,0x00BA,0x03A9,0x00E6,0x00F8,
159  0x00BF,0x00A1,0x00AC,0x221A,0x0192,0x2248,0x2206,0x00AB,
160  0x00BB,0x2026,0x00A0,0x00C0,0x00C3,0x00D5,0x0152,0x0153,
161  0x2013,0x2014,0x201C,0x201D,0x2018,0x2019,0x00F7,0x25CA,
162  0x00FF,0x0178,0x2044,0x20AC,0x2039,0x203A,0xFB01,0xFB02,
163  0x2021,0x00B7,0x201A,0x201E,0x2030,0x00C2,0x00CA,0x00C1,
164  0x00CB,0x00C8,0x00CD,0x00CE,0x00CF,0x00CC,0x00D3,0x00D4,
165  0xF8FF,0x00D2,0x00DA,0x00DB,0x00D9,0x0131,0x02C6,0x02DC,
166  0x00AF,0x02D8,0x02D9,0x02DA,0x00B8,0x02DD,0x02DB,0x02C7,
167 };
168 
170  char *dst, int dstlen)
171 {
172  char *p = dst;
173  char *end = dst+dstlen-1;
174  int i;
175 
176  for (i = 0; i < len; i++) {
177  uint8_t t, c = avio_r8(pb);
178 
179  if (p >= end)
180  continue;
181 
182  if (c < 0x80)
183  *p++ = c;
184  else if (p < end)
185  PUT_UTF8(mac_to_unicode[c-0x80], t, if (p < end) *p++ = t;);
186  }
187  *p = 0;
188  return p - dst;
189 }
190 
191 /**
192  * Get the requested item.
193  */
194 static HEIFItem *get_heif_item(MOVContext *c, unsigned id)
195 {
196  HEIFItem *item = NULL;
197 
198  for (int i = 0; i < c->nb_heif_item; i++) {
199  if (!c->heif_item[i] || c->heif_item[i]->item_id != id)
200  continue;
201 
202  item = c->heif_item[i];
203  break;
204  }
205 
206  return item;
207 }
208 
209 /**
210  * Get the current stream in the parsing process. This can either be the
211  * latest stream added to the context, or the stream referenced by an item.
212  */
214 {
215  AVStream *st = NULL;
216  HEIFItem *item;
217 
218  if (c->fc->nb_streams < 1)
219  return NULL;
220 
221  if (c->cur_item_id == -1)
222  return c->fc->streams[c->fc->nb_streams-1];
223 
224  item = get_heif_item(c, c->cur_item_id);
225  if (item)
226  st = item->st;
227 
228  return st;
229 }
230 
231 static int mov_read_covr(MOVContext *c, AVIOContext *pb, int type, int len)
232 {
233  AVStream *st;
234  MOVStreamContext *sc;
235  enum AVCodecID id;
236  int ret;
237 
238  switch (type) {
239  case 0xd: id = AV_CODEC_ID_MJPEG; break;
240  case 0xe: id = AV_CODEC_ID_PNG; break;
241  case 0x1b: id = AV_CODEC_ID_BMP; break;
242  default:
243  av_log(c->fc, AV_LOG_WARNING, "Unknown cover type: 0x%x.\n", type);
244  avio_skip(pb, len);
245  return 0;
246  }
247 
248  sc = av_mallocz(sizeof(*sc));
249  if (!sc)
250  return AVERROR(ENOMEM);
251  ret = ff_add_attached_pic(c->fc, NULL, pb, NULL, len);
252  if (ret < 0) {
253  av_free(sc);
254  return ret;
255  }
256  st = c->fc->streams[c->fc->nb_streams - 1];
257  st->priv_data = sc;
258  sc->id = st->id;
259  sc->refcount = 1;
260 
261  if (st->attached_pic.size >= 8 && id != AV_CODEC_ID_BMP) {
262  if (AV_RB64(st->attached_pic.data) == 0x89504e470d0a1a0a) {
263  id = AV_CODEC_ID_PNG;
264  } else {
265  id = AV_CODEC_ID_MJPEG;
266  }
267  }
268  st->codecpar->codec_id = id;
269 
270  return 0;
271 }
272 
273 // 3GPP TS 26.244
274 static int mov_metadata_loci(MOVContext *c, AVIOContext *pb, unsigned len)
275 {
276  char language[4] = { 0 };
277  char buf[200], place[100];
278  uint16_t langcode = 0;
279  double longitude, latitude, altitude;
280  const char *key = "location";
281 
282  if (len < 4 + 2 + 1 + 1 + 4 + 4 + 4) {
283  av_log(c->fc, AV_LOG_ERROR, "loci too short\n");
284  return AVERROR_INVALIDDATA;
285  }
286 
287  avio_skip(pb, 4); // version+flags
288  langcode = avio_rb16(pb);
289  ff_mov_lang_to_iso639(langcode, language);
290  len -= 6;
291 
292  len -= avio_get_str(pb, len, place, sizeof(place));
293  if (len < 1) {
294  av_log(c->fc, AV_LOG_ERROR, "place name too long\n");
295  return AVERROR_INVALIDDATA;
296  }
297  avio_skip(pb, 1); // role
298  len -= 1;
299 
300  if (len < 12) {
301  av_log(c->fc, AV_LOG_ERROR,
302  "loci too short (%u bytes left, need at least %d)\n", len, 12);
303  return AVERROR_INVALIDDATA;
304  }
305  longitude = ((int32_t) avio_rb32(pb)) / (float) (1 << 16);
306  latitude = ((int32_t) avio_rb32(pb)) / (float) (1 << 16);
307  altitude = ((int32_t) avio_rb32(pb)) / (float) (1 << 16);
308 
309  // Try to output in the same format as the ?xyz field
310  snprintf(buf, sizeof(buf), "%+08.4f%+09.4f", latitude, longitude);
311  if (altitude)
312  av_strlcatf(buf, sizeof(buf), "%+f", altitude);
313  av_strlcatf(buf, sizeof(buf), "/%s", place);
314 
315  if (*language && strcmp(language, "und")) {
316  char key2[16];
317  snprintf(key2, sizeof(key2), "%s-%s", key, language);
318  av_dict_set(&c->fc->metadata, key2, buf, 0);
319  }
320  c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
321  return av_dict_set(&c->fc->metadata, key, buf, 0);
322 }
323 
324 static int mov_metadata_hmmt(MOVContext *c, AVIOContext *pb, unsigned len)
325 {
326  int i, n_hmmt;
327 
328  if (len < 2)
329  return 0;
330  if (c->ignore_chapters)
331  return 0;
332 
333  n_hmmt = avio_rb32(pb);
334  if (n_hmmt > len / 4)
335  return AVERROR_INVALIDDATA;
336  for (i = 0; i < n_hmmt && !pb->eof_reached; i++) {
337  int moment_time = avio_rb32(pb);
338  avpriv_new_chapter(c->fc, i, av_make_q(1, 1000), moment_time, AV_NOPTS_VALUE, NULL);
339  }
340  if (avio_feof(pb))
341  return AVERROR_INVALIDDATA;
342  return 0;
343 }
344 
346 {
347  char tmp_key[AV_FOURCC_MAX_STRING_SIZE] = {0};
348  char key2[32], language[4] = {0};
349  char *str = NULL;
350  const char *key = NULL;
351  uint16_t langcode = 0;
352  uint32_t data_type = 0, str_size_alloc;
353  uint64_t str_size;
354  int (*parse)(MOVContext*, AVIOContext*, unsigned, const char*) = NULL;
355  int raw = 0;
356  int num = 0;
358 
359  if (c->trak_index >= 0 && c->trak_index < c->fc->nb_streams)
360  metadata = &c->fc->streams[c->trak_index]->metadata;
361  else
362  metadata = &c->fc->metadata;
363 
364  switch (atom.type) {
365  case MKTAG( '@','P','R','M'): key = "premiere_version"; raw = 1; break;
366  case MKTAG( '@','P','R','Q'): key = "quicktime_version"; raw = 1; break;
367  case MKTAG( 'X','M','P','_'):
368  if (c->export_xmp) { key = "xmp"; raw = 1; } break;
369  case MKTAG( 'a','A','R','T'): key = "album_artist"; break;
370  case MKTAG( 'a','k','I','D'): key = "account_type";
372  case MKTAG( 'a','p','I','D'): key = "account_id"; break;
373  case MKTAG( 'c','a','t','g'): key = "category"; break;
374  case MKTAG( 'c','p','i','l'): key = "compilation";
376  case MKTAG( 'c','p','r','t'): key = "copyright"; break;
377  case MKTAG( 'd','e','s','c'): key = "description"; break;
378  case MKTAG( 'd','i','s','k'): key = "disc";
380  case MKTAG( 'e','g','i','d'): key = "episode_uid";
382  case MKTAG( 'F','I','R','M'): key = "firmware"; raw = 1; break;
383  case MKTAG( 'g','n','r','e'): key = "genre";
384  parse = mov_metadata_gnre; break;
385  case MKTAG( 'h','d','v','d'): key = "hd_video";
387  case MKTAG( 'H','M','M','T'):
388  return mov_metadata_hmmt(c, pb, atom.size);
389  case MKTAG( 'k','e','y','w'): key = "keywords"; break;
390  case MKTAG( 'l','d','e','s'): key = "synopsis"; break;
391  case MKTAG( 'l','o','c','i'):
392  return mov_metadata_loci(c, pb, atom.size);
393  case MKTAG( 'm','a','n','u'): key = "make"; break;
394  case MKTAG( 'm','o','d','l'): key = "model"; break;
395  case MKTAG( 'n','a','m','e'): key = "name"; break;
396  case MKTAG( 'p','c','s','t'): key = "podcast";
398  case MKTAG( 'p','g','a','p'): key = "gapless_playback";
400  case MKTAG( 'p','u','r','d'): key = "purchase_date"; break;
401  case MKTAG( 'r','t','n','g'): key = "rating";
403  case MKTAG( 's','o','a','a'): key = "sort_album_artist"; break;
404  case MKTAG( 's','o','a','l'): key = "sort_album"; break;
405  case MKTAG( 's','o','a','r'): key = "sort_artist"; break;
406  case MKTAG( 's','o','c','o'): key = "sort_composer"; break;
407  case MKTAG( 's','o','n','m'): key = "sort_name"; break;
408  case MKTAG( 's','o','s','n'): key = "sort_show"; break;
409  case MKTAG( 's','t','i','k'): key = "media_type";
411  case MKTAG( 't','r','k','n'): key = "track";
413  case MKTAG( 't','v','e','n'): key = "episode_id"; break;
414  case MKTAG( 't','v','e','s'): key = "episode_sort";
416  case MKTAG( 't','v','n','n'): key = "network"; break;
417  case MKTAG( 't','v','s','h'): key = "show"; break;
418  case MKTAG( 't','v','s','n'): key = "season_number";
420  case MKTAG(0xa9,'A','R','T'): key = "artist"; break;
421  case MKTAG(0xa9,'P','R','D'): key = "producer"; break;
422  case MKTAG(0xa9,'a','l','b'): key = "album"; break;
423  case MKTAG(0xa9,'a','u','t'): key = "artist"; break;
424  case MKTAG(0xa9,'c','h','p'): key = "chapter"; break;
425  case MKTAG(0xa9,'c','m','t'): key = "comment"; break;
426  case MKTAG(0xa9,'c','o','m'): key = "composer"; break;
427  case MKTAG(0xa9,'c','p','y'): key = "copyright"; break;
428  case MKTAG(0xa9,'d','a','y'): key = "date"; break;
429  case MKTAG(0xa9,'d','i','r'): key = "director"; break;
430  case MKTAG(0xa9,'d','i','s'): key = "disclaimer"; break;
431  case MKTAG(0xa9,'e','d','1'): key = "edit_date"; break;
432  case MKTAG(0xa9,'e','n','c'): key = "encoder"; break;
433  case MKTAG(0xa9,'f','m','t'): key = "original_format"; break;
434  case MKTAG(0xa9,'g','e','n'): key = "genre"; break;
435  case MKTAG(0xa9,'g','r','p'): key = "grouping"; break;
436  case MKTAG(0xa9,'h','s','t'): key = "host_computer"; break;
437  case MKTAG(0xa9,'i','n','f'): key = "comment"; break;
438  case MKTAG(0xa9,'l','y','r'): key = "lyrics"; break;
439  case MKTAG(0xa9,'m','a','k'): key = "make"; break;
440  case MKTAG(0xa9,'m','o','d'): key = "model"; break;
441  case MKTAG(0xa9,'n','a','m'): key = "title"; break;
442  case MKTAG(0xa9,'o','p','e'): key = "original_artist"; break;
443  case MKTAG(0xa9,'p','r','d'): key = "producer"; break;
444  case MKTAG(0xa9,'p','r','f'): key = "performers"; break;
445  case MKTAG(0xa9,'r','e','q'): key = "playback_requirements"; break;
446  case MKTAG(0xa9,'s','r','c'): key = "original_source"; break;
447  case MKTAG(0xa9,'s','t','3'): key = "subtitle"; break;
448  case MKTAG(0xa9,'s','w','r'): key = "encoder"; break;
449  case MKTAG(0xa9,'t','o','o'): key = "encoder"; break;
450  case MKTAG(0xa9,'t','r','k'): key = "track"; break;
451  case MKTAG(0xa9,'u','r','l'): key = "URL"; break;
452  case MKTAG(0xa9,'w','r','n'): key = "warning"; break;
453  case MKTAG(0xa9,'w','r','t'): key = "composer"; break;
454  case MKTAG(0xa9,'x','y','z'): key = "location"; break;
455  }
456 retry:
457  if (c->itunes_metadata && atom.size > 8) {
458  int data_size = avio_rb32(pb);
459  int tag = avio_rl32(pb);
460  if (tag == MKTAG('d','a','t','a') && data_size <= atom.size && data_size >= 16) {
461  data_type = avio_rb32(pb); // type
462  avio_rb32(pb); // unknown
463  str_size = data_size - 16;
464  atom.size -= 16;
465 
466  if (!key && c->found_hdlr_mdta && c->meta_keys) {
467  uint32_t index = av_bswap32(atom.type); // BE number has been read as LE
468  if (index < c->meta_keys_count && index > 0) {
469  key = c->meta_keys[index];
470  } else if (atom.type != MKTAG('c', 'o', 'v', 'r')) {
471  av_log(c->fc, AV_LOG_WARNING,
472  "The index of 'data' is out of range: %"PRId32" < 1 or >= %d.\n",
473  index, c->meta_keys_count);
474  }
475  }
476  if (atom.type == MKTAG('c', 'o', 'v', 'r') ||
477  (key && !strcmp(key, "com.apple.quicktime.artwork"))) {
478  int ret = mov_read_covr(c, pb, data_type, str_size);
479  if (ret < 0) {
480  av_log(c->fc, AV_LOG_ERROR, "Error parsing cover art.\n");
481  return ret;
482  }
483  atom.size -= str_size;
484  if (atom.size > 8)
485  goto retry;
486  return ret;
487  }
488  } else return 0;
489  } else if (atom.size > 4 && (key || c->export_all) && !c->itunes_metadata && !raw) {
490  str_size = avio_rb16(pb); // string length
491  if (str_size > atom.size) {
492  raw = 1;
493  avio_seek(pb, -2, SEEK_CUR);
494  av_log(c->fc, AV_LOG_WARNING, "UDTA parsing failed retrying raw\n");
495  goto retry;
496  }
497  langcode = avio_rb16(pb);
498  ff_mov_lang_to_iso639(langcode, language);
499  atom.size -= 4;
500  } else
501  str_size = atom.size;
502 
503  if (c->export_all && !key) {
504  key = av_fourcc_make_string(tmp_key, atom.type);
505  }
506 
507  if (!key)
508  return 0;
509  if (atom.size < 0 || str_size >= INT_MAX/2)
510  return AVERROR_INVALIDDATA;
511 
512  // Allocates enough space if data_type is a int32 or float32 number, otherwise
513  // worst-case requirement for output string in case of utf8 coded input
514  num = (data_type >= 21 && data_type <= 23);
515  str_size_alloc = (num ? 512 : (raw ? str_size : str_size * 2)) + 1;
516  str = av_mallocz(str_size_alloc);
517  if (!str)
518  return AVERROR(ENOMEM);
519 
520  if (parse)
521  parse(c, pb, str_size, key);
522  else {
523  if (!raw && (data_type == 3 || (data_type == 0 && (langcode < 0x400 || langcode == 0x7fff)))) { // MAC Encoded
524  mov_read_mac_string(c, pb, str_size, str, str_size_alloc);
525  } else if (data_type == 21) { // BE signed integer, variable size
526  int val = 0;
527  if (str_size == 1)
528  val = (int8_t)avio_r8(pb);
529  else if (str_size == 2)
530  val = (int16_t)avio_rb16(pb);
531  else if (str_size == 3)
532  val = ((int32_t)(avio_rb24(pb)<<8))>>8;
533  else if (str_size == 4)
534  val = (int32_t)avio_rb32(pb);
535  if (snprintf(str, str_size_alloc, "%d", val) >= str_size_alloc) {
536  av_log(c->fc, AV_LOG_ERROR,
537  "Failed to store the number (%d) in string.\n", val);
538  av_free(str);
539  return AVERROR_INVALIDDATA;
540  }
541  } else if (data_type == 22) { // BE unsigned integer, variable size
542  unsigned int val = 0;
543  if (str_size == 1)
544  val = avio_r8(pb);
545  else if (str_size == 2)
546  val = avio_rb16(pb);
547  else if (str_size == 3)
548  val = avio_rb24(pb);
549  else if (str_size == 4)
550  val = avio_rb32(pb);
551  if (snprintf(str, str_size_alloc, "%u", val) >= str_size_alloc) {
552  av_log(c->fc, AV_LOG_ERROR,
553  "Failed to store the number (%u) in string.\n", val);
554  av_free(str);
555  return AVERROR_INVALIDDATA;
556  }
557  } else if (data_type == 23 && str_size >= 4) { // BE float32
558  float val = av_int2float(avio_rb32(pb));
559  if (snprintf(str, str_size_alloc, "%f", val) >= str_size_alloc) {
560  av_log(c->fc, AV_LOG_ERROR,
561  "Failed to store the float32 number (%f) in string.\n", val);
562  av_free(str);
563  return AVERROR_INVALIDDATA;
564  }
565  } else if (data_type > 1 && data_type != 4) {
566  // data_type can be 0 if not set at all above. data_type 1 means
567  // UTF8 and 4 means "UTF8 sort". For any other type (UTF16 or e.g.
568  // a picture), don't return it blindly in a string that is supposed
569  // to be UTF8 text.
570  av_log(c->fc, AV_LOG_WARNING, "Skipping unhandled metadata %s of type %d\n", key, data_type);
571  av_free(str);
572  return 0;
573  } else {
574  int ret = ffio_read_size(pb, str, str_size);
575  if (ret < 0) {
576  av_free(str);
577  return ret;
578  }
579  str[str_size] = 0;
580  }
581  c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
582  av_dict_set(metadata, key, str, 0);
583  if (*language && strcmp(language, "und")) {
584  snprintf(key2, sizeof(key2), "%s-%s", key, language);
585  av_dict_set(metadata, key2, str, 0);
586  }
587  if (!strcmp(key, "encoder")) {
588  int major, minor, micro;
589  if (sscanf(str, "HandBrake %d.%d.%d", &major, &minor, &micro) == 3) {
590  c->handbrake_version = 1000000*major + 1000*minor + micro;
591  }
592  }
593  }
594 
595  av_freep(&str);
596  return 0;
597 }
598 
600 {
601  int64_t start;
602  int i, nb_chapters, str_len, version;
603  char str[256+1];
604  int ret;
605 
606  if (c->ignore_chapters)
607  return 0;
608 
609  if ((atom.size -= 5) < 0)
610  return 0;
611 
612  version = avio_r8(pb);
613  avio_rb24(pb);
614  if (version)
615  avio_rb32(pb); // ???
616  nb_chapters = avio_r8(pb);
617 
618  for (i = 0; i < nb_chapters; i++) {
619  if (atom.size < 9)
620  return 0;
621 
622  start = avio_rb64(pb);
623  str_len = avio_r8(pb);
624 
625  if ((atom.size -= 9+str_len) < 0)
626  return 0;
627 
628  ret = ffio_read_size(pb, str, str_len);
629  if (ret < 0)
630  return ret;
631  str[str_len] = 0;
632  avpriv_new_chapter(c->fc, i, (AVRational){1,10000000}, start, AV_NOPTS_VALUE, str);
633  }
634  return 0;
635 }
636 
637 #define MIN_DATA_ENTRY_BOX_SIZE 12
639 {
640  AVStream *st;
641  MOVStreamContext *sc;
642  int entries, i, j;
643 
644  if (c->fc->nb_streams < 1)
645  return 0;
646  st = c->fc->streams[c->fc->nb_streams-1];
647  sc = st->priv_data;
648 
649  avio_rb32(pb); // version + flags
650  entries = avio_rb32(pb);
651  if (!entries ||
652  entries > (atom.size - 1) / MIN_DATA_ENTRY_BOX_SIZE + 1 ||
653  entries >= UINT_MAX / sizeof(*sc->drefs))
654  return AVERROR_INVALIDDATA;
655 
656  for (i = 0; i < sc->drefs_count; i++) {
657  MOVDref *dref = &sc->drefs[i];
658  av_freep(&dref->path);
659  av_freep(&dref->dir);
660  }
661  av_free(sc->drefs);
662  sc->drefs_count = 0;
663  sc->drefs = av_mallocz(entries * sizeof(*sc->drefs));
664  if (!sc->drefs)
665  return AVERROR(ENOMEM);
666  sc->drefs_count = entries;
667 
668  for (i = 0; i < entries; i++) {
669  MOVDref *dref = &sc->drefs[i];
670  uint32_t size = avio_rb32(pb);
671  int64_t next = avio_tell(pb);
672 
673  if (size < 12 || next < 0 || next > INT64_MAX - size)
674  return AVERROR_INVALIDDATA;
675 
676  next += size - 4;
677 
678  dref->type = avio_rl32(pb);
679  avio_rb32(pb); // version + flags
680 
681  if (dref->type == MKTAG('a','l','i','s') && size > 150) {
682  /* macintosh alias record */
683  uint16_t volume_len, len;
684  int16_t type;
685  int ret;
686 
687  avio_skip(pb, 10);
688 
689  volume_len = avio_r8(pb);
690  volume_len = FFMIN(volume_len, 27);
691  ret = ffio_read_size(pb, dref->volume, 27);
692  if (ret < 0)
693  return ret;
694  dref->volume[volume_len] = 0;
695  av_log(c->fc, AV_LOG_DEBUG, "volume %s, len %d\n", dref->volume, volume_len);
696 
697  avio_skip(pb, 12);
698 
699  len = avio_r8(pb);
700  len = FFMIN(len, 63);
701  ret = ffio_read_size(pb, dref->filename, 63);
702  if (ret < 0)
703  return ret;
704  dref->filename[len] = 0;
705  av_log(c->fc, AV_LOG_DEBUG, "filename %s, len %d\n", dref->filename, len);
706 
707  avio_skip(pb, 16);
708 
709  /* read next level up_from_alias/down_to_target */
710  dref->nlvl_from = avio_rb16(pb);
711  dref->nlvl_to = avio_rb16(pb);
712  av_log(c->fc, AV_LOG_DEBUG, "nlvl from %d, nlvl to %d\n",
713  dref->nlvl_from, dref->nlvl_to);
714 
715  avio_skip(pb, 16);
716 
717  for (type = 0; type != -1 && avio_tell(pb) < next; ) {
718  if (avio_feof(pb))
719  return AVERROR_EOF;
720  type = avio_rb16(pb);
721  len = avio_rb16(pb);
722  av_log(c->fc, AV_LOG_DEBUG, "type %d, len %d\n", type, len);
723  if (len&1)
724  len += 1;
725  if (type == 2) { // absolute path
726  av_free(dref->path);
727  dref->path = av_mallocz(len+1);
728  if (!dref->path)
729  return AVERROR(ENOMEM);
730 
731  ret = ffio_read_size(pb, dref->path, len);
732  if (ret < 0) {
733  av_freep(&dref->path);
734  return ret;
735  }
736  if (len > volume_len && !strncmp(dref->path, dref->volume, volume_len)) {
737  len -= volume_len;
738  memmove(dref->path, dref->path+volume_len, len);
739  dref->path[len] = 0;
740  }
741  // trim string of any ending zeros
742  for (j = len - 1; j >= 0; j--) {
743  if (dref->path[j] == 0)
744  len--;
745  else
746  break;
747  }
748  for (j = 0; j < len; j++)
749  if (dref->path[j] == ':' || dref->path[j] == 0)
750  dref->path[j] = '/';
751  av_log(c->fc, AV_LOG_DEBUG, "path %s\n", dref->path);
752  } else if (type == 0) { // directory name
753  av_free(dref->dir);
754  dref->dir = av_malloc(len+1);
755  if (!dref->dir)
756  return AVERROR(ENOMEM);
757 
758  ret = ffio_read_size(pb, dref->dir, len);
759  if (ret < 0) {
760  av_freep(&dref->dir);
761  return ret;
762  }
763  dref->dir[len] = 0;
764  for (j = 0; j < len; j++)
765  if (dref->dir[j] == ':')
766  dref->dir[j] = '/';
767  av_log(c->fc, AV_LOG_DEBUG, "dir %s\n", dref->dir);
768  } else
769  avio_skip(pb, len);
770  }
771  } else {
772  av_log(c->fc, AV_LOG_DEBUG, "Unknown dref type 0x%08"PRIx32" size %"PRIu32"\n",
773  dref->type, size);
774  entries--;
775  i--;
776  }
777  avio_seek(pb, next, SEEK_SET);
778  }
779  return 0;
780 }
781 
783 {
784  AVStream *st;
785  uint32_t type;
786  uint32_t ctype;
787  int64_t title_size;
788  char *title_str;
789  int ret;
790 
791  avio_r8(pb); /* version */
792  avio_rb24(pb); /* flags */
793 
794  /* component type */
795  ctype = avio_rl32(pb);
796  type = avio_rl32(pb); /* component subtype */
797 
798  av_log(c->fc, AV_LOG_TRACE, "ctype=%s\n", av_fourcc2str(ctype));
799  av_log(c->fc, AV_LOG_TRACE, "stype=%s\n", av_fourcc2str(type));
800 
801  if (c->trak_index < 0) { // meta not inside a trak
802  if (type == MKTAG('m','d','t','a')) {
803  c->found_hdlr_mdta = 1;
804  }
805  return 0;
806  }
807 
808  st = c->fc->streams[c->fc->nb_streams-1];
809 
810  if (type == MKTAG('v','i','d','e'))
812  else if (type == MKTAG('s','o','u','n'))
814  else if (type == MKTAG('m','1','a',' '))
816  else if ((type == MKTAG('s','u','b','p')) || (type == MKTAG('c','l','c','p')))
818 
819  avio_rb32(pb); /* component manufacture */
820  avio_rb32(pb); /* component flags */
821  avio_rb32(pb); /* component flags mask */
822 
823  title_size = atom.size - 24;
824  if (title_size > 0) {
825  if (title_size > FFMIN(INT_MAX, SIZE_MAX-1))
826  return AVERROR_INVALIDDATA;
827  title_str = av_malloc(title_size + 1); /* Add null terminator */
828  if (!title_str)
829  return AVERROR(ENOMEM);
830 
831  ret = ffio_read_size(pb, title_str, title_size);
832  if (ret < 0) {
833  av_freep(&title_str);
834  return ret;
835  }
836  title_str[title_size] = 0;
837  if (title_str[0]) {
838  int off = (!c->isom && title_str[0] == title_size - 1);
839  // flag added so as to not set stream handler name if already set from mdia->hdlr
840  av_dict_set(&st->metadata, "handler_name", title_str + off, AV_DICT_DONT_OVERWRITE);
841  }
842  av_freep(&title_str);
843  }
844 
845  return 0;
846 }
847 
849 {
850  return ff_mov_read_esds(c->fc, pb);
851 }
852 
854 {
855  AVStream *st;
856  AVPacketSideData *sd;
857  enum AVAudioServiceType *ast;
858  int ac3info, acmod, lfeon, bsmod;
859  uint64_t mask;
860 
861  if (c->fc->nb_streams < 1)
862  return 0;
863  st = c->fc->streams[c->fc->nb_streams-1];
864 
868  sizeof(*ast), 0);
869  if (!sd)
870  return AVERROR(ENOMEM);
871 
872  ast = (enum AVAudioServiceType*)sd->data;
873  ac3info = avio_rb24(pb);
874  bsmod = (ac3info >> 14) & 0x7;
875  acmod = (ac3info >> 11) & 0x7;
876  lfeon = (ac3info >> 10) & 0x1;
877 
879  if (lfeon)
883 
884  *ast = bsmod;
885  if (st->codecpar->ch_layout.nb_channels > 1 && bsmod == 0x7)
887 
888  return 0;
889 }
890 
891 #if CONFIG_IAMFDEC
892 static int mov_read_iacb(MOVContext *c, AVIOContext *pb, MOVAtom atom)
893 {
894  AVStream *st;
895  MOVStreamContext *sc;
896  FFIOContext b;
897  AVIOContext *descriptor_pb;
899  IAMFContext *iamf;
901  unsigned descriptors_size;
902  int nb_frames, disposition;
903  int version, ret;
904 
905  if (atom.size < 5)
906  return AVERROR_INVALIDDATA;
907 
908  if (c->fc->nb_streams < 1)
909  return 0;
910 
911  version = avio_r8(pb);
912  if (version != 1) {
913  av_log(c->fc, AV_LOG_ERROR, "%s configurationVersion %d",
914  version < 1 ? "invalid" : "unsupported", version);
915  return AVERROR_INVALIDDATA;
916  }
917 
918  descriptors_size = ffio_read_leb(pb);
919  if (!descriptors_size || descriptors_size > INT_MAX)
920  return AVERROR_INVALIDDATA;
921 
922  st = c->fc->streams[c->fc->nb_streams - 1];
923  sc = st->priv_data;
924 
925  if (st->codecpar->extradata) {
926  av_log(c->fc, AV_LOG_WARNING, "ignoring iacb\n");
927  return 0;
928  }
929 
930  sc->iamf = av_mallocz(sizeof(*sc->iamf));
931  if (!sc->iamf)
932  return AVERROR(ENOMEM);
933  iamf = &sc->iamf->iamf;
934 
935  st->codecpar->extradata = av_malloc(descriptors_size);
936  if (!st->codecpar->extradata)
937  return AVERROR(ENOMEM);
938  st->codecpar->extradata_size = descriptors_size;
939 
940  ret = avio_read(pb, st->codecpar->extradata, descriptors_size);
941  if (ret != descriptors_size)
942  return ret < 0 ? ret : AVERROR_INVALIDDATA;
943 
944  ffio_init_read_context(&b, st->codecpar->extradata, descriptors_size);
945  descriptor_pb = &b.pub;
946 
947  ret = ff_iamfdec_read_descriptors(iamf, descriptor_pb, descriptors_size, c->fc);
948  if (ret < 0)
949  return ret;
950 
951  metadata = st->metadata;
952  st->metadata = NULL;
953  start_time = st->start_time;
954  nb_frames = st->nb_frames;
955  duration = st->duration;
956  disposition = st->disposition;
957 
958  for (int i = 0; i < iamf->nb_audio_elements; i++) {
959  IAMFAudioElement *audio_element = iamf->audio_elements[i];
960  const AVIAMFAudioElement *element;
961  AVStreamGroup *stg =
963 
964  if (!stg) {
965  ret = AVERROR(ENOMEM);
966  goto fail;
967  }
968 
970  stg->id = audio_element->audio_element_id;
971  /* Transfer ownership */
972  element = stg->params.iamf_audio_element = audio_element->element;
973  audio_element->element = NULL;
974 
975  for (int j = 0; j < audio_element->nb_substreams; j++) {
976  IAMFSubStream *substream = &audio_element->substreams[j];
977  AVStream *stream;
978 
979  if (!i && !j) {
980  if (audio_element->layers[0].substream_count != 1)
981  disposition &= ~AV_DISPOSITION_DEFAULT;
982  stream = st;
983  } else
984  stream = avformat_new_stream(c->fc, NULL);
985  if (!stream) {
986  ret = AVERROR(ENOMEM);
987  goto fail;
988  }
989 
990  stream->start_time = start_time;
991  stream->nb_frames = nb_frames;
992  stream->duration = duration;
993  stream->disposition = disposition;
994  if (stream != st) {
995  stream->priv_data = sc;
996  sc->refcount++;
997  }
998 
1001  if (i || j) {
1003  if (audio_element->layers[0].substream_count == 1)
1004  stream->disposition &= ~AV_DISPOSITION_DEFAULT;
1005  }
1006 
1007  ret = avcodec_parameters_copy(stream->codecpar, substream->codecpar);
1008  if (ret < 0)
1009  goto fail;
1010 
1011  stream->id = substream->audio_substream_id;
1012 
1013  avpriv_set_pts_info(st, 64, 1, sc->time_scale);
1014 
1015  ret = avformat_stream_group_add_stream(stg, stream);
1016  if (ret < 0)
1017  goto fail;
1018  }
1019 
1020  ret = av_dict_copy(&stg->metadata, metadata, 0);
1021  if (ret < 0)
1022  goto fail;
1023  }
1024 
1025  for (int i = 0; i < iamf->nb_mix_presentations; i++) {
1026  IAMFMixPresentation *mix_presentation = iamf->mix_presentations[i];
1027  const AVIAMFMixPresentation *mix = mix_presentation->cmix;
1028  AVStreamGroup *stg =
1030 
1031  if (!stg) {
1032  ret = AVERROR(ENOMEM);
1033  goto fail;
1034  }
1035 
1037  stg->id = mix_presentation->mix_presentation_id;
1038  /* Transfer ownership */
1039  stg->params.iamf_mix_presentation = mix_presentation->mix;
1040  mix_presentation->mix = NULL;
1041 
1042  for (int j = 0; j < mix->nb_submixes; j++) {
1043  const AVIAMFSubmix *submix = mix->submixes[j];
1044 
1045  for (int k = 0; k < submix->nb_elements; k++) {
1046  const AVIAMFSubmixElement *submix_element = submix->elements[k];
1047  const AVStreamGroup *audio_element = NULL;
1048 
1049  for (int l = 0; l < c->fc->nb_stream_groups; l++)
1050  if (c->fc->stream_groups[l]->type == AV_STREAM_GROUP_PARAMS_IAMF_AUDIO_ELEMENT &&
1051  c->fc->stream_groups[l]->id == submix_element->audio_element_id) {
1052  audio_element = c->fc->stream_groups[l];
1053  break;
1054  }
1055  av_assert0(audio_element);
1056 
1057  for (int l = 0; l < audio_element->nb_streams; l++) {
1058  ret = avformat_stream_group_add_stream(stg, audio_element->streams[l]);
1059  if (ret < 0 && ret != AVERROR(EEXIST))
1060  goto fail;
1061  }
1062  }
1063  }
1064 
1065  ret = av_dict_copy(&stg->metadata, metadata, 0);
1066  if (ret < 0)
1067  goto fail;
1068  }
1069 
1070  ret = 0;
1071 fail:
1073 
1074  return ret;
1075 }
1076 #endif
1077 
1079 {
1080  AVStream *st;
1081  AVPacketSideData *sd;
1082  enum AVAudioServiceType *ast;
1083  int eac3info, acmod, lfeon, bsmod;
1084  uint64_t mask;
1085 
1086  if (c->fc->nb_streams < 1)
1087  return 0;
1088  st = c->fc->streams[c->fc->nb_streams-1];
1089 
1093  sizeof(*ast), 0);
1094  if (!sd)
1095  return AVERROR(ENOMEM);
1096 
1097  ast = (enum AVAudioServiceType*)sd->data;
1098 
1099  /* No need to parse fields for additional independent substreams and its
1100  * associated dependent substreams since libavcodec's E-AC-3 decoder
1101  * does not support them yet. */
1102  avio_rb16(pb); /* data_rate and num_ind_sub */
1103  eac3info = avio_rb24(pb);
1104  bsmod = (eac3info >> 12) & 0x1f;
1105  acmod = (eac3info >> 9) & 0x7;
1106  lfeon = (eac3info >> 8) & 0x1;
1107 
1109  if (lfeon)
1113 
1114  *ast = bsmod;
1115  if (st->codecpar->ch_layout.nb_channels > 1 && bsmod == 0x7)
1117 
1118  return 0;
1119 }
1120 
1122 {
1123 #define DDTS_SIZE 20
1124  uint8_t buf[DDTS_SIZE + AV_INPUT_BUFFER_PADDING_SIZE];
1125  AVStream *st = NULL;
1126  uint32_t frame_duration_code = 0;
1127  uint32_t channel_layout_code = 0;
1128  GetBitContext gb;
1129  int ret;
1130 
1131  if ((ret = ffio_read_size(pb, buf, DDTS_SIZE)) < 0)
1132  return ret;
1133 
1134  init_get_bits(&gb, buf, 8 * DDTS_SIZE);
1135 
1136  if (c->fc->nb_streams < 1) {
1137  return 0;
1138  }
1139  st = c->fc->streams[c->fc->nb_streams-1];
1140 
1141  st->codecpar->sample_rate = get_bits_long(&gb, 32);
1142  if (st->codecpar->sample_rate <= 0) {
1143  av_log(c->fc, AV_LOG_ERROR, "Invalid sample rate %d\n", st->codecpar->sample_rate);
1144  return AVERROR_INVALIDDATA;
1145  }
1146  skip_bits_long(&gb, 32); /* max bitrate */
1147  st->codecpar->bit_rate = get_bits_long(&gb, 32);
1148  st->codecpar->bits_per_coded_sample = get_bits(&gb, 8);
1149  frame_duration_code = get_bits(&gb, 2);
1150  skip_bits(&gb, 30); /* various fields */
1151  channel_layout_code = get_bits(&gb, 16);
1152 
1153  st->codecpar->frame_size =
1154  (frame_duration_code == 0) ? 512 :
1155  (frame_duration_code == 1) ? 1024 :
1156  (frame_duration_code == 2) ? 2048 :
1157  (frame_duration_code == 3) ? 4096 : 0;
1158 
1159  if (channel_layout_code > 0xff) {
1160  av_log(c->fc, AV_LOG_WARNING, "Unsupported DTS audio channel layout\n");
1161  }
1164  ((channel_layout_code & 0x1) ? AV_CH_FRONT_CENTER : 0) |
1165  ((channel_layout_code & 0x2) ? AV_CH_FRONT_LEFT : 0) |
1166  ((channel_layout_code & 0x2) ? AV_CH_FRONT_RIGHT : 0) |
1167  ((channel_layout_code & 0x4) ? AV_CH_SIDE_LEFT : 0) |
1168  ((channel_layout_code & 0x4) ? AV_CH_SIDE_RIGHT : 0) |
1169  ((channel_layout_code & 0x8) ? AV_CH_LOW_FREQUENCY : 0));
1170 
1171  return 0;
1172 }
1173 
1175 {
1176  AVStream *st;
1177 
1178  if (c->fc->nb_streams < 1)
1179  return 0;
1180  st = c->fc->streams[c->fc->nb_streams-1];
1181 
1182  if (atom.size < 16)
1183  return 0;
1184 
1185  /* skip version and flags */
1186  avio_skip(pb, 4);
1187 
1188  ff_mov_read_chan(c->fc, pb, st, atom.size - 4);
1189 
1190  return 0;
1191 }
1192 
1194 {
1195  int64_t end = av_sat_add64(avio_tell(pb), atom.size);
1196  int version, flags;
1197  int ret;
1198  AVStream *st;
1199 
1200  if (c->fc->nb_streams < 1)
1201  return 0;
1202  st = c->fc->streams[c->fc->nb_streams-1];
1203 
1204  version = avio_r8(pb);
1205  flags = avio_rb24(pb);
1206  if (version != 0 || flags != 0) {
1207  av_log(c->fc, AV_LOG_ERROR,
1208  "Unsupported 'chnl' box with version %d, flags: %#x",
1209  version, flags);
1210  return AVERROR_INVALIDDATA;
1211  }
1212 
1213  ret = ff_mov_read_chnl(c->fc, pb, st);
1214  if (ret < 0)
1215  return ret;
1216 
1217  if (avio_tell(pb) != end) {
1218  av_log(c->fc, AV_LOG_WARNING, "skip %" PRId64 " bytes of unknown data inside chnl\n",
1219  end - avio_tell(pb));
1220  avio_seek(pb, end, SEEK_SET);
1221  }
1222  return ret;
1223 }
1224 
1226 {
1227  AVStream *st;
1228  int ret;
1229 
1230  if (c->fc->nb_streams < 1)
1231  return 0;
1232  st = c->fc->streams[c->fc->nb_streams-1];
1233 
1234  if ((ret = ff_get_wav_header(c->fc, pb, st->codecpar, atom.size, 0)) < 0)
1235  av_log(c->fc, AV_LOG_WARNING, "get_wav_header failed\n");
1236 
1237  return ret;
1238 }
1239 
1241 {
1242  AVStream *st;
1243  HEIFItem *item;
1244  AVPacketSideData *sd;
1245  int width, height, err = 0;
1246  AVRational aperture_width, aperture_height, horiz_off, vert_off;
1247  AVRational pc_x, pc_y;
1248  uint64_t top, bottom, left, right;
1249 
1250  item = get_heif_item(c, c->cur_item_id);
1251  st = get_curr_st(c);
1252  if (!st)
1253  return 0;
1254 
1255  width = st->codecpar->width;
1256  height = st->codecpar->height;
1257  if ((!width || !height) && item) {
1258  width = item->width;
1259  height = item->height;
1260  }
1261  if (!width || !height) {
1262  err = AVERROR_INVALIDDATA;
1263  goto fail;
1264  }
1265 
1266  aperture_width.num = avio_rb32(pb);
1267  aperture_width.den = avio_rb32(pb);
1268  aperture_height.num = avio_rb32(pb);
1269  aperture_height.den = avio_rb32(pb);
1270 
1271  horiz_off.num = avio_rb32(pb);
1272  horiz_off.den = avio_rb32(pb);
1273  vert_off.num = avio_rb32(pb);
1274  vert_off.den = avio_rb32(pb);
1275 
1276  if (aperture_width.num < 0 || aperture_width.den < 0 ||
1277  aperture_height.num < 0 || aperture_height.den < 0 ||
1278  horiz_off.den < 0 || vert_off.den < 0) {
1279  err = AVERROR_INVALIDDATA;
1280  goto fail;
1281  }
1282  if ((av_cmp_q((AVRational) { width, 1 }, aperture_width) < 0) ||
1283  (av_cmp_q((AVRational) { height, 1 }, aperture_height) < 0)) {
1284  err = AVERROR_INVALIDDATA;
1285  goto fail;
1286  }
1287  av_log(c->fc, AV_LOG_TRACE, "clap: apertureWidth %d/%d, apertureHeight %d/%d "
1288  "horizOff %d/%d vertOff %d/%d\n",
1289  aperture_width.num, aperture_width.den, aperture_height.num, aperture_height.den,
1290  horiz_off.num, horiz_off.den, vert_off.num, vert_off.den);
1291 
1292  pc_x = av_mul_q((AVRational) { width - 1, 1 }, (AVRational) { 1, 2 });
1293  pc_x = av_add_q(pc_x, horiz_off);
1294  pc_y = av_mul_q((AVRational) { height - 1, 1 }, (AVRational) { 1, 2 });
1295  pc_y = av_add_q(pc_y, vert_off);
1296 
1297  aperture_width = av_sub_q(aperture_width, (AVRational) { 1, 1 });
1298  aperture_width = av_mul_q(aperture_width, (AVRational) { 1, 2 });
1299  aperture_height = av_sub_q(aperture_height, (AVRational) { 1, 1 });
1300  aperture_height = av_mul_q(aperture_height, (AVRational) { 1, 2 });
1301 
1302  left = av_q2d(av_sub_q(pc_x, aperture_width));
1303  right = av_q2d(av_add_q(pc_x, aperture_width));
1304  top = av_q2d(av_sub_q(pc_y, aperture_height));
1305  bottom = av_q2d(av_add_q(pc_y, aperture_height));
1306 
1307  if (bottom > (height - 1) ||
1308  right > (width - 1)) {
1309  err = AVERROR_INVALIDDATA;
1310  goto fail;
1311  }
1312 
1313  bottom = height - 1 - bottom;
1314  right = width - 1 - right;
1315 
1316  if (!(left | right | top | bottom))
1317  return 0;
1318 
1319  if ((left + right) >= width ||
1320  (top + bottom) >= height) {
1321  err = AVERROR_INVALIDDATA;
1322  goto fail;
1323  }
1324 
1328  sizeof(uint32_t) * 4, 0);
1329  if (!sd)
1330  return AVERROR(ENOMEM);
1331 
1332  AV_WL32A(sd->data, top);
1333  AV_WL32A(sd->data + 4, bottom);
1334  AV_WL32A(sd->data + 8, left);
1335  AV_WL32A(sd->data + 12, right);
1336 
1337 fail:
1338  if (err < 0) {
1339  int explode = !!(c->fc->error_recognition & AV_EF_EXPLODE);
1340  av_log(c->fc, explode ? AV_LOG_ERROR : AV_LOG_WARNING, "Invalid clap box\n");
1341  if (!explode)
1342  err = 0;
1343  }
1344 
1345  return err;
1346 }
1347 
1348 /* This atom overrides any previously set aspect ratio */
1350 {
1351  const int num = avio_rb32(pb);
1352  const int den = avio_rb32(pb);
1353  AVStream *st;
1354  MOVStreamContext *sc;
1355 
1356  if (c->fc->nb_streams < 1)
1357  return 0;
1358  st = c->fc->streams[c->fc->nb_streams-1];
1359  sc = st->priv_data;
1360 
1361  av_log(c->fc, AV_LOG_TRACE, "pasp: hSpacing %d, vSpacing %d\n", num, den);
1362 
1363  if (den != 0) {
1364  sc->h_spacing = num;
1365  sc->v_spacing = den;
1366  }
1367  return 0;
1368 }
1369 
1370 /* this atom contains actual media data */
1372 {
1373  if (atom.size == 0) /* wrong one (MP4) */
1374  return 0;
1375  c->found_mdat=1;
1376  return 0; /* now go for moov */
1377 }
1378 
1379 #define DRM_BLOB_SIZE 56
1380 
1382 {
1383  uint8_t intermediate_key[20];
1384  uint8_t intermediate_iv[20];
1385  uint8_t input[64];
1386  uint8_t output[64];
1387  uint8_t file_checksum[20];
1388  uint8_t calculated_checksum[20];
1389  char checksum_string[2 * sizeof(file_checksum) + 1];
1390  struct AVSHA *sha;
1391  int i;
1392  int ret = 0;
1393  uint8_t *activation_bytes = c->activation_bytes;
1394  uint8_t *fixed_key = c->audible_fixed_key;
1395 
1396  c->aax_mode = 1;
1397 
1398  sha = av_sha_alloc();
1399  if (!sha)
1400  return AVERROR(ENOMEM);
1401  av_free(c->aes_decrypt);
1402  c->aes_decrypt = av_aes_alloc();
1403  if (!c->aes_decrypt) {
1404  ret = AVERROR(ENOMEM);
1405  goto fail;
1406  }
1407 
1408  /* drm blob processing */
1409  avio_read(pb, output, 8); // go to offset 8, absolute position 0x251
1411  avio_read(pb, output, 4); // go to offset 4, absolute position 0x28d
1412  ret = ffio_read_size(pb, file_checksum, 20);
1413  if (ret < 0)
1414  goto fail;
1415 
1416  // required by external tools
1417  ff_data_to_hex(checksum_string, file_checksum, sizeof(file_checksum), 1);
1418  av_log(c->fc, AV_LOG_INFO, "[aax] file checksum == %s\n", checksum_string);
1419 
1420  /* verify activation data */
1421  if (!activation_bytes) {
1422  av_log(c->fc, AV_LOG_WARNING, "[aax] activation_bytes option is missing!\n");
1423  ret = 0; /* allow ffprobe to continue working on .aax files */
1424  goto fail;
1425  }
1426  if (c->activation_bytes_size != 4) {
1427  av_log(c->fc, AV_LOG_FATAL, "[aax] activation_bytes value needs to be 4 bytes!\n");
1428  ret = AVERROR(EINVAL);
1429  goto fail;
1430  }
1431 
1432  /* verify fixed key */
1433  if (c->audible_fixed_key_size != 16) {
1434  av_log(c->fc, AV_LOG_FATAL, "[aax] audible_fixed_key value needs to be 16 bytes!\n");
1435  ret = AVERROR(EINVAL);
1436  goto fail;
1437  }
1438 
1439  /* AAX (and AAX+) key derivation */
1440  av_sha_init(sha, 160);
1441  av_sha_update(sha, fixed_key, 16);
1442  av_sha_update(sha, activation_bytes, 4);
1443  av_sha_final(sha, intermediate_key);
1444  av_sha_init(sha, 160);
1445  av_sha_update(sha, fixed_key, 16);
1446  av_sha_update(sha, intermediate_key, 20);
1447  av_sha_update(sha, activation_bytes, 4);
1448  av_sha_final(sha, intermediate_iv);
1449  av_sha_init(sha, 160);
1450  av_sha_update(sha, intermediate_key, 16);
1451  av_sha_update(sha, intermediate_iv, 16);
1452  av_sha_final(sha, calculated_checksum);
1453  if (memcmp(calculated_checksum, file_checksum, 20)) { // critical error
1454  av_log(c->fc, AV_LOG_ERROR, "[aax] mismatch in checksums!\n");
1456  goto fail;
1457  }
1458  av_aes_init(c->aes_decrypt, intermediate_key, 128, 1);
1459  av_aes_crypt(c->aes_decrypt, output, input, DRM_BLOB_SIZE >> 4, intermediate_iv, 1);
1460  for (i = 0; i < 4; i++) {
1461  // file data (in output) is stored in big-endian mode
1462  if (activation_bytes[i] != output[3 - i]) { // critical error
1463  av_log(c->fc, AV_LOG_ERROR, "[aax] error in drm blob decryption!\n");
1465  goto fail;
1466  }
1467  }
1468  memcpy(c->file_key, output + 8, 16);
1469  memcpy(input, output + 26, 16);
1470  av_sha_init(sha, 160);
1471  av_sha_update(sha, input, 16);
1472  av_sha_update(sha, c->file_key, 16);
1473  av_sha_update(sha, fixed_key, 16);
1474  av_sha_final(sha, c->file_iv);
1475 
1476 fail:
1477  av_free(sha);
1478 
1479  return ret;
1480 }
1481 
1483 {
1484  if (c->audible_key_size != 16) {
1485  av_log(c->fc, AV_LOG_FATAL, "[aaxc] audible_key value needs to be 16 bytes!\n");
1486  return AVERROR(EINVAL);
1487  }
1488 
1489  if (c->audible_iv_size != 16) {
1490  av_log(c->fc, AV_LOG_FATAL, "[aaxc] audible_iv value needs to be 16 bytes!\n");
1491  return AVERROR(EINVAL);
1492  }
1493 
1494  c->aes_decrypt = av_aes_alloc();
1495  if (!c->aes_decrypt) {
1496  return AVERROR(ENOMEM);
1497  }
1498 
1499  memcpy(c->file_key, c->audible_key, 16);
1500  memcpy(c->file_iv, c->audible_iv, 16);
1501  c->aax_mode = 1;
1502 
1503  return 0;
1504 }
1505 
1506 // Audible AAX (and AAX+) bytestream decryption
1507 static int aax_filter(uint8_t *input, int size, MOVContext *c)
1508 {
1509  int blocks = 0;
1510  unsigned char iv[16];
1511 
1512  memcpy(iv, c->file_iv, 16); // iv is overwritten
1513  blocks = size >> 4; // trailing bytes are not encrypted!
1514  av_aes_init(c->aes_decrypt, c->file_key, 128, 1);
1515  av_aes_crypt(c->aes_decrypt, input, input, blocks, iv, 1);
1516 
1517  return 0;
1518 }
1519 
1520 /* read major brand, minor version and compatible brands and store them as metadata */
1522 {
1523  uint32_t minor_ver;
1524  int comp_brand_size;
1525  char* comp_brands_str;
1526  uint8_t type[5] = {0};
1527  int ret = ffio_read_size(pb, type, 4);
1528  if (ret < 0)
1529  return ret;
1530  if (c->fc->nb_streams) {
1531  if (c->fc->strict_std_compliance >= FF_COMPLIANCE_STRICT)
1532  return AVERROR_INVALIDDATA;
1533  av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate FTYP\n");
1534  return 0;
1535  }
1536 
1537  if (strcmp(type, "qt "))
1538  c->isom = 1;
1539  av_log(c->fc, AV_LOG_DEBUG, "ISO: File Type Major Brand: %.4s\n",(char *)&type);
1540  av_dict_set(&c->fc->metadata, "major_brand", type, 0);
1541  minor_ver = avio_rb32(pb); /* minor version */
1542  av_dict_set_int(&c->fc->metadata, "minor_version", minor_ver, 0);
1543 
1544  comp_brand_size = atom.size - 8;
1545  if (comp_brand_size < 0 || comp_brand_size == INT_MAX)
1546  return AVERROR_INVALIDDATA;
1547  comp_brands_str = av_malloc(comp_brand_size + 1); /* Add null terminator */
1548  if (!comp_brands_str)
1549  return AVERROR(ENOMEM);
1550 
1551  ret = ffio_read_size(pb, comp_brands_str, comp_brand_size);
1552  if (ret < 0) {
1553  av_freep(&comp_brands_str);
1554  return ret;
1555  }
1556  comp_brands_str[comp_brand_size] = 0;
1557  av_dict_set(&c->fc->metadata, "compatible_brands",
1558  comp_brands_str, AV_DICT_DONT_STRDUP_VAL);
1559 
1560  // Logic for handling Audible's .aaxc files
1561  if (!strcmp(type, "aaxc")) {
1562  mov_aaxc_crypto(c);
1563  }
1564 
1565  return 0;
1566 }
1567 
1568 /* this atom should contain all header atoms */
1570 {
1571  int ret;
1572 
1573  if (c->found_moov) {
1574  av_log(c->fc, AV_LOG_WARNING, "Found duplicated MOOV Atom. Skipped it\n");
1575  avio_skip(pb, atom.size);
1576  return 0;
1577  }
1578 
1579  if ((ret = mov_read_default(c, pb, atom)) < 0)
1580  return ret;
1581  /* we parsed the 'moov' atom, we can terminate the parsing as soon as we find the 'mdat' */
1582  /* so we don't parse the whole file if over a network */
1583  c->found_moov=1;
1584  return 0; /* now go for mdat */
1585 }
1586 
1588  MOVFragmentIndex *frag_index,
1589  int index,
1590  int id)
1591 {
1592  int i;
1593  MOVFragmentIndexItem * item;
1594 
1595  if (index < 0 || index >= frag_index->nb_items)
1596  return NULL;
1597  item = &frag_index->item[index];
1598  for (i = 0; i < item->nb_stream_info; i++)
1599  if (item->stream_info[i].id == id)
1600  return &item->stream_info[i];
1601 
1602  // This shouldn't happen
1603  return NULL;
1604 }
1605 
1606 static void set_frag_stream(MOVFragmentIndex *frag_index, int id)
1607 {
1608  int i;
1609  MOVFragmentIndexItem * item;
1610 
1611  if (frag_index->current < 0 ||
1612  frag_index->current >= frag_index->nb_items)
1613  return;
1614 
1615  item = &frag_index->item[frag_index->current];
1616  for (i = 0; i < item->nb_stream_info; i++)
1617  if (item->stream_info[i].id == id) {
1618  item->current = i;
1619  return;
1620  }
1621 
1622  // id not found. This shouldn't happen.
1623  item->current = -1;
1624 }
1625 
1627  MOVFragmentIndex *frag_index)
1628 {
1629  MOVFragmentIndexItem *item;
1630  if (frag_index->current < 0 ||
1631  frag_index->current >= frag_index->nb_items)
1632  return NULL;
1633 
1634  item = &frag_index->item[frag_index->current];
1635  if (item->current >= 0 && item->current < item->nb_stream_info)
1636  return &item->stream_info[item->current];
1637 
1638  // This shouldn't happen
1639  return NULL;
1640 }
1641 
1643 {
1644  int a, b, m;
1645  int64_t moof_offset;
1646 
1647  // Optimize for appending new entries
1648  if (!frag_index->nb_items ||
1649  frag_index->item[frag_index->nb_items - 1].moof_offset < offset)
1650  return frag_index->nb_items;
1651 
1652  a = -1;
1653  b = frag_index->nb_items;
1654 
1655  while (b - a > 1) {
1656  m = (a + b) >> 1;
1657  moof_offset = frag_index->item[m].moof_offset;
1658  if (moof_offset >= offset)
1659  b = m;
1660  if (moof_offset <= offset)
1661  a = m;
1662  }
1663  return b;
1664 }
1665 
1667 {
1668  av_assert0(frag_stream_info);
1669  if (frag_stream_info->sidx_pts != AV_NOPTS_VALUE)
1670  return frag_stream_info->sidx_pts;
1671  if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE)
1672  return frag_stream_info->first_tfra_pts;
1673  return frag_stream_info->tfdt_dts;
1674 }
1675 
1677  MOVFragmentIndex *frag_index, int index)
1678 {
1679  MOVFragmentStreamInfo * frag_stream_info;
1680  MOVStreamContext *sc = dst_st->priv_data;
1681  int64_t timestamp;
1682  int i, j;
1683 
1684  // If the stream is referenced by any sidx, limit the search
1685  // to fragments that referenced this stream in the sidx
1686  if (sc->has_sidx) {
1687  frag_stream_info = get_frag_stream_info(frag_index, index, sc->id);
1688  if (!frag_stream_info)
1689  return AV_NOPTS_VALUE;
1690  if (frag_stream_info->sidx_pts != AV_NOPTS_VALUE)
1691  return frag_stream_info->sidx_pts;
1692  if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE)
1693  return frag_stream_info->first_tfra_pts;
1694  return frag_stream_info->sidx_pts;
1695  }
1696 
1697  for (i = 0; i < frag_index->item[index].nb_stream_info; i++) {
1698  AVStream *frag_stream = NULL;
1699  frag_stream_info = &frag_index->item[index].stream_info[i];
1700  for (j = 0; j < s->nb_streams; j++) {
1701  MOVStreamContext *sc2 = s->streams[j]->priv_data;
1702  if (sc2->id == frag_stream_info->id)
1703  frag_stream = s->streams[j];
1704  }
1705  if (!frag_stream) {
1706  av_log(s, AV_LOG_WARNING, "No stream matching sidx ID found.\n");
1707  continue;
1708  }
1709  timestamp = get_stream_info_time(frag_stream_info);
1710  if (timestamp != AV_NOPTS_VALUE)
1711  return av_rescale_q(timestamp, frag_stream->time_base, dst_st->time_base);
1712  }
1713  return AV_NOPTS_VALUE;
1714 }
1715 
1717  AVStream *st, int64_t timestamp)
1718 {
1719  int a, b, m, m0;
1720  int64_t frag_time;
1721 
1722  a = -1;
1723  b = frag_index->nb_items;
1724 
1725  while (b - a > 1) {
1726  m0 = m = (a + b) >> 1;
1727 
1728  while (m < b &&
1729  (frag_time = get_frag_time(s, st, frag_index, m)) == AV_NOPTS_VALUE)
1730  m++;
1731 
1732  if (m < b && frag_time <= timestamp)
1733  a = m;
1734  else
1735  b = m0;
1736  }
1737 
1738  return a;
1739 }
1740 
1742 {
1743  int index, i;
1744  MOVFragmentIndexItem * item;
1745  MOVFragmentStreamInfo * frag_stream_info;
1746 
1747  // If moof_offset already exists in frag_index, return index to it
1748  index = search_frag_moof_offset(&c->frag_index, offset);
1749  if (index < c->frag_index.nb_items &&
1750  c->frag_index.item[index].moof_offset == offset)
1751  return index;
1752 
1753  // offset is not yet in frag index.
1754  // Insert new item at index (sorted by moof offset)
1755  item = av_fast_realloc(c->frag_index.item,
1756  &c->frag_index.allocated_size,
1757  (c->frag_index.nb_items + 1) *
1758  sizeof(*c->frag_index.item));
1759  if (!item)
1760  return -1;
1761  c->frag_index.item = item;
1762 
1763  frag_stream_info = av_realloc_array(NULL, c->fc->nb_streams,
1764  sizeof(*item->stream_info));
1765  if (!frag_stream_info)
1766  return -1;
1767 
1768  for (i = 0; i < c->fc->nb_streams; i++) {
1769  // Avoid building frag index if streams lack track id.
1770  MOVStreamContext *sc = c->fc->streams[i]->priv_data;
1771  if (sc->id < 0) {
1772  av_free(frag_stream_info);
1773  return AVERROR_INVALIDDATA;
1774  }
1775 
1776  frag_stream_info[i].id = sc->id;
1777  frag_stream_info[i].sidx_pts = AV_NOPTS_VALUE;
1778  frag_stream_info[i].tfdt_dts = AV_NOPTS_VALUE;
1779  frag_stream_info[i].next_trun_dts = AV_NOPTS_VALUE;
1780  frag_stream_info[i].first_tfra_pts = AV_NOPTS_VALUE;
1781  frag_stream_info[i].index_base = -1;
1782  frag_stream_info[i].index_entry = -1;
1783  frag_stream_info[i].encryption_index = NULL;
1784  frag_stream_info[i].stsd_id = -1;
1785  }
1786 
1787  if (index < c->frag_index.nb_items)
1788  memmove(c->frag_index.item + index + 1, c->frag_index.item + index,
1789  (c->frag_index.nb_items - index) * sizeof(*c->frag_index.item));
1790 
1791  item = &c->frag_index.item[index];
1792  item->headers_read = 0;
1793  item->current = 0;
1794  item->nb_stream_info = c->fc->nb_streams;
1795  item->moof_offset = offset;
1796  item->stream_info = frag_stream_info;
1797  c->frag_index.nb_items++;
1798 
1799  return index;
1800 }
1801 
1802 static void fix_frag_index_entries(MOVFragmentIndex *frag_index, int index,
1803  int id, int entries)
1804 {
1805  int i;
1806  MOVFragmentStreamInfo * frag_stream_info;
1807 
1808  if (index < 0)
1809  return;
1810  for (i = index; i < frag_index->nb_items; i++) {
1811  frag_stream_info = get_frag_stream_info(frag_index, i, id);
1812  if (frag_stream_info && frag_stream_info->index_entry >= 0)
1813  frag_stream_info->index_entry += entries;
1814  }
1815 }
1816 
1818 {
1819  // Set by mov_read_tfhd(). mov_read_trun() will reject files missing tfhd.
1820  c->fragment.found_tfhd = 0;
1821 
1822  if (!c->has_looked_for_mfra && c->use_mfra_for > 0) {
1823  c->has_looked_for_mfra = 1;
1824  if (pb->seekable & AVIO_SEEKABLE_NORMAL) {
1825  int ret;
1826  av_log(c->fc, AV_LOG_VERBOSE, "stream has moof boxes, will look "
1827  "for a mfra\n");
1828  if ((ret = mov_read_mfra(c, pb)) < 0) {
1829  av_log(c->fc, AV_LOG_VERBOSE, "found a moof box but failed to "
1830  "read the mfra (may be a live ismv)\n");
1831  }
1832  } else {
1833  av_log(c->fc, AV_LOG_VERBOSE, "found a moof box but stream is not "
1834  "seekable, can not look for mfra\n");
1835  }
1836  }
1837  c->fragment.moof_offset = c->fragment.implicit_offset = avio_tell(pb) - 8;
1838  av_log(c->fc, AV_LOG_TRACE, "moof offset %"PRIx64"\n", c->fragment.moof_offset);
1839  c->frag_index.current = update_frag_index(c, c->fragment.moof_offset);
1840  return mov_read_default(c, pb, atom);
1841 }
1842 
1844 {
1845  int64_t time;
1846  if (version == 1) {
1847  time = avio_rb64(pb);
1848  avio_rb64(pb);
1849  if (time < 0) {
1850  av_log(c->fc, AV_LOG_DEBUG, "creation_time is negative\n");
1851  return;
1852  }
1853  } else {
1854  time = avio_rb32(pb);
1855  avio_rb32(pb); /* modification time */
1856  if (time > 0 && time < 2082844800) {
1857  av_log(c->fc, AV_LOG_WARNING, "Detected creation time before 1970, parsing as unix timestamp.\n");
1858  time += 2082844800;
1859  }
1860  }
1861  if (time) {
1862  time -= 2082844800; /* seconds between 1904-01-01 and Epoch */
1863 
1864  if ((int64_t)(time * 1000000ULL) / 1000000 != time) {
1865  av_log(c->fc, AV_LOG_DEBUG, "creation_time is not representable\n");
1866  return;
1867  }
1868 
1869  ff_dict_set_timestamp(metadata, "creation_time", time * 1000000);
1870  }
1871 }
1872 
1874 {
1875  AVStream *st;
1876  MOVStreamContext *sc;
1877  int version;
1878  char language[4] = {0};
1879  unsigned lang;
1880 
1881  if (c->fc->nb_streams < 1)
1882  return 0;
1883  st = c->fc->streams[c->fc->nb_streams-1];
1884  sc = st->priv_data;
1885 
1886  if (sc->time_scale) {
1887  av_log(c->fc, AV_LOG_ERROR, "Multiple mdhd?\n");
1888  return AVERROR_INVALIDDATA;
1889  }
1890 
1891  version = avio_r8(pb);
1892  if (version > 1) {
1893  avpriv_request_sample(c->fc, "Version %d", version);
1894  return AVERROR_PATCHWELCOME;
1895  }
1896  avio_rb24(pb); /* flags */
1898 
1899  sc->time_scale = avio_rb32(pb);
1900  if (sc->time_scale <= 0) {
1901  av_log(c->fc, AV_LOG_ERROR, "Invalid mdhd time scale %d, defaulting to 1\n", sc->time_scale);
1902  sc->time_scale = 1;
1903  }
1904  st->duration = (version == 1) ? avio_rb64(pb) : avio_rb32(pb); /* duration */
1905 
1906  if ((version == 1 && st->duration == UINT64_MAX) ||
1907  (version != 1 && st->duration == UINT32_MAX)) {
1908  st->duration = 0;
1909  }
1910 
1911  lang = avio_rb16(pb); /* language */
1912  if (ff_mov_lang_to_iso639(lang, language))
1913  av_dict_set(&st->metadata, "language", language, 0);
1914  avio_rb16(pb); /* quality */
1915 
1916  return 0;
1917 }
1918 
1920 {
1921  int i;
1922  int version = avio_r8(pb); /* version */
1923  avio_rb24(pb); /* flags */
1924 
1925  mov_metadata_creation_time(c, pb, &c->fc->metadata, version);
1926  c->time_scale = avio_rb32(pb); /* time scale */
1927  if (c->time_scale <= 0) {
1928  av_log(c->fc, AV_LOG_ERROR, "Invalid mvhd time scale %d, defaulting to 1\n", c->time_scale);
1929  c->time_scale = 1;
1930  }
1931  av_log(c->fc, AV_LOG_TRACE, "time scale = %i\n", c->time_scale);
1932 
1933  c->duration = (version == 1) ? avio_rb64(pb) : avio_rb32(pb); /* duration */
1934  avio_rb32(pb); /* preferred scale */
1935 
1936  avio_rb16(pb); /* preferred volume */
1937 
1938  avio_skip(pb, 10); /* reserved */
1939 
1940  /* movie display matrix, store it in main context and use it later on */
1941  for (i = 0; i < 3; i++) {
1942  c->movie_display_matrix[i][0] = avio_rb32(pb); // 16.16 fixed point
1943  c->movie_display_matrix[i][1] = avio_rb32(pb); // 16.16 fixed point
1944  c->movie_display_matrix[i][2] = avio_rb32(pb); // 2.30 fixed point
1945  }
1946 
1947  avio_rb32(pb); /* preview time */
1948  avio_rb32(pb); /* preview duration */
1949  avio_rb32(pb); /* poster time */
1950  avio_rb32(pb); /* selection time */
1951  avio_rb32(pb); /* selection duration */
1952  avio_rb32(pb); /* current time */
1953  avio_rb32(pb); /* next track ID */
1954 
1955  return 0;
1956 }
1957 
1959 {
1960  AVStream *st;
1961 
1962  if (fc->nb_streams < 1)
1963  return;
1964  st = fc->streams[fc->nb_streams-1];
1965 
1966  switch (st->codecpar->codec_id) {
1967  case AV_CODEC_ID_PCM_S16BE:
1969  break;
1970  case AV_CODEC_ID_PCM_S24BE:
1972  break;
1973  case AV_CODEC_ID_PCM_S32BE:
1975  break;
1976  case AV_CODEC_ID_PCM_F32BE:
1978  break;
1979  case AV_CODEC_ID_PCM_F64BE:
1981  break;
1982  default:
1983  break;
1984  }
1985 }
1986 
1988 {
1989  int little_endian = avio_rb16(pb) & 0xFF;
1990  av_log(c->fc, AV_LOG_TRACE, "enda %d\n", little_endian);
1991  if (little_endian == 1)
1993  return 0;
1994 }
1995 
1997 {
1998  int format_flags;
1999  int version, flags;
2000  int pcm_sample_size;
2001  AVFormatContext *fc = c->fc;
2002  AVStream *st;
2003  MOVStreamContext *sc;
2004 
2005  if (atom.size < 6) {
2006  av_log(c->fc, AV_LOG_ERROR, "Empty pcmC box\n");
2007  return AVERROR_INVALIDDATA;
2008  }
2009 
2010  version = avio_r8(pb);
2011  flags = avio_rb24(pb);
2012 
2013  if (version != 0 || flags != 0) {
2014  av_log(c->fc, AV_LOG_ERROR,
2015  "Unsupported 'pcmC' box with version %d, flags: %x",
2016  version, flags);
2017  return AVERROR_INVALIDDATA;
2018  }
2019 
2020  format_flags = avio_r8(pb);
2021  pcm_sample_size = avio_r8(pb);
2022 
2023  if (fc->nb_streams < 1)
2024  return AVERROR_INVALIDDATA;
2025 
2026  st = fc->streams[fc->nb_streams - 1];
2027  sc = st->priv_data;
2028 
2029  if (sc->format == MOV_MP4_FPCM_TAG) {
2030  switch (pcm_sample_size) {
2031  case 32:
2033  break;
2034  case 64:
2036  break;
2037  default:
2038  av_log(fc, AV_LOG_ERROR, "invalid pcm_sample_size %d for %s\n",
2039  pcm_sample_size,
2040  av_fourcc2str(sc->format));
2041  return AVERROR_INVALIDDATA;
2042  }
2043  } else if (sc->format == MOV_MP4_IPCM_TAG) {
2044  switch (pcm_sample_size) {
2045  case 16:
2047  break;
2048  case 24:
2050  break;
2051  case 32:
2053  break;
2054  default:
2055  av_log(fc, AV_LOG_ERROR, "invalid pcm_sample_size %d for %s\n",
2056  pcm_sample_size,
2057  av_fourcc2str(sc->format));
2058  return AVERROR_INVALIDDATA;
2059  }
2060  } else {
2061  av_log(fc, AV_LOG_ERROR, "'pcmC' with invalid sample entry '%s'\n",
2062  av_fourcc2str(sc->format));
2063  return AVERROR_INVALIDDATA;
2064  }
2065 
2066  if (format_flags & 1) // indicates little-endian format. If not present, big-endian format is used
2069 
2070  return 0;
2071 }
2072 
2074 {
2075  AVStream *st;
2076  HEIFItem *item = NULL;
2077  char color_parameter_type[5] = { 0 };
2078  uint16_t color_primaries, color_trc, color_matrix;
2079  int ret;
2080 
2081  st = get_curr_st(c);
2082  if (!st) {
2083  item = get_heif_item(c, c->cur_item_id);
2084  if (!item)
2085  return 0;
2086  }
2087 
2088  ret = ffio_read_size(pb, color_parameter_type, 4);
2089  if (ret < 0)
2090  return ret;
2091  if (strncmp(color_parameter_type, "nclx", 4) &&
2092  strncmp(color_parameter_type, "nclc", 4) &&
2093  strncmp(color_parameter_type, "prof", 4)) {
2094  av_log(c->fc, AV_LOG_WARNING, "unsupported color_parameter_type %s\n",
2095  color_parameter_type);
2096  return 0;
2097  }
2098 
2099  if (!strncmp(color_parameter_type, "prof", 4)) {
2100  AVPacketSideData *sd;
2101  uint8_t *icc_profile;
2102  if (st) {
2106  atom.size - 4, 0);
2107  if (!sd)
2108  return AVERROR(ENOMEM);
2109  icc_profile = sd->data;
2110  } else {
2111  av_freep(&item->icc_profile);
2112  icc_profile = item->icc_profile = av_malloc(atom.size - 4);
2113  if (!icc_profile) {
2114  item->icc_profile_size = 0;
2115  return AVERROR(ENOMEM);
2116  }
2117  item->icc_profile_size = atom.size - 4;
2118  }
2119  ret = ffio_read_size(pb, icc_profile, atom.size - 4);
2120  if (ret < 0)
2121  return ret;
2122  } else if (st) {
2123  color_primaries = avio_rb16(pb);
2124  color_trc = avio_rb16(pb);
2125  color_matrix = avio_rb16(pb);
2126 
2127  av_log(c->fc, AV_LOG_TRACE,
2128  "%s: pri %d trc %d matrix %d",
2129  color_parameter_type, color_primaries, color_trc, color_matrix);
2130 
2131  if (!strncmp(color_parameter_type, "nclx", 4)) {
2132  uint8_t color_range = avio_r8(pb) >> 7;
2133  av_log(c->fc, AV_LOG_TRACE, " full %"PRIu8"", color_range);
2134  if (color_range)
2136  else
2138  }
2139 
2142  if (!av_color_transfer_name(color_trc))
2143  color_trc = AVCOL_TRC_UNSPECIFIED;
2144  if (!av_color_space_name(color_matrix))
2145  color_matrix = AVCOL_SPC_UNSPECIFIED;
2146 
2148  st->codecpar->color_trc = color_trc;
2149  st->codecpar->color_space = color_matrix;
2150  av_log(c->fc, AV_LOG_TRACE, "\n");
2151  }
2152  return 0;
2153 }
2154 
2156 {
2157  AVStream *st;
2158  unsigned mov_field_order;
2159  enum AVFieldOrder decoded_field_order = AV_FIELD_UNKNOWN;
2160 
2161  if (c->fc->nb_streams < 1) // will happen with jp2 files
2162  return 0;
2163  st = c->fc->streams[c->fc->nb_streams-1];
2164  if (atom.size < 2)
2165  return AVERROR_INVALIDDATA;
2166  mov_field_order = avio_rb16(pb);
2167  if ((mov_field_order & 0xFF00) == 0x0100)
2168  decoded_field_order = AV_FIELD_PROGRESSIVE;
2169  else if ((mov_field_order & 0xFF00) == 0x0200) {
2170  switch (mov_field_order & 0xFF) {
2171  case 0x01: decoded_field_order = AV_FIELD_TT;
2172  break;
2173  case 0x06: decoded_field_order = AV_FIELD_BB;
2174  break;
2175  case 0x09: decoded_field_order = AV_FIELD_TB;
2176  break;
2177  case 0x0E: decoded_field_order = AV_FIELD_BT;
2178  break;
2179  }
2180  }
2181  if (decoded_field_order == AV_FIELD_UNKNOWN && mov_field_order) {
2182  av_log(c->fc, AV_LOG_ERROR, "Unknown MOV field order 0x%04x\n", mov_field_order);
2183  }
2184  st->codecpar->field_order = decoded_field_order;
2185 
2186  return 0;
2187 }
2188 
2190 {
2191  int err = 0;
2192  uint64_t size = (uint64_t)par->extradata_size + atom.size + 8 + AV_INPUT_BUFFER_PADDING_SIZE;
2193  if (size > INT_MAX || (uint64_t)atom.size > INT_MAX)
2194  return AVERROR_INVALIDDATA;
2195  if ((err = av_reallocp(&par->extradata, size)) < 0) {
2196  par->extradata_size = 0;
2197  return err;
2198  }
2200  return 0;
2201 }
2202 
2203 /* Read a whole atom into the extradata return the size of the atom read, possibly truncated if != atom.size */
2205  AVCodecParameters *par, uint8_t *buf)
2206 {
2207  int64_t result = atom.size;
2208  int err;
2209 
2210  AV_WB32(buf , atom.size + 8);
2211  AV_WL32(buf + 4, atom.type);
2212  err = ffio_read_size(pb, buf + 8, atom.size);
2213  if (err < 0) {
2214  par->extradata_size -= atom.size;
2215  return err;
2216  } else if (err < atom.size) {
2217  av_log(c->fc, AV_LOG_WARNING, "truncated extradata\n");
2218  par->extradata_size -= atom.size - err;
2219  result = err;
2220  }
2221  memset(buf + 8 + err, 0, AV_INPUT_BUFFER_PADDING_SIZE);
2222  return result;
2223 }
2224 
2225 /* FIXME modify QDM2/SVQ3/H.264 decoders to take full atom as extradata */
2227  enum AVCodecID codec_id)
2228 {
2229  AVStream *st;
2230  uint64_t original_size;
2231  int err;
2232 
2233  if (c->fc->nb_streams < 1) // will happen with jp2 files
2234  return 0;
2235  st = c->fc->streams[c->fc->nb_streams-1];
2236 
2237  if (st->codecpar->codec_id != codec_id)
2238  return 0; /* unexpected codec_id - don't mess with extradata */
2239 
2240  original_size = st->codecpar->extradata_size;
2241  err = mov_realloc_extradata(st->codecpar, atom);
2242  if (err)
2243  return err;
2244 
2245  err = mov_read_atom_into_extradata(c, pb, atom, st->codecpar, st->codecpar->extradata + original_size);
2246  if (err < 0)
2247  return err;
2248  return 0; // Note: this is the original behavior to ignore truncation.
2249 }
2250 
2251 /* wrapper functions for reading ALAC/AVS/MJPEG/MJPEG2000 extradata atoms only for those codecs */
2253 {
2254  return mov_read_extradata(c, pb, atom, AV_CODEC_ID_ALAC);
2255 }
2256 
2258 {
2259  return mov_read_extradata(c, pb, atom, AV_CODEC_ID_CAVS);
2260 }
2261 
2263 {
2264  return mov_read_extradata(c, pb, atom, AV_CODEC_ID_JPEG2000);
2265 }
2266 
2268 {
2269  return mov_read_extradata(c, pb, atom, AV_CODEC_ID_R10K);
2270 }
2271 
2273 {
2274  int ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_AVUI);
2275  if (!ret)
2276  ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_DNXHD);
2277  return ret;
2278 }
2279 
2281 {
2282  int ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_TARGA_Y216);
2283 
2284  if (!ret && c->fc->nb_streams >= 1) {
2285  AVCodecParameters *par = c->fc->streams[c->fc->nb_streams-1]->codecpar;
2286  if (par->extradata_size >= 40) {
2287  par->height = AV_RB16(&par->extradata[36]);
2288  par->width = AV_RB16(&par->extradata[38]);
2289  }
2290  }
2291  return ret;
2292 }
2293 
2295 {
2296  if (c->fc->nb_streams >= 1) {
2297  AVStream *const st = c->fc->streams[c->fc->nb_streams - 1];
2298  FFStream *const sti = ffstream(st);
2299  AVCodecParameters *par = st->codecpar;
2300 
2301  if (par->codec_tag == MKTAG('A', 'V', 'i', 'n') &&
2302  par->codec_id == AV_CODEC_ID_H264 &&
2303  atom.size > 11) {
2304  int cid;
2305  avio_skip(pb, 10);
2306  cid = avio_rb16(pb);
2307  /* For AVID AVCI50, force width of 1440 to be able to select the correct SPS and PPS */
2308  if (cid == 0xd4d || cid == 0xd4e)
2309  par->width = 1440;
2310  return 0;
2311  } else if ((par->codec_tag == MKTAG('A', 'V', 'd', '1') ||
2312  par->codec_tag == MKTAG('A', 'V', 'j', '2') ||
2313  par->codec_tag == MKTAG('A', 'V', 'd', 'n')) &&
2314  atom.size >= 24) {
2315  int num, den;
2316  avio_skip(pb, 12);
2317  num = avio_rb32(pb);
2318  den = avio_rb32(pb);
2319  if (num <= 0 || den <= 0)
2320  return 0;
2321  switch (avio_rb32(pb)) {
2322  case 2:
2323  if (den >= INT_MAX / 2)
2324  return 0;
2325  den *= 2;
2326  case 1:
2327  sti->display_aspect_ratio = (AVRational){ num, den };
2328  default:
2329  return 0;
2330  }
2331  }
2332  }
2333 
2334  return mov_read_avid(c, pb, atom);
2335 }
2336 
2338 {
2339  int ret = 0;
2340  int length = 0;
2341  uint64_t original_size;
2342  if (c->fc->nb_streams >= 1) {
2343  AVCodecParameters *par = c->fc->streams[c->fc->nb_streams-1]->codecpar;
2344  if (par->codec_id == AV_CODEC_ID_H264)
2345  return 0;
2346  if (atom.size == 16) {
2347  original_size = par->extradata_size;
2348  ret = mov_realloc_extradata(par, atom);
2349  if (!ret) {
2350  length = mov_read_atom_into_extradata(c, pb, atom, par, par->extradata + original_size);
2351  if (length == atom.size) {
2352  const uint8_t range_value = par->extradata[original_size + 19];
2353  switch (range_value) {
2354  case 1:
2356  break;
2357  case 2:
2359  break;
2360  default:
2361  av_log(c->fc, AV_LOG_WARNING, "ignored unknown aclr value (%d)\n", range_value);
2362  break;
2363  }
2364  ff_dlog(c->fc, "color_range: %d\n", par->color_range);
2365  } else {
2366  /* For some reason the whole atom was not added to the extradata */
2367  av_log(c->fc, AV_LOG_ERROR, "aclr not decoded - incomplete atom\n");
2368  }
2369  } else {
2370  av_log(c->fc, AV_LOG_ERROR, "aclr not decoded - unable to add atom to extradata\n");
2371  }
2372  } else {
2373  av_log(c->fc, AV_LOG_WARNING, "aclr not decoded - unexpected size %"PRId64"\n", atom.size);
2374  }
2375  }
2376 
2377  return ret;
2378 }
2379 
2381 {
2382  return mov_read_extradata(c, pb, atom, AV_CODEC_ID_SVQ3);
2383 }
2384 
2386 {
2387  AVStream *st;
2388  int ret;
2389 
2390  if (c->fc->nb_streams < 1)
2391  return 0;
2392  st = c->fc->streams[c->fc->nb_streams-1];
2393 
2394  if ((uint64_t)atom.size > (1<<30))
2395  return AVERROR_INVALIDDATA;
2396 
2397  if (st->codecpar->codec_id == AV_CODEC_ID_QDM2 ||
2400  // pass all frma atom to codec, needed at least for QDMC and QDM2
2401  ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size);
2402  if (ret < 0)
2403  return ret;
2404  } else if (atom.size > 8) { /* to read frma, esds atoms */
2405  if (st->codecpar->codec_id == AV_CODEC_ID_ALAC && atom.size >= 24) {
2406  uint64_t buffer;
2407  ret = ffio_ensure_seekback(pb, 8);
2408  if (ret < 0)
2409  return ret;
2410  buffer = avio_rb64(pb);
2411  atom.size -= 8;
2412  if ( (buffer & 0xFFFFFFFF) == MKBETAG('f','r','m','a')
2413  && buffer >> 32 <= atom.size
2414  && buffer >> 32 >= 8) {
2415  avio_skip(pb, -8);
2416  atom.size += 8;
2417  } else if (!st->codecpar->extradata_size) {
2418 #define ALAC_EXTRADATA_SIZE 36
2420  if (!st->codecpar->extradata)
2421  return AVERROR(ENOMEM);
2424  AV_WB32(st->codecpar->extradata + 4, MKTAG('a','l','a','c'));
2425  AV_WB64(st->codecpar->extradata + 12, buffer);
2426  avio_read(pb, st->codecpar->extradata + 20, 16);
2427  avio_skip(pb, atom.size - 24);
2428  return 0;
2429  }
2430  }
2431  if ((ret = mov_read_default(c, pb, atom)) < 0)
2432  return ret;
2433  } else
2434  avio_skip(pb, atom.size);
2435  return 0;
2436 }
2437 
2438 /**
2439  * This function reads atom content and puts data in extradata without tag
2440  * nor size unlike mov_read_extradata.
2441  */
2443 {
2444  AVStream *st;
2445  int ret;
2446 
2447  st = get_curr_st(c);
2448  if (!st)
2449  return 0;
2450 
2451  if ((uint64_t)atom.size > (1<<30))
2452  return AVERROR_INVALIDDATA;
2453 
2454  if (atom.type == MKTAG('v','v','c','C')) {
2455  avio_skip(pb, 4);
2456  atom.size -= 4;
2457  }
2458 
2459  if (atom.size >= 10) {
2460  // Broken files created by legacy versions of libavformat will
2461  // wrap a whole fiel atom inside of a glbl atom.
2462  unsigned size = avio_rb32(pb);
2463  unsigned type = avio_rl32(pb);
2464  if (avio_feof(pb))
2465  return AVERROR_INVALIDDATA;
2466  avio_seek(pb, -8, SEEK_CUR);
2467  if (type == MKTAG('f','i','e','l') && size == atom.size)
2468  return mov_read_default(c, pb, atom);
2469  }
2470  if (st->codecpar->extradata_size > 1 && st->codecpar->extradata) {
2471  av_log(c->fc, AV_LOG_WARNING, "ignoring multiple glbl\n");
2472  return 0;
2473  }
2474  ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size);
2475  if (ret < 0)
2476  return ret;
2477  if (atom.type == MKTAG('h','v','c','C') && st->codecpar->codec_tag == MKTAG('d','v','h','1'))
2478  /* HEVC-based Dolby Vision derived from hvc1.
2479  Happens to match with an identifier
2480  previously utilized for DV. Thus, if we have
2481  the hvcC extradata box available as specified,
2482  set codec to HEVC */
2484 
2485  return 0;
2486 }
2487 
2489 {
2490  AVStream *st;
2491  uint8_t profile_level;
2492  int ret;
2493 
2494  if (c->fc->nb_streams < 1)
2495  return 0;
2496  st = c->fc->streams[c->fc->nb_streams-1];
2497 
2498  if (atom.size >= (1<<28) || atom.size < 7)
2499  return AVERROR_INVALIDDATA;
2500 
2501  profile_level = avio_r8(pb);
2502  if ((profile_level & 0xf0) != 0xc0)
2503  return 0;
2504 
2505  avio_seek(pb, 6, SEEK_CUR);
2506  ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size - 7);
2507  if (ret < 0)
2508  return ret;
2509 
2510  return 0;
2511 }
2512 
2514 {
2515  AVStream* st;
2516  MOVStreamContext* sc;
2517 
2518  if (c->fc->nb_streams < 1)
2519  return 0;
2520 
2521  /* For SBAS this should be fine - though beware if someone implements a
2522  * tref atom processor that doesn't drop down to default then this may
2523  * be lost. */
2524  if (atom.size > 4) {
2525  av_log(c->fc, AV_LOG_ERROR, "Only a single tref of type sbas is supported\n");
2526  return AVERROR_PATCHWELCOME;
2527  }
2528 
2529  st = c->fc->streams[c->fc->nb_streams - 1];
2530  sc = st->priv_data;
2531  sc->tref_id = avio_rb32(pb);
2533 
2534  return 0;
2535 }
2536 
2537 /**
2538  * An strf atom is a BITMAPINFOHEADER struct. This struct is 40 bytes itself,
2539  * but can have extradata appended at the end after the 40 bytes belonging
2540  * to the struct.
2541  */
2543 {
2544  AVStream *st;
2545  int ret;
2546 
2547  if (c->fc->nb_streams < 1)
2548  return 0;
2549  if (atom.size <= 40)
2550  return 0;
2551  st = c->fc->streams[c->fc->nb_streams-1];
2552 
2553  if ((uint64_t)atom.size > (1<<30))
2554  return AVERROR_INVALIDDATA;
2555 
2556  avio_skip(pb, 40);
2557  ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size - 40);
2558  if (ret < 0)
2559  return ret;
2560 
2561  return 0;
2562 }
2563 
2565 {
2566  AVStream *st;
2567  MOVStreamContext *sc;
2568  unsigned int i, entries;
2569 
2570  if (c->trak_index < 0) {
2571  av_log(c->fc, AV_LOG_WARNING, "STCO outside TRAK\n");
2572  return 0;
2573  }
2574  if (c->fc->nb_streams < 1)
2575  return 0;
2576  st = c->fc->streams[c->fc->nb_streams-1];
2577  sc = st->priv_data;
2578 
2579  avio_r8(pb); /* version */
2580  avio_rb24(pb); /* flags */
2581 
2582  // Clamp allocation size for `chunk_offsets` -- don't throw an error for an
2583  // invalid count since the EOF path doesn't throw either.
2584  entries = avio_rb32(pb);
2585  entries =
2586  FFMIN(entries,
2587  FFMAX(0, (atom.size - 8) /
2588  (atom.type == MKTAG('s', 't', 'c', 'o') ? 4 : 8)));
2589 
2590  if (!entries)
2591  return 0;
2592 
2593  if (sc->chunk_offsets) {
2594  av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicated STCO atom\n");
2595  return 0;
2596  }
2597 
2598  av_free(sc->chunk_offsets);
2599  sc->chunk_count = 0;
2600  sc->chunk_offsets = av_malloc_array(entries, sizeof(*sc->chunk_offsets));
2601  if (!sc->chunk_offsets)
2602  return AVERROR(ENOMEM);
2603  sc->chunk_count = entries;
2604 
2605  if (atom.type == MKTAG('s','t','c','o'))
2606  for (i = 0; i < entries && !pb->eof_reached; i++)
2607  sc->chunk_offsets[i] = avio_rb32(pb);
2608  else if (atom.type == MKTAG('c','o','6','4'))
2609  for (i = 0; i < entries && !pb->eof_reached; i++) {
2610  sc->chunk_offsets[i] = avio_rb64(pb);
2611  if (sc->chunk_offsets[i] < 0) {
2612  av_log(c->fc, AV_LOG_WARNING, "Impossible chunk_offset\n");
2613  sc->chunk_offsets[i] = 0;
2614  }
2615  }
2616  else
2617  return AVERROR_INVALIDDATA;
2618 
2619  sc->chunk_count = i;
2620 
2621  if (pb->eof_reached) {
2622  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STCO atom\n");
2623  return AVERROR_EOF;
2624  }
2625 
2626  return 0;
2627 }
2628 
2629 static int mov_codec_id(AVStream *st, uint32_t format)
2630 {
2632 
2633  if (id <= 0 &&
2634  ((format & 0xFFFF) == 'm' + ('s' << 8) ||
2635  (format & 0xFFFF) == 'T' + ('S' << 8)))
2637 
2638  if (st->codecpar->codec_type != AVMEDIA_TYPE_VIDEO && id > 0) {
2640  } else if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO &&
2641  /* skip old ASF MPEG-4 tag */
2642  format && format != MKTAG('m','p','4','s')) {
2644  if (id <= 0)
2646  if (id > 0)
2648  else if (st->codecpar->codec_type == AVMEDIA_TYPE_DATA ||
2650  st->codecpar->codec_id == AV_CODEC_ID_NONE)) {
2652  if (id <= 0) {
2654  AV_CODEC_ID_TTML : id;
2655  }
2656 
2657  if (id > 0)
2659  else
2661  }
2662  }
2663 
2664  st->codecpar->codec_tag = format;
2665 
2666  return id;
2667 }
2668 
2670  AVStream *st, MOVStreamContext *sc)
2671 {
2672  uint8_t codec_name[32] = { 0 };
2673  int64_t stsd_start;
2674  unsigned int len;
2675  uint32_t id = 0;
2676 
2677  /* The first 16 bytes of the video sample description are already
2678  * read in ff_mov_read_stsd_entries() */
2679  stsd_start = avio_tell(pb) - 16;
2680 
2681  avio_rb16(pb); /* version */
2682  avio_rb16(pb); /* revision level */
2683  id = avio_rl32(pb); /* vendor */
2684  av_dict_set(&st->metadata, "vendor_id", av_fourcc2str(id), 0);
2685  avio_rb32(pb); /* temporal quality */
2686  avio_rb32(pb); /* spatial quality */
2687 
2688  st->codecpar->width = avio_rb16(pb); /* width */
2689  st->codecpar->height = avio_rb16(pb); /* height */
2690 
2691  avio_rb32(pb); /* horiz resolution */
2692  avio_rb32(pb); /* vert resolution */
2693  avio_rb32(pb); /* data size, always 0 */
2694  avio_rb16(pb); /* frames per samples */
2695 
2696  len = avio_r8(pb); /* codec name, pascal string */
2697  if (len > 31)
2698  len = 31;
2699  mov_read_mac_string(c, pb, len, codec_name, sizeof(codec_name));
2700  if (len < 31)
2701  avio_skip(pb, 31 - len);
2702 
2703  if (codec_name[0])
2704  av_dict_set(&st->metadata, "encoder", codec_name, 0);
2705 
2706  /* codec_tag YV12 triggers an UV swap in rawdec.c */
2707  if (!strncmp(codec_name, "Planar Y'CbCr 8-bit 4:2:0", 25)) {
2708  st->codecpar->codec_tag = MKTAG('I', '4', '2', '0');
2709  st->codecpar->width &= ~1;
2710  st->codecpar->height &= ~1;
2711  }
2712  /* Flash Media Server uses tag H.263 with Sorenson Spark */
2713  if (st->codecpar->codec_tag == MKTAG('H','2','6','3') &&
2714  !strncmp(codec_name, "Sorenson H263", 13))
2716 
2717  st->codecpar->bits_per_coded_sample = avio_rb16(pb); /* depth */
2718 
2719  avio_seek(pb, stsd_start, SEEK_SET);
2720 
2721  if (ff_get_qtpalette(st->codecpar->codec_id, pb, sc->palette)) {
2722  st->codecpar->bits_per_coded_sample &= 0x1F;
2723  sc->has_palette = 1;
2724  }
2725 }
2726 
2728  AVStream *st, MOVStreamContext *sc)
2729 {
2730  int bits_per_sample, flags;
2731  uint16_t version = avio_rb16(pb);
2732  uint32_t id = 0;
2733  AVDictionaryEntry *compatible_brands = av_dict_get(c->fc->metadata, "compatible_brands", NULL, AV_DICT_MATCH_CASE);
2734  int channel_count;
2735 
2736  avio_rb16(pb); /* revision level */
2737  id = avio_rl32(pb); /* vendor */
2738  av_dict_set(&st->metadata, "vendor_id", av_fourcc2str(id), 0);
2739 
2740  channel_count = avio_rb16(pb);
2741 
2743  st->codecpar->ch_layout.nb_channels = channel_count;
2744  st->codecpar->bits_per_coded_sample = avio_rb16(pb); /* sample size */
2745  av_log(c->fc, AV_LOG_TRACE, "audio channels %d\n", channel_count);
2746 
2747  sc->audio_cid = avio_rb16(pb);
2748  avio_rb16(pb); /* packet size = 0 */
2749 
2750  st->codecpar->sample_rate = ((avio_rb32(pb) >> 16));
2751 
2752  // Read QT version 1 fields. In version 0 these do not exist.
2753  av_log(c->fc, AV_LOG_TRACE, "version =%d, isom =%d\n", version, c->isom);
2754  if (!c->isom ||
2755  (compatible_brands && strstr(compatible_brands->value, "qt ")) ||
2756  (sc->stsd_version == 0 && version > 0)) {
2757  if (version == 1) {
2758  sc->samples_per_frame = avio_rb32(pb);
2759  avio_rb32(pb); /* bytes per packet */
2760  sc->bytes_per_frame = avio_rb32(pb);
2761  avio_rb32(pb); /* bytes per sample */
2762  } else if (version == 2) {
2763  avio_rb32(pb); /* sizeof struct only */
2765  channel_count = avio_rb32(pb);
2767  st->codecpar->ch_layout.nb_channels = channel_count;
2768  avio_rb32(pb); /* always 0x7F000000 */
2770 
2771  flags = avio_rb32(pb); /* lpcm format specific flag */
2772  sc->bytes_per_frame = avio_rb32(pb);
2773  sc->samples_per_frame = avio_rb32(pb);
2774  if (st->codecpar->codec_tag == MKTAG('l','p','c','m'))
2775  st->codecpar->codec_id =
2777  flags);
2778  }
2779  if (version == 0 || (version == 1 && sc->audio_cid != -2)) {
2780  /* can't correctly handle variable sized packet as audio unit */
2781  switch (st->codecpar->codec_id) {
2782  case AV_CODEC_ID_MP2:
2783  case AV_CODEC_ID_MP3:
2785  break;
2786  }
2787  }
2788  }
2789 
2790  if (sc->format == 0) {
2791  if (st->codecpar->bits_per_coded_sample == 8)
2792  st->codecpar->codec_id = mov_codec_id(st, MKTAG('r','a','w',' '));
2793  else if (st->codecpar->bits_per_coded_sample == 16)
2794  st->codecpar->codec_id = mov_codec_id(st, MKTAG('t','w','o','s'));
2795  }
2796 
2797  switch (st->codecpar->codec_id) {
2798  case AV_CODEC_ID_PCM_S8:
2799  case AV_CODEC_ID_PCM_U8:
2800  if (st->codecpar->bits_per_coded_sample == 16)
2802  break;
2803  case AV_CODEC_ID_PCM_S16LE:
2804  case AV_CODEC_ID_PCM_S16BE:
2805  if (st->codecpar->bits_per_coded_sample == 8)
2807  else if (st->codecpar->bits_per_coded_sample == 24)
2808  st->codecpar->codec_id =
2811  else if (st->codecpar->bits_per_coded_sample == 32)
2812  st->codecpar->codec_id =
2815  break;
2816  /* set values for old format before stsd version 1 appeared */
2817  case AV_CODEC_ID_MACE3:
2818  sc->samples_per_frame = 6;
2820  break;
2821  case AV_CODEC_ID_MACE6:
2822  sc->samples_per_frame = 6;
2824  break;
2826  sc->samples_per_frame = 64;
2828  break;
2829  case AV_CODEC_ID_GSM:
2830  sc->samples_per_frame = 160;
2831  sc->bytes_per_frame = 33;
2832  break;
2833  default:
2834  break;
2835  }
2836 
2837  bits_per_sample = av_get_bits_per_sample(st->codecpar->codec_id);
2838  if (bits_per_sample && (bits_per_sample >> 3) * (uint64_t)st->codecpar->ch_layout.nb_channels <= INT_MAX) {
2839  st->codecpar->bits_per_coded_sample = bits_per_sample;
2840  sc->sample_size = (bits_per_sample >> 3) * st->codecpar->ch_layout.nb_channels;
2841  }
2842 }
2843 
2845  AVStream *st, MOVStreamContext *sc,
2846  int64_t size)
2847 {
2848  // ttxt stsd contains display flags, justification, background
2849  // color, fonts, and default styles, so fake an atom to read it
2850  MOVAtom fake_atom = { .size = size };
2851  // mp4s contains a regular esds atom, dfxp ISMV TTML has no content
2852  // in extradata unlike stpp MP4 TTML.
2853  if (st->codecpar->codec_tag != AV_RL32("mp4s") &&
2855  mov_read_glbl(c, pb, fake_atom);
2856  st->codecpar->width = sc->width;
2857  st->codecpar->height = sc->height;
2858 }
2859 
2861  AVStream *st, MOVStreamContext *sc,
2862  int64_t size)
2863 {
2864  int ret;
2865 
2866  if (st->codecpar->codec_tag == MKTAG('t','m','c','d')) {
2867  if ((int)size != size)
2868  return AVERROR(ENOMEM);
2869 
2870  ret = ff_get_extradata(c->fc, st->codecpar, pb, size);
2871  if (ret < 0)
2872  return ret;
2873  if (size > 16) {
2874  MOVStreamContext *tmcd_ctx = st->priv_data;
2875  int val;
2876  val = AV_RB32(st->codecpar->extradata + 4);
2877  tmcd_ctx->tmcd_flags = val;
2878  st->avg_frame_rate.num = AV_RB32(st->codecpar->extradata + 8); /* timescale */
2879  st->avg_frame_rate.den = AV_RB32(st->codecpar->extradata + 12); /* frameDuration */
2880  tmcd_ctx->tmcd_nb_frames = st->codecpar->extradata[16]; /* number of frames */
2881  if (size > 30) {
2882  uint32_t len = AV_RB32(st->codecpar->extradata + 18); /* name atom length */
2883  uint32_t format = AV_RB32(st->codecpar->extradata + 22);
2884  if (format == AV_RB32("name") && (int64_t)size >= (int64_t)len + 18) {
2885  uint16_t str_size = AV_RB16(st->codecpar->extradata + 26); /* string length */
2886  if (str_size > 0 && size >= (int)str_size + 30 &&
2887  st->codecpar->extradata[30] /* Don't add empty string */) {
2888  char *reel_name = av_malloc(str_size + 1);
2889  if (!reel_name)
2890  return AVERROR(ENOMEM);
2891  memcpy(reel_name, st->codecpar->extradata + 30, str_size);
2892  reel_name[str_size] = 0; /* Add null terminator */
2893  av_dict_set(&st->metadata, "reel_name", reel_name,
2895  }
2896  }
2897  }
2898  }
2899  } else {
2900  /* other codec type, just skip (rtp, mp4s ...) */
2901  avio_skip(pb, size);
2902  }
2903  return 0;
2904 }
2905 
2907  AVStream *st, MOVStreamContext *sc)
2908 {
2909  FFStream *const sti = ffstream(st);
2910 
2911  if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
2912  !st->codecpar->sample_rate && sc->time_scale > 1)
2913  st->codecpar->sample_rate = sc->time_scale;
2914 
2915  /* special codec parameters handling */
2916  switch (st->codecpar->codec_id) {
2917 #if CONFIG_DV_DEMUXER
2918  case AV_CODEC_ID_DVAUDIO:
2919  if (c->dv_fctx) {
2920  avpriv_request_sample(c->fc, "multiple DV audio streams");
2921  return AVERROR(ENOSYS);
2922  }
2923 
2924  c->dv_fctx = avformat_alloc_context();
2925  if (!c->dv_fctx) {
2926  av_log(c->fc, AV_LOG_ERROR, "dv demux context alloc error\n");
2927  return AVERROR(ENOMEM);
2928  }
2929  c->dv_demux = avpriv_dv_init_demux(c->dv_fctx);
2930  if (!c->dv_demux) {
2931  av_log(c->fc, AV_LOG_ERROR, "dv demux context init error\n");
2932  return AVERROR(ENOMEM);
2933  }
2934  sc->dv_audio_container = 1;
2936  break;
2937 #endif
2938  /* no ifdef since parameters are always those */
2939  case AV_CODEC_ID_QCELP:
2942  // force sample rate for qcelp when not stored in mov
2943  if (st->codecpar->codec_tag != MKTAG('Q','c','l','p'))
2944  st->codecpar->sample_rate = 8000;
2945  // FIXME: Why is the following needed for some files?
2946  sc->samples_per_frame = 160;
2947  if (!sc->bytes_per_frame)
2948  sc->bytes_per_frame = 35;
2949  break;
2950  case AV_CODEC_ID_AMR_NB:
2953  /* force sample rate for amr, stsd in 3gp does not store sample rate */
2954  st->codecpar->sample_rate = 8000;
2955  break;
2956  case AV_CODEC_ID_AMR_WB:
2959  st->codecpar->sample_rate = 16000;
2960  break;
2961  case AV_CODEC_ID_MP2:
2962  case AV_CODEC_ID_MP3:
2963  /* force type after stsd for m1a hdlr */
2965  break;
2966  case AV_CODEC_ID_GSM:
2967  case AV_CODEC_ID_ADPCM_MS:
2969  case AV_CODEC_ID_ILBC:
2970  case AV_CODEC_ID_MACE3:
2971  case AV_CODEC_ID_MACE6:
2972  case AV_CODEC_ID_QDM2:
2974  break;
2975  case AV_CODEC_ID_ALAC:
2976  if (st->codecpar->extradata_size == 36) {
2977  int channel_count = AV_RB8(st->codecpar->extradata + 21);
2978  if (st->codecpar->ch_layout.nb_channels != channel_count) {
2981  st->codecpar->ch_layout.nb_channels = channel_count;
2982  }
2983  st->codecpar->sample_rate = AV_RB32(st->codecpar->extradata + 32);
2984  }
2985  break;
2986  case AV_CODEC_ID_AC3:
2987  case AV_CODEC_ID_EAC3:
2989  case AV_CODEC_ID_VC1:
2990  case AV_CODEC_ID_VP8:
2991  case AV_CODEC_ID_VP9:
2993  break;
2995  case AV_CODEC_ID_PRORES:
2996  case AV_CODEC_ID_APV:
2997  case AV_CODEC_ID_EVC:
2998  case AV_CODEC_ID_AV1:
2999  /* field_order detection of H264 requires parsing */
3000  case AV_CODEC_ID_H264:
3002  break;
3003  default:
3004  break;
3005  }
3006  return 0;
3007 }
3008 
3010  int codec_tag, int format,
3011  int64_t size)
3012 {
3013  if (codec_tag &&
3014  (codec_tag != format &&
3015  // AVID 1:1 samples with differing data format and codec tag exist
3016  (codec_tag != AV_RL32("AV1x") || format != AV_RL32("AVup")) &&
3017  // prores is allowed to have differing data format and codec tag
3018  codec_tag != AV_RL32("apcn") && codec_tag != AV_RL32("apch") &&
3019  // so is dv (sigh)
3020  codec_tag != AV_RL32("dvpp") && codec_tag != AV_RL32("dvcp") &&
3021  (c->fc->video_codec_id ? ff_codec_get_id(ff_codec_movvideo_tags, format) != c->fc->video_codec_id
3022  : codec_tag != MKTAG('j','p','e','g')))) {
3023  /* Multiple fourcc, we skip JPEG. This is not correct, we should
3024  * export it as a separate AVStream but this needs a few changes
3025  * in the MOV demuxer, patch welcome. */
3026 
3027  av_log(c->fc, AV_LOG_WARNING, "multiple fourcc not supported\n");
3028  avio_skip(pb, size);
3029  return 1;
3030  }
3031 
3032  return 0;
3033 }
3034 
3036 {
3037  int ret;
3038 
3039  /* special codec parameters handling */
3040  switch (st->codecpar->codec_id) {
3041  case AV_CODEC_ID_H264:
3042  // done for ai5q, ai52, ai55, ai1q, ai12 and ai15.
3043  if (!st->codecpar->extradata_size && TAG_IS_AVCI(st->codecpar->codec_tag)) {
3045  if (ret < 0)
3046  return ret;
3047  }
3048  break;
3049  default:
3050  break;
3051  }
3052 
3053  return 0;
3054 }
3055 
3057 {
3058  AVStream *st;
3059  MOVStreamContext *sc;
3060  int pseudo_stream_id;
3061 
3062  av_assert0 (c->fc->nb_streams >= 1);
3063  st = c->fc->streams[c->fc->nb_streams-1];
3064  sc = st->priv_data;
3065 
3066  for (pseudo_stream_id = 0;
3067  pseudo_stream_id < entries && !pb->eof_reached;
3068  pseudo_stream_id++) {
3069  //Parsing Sample description table
3070  enum AVCodecID id;
3071  int ret, dref_id = 1;
3072  MOVAtom a = { AV_RL32("stsd") };
3073  int64_t start_pos = avio_tell(pb);
3074  int64_t size = avio_rb32(pb); /* size */
3075  uint32_t format = avio_rl32(pb); /* data format */
3076 
3077  if (size >= 16) {
3078  avio_rb32(pb); /* reserved */
3079  avio_rb16(pb); /* reserved */
3080  dref_id = avio_rb16(pb);
3081  } else if (size <= 7) {
3082  av_log(c->fc, AV_LOG_ERROR,
3083  "invalid size %"PRId64" in stsd\n", size);
3084  return AVERROR_INVALIDDATA;
3085  }
3086 
3088  size - (avio_tell(pb) - start_pos))) {
3089  sc->stsd_count++;
3090  continue;
3091  }
3092 
3093  sc->pseudo_stream_id = st->codecpar->codec_tag ? -1 : pseudo_stream_id;
3094  sc->dref_id= dref_id;
3095  sc->format = format;
3096 
3097  id = mov_codec_id(st, format);
3098 
3099  av_log(c->fc, AV_LOG_TRACE,
3100  "size=%"PRId64" 4CC=%s codec_type=%d\n", size,
3102 
3103  st->codecpar->codec_id = id;
3105  mov_parse_stsd_video(c, pb, st, sc);
3106  } else if (st->codecpar->codec_type==AVMEDIA_TYPE_AUDIO) {
3107  mov_parse_stsd_audio(c, pb, st, sc);
3108  if (st->codecpar->sample_rate < 0) {
3109  av_log(c->fc, AV_LOG_ERROR, "Invalid sample rate %d\n", st->codecpar->sample_rate);
3110  return AVERROR_INVALIDDATA;
3111  }
3112  if (st->codecpar->ch_layout.nb_channels < 0) {
3113  av_log(c->fc, AV_LOG_ERROR, "Invalid channels %d\n", st->codecpar->ch_layout.nb_channels);
3114  return AVERROR_INVALIDDATA;
3115  }
3116  } else if (st->codecpar->codec_type==AVMEDIA_TYPE_SUBTITLE){
3117  mov_parse_stsd_subtitle(c, pb, st, sc,
3118  size - (avio_tell(pb) - start_pos));
3119  } else {
3120  ret = mov_parse_stsd_data(c, pb, st, sc,
3121  size - (avio_tell(pb) - start_pos));
3122  if (ret < 0)
3123  return ret;
3124  }
3125  /* this will read extra atoms at the end (wave, alac, damr, avcC, hvcC, SMI ...) */
3126  a.size = size - (avio_tell(pb) - start_pos);
3127  if (a.size > 8) {
3128  if ((ret = mov_read_default(c, pb, a)) < 0)
3129  return ret;
3130  } else if (a.size > 0)
3131  avio_skip(pb, a.size);
3132 
3133  ret = mov_finalize_stsd_entry(c, st);
3134  if (ret < 0)
3135  return ret;
3136 
3137  if (sc->extradata && st->codecpar->extradata) {
3138  int extra_size = st->codecpar->extradata_size;
3139 
3140  /* Move the current stream extradata to the stream context one. */
3141  sc->extradata_size[pseudo_stream_id] = extra_size;
3142  sc->extradata[pseudo_stream_id] = st->codecpar->extradata;
3143  st->codecpar->extradata = NULL;
3144  st->codecpar->extradata_size = 0;
3145  }
3146  sc->stsd_count++;
3147  }
3148 
3149  if (pb->eof_reached) {
3150  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSD atom\n");
3151  return AVERROR_EOF;
3152  }
3153 
3154  return 0;
3155 }
3156 
3158 {
3159  AVStream *st;
3160  MOVStreamContext *sc;
3161  int ret, entries;
3162 
3163  if (c->fc->nb_streams < 1)
3164  return 0;
3165  st = c->fc->streams[c->fc->nb_streams - 1];
3166  sc = st->priv_data;
3167 
3168  sc->stsd_version = avio_r8(pb);
3169  avio_rb24(pb); /* flags */
3170  entries = avio_rb32(pb);
3171 
3172  /* Each entry contains a size (4 bytes) and format (4 bytes). */
3173  if (entries <= 0 || entries > atom.size / 8 || entries > 1024) {
3174  av_log(c->fc, AV_LOG_ERROR, "invalid STSD entries %d\n", entries);
3175  return AVERROR_INVALIDDATA;
3176  }
3177 
3178  if (sc->extradata) {
3179  av_log(c->fc, AV_LOG_ERROR,
3180  "Duplicate stsd found in this track.\n");
3181  return AVERROR_INVALIDDATA;
3182  }
3183 
3184  /* Prepare space for hosting multiple extradata. */
3185  sc->extradata = av_calloc(entries, sizeof(*sc->extradata));
3186  if (!sc->extradata)
3187  return AVERROR(ENOMEM);
3188 
3189  sc->extradata_size = av_calloc(entries, sizeof(*sc->extradata_size));
3190  if (!sc->extradata_size) {
3191  ret = AVERROR(ENOMEM);
3192  goto fail;
3193  }
3194 
3195  ret = ff_mov_read_stsd_entries(c, pb, entries);
3196  if (ret < 0)
3197  goto fail;
3198 
3199  /* Restore back the primary extradata. */
3200  av_freep(&st->codecpar->extradata);
3201  st->codecpar->extradata_size = sc->extradata_size[0];
3202  if (sc->extradata_size[0]) {
3204  if (!st->codecpar->extradata)
3205  return AVERROR(ENOMEM);
3206  memcpy(st->codecpar->extradata, sc->extradata[0], sc->extradata_size[0]);
3207  }
3208 
3209  return mov_finalize_stsd_codec(c, pb, st, sc);
3210 fail:
3211  if (sc->extradata) {
3212  int j;
3213  for (j = 0; j < sc->stsd_count; j++)
3214  av_freep(&sc->extradata[j]);
3215  }
3216 
3217  av_freep(&sc->extradata);
3218  av_freep(&sc->extradata_size);
3219  return ret;
3220 }
3221 
3223 {
3224  AVStream *st;
3225  MOVStreamContext *sc;
3226  unsigned int i, entries;
3227 
3228  if (c->trak_index < 0) {
3229  av_log(c->fc, AV_LOG_WARNING, "STSC outside TRAK\n");
3230  return 0;
3231  }
3232 
3233  if (c->fc->nb_streams < 1)
3234  return 0;
3235  st = c->fc->streams[c->fc->nb_streams-1];
3236  sc = st->priv_data;
3237 
3238  avio_r8(pb); /* version */
3239  avio_rb24(pb); /* flags */
3240 
3241  entries = avio_rb32(pb);
3242  if ((uint64_t)entries * 12 + 4 > atom.size)
3243  return AVERROR_INVALIDDATA;
3244 
3245  av_log(c->fc, AV_LOG_TRACE, "track[%u].stsc.entries = %u\n", c->fc->nb_streams - 1, entries);
3246 
3247  if (!entries)
3248  return 0;
3249  if (sc->stsc_data) {
3250  av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicated STSC atom\n");
3251  return 0;
3252  }
3253  av_free(sc->stsc_data);
3254  sc->stsc_count = 0;
3255  sc->stsc_data = av_malloc_array(entries, sizeof(*sc->stsc_data));
3256  if (!sc->stsc_data)
3257  return AVERROR(ENOMEM);
3258 
3259  for (i = 0; i < entries && !pb->eof_reached; i++) {
3260  sc->stsc_data[i].first = avio_rb32(pb);
3261  sc->stsc_data[i].count = avio_rb32(pb);
3262  sc->stsc_data[i].id = avio_rb32(pb);
3263  }
3264 
3265  sc->stsc_count = i;
3266  for (i = sc->stsc_count - 1; i < UINT_MAX; i--) {
3267  int64_t first_min = i + 1;
3268  if ((i+1 < sc->stsc_count && sc->stsc_data[i].first >= sc->stsc_data[i+1].first) ||
3269  (i > 0 && sc->stsc_data[i].first <= sc->stsc_data[i-1].first) ||
3270  sc->stsc_data[i].first < first_min ||
3271  sc->stsc_data[i].count < 1 ||
3272  sc->stsc_data[i].id < 1) {
3273  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);
3274  if (i+1 >= sc->stsc_count) {
3275  if (sc->stsc_data[i].count == 0 && i > 0) {
3276  sc->stsc_count --;
3277  continue;
3278  }
3279  sc->stsc_data[i].first = FFMAX(sc->stsc_data[i].first, first_min);
3280  if (i > 0 && sc->stsc_data[i].first <= sc->stsc_data[i-1].first)
3281  sc->stsc_data[i].first = FFMIN(sc->stsc_data[i-1].first + 1LL, INT_MAX);
3282  sc->stsc_data[i].count = FFMAX(sc->stsc_data[i].count, 1);
3283  sc->stsc_data[i].id = FFMAX(sc->stsc_data[i].id, 1);
3284  continue;
3285  }
3286  av_assert0(sc->stsc_data[i+1].first >= 2);
3287  // We replace this entry by the next valid
3288  sc->stsc_data[i].first = sc->stsc_data[i+1].first - 1;
3289  sc->stsc_data[i].count = sc->stsc_data[i+1].count;
3290  sc->stsc_data[i].id = sc->stsc_data[i+1].id;
3291  }
3292  }
3293 
3294  if (pb->eof_reached) {
3295  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSC atom\n");
3296  return AVERROR_EOF;
3297  }
3298 
3299  return 0;
3300 }
3301 
3302 static inline int mov_stsc_index_valid(unsigned int index, unsigned int count)
3303 {
3304  return index < count - 1;
3305 }
3306 
3307 /* Compute the samples value for the stsc entry at the given index. */
3308 static inline int64_t mov_get_stsc_samples(MOVStreamContext *sc, unsigned int index)
3309 {
3310  int chunk_count;
3311 
3313  chunk_count = sc->stsc_data[index + 1].first - sc->stsc_data[index].first;
3314  else {
3315  // Validation for stsc / stco happens earlier in mov_read_stsc + mov_read_trak.
3317  chunk_count = sc->chunk_count - (sc->stsc_data[index].first - 1);
3318  }
3319 
3320  return sc->stsc_data[index].count * (int64_t)chunk_count;
3321 }
3322 
3324 {
3325  AVStream *st;
3326  MOVStreamContext *sc;
3327  unsigned i, entries;
3328 
3329  if (c->trak_index < 0) {
3330  av_log(c->fc, AV_LOG_WARNING, "STPS outside TRAK\n");
3331  return 0;
3332  }
3333 
3334  if (c->fc->nb_streams < 1)
3335  return 0;
3336  st = c->fc->streams[c->fc->nb_streams-1];
3337  sc = st->priv_data;
3338 
3339  avio_rb32(pb); // version + flags
3340 
3341  entries = avio_rb32(pb);
3342  if (sc->stps_data)
3343  av_log(c->fc, AV_LOG_WARNING, "Duplicated STPS atom\n");
3344  av_free(sc->stps_data);
3345  sc->stps_count = 0;
3346  sc->stps_data = av_malloc_array(entries, sizeof(*sc->stps_data));
3347  if (!sc->stps_data)
3348  return AVERROR(ENOMEM);
3349 
3350  for (i = 0; i < entries && !pb->eof_reached; i++) {
3351  sc->stps_data[i] = avio_rb32(pb);
3352  }
3353 
3354  sc->stps_count = i;
3355 
3356  if (pb->eof_reached) {
3357  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STPS atom\n");
3358  return AVERROR_EOF;
3359  }
3360 
3361  return 0;
3362 }
3363 
3365 {
3366  AVStream *st;
3367  FFStream *sti;
3368  MOVStreamContext *sc;
3369  unsigned int i, entries;
3370 
3371  if (c->trak_index < 0) {
3372  av_log(c->fc, AV_LOG_WARNING, "STSS outside TRAK\n");
3373  return 0;
3374  }
3375 
3376  if (c->fc->nb_streams < 1)
3377  return 0;
3378  st = c->fc->streams[c->fc->nb_streams-1];
3379  sti = ffstream(st);
3380  sc = st->priv_data;
3381 
3382  avio_r8(pb); /* version */
3383  avio_rb24(pb); /* flags */
3384 
3385  entries = avio_rb32(pb);
3386 
3387  av_log(c->fc, AV_LOG_TRACE, "keyframe_count = %u\n", entries);
3388 
3389  if (!entries) {
3390  sc->keyframe_absent = 1;
3391  if (!sti->need_parsing && st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
3393  return 0;
3394  }
3395  if (sc->keyframes)
3396  av_log(c->fc, AV_LOG_WARNING, "Duplicated STSS atom\n");
3397  if (entries >= UINT_MAX / sizeof(int))
3398  return AVERROR_INVALIDDATA;
3399  av_freep(&sc->keyframes);
3400  sc->keyframe_count = 0;
3401  sc->keyframes = av_malloc_array(entries, sizeof(*sc->keyframes));
3402  if (!sc->keyframes)
3403  return AVERROR(ENOMEM);
3404 
3405  for (i = 0; i < entries && !pb->eof_reached; i++) {
3406  sc->keyframes[i] = avio_rb32(pb);
3407  }
3408 
3409  sc->keyframe_count = i;
3410 
3411  if (pb->eof_reached) {
3412  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSS atom\n");
3413  return AVERROR_EOF;
3414  }
3415 
3416  return 0;
3417 }
3418 
3420 {
3421  AVStream *st;
3422  MOVStreamContext *sc;
3423  unsigned int i, entries, sample_size, field_size, num_bytes;
3424  GetBitContext gb;
3425  unsigned char* buf;
3426  int ret;
3427 
3428  if (c->trak_index < 0) {
3429  av_log(c->fc, AV_LOG_WARNING, "STSZ outside TRAK\n");
3430  return 0;
3431  }
3432 
3433  if (c->fc->nb_streams < 1)
3434  return 0;
3435  st = c->fc->streams[c->fc->nb_streams-1];
3436  sc = st->priv_data;
3437 
3438  avio_r8(pb); /* version */
3439  avio_rb24(pb); /* flags */
3440 
3441  if (atom.type == MKTAG('s','t','s','z')) {
3442  sample_size = avio_rb32(pb);
3443  if (!sc->sample_size) /* do not overwrite value computed in stsd */
3444  sc->sample_size = sample_size;
3445  sc->stsz_sample_size = sample_size;
3446  field_size = 32;
3447  } else {
3448  sample_size = 0;
3449  avio_rb24(pb); /* reserved */
3450  field_size = avio_r8(pb);
3451  }
3452  entries = avio_rb32(pb);
3453 
3454  av_log(c->fc, AV_LOG_TRACE, "sample_size = %u sample_count = %u\n", sc->sample_size, entries);
3455 
3456  sc->sample_count = entries;
3457  if (sample_size)
3458  return 0;
3459 
3460  if (field_size != 4 && field_size != 8 && field_size != 16 && field_size != 32) {
3461  av_log(c->fc, AV_LOG_ERROR, "Invalid sample field size %u\n", field_size);
3462  return AVERROR_INVALIDDATA;
3463  }
3464 
3465  if (!entries)
3466  return 0;
3467  if (entries >= (INT_MAX - 4 - 8 * AV_INPUT_BUFFER_PADDING_SIZE) / field_size)
3468  return AVERROR_INVALIDDATA;
3469  if (sc->sample_sizes)
3470  av_log(c->fc, AV_LOG_WARNING, "Duplicated STSZ atom\n");
3471  av_free(sc->sample_sizes);
3472  sc->sample_count = 0;
3473  sc->sample_sizes = av_malloc_array(entries, sizeof(*sc->sample_sizes));
3474  if (!sc->sample_sizes)
3475  return AVERROR(ENOMEM);
3476 
3477  num_bytes = (entries*field_size+4)>>3;
3478 
3479  buf = av_malloc(num_bytes+AV_INPUT_BUFFER_PADDING_SIZE);
3480  if (!buf) {
3481  av_freep(&sc->sample_sizes);
3482  return AVERROR(ENOMEM);
3483  }
3484 
3485  ret = ffio_read_size(pb, buf, num_bytes);
3486  if (ret < 0) {
3487  av_freep(&sc->sample_sizes);
3488  av_free(buf);
3489  av_log(c->fc, AV_LOG_WARNING, "STSZ atom truncated\n");
3490  return 0;
3491  }
3492 
3493  init_get_bits(&gb, buf, 8*num_bytes);
3494 
3495  for (i = 0; i < entries; i++) {
3496  sc->sample_sizes[i] = get_bits_long(&gb, field_size);
3497  if (sc->sample_sizes[i] > INT64_MAX - sc->data_size) {
3498  av_free(buf);
3499  av_log(c->fc, AV_LOG_ERROR, "Sample size overflow in STSZ\n");
3500  return AVERROR_INVALIDDATA;
3501  }
3502  sc->data_size += sc->sample_sizes[i];
3503  }
3504 
3505  sc->sample_count = i;
3506 
3507  av_free(buf);
3508 
3509  return 0;
3510 }
3511 
3513 {
3514  AVStream *st;
3515  MOVStreamContext *sc;
3516  unsigned int i, entries;
3517  int64_t duration = 0;
3518  int64_t total_sample_count = 0;
3519  int64_t current_dts = 0;
3520  int64_t corrected_dts = 0;
3521 
3522  if (c->trak_index < 0) {
3523  av_log(c->fc, AV_LOG_WARNING, "STTS outside TRAK\n");
3524  return 0;
3525  }
3526 
3527  if (c->fc->nb_streams < 1)
3528  return 0;
3529  st = c->fc->streams[c->fc->nb_streams-1];
3530  sc = st->priv_data;
3531 
3532  avio_r8(pb); /* version */
3533  avio_rb24(pb); /* flags */
3534  entries = avio_rb32(pb);
3535 
3536  av_log(c->fc, AV_LOG_TRACE, "track[%u].stts.entries = %u\n",
3537  c->fc->nb_streams-1, entries);
3538 
3539  if (sc->stts_data)
3540  av_log(c->fc, AV_LOG_WARNING, "Duplicated STTS atom\n");
3541  av_freep(&sc->stts_data);
3542  sc->stts_count = 0;
3543  if (entries >= INT_MAX / sizeof(*sc->stts_data))
3544  return AVERROR(ENOMEM);
3545 
3546  for (i = 0; i < entries && !pb->eof_reached; i++) {
3547  unsigned int sample_duration;
3548  unsigned int sample_count;
3549  unsigned int min_entries = FFMIN(FFMAX(i + 1, 1024 * 1024), entries);
3550  MOVStts *stts_data = av_fast_realloc(sc->stts_data, &sc->stts_allocated_size,
3551  min_entries * sizeof(*sc->stts_data));
3552  if (!stts_data) {
3553  av_freep(&sc->stts_data);
3554  sc->stts_count = 0;
3555  return AVERROR(ENOMEM);
3556  }
3557  sc->stts_count = min_entries;
3558  sc->stts_data = stts_data;
3559 
3560  sample_count = avio_rb32(pb);
3561  sample_duration = avio_rb32(pb);
3562 
3563  sc->stts_data[i].count= sample_count;
3564  sc->stts_data[i].duration= sample_duration;
3565 
3566  av_log(c->fc, AV_LOG_TRACE, "sample_count=%u, sample_duration=%u\n",
3567  sample_count, sample_duration);
3568 
3569  /* STTS sample offsets are uint32 but some files store it as int32
3570  * with negative values used to correct DTS delays.
3571  There may be abnormally large values as well. */
3572  if (sample_duration > c->max_stts_delta) {
3573  // assume high delta is a correction if negative when cast as int32
3574  int32_t delta_magnitude = (int32_t)sample_duration;
3575  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",
3576  sample_duration, i, sample_count, st->index);
3577  sc->stts_data[i].duration = 1;
3578  corrected_dts = av_sat_add64(corrected_dts, (delta_magnitude < 0 ? (int64_t)delta_magnitude : 1) * sample_count);
3579  } else {
3580  corrected_dts += sample_duration * (uint64_t)sample_count;
3581  }
3582 
3583  current_dts += sc->stts_data[i].duration * (uint64_t)sample_count;
3584 
3585  if (current_dts > corrected_dts) {
3586  int64_t drift = av_sat_sub64(current_dts, corrected_dts) / FFMAX(sample_count, 1);
3587  uint32_t correction = (sc->stts_data[i].duration > drift) ? drift : sc->stts_data[i].duration - 1;
3588  current_dts -= correction * (uint64_t)sample_count;
3589  sc->stts_data[i].duration -= correction;
3590  }
3591 
3592  duration+=(int64_t)sc->stts_data[i].duration*(uint64_t)sc->stts_data[i].count;
3593  total_sample_count+=sc->stts_data[i].count;
3594  }
3595 
3596  sc->stts_count = i;
3597 
3598  if (duration > 0 &&
3599  duration <= INT64_MAX - sc->duration_for_fps &&
3600  total_sample_count <= INT_MAX - sc->nb_frames_for_fps) {
3601  sc->duration_for_fps += duration;
3602  sc->nb_frames_for_fps += total_sample_count;
3603  }
3604 
3605  if (pb->eof_reached) {
3606  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STTS atom\n");
3607  return AVERROR_EOF;
3608  }
3609 
3610  st->nb_frames= total_sample_count;
3611  if (duration)
3612  st->duration= FFMIN(st->duration, duration);
3613 
3614  // All samples have zero duration. They have higher chance be chose by
3615  // mov_find_next_sample, which leads to seek again and again.
3616  //
3617  // It's AVERROR_INVALIDDATA actually, but such files exist in the wild.
3618  // So only mark data stream as discarded for safety.
3619  if (!duration && sc->stts_count &&
3621  av_log(c->fc, AV_LOG_WARNING,
3622  "All samples in data stream index:id [%d:%d] have zero "
3623  "duration, stream set to be discarded by default. Override "
3624  "using AVStream->discard or -discard for ffmpeg command.\n",
3625  st->index, sc->id);
3626  st->discard = AVDISCARD_ALL;
3627  }
3628  sc->track_end = duration;
3629  return 0;
3630 }
3631 
3633 {
3634  AVStream *st;
3635  MOVStreamContext *sc;
3636  int64_t i, entries;
3637 
3638  if (c->fc->nb_streams < 1)
3639  return 0;
3640  st = c->fc->streams[c->fc->nb_streams - 1];
3641  sc = st->priv_data;
3642 
3643  avio_r8(pb); /* version */
3644  avio_rb24(pb); /* flags */
3645  entries = atom.size - 4;
3646 
3647  av_log(c->fc, AV_LOG_TRACE, "track[%u].sdtp.entries = %" PRId64 "\n",
3648  c->fc->nb_streams - 1, entries);
3649 
3650  if (sc->sdtp_data)
3651  av_log(c->fc, AV_LOG_WARNING, "Duplicated SDTP atom\n");
3652  av_freep(&sc->sdtp_data);
3653  sc->sdtp_count = 0;
3654 
3655  sc->sdtp_data = av_malloc(entries);
3656  if (!sc->sdtp_data)
3657  return AVERROR(ENOMEM);
3658 
3659  for (i = 0; i < entries && !pb->eof_reached; i++)
3660  sc->sdtp_data[i] = avio_r8(pb);
3661  sc->sdtp_count = i;
3662 
3663  return 0;
3664 }
3665 
3666 static void mov_update_dts_shift(MOVStreamContext *sc, int duration, void *logctx)
3667 {
3668  if (duration < 0) {
3669  if (duration == INT_MIN) {
3670  av_log(logctx, AV_LOG_WARNING, "mov_update_dts_shift(): dts_shift set to %d\n", INT_MAX);
3671  duration++;
3672  }
3673  sc->dts_shift = FFMAX(sc->dts_shift, -duration);
3674  }
3675 }
3676 
3678 {
3679  AVStream *st;
3680  MOVStreamContext *sc;
3681  unsigned int i, entries, ctts_count = 0;
3682 
3683  if (c->trak_index < 0) {
3684  av_log(c->fc, AV_LOG_WARNING, "CTTS outside TRAK\n");
3685  return 0;
3686  }
3687 
3688  if (c->fc->nb_streams < 1)
3689  return 0;
3690  st = c->fc->streams[c->fc->nb_streams-1];
3691  sc = st->priv_data;
3692 
3693  avio_r8(pb); /* version */
3694  avio_rb24(pb); /* flags */
3695  entries = avio_rb32(pb);
3696 
3697  av_log(c->fc, AV_LOG_TRACE, "track[%u].ctts.entries = %u\n", c->fc->nb_streams - 1, entries);
3698 
3699  if (!entries)
3700  return 0;
3701  if (entries >= UINT_MAX / sizeof(*sc->ctts_data))
3702  return AVERROR_INVALIDDATA;
3703  av_freep(&sc->ctts_data);
3704  sc->ctts_data = av_fast_realloc(NULL, &sc->ctts_allocated_size, entries * sizeof(*sc->ctts_data));
3705  if (!sc->ctts_data)
3706  return AVERROR(ENOMEM);
3707 
3708  for (i = 0; i < entries && !pb->eof_reached; i++) {
3709  MOVCtts *ctts_data;
3710  const size_t min_size_needed = (ctts_count + 1) * sizeof(MOVCtts);
3711  const size_t requested_size =
3712  min_size_needed > sc->ctts_allocated_size ?
3713  FFMAX(min_size_needed, 2 * sc->ctts_allocated_size) :
3714  min_size_needed;
3715  int count = avio_rb32(pb);
3716  int duration = avio_rb32(pb);
3717 
3718  if (count <= 0) {
3719  av_log(c->fc, AV_LOG_TRACE,
3720  "ignoring CTTS entry with count=%d duration=%d\n",
3721  count, duration);
3722  continue;
3723  }
3724 
3725  if (ctts_count >= UINT_MAX / sizeof(MOVCtts) - 1)
3726  return AVERROR(ENOMEM);
3727 
3728  ctts_data = av_fast_realloc(sc->ctts_data, &sc->ctts_allocated_size, requested_size);
3729 
3730  if (!ctts_data)
3731  return AVERROR(ENOMEM);
3732 
3733  sc->ctts_data = ctts_data;
3734 
3735  ctts_data[ctts_count].count = count;
3736  ctts_data[ctts_count].offset = duration;
3737  ctts_count++;
3738 
3739  av_log(c->fc, AV_LOG_TRACE, "count=%d, duration=%d\n",
3740  count, duration);
3741 
3742  if (i+2<entries)
3743  mov_update_dts_shift(sc, duration, c->fc);
3744  }
3745 
3746  sc->ctts_count = ctts_count;
3747 
3748  if (pb->eof_reached) {
3749  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted CTTS atom\n");
3750  return AVERROR_EOF;
3751  }
3752 
3753  av_log(c->fc, AV_LOG_TRACE, "dts shift %d\n", sc->dts_shift);
3754 
3755  return 0;
3756 }
3757 
3759 {
3760  AVStream *st;
3761  MOVStreamContext *sc;
3762  uint8_t version;
3763  uint32_t grouping_type;
3764  uint32_t default_length;
3765  av_unused uint32_t default_group_description_index;
3766  uint32_t entry_count;
3767 
3768  if (c->fc->nb_streams < 1)
3769  return 0;
3770  st = c->fc->streams[c->fc->nb_streams - 1];
3771  sc = st->priv_data;
3772 
3773  version = avio_r8(pb); /* version */
3774  avio_rb24(pb); /* flags */
3775  grouping_type = avio_rl32(pb);
3776 
3777  /*
3778  * This function only supports "sync" boxes, but the code is able to parse
3779  * other boxes (such as "tscl", "tsas" and "stsa")
3780  */
3781  if (grouping_type != MKTAG('s','y','n','c'))
3782  return 0;
3783 
3784  default_length = version >= 1 ? avio_rb32(pb) : 0;
3785  default_group_description_index = version >= 2 ? avio_rb32(pb) : 0;
3786  entry_count = avio_rb32(pb);
3787 
3788  av_freep(&sc->sgpd_sync);
3789  sc->sgpd_sync_count = entry_count;
3790  sc->sgpd_sync = av_calloc(entry_count, sizeof(*sc->sgpd_sync));
3791  if (!sc->sgpd_sync)
3792  return AVERROR(ENOMEM);
3793 
3794  for (uint32_t i = 0; i < entry_count && !pb->eof_reached; i++) {
3795  uint32_t description_length = default_length;
3796  if (version >= 1 && default_length == 0)
3797  description_length = avio_rb32(pb);
3798  if (grouping_type == MKTAG('s','y','n','c')) {
3799  const uint8_t nal_unit_type = avio_r8(pb) & 0x3f;
3800  sc->sgpd_sync[i] = nal_unit_type;
3801  description_length -= 1;
3802  }
3803  avio_skip(pb, description_length);
3804  }
3805 
3806  if (pb->eof_reached) {
3807  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted SGPD atom\n");
3808  return AVERROR_EOF;
3809  }
3810 
3811  return 0;
3812 }
3813 
3815 {
3816  AVStream *st;
3817  MOVStreamContext *sc;
3818  unsigned int i, entries;
3819  uint8_t version;
3820  uint32_t grouping_type;
3821  MOVSbgp *table, **tablep;
3822  int *table_count;
3823 
3824  if (c->fc->nb_streams < 1)
3825  return 0;
3826  st = c->fc->streams[c->fc->nb_streams-1];
3827  sc = st->priv_data;
3828 
3829  version = avio_r8(pb); /* version */
3830  avio_rb24(pb); /* flags */
3831  grouping_type = avio_rl32(pb);
3832 
3833  if (grouping_type == MKTAG('r','a','p',' ')) {
3834  tablep = &sc->rap_group;
3835  table_count = &sc->rap_group_count;
3836  } else if (grouping_type == MKTAG('s','y','n','c')) {
3837  tablep = &sc->sync_group;
3838  table_count = &sc->sync_group_count;
3839  } else {
3840  return 0;
3841  }
3842 
3843  if (version == 1)
3844  avio_rb32(pb); /* grouping_type_parameter */
3845 
3846  entries = avio_rb32(pb);
3847  if (!entries)
3848  return 0;
3849  if (*tablep)
3850  av_log(c->fc, AV_LOG_WARNING, "Duplicated SBGP %s atom\n", av_fourcc2str(grouping_type));
3851  av_freep(tablep);
3852  table = av_malloc_array(entries, sizeof(*table));
3853  if (!table)
3854  return AVERROR(ENOMEM);
3855  *tablep = table;
3856 
3857  for (i = 0; i < entries && !pb->eof_reached; i++) {
3858  table[i].count = avio_rb32(pb); /* sample_count */
3859  table[i].index = avio_rb32(pb); /* group_description_index */
3860  }
3861 
3862  *table_count = i;
3863 
3864  if (pb->eof_reached) {
3865  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted SBGP atom\n");
3866  return AVERROR_EOF;
3867  }
3868 
3869  return 0;
3870 }
3871 
3872 /**
3873  * Get ith edit list entry (media time, duration).
3874  */
3876  const MOVStreamContext *msc,
3877  unsigned int edit_list_index,
3878  int64_t *edit_list_media_time,
3879  int64_t *edit_list_duration,
3880  int64_t global_timescale)
3881 {
3882  if (edit_list_index == msc->elst_count) {
3883  return 0;
3884  }
3885  *edit_list_media_time = msc->elst_data[edit_list_index].time;
3886  *edit_list_duration = msc->elst_data[edit_list_index].duration;
3887 
3888  /* duration is in global timescale units;convert to msc timescale */
3889  if (global_timescale == 0) {
3890  avpriv_request_sample(mov->fc, "Support for mvhd.timescale = 0 with editlists");
3891  return 0;
3892  }
3893  *edit_list_duration = av_rescale(*edit_list_duration, msc->time_scale,
3894  global_timescale);
3895 
3896  if (*edit_list_duration + (uint64_t)*edit_list_media_time > INT64_MAX)
3897  *edit_list_duration = 0;
3898 
3899  return 1;
3900 }
3901 
3902 /**
3903  * Find the closest previous frame to the timestamp_pts, in e_old index
3904  * entries. Searching for just any frame / just key frames can be controlled by
3905  * last argument 'flag'.
3906  * Note that if ctts_data is not NULL, we will always search for a key frame
3907  * irrespective of the value of 'flag'. If we don't find any keyframe, we will
3908  * return the first frame of the video.
3909  *
3910  * Here the timestamp_pts is considered to be a presentation timestamp and
3911  * the timestamp of index entries are considered to be decoding timestamps.
3912  *
3913  * Returns 0 if successful in finding a frame, else returns -1.
3914  * Places the found index corresponding output arg.
3915  *
3916  * If ctts_old is not NULL, then refines the searched entry by searching
3917  * backwards from the found timestamp, to find the frame with correct PTS.
3918  *
3919  * Places the found ctts_index and ctts_sample in corresponding output args.
3920  */
3922  AVIndexEntry *e_old,
3923  int nb_old,
3924  MOVTimeToSample *tts_data,
3925  int64_t tts_count,
3926  int64_t timestamp_pts,
3927  int flag,
3928  int64_t* index,
3929  int64_t* tts_index,
3930  int64_t* tts_sample)
3931 {
3932  MOVStreamContext *msc = st->priv_data;
3933  FFStream *const sti = ffstream(st);
3934  AVIndexEntry *e_keep = sti->index_entries;
3935  int nb_keep = sti->nb_index_entries;
3936  int64_t i = 0;
3937 
3938  av_assert0(index);
3939 
3940  // If dts_shift > 0, then all the index timestamps will have to be offset by
3941  // at least dts_shift amount to obtain PTS.
3942  // Hence we decrement the searched timestamp_pts by dts_shift to find the closest index element.
3943  if (msc->dts_shift > 0) {
3944  timestamp_pts -= msc->dts_shift;
3945  }
3946 
3947  sti->index_entries = e_old;
3948  sti->nb_index_entries = nb_old;
3949  *index = av_index_search_timestamp(st, timestamp_pts, flag | AVSEEK_FLAG_BACKWARD);
3950 
3951  // Keep going backwards in the index entries until the timestamp is the same.
3952  if (*index >= 0) {
3953  for (i = *index; i > 0 && e_old[i].timestamp == e_old[i - 1].timestamp;
3954  i--) {
3955  if ((flag & AVSEEK_FLAG_ANY) ||
3956  (e_old[i - 1].flags & AVINDEX_KEYFRAME)) {
3957  *index = i - 1;
3958  }
3959  }
3960  }
3961 
3962  // If we have CTTS then refine the search, by searching backwards over PTS
3963  // computed by adding corresponding CTTS durations to index timestamps.
3964  if (msc->ctts_count && *index >= 0) {
3965  av_assert0(tts_index);
3966  av_assert0(tts_sample);
3967  // Find out the ctts_index for the found frame.
3968  *tts_index = 0;
3969  *tts_sample = 0;
3970  for (int64_t index_tts_count = 0; index_tts_count < *index; index_tts_count++) {
3971  if (*tts_index < tts_count) {
3972  (*tts_sample)++;
3973  if (tts_data[*tts_index].count == *tts_sample) {
3974  (*tts_index)++;
3975  *tts_sample = 0;
3976  }
3977  }
3978  }
3979 
3980  while (*index >= 0 && (*tts_index) >= 0 && (*tts_index) < tts_count) {
3981  // Find a "key frame" with PTS <= timestamp_pts (So that we can decode B-frames correctly).
3982  // No need to add dts_shift to the timestamp here because timestamp_pts has already been
3983  // compensated by dts_shift above.
3984  if ((e_old[*index].timestamp + tts_data[*tts_index].offset) <= timestamp_pts &&
3985  (e_old[*index].flags & AVINDEX_KEYFRAME)) {
3986  break;
3987  }
3988 
3989  (*index)--;
3990  if (*tts_sample == 0) {
3991  (*tts_index)--;
3992  if (*tts_index >= 0)
3993  *tts_sample = tts_data[*tts_index].count - 1;
3994  } else {
3995  (*tts_sample)--;
3996  }
3997  }
3998  }
3999 
4000  /* restore AVStream state*/
4001  sti->index_entries = e_keep;
4002  sti->nb_index_entries = nb_keep;
4003  return *index >= 0 ? 0 : -1;
4004 }
4005 
4006 /**
4007  * Add index entry with the given values, to the end of ffstream(st)->index_entries.
4008  * Returns the new size ffstream(st)->index_entries if successful, else returns -1.
4009  *
4010  * This function is similar to ff_add_index_entry in libavformat/utils.c
4011  * except that here we are always unconditionally adding an index entry to
4012  * the end, instead of searching the entries list and skipping the add if
4013  * there is an existing entry with the same timestamp.
4014  * This is needed because the mov_fix_index calls this func with the same
4015  * unincremented timestamp for successive discarded frames.
4016  */
4018  int size, int distance, int flags)
4019 {
4020  FFStream *const sti = ffstream(st);
4021  AVIndexEntry *entries, *ie;
4022  int64_t index = -1;
4023  const size_t min_size_needed = (sti->nb_index_entries + 1) * sizeof(AVIndexEntry);
4024 
4025  // Double the allocation each time, to lower memory fragmentation.
4026  // Another difference from ff_add_index_entry function.
4027  const size_t requested_size =
4028  min_size_needed > sti->index_entries_allocated_size ?
4029  FFMAX(min_size_needed, 2 * sti->index_entries_allocated_size) :
4030  min_size_needed;
4031 
4032  if (sti->nb_index_entries + 1U >= UINT_MAX / sizeof(AVIndexEntry))
4033  return -1;
4034 
4035  entries = av_fast_realloc(sti->index_entries,
4037  requested_size);
4038  if (!entries)
4039  return -1;
4040 
4041  sti->index_entries = entries;
4042 
4043  index = sti->nb_index_entries++;
4044  ie= &entries[index];
4045 
4046  ie->pos = pos;
4047  ie->timestamp = timestamp;
4048  ie->min_distance= distance;
4049  ie->size= size;
4050  ie->flags = flags;
4051  return index;
4052 }
4053 
4054 /**
4055  * Rewrite timestamps of index entries in the range [end_index - frame_duration_buffer_size, end_index)
4056  * by subtracting end_ts successively by the amounts given in frame_duration_buffer.
4057  */
4058 static void fix_index_entry_timestamps(AVStream* st, int end_index, int64_t end_ts,
4059  int64_t* frame_duration_buffer,
4060  int frame_duration_buffer_size) {
4061  FFStream *const sti = ffstream(st);
4062  int i = 0;
4063  av_assert0(end_index >= 0 && end_index <= sti->nb_index_entries);
4064  for (i = 0; i < frame_duration_buffer_size; i++) {
4065  end_ts -= frame_duration_buffer[frame_duration_buffer_size - 1 - i];
4066  sti->index_entries[end_index - 1 - i].timestamp = end_ts;
4067  }
4068 }
4069 
4070 static int add_tts_entry(MOVTimeToSample **tts_data, unsigned int *tts_count, unsigned int *allocated_size,
4071  int count, int offset, unsigned int duration)
4072 {
4073  MOVTimeToSample *tts_buf_new;
4074  const size_t min_size_needed = (*tts_count + 1) * sizeof(MOVTimeToSample);
4075  const size_t requested_size =
4076  min_size_needed > *allocated_size ?
4077  FFMAX(min_size_needed, 2 * (*allocated_size)) :
4078  min_size_needed;
4079 
4080  if ((unsigned)(*tts_count) >= UINT_MAX / sizeof(MOVTimeToSample) - 1)
4081  return -1;
4082 
4083  tts_buf_new = av_fast_realloc(*tts_data, allocated_size, requested_size);
4084 
4085  if (!tts_buf_new)
4086  return -1;
4087 
4088  *tts_data = tts_buf_new;
4089 
4090  tts_buf_new[*tts_count].count = count;
4091  tts_buf_new[*tts_count].offset = offset;
4092  tts_buf_new[*tts_count].duration = duration;
4093 
4094  *tts_count = (*tts_count) + 1;
4095  return 0;
4096 }
4097 
4098 #define MAX_REORDER_DELAY 16
4100 {
4101  MOVStreamContext *msc = st->priv_data;
4102  FFStream *const sti = ffstream(st);
4103  int ctts_ind = 0;
4104  int ctts_sample = 0;
4105  int64_t pts_buf[MAX_REORDER_DELAY + 1]; // Circular buffer to sort pts.
4106  int buf_start = 0;
4107  int j, r, num_swaps;
4108 
4109  for (j = 0; j < MAX_REORDER_DELAY + 1; j++)
4110  pts_buf[j] = INT64_MIN;
4111 
4112  if (st->codecpar->video_delay <= 0 && msc->ctts_count &&
4114  st->codecpar->video_delay = 0;
4115  for (int ind = 0; ind < sti->nb_index_entries && ctts_ind < msc->tts_count; ++ind) {
4116  // Point j to the last elem of the buffer and insert the current pts there.
4117  j = buf_start;
4118  buf_start = (buf_start + 1);
4119  if (buf_start == MAX_REORDER_DELAY + 1)
4120  buf_start = 0;
4121 
4122  pts_buf[j] = sti->index_entries[ind].timestamp + msc->tts_data[ctts_ind].offset;
4123 
4124  // The timestamps that are already in the sorted buffer, and are greater than the
4125  // current pts, are exactly the timestamps that need to be buffered to output PTS
4126  // in correct sorted order.
4127  // Hence the video delay (which is the buffer size used to sort DTS and output PTS),
4128  // can be computed as the maximum no. of swaps any particular timestamp needs to
4129  // go through, to keep this buffer in sorted order.
4130  num_swaps = 0;
4131  while (j != buf_start) {
4132  r = j - 1;
4133  if (r < 0) r = MAX_REORDER_DELAY;
4134  if (pts_buf[j] < pts_buf[r]) {
4135  FFSWAP(int64_t, pts_buf[j], pts_buf[r]);
4136  ++num_swaps;
4137  } else {
4138  break;
4139  }
4140  j = r;
4141  }
4142  st->codecpar->video_delay = FFMAX(st->codecpar->video_delay, num_swaps);
4143 
4144  ctts_sample++;
4145  if (ctts_sample == msc->tts_data[ctts_ind].count) {
4146  ctts_ind++;
4147  ctts_sample = 0;
4148  }
4149  }
4150  av_log(c->fc, AV_LOG_DEBUG, "Setting codecpar->delay to %d for stream st: %d\n",
4151  st->codecpar->video_delay, st->index);
4152  }
4153 }
4154 
4156 {
4157  sc->current_sample++;
4158  sc->current_index++;
4159  if (sc->index_ranges &&
4160  sc->current_index >= sc->current_index_range->end &&
4161  sc->current_index_range->end) {
4162  sc->current_index_range++;
4164  }
4165 }
4166 
4168 {
4169  sc->current_sample--;
4170  sc->current_index--;
4171  if (sc->index_ranges &&
4173  sc->current_index_range > sc->index_ranges) {
4174  sc->current_index_range--;
4175  sc->current_index = sc->current_index_range->end - 1;
4176  }
4177 }
4178 
4179 static void mov_current_sample_set(MOVStreamContext *sc, int current_sample)
4180 {
4181  int64_t range_size;
4182 
4183  sc->current_sample = current_sample;
4184  sc->current_index = current_sample;
4185  if (!sc->index_ranges) {
4186  return;
4187  }
4188 
4189  for (sc->current_index_range = sc->index_ranges;
4190  sc->current_index_range->end;
4191  sc->current_index_range++) {
4192  range_size = sc->current_index_range->end - sc->current_index_range->start;
4193  if (range_size > current_sample) {
4194  sc->current_index = sc->current_index_range->start + current_sample;
4195  break;
4196  }
4197  current_sample -= range_size;
4198  }
4199 }
4200 
4201 /**
4202  * Fix ffstream(st)->index_entries, so that it contains only the entries (and the entries
4203  * which are needed to decode them) that fall in the edit list time ranges.
4204  * Also fixes the timestamps of the index entries to match the timeline
4205  * specified the edit lists.
4206  */
4207 static void mov_fix_index(MOVContext *mov, AVStream *st)
4208 {
4209  MOVStreamContext *msc = st->priv_data;
4210  FFStream *const sti = ffstream(st);
4211  AVIndexEntry *e_old = sti->index_entries;
4212  int nb_old = sti->nb_index_entries;
4213  const AVIndexEntry *e_old_end = e_old + nb_old;
4214  const AVIndexEntry *current = NULL;
4215  MOVTimeToSample *tts_data_old = msc->tts_data;
4216  int64_t tts_index_old = 0;
4217  int64_t tts_sample_old = 0;
4218  int64_t tts_count_old = msc->tts_count;
4219  int64_t edit_list_media_time = 0;
4220  int64_t edit_list_duration = 0;
4221  int64_t frame_duration = 0;
4222  int64_t edit_list_dts_counter = 0;
4223  int64_t edit_list_dts_entry_end = 0;
4224  int64_t edit_list_start_tts_sample = 0;
4225  int64_t curr_cts;
4226  int64_t curr_ctts = 0;
4227  int64_t empty_edits_sum_duration = 0;
4228  int64_t edit_list_index = 0;
4229  int64_t index;
4230  int flags;
4231  int64_t start_dts = 0;
4232  int64_t edit_list_start_encountered = 0;
4233  int64_t search_timestamp = 0;
4234  int64_t* frame_duration_buffer = NULL;
4235  int num_discarded_begin = 0;
4236  int first_non_zero_audio_edit = -1;
4237  int packet_skip_samples = 0;
4238  MOVIndexRange *current_index_range = NULL;
4239  int found_keyframe_after_edit = 0;
4240  int found_non_empty_edit = 0;
4241 
4242  if (!msc->elst_data || msc->elst_count <= 0 || nb_old <= 0) {
4243  return;
4244  }
4245 
4246  // allocate the index ranges array
4247  msc->index_ranges = av_malloc_array(msc->elst_count + 1,
4248  sizeof(msc->index_ranges[0]));
4249  if (!msc->index_ranges) {
4250  av_log(mov->fc, AV_LOG_ERROR, "Cannot allocate index ranges buffer\n");
4251  return;
4252  }
4253  msc->current_index_range = msc->index_ranges;
4254 
4255  // Clean AVStream from traces of old index
4256  sti->index_entries = NULL;
4258  sti->nb_index_entries = 0;
4259 
4260  // Clean time to sample fields of MOVStreamContext
4261  msc->tts_data = NULL;
4262  msc->tts_count = 0;
4263  msc->tts_index = 0;
4264  msc->tts_sample = 0;
4265  msc->tts_allocated_size = 0;
4266 
4267  // Reinitialize min_corrected_pts so that it can be computed again.
4268  msc->min_corrected_pts = -1;
4269 
4270  // If the dts_shift is positive (in case of negative ctts values in mov),
4271  // then negate the DTS by dts_shift
4272  if (msc->dts_shift > 0) {
4273  edit_list_dts_entry_end -= msc->dts_shift;
4274  av_log(mov->fc, AV_LOG_DEBUG, "Shifting DTS by %d because of negative CTTS.\n", msc->dts_shift);
4275  }
4276 
4277  start_dts = edit_list_dts_entry_end;
4278 
4279  while (get_edit_list_entry(mov, msc, edit_list_index, &edit_list_media_time,
4280  &edit_list_duration, mov->time_scale)) {
4281  av_log(mov->fc, AV_LOG_DEBUG, "Processing st: %d, edit list %"PRId64" - media time: %"PRId64", duration: %"PRId64"\n",
4282  st->index, edit_list_index, edit_list_media_time, edit_list_duration);
4283  edit_list_index++;
4284  edit_list_dts_counter = edit_list_dts_entry_end;
4285  edit_list_dts_entry_end += edit_list_duration;
4286  num_discarded_begin = 0;
4287  if (!found_non_empty_edit && edit_list_media_time == -1) {
4288  empty_edits_sum_duration += edit_list_duration;
4289  continue;
4290  }
4291  found_non_empty_edit = 1;
4292 
4293  // If we encounter a non-negative edit list reset the skip_samples/start_pad fields and set them
4294  // according to the edit list below.
4295  if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
4296  if (first_non_zero_audio_edit < 0) {
4297  first_non_zero_audio_edit = 1;
4298  } else {
4299  first_non_zero_audio_edit = 0;
4300  }
4301 
4302  if (first_non_zero_audio_edit > 0)
4303  sti->skip_samples = msc->start_pad = 0;
4304  }
4305 
4306  // While reordering frame index according to edit list we must handle properly
4307  // the scenario when edit list entry starts from none key frame.
4308  // We find closest previous key frame and preserve it and consequent frames in index.
4309  // All frames which are outside edit list entry time boundaries will be dropped after decoding.
4310  search_timestamp = edit_list_media_time;
4311  if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
4312  // Audio decoders like AAC need need a decoder delay samples previous to the current sample,
4313  // to correctly decode this frame. Hence for audio we seek to a frame 1 sec. before the
4314  // edit_list_media_time to cover the decoder delay.
4315  search_timestamp = FFMAX(search_timestamp - msc->time_scale, e_old[0].timestamp);
4316  }
4317 
4318  if (find_prev_closest_index(st, e_old, nb_old, tts_data_old, tts_count_old, search_timestamp, 0,
4319  &index, &tts_index_old, &tts_sample_old) < 0) {
4320  av_log(mov->fc, AV_LOG_WARNING,
4321  "st: %d edit list: %"PRId64" Missing key frame while searching for timestamp: %"PRId64"\n",
4322  st->index, edit_list_index, search_timestamp);
4323  if (find_prev_closest_index(st, e_old, nb_old, tts_data_old, tts_count_old, search_timestamp, AVSEEK_FLAG_ANY,
4324  &index, &tts_index_old, &tts_sample_old) < 0) {
4325  av_log(mov->fc, AV_LOG_WARNING,
4326  "st: %d edit list %"PRId64" Cannot find an index entry before timestamp: %"PRId64".\n",
4327  st->index, edit_list_index, search_timestamp);
4328  index = 0;
4329  tts_index_old = 0;
4330  tts_sample_old = 0;
4331  }
4332  }
4333  current = e_old + index;
4334  edit_list_start_tts_sample = tts_sample_old;
4335 
4336  // Iterate over index and arrange it according to edit list
4337  edit_list_start_encountered = 0;
4338  found_keyframe_after_edit = 0;
4339  for (; current < e_old_end; current++, index++) {
4340  // check if frame outside edit list mark it for discard
4341  frame_duration = (current + 1 < e_old_end) ?
4342  ((current + 1)->timestamp - current->timestamp) : edit_list_duration;
4343 
4344  flags = current->flags;
4345 
4346  // frames (pts) before or after edit list
4347  curr_cts = current->timestamp + msc->dts_shift;
4348  curr_ctts = 0;
4349 
4350  if (tts_data_old && tts_index_old < tts_count_old) {
4351  curr_ctts = tts_data_old[tts_index_old].offset;
4352  av_log(mov->fc, AV_LOG_TRACE, "stts: %"PRId64" ctts: %"PRId64", tts_index: %"PRId64", tts_count: %"PRId64"\n",
4353  curr_cts, curr_ctts, tts_index_old, tts_count_old);
4354  curr_cts += curr_ctts;
4355  tts_sample_old++;
4356  if (tts_sample_old == tts_data_old[tts_index_old].count) {
4357  if (add_tts_entry(&msc->tts_data, &msc->tts_count,
4358  &msc->tts_allocated_size,
4359  tts_data_old[tts_index_old].count - edit_list_start_tts_sample,
4360  tts_data_old[tts_index_old].offset, tts_data_old[tts_index_old].duration) == -1) {
4361  av_log(mov->fc, AV_LOG_ERROR, "Cannot add Time To Sample entry %"PRId64" - {%"PRId64", %d}\n",
4362  tts_index_old,
4363  tts_data_old[tts_index_old].count - edit_list_start_tts_sample,
4364  tts_data_old[tts_index_old].offset);
4365  break;
4366  }
4367  tts_index_old++;
4368  tts_sample_old = 0;
4369  edit_list_start_tts_sample = 0;
4370  }
4371  }
4372 
4373  if (curr_cts < edit_list_media_time || curr_cts >= (edit_list_duration + edit_list_media_time)) {
4375  curr_cts < edit_list_media_time && curr_cts + frame_duration > edit_list_media_time &&
4376  first_non_zero_audio_edit > 0) {
4377  packet_skip_samples = edit_list_media_time - curr_cts;
4378  sti->skip_samples += packet_skip_samples;
4379 
4380  // Shift the index entry timestamp by packet_skip_samples to be correct.
4381  edit_list_dts_counter -= packet_skip_samples;
4382  if (edit_list_start_encountered == 0) {
4383  edit_list_start_encountered = 1;
4384  // Make timestamps strictly monotonically increasing for audio, by rewriting timestamps for
4385  // discarded packets.
4386  if (frame_duration_buffer) {
4387  fix_index_entry_timestamps(st, sti->nb_index_entries, edit_list_dts_counter,
4388  frame_duration_buffer, num_discarded_begin);
4389  av_freep(&frame_duration_buffer);
4390  }
4391  }
4392 
4393  av_log(mov->fc, AV_LOG_DEBUG, "skip %d audio samples from curr_cts: %"PRId64"\n", packet_skip_samples, curr_cts);
4394  } else {
4396  av_log(mov->fc, AV_LOG_DEBUG, "drop a frame at curr_cts: %"PRId64" @ %"PRId64"\n", curr_cts, index);
4397 
4398  if (edit_list_start_encountered == 0) {
4399  num_discarded_begin++;
4400  frame_duration_buffer = av_realloc(frame_duration_buffer,
4401  num_discarded_begin * sizeof(int64_t));
4402  if (!frame_duration_buffer) {
4403  av_log(mov->fc, AV_LOG_ERROR, "Cannot reallocate frame duration buffer\n");
4404  break;
4405  }
4406  frame_duration_buffer[num_discarded_begin - 1] = frame_duration;
4407 
4408  // Increment skip_samples for the first non-zero audio edit list
4409  if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
4410  first_non_zero_audio_edit > 0 && st->codecpar->codec_id != AV_CODEC_ID_VORBIS) {
4411  sti->skip_samples += frame_duration;
4412  }
4413  }
4414  }
4415  } else {
4416  if (msc->min_corrected_pts < 0) {
4417  msc->min_corrected_pts = edit_list_dts_counter + curr_ctts + msc->dts_shift;
4418  } else {
4419  msc->min_corrected_pts = FFMIN(msc->min_corrected_pts, edit_list_dts_counter + curr_ctts + msc->dts_shift);
4420  }
4421  if (edit_list_start_encountered == 0) {
4422  edit_list_start_encountered = 1;
4423  // Make timestamps strictly monotonically increasing by rewriting timestamps for
4424  // discarded packets.
4425  if (frame_duration_buffer) {
4426  fix_index_entry_timestamps(st, sti->nb_index_entries, edit_list_dts_counter,
4427  frame_duration_buffer, num_discarded_begin);
4428  av_freep(&frame_duration_buffer);
4429  }
4430  }
4431  }
4432 
4433  if (add_index_entry(st, current->pos, edit_list_dts_counter, current->size,
4434  current->min_distance, flags) == -1) {
4435  av_log(mov->fc, AV_LOG_ERROR, "Cannot add index entry\n");
4436  break;
4437  }
4438 
4439  // Update the index ranges array
4440  if (!current_index_range || index != current_index_range->end) {
4441  current_index_range = current_index_range ? current_index_range + 1
4442  : msc->index_ranges;
4443  current_index_range->start = index;
4444  }
4445  current_index_range->end = index + 1;
4446 
4447  // Only start incrementing DTS in frame_duration amounts, when we encounter a frame in edit list.
4448  if (edit_list_start_encountered > 0) {
4449  edit_list_dts_counter = edit_list_dts_counter + frame_duration;
4450  }
4451 
4452  // Break when found first key frame after edit entry completion
4453  if ((curr_cts + frame_duration >= (edit_list_duration + edit_list_media_time)) &&
4455  if (msc->ctts_count) {
4456  // If we have CTTS and this is the first keyframe after edit elist,
4457  // wait for one more, because there might be trailing B-frames after this I-frame
4458  // that do belong to the edit.
4459  if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO && found_keyframe_after_edit == 0) {
4460  found_keyframe_after_edit = 1;
4461  continue;
4462  }
4463  if (tts_sample_old != 0) {
4464  if (add_tts_entry(&msc->tts_data, &msc->tts_count,
4465  &msc->tts_allocated_size,
4466  tts_sample_old - edit_list_start_tts_sample,
4467  tts_data_old[tts_index_old].offset, tts_data_old[tts_index_old].duration) == -1) {
4468  av_log(mov->fc, AV_LOG_ERROR, "Cannot add Time To Sample entry %"PRId64" - {%"PRId64", %d}\n",
4469  tts_index_old, tts_sample_old - edit_list_start_tts_sample,
4470  tts_data_old[tts_index_old].offset);
4471  break;
4472  }
4473  }
4474  }
4475  break;
4476  }
4477  }
4478  }
4479  // If there are empty edits, then msc->min_corrected_pts might be positive
4480  // intentionally. So we subtract the sum duration of empty edits here.
4481  msc->min_corrected_pts -= empty_edits_sum_duration;
4482 
4483  // If the minimum pts turns out to be greater than zero after fixing the index, then we subtract the
4484  // dts by that amount to make the first pts zero.
4485  if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
4486  if (msc->min_corrected_pts > 0) {
4487  av_log(mov->fc, AV_LOG_DEBUG, "Offset DTS by %"PRId64" to make first pts zero.\n", msc->min_corrected_pts);
4488  for (int i = 0; i < sti->nb_index_entries; ++i)
4490  }
4491  }
4492  // Start time should be equal to zero or the duration of any empty edits.
4493  st->start_time = empty_edits_sum_duration;
4494 
4495  // Update av stream length, if it ends up shorter than the track's media duration
4496  st->duration = FFMIN(st->duration, edit_list_dts_entry_end - start_dts);
4497  msc->start_pad = sti->skip_samples;
4498 
4499  // Free the old index and the old CTTS structures
4500  av_free(e_old);
4501  av_free(tts_data_old);
4502  av_freep(&frame_duration_buffer);
4503 
4504  // Null terminate the index ranges array
4505  current_index_range = current_index_range ? current_index_range + 1
4506  : msc->index_ranges;
4507  current_index_range->start = 0;
4508  current_index_range->end = 0;
4509  msc->current_index = msc->index_ranges[0].start;
4510 }
4511 
4512 static uint32_t get_sgpd_sync_index(const MOVStreamContext *sc, int nal_unit_type)
4513 {
4514  for (uint32_t i = 0; i < sc->sgpd_sync_count; i++)
4515  if (sc->sgpd_sync[i] == nal_unit_type)
4516  return i + 1;
4517  return 0;
4518 }
4519 
4521 {
4522  int k;
4523  int sample_id = 0;
4524  uint32_t cra_index;
4525  MOVStreamContext *sc = st->priv_data;
4526 
4527  if (st->codecpar->codec_id != AV_CODEC_ID_HEVC || !sc->sync_group_count)
4528  return 0;
4529 
4530  /* Build an unrolled index of the samples */
4531  sc->sample_offsets_count = 0;
4532  for (uint32_t i = 0; i < sc->ctts_count; i++) {
4533  if (sc->ctts_data[i].count > INT_MAX - sc->sample_offsets_count)
4534  return AVERROR(ENOMEM);
4535  sc->sample_offsets_count += sc->ctts_data[i].count;
4536  }
4537  av_freep(&sc->sample_offsets);
4539  if (!sc->sample_offsets)
4540  return AVERROR(ENOMEM);
4541  k = 0;
4542  for (uint32_t i = 0; i < sc->ctts_count; i++)
4543  for (int j = 0; j < sc->ctts_data[i].count; j++)
4544  sc->sample_offsets[k++] = sc->ctts_data[i].offset;
4545 
4546  /* The following HEVC NAL type reveal the use of open GOP sync points
4547  * (TODO: BLA types may also be concerned) */
4548  cra_index = get_sgpd_sync_index(sc, HEVC_NAL_CRA_NUT); /* Clean Random Access */
4549  if (!cra_index)
4550  return 0;
4551 
4552  /* Build a list of open-GOP key samples */
4553  sc->open_key_samples_count = 0;
4554  for (uint32_t i = 0; i < sc->sync_group_count; i++)
4555  if (sc->sync_group[i].index == cra_index) {
4556  if (sc->sync_group[i].count > INT_MAX - sc->open_key_samples_count)
4557  return AVERROR(ENOMEM);
4559  }
4560  av_freep(&sc->open_key_samples);
4562  if (!sc->open_key_samples)
4563  return AVERROR(ENOMEM);
4564  k = 0;
4565  for (uint32_t i = 0; i < sc->sync_group_count; i++) {
4566  const MOVSbgp *sg = &sc->sync_group[i];
4567  if (sg->index == cra_index)
4568  for (uint32_t j = 0; j < sg->count; j++)
4569  sc->open_key_samples[k++] = sample_id;
4570  if (sg->count > INT_MAX - sample_id)
4571  return AVERROR_PATCHWELCOME;
4572  sample_id += sg->count;
4573  }
4574 
4575  /* Identify the minimal time step between samples */
4576  sc->min_sample_duration = UINT_MAX;
4577  for (uint32_t i = 0; i < sc->stts_count; i++)
4579 
4580  return 0;
4581 }
4582 
4583 #define MOV_MERGE_CTTS 1
4584 #define MOV_MERGE_STTS 2
4585 /*
4586  * Merge stts and ctts arrays into a new combined array.
4587  * stts_count and ctts_count may be left untouched as they will be
4588  * used to check for the presence of either of them.
4589  */
4590 static int mov_merge_tts_data(MOVContext *mov, AVStream *st, int flags)
4591 {
4592  MOVStreamContext *sc = st->priv_data;
4593  int ctts = sc->ctts_data && (flags & MOV_MERGE_CTTS);
4594  int stts = sc->stts_data && (flags & MOV_MERGE_STTS);
4595  int idx = 0;
4596 
4597  if (!sc->ctts_data && !sc->stts_data)
4598  return 0;
4599  // Expand time to sample entries such that we have a 1-1 mapping with samples
4600  if (!sc->sample_count || sc->sample_count >= UINT_MAX / sizeof(*sc->tts_data))
4601  return -1;
4602 
4603  if (ctts) {
4605  sc->sample_count * sizeof(*sc->tts_data));
4606  if (!sc->tts_data)
4607  return -1;
4608 
4609  memset(sc->tts_data, 0, sc->tts_allocated_size);
4610 
4611  for (int i = 0; i < sc->ctts_count &&
4612  idx < sc->sample_count; i++)
4613  for (int j = 0; j < sc->ctts_data[i].count &&
4614  idx < sc->sample_count; j++) {
4615  sc->tts_data[idx].offset = sc->ctts_data[i].offset;
4616  sc->tts_data[idx++].count = 1;
4617  }
4618 
4619  sc->tts_count = idx;
4620  } else
4621  sc->ctts_count = 0;
4622  av_freep(&sc->ctts_data);
4623  sc->ctts_allocated_size = 0;
4624 
4625  idx = 0;
4626  if (stts) {
4628  sc->sample_count * sizeof(*sc->tts_data));
4629  if (!tts_data)
4630  return -1;
4631 
4632  if (!sc->tts_data)
4633  memset(tts_data, 0, sc->tts_allocated_size);
4634  sc->tts_data = tts_data;
4635 
4636  for (int i = 0; i < sc->stts_count &&
4637  idx < sc->sample_count; i++)
4638  for (int j = 0; j < sc->stts_data[i].count &&
4639  idx < sc->sample_count; j++) {
4640  sc->tts_data[idx].duration = sc->stts_data[i].duration;
4641  sc->tts_data[idx++].count = 1;
4642  }
4643 
4644  sc->tts_count = FFMAX(sc->tts_count, idx);
4645  } else
4646  sc->stts_count = 0;
4647  av_freep(&sc->stts_data);
4648  sc->stts_allocated_size = 0;
4649 
4650  return 0;
4651 }
4652 
4653 static void mov_build_index(MOVContext *mov, AVStream *st)
4654 {
4655  MOVStreamContext *sc = st->priv_data;
4656  FFStream *const sti = ffstream(st);
4657  int64_t current_offset;
4658  int64_t current_dts = 0;
4659  unsigned int stts_index = 0;
4660  unsigned int stsc_index = 0;
4661  unsigned int stss_index = 0;
4662  unsigned int stps_index = 0;
4663  unsigned int i, j;
4664  uint64_t stream_size = 0;
4665 
4666  int ret = build_open_gop_key_points(st);
4667  if (ret < 0)
4668  return;
4669 
4670  if (sc->elst_count) {
4671  int i, edit_start_index = 0, multiple_edits = 0;
4672  int64_t empty_duration = 0; // empty duration of the first edit list entry
4673  int64_t start_time = 0; // start time of the media
4674 
4675  for (i = 0; i < sc->elst_count; i++) {
4676  const MOVElst *e = &sc->elst_data[i];
4677  if (i == 0 && e->time == -1) {
4678  /* if empty, the first entry is the start time of the stream
4679  * relative to the presentation itself */
4680  empty_duration = e->duration;
4681  edit_start_index = 1;
4682  } else if (i == edit_start_index && e->time >= 0) {
4683  start_time = e->time;
4684  } else {
4685  multiple_edits = 1;
4686  }
4687  }
4688 
4689  if (multiple_edits && !mov->advanced_editlist) {
4691  av_log(mov->fc, AV_LOG_WARNING, "multiple edit list entries, "
4692  "not supported in fragmented MP4 files\n");
4693  else
4694  av_log(mov->fc, AV_LOG_WARNING, "multiple edit list entries, "
4695  "Use -advanced_editlist to correctly decode otherwise "
4696  "a/v desync might occur\n");
4697  }
4698 
4699  /* adjust first dts according to edit list */
4700  if ((empty_duration || start_time) && mov->time_scale > 0) {
4701  if (empty_duration)
4702  empty_duration = av_rescale(empty_duration, sc->time_scale, mov->time_scale);
4703 
4704  if (av_sat_sub64(start_time, empty_duration) != start_time - (uint64_t)empty_duration)
4705  av_log(mov->fc, AV_LOG_WARNING, "start_time - empty_duration is not representable\n");
4706 
4707  sc->time_offset = start_time - (uint64_t)empty_duration;
4709  if (!mov->advanced_editlist)
4710  current_dts = -sc->time_offset;
4711  }
4712 
4713  if (!multiple_edits && !mov->advanced_editlist &&
4715  sc->start_pad = start_time;
4716  }
4717 
4718  /* only use old uncompressed audio chunk demuxing when stts specifies it */
4719  if (!(st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
4720  sc->stts_count == 1 && sc->stts_data && sc->stts_data[0].duration == 1)) {
4721  unsigned int current_sample = 0;
4722  unsigned int stts_sample = 0;
4723  unsigned int sample_size;
4724  unsigned int distance = 0;
4725  unsigned int rap_group_index = 0;
4726  unsigned int rap_group_sample = 0;
4727  int rap_group_present = sc->rap_group_count && sc->rap_group;
4728  int key_off = (sc->keyframe_count && sc->keyframes[0] > 0) || (sc->stps_count && sc->stps_data[0] > 0);
4729 
4730  current_dts -= sc->dts_shift;
4731 
4732  if (!sc->sample_count || sti->nb_index_entries || sc->tts_count)
4733  return;
4734  if (sc->sample_count >= UINT_MAX / sizeof(*sti->index_entries) - sti->nb_index_entries)
4735  return;
4736  if (av_reallocp_array(&sti->index_entries,
4737  sti->nb_index_entries + sc->sample_count,
4738  sizeof(*sti->index_entries)) < 0) {
4739  sti->nb_index_entries = 0;
4740  return;
4741  }
4742  sti->index_entries_allocated_size = (sti->nb_index_entries + sc->sample_count) * sizeof(*sti->index_entries);
4743 
4745  if (ret < 0)
4746  return;
4747 
4748  for (i = 0; i < sc->chunk_count; i++) {
4749  int64_t next_offset = i+1 < sc->chunk_count ? sc->chunk_offsets[i+1] : INT64_MAX;
4750  current_offset = sc->chunk_offsets[i];
4751  while (mov_stsc_index_valid(stsc_index, sc->stsc_count) &&
4752  i + 1 == sc->stsc_data[stsc_index + 1].first)
4753  stsc_index++;
4754 
4755  if (next_offset > current_offset && sc->sample_size>0 && sc->sample_size < sc->stsz_sample_size &&
4756  sc->stsc_data[stsc_index].count * (int64_t)sc->stsz_sample_size > next_offset - current_offset) {
4757  av_log(mov->fc, AV_LOG_WARNING, "STSZ sample size %d invalid (too large), ignoring\n", sc->stsz_sample_size);
4758  sc->stsz_sample_size = sc->sample_size;
4759  }
4760  if (sc->stsz_sample_size>0 && sc->stsz_sample_size < sc->sample_size) {
4761  av_log(mov->fc, AV_LOG_WARNING, "STSZ sample size %d invalid (too small), ignoring\n", sc->stsz_sample_size);
4762  sc->stsz_sample_size = sc->sample_size;
4763  }
4764 
4765  for (j = 0; j < sc->stsc_data[stsc_index].count; j++) {
4766  int keyframe = 0;
4767  if (current_sample >= sc->sample_count) {
4768  av_log(mov->fc, AV_LOG_ERROR, "wrong sample count\n");
4769  return;
4770  }
4771 
4772  if (!sc->keyframe_absent && (!sc->keyframe_count || current_sample+key_off == sc->keyframes[stss_index])) {
4773  keyframe = 1;
4774  if (stss_index + 1 < sc->keyframe_count)
4775  stss_index++;
4776  } else if (sc->stps_count && current_sample+key_off == sc->stps_data[stps_index]) {
4777  keyframe = 1;
4778  if (stps_index + 1 < sc->stps_count)
4779  stps_index++;
4780  }
4781  if (rap_group_present && rap_group_index < sc->rap_group_count) {
4782  if (sc->rap_group[rap_group_index].index > 0)
4783  keyframe = 1;
4784  if (++rap_group_sample == sc->rap_group[rap_group_index].count) {
4785  rap_group_sample = 0;
4786  rap_group_index++;
4787  }
4788  }
4789  if (sc->keyframe_absent
4790  && !sc->stps_count
4791  && !rap_group_present
4792  && (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO || (i==0 && j==0)))
4793  keyframe = 1;
4794  if (keyframe)
4795  distance = 0;
4796  sample_size = sc->stsz_sample_size > 0 ? sc->stsz_sample_size : sc->sample_sizes[current_sample];
4797  if (current_offset > INT64_MAX - sample_size) {
4798  av_log(mov->fc, AV_LOG_ERROR, "Current offset %"PRId64" or sample size %u is too large\n",
4799  current_offset,
4800  sample_size);
4801  return;
4802  }
4803 
4804  if (sc->pseudo_stream_id == -1 ||
4805  sc->stsc_data[stsc_index].id - 1 == sc->pseudo_stream_id) {
4806  AVIndexEntry *e;
4807  if (sample_size > 0x3FFFFFFF) {
4808  av_log(mov->fc, AV_LOG_ERROR, "Sample size %u is too large\n", sample_size);
4809  return;
4810  }
4811  e = &sti->index_entries[sti->nb_index_entries++];
4812  e->pos = current_offset;
4813  e->timestamp = current_dts;
4814  e->size = sample_size;
4815  e->min_distance = distance;
4816  e->flags = keyframe ? AVINDEX_KEYFRAME : 0;
4817  av_log(mov->fc, AV_LOG_TRACE, "AVIndex stream %d, sample %u, offset %"PRIx64", dts %"PRId64", "
4818  "size %u, distance %u, keyframe %d\n", st->index, current_sample,
4819  current_offset, current_dts, sample_size, distance, keyframe);
4820  if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && sti->nb_index_entries < 100)
4821  ff_rfps_add_frame(mov->fc, st, current_dts);
4822  }
4823 
4824  current_offset += sample_size;
4825  stream_size += sample_size;
4826 
4827  current_dts += sc->tts_data[stts_index].duration;
4828 
4829  distance++;
4830  stts_sample++;
4831  current_sample++;
4832  if (stts_index + 1 < sc->tts_count && stts_sample == sc->tts_data[stts_index].count) {
4833  stts_sample = 0;
4834  stts_index++;
4835  }
4836  }
4837  }
4838  if (st->duration > 0)
4839  st->codecpar->bit_rate = stream_size*8*sc->time_scale/st->duration;
4840  } else {
4841  unsigned chunk_samples, total = 0;
4842 
4843  if (!sc->chunk_count || sc->tts_count)
4844  return;
4845 
4846  // compute total chunk count
4847  for (i = 0; i < sc->stsc_count; i++) {
4848  unsigned count, chunk_count;
4849 
4850  chunk_samples = sc->stsc_data[i].count;
4851  if (i != sc->stsc_count - 1 &&
4852  sc->samples_per_frame && chunk_samples % sc->samples_per_frame) {
4853  av_log(mov->fc, AV_LOG_ERROR, "error unaligned chunk\n");
4854  return;
4855  }
4856 
4857  if (sc->samples_per_frame >= 160) { // gsm
4858  count = chunk_samples / sc->samples_per_frame;
4859  } else if (sc->samples_per_frame > 1) {
4860  unsigned samples = (1024/sc->samples_per_frame)*sc->samples_per_frame;
4861  count = (chunk_samples+samples-1) / samples;
4862  } else {
4863  count = (chunk_samples+1023) / 1024;
4864  }
4865 
4866  if (mov_stsc_index_valid(i, sc->stsc_count))
4867  chunk_count = sc->stsc_data[i+1].first - sc->stsc_data[i].first;
4868  else
4869  chunk_count = sc->chunk_count - (sc->stsc_data[i].first - 1);
4870  total += chunk_count * count;
4871  }
4872 
4873  av_log(mov->fc, AV_LOG_TRACE, "chunk count %u\n", total);
4874  if (total >= UINT_MAX / sizeof(*sti->index_entries) - sti->nb_index_entries)
4875  return;
4876  if (av_reallocp_array(&sti->index_entries,
4877  sti->nb_index_entries + total,
4878  sizeof(*sti->index_entries)) < 0) {
4879  sti->nb_index_entries = 0;
4880  return;
4881  }
4882  sti->index_entries_allocated_size = (sti->nb_index_entries + total) * sizeof(*sti->index_entries);
4883 
4884  // populate index
4885  for (i = 0; i < sc->chunk_count; i++) {
4886  current_offset = sc->chunk_offsets[i];
4887  if (mov_stsc_index_valid(stsc_index, sc->stsc_count) &&
4888  i + 1 == sc->stsc_data[stsc_index + 1].first)
4889  stsc_index++;
4890  chunk_samples = sc->stsc_data[stsc_index].count;
4891 
4892  while (chunk_samples > 0) {
4893  AVIndexEntry *e;
4894  unsigned size, samples;
4895 
4896  if (sc->samples_per_frame > 1 && !sc->bytes_per_frame) {
4898  "Zero bytes per frame, but %d samples per frame",
4899  sc->samples_per_frame);
4900  return;
4901  }
4902 
4903  if (sc->samples_per_frame >= 160) { // gsm
4904  samples = sc->samples_per_frame;
4905  size = sc->bytes_per_frame;
4906  } else {
4907  if (sc->samples_per_frame > 1) {
4908  samples = FFMIN((1024 / sc->samples_per_frame)*
4909  sc->samples_per_frame, chunk_samples);
4911  } else {
4912  samples = FFMIN(1024, chunk_samples);
4913  size = samples * sc->sample_size;
4914  }
4915  }
4916 
4917  if (sti->nb_index_entries >= total) {
4918  av_log(mov->fc, AV_LOG_ERROR, "wrong chunk count %u\n", total);
4919  return;
4920  }
4921  if (size > 0x3FFFFFFF) {
4922  av_log(mov->fc, AV_LOG_ERROR, "Sample size %u is too large\n", size);
4923  return;
4924  }
4925  e = &sti->index_entries[sti->nb_index_entries++];
4926  e->pos = current_offset;
4927  e->timestamp = current_dts;
4928  e->size = size;
4929  e->min_distance = 0;
4930  e->flags = AVINDEX_KEYFRAME;
4931  av_log(mov->fc, AV_LOG_TRACE, "AVIndex stream %d, chunk %u, offset %"PRIx64", dts %"PRId64", "
4932  "size %u, duration %u\n", st->index, i, current_offset, current_dts,
4933  size, samples);
4934 
4935  current_offset += size;
4936  current_dts += samples;
4937  chunk_samples -= samples;
4938  }
4939  }
4940 
4942  if (ret < 0)
4943  return;
4944  }
4945 
4946  if (!mov->ignore_editlist && mov->advanced_editlist) {
4947  // Fix index according to edit lists.
4948  mov_fix_index(mov, st);
4949  }
4950 
4951  // Update start time of the stream.
4953  st->start_time = sti->index_entries[0].timestamp + sc->dts_shift;
4954  if (sc->tts_data) {
4955  st->start_time += sc->tts_data[0].offset;
4956  }
4957  }
4958 
4959  mov_estimate_video_delay(mov, st);
4960 }
4961 
4962 static int test_same_origin(const char *src, const char *ref) {
4963  char src_proto[64];
4964  char ref_proto[64];
4965  char src_auth[256];
4966  char ref_auth[256];
4967  char src_host[256];
4968  char ref_host[256];
4969  int src_port=-1;
4970  int ref_port=-1;
4971 
4972  av_url_split(src_proto, sizeof(src_proto), src_auth, sizeof(src_auth), src_host, sizeof(src_host), &src_port, NULL, 0, src);
4973  av_url_split(ref_proto, sizeof(ref_proto), ref_auth, sizeof(ref_auth), ref_host, sizeof(ref_host), &ref_port, NULL, 0, ref);
4974 
4975  if (strlen(src) == 0) {
4976  return -1;
4977  } else if (strlen(src_auth) + 1 >= sizeof(src_auth) ||
4978  strlen(ref_auth) + 1 >= sizeof(ref_auth) ||
4979  strlen(src_host) + 1 >= sizeof(src_host) ||
4980  strlen(ref_host) + 1 >= sizeof(ref_host)) {
4981  return 0;
4982  } else if (strcmp(src_proto, ref_proto) ||
4983  strcmp(src_auth, ref_auth) ||
4984  strcmp(src_host, ref_host) ||
4985  src_port != ref_port) {
4986  return 0;
4987  } else
4988  return 1;
4989 }
4990 
4991 static int mov_open_dref(MOVContext *c, AVIOContext **pb, const char *src, MOVDref *ref)
4992 {
4993  /* try relative path, we do not try the absolute because it can leak information about our
4994  system to an attacker */
4995  if (ref->nlvl_to > 0 && ref->nlvl_from > 0) {
4996  char filename[1025];
4997  const char *src_path;
4998  int i, l;
4999 
5000  /* find a source dir */
5001  src_path = strrchr(src, '/');
5002  if (src_path)
5003  src_path++;
5004  else
5005  src_path = src;
5006 
5007  /* find a next level down to target */
5008  for (i = 0, l = strlen(ref->path) - 1; l >= 0; l--)
5009  if (ref->path[l] == '/') {
5010  if (i == ref->nlvl_to - 1)
5011  break;
5012  else
5013  i++;
5014  }
5015 
5016  /* compose filename if next level down to target was found */
5017  if (i == ref->nlvl_to - 1 && src_path - src < sizeof(filename)) {
5018  memcpy(filename, src, src_path - src);
5019  filename[src_path - src] = 0;
5020 
5021  for (i = 1; i < ref->nlvl_from; i++)
5022  av_strlcat(filename, "../", sizeof(filename));
5023 
5024  av_strlcat(filename, ref->path + l + 1, sizeof(filename));
5025  if (!c->use_absolute_path) {
5026  int same_origin = test_same_origin(src, filename);
5027 
5028  if (!same_origin) {
5029  av_log(c->fc, AV_LOG_ERROR,
5030  "Reference with mismatching origin, %s not tried for security reasons, "
5031  "set demuxer option use_absolute_path to allow it anyway\n",
5032  ref->path);
5033  return AVERROR(ENOENT);
5034  }
5035 
5036  if (strstr(ref->path + l + 1, "..") ||
5037  strstr(ref->path + l + 1, ":") ||
5038  (ref->nlvl_from > 1 && same_origin < 0) ||
5039  (filename[0] == '/' && src_path == src))
5040  return AVERROR(ENOENT);
5041  }
5042 
5043  if (strlen(filename) + 1 == sizeof(filename))
5044  return AVERROR(ENOENT);
5045  if (!c->fc->io_open(c->fc, pb, filename, AVIO_FLAG_READ, NULL))
5046  return 0;
5047  }
5048  } else if (c->use_absolute_path) {
5049  av_log(c->fc, AV_LOG_WARNING, "Using absolute path on user request, "
5050  "this is a possible security issue\n");
5051  if (!c->fc->io_open(c->fc, pb, ref->path, AVIO_FLAG_READ, NULL))
5052  return 0;
5053  } else {
5054  av_log(c->fc, AV_LOG_ERROR,
5055  "Absolute path %s not tried for security reasons, "
5056  "set demuxer option use_absolute_path to allow absolute paths\n",
5057  ref->path);
5058  }
5059 
5060  return AVERROR(ENOENT);
5061 }
5062 
5064 {
5065  if (sc->time_scale <= 0) {
5066  av_log(c->fc, AV_LOG_WARNING, "stream %d, timescale not set\n", sc->ffindex);
5067  sc->time_scale = c->time_scale;
5068  if (sc->time_scale <= 0)
5069  sc->time_scale = 1;
5070  }
5071 }
5072 
5073 #if CONFIG_IAMFDEC
5074 static int mov_update_iamf_streams(MOVContext *c, const AVStream *st)
5075 {
5076  const MOVStreamContext *sc = st->priv_data;
5077  const IAMFContext *iamf = &sc->iamf->iamf;
5078 
5079  for (int i = 0; i < iamf->nb_audio_elements; i++) {
5080  const AVStreamGroup *stg = NULL;
5081 
5082  for (int j = 0; j < c->fc->nb_stream_groups; j++)
5083  if (c->fc->stream_groups[j]->id == iamf->audio_elements[i]->audio_element_id)
5084  stg = c->fc->stream_groups[j];
5085  av_assert0(stg);
5086 
5087  for (int j = 0; j < stg->nb_streams; j++) {
5088  const FFStream *sti = cffstream(st);
5089  AVStream *out = stg->streams[j];
5090  FFStream *out_sti = ffstream(stg->streams[j]);
5091 
5092  out->codecpar->bit_rate = 0;
5093 
5094  if (out == st)
5095  continue;
5096 
5097  out->time_base = st->time_base;
5098  out->start_time = st->start_time;
5099  out->duration = st->duration;
5100  out->nb_frames = st->nb_frames;
5101  out->discard = st->discard;
5102 
5103  av_assert0(!out_sti->index_entries);
5105  if (!out_sti->index_entries)
5106  return AVERROR(ENOMEM);
5107 
5109  out_sti->nb_index_entries = sti->nb_index_entries;
5110  out_sti->skip_samples = sti->skip_samples;
5111  memcpy(out_sti->index_entries, sti->index_entries, sti->index_entries_allocated_size);
5112  }
5113  }
5114 
5115  return 0;
5116 }
5117 #endif
5118 
5119 static int sanity_checks(void *log_obj, MOVStreamContext *sc, int index)
5120 {
5121  if ((sc->chunk_count && (!sc->stts_count || !sc->stsc_count ||
5122  (!sc->sample_size && !sc->sample_count))) ||
5123  (!sc->chunk_count && sc->sample_count)) {
5124  av_log(log_obj, AV_LOG_ERROR, "stream %d, missing mandatory atoms, broken header\n",
5125  index);
5126  return 1;
5127  }
5128 
5129  if (sc->stsc_count && sc->stsc_data[ sc->stsc_count - 1 ].first > sc->chunk_count) {
5130  av_log(log_obj, AV_LOG_ERROR, "stream %d, contradictionary STSC and STCO\n",
5131  index);
5132  return 2;
5133  }
5134  return 0;
5135 }
5136 
5138 {
5139  AVStream *st;
5140  MOVStreamContext *sc;
5141  int ret;
5142 
5143  st = avformat_new_stream(c->fc, NULL);
5144  if (!st) return AVERROR(ENOMEM);
5145  st->id = -1;
5146  sc = av_mallocz(sizeof(MOVStreamContext));
5147  if (!sc) return AVERROR(ENOMEM);
5148 
5149  st->priv_data = sc;
5151  sc->ffindex = st->index;
5152  c->trak_index = st->index;
5153  sc->tref_flags = 0;
5154  sc->tref_id = -1;
5155  sc->refcount = 1;
5156 
5157  if ((ret = mov_read_default(c, pb, atom)) < 0)
5158  return ret;
5159 
5160  c->trak_index = -1;
5161 
5162  // Here stsc refers to a chunk not described in stco. This is technically invalid,
5163  // but we can overlook it (clearing stsc) whenever stts_count == 0 (indicating no samples).
5164  if (!sc->chunk_count && !sc->stts_count && sc->stsc_count) {
5165  sc->stsc_count = 0;
5166  av_freep(&sc->stsc_data);
5167  }
5168 
5169  ret = sanity_checks(c->fc, sc, st->index);
5170  if (ret)
5171  return ret > 1 ? AVERROR_INVALIDDATA : 0;
5172 
5173  fix_timescale(c, sc);
5174 
5175  avpriv_set_pts_info(st, 64, 1, sc->time_scale);
5176 
5177  /*
5178  * Advanced edit list support does not work with fragemented MP4s, which
5179  * have stsc, stsz, stco, and stts with zero entries in the moov atom.
5180  * In these files, trun atoms may be streamed in.
5181  */
5182  if (!sc->stts_count && c->advanced_editlist) {
5183 
5184  av_log(c->fc, AV_LOG_VERBOSE, "advanced_editlist does not work with fragmented "
5185  "MP4. disabling.\n");
5186  c->advanced_editlist = 0;
5187  c->advanced_editlist_autodisabled = 1;
5188  }
5189 
5190  mov_build_index(c, st);
5191 
5192 #if CONFIG_IAMFDEC
5193  if (sc->iamf) {
5194  ret = mov_update_iamf_streams(c, st);
5195  if (ret < 0)
5196  return ret;
5197  }
5198 #endif
5199 
5200  if (sc->dref_id-1 < sc->drefs_count && sc->drefs[sc->dref_id-1].path) {
5201  MOVDref *dref = &sc->drefs[sc->dref_id - 1];
5202  if (c->enable_drefs) {
5203  if (mov_open_dref(c, &sc->pb, c->fc->url, dref) < 0)
5204  av_log(c->fc, AV_LOG_ERROR,
5205  "stream %d, error opening alias: path='%s', dir='%s', "
5206  "filename='%s', volume='%s', nlvl_from=%d, nlvl_to=%d\n",
5207  st->index, dref->path, dref->dir, dref->filename,
5208  dref->volume, dref->nlvl_from, dref->nlvl_to);
5209  } else {
5210  av_log(c->fc, AV_LOG_WARNING,
5211  "Skipped opening external track: "
5212  "stream %d, alias: path='%s', dir='%s', "
5213  "filename='%s', volume='%s', nlvl_from=%d, nlvl_to=%d."
5214  "Set enable_drefs to allow this.\n",
5215  st->index, dref->path, dref->dir, dref->filename,
5216  dref->volume, dref->nlvl_from, dref->nlvl_to);
5217  }
5218  } else {
5219  sc->pb = c->fc->pb;
5220  sc->pb_is_copied = 1;
5221  }
5222 
5223  if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
5224  int stts_constant = sc->stts_count && sc->tts_count;
5225  if (sc->h_spacing && sc->v_spacing)
5227  sc->h_spacing, sc->v_spacing, INT_MAX);
5228  if (!st->sample_aspect_ratio.num && st->codecpar->width && st->codecpar->height &&
5229  sc->height && sc->width &&
5230  (st->codecpar->width != sc->width || st->codecpar->height != sc->height)) {
5232  (int64_t)st->codecpar->height * sc->width,
5233  (int64_t)st->codecpar->width * sc->height, INT_MAX);
5234  }
5235 
5236 #if FF_API_R_FRAME_RATE
5237  for (unsigned int i = 1; sc->stts_count && i + 1 < sc->tts_count; i++) {
5238  if (sc->tts_data[i].duration == sc->tts_data[0].duration)
5239  continue;
5240  stts_constant = 0;
5241  }
5242  if (stts_constant)
5244  sc->time_scale, sc->tts_data[0].duration, INT_MAX);
5245 #endif
5246  }
5247 
5248 #if CONFIG_H261_DECODER || CONFIG_H263_DECODER || CONFIG_MPEG4_DECODER
5249  switch (st->codecpar->codec_id) {
5250 #if CONFIG_H261_DECODER
5251  case AV_CODEC_ID_H261:
5252 #endif
5253 #if CONFIG_H263_DECODER
5254  case AV_CODEC_ID_H263:
5255 #endif
5256 #if CONFIG_MPEG4_DECODER
5257  case AV_CODEC_ID_MPEG4:
5258 #endif
5259  st->codecpar->width = 0; /* let decoder init width/height */
5260  st->codecpar->height= 0;
5261  break;
5262  }
5263 #endif
5264 
5265  // If the duration of the mp3 packets is not constant, then they could need a parser
5266  if (st->codecpar->codec_id == AV_CODEC_ID_MP3
5267  && sc->time_scale == st->codecpar->sample_rate) {
5268  int stts_constant = 1;
5269  for (int i = 1; sc->stts_count && i < sc->tts_count; i++) {
5270  if (sc->tts_data[i].duration == sc->tts_data[0].duration)
5271  continue;
5272  stts_constant = 0;
5273  }
5274  if (!stts_constant)
5276  }
5277  /* Do not need those anymore. */
5278  av_freep(&sc->chunk_offsets);
5279  av_freep(&sc->sample_sizes);
5280  av_freep(&sc->keyframes);
5281  av_freep(&sc->stps_data);
5282  av_freep(&sc->elst_data);
5283  av_freep(&sc->rap_group);
5284  av_freep(&sc->sync_group);
5285  av_freep(&sc->sgpd_sync);
5286 
5287  return 0;
5288 }
5289 
5291 {
5292  int ret;
5293  c->itunes_metadata = 1;
5294  ret = mov_read_default(c, pb, atom);
5295  c->itunes_metadata = 0;
5296  return ret;
5297 }
5298 
5300 {
5301  uint32_t count;
5302  uint32_t i;
5303 
5304  if (atom.size < 8)
5305  return 0;
5306 
5307  avio_skip(pb, 4);
5308  count = avio_rb32(pb);
5309  atom.size -= 8;
5310  if (count >= UINT_MAX / sizeof(*c->meta_keys)) {
5311  av_log(c->fc, AV_LOG_ERROR,
5312  "The 'keys' atom with the invalid key count: %"PRIu32"\n", count);
5313  return AVERROR_INVALIDDATA;
5314  }
5315 
5316  c->meta_keys_count = count + 1;
5317  c->meta_keys = av_mallocz(c->meta_keys_count * sizeof(*c->meta_keys));
5318  if (!c->meta_keys)
5319  return AVERROR(ENOMEM);
5320 
5321  for (i = 1; i <= count; ++i) {
5322  uint32_t key_size = avio_rb32(pb);
5323  uint32_t type = avio_rl32(pb);
5324  if (key_size < 8 || key_size > atom.size) {
5325  av_log(c->fc, AV_LOG_ERROR,
5326  "The key# %"PRIu32" in meta has invalid size:"
5327  "%"PRIu32"\n", i, key_size);
5328  return AVERROR_INVALIDDATA;
5329  }
5330  atom.size -= key_size;
5331  key_size -= 8;
5332  if (type != MKTAG('m','d','t','a')) {
5333  avio_skip(pb, key_size);
5334  continue;
5335  }
5336  c->meta_keys[i] = av_mallocz(key_size + 1);
5337  if (!c->meta_keys[i])
5338  return AVERROR(ENOMEM);
5339  avio_read(pb, c->meta_keys[i], key_size);
5340  }
5341 
5342  return 0;
5343 }
5344 
5346 {
5347  int64_t end = av_sat_add64(avio_tell(pb), atom.size);
5348  uint8_t *key = NULL, *val = NULL, *mean = NULL;
5349  int i;
5350  int ret = 0;
5351  AVStream *st;
5352  MOVStreamContext *sc;
5353 
5354  if (c->fc->nb_streams < 1)
5355  return 0;
5356  st = c->fc->streams[c->fc->nb_streams-1];
5357  sc = st->priv_data;
5358 
5359  for (i = 0; i < 3; i++) {
5360  uint8_t **p;
5361  uint32_t len, tag;
5362 
5363  if (end - avio_tell(pb) <= 12)
5364  break;
5365 
5366  len = avio_rb32(pb);
5367  tag = avio_rl32(pb);
5368  avio_skip(pb, 4); // flags
5369 
5370  if (len < 12 || len - 12 > end - avio_tell(pb))
5371  break;
5372  len -= 12;
5373 
5374  if (tag == MKTAG('m', 'e', 'a', 'n'))
5375  p = &mean;
5376  else if (tag == MKTAG('n', 'a', 'm', 'e'))
5377  p = &key;
5378  else if (tag == MKTAG('d', 'a', 't', 'a') && len > 4) {
5379  avio_skip(pb, 4);
5380  len -= 4;
5381  p = &val;
5382  } else
5383  break;
5384 
5385  if (*p)
5386  break;
5387 
5388  *p = av_malloc(len + 1);
5389  if (!*p) {
5390  ret = AVERROR(ENOMEM);
5391  break;
5392  }
5393  ret = ffio_read_size(pb, *p, len);
5394  if (ret < 0) {
5395  av_freep(p);
5396  break;
5397  }
5398  (*p)[len] = 0;
5399  }
5400 
5401  if (mean && key && val) {
5402  if (strcmp(key, "iTunSMPB") == 0) {
5403  int priming, remainder, samples;
5404  if(sscanf(val, "%*X %X %X %X", &priming, &remainder, &samples) == 3){
5405  if(priming>0 && priming<16384)
5406  sc->start_pad = priming;
5407  }
5408  }
5409  if (strcmp(key, "cdec") != 0) {
5410  av_dict_set(&c->fc->metadata, key, val,
5412  key = val = NULL;
5413  }
5414  } else {
5415  av_log(c->fc, AV_LOG_VERBOSE,
5416  "Unhandled or malformed custom metadata of size %"PRId64"\n", atom.size);
5417  }
5418 
5419  avio_seek(pb, end, SEEK_SET);
5420  av_freep(&key);
5421  av_freep(&val);
5422  av_freep(&mean);
5423  return ret;
5424 }
5425 
5427 {
5428  MOVStreamContext *sc;
5429  AVStream *st;
5430 
5431  st = avformat_new_stream(c->fc, NULL);
5432  if (!st)
5433  return AVERROR(ENOMEM);
5434  sc = av_mallocz(sizeof(MOVStreamContext));
5435  if (!sc)
5436  goto fail;
5437 
5438  item->st = st;
5439  st->id = item->item_id;
5440  st->priv_data = sc;
5442  st->codecpar->codec_id = mov_codec_id(st, item->type);
5443  sc->id = st->id;
5444  sc->ffindex = st->index;
5445  st->avg_frame_rate.num = st->avg_frame_rate.den = 1;
5446  st->time_base.num = st->time_base.den = 1;
5447  st->nb_frames = 1;
5448  sc->time_scale = 1;
5449  sc->pb = c->fc->pb;
5450  sc->pb_is_copied = 1;
5451  sc->refcount = 1;
5452 
5453  if (item->name)
5454  av_dict_set(&st->metadata, "title", item->name, 0);
5455 
5456  // Populate the necessary fields used by mov_build_index.
5457  sc->stsc_data = av_malloc_array(1, sizeof(*sc->stsc_data));
5458  if (!sc->stsc_data)
5459  goto fail;
5460  sc->stsc_count = 1;
5461  sc->stsc_data[0].first = 1;
5462  sc->stsc_data[0].count = 1;
5463  sc->stsc_data[0].id = 1;
5464  sc->chunk_offsets = av_malloc_array(1, sizeof(*sc->chunk_offsets));
5465  if (!sc->chunk_offsets)
5466  goto fail;
5467  sc->chunk_count = 1;
5468  sc->stts_data = av_malloc_array(1, sizeof(*sc->stts_data));
5469  if (!sc->stts_data)
5470  goto fail;
5471  sc->stts_count = 1;
5472  sc->stts_data[0].count = 1;
5473  // Not used for still images. But needed by mov_build_index.
5474  sc->stts_data[0].duration = 0;
5475 
5476  return 0;
5477 fail:
5478  mov_free_stream_context(c->fc, st);
5479  ff_remove_stream(c->fc, st);
5480  item->st = NULL;
5481 
5482  return AVERROR(ENOMEM);
5483 }
5484 
5486 {
5487  while (atom.size > 8) {
5488  uint32_t tag;
5489  if (avio_feof(pb))
5490  return AVERROR_EOF;
5491  tag = avio_rl32(pb);
5492  atom.size -= 4;
5493  if (tag == MKTAG('h','d','l','r')) {
5494  avio_seek(pb, -8, SEEK_CUR);
5495  atom.size += 8;
5496  return mov_read_default(c, pb, atom);
5497  }
5498  }
5499  return 0;
5500 }
5501 
5502 // return 1 when matrix is identity, 0 otherwise
5503 #define IS_MATRIX_IDENT(matrix) \
5504  ( (matrix)[0][0] == (1 << 16) && \
5505  (matrix)[1][1] == (1 << 16) && \
5506  (matrix)[2][2] == (1 << 30) && \
5507  !(matrix)[0][1] && !(matrix)[0][2] && \
5508  !(matrix)[1][0] && !(matrix)[1][2] && \
5509  !(matrix)[2][0] && !(matrix)[2][1])
5510 
5512 {
5513  int i, j, e;
5514  int width;
5515  int height;
5516  int display_matrix[3][3];
5517  int res_display_matrix[3][3] = { { 0 } };
5518  AVStream *st;
5519  MOVStreamContext *sc;
5520  int version;
5521  int flags;
5522 
5523  if (c->fc->nb_streams < 1)
5524  return 0;
5525  st = c->fc->streams[c->fc->nb_streams-1];
5526  sc = st->priv_data;
5527 
5528  // Each stream (trak) should have exactly 1 tkhd. This catches bad files and
5529  // avoids corrupting AVStreams mapped to an earlier tkhd.
5530  if (st->id != -1)
5531  return AVERROR_INVALIDDATA;
5532 
5533  version = avio_r8(pb);
5534  flags = avio_rb24(pb);
5536 
5537  if (version == 1) {
5538  avio_rb64(pb);
5539  avio_rb64(pb);
5540  } else {
5541  avio_rb32(pb); /* creation time */
5542  avio_rb32(pb); /* modification time */
5543  }
5544  st->id = (int)avio_rb32(pb); /* track id (NOT 0 !)*/
5545  sc->id = st->id;
5546  avio_rb32(pb); /* reserved */
5547 
5548  /* highlevel (considering edits) duration in movie timebase */
5549  (version == 1) ? avio_rb64(pb) : avio_rb32(pb);
5550  avio_rb32(pb); /* reserved */
5551  avio_rb32(pb); /* reserved */
5552 
5553  avio_rb16(pb); /* layer */
5554  avio_rb16(pb); /* alternate group */
5555  avio_rb16(pb); /* volume */
5556  avio_rb16(pb); /* reserved */
5557 
5558  //read in the display matrix (outlined in ISO 14496-12, Section 6.2.2)
5559  // they're kept in fixed point format through all calculations
5560  // save u,v,z to store the whole matrix in the AV_PKT_DATA_DISPLAYMATRIX
5561  // side data, but the scale factor is not needed to calculate aspect ratio
5562  for (i = 0; i < 3; i++) {
5563  display_matrix[i][0] = avio_rb32(pb); // 16.16 fixed point
5564  display_matrix[i][1] = avio_rb32(pb); // 16.16 fixed point
5565  display_matrix[i][2] = avio_rb32(pb); // 2.30 fixed point
5566  }
5567 
5568  width = avio_rb32(pb); // 16.16 fixed point track width
5569  height = avio_rb32(pb); // 16.16 fixed point track height
5570  sc->width = width >> 16;
5571  sc->height = height >> 16;
5572 
5573  // apply the moov display matrix (after the tkhd one)
5574  for (i = 0; i < 3; i++) {
5575  const int sh[3] = { 16, 16, 30 };
5576  for (j = 0; j < 3; j++) {
5577  for (e = 0; e < 3; e++) {
5578  res_display_matrix[i][j] +=
5579  ((int64_t) display_matrix[i][e] *
5580  c->movie_display_matrix[e][j]) >> sh[e];
5581  }
5582  }
5583  }
5584 
5585  // save the matrix when it is not the default identity
5586  if (!IS_MATRIX_IDENT(res_display_matrix)) {
5587  av_freep(&sc->display_matrix);
5588  sc->display_matrix = av_malloc(sizeof(int32_t) * 9);
5589  if (!sc->display_matrix)
5590  return AVERROR(ENOMEM);
5591 
5592  for (i = 0; i < 3; i++)
5593  for (j = 0; j < 3; j++)
5594  sc->display_matrix[i * 3 + j] = res_display_matrix[i][j];
5595  }
5596 
5597  // transform the display width/height according to the matrix
5598  // to keep the same scale, use [width height 1<<16]
5599  if (width && height && sc->display_matrix) {
5600  double disp_transform[2];
5601 
5602  for (i = 0; i < 2; i++)
5603  disp_transform[i] = hypot(sc->display_matrix[0 + i],
5604  sc->display_matrix[3 + i]);
5605 
5606  if (disp_transform[0] > 1 && disp_transform[1] > 1 &&
5607  disp_transform[0] < (1<<24) && disp_transform[1] < (1<<24) &&
5608  fabs((disp_transform[0] / disp_transform[1]) - 1.0) > 0.01)
5610  disp_transform[0] / disp_transform[1],
5611  INT_MAX);
5612  }
5613  return 0;
5614 }
5615 
5617 {
5618  MOVFragment *frag = &c->fragment;
5619  MOVTrackExt *trex = NULL;
5620  int flags, track_id, i;
5621  MOVFragmentStreamInfo * frag_stream_info;
5622 
5623  avio_r8(pb); /* version */
5624  flags = avio_rb24(pb);
5625 
5626  track_id = avio_rb32(pb);
5627  if (!track_id)
5628  return AVERROR_INVALIDDATA;
5629  for (i = 0; i < c->trex_count; i++)
5630  if (c->trex_data[i].track_id == track_id) {
5631  trex = &c->trex_data[i];
5632  break;
5633  }
5634  if (!trex) {
5635  av_log(c->fc, AV_LOG_WARNING, "could not find corresponding trex (id %u)\n", track_id);
5636  return 0;
5637  }
5638  c->fragment.found_tfhd = 1;
5639  frag->track_id = track_id;
5640  set_frag_stream(&c->frag_index, track_id);
5641 
5644  frag->moof_offset : frag->implicit_offset;
5645  frag->stsd_id = flags & MOV_TFHD_STSD_ID ? avio_rb32(pb) : trex->stsd_id;
5646 
5648  avio_rb32(pb) : trex->duration;
5649  frag->size = flags & MOV_TFHD_DEFAULT_SIZE ?
5650  avio_rb32(pb) : trex->size;
5651  frag->flags = flags & MOV_TFHD_DEFAULT_FLAGS ?
5652  avio_rb32(pb) : trex->flags;
5653  av_log(c->fc, AV_LOG_TRACE, "frag flags 0x%x\n", frag->flags);
5654 
5655  frag_stream_info = get_current_frag_stream_info(&c->frag_index);
5656  if (frag_stream_info) {
5657  frag_stream_info->next_trun_dts = AV_NOPTS_VALUE;
5658  frag_stream_info->stsd_id = frag->stsd_id;
5659  }
5660  return 0;
5661 }
5662 
5664 {
5665  unsigned i, num;
5666  void *new_tracks;
5667 
5668  num = atom.size / 4;
5669  if (!(new_tracks = av_malloc_array(num, sizeof(int))))
5670  return AVERROR(ENOMEM);
5671 
5672  av_free(c->chapter_tracks);
5673  c->chapter_tracks = new_tracks;
5674  c->nb_chapter_tracks = num;
5675 
5676  for (i = 0; i < num && !pb->eof_reached; i++)
5677  c->chapter_tracks[i] = avio_rb32(pb);
5678 
5679  c->nb_chapter_tracks = i;
5680 
5681  return 0;
5682 }
5683 
5685 {
5686  MOVTrackExt *trex;
5687  int err;
5688 
5689  if ((uint64_t)c->trex_count+1 >= UINT_MAX / sizeof(*c->trex_data))
5690  return AVERROR_INVALIDDATA;
5691  if ((err = av_reallocp_array(&c->trex_data, c->trex_count + 1,
5692  sizeof(*c->trex_data))) < 0) {
5693  c->trex_count = 0;
5694  return err;
5695  }
5696 
5697  c->fc->duration = AV_NOPTS_VALUE; // the duration from mvhd is not representing the whole file when fragments are used.
5698 
5699  trex = &c->trex_data[c->trex_count++];
5700  avio_r8(pb); /* version */
5701  avio_rb24(pb); /* flags */
5702  trex->track_id = avio_rb32(pb);
5703  trex->stsd_id = avio_rb32(pb);
5704  trex->duration = avio_rb32(pb);
5705  trex->size = avio_rb32(pb);
5706  trex->flags = avio_rb32(pb);
5707  return 0;
5708 }
5709 
5711 {
5712  MOVFragment *frag = &c->fragment;
5713  AVStream *st = NULL;
5714  MOVStreamContext *sc;
5715  int version, i;
5716  MOVFragmentStreamInfo * frag_stream_info;
5717  int64_t base_media_decode_time;
5718 
5719  for (i = 0; i < c->fc->nb_streams; i++) {
5720  sc = c->fc->streams[i]->priv_data;
5721  if (sc->id == frag->track_id) {
5722  st = c->fc->streams[i];
5723  break;
5724  }
5725  }
5726  if (!st) {
5727  av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %u\n", frag->track_id);
5728  return 0;
5729  }
5730  sc = st->priv_data;
5731  if (sc->pseudo_stream_id + 1 != frag->stsd_id && sc->pseudo_stream_id != -1)
5732  return 0;
5733  version = avio_r8(pb);
5734  avio_rb24(pb); /* flags */
5735  if (version) {
5736  base_media_decode_time = avio_rb64(pb);
5737  } else {
5738  base_media_decode_time = avio_rb32(pb);
5739  }
5740 
5741  frag_stream_info = get_current_frag_stream_info(&c->frag_index);
5742  if (frag_stream_info)
5743  frag_stream_info->tfdt_dts = base_media_decode_time;
5744  sc->track_end = base_media_decode_time;
5745 
5746  return 0;
5747 }
5748 
5750 {
5751  MOVFragment *frag = &c->fragment;
5752  AVStream *st = NULL;
5753  FFStream *sti = NULL;
5754  MOVStreamContext *sc;
5755  MOVTimeToSample *tts_data;
5756  uint64_t offset;
5757  int64_t dts, pts = AV_NOPTS_VALUE;
5758  int data_offset = 0;
5759  unsigned entries, first_sample_flags = frag->flags;
5760  int flags, distance, i;
5761  int64_t prev_dts = AV_NOPTS_VALUE;
5762  int next_frag_index = -1, index_entry_pos;
5763  size_t requested_size;
5764  size_t old_allocated_size;
5765  AVIndexEntry *new_entries;
5766  MOVFragmentStreamInfo * frag_stream_info;
5767 
5768  if (!frag->found_tfhd) {
5769  av_log(c->fc, AV_LOG_ERROR, "trun track id unknown, no tfhd was found\n");
5770  return AVERROR_INVALIDDATA;
5771  }
5772 
5773  for (i = 0; i < c->fc->nb_streams; i++) {
5774  sc = c->fc->streams[i]->priv_data;
5775  if (sc->id == frag->track_id) {
5776  st = c->fc->streams[i];
5777  sti = ffstream(st);
5778  break;
5779  }
5780  }
5781  if (!st) {
5782  av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %u\n", frag->track_id);
5783  return 0;
5784  }
5785  sc = st->priv_data;
5786  if (sc->pseudo_stream_id+1 != frag->stsd_id && sc->pseudo_stream_id != -1)
5787  return 0;
5788 
5789  // Find the next frag_index index that has a valid index_entry for
5790  // the current track_id.
5791  //
5792  // A valid index_entry means the trun for the fragment was read
5793  // and it's samples are in index_entries at the given position.
5794  // New index entries will be inserted before the index_entry found.
5795  index_entry_pos = sti->nb_index_entries;
5796  for (i = c->frag_index.current + 1; i < c->frag_index.nb_items; i++) {
5797  frag_stream_info = get_frag_stream_info(&c->frag_index, i, frag->track_id);
5798  if (frag_stream_info && frag_stream_info->index_entry >= 0) {
5799  next_frag_index = i;
5800  index_entry_pos = frag_stream_info->index_entry;
5801  break;
5802  }
5803  }
5804  av_assert0(index_entry_pos <= sti->nb_index_entries);
5805 
5806  avio_r8(pb); /* version */
5807  flags = avio_rb24(pb);
5808  entries = avio_rb32(pb);
5809  av_log(c->fc, AV_LOG_TRACE, "flags 0x%x entries %u\n", flags, entries);
5810 
5811  if ((uint64_t)entries+sc->tts_count >= UINT_MAX/sizeof(*sc->tts_data))
5812  return AVERROR_INVALIDDATA;
5813  if (flags & MOV_TRUN_DATA_OFFSET) data_offset = avio_rb32(pb);
5814  if (flags & MOV_TRUN_FIRST_SAMPLE_FLAGS) first_sample_flags = avio_rb32(pb);
5815 
5816  frag_stream_info = get_current_frag_stream_info(&c->frag_index);
5817  if (frag_stream_info) {
5818  if (frag_stream_info->next_trun_dts != AV_NOPTS_VALUE) {
5819  dts = frag_stream_info->next_trun_dts - sc->time_offset;
5820  } else if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE &&
5821  c->use_mfra_for == FF_MOV_FLAG_MFRA_PTS) {
5822  pts = frag_stream_info->first_tfra_pts;
5823  av_log(c->fc, AV_LOG_DEBUG, "found mfra time %"PRId64
5824  ", using it for pts\n", pts);
5825  } else if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE &&
5826  c->use_mfra_for == FF_MOV_FLAG_MFRA_DTS) {
5827  dts = frag_stream_info->first_tfra_pts;
5828  av_log(c->fc, AV_LOG_DEBUG, "found mfra time %"PRId64
5829  ", using it for dts\n", pts);
5830  } else {
5831  int has_tfdt = frag_stream_info->tfdt_dts != AV_NOPTS_VALUE;
5832  int has_sidx = frag_stream_info->sidx_pts != AV_NOPTS_VALUE;
5833  int fallback_tfdt = !c->use_tfdt && !has_sidx && has_tfdt;
5834  int fallback_sidx = c->use_tfdt && !has_tfdt && has_sidx;
5835 
5836  if (fallback_sidx) {
5837  av_log(c->fc, AV_LOG_DEBUG, "use_tfdt set but no tfdt found, using sidx instead\n");
5838  }
5839  if (fallback_tfdt) {
5840  av_log(c->fc, AV_LOG_DEBUG, "use_tfdt not set but no sidx found, using tfdt instead\n");
5841  }
5842 
5843  if (has_tfdt && c->use_tfdt || fallback_tfdt) {
5844  dts = frag_stream_info->tfdt_dts - sc->time_offset;
5845  av_log(c->fc, AV_LOG_DEBUG, "found tfdt time %"PRId64
5846  ", using it for dts\n", dts);
5847  } else if (has_sidx && !c->use_tfdt || fallback_sidx) {
5848  // FIXME: sidx earliest_presentation_time is *PTS*, s.b.
5849  // pts = frag_stream_info->sidx_pts;
5850  dts = frag_stream_info->sidx_pts;
5851  av_log(c->fc, AV_LOG_DEBUG, "found sidx time %"PRId64
5852  ", using it for dts\n", frag_stream_info->sidx_pts);
5853  } else {
5854  dts = sc->track_end - sc->time_offset;
5855  av_log(c->fc, AV_LOG_DEBUG, "found track end time %"PRId64
5856  ", using it for dts\n", dts);
5857  }
5858  }
5859  } else {
5860  dts = sc->track_end - sc->time_offset;
5861  av_log(c->fc, AV_LOG_DEBUG, "found track end time %"PRId64
5862  ", using it for dts\n", dts);
5863  }
5864  offset = frag->base_data_offset + data_offset;
5865  distance = 0;
5866  av_log(c->fc, AV_LOG_TRACE, "first sample flags 0x%x\n", first_sample_flags);
5867 
5868  // realloc space for new index entries
5869  if ((uint64_t)sti->nb_index_entries + entries >= UINT_MAX / sizeof(AVIndexEntry)) {
5870  entries = UINT_MAX / sizeof(AVIndexEntry) - sti->nb_index_entries;
5871  av_log(c->fc, AV_LOG_ERROR, "Failed to add index entry\n");
5872  }
5873  if (entries == 0)
5874  return 0;
5875 
5876  requested_size = (sti->nb_index_entries + entries) * sizeof(AVIndexEntry);
5877  new_entries = av_fast_realloc(sti->index_entries,
5879  requested_size);
5880  if (!new_entries)
5881  return AVERROR(ENOMEM);
5882  sti->index_entries= new_entries;
5883 
5884  requested_size = (sti->nb_index_entries + entries) * sizeof(*sc->tts_data);
5885  old_allocated_size = sc->tts_allocated_size;
5886  tts_data = av_fast_realloc(sc->tts_data, &sc->tts_allocated_size,
5887  requested_size);
5888  if (!tts_data)
5889  return AVERROR(ENOMEM);
5890  sc->tts_data = tts_data;
5891 
5892  // In case there were samples without time to sample entries, ensure they get
5893  // zero valued entries. This ensures clips which mix boxes with and
5894  // without time to sample entries don't pickup uninitialized data.
5895  memset((uint8_t*)(sc->tts_data) + old_allocated_size, 0,
5896  sc->tts_allocated_size - old_allocated_size);
5897 
5898  if (index_entry_pos < sti->nb_index_entries) {
5899  // Make hole in index_entries and tts_data for new samples
5900  memmove(sti->index_entries + index_entry_pos + entries,
5901  sti->index_entries + index_entry_pos,
5902  sizeof(*sti->index_entries) *
5903  (sti->nb_index_entries - index_entry_pos));
5904  memmove(sc->tts_data + index_entry_pos + entries,
5905  sc->tts_data + index_entry_pos,
5906  sizeof(*sc->tts_data) * (sc->tts_count - index_entry_pos));
5907  if (index_entry_pos < sc->current_sample) {
5908  sc->current_sample += entries;
5909  }
5910  }
5911 
5912  sti->nb_index_entries += entries;
5913  sc->tts_count = sti->nb_index_entries;
5914  sc->stts_count = sti->nb_index_entries;
5915  if (flags & MOV_TRUN_SAMPLE_CTS)
5916  sc->ctts_count = sti->nb_index_entries;
5917 
5918  // Record the index_entry position in frag_index of this fragment
5919  if (frag_stream_info) {
5920  frag_stream_info->index_entry = index_entry_pos;
5921  if (frag_stream_info->index_base < 0)
5922  frag_stream_info->index_base = index_entry_pos;
5923  }
5924 
5925  if (index_entry_pos > 0)
5926  prev_dts = sti->index_entries[index_entry_pos-1].timestamp;
5927 
5928  for (i = 0; i < entries && !pb->eof_reached; i++) {
5929  unsigned sample_size = frag->size;
5930  int sample_flags = i ? frag->flags : first_sample_flags;
5931  unsigned sample_duration = frag->duration;
5932  unsigned ctts_duration = 0;
5933  int keyframe = 0;
5934  int index_entry_flags = 0;
5935 
5936  if (flags & MOV_TRUN_SAMPLE_DURATION) sample_duration = avio_rb32(pb);
5937  if (flags & MOV_TRUN_SAMPLE_SIZE) sample_size = avio_rb32(pb);
5938  if (flags & MOV_TRUN_SAMPLE_FLAGS) sample_flags = avio_rb32(pb);
5939  if (flags & MOV_TRUN_SAMPLE_CTS) ctts_duration = avio_rb32(pb);
5940 
5941  mov_update_dts_shift(sc, ctts_duration, c->fc);
5942  if (pts != AV_NOPTS_VALUE) {
5943  dts = pts - sc->dts_shift;
5944  if (flags & MOV_TRUN_SAMPLE_CTS) {
5945  dts -= ctts_duration;
5946  } else {
5947  dts -= sc->time_offset;
5948  }
5949  av_log(c->fc, AV_LOG_DEBUG,
5950  "pts %"PRId64" calculated dts %"PRId64
5951  " sc->dts_shift %d ctts.duration %d"
5952  " sc->time_offset %"PRId64
5953  " flags & MOV_TRUN_SAMPLE_CTS %d\n",
5954  pts, dts,
5955  sc->dts_shift, ctts_duration,
5957  pts = AV_NOPTS_VALUE;
5958  }
5959 
5960  keyframe =
5961  !(sample_flags & (MOV_FRAG_SAMPLE_FLAG_IS_NON_SYNC |
5963  if (keyframe) {
5964  distance = 0;
5965  index_entry_flags |= AVINDEX_KEYFRAME;
5966  }
5967  // Fragments can overlap in time. Discard overlapping frames after
5968  // decoding.
5969  if (prev_dts >= dts)
5970  index_entry_flags |= AVINDEX_DISCARD_FRAME;
5971 
5972  sti->index_entries[index_entry_pos].pos = offset;
5973  sti->index_entries[index_entry_pos].timestamp = dts;
5974  sti->index_entries[index_entry_pos].size = sample_size;
5975  sti->index_entries[index_entry_pos].min_distance = distance;
5976  sti->index_entries[index_entry_pos].flags = index_entry_flags;
5977 
5978  sc->tts_data[index_entry_pos].count = 1;
5979  sc->tts_data[index_entry_pos].offset = ctts_duration;
5980  sc->tts_data[index_entry_pos].duration = sample_duration;
5981  index_entry_pos++;
5982 
5983  av_log(c->fc, AV_LOG_TRACE, "AVIndex stream %d, sample %d, offset %"PRIx64", dts %"PRId64", "
5984  "size %u, distance %d, keyframe %d\n", st->index,
5985  index_entry_pos, offset, dts, sample_size, distance, keyframe);
5986  distance++;
5987  if (av_sat_add64(dts, sample_duration) != dts + (uint64_t)sample_duration)
5988  return AVERROR_INVALIDDATA;
5989  if (!sample_size)
5990  return AVERROR_INVALIDDATA;
5991  dts += sample_duration;
5992  offset += sample_size;
5993  sc->data_size += sample_size;
5994 
5995  if (sample_duration <= INT64_MAX - sc->duration_for_fps &&
5996  1 <= INT_MAX - sc->nb_frames_for_fps
5997  ) {
5998  sc->duration_for_fps += sample_duration;
5999  sc->nb_frames_for_fps ++;
6000  }
6001  }
6002  if (frag_stream_info)
6003  frag_stream_info->next_trun_dts = dts + sc->time_offset;
6004  if (i < entries) {
6005  // EOF found before reading all entries. Fix the hole this would
6006  // leave in index_entries and tts_data
6007  int gap = entries - i;
6008  memmove(sti->index_entries + index_entry_pos,
6009  sti->index_entries + index_entry_pos + gap,
6010  sizeof(*sti->index_entries) *
6011  (sti->nb_index_entries - (index_entry_pos + gap)));
6012  memmove(sc->tts_data + index_entry_pos,
6013  sc->tts_data + index_entry_pos + gap,
6014  sizeof(*sc->tts_data) *
6015  (sc->tts_count - (index_entry_pos + gap)));
6016 
6017  sti->nb_index_entries -= gap;
6018  sc->tts_count -= gap;
6019  if (index_entry_pos < sc->current_sample) {
6020  sc->current_sample -= gap;
6021  }
6022  entries = i;
6023  }
6024 
6025  // The end of this new fragment may overlap in time with the start
6026  // of the next fragment in index_entries. Mark the samples in the next
6027  // fragment that overlap with AVINDEX_DISCARD_FRAME
6028  prev_dts = AV_NOPTS_VALUE;
6029  if (index_entry_pos > 0)
6030  prev_dts = sti->index_entries[index_entry_pos-1].timestamp;
6031  for (int i = index_entry_pos; i < sti->nb_index_entries; i++) {
6032  if (prev_dts < sti->index_entries[i].timestamp)
6033  break;
6035  }
6036 
6037  // If a hole was created to insert the new index_entries into,
6038  // the index_entry recorded for all subsequent moof must
6039  // be incremented by the number of entries inserted.
6040  fix_frag_index_entries(&c->frag_index, next_frag_index,
6041  frag->track_id, entries);
6042 
6043  if (pb->eof_reached) {
6044  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted TRUN atom\n");
6045  return AVERROR_EOF;
6046  }
6047 
6048  frag->implicit_offset = offset;
6049 
6050  sc->track_end = dts + sc->time_offset;
6051  if (st->duration < sc->track_end)
6052  st->duration = sc->track_end;
6053 
6054  return 0;
6055 }
6056 
6058 {
6059  int64_t stream_size = avio_size(pb);
6060  int64_t offset = av_sat_add64(avio_tell(pb), atom.size), pts, timestamp;
6061  uint8_t version, is_complete;
6062  int64_t offadd;
6063  unsigned i, j, track_id, item_count;
6064  AVStream *st = NULL;
6065  AVStream *ref_st = NULL;
6066  MOVStreamContext *sc, *ref_sc = NULL;
6067  AVRational timescale;
6068 
6069  version = avio_r8(pb);
6070  if (version > 1) {
6071  avpriv_request_sample(c->fc, "sidx version %u", version);
6072  return 0;
6073  }
6074 
6075  avio_rb24(pb); // flags
6076 
6077  track_id = avio_rb32(pb); // Reference ID
6078  for (i = 0; i < c->fc->nb_streams; i++) {
6079  sc = c->fc->streams[i]->priv_data;
6080  if (sc->id == track_id) {
6081  st = c->fc->streams[i];
6082  break;
6083  }
6084  }
6085  if (!st) {
6086  av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %d\n", track_id);
6087  return 0;
6088  }
6089 
6090  sc = st->priv_data;
6091 
6092  timescale = av_make_q(1, avio_rb32(pb));
6093 
6094  if (timescale.den <= 0) {
6095  av_log(c->fc, AV_LOG_ERROR, "Invalid sidx timescale 1/%d\n", timescale.den);
6096  return AVERROR_INVALIDDATA;
6097  }
6098 
6099  if (version == 0) {
6100  pts = avio_rb32(pb);
6101  offadd= avio_rb32(pb);
6102  } else {
6103  pts = avio_rb64(pb);
6104  offadd= avio_rb64(pb);
6105  }
6106  if (av_sat_add64(offset, offadd) != offset + (uint64_t)offadd)
6107  return AVERROR_INVALIDDATA;
6108 
6109  offset += (uint64_t)offadd;
6110 
6111  avio_rb16(pb); // reserved
6112 
6113  item_count = avio_rb16(pb);
6114  if (item_count == 0)
6115  return AVERROR_INVALIDDATA;
6116 
6117  for (i = 0; i < item_count; i++) {
6118  int index;
6119  MOVFragmentStreamInfo * frag_stream_info;
6120  uint32_t size = avio_rb32(pb);
6121  uint32_t duration = avio_rb32(pb);
6122  if (size & 0x80000000) {
6123  avpriv_request_sample(c->fc, "sidx reference_type 1");
6124  return AVERROR_PATCHWELCOME;
6125  }
6126  avio_rb32(pb); // sap_flags
6127  timestamp = av_rescale_q(pts, timescale, st->time_base);
6128 
6130  frag_stream_info = get_frag_stream_info(&c->frag_index, index, track_id);
6131  if (frag_stream_info)
6132  frag_stream_info->sidx_pts = timestamp;
6133 
6134  if (av_sat_add64(offset, size) != offset + (uint64_t)size ||
6135  av_sat_add64(pts, duration) != pts + (uint64_t)duration
6136  )
6137  return AVERROR_INVALIDDATA;
6138  offset += size;
6139  pts += duration;
6140  }
6141 
6142  st->duration = sc->track_end = pts;
6143 
6144  sc->has_sidx = 1;
6145 
6146  // See if the remaining bytes are just an mfra which we can ignore.
6147  is_complete = offset == stream_size;
6148  if (!is_complete && (pb->seekable & AVIO_SEEKABLE_NORMAL) && stream_size > 0 ) {
6149  int64_t ret;
6150  int64_t original_pos = avio_tell(pb);
6151  if (!c->have_read_mfra_size) {
6152  if ((ret = avio_seek(pb, stream_size - 4, SEEK_SET)) < 0)
6153  return ret;
6154  c->mfra_size = avio_rb32(pb);
6155  c->have_read_mfra_size = 1;
6156  if ((ret = avio_seek(pb, original_pos, SEEK_SET)) < 0)
6157  return ret;
6158  }
6159  if (offset == stream_size - c->mfra_size)
6160  is_complete = 1;
6161  }
6162 
6163  if (is_complete) {
6164  // Find first entry in fragment index that came from an sidx.
6165  // This will pretty much always be the first entry.
6166  for (i = 0; i < c->frag_index.nb_items; i++) {
6167  MOVFragmentIndexItem * item = &c->frag_index.item[i];
6168  for (j = 0; ref_st == NULL && j < item->nb_stream_info; j++) {
6169  MOVFragmentStreamInfo * si;
6170  si = &item->stream_info[j];
6171  if (si->sidx_pts != AV_NOPTS_VALUE) {
6172  ref_st = c->fc->streams[j];
6173  ref_sc = ref_st->priv_data;
6174  break;
6175  }
6176  }
6177  }
6178  if (ref_st) for (i = 0; i < c->fc->nb_streams; i++) {
6179  st = c->fc->streams[i];
6180  sc = st->priv_data;
6181  if (!sc->has_sidx) {
6182  st->duration = sc->track_end = av_rescale(ref_st->duration, sc->time_scale, ref_sc->time_scale);
6183  }
6184  }
6185 
6186  c->frag_index.complete = 1;
6187  }
6188 
6189  return 0;
6190 }
6191 
6192 /* this atom should be null (from specs), but some buggy files put the 'moov' atom inside it... */
6193 /* like the files created with Adobe Premiere 5.0, for samples see */
6194 /* http://graphics.tudelft.nl/~wouter/publications/soundtests/ */
6196 {
6197  int err;
6198 
6199  if (atom.size < 8)
6200  return 0; /* continue */
6201  if (avio_rb32(pb) != 0) { /* 0 sized mdat atom... use the 'wide' atom size */
6202  avio_skip(pb, atom.size - 4);
6203  return 0;
6204  }
6205  atom.type = avio_rl32(pb);
6206  atom.size -= 8;
6207  if (atom.type != MKTAG('m','d','a','t')) {
6208  avio_skip(pb, atom.size);
6209  return 0;
6210  }
6211  err = mov_read_mdat(c, pb, atom);
6212  return err;
6213 }
6214 
6216 {
6217 #if CONFIG_ZLIB
6218  FFIOContext ctx;
6219  uint8_t *cmov_data;
6220  uint8_t *moov_data; /* uncompressed data */
6221  long cmov_len, moov_len;
6222  int ret = -1;
6223 
6224  avio_rb32(pb); /* dcom atom */
6225  if (avio_rl32(pb) != MKTAG('d','c','o','m'))
6226  return AVERROR_INVALIDDATA;
6227  if (avio_rl32(pb) != MKTAG('z','l','i','b')) {
6228  av_log(c->fc, AV_LOG_ERROR, "unknown compression for cmov atom !\n");
6229  return AVERROR_INVALIDDATA;
6230  }
6231  avio_rb32(pb); /* cmvd atom */
6232  if (avio_rl32(pb) != MKTAG('c','m','v','d'))
6233  return AVERROR_INVALIDDATA;
6234  moov_len = avio_rb32(pb); /* uncompressed size */
6235  cmov_len = atom.size - 6 * 4;
6236 
6237  cmov_data = av_malloc(cmov_len);
6238  if (!cmov_data)
6239  return AVERROR(ENOMEM);
6240  moov_data = av_malloc(moov_len);
6241  if (!moov_data) {
6242  av_free(cmov_data);
6243  return AVERROR(ENOMEM);
6244  }
6245  ret = ffio_read_size(pb, cmov_data, cmov_len);
6246  if (ret < 0)
6247  goto free_and_return;
6248 
6250  if (uncompress (moov_data, (uLongf *) &moov_len, (const Bytef *)cmov_data, cmov_len) != Z_OK)
6251  goto free_and_return;
6252  ffio_init_read_context(&ctx, moov_data, moov_len);
6253  ctx.pub.seekable = AVIO_SEEKABLE_NORMAL;
6254  atom.type = MKTAG('m','o','o','v');
6255  atom.size = moov_len;
6256  ret = mov_read_default(c, &ctx.pub, atom);
6257 free_and_return:
6258  av_free(moov_data);
6259  av_free(cmov_data);
6260  return ret;
6261 #else
6262  av_log(c->fc, AV_LOG_ERROR, "this file requires zlib support compiled in\n");
6263  return AVERROR(ENOSYS);
6264 #endif
6265 }
6266 
6267 /* edit list atom */
6269 {
6270  MOVStreamContext *sc;
6271  int i, edit_count, version;
6272  int64_t elst_entry_size;
6273 
6274  if (c->fc->nb_streams < 1 || c->ignore_editlist)
6275  return 0;
6276  sc = c->fc->streams[c->fc->nb_streams-1]->priv_data;
6277 
6278  version = avio_r8(pb); /* version */
6279  avio_rb24(pb); /* flags */
6280  edit_count = avio_rb32(pb); /* entries */
6281  atom.size -= 8;
6282 
6283  elst_entry_size = version == 1 ? 20 : 12;
6284  if (atom.size != edit_count * elst_entry_size) {
6285  if (c->fc->strict_std_compliance >= FF_COMPLIANCE_STRICT) {
6286  av_log(c->fc, AV_LOG_ERROR, "Invalid edit list entry_count: %d for elst atom of size: %"PRId64" bytes.\n",
6287  edit_count, atom.size + 8);
6288  return AVERROR_INVALIDDATA;
6289  } else {
6290  edit_count = atom.size / elst_entry_size;
6291  if (edit_count * elst_entry_size != atom.size) {
6292  av_log(c->fc, AV_LOG_WARNING, "ELST atom of %"PRId64" bytes, bigger than %d entries.\n", atom.size, edit_count);
6293  }
6294  }
6295  }
6296 
6297  if (!edit_count)
6298  return 0;
6299  if (sc->elst_data)
6300  av_log(c->fc, AV_LOG_WARNING, "Duplicated ELST atom\n");
6301  av_free(sc->elst_data);
6302  sc->elst_count = 0;
6303  sc->elst_data = av_malloc_array(edit_count, sizeof(*sc->elst_data));
6304  if (!sc->elst_data)
6305  return AVERROR(ENOMEM);
6306 
6307  av_log(c->fc, AV_LOG_TRACE, "track[%u].edit_count = %i\n", c->fc->nb_streams - 1, edit_count);
6308  for (i = 0; i < edit_count && atom.size > 0 && !pb->eof_reached; i++) {
6309  MOVElst *e = &sc->elst_data[i];
6310 
6311  if (version == 1) {
6312  e->duration = avio_rb64(pb);
6313  e->time = avio_rb64(pb);
6314  atom.size -= 16;
6315  } else {
6316  e->duration = avio_rb32(pb); /* segment duration */
6317  e->time = (int32_t)avio_rb32(pb); /* media time */
6318  atom.size -= 8;
6319  }
6320  e->rate = avio_rb32(pb) / 65536.0;
6321  atom.size -= 4;
6322  av_log(c->fc, AV_LOG_TRACE, "duration=%"PRId64" time=%"PRId64" rate=%f\n",
6323  e->duration, e->time, e->rate);
6324 
6325  if (e->time < 0 && e->time != -1 &&
6326  c->fc->strict_std_compliance >= FF_COMPLIANCE_STRICT) {
6327  av_log(c->fc, AV_LOG_ERROR, "Track %d, edit %d: Invalid edit list media time=%"PRId64"\n",
6328  c->fc->nb_streams-1, i, e->time);
6329  return AVERROR_INVALIDDATA;
6330  }
6331  if (e->duration < 0) {
6332  av_log(c->fc, AV_LOG_ERROR, "Track %d, edit %d: Invalid edit list duration=%"PRId64"\n",
6333  c->fc->nb_streams-1, i, e->duration);
6334  return AVERROR_INVALIDDATA;
6335  }
6336  }
6337  sc->elst_count = i;
6338 
6339  return 0;
6340 }
6341 
6343 {
6344  MOVStreamContext *sc;
6345 
6346  if (c->fc->nb_streams < 1)
6347  return AVERROR_INVALIDDATA;
6348  sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
6349  sc->timecode_track = avio_rb32(pb);
6350  return 0;
6351 }
6352 
6354 {
6355  AVStream *st;
6356  int version, color_range, color_primaries, color_trc, color_space;
6357 
6358  if (c->fc->nb_streams < 1)
6359  return 0;
6360  st = c->fc->streams[c->fc->nb_streams - 1];
6361 
6362  if (atom.size < 5) {
6363  av_log(c->fc, AV_LOG_ERROR, "Empty VP Codec Configuration box\n");
6364  return AVERROR_INVALIDDATA;
6365  }
6366 
6367  version = avio_r8(pb);
6368  if (version != 1) {
6369  av_log(c->fc, AV_LOG_WARNING, "Unsupported VP Codec Configuration box version %d\n", version);
6370  return 0;
6371  }
6372  avio_skip(pb, 3); /* flags */
6373 
6374  avio_skip(pb, 2); /* profile + level */
6375  color_range = avio_r8(pb); /* bitDepth, chromaSubsampling, videoFullRangeFlag */
6376  color_primaries = avio_r8(pb);
6377  color_trc = avio_r8(pb);
6378  color_space = avio_r8(pb);
6379  if (avio_rb16(pb)) /* codecIntializationDataSize */
6380  return AVERROR_INVALIDDATA;
6381 
6384  if (!av_color_transfer_name(color_trc))
6385  color_trc = AVCOL_TRC_UNSPECIFIED;
6386  if (!av_color_space_name(color_space))
6387  color_space = AVCOL_SPC_UNSPECIFIED;
6388 
6391  st->codecpar->color_trc = color_trc;
6392  st->codecpar->color_space = color_space;
6393 
6394  return 0;
6395 }
6396 
6398 {
6399  MOVStreamContext *sc;
6400  int i, version;
6401 
6402  if (c->fc->nb_streams < 1)
6403  return AVERROR_INVALIDDATA;
6404 
6405  sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
6406 
6407  if (atom.size < 5) {
6408  av_log(c->fc, AV_LOG_ERROR, "Empty Mastering Display Metadata box\n");
6409  return AVERROR_INVALIDDATA;
6410  }
6411 
6412  version = avio_r8(pb);
6413  if (version) {
6414  av_log(c->fc, AV_LOG_WARNING, "Unsupported Mastering Display Metadata box version %d\n", version);
6415  return 0;
6416  }
6417  if (sc->mastering) {
6418  av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicate Mastering Display Metadata\n");
6419  return 0;
6420  }
6421 
6422  avio_skip(pb, 3); /* flags */
6423 
6425  if (!sc->mastering)
6426  return AVERROR(ENOMEM);
6427 
6428  for (i = 0; i < 3; i++) {
6429  sc->mastering->display_primaries[i][0] = av_make_q(avio_rb16(pb), 1 << 16);
6430  sc->mastering->display_primaries[i][1] = av_make_q(avio_rb16(pb), 1 << 16);
6431  }
6432  sc->mastering->white_point[0] = av_make_q(avio_rb16(pb), 1 << 16);
6433  sc->mastering->white_point[1] = av_make_q(avio_rb16(pb), 1 << 16);
6434 
6435  sc->mastering->max_luminance = av_make_q(avio_rb32(pb), 1 << 8);
6436  sc->mastering->min_luminance = av_make_q(avio_rb32(pb), 1 << 14);
6437 
6438  sc->mastering->has_primaries = 1;
6439  sc->mastering->has_luminance = 1;
6440 
6441  return 0;
6442 }
6443 
6445 {
6446  MOVStreamContext *sc;
6447  const int mapping[3] = {1, 2, 0};
6448  const int chroma_den = 50000;
6449  const int luma_den = 10000;
6450  int i;
6451 
6452  if (c->fc->nb_streams < 1)
6453  return AVERROR_INVALIDDATA;
6454 
6455  sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
6456 
6457  if (atom.size < 24) {
6458  av_log(c->fc, AV_LOG_ERROR, "Invalid Mastering Display Color Volume box\n");
6459  return AVERROR_INVALIDDATA;
6460  }
6461 
6462  if (sc->mastering) {
6463  av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicate Mastering Display Color Volume\n");
6464  return 0;
6465  }
6466 
6468  if (!sc->mastering)
6469  return AVERROR(ENOMEM);
6470 
6471  for (i = 0; i < 3; i++) {
6472  const int j = mapping[i];
6473  sc->mastering->display_primaries[j][0] = av_make_q(avio_rb16(pb), chroma_den);
6474  sc->mastering->display_primaries[j][1] = av_make_q(avio_rb16(pb), chroma_den);
6475  }
6476  sc->mastering->white_point[0] = av_make_q(avio_rb16(pb), chroma_den);
6477  sc->mastering->white_point[1] = av_make_q(avio_rb16(pb), chroma_den);
6478 
6479  sc->mastering->max_luminance = av_make_q(avio_rb32(pb), luma_den);
6480  sc->mastering->min_luminance = av_make_q(avio_rb32(pb), luma_den);
6481 
6482  sc->mastering->has_luminance = 1;
6483  sc->mastering->has_primaries = 1;
6484 
6485  return 0;
6486 }
6487 
6489 {
6490  MOVStreamContext *sc;
6491  int version;
6492 
6493  if (c->fc->nb_streams < 1)
6494  return AVERROR_INVALIDDATA;
6495 
6496  sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
6497 
6498  if (atom.size < 5) {
6499  av_log(c->fc, AV_LOG_ERROR, "Empty Content Light Level box\n");
6500  return AVERROR_INVALIDDATA;
6501  }
6502 
6503  version = avio_r8(pb);
6504  if (version) {
6505  av_log(c->fc, AV_LOG_WARNING, "Unsupported Content Light Level box version %d\n", version);
6506  return 0;
6507  }
6508  avio_skip(pb, 3); /* flags */
6509 
6510  if (sc->coll){
6511  av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicate COLL\n");
6512  return 0;
6513  }
6514 
6516  if (!sc->coll)
6517  return AVERROR(ENOMEM);
6518 
6519  sc->coll->MaxCLL = avio_rb16(pb);
6520  sc->coll->MaxFALL = avio_rb16(pb);
6521 
6522  return 0;
6523 }
6524 
6526 {
6527  MOVStreamContext *sc;
6528 
6529  if (c->fc->nb_streams < 1)
6530  return AVERROR_INVALIDDATA;
6531 
6532  sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
6533 
6534  if (atom.size < 4) {
6535  av_log(c->fc, AV_LOG_ERROR, "Empty Content Light Level Info box\n");
6536  return AVERROR_INVALIDDATA;
6537  }
6538 
6539  if (sc->coll){
6540  av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicate CLLI/COLL\n");
6541  return 0;
6542  }
6543 
6545  if (!sc->coll)
6546  return AVERROR(ENOMEM);
6547 
6548  sc->coll->MaxCLL = avio_rb16(pb);
6549  sc->coll->MaxFALL = avio_rb16(pb);
6550 
6551  return 0;
6552 }
6553 
6555 {
6556  MOVStreamContext *sc;
6557  const int illuminance_den = 10000;
6558  const int ambient_den = 50000;
6559  if (c->fc->nb_streams < 1)
6560  return AVERROR_INVALIDDATA;
6561  sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
6562  if (atom.size < 6) {
6563  av_log(c->fc, AV_LOG_ERROR, "Empty Ambient Viewing Environment Info box\n");
6564  return AVERROR_INVALIDDATA;
6565  }
6566  if (sc->ambient){
6567  av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicate AMVE\n");
6568  return 0;
6569  }
6571  if (!sc->ambient)
6572  return AVERROR(ENOMEM);
6573  sc->ambient->ambient_illuminance = av_make_q(avio_rb32(pb), illuminance_den);
6574  sc->ambient->ambient_light_x = av_make_q(avio_rb16(pb), ambient_den);
6575  sc->ambient->ambient_light_y = av_make_q(avio_rb16(pb), ambient_den);
6576  return 0;
6577 }
6578 
6580 {
6581  AVStream *st;
6582  MOVStreamContext *sc;
6583  enum AVStereo3DType type;
6584  int mode;
6585 
6586  if (c->fc->nb_streams < 1)
6587  return 0;
6588 
6589  st = c->fc->streams[c->fc->nb_streams - 1];
6590  sc = st->priv_data;
6591 
6592  if (atom.size < 5) {
6593  av_log(c->fc, AV_LOG_ERROR, "Empty stereoscopic video box\n");
6594  return AVERROR_INVALIDDATA;
6595  }
6596 
6597  if (sc->stereo3d)
6598  return AVERROR_INVALIDDATA;
6599 
6600  avio_skip(pb, 4); /* version + flags */
6601 
6602  mode = avio_r8(pb);
6603  switch (mode) {
6604  case 0:
6605  type = AV_STEREO3D_2D;
6606  break;
6607  case 1:
6609  break;
6610  case 2:
6612  break;
6613  default:
6614  av_log(c->fc, AV_LOG_WARNING, "Unknown st3d mode value %d\n", mode);
6615  return 0;
6616  }
6617 
6619  if (!sc->stereo3d)
6620  return AVERROR(ENOMEM);
6621 
6622  sc->stereo3d->type = type;
6623  return 0;
6624 }
6625 
6627 {
6628  AVStream *st;
6629  MOVStreamContext *sc;
6630  int size = 0;
6631  int64_t remaining;
6632  uint32_t tag = 0;
6634 
6635  if (c->fc->nb_streams < 1)
6636  return 0;
6637 
6638  st = c->fc->streams[c->fc->nb_streams - 1];
6639  sc = st->priv_data;
6640 
6641  remaining = atom.size;
6642  while (remaining > 0) {
6643  size = avio_rb32(pb);
6644  if (size < 8 || size > remaining ) {
6645  av_log(c->fc, AV_LOG_ERROR, "Invalid child size in pack box\n");
6646  return AVERROR_INVALIDDATA;
6647  }
6648 
6649  tag = avio_rl32(pb);
6650  switch (tag) {
6651  case MKTAG('p','k','i','n'): {
6652  if (size != 16) {
6653  av_log(c->fc, AV_LOG_ERROR, "Invalid size of pkin box: %d\n", size);
6654  return AVERROR_INVALIDDATA;
6655  }
6656  avio_skip(pb, 1); // version
6657  avio_skip(pb, 3); // flags
6658 
6659  tag = avio_rl32(pb);
6660  switch (tag) {
6661  case MKTAG('s','i','d','e'):
6663  break;
6664  case MKTAG('o','v','e','r'):
6666  break;
6667  case 0:
6668  // This means value will be set in another layer
6669  break;
6670  default:
6671  av_log(c->fc, AV_LOG_WARNING, "Unknown tag in pkin: %s\n",
6672  av_fourcc2str(tag));
6673  avio_skip(pb, size - 8);
6674  break;
6675  }
6676 
6677  break;
6678  }
6679  default:
6680  av_log(c->fc, AV_LOG_WARNING, "Unknown tag in pack: %s\n",
6681  av_fourcc2str(tag));
6682  avio_skip(pb, size - 8);
6683  break;
6684  }
6685  remaining -= size;
6686  }
6687 
6688  if (remaining != 0) {
6689  av_log(c->fc, AV_LOG_ERROR, "Broken pack box\n");
6690  return AVERROR_INVALIDDATA;
6691  }
6692 
6693  if (type == AV_STEREO3D_2D)
6694  return 0;
6695 
6696  if (!sc->stereo3d) {
6698  if (!sc->stereo3d)
6699  return AVERROR(ENOMEM);
6700  }
6701 
6702  sc->stereo3d->type = type;
6703 
6704  return 0;
6705 }
6706 
6708 {
6709  AVStream *st;
6710  MOVStreamContext *sc;
6711  int size, version, layout;
6712  int32_t yaw, pitch, roll;
6713  uint32_t l = 0, t = 0, r = 0, b = 0;
6714  uint32_t tag, padding = 0;
6715  enum AVSphericalProjection projection;
6716 
6717  if (c->fc->nb_streams < 1)
6718  return 0;
6719 
6720  st = c->fc->streams[c->fc->nb_streams - 1];
6721  sc = st->priv_data;
6722 
6723  if (atom.size < 8) {
6724  av_log(c->fc, AV_LOG_ERROR, "Empty spherical video box\n");
6725  return AVERROR_INVALIDDATA;
6726  }
6727 
6728  size = avio_rb32(pb);
6729  if (size <= 12 || size > atom.size)
6730  return AVERROR_INVALIDDATA;
6731 
6732  tag = avio_rl32(pb);
6733  if (tag != MKTAG('s','v','h','d')) {
6734  av_log(c->fc, AV_LOG_ERROR, "Missing spherical video header\n");
6735  return 0;
6736  }
6737  version = avio_r8(pb);
6738  if (version != 0) {
6739  av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
6740  version);
6741  return 0;
6742  }
6743  avio_skip(pb, 3); /* flags */
6744  avio_skip(pb, size - 12); /* metadata_source */
6745 
6746  size = avio_rb32(pb);
6747  if (size > atom.size)
6748  return AVERROR_INVALIDDATA;
6749 
6750  tag = avio_rl32(pb);
6751  if (tag != MKTAG('p','r','o','j')) {
6752  av_log(c->fc, AV_LOG_ERROR, "Missing projection box\n");
6753  return 0;
6754  }
6755 
6756  size = avio_rb32(pb);
6757  if (size > atom.size)
6758  return AVERROR_INVALIDDATA;
6759 
6760  tag = avio_rl32(pb);
6761  if (tag != MKTAG('p','r','h','d')) {
6762  av_log(c->fc, AV_LOG_ERROR, "Missing projection header box\n");
6763  return 0;
6764  }
6765  version = avio_r8(pb);
6766  if (version != 0) {
6767  av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
6768  version);
6769  return 0;
6770  }
6771  avio_skip(pb, 3); /* flags */
6772 
6773  /* 16.16 fixed point */
6774  yaw = avio_rb32(pb);
6775  pitch = avio_rb32(pb);
6776  roll = avio_rb32(pb);
6777 
6778  size = avio_rb32(pb);
6779  if (size > atom.size)
6780  return AVERROR_INVALIDDATA;
6781 
6782  tag = avio_rl32(pb);
6783  version = avio_r8(pb);
6784  if (version != 0) {
6785  av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
6786  version);
6787  return 0;
6788  }
6789  avio_skip(pb, 3); /* flags */
6790  switch (tag) {
6791  case MKTAG('c','b','m','p'):
6792  layout = avio_rb32(pb);
6793  if (layout) {
6794  av_log(c->fc, AV_LOG_WARNING,
6795  "Unsupported cubemap layout %d\n", layout);
6796  return 0;
6797  }
6798  projection = AV_SPHERICAL_CUBEMAP;
6799  padding = avio_rb32(pb);
6800  break;
6801  case MKTAG('e','q','u','i'):
6802  t = avio_rb32(pb);
6803  b = avio_rb32(pb);
6804  l = avio_rb32(pb);
6805  r = avio_rb32(pb);
6806 
6807  if (b >= UINT_MAX - t || r >= UINT_MAX - l) {
6808  av_log(c->fc, AV_LOG_ERROR,
6809  "Invalid bounding rectangle coordinates "
6810  "%"PRIu32",%"PRIu32",%"PRIu32",%"PRIu32"\n", l, t, r, b);
6811  return AVERROR_INVALIDDATA;
6812  }
6813 
6814  if (l || t || r || b)
6815  projection = AV_SPHERICAL_EQUIRECTANGULAR_TILE;
6816  else
6817  projection = AV_SPHERICAL_EQUIRECTANGULAR;
6818  break;
6819  default:
6820  av_log(c->fc, AV_LOG_ERROR, "Unknown projection type: %s\n", av_fourcc2str(tag));
6821  return 0;
6822  }
6823 
6825  if (!sc->spherical)
6826  return AVERROR(ENOMEM);
6827 
6828  sc->spherical->projection = projection;
6829 
6830  sc->spherical->yaw = yaw;
6831  sc->spherical->pitch = pitch;
6832  sc->spherical->roll = roll;
6833 
6834  sc->spherical->padding = padding;
6835 
6836  sc->spherical->bound_left = l;
6837  sc->spherical->bound_top = t;
6838  sc->spherical->bound_right = r;
6839  sc->spherical->bound_bottom = b;
6840 
6841  return 0;
6842 }
6843 
6845 {
6846  AVStream *st;
6847  MOVStreamContext *sc;
6848  int size;
6849  uint32_t tag;
6850  enum AVSphericalProjection projection;
6851 
6852  if (c->fc->nb_streams < 1)
6853  return 0;
6854 
6855  st = c->fc->streams[c->fc->nb_streams - 1];
6856  sc = st->priv_data;
6857 
6858  if (atom.size < 16) {
6859  av_log(c->fc, AV_LOG_ERROR, "Invalid size for proj box: %"PRIu64"\n", atom.size);
6860  return AVERROR_INVALIDDATA;
6861  }
6862 
6863  size = avio_rb32(pb);
6864  if (size < 16) {
6865  av_log(c->fc, AV_LOG_ERROR, "Invalid size for prji box: %d\n", size);
6866  return AVERROR_INVALIDDATA;
6867  } else if (size > 16) {
6868  av_log(c->fc, AV_LOG_WARNING, "Box has more bytes (%d) than prji box required (16) \n", size);
6869  }
6870 
6871  tag = avio_rl32(pb);
6872  if (tag != MKTAG('p','r','j','i')) {
6873  av_log(c->fc, AV_LOG_ERROR, "Invalid child box of proj box: %s\n",
6874  av_fourcc2str(tag));
6875  return AVERROR_INVALIDDATA;
6876  }
6877 
6878  // version and flags, only support (0, 0)
6879  unsigned n = avio_rl32(pb);
6880  if (n != 0) {
6881  av_log(c->fc, AV_LOG_ERROR, "prji version %u, flag %u are not supported\n",
6882  n & 0xFF, n >> 8);
6883  return AVERROR_PATCHWELCOME;
6884  }
6885 
6886  tag = avio_rl32(pb);
6887  switch (tag) {
6888  case MKTAG('r','e','c','t'):
6889  projection = AV_SPHERICAL_RECTILINEAR;
6890  break;
6891  case MKTAG('e','q','u','i'):
6892  projection = AV_SPHERICAL_EQUIRECTANGULAR;
6893  break;
6894  case MKTAG('h','e','q','u'):
6895  projection = AV_SPHERICAL_HALF_EQUIRECTANGULAR;
6896  break;
6897  case MKTAG('f','i','s','h'):
6898  projection = AV_SPHERICAL_FISHEYE;
6899  break;
6900  case MKTAG('p','r','i','m'):
6901  projection = AV_SPHERICAL_PARAMETRIC_IMMERSIVE;
6902  break;
6903  default:
6904  av_log(c->fc, AV_LOG_ERROR, "Invalid projection type in prji box: %s\n", av_fourcc2str(tag));
6905  return AVERROR_INVALIDDATA;
6906  }
6907 
6909  if (!sc->spherical)
6910  return AVERROR(ENOMEM);
6911 
6912  sc->spherical->projection = projection;
6913 
6914  return 0;
6915 }
6916 
6918 {
6919  AVStream *st;
6920  MOVStreamContext *sc;
6921  int size, flags = 0;
6922  int64_t remaining;
6923  uint32_t tag, baseline = 0;
6926  enum AVStereo3DPrimaryEye primary_eye = AV_PRIMARY_EYE_NONE;
6927  AVRational horizontal_disparity_adjustment = { 0, 1 };
6928 
6929  if (c->fc->nb_streams < 1)
6930  return 0;
6931 
6932  st = c->fc->streams[c->fc->nb_streams - 1];
6933  sc = st->priv_data;
6934 
6935  remaining = atom.size;
6936  while (remaining > 0) {
6937  size = avio_rb32(pb);
6938  if (size < 8 || size > remaining ) {
6939  av_log(c->fc, AV_LOG_ERROR, "Invalid child size in eyes box\n");
6940  return AVERROR_INVALIDDATA;
6941  }
6942 
6943  tag = avio_rl32(pb);
6944  switch (tag) {
6945  case MKTAG('s','t','r','i'): {
6946  int has_right, has_left;
6947  uint8_t tmp;
6948  if (size != 13) {
6949  av_log(c->fc, AV_LOG_ERROR, "Invalid size of stri box: %d\n", size);
6950  return AVERROR_INVALIDDATA;
6951  }
6952  avio_skip(pb, 1); // version
6953  avio_skip(pb, 3); // flags
6954 
6955  tmp = avio_r8(pb);
6956 
6957  // eye_views_reversed
6958  if (tmp & 8) {
6960  }
6961  // has_additional_views
6962  if (tmp & 4) {
6963  // skip...
6964  }
6965 
6966  has_right = tmp & 2; // has_right_eye_view
6967  has_left = tmp & 1; // has_left_eye_view
6968 
6969  if (has_left && has_right)
6970  view = AV_STEREO3D_VIEW_PACKED;
6971  else if (has_left)
6972  view = AV_STEREO3D_VIEW_LEFT;
6973  else if (has_right)
6974  view = AV_STEREO3D_VIEW_RIGHT;
6975  if (has_left || has_right)
6977 
6978  break;
6979  }
6980  case MKTAG('h','e','r','o'): {
6981  int tmp;
6982  if (size != 13) {
6983  av_log(c->fc, AV_LOG_ERROR, "Invalid size of hero box: %d\n", size);
6984  return AVERROR_INVALIDDATA;
6985  }
6986  avio_skip(pb, 1); // version
6987  avio_skip(pb, 3); // flags
6988 
6989  tmp = avio_r8(pb);
6990  if (tmp == 0)
6991  primary_eye = AV_PRIMARY_EYE_NONE;
6992  else if (tmp == 1)
6993  primary_eye = AV_PRIMARY_EYE_LEFT;
6994  else if (tmp == 2)
6995  primary_eye = AV_PRIMARY_EYE_RIGHT;
6996  else
6997  av_log(c->fc, AV_LOG_WARNING, "Unknown hero eye type: %d\n", tmp);
6998 
6999  break;
7000  }
7001  case MKTAG('c','a','m','s'): {
7002  uint32_t subtag;
7003  int subsize;
7004  if (size != 24) {
7005  av_log(c->fc, AV_LOG_ERROR, "Invalid size of cams box: %d\n", size);
7006  return AVERROR_INVALIDDATA;
7007  }
7008 
7009  subsize = avio_rb32(pb);
7010  if (subsize != 16) {
7011  av_log(c->fc, AV_LOG_ERROR, "Invalid size of blin box: %d\n", size);
7012  return AVERROR_INVALIDDATA;
7013  }
7014 
7015  subtag = avio_rl32(pb);
7016  if (subtag != MKTAG('b','l','i','n')) {
7017  av_log(c->fc, AV_LOG_ERROR, "Expected blin box, got %s\n",
7018  av_fourcc2str(subtag));
7019  return AVERROR_INVALIDDATA;
7020  }
7021 
7022  avio_skip(pb, 1); // version
7023  avio_skip(pb, 3); // flags
7024 
7025  baseline = avio_rb32(pb);
7026 
7027  break;
7028  }
7029  case MKTAG('c','m','f','y'): {
7030  uint32_t subtag;
7031  int subsize;
7032  int32_t adjustment;
7033  if (size != 24) {
7034  av_log(c->fc, AV_LOG_ERROR, "Invalid size of cmfy box: %d\n", size);
7035  return AVERROR_INVALIDDATA;
7036  }
7037 
7038  subsize = avio_rb32(pb);
7039  if (subsize != 16) {
7040  av_log(c->fc, AV_LOG_ERROR, "Invalid size of dadj box: %d\n", size);
7041  return AVERROR_INVALIDDATA;
7042  }
7043 
7044  subtag = avio_rl32(pb);
7045  if (subtag != MKTAG('d','a','d','j')) {
7046  av_log(c->fc, AV_LOG_ERROR, "Expected dadj box, got %s\n",
7047  av_fourcc2str(subtag));
7048  return AVERROR_INVALIDDATA;
7049  }
7050 
7051  avio_skip(pb, 1); // version
7052  avio_skip(pb, 3); // flags
7053 
7054  adjustment = (int32_t) avio_rb32(pb);
7055 
7056  horizontal_disparity_adjustment.num = (int) adjustment;
7057  horizontal_disparity_adjustment.den = 10000;
7058 
7059  break;
7060  }
7061  default:
7062  av_log(c->fc, AV_LOG_WARNING, "Unknown tag in eyes: %s\n",
7063  av_fourcc2str(tag));
7064  avio_skip(pb, size - 8);
7065  break;
7066  }
7067  remaining -= size;
7068  }
7069 
7070  if (remaining != 0) {
7071  av_log(c->fc, AV_LOG_ERROR, "Broken eyes box\n");
7072  return AVERROR_INVALIDDATA;
7073  }
7074 
7075  if (type == AV_STEREO3D_2D)
7076  return 0;
7077 
7078  if (!sc->stereo3d) {
7080  if (!sc->stereo3d)
7081  return AVERROR(ENOMEM);
7082  }
7083 
7084  sc->stereo3d->flags = flags;
7085  sc->stereo3d->type = type;
7086  sc->stereo3d->view = view;
7087  sc->stereo3d->primary_eye = primary_eye;
7088  sc->stereo3d->baseline = baseline;
7089  sc->stereo3d->horizontal_disparity_adjustment = horizontal_disparity_adjustment;
7090 
7091  return 0;
7092 }
7093 
7095 {
7096  int size;
7097  int64_t remaining;
7098  uint32_t tag;
7099 
7100  if (c->fc->nb_streams < 1)
7101  return 0;
7102 
7103  if (atom.size < 8) {
7104  av_log(c->fc, AV_LOG_ERROR, "Empty video extension usage box\n");
7105  return AVERROR_INVALIDDATA;
7106  }
7107 
7108  remaining = atom.size;
7109  while (remaining > 0) {
7110  size = avio_rb32(pb);
7111  if (size < 8 || size > remaining ) {
7112  av_log(c->fc, AV_LOG_ERROR, "Invalid child size in vexu box\n");
7113  return AVERROR_INVALIDDATA;
7114  }
7115 
7116  tag = avio_rl32(pb);
7117  switch (tag) {
7118  case MKTAG('p','r','o','j'): {
7119  MOVAtom proj = { tag, size - 8 };
7120  int ret = mov_read_vexu_proj(c, pb, proj);
7121  if (ret < 0)
7122  return ret;
7123  break;
7124  }
7125  case MKTAG('e','y','e','s'): {
7126  MOVAtom eyes = { tag, size - 8 };
7127  int ret = mov_read_eyes(c, pb, eyes);
7128  if (ret < 0)
7129  return ret;
7130  break;
7131  }
7132  case MKTAG('p','a','c','k'): {
7133  MOVAtom pack = { tag, size - 8 };
7134  int ret = mov_read_pack(c, pb, pack);
7135  if (ret < 0)
7136  return ret;
7137  break;
7138  }
7139  default:
7140  av_log(c->fc, AV_LOG_WARNING, "Unknown tag in vexu: %s\n",
7141  av_fourcc2str(tag));
7142  avio_skip(pb, size - 8);
7143  break;
7144  }
7145  remaining -= size;
7146  }
7147 
7148  if (remaining != 0) {
7149  av_log(c->fc, AV_LOG_ERROR, "Broken vexu box\n");
7150  return AVERROR_INVALIDDATA;
7151  }
7152 
7153  return 0;
7154 }
7155 
7157 {
7158  AVStream *st;
7159  MOVStreamContext *sc;
7160 
7161  if (c->fc->nb_streams < 1)
7162  return 0;
7163 
7164  st = c->fc->streams[c->fc->nb_streams - 1];
7165  sc = st->priv_data;
7166 
7167  if (atom.size != 4) {
7168  av_log(c->fc, AV_LOG_ERROR, "Invalid size of hfov box: %"PRIu64"\n", atom.size);
7169  return AVERROR_INVALIDDATA;
7170  }
7171 
7172 
7173  if (!sc->stereo3d) {
7175  if (!sc->stereo3d)
7176  return AVERROR(ENOMEM);
7177  }
7178 
7180  sc->stereo3d->horizontal_field_of_view.den = 1000; // thousands of a degree
7181 
7182  return 0;
7183 }
7184 
7186 {
7187  int ret = 0;
7188  uint8_t *buffer = av_malloc(len + 1);
7189  const char *val;
7190 
7191  if (!buffer)
7192  return AVERROR(ENOMEM);
7193  buffer[len] = '\0';
7194 
7195  ret = ffio_read_size(pb, buffer, len);
7196  if (ret < 0)
7197  goto out;
7198 
7199  /* Check for mandatory keys and values, try to support XML as best-effort */
7200  if (!sc->spherical &&
7201  av_stristr(buffer, "<GSpherical:StitchingSoftware>") &&
7202  (val = av_stristr(buffer, "<GSpherical:Spherical>")) &&
7203  av_stristr(val, "true") &&
7204  (val = av_stristr(buffer, "<GSpherical:Stitched>")) &&
7205  av_stristr(val, "true") &&
7206  (val = av_stristr(buffer, "<GSpherical:ProjectionType>")) &&
7207  av_stristr(val, "equirectangular")) {
7209  if (!sc->spherical)
7210  goto out;
7211 
7213 
7214  if (av_stristr(buffer, "<GSpherical:StereoMode>") && !sc->stereo3d) {
7215  enum AVStereo3DType mode;
7216 
7217  if (av_stristr(buffer, "left-right"))
7219  else if (av_stristr(buffer, "top-bottom"))
7221  else
7222  mode = AV_STEREO3D_2D;
7223 
7225  if (!sc->stereo3d)
7226  goto out;
7227 
7228  sc->stereo3d->type = mode;
7229  }
7230 
7231  /* orientation */
7232  val = av_stristr(buffer, "<GSpherical:InitialViewHeadingDegrees>");
7233  if (val)
7234  sc->spherical->yaw = strtol(val, NULL, 10) * (1 << 16);
7235  val = av_stristr(buffer, "<GSpherical:InitialViewPitchDegrees>");
7236  if (val)
7237  sc->spherical->pitch = strtol(val, NULL, 10) * (1 << 16);
7238  val = av_stristr(buffer, "<GSpherical:InitialViewRollDegrees>");
7239  if (val)
7240  sc->spherical->roll = strtol(val, NULL, 10) * (1 << 16);
7241  }
7242 
7243 out:
7244  av_free(buffer);
7245  return ret;
7246 }
7247 
7249 {
7250  AVStream *st;
7251  MOVStreamContext *sc;
7252  int64_t ret;
7253  AVUUID uuid;
7254  static const AVUUID uuid_isml_manifest = {
7255  0xa5, 0xd4, 0x0b, 0x30, 0xe8, 0x14, 0x11, 0xdd,
7256  0xba, 0x2f, 0x08, 0x00, 0x20, 0x0c, 0x9a, 0x66
7257  };
7258  static const AVUUID uuid_xmp = {
7259  0xbe, 0x7a, 0xcf, 0xcb, 0x97, 0xa9, 0x42, 0xe8,
7260  0x9c, 0x71, 0x99, 0x94, 0x91, 0xe3, 0xaf, 0xac
7261  };
7262  static const AVUUID uuid_spherical = {
7263  0xff, 0xcc, 0x82, 0x63, 0xf8, 0x55, 0x4a, 0x93,
7264  0x88, 0x14, 0x58, 0x7a, 0x02, 0x52, 0x1f, 0xdd,
7265  };
7266 
7267  if (atom.size < AV_UUID_LEN || atom.size >= FFMIN(INT_MAX, SIZE_MAX))
7268  return AVERROR_INVALIDDATA;
7269 
7270  if (c->fc->nb_streams < 1)
7271  return 0;
7272  st = c->fc->streams[c->fc->nb_streams - 1];
7273  sc = st->priv_data;
7274 
7275  ret = ffio_read_size(pb, uuid, AV_UUID_LEN);
7276  if (ret < 0)
7277  return ret;
7278  if (av_uuid_equal(uuid, uuid_isml_manifest)) {
7279  uint8_t *buffer, *ptr;
7280  char *endptr;
7281  size_t len = atom.size - AV_UUID_LEN;
7282 
7283  if (len < 4) {
7284  return AVERROR_INVALIDDATA;
7285  }
7286  ret = avio_skip(pb, 4); // zeroes
7287  len -= 4;
7288 
7289  buffer = av_mallocz(len + 1);
7290  if (!buffer) {
7291  return AVERROR(ENOMEM);
7292  }
7293  ret = ffio_read_size(pb, buffer, len);
7294  if (ret < 0) {
7295  av_free(buffer);
7296  return ret;
7297  }
7298 
7299  ptr = buffer;
7300  while ((ptr = av_stristr(ptr, "systemBitrate=\""))) {
7301  ptr += sizeof("systemBitrate=\"") - 1;
7302  c->bitrates_count++;
7303  c->bitrates = av_realloc_f(c->bitrates, c->bitrates_count, sizeof(*c->bitrates));
7304  if (!c->bitrates) {
7305  c->bitrates_count = 0;
7306  av_free(buffer);
7307  return AVERROR(ENOMEM);
7308  }
7309  errno = 0;
7310  ret = strtol(ptr, &endptr, 10);
7311  if (ret < 0 || errno || *endptr != '"') {
7312  c->bitrates[c->bitrates_count - 1] = 0;
7313  } else {
7314  c->bitrates[c->bitrates_count - 1] = ret;
7315  }
7316  }
7317 
7318  av_free(buffer);
7319  } else if (av_uuid_equal(uuid, uuid_xmp)) {
7320  uint8_t *buffer;
7321  size_t len = atom.size - AV_UUID_LEN;
7322  if (c->export_xmp) {
7323  buffer = av_mallocz(len + 1);
7324  if (!buffer) {
7325  return AVERROR(ENOMEM);
7326  }
7327  ret = ffio_read_size(pb, buffer, len);
7328  if (ret < 0) {
7329  av_free(buffer);
7330  return ret;
7331  }
7332  buffer[len] = '\0';
7333  av_dict_set(&c->fc->metadata, "xmp",
7335  } else {
7336  // skip all uuid atom, which makes it fast for long uuid-xmp file
7337  ret = avio_skip(pb, len);
7338  if (ret < 0)
7339  return ret;
7340  }
7341  } else if (av_uuid_equal(uuid, uuid_spherical)) {
7342  size_t len = atom.size - AV_UUID_LEN;
7343  ret = mov_parse_uuid_spherical(sc, pb, len);
7344  if (ret < 0)
7345  return ret;
7346  if (!sc->spherical)
7347  av_log(c->fc, AV_LOG_WARNING, "Invalid spherical metadata found\n");
7348  }
7349 
7350  return 0;
7351 }
7352 
7354 {
7355  int ret;
7356  uint8_t content[16];
7357 
7358  if (atom.size < 8)
7359  return 0;
7360 
7361  ret = ffio_read_size(pb, content, FFMIN(sizeof(content), atom.size));
7362  if (ret < 0)
7363  return ret;
7364 
7365  if ( !c->found_moov
7366  && !c->found_mdat
7367  && !memcmp(content, "Anevia\x1A\x1A", 8)
7368  && c->use_mfra_for == FF_MOV_FLAG_MFRA_AUTO) {
7369  c->use_mfra_for = FF_MOV_FLAG_MFRA_PTS;
7370  }
7371 
7372  return 0;
7373 }
7374 
7376 {
7377  uint32_t format = avio_rl32(pb);
7378  MOVStreamContext *sc;
7379  enum AVCodecID id;
7380  AVStream *st;
7381 
7382  if (c->fc->nb_streams < 1)
7383  return 0;
7384  st = c->fc->streams[c->fc->nb_streams - 1];
7385  sc = st->priv_data;
7386 
7387  switch (sc->format)
7388  {
7389  case MKTAG('e','n','c','v'): // encrypted video
7390  case MKTAG('e','n','c','a'): // encrypted audio
7391  id = mov_codec_id(st, format);
7392  if (st->codecpar->codec_id != AV_CODEC_ID_NONE &&
7393  st->codecpar->codec_id != id) {
7394  av_log(c->fc, AV_LOG_WARNING,
7395  "ignoring 'frma' atom of '%.4s', stream has codec id %d\n",
7396  (char*)&format, st->codecpar->codec_id);
7397  break;
7398  }
7399 
7400  st->codecpar->codec_id = id;
7401  sc->format = format;
7402  break;
7403 
7404  default:
7405  if (format != sc->format) {
7406  av_log(c->fc, AV_LOG_WARNING,
7407  "ignoring 'frma' atom of '%.4s', stream format is '%.4s'\n",
7408  (char*)&format, (char*)&sc->format);
7409  }
7410  break;
7411  }
7412 
7413  return 0;
7414 }
7415 
7416 /**
7417  * Gets the current encryption info and associated current stream context. If
7418  * we are parsing a track fragment, this will return the specific encryption
7419  * info for this fragment; otherwise this will return the global encryption
7420  * info for the current stream.
7421  */
7423 {
7424  MOVFragmentStreamInfo *frag_stream_info;
7425  AVStream *st;
7426  int i;
7427 
7428  frag_stream_info = get_current_frag_stream_info(&c->frag_index);
7429  if (frag_stream_info) {
7430  for (i = 0; i < c->fc->nb_streams; i++) {
7431  *sc = c->fc->streams[i]->priv_data;
7432  if ((*sc)->id == frag_stream_info->id) {
7433  st = c->fc->streams[i];
7434  break;
7435  }
7436  }
7437  if (i == c->fc->nb_streams)
7438  return 0;
7439  *sc = st->priv_data;
7440 
7441  if (!frag_stream_info->encryption_index) {
7442  // If this stream isn't encrypted, don't create the index.
7443  if (!(*sc)->cenc.default_encrypted_sample)
7444  return 0;
7445  frag_stream_info->encryption_index = av_mallocz(sizeof(*frag_stream_info->encryption_index));
7446  if (!frag_stream_info->encryption_index)
7447  return AVERROR(ENOMEM);
7448  }
7449  *encryption_index = frag_stream_info->encryption_index;
7450  return 1;
7451  } else {
7452  // No current track fragment, using stream level encryption info.
7453 
7454  if (c->fc->nb_streams < 1)
7455  return 0;
7456  st = c->fc->streams[c->fc->nb_streams - 1];
7457  *sc = st->priv_data;
7458 
7459  if (!(*sc)->cenc.encryption_index) {
7460  // If this stream isn't encrypted, don't create the index.
7461  if (!(*sc)->cenc.default_encrypted_sample)
7462  return 0;
7463  (*sc)->cenc.encryption_index = av_mallocz(sizeof(*frag_stream_info->encryption_index));
7464  if (!(*sc)->cenc.encryption_index)
7465  return AVERROR(ENOMEM);
7466  }
7467 
7468  *encryption_index = (*sc)->cenc.encryption_index;
7469  return 1;
7470  }
7471 }
7472 
7474 {
7475  int i, ret;
7476  unsigned int subsample_count;
7477  AVSubsampleEncryptionInfo *subsamples;
7478 
7479  if (!sc->cenc.default_encrypted_sample) {
7480  av_log(c->fc, AV_LOG_ERROR, "Missing schm or tenc\n");
7481  return AVERROR_INVALIDDATA;
7482  }
7483 
7484  if (sc->cenc.per_sample_iv_size || use_subsamples) {
7486  if (!*sample)
7487  return AVERROR(ENOMEM);
7488  } else
7489  *sample = NULL;
7490 
7491  if (sc->cenc.per_sample_iv_size != 0) {
7492  if ((ret = ffio_read_size(pb, (*sample)->iv, sc->cenc.per_sample_iv_size)) < 0) {
7493  av_log(c->fc, AV_LOG_ERROR, "failed to read the initialization vector\n");
7495  *sample = NULL;
7496  return ret;
7497  }
7498  }
7499 
7500  if (use_subsamples) {
7501  subsample_count = avio_rb16(pb);
7502  av_free((*sample)->subsamples);
7503  (*sample)->subsamples = av_calloc(subsample_count, sizeof(*subsamples));
7504  if (!(*sample)->subsamples) {
7506  *sample = NULL;
7507  return AVERROR(ENOMEM);
7508  }
7509 
7510  for (i = 0; i < subsample_count && !pb->eof_reached; i++) {
7511  (*sample)->subsamples[i].bytes_of_clear_data = avio_rb16(pb);
7512  (*sample)->subsamples[i].bytes_of_protected_data = avio_rb32(pb);
7513  }
7514 
7515  if (pb->eof_reached) {
7516  av_log(c->fc, AV_LOG_ERROR, "hit EOF while reading sub-sample encryption info\n");
7518  *sample = NULL;
7519  return AVERROR_INVALIDDATA;
7520  }
7521  (*sample)->subsample_count = subsample_count;
7522  }
7523 
7524  return 0;
7525 }
7526 
7528 {
7529  AVEncryptionInfo **encrypted_samples;
7530  MOVEncryptionIndex *encryption_index;
7531  MOVStreamContext *sc;
7532  int use_subsamples, ret;
7533  unsigned int sample_count, i, alloc_size = 0;
7534 
7535  ret = get_current_encryption_info(c, &encryption_index, &sc);
7536  if (ret != 1)
7537  return ret;
7538 
7539  if (encryption_index->nb_encrypted_samples) {
7540  // This can happen if we have both saio/saiz and senc atoms.
7541  av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in senc\n");
7542  return 0;
7543  }
7544 
7545  avio_r8(pb); /* version */
7546  use_subsamples = avio_rb24(pb) & 0x02; /* flags */
7547 
7548  sample_count = avio_rb32(pb);
7549  if (sample_count >= INT_MAX / sizeof(*encrypted_samples))
7550  return AVERROR(ENOMEM);
7551 
7552  for (i = 0; i < sample_count; i++) {
7553  unsigned int min_samples = FFMIN(FFMAX(i + 1, 1024 * 1024), sample_count);
7554  encrypted_samples = av_fast_realloc(encryption_index->encrypted_samples, &alloc_size,
7555  min_samples * sizeof(*encrypted_samples));
7556  if (encrypted_samples) {
7557  encryption_index->encrypted_samples = encrypted_samples;
7558 
7560  c, pb, sc, &encryption_index->encrypted_samples[i], use_subsamples);
7561  } else {
7562  ret = AVERROR(ENOMEM);
7563  }
7564  if (pb->eof_reached) {
7565  av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading senc\n");
7566  if (ret >= 0)
7567  av_encryption_info_free(encryption_index->encrypted_samples[i]);
7569  }
7570 
7571  if (ret < 0) {
7572  for (; i > 0; i--)
7573  av_encryption_info_free(encryption_index->encrypted_samples[i - 1]);
7574  av_freep(&encryption_index->encrypted_samples);
7575  return ret;
7576  }
7577  }
7578  encryption_index->nb_encrypted_samples = sample_count;
7579 
7580  return 0;
7581 }
7582 
7584 {
7585  AVEncryptionInfo **sample, **encrypted_samples;
7586  int64_t prev_pos;
7587  size_t sample_count, sample_info_size, i;
7588  int ret = 0;
7589  unsigned int alloc_size = 0;
7590 
7591  if (encryption_index->nb_encrypted_samples)
7592  return 0;
7593  sample_count = encryption_index->auxiliary_info_sample_count;
7594  if (encryption_index->auxiliary_offsets_count != 1) {
7595  av_log(c->fc, AV_LOG_ERROR, "Multiple auxiliary info chunks are not supported\n");
7596  return AVERROR_PATCHWELCOME;
7597  }
7598  if (sample_count >= INT_MAX / sizeof(*encrypted_samples))
7599  return AVERROR(ENOMEM);
7600 
7601  prev_pos = avio_tell(pb);
7602  if (!(pb->seekable & AVIO_SEEKABLE_NORMAL) ||
7603  avio_seek(pb, encryption_index->auxiliary_offsets[0], SEEK_SET) != encryption_index->auxiliary_offsets[0]) {
7604  av_log(c->fc, AV_LOG_INFO, "Failed to seek for auxiliary info, will only parse senc atoms for encryption info\n");
7605  goto finish;
7606  }
7607 
7608  for (i = 0; i < sample_count && !pb->eof_reached; i++) {
7609  unsigned int min_samples = FFMIN(FFMAX(i + 1, 1024 * 1024), sample_count);
7610  encrypted_samples = av_fast_realloc(encryption_index->encrypted_samples, &alloc_size,
7611  min_samples * sizeof(*encrypted_samples));
7612  if (!encrypted_samples) {
7613  ret = AVERROR(ENOMEM);
7614  goto finish;
7615  }
7616  encryption_index->encrypted_samples = encrypted_samples;
7617 
7618  sample = &encryption_index->encrypted_samples[i];
7619  sample_info_size = encryption_index->auxiliary_info_default_size
7620  ? encryption_index->auxiliary_info_default_size
7621  : encryption_index->auxiliary_info_sizes[i];
7622 
7623  ret = mov_read_sample_encryption_info(c, pb, sc, sample, sample_info_size > sc->cenc.per_sample_iv_size);
7624  if (ret < 0)
7625  goto finish;
7626  }
7627  if (pb->eof_reached) {
7628  av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading auxiliary info\n");
7630  } else {
7631  encryption_index->nb_encrypted_samples = sample_count;
7632  }
7633 
7634 finish:
7635  avio_seek(pb, prev_pos, SEEK_SET);
7636  if (ret < 0) {
7637  for (; i > 0; i--) {
7638  av_encryption_info_free(encryption_index->encrypted_samples[i - 1]);
7639  }
7640  av_freep(&encryption_index->encrypted_samples);
7641  }
7642  return ret;
7643 }
7644 
7646 {
7647  MOVEncryptionIndex *encryption_index;
7648  MOVStreamContext *sc;
7649  int ret;
7650  unsigned int sample_count, aux_info_type, aux_info_param;
7651 
7652  ret = get_current_encryption_info(c, &encryption_index, &sc);
7653  if (ret != 1)
7654  return ret;
7655 
7656  if (encryption_index->nb_encrypted_samples) {
7657  // This can happen if we have both saio/saiz and senc atoms.
7658  av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in saiz\n");
7659  return 0;
7660  }
7661 
7662  if (encryption_index->auxiliary_info_sample_count) {
7663  av_log(c->fc, AV_LOG_ERROR, "Duplicate saiz atom\n");
7664  return AVERROR_INVALIDDATA;
7665  }
7666 
7667  avio_r8(pb); /* version */
7668  if (avio_rb24(pb) & 0x01) { /* flags */
7669  aux_info_type = avio_rb32(pb);
7670  aux_info_param = avio_rb32(pb);
7671  if (sc->cenc.default_encrypted_sample) {
7672  if (aux_info_type != sc->cenc.default_encrypted_sample->scheme) {
7673  av_log(c->fc, AV_LOG_DEBUG, "Ignoring saiz box with non-zero aux_info_type\n");
7674  return 0;
7675  }
7676  if (aux_info_param != 0) {
7677  av_log(c->fc, AV_LOG_DEBUG, "Ignoring saiz box with non-zero aux_info_type_parameter\n");
7678  return 0;
7679  }
7680  } else {
7681  // Didn't see 'schm' or 'tenc', so this isn't encrypted.
7682  if ((aux_info_type == MKBETAG('c','e','n','c') ||
7683  aux_info_type == MKBETAG('c','e','n','s') ||
7684  aux_info_type == MKBETAG('c','b','c','1') ||
7685  aux_info_type == MKBETAG('c','b','c','s')) &&
7686  aux_info_param == 0) {
7687  av_log(c->fc, AV_LOG_ERROR, "Saw encrypted saiz without schm/tenc\n");
7688  return AVERROR_INVALIDDATA;
7689  } else {
7690  return 0;
7691  }
7692  }
7693  } else if (!sc->cenc.default_encrypted_sample) {
7694  // Didn't see 'schm' or 'tenc', so this isn't encrypted.
7695  return 0;
7696  }
7697 
7698  encryption_index->auxiliary_info_default_size = avio_r8(pb);
7699  sample_count = avio_rb32(pb);
7700 
7701  if (encryption_index->auxiliary_info_default_size == 0) {
7702  if (sample_count == 0)
7703  return AVERROR_INVALIDDATA;
7704 
7705  encryption_index->auxiliary_info_sizes = av_malloc(sample_count);
7706  if (!encryption_index->auxiliary_info_sizes)
7707  return AVERROR(ENOMEM);
7708 
7709  ret = avio_read(pb, encryption_index->auxiliary_info_sizes, sample_count);
7710  if (ret != sample_count) {
7711  av_freep(&encryption_index->auxiliary_info_sizes);
7712 
7713  if (ret >= 0)
7715  av_log(c->fc, AV_LOG_ERROR, "Failed to read the auxiliary info, %s\n",
7716  av_err2str(ret));
7717  return ret;
7718  }
7719  }
7720  encryption_index->auxiliary_info_sample_count = sample_count;
7721 
7722  if (encryption_index->auxiliary_offsets_count) {
7723  return mov_parse_auxiliary_info(c, sc, pb, encryption_index);
7724  }
7725 
7726  return 0;
7727 }
7728 
7730 {
7731  uint64_t *auxiliary_offsets;
7732  MOVEncryptionIndex *encryption_index;
7733  MOVStreamContext *sc;
7734  int i, ret;
7735  unsigned int version, entry_count, aux_info_type, aux_info_param;
7736  unsigned int alloc_size = 0;
7737 
7738  ret = get_current_encryption_info(c, &encryption_index, &sc);
7739  if (ret != 1)
7740  return ret;
7741 
7742  if (encryption_index->nb_encrypted_samples) {
7743  // This can happen if we have both saio/saiz and senc atoms.
7744  av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in saio\n");
7745  return 0;
7746  }
7747 
7748  if (encryption_index->auxiliary_offsets_count) {
7749  av_log(c->fc, AV_LOG_ERROR, "Duplicate saio atom\n");
7750  return AVERROR_INVALIDDATA;
7751  }
7752 
7753  version = avio_r8(pb); /* version */
7754  if (avio_rb24(pb) & 0x01) { /* flags */
7755  aux_info_type = avio_rb32(pb);
7756  aux_info_param = avio_rb32(pb);
7757  if (sc->cenc.default_encrypted_sample) {
7758  if (aux_info_type != sc->cenc.default_encrypted_sample->scheme) {
7759  av_log(c->fc, AV_LOG_DEBUG, "Ignoring saio box with non-zero aux_info_type\n");
7760  return 0;
7761  }
7762  if (aux_info_param != 0) {
7763  av_log(c->fc, AV_LOG_DEBUG, "Ignoring saio box with non-zero aux_info_type_parameter\n");
7764  return 0;
7765  }
7766  } else {
7767  // Didn't see 'schm' or 'tenc', so this isn't encrypted.
7768  if ((aux_info_type == MKBETAG('c','e','n','c') ||
7769  aux_info_type == MKBETAG('c','e','n','s') ||
7770  aux_info_type == MKBETAG('c','b','c','1') ||
7771  aux_info_type == MKBETAG('c','b','c','s')) &&
7772  aux_info_param == 0) {
7773  av_log(c->fc, AV_LOG_ERROR, "Saw encrypted saio without schm/tenc\n");
7774  return AVERROR_INVALIDDATA;
7775  } else {
7776  return 0;
7777  }
7778  }
7779  } else if (!sc->cenc.default_encrypted_sample) {
7780  // Didn't see 'schm' or 'tenc', so this isn't encrypted.
7781  return 0;
7782  }
7783 
7784  entry_count = avio_rb32(pb);
7785  if (entry_count >= INT_MAX / sizeof(*auxiliary_offsets))
7786  return AVERROR(ENOMEM);
7787 
7788  for (i = 0; i < entry_count && !pb->eof_reached; i++) {
7789  unsigned int min_offsets = FFMIN(FFMAX(i + 1, 1024), entry_count);
7790  auxiliary_offsets = av_fast_realloc(
7791  encryption_index->auxiliary_offsets, &alloc_size,
7792  min_offsets * sizeof(*auxiliary_offsets));
7793  if (!auxiliary_offsets) {
7794  av_freep(&encryption_index->auxiliary_offsets);
7795  return AVERROR(ENOMEM);
7796  }
7797  encryption_index->auxiliary_offsets = auxiliary_offsets;
7798 
7799  if (version == 0) {
7800  encryption_index->auxiliary_offsets[i] = avio_rb32(pb);
7801  } else {
7802  encryption_index->auxiliary_offsets[i] = avio_rb64(pb);
7803  }
7804  if (c->frag_index.current >= 0) {
7805  encryption_index->auxiliary_offsets[i] += c->fragment.base_data_offset;
7806  }
7807  }
7808 
7809  if (pb->eof_reached) {
7810  av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading saio\n");
7811  av_freep(&encryption_index->auxiliary_offsets);
7812  return AVERROR_INVALIDDATA;
7813  }
7814 
7815  encryption_index->auxiliary_offsets_count = entry_count;
7816 
7817  if (encryption_index->auxiliary_info_sample_count) {
7818  return mov_parse_auxiliary_info(c, sc, pb, encryption_index);
7819  }
7820 
7821  return 0;
7822 }
7823 
7825 {
7826  AVEncryptionInitInfo *info, *old_init_info;
7827  uint8_t **key_ids;
7828  AVStream *st;
7829  const AVPacketSideData *old_side_data;
7830  uint8_t *side_data, *extra_data;
7831  size_t side_data_size;
7832  int ret = 0;
7833  unsigned int version, kid_count, extra_data_size, alloc_size = 0;
7834 
7835  if (c->fc->nb_streams < 1)
7836  return 0;
7837  st = c->fc->streams[c->fc->nb_streams-1];
7838 
7839  version = avio_r8(pb); /* version */
7840  avio_rb24(pb); /* flags */
7841 
7842  info = av_encryption_init_info_alloc(/* system_id_size */ 16, /* num_key_ids */ 0,
7843  /* key_id_size */ 16, /* data_size */ 0);
7844  if (!info)
7845  return AVERROR(ENOMEM);
7846 
7847  if ((ret = ffio_read_size(pb, info->system_id, 16)) < 0) {
7848  av_log(c->fc, AV_LOG_ERROR, "Failed to read the system id\n");
7849  goto finish;
7850  }
7851 
7852  if (version > 0) {
7853  kid_count = avio_rb32(pb);
7854  if (kid_count >= INT_MAX / sizeof(*key_ids)) {
7855  ret = AVERROR(ENOMEM);
7856  goto finish;
7857  }
7858 
7859  for (unsigned int i = 0; i < kid_count && !pb->eof_reached; i++) {
7860  unsigned int min_kid_count = FFMIN(FFMAX(i + 1, 1024), kid_count);
7861  key_ids = av_fast_realloc(info->key_ids, &alloc_size,
7862  min_kid_count * sizeof(*key_ids));
7863  if (!key_ids) {
7864  ret = AVERROR(ENOMEM);
7865  goto finish;
7866  }
7867  info->key_ids = key_ids;
7868 
7869  info->key_ids[i] = av_mallocz(16);
7870  if (!info->key_ids[i]) {
7871  ret = AVERROR(ENOMEM);
7872  goto finish;
7873  }
7874  info->num_key_ids = i + 1;
7875 
7876  if ((ret = ffio_read_size(pb, info->key_ids[i], 16)) < 0) {
7877  av_log(c->fc, AV_LOG_ERROR, "Failed to read the key id\n");
7878  goto finish;
7879  }
7880  }
7881 
7882  if (pb->eof_reached) {
7883  av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading pssh\n");
7885  goto finish;
7886  }
7887  }
7888 
7889  extra_data_size = avio_rb32(pb);
7890  extra_data = av_malloc(extra_data_size);
7891  if (!extra_data) {
7892  ret = AVERROR(ENOMEM);
7893  goto finish;
7894  }
7895  ret = avio_read(pb, extra_data, extra_data_size);
7896  if (ret != extra_data_size) {
7897  av_free(extra_data);
7898 
7899  if (ret >= 0)
7901  goto finish;
7902  }
7903 
7904  av_freep(&info->data); // malloc(0) may still allocate something.
7905  info->data = extra_data;
7906  info->data_size = extra_data_size;
7907 
7908  // If there is existing initialization data, append to the list.
7911  if (old_side_data) {
7912  old_init_info = av_encryption_init_info_get_side_data(old_side_data->data, old_side_data->size);
7913  if (old_init_info) {
7914  // Append to the end of the list.
7915  for (AVEncryptionInitInfo *cur = old_init_info;; cur = cur->next) {
7916  if (!cur->next) {
7917  cur->next = info;
7918  break;
7919  }
7920  }
7921  info = old_init_info;
7922  } else {
7923  // Assume existing side-data will be valid, so the only error we could get is OOM.
7924  ret = AVERROR(ENOMEM);
7925  goto finish;
7926  }
7927  }
7928 
7929  side_data = av_encryption_init_info_add_side_data(info, &side_data_size);
7930  if (!side_data) {
7931  ret = AVERROR(ENOMEM);
7932  goto finish;
7933  }
7937  side_data, side_data_size, 0))
7938  av_free(side_data);
7939 
7940 finish:
7942  return ret;
7943 }
7944 
7946 {
7947  AVStream *st;
7948  MOVStreamContext *sc;
7949 
7950  if (c->fc->nb_streams < 1)
7951  return 0;
7952  st = c->fc->streams[c->fc->nb_streams-1];
7953  sc = st->priv_data;
7954 
7955  if (sc->pseudo_stream_id != 0) {
7956  av_log(c->fc, AV_LOG_ERROR, "schm boxes are only supported in first sample descriptor\n");
7957  return AVERROR_PATCHWELCOME;
7958  }
7959 
7960  if (atom.size < 8)
7961  return AVERROR_INVALIDDATA;
7962 
7963  avio_rb32(pb); /* version and flags */
7964 
7965  if (!sc->cenc.default_encrypted_sample) {
7967  if (!sc->cenc.default_encrypted_sample) {
7968  return AVERROR(ENOMEM);
7969  }
7970  }
7971 
7973  return 0;
7974 }
7975 
7977 {
7978  AVStream *st;
7979  MOVStreamContext *sc;
7980  unsigned int version, pattern, is_protected, iv_size;
7981 
7982  if (c->fc->nb_streams < 1)
7983  return 0;
7984  st = c->fc->streams[c->fc->nb_streams-1];
7985  sc = st->priv_data;
7986 
7987  if (sc->pseudo_stream_id != 0) {
7988  av_log(c->fc, AV_LOG_ERROR, "tenc atom are only supported in first sample descriptor\n");
7989  return AVERROR_PATCHWELCOME;
7990  }
7991 
7992  if (!sc->cenc.default_encrypted_sample) {
7994  if (!sc->cenc.default_encrypted_sample) {
7995  return AVERROR(ENOMEM);
7996  }
7997  }
7998 
7999  if (atom.size < 20)
8000  return AVERROR_INVALIDDATA;
8001 
8002  version = avio_r8(pb); /* version */
8003  avio_rb24(pb); /* flags */
8004 
8005  avio_r8(pb); /* reserved */
8006  pattern = avio_r8(pb);
8007 
8008  if (version > 0) {
8009  sc->cenc.default_encrypted_sample->crypt_byte_block = pattern >> 4;
8010  sc->cenc.default_encrypted_sample->skip_byte_block = pattern & 0xf;
8011  }
8012 
8013  is_protected = avio_r8(pb);
8014  if (is_protected && !sc->cenc.encryption_index) {
8015  // The whole stream should be by-default encrypted.
8017  if (!sc->cenc.encryption_index)
8018  return AVERROR(ENOMEM);
8019  }
8020  sc->cenc.per_sample_iv_size = avio_r8(pb);
8021  if (sc->cenc.per_sample_iv_size != 0 && sc->cenc.per_sample_iv_size != 8 &&
8022  sc->cenc.per_sample_iv_size != 16) {
8023  av_log(c->fc, AV_LOG_ERROR, "invalid per-sample IV size value\n");
8024  return AVERROR_INVALIDDATA;
8025  }
8026  if (avio_read(pb, sc->cenc.default_encrypted_sample->key_id, 16) != 16) {
8027  av_log(c->fc, AV_LOG_ERROR, "failed to read the default key ID\n");
8028  return AVERROR_INVALIDDATA;
8029  }
8030 
8031  if (is_protected && !sc->cenc.per_sample_iv_size) {
8032  iv_size = avio_r8(pb);
8033  if (iv_size != 8 && iv_size != 16) {
8034  av_log(c->fc, AV_LOG_ERROR, "invalid default_constant_IV_size in tenc atom\n");
8035  return AVERROR_INVALIDDATA;
8036  }
8037 
8038  if (avio_read(pb, sc->cenc.default_encrypted_sample->iv, iv_size) != iv_size) {
8039  av_log(c->fc, AV_LOG_ERROR, "failed to read the default IV\n");
8040  return AVERROR_INVALIDDATA;
8041  }
8042  }
8043 
8044  return 0;
8045 }
8046 
8048 {
8049  AVStream *st;
8050  int last, type, size, ret;
8051  uint8_t buf[4];
8052 
8053  if (c->fc->nb_streams < 1)
8054  return 0;
8055  st = c->fc->streams[c->fc->nb_streams-1];
8056 
8057  if ((uint64_t)atom.size > (1<<30) || atom.size < 42)
8058  return AVERROR_INVALIDDATA;
8059 
8060  /* Check FlacSpecificBox version. */
8061  if (avio_r8(pb) != 0)
8062  return AVERROR_INVALIDDATA;
8063 
8064  avio_rb24(pb); /* Flags */
8065 
8066  if (avio_read(pb, buf, sizeof(buf)) != sizeof(buf)) {
8067  av_log(c->fc, AV_LOG_ERROR, "failed to read FLAC metadata block header\n");
8068  return pb->error < 0 ? pb->error : AVERROR_INVALIDDATA;
8069  }
8070  flac_parse_block_header(buf, &last, &type, &size);
8071 
8073  av_log(c->fc, AV_LOG_ERROR, "STREAMINFO must be first FLACMetadataBlock\n");
8074  return AVERROR_INVALIDDATA;
8075  }
8076 
8077  ret = ff_get_extradata(c->fc, st->codecpar, pb, size);
8078  if (ret < 0)
8079  return ret;
8080 
8081  if (!last)
8082  av_log(c->fc, AV_LOG_WARNING, "non-STREAMINFO FLACMetadataBlock(s) ignored\n");
8083 
8084  return 0;
8085 }
8086 
8088 {
8089  int i, ret;
8090  int bytes_of_protected_data;
8091 
8092  if (!sc->cenc.aes_ctr) {
8093  /* initialize the cipher */
8094  sc->cenc.aes_ctr = av_aes_ctr_alloc();
8095  if (!sc->cenc.aes_ctr) {
8096  return AVERROR(ENOMEM);
8097  }
8098 
8099  ret = av_aes_ctr_init(sc->cenc.aes_ctr, c->decryption_key);
8100  if (ret < 0) {
8101  return ret;
8102  }
8103  }
8104 
8106 
8107  if (!sample->subsample_count) {
8108  /* decrypt the whole packet */
8110  return 0;
8111  }
8112 
8113  for (i = 0; i < sample->subsample_count; i++) {
8114  if (sample->subsamples[i].bytes_of_clear_data + sample->subsamples[i].bytes_of_protected_data > size) {
8115  av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n");
8116  return AVERROR_INVALIDDATA;
8117  }
8118 
8119  /* skip the clear bytes */
8120  input += sample->subsamples[i].bytes_of_clear_data;
8121  size -= sample->subsamples[i].bytes_of_clear_data;
8122 
8123  /* decrypt the encrypted bytes */
8124 
8125  bytes_of_protected_data = sample->subsamples[i].bytes_of_protected_data;
8126  av_aes_ctr_crypt(sc->cenc.aes_ctr, input, input, bytes_of_protected_data);
8127 
8128  input += bytes_of_protected_data;
8129  size -= bytes_of_protected_data;
8130  }
8131 
8132  if (size > 0) {
8133  av_log(c->fc, AV_LOG_ERROR, "leftover packet bytes after subsample processing\n");
8134  return AVERROR_INVALIDDATA;
8135  }
8136 
8137  return 0;
8138 }
8139 
8141 {
8142  int i, ret;
8143  int num_of_encrypted_blocks;
8144  uint8_t iv[16];
8145 
8146  if (!sc->cenc.aes_ctx) {
8147  /* initialize the cipher */
8148  sc->cenc.aes_ctx = av_aes_alloc();
8149  if (!sc->cenc.aes_ctx) {
8150  return AVERROR(ENOMEM);
8151  }
8152 
8153  ret = av_aes_init(sc->cenc.aes_ctx, c->decryption_key, 16 * 8, 1);
8154  if (ret < 0) {
8155  return ret;
8156  }
8157  }
8158 
8159  memcpy(iv, sample->iv, 16);
8160 
8161  /* whole-block full sample encryption */
8162  if (!sample->subsample_count) {
8163  /* decrypt the whole packet */
8164  av_aes_crypt(sc->cenc.aes_ctx, input, input, size/16, iv, 1);
8165  return 0;
8166  }
8167 
8168  for (i = 0; i < sample->subsample_count; i++) {
8169  if (sample->subsamples[i].bytes_of_clear_data + sample->subsamples[i].bytes_of_protected_data > size) {
8170  av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n");
8171  return AVERROR_INVALIDDATA;
8172  }
8173 
8174  if (sample->subsamples[i].bytes_of_protected_data % 16) {
8175  av_log(c->fc, AV_LOG_ERROR, "subsample BytesOfProtectedData is not a multiple of 16\n");
8176  return AVERROR_INVALIDDATA;
8177  }
8178 
8179  /* skip the clear bytes */
8180  input += sample->subsamples[i].bytes_of_clear_data;
8181  size -= sample->subsamples[i].bytes_of_clear_data;
8182 
8183  /* decrypt the encrypted bytes */
8184  num_of_encrypted_blocks = sample->subsamples[i].bytes_of_protected_data/16;
8185  if (num_of_encrypted_blocks > 0) {
8186  av_aes_crypt(sc->cenc.aes_ctx, input, input, num_of_encrypted_blocks, iv, 1);
8187  }
8188  input += sample->subsamples[i].bytes_of_protected_data;
8189  size -= sample->subsamples[i].bytes_of_protected_data;
8190  }
8191 
8192  if (size > 0) {
8193  av_log(c->fc, AV_LOG_ERROR, "leftover packet bytes after subsample processing\n");
8194  return AVERROR_INVALIDDATA;
8195  }
8196 
8197  return 0;
8198 }
8199 
8201 {
8202  int i, ret, rem_bytes;
8203  uint8_t *data;
8204 
8205  if (!sc->cenc.aes_ctr) {
8206  /* initialize the cipher */
8207  sc->cenc.aes_ctr = av_aes_ctr_alloc();
8208  if (!sc->cenc.aes_ctr) {
8209  return AVERROR(ENOMEM);
8210  }
8211 
8212  ret = av_aes_ctr_init(sc->cenc.aes_ctr, c->decryption_key);
8213  if (ret < 0) {
8214  return ret;
8215  }
8216  }
8217 
8219 
8220  /* whole-block full sample encryption */
8221  if (!sample->subsample_count) {
8222  /* decrypt the whole packet */
8224  return 0;
8225  } else if (!sample->crypt_byte_block && !sample->skip_byte_block) {
8226  av_log(c->fc, AV_LOG_ERROR, "pattern encryption is not present in 'cens' scheme\n");
8227  return AVERROR_INVALIDDATA;
8228  }
8229 
8230  for (i = 0; i < sample->subsample_count; i++) {
8231  if (sample->subsamples[i].bytes_of_clear_data + sample->subsamples[i].bytes_of_protected_data > size) {
8232  av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n");
8233  return AVERROR_INVALIDDATA;
8234  }
8235 
8236  /* skip the clear bytes */
8237  input += sample->subsamples[i].bytes_of_clear_data;
8238  size -= sample->subsamples[i].bytes_of_clear_data;
8239 
8240  /* decrypt the encrypted bytes */
8241  data = input;
8242  rem_bytes = sample->subsamples[i].bytes_of_protected_data;
8243  while (rem_bytes > 0) {
8244  if (rem_bytes < 16*sample->crypt_byte_block) {
8245  break;
8246  }
8247  av_aes_ctr_crypt(sc->cenc.aes_ctr, data, data, 16*sample->crypt_byte_block);
8248  data += 16*sample->crypt_byte_block;
8249  rem_bytes -= 16*sample->crypt_byte_block;
8250  data += FFMIN(16*sample->skip_byte_block, rem_bytes);
8251  rem_bytes -= FFMIN(16*sample->skip_byte_block, rem_bytes);
8252  }
8253  input += sample->subsamples[i].bytes_of_protected_data;
8254  size -= sample->subsamples[i].bytes_of_protected_data;
8255  }
8256 
8257  if (size > 0) {
8258  av_log(c->fc, AV_LOG_ERROR, "leftover packet bytes after subsample processing\n");
8259  return AVERROR_INVALIDDATA;
8260  }
8261 
8262  return 0;
8263 }
8264 
8266 {
8267  int i, ret, rem_bytes;
8268  uint8_t iv[16];
8269  uint8_t *data;
8270 
8271  if (!sc->cenc.aes_ctx) {
8272  /* initialize the cipher */
8273  sc->cenc.aes_ctx = av_aes_alloc();
8274  if (!sc->cenc.aes_ctx) {
8275  return AVERROR(ENOMEM);
8276  }
8277 
8278  ret = av_aes_init(sc->cenc.aes_ctx, c->decryption_key, 16 * 8, 1);
8279  if (ret < 0) {
8280  return ret;
8281  }
8282  }
8283 
8284  /* whole-block full sample encryption */
8285  if (!sample->subsample_count) {
8286  /* decrypt the whole packet */
8287  memcpy(iv, sample->iv, 16);
8288  av_aes_crypt(sc->cenc.aes_ctx, input, input, size/16, iv, 1);
8289  return 0;
8290  } else if (!sample->crypt_byte_block && !sample->skip_byte_block) {
8291  av_log(c->fc, AV_LOG_ERROR, "pattern encryption is not present in 'cbcs' scheme\n");
8292  return AVERROR_INVALIDDATA;
8293  }
8294 
8295  for (i = 0; i < sample->subsample_count; i++) {
8296  if (sample->subsamples[i].bytes_of_clear_data + sample->subsamples[i].bytes_of_protected_data > size) {
8297  av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n");
8298  return AVERROR_INVALIDDATA;
8299  }
8300 
8301  /* skip the clear bytes */
8302  input += sample->subsamples[i].bytes_of_clear_data;
8303  size -= sample->subsamples[i].bytes_of_clear_data;
8304 
8305  /* decrypt the encrypted bytes */
8306  memcpy(iv, sample->iv, 16);
8307  data = input;
8308  rem_bytes = sample->subsamples[i].bytes_of_protected_data;
8309  while (rem_bytes > 0) {
8310  if (rem_bytes < 16*sample->crypt_byte_block) {
8311  break;
8312  }
8313  av_aes_crypt(sc->cenc.aes_ctx, data, data, sample->crypt_byte_block, iv, 1);
8314  data += 16*sample->crypt_byte_block;
8315  rem_bytes -= 16*sample->crypt_byte_block;
8316  data += FFMIN(16*sample->skip_byte_block, rem_bytes);
8317  rem_bytes -= FFMIN(16*sample->skip_byte_block, rem_bytes);
8318  }
8319  input += sample->subsamples[i].bytes_of_protected_data;
8320  size -= sample->subsamples[i].bytes_of_protected_data;
8321  }
8322 
8323  if (size > 0) {
8324  av_log(c->fc, AV_LOG_ERROR, "leftover packet bytes after subsample processing\n");
8325  return AVERROR_INVALIDDATA;
8326  }
8327 
8328  return 0;
8329 }
8330 
8332 {
8333  if (sample->scheme == MKBETAG('c','e','n','c') && !sample->crypt_byte_block && !sample->skip_byte_block) {
8334  return cenc_scheme_decrypt(c, sc, sample, input, size);
8335  } else if (sample->scheme == MKBETAG('c','b','c','1') && !sample->crypt_byte_block && !sample->skip_byte_block) {
8336  return cbc1_scheme_decrypt(c, sc, sample, input, size);
8337  } else if (sample->scheme == MKBETAG('c','e','n','s')) {
8338  return cens_scheme_decrypt(c, sc, sample, input, size);
8339  } else if (sample->scheme == MKBETAG('c','b','c','s')) {
8340  return cbcs_scheme_decrypt(c, sc, sample, input, size);
8341  } else {
8342  av_log(c->fc, AV_LOG_ERROR, "invalid encryption scheme\n");
8343  return AVERROR_INVALIDDATA;
8344  }
8345 }
8346 
8348 {
8349  int current = frag_index->current;
8350 
8351  if (!frag_index->nb_items)
8352  return NULL;
8353 
8354  // Check frag_index->current is the right one for pkt. It can out of sync.
8355  if (current >= 0 && current < frag_index->nb_items) {
8356  if (frag_index->item[current].moof_offset < pkt->pos &&
8357  (current + 1 == frag_index->nb_items ||
8358  frag_index->item[current + 1].moof_offset > pkt->pos))
8359  return get_frag_stream_info(frag_index, current, id);
8360  }
8361 
8362 
8363  for (int i = 0; i < frag_index->nb_items; i++) {
8364  if (frag_index->item[i].moof_offset > pkt->pos)
8365  break;
8366  current = i;
8367  }
8368  frag_index->current = current;
8369  return get_frag_stream_info(frag_index, current, id);
8370 }
8371 
8372 static int cenc_filter(MOVContext *mov, AVStream* st, MOVStreamContext *sc, AVPacket *pkt, int current_index)
8373 {
8374  MOVFragmentStreamInfo *frag_stream_info;
8375  MOVEncryptionIndex *encryption_index;
8376  AVEncryptionInfo *encrypted_sample;
8377  int encrypted_index, ret;
8378 
8379  frag_stream_info = get_frag_stream_info_from_pkt(&mov->frag_index, pkt, sc->id);
8380  encrypted_index = current_index;
8381  encryption_index = NULL;
8382  if (frag_stream_info) {
8383  // Note this only supports encryption info in the first sample descriptor.
8384  if (frag_stream_info->stsd_id == 1) {
8385  if (frag_stream_info->encryption_index) {
8386  encrypted_index = current_index - frag_stream_info->index_base;
8387  encryption_index = frag_stream_info->encryption_index;
8388  } else {
8389  encryption_index = sc->cenc.encryption_index;
8390  }
8391  }
8392  } else {
8393  encryption_index = sc->cenc.encryption_index;
8394  }
8395 
8396  if (encryption_index) {
8397  if (encryption_index->auxiliary_info_sample_count &&
8398  !encryption_index->nb_encrypted_samples) {
8399  av_log(mov->fc, AV_LOG_ERROR, "saiz atom found without saio\n");
8400  return AVERROR_INVALIDDATA;
8401  }
8402  if (encryption_index->auxiliary_offsets_count &&
8403  !encryption_index->nb_encrypted_samples) {
8404  av_log(mov->fc, AV_LOG_ERROR, "saio atom found without saiz\n");
8405  return AVERROR_INVALIDDATA;
8406  }
8407 
8408  encrypted_sample = NULL;
8409  if (!encryption_index->nb_encrypted_samples) {
8410  // Full-sample encryption with default settings.
8411  encrypted_sample = sc->cenc.default_encrypted_sample;
8412  } else if (encrypted_index >= 0 && encrypted_index < encryption_index->nb_encrypted_samples) {
8413  // Per-sample setting override.
8414  encrypted_sample = encryption_index->encrypted_samples[encrypted_index];
8415  if (!encrypted_sample) {
8416  encrypted_sample = sc->cenc.default_encrypted_sample;
8417  }
8418  }
8419 
8420  if (!encrypted_sample) {
8421  av_log(mov->fc, AV_LOG_ERROR, "Incorrect number of samples in encryption info\n");
8422  return AVERROR_INVALIDDATA;
8423  }
8424 
8425  if (mov->decryption_key) {
8426  return cenc_decrypt(mov, sc, encrypted_sample, pkt->data, pkt->size);
8427  } else {
8428  size_t size;
8429  uint8_t *side_data = av_encryption_info_add_side_data(encrypted_sample, &size);
8430  if (!side_data)
8431  return AVERROR(ENOMEM);
8433  if (ret < 0)
8434  av_free(side_data);
8435  return ret;
8436  }
8437  }
8438 
8439  return 0;
8440 }
8441 
8443 {
8444  const int OPUS_SEEK_PREROLL_MS = 80;
8445  int ret;
8446  AVStream *st;
8447  size_t size;
8448  uint16_t pre_skip;
8449 
8450  if (c->fc->nb_streams < 1)
8451  return 0;
8452  st = c->fc->streams[c->fc->nb_streams-1];
8453 
8454  if ((uint64_t)atom.size > (1<<30) || atom.size < 11)
8455  return AVERROR_INVALIDDATA;
8456 
8457  /* Check OpusSpecificBox version. */
8458  if (avio_r8(pb) != 0) {
8459  av_log(c->fc, AV_LOG_ERROR, "unsupported OpusSpecificBox version\n");
8460  return AVERROR_INVALIDDATA;
8461  }
8462 
8463  /* OpusSpecificBox size plus magic for Ogg OpusHead header. */
8464  size = atom.size + 8;
8465 
8466  if ((ret = ff_alloc_extradata(st->codecpar, size)) < 0)
8467  return ret;
8468 
8469  AV_WL32A(st->codecpar->extradata, MKTAG('O','p','u','s'));
8470  AV_WL32A(st->codecpar->extradata + 4, MKTAG('H','e','a','d'));
8471  AV_WB8(st->codecpar->extradata + 8, 1); /* OpusHead version */
8472  avio_read(pb, st->codecpar->extradata + 9, size - 9);
8473 
8474  /* OpusSpecificBox is stored in big-endian, but OpusHead is
8475  little-endian; aside from the preceding magic and version they're
8476  otherwise currently identical. Data after output gain at offset 16
8477  doesn't need to be bytewapped. */
8478  pre_skip = AV_RB16A(st->codecpar->extradata + 10);
8479  AV_WL16A(st->codecpar->extradata + 10, pre_skip);
8480  AV_WL32A(st->codecpar->extradata + 12, AV_RB32A(st->codecpar->extradata + 12));
8481  AV_WL16A(st->codecpar->extradata + 16, AV_RB16A(st->codecpar->extradata + 16));
8482 
8483  st->codecpar->initial_padding = pre_skip;
8485  (AVRational){1, 1000},
8486  (AVRational){1, 48000});
8487 
8488  return 0;
8489 }
8490 
8492 {
8493  AVStream *st;
8494  unsigned format_info;
8495  int channel_assignment, channel_assignment1, channel_assignment2;
8496  int ratebits;
8497  uint64_t chmask;
8498 
8499  if (c->fc->nb_streams < 1)
8500  return 0;
8501  st = c->fc->streams[c->fc->nb_streams-1];
8502 
8503  if (atom.size < 10)
8504  return AVERROR_INVALIDDATA;
8505 
8506  format_info = avio_rb32(pb);
8507 
8508  ratebits = (format_info >> 28) & 0xF;
8509  channel_assignment1 = (format_info >> 15) & 0x1F;
8510  channel_assignment2 = format_info & 0x1FFF;
8511  if (channel_assignment2)
8512  channel_assignment = channel_assignment2;
8513  else
8514  channel_assignment = channel_assignment1;
8515 
8516  st->codecpar->frame_size = 40 << (ratebits & 0x7);
8517  st->codecpar->sample_rate = mlp_samplerate(ratebits);
8518 
8520  chmask = truehd_layout(channel_assignment);
8522 
8523  return 0;
8524 }
8525 
8527 {
8528  AVStream *st;
8529  uint8_t buf[ISOM_DVCC_DVVC_SIZE];
8530  int ret;
8531  int64_t read_size = atom.size;
8532 
8533  if (c->fc->nb_streams < 1)
8534  return 0;
8535  st = c->fc->streams[c->fc->nb_streams-1];
8536 
8537  // At most 24 bytes
8538  read_size = FFMIN(read_size, ISOM_DVCC_DVVC_SIZE);
8539 
8540  if ((ret = ffio_read_size(pb, buf, read_size)) < 0)
8541  return ret;
8542 
8543  return ff_isom_parse_dvcc_dvvc(c->fc, st, buf, read_size);
8544 }
8545 
8547 {
8548  AVStream *st;
8549  uint8_t *buf;
8550  int ret, old_size, num_arrays;
8551 
8552  if (c->fc->nb_streams < 1)
8553  return 0;
8554  st = c->fc->streams[c->fc->nb_streams-1];
8555 
8556  if (!st->codecpar->extradata_size)
8557  // TODO: handle lhvC when present before hvcC
8558  return 0;
8559 
8560  if (atom.size < 6 || st->codecpar->extradata_size < 23)
8561  return AVERROR_INVALIDDATA;
8562 
8564  if (!buf)
8565  return AVERROR(ENOMEM);
8566  memset(buf + atom.size, 0, AV_INPUT_BUFFER_PADDING_SIZE);
8567 
8568  ret = ffio_read_size(pb, buf, atom.size);
8569  if (ret < 0) {
8570  av_free(buf);
8571  av_log(c->fc, AV_LOG_WARNING, "lhvC atom truncated\n");
8572  return 0;
8573  }
8574 
8575  num_arrays = buf[5];
8576  old_size = st->codecpar->extradata_size;
8577  atom.size -= 8 /* account for mov_realloc_extradata offsetting */
8578  + 6 /* lhvC bytes before the arrays*/;
8579 
8580  ret = mov_realloc_extradata(st->codecpar, atom);
8581  if (ret < 0) {
8582  av_free(buf);
8583  return ret;
8584  }
8585 
8586  st->codecpar->extradata[22] += num_arrays;
8587  memcpy(st->codecpar->extradata + old_size, buf + 6, atom.size + 8);
8588 
8590 
8591  av_free(buf);
8592  return 0;
8593 }
8594 
8596 {
8597  AVFormatContext *ctx = c->fc;
8598  AVStream *st = NULL;
8599  AVBPrint scheme_buf, value_buf;
8600  int64_t scheme_str_len = 0, value_str_len = 0;
8601  int version, flags, ret = AVERROR_BUG;
8602  int64_t size = atom.size;
8603 
8604  if (atom.size < 6)
8605  // 4 bytes for version + flags, 2x 1 byte for null
8606  return AVERROR_INVALIDDATA;
8607 
8608  if (c->fc->nb_streams < 1)
8609  return 0;
8610  st = c->fc->streams[c->fc->nb_streams-1];
8611 
8612  version = avio_r8(pb);
8613  flags = avio_rb24(pb);
8614  size -= 4;
8615 
8616  if (version != 0 || flags != 0) {
8618  "Unsupported 'kind' box with version %d, flags: %x",
8619  version, flags);
8620  return AVERROR_INVALIDDATA;
8621  }
8622 
8623  av_bprint_init(&scheme_buf, 0, AV_BPRINT_SIZE_UNLIMITED);
8624  av_bprint_init(&value_buf, 0, AV_BPRINT_SIZE_UNLIMITED);
8625 
8626  if ((scheme_str_len = ff_read_string_to_bprint_overwrite(pb, &scheme_buf,
8627  size)) < 0) {
8628  ret = scheme_str_len;
8629  goto cleanup;
8630  }
8631 
8632  if (scheme_str_len + 1 >= size) {
8633  // we need to have another string, even if nullptr.
8634  // we check with + 1 since we expect that if size was not hit,
8635  // an additional null was read.
8637  goto cleanup;
8638  }
8639 
8640  size -= scheme_str_len + 1;
8641 
8642  if ((value_str_len = ff_read_string_to_bprint_overwrite(pb, &value_buf,
8643  size)) < 0) {
8644  ret = value_str_len;
8645  goto cleanup;
8646  }
8647 
8648  if (value_str_len == size) {
8649  // in case of no trailing null, box is not valid.
8651  goto cleanup;
8652  }
8653 
8655  "%s stream %d KindBox(scheme: %s, value: %s)\n",
8657  st->index,
8658  scheme_buf.str, value_buf.str);
8659 
8660  for (int i = 0; ff_mov_track_kind_table[i].scheme_uri; i++) {
8662  if (!av_strstart(scheme_buf.str, map.scheme_uri, NULL))
8663  continue;
8664 
8665  for (int j = 0; map.value_maps[j].disposition; j++) {
8666  const struct MP4TrackKindValueMapping value_map = map.value_maps[j];
8667  if (!av_strstart(value_buf.str, value_map.value, NULL))
8668  continue;
8669 
8670  st->disposition |= value_map.disposition;
8671  }
8672  }
8673 
8674  ret = 0;
8675 
8676 cleanup:
8677 
8678  av_bprint_finalize(&scheme_buf, NULL);
8679  av_bprint_finalize(&value_buf, NULL);
8680 
8681  return ret;
8682 }
8683 
8685 {
8686  AVStream *st;
8687  AVChannelLayout ch_layout = { 0 };
8688  int ret, i, version, type;
8689  int ambisonic_order, channel_order, normalization, channel_count;
8690  int ambi_channels, non_diegetic_channels;
8691 
8692  if (c->fc->nb_streams < 1)
8693  return 0;
8694 
8695  st = c->fc->streams[c->fc->nb_streams - 1];
8696 
8697  if (atom.size < 16) {
8698  av_log(c->fc, AV_LOG_ERROR, "SA3D audio box too small\n");
8699  return AVERROR_INVALIDDATA;
8700  }
8701 
8702  version = avio_r8(pb);
8703  if (version) {
8704  av_log(c->fc, AV_LOG_WARNING, "Unsupported SA3D box version %d\n", version);
8705  return 0;
8706  }
8707 
8708  type = avio_r8(pb);
8709  if (type & 0x7f) {
8710  av_log(c->fc, AV_LOG_WARNING,
8711  "Unsupported ambisonic type %d\n", type & 0x7f);
8712  return 0;
8713  }
8714  non_diegetic_channels = (type >> 7) * 2; // head_locked_stereo
8715 
8716  ambisonic_order = avio_rb32(pb);
8717 
8718  channel_order = avio_r8(pb);
8719  if (channel_order) {
8720  av_log(c->fc, AV_LOG_WARNING,
8721  "Unsupported channel_order %d\n", channel_order);
8722  return 0;
8723  }
8724 
8725  normalization = avio_r8(pb);
8726  if (normalization) {
8727  av_log(c->fc, AV_LOG_WARNING,
8728  "Unsupported normalization %d\n", normalization);
8729  return 0;
8730  }
8731 
8732  channel_count = avio_rb32(pb);
8733  if (ambisonic_order < 0 || ambisonic_order > 31 ||
8734  channel_count != ((ambisonic_order + 1LL) * (ambisonic_order + 1LL) +
8735  non_diegetic_channels)) {
8736  av_log(c->fc, AV_LOG_ERROR,
8737  "Invalid number of channels (%d / %d)\n",
8738  channel_count, ambisonic_order);
8739  return 0;
8740  }
8741  ambi_channels = channel_count - non_diegetic_channels;
8742 
8743  ret = av_channel_layout_custom_init(&ch_layout, channel_count);
8744  if (ret < 0)
8745  return 0;
8746 
8747  for (i = 0; i < channel_count; i++) {
8748  unsigned channel = avio_rb32(pb);
8749 
8750  if (channel >= channel_count) {
8751  av_log(c->fc, AV_LOG_ERROR, "Invalid channel index (%d / %d)\n",
8752  channel, ambisonic_order);
8753  av_channel_layout_uninit(&ch_layout);
8754  return 0;
8755  }
8756  if (channel >= ambi_channels)
8757  ch_layout.u.map[i].id = channel - ambi_channels;
8758  else
8759  ch_layout.u.map[i].id = AV_CHAN_AMBISONIC_BASE + channel;
8760  }
8761 
8763  if (ret < 0) {
8764  av_channel_layout_uninit(&ch_layout);
8765  return 0;
8766  }
8767 
8769  st->codecpar->ch_layout = ch_layout;
8770 
8771  return 0;
8772 }
8773 
8775 {
8776  AVStream *st;
8777  int version;
8778 
8779  if (c->fc->nb_streams < 1)
8780  return 0;
8781 
8782  st = c->fc->streams[c->fc->nb_streams - 1];
8783 
8784  if (atom.size < 5) {
8785  av_log(c->fc, AV_LOG_ERROR, "Empty SAND audio box\n");
8786  return AVERROR_INVALIDDATA;
8787  }
8788 
8789  version = avio_r8(pb);
8790  if (version) {
8791  av_log(c->fc, AV_LOG_WARNING, "Unsupported SAND box version %d\n", version);
8792  return 0;
8793  }
8794 
8796 
8797  return 0;
8798 }
8799 
8800 static int rb_size(AVIOContext *pb, int64_t *value, int size)
8801 {
8802  if (size == 0)
8803  *value = 0;
8804  else if (size == 1)
8805  *value = avio_r8(pb);
8806  else if (size == 2)
8807  *value = avio_rb16(pb);
8808  else if (size == 4)
8809  *value = avio_rb32(pb);
8810  else if (size == 8) {
8811  *value = avio_rb64(pb);
8812  if (*value < 0)
8813  return -1;
8814  } else
8815  return -1;
8816  return size;
8817 }
8818 
8820 {
8821  avio_rb32(pb); // version & flags.
8822  c->primary_item_id = avio_rb16(pb);
8823  av_log(c->fc, AV_LOG_TRACE, "pitm: primary_item_id %d\n", c->primary_item_id);
8824  return atom.size;
8825 }
8826 
8828 {
8829  c->idat_offset = avio_tell(pb);
8830  return 0;
8831 }
8832 
8834 {
8835  HEIFItem **heif_item;
8836  int version, offset_size, length_size, base_offset_size, index_size;
8837  int item_count, extent_count;
8838  int64_t base_offset, extent_offset, extent_length;
8839  uint8_t value;
8840 
8841  if (c->found_iloc) {
8842  av_log(c->fc, AV_LOG_INFO, "Duplicate iloc box found\n");
8843  return 0;
8844  }
8845 
8846  version = avio_r8(pb);
8847  avio_rb24(pb); // flags.
8848 
8849  value = avio_r8(pb);
8850  offset_size = (value >> 4) & 0xF;
8851  length_size = value & 0xF;
8852  value = avio_r8(pb);
8853  base_offset_size = (value >> 4) & 0xF;
8854  index_size = !version ? 0 : (value & 0xF);
8855  if (index_size) {
8856  avpriv_report_missing_feature(c->fc, "iloc: index_size != 0");
8857  return AVERROR_PATCHWELCOME;
8858  }
8859  item_count = (version < 2) ? avio_rb16(pb) : avio_rb32(pb);
8860 
8861  heif_item = av_realloc_array(c->heif_item, FFMAX(item_count, c->nb_heif_item), sizeof(*c->heif_item));
8862  if (!heif_item)
8863  return AVERROR(ENOMEM);
8864  c->heif_item = heif_item;
8865  if (item_count > c->nb_heif_item)
8866  memset(&c->heif_item[c->nb_heif_item], 0,
8867  sizeof(*c->heif_item) * (item_count - c->nb_heif_item));
8868  c->nb_heif_item = FFMAX(c->nb_heif_item, item_count);
8869 
8870  av_log(c->fc, AV_LOG_TRACE, "iloc: item_count %d\n", item_count);
8871  for (int i = 0; i < item_count; i++) {
8872  HEIFItem *item = NULL;
8873  int item_id = (version < 2) ? avio_rb16(pb) : avio_rb32(pb);
8874  int offset_type = (version > 0) ? avio_rb16(pb) & 0xf : 0;
8875 
8876  if (avio_feof(pb))
8877  return AVERROR_INVALIDDATA;
8878  if (offset_type > 1) {
8879  avpriv_report_missing_feature(c->fc, "iloc offset type %d", offset_type);
8880  return AVERROR_PATCHWELCOME;
8881  }
8882 
8883  avio_rb16(pb); // data_reference_index.
8884  if (rb_size(pb, &base_offset, base_offset_size) < 0)
8885  return AVERROR_INVALIDDATA;
8886  extent_count = avio_rb16(pb);
8887  if (extent_count > 1) {
8888  // For still AVIF images, we only support one extent item.
8889  avpriv_report_missing_feature(c->fc, "iloc: extent_count > 1");
8890  return AVERROR_PATCHWELCOME;
8891  }
8892 
8893  if (rb_size(pb, &extent_offset, offset_size) < 0 ||
8894  rb_size(pb, &extent_length, length_size) < 0 ||
8895  base_offset > INT64_MAX - extent_offset)
8896  return AVERROR_INVALIDDATA;
8897 
8898  for (int j = 0; j < c->nb_heif_item; j++) {
8899  item = c->heif_item[j];
8900  if (!item)
8901  item = c->heif_item[j] = av_mallocz(sizeof(*item));
8902  else if (item->item_id != item_id)
8903  continue;
8904  break;
8905  }
8906  if (!item)
8907  return AVERROR(ENOMEM);
8908 
8909  item->item_id = item_id;
8910 
8911  if (offset_type == 1)
8912  item->is_idat_relative = 1;
8913  item->extent_length = extent_length;
8914  item->extent_offset = base_offset + extent_offset;
8915  av_log(c->fc, AV_LOG_TRACE, "iloc: item_idx %d, item->item_id %d, offset_type %d, "
8916  "extent_offset %"PRId64", extent_length %"PRId64"\n",
8917  i, item->item_id, offset_type, item->extent_offset, item->extent_length);
8918  }
8919 
8920  c->found_iloc = 1;
8921  return atom.size;
8922 }
8923 
8925 {
8926  HEIFItem *item = NULL;
8927  AVBPrint item_name;
8928  int64_t size = atom.size;
8929  uint32_t item_type;
8930  int item_id;
8931  int version, ret;
8932 
8933  version = avio_r8(pb);
8934  avio_rb24(pb); // flags.
8935  size -= 4;
8936  if (size < 0)
8937  return AVERROR_INVALIDDATA;
8938 
8939  if (version < 2) {
8940  avpriv_report_missing_feature(c->fc, "infe version < 2");
8941  avio_skip(pb, size);
8942  return 1;
8943  }
8944 
8945  item_id = version > 2 ? avio_rb32(pb) : avio_rb16(pb);
8946  avio_rb16(pb); // item_protection_index
8947  item_type = avio_rl32(pb);
8948  size -= 8;
8949  if (size < 1)
8950  return AVERROR_INVALIDDATA;
8951 
8954  if (ret < 0) {
8956  return ret;
8957  }
8958 
8959  av_log(c->fc, AV_LOG_TRACE, "infe: item_id %d, item_type %s, item_name %s\n",
8960  item_id, av_fourcc2str(item_type), item_name.str);
8961 
8962  size -= ret + 1;
8963  if (size > 0)
8964  avio_skip(pb, size);
8965 
8966  for (int i = 0; i < c->nb_heif_item; i++) {
8967  item = c->heif_item[i];
8968  if (!item)
8969  item = c->heif_item[i] = av_mallocz(sizeof(*item));
8970  else if (item->item_id != item_id)
8971  continue;
8972  break;
8973  }
8974  if (!item) {
8976  return AVERROR(ENOMEM);
8977  }
8978 
8979  av_freep(&item->name);
8980  av_bprint_finalize(&item_name, ret ? &item->name : NULL);
8981  item->item_id = item_id;
8982  item->type = item_type;
8983 
8984  switch (item_type) {
8985  case MKTAG('a','v','0','1'):
8986  case MKTAG('j','p','e','g'):
8987  case MKTAG('h','v','c','1'):
8988  ret = heif_add_stream(c, item);
8989  if (ret < 0)
8990  return ret;
8991  break;
8992  }
8993 
8994  return 0;
8995 }
8996 
8998 {
8999  HEIFItem **heif_item;
9000  int entry_count;
9001  int version, got_stream = 0, ret, i;
9002 
9003  if (c->found_iinf) {
9004  av_log(c->fc, AV_LOG_WARNING, "Duplicate iinf box found\n");
9005  return 0;
9006  }
9007 
9008  version = avio_r8(pb);
9009  avio_rb24(pb); // flags.
9010  entry_count = version ? avio_rb32(pb) : avio_rb16(pb);
9011 
9012  heif_item = av_realloc_array(c->heif_item, FFMAX(entry_count, c->nb_heif_item), sizeof(*c->heif_item));
9013  if (!heif_item)
9014  return AVERROR(ENOMEM);
9015  c->heif_item = heif_item;
9016  if (entry_count > c->nb_heif_item)
9017  memset(&c->heif_item[c->nb_heif_item], 0,
9018  sizeof(*c->heif_item) * (entry_count - c->nb_heif_item));
9019  c->nb_heif_item = FFMAX(c->nb_heif_item, entry_count);
9020 
9021  for (i = 0; i < entry_count; i++) {
9022  MOVAtom infe;
9023 
9024  infe.size = avio_rb32(pb) - 8;
9025  infe.type = avio_rl32(pb);
9026  if (avio_feof(pb)) {
9028  goto fail;
9029  }
9030  ret = mov_read_infe(c, pb, infe);
9031  if (ret < 0)
9032  goto fail;
9033  if (!ret)
9034  got_stream = 1;
9035  }
9036 
9037  c->found_iinf = got_stream;
9038  return 0;
9039 fail:
9040  for (; i >= 0; i--) {
9041  HEIFItem *item = c->heif_item[i];
9042 
9043  if (!item)
9044  continue;
9045 
9046  av_freep(&item->name);
9047  }
9048  return ret;
9049 }
9050 
9052 {
9053  HEIFItem *item = NULL;
9054  HEIFGrid *grid;
9055  int entries, i;
9056  int from_item_id = version ? avio_rb32(pb) : avio_rb16(pb);
9057 
9058  for (int i = 0; i < c->nb_heif_grid; i++) {
9059  if (c->heif_grid[i].item->item_id == from_item_id) {
9060  av_log(c->fc, AV_LOG_ERROR, "More than one 'dimg' box "
9061  "referencing the same Derived Image item\n");
9062  return AVERROR_INVALIDDATA;
9063  }
9064  }
9065  for (int i = 0; i < c->nb_heif_item; i++) {
9066  if (!c->heif_item[i] || c->heif_item[i]->item_id != from_item_id)
9067  continue;
9068  item = c->heif_item[i];
9069 
9070  switch (item->type) {
9071  case MKTAG('g','r','i','d'):
9072  case MKTAG('i','o','v','l'):
9073  break;
9074  default:
9075  avpriv_report_missing_feature(c->fc, "Derived Image item of type %s",
9076  av_fourcc2str(item->type));
9077  return 0;
9078  }
9079  break;
9080  }
9081  if (!item) {
9082  av_log(c->fc, AV_LOG_ERROR, "Missing grid information\n");
9083  return AVERROR_INVALIDDATA;
9084  }
9085 
9086  grid = av_realloc_array(c->heif_grid, c->nb_heif_grid + 1U,
9087  sizeof(*c->heif_grid));
9088  if (!grid)
9089  return AVERROR(ENOMEM);
9090  c->heif_grid = grid;
9091  grid = &grid[c->nb_heif_grid++];
9092 
9093  entries = avio_rb16(pb);
9094  grid->tile_id_list = av_malloc_array(entries, sizeof(*grid->tile_id_list));
9095  grid->tile_idx_list = av_calloc(entries, sizeof(*grid->tile_idx_list));
9096  grid->tile_item_list = av_calloc(entries, sizeof(*grid->tile_item_list));
9097  if (!grid->tile_id_list || !grid->tile_item_list || !grid->tile_idx_list)
9098  return AVERROR(ENOMEM);
9099  /* 'to' item ids */
9100  for (i = 0; i < entries; i++)
9101  grid->tile_id_list[i] = version ? avio_rb32(pb) : avio_rb16(pb);
9102  grid->nb_tiles = entries;
9103  grid->item = item;
9104 
9105  av_log(c->fc, AV_LOG_TRACE, "dimg: from_item_id %d, entries %d\n",
9106  from_item_id, entries);
9107 
9108  return 0;
9109 }
9110 
9111 static int mov_read_iref_cdsc(MOVContext *c, AVIOContext *pb, uint32_t type, int version)
9112 {
9113  HEIFItem *from_item = NULL;
9114  int entries;
9115  int from_item_id = version ? avio_rb32(pb) : avio_rb16(pb);
9116  const HEIFItemRef ref = { type, from_item_id };
9117 
9118  from_item = get_heif_item(c, from_item_id);
9119  if (!from_item) {
9120  av_log(c->fc, AV_LOG_ERROR, "Missing stream referenced by thmb item\n");
9121  return AVERROR_INVALIDDATA;
9122  }
9123 
9124  entries = avio_rb16(pb);
9125  /* 'to' item ids */
9126  for (int i = 0; i < entries; i++) {
9127  HEIFItem *item = get_heif_item(c, version ? avio_rb32(pb) : avio_rb16(pb));
9128  if (!item) {
9129  av_log(c->fc, AV_LOG_WARNING, "Missing stream referenced by %s item\n",
9130  av_fourcc2str(type));
9131  continue;
9132  }
9133 
9134  if (!av_dynarray2_add((void **)&item->iref_list, &item->nb_iref_list,
9135  sizeof(*item->iref_list), (const uint8_t *)&ref))
9136  return AVERROR(ENOMEM);
9137  }
9138 
9139  av_log(c->fc, AV_LOG_TRACE, "%s: from_item_id %d, entries %d\n",
9140  av_fourcc2str(type), from_item_id, entries);
9141 
9142  return 0;
9143 }
9144 
9146 {
9147  int version = avio_r8(pb);
9148  avio_rb24(pb); // flags
9149  atom.size -= 4;
9150 
9151  if (version > 1) {
9152  av_log(c->fc, AV_LOG_WARNING, "Unknown iref box version %d\n", version);
9153  return 0;
9154  }
9155 
9156  while (atom.size) {
9157  uint32_t type, size = avio_rb32(pb);
9158  int64_t next = avio_tell(pb);
9159 
9160  if (size < 14 || next < 0 || next > INT64_MAX - size)
9161  return AVERROR_INVALIDDATA;
9162 
9163  next += size - 4;
9164  type = avio_rl32(pb);
9165  switch (type) {
9166  case MKTAG('d','i','m','g'):
9168  break;
9169  case MKTAG('c','d','s','c'):
9170  case MKTAG('t','h','m','b'):
9172  break;
9173  default:
9174  av_log(c->fc, AV_LOG_DEBUG, "Unknown iref type %s size %"PRIu32"\n",
9175  av_fourcc2str(type), size);
9176  }
9177 
9178  atom.size -= size;
9179  avio_seek(pb, next, SEEK_SET);
9180  }
9181  return 0;
9182 }
9183 
9185 {
9186  HEIFItem *item;
9187  uint32_t width, height;
9188 
9189  avio_r8(pb); /* version */
9190  avio_rb24(pb); /* flags */
9191  width = avio_rb32(pb);
9192  height = avio_rb32(pb);
9193 
9194  av_log(c->fc, AV_LOG_TRACE, "ispe: item_id %d, width %u, height %u\n",
9195  c->cur_item_id, width, height);
9196 
9197  item = get_heif_item(c, c->cur_item_id);
9198  if (item) {
9199  item->width = width;
9200  item->height = height;
9201  }
9202 
9203  return 0;
9204 }
9205 
9207 {
9208  HEIFItem *item;
9209  int angle;
9210 
9211  angle = avio_r8(pb) & 0x3;
9212 
9213  av_log(c->fc, AV_LOG_TRACE, "irot: item_id %d, angle %u\n",
9214  c->cur_item_id, angle);
9215 
9216  item = get_heif_item(c, c->cur_item_id);
9217  if (item) {
9218  // angle * 90 specifies the angle (in anti-clockwise direction)
9219  // in units of degrees.
9220  item->rotation = angle * 90;
9221  }
9222 
9223  return 0;
9224 }
9225 
9227 {
9228  HEIFItem *item;
9229  int axis;
9230 
9231  axis = avio_r8(pb) & 0x1;
9232 
9233  av_log(c->fc, AV_LOG_TRACE, "imir: item_id %d, axis %u\n",
9234  c->cur_item_id, axis);
9235 
9236  item = get_heif_item(c, c->cur_item_id);
9237  if (item) {
9238  item->hflip = axis;
9239  item->vflip = !axis;
9240  }
9241 
9242  return 0;
9243 }
9244 
9246 {
9247  typedef struct MOVAtoms {
9248  FFIOContext b;
9249  uint32_t type;
9250  int64_t size;
9251  uint8_t *data;
9252  } MOVAtoms;
9253  MOVAtoms *atoms = NULL;
9254  MOVAtom a;
9255  unsigned count;
9256  int nb_atoms = 0;
9257  int version, flags;
9258  int ret;
9259 
9260  a.size = avio_rb32(pb);
9261  a.type = avio_rl32(pb);
9262 
9263  if (a.size < 8 || a.type != MKTAG('i','p','c','o'))
9264  return AVERROR_INVALIDDATA;
9265 
9266  a.size -= 8;
9267  while (a.size >= 8) {
9268  MOVAtoms *ref = av_dynarray2_add((void**)&atoms, &nb_atoms, sizeof(MOVAtoms), NULL);
9269  if (!ref) {
9270  ret = AVERROR(ENOMEM);
9271  goto fail;
9272  }
9273  ref->data = NULL;
9274  ref->size = avio_rb32(pb);
9275  ref->type = avio_rl32(pb);
9276  if (ref->size > a.size || ref->size < 8)
9277  break;
9278  ref->data = av_malloc(ref->size);
9279  if (!ref->data) {
9281  goto fail;
9282  }
9283  av_log(c->fc, AV_LOG_TRACE, "ipco: index %d, box type %s\n", nb_atoms, av_fourcc2str(ref->type));
9284  avio_seek(pb, -8, SEEK_CUR);
9285  if (avio_read(pb, ref->data, ref->size) != ref->size) {
9287  goto fail;
9288  }
9289  ffio_init_read_context(&ref->b, ref->data, ref->size);
9290  a.size -= ref->size;
9291  }
9292 
9293  if (a.size) {
9295  goto fail;
9296  }
9297 
9298  a.size = avio_rb32(pb);
9299  a.type = avio_rl32(pb);
9300 
9301  if (a.size < 8 || a.type != MKTAG('i','p','m','a')) {
9303  goto fail;
9304  }
9305 
9306  version = avio_r8(pb);
9307  flags = avio_rb24(pb);
9308  count = avio_rb32(pb);
9309 
9310  for (int i = 0; i < count; i++) {
9311  int item_id = version ? avio_rb32(pb) : avio_rb16(pb);
9312  int assoc_count = avio_r8(pb);
9313 
9314  if (avio_feof(pb)) {
9316  goto fail;
9317  }
9318 
9319  for (int j = 0; j < assoc_count; j++) {
9320  MOVAtoms *ref;
9321  int index = avio_r8(pb) & 0x7f;
9322  if (flags & 1) {
9323  index <<= 8;
9324  index |= avio_r8(pb);
9325  }
9326  if (index > nb_atoms || index <= 0) {
9328  goto fail;
9329  }
9330  ref = &atoms[--index];
9331 
9332  av_log(c->fc, AV_LOG_TRACE, "ipma: property_index %d, item_id %d, item_type %s\n",
9333  index + 1, item_id, av_fourcc2str(ref->type));
9334 
9335  c->cur_item_id = item_id;
9336 
9337  ret = mov_read_default(c, &ref->b.pub,
9338  (MOVAtom) { .size = ref->size,
9339  .type = MKTAG('i','p','c','o') });
9340  if (ret < 0)
9341  goto fail;
9342  ffio_init_read_context(&ref->b, ref->data, ref->size);
9343  }
9344  }
9345 
9346  ret = 0;
9347 fail:
9348  c->cur_item_id = -1;
9349  for (int i = 0; i < nb_atoms; i++)
9350  av_free(atoms[i].data);
9351  av_free(atoms);
9352 
9353  return ret;
9354 }
9355 
9357 { MKTAG('A','C','L','R'), mov_read_aclr },
9358 { MKTAG('A','P','R','G'), mov_read_avid },
9359 { MKTAG('A','A','L','P'), mov_read_avid },
9360 { MKTAG('A','R','E','S'), mov_read_ares },
9361 { MKTAG('a','v','s','s'), mov_read_avss },
9362 { MKTAG('a','v','1','C'), mov_read_glbl },
9363 { MKTAG('c','h','p','l'), mov_read_chpl },
9364 { MKTAG('c','o','6','4'), mov_read_stco },
9365 { MKTAG('c','o','l','r'), mov_read_colr },
9366 { MKTAG('c','t','t','s'), mov_read_ctts }, /* composition time to sample */
9367 { MKTAG('d','i','n','f'), mov_read_default },
9368 { MKTAG('D','p','x','E'), mov_read_dpxe },
9369 { MKTAG('d','r','e','f'), mov_read_dref },
9370 { MKTAG('e','d','t','s'), mov_read_default },
9371 { MKTAG('e','l','s','t'), mov_read_elst },
9372 { MKTAG('e','n','d','a'), mov_read_enda },
9373 { MKTAG('f','i','e','l'), mov_read_fiel },
9374 { MKTAG('a','d','r','m'), mov_read_adrm },
9375 { MKTAG('f','t','y','p'), mov_read_ftyp },
9376 { MKTAG('g','l','b','l'), mov_read_glbl },
9377 { MKTAG('h','d','l','r'), mov_read_hdlr },
9378 { MKTAG('i','l','s','t'), mov_read_ilst },
9379 { MKTAG('j','p','2','h'), mov_read_jp2h },
9380 { MKTAG('m','d','a','t'), mov_read_mdat },
9381 { MKTAG('m','d','h','d'), mov_read_mdhd },
9382 { MKTAG('m','d','i','a'), mov_read_default },
9383 { MKTAG('m','e','t','a'), mov_read_meta },
9384 { MKTAG('m','i','n','f'), mov_read_default },
9385 { MKTAG('m','o','o','f'), mov_read_moof },
9386 { MKTAG('m','o','o','v'), mov_read_moov },
9387 { MKTAG('m','v','e','x'), mov_read_default },
9388 { MKTAG('m','v','h','d'), mov_read_mvhd },
9389 { MKTAG('S','M','I',' '), mov_read_svq3 },
9390 { MKTAG('a','l','a','c'), mov_read_alac }, /* alac specific atom */
9391 { MKTAG('a','v','c','C'), mov_read_glbl },
9392 { MKTAG('p','a','s','p'), mov_read_pasp },
9393 { MKTAG('c','l','a','p'), mov_read_clap },
9394 { MKTAG('s','b','a','s'), mov_read_sbas },
9395 { MKTAG('s','i','d','x'), mov_read_sidx },
9396 { MKTAG('s','t','b','l'), mov_read_default },
9397 { MKTAG('s','t','c','o'), mov_read_stco },
9398 { MKTAG('s','t','p','s'), mov_read_stps },
9399 { MKTAG('s','t','r','f'), mov_read_strf },
9400 { MKTAG('s','t','s','c'), mov_read_stsc },
9401 { MKTAG('s','t','s','d'), mov_read_stsd }, /* sample description */
9402 { MKTAG('s','t','s','s'), mov_read_stss }, /* sync sample */
9403 { MKTAG('s','t','s','z'), mov_read_stsz }, /* sample size */
9404 { MKTAG('s','t','t','s'), mov_read_stts },
9405 { MKTAG('s','t','z','2'), mov_read_stsz }, /* compact sample size */
9406 { MKTAG('s','d','t','p'), mov_read_sdtp }, /* independent and disposable samples */
9407 { MKTAG('t','k','h','d'), mov_read_tkhd }, /* track header */
9408 { MKTAG('t','f','d','t'), mov_read_tfdt },
9409 { MKTAG('t','f','h','d'), mov_read_tfhd }, /* track fragment header */
9410 { MKTAG('t','r','a','k'), mov_read_trak },
9411 { MKTAG('t','r','a','f'), mov_read_default },
9412 { MKTAG('t','r','e','f'), mov_read_default },
9413 { MKTAG('t','m','c','d'), mov_read_tmcd },
9414 { MKTAG('c','h','a','p'), mov_read_chap },
9415 { MKTAG('t','r','e','x'), mov_read_trex },
9416 { MKTAG('t','r','u','n'), mov_read_trun },
9417 { MKTAG('u','d','t','a'), mov_read_default },
9418 { MKTAG('w','a','v','e'), mov_read_wave },
9419 { MKTAG('e','s','d','s'), mov_read_esds },
9420 { MKTAG('d','a','c','3'), mov_read_dac3 }, /* AC-3 info */
9421 { MKTAG('d','e','c','3'), mov_read_dec3 }, /* EAC-3 info */
9422 { MKTAG('d','d','t','s'), mov_read_ddts }, /* DTS audio descriptor */
9423 { MKTAG('w','i','d','e'), mov_read_wide }, /* place holder */
9424 { MKTAG('w','f','e','x'), mov_read_wfex },
9425 { MKTAG('c','m','o','v'), mov_read_cmov },
9426 { MKTAG('c','h','a','n'), mov_read_chan }, /* channel layout from quicktime */
9427 { MKTAG('c','h','n','l'), mov_read_chnl }, /* channel layout from ISO-14496-12 */
9428 { MKTAG('d','v','c','1'), mov_read_dvc1 },
9429 { MKTAG('s','g','p','d'), mov_read_sgpd },
9430 { MKTAG('s','b','g','p'), mov_read_sbgp },
9431 { MKTAG('h','v','c','C'), mov_read_glbl },
9432 { MKTAG('v','v','c','C'), mov_read_glbl },
9433 { MKTAG('u','u','i','d'), mov_read_uuid },
9434 { MKTAG('C','i','n', 0x8e), mov_read_targa_y216 },
9435 { MKTAG('f','r','e','e'), mov_read_free },
9436 { MKTAG('-','-','-','-'), mov_read_custom },
9437 { MKTAG('s','i','n','f'), mov_read_default },
9438 { MKTAG('f','r','m','a'), mov_read_frma },
9439 { MKTAG('s','e','n','c'), mov_read_senc },
9440 { MKTAG('s','a','i','z'), mov_read_saiz },
9441 { MKTAG('s','a','i','o'), mov_read_saio },
9442 { MKTAG('p','s','s','h'), mov_read_pssh },
9443 { MKTAG('s','c','h','m'), mov_read_schm },
9444 { MKTAG('s','c','h','i'), mov_read_default },
9445 { MKTAG('t','e','n','c'), mov_read_tenc },
9446 { MKTAG('d','f','L','a'), mov_read_dfla },
9447 { MKTAG('s','t','3','d'), mov_read_st3d }, /* stereoscopic 3D video box */
9448 { MKTAG('s','v','3','d'), mov_read_sv3d }, /* spherical video box */
9449 { MKTAG('v','e','x','u'), mov_read_vexu }, /* video extension usage */
9450 { MKTAG('h','f','o','v'), mov_read_hfov },
9451 { MKTAG('d','O','p','s'), mov_read_dops },
9452 { MKTAG('d','m','l','p'), mov_read_dmlp },
9453 { MKTAG('S','m','D','m'), mov_read_smdm },
9454 { MKTAG('C','o','L','L'), mov_read_coll },
9455 { MKTAG('v','p','c','C'), mov_read_vpcc },
9456 { MKTAG('m','d','c','v'), mov_read_mdcv },
9457 { MKTAG('c','l','l','i'), mov_read_clli },
9458 { MKTAG('d','v','c','C'), mov_read_dvcc_dvvc },
9459 { MKTAG('d','v','v','C'), mov_read_dvcc_dvvc },
9460 { MKTAG('d','v','w','C'), mov_read_dvcc_dvvc },
9461 { MKTAG('k','i','n','d'), mov_read_kind },
9462 { MKTAG('S','A','3','D'), mov_read_SA3D }, /* ambisonic audio box */
9463 { MKTAG('S','A','N','D'), mov_read_SAND }, /* non diegetic audio box */
9464 { MKTAG('i','l','o','c'), mov_read_iloc },
9465 { MKTAG('p','c','m','C'), mov_read_pcmc }, /* PCM configuration box */
9466 { MKTAG('p','i','t','m'), mov_read_pitm },
9467 { MKTAG('e','v','c','C'), mov_read_glbl },
9468 { MKTAG('i','d','a','t'), mov_read_idat },
9469 { MKTAG('i','m','i','r'), mov_read_imir },
9470 { MKTAG('i','r','e','f'), mov_read_iref },
9471 { MKTAG('i','s','p','e'), mov_read_ispe },
9472 { MKTAG('i','r','o','t'), mov_read_irot },
9473 { MKTAG('i','p','r','p'), mov_read_iprp },
9474 { MKTAG('i','i','n','f'), mov_read_iinf },
9475 { MKTAG('a','m','v','e'), mov_read_amve }, /* ambient viewing environment box */
9476 { MKTAG('l','h','v','C'), mov_read_lhvc },
9477 { MKTAG('l','v','c','C'), mov_read_glbl },
9478 { MKTAG('a','p','v','C'), mov_read_glbl },
9479 #if CONFIG_IAMFDEC
9480 { MKTAG('i','a','c','b'), mov_read_iacb },
9481 #endif
9482 { 0, NULL }
9483 };
9484 
9486 {
9487  int64_t total_size = 0;
9488  MOVAtom a;
9489  int i;
9490 
9491  if (c->atom_depth > 10) {
9492  av_log(c->fc, AV_LOG_ERROR, "Atoms too deeply nested\n");
9493  return AVERROR_INVALIDDATA;
9494  }
9495  c->atom_depth ++;
9496 
9497  if (atom.size < 0)
9498  atom.size = INT64_MAX;
9499  while (total_size <= atom.size - 8) {
9500  int (*parse)(MOVContext*, AVIOContext*, MOVAtom) = NULL;
9501  a.size = avio_rb32(pb);
9502  a.type = avio_rl32(pb);
9503  if (avio_feof(pb))
9504  break;
9505  if (((a.type == MKTAG('f','r','e','e') && c->moov_retry) ||
9506  a.type == MKTAG('h','o','o','v')) &&
9507  a.size >= 8 &&
9508  c->fc->strict_std_compliance < FF_COMPLIANCE_STRICT) {
9509  uint32_t type;
9510  avio_skip(pb, 4);
9511  type = avio_rl32(pb);
9512  if (avio_feof(pb))
9513  break;
9514  avio_seek(pb, -8, SEEK_CUR);
9515  if (type == MKTAG('m','v','h','d') ||
9516  type == MKTAG('c','m','o','v')) {
9517  av_log(c->fc, AV_LOG_ERROR, "Detected moov in a free or hoov atom.\n");
9518  a.type = MKTAG('m','o','o','v');
9519  }
9520  }
9521  if (atom.type != MKTAG('r','o','o','t') &&
9522  atom.type != MKTAG('m','o','o','v')) {
9523  if (a.type == MKTAG('t','r','a','k') ||
9524  a.type == MKTAG('m','d','a','t')) {
9525  av_log(c->fc, AV_LOG_ERROR, "Broken file, trak/mdat not at top-level\n");
9526  avio_skip(pb, -8);
9527  c->atom_depth --;
9528  return 0;
9529  }
9530  }
9531  total_size += 8;
9532  if (a.size == 1 && total_size + 8 <= atom.size) { /* 64 bit extended size */
9533  a.size = avio_rb64(pb) - 8;
9534  total_size += 8;
9535  }
9536  av_log(c->fc, AV_LOG_TRACE, "type:'%s' parent:'%s' sz: %"PRId64" %"PRId64" %"PRId64"\n",
9537  av_fourcc2str(a.type), av_fourcc2str(atom.type), a.size, total_size, atom.size);
9538  if (a.size == 0) {
9539  a.size = atom.size - total_size + 8;
9540  }
9541  if (a.size < 0)
9542  break;
9543  a.size -= 8;
9544  if (a.size < 0)
9545  break;
9546  a.size = FFMIN(a.size, atom.size - total_size);
9547 
9548  for (i = 0; mov_default_parse_table[i].type; i++)
9549  if (mov_default_parse_table[i].type == a.type) {
9551  break;
9552  }
9553 
9554  // container is user data
9555  if (!parse && (atom.type == MKTAG('u','d','t','a') ||
9556  atom.type == MKTAG('i','l','s','t')))
9558 
9559  // Supports parsing the QuickTime Metadata Keys.
9560  // https://developer.apple.com/library/mac/documentation/QuickTime/QTFF/Metadata/Metadata.html
9561  if (!parse && c->found_hdlr_mdta &&
9562  atom.type == MKTAG('m','e','t','a') &&
9563  a.type == MKTAG('k','e','y','s') &&
9564  c->meta_keys_count == 0) {
9565  parse = mov_read_keys;
9566  }
9567 
9568  if (!parse) { /* skip leaf atoms data */
9569  avio_skip(pb, a.size);
9570  } else {
9571  int64_t start_pos = avio_tell(pb);
9572  int64_t left;
9573  int err = parse(c, pb, a);
9574  if (err < 0) {
9575  c->atom_depth --;
9576  return err;
9577  }
9578  if (c->found_moov && c->found_mdat && a.size <= INT64_MAX - start_pos &&
9579  ((!(pb->seekable & AVIO_SEEKABLE_NORMAL) || c->fc->flags & AVFMT_FLAG_IGNIDX || c->frag_index.complete) ||
9580  start_pos + a.size == avio_size(pb))) {
9581  if (!(pb->seekable & AVIO_SEEKABLE_NORMAL) || c->fc->flags & AVFMT_FLAG_IGNIDX || c->frag_index.complete)
9582  c->next_root_atom = start_pos + a.size;
9583  c->atom_depth --;
9584  return 0;
9585  }
9586  left = a.size - avio_tell(pb) + start_pos;
9587  if (left > 0) /* skip garbage at atom end */
9588  avio_skip(pb, left);
9589  else if (left < 0) {
9590  av_log(c->fc, AV_LOG_WARNING,
9591  "overread end of atom '%s' by %"PRId64" bytes\n",
9592  av_fourcc2str(a.type), -left);
9593  avio_seek(pb, left, SEEK_CUR);
9594  }
9595  }
9596 
9597  total_size += a.size;
9598  }
9599 
9600  if (total_size < atom.size && atom.size < 0x7ffff)
9601  avio_skip(pb, atom.size - total_size);
9602 
9603  c->atom_depth --;
9604  return 0;
9605 }
9606 
9607 static int mov_probe(const AVProbeData *p)
9608 {
9609  int64_t offset;
9610  uint32_t tag;
9611  int score = 0;
9612  int moov_offset = -1;
9613 
9614  /* check file header */
9615  offset = 0;
9616  for (;;) {
9617  int64_t size;
9618  int minsize = 8;
9619  /* ignore invalid offset */
9620  if ((offset + 8ULL) > (unsigned int)p->buf_size)
9621  break;
9622  size = AV_RB32(p->buf + offset);
9623  if (size == 1 && offset + 16 <= (unsigned int)p->buf_size) {
9624  size = AV_RB64(p->buf+offset + 8);
9625  minsize = 16;
9626  } else if (size == 0) {
9627  size = p->buf_size - offset;
9628  }
9629  if (size < minsize) {
9630  offset += 4;
9631  continue;
9632  }
9633  tag = AV_RL32(p->buf + offset + 4);
9634  switch(tag) {
9635  /* check for obvious tags */
9636  case MKTAG('m','o','o','v'):
9637  moov_offset = offset + 4;
9638  case MKTAG('m','d','a','t'):
9639  case MKTAG('p','n','o','t'): /* detect movs with preview pics like ew.mov and april.mov */
9640  case MKTAG('u','d','t','a'): /* Packet Video PVAuthor adds this and a lot of more junk */
9641  case MKTAG('f','t','y','p'):
9642  if (tag == MKTAG('f','t','y','p') &&
9643  ( AV_RL32(p->buf + offset + 8) == MKTAG('j','p','2',' ')
9644  || AV_RL32(p->buf + offset + 8) == MKTAG('j','p','x',' ')
9645  || AV_RL32(p->buf + offset + 8) == MKTAG('j','x','l',' ')
9646  )) {
9647  score = FFMAX(score, 5);
9648  } else {
9649  score = AVPROBE_SCORE_MAX;
9650  }
9651  break;
9652  /* those are more common words, so rate then a bit less */
9653  case MKTAG('e','d','i','w'): /* xdcam files have reverted first tags */
9654  case MKTAG('w','i','d','e'):
9655  case MKTAG('f','r','e','e'):
9656  case MKTAG('j','u','n','k'):
9657  case MKTAG('p','i','c','t'):
9658  score = FFMAX(score, AVPROBE_SCORE_MAX - 5);
9659  break;
9660  case MKTAG(0x82,0x82,0x7f,0x7d):
9661  score = FFMAX(score, AVPROBE_SCORE_EXTENSION - 5);
9662  break;
9663  case MKTAG('s','k','i','p'):
9664  case MKTAG('u','u','i','d'):
9665  case MKTAG('p','r','f','l'):
9666  /* if we only find those cause probedata is too small at least rate them */
9667  score = FFMAX(score, AVPROBE_SCORE_EXTENSION);
9668  break;
9669  }
9670  if (size > INT64_MAX - offset)
9671  break;
9672  offset += size;
9673  }
9674  if (score > AVPROBE_SCORE_MAX - 50 && moov_offset != -1) {
9675  /* moov atom in the header - we should make sure that this is not a
9676  * MOV-packed MPEG-PS */
9677  offset = moov_offset;
9678 
9679  while (offset < (p->buf_size - 16)) { /* Sufficient space */
9680  /* We found an actual hdlr atom */
9681  if (AV_RL32(p->buf + offset ) == MKTAG('h','d','l','r') &&
9682  AV_RL32(p->buf + offset + 8) == MKTAG('m','h','l','r') &&
9683  AV_RL32(p->buf + offset + 12) == MKTAG('M','P','E','G')) {
9684  av_log(NULL, AV_LOG_WARNING, "Found media data tag MPEG indicating this is a MOV-packed MPEG-PS.\n");
9685  /* We found a media handler reference atom describing an
9686  * MPEG-PS-in-MOV, return a
9687  * low score to force expanding the probe window until
9688  * mpegps_probe finds what it needs */
9689  return 5;
9690  } else {
9691  /* Keep looking */
9692  offset += 2;
9693  }
9694  }
9695  }
9696 
9697  return score;
9698 }
9699 
9700 // must be done after parsing all trak because there's no order requirement
9702 {
9703  MOVContext *mov = s->priv_data;
9704  MOVStreamContext *sc;
9705  int64_t cur_pos;
9706  int i, j;
9707  int chapter_track;
9708 
9709  for (j = 0; j < mov->nb_chapter_tracks; j++) {
9710  AVStream *st = NULL;
9711  FFStream *sti = NULL;
9712  chapter_track = mov->chapter_tracks[j];
9713  for (i = 0; i < s->nb_streams; i++) {
9714  sc = mov->fc->streams[i]->priv_data;
9715  if (sc->id == chapter_track) {
9716  st = s->streams[i];
9717  break;
9718  }
9719  }
9720  if (!st) {
9721  av_log(s, AV_LOG_ERROR, "Referenced QT chapter track not found\n");
9722  continue;
9723  }
9724  sti = ffstream(st);
9725 
9726  sc = st->priv_data;
9727  cur_pos = avio_tell(sc->pb);
9728 
9729  if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
9731  if (!st->attached_pic.data && sti->nb_index_entries) {
9732  // Retrieve the first frame, if possible
9733  AVIndexEntry *sample = &sti->index_entries[0];
9734  if (avio_seek(sc->pb, sample->pos, SEEK_SET) != sample->pos) {
9735  av_log(s, AV_LOG_ERROR, "Failed to retrieve first frame\n");
9736  goto finish;
9737  }
9738 
9739  if (ff_add_attached_pic(s, st, sc->pb, NULL, sample->size) < 0)
9740  goto finish;
9741  }
9742  } else {
9745  st->discard = AVDISCARD_ALL;
9746  for (int i = 0; i < sti->nb_index_entries; i++) {
9747  AVIndexEntry *sample = &sti->index_entries[i];
9748  int64_t end = i+1 < sti->nb_index_entries ? sti->index_entries[i+1].timestamp : st->duration;
9749  uint8_t *title;
9750  uint16_t ch;
9751  int len, title_len;
9752 
9753  if (end < sample->timestamp) {
9754  av_log(s, AV_LOG_WARNING, "ignoring stream duration which is shorter than chapters\n");
9755  end = AV_NOPTS_VALUE;
9756  }
9757 
9758  if (avio_seek(sc->pb, sample->pos, SEEK_SET) != sample->pos) {
9759  av_log(s, AV_LOG_ERROR, "Chapter %d not found in file\n", i);
9760  goto finish;
9761  }
9762 
9763  // the first two bytes are the length of the title
9764  len = avio_rb16(sc->pb);
9765  if (len > sample->size-2)
9766  continue;
9767  title_len = 2*len + 1;
9768  if (!(title = av_mallocz(title_len)))
9769  goto finish;
9770 
9771  // The samples could theoretically be in any encoding if there's an encd
9772  // atom following, but in practice are only utf-8 or utf-16, distinguished
9773  // instead by the presence of a BOM
9774  if (!len) {
9775  title[0] = 0;
9776  } else {
9777  ch = avio_rb16(sc->pb);
9778  if (ch == 0xfeff)
9779  avio_get_str16be(sc->pb, len, title, title_len);
9780  else if (ch == 0xfffe)
9781  avio_get_str16le(sc->pb, len, title, title_len);
9782  else {
9783  AV_WB16(title, ch);
9784  if (len == 1 || len == 2)
9785  title[len] = 0;
9786  else
9787  avio_get_str(sc->pb, INT_MAX, title + 2, len - 1);
9788  }
9789  }
9790 
9791  avpriv_new_chapter(s, i, st->time_base, sample->timestamp, end, title);
9792  av_freep(&title);
9793  }
9794  }
9795 finish:
9796  avio_seek(sc->pb, cur_pos, SEEK_SET);
9797  }
9798 }
9799 
9801  int64_t value, int flags)
9802 {
9803  AVTimecode tc;
9804  char buf[AV_TIMECODE_STR_SIZE];
9805  AVRational rate = st->avg_frame_rate;
9806  int ret = av_timecode_init(&tc, rate, flags, 0, s);
9807  if (ret < 0)
9808  return ret;
9809  av_dict_set(&st->metadata, "timecode",
9810  av_timecode_make_string(&tc, buf, value), 0);
9811  return 0;
9812 }
9813 
9815 {
9816  MOVStreamContext *sc = st->priv_data;
9817  FFStream *const sti = ffstream(st);
9818  char buf[AV_TIMECODE_STR_SIZE];
9819  int64_t cur_pos = avio_tell(sc->pb);
9820  int hh, mm, ss, ff, drop;
9821 
9822  if (!sti->nb_index_entries)
9823  return -1;
9824 
9825  avio_seek(sc->pb, sti->index_entries->pos, SEEK_SET);
9826  avio_skip(s->pb, 13);
9827  hh = avio_r8(s->pb);
9828  mm = avio_r8(s->pb);
9829  ss = avio_r8(s->pb);
9830  drop = avio_r8(s->pb);
9831  ff = avio_r8(s->pb);
9832  snprintf(buf, AV_TIMECODE_STR_SIZE, "%02d:%02d:%02d%c%02d",
9833  hh, mm, ss, drop ? ';' : ':', ff);
9834  av_dict_set(&st->metadata, "timecode", buf, 0);
9835 
9836  avio_seek(sc->pb, cur_pos, SEEK_SET);
9837  return 0;
9838 }
9839 
9841 {
9842  MOVStreamContext *sc = st->priv_data;
9843  FFStream *const sti = ffstream(st);
9844  int flags = 0;
9845  int64_t cur_pos = avio_tell(sc->pb);
9846  int64_t value;
9847  AVRational tc_rate = st->avg_frame_rate;
9848  int tmcd_nb_frames = sc->tmcd_nb_frames;
9849  int rounded_tc_rate;
9850 
9851  if (!sti->nb_index_entries)
9852  return -1;
9853 
9854  if (!tc_rate.num || !tc_rate.den || !tmcd_nb_frames)
9855  return -1;
9856 
9857  avio_seek(sc->pb, sti->index_entries->pos, SEEK_SET);
9858  value = avio_rb32(s->pb);
9859 
9860  if (sc->tmcd_flags & 0x0001) flags |= AV_TIMECODE_FLAG_DROPFRAME;
9861  if (sc->tmcd_flags & 0x0002) flags |= AV_TIMECODE_FLAG_24HOURSMAX;
9862  if (sc->tmcd_flags & 0x0004) flags |= AV_TIMECODE_FLAG_ALLOWNEGATIVE;
9863 
9864  /* Assume Counter flag is set to 1 in tmcd track (even though it is likely
9865  * not the case) and thus assume "frame number format" instead of QT one.
9866  * No sample with tmcd track can be found with a QT timecode at the moment,
9867  * despite what the tmcd track "suggests" (Counter flag set to 0 means QT
9868  * format). */
9869 
9870  /* 60 fps content have tmcd_nb_frames set to 30 but tc_rate set to 60, so
9871  * we multiply the frame number with the quotient.
9872  * See tickets #9492, #9710. */
9873  rounded_tc_rate = (tc_rate.num + tc_rate.den / 2LL) / tc_rate.den;
9874  /* Work around files where tmcd_nb_frames is rounded down from frame rate
9875  * instead of up. See ticket #5978. */
9876  if (tmcd_nb_frames == tc_rate.num / tc_rate.den &&
9877  s->strict_std_compliance < FF_COMPLIANCE_STRICT)
9878  tmcd_nb_frames = rounded_tc_rate;
9879  value = av_rescale(value, rounded_tc_rate, tmcd_nb_frames);
9880 
9882 
9883  avio_seek(sc->pb, cur_pos, SEEK_SET);
9884  return 0;
9885 }
9886 
9888  int i;
9889  if (!index || !*index) return;
9890  for (i = 0; i < (*index)->nb_encrypted_samples; i++) {
9891  av_encryption_info_free((*index)->encrypted_samples[i]);
9892  }
9893  av_freep(&(*index)->encrypted_samples);
9894  av_freep(&(*index)->auxiliary_info_sizes);
9895  av_freep(&(*index)->auxiliary_offsets);
9896  av_freep(index);
9897 }
9898 
9900 {
9901  MOVStreamContext *sc = st->priv_data;
9902 
9903  if (!sc || --sc->refcount) {
9904  st->priv_data = NULL;
9905  return;
9906  }
9907 
9908  av_freep(&sc->tts_data);
9909  for (int i = 0; i < sc->drefs_count; i++) {
9910  av_freep(&sc->drefs[i].path);
9911  av_freep(&sc->drefs[i].dir);
9912  }
9913  av_freep(&sc->drefs);
9914 
9915  sc->drefs_count = 0;
9916 
9917  if (!sc->pb_is_copied)
9918  ff_format_io_close(s, &sc->pb);
9919 
9920  sc->pb = NULL;
9921  av_freep(&sc->chunk_offsets);
9922  av_freep(&sc->stsc_data);
9923  av_freep(&sc->sample_sizes);
9924  av_freep(&sc->keyframes);
9925  av_freep(&sc->ctts_data);
9926  av_freep(&sc->stts_data);
9927  av_freep(&sc->sdtp_data);
9928  av_freep(&sc->stps_data);
9929  av_freep(&sc->elst_data);
9930  av_freep(&sc->rap_group);
9931  av_freep(&sc->sync_group);
9932  av_freep(&sc->sgpd_sync);
9933  av_freep(&sc->sample_offsets);
9934  av_freep(&sc->open_key_samples);
9935  av_freep(&sc->display_matrix);
9936  av_freep(&sc->index_ranges);
9937 
9938  if (sc->extradata)
9939  for (int i = 0; i < sc->stsd_count; i++)
9940  av_free(sc->extradata[i]);
9941  av_freep(&sc->extradata);
9942  av_freep(&sc->extradata_size);
9943 
9947 
9948  av_freep(&sc->stereo3d);
9949  av_freep(&sc->spherical);
9950  av_freep(&sc->mastering);
9951  av_freep(&sc->coll);
9952  av_freep(&sc->ambient);
9953 
9954 #if CONFIG_IAMFDEC
9955  if (sc->iamf)
9957 #endif
9958  av_freep(&sc->iamf);
9959 }
9960 
9962 {
9963  MOVContext *mov = s->priv_data;
9964  int i, j;
9965 
9966  for (i = 0; i < s->nb_streams; i++) {
9967  AVStream *st = s->streams[i];
9968 
9970  }
9971 
9972  av_freep(&mov->dv_demux);
9974  mov->dv_fctx = NULL;
9975 
9976  if (mov->meta_keys) {
9977  for (i = 1; i < mov->meta_keys_count; i++) {
9978  av_freep(&mov->meta_keys[i]);
9979  }
9980  av_freep(&mov->meta_keys);
9981  }
9982 
9983  av_freep(&mov->trex_data);
9984  av_freep(&mov->bitrates);
9985 
9986  for (i = 0; i < mov->frag_index.nb_items; i++) {
9988  for (j = 0; j < mov->frag_index.item[i].nb_stream_info; j++) {
9989  mov_free_encryption_index(&frag[j].encryption_index);
9990  }
9992  }
9993  av_freep(&mov->frag_index.item);
9994 
9995  av_freep(&mov->aes_decrypt);
9996  av_freep(&mov->chapter_tracks);
9997  for (i = 0; i < mov->nb_heif_item; i++) {
9998  if (!mov->heif_item[i])
9999  continue;
10000  av_freep(&mov->heif_item[i]->name);
10001  av_freep(&mov->heif_item[i]->iref_list);
10002  av_freep(&mov->heif_item[i]->icc_profile);
10003  av_freep(&mov->heif_item[i]);
10004  }
10005  av_freep(&mov->heif_item);
10006  for (i = 0; i < mov->nb_heif_grid; i++) {
10007  av_freep(&mov->heif_grid[i].tile_id_list);
10010  }
10011  av_freep(&mov->heif_grid);
10012 
10013  return 0;
10014 }
10015 
10016 static int tmcd_is_referenced(AVFormatContext *s, int tmcd_id)
10017 {
10018  int i;
10019 
10020  for (i = 0; i < s->nb_streams; i++) {
10021  AVStream *st = s->streams[i];
10022  MOVStreamContext *sc = st->priv_data;
10023 
10024  if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO &&
10025  sc->timecode_track == tmcd_id)
10026  return 1;
10027  }
10028  return 0;
10029 }
10030 
10031 /* look for a tmcd track not referenced by any video track, and export it globally */
10033 {
10034  int i;
10035 
10036  for (i = 0; i < s->nb_streams; i++) {
10037  AVStream *st = s->streams[i];
10038 
10039  if (st->codecpar->codec_tag == MKTAG('t','m','c','d') &&
10040  !tmcd_is_referenced(s, i + 1)) {
10041  AVDictionaryEntry *tcr = av_dict_get(st->metadata, "timecode", NULL, 0);
10042  if (tcr) {
10043  av_dict_set(&s->metadata, "timecode", tcr->value, 0);
10044  break;
10045  }
10046  }
10047  }
10048 }
10049 
10050 static int read_tfra(MOVContext *mov, AVIOContext *f)
10051 {
10052  int version, fieldlength, i, j;
10053  int64_t pos = avio_tell(f);
10054  uint32_t size = avio_rb32(f);
10055  unsigned track_id, item_count;
10056 
10057  if (avio_rb32(f) != MKBETAG('t', 'f', 'r', 'a')) {
10058  return 1;
10059  }
10060  av_log(mov->fc, AV_LOG_VERBOSE, "found tfra\n");
10061 
10062  version = avio_r8(f);
10063  avio_rb24(f);
10064  track_id = avio_rb32(f);
10065  fieldlength = avio_rb32(f);
10066  item_count = avio_rb32(f);
10067  for (i = 0; i < item_count; i++) {
10068  int64_t time, offset;
10069  int index;
10070  MOVFragmentStreamInfo * frag_stream_info;
10071 
10072  if (avio_feof(f)) {
10073  return AVERROR_INVALIDDATA;
10074  }
10075 
10076  if (version == 1) {
10077  time = avio_rb64(f);
10078  offset = avio_rb64(f);
10079  } else {
10080  time = avio_rb32(f);
10081  offset = avio_rb32(f);
10082  }
10083 
10084  // The first sample of each stream in a fragment is always a random
10085  // access sample. So it's entry in the tfra can be used as the
10086  // initial PTS of the fragment.
10087  index = update_frag_index(mov, offset);
10088  frag_stream_info = get_frag_stream_info(&mov->frag_index, index, track_id);
10089  if (frag_stream_info &&
10090  frag_stream_info->first_tfra_pts == AV_NOPTS_VALUE)
10091  frag_stream_info->first_tfra_pts = time;
10092 
10093  for (j = 0; j < ((fieldlength >> 4) & 3) + 1; j++)
10094  avio_r8(f);
10095  for (j = 0; j < ((fieldlength >> 2) & 3) + 1; j++)
10096  avio_r8(f);
10097  for (j = 0; j < ((fieldlength >> 0) & 3) + 1; j++)
10098  avio_r8(f);
10099  }
10100 
10101  avio_seek(f, pos + size, SEEK_SET);
10102  return 0;
10103 }
10104 
10106 {
10107  int64_t stream_size = avio_size(f);
10108  int64_t original_pos = avio_tell(f);
10109  int64_t seek_ret;
10110  int ret = -1;
10111  if ((seek_ret = avio_seek(f, stream_size - 4, SEEK_SET)) < 0) {
10112  ret = seek_ret;
10113  goto fail;
10114  }
10115  c->mfra_size = avio_rb32(f);
10116  c->have_read_mfra_size = 1;
10117  if (!c->mfra_size || c->mfra_size > stream_size) {
10118  av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (unreasonable size)\n");
10119  goto fail;
10120  }
10121  if ((seek_ret = avio_seek(f, -((int64_t) c->mfra_size), SEEK_CUR)) < 0) {
10122  ret = seek_ret;
10123  goto fail;
10124  }
10125  if (avio_rb32(f) != c->mfra_size) {
10126  av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (size mismatch)\n");
10127  goto fail;
10128  }
10129  if (avio_rb32(f) != MKBETAG('m', 'f', 'r', 'a')) {
10130  av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (tag mismatch)\n");
10131  goto fail;
10132  }
10133  av_log(c->fc, AV_LOG_VERBOSE, "stream has mfra\n");
10134  do {
10135  ret = read_tfra(c, f);
10136  if (ret < 0)
10137  goto fail;
10138  } while (!ret);
10139  ret = 0;
10140  c->frag_index.complete = 1;
10141 fail:
10142  seek_ret = avio_seek(f, original_pos, SEEK_SET);
10143  if (seek_ret < 0) {
10144  av_log(c->fc, AV_LOG_ERROR,
10145  "failed to seek back after looking for mfra\n");
10146  ret = seek_ret;
10147  }
10148  return ret;
10149 }
10150 
10151 static int set_icc_profile_from_item(AVPacketSideData **coded_side_data, int *nb_coded_side_data,
10152  const HEIFItem *item)
10153 {
10154  AVPacketSideData *sd = av_packet_side_data_new(coded_side_data, nb_coded_side_data,
10156  item->icc_profile_size, 0);
10157  if (!sd)
10158  return AVERROR(ENOMEM);
10159 
10160  memcpy(sd->data, item->icc_profile, item->icc_profile_size);
10161 
10162  return 0;
10163 }
10164 
10165 static int set_display_matrix_from_item(AVPacketSideData **coded_side_data, int *nb_coded_side_data,
10166  const HEIFItem *item)
10167 {
10168  int32_t *matrix;
10169  AVPacketSideData *sd = av_packet_side_data_new(coded_side_data,
10170  nb_coded_side_data,
10172  9 * sizeof(*matrix), 0);
10173  if (!sd)
10174  return AVERROR(ENOMEM);
10175 
10176  matrix = (int32_t*)sd->data;
10177  /* rotation is in the counter-clockwise direction whereas
10178  * av_display_rotation_set() expects its argument to be
10179  * oriented clockwise, so we need to negate it. */
10181  av_display_matrix_flip(matrix, item->hflip, item->vflip);
10182 
10183  return 0;
10184 }
10185 
10186 static int read_image_grid(AVFormatContext *s, const HEIFGrid *grid,
10187  AVStreamGroupTileGrid *tile_grid)
10188 {
10189  MOVContext *c = s->priv_data;
10190  const HEIFItem *item = grid->item;
10191  int64_t offset = 0, pos = avio_tell(s->pb);
10192  int x = 0, y = 0, i = 0;
10193  int tile_rows, tile_cols;
10194  int flags, size;
10195 
10196  if (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL)) {
10197  av_log(c->fc, AV_LOG_INFO, "grid box with non seekable input\n");
10198  return AVERROR_PATCHWELCOME;
10199  }
10200  if (item->is_idat_relative) {
10201  if (!c->idat_offset) {
10202  av_log(c->fc, AV_LOG_ERROR, "missing idat box required by the image grid\n");
10203  return AVERROR_INVALIDDATA;
10204  }
10205  offset = c->idat_offset;
10206  }
10207 
10208  avio_seek(s->pb, item->extent_offset + offset, SEEK_SET);
10209 
10210  avio_r8(s->pb); /* version */
10211  flags = avio_r8(s->pb);
10212 
10213  tile_rows = avio_r8(s->pb) + 1;
10214  tile_cols = avio_r8(s->pb) + 1;
10215  /* actual width and height of output image */
10216  tile_grid->width = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
10217  tile_grid->height = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
10218 
10219  av_log(c->fc, AV_LOG_TRACE, "grid: grid_rows %d grid_cols %d output_width %d output_height %d\n",
10220  tile_rows, tile_cols, tile_grid->width, tile_grid->height);
10221 
10222  avio_seek(s->pb, pos, SEEK_SET);
10223 
10224  size = tile_rows * tile_cols;
10225  tile_grid->nb_tiles = grid->nb_tiles;
10226 
10227  if (tile_grid->nb_tiles != size)
10228  return AVERROR_INVALIDDATA;
10229 
10230  for (int i = 0; i < tile_cols; i++)
10231  tile_grid->coded_width += grid->tile_item_list[i]->width;
10232  for (int i = 0; i < size; i += tile_cols)
10233  tile_grid->coded_height += grid->tile_item_list[i]->height;
10234 
10235  tile_grid->offsets = av_calloc(tile_grid->nb_tiles, sizeof(*tile_grid->offsets));
10236  if (!tile_grid->offsets)
10237  return AVERROR(ENOMEM);
10238 
10239  while (y < tile_grid->coded_height) {
10240  int left_col = i;
10241 
10242  while (x < tile_grid->coded_width) {
10243  if (i == tile_grid->nb_tiles)
10244  return AVERROR_INVALIDDATA;
10245 
10246  tile_grid->offsets[i].idx = grid->tile_idx_list[i];
10247  tile_grid->offsets[i].horizontal = x;
10248  tile_grid->offsets[i].vertical = y;
10249 
10250  x += grid->tile_item_list[i++]->width;
10251  }
10252 
10253  if (x > tile_grid->coded_width) {
10254  av_log(c->fc, AV_LOG_ERROR, "Non uniform HEIF tiles\n");
10255  return AVERROR_INVALIDDATA;
10256  }
10257 
10258  x = 0;
10259  y += grid->tile_item_list[left_col]->height;
10260  }
10261 
10262  if (y > tile_grid->coded_height || i != tile_grid->nb_tiles) {
10263  av_log(c->fc, AV_LOG_ERROR, "Non uniform HEIF tiles\n");
10264  return AVERROR_INVALIDDATA;
10265  }
10266 
10267  return 0;
10268 }
10269 
10270 static int read_image_iovl(AVFormatContext *s, const HEIFGrid *grid,
10271  AVStreamGroupTileGrid *tile_grid)
10272 {
10273  MOVContext *c = s->priv_data;
10274  const HEIFItem *item = grid->item;
10275  uint16_t canvas_fill_value[4];
10276  int64_t offset = 0, pos = avio_tell(s->pb);
10277  int ret = 0, flags;
10278 
10279  if (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL)) {
10280  av_log(c->fc, AV_LOG_INFO, "iovl box with non seekable input\n");
10281  return AVERROR_PATCHWELCOME;
10282  }
10283  if (item->is_idat_relative) {
10284  if (!c->idat_offset) {
10285  av_log(c->fc, AV_LOG_ERROR, "missing idat box required by the image overlay\n");
10286  return AVERROR_INVALIDDATA;
10287  }
10288  offset = c->idat_offset;
10289  }
10290 
10291  avio_seek(s->pb, item->extent_offset + offset, SEEK_SET);
10292 
10293  avio_r8(s->pb); /* version */
10294  flags = avio_r8(s->pb);
10295 
10296  for (int i = 0; i < 4; i++)
10297  canvas_fill_value[i] = avio_rb16(s->pb);
10298  av_log(c->fc, AV_LOG_TRACE, "iovl: canvas_fill_value { %u, %u, %u, %u }\n",
10299  canvas_fill_value[0], canvas_fill_value[1],
10300  canvas_fill_value[2], canvas_fill_value[3]);
10301  for (int i = 0; i < 4; i++)
10302  tile_grid->background[i] = canvas_fill_value[i];
10303 
10304  /* actual width and height of output image */
10305  tile_grid->width =
10306  tile_grid->coded_width = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
10307  tile_grid->height =
10308  tile_grid->coded_height = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
10309 
10310  av_log(c->fc, AV_LOG_TRACE, "iovl: output_width %d, output_height %d\n",
10311  tile_grid->width, tile_grid->height);
10312 
10313  tile_grid->nb_tiles = grid->nb_tiles;
10314  tile_grid->offsets = av_malloc_array(tile_grid->nb_tiles, sizeof(*tile_grid->offsets));
10315  if (!tile_grid->offsets) {
10316  ret = AVERROR(ENOMEM);
10317  goto fail;
10318  }
10319 
10320  for (int i = 0; i < tile_grid->nb_tiles; i++) {
10321  tile_grid->offsets[i].idx = grid->tile_idx_list[i];
10322  tile_grid->offsets[i].horizontal = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
10323  tile_grid->offsets[i].vertical = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
10324  av_log(c->fc, AV_LOG_TRACE, "iovl: stream_idx[%d] %u, "
10325  "horizontal_offset[%d] %d, vertical_offset[%d] %d\n",
10326  i, tile_grid->offsets[i].idx,
10327  i, tile_grid->offsets[i].horizontal, i, tile_grid->offsets[i].vertical);
10328  }
10329 
10330 fail:
10331  avio_seek(s->pb, pos, SEEK_SET);
10332 
10333  return ret;
10334 }
10335 
10337  AVPacketSideData **coded_side_data, int *nb_coded_side_data,
10338  const HEIFItem *ref)
10339 {
10340  MOVContext *c = s->priv_data;
10341  AVPacketSideData *sd;
10342  AVExifMetadata ifd = { 0 };
10343  AVBufferRef *buf;
10344  int64_t offset = 0, pos = avio_tell(s->pb);
10345  unsigned orientation_id = av_exif_get_tag_id("Orientation");
10346  int err;
10347 
10348  if (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL)) {
10349  av_log(c->fc, AV_LOG_WARNING, "Exif metadata with non seekable input\n");
10350  return AVERROR_PATCHWELCOME;
10351  }
10352  if (ref->is_idat_relative) {
10353  if (!c->idat_offset) {
10354  av_log(c->fc, AV_LOG_ERROR, "missing idat box required by the Exif metadata\n");
10355  return AVERROR_INVALIDDATA;
10356  }
10357  offset = c->idat_offset;
10358  }
10359 
10360  buf = av_buffer_alloc(ref->extent_length);
10361  if (!buf)
10362  return AVERROR(ENOMEM);
10363 
10364  avio_seek(s->pb, ref->extent_offset + offset, SEEK_SET);
10365  err = avio_read(s->pb, buf->data, ref->extent_length);
10366  if (err != ref->extent_length) {
10367  if (err > 0)
10368  err = AVERROR_INVALIDDATA;
10369  goto fail;
10370  }
10371 
10372  // HEIF spec states that Exif metadata is informative. The irot item property is
10373  // the normative source of rotation information. So we remove any Orientation tag
10374  // present in the Exif buffer.
10375  err = av_exif_parse_buffer(s, buf->data, ref->extent_length, &ifd, AV_EXIF_T_OFF);
10376  if (err < 0) {
10377  av_log(s, AV_LOG_ERROR, "Unable to parse Exif metadata\n");
10378  goto fail;
10379  }
10380 
10381  err = av_exif_remove_entry(s, &ifd, orientation_id, 0);
10382  if (err < 0)
10383  goto fail;
10384  else if (!err)
10385  goto finish;
10386 
10387  av_buffer_unref(&buf);
10388  err = av_exif_write(s, &ifd, &buf, AV_EXIF_T_OFF);
10389  if (err < 0)
10390  goto fail;
10391 
10392 finish:
10393  offset = AV_RB32(buf->data) + 4;
10394  if (offset >= buf->size) {
10395  err = AVERROR_INVALIDDATA;
10396  goto fail;
10397  }
10398  sd = av_packet_side_data_new(coded_side_data, nb_coded_side_data,
10399  AV_PKT_DATA_EXIF, buf->size - offset, 0);
10400  if (!sd) {
10401  err = AVERROR(ENOMEM);
10402  goto fail;
10403  }
10404  memcpy(sd->data, buf->data + offset, buf->size - offset);
10405 
10406  err = 0;
10407 fail:
10408  av_buffer_unref(&buf);
10409  av_exif_free(&ifd);
10410  avio_seek(s->pb, pos, SEEK_SET);
10411 
10412  return err;
10413 }
10414 
10416 {
10417  MOVContext *mov = s->priv_data;
10418 
10419  for (int i = 0; i < mov->nb_heif_grid; i++) {
10421  AVStreamGroupTileGrid *tile_grid;
10422  const HEIFGrid *grid = &mov->heif_grid[i];
10423  int err, loop = 1;
10424 
10425  if (!stg)
10426  return AVERROR(ENOMEM);
10427 
10428  stg->id = grid->item->item_id;
10429  tile_grid = stg->params.tile_grid;
10430 
10431  for (int j = 0; j < grid->nb_tiles; j++) {
10432  int tile_id = grid->tile_id_list[j];
10433  int k;
10434 
10435  for (k = 0; k < mov->nb_heif_item; k++) {
10436  HEIFItem *item = mov->heif_item[k];
10437  AVStream *st;
10438 
10439  if (!item || item->item_id != tile_id)
10440  continue;
10441  st = item->st;
10442  if (!st) {
10443  av_log(s, AV_LOG_WARNING, "HEIF item id %d from grid id %d doesn't "
10444  "reference a stream\n",
10445  tile_id, grid->item->item_id);
10446  ff_remove_stream_group(s, stg);
10447  loop = 0;
10448  break;
10449  }
10450 
10451  grid->tile_item_list[j] = item;
10452  grid->tile_idx_list[j] = stg->nb_streams;
10453 
10454  err = avformat_stream_group_add_stream(stg, st);
10455  if (err < 0) {
10456  int l;
10457  if (err != AVERROR(EEXIST))
10458  return err;
10459 
10460  for (l = 0; l < stg->nb_streams; l++)
10461  if (stg->streams[l]->index == st->index)
10462  break;
10463  av_assert0(l < stg->nb_streams);
10464  grid->tile_idx_list[j] = l;
10465  }
10466 
10467  if (item->item_id != mov->primary_item_id)
10469  break;
10470  }
10471 
10472  if (k == mov->nb_heif_item) {
10473  av_assert0(loop);
10474  av_log(s, AV_LOG_WARNING, "HEIF item id %d referenced by grid id %d doesn't "
10475  "exist\n",
10476  tile_id, grid->item->item_id);
10477  ff_remove_stream_group(s, stg);
10478  loop = 0;
10479  }
10480  if (!loop)
10481  break;
10482  }
10483 
10484  if (!loop)
10485  continue;
10486 
10487  switch (grid->item->type) {
10488  case MKTAG('g','r','i','d'):
10489  err = read_image_grid(s, grid, tile_grid);
10490  break;
10491  case MKTAG('i','o','v','l'):
10492  err = read_image_iovl(s, grid, tile_grid);
10493  break;
10494  default:
10495  av_assert0(0);
10496  }
10497  if (err < 0)
10498  return err;
10499 
10500  for (int j = 0; j < grid->item->nb_iref_list; j++) {
10501  HEIFItem *ref = get_heif_item(mov, grid->item->iref_list[j].item_id);
10502 
10503  av_assert0(ref);
10504  switch(ref->type) {
10505  case MKTAG('E','x','i','f'):
10506  err = mov_parse_exif_item(s, &tile_grid->coded_side_data,
10507  &tile_grid->nb_coded_side_data, ref);
10508  if (err < 0 && (s->error_recognition & AV_EF_EXPLODE))
10509  return err;
10510  break;
10511  default:
10512  break;
10513  }
10514  }
10515 
10516  /* rotation */
10517  if (grid->item->rotation || grid->item->hflip || grid->item->vflip) {
10519  &tile_grid->nb_coded_side_data, grid->item);
10520  if (err < 0)
10521  return err;
10522  }
10523 
10524  /* ICC profile */
10525  if (grid->item->icc_profile_size) {
10526  err = set_icc_profile_from_item(&tile_grid->coded_side_data,
10527  &tile_grid->nb_coded_side_data, grid->item);
10528  if (err < 0)
10529  return err;
10530  }
10531 
10532  if (grid->item->name)
10533  av_dict_set(&stg->metadata, "title", grid->item->name, 0);
10534  if (grid->item->item_id == mov->primary_item_id)
10536  }
10537 
10538  return 0;
10539 }
10540 
10542 {
10543  MOVContext *mov = s->priv_data;
10544  int err;
10545 
10546  for (int i = 0; i < mov->nb_heif_item; i++) {
10547  HEIFItem *item = mov->heif_item[i];
10548  MOVStreamContext *sc;
10549  AVStream *st;
10550  int64_t offset = 0;
10551 
10552  if (!item)
10553  continue;
10554  if (!item->st) {
10555  continue;
10556  }
10557  if (item->is_idat_relative) {
10558  if (!mov->idat_offset) {
10559  av_log(s, AV_LOG_ERROR, "Missing idat box for item %d\n", item->item_id);
10560  return AVERROR_INVALIDDATA;
10561  }
10562  offset = mov->idat_offset;
10563  }
10564 
10565  st = item->st;
10566  sc = st->priv_data;
10567  st->codecpar->width = item->width;
10568  st->codecpar->height = item->height;
10569 
10570  sc->sample_size = sc->stsz_sample_size = item->extent_length;
10571  sc->sample_count = 1;
10572 
10573  err = sanity_checks(s, sc, st->index);
10574  if (err)
10575  return AVERROR_INVALIDDATA;
10576 
10577  sc->chunk_offsets[0] = item->extent_offset + offset;
10578 
10579  if (item->item_id == mov->primary_item_id)
10581 
10582  for (int j = 0; j < item->nb_iref_list; j++) {
10583  HEIFItem *ref = get_heif_item(mov, item->iref_list[j].item_id);
10584 
10585  av_assert0(ref);
10586  switch(ref->type) {
10587  case MKTAG('E','x','i','f'):
10590  if (err < 0 && (s->error_recognition & AV_EF_EXPLODE))
10591  return err;
10592  break;
10593  default:
10594  break;
10595  }
10596  }
10597 
10598  if (item->rotation || item->hflip || item->vflip) {
10600  &st->codecpar->nb_coded_side_data, item);
10601  if (err < 0)
10602  return err;
10603  }
10604 
10605  mov_build_index(mov, st);
10606  }
10607 
10608  if (mov->nb_heif_grid) {
10609  err = mov_parse_tiles(s);
10610  if (err < 0)
10611  return err;
10612  }
10613 
10614  return 0;
10615 }
10616 
10618  int first_index)
10619 {
10620  MOVStreamContext *sc = st->priv_data;
10621 
10622  if (sc->tref_id < 0)
10623  return NULL;
10624 
10625  for (int i = first_index; i < s->nb_streams; i++)
10626  if (s->streams[i]->id == sc->tref_id)
10627  return s->streams[i];
10628 
10629  return NULL;
10630 }
10631 
10633 {
10634  int err;
10635 
10636  for (int i = 0; i < s->nb_streams; i++) {
10637  AVStreamGroup *stg;
10638  AVStream *st = s->streams[i];
10639  AVStream *st_base;
10640  MOVStreamContext *sc = st->priv_data;
10641  int j = 0;
10642 
10643  /* Find an enhancement stream. */
10644  if (st->codecpar->codec_id != AV_CODEC_ID_LCEVC ||
10646  continue;
10647 
10649 
10651  if (!stg)
10652  return AVERROR(ENOMEM);
10653 
10654  stg->id = st->id;
10655  stg->params.lcevc->width = st->codecpar->width;
10656  stg->params.lcevc->height = st->codecpar->height;
10657  st->codecpar->width = 0;
10658  st->codecpar->height = 0;
10659 
10660  while (st_base = mov_find_reference_track(s, st, j)) {
10661  err = avformat_stream_group_add_stream(stg, st_base);
10662  if (err < 0)
10663  return err;
10664 
10665  j = st_base->index + 1;
10666  }
10667  if (!j) {
10668  av_log(s, AV_LOG_ERROR, "Failed to find base stream for enhancement stream\n");
10669  return AVERROR_INVALIDDATA;
10670  }
10671 
10672  err = avformat_stream_group_add_stream(stg, st);
10673  if (err < 0)
10674  return err;
10675 
10676  stg->params.lcevc->lcevc_index = stg->nb_streams - 1;
10677  }
10678 
10679  return 0;
10680 }
10681 
10683 {
10684  int highest_id = 0;
10685 
10686  for (int i = 0; i < s->nb_streams; i++) {
10687  const AVStream *st = s->streams[i];
10688  const MOVStreamContext *sc = st->priv_data;
10689  if (!sc->iamf)
10690  highest_id = FFMAX(highest_id, st->id);
10691  }
10692  highest_id += !highest_id;
10693  for (int i = 0; highest_id > 1 && i < s->nb_stream_groups; i++) {
10694  AVStreamGroup *stg = s->stream_groups[i];
10696  continue;
10697  for (int j = 0; j < stg->nb_streams; j++) {
10698  AVStream *st = stg->streams[j];
10699  MOVStreamContext *sc = st->priv_data;
10700  st->id += highest_id;
10701  sc->iamf_stream_offset = highest_id;
10702  }
10703  }
10704 }
10705 
10707 {
10708  MOVContext *mov = s->priv_data;
10709  AVIOContext *pb = s->pb;
10710  int j, err;
10711  MOVAtom atom = { AV_RL32("root") };
10712  int i;
10713 
10714  if (mov->decryption_key_len != 0 && mov->decryption_key_len != AES_CTR_KEY_SIZE) {
10715  av_log(s, AV_LOG_ERROR, "Invalid decryption key len %d expected %d\n",
10717  return AVERROR(EINVAL);
10718  }
10719 
10720  mov->fc = s;
10721  mov->trak_index = -1;
10722  mov->primary_item_id = -1;
10723  mov->cur_item_id = -1;
10724  /* .mov and .mp4 aren't streamable anyway (only progressive download if moov is before mdat) */
10725  if (pb->seekable & AVIO_SEEKABLE_NORMAL)
10726  atom.size = avio_size(pb);
10727  else
10728  atom.size = INT64_MAX;
10729 
10730  /* check MOV header */
10731  do {
10732  if (mov->moov_retry)
10733  avio_seek(pb, 0, SEEK_SET);
10734  if ((err = mov_read_default(mov, pb, atom)) < 0) {
10735  av_log(s, AV_LOG_ERROR, "error reading header\n");
10736  return err;
10737  }
10738  } while ((pb->seekable & AVIO_SEEKABLE_NORMAL) &&
10739  !mov->found_moov && (!mov->found_iloc || !mov->found_iinf) && !mov->moov_retry++);
10740  if (!mov->found_moov && !mov->found_iloc && !mov->found_iinf) {
10741  av_log(s, AV_LOG_ERROR, "moov atom not found\n");
10742  return AVERROR_INVALIDDATA;
10743  }
10744  av_log(mov->fc, AV_LOG_TRACE, "on_parse_exit_offset=%"PRId64"\n", avio_tell(pb));
10745 
10746  if (mov->found_iloc && mov->found_iinf) {
10747  err = mov_parse_heif_items(s);
10748  if (err < 0)
10749  return err;
10750  }
10751  // prevent iloc and iinf boxes from being parsed while reading packets.
10752  // this is needed because an iinf box may have been parsed but ignored
10753  // for having old infe boxes which create no streams.
10754  mov->found_iloc = mov->found_iinf = 1;
10755 
10756  if (pb->seekable & AVIO_SEEKABLE_NORMAL) {
10757  if (mov->nb_chapter_tracks > 0 && !mov->ignore_chapters)
10759  for (i = 0; i < s->nb_streams; i++)
10760  if (s->streams[i]->codecpar->codec_tag == AV_RL32("tmcd")) {
10761  mov_read_timecode_track(s, s->streams[i]);
10762  } else if (s->streams[i]->codecpar->codec_tag == AV_RL32("rtmd")) {
10763  mov_read_rtmd_track(s, s->streams[i]);
10764  }
10765  }
10766 
10767  /* copy timecode metadata from tmcd tracks to the related video streams */
10768  for (i = 0; i < s->nb_streams; i++) {
10769  AVStream *st = s->streams[i];
10770  MOVStreamContext *sc = st->priv_data;
10771  if (sc->timecode_track > 0) {
10772  AVDictionaryEntry *tcr;
10773  int tmcd_st_id = -1;
10774 
10775  for (j = 0; j < s->nb_streams; j++) {
10776  MOVStreamContext *sc2 = s->streams[j]->priv_data;
10777  if (sc2->id == sc->timecode_track)
10778  tmcd_st_id = j;
10779  }
10780 
10781  if (tmcd_st_id < 0 || tmcd_st_id == i)
10782  continue;
10783  tcr = av_dict_get(s->streams[tmcd_st_id]->metadata, "timecode", NULL, 0);
10784  if (tcr)
10785  av_dict_set(&st->metadata, "timecode", tcr->value, 0);
10786  }
10787  }
10789 
10790  /* Create LCEVC stream groups. */
10791  err = mov_parse_lcevc_streams(s);
10792  if (err < 0)
10793  return err;
10794 
10795  for (i = 0; i < s->nb_streams; i++) {
10796  AVStream *st = s->streams[i];
10797  FFStream *const sti = ffstream(st);
10798  MOVStreamContext *sc = st->priv_data;
10799  uint32_t dvdsub_clut[FF_DVDCLUT_CLUT_LEN] = {0};
10800  fix_timescale(mov, sc);
10801 
10802  /* Set the primary extradata based on the first Sample if it doesn't reference the first stsd entry. */
10803  if (sc->stsc_count && sc->extradata_size && !sc->iamf &&
10804  sc->stsc_data[0].id > 1 && sc->stsc_data[0].id <= sc->stsd_count) {
10805  sc->last_stsd_index = sc->stsc_data[0].id - 1;
10806  av_freep(&st->codecpar->extradata);
10808  if (sc->extradata_size[sc->last_stsd_index]) {
10810  if (!st->codecpar->extradata)
10811  return AVERROR(ENOMEM);
10812  memcpy(st->codecpar->extradata, sc->extradata[sc->last_stsd_index], sc->extradata_size[sc->last_stsd_index]);
10813  }
10814  }
10815 
10816  if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
10817  st->codecpar->codec_id == AV_CODEC_ID_AAC) {
10818  sti->skip_samples = sc->start_pad;
10819  }
10820  if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && sc->nb_frames_for_fps > 0 && sc->duration_for_fps > 0)
10822  sc->time_scale*(int64_t)sc->nb_frames_for_fps, sc->duration_for_fps, INT_MAX);
10824  if (st->codecpar->width <= 0 || st->codecpar->height <= 0) {
10825  st->codecpar->width = sc->width;
10826  st->codecpar->height = sc->height;
10827  }
10830 
10831  for (j = 0; j < FF_DVDCLUT_CLUT_LEN; j++)
10832  dvdsub_clut[j] = AV_RB32(st->codecpar->extradata + j * 4);
10833 
10834  err = ff_dvdclut_yuv_to_rgb(dvdsub_clut, FF_DVDCLUT_CLUT_SIZE);
10835  if (err < 0)
10836  return err;
10837 
10838  av_freep(&st->codecpar->extradata);
10839  st->codecpar->extradata_size = 0;
10840 
10842  st->codecpar);
10843  if (err < 0)
10844  return err;
10845  }
10846  }
10847  if (mov->handbrake_version &&
10848  mov->handbrake_version <= 1000000*0 + 1000*10 + 2 && // 0.10.2
10849  st->codecpar->codec_id == AV_CODEC_ID_MP3) {
10850  av_log(s, AV_LOG_VERBOSE, "Forcing full parsing for mp3 stream\n");
10852  }
10853  }
10854 
10855  if (mov->trex_data || mov->use_mfra_for > 0) {
10856  for (i = 0; i < s->nb_streams; i++) {
10857  AVStream *st = s->streams[i];
10858  MOVStreamContext *sc = st->priv_data;
10859  if (sc->duration_for_fps > 0) {
10860  /* Akin to sc->data_size * 8 * sc->time_scale / sc->duration_for_fps but accounting for overflows. */
10862  if (st->codecpar->bit_rate == INT64_MIN) {
10863  av_log(s, AV_LOG_WARNING, "Overflow during bit rate calculation %"PRId64" * 8 * %d\n",
10864  sc->data_size, sc->time_scale);
10865  st->codecpar->bit_rate = 0;
10866  if (s->error_recognition & AV_EF_EXPLODE)
10867  return AVERROR_INVALIDDATA;
10868  }
10869  }
10870  }
10871  }
10872 
10873  for (i = 0; i < mov->bitrates_count && i < s->nb_streams; i++) {
10874  if (mov->bitrates[i]) {
10875  s->streams[i]->codecpar->bit_rate = mov->bitrates[i];
10876  }
10877  }
10878 
10880 
10881  for (i = 0; i < s->nb_streams; i++) {
10882  AVStream *st = s->streams[i];
10883  MOVStreamContext *sc = st->priv_data;
10884 
10885  switch (st->codecpar->codec_type) {
10886  case AVMEDIA_TYPE_AUDIO:
10887  err = ff_replaygain_export(st, s->metadata);
10888  if (err < 0)
10889  return err;
10890  break;
10891  case AVMEDIA_TYPE_VIDEO:
10892  if (sc->display_matrix) {
10895  (uint8_t*)sc->display_matrix, sizeof(int32_t) * 9, 0))
10896  return AVERROR(ENOMEM);
10897 
10898  sc->display_matrix = NULL;
10899  }
10900  if (sc->stereo3d) {
10903  (uint8_t *)sc->stereo3d, sc->stereo3d_size, 0))
10904  return AVERROR(ENOMEM);
10905 
10906  sc->stereo3d = NULL;
10907  }
10908  if (sc->spherical) {
10911  (uint8_t *)sc->spherical, sc->spherical_size, 0))
10912  return AVERROR(ENOMEM);
10913 
10914  sc->spherical = NULL;
10915  }
10916  if (sc->mastering) {
10919  (uint8_t *)sc->mastering, sc->mastering_size, 0))
10920  return AVERROR(ENOMEM);
10921 
10922  sc->mastering = NULL;
10923  }
10924  if (sc->coll) {
10927  (uint8_t *)sc->coll, sc->coll_size, 0))
10928  return AVERROR(ENOMEM);
10929 
10930  sc->coll = NULL;
10931  }
10932  if (sc->ambient) {
10935  (uint8_t *) sc->ambient, sc->ambient_size, 0))
10936  return AVERROR(ENOMEM);
10937 
10938  sc->ambient = NULL;
10939  }
10940  break;
10941  }
10942  }
10943 
10944  fix_stream_ids(s);
10945 
10947 
10948  for (i = 0; i < mov->frag_index.nb_items; i++)
10949  if (mov->frag_index.item[i].moof_offset <= mov->fragment.moof_offset)
10950  mov->frag_index.item[i].headers_read = 1;
10951 
10952  return 0;
10953 }
10954 
10956 {
10958  int64_t best_dts = INT64_MAX;
10959  int i;
10960  MOVContext *mov = s->priv_data;
10961  int no_interleave = !mov->interleaved_read || !(s->pb->seekable & AVIO_SEEKABLE_NORMAL);
10962  for (i = 0; i < s->nb_streams; i++) {
10963  AVStream *avst = s->streams[i];
10964  FFStream *const avsti = ffstream(avst);
10965  MOVStreamContext *msc = avst->priv_data;
10966  if (msc->pb && msc->current_sample < avsti->nb_index_entries) {
10967  AVIndexEntry *current_sample = &avsti->index_entries[msc->current_sample];
10968  int64_t dts = av_rescale(current_sample->timestamp, AV_TIME_BASE, msc->time_scale);
10969  uint64_t dtsdiff = best_dts > dts ? best_dts - (uint64_t)dts : ((uint64_t)dts - best_dts);
10970  av_log(s, AV_LOG_TRACE, "stream %d, sample %d, dts %"PRId64"\n", i, msc->current_sample, dts);
10971  if (!sample || (no_interleave && current_sample->pos < sample->pos) ||
10972  ((s->pb->seekable & AVIO_SEEKABLE_NORMAL) &&
10973  ((msc->pb != s->pb && dts < best_dts) || (msc->pb == s->pb && dts != AV_NOPTS_VALUE &&
10974  ((dtsdiff <= AV_TIME_BASE && current_sample->pos < sample->pos) ||
10975  (dtsdiff > AV_TIME_BASE && dts < best_dts && mov->interleaved_read)))))) {
10976  sample = current_sample;
10977  best_dts = dts;
10978  *st = avst;
10979  }
10980  }
10981  }
10982  return sample;
10983 }
10984 
10985 static int should_retry(AVIOContext *pb, int error_code) {
10986  if (error_code == AVERROR_EOF || avio_feof(pb))
10987  return 0;
10988 
10989  return 1;
10990 }
10991 
10992 static int mov_switch_root(AVFormatContext *s, int64_t target, int index)
10993 {
10994  int ret;
10995  MOVContext *mov = s->priv_data;
10996 
10997  if (index >= 0 && index < mov->frag_index.nb_items)
10998  target = mov->frag_index.item[index].moof_offset;
10999  if (target >= 0 && avio_seek(s->pb, target, SEEK_SET) != target) {
11000  av_log(mov->fc, AV_LOG_ERROR, "root atom offset 0x%"PRIx64": partial file\n", target);
11001  return AVERROR_INVALIDDATA;
11002  }
11003 
11004  mov->next_root_atom = 0;
11005  if ((index < 0 && target >= 0) || index >= mov->frag_index.nb_items)
11006  index = search_frag_moof_offset(&mov->frag_index, target);
11007  if (index >= 0 && index < mov->frag_index.nb_items &&
11008  mov->frag_index.item[index].moof_offset == target) {
11009  if (index + 1 < mov->frag_index.nb_items)
11010  mov->next_root_atom = mov->frag_index.item[index + 1].moof_offset;
11011  if (mov->frag_index.item[index].headers_read)
11012  return 0;
11013  mov->frag_index.item[index].headers_read = 1;
11014  }
11015 
11016  mov->found_mdat = 0;
11017 
11018  ret = mov_read_default(mov, s->pb, (MOVAtom){ AV_RL32("root"), INT64_MAX });
11019  if (ret < 0)
11020  return ret;
11021  if (avio_feof(s->pb))
11022  return AVERROR_EOF;
11023  av_log(s, AV_LOG_TRACE, "read fragments, offset 0x%"PRIx64"\n", avio_tell(s->pb));
11024 
11025  return 1;
11026 }
11027 
11029 {
11030  MOVStreamContext *sc = st->priv_data;
11031  uint8_t *side, *extradata;
11032  int extradata_size;
11033 
11034  /* Save the current index. */
11035  sc->last_stsd_index = sc->stsc_data[sc->stsc_index].id - 1;
11036 
11037  /* Notify the decoder that extradata changed. */
11038  extradata_size = sc->extradata_size[sc->last_stsd_index];
11039  extradata = sc->extradata[sc->last_stsd_index];
11040  if (st->discard != AVDISCARD_ALL && extradata_size > 0 && extradata) {
11043  extradata_size);
11044  if (!side)
11045  return AVERROR(ENOMEM);
11046  memcpy(side, extradata, extradata_size);
11047  }
11048 
11049  return 0;
11050 }
11051 
11052 static int get_eia608_packet(AVIOContext *pb, AVPacket *pkt, int src_size)
11053 {
11054  /* We can't make assumptions about the structure of the payload,
11055  because it may include multiple cdat and cdt2 samples. */
11056  const uint32_t cdat = AV_RB32("cdat");
11057  const uint32_t cdt2 = AV_RB32("cdt2");
11058  int ret, out_size = 0;
11059 
11060  /* a valid payload must have size, 4cc, and at least 1 byte pair: */
11061  if (src_size < 10)
11062  return AVERROR_INVALIDDATA;
11063 
11064  /* avoid an int overflow: */
11065  if ((src_size - 8) / 2 >= INT_MAX / 3)
11066  return AVERROR_INVALIDDATA;
11067 
11068  ret = av_new_packet(pkt, ((src_size - 8) / 2) * 3);
11069  if (ret < 0)
11070  return ret;
11071 
11072  /* parse and re-format the c608 payload in one pass. */
11073  while (src_size >= 10) {
11074  const uint32_t atom_size = avio_rb32(pb);
11075  const uint32_t atom_type = avio_rb32(pb);
11076  const uint32_t data_size = atom_size - 8;
11077  const uint8_t cc_field =
11078  atom_type == cdat ? 1 :
11079  atom_type == cdt2 ? 2 :
11080  0;
11081 
11082  /* account for bytes consumed for atom size and type. */
11083  src_size -= 8;
11084 
11085  /* make sure the data size stays within the buffer boundaries. */
11086  if (data_size < 2 || data_size > src_size) {
11088  break;
11089  }
11090 
11091  /* make sure the data size is consistent with N byte pairs. */
11092  if (data_size % 2 != 0) {
11094  break;
11095  }
11096 
11097  if (!cc_field) {
11098  /* neither cdat or cdt2 ... skip it */
11099  avio_skip(pb, data_size);
11100  src_size -= data_size;
11101  continue;
11102  }
11103 
11104  for (uint32_t i = 0; i < data_size; i += 2) {
11105  pkt->data[out_size] = (0x1F << 3) | (1 << 2) | (cc_field - 1);
11106  pkt->data[out_size + 1] = avio_r8(pb);
11107  pkt->data[out_size + 2] = avio_r8(pb);
11108  out_size += 3;
11109  src_size -= 2;
11110  }
11111  }
11112 
11113  if (src_size > 0)
11114  /* skip any remaining unread portion of the input payload */
11115  avio_skip(pb, src_size);
11116 
11118  return ret;
11119 }
11120 
11122  int64_t current_index, AVPacket *pkt)
11123 {
11124  MOVStreamContext *sc = st->priv_data;
11125 
11126  pkt->stream_index = sc->ffindex;
11127  pkt->dts = sample->timestamp;
11128  if (sample->flags & AVINDEX_DISCARD_FRAME) {
11130  }
11131  if (sc->stts_count && sc->tts_index < sc->tts_count)
11132  pkt->duration = sc->tts_data[sc->tts_index].duration;
11133  if (sc->ctts_count && sc->tts_index < sc->tts_count) {
11135  } else {
11136  if (pkt->duration == 0) {
11137  int64_t next_dts = (sc->current_sample < ffstream(st)->nb_index_entries) ?
11139  if (next_dts >= pkt->dts)
11140  pkt->duration = next_dts - pkt->dts;
11141  }
11142  pkt->pts = pkt->dts;
11143  }
11144 
11145  if (sc->tts_data && sc->tts_index < sc->tts_count) {
11146  /* update tts context */
11147  sc->tts_sample++;
11148  if (sc->tts_index < sc->tts_count &&
11149  sc->tts_data[sc->tts_index].count == sc->tts_sample) {
11150  sc->tts_index++;
11151  sc->tts_sample = 0;
11152  }
11153  }
11154 
11155  if (sc->sdtp_data && sc->current_sample <= sc->sdtp_count) {
11156  uint8_t sample_flags = sc->sdtp_data[sc->current_sample - 1];
11157  uint8_t sample_is_depended_on = (sample_flags >> 2) & 0x3;
11158  pkt->flags |= sample_is_depended_on == MOV_SAMPLE_DEPENDENCY_NO ? AV_PKT_FLAG_DISPOSABLE : 0;
11159  }
11160  pkt->flags |= sample->flags & AVINDEX_KEYFRAME ? AV_PKT_FLAG_KEY : 0;
11161  pkt->pos = sample->pos;
11162 
11163  /* Multiple stsd handling. */
11164  if (sc->stsc_data) {
11165  if (sc->stsc_data[sc->stsc_index].id > 0 &&
11166  sc->stsc_data[sc->stsc_index].id - 1 < sc->stsd_count &&
11167  sc->stsc_data[sc->stsc_index].id - 1 != sc->last_stsd_index) {
11168  int ret = mov_change_extradata(st, pkt);
11169  if (ret < 0)
11170  return ret;
11171  }
11172 
11173  /* Update the stsc index for the next sample */
11174  sc->stsc_sample++;
11175  if (mov_stsc_index_valid(sc->stsc_index, sc->stsc_count) &&
11176  mov_get_stsc_samples(sc, sc->stsc_index) == sc->stsc_sample) {
11177  sc->stsc_index++;
11178  sc->stsc_sample = 0;
11179  }
11180  }
11181 
11182  return 0;
11183 }
11184 
11186 {
11187  MOVContext *mov = s->priv_data;
11188  MOVStreamContext *sc;
11190  AVStream *st = NULL;
11191  FFStream *avsti = NULL;
11192  int64_t current_index;
11193  int ret;
11194  int i;
11195  mov->fc = s;
11196  retry:
11197  if (s->pb->pos == 0) {
11198 
11199  // Discard current fragment index
11200  if (mov->frag_index.allocated_size > 0) {
11201  for(int i = 0; i < mov->frag_index.nb_items; i++) {
11203  }
11204  av_freep(&mov->frag_index.item);
11205  mov->frag_index.nb_items = 0;
11206  mov->frag_index.allocated_size = 0;
11207  mov->frag_index.current = -1;
11208  mov->frag_index.complete = 0;
11209  }
11210 
11211  for (i = 0; i < s->nb_streams; i++) {
11212  AVStream *avst = s->streams[i];
11213  MOVStreamContext *msc = avst->priv_data;
11214 
11215  // Clear current sample
11216  mov_current_sample_set(msc, 0);
11217  msc->tts_index = 0;
11218 
11219  // Discard current index entries
11220  avsti = ffstream(avst);
11221  if (avsti->index_entries_allocated_size > 0) {
11222  av_freep(&avsti->index_entries);
11223  avsti->index_entries_allocated_size = 0;
11224  avsti->nb_index_entries = 0;
11225  }
11226  }
11227 
11228  if ((ret = mov_switch_root(s, -1, -1)) < 0)
11229  return ret;
11230  }
11231  sample = mov_find_next_sample(s, &st);
11232  if (!sample || (mov->next_root_atom && sample->pos > mov->next_root_atom)) {
11233  if (!mov->next_root_atom)
11234  return AVERROR_EOF;
11235  if ((ret = mov_switch_root(s, mov->next_root_atom, -1)) < 0)
11236  return ret;
11237  goto retry;
11238  }
11239  sc = st->priv_data;
11240  /* must be done just before reading, to avoid infinite loop on sample */
11241  current_index = sc->current_index;
11243 
11244  if (mov->next_root_atom) {
11245  sample->pos = FFMIN(sample->pos, mov->next_root_atom);
11246  sample->size = FFMIN(sample->size, (mov->next_root_atom - sample->pos));
11247  }
11248 
11249  if (st->discard != AVDISCARD_ALL) {
11250  int64_t ret64 = avio_seek(sc->pb, sample->pos, SEEK_SET);
11251  if (ret64 != sample->pos) {
11252  av_log(mov->fc, AV_LOG_ERROR, "stream %d, offset 0x%"PRIx64": partial file\n",
11253  sc->ffindex, sample->pos);
11254  if (should_retry(sc->pb, ret64)) {
11256  } else if (ret64 < 0) {
11257  return (int)ret64;
11258  }
11259  return AVERROR_INVALIDDATA;
11260  }
11261 
11262  if (st->discard == AVDISCARD_NONKEY && !(sample->flags & AVINDEX_KEYFRAME)) {
11263  av_log(mov->fc, AV_LOG_DEBUG, "Nonkey frame from stream %d discarded due to AVDISCARD_NONKEY\n", sc->ffindex);
11264  goto retry;
11265  }
11266 
11267  if (st->codecpar->codec_id == AV_CODEC_ID_EIA_608 && sample->size > 8)
11268  ret = get_eia608_packet(sc->pb, pkt, sample->size);
11269 #if CONFIG_IAMFDEC
11270  else if (sc->iamf) {
11271  int64_t pts, dts, pos, duration;
11272  int flags, size = sample->size;
11273  ret = mov_finalize_packet(s, st, sample, current_index, pkt);
11274  pts = pkt->pts; dts = pkt->dts;
11275  pos = pkt->pos; flags = pkt->flags;
11276  duration = pkt->duration;
11277  while (!ret && size > 0) {
11278  ret = ff_iamf_read_packet(s, sc->iamf, sc->pb, size, sc->iamf_stream_offset, pkt);
11279  if (ret < 0) {
11280  if (should_retry(sc->pb, ret))
11282  return ret;
11283  }
11284  size -= ret;
11285  pkt->pts = pts; pkt->dts = dts;
11286  pkt->pos = pos; pkt->flags |= flags;
11287  pkt->duration = duration;
11288  ret = ff_buffer_packet(s, pkt);
11289  }
11290  if (!ret)
11291  return FFERROR_REDO;
11292  }
11293 #endif
11294  else if (st->codecpar->codec_id == AV_CODEC_ID_APV && sample->size > 4) {
11295  const uint32_t au_size = avio_rb32(sc->pb);
11296  ret = av_get_packet(sc->pb, pkt, au_size);
11297  } else
11298  ret = av_get_packet(sc->pb, pkt, sample->size);
11299  if (ret < 0) {
11300  if (should_retry(sc->pb, ret)) {
11302  }
11303  return ret;
11304  }
11305 #if CONFIG_DV_DEMUXER
11306  if (mov->dv_demux && sc->dv_audio_container) {
11309  if (ret < 0)
11310  return ret;
11312  if (ret < 0)
11313  return ret;
11314  }
11315 #endif
11316  if (sc->has_palette) {
11317  uint8_t *pal;
11318 
11320  if (!pal) {
11321  av_log(mov->fc, AV_LOG_ERROR, "Cannot append palette to packet\n");
11322  } else {
11323  memcpy(pal, sc->palette, AVPALETTE_SIZE);
11324  sc->has_palette = 0;
11325  }
11326  }
11327  if (st->codecpar->codec_id == AV_CODEC_ID_MP3 && !ffstream(st)->need_parsing && pkt->size > 4) {
11328  if (ff_mpa_check_header(AV_RB32(pkt->data)) < 0)
11330  }
11331  }
11332 
11333  ret = mov_finalize_packet(s, st, sample, current_index, pkt);
11334  if (ret < 0)
11335  return ret;
11336 
11337  if (st->discard == AVDISCARD_ALL)
11338  goto retry;
11339 
11340  if (mov->aax_mode)
11341  aax_filter(pkt->data, pkt->size, mov);
11342 
11343  ret = cenc_filter(mov, st, sc, pkt, current_index);
11344  if (ret < 0) {
11345  return ret;
11346  }
11347 
11348  return 0;
11349 }
11350 
11352 {
11353  MOVContext *mov = s->priv_data;
11354  int index;
11355 
11356  if (!mov->frag_index.complete)
11357  return 0;
11358 
11359  index = search_frag_timestamp(s, &mov->frag_index, st, timestamp);
11360  if (index < 0)
11361  index = 0;
11362  if (!mov->frag_index.item[index].headers_read)
11363  return mov_switch_root(s, -1, index);
11364  if (index + 1 < mov->frag_index.nb_items)
11365  mov->next_root_atom = mov->frag_index.item[index + 1].moof_offset;
11366 
11367  return 0;
11368 }
11369 
11370 static int is_open_key_sample(const MOVStreamContext *sc, int sample)
11371 {
11372  // TODO: a bisect search would scale much better
11373  for (int i = 0; i < sc->open_key_samples_count; i++) {
11374  const int oks = sc->open_key_samples[i];
11375  if (oks == sample)
11376  return 1;
11377  if (oks > sample) /* list is monotically increasing so we can stop early */
11378  break;
11379  }
11380  return 0;
11381 }
11382 
11383 /*
11384  * Some key sample may be key frames but not IDR frames, so a random access to
11385  * them may not be allowed.
11386  */
11387 static int can_seek_to_key_sample(AVStream *st, int sample, int64_t requested_pts)
11388 {
11389  MOVStreamContext *sc = st->priv_data;
11390  FFStream *const sti = ffstream(st);
11391  int64_t key_sample_dts, key_sample_pts;
11392 
11393  if (st->codecpar->codec_id != AV_CODEC_ID_HEVC)
11394  return 1;
11395 
11396  if (sample >= sc->sample_offsets_count)
11397  return 1;
11398 
11399  key_sample_dts = sti->index_entries[sample].timestamp;
11400  key_sample_pts = key_sample_dts + sc->sample_offsets[sample] + sc->dts_shift;
11401 
11402  /*
11403  * If the sample needs to be presented before an open key sample, they may
11404  * not be decodable properly, even though they come after in decoding
11405  * order.
11406  */
11407  if (is_open_key_sample(sc, sample) && key_sample_pts > requested_pts)
11408  return 0;
11409 
11410  return 1;
11411 }
11412 
11413 static int mov_seek_stream(AVFormatContext *s, AVStream *st, int64_t timestamp, int flags)
11414 {
11415  MOVStreamContext *sc = st->priv_data;
11416  FFStream *const sti = ffstream(st);
11417  int sample, time_sample, ret, requested_sample;
11418  int64_t next_ts;
11419  unsigned int i;
11420 
11421  // Here we consider timestamp to be PTS, hence try to offset it so that we
11422  // can search over the DTS timeline.
11423  timestamp -= (sc->min_corrected_pts + sc->dts_shift);
11424 
11425  ret = mov_seek_fragment(s, st, timestamp);
11426  if (ret < 0)
11427  return ret;
11428 
11429  for (;;) {
11430  sample = av_index_search_timestamp(st, timestamp, flags);
11431  av_log(s, AV_LOG_TRACE, "stream %d, timestamp %"PRId64", sample %d\n", st->index, timestamp, sample);
11432  if (sample < 0 && sti->nb_index_entries && timestamp < sti->index_entries[0].timestamp)
11433  sample = 0;
11434  if (sample < 0) /* not sure what to do */
11435  return AVERROR_INVALIDDATA;
11436 
11437  if (!sample || can_seek_to_key_sample(st, sample, timestamp))
11438  break;
11439 
11440  next_ts = timestamp - FFMAX(sc->min_sample_duration, 1);
11441  requested_sample = av_index_search_timestamp(st, next_ts, flags);
11442 
11443  // If we've reached a different sample trying to find a good pts to
11444  // seek to, give up searching because we'll end up seeking back to
11445  // sample 0 on every seek.
11446  if (sample != requested_sample && !can_seek_to_key_sample(st, requested_sample, next_ts))
11447  break;
11448 
11449  timestamp = next_ts;
11450  }
11451 
11453  av_log(s, AV_LOG_TRACE, "stream %d, found sample %d\n", st->index, sc->current_sample);
11454  /* adjust time to sample index */
11455  if (sc->tts_data) {
11456  time_sample = 0;
11457  for (i = 0; i < sc->tts_count; i++) {
11458  int next = time_sample + sc->tts_data[i].count;
11459  if (next > sc->current_sample) {
11460  sc->tts_index = i;
11461  sc->tts_sample = sc->current_sample - time_sample;
11462  break;
11463  }
11464  time_sample = next;
11465  }
11466  }
11467 
11468  /* adjust stsd index */
11469  if (sc->chunk_count) {
11470  time_sample = 0;
11471  for (i = 0; i < sc->stsc_count; i++) {
11472  int64_t next = time_sample + mov_get_stsc_samples(sc, i);
11473  if (next > sc->current_sample) {
11474  sc->stsc_index = i;
11475  sc->stsc_sample = sc->current_sample - time_sample;
11476  break;
11477  }
11478  av_assert0(next == (int)next);
11479  time_sample = next;
11480  }
11481  }
11482 
11483  return sample;
11484 }
11485 
11487 {
11488  MOVStreamContext *sc = st->priv_data;
11489  FFStream *const sti = ffstream(st);
11490  int64_t first_ts = sti->index_entries[0].timestamp;
11492  int64_t off;
11493 
11495  return 0;
11496 
11497  /* compute skip samples according to stream start_pad, seek ts and first ts */
11498  off = av_rescale_q(ts - first_ts, st->time_base,
11499  (AVRational){1, st->codecpar->sample_rate});
11500  return FFMAX(sc->start_pad - off, 0);
11501 }
11502 
11503 static int mov_read_seek(AVFormatContext *s, int stream_index, int64_t sample_time, int flags)
11504 {
11505  MOVContext *mc = s->priv_data;
11506  AVStream *st;
11507  FFStream *sti;
11508  int sample;
11509  int i;
11510 
11511  if (stream_index >= s->nb_streams)
11512  return AVERROR_INVALIDDATA;
11513 
11514  st = s->streams[stream_index];
11515  sti = ffstream(st);
11516  sample = mov_seek_stream(s, st, sample_time, flags);
11517  if (sample < 0)
11518  return sample;
11519 
11520  if (mc->seek_individually) {
11521  /* adjust seek timestamp to found sample timestamp */
11522  int64_t seek_timestamp = sti->index_entries[sample].timestamp;
11524 
11525  for (i = 0; i < s->nb_streams; i++) {
11526  AVStream *const st = s->streams[i];
11527  FFStream *const sti = ffstream(st);
11528  int64_t timestamp;
11529 
11530  if (stream_index == i)
11531  continue;
11532 
11533  timestamp = av_rescale_q(seek_timestamp, s->streams[stream_index]->time_base, st->time_base);
11534  sample = mov_seek_stream(s, st, timestamp, flags);
11535  if (sample >= 0)
11537  }
11538  } else {
11539  for (i = 0; i < s->nb_streams; i++) {
11540  MOVStreamContext *sc;
11541  st = s->streams[i];
11542  sc = st->priv_data;
11543  mov_current_sample_set(sc, 0);
11544  }
11545  while (1) {
11546  MOVStreamContext *sc;
11548  if (!entry)
11549  return AVERROR_INVALIDDATA;
11550  sc = st->priv_data;
11551  if (sc->ffindex == stream_index && sc->current_sample == sample)
11552  break;
11554  }
11555  }
11556  return 0;
11557 }
11558 
11559 #define OFFSET(x) offsetof(MOVContext, x)
11560 #define FLAGS AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM
11561 static const AVOption mov_options[] = {
11562  {"use_absolute_path",
11563  "allow using absolute path when opening alias, this is a possible security issue",
11564  OFFSET(use_absolute_path), AV_OPT_TYPE_BOOL, {.i64 = 0},
11565  0, 1, FLAGS},
11566  {"seek_streams_individually",
11567  "Seek each stream individually to the closest point",
11568  OFFSET(seek_individually), AV_OPT_TYPE_BOOL, { .i64 = 1 },
11569  0, 1, FLAGS},
11570  {"ignore_editlist", "Ignore the edit list atom.", OFFSET(ignore_editlist), AV_OPT_TYPE_BOOL, {.i64 = 0},
11571  0, 1, FLAGS},
11572  {"advanced_editlist",
11573  "Modify the AVIndex according to the editlists. Use this option to decode in the order specified by the edits.",
11574  OFFSET(advanced_editlist), AV_OPT_TYPE_BOOL, {.i64 = 1},
11575  0, 1, FLAGS},
11576  {"ignore_chapters", "", OFFSET(ignore_chapters), AV_OPT_TYPE_BOOL, {.i64 = 0},
11577  0, 1, FLAGS},
11578  {"use_mfra_for",
11579  "use mfra for fragment timestamps",
11580  OFFSET(use_mfra_for), AV_OPT_TYPE_INT, {.i64 = FF_MOV_FLAG_MFRA_AUTO},
11582  .unit = "use_mfra_for"},
11583  {"auto", "auto", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_AUTO}, 0, 0,
11584  FLAGS, .unit = "use_mfra_for" },
11585  {"dts", "dts", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_DTS}, 0, 0,
11586  FLAGS, .unit = "use_mfra_for" },
11587  {"pts", "pts", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_PTS}, 0, 0,
11588  FLAGS, .unit = "use_mfra_for" },
11589  {"use_tfdt", "use tfdt for fragment timestamps", OFFSET(use_tfdt), AV_OPT_TYPE_BOOL, {.i64 = 1},
11590  0, 1, FLAGS},
11591  { "export_all", "Export unrecognized metadata entries", OFFSET(export_all),
11592  AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = FLAGS },
11593  { "export_xmp", "Export full XMP metadata", OFFSET(export_xmp),
11594  AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = FLAGS },
11595  { "activation_bytes", "Secret bytes for Audible AAX files", OFFSET(activation_bytes),
11597  { "audible_key", "AES-128 Key for Audible AAXC files", OFFSET(audible_key),
11599  { "audible_iv", "AES-128 IV for Audible AAXC files", OFFSET(audible_iv),
11601  { "audible_fixed_key", // extracted from libAAX_SDK.so and AAXSDKWin.dll files!
11602  "Fixed key used for handling Audible AAX files", OFFSET(audible_fixed_key),
11603  AV_OPT_TYPE_BINARY, {.str="77214d4b196a87cd520045fd20a51d67"},
11604  .flags = AV_OPT_FLAG_DECODING_PARAM },
11605  { "decryption_key", "The media decryption key (hex)", OFFSET(decryption_key), AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM },
11606  { "enable_drefs", "Enable external track support.", OFFSET(enable_drefs), AV_OPT_TYPE_BOOL,
11607  {.i64 = 0}, 0, 1, FLAGS },
11608  { "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 },
11609  { "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 },
11610 
11611  { NULL },
11612 };
11613 
11614 static const AVClass mov_class = {
11615  .class_name = "mov,mp4,m4a,3gp,3g2,mj2",
11616  .item_name = av_default_item_name,
11617  .option = mov_options,
11618  .version = LIBAVUTIL_VERSION_INT,
11619 };
11620 
11622  .p.name = "mov,mp4,m4a,3gp,3g2,mj2",
11623  .p.long_name = NULL_IF_CONFIG_SMALL("QuickTime / MOV"),
11624  .p.priv_class = &mov_class,
11625  .p.extensions = "mov,mp4,m4a,3gp,3g2,mj2,psp,m4b,ism,ismv,isma,f4v,avif,heic,heif",
11627  .priv_data_size = sizeof(MOVContext),
11628  .flags_internal = FF_INFMT_FLAG_INIT_CLEANUP,
11629  .read_probe = mov_probe,
11634 };
HEIFItemRef::item_id
int item_id
Definition: isom.h:291
avpriv_new_chapter
AVChapter * avpriv_new_chapter(AVFormatContext *s, int64_t id, AVRational time_base, int64_t start, int64_t end, const char *title)
Add a new chapter.
Definition: demux_utils.c:43
MOVStreamContext::ctts_allocated_size
unsigned int ctts_allocated_size
Definition: isom.h:191
item_name
item_name
Definition: libkvazaar.c:311
AV_CODEC_ID_PCM_S16LE
@ AV_CODEC_ID_PCM_S16LE
Definition: codec_id.h:337
flags
const SwsFlags flags[]
Definition: swscale.c:61
AV_EXIF_T_OFF
@ AV_EXIF_T_OFF
The first four bytes point to the actual start, then it's AV_EXIF_TIFF_HEADER.
Definition: exif.h:69
mov_finalize_stsd_entry
static int mov_finalize_stsd_entry(MOVContext *c, AVStream *st)
Definition: mov.c:3035
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:7375
mov_read_meta
static int mov_read_meta(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5485
AV_CODEC_ID_EIA_608
@ AV_CODEC_ID_EIA_608
Definition: codec_id.h:581
AV_PKT_DATA_DISPLAYMATRIX
@ AV_PKT_DATA_DISPLAYMATRIX
This side data contains a 3x3 transformation matrix describing an affine transformation that needs to...
Definition: packet.h:105
av_packet_unref
void av_packet_unref(AVPacket *pkt)
Wipe the packet.
Definition: packet.c:432
MOVContext::found_iloc
int found_iloc
'iloc' atom has been found
Definition: isom.h:327
AV_CODEC_ID_MACE6
@ AV_CODEC_ID_MACE6
Definition: codec_id.h:469
MOVFragmentStreamInfo::first_tfra_pts
int64_t first_tfra_pts
Definition: isom.h:142
ff_rfps_add_frame
int ff_rfps_add_frame(AVFormatContext *ic, AVStream *st, int64_t ts)
add frame for rfps calculation.
Definition: demux.c:2306
read_image_iovl
static int read_image_iovl(AVFormatContext *s, const HEIFGrid *grid, AVStreamGroupTileGrid *tile_grid)
Definition: mov.c:10270
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:9206
AVMEDIA_TYPE_SUBTITLE
@ AVMEDIA_TYPE_SUBTITLE
Definition: avutil.h:203
AVIAMFSubmix::elements
AVIAMFSubmixElement ** elements
Array of submix elements.
Definition: iamf.h:565
skip_bits_long
static void skip_bits_long(GetBitContext *s, int n)
Skips the specified number of bits.
Definition: get_bits.h:280
AV_LOG_WARNING
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:216
AV_BPRINT_SIZE_UNLIMITED
#define AV_BPRINT_SIZE_UNLIMITED
MOV_TFHD_DEFAULT_FLAGS
#define MOV_TFHD_DEFAULT_FLAGS
Definition: isom.h:406
PUT_UTF8
#define PUT_UTF8(val, tmp, PUT_BYTE)
Definition: common.h:541
AV_TIMECODE_STR_SIZE
#define AV_TIMECODE_STR_SIZE
Definition: timecode.h:33
av_aes_init
int av_aes_init(AVAES *a, const uint8_t *key, int key_bits, int decrypt)
Initialize an AVAES context.
Definition: aes.c:231
AV_CODEC_ID_PCM_F32BE
@ AV_CODEC_ID_PCM_F32BE
Definition: codec_id.h:357
FFStream::skip_samples
int skip_samples
Number of samples to skip at the start of the frame decoded from the next packet.
Definition: internal.h:208
MOVStreamContext::audio_cid
int16_t audio_cid
stsd audio compression id
Definition: isom.h:221
AVMasteringDisplayMetadata::max_luminance
AVRational max_luminance
Max luminance of mastering display (cd/m^2).
Definition: mastering_display_metadata.h:57
AVSphericalProjection
AVSphericalProjection
Projection of the video surface(s) on a sphere.
Definition: spherical.h:47
AV_CODEC_ID_ADPCM_MS
@ AV_CODEC_ID_ADPCM_MS
Definition: codec_id.h:382
AVCodecParameters::extradata
uint8_t * extradata
Extra binary data needed for initializing the decoder, codec-dependent.
Definition: codec_par.h:69
mov_read_dops
static int mov_read_dops(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:8442
can_seek_to_key_sample
static int can_seek_to_key_sample(AVStream *st, int sample, int64_t requested_pts)
Definition: mov.c:11387
AV_CODEC_ID_ADPCM_IMA_QT
@ AV_CODEC_ID_ADPCM_IMA_QT
Definition: codec_id.h:376
entry
#define entry
Definition: aom_film_grain_template.c:66
AVFMT_NO_BYTE_SEEK
#define AVFMT_NO_BYTE_SEEK
Format does not allow seeking by bytes.
Definition: avformat.h:486
AV_EF_EXPLODE
#define AV_EF_EXPLODE
abort decoding on minor error detection
Definition: defs.h:51
AVStreamGroup::id
int64_t id
Group type-specific group ID.
Definition: avformat.h:1117
AV_CODEC_ID_AC3
@ AV_CODEC_ID_AC3
Definition: codec_id.h:462
HEIFItem::name
char * name
Definition: isom.h:298
AV_STEREO3D_VIEW_LEFT
@ AV_STEREO3D_VIEW_LEFT
Frame contains only the left view.
Definition: stereo3d.h:158
MOVStreamContext::sync_group
MOVSbgp * sync_group
Definition: isom.h:243
MOVStreamContext::height
int height
tkhd height
Definition: isom.h:229
MOVContext::moov_retry
int moov_retry
Definition: isom.h:355
MOV_TRUN_SAMPLE_FLAGS
#define MOV_TRUN_SAMPLE_FLAGS
Definition: isom.h:414
MOVStreamContext::cenc
struct MOVStreamContext::@451 cenc
AV_PKT_DATA_AMBIENT_VIEWING_ENVIRONMENT
@ AV_PKT_DATA_AMBIENT_VIEWING_ENVIRONMENT
Ambient viewing environment metadata, as defined by H.274.
Definition: packet.h:327
MOVContext::nb_chapter_tracks
unsigned int nb_chapter_tracks
Definition: isom.h:343
mix
static int mix(int c0, int c1)
Definition: 4xm.c:717
MOVStreamContext::last_stsd_index
int last_stsd_index
Definition: isom.h:258
ff_ac3_channel_layout_tab
const uint16_t ff_ac3_channel_layout_tab[8]
Map audio coding mode (acmod) to channel layout mask.
Definition: ac3_channel_layout_tab.h:31
r
const char * r
Definition: vf_curves.c:127
AVERROR
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later. That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another. Frame references ownership and permissions
opt.h
get_heif_item
static HEIFItem * get_heif_item(MOVContext *c, unsigned id)
Get the requested item.
Definition: mov.c:194
MOV_TKHD_FLAG_ENABLED
#define MOV_TKHD_FLAG_ENABLED
Definition: isom.h:427
AVCodecParameters::codec_type
enum AVMediaType codec_type
General type of the encoded data.
Definition: codec_par.h:51
AVStreamGroup::tile_grid
struct AVStreamGroupTileGrid * tile_grid
Definition: avformat.h:1133
AVFMT_SHOW_IDS
#define AVFMT_SHOW_IDS
Show format stream IDs numbers.
Definition: avformat.h:476
AVSphericalMapping::projection
enum AVSphericalProjection projection
Projection type.
Definition: spherical.h:104
AV_WL32
#define AV_WL32(p, v)
Definition: intreadwrite.h:422
av_exif_parse_buffer
int av_exif_parse_buffer(void *logctx, const uint8_t *buf, size_t size, AVExifMetadata *ifd, enum AVExifHeaderMode header_mode)
Decodes the EXIF data provided in the buffer and writes it into the struct *ifd.
Definition: exif.c:767
AV_STREAM_GROUP_PARAMS_LCEVC
@ AV_STREAM_GROUP_PARAMS_LCEVC
Definition: avformat.h:1092
MOVStreamContext::extradata
uint8_t ** extradata
extradata array (and size) for multiple stsd
Definition: isom.h:256
mov_class
static const AVClass mov_class
Definition: mov.c:11614
AVSphericalMapping::bound_bottom
uint32_t bound_bottom
Distance from the bottom edge.
Definition: spherical.h:188
MOVStreamContext::open_key_samples
int * open_key_samples
Definition: isom.h:248
AVUUID
uint8_t AVUUID[AV_UUID_LEN]
Definition: uuid.h:60
out
FILE * out
Definition: movenc.c:55
MOVFragmentStreamInfo
Definition: isom.h:139
AVFieldOrder
AVFieldOrder
Definition: defs.h:211
mov_read_targa_y216
static int mov_read_targa_y216(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2280
mov_read_chnl
static int mov_read_chnl(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1193
mov_read_moof
static int mov_read_moof(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1817
av_bprint_init
void av_bprint_init(AVBPrint *buf, unsigned size_init, unsigned size_max)
Definition: bprint.c:69
ctype
#define ctype
Definition: afir_template.c:46
AV_PKT_DATA_FRAME_CROPPING
@ AV_PKT_DATA_FRAME_CROPPING
The number of pixels to discard from the top/bottom/left/right border of the decoded frame to obtain ...
Definition: packet.h:340
av_exif_write
int av_exif_write(void *logctx, const AVExifMetadata *ifd, AVBufferRef **buffer, enum AVExifHeaderMode header_mode)
Allocates a buffer using av_malloc of an appropriate size and writes the EXIF data represented by ifd...
Definition: exif.c:706
AVCodecParameters
This struct describes the properties of an encoded stream.
Definition: codec_par.h:47
HEIFItem::icc_profile
uint8_t * icc_profile
Definition: isom.h:309
AVFMT_FLAG_IGNIDX
#define AVFMT_FLAG_IGNIDX
Ignore index.
Definition: avformat.h:1417
AVExifMetadata
Definition: exif.h:76
sanity_checks
static int sanity_checks(void *log_obj, MOVStreamContext *sc, int index)
Definition: mov.c:5119
av_stristr
char * av_stristr(const char *s1, const char *s2)
Locate the first case-independent occurrence in the string haystack of the string needle.
Definition: avstring.c:58
AVCodecParameters::color_space
enum AVColorSpace color_space
Definition: codec_par.h:169
avformat_new_stream
AVStream * avformat_new_stream(AVFormatContext *s, const struct AVCodec *c)
Add a new stream to a media file.
ff_replaygain_export
int ff_replaygain_export(AVStream *st, AVDictionary *metadata)
Parse replaygain tags and export them as per-stream side data.
Definition: replaygain.c:94
tmcd_is_referenced
static int tmcd_is_referenced(AVFormatContext *s, int tmcd_id)
Definition: mov.c:10016
HEIFItem::hflip
int hflip
Definition: isom.h:305
AV_PKT_DATA_NEW_EXTRADATA
@ AV_PKT_DATA_NEW_EXTRADATA
The AV_PKT_DATA_NEW_EXTRADATA is used to notify the codec or the format that the extradata buffer was...
Definition: packet.h:56
IAMFAudioElement::nb_substreams
unsigned int nb_substreams
Definition: iamf.h:99
AVStream::priv_data
void * priv_data
Definition: avformat.h:769
AVERROR_EOF
#define AVERROR_EOF
End of file.
Definition: error.h:57
AVBufferRef::data
uint8_t * data
The data buffer.
Definition: buffer.h:90
AV_DISPOSITION_ATTACHED_PIC
#define AV_DISPOSITION_ATTACHED_PIC
The stream is stored in the file as an attached picture/"cover art" (e.g.
Definition: avformat.h:670
AVStream::discard
enum AVDiscard discard
Selects which packets can be discarded at will and do not need to be demuxed.
Definition: avformat.h:815
AV_FIELD_PROGRESSIVE
@ AV_FIELD_PROGRESSIVE
Definition: defs.h:213
mov_options
static const AVOption mov_options[]
Definition: mov.c:11561
mov_codec_id
static int mov_codec_id(AVStream *st, uint32_t format)
Definition: mov.c:2629
AV_PKT_DATA_MASTERING_DISPLAY_METADATA
@ AV_PKT_DATA_MASTERING_DISPLAY_METADATA
Mastering display metadata (based on SMPTE-2086:2014).
Definition: packet.h:219
MOVStreamContext::sample_offsets
int32_t * sample_offsets
Definition: isom.h:246
av_int2double
static av_always_inline double av_int2double(uint64_t i)
Reinterpret a 64-bit integer as a double.
Definition: intfloat.h:60
mov_read_iloc
static int mov_read_iloc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:8833
matrix
Definition: vc1dsp.c:43
AVMasteringDisplayMetadata::display_primaries
AVRational display_primaries[3][2]
CIE 1931 xy chromaticity coords of color primaries (r, g, b order).
Definition: mastering_display_metadata.h:42
AV_PKT_FLAG_DISCARD
#define AV_PKT_FLAG_DISCARD
Flag is used to discard packets which are required to maintain valid decoder state but are not requir...
Definition: packet.h:650
AVMasteringDisplayMetadata::has_luminance
int has_luminance
Flag indicating whether the luminance (min_ and max_) have been set.
Definition: mastering_display_metadata.h:67
get_bits_long
static unsigned int get_bits_long(GetBitContext *s, int n)
Read 0-32 bits.
Definition: get_bits.h:424
int64_t
long long int64_t
Definition: coverity.c:34
output
filter_frame For filters that do not use the this method is called when a frame is pushed to the filter s input It can be called at any time except in a reentrant way If the input frame is enough to produce output
Definition: filter_design.txt:226
mov_read_alac
static int mov_read_alac(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2252
test_same_origin
static int test_same_origin(const char *src, const char *ref)
Definition: mov.c:4962
cbcs_scheme_decrypt
static int cbcs_scheme_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
Definition: mov.c:8265
MOVFragment::base_data_offset
uint64_t base_data_offset
Definition: isom.h:104
MOVStreamContext
Definition: isom.h:173
AVChannelLayout::map
AVChannelCustom * map
This member must be used when the channel order is AV_CHANNEL_ORDER_CUSTOM.
Definition: channel_layout.h:370
MOVStreamContext::stsc_data
MOVStsc * stsc_data
Definition: isom.h:194
ff_buffer_packet
int ff_buffer_packet(AVFormatContext *s, AVPacket *pkt)
Definition: demux.c:612
IS_MATRIX_IDENT
#define IS_MATRIX_IDENT(matrix)
Definition: mov.c:5503
AVStreamGroup::disposition
int disposition
Stream group disposition - a combination of AV_DISPOSITION_* flags.
Definition: avformat.h:1175
av_unused
#define av_unused
Definition: attributes.h:151
AV_DISPOSITION_DEFAULT
#define AV_DISPOSITION_DEFAULT
The stream should be chosen by default among other streams of the same type, unless the user has expl...
Definition: avformat.h:617
mov_update_dts_shift
static void mov_update_dts_shift(MOVStreamContext *sc, int duration, void *logctx)
Definition: mov.c:3666
MOVStreamContext::spherical
AVSphericalMapping * spherical
Definition: isom.h:265
mask
int mask
Definition: mediacodecdec_common.c:154
out_size
int out_size
Definition: movenc.c:56
AV_CODEC_ID_MPEG4
@ AV_CODEC_ID_MPEG4
Definition: codec_id.h:64
AVContentLightMetadata::MaxCLL
unsigned MaxCLL
Max content light level (cd/m^2).
Definition: mastering_display_metadata.h:111
avio_get_str16be
int avio_get_str16be(AVIOContext *pb, int maxlen, char *buf, int buflen)
MOVEncryptionIndex
Definition: isom.h:126
av_encryption_init_info_free
void av_encryption_init_info_free(AVEncryptionInitInfo *info)
Frees the given encryption init info object.
Definition: encryption_info.c:216
mov_read_avss
static int mov_read_avss(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2257
AV_RB32A
#define AV_RB32A(p)
Definition: intreadwrite.h:575
MOVContext::primary_item_id
int primary_item_id
Definition: isom.h:380
mode
Definition: swscale.c:56
MOVContext::found_moov
int found_moov
'moov' atom has been found
Definition: isom.h:326
ff_iamf_read_packet
int ff_iamf_read_packet(AVFormatContext *s, IAMFDemuxContext *c, AVIOContext *pb, int max_size, int stream_id_offset, AVPacket *pkt)
Definition: iamf_reader.c:279
mov_read_custom
static int mov_read_custom(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5345
pixdesc.h
cleanup
static av_cold void cleanup(FlashSV2Context *s)
Definition: flashsv2enc.c:130
AVFormatContext::streams
AVStream ** streams
A list of all streams in the file.
Definition: avformat.h:1332
HEIFGrid::nb_tiles
int nb_tiles
Definition: isom.h:318
ID3v1_GENRE_MAX
#define ID3v1_GENRE_MAX
Definition: id3v1.h:29
MOVSbgp
Definition: isom.h:121
MOVCtts
Definition: isom.h:68
AVPacketSideData
This structure stores auxiliary information for decoding, presenting, or otherwise processing the cod...
Definition: packet.h:409
mov_read_extradata
static int mov_read_extradata(MOVContext *c, AVIOContext *pb, MOVAtom atom, enum AVCodecID codec_id)
Definition: mov.c:2226
AVCOL_RANGE_JPEG
@ AVCOL_RANGE_JPEG
Full range content.
Definition: pixfmt.h:777
mpegaudiodecheader.h
MOVStreamContext::rap_group_count
unsigned int rap_group_count
Definition: isom.h:240
av_display_matrix_flip
void av_display_matrix_flip(int32_t matrix[9], int hflip, int vflip)
Flip the input matrix horizontally and/or vertically.
Definition: display.c:66
av_sha_init
av_cold int av_sha_init(AVSHA *ctx, int bits)
Initialize SHA-1 or SHA-2 hashing.
Definition: sha.c:274
HEIFItem::type
int type
Definition: isom.h:307
mov_read_mvhd
static int mov_read_mvhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1919
mov_read_idat
static int mov_read_idat(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:8827
AVPacket::data
uint8_t * data
Definition: packet.h:588
MOVContext::found_mdat
int found_mdat
'mdat' atom has been found
Definition: isom.h:329
MOVStreamContext::drefs_count
unsigned drefs_count
Definition: isom.h:222
AVEncryptionInfo::crypt_byte_block
uint32_t crypt_byte_block
Only used for pattern encryption.
Definition: encryption_info.h:51
AV_PKT_DATA_ENCRYPTION_INIT_INFO
@ AV_PKT_DATA_ENCRYPTION_INIT_INFO
This side data is encryption initialization data.
Definition: packet.h:246
mov_read_avid
static int mov_read_avid(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2272
AVAmbientViewingEnvironment::ambient_light_x
AVRational ambient_light_x
Normalized x chromaticity coordinate of the environmental ambient light in the nominal viewing enviro...
Definition: ambient_viewing_environment.h:47
AVCodecParameters::seek_preroll
int seek_preroll
Audio only.
Definition: codec_par.h:214
av_dynarray2_add
void * av_dynarray2_add(void **tab_ptr, int *nb_ptr, size_t elem_size, const uint8_t *elem_data)
Add an element of size elem_size to a dynamic array.
Definition: mem.c:343
AVOption
AVOption.
Definition: opt.h:429
MOVContext::trex_data
MOVTrackExt * trex_data
Definition: isom.h:338
mov_read_stps
static int mov_read_stps(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:3323
MOVContext::bitrates
int * bitrates
bitrates read before streams creation
Definition: isom.h:353
b
#define b
Definition: input.c:42
AVCOL_TRC_UNSPECIFIED
@ AVCOL_TRC_UNSPECIFIED
Definition: pixfmt.h:669
MOVContext::interleaved_read
int interleaved_read
Definition: isom.h:387
mov_read_tkhd
static int mov_read_tkhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5511
MOVElst::rate
float rate
Definition: isom.h:82
AVStream::avg_frame_rate
AVRational avg_frame_rate
Average framerate.
Definition: avformat.h:833
table
static const uint16_t table[]
Definition: prosumer.c:203
spherical.h
mov_read_colr
static int mov_read_colr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2073
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:1958
mov_read_strf
static int mov_read_strf(MOVContext *c, AVIOContext *pb, MOVAtom atom)
An strf atom is a BITMAPINFOHEADER struct.
Definition: mov.c:2542
AV_CODEC_ID_ALAC
@ AV_CODEC_ID_ALAC
Definition: codec_id.h:475
HEIFItem::st
AVStream * st
Definition: isom.h:295
FF_COMPLIANCE_STRICT
#define FF_COMPLIANCE_STRICT
Strictly conform to all the things in the spec no matter what consequences.
Definition: defs.h:59
AVIOContext::error
int error
contains the error code or 0 if no error happened
Definition: avio.h:239
AV_CODEC_ID_AMR_NB
@ AV_CODEC_ID_AMR_NB
Definition: codec_id.h:440
av_iamf_mix_presentation_free
void av_iamf_mix_presentation_free(AVIAMFMixPresentation **pmix_presentation)
Free an AVIAMFMixPresentation and all its contents.
Definition: iamf.c:534
mov_parse_auxiliary_info
static int mov_parse_auxiliary_info(MOVContext *c, MOVStreamContext *sc, AVIOContext *pb, MOVEncryptionIndex *encryption_index)
Definition: mov.c:7583
mov_seek_stream
static int mov_seek_stream(AVFormatContext *s, AVStream *st, int64_t timestamp, int flags)
Definition: mov.c:11413
mov_read_saio
static int mov_read_saio(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:7729
mov_get_stsc_samples
static int64_t mov_get_stsc_samples(MOVStreamContext *sc, unsigned int index)
Definition: mov.c:3308
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:3875
MOVFragmentIndexItem::moof_offset
int64_t moof_offset
Definition: isom.h:153
MOVStreamContext::spherical_size
size_t spherical_size
Definition: isom.h:266
mov_change_extradata
static int mov_change_extradata(AVStream *st, AVPacket *pkt)
Definition: mov.c:11028
HEIFItemRef
Definition: isom.h:289
MOVStreamContext::tref_id
int tref_id
Definition: isom.h:226
MP4TrackKindMapping::scheme_uri
const char * scheme_uri
Definition: isom.h:489
AVINDEX_DISCARD_FRAME
#define AVINDEX_DISCARD_FRAME
Definition: avformat.h:607
av_display_rotation_set
void av_display_rotation_set(int32_t matrix[9], double angle)
Initialize a transformation matrix describing a pure clockwise rotation by the specified angle (in de...
Definition: display.c:51
AVPacket::duration
int64_t duration
Duration of this packet in AVStream->time_base units, 0 if unknown.
Definition: packet.h:606
AVCodecParameters::codec_tag
uint32_t codec_tag
Additional information about the codec (corresponds to the AVI FOURCC).
Definition: codec_par.h:59
fixed_key
static const uint8_t fixed_key[]
Definition: aes_ctr.c:45
AV_SPHERICAL_EQUIRECTANGULAR_TILE
@ AV_SPHERICAL_EQUIRECTANGULAR_TILE
Video represents a portion of a sphere mapped on a flat surface using equirectangular projection.
Definition: spherical.h:68
AVStereo3D::baseline
uint32_t baseline
The distance between the centres of the lenses of the camera system, in micrometers.
Definition: stereo3d.h:228
MOVDref::dir
char * dir
Definition: isom.h:88
mov_current_sample_set
static void mov_current_sample_set(MOVStreamContext *sc, int current_sample)
Definition: mov.c:4179
mathematics.h
AVDictionary
Definition: dict.c:32
ffio_init_read_context
void ffio_init_read_context(FFIOContext *s, const uint8_t *buffer, int buffer_size)
Wrap a buffer in an AVIOContext for reading.
Definition: aviobuf.c:99
AV_PKT_FLAG_DISPOSABLE
#define AV_PKT_FLAG_DISPOSABLE
Flag is used to indicate packets that contain frames that can be discarded by the decoder.
Definition: packet.h:662
AVChannelLayout::order
enum AVChannelOrder order
Channel order used in this layout.
Definition: channel_layout.h:324
FFMAX
#define FFMAX(a, b)
Definition: macros.h:47
MOVAtom
Definition: isom.h:94
AVStreamGroupTileGrid::vertical
int vertical
Offset in pixels from the top edge of the canvas where the tile should be placed.
Definition: avformat.h:1000
iamf_parse.h
mov_read_moov
static int mov_read_moov(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1569
av_sub_q
AVRational av_sub_q(AVRational b, AVRational c)
Subtract one rational from another.
Definition: rational.c:101
cffstream
static const av_always_inline FFStream * cffstream(const AVStream *st)
Definition: internal.h:352
mov_read_esds
static int mov_read_esds(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:848
MOVStreamContext::sample_count
unsigned int sample_count
Definition: isom.h:205
MOVFragmentIndex::allocated_size
int allocated_size
Definition: isom.h:161
MOVTrackExt::flags
unsigned flags
Definition: isom.h:118
AVChannelLayout::nb_channels
int nb_channels
Number of channels in this layout.
Definition: channel_layout.h:329
HEIFItem::height
int height
Definition: isom.h:303
AV_SPHERICAL_EQUIRECTANGULAR
@ AV_SPHERICAL_EQUIRECTANGULAR
Video represents a sphere mapped on a flat surface using equirectangular projection.
Definition: spherical.h:52
intfloat.h
id3v1.h
MOVStreamContext::ctts_data
MOVCtts * ctts_data
Definition: isom.h:192
ff_dvdclut_yuv_to_rgb
int ff_dvdclut_yuv_to_rgb(uint32_t *clut, const size_t clut_size)
Definition: dvdclut.c:50
AV_CODEC_ID_R10K
@ AV_CODEC_ID_R10K
Definition: codec_id.h:197
av_encryption_init_info_get_side_data
AVEncryptionInitInfo * av_encryption_init_info_get_side_data(const uint8_t *side_data, size_t side_data_size)
Creates a copy of the AVEncryptionInitInfo that is contained in the given side data.
Definition: encryption_info.c:231
AV_STEREO3D_VIEW_RIGHT
@ AV_STEREO3D_VIEW_RIGHT
Frame contains only the right view.
Definition: stereo3d.h:163
MOVContext::advanced_editlist_autodisabled
int advanced_editlist_autodisabled
Definition: isom.h:347
avio_size
int64_t avio_size(AVIOContext *s)
Get the filesize.
Definition: aviobuf.c:326
av_strlcatf
size_t av_strlcatf(char *dst, size_t size, const char *fmt,...)
Definition: avstring.c:103
mov_read_stco
static int mov_read_stco(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2564
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:7094
FFIOContext
Definition: avio_internal.h:28
AV_PKT_FLAG_KEY
#define AV_PKT_FLAG_KEY
The packet contains a keyframe.
Definition: packet.h:643
init_get_bits
static int init_get_bits(GetBitContext *s, const uint8_t *buffer, int bit_size)
Initialize GetBitContext.
Definition: get_bits.h:517
MOVStreamContext::aes_ctr
struct AVAESCTR * aes_ctr
Definition: isom.h:278
cenc_filter
static int cenc_filter(MOVContext *mov, AVStream *st, MOVStreamContext *sc, AVPacket *pkt, int current_index)
Definition: mov.c:8372
mov_read_sdtp
static int mov_read_sdtp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:3632
mov_read_jp2h
static int mov_read_jp2h(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2262
AV_STEREO3D_UNSPEC
@ AV_STEREO3D_UNSPEC
Video is stereoscopic but the packing is unspecified.
Definition: stereo3d.h:143
AVIndexEntry
Definition: avformat.h:598
AV_WB64
#define AV_WB64(p, v)
Definition: intreadwrite.h:429
MOVStreamContext::dv_audio_container
int dv_audio_container
Definition: isom.h:219
AV_CODEC_ID_AMR_WB
@ AV_CODEC_ID_AMR_WB
Definition: codec_id.h:441
mov_read_tfhd
static int mov_read_tfhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5616
AV_CODEC_ID_BIN_DATA
@ AV_CODEC_ID_BIN_DATA
Definition: codec_id.h:612
av_malloc
#define av_malloc(s)
Definition: tableprint_vlc.h:31
OPUS_SEEK_PREROLL_MS
#define OPUS_SEEK_PREROLL_MS
Definition: oggparseopus.c:36
AV_CODEC_ID_H261
@ AV_CODEC_ID_H261
Definition: codec_id.h:55
IAMFMixPresentation::cmix
const AVIAMFMixPresentation * cmix
Definition: iamf.h:108
AVChannelLayout::u
union AVChannelLayout::@487 u
Details about which channels are present in this layout.
mov_read_wide
static int mov_read_wide(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6195
AVINDEX_KEYFRAME
#define AVINDEX_KEYFRAME
Definition: avformat.h:606
AV_FIELD_BT
@ AV_FIELD_BT
Bottom coded first, top displayed first.
Definition: defs.h:217
AVStreamGroup::params
union AVStreamGroup::@420 params
Group type-specific parameters.
MOVStreamContext::stsd_count
int stsd_count
Definition: isom.h:259
ff_mov_lang_to_iso639
int ff_mov_lang_to_iso639(unsigned code, char to[4])
Definition: isom.c:260
ff_generate_avci_extradata
int ff_generate_avci_extradata(AVStream *st)
Generate standard extradata for AVC-Intra based on width/height and field order.
Definition: demux_utils.c:191
ff_get_extradata
int ff_get_extradata(void *logctx, AVCodecParameters *par, AVIOContext *pb, int size)
Allocate extradata with additional AV_INPUT_BUFFER_PADDING_SIZE at end which is always set to 0 and f...
Definition: demux_utils.c:326
AVStereo3D::horizontal_field_of_view
AVRational horizontal_field_of_view
Horizontal field of view, in degrees.
Definition: stereo3d.h:239
skip_bits
static void skip_bits(GetBitContext *s, int n)
Definition: get_bits.h:383
AVCodecParameters::color_primaries
enum AVColorPrimaries color_primaries
Definition: codec_par.h:167
AVEncryptionInfo::scheme
uint32_t scheme
The fourcc encryption scheme, in big-endian byte order.
Definition: encryption_info.h:45
MOVStreamContext::stsc_count
unsigned int stsc_count
Definition: isom.h:193
MOVStreamContext::has_palette
int has_palette
Definition: isom.h:234
AVPROBE_SCORE_MAX
#define AVPROBE_SCORE_MAX
maximum score
Definition: avformat.h:463
AV_STEREO3D_SIDEBYSIDE
@ AV_STEREO3D_SIDEBYSIDE
Views are next to each other.
Definition: stereo3d.h:64
MOVIndexRange::start
int64_t start
Definition: isom.h:169
AVPacketSideData::size
size_t size
Definition: packet.h:411
get_bits
static unsigned int get_bits(GetBitContext *s, int n)
Read 1-25 bits.
Definition: get_bits.h:337
ff_remove_stream
void ff_remove_stream(AVFormatContext *s, AVStream *st)
Remove a stream from its AVFormatContext and free it.
Definition: avformat.c:113
OFFSET
#define OFFSET(x)
Definition: mov.c:11559
HEIFGrid::tile_item_list
HEIFItem ** tile_item_list
Definition: isom.h:315
set_icc_profile_from_item
static int set_icc_profile_from_item(AVPacketSideData **coded_side_data, int *nb_coded_side_data, const HEIFItem *item)
Definition: mov.c:10151
AV_FIELD_TT
@ AV_FIELD_TT
Top coded_first, top displayed first.
Definition: defs.h:214
AV_STEREO3D_VIEW_PACKED
@ AV_STEREO3D_VIEW_PACKED
Frame contains two packed views.
Definition: stereo3d.h:153
AV_SPHERICAL_PARAMETRIC_IMMERSIVE
@ AV_SPHERICAL_PARAMETRIC_IMMERSIVE
Parametric Immersive projection (Apple).
Definition: spherical.h:90
MOVStreamContext::nb_frames_for_fps
int nb_frames_for_fps
Definition: isom.h:252
avpriv_dv_produce_packet
int avpriv_dv_produce_packet(DVDemuxContext *c, AVPacket *pkt, uint8_t *buf, int buf_size, int64_t pos)
Definition: dv.c:736
avpriv_set_pts_info
void avpriv_set_pts_info(AVStream *st, int pts_wrap_bits, unsigned int pts_num, unsigned int pts_den)
Set the time base and wrapping info for a given stream.
Definition: avformat.c:777
FF_DVDCLUT_CLUT_LEN
#define FF_DVDCLUT_CLUT_LEN
Definition: dvdclut.h:28
AVEncryptionInfo::skip_byte_block
uint32_t skip_byte_block
Only used for pattern encryption.
Definition: encryption_info.h:57
finish
static void finish(void)
Definition: movenc.c:374
aax_filter
static int aax_filter(uint8_t *input, int size, MOVContext *c)
Definition: mov.c:1507
AV_OPT_TYPE_BINARY
@ AV_OPT_TYPE_BINARY
Underlying C type is a uint8_t* that is either NULL or points to an array allocated with the av_mallo...
Definition: opt.h:286
av_color_space_name
const char * av_color_space_name(enum AVColorSpace space)
Definition: pixdesc.c:3856
av_packet_add_side_data
int av_packet_add_side_data(AVPacket *pkt, enum AVPacketSideDataType type, uint8_t *data, size_t size)
Wrap an existing array as a packet side data.
Definition: packet.c:197
MOVStreamContext::mastering
AVMasteringDisplayMetadata * mastering
Definition: isom.h:267
AV_CODEC_ID_SPEEX
@ AV_CODEC_ID_SPEEX
Definition: codec_id.h:494
AV_FOURCC_MAX_STRING_SIZE
#define AV_FOURCC_MAX_STRING_SIZE
Definition: avutil.h:345
AV_PKT_DATA_PALETTE
@ AV_PKT_DATA_PALETTE
An AV_PKT_DATA_PALETTE side data packet contains exactly AVPALETTE_SIZE bytes worth of palette.
Definition: packet.h:47
ffstream
static av_always_inline FFStream * ffstream(AVStream *st)
Definition: internal.h:347
MOVFragmentIndexItem::current
int current
Definition: isom.h:155
AVFMT_SEEK_TO_PTS
#define AVFMT_SEEK_TO_PTS
Seeking is based on PTS.
Definition: avformat.h:499
AV_CODEC_ID_PCM_S16BE
@ AV_CODEC_ID_PCM_S16BE
Definition: codec_id.h:338
mov_read_mdhd
static int mov_read_mdhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1873
mov_read_ctts
static int mov_read_ctts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:3677
MOVTrackExt
Definition: isom.h:113
MOV_FRAG_SAMPLE_FLAG_IS_NON_SYNC
#define MOV_FRAG_SAMPLE_FLAG_IS_NON_SYNC
Definition: isom.h:418
fail
#define fail()
Definition: checkasm.h:206
mov_read_aclr
static int mov_read_aclr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2337
AVSEEK_FLAG_ANY
#define AVSEEK_FLAG_ANY
seek to any frame, even non-keyframes
Definition: avformat.h:2376
av_int2float
static av_always_inline float av_int2float(uint32_t i)
Reinterpret a 32-bit integer as a float.
Definition: intfloat.h:40
MOVFragment::found_tfhd
int found_tfhd
Definition: isom.h:102
AVStreamGroupTileGrid
AVStreamGroupTileGrid holds information on how to combine several independent images on a single canv...
Definition: avformat.h:951
MOVContext::decryption_key
uint8_t * decryption_key
Definition: isom.h:373
FF_DVDCLUT_CLUT_SIZE
#define FF_DVDCLUT_CLUT_SIZE
Definition: dvdclut.h:29
AV_STEREO3D_2D
@ AV_STEREO3D_2D
Video is not stereoscopic (and metadata has to be there).
Definition: stereo3d.h:52
read_seek
static int read_seek(AVFormatContext *ctx, int stream_index, int64_t timestamp, int flags)
Definition: libcdio.c:151
HEIFItem::item_id
int item_id
Definition: isom.h:299
av_shrink_packet
void av_shrink_packet(AVPacket *pkt, int size)
Reduce packet size, correctly zeroing padding.
Definition: packet.c:113
timecode.h
get_current_frag_stream_info
static MOVFragmentStreamInfo * get_current_frag_stream_info(MOVFragmentIndex *frag_index)
Definition: mov.c:1626
GetBitContext
Definition: get_bits.h:109
MOVStreamContext::mastering_size
size_t mastering_size
Definition: isom.h:268
AVStreamGroupTileGrid::coded_width
int coded_width
Width of the canvas.
Definition: avformat.h:966
av_iamf_audio_element_free
void av_iamf_audio_element_free(AVIAMFAudioElement **paudio_element)
Free an AVIAMFAudioElement and all its contents.
Definition: iamf.c:336
FFStream::index_entries_allocated_size
unsigned int index_entries_allocated_size
Definition: internal.h:187
read_close
static av_cold int read_close(AVFormatContext *ctx)
Definition: libcdio.c:143
mov_read_amve
static int mov_read_amve(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6554
mov_read_enda
static int mov_read_enda(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1987
mov_read_chap
static int mov_read_chap(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5663
MOVParseTableEntry
Definition: mov.c:82
avio_tell
static av_always_inline int64_t avio_tell(AVIOContext *s)
ftell() equivalent for AVIOContext.
Definition: avio.h:494
av_exif_free
void av_exif_free(AVExifMetadata *ifd)
Frees all resources associated with the given EXIF metadata struct.
Definition: exif.c:612
MOV_TRUN_SAMPLE_DURATION
#define MOV_TRUN_SAMPLE_DURATION
Definition: isom.h:412
val
static double val(void *priv, double ch)
Definition: aeval.c:77
set_display_matrix_from_item
static int set_display_matrix_from_item(AVPacketSideData **coded_side_data, int *nb_coded_side_data, const HEIFItem *item)
Definition: mov.c:10165
type
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf type
Definition: writing_filters.txt:86
MOVContext
Definition: isom.h:321
AV_DISPOSITION_TIMED_THUMBNAILS
#define AV_DISPOSITION_TIMED_THUMBNAILS
The stream is sparse, and contains thumbnail images, often corresponding to chapter markers.
Definition: avformat.h:675
AVStreamGroupTileGrid::coded_height
int coded_height
Width of the canvas.
Definition: avformat.h:972
pts
static int64_t pts
Definition: transcode_aac.c:644
MOVStreamContext::v_spacing
int v_spacing
pasp vSpacing
Definition: isom.h:231
AVEncryptionInfo::iv
uint8_t * iv
The initialization vector.
Definition: encryption_info.h:71
AV_CODEC_ID_MP3
@ AV_CODEC_ID_MP3
preferred ID for decoding MPEG audio layer 1, 2 or 3
Definition: codec_id.h:460
AVStream::duration
int64_t duration
Decoding: duration of the stream, in stream time base.
Definition: avformat.h:803
AVAmbientViewingEnvironment::ambient_illuminance
AVRational ambient_illuminance
Environmental illuminance of the ambient viewing environment in lux.
Definition: ambient_viewing_environment.h:40
ss
#define ss(width, name, subs,...)
Definition: cbs_vp9.c:202
MOVStreamContext::width
int width
tkhd width
Definition: isom.h:228
MOVContext::meta_keys
char ** meta_keys
Definition: isom.h:332
av_reduce
int av_reduce(int *dst_num, int *dst_den, int64_t num, int64_t den, int64_t max)
Reduce a fraction.
Definition: rational.c:35
MOVStreamContext::extradata_size
int * extradata_size
Definition: isom.h:257
AVIAMFAudioElement::audio_element_type
enum AVIAMFAudioElementType audio_element_type
Audio element type as defined in section 3.6 of IAMF.
Definition: iamf.h:388
loop
static int loop
Definition: ffplay.c:335
ff_data_to_hex
char * ff_data_to_hex(char *buf, const uint8_t *src, int size, int lowercase)
Write hexadecimal string corresponding to given binary data.
Definition: utils.c:458
update_frag_index
static int update_frag_index(MOVContext *c, int64_t offset)
Definition: mov.c:1741
AV_CODEC_ID_PRORES_RAW
@ AV_CODEC_ID_PRORES_RAW
Definition: codec_id.h:333
AVRational::num
int num
Numerator.
Definition: rational.h:59
MOVStreamContext::keyframes
int * keyframes
Definition: isom.h:209
MOVEncryptionIndex::auxiliary_info_sample_count
size_t auxiliary_info_sample_count
Definition: isom.h:133
AV_FIELD_TB
@ AV_FIELD_TB
Top coded first, bottom displayed first.
Definition: defs.h:216
mov_read_pack
static int mov_read_pack(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6626
AVStream::attached_pic
AVPacket attached_pic
For streams with AV_DISPOSITION_ATTACHED_PIC disposition, this packet will contain the attached pictu...
Definition: avformat.h:842
MOVStsc::id
int id
Definition: isom.h:76
mov_read_saiz
static int mov_read_saiz(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:7645
MOV_FRAG_SAMPLE_FLAG_DEPENDS_YES
#define MOV_FRAG_SAMPLE_FLAG_DEPENDS_YES
Definition: isom.h:425
mov_merge_tts_data
static int mov_merge_tts_data(MOVContext *mov, AVStream *st, int flags)
Definition: mov.c:4590
MOVContext::idat_offset
int64_t idat_offset
Definition: isom.h:386
MOV_TRUN_DATA_OFFSET
#define MOV_TRUN_DATA_OFFSET
Definition: isom.h:410
av_encryption_info_clone
AVEncryptionInfo * av_encryption_info_clone(const AVEncryptionInfo *info)
Allocates an AVEncryptionInfo structure with a copy of the given data.
Definition: encryption_info.c:65
av_ambient_viewing_environment_alloc
AVAmbientViewingEnvironment * av_ambient_viewing_environment_alloc(size_t *size)
Allocate an AVAmbientViewingEnvironment structure.
Definition: ambient_viewing_environment.c:31
AV_DICT_DONT_STRDUP_VAL
#define AV_DICT_DONT_STRDUP_VAL
Take ownership of a value that's been allocated with av_malloc() or another memory allocation functio...
Definition: dict.h:79
IAMFAudioElement::element
AVIAMFAudioElement * element
element backs celement iff the AVIAMFAudioElement is owned by this structure.
Definition: iamf.h:95
MOVStreamContext::elst_data
MOVElst * elst_data
Definition: isom.h:199
mov_read_ares
static int mov_read_ares(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2294
mov_read_adrm
static int mov_read_adrm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1381
av_get_bits_per_sample
int av_get_bits_per_sample(enum AVCodecID codec_id)
Return codec bits per sample.
Definition: utils.c:549
AVCodecParameters::color_trc
enum AVColorTransferCharacteristic color_trc
Definition: codec_par.h:168
IAMFContext::audio_elements
IAMFAudioElement ** audio_elements
Definition: iamf.h:131
MOVFragmentIndex::complete
int complete
Definition: isom.h:162
AV_CODEC_ID_PCM_S8
@ AV_CODEC_ID_PCM_S8
Definition: codec_id.h:341
avassert.h
avio_rb32
unsigned int avio_rb32(AVIOContext *s)
Definition: aviobuf.c:764
AV_LOG_TRACE
#define AV_LOG_TRACE
Extremely verbose debugging, useful for libav* development.
Definition: log.h:236
MOVStreamContext::stsc_sample
int stsc_sample
Definition: isom.h:196
pkt
AVPacket * pkt
Definition: movenc.c:60
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:210
AV_CODEC_ID_MACE3
@ AV_CODEC_ID_MACE3
Definition: codec_id.h:468
MOVTrackExt::track_id
unsigned track_id
Definition: isom.h:114
mov_free_encryption_index
static void mov_free_encryption_index(MOVEncryptionIndex **index)
Definition: mov.c:9887
AV_CH_LOW_FREQUENCY
#define AV_CH_LOW_FREQUENCY
Definition: channel_layout.h:178
duration
int64_t duration
Definition: movenc.c:65
MOVEncryptionIndex::auxiliary_offsets
uint64_t * auxiliary_offsets
Absolute seek position.
Definition: isom.h:135
read_packet
static int read_packet(void *opaque, uint8_t *buf, int buf_size)
Definition: avio_read_callback.c:42
AV_FIELD_UNKNOWN
@ AV_FIELD_UNKNOWN
Definition: defs.h:212
MOVStreamContext::dts_shift
int dts_shift
dts shift when ctts is negative
Definition: isom.h:232
av_timecode_init
int av_timecode_init(AVTimecode *tc, AVRational rate, int flags, int frame_start, void *log_ctx)
Init a timecode struct with the passed parameters.
Definition: timecode.c:201
AVCodecParameters::frame_size
int frame_size
Audio only.
Definition: codec_par.h:195
avio_get_str16le
int avio_get_str16le(AVIOContext *pb, int maxlen, char *buf, int buflen)
Read a UTF-16 string from pb and convert it to UTF-8.
mov_metadata_track_or_disc_number
static int mov_metadata_track_or_disc_number(MOVContext *c, AVIOContext *pb, unsigned len, const char *key)
Definition: mov.c:91
av_dict_get
AVDictionaryEntry * av_dict_get(const AVDictionary *m, const char *key, const AVDictionaryEntry *prev, int flags)
Get a dictionary entry with matching key.
Definition: dict.c:60
AES_CTR_KEY_SIZE
#define AES_CTR_KEY_SIZE
Definition: aes_ctr.h:35
MOVStreamContext::stsd_version
int stsd_version
Definition: isom.h:260
mov_parse_exif_item
static int mov_parse_exif_item(AVFormatContext *s, AVPacketSideData **coded_side_data, int *nb_coded_side_data, const HEIFItem *ref)
Definition: mov.c:10336
AV_STREAM_GROUP_PARAMS_IAMF_MIX_PRESENTATION
@ AV_STREAM_GROUP_PARAMS_IAMF_MIX_PRESENTATION
Definition: avformat.h:1090
ff_add_attached_pic
int ff_add_attached_pic(AVFormatContext *s, AVStream *st, AVIOContext *pb, AVBufferRef **buf, int size)
Add an attached pic to an AVStream.
Definition: demux_utils.c:107
add_tts_entry
static int add_tts_entry(MOVTimeToSample **tts_data, unsigned int *tts_count, unsigned int *allocated_size, int count, int offset, unsigned int duration)
Definition: mov.c:4070
av_fast_realloc
void * av_fast_realloc(void *ptr, unsigned int *size, size_t min_size)
Reallocate the given buffer if it is not large enough, otherwise do nothing.
Definition: mem.c:497
FF_MOV_FLAG_MFRA_PTS
#define FF_MOV_FLAG_MFRA_PTS
Definition: isom.h:462
MOV_MERGE_STTS
#define MOV_MERGE_STTS
Definition: mov.c:4584
MOVStreamContext::iamf_stream_offset
int iamf_stream_offset
Definition: isom.h:286
ff_mov_read_esds
int ff_mov_read_esds(AVFormatContext *fc, AVIOContext *pb)
Definition: mov_esds.c:23
stereo3d.h
AVMasteringDisplayMetadata::white_point
AVRational white_point[2]
CIE 1931 xy chromaticity coords of white point.
Definition: mastering_display_metadata.h:47
intreadwrite.h
mov_read_coll
static int mov_read_coll(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6488
s
#define s(width, name)
Definition: cbs_vp9.c:198
MOVFragmentStreamInfo::encryption_index
MOVEncryptionIndex * encryption_index
Definition: isom.h:148
mov_read_trak
static int mov_read_trak(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5137
IAMFSubStream::audio_substream_id
unsigned int audio_substream_id
Definition: iamf.h:83
MOVContext::fc
AVFormatContext * fc
Definition: isom.h:323
MOV_TFHD_DEFAULT_BASE_IS_MOOF
#define MOV_TFHD_DEFAULT_BASE_IS_MOOF
Definition: isom.h:408
av_new_packet
int av_new_packet(AVPacket *pkt, int size)
Allocate the payload of a packet and initialize its fields with default values.
Definition: packet.c:98
AV_CODEC_ID_BMP
@ AV_CODEC_ID_BMP
Definition: codec_id.h:130
AV_CODEC_ID_EVC
@ AV_CODEC_ID_EVC
Definition: codec_id.h:325
IAMFLayer::substream_count
unsigned int substream_count
Definition: iamf.h:78
MOV_TFHD_DEFAULT_DURATION
#define MOV_TFHD_DEFAULT_DURATION
Definition: isom.h:404
ALAC_EXTRADATA_SIZE
#define ALAC_EXTRADATA_SIZE
DRM_BLOB_SIZE
#define DRM_BLOB_SIZE
Definition: mov.c:1379
MOVStreamContext::sample_offsets_count
int sample_offsets_count
Definition: isom.h:247
MOVCtts::count
unsigned int count
Definition: isom.h:69
MOVStreamContext::drefs
MOVDref * drefs
Definition: isom.h:223
av_realloc_array
void * av_realloc_array(void *ptr, size_t nmemb, size_t size)
Definition: mem.c:217
AVInputFormat::name
const char * name
A comma separated list of short names for the format.
Definition: avformat.h:549
MOVContext::aes_decrypt
struct AVAES * aes_decrypt
Definition: isom.h:372
AVSphericalMapping::bound_top
uint32_t bound_top
Distance from the top edge.
Definition: spherical.h:186
AVMEDIA_TYPE_AUDIO
@ AVMEDIA_TYPE_AUDIO
Definition: avutil.h:201
AV_CODEC_ID_VP9
@ AV_CODEC_ID_VP9
Definition: codec_id.h:222
MOVFragmentIndex::nb_items
int nb_items
Definition: isom.h:164
AVCodecParameters::width
int width
Video only.
Definition: codec_par.h:134
MOVTimeToSample
Definition: isom.h:57
AV_CHANNEL_ORDER_UNSPEC
@ AV_CHANNEL_ORDER_UNSPEC
Only the channel count is specified, without any further information about the channel order.
Definition: channel_layout.h:119
AV_CODEC_ID_MP2
@ AV_CODEC_ID_MP2
Definition: codec_id.h:459
HEIFGrid::tile_idx_list
unsigned * tile_idx_list
Definition: isom.h:317
MOV_TRUN_FIRST_SAMPLE_FLAGS
#define MOV_TRUN_FIRST_SAMPLE_FLAGS
Definition: isom.h:411
av_q2d
static double av_q2d(AVRational a)
Convert an AVRational to a double.
Definition: rational.h:104
AVIndexEntry::size
int size
Definition: avformat.h:609
av_channel_layout_from_mask
int av_channel_layout_from_mask(AVChannelLayout *channel_layout, uint64_t mask)
Initialize a native channel layout from a bitmask indicating which channels are present.
Definition: channel_layout.c:252
MOVStreamContext::keyframe_absent
int keyframe_absent
Definition: isom.h:207
info
MIPS optimizations info
Definition: mips.txt:2
MOVStts::duration
unsigned int duration
Definition: isom.h:65
fc
#define fc(width, name, range_min, range_max)
Definition: cbs_av1.c:494
MOVStreamContext::coll_size
size_t coll_size
Definition: isom.h:270
tile_rows
int tile_rows
Definition: h265_levels.c:217
mov_estimate_video_delay
static void mov_estimate_video_delay(MOVContext *c, AVStream *st)
Definition: mov.c:4099
AVIndexEntry::timestamp
int64_t timestamp
Timestamp in AVStream.time_base units, preferably the time from which on correctly decoded frames are...
Definition: avformat.h:600
av_assert0
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:41
MOVStreamContext::min_corrected_pts
int64_t min_corrected_pts
minimum Composition time shown by the edits excluding empty edits.
Definition: isom.h:212
ffio_read_leb
unsigned int ffio_read_leb(AVIOContext *s)
Read a unsigned integer coded as a variable number of up to eight little-endian bytes,...
Definition: aviobuf.c:930
tile_cols
int tile_cols
Definition: av1_levels.c:73
MOVStreamContext::sdtp_count
unsigned int sdtp_count
Definition: isom.h:188
dvdclut.h
mov_read_lhvc
static int mov_read_lhvc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:8546
AV_LOG_DEBUG
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:231
AVPacketSideData::data
uint8_t * data
Definition: packet.h:410
ctx
AVFormatContext * ctx
Definition: movenc.c:49
hevc.h
get_bits.h
limits.h
mov_read_sidx
static int mov_read_sidx(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6057
AV_PKT_DATA_STEREO3D
@ AV_PKT_DATA_STEREO3D
This side data should be associated with a video stream and contains Stereoscopic 3D information in f...
Definition: packet.h:111
nb_streams
static int nb_streams
Definition: ffprobe.c:340
av_rescale_q
int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq)
Rescale a 64-bit integer by 2 rational numbers.
Definition: mathematics.c:142
ff_iamfdec_read_descriptors
int ff_iamfdec_read_descriptors(IAMFContext *c, AVIOContext *pb, int max_size, void *log_ctx)
Definition: iamf_parse.c:1165
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:10955
AV_CODEC_ID_TARGA_Y216
@ AV_CODEC_ID_TARGA_Y216
Definition: codec_id.h:258
AVStreamGroupTileGrid::offsets
struct AVStreamGroupTileGrid::@419 * offsets
An nb_tiles sized array of offsets in pixels from the topleft edge of the canvas, indicating where ea...
AVIndexEntry::min_distance
int min_distance
Minimum distance between this and the previous keyframe, used to avoid unneeded searching.
Definition: avformat.h:610
mov_read_dvcc_dvvc
static int mov_read_dvcc_dvvc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:8526
MOVParseTableEntry::parse
int(* parse)(MOVContext *ctx, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:84
codec_id
enum AVCodecID codec_id
Definition: vaapi_decode.c:410
AV_CODEC_ID_SVQ3
@ AV_CODEC_ID_SVQ3
Definition: codec_id.h:75
key
const char * key
Definition: hwcontext_opencl.c:189
AVCodecParameters::nb_coded_side_data
int nb_coded_side_data
Amount of entries in coded_side_data.
Definition: codec_par.h:86
MOVStreamContext::sdtp_data
uint8_t * sdtp_data
Definition: isom.h:189
color_range
color_range
Definition: vf_selectivecolor.c:43
AVMEDIA_TYPE_DATA
@ AVMEDIA_TYPE_DATA
Opaque data information usually continuous.
Definition: avutil.h:202
mov_read_udta_string
static int mov_read_udta_string(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:345
mov_read_stss
static int mov_read_stss(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:3364
mov_read_ddts
static int mov_read_ddts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1121
mov_read_uuid
static int mov_read_uuid(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:7248
AVCOL_PRI_UNSPECIFIED
@ AVCOL_PRI_UNSPECIFIED
Definition: pixfmt.h:639
MOVTrackExt::duration
unsigned duration
Definition: isom.h:116
AV_CODEC_ID_H264
@ AV_CODEC_ID_H264
Definition: codec_id.h:79
av_content_light_metadata_alloc
AVContentLightMetadata * av_content_light_metadata_alloc(size_t *size)
Allocate an AVContentLightMetadata structure and set its fields to default values.
Definition: mastering_display_metadata.c:72
tmp
static uint8_t tmp[40]
Definition: aes_ctr.c:52
av_sha_final
void av_sha_final(AVSHA *ctx, uint8_t *digest)
Finish hashing and output digest value.
Definition: sha.c:347
MOVStreamContext::current_sample
int current_sample
Definition: isom.h:213
MOVFragmentStreamInfo::sidx_pts
int64_t sidx_pts
Definition: isom.h:141
MAX_REORDER_DELAY
#define MAX_REORDER_DELAY
Definition: mov.c:4098
MOVFragmentIndex::current
int current
Definition: isom.h:163
MOVEncryptionIndex::encrypted_samples
AVEncryptionInfo ** encrypted_samples
Definition: isom.h:130
mov_read_close
static int mov_read_close(AVFormatContext *s)
Definition: mov.c:9961
MOVAtom::size
int64_t size
Definition: isom.h:96
MOVStreamContext::refcount
int refcount
Definition: isom.h:175
AVStereo3D::flags
int flags
Additional information about the frame packing.
Definition: stereo3d.h:212
ff_mov_get_lpcm_codec_id
static enum AVCodecID ff_mov_get_lpcm_codec_id(int bps, int flags)
Compute codec id for 'lpcm' tag.
Definition: isom.h:468
AV_CODEC_ID_PNG
@ AV_CODEC_ID_PNG
Definition: codec_id.h:113
AV_CODEC_ID_AVUI
@ AV_CODEC_ID_AVUI
Definition: codec_id.h:257
if
if(ret)
Definition: filter_design.txt:179
mov_read_cmov
static int mov_read_cmov(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6215
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:7473
FFStream::need_parsing
enum AVStreamParseType need_parsing
Definition: internal.h:314
MOVStreamContext::keyframe_count
unsigned int keyframe_count
Definition: isom.h:208
mov_read_SAND
static int mov_read_SAND(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:8774
IAMFAudioElement::audio_element_id
unsigned int audio_element_id
Definition: iamf.h:96
AVDISCARD_ALL
@ AVDISCARD_ALL
discard all
Definition: defs.h:232
AVFormatContext
Format I/O context.
Definition: avformat.h:1264
av_realloc_f
#define av_realloc_f(p, o, n)
Definition: tableprint_vlc.h:33
mov_read_stts
static int mov_read_stts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:3512
MOVStreamContext::index_ranges
MOVIndexRange * index_ranges
Definition: isom.h:215
DDTS_SIZE
#define DDTS_SIZE
internal.h
MOVTrackExt::stsd_id
unsigned stsd_id
Definition: isom.h:115
AVStreamGroupLCEVC::height
int height
Height of the final image for presentation.
Definition: avformat.h:1084
find_prev_closest_index
static int find_prev_closest_index(AVStream *st, AVIndexEntry *e_old, int nb_old, MOVTimeToSample *tts_data, int64_t tts_count, int64_t timestamp_pts, int flag, int64_t *index, int64_t *tts_index, int64_t *tts_sample)
Find the closest previous frame to the timestamp_pts, in e_old index entries.
Definition: mov.c:3921
set_frag_stream
static void set_frag_stream(MOVFragmentIndex *frag_index, int id)
Definition: mov.c:1606
mov_read_free
static int mov_read_free(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:7353
mov_realloc_extradata
static int mov_realloc_extradata(AVCodecParameters *par, MOVAtom atom)
Definition: mov.c:2189
AVStream::codecpar
AVCodecParameters * codecpar
Codec parameters associated with this stream.
Definition: avformat.h:767
LIBAVUTIL_VERSION_INT
#define LIBAVUTIL_VERSION_INT
Definition: version.h:85
av_exif_get_tag_id
int32_t av_exif_get_tag_id(const char *name)
Retrieves the tag ID associated with the provided tag string name.
Definition: exif.c:225
AV_PKT_DATA_EXIF
@ AV_PKT_DATA_EXIF
Extensible image file format metadata.
Definition: packet.h:369
AVSEEK_FLAG_BACKWARD
#define AVSEEK_FLAG_BACKWARD
Definition: avformat.h:2374
aes.h
AVClass
Describe the class of an AVClass context structure.
Definition: log.h:76
MOVStreamContext::tts_sample
int tts_sample
Definition: isom.h:202
avpriv_dv_get_packet
int avpriv_dv_get_packet(DVDemuxContext *c, AVPacket *pkt)
Definition: dv.c:731
MOVContext::ignore_editlist
int ignore_editlist
Definition: isom.h:345
result
and forward the result(frame or status change) to the corresponding input. If nothing is possible
fabs
static __device__ float fabs(float a)
Definition: cuda_runtime.h:182
metadata
Stream codec metadata
Definition: ogg-flac-chained-meta.txt:2
AVStream::time_base
AVRational time_base
This is the fundamental unit of time (in seconds) in terms of which frame timestamps are represented.
Definition: avformat.h:783
NULL
#define NULL
Definition: coverity.c:32
sha.h
truehd_layout
static uint64_t truehd_layout(int chanmap)
Definition: mlp_parse.h:105
MOVDref
Definition: isom.h:85
AVERROR_PATCHWELCOME
#define AVERROR_PATCHWELCOME
Not yet implemented in FFmpeg, patches welcome.
Definition: error.h:64
format
New swscale design to change SwsGraph is what coordinates multiple passes These can include cascaded scaling error diffusion and so on Or we could have separate passes for the vertical and horizontal scaling In between each SwsPass lies a fully allocated image buffer Graph passes may have different levels of e g we can have a single threaded error diffusion pass following a multi threaded scaling pass SwsGraph is internally recreated whenever the image format
Definition: swscale-v2.txt:14
av_buffer_unref
void av_buffer_unref(AVBufferRef **buf)
Free a given reference and automatically free the buffer if there are no more references to it.
Definition: buffer.c:139
AV_CODEC_ID_AV1
@ AV_CODEC_ID_AV1
Definition: codec_id.h:284
MOVStreamContext::ctts_count
unsigned int ctts_count
Definition: isom.h:190
AVEncryptionInitInfo
This describes info used to initialize an encryption key system.
Definition: encryption_info.h:88
isom.h
MP4TrackKindValueMapping::disposition
int disposition
Definition: isom.h:484
mov_read_ftyp
static int mov_read_ftyp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1521
AV_WB16
#define AV_WB16(p, v)
Definition: intreadwrite.h:401
MOVContext::nb_heif_grid
int nb_heif_grid
Definition: isom.h:385
read_image_grid
static int read_image_grid(AVFormatContext *s, const HEIFGrid *grid, AVStreamGroupTileGrid *tile_grid)
Definition: mov.c:10186
MOVElst
Definition: isom.h:79
av_aes_ctr_alloc
struct AVAESCTR * av_aes_ctr_alloc(void)
Allocate an AVAESCTR context.
Definition: aes_ctr.c:41
flac_parse_block_header
static av_always_inline void flac_parse_block_header(const uint8_t *block_header, int *last, int *type, int *size)
Parse the metadata block parameters from the header.
Definition: flac.h:63
AVStreamGroupTileGrid::coded_side_data
AVPacketSideData * coded_side_data
Additional data associated with the grid.
Definition: avformat.h:1054
AVRational
Rational number (pair of numerator and denominator).
Definition: rational.h:58
AV_PRIMARY_EYE_LEFT
@ AV_PRIMARY_EYE_LEFT
Left eye.
Definition: stereo3d.h:183
mov_read_sgpd
static int mov_read_sgpd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:3758
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:9607
AVPALETTE_SIZE
#define AVPALETTE_SIZE
Definition: pixfmt.h:32
MOVDref::nlvl_to
int16_t nlvl_to
Definition: isom.h:91
get_eia608_packet
static int get_eia608_packet(AVIOContext *pb, AVPacket *pkt, int src_size)
Definition: mov.c:11052
AV_CODEC_ID_DVD_SUBTITLE
@ AV_CODEC_ID_DVD_SUBTITLE
Definition: codec_id.h:571
AVIndexEntry::flags
int flags
Definition: avformat.h:608
MOVStreamContext::time_offset
int64_t time_offset
time offset of the edit list entries
Definition: isom.h:211
mov_read_smdm
static int mov_read_smdm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6397
av_default_item_name
const char * av_default_item_name(void *ptr)
Return the context name.
Definition: log.c:241
AVStereo3D::horizontal_disparity_adjustment
AVRational horizontal_disparity_adjustment
Relative shift of the left and right images, which changes the zero parallax plane.
Definition: stereo3d.h:234
avio_rb64
uint64_t avio_rb64(AVIOContext *s)
Definition: aviobuf.c:911
av_aes_crypt
void av_aes_crypt(AVAES *a, uint8_t *dst, const uint8_t *src, int count, uint8_t *iv, int decrypt)
Encrypt or decrypt a buffer using a previously initialized context.
Definition: aes.c:171
MOVStreamContext::current_index_range
MOVIndexRange * current_index_range
Definition: isom.h:216
mov_open_dref
static int mov_open_dref(MOVContext *c, AVIOContext **pb, const char *src, MOVDref *ref)
Definition: mov.c:4991
FFStream::nb_index_entries
int nb_index_entries
Definition: internal.h:186
AVProbeData
This structure contains the data a format has to probe a file.
Definition: avformat.h:451
av_aes_alloc
struct AVAES * av_aes_alloc(void)
Allocate an AVAES context.
Definition: aes.c:37
TAG_IS_AVCI
#define TAG_IS_AVCI(tag)
Definition: isom.h:438
IAMFSubStream
Definition: iamf.h:82
MOVStreamContext::timecode_track
int timecode_track
Definition: isom.h:227
IAMFAudioElement::layers
IAMFLayer * layers
Definition: iamf.h:103
mov_read_schm
static int mov_read_schm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:7945
AVStream::metadata
AVDictionary * metadata
Definition: avformat.h:824
FLAC_STREAMINFO_SIZE
#define FLAC_STREAMINFO_SIZE
Definition: flac.h:32
av_color_primaries_name
const char * av_color_primaries_name(enum AVColorPrimaries primaries)
Definition: pixdesc.c:3790
FF_MOV_FLAG_MFRA_DTS
#define FF_MOV_FLAG_MFRA_DTS
Definition: isom.h:461
MOV_SAMPLE_DEPENDENCY_NO
#define MOV_SAMPLE_DEPENDENCY_NO
Definition: isom.h:434
AV_DICT_DONT_OVERWRITE
#define AV_DICT_DONT_OVERWRITE
Don't overwrite existing entries.
Definition: dict.h:81
ff_codec_movvideo_tags
const AVCodecTag ff_codec_movvideo_tags[]
Definition: isom_tags.c:29
MOVStreamContext::tts_index
int tts_index
Definition: isom.h:201
AV_DISPOSITION_MULTILAYER
#define AV_DISPOSITION_MULTILAYER
The video stream contains multiple layers, e.g.
Definition: avformat.h:714
MOVFragmentStreamInfo::index_base
int index_base
Definition: isom.h:146
MOVStreamContext::rap_group
MOVSbgp * rap_group
Definition: isom.h:241
AV_CODEC_ID_QDM2
@ AV_CODEC_ID_QDM2
Definition: codec_id.h:478
mov_read_ilst
static int mov_read_ilst(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5290
MOVTimeToSample::duration
unsigned int duration
Definition: isom.h:59
AV_CH_FRONT_CENTER
#define AV_CH_FRONT_CENTER
Definition: channel_layout.h:177
AVCodecParameters::ch_layout
AVChannelLayout ch_layout
Audio only.
Definition: codec_par.h:180
get_frag_stream_info_from_pkt
static MOVFragmentStreamInfo * get_frag_stream_info_from_pkt(MOVFragmentIndex *frag_index, AVPacket *pkt, int id)
Definition: mov.c:8347
get_sgpd_sync_index
static uint32_t get_sgpd_sync_index(const MOVStreamContext *sc, int nal_unit_type)
Definition: mov.c:4512
mov_read_fiel
static int mov_read_fiel(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2155
parse
static int parse(AVCodecParserContext *s, AVCodecContext *avctx, const uint8_t **poutbuf, int *poutbuf_size, const uint8_t *buf, int buf_size)
Definition: apv_parser.c:46
MOV_MP4_TTML_TAG
#define MOV_MP4_TTML_TAG
Definition: isom.h:479
AV_PKT_DATA_CONTENT_LIGHT_LEVEL
@ AV_PKT_DATA_CONTENT_LIGHT_LEVEL
Content light level (based on CTA-861.3).
Definition: packet.h:232
av_encryption_info_add_side_data
uint8_t * av_encryption_info_add_side_data(const AVEncryptionInfo *info, size_t *size)
Allocates and initializes side data that holds a copy of the given encryption info.
Definition: encryption_info.c:127
MOV_TFHD_BASE_DATA_OFFSET
#define MOV_TFHD_BASE_DATA_OFFSET
Definition: isom.h:402
MOVFragmentStreamInfo::stsd_id
int stsd_id
Definition: isom.h:149
av_exif_remove_entry
int av_exif_remove_entry(void *logctx, AVExifMetadata *ifd, uint16_t id, int flags)
Remove an entry from the provided EXIF metadata struct.
Definition: exif.c:1143
MOVStreamContext::open_key_samples_count
int open_key_samples_count
Definition: isom.h:249
HEIFItem
Definition: isom.h:294
ff_codec_movaudio_tags
const AVCodecTag ff_codec_movaudio_tags[]
Definition: isom_tags.c:311
ff_codec_movdata_tags
const AVCodecTag ff_codec_movdata_tags[]
Definition: isom.c:82
mov_read_wfex
static int mov_read_wfex(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1225
av_stereo3d_alloc_size
AVStereo3D * av_stereo3d_alloc_size(size_t *size)
Allocate an AVStereo3D structure and set its fields to default values.
Definition: stereo3d.c:40
index
int index
Definition: gxfenc.c:90
c
Undefined Behavior In the C some operations are like signed integer dereferencing freed accessing outside allocated Undefined Behavior must not occur in a C it is not safe even if the output of undefined operations is unused The unsafety may seem nit picking but Optimizing compilers have in fact optimized code on the assumption that no undefined Behavior occurs Optimizing code based on wrong assumptions can and has in some cases lead to effects beyond the output of computations The signed integer overflow problem in speed critical code Code which is highly optimized and works with signed integers sometimes has the problem that often the output of the computation does not c
Definition: undefined.txt:32
AVPROBE_SCORE_EXTENSION
#define AVPROBE_SCORE_EXTENSION
score for file extension
Definition: avformat.h:461
MOVSbgp::count
unsigned int count
Definition: isom.h:122
AVCodecParameters::sample_rate
int sample_rate
Audio only.
Definition: codec_par.h:184
mov_parse_stsd_subtitle
static void mov_parse_stsd_subtitle(MOVContext *c, AVIOContext *pb, AVStream *st, MOVStreamContext *sc, int64_t size)
Definition: mov.c:2844
cid
uint16_t cid
Definition: mxfenc.c:2333
mov_skip_multiple_stsd
static int mov_skip_multiple_stsd(MOVContext *c, AVIOContext *pb, int codec_tag, int format, int64_t size)
Definition: mov.c:3009
MOVStts
Definition: isom.h:63
AVAudioServiceType
AVAudioServiceType
Definition: defs.h:235
AV_CODEC_ID_MPEG1VIDEO
@ AV_CODEC_ID_MPEG1VIDEO
Definition: codec_id.h:53
AV_CODEC_ID_GSM
@ AV_CODEC_ID_GSM
as in Berlin toast format
Definition: codec_id.h:477
AVStream::nb_frames
int64_t nb_frames
number of frames in this stream if known or 0
Definition: avformat.h:805
AVCodecID
AVCodecID
Identify the syntax and semantics of the bitstream.
Definition: codec_id.h:49
av_packet_side_data_get
const AVPacketSideData * av_packet_side_data_get(const AVPacketSideData *sd, int nb_sd, enum AVPacketSideDataType type)
Get side information from a side data array.
Definition: packet.c:644
AVIAMFSubmixElement::audio_element_id
unsigned int audio_element_id
The id of the Audio Element this submix element references.
Definition: iamf.h:452
AV_CODEC_ID_EAC3
@ AV_CODEC_ID_EAC3
Definition: codec_id.h:499
should_retry
static int should_retry(AVIOContext *pb, int error_code)
Definition: mov.c:10985
avformat_stream_group_add_stream
int avformat_stream_group_add_stream(AVStreamGroup *stg, AVStream *st)
Add an already allocated stream to a stream group.
Definition: options.c:513
AV_PKT_DATA_SPHERICAL
@ AV_PKT_DATA_SPHERICAL
This side data should be associated with a video stream and corresponds to the AVSphericalMapping str...
Definition: packet.h:225
AVCodecParameters::extradata_size
int extradata_size
Size of the extradata content in bytes.
Definition: codec_par.h:73
AVIAMFSubmix
Submix layout as defined in section 3.7 of IAMF.
Definition: iamf.h:556
AV_WB32
#define AV_WB32(p, v)
Definition: intreadwrite.h:415
mov_read_pasp
static int mov_read_pasp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1349
MOVContext::dv_demux
DVDemuxContext * dv_demux
Definition: isom.h:334
AV_CODEC_ID_AAC
@ AV_CODEC_ID_AAC
Definition: codec_id.h:461
AVStereo3D::primary_eye
enum AVStereo3DPrimaryEye primary_eye
Which eye is the primary eye when rendering in 2D.
Definition: stereo3d.h:222
ff_dlog
#define ff_dlog(a,...)
Definition: tableprint_vlc.h:28
color_primaries
static const AVColorPrimariesDesc color_primaries[AVCOL_PRI_NB]
Definition: csp.c:76
mov_read_SA3D
static int mov_read_SA3D(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:8684
mov_read_elst
static int mov_read_elst(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6268
MOVEncryptionIndex::auxiliary_info_default_size
uint8_t auxiliary_info_default_size
Definition: isom.h:134
AV_STREAM_GROUP_PARAMS_TILE_GRID
@ AV_STREAM_GROUP_PARAMS_TILE_GRID
Definition: avformat.h:1091
IAMFAudioElement
Definition: iamf.h:89
AV_UUID_LEN
#define AV_UUID_LEN
Definition: uuid.h:57
av_sat_sub64
#define av_sat_sub64
Definition: common.h:142
mov_read_header
static int mov_read_header(AVFormatContext *s)
Definition: mov.c:10706
AV_CODEC_ID_QCELP
@ AV_CODEC_ID_QCELP
Definition: codec_id.h:483
AV_SPHERICAL_HALF_EQUIRECTANGULAR
@ AV_SPHERICAL_HALF_EQUIRECTANGULAR
Video frame displays as a 180 degree equirectangular projection.
Definition: spherical.h:73
cbc1_scheme_decrypt
static int cbc1_scheme_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
Definition: mov.c:8140
avio_rl32
unsigned int avio_rl32(AVIOContext *s)
Definition: aviobuf.c:733
MOVStreamContext::tref_flags
unsigned tref_flags
Definition: isom.h:225
AVDISCARD_NONKEY
@ AVDISCARD_NONKEY
discard all frames except keyframes
Definition: defs.h:231
MOVFragment::flags
unsigned flags
Definition: isom.h:110
f
f
Definition: af_crystalizer.c:122
AVIOContext
Bytestream IO Context.
Definition: avio.h:160
AV_CODEC_ID_PCM_S24LE
@ AV_CODEC_ID_PCM_S24LE
Definition: codec_id.h:349
mov_read_wave
static int mov_read_wave(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2385
AV_SPHERICAL_CUBEMAP
@ AV_SPHERICAL_CUBEMAP
Video frame is split into 6 faces of a cube, and arranged on a 3x2 layout.
Definition: spherical.h:61
avio_rb24
unsigned int avio_rb24(AVIOContext *s)
Definition: aviobuf.c:757
ff_mpa_check_header
static int ff_mpa_check_header(uint32_t header)
Definition: mpegaudiodecheader.h:62
MOVStreamContext::aes_ctx
struct AVAES * aes_ctx
Definition: isom.h:279
MOV_TREF_FLAG_ENHANCEMENT
#define MOV_TREF_FLAG_ENHANCEMENT
Definition: isom.h:436
cens_scheme_decrypt
static int cens_scheme_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
Definition: mov.c:8200
MOVContext::handbrake_version
int handbrake_version
Definition: isom.h:341
mov_free_stream_context
static void mov_free_stream_context(AVFormatContext *s, AVStream *st)
Definition: mov.c:9899
AVPacket::size
int size
Definition: packet.h:589
NULL_IF_CONFIG_SMALL
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
Definition: internal.h:94
ff_codec_get_id
enum AVCodecID ff_codec_get_id(const AVCodecTag *tags, unsigned int tag)
Definition: utils.c:143
FLAC_METADATA_TYPE_STREAMINFO
@ FLAC_METADATA_TYPE_STREAMINFO
Definition: flac.h:46
avformat_alloc_context
AVFormatContext * avformat_alloc_context(void)
Allocate an AVFormatContext.
Definition: options.c:162
MOVFragmentIndexItem
Definition: isom.h:152
get_current_encryption_info
static int get_current_encryption_info(MOVContext *c, MOVEncryptionIndex **encryption_index, MOVStreamContext **sc)
Gets the current encryption info and associated current stream context.
Definition: mov.c:7422
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:4167
AVSphericalMapping::bound_right
uint32_t bound_right
Distance from the right edge.
Definition: spherical.h:187
MOVStsc::first
int first
Definition: isom.h:74
dst
uint8_t ptrdiff_t const uint8_t ptrdiff_t int intptr_t intptr_t int int16_t * dst
Definition: dsp.h:87
av_bswap32
#define av_bswap32
Definition: bswap.h:47
MOVStreamContext::stsz_sample_size
unsigned int stsz_sample_size
always contains sample size from stsz atom
Definition: isom.h:204
FF_MOV_FLAG_MFRA_AUTO
#define FF_MOV_FLAG_MFRA_AUTO
Definition: isom.h:460
ff_dict_set_timestamp
int ff_dict_set_timestamp(AVDictionary **dict, const char *key, int64_t timestamp)
Set a dictionary value to an ISO-8601 compliant timestamp string.
Definition: utils.c:610
av_err2str
#define av_err2str(errnum)
Convenience macro, the return value should be used only directly in function arguments but never stan...
Definition: error.h:122
for
for(k=2;k<=8;++k)
Definition: h264pred_template.c:424
MOVStreamContext::sgpd_sync
uint8_t * sgpd_sync
Definition: isom.h:244
start_time
static int64_t start_time
Definition: ffplay.c:326
uuid.h
ff_dvdclut_palette_extradata_cat
int ff_dvdclut_palette_extradata_cat(const uint32_t *clut, const size_t clut_size, AVCodecParameters *par)
Definition: dvdclut.c:28
mov_read_trun
static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5749
MOVStreamContext::stereo3d_size
size_t stereo3d_size
Definition: isom.h:264
avio_get_str
int avio_get_str(AVIOContext *pb, int maxlen, char *buf, int buflen)
Read a string from pb into buf.
Definition: aviobuf.c:869
mov_read_iprp
static int mov_read_iprp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:9245
av_sha_update
void av_sha_update(struct AVSHA *ctx, const uint8_t *data, size_t len)
Update hash value.
Definition: sha.c:315
sample
#define sample
Definition: flacdsp_template.c:44
hypot
static av_const double hypot(double x, double y)
Definition: libm.h:368
AV_CODEC_ID_H263
@ AV_CODEC_ID_H263
Definition: codec_id.h:56
MOV_TFHD_STSD_ID
#define MOV_TFHD_STSD_ID
Definition: isom.h:403
size
int size
Definition: twinvq_data.h:10344
mov_read_chan
static int mov_read_chan(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1174
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:3222
AV_WL32A
#define AV_WL32A(p, v)
Definition: intreadwrite.h:571
av_reallocp
int av_reallocp(void *ptr, size_t size)
Allocate, reallocate, or free a block of memory through a pointer to a pointer.
Definition: mem.c:188
ff_get_qtpalette
int ff_get_qtpalette(int codec_id, AVIOContext *pb, uint32_t *palette)
Retrieve the palette (or "color table" in QuickTime terms), either from the video sample description,...
Definition: qtpalette.c:323
AV_NOPTS_VALUE
#define AV_NOPTS_VALUE
Undefined timestamp value.
Definition: avutil.h:247
MKBETAG
#define MKBETAG(a, b, c, d)
Definition: macros.h:56
AV_CODEC_ID_QDMC
@ AV_CODEC_ID_QDMC
Definition: codec_id.h:509
av_fourcc_make_string
char * av_fourcc_make_string(char *buf, uint32_t fourcc)
Fill the provided buffer with a string containing a FourCC (four-character code) representation.
Definition: utils.c:75
AV_RB32
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_WL16 uint64_t_TMPL AV_WB64 unsigned int_TMPL AV_RB32
Definition: bytestream.h:96
avpriv_report_missing_feature
void avpriv_report_missing_feature(void *avc, const char *msg,...) av_printf_format(2
Log a generic warning message about a missing feature.
av_aes_ctr_set_full_iv
void av_aes_ctr_set_full_iv(struct AVAESCTR *a, const uint8_t *iv)
Forcefully change the "full" 16-byte iv, including the counter.
Definition: aes_ctr.c:53
AVStreamGroup::iamf_audio_element
struct AVIAMFAudioElement * iamf_audio_element
Definition: avformat.h:1131
MOVStreamContext::coll
AVContentLightMetadata * coll
Definition: isom.h:269
aes_ctr.h
ff_format_io_close
int ff_format_io_close(AVFormatContext *s, AVIOContext **pb)
Definition: avformat.c:868
mov_parse_heif_items
static int mov_parse_heif_items(AVFormatContext *s)
Definition: mov.c:10541
HEIFItem::is_idat_relative
int is_idat_relative
Definition: isom.h:308
IAMFContext
Definition: iamf.h:128
add_index_entry
static int64_t add_index_entry(AVStream *st, int64_t pos, int64_t timestamp, int size, int distance, int flags)
Add index entry with the given values, to the end of ffstream(st)->index_entries.
Definition: mov.c:4017
MOVDref::path
char * path
Definition: isom.h:87
mov_current_sample_inc
static void mov_current_sample_inc(MOVStreamContext *sc)
Definition: mov.c:4155
AVStream::sample_aspect_ratio
AVRational sample_aspect_ratio
sample aspect ratio (0 if unknown)
Definition: avformat.h:822
FFInputFormat::p
AVInputFormat p
The public AVInputFormat.
Definition: demux.h:51
dovi_isom.h
AVPacket::dts
int64_t dts
Decompression timestamp in AVStream->time_base units; the time at which the packet is decompressed.
Definition: packet.h:587
mov_read_vexu_proj
static int mov_read_vexu_proj(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6844
fix_timescale
static void fix_timescale(MOVContext *c, MOVStreamContext *sc)
Definition: mov.c:5063
avio_r8
int avio_r8(AVIOContext *s)
Definition: aviobuf.c:606
IAMFAudioElement::substreams
IAMFSubStream * substreams
Definition: iamf.h:98
AVSphericalMapping::padding
uint32_t padding
Number of pixels to pad from the edge of each cube face.
Definition: spherical.h:200
a
The reader does not expect b to be semantically here and if the code is changed by maybe adding a a division or other the signedness will almost certainly be mistaken To avoid this confusion a new type was SUINT is the C unsigned type but it holds a signed int to use the same example SUINT a
Definition: undefined.txt:41
av_channel_layout_retype
int av_channel_layout_retype(AVChannelLayout *channel_layout, enum AVChannelOrder order, int flags)
Change the AVChannelOrder of a channel layout.
Definition: channel_layout.c:885
av_reallocp_array
int av_reallocp_array(void *ptr, size_t nmemb, size_t size)
Allocate, reallocate an array through a pointer to a pointer.
Definition: mem.c:225
AVIAMFAudioElement
Information on how to combine one or more audio streams, as defined in section 3.6 of IAMF.
Definition: iamf.h:356
AV_PRIMARY_EYE_NONE
@ AV_PRIMARY_EYE_NONE
Neither eye.
Definition: stereo3d.h:178
mov_read_default
static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:9485
AV_TIMECODE_FLAG_24HOURSMAX
@ AV_TIMECODE_FLAG_24HOURSMAX
timecode wraps after 24 hours
Definition: timecode.h:37
MOV_MP4_FPCM_TAG
#define MOV_MP4_FPCM_TAG
Definition: isom.h:480
ffio_ensure_seekback
int ffio_ensure_seekback(AVIOContext *s, int64_t buf_size)
Ensures that the requested seekback buffer size will be available.
Definition: aviobuf.c:1026
AVStreamGroupTileGrid::nb_tiles
unsigned int nb_tiles
Amount of tiles in the grid.
Definition: avformat.h:959
av_packet_side_data_add
AVPacketSideData * av_packet_side_data_add(AVPacketSideData **psd, int *pnb_sd, enum AVPacketSideDataType type, void *data, size_t size, int flags)
Wrap existing data as packet side data.
Definition: packet.c:687
mov_read_packet
static int mov_read_packet(AVFormatContext *s, AVPacket *pkt)
Definition: mov.c:11185
mov_read_infe
static int mov_read_infe(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:8924
offset
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf offset
Definition: writing_filters.txt:86
AVStreamGroupLCEVC::lcevc_index
unsigned int lcevc_index
Index of the LCEVC data stream in AVStreamGroup.
Definition: avformat.h:1076
AVStreamGroup::lcevc
struct AVStreamGroupLCEVC * lcevc
Definition: avformat.h:1134
attributes.h
AV_CODEC_ID_LCEVC
@ AV_CODEC_ID_LCEVC
Definition: codec_id.h:614
MOVEncryptionIndex::auxiliary_offsets_count
size_t auxiliary_offsets_count
Definition: isom.h:136
HEIFItem::vflip
int vflip
Definition: isom.h:306
AVPacket::flags
int flags
A combination of AV_PKT_FLAG values.
Definition: packet.h:594
av_dict_free
void av_dict_free(AVDictionary **pm)
Free all the memory allocated for an AVDictionary struct and all keys and values.
Definition: dict.c:233
av_encryption_info_free
void av_encryption_info_free(AVEncryptionInfo *info)
Frees the given encryption info object.
Definition: encryption_info.c:82
read_header
static int read_header(FFV1Context *f, RangeCoder *c)
Definition: ffv1dec.c:498
av_strstart
int av_strstart(const char *str, const char *pfx, const char **ptr)
Return non-zero if pfx is a prefix of str.
Definition: avstring.c:36
mov_find_reference_track
static AVStream * mov_find_reference_track(AVFormatContext *s, AVStream *st, int first_index)
Definition: mov.c:10617
AVSubsampleEncryptionInfo
This file is part of FFmpeg.
Definition: encryption_info.h:25
av_buffer_alloc
AVBufferRef * av_buffer_alloc(size_t size)
Allocate an AVBuffer of the given size using av_malloc().
Definition: buffer.c:77
MOVFragmentIndexItem::stream_info
MOVFragmentStreamInfo * stream_info
Definition: isom.h:157
version
version
Definition: libkvazaar.c:313
AV_STREAM_GROUP_PARAMS_IAMF_AUDIO_ELEMENT
@ AV_STREAM_GROUP_PARAMS_IAMF_AUDIO_ELEMENT
Definition: avformat.h:1089
AVEncryptionInitInfo::next
struct AVEncryptionInitInfo * next
An optional pointer to the next initialization info in the list.
Definition: encryption_info.h:122
AV_STEREO3D_FLAG_INVERT
#define AV_STEREO3D_FLAG_INVERT
Inverted views, Right/Bottom represents the left view.
Definition: stereo3d.h:194
AVStreamGroup::streams
AVStream ** streams
A list of streams in the group.
Definition: avformat.h:1165
ff_rfps_calculate
void ff_rfps_calculate(AVFormatContext *ic)
Definition: demux.c:2367
input
and forward the test the status of outputs and forward it to the corresponding return FFERROR_NOT_READY If the filters stores internally one or a few frame for some input
Definition: filter_design.txt:172
MOV_MP4_IPCM_TAG
#define MOV_MP4_IPCM_TAG
Definition: isom.h:481
mov_read_clli
static int mov_read_clli(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6525
MOVStreamContext::chunk_offsets
int64_t * chunk_offsets
Definition: isom.h:181
AVStreamGroup::iamf_mix_presentation
struct AVIAMFMixPresentation * iamf_mix_presentation
Definition: avformat.h:1132
AVBufferRef::size
size_t size
Size of data in bytes.
Definition: buffer.h:94
MOVFragmentIndex::item
MOVFragmentIndexItem * item
Definition: isom.h:165
AV_LOG_INFO
#define AV_LOG_INFO
Standard information.
Definition: log.h:221
MOVStreamContext::iamf
struct IAMFDemuxContext * iamf
Definition: isom.h:285
FFERROR_REDO
#define FFERROR_REDO
Returned by demuxers to indicate that data was consumed but discarded (ignored streams or junk data).
Definition: demux.h:181
av_encryption_init_info_alloc
AVEncryptionInitInfo * av_encryption_init_info_alloc(uint32_t system_id_size, uint32_t num_key_ids, uint32_t key_id_size, uint32_t data_size)
Allocates an AVEncryptionInitInfo structure and sub-pointers to hold the given sizes.
Definition: encryption_info.c:178
av_channel_layout_custom_init
int av_channel_layout_custom_init(AVChannelLayout *channel_layout, int nb_channels)
Initialize a custom channel layout with the specified number of channels.
Definition: channel_layout.c:232
MOVContext::decryption_key_len
int decryption_key_len
Definition: isom.h:374
av_aes_ctr_free
void av_aes_ctr_free(struct AVAESCTR *a)
Release an AVAESCTR context.
Definition: aes_ctr.c:84
av_mastering_display_metadata_alloc_size
AVMasteringDisplayMetadata * av_mastering_display_metadata_alloc_size(size_t *size)
Allocate an AVMasteringDisplayMetadata structure and set its fields to default values.
Definition: mastering_display_metadata.c:44
mov_read_dfla
static int mov_read_dfla(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:8047
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:9356
layout
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel layout
Definition: filter_design.txt:18
MOVDref::nlvl_from
int16_t nlvl_from
Definition: isom.h:91
AVStreamGroupTileGrid::nb_coded_side_data
int nb_coded_side_data
Amount of entries in coded_side_data.
Definition: avformat.h:1059
mov_metadata_creation_time
static void mov_metadata_creation_time(MOVContext *c, AVIOContext *pb, AVDictionary **metadata, int version)
Definition: mov.c:1843
mov_metadata_hmmt
static int mov_metadata_hmmt(MOVContext *c, AVIOContext *pb, unsigned len)
Definition: mov.c:324
AV_CODEC_ID_MJPEG
@ AV_CODEC_ID_MJPEG
Definition: codec_id.h:59
MOVFragmentStreamInfo::next_trun_dts
int64_t next_trun_dts
Definition: isom.h:144
MOVStreamContext::stsc_index
unsigned int stsc_index
Definition: isom.h:195
av_sha_alloc
struct AVSHA * av_sha_alloc(void)
Allocate an AVSHA context.
Definition: sha.c:46
mov_read_tenc
static int mov_read_tenc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:7976
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:3302
mov_finalize_packet
static int mov_finalize_packet(AVFormatContext *s, AVStream *st, AVIndexEntry *sample, int64_t current_index, AVPacket *pkt)
Definition: mov.c:11121
MOVIndexRange
Definition: isom.h:168
mov_read_seek
static int mov_read_seek(AVFormatContext *s, int stream_index, int64_t sample_time, int flags)
Definition: mov.c:11503
bprint.h
MOVContext::advanced_editlist
int advanced_editlist
Definition: isom.h:346
MOVStreamContext::time_scale
int time_scale
Definition: isom.h:210
mlp_parse.h
mac_to_unicode
static const uint32_t mac_to_unicode[128]
Definition: mov.c:150
AVStreamGroupTileGrid::width
int width
Width of the final image for presentation.
Definition: avformat.h:1036
MOVStreamContext::bytes_per_frame
unsigned int bytes_per_frame
Definition: isom.h:217
AVSphericalMapping::roll
int32_t roll
Rotation around the forward vector [-180, 180].
Definition: spherical.h:146
IAMFContext::nb_audio_elements
int nb_audio_elements
Definition: iamf.h:132
MOVIndexRange::end
int64_t end
Definition: isom.h:170
AV_CODEC_ID_NONE
@ AV_CODEC_ID_NONE
Definition: codec_id.h:50
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:256
AVPacket::pts
int64_t pts
Presentation timestamp in AVStream->time_base units; the time at which the decompressed packet will b...
Definition: packet.h:581
avio_internal.h
MOVCtts::offset
int offset
Definition: isom.h:70
mov_read_trex
static int mov_read_trex(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5684
search_frag_timestamp
static int search_frag_timestamp(AVFormatContext *s, MOVFragmentIndex *frag_index, AVStream *st, int64_t timestamp)
Definition: mov.c:1716
HEIFItem::width
int width
Definition: isom.h:302
FLAGS
#define FLAGS
Definition: mov.c:11560
MOVStreamContext::stereo3d
AVStereo3D * stereo3d
Definition: isom.h:263
mov_fix_index
static void mov_fix_index(MOVContext *mov, AVStream *st)
Fix ffstream(st)->index_entries, so that it contains only the entries (and the entries which are need...
Definition: mov.c:4207
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:7824
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:3157
internal.h
AV_SPHERICAL_FISHEYE
@ AV_SPHERICAL_FISHEYE
Fisheye projection (Apple).
Definition: spherical.h:84
AVCodecParameters::height
int height
Definition: codec_par.h:135
AV_TIME_BASE
#define AV_TIME_BASE
Internal time base represented as integer.
Definition: avutil.h:253
MOVStreamContext::stps_count
unsigned int stps_count
Definition: isom.h:197
AVCodecParameters::block_align
int block_align
Audio only.
Definition: codec_par.h:191
AV_CODEC_ID_TTML
@ AV_CODEC_ID_TTML
Definition: codec_id.h:595
rb_size
static int rb_size(AVIOContext *pb, int64_t *value, int size)
Definition: mov.c:8800
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:3056
AV_FIELD_BB
@ AV_FIELD_BB
Bottom coded first, bottom displayed first.
Definition: defs.h:215
AV_PKT_DATA_ICC_PROFILE
@ AV_PKT_DATA_ICC_PROFILE
ICC profile data consisting of an opaque octet buffer following the format described by ISO 15076-1.
Definition: packet.h:271
AV_STEREO3D_TOPBOTTOM
@ AV_STEREO3D_TOPBOTTOM
Views are on top of each other.
Definition: stereo3d.h:76
MOVFragment::duration
unsigned duration
Definition: isom.h:108
AVIAMFMixPresentation
Information on how to render and mix one or more AVIAMFAudioElement to generate the final audio outpu...
Definition: iamf.h:613
ff_id3v1_genre_str
const char *const ff_id3v1_genre_str[ID3v1_GENRE_MAX+1]
ID3v1 genres.
Definition: id3v1.c:26
MOVStreamContext::sample_sizes
unsigned int * sample_sizes
Definition: isom.h:206
MOVContext::frag_index
MOVFragmentIndex frag_index
Definition: isom.h:359
mov_read_vpcc
static int mov_read_vpcc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6353
AV_CODEC_ID_PCM_F64BE
@ AV_CODEC_ID_PCM_F64BE
Definition: codec_id.h:359
AV_CODEC_ID_HEVC
@ AV_CODEC_ID_HEVC
Definition: codec_id.h:228
value
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf default value
Definition: writing_filters.txt:86
av_url_split
void av_url_split(char *proto, int proto_size, char *authorization, int authorization_size, char *hostname, int hostname_size, int *port_ptr, char *path, int path_size, const char *url)
Split a URL string into components.
Definition: utils.c:361
MOVStreamContext::dref_id
int dref_id
Definition: isom.h:224
FFMIN
#define FFMIN(a, b)
Definition: macros.h:49
av_d2q
AVRational av_d2q(double d, int max)
Convert a double precision floating point number to a rational.
Definition: rational.c:106
fix_frag_index_entries
static void fix_frag_index_entries(MOVFragmentIndex *frag_index, int index, int id, int entries)
Definition: mov.c:1802
mov_finalize_stsd_codec
static int mov_finalize_stsd_codec(MOVContext *c, AVIOContext *pb, AVStream *st, MOVStreamContext *sc)
Definition: mov.c:2906
AV_CH_FRONT_LEFT
#define AV_CH_FRONT_LEFT
Definition: channel_layout.h:175
AV_CODEC_ID_PCM_S32BE
@ AV_CODEC_ID_PCM_S32BE
Definition: codec_id.h:346
mov_read_mdcv
static int mov_read_mdcv(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6444
av_mallocz
void * av_mallocz(size_t size)
Allocate a memory block with alignment suitable for all memory accesses (including vectors if availab...
Definition: mem.c:256
AV_TIMECODE_FLAG_ALLOWNEGATIVE
@ AV_TIMECODE_FLAG_ALLOWNEGATIVE
negative time values are allowed
Definition: timecode.h:38
mov_read_mdat
static int mov_read_mdat(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1371
AV_CODEC_ID_VC1
@ AV_CODEC_ID_VC1
Definition: codec_id.h:122
demux.h
AV_DISPOSITION_DEPENDENT
#define AV_DISPOSITION_DEPENDENT
The stream is intended to be mixed with another stream before presentation.
Definition: avformat.h:705
MOVStreamContext::pb
AVIOContext * pb
Definition: isom.h:174
mov_read_keys
static int mov_read_keys(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5299
mov_read_iref_cdsc
static int mov_read_iref_cdsc(MOVContext *c, AVIOContext *pb, uint32_t type, int version)
Definition: mov.c:9111
AVCodecParameters::color_range
enum AVColorRange color_range
Video only.
Definition: codec_par.h:166
AV_CH_SIDE_RIGHT
#define AV_CH_SIDE_RIGHT
Definition: channel_layout.h:185
len
int len
Definition: vorbis_enc_data.h:426
AV_CODEC_ID_JPEG2000
@ AV_CODEC_ID_JPEG2000
Definition: codec_id.h:140
exif.h
MOVFragment::size
unsigned size
Definition: isom.h:109
MOV_TFHD_DEFAULT_SIZE
#define MOV_TFHD_DEFAULT_SIZE
Definition: isom.h:405
MOVTimeToSample::count
unsigned int count
Definition: isom.h:58
ff_get_wav_header
int ff_get_wav_header(AVFormatContext *s, AVIOContext *pb, AVCodecParameters *par, int size, int big_endian)
Definition: riffdec.c:95
AVCOL_SPC_UNSPECIFIED
@ AVCOL_SPC_UNSPECIFIED
Definition: pixfmt.h:703
fix_stream_ids
static void fix_stream_ids(AVFormatContext *s)
Definition: mov.c:10682
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:4653
AVCodecParameters::coded_side_data
AVPacketSideData * coded_side_data
Additional data associated with the entire stream.
Definition: codec_par.h:81
mov_read_svq3
static int mov_read_svq3(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2380
AVSHA
hash context
Definition: sha.c:35
AVCOL_RANGE_MPEG
@ AVCOL_RANGE_MPEG
Narrow or limited range content.
Definition: pixfmt.h:760
av_calloc
void * av_calloc(size_t nmemb, size_t size)
Definition: mem.c:264
MOVFragmentStreamInfo::tfdt_dts
int64_t tfdt_dts
Definition: isom.h:143
AV_IAMF_AUDIO_ELEMENT_TYPE_SCENE
@ AV_IAMF_AUDIO_ELEMENT_TYPE_SCENE
Definition: iamf.h:346
AVCodecParameters::field_order
enum AVFieldOrder field_order
Video only.
Definition: codec_par.h:161
av_get_packet
int av_get_packet(AVIOContext *s, AVPacket *pkt, int size)
Allocate and read the payload of a packet and initialize its fields with default values.
Definition: utils.c:98
mov_read_iinf
static int mov_read_iinf(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:8997
ff_read_string_to_bprint_overwrite
int64_t ff_read_string_to_bprint_overwrite(AVIOContext *s, struct AVBPrint *bp, int64_t max_len)
Read a whole null-terminated string of text from AVIOContext to an AVBPrint buffer overwriting its co...
Definition: aviobuf.c:863
AVStreamGroupTileGrid::horizontal
int horizontal
Offset in pixels from the left edge of the canvas where the tile should be placed.
Definition: avformat.h:995
get_stream_info_time
static int64_t get_stream_info_time(MOVFragmentStreamInfo *frag_stream_info)
Definition: mov.c:1666
MP4TrackKindValueMapping
Definition: isom.h:483
fix_index_entry_timestamps
static void fix_index_entry_timestamps(AVStream *st, int end_index, int64_t end_ts, int64_t *frame_duration_buffer, int frame_duration_buffer_size)
Rewrite timestamps of index entries in the range [end_index - frame_duration_buffer_size,...
Definition: mov.c:4058
AV_WB8
#define AV_WB8(p, d)
Definition: intreadwrite.h:392
MOVStreamContext::chunk_count
unsigned int chunk_count
Definition: isom.h:180
av_cmp_q
static int av_cmp_q(AVRational a, AVRational b)
Compare two rationals.
Definition: rational.h:89
MOVStreamContext::data_size
int64_t data_size
Definition: isom.h:235
AV_TIMECODE_FLAG_DROPFRAME
@ AV_TIMECODE_FLAG_DROPFRAME
timecode is drop frame
Definition: timecode.h:36
language
Undefined Behavior In the C language
Definition: undefined.txt:3
MOVStreamContext::ambient
AVAmbientViewingEnvironment * ambient
Definition: isom.h:271
mov_read_tmcd
static int mov_read_tmcd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6342
mov_chan.h
AVStream::disposition
int disposition
Stream disposition - a combination of AV_DISPOSITION_* flags.
Definition: avformat.h:813
MOVStreamContext::ambient_size
size_t ambient_size
Definition: isom.h:272
tag
uint32_t tag
Definition: movenc.c:1995
AVStream::id
int id
Format-specific stream ID.
Definition: avformat.h:756
ret
ret
Definition: filter_design.txt:187
AVStream
Stream structure.
Definition: avformat.h:744
AV_CODEC_ID_APV
@ AV_CODEC_ID_APV
Definition: codec_id.h:332
AV_LOG_FATAL
#define AV_LOG_FATAL
Something went wrong and recovery is not possible.
Definition: log.h:204
HEIFItem::extent_length
int64_t extent_length
Definition: isom.h:300
MOVEncryptionIndex::nb_encrypted_samples
unsigned int nb_encrypted_samples
Definition: isom.h:129
mov_read_senc
static int mov_read_senc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:7527
avio_seek
int64_t avio_seek(AVIOContext *s, int64_t offset, int whence)
fseek() equivalent for AVIOContext.
Definition: aviobuf.c:236
FFSWAP
#define FFSWAP(type, a, b)
Definition: macros.h:52
AVClass::class_name
const char * class_name
The name of the class; usually it is the same name as the context structure type to which the AVClass...
Definition: log.h:81
AVEncryptionInfo::key_id
uint8_t * key_id
The ID of the key used to encrypt the packet.
Definition: encryption_info.h:63
av_strlcat
size_t av_strlcat(char *dst, const char *src, size_t size)
Append the string src to the string dst, but to a total length of no more than size - 1 bytes,...
Definition: avstring.c:95
MOVStreamContext::stts_data
MOVStts * stts_data
Definition: isom.h:187
AVSphericalMapping::pitch
int32_t pitch
Rotation around the right vector [-90, 90].
Definition: spherical.h:145
AVStreamGroup::metadata
AVDictionary * metadata
Metadata that applies to the whole group.
Definition: avformat.h:1145
avio_rb16
unsigned int avio_rb16(AVIOContext *s)
Definition: aviobuf.c:749
AVStereo3D::type
enum AVStereo3DType type
How views are packed within the video.
Definition: stereo3d.h:207
MOVSbgp::index
unsigned int index
Definition: isom.h:123
HEIFItem::icc_profile_size
size_t icc_profile_size
Definition: isom.h:310
MOVContext::chapter_tracks
int * chapter_tracks
Definition: isom.h:342
cdt2
static const int16_t cdt2[8]
Definition: truemotion1data.h:43
AVSTREAM_PARSE_HEADERS
@ AVSTREAM_PARSE_HEADERS
Only parse headers, do not repack.
Definition: avformat.h:590
pos
unsigned int pos
Definition: spdifenc.c:414
avformat.h
MOVFragment::implicit_offset
uint64_t implicit_offset
Definition: isom.h:106
dict.h
av_packet_side_data_new
AVPacketSideData * av_packet_side_data_new(AVPacketSideData **psd, int *pnb_sd, enum AVPacketSideDataType type, size_t size, int flags)
Allocate a new packet side data.
Definition: packet.c:694
AV_AUDIO_SERVICE_TYPE_KARAOKE
@ AV_AUDIO_SERVICE_TYPE_KARAOKE
Definition: defs.h:244
mov_read_dmlp
static int mov_read_dmlp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:8491
flag
#define flag(name)
Definition: cbs_av1.c:496
AV_INPUT_BUFFER_PADDING_SIZE
#define AV_INPUT_BUFFER_PADDING_SIZE
Definition: defs.h:40
MOVStreamContext::pseudo_stream_id
int pseudo_stream_id
-1 means demux all ids
Definition: isom.h:220
MOVContext::time_scale
int time_scale
Definition: isom.h:324
id
enum AVCodecID id
Definition: dts2pts.c:549
mov_read_tfdt
static int mov_read_tfdt(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5710
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:5426
search_frag_moof_offset
static int search_frag_moof_offset(MOVFragmentIndex *frag_index, int64_t offset)
Definition: mov.c:1642
MOVFragment
Definition: isom.h:101
AV_DICT_MATCH_CASE
#define AV_DICT_MATCH_CASE
Only get an entry with exact-case key match.
Definition: dict.h:74
AV_RL32
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_RL32
Definition: bytestream.h:92
U
#define U(x)
Definition: vpx_arith.h:37
mov_switch_root
static int mov_switch_root(AVFormatContext *s, int64_t target, int index)
Definition: mov.c:10992
MOVContext::use_mfra_for
int use_mfra_for
Definition: isom.h:356
AVEncryptionInfo
This describes encryption info for a packet.
Definition: encryption_info.h:43
MOVStreamContext::encryption_index
MOVEncryptionIndex * encryption_index
Definition: isom.h:282
MIN_DATA_ENTRY_BOX_SIZE
#define MIN_DATA_ENTRY_BOX_SIZE
Definition: mov.c:637
AVStreamGroup
Definition: avformat.h:1098
av_get_media_type_string
const char * av_get_media_type_string(enum AVMediaType media_type)
Return a string describing the media_type enum, NULL if media_type is unknown.
Definition: utils.c:28
IAMFMixPresentation
Definition: iamf.h:107
AVStream::index
int index
stream index in AVFormatContext
Definition: avformat.h:750
avpriv_dv_init_demux
DVDemuxContext * avpriv_dv_init_demux(AVFormatContext *s)
Definition: dv.c:726
mov_seek_fragment
static int mov_seek_fragment(AVFormatContext *s, AVStream *st, int64_t timestamp)
Definition: mov.c:11351
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:2669
ff_codec_bmp_tags
const AVCodecTag ff_codec_bmp_tags[]
Definition: riff.c:36
MOVStreamContext::h_spacing
int h_spacing
pasp hSpacing
Definition: isom.h:230
mov_read_dec3
static int mov_read_dec3(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1078
get_frag_time
static int64_t get_frag_time(AVFormatContext *s, AVStream *dst_st, MOVFragmentIndex *frag_index, int index)
Definition: mov.c:1676
MOVStreamContext::sample_size
unsigned int sample_size
may contain value calculated from stsd or value from stsz atom
Definition: isom.h:203
HEVC_NAL_CRA_NUT
@ HEVC_NAL_CRA_NUT
Definition: hevc.h:50
AVStreamGroup::nb_streams
unsigned int nb_streams
Number of elements in AVStreamGroup.streams.
Definition: avformat.h:1152
mlp_samplerate
static int mlp_samplerate(int in)
Definition: mlp_parse.h:87
channel_layout.h
MOVStreamContext::duration_for_fps
int64_t duration_for_fps
Definition: isom.h:253
ISOM_DVCC_DVVC_SIZE
#define ISOM_DVCC_DVVC_SIZE
Definition: dovi_isom.h:29
mov_read_sbgp
static int mov_read_sbgp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:3814
MOVFragment::moof_offset
uint64_t moof_offset
Definition: isom.h:105
AVIO_SEEKABLE_NORMAL
#define AVIO_SEEKABLE_NORMAL
Seeking works like for a local file.
Definition: avio.h:41
av_packet_new_side_data
uint8_t * av_packet_new_side_data(AVPacket *pkt, enum AVPacketSideDataType type, size_t size)
Allocate new information of a packet.
Definition: packet.c:231
buffer
the frame and frame reference mechanism is intended to as much as expensive copies of that data while still allowing the filters to produce correct results The data is stored in buffers represented by AVFrame structures Several references can point to the same frame buffer
Definition: filter_design.txt:49
mov_read_glbl
static int mov_read_glbl(MOVContext *c, AVIOContext *pb, MOVAtom atom)
This function reads atom content and puts data in extradata without tag nor size unlike mov_read_extr...
Definition: mov.c:2442
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:7185
MOVTrackExt::size
unsigned size
Definition: isom.h:117
ff_remove_stream_group
void ff_remove_stream_group(AVFormatContext *s, AVStreamGroup *stg)
Remove a stream group from its AVFormatContext and free it.
Definition: avformat.c:121
AV_OPT_TYPE_INT
@ AV_OPT_TYPE_INT
Underlying C type is int.
Definition: opt.h:259
MOVContext::dv_fctx
AVFormatContext * dv_fctx
Definition: isom.h:335
av_channel_layout_uninit
void av_channel_layout_uninit(AVChannelLayout *channel_layout)
Free any allocated data in the channel layout and reset the channel count to 0.
Definition: channel_layout.c:442
AV_CODEC_ID_DVAUDIO
@ AV_CODEC_ID_DVAUDIO
Definition: codec_id.h:465
avformat_free_context
void avformat_free_context(AVFormatContext *s)
Free an AVFormatContext and all its streams.
Definition: avformat.c:141
MOVContext::aax_mode
unsigned int aax_mode
'aax' file has been detected
Definition: isom.h:361
mov_read_sv3d
static int mov_read_sv3d(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6707
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:1482
mov_get_skip_samples
static int64_t mov_get_skip_samples(AVStream *st, int sample)
Definition: mov.c:11486
MOVFragmentIndex
Definition: isom.h:160
AV_RB8
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_WL16 uint64_t_TMPL AV_WB64 unsigned int_TMPL AV_WB32 unsigned int_TMPL AV_WB24 unsigned int_TMPL AV_WB16 unsigned int_TMPL AV_RB8
Definition: bytestream.h:99
ref
static int ref[MAX_W *MAX_W]
Definition: jpeg2000dwt.c:117
AVStream::r_frame_rate
AVRational r_frame_rate
Real base framerate of the stream.
Definition: avformat.h:878
MOVStreamContext::tts_count
unsigned int tts_count
Definition: isom.h:182
MOVStreamContext::track_end
int64_t track_end
used for dts generation in fragmented movie files
Definition: isom.h:238
MOVStreamContext::sgpd_sync_count
uint32_t sgpd_sync_count
Definition: isom.h:245
MOVContext::fragment
MOVFragment fragment
current fragment in moof atom
Definition: isom.h:337
AVIndexEntry::pos
int64_t pos
Definition: avformat.h:599
AVIOContext::eof_reached
int eof_reached
true if was unable to read due to error or eof
Definition: avio.h:238
mov_metadata_int8_bypass_padding
static int mov_metadata_int8_bypass_padding(MOVContext *c, AVIOContext *pb, unsigned len, const char *key)
Definition: mov.c:111
AVStreamGroupLCEVC::width
int width
Width of the final stream for presentation.
Definition: avformat.h:1080
MOVDref::type
uint32_t type
Definition: isom.h:86
samples
Filter the word “frame” indicates either a video frame or a group of audio samples
Definition: filter_design.txt:8
mean
static float mean(const float *input, int size)
Definition: vf_nnedi.c:861
mov_read_covr
static int mov_read_covr(MOVContext *c, AVIOContext *pb, int type, int len)
Definition: mov.c:231
MOVParseTableEntry::type
uint32_t type
Definition: mov.c:83
Windows::Graphics::DirectX::Direct3D11::p
IDirect3DDxgiInterfaceAccess _COM_Outptr_ void ** p
Definition: vsrc_gfxcapture_winrt.hpp:53
AVMasteringDisplayMetadata::min_luminance
AVRational min_luminance
Min luminance of mastering display (cd/m^2).
Definition: mastering_display_metadata.h:52
MOVStreamContext::per_sample_iv_size
unsigned int per_sample_iv_size
Definition: isom.h:280
ff_codec_movsubtitle_tags
const AVCodecTag ff_codec_movsubtitle_tags[]
Definition: isom.c:75
av_mul_q
AVRational av_mul_q(AVRational b, AVRational c)
Multiply two rationals.
Definition: rational.c:80
AVPacket::stream_index
int stream_index
Definition: packet.h:590
MOVFragmentIndexItem::nb_stream_info
int nb_stream_info
Definition: isom.h:156
avio_skip
int64_t avio_skip(AVIOContext *s, int64_t offset)
Skip given number of bytes forward.
Definition: aviobuf.c:321
export_orphan_timecode
static void export_orphan_timecode(AVFormatContext *s)
Definition: mov.c:10032
mov_read_sbas
static int mov_read_sbas(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2513
MOVStreamContext::has_sidx
int has_sidx
Definition: isom.h:276
AV_CH_FRONT_RIGHT
#define AV_CH_FRONT_RIGHT
Definition: channel_layout.h:176
av_aes_ctr_crypt
void av_aes_ctr_crypt(struct AVAESCTR *a, uint8_t *dst, const uint8_t *src, int count)
Process a buffer using a previously initialized context.
Definition: aes_ctr.c:102
mov_metadata_gnre
static int mov_metadata_gnre(MOVContext *c, AVIOContext *pb, unsigned len, const char *key)
Definition: mov.c:134
AV_PKT_DATA_ENCRYPTION_INFO
@ AV_PKT_DATA_ENCRYPTION_INFO
This side data contains encryption info for how to decrypt the packet.
Definition: packet.h:252
MOV_MERGE_CTTS
#define MOV_MERGE_CTTS
Definition: mov.c:4583
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:2267
AVIAMFSubmix::nb_elements
unsigned int nb_elements
Number of elements in the submix.
Definition: iamf.h:572
MOVFragmentStreamInfo::id
int id
Definition: isom.h:140
AVIO_FLAG_READ
#define AVIO_FLAG_READ
read-only
Definition: avio.h:617
AV_PKT_DATA_AUDIO_SERVICE_TYPE
@ AV_PKT_DATA_AUDIO_SERVICE_TYPE
This side data should be associated with an audio stream and corresponds to enum AVAudioServiceType.
Definition: packet.h:117
av_spherical_alloc
AVSphericalMapping * av_spherical_alloc(size_t *size)
Allocate a AVSphericalVideo structure and initialize its fields to default values.
Definition: spherical.c:26
AV_OPT_FLAG_DECODING_PARAM
#define AV_OPT_FLAG_DECODING_PARAM
A generic parameter which can be set by the user for demuxing or decoding.
Definition: opt.h:356
mov_read_rtmd_track
static int mov_read_rtmd_track(AVFormatContext *s, AVStream *st)
Definition: mov.c:9814
AVMEDIA_TYPE_VIDEO
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:200
read_probe
static int read_probe(const AVProbeData *p)
Definition: cdg.c:30
MOVStreamContext::pb_is_copied
int pb_is_copied
Definition: isom.h:176
AV_CODEC_ID_PCM_S32LE
@ AV_CODEC_ID_PCM_S32LE
Definition: codec_id.h:345
AVCodecParameters::bits_per_coded_sample
int bits_per_coded_sample
The number of bits per sample in the codedwords.
Definition: codec_par.h:110
mov_parse_tiles
static int mov_parse_tiles(AVFormatContext *s)
Definition: mov.c:10415
mem.h
AVStreamGroup::type
enum AVStreamGroupParamsType type
Group type.
Definition: avformat.h:1125
MOVElst::time
int64_t time
Definition: isom.h:81
AVBufferRef
A reference to a data buffer.
Definition: buffer.h:82
HEIFGrid
Definition: isom.h:313
mov_read_iref_dimg
static int mov_read_iref_dimg(MOVContext *c, AVIOContext *pb, int version)
Definition: mov.c:9051
mov_read_pcmc
static int mov_read_pcmc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1996
build_open_gop_key_points
static int build_open_gop_key_points(AVStream *st)
Definition: mov.c:4520
mov_parse_stsd_audio
static void mov_parse_stsd_audio(MOVContext *c, AVIOContext *pb, AVStream *st, MOVStreamContext *sc)
Definition: mov.c:2727
IAMFContext::mix_presentations
IAMFMixPresentation ** mix_presentations
Definition: iamf.h:133
AV_CODEC_ID_PCM_U8
@ AV_CODEC_ID_PCM_U8
Definition: codec_id.h:342
MOVContext::trak_index
int trak_index
Index of the current 'trak'.
Definition: isom.h:331
mov_read_timecode_track
static int mov_read_timecode_track(AVFormatContext *s, AVStream *st)
Definition: mov.c:9840
HEIFGrid::item
HEIFItem * item
Definition: isom.h:314
AVSphericalMapping::bound_left
uint32_t bound_left
Distance from the left edge.
Definition: spherical.h:185
mov_read_mac_string
static int mov_read_mac_string(MOVContext *c, AVIOContext *pb, int len, char *dst, int dstlen)
Definition: mov.c:169
MOVEncryptionIndex::auxiliary_info_sizes
uint8_t * auxiliary_info_sizes
Definition: isom.h:132
MOVFragment::stsd_id
unsigned stsd_id
Definition: isom.h:107
AVCodecParameters::video_delay
int video_delay
Video only.
Definition: codec_par.h:175
HEIFGrid::tile_id_list
int16_t * tile_id_list
Definition: isom.h:316
avpriv_request_sample
#define avpriv_request_sample(...)
Definition: tableprint_vlc.h:37
MOVStreamContext::tts_data
MOVTimeToSample * tts_data
Definition: isom.h:184
map
const VDPAUPixFmtMap * map
Definition: hwcontext_vdpau.c:71
avformat_stream_group_create
AVStreamGroup * avformat_stream_group_create(AVFormatContext *s, enum AVStreamGroupParamsType type, AVDictionary **options)
Add a new empty stream group to a media file.
Definition: options.c:433
AV_CHANNEL_LAYOUT_MONO
#define AV_CHANNEL_LAYOUT_MONO
Definition: channel_layout.h:394
AV_CODEC_ID_PCM_F64LE
@ AV_CODEC_ID_PCM_F64LE
Definition: codec_id.h:360
AVStreamGroupTileGrid::height
int height
Height of the final image for presentation.
Definition: avformat.h:1046
AVStereo3D::view
enum AVStereo3DView view
Determines which views are packed.
Definition: stereo3d.h:217
read_tfra
static int read_tfra(MOVContext *mov, AVIOContext *f)
Definition: mov.c:10050
av_free
#define av_free(p)
Definition: tableprint_vlc.h:34
AVDictionaryEntry
Definition: dict.h:90
av_add_q
AVRational av_add_q(AVRational b, AVRational c)
Add two rationals.
Definition: rational.c:93
AVCodecParameters::codec_id
enum AVCodecID codec_id
Specific type of the encoded data (the codec used).
Definition: codec_par.h:55
AVStereo3DView
AVStereo3DView
List of possible view types.
Definition: stereo3d.h:149
AVPacket
This structure stores compressed data.
Definition: packet.h:565
AVContentLightMetadata::MaxFALL
unsigned MaxFALL
Max average light level per frame (cd/m^2).
Definition: mastering_display_metadata.h:116
mov_parse_lcevc_streams
static int mov_parse_lcevc_streams(AVFormatContext *s)
Definition: mov.c:10632
mov_read_hfov
static int mov_read_hfov(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:7156
AV_OPT_TYPE_BOOL
@ AV_OPT_TYPE_BOOL
Underlying C type is int.
Definition: opt.h:327
MOVStreamContext::stps_data
unsigned * stps_data
partial sync sample for mpeg-2 open gop
Definition: isom.h:198
AV_CODEC_ID_ADPCM_IMA_WAV
@ AV_CODEC_ID_ADPCM_IMA_WAV
Definition: codec_id.h:377
MOVContext::nb_heif_item
int nb_heif_item
Definition: isom.h:383
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:35
av_dict_set
int av_dict_set(AVDictionary **pm, const char *key, const char *value, int flags)
Set the given entry in *pm, overwriting an existing entry.
Definition: dict.c:86
riff.h
av_dict_copy
int av_dict_copy(AVDictionary **dst, const AVDictionary *src, int flags)
Copy entries from one AVDictionary struct into another.
Definition: dict.c:247
av_encryption_info_alloc
AVEncryptionInfo * av_encryption_info_alloc(uint32_t subsample_count, uint32_t key_id_size, uint32_t iv_size)
Allocates an AVEncryptionInfo structure and sub-pointers to hold the given number of subsamples.
Definition: encryption_info.c:41
AVPacket::pos
int64_t pos
byte position in stream, -1 if unknown
Definition: packet.h:608
FFInputFormat
Definition: demux.h:47
mov_metadata_loci
static int mov_metadata_loci(MOVContext *c, AVIOContext *pb, unsigned len)
Definition: mov.c:274
mov_read_eyes
static int mov_read_eyes(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6917
AV_CODEC_ID_ILBC
@ AV_CODEC_ID_ILBC
Definition: codec_id.h:518
AV_CHAN_AMBISONIC_BASE
@ AV_CHAN_AMBISONIC_BASE
Range of channels between AV_CHAN_AMBISONIC_BASE and AV_CHAN_AMBISONIC_END represent Ambisonic compon...
Definition: channel_layout.h:108
MOV_TRUN_SAMPLE_SIZE
#define MOV_TRUN_SAMPLE_SIZE
Definition: isom.h:413
MOVStreamContext::tmcd_flags
uint32_t tmcd_flags
tmcd track flags
Definition: isom.h:236
int32_t
int32_t
Definition: audioconvert.c:56
HEIFItem::rotation
int rotation
Definition: isom.h:304
MOVAtom::type
uint32_t type
Definition: isom.h:95
distance
static float distance(float x, float y, int band)
Definition: nellymoserenc.c:231
AVSTREAM_PARSE_FULL
@ AVSTREAM_PARSE_FULL
full parsing and repack
Definition: avformat.h:589
parse_timecode_in_framenum_format
static int parse_timecode_in_framenum_format(AVFormatContext *s, AVStream *st, int64_t value, int flags)
Definition: mov.c:9800
MOVStreamContext::tmcd_nb_frames
uint8_t tmcd_nb_frames
tmcd number of frames per tick / second
Definition: isom.h:237
AVIAMFSubmixElement
Submix element as defined in section 3.7 of IAMF.
Definition: iamf.h:446
replaygain.h
MOVFragmentIndexItem::headers_read
int headers_read
Definition: isom.h:154
AV_CODEC_ID_VP8
@ AV_CODEC_ID_VP8
Definition: codec_id.h:192
AVERROR_BUG
#define AVERROR_BUG
Internal bug, also see AVERROR_BUG2.
Definition: error.h:52
MOVStreamContext::start_pad
int start_pad
amount of samples to skip due to enc-dec delay
Definition: isom.h:239
MP4TrackKindValueMapping::value
const char * value
Definition: isom.h:485
AVStereo3DType
AVStereo3DType
List of possible 3D Types.
Definition: stereo3d.h:48
MOVDref::filename
char filename[64]
Definition: isom.h:90
ff_mov_read_chnl
int ff_mov_read_chnl(AVFormatContext *s, AVIOContext *pb, AVStream *st)
Read 'chnl' tag from the input stream.
Definition: mov_chan.c:729
MOVStsc::count
int count
Definition: isom.h:75
AV_CODEC_ID_PCM_F32LE
@ AV_CODEC_ID_PCM_F32LE
Definition: codec_id.h:358
ff_mov_demuxer
const FFInputFormat ff_mov_demuxer
Definition: mov.c:11621
AVCodecParameters::bit_rate
int64_t bit_rate
The average bitrate of the encoded data (in bits per second).
Definition: codec_par.h:97
MOVStts::count
unsigned int count
Definition: isom.h:64
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
MOVStreamContext::display_matrix
int32_t * display_matrix
Definition: isom.h:262
MOVContext::heif_grid
HEIFGrid * heif_grid
Definition: isom.h:384
MOVStreamContext::min_sample_duration
uint32_t min_sample_duration
Definition: isom.h:250
MOVStreamContext::current_index
int64_t current_index
Definition: isom.h:214
AVERROR_INVALIDDATA
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:61
ff_mov_track_kind_table
const struct MP4TrackKindMapping ff_mov_track_kind_table[]
Definition: isom.c:451
get_curr_st
static AVStream * get_curr_st(MOVContext *c)
Get the current stream in the parsing process.
Definition: mov.c:213
MOVStreamContext::stts_allocated_size
unsigned int stts_allocated_size
Definition: isom.h:186
MOVFragmentStreamInfo::index_entry
int index_entry
Definition: isom.h:147
cenc_decrypt
static int cenc_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
Definition: mov.c:8331
MOVStreamContext::format
uint32_t format
Definition: isom.h:274
MKTAG
#define MKTAG(a, b, c, d)
Definition: macros.h:55
ffio_read_size
int ffio_read_size(AVIOContext *s, unsigned char *buf, int size)
Read size bytes from AVIOContext into buf.
Definition: aviobuf.c:665
MOVStreamContext::sync_group_count
unsigned int sync_group_count
Definition: isom.h:242
MOVContext::bitrates_count
int bitrates_count
Definition: isom.h:354
AV_CODEC_ID_VORBIS
@ AV_CODEC_ID_VORBIS
Definition: codec_id.h:464
AVDictionaryEntry::value
char * value
Definition: dict.h:92
AVStream::start_time
int64_t start_time
Decoding: pts of the first frame of the stream in presentation order, in stream time base.
Definition: avformat.h:793
MOVStreamContext::id
int id
AVStream id.
Definition: isom.h:177
MOVStreamContext::samples_per_frame
unsigned int samples_per_frame
Definition: isom.h:218
MOVStreamContext::tts_allocated_size
unsigned int tts_allocated_size
Definition: isom.h:183
MOVElst::duration
int64_t duration
Definition: isom.h:80
ac3tab.h
avstring.h
mov_read_ispe
static int mov_read_ispe(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:9184
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:9145
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:1240
mov_read_mfra
static int mov_read_mfra(MOVContext *c, AVIOContext *f)
Definition: mov.c:10105
AV_CODEC_ID_FLV1
@ AV_CODEC_ID_FLV1
Definition: codec_id.h:73
mov_metadata_int8_no_padding
static int mov_metadata_int8_no_padding(MOVContext *c, AVIOContext *pb, unsigned len, const char *key)
Definition: mov.c:125
flac.h
AVStreamGroupTileGrid::idx
unsigned int idx
Index of the stream in the group this tile references.
Definition: avformat.h:990
AVTimecode
Definition: timecode.h:41
get_frag_stream_info
static MOVFragmentStreamInfo * get_frag_stream_info(MOVFragmentIndex *frag_index, int index, int id)
Definition: mov.c:1587
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:8595
MOVContext::heif_item
HEIFItem ** heif_item
Definition: isom.h:382
MOVStreamContext::stts_count
unsigned int stts_count
Definition: isom.h:185
MOV_TRUN_SAMPLE_CTS
#define MOV_TRUN_SAMPLE_CTS
Definition: isom.h:415
HEIFItem::iref_list
HEIFItemRef * iref_list
Definition: isom.h:296
AV_OPT_TYPE_CONST
@ AV_OPT_TYPE_CONST
Special option type for declaring named constants.
Definition: opt.h:299
MOV_ISMV_TTML_TAG
#define MOV_ISMV_TTML_TAG
Definition: isom.h:478
snprintf
#define snprintf
Definition: snprintf.h:34
IAMFMixPresentation::mix_presentation_id
unsigned int mix_presentation_id
Definition: iamf.h:114
AVCodecParameters::initial_padding
int initial_padding
Audio only.
Definition: codec_par.h:203
AV_CODEC_ID_PCM_S24BE
@ AV_CODEC_ID_PCM_S24BE
Definition: codec_id.h:350
mov_read_st3d
static int mov_read_st3d(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6579
mov_read_imir
static int mov_read_imir(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:9226
is_open_key_sample
static int is_open_key_sample(const MOVStreamContext *sc, int sample)
Definition: mov.c:11370
mov_read_dvc1
static int mov_read_dvc1(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2488
MOVStreamContext::elst_count
unsigned int elst_count
Definition: isom.h:200
av_color_transfer_name
const char * av_color_transfer_name(enum AVColorTransferCharacteristic transfer)
Definition: pixdesc.c:3823
AVChannelCustom::id
enum AVChannel id
Definition: channel_layout.h:284
mov_read_atom_into_extradata
static int64_t mov_read_atom_into_extradata(MOVContext *c, AVIOContext *pb, MOVAtom atom, AVCodecParameters *par, uint8_t *buf)
Definition: mov.c:2204
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:9701
AV_CODEC_ID_DNXHD
@ AV_CODEC_ID_DNXHD
Definition: codec_id.h:151
channel
channel
Definition: ebur128.h:39
MOVStreamContext::default_encrypted_sample
AVEncryptionInfo * default_encrypted_sample
Definition: isom.h:281
MOVContext::cur_item_id
int cur_item_id
Definition: isom.h:381
av_timecode_make_string
char * av_timecode_make_string(const AVTimecode *tc, char *buf, int framenum_arg)
Load timecode string in buf.
Definition: timecode.c:104
AVFMT_EVENT_FLAG_METADATA_UPDATED
#define AVFMT_EVENT_FLAG_METADATA_UPDATED
Definition: avformat.h:1638
AV_DICT_DONT_STRDUP_KEY
#define AV_DICT_DONT_STRDUP_KEY
Take ownership of a key that's been allocated with av_malloc() or another memory allocation function.
Definition: dict.h:77
MOVContext::next_root_atom
int64_t next_root_atom
offset of the next root atom
Definition: isom.h:350
MOVContext::found_iinf
int found_iinf
'iinf' atom has been found
Definition: isom.h:328
MOVContext::meta_keys_count
unsigned meta_keys_count
Definition: isom.h:333
avcodec_parameters_copy
int avcodec_parameters_copy(AVCodecParameters *dst, const AVCodecParameters *src)
Copy the contents of src to dst.
Definition: codec_par.c:107
iamf_reader.h
AVStreamGroupTileGrid::background
uint8_t background[4]
The pixel value per channel in RGBA format used if no pixel of any tile is located at a particular pi...
Definition: avformat.h:1010
MOVStreamContext::palette
uint32_t palette[256]
Definition: isom.h:233
cenc_scheme_decrypt
static int cenc_scheme_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
Definition: mov.c:8087
MOVFragment::track_id
unsigned track_id
Definition: isom.h:103
mov_read_hdlr
static int mov_read_hdlr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:782
mov_parse_stsd_data
static int mov_parse_stsd_data(MOVContext *c, AVIOContext *pb, AVStream *st, MOVStreamContext *sc, int64_t size)
Definition: mov.c:2860
AV_CH_SIDE_LEFT
#define AV_CH_SIDE_LEFT
Definition: channel_layout.h:184
ff_iamf_read_deinit
void ff_iamf_read_deinit(IAMFDemuxContext *c)
Definition: iamf_reader.c:342
AV_CODEC_ID_PRORES
@ AV_CODEC_ID_PRORES
Definition: codec_id.h:200
AV_RB16
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_WL16 uint64_t_TMPL AV_WB64 unsigned int_TMPL AV_WB32 unsigned int_TMPL AV_WB24 unsigned int_TMPL AV_RB16
Definition: bytestream.h:98
av_realloc
void * av_realloc(void *ptr, size_t size)
Allocate, reallocate, or free a block of memory.
Definition: mem.c:155
av_encryption_init_info_add_side_data
uint8_t * av_encryption_init_info_add_side_data(const AVEncryptionInitInfo *info, size_t *side_data_size)
Allocates and initializes side data that holds a copy of the given encryption init info.
Definition: encryption_info.c:292
av_fourcc2str
#define av_fourcc2str(fourcc)
Definition: avutil.h:347
ff_mov_read_chan
int ff_mov_read_chan(AVFormatContext *s, AVIOContext *pb, AVStream *st, int64_t size)
Read 'chan' tag from the input stream.
Definition: mov_chan.c:524
av_index_search_timestamp
int av_index_search_timestamp(AVStream *st, int64_t timestamp, int flags)
Get the index for a specific timestamp.
Definition: seek.c:245
mov_read_pitm
static int mov_read_pitm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:8819
MOVContext::ignore_chapters
int ignore_chapters
Definition: isom.h:348
MOVTimeToSample::offset
int offset
Definition: isom.h:60
mov_read_dac3
static int mov_read_dac3(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:853
MP4TrackKindMapping
Definition: isom.h:488
ff_alloc_extradata
int ff_alloc_extradata(AVCodecParameters *par, int size)
Allocate extradata with additional AV_INPUT_BUFFER_PADDING_SIZE at end which is always set to 0.
Definition: utils.c:237
HEIFItem::nb_iref_list
int nb_iref_list
Definition: isom.h:297
AV_DISPOSITION_NON_DIEGETIC
#define AV_DISPOSITION_NON_DIEGETIC
The stream is intended to be mixed with a spatial audio track.
Definition: avformat.h:682
avio_feof
int avio_feof(AVIOContext *s)
Similar to feof() but also returns nonzero on read errors.
Definition: aviobuf.c:349
mc
#define mc
Definition: vf_colormatrix.c:100
MOVStreamContext::ffindex
int ffindex
AVStream index.
Definition: isom.h:178
HEIFItem::extent_offset
int64_t extent_offset
Definition: isom.h:301
mov_read_stsz
static int mov_read_stsz(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:3419