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 #include <stdlib.h>
32 
33 #include "libavutil/attributes.h"
34 #include "libavutil/bprint.h"
36 #include "libavutil/dovi_meta.h"
37 #include "libavutil/internal.h"
38 #include "libavutil/intreadwrite.h"
39 #include "libavutil/intfloat.h"
40 #include "libavutil/mathematics.h"
41 #include "libavutil/avassert.h"
42 #include "libavutil/avstring.h"
43 #include "libavutil/dict.h"
44 #include "libavutil/display.h"
45 #include "libavutil/mem.h"
46 #include "libavutil/opt.h"
47 #include "libavutil/aes.h"
48 #include "libavutil/aes_ctr.h"
49 #include "libavutil/pixdesc.h"
50 #include "libavutil/sha.h"
51 #include "libavutil/spherical.h"
52 #include "libavutil/stereo3d.h"
53 #include "libavutil/timecode.h"
54 #include "libavutil/uuid.h"
55 #include "libavcodec/ac3tab.h"
56 #include "libavcodec/exif.h"
57 #include "libavcodec/flac.h"
58 #include "libavcodec/hevc/hevc.h"
60 #include "libavcodec/mlp_parse.h"
61 #include "avformat.h"
62 #include "internal.h"
63 #include "avio_internal.h"
64 #include "demux.h"
65 #include "dvdclut.h"
66 #include "iamf_parse.h"
67 #include "iamf_reader.h"
68 #include "dovi_isom.h"
69 #include "riff.h"
70 #include "isom.h"
71 #include "libavcodec/get_bits.h"
72 #include "id3v1.h"
73 #include "mov_chan.h"
74 #include "replaygain.h"
75 
76 #if CONFIG_ZLIB
77 #include <zlib.h>
78 #endif
79 
80 #include "qtpalette.h"
81 
82 /* those functions parse an atom */
83 /* links atom IDs to parse functions */
84 typedef struct MOVParseTableEntry {
85  uint32_t type;
86  int (*parse)(MOVContext *ctx, AVIOContext *pb, MOVAtom atom);
88 
89 static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom);
90 static int mov_read_mfra(MOVContext *c, AVIOContext *f);
92 
94  unsigned len, const char *key)
95 {
96  char buf[16];
97 
98  short current, total = 0;
99  avio_rb16(pb); // unknown
100  current = avio_rb16(pb);
101  if (len >= 6)
102  total = avio_rb16(pb);
103  if (!total)
104  snprintf(buf, sizeof(buf), "%d", current);
105  else
106  snprintf(buf, sizeof(buf), "%d/%d", current, total);
107  c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
108  av_dict_set(&c->fc->metadata, key, buf, 0);
109 
110  return 0;
111 }
112 
114  unsigned len, const char *key)
115 {
116  /* bypass padding bytes */
117  avio_r8(pb);
118  avio_r8(pb);
119  avio_r8(pb);
120 
121  c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
122  av_dict_set_int(&c->fc->metadata, key, avio_r8(pb), 0);
123 
124  return 0;
125 }
126 
128  unsigned len, const char *key)
129 {
130  c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
131  av_dict_set_int(&c->fc->metadata, key, avio_r8(pb), 0);
132 
133  return 0;
134 }
135 
137  unsigned len, const char *key)
138 {
139  short genre;
140 
141  avio_r8(pb); // unknown
142 
143  genre = avio_r8(pb);
144  if (genre < 1 || genre > ID3v1_GENRE_MAX)
145  return 0;
146  c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
147  av_dict_set(&c->fc->metadata, key, ff_id3v1_genre_str[genre-1], 0);
148 
149  return 0;
150 }
151 
152 static const uint32_t mac_to_unicode[128] = {
153  0x00C4,0x00C5,0x00C7,0x00C9,0x00D1,0x00D6,0x00DC,0x00E1,
154  0x00E0,0x00E2,0x00E4,0x00E3,0x00E5,0x00E7,0x00E9,0x00E8,
155  0x00EA,0x00EB,0x00ED,0x00EC,0x00EE,0x00EF,0x00F1,0x00F3,
156  0x00F2,0x00F4,0x00F6,0x00F5,0x00FA,0x00F9,0x00FB,0x00FC,
157  0x2020,0x00B0,0x00A2,0x00A3,0x00A7,0x2022,0x00B6,0x00DF,
158  0x00AE,0x00A9,0x2122,0x00B4,0x00A8,0x2260,0x00C6,0x00D8,
159  0x221E,0x00B1,0x2264,0x2265,0x00A5,0x00B5,0x2202,0x2211,
160  0x220F,0x03C0,0x222B,0x00AA,0x00BA,0x03A9,0x00E6,0x00F8,
161  0x00BF,0x00A1,0x00AC,0x221A,0x0192,0x2248,0x2206,0x00AB,
162  0x00BB,0x2026,0x00A0,0x00C0,0x00C3,0x00D5,0x0152,0x0153,
163  0x2013,0x2014,0x201C,0x201D,0x2018,0x2019,0x00F7,0x25CA,
164  0x00FF,0x0178,0x2044,0x20AC,0x2039,0x203A,0xFB01,0xFB02,
165  0x2021,0x00B7,0x201A,0x201E,0x2030,0x00C2,0x00CA,0x00C1,
166  0x00CB,0x00C8,0x00CD,0x00CE,0x00CF,0x00CC,0x00D3,0x00D4,
167  0xF8FF,0x00D2,0x00DA,0x00DB,0x00D9,0x0131,0x02C6,0x02DC,
168  0x00AF,0x02D8,0x02D9,0x02DA,0x00B8,0x02DD,0x02DB,0x02C7,
169 };
170 
172  char *dst, int dstlen)
173 {
174  char *p = dst;
175  char *end = dst+dstlen-1;
176  int i;
177 
178  for (i = 0; i < len; i++) {
179  uint8_t t, c = avio_r8(pb);
180 
181  if (p >= end)
182  continue;
183 
184  if (c < 0x80)
185  *p++ = c;
186  else if (p < end)
187  PUT_UTF8(mac_to_unicode[c-0x80], t, if (p < end) *p++ = t;);
188  }
189  *p = 0;
190  return p - dst;
191 }
192 
193 /**
194  * Get the requested item.
195  */
196 static HEIFItem *get_heif_item(MOVContext *c, unsigned id)
197 {
198  HEIFItem *item = NULL;
199 
200  for (int i = 0; i < c->nb_heif_item; i++) {
201  if (!c->heif_item[i] || c->heif_item[i]->item_id != id)
202  continue;
203 
204  item = c->heif_item[i];
205  break;
206  }
207 
208  return item;
209 }
210 
211 /**
212  * Get the current stream in the parsing process. This can either be the
213  * latest stream added to the context, or the stream referenced by an item.
214  */
216 {
217  AVStream *st = NULL;
218  HEIFItem *item;
219 
220  if (c->fc->nb_streams < 1)
221  return NULL;
222 
223  if (c->cur_item_id == -1)
224  return c->fc->streams[c->fc->nb_streams-1];
225 
226  item = get_heif_item(c, c->cur_item_id);
227  if (item)
228  st = item->st;
229 
230  return st;
231 }
232 
233 static int mov_read_covr(MOVContext *c, AVIOContext *pb, int type, int len)
234 {
235  AVStream *st;
236  MOVStreamContext *sc;
237  enum AVCodecID id;
238  int ret;
239 
240  switch (type) {
241  case 0xd: id = AV_CODEC_ID_MJPEG; break;
242  case 0xe: id = AV_CODEC_ID_PNG; break;
243  case 0x1b: id = AV_CODEC_ID_BMP; break;
244  default:
245  av_log(c->fc, AV_LOG_WARNING, "Unknown cover type: 0x%x.\n", type);
246  avio_skip(pb, len);
247  return 0;
248  }
249 
250  sc = av_mallocz(sizeof(*sc));
251  if (!sc)
252  return AVERROR(ENOMEM);
253  ret = ff_add_attached_pic(c->fc, NULL, pb, NULL, len);
254  if (ret < 0) {
255  av_free(sc);
256  return ret;
257  }
258  st = c->fc->streams[c->fc->nb_streams - 1];
259  st->priv_data = sc;
260  sc->id = st->id;
261  sc->refcount = 1;
262 
263  if (st->attached_pic.size >= 8 && id != AV_CODEC_ID_BMP) {
264  if (AV_RB64(st->attached_pic.data) == 0x89504e470d0a1a0a) {
265  id = AV_CODEC_ID_PNG;
266  } else {
267  id = AV_CODEC_ID_MJPEG;
268  }
269  }
270  st->codecpar->codec_id = id;
271 
272  return 0;
273 }
274 
275 // 3GPP TS 26.244
276 static int mov_metadata_loci(MOVContext *c, AVIOContext *pb, unsigned len)
277 {
278  char language[4] = { 0 };
279  char buf[200], place[100];
280  uint16_t langcode = 0;
281  double longitude, latitude, altitude;
282  const char *key = "location";
283 
284  if (len < 4 + 2 + 1 + 1 + 4 + 4 + 4) {
285  av_log(c->fc, AV_LOG_ERROR, "loci too short\n");
286  return AVERROR_INVALIDDATA;
287  }
288 
289  avio_skip(pb, 4); // version+flags
290  langcode = avio_rb16(pb);
291  ff_mov_lang_to_iso639(langcode, language);
292  len -= 6;
293 
294  len -= avio_get_str(pb, len, place, sizeof(place));
295  if (len < 1) {
296  av_log(c->fc, AV_LOG_ERROR, "place name too long\n");
297  return AVERROR_INVALIDDATA;
298  }
299  avio_skip(pb, 1); // role
300  len -= 1;
301 
302  if (len < 12) {
303  av_log(c->fc, AV_LOG_ERROR,
304  "loci too short (%u bytes left, need at least %d)\n", len, 12);
305  return AVERROR_INVALIDDATA;
306  }
307  longitude = ((int32_t) avio_rb32(pb)) / (float) (1 << 16);
308  latitude = ((int32_t) avio_rb32(pb)) / (float) (1 << 16);
309  altitude = ((int32_t) avio_rb32(pb)) / (float) (1 << 16);
310 
311  // Try to output in the same format as the ?xyz field
312  snprintf(buf, sizeof(buf), "%+08.4f%+09.4f", latitude, longitude);
313  if (altitude)
314  av_strlcatf(buf, sizeof(buf), "%+f", altitude);
315  av_strlcatf(buf, sizeof(buf), "/%s", place);
316 
317  if (*language && strcmp(language, "und")) {
318  char key2[16];
319  snprintf(key2, sizeof(key2), "%s-%s", key, language);
320  av_dict_set(&c->fc->metadata, key2, buf, 0);
321  }
322  c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
323  return av_dict_set(&c->fc->metadata, key, buf, 0);
324 }
325 
326 static int mov_metadata_hmmt(MOVContext *c, AVIOContext *pb, unsigned len)
327 {
328  int i, n_hmmt;
329 
330  if (len < 2)
331  return 0;
332  if (c->ignore_chapters)
333  return 0;
334 
335  n_hmmt = avio_rb32(pb);
336  if (n_hmmt > len / 4)
337  return AVERROR_INVALIDDATA;
338  for (i = 0; i < n_hmmt && !pb->eof_reached; i++) {
339  int moment_time = avio_rb32(pb);
340  avpriv_new_chapter(c->fc, i, av_make_q(1, 1000), moment_time, AV_NOPTS_VALUE, NULL);
341  }
342  if (avio_feof(pb))
343  return AVERROR_INVALIDDATA;
344  return 0;
345 }
346 
348 {
349  char tmp_key[AV_FOURCC_MAX_STRING_SIZE] = {0};
350  char key2[32], language[4] = {0};
351  char *str = NULL;
352  const char *key = NULL;
353  uint16_t langcode = 0;
354  uint32_t data_type = 0, str_size_alloc;
355  uint64_t str_size;
356  int (*parse)(MOVContext*, AVIOContext*, unsigned, const char*) = NULL;
357  int raw = 0;
358  int num = 0;
360 
361  if (c->trak_index >= 0 && c->trak_index < c->fc->nb_streams)
362  metadata = &c->fc->streams[c->trak_index]->metadata;
363  else
364  metadata = &c->fc->metadata;
365 
366  switch (atom.type) {
367  case MKTAG( '@','P','R','M'): key = "premiere_version"; raw = 1; break;
368  case MKTAG( '@','P','R','Q'): key = "quicktime_version"; raw = 1; break;
369  case MKTAG( 'X','M','P','_'):
370  if (c->export_xmp) { key = "xmp"; raw = 1; } break;
371  case MKTAG( 'a','A','R','T'): key = "album_artist"; break;
372  case MKTAG( 'a','k','I','D'): key = "account_type";
374  case MKTAG( 'a','p','I','D'): key = "account_id"; break;
375  case MKTAG( 'c','a','t','g'): key = "category"; break;
376  case MKTAG( 'c','p','i','l'): key = "compilation";
378  case MKTAG( 'c','p','r','t'): key = "copyright"; break;
379  case MKTAG( 'd','e','s','c'): key = "description"; break;
380  case MKTAG( 'd','i','s','k'): key = "disc";
382  case MKTAG( 'e','g','i','d'): key = "episode_uid";
384  case MKTAG( 'F','I','R','M'): key = "firmware"; raw = 1; break;
385  case MKTAG( 'g','n','r','e'): key = "genre";
386  parse = mov_metadata_gnre; break;
387  case MKTAG( 'h','d','v','d'): key = "hd_video";
389  case MKTAG( 'H','M','M','T'):
390  return mov_metadata_hmmt(c, pb, atom.size);
391  case MKTAG( 'k','e','y','w'): key = "keywords"; break;
392  case MKTAG( 'l','d','e','s'): key = "synopsis"; break;
393  case MKTAG( 'l','o','c','i'):
394  return mov_metadata_loci(c, pb, atom.size);
395  case MKTAG( 'm','a','n','u'): key = "make"; break;
396  case MKTAG( 'm','o','d','l'): key = "model"; break;
397  case MKTAG( 'n','a','m','e'): key = "name"; break;
398  case MKTAG( 'p','c','s','t'): key = "podcast";
400  case MKTAG( 'p','g','a','p'): key = "gapless_playback";
402  case MKTAG( 'p','u','r','d'): key = "purchase_date"; break;
403  case MKTAG( 'r','t','n','g'): key = "rating";
405  case MKTAG( 's','o','a','a'): key = "sort_album_artist"; break;
406  case MKTAG( 's','o','a','l'): key = "sort_album"; break;
407  case MKTAG( 's','o','a','r'): key = "sort_artist"; break;
408  case MKTAG( 's','o','c','o'): key = "sort_composer"; break;
409  case MKTAG( 's','o','n','m'): key = "sort_name"; break;
410  case MKTAG( 's','o','s','n'): key = "sort_show"; break;
411  case MKTAG( 's','t','i','k'): key = "media_type";
413  case MKTAG( 't','r','k','n'): key = "track";
415  case MKTAG( 't','v','e','n'): key = "episode_id"; break;
416  case MKTAG( 't','v','e','s'): key = "episode_sort";
418  case MKTAG( 't','v','n','n'): key = "network"; break;
419  case MKTAG( 't','v','s','h'): key = "show"; break;
420  case MKTAG( 't','v','s','n'): key = "season_number";
422  case MKTAG(0xa9,'A','R','T'): key = "artist"; break;
423  case MKTAG(0xa9,'P','R','D'): key = "producer"; break;
424  case MKTAG(0xa9,'a','l','b'): key = "album"; break;
425  case MKTAG(0xa9,'a','u','t'): key = "artist"; break;
426  case MKTAG(0xa9,'c','h','p'): key = "chapter"; break;
427  case MKTAG(0xa9,'c','m','t'): key = "comment"; break;
428  case MKTAG(0xa9,'c','o','m'): key = "composer"; break;
429  case MKTAG(0xa9,'c','p','y'): key = "copyright"; break;
430  case MKTAG(0xa9,'d','a','y'): key = "date"; break;
431  case MKTAG(0xa9,'d','i','r'): key = "director"; break;
432  case MKTAG(0xa9,'d','i','s'): key = "disclaimer"; break;
433  case MKTAG(0xa9,'e','d','1'): key = "edit_date"; break;
434  case MKTAG(0xa9,'e','n','c'): key = "encoder"; break;
435  case MKTAG(0xa9,'f','m','t'): key = "original_format"; break;
436  case MKTAG(0xa9,'g','e','n'): key = "genre"; break;
437  case MKTAG(0xa9,'g','r','p'): key = "grouping"; break;
438  case MKTAG(0xa9,'h','s','t'): key = "host_computer"; break;
439  case MKTAG(0xa9,'i','n','f'): key = "comment"; break;
440  case MKTAG(0xa9,'l','y','r'): key = "lyrics"; break;
441  case MKTAG(0xa9,'m','a','k'): key = "make"; break;
442  case MKTAG(0xa9,'m','o','d'): key = "model"; break;
443  case MKTAG(0xa9,'n','a','m'): key = "title"; break;
444  case MKTAG(0xa9,'o','p','e'): key = "original_artist"; break;
445  case MKTAG(0xa9,'p','r','d'): key = "producer"; break;
446  case MKTAG(0xa9,'p','r','f'): key = "performers"; break;
447  case MKTAG(0xa9,'r','e','q'): key = "playback_requirements"; break;
448  case MKTAG(0xa9,'s','r','c'): key = "original_source"; break;
449  case MKTAG(0xa9,'s','t','3'): key = "subtitle"; break;
450  case MKTAG(0xa9,'s','w','r'): key = "encoder"; break;
451  case MKTAG(0xa9,'t','o','o'): key = "encoder"; break;
452  case MKTAG(0xa9,'t','r','k'): key = "track"; break;
453  case MKTAG(0xa9,'u','r','l'): key = "URL"; break;
454  case MKTAG(0xa9,'w','r','n'): key = "warning"; break;
455  case MKTAG(0xa9,'w','r','t'): key = "composer"; break;
456  case MKTAG(0xa9,'x','y','z'): key = "location"; break;
457  }
458 retry:
459  if (c->itunes_metadata && atom.size > 8) {
460  int data_size = avio_rb32(pb);
461  int tag = avio_rl32(pb);
462  if (tag == MKTAG('d','a','t','a') && data_size <= atom.size && data_size >= 16) {
463  data_type = avio_rb32(pb); // type
464  avio_rb32(pb); // unknown
465  str_size = data_size - 16;
466  atom.size -= 16;
467 
468  if (!key && c->found_hdlr_mdta && c->meta_keys) {
469  uint32_t index = av_bswap32(atom.type); // BE number has been read as LE
470  if (index < c->meta_keys_count && index > 0) {
471  key = c->meta_keys[index];
472  } else if (atom.type != MKTAG('c', 'o', 'v', 'r')) {
473  av_log(c->fc, AV_LOG_WARNING,
474  "The index of 'data' is out of range: %"PRId32" < 1 or >= %d.\n",
475  index, c->meta_keys_count);
476  }
477  }
478  if (atom.type == MKTAG('c', 'o', 'v', 'r') ||
479  (key && !strcmp(key, "com.apple.quicktime.artwork"))) {
480  int ret = mov_read_covr(c, pb, data_type, str_size);
481  if (ret < 0) {
482  av_log(c->fc, AV_LOG_ERROR, "Error parsing cover art.\n");
483  return ret;
484  }
485  atom.size -= str_size;
486  if (atom.size > 8)
487  goto retry;
488  return ret;
489  }
490  } else return 0;
491  } else if (atom.size > 4 && (key || c->export_all) && !c->itunes_metadata && !raw) {
492  str_size = avio_rb16(pb); // string length
493  if (str_size > atom.size) {
494  raw = 1;
495  avio_seek(pb, -2, SEEK_CUR);
496  av_log(c->fc, AV_LOG_WARNING, "UDTA parsing failed retrying raw\n");
497  goto retry;
498  }
499  langcode = avio_rb16(pb);
500  ff_mov_lang_to_iso639(langcode, language);
501  atom.size -= 4;
502  } else
503  str_size = atom.size;
504 
505  if (c->export_all && !key) {
506  key = av_fourcc_make_string(tmp_key, atom.type);
507  }
508 
509  if (!key)
510  return 0;
511  if (atom.size < 0 || str_size >= INT_MAX/2)
512  return AVERROR_INVALIDDATA;
513 
514  // Allocates enough space if data_type is a int32 or float32 number, otherwise
515  // worst-case requirement for output string in case of utf8 coded input
516  num = (data_type >= 21 && data_type <= 23);
517  str_size_alloc = (num ? 512 : (raw ? str_size : str_size * 2)) + 1;
518  str = av_mallocz(str_size_alloc);
519  if (!str)
520  return AVERROR(ENOMEM);
521 
522  if (parse)
523  parse(c, pb, str_size, key);
524  else {
525  if (!raw && (data_type == 3 || (data_type == 0 && (langcode < 0x400 || langcode == 0x7fff)))) { // MAC Encoded
526  mov_read_mac_string(c, pb, str_size, str, str_size_alloc);
527  } else if (data_type == 21) { // BE signed integer, variable size
528  int val = 0;
529  if (str_size == 1)
530  val = (int8_t)avio_r8(pb);
531  else if (str_size == 2)
532  val = (int16_t)avio_rb16(pb);
533  else if (str_size == 3)
534  val = ((int32_t)(avio_rb24(pb)<<8))>>8;
535  else if (str_size == 4)
536  val = (int32_t)avio_rb32(pb);
537  if (snprintf(str, str_size_alloc, "%d", val) >= str_size_alloc) {
538  av_log(c->fc, AV_LOG_ERROR,
539  "Failed to store the number (%d) in string.\n", val);
540  av_free(str);
541  return AVERROR_INVALIDDATA;
542  }
543  } else if (data_type == 22) { // BE unsigned integer, variable size
544  unsigned int val = 0;
545  if (str_size == 1)
546  val = avio_r8(pb);
547  else if (str_size == 2)
548  val = avio_rb16(pb);
549  else if (str_size == 3)
550  val = avio_rb24(pb);
551  else if (str_size == 4)
552  val = avio_rb32(pb);
553  if (snprintf(str, str_size_alloc, "%u", val) >= str_size_alloc) {
554  av_log(c->fc, AV_LOG_ERROR,
555  "Failed to store the number (%u) in string.\n", val);
556  av_free(str);
557  return AVERROR_INVALIDDATA;
558  }
559  } else if (data_type == 23 && str_size >= 4) { // BE float32
560  float val = av_int2float(avio_rb32(pb));
561  if (snprintf(str, str_size_alloc, "%f", val) >= str_size_alloc) {
562  av_log(c->fc, AV_LOG_ERROR,
563  "Failed to store the float32 number (%f) in string.\n", val);
564  av_free(str);
565  return AVERROR_INVALIDDATA;
566  }
567  } else if (data_type > 1 && data_type != 4) {
568  // data_type can be 0 if not set at all above. data_type 1 means
569  // UTF8 and 4 means "UTF8 sort". For any other type (UTF16 or e.g.
570  // a picture), don't return it blindly in a string that is supposed
571  // to be UTF8 text.
572  av_log(c->fc, AV_LOG_WARNING, "Skipping unhandled metadata %s of type %"PRIu32"\n", key, data_type);
573  av_free(str);
574  return 0;
575  } else {
576  int ret = ffio_read_size(pb, str, str_size);
577  if (ret < 0) {
578  av_free(str);
579  return ret;
580  }
581  str[str_size] = 0;
582  }
583  c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
584  if (c->itunes_metadata && av_dict_get(*metadata, key, NULL, 0))
586  av_dict_set(metadata, key, str, c->itunes_metadata ? AV_DICT_APPEND : 0);
587  if (*language && strcmp(language, "und")) {
588  snprintf(key2, sizeof(key2), "%s-%s", key, language);
589  av_dict_set(metadata, key2, str, 0);
590  }
591  if (!strcmp(key, "encoder")) {
592  int major, minor, micro;
593  if (sscanf(str, "HandBrake %d.%d.%d", &major, &minor, &micro) == 3) {
594  c->handbrake_version = 1000000*major + 1000*minor + micro;
595  }
596  }
597 
598  atom.size -= str_size;
599  av_freep(&str);
600 
601  // Read remaining data atoms for multi-valued iTunes tags (e.g. multiple
602  // artists stored as multiple data atoms within one tag atom), consistent
603  // with the existing covr path.
604  // Note: multiple sibling tag atoms with the same key (e.g. three separate
605  // ©ART atoms under ilst) are handled by the AV_DICT_APPEND logic above,
606  // since mov_read_udta_string() is called once per tag atom.
607  if (c->itunes_metadata && atom.size > 8)
608  goto retry;
609  }
610 
611  av_freep(&str);
612  return 0;
613 }
614 
616 {
617  int64_t start;
618  int i, nb_chapters, str_len, version;
619  char str[256+1];
620  int ret;
621 
622  if (c->ignore_chapters)
623  return 0;
624 
625  if ((atom.size -= 5) < 0)
626  return 0;
627 
628  version = avio_r8(pb);
629  avio_rb24(pb);
630  if (version)
631  avio_rb32(pb); // ???
632  nb_chapters = avio_r8(pb);
633 
634  for (i = 0; i < nb_chapters; i++) {
635  if (atom.size < 9)
636  return 0;
637 
638  start = avio_rb64(pb);
639  str_len = avio_r8(pb);
640 
641  if ((atom.size -= 9+str_len) < 0)
642  return 0;
643 
644  ret = ffio_read_size(pb, str, str_len);
645  if (ret < 0)
646  return ret;
647  str[str_len] = 0;
648  avpriv_new_chapter(c->fc, i, (AVRational){1,10000000}, start, AV_NOPTS_VALUE, str);
649  }
650  return 0;
651 }
652 
653 #define MIN_DATA_ENTRY_BOX_SIZE 12
655 {
656  AVStream *st;
657  MOVStreamContext *sc;
658  int entries, i, j;
659 
660  if (c->fc->nb_streams < 1)
661  return 0;
662  st = c->fc->streams[c->fc->nb_streams-1];
663  sc = st->priv_data;
664 
665  avio_rb32(pb); // version + flags
666  entries = avio_rb32(pb);
667  if (!entries ||
668  entries > (atom.size - 1) / MIN_DATA_ENTRY_BOX_SIZE + 1 ||
669  entries >= UINT_MAX / sizeof(*sc->drefs))
670  return AVERROR_INVALIDDATA;
671 
672  for (i = 0; i < sc->drefs_count; i++) {
673  MOVDref *dref = &sc->drefs[i];
674  av_freep(&dref->path);
675  av_freep(&dref->dir);
676  }
677  av_free(sc->drefs);
678  sc->drefs_count = 0;
679  sc->drefs = av_mallocz(entries * sizeof(*sc->drefs));
680  if (!sc->drefs)
681  return AVERROR(ENOMEM);
682  sc->drefs_count = entries;
683 
684  for (i = 0; i < entries; i++) {
685  MOVDref *dref = &sc->drefs[i];
686  uint32_t size = avio_rb32(pb);
687  int64_t next = avio_tell(pb);
688 
689  if (size < 12 || next < 0 || next > INT64_MAX - size)
690  return AVERROR_INVALIDDATA;
691 
692  next += size - 4;
693 
694  dref->type = avio_rl32(pb);
695  avio_rb32(pb); // version + flags
696 
697  if (dref->type == MKTAG('a','l','i','s') && size > 150) {
698  /* macintosh alias record */
699  uint16_t volume_len, len;
700  int16_t type;
701  int ret;
702 
703  avio_skip(pb, 10);
704 
705  volume_len = avio_r8(pb);
706  volume_len = FFMIN(volume_len, 27);
707  ret = ffio_read_size(pb, dref->volume, 27);
708  if (ret < 0)
709  return ret;
710  dref->volume[volume_len] = 0;
711  av_log(c->fc, AV_LOG_DEBUG, "volume %s, len %d\n", dref->volume, volume_len);
712 
713  avio_skip(pb, 12);
714 
715  len = avio_r8(pb);
716  len = FFMIN(len, 63);
717  ret = ffio_read_size(pb, dref->filename, 63);
718  if (ret < 0)
719  return ret;
720  dref->filename[len] = 0;
721  av_log(c->fc, AV_LOG_DEBUG, "filename %s, len %d\n", dref->filename, len);
722 
723  avio_skip(pb, 16);
724 
725  /* read next level up_from_alias/down_to_target */
726  dref->nlvl_from = avio_rb16(pb);
727  dref->nlvl_to = avio_rb16(pb);
728  av_log(c->fc, AV_LOG_DEBUG, "nlvl from %d, nlvl to %d\n",
729  dref->nlvl_from, dref->nlvl_to);
730 
731  avio_skip(pb, 16);
732 
733  for (type = 0; type != -1 && avio_tell(pb) < next; ) {
734  if (avio_feof(pb))
735  return AVERROR_EOF;
736  type = avio_rb16(pb);
737  len = avio_rb16(pb);
738  av_log(c->fc, AV_LOG_DEBUG, "type %d, len %d\n", type, len);
739  if (len&1)
740  len += 1;
741  if (type == 2) { // absolute path
742  av_free(dref->path);
743  dref->path = av_mallocz(len+1);
744  if (!dref->path)
745  return AVERROR(ENOMEM);
746 
747  ret = ffio_read_size(pb, dref->path, len);
748  if (ret < 0) {
749  av_freep(&dref->path);
750  return ret;
751  }
752  if (len > volume_len && !strncmp(dref->path, dref->volume, volume_len)) {
753  len -= volume_len;
754  memmove(dref->path, dref->path+volume_len, len);
755  dref->path[len] = 0;
756  }
757  // trim string of any ending zeros
758  for (j = len - 1; j >= 0; j--) {
759  if (dref->path[j] == 0)
760  len--;
761  else
762  break;
763  }
764  for (j = 0; j < len; j++)
765  if (dref->path[j] == ':' || dref->path[j] == 0)
766  dref->path[j] = '/';
767  av_log(c->fc, AV_LOG_DEBUG, "path %s\n", dref->path);
768  } else if (type == 0) { // directory name
769  av_free(dref->dir);
770  dref->dir = av_malloc(len+1);
771  if (!dref->dir)
772  return AVERROR(ENOMEM);
773 
774  ret = ffio_read_size(pb, dref->dir, len);
775  if (ret < 0) {
776  av_freep(&dref->dir);
777  return ret;
778  }
779  dref->dir[len] = 0;
780  for (j = 0; j < len; j++)
781  if (dref->dir[j] == ':')
782  dref->dir[j] = '/';
783  av_log(c->fc, AV_LOG_DEBUG, "dir %s\n", dref->dir);
784  } else
785  avio_skip(pb, len);
786  }
787  } else {
788  av_log(c->fc, AV_LOG_DEBUG, "Unknown dref type 0x%08"PRIx32" size %"PRIu32"\n",
789  dref->type, size);
790  entries--;
791  i--;
792  }
793  avio_seek(pb, next, SEEK_SET);
794  }
795  return 0;
796 }
797 
799 {
800  AVStream *st;
801  uint32_t type;
802  uint32_t ctype;
803  int64_t title_size;
804  char *title_str;
805  int ret;
806 
807  avio_r8(pb); /* version */
808  avio_rb24(pb); /* flags */
809 
810  /* component type */
811  ctype = avio_rl32(pb);
812  type = avio_rl32(pb); /* component subtype */
813 
814  av_log(c->fc, AV_LOG_TRACE, "ctype=%s\n", av_fourcc2str(ctype));
815  av_log(c->fc, AV_LOG_TRACE, "stype=%s\n", av_fourcc2str(type));
816 
817  if (c->trak_index < 0) { // meta not inside a trak
818  if (type == MKTAG('m','d','t','a')) {
819  c->found_hdlr_mdta = 1;
820  }
821  return 0;
822  }
823 
824  st = c->fc->streams[c->fc->nb_streams-1];
825 
826  if (type == MKTAG('v','i','d','e'))
828  else if (type == MKTAG('s','o','u','n'))
830  else if (type == MKTAG('m','1','a',' '))
832  else if ((type == MKTAG('s','u','b','p')) || (type == MKTAG('c','l','c','p')))
834 
835  avio_rb32(pb); /* component manufacture */
836  avio_rb32(pb); /* component flags */
837  avio_rb32(pb); /* component flags mask */
838 
839  title_size = atom.size - 24;
840  if (title_size > 0) {
841  if (title_size > FFMIN(INT_MAX, SIZE_MAX-1))
842  return AVERROR_INVALIDDATA;
843  title_str = av_malloc(title_size + 1); /* Add null terminator */
844  if (!title_str)
845  return AVERROR(ENOMEM);
846 
847  ret = ffio_read_size(pb, title_str, title_size);
848  if (ret < 0) {
849  av_freep(&title_str);
850  return ret;
851  }
852  title_str[title_size] = 0;
853  if (title_str[0]) {
854  int off = (!c->isom && title_str[0] == title_size - 1);
855  // flag added so as to not set stream handler name if already set from mdia->hdlr
856  av_dict_set(&st->metadata, "handler_name", title_str + off, AV_DICT_DONT_OVERWRITE);
857  }
858  av_freep(&title_str);
859  }
860 
861  return 0;
862 }
863 
865 {
866  return ff_mov_read_esds(c->fc, pb);
867 }
868 
870 {
871  AVStream *st;
872  AVPacketSideData *sd;
873  enum AVAudioServiceType *ast;
874  int ac3info, acmod, lfeon, bsmod;
875  uint64_t mask;
876 
877  if (c->fc->nb_streams < 1)
878  return 0;
879  st = c->fc->streams[c->fc->nb_streams-1];
880 
884  sizeof(*ast), 0);
885  if (!sd)
886  return AVERROR(ENOMEM);
887 
888  ast = (enum AVAudioServiceType*)sd->data;
889  ac3info = avio_rb24(pb);
890  bsmod = (ac3info >> 14) & 0x7;
891  acmod = (ac3info >> 11) & 0x7;
892  lfeon = (ac3info >> 10) & 0x1;
893 
895  if (lfeon)
899 
900  *ast = bsmod;
901  if (st->codecpar->ch_layout.nb_channels > 1 && bsmod == 0x7)
903 
904  return 0;
905 }
906 
907 #if CONFIG_IAMFDEC
908 static int mov_read_iacb(MOVContext *c, AVIOContext *pb, MOVAtom atom)
909 {
910  AVStream *st;
911  MOVStreamContext *sc;
912  FFIOContext b;
913  AVIOContext *descriptor_pb;
915  IAMFContext *iamf;
917  unsigned descriptors_size;
918  int nb_frames, disposition;
919  int version, ret;
920 
921  if (atom.size < 5)
922  return AVERROR_INVALIDDATA;
923 
924  if (c->fc->nb_streams < 1)
925  return 0;
926 
927  version = avio_r8(pb);
928  if (version != 1) {
929  av_log(c->fc, AV_LOG_ERROR, "%s configurationVersion %d",
930  version < 1 ? "invalid" : "unsupported", version);
931  return AVERROR_INVALIDDATA;
932  }
933 
934  descriptors_size = ffio_read_leb(pb);
935  if (!descriptors_size || descriptors_size > INT_MAX)
936  return AVERROR_INVALIDDATA;
937 
938  st = c->fc->streams[c->fc->nb_streams - 1];
939  sc = st->priv_data;
940 
941  if (st->codecpar->extradata) {
942  av_log(c->fc, AV_LOG_WARNING, "ignoring iacb\n");
943  return 0;
944  }
945 
946  sc->iamf = av_mallocz(sizeof(*sc->iamf));
947  if (!sc->iamf)
948  return AVERROR(ENOMEM);
949  iamf = &sc->iamf->iamf;
950 
951  ret = ff_alloc_extradata(st->codecpar, descriptors_size);
952  if (ret < 0)
953  return ret;
954 
955  ret = avio_read(pb, st->codecpar->extradata, descriptors_size);
956  if (ret != descriptors_size)
957  return ret < 0 ? ret : AVERROR_INVALIDDATA;
958 
959  ffio_init_read_context(&b, st->codecpar->extradata, descriptors_size);
960  descriptor_pb = &b.pub;
961 
962  ret = ff_iamfdec_read_descriptors(iamf, descriptor_pb, descriptors_size, c->fc);
963  if (ret < 0)
964  return ret;
965 
966  metadata = st->metadata;
967  st->metadata = NULL;
968  start_time = st->start_time;
969  nb_frames = st->nb_frames;
970  duration = st->duration;
971  disposition = st->disposition;
972 
973  for (int i = 0; i < iamf->nb_audio_elements; i++) {
974  IAMFAudioElement *audio_element = iamf->audio_elements[i];
975  const AVIAMFAudioElement *element;
976  AVStreamGroup *stg =
978 
979  if (!stg) {
980  ret = AVERROR(ENOMEM);
981  goto fail;
982  }
983 
985  stg->id = audio_element->audio_element_id;
986  /* Transfer ownership */
987  element = stg->params.iamf_audio_element = audio_element->element;
988  audio_element->element = NULL;
989 
990  for (int j = 0; j < audio_element->nb_substreams; j++) {
991  IAMFSubStream *substream = &audio_element->substreams[j];
992  AVStream *stream;
993 
994  if (!i && !j) {
995  if (audio_element->layers[0].substream_count != 1)
996  disposition &= ~AV_DISPOSITION_DEFAULT;
997  stream = st;
998  } else
999  stream = avformat_new_stream(c->fc, NULL);
1000  if (!stream) {
1001  ret = AVERROR(ENOMEM);
1002  goto fail;
1003  }
1004 
1005  stream->start_time = start_time;
1006  stream->nb_frames = nb_frames;
1007  stream->duration = duration;
1008  stream->disposition = disposition;
1009  if (stream != st) {
1010  stream->priv_data = sc;
1011  sc->refcount++;
1012  }
1013 
1016  if (i || j) {
1018  if (audio_element->layers[0].substream_count == 1)
1019  stream->disposition &= ~AV_DISPOSITION_DEFAULT;
1020  }
1021 
1022  ret = avcodec_parameters_copy(stream->codecpar, substream->codecpar);
1023  if (ret < 0)
1024  goto fail;
1025 
1026  stream->id = substream->audio_substream_id;
1027 
1028  avpriv_set_pts_info(st, 64, 1, sc->time_scale);
1029 
1030  ret = avformat_stream_group_add_stream(stg, stream);
1031  if (ret < 0)
1032  goto fail;
1033  }
1034 
1035  ret = av_dict_copy(&stg->metadata, metadata, 0);
1036  if (ret < 0)
1037  goto fail;
1038  }
1039 
1040  for (int i = 0; i < iamf->nb_mix_presentations; i++) {
1041  IAMFMixPresentation *mix_presentation = iamf->mix_presentations[i];
1042  const AVIAMFMixPresentation *mix = mix_presentation->cmix;
1043  AVStreamGroup *stg =
1045 
1046  if (!stg) {
1047  ret = AVERROR(ENOMEM);
1048  goto fail;
1049  }
1050 
1052  stg->id = mix_presentation->mix_presentation_id;
1053  /* Transfer ownership */
1054  stg->params.iamf_mix_presentation = mix_presentation->mix;
1055  mix_presentation->mix = NULL;
1056 
1057  for (int j = 0; j < mix->nb_submixes; j++) {
1058  const AVIAMFSubmix *submix = mix->submixes[j];
1059 
1060  for (int k = 0; k < submix->nb_elements; k++) {
1061  const AVIAMFSubmixElement *submix_element = submix->elements[k];
1062  const AVStreamGroup *audio_element = NULL;
1063 
1064  for (int l = 0; l < c->fc->nb_stream_groups; l++)
1065  if (c->fc->stream_groups[l]->type == AV_STREAM_GROUP_PARAMS_IAMF_AUDIO_ELEMENT &&
1066  c->fc->stream_groups[l]->id == submix_element->audio_element_id) {
1067  audio_element = c->fc->stream_groups[l];
1068  break;
1069  }
1070  av_assert0(audio_element);
1071 
1072  for (int l = 0; l < audio_element->nb_streams; l++) {
1073  ret = avformat_stream_group_add_stream(stg, audio_element->streams[l]);
1074  if (ret < 0 && ret != AVERROR(EEXIST))
1075  goto fail;
1076  }
1077  }
1078  }
1079 
1080  ret = av_dict_copy(&stg->metadata, metadata, 0);
1081  if (ret < 0)
1082  goto fail;
1083  }
1084 
1085  ret = 0;
1086 fail:
1088 
1089  return ret;
1090 }
1091 #endif
1092 
1094 {
1095  AVStream *st;
1096  int32_t sample_rate;
1097 
1098  if (atom.size < 8 || c->fc->nb_streams < 1)
1099  return 0;
1100 
1101  st = c->fc->streams[c->fc->nb_streams-1];
1102  if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO) {
1103  av_log(c->fc, AV_LOG_WARNING, "'srat' within non-audio sample entry, skip\n");
1104  return 0;
1105  }
1106 
1107  if (!c->isom) {
1108  av_log(c->fc, AV_LOG_WARNING, "'srat' within non-isom, skip\n");
1109  return 0;
1110  }
1111 
1112  avio_skip(pb, 4); // version+flags
1113  sample_rate = avio_rb32(pb);
1114  if (sample_rate > 0) {
1115  av_log(c->fc, AV_LOG_DEBUG,
1116  "overwrite sample rate from %d to %d by 'srat'\n",
1117  st->codecpar->sample_rate, sample_rate);
1118  st->codecpar->sample_rate = sample_rate;
1119  } else {
1120  av_log(c->fc, AV_LOG_WARNING,
1121  "ignore invalid sample rate %d in 'srat'\n", sample_rate);
1122  }
1123 
1124  return 0;
1125 }
1126 
1128 {
1129  AVStream *st;
1130  AVPacketSideData *sd;
1131  enum AVAudioServiceType *ast;
1132  int eac3info, acmod, lfeon, bsmod;
1133  uint64_t mask;
1134 
1135  if (c->fc->nb_streams < 1)
1136  return 0;
1137  st = c->fc->streams[c->fc->nb_streams-1];
1138 
1142  sizeof(*ast), 0);
1143  if (!sd)
1144  return AVERROR(ENOMEM);
1145 
1146  ast = (enum AVAudioServiceType*)sd->data;
1147 
1148  /* No need to parse fields for additional independent substreams and its
1149  * associated dependent substreams since libavcodec's E-AC-3 decoder
1150  * does not support them yet. */
1151  avio_rb16(pb); /* data_rate and num_ind_sub */
1152  eac3info = avio_rb24(pb);
1153  bsmod = (eac3info >> 12) & 0x1f;
1154  acmod = (eac3info >> 9) & 0x7;
1155  lfeon = (eac3info >> 8) & 0x1;
1156 
1158  if (lfeon)
1162 
1163  *ast = bsmod;
1164  if (st->codecpar->ch_layout.nb_channels > 1 && bsmod == 0x7)
1166 
1167  return 0;
1168 }
1169 
1170 /* Maps the DTS `StreamConstruction` field (ETSI TS 102 114 Table E-2) to the
1171  * coarse FFmpeg DTS profile enum. Extension-substream XLL maps to HD_MA;
1172  * extension-substream XXCH, X96, or XBR maps to HD_HRA; core-substream XCH or
1173  * XXCH maps to ES; core-substream X96 maps to 96/24; a core component alone
1174  * maps to DTS; and extension-substream LBR maps to Express. Value 0 (undefined)
1175  * and values outside 1..21 map to AV_PROFILE_UNKNOWN. */
1176 static int mov_dts_stream_construction_to_profile(unsigned int sc)
1177 {
1178  static const int profile[22] = {
1179  [ 1] = AV_PROFILE_DTS, /* core Core */
1180  [ 2] = AV_PROFILE_DTS_ES, /* core Core + core XCH */
1181  [ 3] = AV_PROFILE_DTS_ES, /* core Core + core XXCH */
1182  [ 4] = AV_PROFILE_DTS_96_24, /* core Core + core X96 */
1183  [ 5] = AV_PROFILE_DTS_HD_HRA, /* core Core + ext XXCH */
1184  [ 6] = AV_PROFILE_DTS_HD_HRA, /* core Core + ext XBR */
1185  [ 7] = AV_PROFILE_DTS_HD_HRA, /* core Core + core XCH + ext XBR */
1186  [ 8] = AV_PROFILE_DTS_HD_HRA, /* core Core + core XXCH + ext XBR */
1187  [ 9] = AV_PROFILE_DTS_HD_HRA, /* core Core + ext XXCH + ext XBR */
1188  [10] = AV_PROFILE_DTS_HD_HRA, /* core Core + ext X96 */
1189  [11] = AV_PROFILE_DTS_HD_HRA, /* core Core + core XCH + ext X96 */
1190  [12] = AV_PROFILE_DTS_HD_HRA, /* core Core + core XXCH + ext X96 */
1191  [13] = AV_PROFILE_DTS_HD_HRA, /* core Core + ext XXCH + ext X96 */
1192  [14] = AV_PROFILE_DTS_HD_MA, /* core Core + ext XLL */
1193  [15] = AV_PROFILE_DTS_HD_MA, /* core Core + core XCH + ext XLL */
1194  [16] = AV_PROFILE_DTS_HD_MA, /* core Core + core X96 + ext XLL */
1195  [17] = AV_PROFILE_DTS_HD_MA, /* ext XLL */
1196  [18] = AV_PROFILE_DTS_EXPRESS, /* ext LBR */
1197  [19] = AV_PROFILE_DTS, /* ext Core */
1198  [20] = AV_PROFILE_DTS_HD_HRA, /* ext Core + ext XXCH */
1199  [21] = AV_PROFILE_DTS_HD_MA, /* ext Core + ext XLL */
1200  };
1201  if (!sc || sc > 21)
1202  return AV_PROFILE_UNKNOWN;
1203  return profile[sc];
1204 }
1205 
1206 /* Maps the 16-bit DTS `ChannelLayout` bitmask (ETSI TS 102 114 Table E-5) to an
1207  * ffmpeg channel mask. Pair bits follow Table 7-10 / DCA_SPEAKER_PAIR_*;
1208  * LwRw (0x0400) and LssRss (0x0800) must not collapse onto SIDE like LsRs. */
1209 static uint64_t mov_dts_channel_layout_to_mask(unsigned int code)
1210 {
1211  static const struct { unsigned int dts; uint64_t av; } map[] = {
1212  { 0x0001, AV_CH_FRONT_CENTER },
1213  { 0x0002, AV_CH_FRONT_LEFT | AV_CH_FRONT_RIGHT },
1214  { 0x0004, AV_CH_SIDE_LEFT | AV_CH_SIDE_RIGHT },
1215  { 0x0008, AV_CH_LOW_FREQUENCY },
1216  { 0x0010, AV_CH_BACK_CENTER },
1218  { 0x0040, AV_CH_BACK_LEFT | AV_CH_BACK_RIGHT },
1219  { 0x0080, AV_CH_TOP_FRONT_CENTER },
1220  { 0x0100, AV_CH_TOP_CENTER },
1222  { 0x0400, AV_CH_WIDE_LEFT | AV_CH_WIDE_RIGHT },
1224  { 0x1000, AV_CH_LOW_FREQUENCY_2 },
1226  { 0x4000, AV_CH_TOP_BACK_CENTER },
1228  };
1229  uint64_t mask = 0;
1230  int i;
1231  for (i = 0; i < FF_ARRAY_ELEMS(map); i++)
1232  if (code & map[i].dts)
1233  mask |= map[i].av;
1234  return mask;
1235 }
1236 
1238 {
1239 #define DDTS_SIZE 20
1240  uint8_t buf[DDTS_SIZE + AV_INPUT_BUFFER_PADDING_SIZE];
1241  AVStream *st = NULL;
1242  uint32_t frame_duration_code = 0;
1243  uint32_t channel_layout_code = 0;
1244  uint64_t channel_layout_mask;
1245  unsigned int stream_construction;
1246  unsigned int representation_type;
1247  GetBitContext gb;
1248  int ret;
1249 
1250  if ((ret = ffio_read_size(pb, buf, DDTS_SIZE)) < 0)
1251  return ret;
1252 
1253  init_get_bits(&gb, buf, 8 * DDTS_SIZE);
1254 
1255  if (c->fc->nb_streams < 1) {
1256  return 0;
1257  }
1258  st = c->fc->streams[c->fc->nb_streams-1];
1259 
1260  st->codecpar->sample_rate = get_bits_long(&gb, 32);
1261  if (st->codecpar->sample_rate <= 0) {
1262  av_log(c->fc, AV_LOG_ERROR, "Invalid sample rate %d\n", st->codecpar->sample_rate);
1263  return AVERROR_INVALIDDATA;
1264  }
1265  skip_bits_long(&gb, 32); /* max bitrate */
1266  st->codecpar->bit_rate = get_bits_long(&gb, 32);
1267  st->codecpar->bits_per_coded_sample = get_bits(&gb, 8);
1268  frame_duration_code = get_bits(&gb, 2);
1269  stream_construction = get_bits(&gb, 5); /* Table E-2 - profile source */
1270  skip_bits(&gb, 1); /* CoreLFEPresent */
1271  skip_bits(&gb, 6); /* CoreLayout */
1272  skip_bits(&gb, 14); /* CoreSize */
1273  skip_bits(&gb, 1); /* StereoDownmix */
1274  representation_type = get_bits(&gb, 3);
1275  channel_layout_code = get_bits(&gb, 16);
1276 
1277  st->codecpar->frame_size =
1278  (frame_duration_code == 0) ? 512 :
1279  (frame_duration_code == 1) ? 1024 :
1280  (frame_duration_code == 2) ? 2048 :
1281  (frame_duration_code == 3) ? 4096 : 0;
1282 
1283  /* Publish StreamConstruction as codecpar->profile, including for encrypted
1284  * tracks where frame headers cannot be inspected. */
1285  st->codecpar->profile = mov_dts_stream_construction_to_profile(stream_construction);
1286 
1287  channel_layout_mask = mov_dts_channel_layout_to_mask(channel_layout_code);
1288  if (channel_layout_mask) {
1290  av_channel_layout_from_mask(&st->codecpar->ch_layout, channel_layout_mask);
1291  } else if (representation_type == 2 || representation_type == 3) {
1294  }
1295 
1296  return 0;
1297 }
1298 
1300 {
1301  AVStream *st;
1302 
1303  if (c->fc->nb_streams < 1)
1304  return 0;
1305  st = c->fc->streams[c->fc->nb_streams-1];
1306 
1307  if (atom.size < 16)
1308  return 0;
1309 
1310  /* skip version and flags */
1311  avio_skip(pb, 4);
1312 
1313  ff_mov_read_chan(c->fc, pb, st, atom.size - 4);
1314 
1315  return 0;
1316 }
1317 
1319 {
1320  int64_t end = av_sat_add64(avio_tell(pb), atom.size);
1321  int version, flags;
1322  int ret;
1323  AVStream *st;
1324 
1325  if (c->fc->nb_streams < 1)
1326  return 0;
1327  st = c->fc->streams[c->fc->nb_streams-1];
1328 
1329  version = avio_r8(pb);
1330  flags = avio_rb24(pb);
1331  if (version > 1 || flags != 0) {
1332  av_log(c->fc, AV_LOG_WARNING,
1333  "Unsupported 'chnl' box with version %d, flags: %#x\n",
1334  version, flags);
1335  return 0;
1336  }
1337 
1338  ret = ff_mov_read_chnl(c->fc, pb, st, version);
1339  if (ret < 0) {
1340  avio_seek(pb, end, SEEK_SET);
1341  return 0;
1342  }
1343 
1344  if (avio_tell(pb) != end) {
1345  av_log(c->fc, AV_LOG_WARNING, "skip %" PRId64 " bytes of unknown data inside chnl\n",
1346  end - avio_tell(pb));
1347  avio_seek(pb, end, SEEK_SET);
1348  }
1349  return ret;
1350 }
1351 
1353 {
1354  AVStream *st;
1355  int ret;
1356 
1357  if (c->fc->nb_streams < 1)
1358  return 0;
1359  st = c->fc->streams[c->fc->nb_streams-1];
1360 
1361  if ((ret = ff_get_wav_header(c->fc, pb, st->codecpar, atom.size, 0)) < 0)
1362  av_log(c->fc, AV_LOG_WARNING, "get_wav_header failed\n");
1363 
1364  return ret;
1365 }
1366 
1368 {
1369  AVStream *st;
1370  HEIFItem *item;
1371  AVPacketSideData *sd;
1372  int width, height, err = 0;
1373  AVRational aperture_width, aperture_height, horiz_off, vert_off;
1374  AVRational pc_x, pc_y;
1375  uint64_t top, bottom, left, right;
1376 
1377  item = get_heif_item(c, c->cur_item_id);
1378  st = get_curr_st(c);
1379  if (!st)
1380  return 0;
1381 
1382  width = st->codecpar->width;
1383  height = st->codecpar->height;
1384  if ((!width || !height) && item) {
1385  width = item->width;
1386  height = item->height;
1387  }
1388  if (!width || !height) {
1389  err = AVERROR_INVALIDDATA;
1390  goto fail;
1391  }
1392 
1393  aperture_width.num = avio_rb32(pb);
1394  aperture_width.den = avio_rb32(pb);
1395  aperture_height.num = avio_rb32(pb);
1396  aperture_height.den = avio_rb32(pb);
1397 
1398  horiz_off.num = avio_rb32(pb);
1399  horiz_off.den = avio_rb32(pb);
1400  vert_off.num = avio_rb32(pb);
1401  vert_off.den = avio_rb32(pb);
1402 
1403  if (aperture_width.num < 0 || aperture_width.den < 0 ||
1404  aperture_height.num < 0 || aperture_height.den < 0 ||
1405  horiz_off.den < 0 || vert_off.den < 0) {
1406  err = AVERROR_INVALIDDATA;
1407  goto fail;
1408  }
1409  if ((av_cmp_q((AVRational) { width, 1 }, aperture_width) < 0) ||
1410  (av_cmp_q((AVRational) { height, 1 }, aperture_height) < 0)) {
1411  err = AVERROR_INVALIDDATA;
1412  goto fail;
1413  }
1414  av_log(c->fc, AV_LOG_TRACE, "clap: apertureWidth %d/%d, apertureHeight %d/%d "
1415  "horizOff %d/%d vertOff %d/%d\n",
1416  aperture_width.num, aperture_width.den, aperture_height.num, aperture_height.den,
1417  horiz_off.num, horiz_off.den, vert_off.num, vert_off.den);
1418 
1419  pc_x = av_mul_q((AVRational) { width - 1, 1 }, (AVRational) { 1, 2 });
1420  pc_x = av_add_q(pc_x, horiz_off);
1421  pc_y = av_mul_q((AVRational) { height - 1, 1 }, (AVRational) { 1, 2 });
1422  pc_y = av_add_q(pc_y, vert_off);
1423 
1424  aperture_width = av_sub_q(aperture_width, (AVRational) { 1, 1 });
1425  aperture_width = av_mul_q(aperture_width, (AVRational) { 1, 2 });
1426  aperture_height = av_sub_q(aperture_height, (AVRational) { 1, 1 });
1427  aperture_height = av_mul_q(aperture_height, (AVRational) { 1, 2 });
1428 
1429  left = av_q2d(av_sub_q(pc_x, aperture_width));
1430  right = av_q2d(av_add_q(pc_x, aperture_width));
1431  top = av_q2d(av_sub_q(pc_y, aperture_height));
1432  bottom = av_q2d(av_add_q(pc_y, aperture_height));
1433 
1434  if (bottom > (height - 1) ||
1435  right > (width - 1)) {
1436  err = AVERROR_INVALIDDATA;
1437  goto fail;
1438  }
1439 
1440  bottom = height - 1 - bottom;
1441  right = width - 1 - right;
1442 
1443  if (!(left | right | top | bottom))
1444  return 0;
1445 
1446  if ((left + right) >= width ||
1447  (top + bottom) >= height) {
1448  err = AVERROR_INVALIDDATA;
1449  goto fail;
1450  }
1451 
1455  sizeof(uint32_t) * 4, 0);
1456  if (!sd)
1457  return AVERROR(ENOMEM);
1458 
1459  AV_WL32A(sd->data, top);
1460  AV_WL32A(sd->data + 4, bottom);
1461  AV_WL32A(sd->data + 8, left);
1462  AV_WL32A(sd->data + 12, right);
1463 
1464 fail:
1465  if (err < 0) {
1466  int explode = !!(c->fc->error_recognition & AV_EF_EXPLODE);
1467  av_log(c->fc, explode ? AV_LOG_ERROR : AV_LOG_WARNING, "Invalid clap box\n");
1468  if (!explode)
1469  err = 0;
1470  }
1471 
1472  return err;
1473 }
1474 
1475 /* This atom overrides any previously set aspect ratio */
1477 {
1478  const int num = avio_rb32(pb);
1479  const int den = avio_rb32(pb);
1480  AVStream *st;
1481  MOVStreamContext *sc;
1482 
1483  if (c->fc->nb_streams < 1)
1484  return 0;
1485  st = c->fc->streams[c->fc->nb_streams-1];
1486  sc = st->priv_data;
1487 
1488  av_log(c->fc, AV_LOG_TRACE, "pasp: hSpacing %d, vSpacing %d\n", num, den);
1489 
1490  if (den != 0) {
1491  sc->h_spacing = num;
1492  sc->v_spacing = den;
1493  }
1494  return 0;
1495 }
1496 
1497 /* this atom contains actual media data */
1499 {
1500  if (atom.size == 0) /* wrong one (MP4) */
1501  return 0;
1502  c->found_mdat=1;
1503  return 0; /* now go for moov */
1504 }
1505 
1506 #define DRM_BLOB_SIZE 56
1507 
1509 {
1510  uint8_t intermediate_key[20];
1511  uint8_t intermediate_iv[20];
1512  uint8_t input[64];
1513  uint8_t output[64];
1514  uint8_t file_checksum[20];
1515  uint8_t calculated_checksum[20];
1516  char checksum_string[2 * sizeof(file_checksum) + 1];
1517  struct AVSHA *sha;
1518  int i;
1519  int ret = 0;
1520  uint8_t *activation_bytes = c->activation_bytes;
1521  uint8_t *fixed_key = c->audible_fixed_key;
1522 
1523  c->aax_mode = 1;
1524 
1525  sha = av_sha_alloc();
1526  if (!sha)
1527  return AVERROR(ENOMEM);
1528  av_free(c->aes_decrypt);
1529  c->aes_decrypt = av_aes_alloc();
1530  if (!c->aes_decrypt) {
1531  ret = AVERROR(ENOMEM);
1532  goto fail;
1533  }
1534 
1535  /* drm blob processing */
1536  avio_read(pb, output, 8); // go to offset 8, absolute position 0x251
1538  avio_read(pb, output, 4); // go to offset 4, absolute position 0x28d
1539  ret = ffio_read_size(pb, file_checksum, 20);
1540  if (ret < 0)
1541  goto fail;
1542 
1543  // required by external tools
1544  ff_data_to_hex(checksum_string, file_checksum, sizeof(file_checksum), 1);
1545  av_log(c->fc, AV_LOG_INFO, "[aax] file checksum == %s\n", checksum_string);
1546 
1547  /* verify activation data */
1548  if (!activation_bytes) {
1549  av_log(c->fc, AV_LOG_WARNING, "[aax] activation_bytes option is missing!\n");
1550  ret = 0; /* allow ffprobe to continue working on .aax files */
1551  goto fail;
1552  }
1553  if (c->activation_bytes_size != 4) {
1554  av_log(c->fc, AV_LOG_FATAL, "[aax] activation_bytes value needs to be 4 bytes!\n");
1555  ret = AVERROR(EINVAL);
1556  goto fail;
1557  }
1558 
1559  /* verify fixed key */
1560  if (c->audible_fixed_key_size != 16) {
1561  av_log(c->fc, AV_LOG_FATAL, "[aax] audible_fixed_key value needs to be 16 bytes!\n");
1562  ret = AVERROR(EINVAL);
1563  goto fail;
1564  }
1565 
1566  /* AAX (and AAX+) key derivation */
1567  av_sha_init(sha, 160);
1568  av_sha_update(sha, fixed_key, 16);
1569  av_sha_update(sha, activation_bytes, 4);
1570  av_sha_final(sha, intermediate_key);
1571  av_sha_init(sha, 160);
1572  av_sha_update(sha, fixed_key, 16);
1573  av_sha_update(sha, intermediate_key, 20);
1574  av_sha_update(sha, activation_bytes, 4);
1575  av_sha_final(sha, intermediate_iv);
1576  av_sha_init(sha, 160);
1577  av_sha_update(sha, intermediate_key, 16);
1578  av_sha_update(sha, intermediate_iv, 16);
1579  av_sha_final(sha, calculated_checksum);
1580  if (memcmp(calculated_checksum, file_checksum, 20)) { // critical error
1581  av_log(c->fc, AV_LOG_ERROR, "[aax] mismatch in checksums!\n");
1583  goto fail;
1584  }
1585  av_aes_init(c->aes_decrypt, intermediate_key, 128, 1);
1586  av_aes_crypt(c->aes_decrypt, output, input, DRM_BLOB_SIZE >> 4, intermediate_iv, 1);
1587  for (i = 0; i < 4; i++) {
1588  // file data (in output) is stored in big-endian mode
1589  if (activation_bytes[i] != output[3 - i]) { // critical error
1590  av_log(c->fc, AV_LOG_ERROR, "[aax] error in drm blob decryption!\n");
1592  goto fail;
1593  }
1594  }
1595  memcpy(c->file_key, output + 8, 16);
1596  memcpy(input, output + 26, 16);
1597  av_sha_init(sha, 160);
1598  av_sha_update(sha, input, 16);
1599  av_sha_update(sha, c->file_key, 16);
1600  av_sha_update(sha, fixed_key, 16);
1601  av_sha_final(sha, c->file_iv);
1602 
1603 fail:
1604  av_free(sha);
1605 
1606  return ret;
1607 }
1608 
1610 {
1611  if (c->audible_key_size != 16) {
1612  av_log(c->fc, AV_LOG_FATAL, "[aaxc] audible_key value needs to be 16 bytes!\n");
1613  return AVERROR(EINVAL);
1614  }
1615 
1616  if (c->audible_iv_size != 16) {
1617  av_log(c->fc, AV_LOG_FATAL, "[aaxc] audible_iv value needs to be 16 bytes!\n");
1618  return AVERROR(EINVAL);
1619  }
1620 
1621  c->aes_decrypt = av_aes_alloc();
1622  if (!c->aes_decrypt) {
1623  return AVERROR(ENOMEM);
1624  }
1625 
1626  memcpy(c->file_key, c->audible_key, 16);
1627  memcpy(c->file_iv, c->audible_iv, 16);
1628  c->aax_mode = 1;
1629 
1630  return 0;
1631 }
1632 
1633 // Audible AAX (and AAX+) bytestream decryption
1634 static int aax_filter(uint8_t *input, int size, MOVContext *c)
1635 {
1636  int blocks = 0;
1637  unsigned char iv[16];
1638 
1639  memcpy(iv, c->file_iv, 16); // iv is overwritten
1640  blocks = size >> 4; // trailing bytes are not encrypted!
1641  av_aes_init(c->aes_decrypt, c->file_key, 128, 1);
1642  av_aes_crypt(c->aes_decrypt, input, input, blocks, iv, 1);
1643 
1644  return 0;
1645 }
1646 
1647 /* read major brand, minor version and compatible brands and store them as metadata */
1649 {
1650  uint32_t minor_ver;
1651  int comp_brand_size;
1652  char* comp_brands_str;
1653  uint8_t type[5] = {0};
1654  int ret = ffio_read_size(pb, type, 4);
1655  if (ret < 0)
1656  return ret;
1657  if (c->fc->nb_streams) {
1658  if (c->fc->strict_std_compliance >= FF_COMPLIANCE_STRICT)
1659  return AVERROR_INVALIDDATA;
1660  av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate FTYP\n");
1661  return 0;
1662  }
1663 
1664  if (strcmp(type, "qt "))
1665  c->isom = 1;
1666  av_log(c->fc, AV_LOG_DEBUG, "ISO: File Type Major Brand: %.4s\n",(char *)&type);
1667  av_dict_set(&c->fc->metadata, "major_brand", type, 0);
1668  minor_ver = avio_rb32(pb); /* minor version */
1669  av_dict_set_int(&c->fc->metadata, "minor_version", minor_ver, 0);
1670 
1671  comp_brand_size = atom.size - 8;
1672  if (comp_brand_size < 0 || comp_brand_size == INT_MAX)
1673  return AVERROR_INVALIDDATA;
1674  comp_brands_str = av_malloc(comp_brand_size + 1); /* Add null terminator */
1675  if (!comp_brands_str)
1676  return AVERROR(ENOMEM);
1677 
1678  ret = ffio_read_size(pb, comp_brands_str, comp_brand_size);
1679  if (ret < 0) {
1680  av_freep(&comp_brands_str);
1681  return ret;
1682  }
1683  comp_brands_str[comp_brand_size] = 0;
1684  av_dict_set(&c->fc->metadata, "compatible_brands",
1685  comp_brands_str, AV_DICT_DONT_STRDUP_VAL);
1686 
1687  // Logic for handling Audible's .aaxc files
1688  if (!strcmp(type, "aaxc")) {
1689  mov_aaxc_crypto(c);
1690  }
1691 
1692  return 0;
1693 }
1694 
1695 /* this atom should contain all header atoms */
1697 {
1698  int ret;
1699 
1700  if (c->found_moov) {
1701  av_log(c->fc, AV_LOG_WARNING, "Found duplicated MOOV Atom. Skipped it\n");
1702  avio_skip(pb, atom.size);
1703  return 0;
1704  }
1705 
1706  if ((ret = mov_read_default(c, pb, atom)) < 0)
1707  return ret;
1708  /* we parsed the 'moov' atom, we can terminate the parsing as soon as we find the 'mdat' */
1709  /* so we don't parse the whole file if over a network */
1710  c->found_moov=1;
1711  return 0; /* now go for mdat */
1712 }
1713 
1715  MOVFragmentIndex *frag_index,
1716  int index,
1717  int id)
1718 {
1719  int i;
1720  MOVFragmentIndexItem * item;
1721 
1722  if (index < 0 || index >= frag_index->nb_items)
1723  return NULL;
1724  item = &frag_index->item[index];
1725  for (i = 0; i < item->nb_stream_info; i++)
1726  if (item->stream_info[i].id == id)
1727  return &item->stream_info[i];
1728 
1729  // This shouldn't happen
1730  return NULL;
1731 }
1732 
1733 static void set_frag_stream(MOVFragmentIndex *frag_index, int id)
1734 {
1735  int i;
1736  MOVFragmentIndexItem * item;
1737 
1738  if (frag_index->current < 0 ||
1739  frag_index->current >= frag_index->nb_items)
1740  return;
1741 
1742  item = &frag_index->item[frag_index->current];
1743  for (i = 0; i < item->nb_stream_info; i++)
1744  if (item->stream_info[i].id == id) {
1745  item->current = i;
1746  return;
1747  }
1748 
1749  // id not found. This shouldn't happen.
1750  item->current = -1;
1751 }
1752 
1754  MOVFragmentIndex *frag_index)
1755 {
1756  MOVFragmentIndexItem *item;
1757  if (frag_index->current < 0 ||
1758  frag_index->current >= frag_index->nb_items)
1759  return NULL;
1760 
1761  item = &frag_index->item[frag_index->current];
1762  if (item->current >= 0 && item->current < item->nb_stream_info)
1763  return &item->stream_info[item->current];
1764 
1765  // This shouldn't happen
1766  return NULL;
1767 }
1768 
1770 {
1771  int a, b, m;
1772  int64_t moof_offset;
1773 
1774  // Optimize for appending new entries
1775  if (!frag_index->nb_items ||
1776  frag_index->item[frag_index->nb_items - 1].moof_offset < offset)
1777  return frag_index->nb_items;
1778 
1779  a = -1;
1780  b = frag_index->nb_items;
1781 
1782  while (b - a > 1) {
1783  m = (a + b) >> 1;
1784  moof_offset = frag_index->item[m].moof_offset;
1785  if (moof_offset >= offset)
1786  b = m;
1787  if (moof_offset <= offset)
1788  a = m;
1789  }
1790  return b;
1791 }
1792 
1794 {
1795  av_assert0(frag_stream_info);
1796  if (frag_stream_info->sidx_pts != AV_NOPTS_VALUE)
1797  return frag_stream_info->sidx_pts;
1798  if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE)
1799  return frag_stream_info->first_tfra_pts;
1800  return frag_stream_info->tfdt_dts;
1801 }
1802 
1804  MOVFragmentIndex *frag_index, int index)
1805 {
1806  MOVFragmentStreamInfo * frag_stream_info;
1807  MOVStreamContext *sc = dst_st->priv_data;
1808  int64_t timestamp;
1809  int i, j;
1810 
1811  // If the stream is referenced by any sidx, limit the search
1812  // to fragments that referenced this stream in the sidx
1813  if (sc->has_sidx) {
1814  frag_stream_info = get_frag_stream_info(frag_index, index, sc->id);
1815  if (!frag_stream_info)
1816  return AV_NOPTS_VALUE;
1817  if (frag_stream_info->sidx_pts != AV_NOPTS_VALUE)
1818  return frag_stream_info->sidx_pts;
1819  if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE)
1820  return frag_stream_info->first_tfra_pts;
1821  return frag_stream_info->sidx_pts;
1822  }
1823 
1824  for (i = 0; i < frag_index->item[index].nb_stream_info; i++) {
1825  if (dst_st->id != frag_index->item[index].stream_info[i].id)
1826  continue;
1827  AVStream *frag_stream = NULL;
1828  frag_stream_info = &frag_index->item[index].stream_info[i];
1829  for (j = 0; j < s->nb_streams; j++) {
1830  MOVStreamContext *sc2 = s->streams[j]->priv_data;
1831  if (sc2->id == frag_stream_info->id)
1832  frag_stream = s->streams[j];
1833  }
1834  if (!frag_stream) {
1835  av_log(s, AV_LOG_WARNING, "No stream matching sidx ID found.\n");
1836  continue;
1837  }
1838  timestamp = get_stream_info_time(frag_stream_info);
1839  if (timestamp != AV_NOPTS_VALUE)
1840  return av_rescale_q(timestamp, frag_stream->time_base, dst_st->time_base);
1841  }
1842  return AV_NOPTS_VALUE;
1843 }
1844 
1846  AVStream *st, int64_t timestamp)
1847 {
1848  int a, b, m, m0;
1849  int64_t frag_time;
1850 
1851  a = -1;
1852  b = frag_index->nb_items;
1853 
1854  while (b - a > 1) {
1855  m0 = m = (a + b) >> 1;
1856 
1857  while (m < b &&
1858  (frag_time = get_frag_time(s, st, frag_index, m)) == AV_NOPTS_VALUE)
1859  m++;
1860 
1861  if (m < b && frag_time <= timestamp)
1862  a = m;
1863  else
1864  b = m0;
1865  }
1866 
1867  return a;
1868 }
1869 
1871 {
1872  int index, i;
1873  MOVFragmentIndexItem * item;
1874  MOVFragmentStreamInfo * frag_stream_info;
1875 
1876  // If moof_offset already exists in frag_index, return index to it
1877  index = search_frag_moof_offset(&c->frag_index, offset);
1878  if (index < c->frag_index.nb_items &&
1879  c->frag_index.item[index].moof_offset == offset)
1880  return index;
1881 
1882  // offset is not yet in frag index.
1883  // Insert new item at index (sorted by moof offset)
1884  item = av_fast_realloc(c->frag_index.item,
1885  &c->frag_index.allocated_size,
1886  (c->frag_index.nb_items + 1) *
1887  sizeof(*c->frag_index.item));
1888  if (!item)
1889  return -1;
1890  c->frag_index.item = item;
1891 
1892  frag_stream_info = av_realloc_array(NULL, c->fc->nb_streams,
1893  sizeof(*item->stream_info));
1894  if (!frag_stream_info)
1895  return -1;
1896 
1897  for (i = 0; i < c->fc->nb_streams; i++) {
1898  // Avoid building frag index if streams lack track id.
1899  MOVStreamContext *sc = c->fc->streams[i]->priv_data;
1900  if (sc->id < 0) {
1901  av_free(frag_stream_info);
1902  return AVERROR_INVALIDDATA;
1903  }
1904 
1905  frag_stream_info[i].id = sc->id;
1906  frag_stream_info[i].sidx_pts = AV_NOPTS_VALUE;
1907  frag_stream_info[i].tfdt_dts = AV_NOPTS_VALUE;
1908  frag_stream_info[i].next_trun_dts = AV_NOPTS_VALUE;
1909  frag_stream_info[i].first_tfra_pts = AV_NOPTS_VALUE;
1910  frag_stream_info[i].index_base = -1;
1911  frag_stream_info[i].index_entry = -1;
1912  frag_stream_info[i].encryption_index = NULL;
1913  frag_stream_info[i].stsd_id = -1;
1914  }
1915 
1916  if (index < c->frag_index.nb_items)
1917  memmove(c->frag_index.item + index + 1, c->frag_index.item + index,
1918  (c->frag_index.nb_items - index) * sizeof(*c->frag_index.item));
1919 
1920  item = &c->frag_index.item[index];
1921  item->headers_read = 0;
1922  item->current = 0;
1923  item->nb_stream_info = c->fc->nb_streams;
1924  item->moof_offset = offset;
1925  item->stream_info = frag_stream_info;
1926  c->frag_index.nb_items++;
1927 
1928  return index;
1929 }
1930 
1931 static void fix_frag_index_entries(MOVFragmentIndex *frag_index, int index,
1932  int id, int entries)
1933 {
1934  int i;
1935  MOVFragmentStreamInfo * frag_stream_info;
1936 
1937  if (index < 0)
1938  return;
1939  for (i = index; i < frag_index->nb_items; i++) {
1940  frag_stream_info = get_frag_stream_info(frag_index, i, id);
1941  if (frag_stream_info && frag_stream_info->index_entry >= 0)
1942  frag_stream_info->index_entry += entries;
1943  }
1944 }
1945 
1947 {
1948  // Set by mov_read_tfhd(). mov_read_trun() will reject files missing tfhd.
1949  c->fragment.found_tfhd = 0;
1950 
1951  if (!c->has_looked_for_mfra && c->use_mfra_for > 0) {
1952  c->has_looked_for_mfra = 1;
1953  if (pb->seekable & AVIO_SEEKABLE_NORMAL) {
1954  int ret;
1955  av_log(c->fc, AV_LOG_VERBOSE, "stream has moof boxes, will look "
1956  "for a mfra\n");
1957  if ((ret = mov_read_mfra(c, pb)) < 0) {
1958  av_log(c->fc, AV_LOG_VERBOSE, "found a moof box but failed to "
1959  "read the mfra (may be a live ismv)\n");
1960  }
1961  } else {
1962  av_log(c->fc, AV_LOG_VERBOSE, "found a moof box but stream is not "
1963  "seekable, can not look for mfra\n");
1964  }
1965  }
1966  c->fragment.moof_offset = c->fragment.implicit_offset = avio_tell(pb) - 8;
1967  av_log(c->fc, AV_LOG_TRACE, "moof offset %"PRIx64"\n", c->fragment.moof_offset);
1968  c->frag_index.current = update_frag_index(c, c->fragment.moof_offset);
1969  return mov_read_default(c, pb, atom);
1970 }
1971 
1973 {
1974  int64_t time;
1975  if (version == 1) {
1976  time = avio_rb64(pb);
1977  avio_rb64(pb);
1978  if (time < 0) {
1979  av_log(c->fc, AV_LOG_DEBUG, "creation_time is negative\n");
1980  return;
1981  }
1982  } else {
1983  time = avio_rb32(pb);
1984  avio_rb32(pb); /* modification time */
1985  if (time > 0 && time < 2082844800) {
1986  av_log(c->fc, AV_LOG_WARNING, "Detected creation time before 1970, parsing as unix timestamp.\n");
1987  time += 2082844800;
1988  }
1989  }
1990  if (time) {
1991  time -= 2082844800; /* seconds between 1904-01-01 and Epoch */
1992 
1993  if ((int64_t)(time * 1000000ULL) / 1000000 != time) {
1994  av_log(c->fc, AV_LOG_DEBUG, "creation_time is not representable\n");
1995  return;
1996  }
1997 
1998  ff_dict_set_timestamp(metadata, "creation_time", time * 1000000);
1999  }
2000 }
2001 
2003 {
2004  AVStream *st;
2005  MOVStreamContext *sc;
2006  int version;
2007  char language[4] = {0};
2008  unsigned lang;
2009 
2010  if (c->fc->nb_streams < 1)
2011  return 0;
2012  st = c->fc->streams[c->fc->nb_streams-1];
2013  sc = st->priv_data;
2014 
2015  if (sc->time_scale) {
2016  av_log(c->fc, AV_LOG_ERROR, "Multiple mdhd?\n");
2017  return AVERROR_INVALIDDATA;
2018  }
2019 
2020  version = avio_r8(pb);
2021  if (version > 1) {
2022  avpriv_request_sample(c->fc, "Version %d", version);
2023  return AVERROR_PATCHWELCOME;
2024  }
2025  avio_rb24(pb); /* flags */
2027 
2028  sc->time_scale = avio_rb32(pb);
2029  if (sc->time_scale <= 0) {
2030  av_log(c->fc, AV_LOG_ERROR, "Invalid mdhd time scale %d, defaulting to 1\n", sc->time_scale);
2031  sc->time_scale = 1;
2032  }
2033  st->duration = (version == 1) ? avio_rb64(pb) : avio_rb32(pb); /* duration */
2034 
2035  if ((version == 1 && st->duration == UINT64_MAX) ||
2036  (version != 1 && st->duration == UINT32_MAX)) {
2037  st->duration = 0;
2038  }
2039 
2040  lang = avio_rb16(pb); /* language */
2041  if (ff_mov_lang_to_iso639(lang, language))
2042  av_dict_set(&st->metadata, "language", language, 0);
2043  avio_rb16(pb); /* quality */
2044 
2045  return 0;
2046 }
2047 
2049 {
2050  int i;
2051  int version = avio_r8(pb); /* version */
2052  avio_rb24(pb); /* flags */
2053 
2054  mov_metadata_creation_time(c, pb, &c->fc->metadata, version);
2055  c->time_scale = avio_rb32(pb); /* time scale */
2056  if (c->time_scale <= 0) {
2057  av_log(c->fc, AV_LOG_ERROR, "Invalid mvhd time scale %d, defaulting to 1\n", c->time_scale);
2058  c->time_scale = 1;
2059  }
2060  av_log(c->fc, AV_LOG_TRACE, "time scale = %i\n", c->time_scale);
2061 
2062  c->duration = (version == 1) ? avio_rb64(pb) : avio_rb32(pb); /* duration */
2063  avio_rb32(pb); /* preferred scale */
2064 
2065  avio_rb16(pb); /* preferred volume */
2066 
2067  avio_skip(pb, 10); /* reserved */
2068 
2069  /* movie display matrix, store it in main context and use it later on */
2070  for (i = 0; i < 3; i++) {
2071  c->movie_display_matrix[i][0] = avio_rb32(pb); // 16.16 fixed point
2072  c->movie_display_matrix[i][1] = avio_rb32(pb); // 16.16 fixed point
2073  c->movie_display_matrix[i][2] = avio_rb32(pb); // 2.30 fixed point
2074  }
2075 
2076  avio_rb32(pb); /* preview time */
2077  avio_rb32(pb); /* preview duration */
2078  avio_rb32(pb); /* poster time */
2079  avio_rb32(pb); /* selection time */
2080  avio_rb32(pb); /* selection duration */
2081  avio_rb32(pb); /* current time */
2082  avio_rb32(pb); /* next track ID */
2083 
2084  return 0;
2085 }
2086 
2088 {
2089  AVStream *st;
2090 
2091  if (fc->nb_streams < 1)
2092  return;
2093  st = fc->streams[fc->nb_streams-1];
2094 
2095  switch (st->codecpar->codec_id) {
2096  case AV_CODEC_ID_PCM_S16BE:
2098  break;
2099  case AV_CODEC_ID_PCM_S24BE:
2101  break;
2102  case AV_CODEC_ID_PCM_S32BE:
2104  break;
2105  case AV_CODEC_ID_PCM_F32BE:
2107  break;
2108  case AV_CODEC_ID_PCM_F64BE:
2110  break;
2111  default:
2112  break;
2113  }
2114 }
2115 
2117 {
2118  int little_endian = avio_rb16(pb) & 0xFF;
2119  av_log(c->fc, AV_LOG_TRACE, "enda %d\n", little_endian);
2120  if (little_endian == 1)
2122  return 0;
2123 }
2124 
2126 {
2127  int format_flags;
2128  int version, flags;
2129  int pcm_sample_size;
2130  AVFormatContext *fc = c->fc;
2131  AVStream *st;
2132  MOVStreamContext *sc;
2133 
2134  if (atom.size < 6) {
2135  av_log(c->fc, AV_LOG_ERROR, "Empty pcmC box\n");
2136  return AVERROR_INVALIDDATA;
2137  }
2138 
2139  version = avio_r8(pb);
2140  flags = avio_rb24(pb);
2141 
2142  if (version != 0 || flags != 0) {
2143  av_log(c->fc, AV_LOG_ERROR,
2144  "Unsupported 'pcmC' box with version %d, flags: %x",
2145  version, flags);
2146  return AVERROR_INVALIDDATA;
2147  }
2148 
2149  format_flags = avio_r8(pb);
2150  pcm_sample_size = avio_r8(pb);
2151 
2152  if (fc->nb_streams < 1)
2153  return AVERROR_INVALIDDATA;
2154 
2155  st = fc->streams[fc->nb_streams - 1];
2156  sc = st->priv_data;
2157 
2158  if (sc->format == MOV_MP4_FPCM_TAG) {
2159  switch (pcm_sample_size) {
2160  case 32:
2162  break;
2163  case 64:
2165  break;
2166  default:
2167  av_log(fc, AV_LOG_ERROR, "invalid pcm_sample_size %d for %s\n",
2168  pcm_sample_size,
2169  av_fourcc2str(sc->format));
2170  return AVERROR_INVALIDDATA;
2171  }
2172  } else if (sc->format == MOV_MP4_IPCM_TAG) {
2173  switch (pcm_sample_size) {
2174  case 16:
2176  break;
2177  case 24:
2179  break;
2180  case 32:
2182  break;
2183  default:
2184  av_log(fc, AV_LOG_ERROR, "invalid pcm_sample_size %d for %s\n",
2185  pcm_sample_size,
2186  av_fourcc2str(sc->format));
2187  return AVERROR_INVALIDDATA;
2188  }
2189  } else {
2190  av_log(fc, AV_LOG_ERROR, "'pcmC' with invalid sample entry '%s'\n",
2191  av_fourcc2str(sc->format));
2192  return AVERROR_INVALIDDATA;
2193  }
2194 
2195  if (format_flags & 1) // indicates little-endian format. If not present, big-endian format is used
2198 
2199  return 0;
2200 }
2201 
2203 {
2204  AVStream *st;
2205  HEIFItem *item = NULL;
2206  char color_parameter_type[5] = { 0 };
2207  uint16_t color_primaries, color_trc, color_matrix;
2208  int ret;
2209 
2210  st = get_curr_st(c);
2211  if (!st) {
2212  item = get_heif_item(c, c->cur_item_id);
2213  if (!item)
2214  return 0;
2215  }
2216 
2217  ret = ffio_read_size(pb, color_parameter_type, 4);
2218  if (ret < 0)
2219  return ret;
2220  if (strncmp(color_parameter_type, "nclx", 4) &&
2221  strncmp(color_parameter_type, "nclc", 4) &&
2222  strncmp(color_parameter_type, "prof", 4)) {
2223  av_log(c->fc, AV_LOG_WARNING, "unsupported color_parameter_type %s\n",
2224  color_parameter_type);
2225  return 0;
2226  }
2227 
2228  if (!strncmp(color_parameter_type, "prof", 4)) {
2229  AVPacketSideData *sd;
2230  uint8_t *icc_profile;
2231  if (st) {
2235  atom.size - 4, 0);
2236  if (!sd)
2237  return AVERROR(ENOMEM);
2238  icc_profile = sd->data;
2239  } else {
2240  if (c->heif_icc_profile_items >= c->fc->max_streams) {
2241  av_log(c->fc, AV_LOG_WARNING,
2242  "HEIF ICC profile copies exceed cap %d; ignoring further items\n",
2243  c->fc->max_streams);
2244  return 0;
2245  }
2246  av_freep(&item->icc_profile);
2247  icc_profile = item->icc_profile = av_malloc(atom.size - 4);
2248  if (!icc_profile) {
2249  item->icc_profile_size = 0;
2250  return AVERROR(ENOMEM);
2251  }
2252  item->icc_profile_size = atom.size - 4;
2253  c->heif_icc_profile_items++;
2254  }
2255  ret = ffio_read_size(pb, icc_profile, atom.size - 4);
2256  if (ret < 0)
2257  return ret;
2258  } else if (st) {
2259  color_primaries = avio_rb16(pb);
2260  color_trc = avio_rb16(pb);
2261  color_matrix = avio_rb16(pb);
2262 
2263  av_log(c->fc, AV_LOG_TRACE,
2264  "%s: pri %d trc %d matrix %d",
2265  color_parameter_type, color_primaries, color_trc, color_matrix);
2266 
2267  if (!strncmp(color_parameter_type, "nclx", 4)) {
2268  uint8_t color_range = avio_r8(pb) >> 7;
2269  av_log(c->fc, AV_LOG_TRACE, " full %"PRIu8"", color_range);
2270  if (color_range)
2272  else
2274  }
2275 
2278  if (!av_color_transfer_name(color_trc))
2279  color_trc = AVCOL_TRC_UNSPECIFIED;
2280  if (!av_color_space_name(color_matrix))
2281  color_matrix = AVCOL_SPC_UNSPECIFIED;
2282 
2284  st->codecpar->color_trc = color_trc;
2285  st->codecpar->color_space = color_matrix;
2286  av_log(c->fc, AV_LOG_TRACE, "\n");
2287  }
2288  return 0;
2289 }
2290 
2292 {
2293  AVStream *st;
2294  unsigned mov_field_order;
2295  enum AVFieldOrder decoded_field_order = AV_FIELD_UNKNOWN;
2296 
2297  if (c->fc->nb_streams < 1) // will happen with jp2 files
2298  return 0;
2299  st = c->fc->streams[c->fc->nb_streams-1];
2300  if (atom.size < 2)
2301  return AVERROR_INVALIDDATA;
2302  mov_field_order = avio_rb16(pb);
2303  if ((mov_field_order & 0xFF00) == 0x0100)
2304  decoded_field_order = AV_FIELD_PROGRESSIVE;
2305  else if ((mov_field_order & 0xFF00) == 0x0200) {
2306  switch (mov_field_order & 0xFF) {
2307  case 0x01: decoded_field_order = AV_FIELD_TT;
2308  break;
2309  case 0x06: decoded_field_order = AV_FIELD_BB;
2310  break;
2311  case 0x09: decoded_field_order = AV_FIELD_TB;
2312  break;
2313  case 0x0E: decoded_field_order = AV_FIELD_BT;
2314  break;
2315  }
2316  }
2317  if (decoded_field_order == AV_FIELD_UNKNOWN && mov_field_order) {
2318  av_log(c->fc, AV_LOG_ERROR, "Unknown MOV field order 0x%04x\n", mov_field_order);
2319  }
2320  st->codecpar->field_order = decoded_field_order;
2321 
2322  return 0;
2323 }
2324 
2326 {
2327  int err = 0;
2328  uint64_t size = (uint64_t)par->extradata_size + atom.size + 8 + AV_INPUT_BUFFER_PADDING_SIZE;
2329  if (size > INT_MAX || (uint64_t)atom.size > INT_MAX)
2330  return AVERROR_INVALIDDATA;
2331  if ((err = av_reallocp(&par->extradata, size)) < 0) {
2332  par->extradata_size = 0;
2333  return err;
2334  }
2336  return 0;
2337 }
2338 
2339 /* Read a whole atom into the extradata return the size of the atom read, possibly truncated if != atom.size */
2341  AVCodecParameters *par, uint8_t *buf)
2342 {
2343  int64_t result = atom.size;
2344  int err;
2345 
2346  AV_WB32(buf , atom.size + 8);
2347  AV_WL32(buf + 4, atom.type);
2348  err = ffio_read_size(pb, buf + 8, atom.size);
2349  if (err < 0) {
2350  par->extradata_size -= atom.size;
2351  return err;
2352  } else if (err < atom.size) {
2353  av_log(c->fc, AV_LOG_WARNING, "truncated extradata\n");
2354  par->extradata_size -= atom.size - err;
2355  result = err;
2356  }
2357  memset(buf + 8 + err, 0, AV_INPUT_BUFFER_PADDING_SIZE);
2358  return result;
2359 }
2360 
2361 /* FIXME modify QDM2/SVQ3/H.264 decoders to take full atom as extradata */
2363  enum AVCodecID codec_id)
2364 {
2365  AVStream *st;
2366  uint64_t original_size;
2367  int err;
2368 
2369  if (c->fc->nb_streams < 1) // will happen with jp2 files
2370  return 0;
2371  st = c->fc->streams[c->fc->nb_streams-1];
2372 
2373  if (st->codecpar->codec_id != codec_id)
2374  return 0; /* unexpected codec_id - don't mess with extradata */
2375 
2376  original_size = st->codecpar->extradata_size;
2377  err = mov_realloc_extradata(st->codecpar, atom);
2378  if (err)
2379  return err;
2380 
2381  err = mov_read_atom_into_extradata(c, pb, atom, st->codecpar, st->codecpar->extradata + original_size);
2382  if (err < 0)
2383  return err;
2384  return 0; // Note: this is the original behavior to ignore truncation.
2385 }
2386 
2387 /* wrapper functions for reading ALAC/AVS/MJPEG/MJPEG2000 extradata atoms only for those codecs */
2389 {
2390  return mov_read_extradata(c, pb, atom, AV_CODEC_ID_ALAC);
2391 }
2392 
2394 {
2395  return mov_read_extradata(c, pb, atom, AV_CODEC_ID_CAVS);
2396 }
2397 
2399 {
2400  return mov_read_extradata(c, pb, atom, AV_CODEC_ID_JPEG2000);
2401 }
2402 
2404 {
2405  return mov_read_extradata(c, pb, atom, AV_CODEC_ID_R10K);
2406 }
2407 
2409 {
2410  int ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_AVUI);
2411  if (!ret)
2412  ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_DNXHD);
2413  return ret;
2414 }
2415 
2417 {
2418  int ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_TARGA_Y216);
2419 
2420  if (!ret && c->fc->nb_streams >= 1) {
2421  AVCodecParameters *par = c->fc->streams[c->fc->nb_streams-1]->codecpar;
2422  if (par->extradata_size >= 40) {
2423  par->height = AV_RB16(&par->extradata[36]);
2424  par->width = AV_RB16(&par->extradata[38]);
2425  }
2426  }
2427  return ret;
2428 }
2429 
2431 {
2432  if (c->fc->nb_streams >= 1) {
2433  AVStream *const st = c->fc->streams[c->fc->nb_streams - 1];
2434  FFStream *const sti = ffstream(st);
2435  AVCodecParameters *par = st->codecpar;
2436 
2437  if (par->codec_tag == MKTAG('A', 'V', 'i', 'n') &&
2438  par->codec_id == AV_CODEC_ID_H264 &&
2439  atom.size > 11) {
2440  int cid;
2441  avio_skip(pb, 10);
2442  cid = avio_rb16(pb);
2443  /* For AVID AVCI50, force width of 1440 to be able to select the correct SPS and PPS */
2444  if (cid == 0xd4d || cid == 0xd4e)
2445  par->width = 1440;
2446  return 0;
2447  } else if ((par->codec_tag == MKTAG('A', 'V', 'd', '1') ||
2448  par->codec_tag == MKTAG('A', 'V', 'j', '2') ||
2449  par->codec_tag == MKTAG('A', 'V', 'd', 'n')) &&
2450  atom.size >= 24) {
2451  int num, den;
2452  avio_skip(pb, 12);
2453  num = avio_rb32(pb);
2454  den = avio_rb32(pb);
2455  if (num <= 0 || den <= 0)
2456  return 0;
2457  switch (avio_rb32(pb)) {
2458  case 2:
2459  if (den >= INT_MAX / 2)
2460  return 0;
2461  den *= 2;
2463  case 1:
2464  sti->display_aspect_ratio = (AVRational){ num, den };
2466  default:
2467  return 0;
2468  }
2469  }
2470  }
2471 
2472  return mov_read_avid(c, pb, atom);
2473 }
2474 
2476 {
2477  int ret = 0;
2478  int length = 0;
2479  uint64_t original_size;
2480  if (c->fc->nb_streams >= 1) {
2481  AVCodecParameters *par = c->fc->streams[c->fc->nb_streams-1]->codecpar;
2482  if (par->codec_id == AV_CODEC_ID_H264)
2483  return 0;
2484  if (atom.size == 16) {
2485  original_size = par->extradata_size;
2486  ret = mov_realloc_extradata(par, atom);
2487  if (!ret) {
2488  length = mov_read_atom_into_extradata(c, pb, atom, par, par->extradata + original_size);
2489  if (length == atom.size) {
2490  const uint8_t range_value = par->extradata[original_size + 19];
2491  switch (range_value) {
2492  case 1:
2494  break;
2495  case 2:
2497  break;
2498  default:
2499  av_log(c->fc, AV_LOG_WARNING, "ignored unknown aclr value (%d)\n", range_value);
2500  break;
2501  }
2502  ff_dlog(c->fc, "color_range: %d\n", par->color_range);
2503  } else {
2504  /* For some reason the whole atom was not added to the extradata */
2505  av_log(c->fc, AV_LOG_ERROR, "aclr not decoded - incomplete atom\n");
2506  }
2507  } else {
2508  av_log(c->fc, AV_LOG_ERROR, "aclr not decoded - unable to add atom to extradata\n");
2509  }
2510  } else {
2511  av_log(c->fc, AV_LOG_WARNING, "aclr not decoded - unexpected size %"PRId64"\n", atom.size);
2512  }
2513  }
2514 
2515  return ret;
2516 }
2517 
2519 {
2520  return mov_read_extradata(c, pb, atom, AV_CODEC_ID_SVQ3);
2521 }
2522 
2524 {
2525  AVStream *st;
2526  int ret;
2527 
2528  if (c->fc->nb_streams < 1)
2529  return 0;
2530  st = c->fc->streams[c->fc->nb_streams-1];
2531 
2532  if ((uint64_t)atom.size > (1<<30))
2533  return AVERROR_INVALIDDATA;
2534 
2535  if (st->codecpar->codec_id == AV_CODEC_ID_QDM2 ||
2538  // pass all frma atom to codec, needed at least for QDMC and QDM2
2539  ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size);
2540  if (ret < 0)
2541  return ret;
2542  } else if (atom.size > 8) { /* to read frma, esds atoms */
2543  if (st->codecpar->codec_id == AV_CODEC_ID_ALAC && atom.size >= 24) {
2544  uint64_t buffer;
2545  ret = ffio_ensure_seekback(pb, 8);
2546  if (ret < 0)
2547  return ret;
2548  buffer = avio_rb64(pb);
2549  atom.size -= 8;
2550  if ( (buffer & 0xFFFFFFFF) == MKBETAG('f','r','m','a')
2551  && buffer >> 32 <= atom.size
2552  && buffer >> 32 >= 8) {
2553  avio_skip(pb, -8);
2554  atom.size += 8;
2555  } else if (!st->codecpar->extradata_size) {
2556 #define ALAC_EXTRADATA_SIZE 36
2558  if (!st->codecpar->extradata)
2559  return AVERROR(ENOMEM);
2562  AV_WB32(st->codecpar->extradata + 4, MKTAG('a','l','a','c'));
2563  AV_WB64(st->codecpar->extradata + 12, buffer);
2564  avio_read(pb, st->codecpar->extradata + 20, 16);
2565  avio_skip(pb, atom.size - 24);
2566  return 0;
2567  }
2568  }
2569  if ((ret = mov_read_default(c, pb, atom)) < 0)
2570  return ret;
2571  } else
2572  avio_skip(pb, atom.size);
2573  return 0;
2574 }
2575 
2576 /**
2577  * This function reads atom content and puts data in extradata without tag
2578  * nor size unlike mov_read_extradata.
2579  */
2581 {
2582  AVStream *st;
2583  int ret;
2584 
2585  st = get_curr_st(c);
2586  if (!st)
2587  return 0;
2588 
2589  if ((uint64_t)atom.size > (1<<30))
2590  return AVERROR_INVALIDDATA;
2591 
2592  if (atom.type == MKTAG('v','v','c','C')) {
2593  avio_skip(pb, 4);
2594  atom.size -= 4;
2595  }
2596 
2597  if (atom.size >= 10) {
2598  // Broken files created by legacy versions of libavformat will
2599  // wrap a whole fiel atom inside of a glbl atom.
2600  unsigned size = avio_rb32(pb);
2601  unsigned type = avio_rl32(pb);
2602  if (avio_feof(pb))
2603  return AVERROR_INVALIDDATA;
2604  avio_seek(pb, -8, SEEK_CUR);
2605  if (type == MKTAG('f','i','e','l') && size == atom.size)
2606  return mov_read_default(c, pb, atom);
2607  }
2608  if (st->codecpar->extradata_size > 1 && st->codecpar->extradata) {
2609  av_log(c->fc, AV_LOG_WARNING, "ignoring multiple glbl\n");
2610  return 0;
2611  }
2612  ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size);
2613  if (ret < 0)
2614  return ret;
2615  if (atom.type == MKTAG('h','v','c','C') && st->codecpar->codec_tag == MKTAG('d','v','h','1'))
2616  /* HEVC-based Dolby Vision derived from hvc1.
2617  Happens to match with an identifier
2618  previously utilized for DV. Thus, if we have
2619  the hvcC extradata box available as specified,
2620  set codec to HEVC */
2622 
2623  return 0;
2624 }
2625 
2627 {
2628  AVStream *st;
2629  uint8_t profile_level;
2630  int ret;
2631 
2632  if (c->fc->nb_streams < 1)
2633  return 0;
2634  st = c->fc->streams[c->fc->nb_streams-1];
2635 
2636  if (atom.size >= (1<<28) || atom.size < 7)
2637  return AVERROR_INVALIDDATA;
2638 
2639  profile_level = avio_r8(pb);
2640  if ((profile_level & 0xf0) != 0xc0)
2641  return 0;
2642 
2643  avio_seek(pb, 6, SEEK_CUR);
2644  ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size - 7);
2645  if (ret < 0)
2646  return ret;
2647 
2648  return 0;
2649 }
2650 
2651 static int mov_find_tref_id(const MovTref *tag, uint32_t id)
2652 {
2653  for (int i = 0; i < tag->nb_id; i++) {
2654  if (tag->id[i] == id)
2655  return 1;
2656  }
2657  return 0;
2658 }
2659 
2660 static int mov_add_tref_id(MovTref *tag, uint32_t id)
2661 {
2662  int ret = mov_find_tref_id(tag, id);
2663 
2664  if (!ret) {
2665  uint32_t *tmp = av_realloc_array(tag->id, tag->nb_id + 1, sizeof(*tag->id));
2666  if (!tmp)
2667  return AVERROR(ENOMEM);
2668  tag->id = tmp;
2669  tag->id[tag->nb_id++] = id;
2670  }
2671 
2672  return 0;
2673 }
2674 
2675 static MovTref *mov_find_tref_tag(const MOVStreamContext *sc, uint32_t name)
2676 {
2677  for (int i = 0; i < sc->nb_tref_tags; i++) {
2678  MovTref *entry = &sc->tref_tags[i];
2679 
2680  if (entry->name == name)
2681  return entry;
2682  }
2683  return NULL;
2684 }
2685 
2687 {
2689 
2690  if (!tag) {
2692  sizeof(*sc->tref_tags));
2693  if (!tmp)
2694  return NULL;
2695  sc->tref_tags = tmp;
2696  tag = &sc->tref_tags[sc->nb_tref_tags++];
2697  *tag = (MovTref){ .name = name };
2698  }
2699 
2700  return tag;
2701 }
2702 
2704 {
2705  AVStream* st;
2706  MOVStreamContext* sc;
2707 
2708  if (c->fc->nb_streams < 1)
2709  return 0;
2710 
2711  if (atom.size > 4) {
2712  av_log(c->fc, AV_LOG_ERROR, "Only a single tref of type cdsc is supported\n");
2713  return AVERROR_PATCHWELCOME;
2714  }
2715  if (atom.size < 4)
2716  return AVERROR_INVALIDDATA;
2717 
2718  st = get_curr_st(c);
2719  if (!st)
2720  return AVERROR_INVALIDDATA;
2721  sc = st->priv_data;
2722 
2723  MovTref *tag = mov_add_tref_tag(sc, atom.type);
2724  if (!tag)
2725  return AVERROR(ENOMEM);
2726 
2727  int ret = mov_add_tref_id(tag, avio_rb32(pb));
2728  if (ret < 0)
2729  return ret;
2730 
2731  return 0;
2732 }
2733 
2735 {
2736  AVStream* st;
2737  MOVStreamContext* sc;
2738 
2739  if (c->fc->nb_streams < 1)
2740  return 0;
2741 
2742  /* For SBAS this should be fine - though beware if someone implements a
2743  * tref atom processor that doesn't drop down to default then this may
2744  * be lost. */
2745  if (atom.size > 4) {
2746  av_log(c->fc, AV_LOG_ERROR, "Only a single tref of type sbas is supported\n");
2747  return AVERROR_PATCHWELCOME;
2748  }
2749  if (atom.size < 4)
2750  return AVERROR_INVALIDDATA;
2751 
2752  st = c->fc->streams[c->fc->nb_streams - 1];
2753  sc = st->priv_data;
2754 
2755  MovTref *tag = mov_add_tref_tag(sc, atom.type);
2756  if (!tag)
2757  return AVERROR(ENOMEM);
2758 
2759  int ret = mov_add_tref_id(tag, avio_rb32(pb));
2760  if (ret < 0)
2761  return ret;
2762 
2763  return 0;
2764 }
2765 
2767 {
2768  AVStream* st;
2769  MOVStreamContext* sc;
2770 
2771  if (c->fc->nb_streams < 1)
2772  return 0;
2773 
2774  if (atom.size > 4)
2775  av_log(c->fc, AV_LOG_WARNING, "More than one vdep reference is not supported.\n");
2776  if (atom.size < 4)
2777  return AVERROR_INVALIDDATA;
2778 
2779  st = c->fc->streams[c->fc->nb_streams - 1];
2780  sc = st->priv_data;
2781 
2782  MovTref *tag = mov_add_tref_tag(sc, atom.type);
2783  if (!tag)
2784  return AVERROR(ENOMEM);
2785 
2786  int ret = mov_add_tref_id(tag, avio_rb32(pb));
2787  if (ret < 0)
2788  return ret;
2789 
2790  return 0;
2791 }
2792 
2793 /**
2794  * An strf atom is a BITMAPINFOHEADER struct. This struct is 40 bytes itself,
2795  * but can have extradata appended at the end after the 40 bytes belonging
2796  * to the struct.
2797  */
2799 {
2800  AVStream *st;
2801  int ret;
2802 
2803  if (c->fc->nb_streams < 1)
2804  return 0;
2805  if (atom.size <= 40)
2806  return 0;
2807  st = c->fc->streams[c->fc->nb_streams-1];
2808 
2809  if ((uint64_t)atom.size > (1<<30))
2810  return AVERROR_INVALIDDATA;
2811 
2812  avio_skip(pb, 40);
2813  ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size - 40);
2814  if (ret < 0)
2815  return ret;
2816 
2817  return 0;
2818 }
2819 
2821 {
2822  AVStream *st;
2823  MOVStreamContext *sc;
2824  unsigned int i, entries;
2825 
2826  if (c->trak_index < 0) {
2827  av_log(c->fc, AV_LOG_WARNING, "STCO outside TRAK\n");
2828  return 0;
2829  }
2830  if (c->fc->nb_streams < 1)
2831  return 0;
2832  st = c->fc->streams[c->fc->nb_streams-1];
2833  sc = st->priv_data;
2834 
2835  avio_r8(pb); /* version */
2836  avio_rb24(pb); /* flags */
2837 
2838  // Clamp allocation size for `chunk_offsets` -- don't throw an error for an
2839  // invalid count since the EOF path doesn't throw either.
2840  entries = avio_rb32(pb);
2841  entries =
2842  FFMIN(entries,
2843  FFMAX(0, (atom.size - 8) /
2844  (atom.type == MKTAG('s', 't', 'c', 'o') ? 4 : 8)));
2845 
2846  if (!entries)
2847  return 0;
2848 
2849  if (sc->chunk_offsets) {
2850  av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicated STCO atom\n");
2851  return 0;
2852  }
2853 
2854  av_free(sc->chunk_offsets);
2855  sc->chunk_count = 0;
2856  sc->chunk_offsets = av_malloc_array(entries, sizeof(*sc->chunk_offsets));
2857  if (!sc->chunk_offsets)
2858  return AVERROR(ENOMEM);
2859  sc->chunk_count = entries;
2860 
2861  if (atom.type == MKTAG('s','t','c','o'))
2862  for (i = 0; i < entries && !pb->eof_reached; i++)
2863  sc->chunk_offsets[i] = avio_rb32(pb);
2864  else if (atom.type == MKTAG('c','o','6','4'))
2865  for (i = 0; i < entries && !pb->eof_reached; i++) {
2866  sc->chunk_offsets[i] = avio_rb64(pb);
2867  if (sc->chunk_offsets[i] < 0) {
2868  av_log(c->fc, AV_LOG_WARNING, "Impossible chunk_offset\n");
2869  sc->chunk_offsets[i] = 0;
2870  }
2871  }
2872  else
2873  return AVERROR_INVALIDDATA;
2874 
2875  sc->chunk_count = i;
2876 
2877  if (pb->eof_reached) {
2878  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STCO atom\n");
2879  return AVERROR_EOF;
2880  }
2881 
2882  return 0;
2883 }
2884 
2885 static int mov_codec_id(AVStream *st, uint32_t format)
2886 {
2888 
2889  if (id <= 0 &&
2890  ((format & 0xFFFF) == 'm' + ('s' << 8) ||
2891  (format & 0xFFFF) == 'T' + ('S' << 8)))
2893 
2894  if (st->codecpar->codec_type != AVMEDIA_TYPE_VIDEO && id > 0) {
2896  } else if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO &&
2897  /* skip old ASF MPEG-4 tag */
2898  format && format != MKTAG('m','p','4','s')) {
2900  if (id <= 0)
2902  if (id > 0)
2904  else if (st->codecpar->codec_type == AVMEDIA_TYPE_DATA ||
2906  st->codecpar->codec_id == AV_CODEC_ID_NONE)) {
2908  if (id <= 0) {
2910  AV_CODEC_ID_TTML : id;
2911  }
2912 
2913  if (id > 0)
2915  else
2917  }
2918  }
2919 
2920  st->codecpar->codec_tag = format;
2921 
2922  return id;
2923 }
2924 
2926  AVStream *st, MOVStreamContext *sc)
2927 {
2928  uint8_t codec_name[32] = { 0 };
2929  int64_t stsd_start;
2930  unsigned int len;
2931  uint32_t id = 0;
2932 
2933  /* The first 16 bytes of the video sample description are already
2934  * read in ff_mov_read_stsd_entries() */
2935  stsd_start = avio_tell(pb) - 16;
2936 
2937  if (c->isom) {
2938  avio_skip(pb, 2); /* pre_defined */
2939  avio_skip(pb, 2); /* reserved */
2940  avio_skip(pb, 12); /* pre_defined */
2941  } else {
2942  avio_rb16(pb); /* version */
2943  avio_rb16(pb); /* revision level */
2944  id = avio_rl32(pb); /* vendor */
2945  av_dict_set(&st->metadata, "vendor_id", av_fourcc2str(id), 0);
2946  avio_rb32(pb); /* temporal quality */
2947  avio_rb32(pb); /* spatial quality */
2948  }
2949 
2950  st->codecpar->width = avio_rb16(pb); /* width */
2951  st->codecpar->height = avio_rb16(pb); /* height */
2952 
2953  avio_rb32(pb); /* horiz resolution */
2954  avio_rb32(pb); /* vert resolution */
2955  avio_rb32(pb); /* data size, always 0 */
2956  avio_rb16(pb); /* frames per samples */
2957 
2958  len = avio_r8(pb); /* codec name, pascal string */
2959  if (len > 31)
2960  len = 31;
2961  mov_read_mac_string(c, pb, len, codec_name, sizeof(codec_name));
2962  if (len < 31)
2963  avio_skip(pb, 31 - len);
2964 
2965  if (codec_name[0])
2966  av_dict_set(&st->metadata, "encoder", codec_name, 0);
2967 
2968  /* codec_tag YV12 triggers an UV swap in rawdec.c */
2969  if (!strncmp(codec_name, "Planar Y'CbCr 8-bit 4:2:0", 25)) {
2970  st->codecpar->codec_tag = MKTAG('I', '4', '2', '0');
2971  st->codecpar->width &= ~1;
2972  st->codecpar->height &= ~1;
2973  }
2974  /* Flash Media Server uses tag H.263 with Sorenson Spark */
2975  if (st->codecpar->codec_tag == MKTAG('H','2','6','3') &&
2976  !strncmp(codec_name, "Sorenson H263", 13))
2978 
2979  st->codecpar->bits_per_coded_sample = avio_rb16(pb); /* depth */
2980 
2981  avio_seek(pb, stsd_start, SEEK_SET);
2982 
2983  if (ff_get_qtpalette(st->codecpar->codec_id, pb, sc->palette)) {
2984  st->codecpar->bits_per_coded_sample &= 0x1F;
2985  sc->has_palette = 1;
2986  }
2987 }
2988 
2990  AVStream *st, MOVStreamContext *sc)
2991 {
2992  int bits_per_sample, flags;
2993  uint16_t version = avio_rb16(pb);
2994  uint32_t id = 0;
2995  AVDictionaryEntry *compatible_brands = av_dict_get(c->fc->metadata, "compatible_brands", NULL, AV_DICT_MATCH_CASE);
2996  int channel_count;
2997 
2998  if (c->isom)
2999  avio_skip(pb, 6); /* reserved */
3000  else {
3001  avio_rb16(pb); /* revision level */
3002  id = avio_rl32(pb); /* vendor */
3003  av_dict_set(&st->metadata, "vendor_id", av_fourcc2str(id), 0);
3004  }
3005 
3006  channel_count = avio_rb16(pb);
3007 
3009  st->codecpar->ch_layout.nb_channels = channel_count;
3010  st->codecpar->bits_per_coded_sample = avio_rb16(pb); /* sample size */
3011  av_log(c->fc, AV_LOG_TRACE, "audio channels %d\n", channel_count);
3012 
3013  sc->audio_cid = avio_rb16(pb);
3014  avio_rb16(pb); /* packet size = 0 */
3015 
3016  st->codecpar->sample_rate = ((avio_rb32(pb) >> 16));
3017 
3018  // Read QT version 1 fields. In version 0 these do not exist.
3019  av_log(c->fc, AV_LOG_TRACE, "version =%d, isom =%d\n", version, c->isom);
3020  if (!c->isom ||
3021  (compatible_brands && strstr(compatible_brands->value, "qt ")) ||
3022  (sc->stsd_version == 0 && version > 0)) {
3023  if (version == 1) {
3024  sc->samples_per_frame = avio_rb32(pb);
3025  avio_rb32(pb); /* bytes per packet */
3026  sc->bytes_per_frame = avio_rb32(pb);
3027  avio_rb32(pb); /* bytes per sample */
3028  } else if (version == 2) {
3029  avio_rb32(pb); /* sizeof struct only */
3031  channel_count = avio_rb32(pb);
3033  st->codecpar->ch_layout.nb_channels = channel_count;
3034  avio_rb32(pb); /* always 0x7F000000 */
3036 
3037  flags = avio_rb32(pb); /* lpcm format specific flag */
3038  sc->bytes_per_frame = avio_rb32(pb);
3039  sc->samples_per_frame = avio_rb32(pb);
3040  if (st->codecpar->codec_tag == MKTAG('l','p','c','m'))
3041  st->codecpar->codec_id =
3043  flags);
3044  }
3045  if (version == 0 || (version == 1 && sc->audio_cid != -2)) {
3046  /* can't correctly handle variable sized packet as audio unit */
3047  switch (st->codecpar->codec_id) {
3048  case AV_CODEC_ID_MP2:
3049  case AV_CODEC_ID_MP3:
3051  break;
3052  }
3053  }
3054  }
3055 
3056  if (sc->format == 0) {
3057  if (st->codecpar->bits_per_coded_sample == 8)
3058  st->codecpar->codec_id = mov_codec_id(st, MKTAG('r','a','w',' '));
3059  else if (st->codecpar->bits_per_coded_sample == 16)
3060  st->codecpar->codec_id = mov_codec_id(st, MKTAG('t','w','o','s'));
3061  }
3062 
3063  switch (st->codecpar->codec_id) {
3064  case AV_CODEC_ID_PCM_S8:
3065  case AV_CODEC_ID_PCM_U8:
3066  if (st->codecpar->bits_per_coded_sample == 16)
3068  break;
3069  case AV_CODEC_ID_PCM_S16LE:
3070  case AV_CODEC_ID_PCM_S16BE:
3071  if (st->codecpar->bits_per_coded_sample == 8)
3073  else if (st->codecpar->bits_per_coded_sample == 24)
3074  st->codecpar->codec_id =
3077  else if (st->codecpar->bits_per_coded_sample == 32)
3078  st->codecpar->codec_id =
3081  break;
3082  /* set values for old format before stsd version 1 appeared */
3083  case AV_CODEC_ID_MACE3:
3084  sc->samples_per_frame = 6;
3086  break;
3087  case AV_CODEC_ID_MACE6:
3088  sc->samples_per_frame = 6;
3090  break;
3092  sc->samples_per_frame = 64;
3094  break;
3095  case AV_CODEC_ID_GSM:
3096  sc->samples_per_frame = 160;
3097  sc->bytes_per_frame = 33;
3098  break;
3099  default:
3100  break;
3101  }
3102 
3103  bits_per_sample = av_get_bits_per_sample(st->codecpar->codec_id);
3104  if (bits_per_sample && (bits_per_sample >> 3) * (uint64_t)st->codecpar->ch_layout.nb_channels <= INT_MAX) {
3105  st->codecpar->bits_per_coded_sample = bits_per_sample;
3106  sc->sample_size = (bits_per_sample >> 3) * st->codecpar->ch_layout.nb_channels;
3107  }
3108 }
3109 
3111  AVStream *st, MOVStreamContext *sc,
3112  int64_t size)
3113 {
3114  // ttxt stsd contains display flags, justification, background
3115  // color, fonts, and default styles, so fake an atom to read it
3116  MOVAtom fake_atom = { .size = size };
3117  // mp4s contains a regular esds atom, dfxp ISMV TTML has no content
3118  // in extradata unlike stpp MP4 TTML.
3119  if (st->codecpar->codec_tag != AV_RL32("mp4s") &&
3121  mov_read_glbl(c, pb, fake_atom);
3122  st->codecpar->width = sc->width;
3123  st->codecpar->height = sc->height;
3124 }
3125 
3127  AVStream *st, MOVStreamContext *sc,
3128  int64_t size)
3129 {
3130  int ret;
3131 
3132  if (st->codecpar->codec_tag == MKTAG('t','m','c','d')) {
3133  if ((int)size != size)
3134  return AVERROR(ENOMEM);
3135 
3136  ret = ff_get_extradata(c->fc, st->codecpar, pb, size);
3137  if (ret < 0)
3138  return ret;
3139  if (size > 16) {
3140  MOVStreamContext *tmcd_ctx = st->priv_data;
3141  int val;
3142  val = AV_RB32(st->codecpar->extradata + 4);
3143  tmcd_ctx->tmcd_flags = val;
3144  st->avg_frame_rate.num = AV_RB32(st->codecpar->extradata + 8); /* timescale */
3145  st->avg_frame_rate.den = AV_RB32(st->codecpar->extradata + 12); /* frameDuration */
3146  tmcd_ctx->tmcd_nb_frames = st->codecpar->extradata[16]; /* number of frames */
3147  if (size > 30) {
3148  uint32_t len = AV_RB32(st->codecpar->extradata + 18); /* name atom length */
3149  uint32_t format = AV_RB32(st->codecpar->extradata + 22);
3150  if (format == AV_RB32("name") && (int64_t)size >= (int64_t)len + 18) {
3151  uint16_t str_size = AV_RB16(st->codecpar->extradata + 26); /* string length */
3152  if (str_size > 0 && size >= (int)str_size + 30 &&
3153  st->codecpar->extradata[30] /* Don't add empty string */) {
3154  char *reel_name = av_malloc(str_size + 1);
3155  if (!reel_name)
3156  return AVERROR(ENOMEM);
3157  memcpy(reel_name, st->codecpar->extradata + 30, str_size);
3158  reel_name[str_size] = 0; /* Add null terminator */
3159  av_dict_set(&st->metadata, "reel_name", reel_name,
3161  }
3162  }
3163  }
3164  }
3165  } else if (st->codecpar->codec_id == AV_CODEC_ID_ITUT_T35) {
3166  int t35_identifier_length = avio_r8(pb);
3167 
3168  if (t35_identifier_length <= 0 || t35_identifier_length >= size)
3169  return AVERROR_INVALIDDATA;
3170 
3171  ret = ff_get_extradata(c->fc, st->codecpar, pb, t35_identifier_length);
3172  if (ret < 0)
3173  return ret;
3174 
3175  int hrsd_len = size - t35_identifier_length - 1;
3176  if (hrsd_len > 0) {
3177  uint8_t *hrsd_str = av_malloc(hrsd_len + 1);
3178  if (!hrsd_str)
3179  return AVERROR(ENOMEM);
3180 
3181  ret = ffio_read_size(pb, hrsd_str, hrsd_len);
3182  if (ret < 0) {
3183  av_free(hrsd_str);
3184  return ret;
3185  }
3186  if (hrsd_str[0]) {
3187  hrsd_str[hrsd_len] = 0;
3188  ret = av_dict_set(&st->metadata, "description", hrsd_str, AV_DICT_DONT_OVERWRITE);
3189  }
3190  av_free(hrsd_str);
3191  }
3192  } else {
3193  /* other codec type, just skip (rtp, mp4s ...) */
3194  avio_skip(pb, size);
3195  }
3196  return 0;
3197 }
3198 
3200  AVStream *st, MOVStreamContext *sc)
3201 {
3202  FFStream *const sti = ffstream(st);
3203 
3204  if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
3205  !st->codecpar->sample_rate && sc->time_scale > 1)
3206  st->codecpar->sample_rate = sc->time_scale;
3207 
3208  /* special codec parameters handling */
3209  switch (st->codecpar->codec_id) {
3210 #if CONFIG_DV_DEMUXER
3211  case AV_CODEC_ID_DVAUDIO:
3212  if (c->dv_fctx) {
3213  avpriv_request_sample(c->fc, "multiple DV audio streams");
3214  return AVERROR(ENOSYS);
3215  }
3216 
3217  c->dv_fctx = avformat_alloc_context();
3218  if (!c->dv_fctx) {
3219  av_log(c->fc, AV_LOG_ERROR, "dv demux context alloc error\n");
3220  return AVERROR(ENOMEM);
3221  }
3222  c->dv_demux = avpriv_dv_init_demux(c->dv_fctx);
3223  if (!c->dv_demux) {
3224  av_log(c->fc, AV_LOG_ERROR, "dv demux context init error\n");
3225  return AVERROR(ENOMEM);
3226  }
3227  sc->dv_audio_container = 1;
3229  break;
3230 #endif
3231  /* no ifdef since parameters are always those */
3232  case AV_CODEC_ID_QCELP:
3235  // force sample rate for qcelp when not stored in mov
3236  if (st->codecpar->codec_tag != MKTAG('Q','c','l','p'))
3237  st->codecpar->sample_rate = 8000;
3238  // FIXME: Why is the following needed for some files?
3239  sc->samples_per_frame = 160;
3240  if (!sc->bytes_per_frame)
3241  sc->bytes_per_frame = 35;
3242  break;
3243  case AV_CODEC_ID_AMR_NB:
3246  /* force sample rate for amr, stsd in 3gp does not store sample rate */
3247  st->codecpar->sample_rate = 8000;
3248  break;
3249  case AV_CODEC_ID_AMR_WB:
3252  st->codecpar->sample_rate = 16000;
3253  break;
3254  case AV_CODEC_ID_MP2:
3255  case AV_CODEC_ID_MP3:
3256  /* force type after stsd for m1a hdlr */
3258  break;
3259  case AV_CODEC_ID_GSM:
3260  case AV_CODEC_ID_ADPCM_MS:
3262  case AV_CODEC_ID_ILBC:
3263  case AV_CODEC_ID_MACE3:
3264  case AV_CODEC_ID_MACE6:
3265  case AV_CODEC_ID_QDM2:
3267  break;
3268  case AV_CODEC_ID_ALAC:
3269  if (st->codecpar->extradata_size == 36) {
3270  int channel_count = AV_RB8(st->codecpar->extradata + 21);
3271  if (st->codecpar->ch_layout.nb_channels != channel_count) {
3274  st->codecpar->ch_layout.nb_channels = channel_count;
3275  }
3276  st->codecpar->sample_rate = AV_RB32(st->codecpar->extradata + 32);
3277  }
3278  break;
3279  case AV_CODEC_ID_AC3:
3280  case AV_CODEC_ID_EAC3:
3282  case AV_CODEC_ID_VC1:
3283  case AV_CODEC_ID_VP8:
3284  case AV_CODEC_ID_VP9:
3286  break;
3288  case AV_CODEC_ID_PRORES:
3289  case AV_CODEC_ID_APV:
3290  case AV_CODEC_ID_EVC:
3291  case AV_CODEC_ID_LCEVC:
3292  case AV_CODEC_ID_AV1:
3293  /* field_order detection of H264 requires parsing */
3294  case AV_CODEC_ID_H264:
3296  break;
3297  default:
3298  break;
3299  }
3300  return 0;
3301 }
3302 
3304  int codec_tag, int format,
3305  int64_t size)
3306 {
3307  if (codec_tag &&
3308  (codec_tag != format &&
3309  // AVID 1:1 samples with differing data format and codec tag exist
3310  (codec_tag != AV_RL32("AV1x") || format != AV_RL32("AVup")) &&
3311  // prores is allowed to have differing data format and codec tag
3312  codec_tag != AV_RL32("apcn") && codec_tag != AV_RL32("apch") &&
3313  // so is dv (sigh)
3314  codec_tag != AV_RL32("dvpp") && codec_tag != AV_RL32("dvcp") &&
3315  (c->fc->video_codec_id ? ff_codec_get_id(ff_codec_movvideo_tags, format) != c->fc->video_codec_id
3316  : codec_tag != MKTAG('j','p','e','g')))) {
3317  /* Multiple fourcc, we skip JPEG. This is not correct, we should
3318  * export it as a separate AVStream but this needs a few changes
3319  * in the MOV demuxer, patch welcome. */
3320 
3321  av_log(c->fc, AV_LOG_WARNING, "multiple fourcc not supported\n");
3322  avio_skip(pb, size);
3323  return 1;
3324  }
3325 
3326  return 0;
3327 }
3328 
3330 {
3331  int ret;
3332 
3333  /* special codec parameters handling */
3334  switch (st->codecpar->codec_id) {
3335  case AV_CODEC_ID_H264:
3336  // done for ai5q, ai52, ai55, ai1q, ai12 and ai15.
3337  if (!st->codecpar->extradata_size && TAG_IS_AVCI(st->codecpar->codec_tag)) {
3339  if (ret < 0)
3340  return ret;
3341  }
3342  break;
3343  default:
3344  break;
3345  }
3346 
3347  return 0;
3348 }
3349 
3351 {
3352  AVStream *st;
3353  MOVStreamContext *sc;
3354  int pseudo_stream_id;
3355 
3356  av_assert0 (c->fc->nb_streams >= 1);
3357  st = c->fc->streams[c->fc->nb_streams-1];
3358  sc = st->priv_data;
3359 
3360  for (pseudo_stream_id = 0;
3361  pseudo_stream_id < entries && !pb->eof_reached;
3362  pseudo_stream_id++) {
3363  //Parsing Sample description table
3364  enum AVCodecID id;
3365  int ret, dref_id = 1;
3366  MOVAtom a = { AV_RL32("stsd") };
3367  int64_t start_pos = avio_tell(pb);
3368  int64_t size = avio_rb32(pb); /* size */
3369  uint32_t format = avio_rl32(pb); /* data format */
3370 
3371  if (size >= 16) {
3372  avio_rb32(pb); /* reserved */
3373  avio_rb16(pb); /* reserved */
3374  dref_id = avio_rb16(pb);
3375  } else if (size <= 7) {
3376  av_log(c->fc, AV_LOG_ERROR,
3377  "invalid size %"PRId64" in stsd\n", size);
3378  return AVERROR_INVALIDDATA;
3379  }
3380 
3382  size - (avio_tell(pb) - start_pos))) {
3383  sc->stsd_count++;
3384  continue;
3385  }
3386 
3387  sc->pseudo_stream_id = st->codecpar->codec_tag ? -1 : pseudo_stream_id;
3388  sc->dref_id= dref_id;
3389  sc->format = format;
3390 
3391  id = mov_codec_id(st, format);
3392 
3393  av_log(c->fc, AV_LOG_TRACE,
3394  "size=%"PRId64" 4CC=%s codec_type=%d\n", size,
3396 
3397  st->codecpar->codec_id = id;
3399  mov_parse_stsd_video(c, pb, st, sc);
3400  } else if (st->codecpar->codec_type==AVMEDIA_TYPE_AUDIO) {
3401  mov_parse_stsd_audio(c, pb, st, sc);
3402  if (st->codecpar->sample_rate < 0) {
3403  av_log(c->fc, AV_LOG_ERROR, "Invalid sample rate %d\n", st->codecpar->sample_rate);
3404  return AVERROR_INVALIDDATA;
3405  }
3406  if (st->codecpar->ch_layout.nb_channels < 0) {
3407  av_log(c->fc, AV_LOG_ERROR, "Invalid channels %d\n", st->codecpar->ch_layout.nb_channels);
3408  return AVERROR_INVALIDDATA;
3409  }
3410  } else if (st->codecpar->codec_type==AVMEDIA_TYPE_SUBTITLE){
3411  mov_parse_stsd_subtitle(c, pb, st, sc,
3412  size - (avio_tell(pb) - start_pos));
3413  } else {
3414  ret = mov_parse_stsd_data(c, pb, st, sc,
3415  size - (avio_tell(pb) - start_pos));
3416  if (ret < 0)
3417  return ret;
3418  }
3419  /* this will read extra atoms at the end (wave, alac, damr, avcC, hvcC, SMI ...) */
3420  a.size = size - (avio_tell(pb) - start_pos);
3421  if (a.size > 8) {
3422  if ((ret = mov_read_default(c, pb, a)) < 0)
3423  return ret;
3424  } else if (a.size > 0)
3425  avio_skip(pb, a.size);
3426 
3427  ret = mov_finalize_stsd_entry(c, st);
3428  if (ret < 0)
3429  return ret;
3430 
3431  if (sc->extradata && st->codecpar->extradata) {
3432  int extra_size = st->codecpar->extradata_size;
3433 
3434  /* Move the current stream extradata to the stream context one. */
3435  sc->extradata_size[pseudo_stream_id] = extra_size;
3436  sc->extradata[pseudo_stream_id] = st->codecpar->extradata;
3437  st->codecpar->extradata = NULL;
3438  st->codecpar->extradata_size = 0;
3439  }
3440  sc->stsd_count++;
3441  }
3442 
3443  if (pb->eof_reached) {
3444  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSD atom\n");
3445  return AVERROR_EOF;
3446  }
3447 
3448  return 0;
3449 }
3450 
3452 {
3453  AVStream *st;
3454  MOVStreamContext *sc;
3455  int ret, entries;
3456 
3457  if (c->fc->nb_streams < 1)
3458  return 0;
3459  st = c->fc->streams[c->fc->nb_streams - 1];
3460  sc = st->priv_data;
3461 
3462  if (sc->extradata) {
3463  av_log(c->fc, AV_LOG_ERROR,
3464  "Duplicate stsd found in this track.\n");
3465  return AVERROR_INVALIDDATA;
3466  }
3467 
3468  sc->stsd_version = avio_r8(pb);
3469  avio_rb24(pb); /* flags */
3470  entries = avio_rb32(pb);
3471 
3472  /* Each entry contains a size (4 bytes) and format (4 bytes). */
3473  if (entries <= 0 || entries > atom.size / 8 || entries > 1024) {
3474  av_log(c->fc, AV_LOG_ERROR, "invalid STSD entries %d\n", entries);
3475  return AVERROR_INVALIDDATA;
3476  }
3477 
3478  /* Prepare space for hosting multiple extradata. */
3479  sc->extradata = av_calloc(entries, sizeof(*sc->extradata));
3480  if (!sc->extradata)
3481  return AVERROR(ENOMEM);
3482 
3483  sc->extradata_size = av_calloc(entries, sizeof(*sc->extradata_size));
3484  if (!sc->extradata_size) {
3485  ret = AVERROR(ENOMEM);
3486  goto fail;
3487  }
3488 
3489  ret = ff_mov_read_stsd_entries(c, pb, entries);
3490  if (ret < 0)
3491  goto fail;
3492 
3493  /* Restore back the primary extradata. */
3494  av_freep(&st->codecpar->extradata);
3495  st->codecpar->extradata_size = sc->extradata_size[0];
3496  if (sc->extradata_size[0]) {
3498  if (!st->codecpar->extradata)
3499  return AVERROR(ENOMEM);
3500  memcpy(st->codecpar->extradata, sc->extradata[0], sc->extradata_size[0]);
3501  }
3502 
3503  return mov_finalize_stsd_codec(c, pb, st, sc);
3504 fail:
3505  if (sc->extradata) {
3506  int j;
3507  for (j = 0; j < sc->stsd_count; j++)
3508  av_freep(&sc->extradata[j]);
3509  }
3510 
3511  sc->stsd_count = 0;
3512  av_freep(&sc->extradata);
3513  av_freep(&sc->extradata_size);
3514  return ret;
3515 }
3516 
3518 {
3519  AVStream *st;
3520  MOVStreamContext *sc;
3521  unsigned int i, entries;
3522 
3523  if (c->trak_index < 0) {
3524  av_log(c->fc, AV_LOG_WARNING, "STSC outside TRAK\n");
3525  return 0;
3526  }
3527 
3528  if (c->fc->nb_streams < 1)
3529  return 0;
3530  st = c->fc->streams[c->fc->nb_streams-1];
3531  sc = st->priv_data;
3532 
3533  avio_r8(pb); /* version */
3534  avio_rb24(pb); /* flags */
3535 
3536  entries = avio_rb32(pb);
3537  if ((uint64_t)entries * 12 + 4 > atom.size)
3538  return AVERROR_INVALIDDATA;
3539 
3540  av_log(c->fc, AV_LOG_TRACE, "track[%u].stsc.entries = %u\n", c->fc->nb_streams - 1, entries);
3541 
3542  if (!entries)
3543  return 0;
3544  if (sc->stsc_data) {
3545  av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicated STSC atom\n");
3546  return 0;
3547  }
3548  av_free(sc->stsc_data);
3549  sc->stsc_count = 0;
3550  sc->stsc_data = av_malloc_array(entries, sizeof(*sc->stsc_data));
3551  if (!sc->stsc_data)
3552  return AVERROR(ENOMEM);
3553 
3554  for (i = 0; i < entries && !pb->eof_reached; i++) {
3555  sc->stsc_data[i].first = avio_rb32(pb);
3556  sc->stsc_data[i].count = avio_rb32(pb);
3557  sc->stsc_data[i].id = avio_rb32(pb);
3558  }
3559 
3560  sc->stsc_count = i;
3561  for (i = sc->stsc_count - 1; i < UINT_MAX; i--) {
3562  int64_t first_min = i + 1;
3563  if ((i+1 < sc->stsc_count && sc->stsc_data[i].first >= sc->stsc_data[i+1].first) ||
3564  (i > 0 && sc->stsc_data[i].first <= sc->stsc_data[i-1].first) ||
3565  sc->stsc_data[i].first < first_min ||
3566  sc->stsc_data[i].count < 1 ||
3567  sc->stsc_data[i].id < 1) {
3568  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);
3569  if (i+1 >= sc->stsc_count) {
3570  if (sc->stsc_data[i].count == 0 && i > 0) {
3571  sc->stsc_count --;
3572  continue;
3573  }
3574  sc->stsc_data[i].first = FFMAX(sc->stsc_data[i].first, first_min);
3575  if (i > 0 && sc->stsc_data[i].first <= sc->stsc_data[i-1].first)
3576  sc->stsc_data[i].first = FFMIN(sc->stsc_data[i-1].first + 1LL, INT_MAX);
3577  sc->stsc_data[i].count = FFMAX(sc->stsc_data[i].count, 1);
3578  sc->stsc_data[i].id = FFMAX(sc->stsc_data[i].id, 1);
3579  continue;
3580  }
3581  av_assert0(sc->stsc_data[i+1].first >= 2);
3582  // We replace this entry by the next valid
3583  sc->stsc_data[i].first = sc->stsc_data[i+1].first - 1;
3584  sc->stsc_data[i].count = sc->stsc_data[i+1].count;
3585  sc->stsc_data[i].id = sc->stsc_data[i+1].id;
3586  }
3587  }
3588 
3589  if (pb->eof_reached) {
3590  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSC atom\n");
3591  return AVERROR_EOF;
3592  }
3593 
3594  return 0;
3595 }
3596 
3597 static inline int mov_stsc_index_valid(unsigned int index, unsigned int count)
3598 {
3599  return index < count - 1;
3600 }
3601 
3602 /* Compute the samples value for the stsc entry at the given index. */
3603 static inline int64_t mov_get_stsc_samples(MOVStreamContext *sc, unsigned int index)
3604 {
3605  int chunk_count;
3606 
3608  chunk_count = sc->stsc_data[index + 1].first - sc->stsc_data[index].first;
3609  else {
3610  // Validation for stsc / stco happens earlier in mov_read_stsc + mov_read_trak.
3612  chunk_count = sc->chunk_count - (sc->stsc_data[index].first - 1);
3613  }
3614 
3615  return sc->stsc_data[index].count * (int64_t)chunk_count;
3616 }
3617 
3619 {
3620  AVStream *st;
3621  MOVStreamContext *sc;
3622  unsigned i, entries;
3623 
3624  if (c->trak_index < 0) {
3625  av_log(c->fc, AV_LOG_WARNING, "STPS outside TRAK\n");
3626  return 0;
3627  }
3628 
3629  if (c->fc->nb_streams < 1)
3630  return 0;
3631  st = c->fc->streams[c->fc->nb_streams-1];
3632  sc = st->priv_data;
3633 
3634  avio_rb32(pb); // version + flags
3635 
3636  entries = avio_rb32(pb);
3637  if (sc->stps_data)
3638  av_log(c->fc, AV_LOG_WARNING, "Duplicated STPS atom\n");
3639  av_free(sc->stps_data);
3640  sc->stps_count = 0;
3641  sc->stps_data = av_malloc_array(entries, sizeof(*sc->stps_data));
3642  if (!sc->stps_data)
3643  return AVERROR(ENOMEM);
3644 
3645  for (i = 0; i < entries && !pb->eof_reached; i++) {
3646  sc->stps_data[i] = avio_rb32(pb);
3647  }
3648 
3649  sc->stps_count = i;
3650 
3651  if (pb->eof_reached) {
3652  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STPS atom\n");
3653  return AVERROR_EOF;
3654  }
3655 
3656  return 0;
3657 }
3658 
3660 {
3661  AVStream *st;
3662  FFStream *sti;
3663  MOVStreamContext *sc;
3664  unsigned int i, entries;
3665 
3666  if (c->trak_index < 0) {
3667  av_log(c->fc, AV_LOG_WARNING, "STSS outside TRAK\n");
3668  return 0;
3669  }
3670 
3671  if (c->fc->nb_streams < 1)
3672  return 0;
3673  st = c->fc->streams[c->fc->nb_streams-1];
3674  sti = ffstream(st);
3675  sc = st->priv_data;
3676 
3677  avio_r8(pb); /* version */
3678  avio_rb24(pb); /* flags */
3679 
3680  entries = avio_rb32(pb);
3681 
3682  av_log(c->fc, AV_LOG_TRACE, "keyframe_count = %u\n", entries);
3683 
3684  if (!entries) {
3685  sc->keyframe_absent = 1;
3686  if (!sti->need_parsing && st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
3688  return 0;
3689  }
3690  if (sc->keyframes)
3691  av_log(c->fc, AV_LOG_WARNING, "Duplicated STSS atom\n");
3692  if (entries >= UINT_MAX / sizeof(int))
3693  return AVERROR_INVALIDDATA;
3694  av_freep(&sc->keyframes);
3695  sc->keyframe_count = 0;
3696  sc->keyframes = av_malloc_array(entries, sizeof(*sc->keyframes));
3697  if (!sc->keyframes)
3698  return AVERROR(ENOMEM);
3699 
3700  for (i = 0; i < entries && !pb->eof_reached; i++) {
3701  sc->keyframes[i] = avio_rb32(pb);
3702  }
3703 
3704  sc->keyframe_count = i;
3705 
3706  if (pb->eof_reached) {
3707  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSS atom\n");
3708  return AVERROR_EOF;
3709  }
3710 
3711  return 0;
3712 }
3713 
3715 {
3716  AVStream *st;
3717  MOVStreamContext *sc;
3718  unsigned int i, entries, sample_size, field_size, num_bytes;
3719  GetBitContext gb;
3720  unsigned char* buf;
3721  int ret;
3722 
3723  if (c->trak_index < 0) {
3724  av_log(c->fc, AV_LOG_WARNING, "STSZ outside TRAK\n");
3725  return 0;
3726  }
3727 
3728  if (c->fc->nb_streams < 1)
3729  return 0;
3730  st = c->fc->streams[c->fc->nb_streams-1];
3731  sc = st->priv_data;
3732 
3733  avio_r8(pb); /* version */
3734  avio_rb24(pb); /* flags */
3735 
3736  if (atom.type == MKTAG('s','t','s','z')) {
3737  sample_size = avio_rb32(pb);
3738  if (!sc->sample_size) /* do not overwrite value computed in stsd */
3739  sc->sample_size = sample_size;
3740  sc->stsz_sample_size = sample_size;
3741  field_size = 32;
3742  } else {
3743  sample_size = 0;
3744  avio_rb24(pb); /* reserved */
3745  field_size = avio_r8(pb);
3746  }
3747  entries = avio_rb32(pb);
3748 
3749  av_log(c->fc, AV_LOG_TRACE, "sample_size = %u sample_count = %u\n", sc->sample_size, entries);
3750 
3751  sc->sample_count = entries;
3752  if (sample_size)
3753  return 0;
3754 
3755  if (field_size != 4 && field_size != 8 && field_size != 16 && field_size != 32) {
3756  av_log(c->fc, AV_LOG_ERROR, "Invalid sample field size %u\n", field_size);
3757  return AVERROR_INVALIDDATA;
3758  }
3759 
3760  if (!entries)
3761  return 0;
3762  if (entries >= (INT_MAX - 4 - 8 * AV_INPUT_BUFFER_PADDING_SIZE) / field_size)
3763  return AVERROR_INVALIDDATA;
3764  if (sc->sample_sizes)
3765  av_log(c->fc, AV_LOG_WARNING, "Duplicated STSZ atom\n");
3766  av_free(sc->sample_sizes);
3767  sc->sample_count = 0;
3768  sc->sample_sizes = av_malloc_array(entries, sizeof(*sc->sample_sizes));
3769  if (!sc->sample_sizes)
3770  return AVERROR(ENOMEM);
3771 
3772  num_bytes = (entries*field_size+4)>>3;
3773 
3774  buf = av_malloc(num_bytes+AV_INPUT_BUFFER_PADDING_SIZE);
3775  if (!buf) {
3776  av_freep(&sc->sample_sizes);
3777  return AVERROR(ENOMEM);
3778  }
3779 
3780  ret = ffio_read_size(pb, buf, num_bytes);
3781  if (ret < 0) {
3782  av_freep(&sc->sample_sizes);
3783  av_free(buf);
3784  av_log(c->fc, AV_LOG_WARNING, "STSZ atom truncated\n");
3785  return 0;
3786  }
3787 
3788  init_get_bits(&gb, buf, 8*num_bytes);
3789 
3790  for (i = 0; i < entries; i++) {
3791  sc->sample_sizes[i] = get_bits_long(&gb, field_size);
3792  if (sc->sample_sizes[i] > INT64_MAX - sc->data_size) {
3793  av_free(buf);
3794  av_log(c->fc, AV_LOG_ERROR, "Sample size overflow in STSZ\n");
3795  return AVERROR_INVALIDDATA;
3796  }
3797  sc->data_size += sc->sample_sizes[i];
3798  }
3799 
3800  sc->sample_count = i;
3801 
3802  av_free(buf);
3803 
3804  return 0;
3805 }
3806 
3808 {
3809  AVStream *st;
3810  MOVStreamContext *sc;
3811  unsigned int i, entries;
3812  int64_t duration = 0;
3813  int64_t total_sample_count = 0;
3814  int64_t current_dts = 0;
3815  int64_t corrected_dts = 0;
3816 
3817  if (c->trak_index < 0) {
3818  av_log(c->fc, AV_LOG_WARNING, "STTS outside TRAK\n");
3819  return 0;
3820  }
3821 
3822  if (c->fc->nb_streams < 1)
3823  return 0;
3824  st = c->fc->streams[c->fc->nb_streams-1];
3825  sc = st->priv_data;
3826 
3827  avio_r8(pb); /* version */
3828  avio_rb24(pb); /* flags */
3829  entries = avio_rb32(pb);
3830 
3831  av_log(c->fc, AV_LOG_TRACE, "track[%u].stts.entries = %u\n",
3832  c->fc->nb_streams-1, entries);
3833 
3834  if (sc->stts_data)
3835  av_log(c->fc, AV_LOG_WARNING, "Duplicated STTS atom\n");
3836  av_freep(&sc->stts_data);
3837  sc->stts_count = 0;
3838  if (entries >= INT_MAX / sizeof(*sc->stts_data))
3839  return AVERROR(ENOMEM);
3840 
3841  for (i = 0; i < entries && !pb->eof_reached; i++) {
3842  unsigned int sample_duration;
3843  unsigned int sample_count;
3844  unsigned int min_entries = FFMIN(FFMAX(i + 1, 1024 * 1024), entries);
3845  MOVStts *stts_data = av_fast_realloc(sc->stts_data, &sc->stts_allocated_size,
3846  min_entries * sizeof(*sc->stts_data));
3847  if (!stts_data) {
3848  av_freep(&sc->stts_data);
3849  sc->stts_count = 0;
3850  return AVERROR(ENOMEM);
3851  }
3852  sc->stts_count = min_entries;
3853  sc->stts_data = stts_data;
3854 
3855  sample_count = avio_rb32(pb);
3856  sample_duration = avio_rb32(pb);
3857 
3858  sc->stts_data[i].count= sample_count;
3859  sc->stts_data[i].duration= sample_duration;
3860 
3861  av_log(c->fc, AV_LOG_TRACE, "sample_count=%u, sample_duration=%u\n",
3862  sample_count, sample_duration);
3863 
3864  /* STTS sample offsets are uint32 but some files store it as int32
3865  * with negative values used to correct DTS delays.
3866  There may be abnormally large values as well. */
3867  if (sample_duration > c->max_stts_delta) {
3868  // assume high delta is a correction if negative when cast as int32
3869  int32_t delta_magnitude = (int32_t)sample_duration;
3870  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",
3871  sample_duration, i, sample_count, st->index);
3872  sc->stts_data[i].duration = 1;
3873  corrected_dts = av_sat_add64(corrected_dts, (delta_magnitude < 0 ? (int64_t)delta_magnitude : 1) * sample_count);
3874  } else {
3875  corrected_dts += sample_duration * (uint64_t)sample_count;
3876  }
3877 
3878  current_dts += sc->stts_data[i].duration * (uint64_t)sample_count;
3879 
3880  if (current_dts > corrected_dts) {
3881  int64_t drift = av_sat_sub64(current_dts, corrected_dts) / FFMAX(sample_count, 1);
3882  uint32_t correction = (sc->stts_data[i].duration > drift) ? drift : sc->stts_data[i].duration - 1;
3883  current_dts -= correction * (uint64_t)sample_count;
3884  sc->stts_data[i].duration -= correction;
3885  }
3886 
3887  duration+=(int64_t)sc->stts_data[i].duration*(uint64_t)sc->stts_data[i].count;
3888  total_sample_count+=sc->stts_data[i].count;
3889  }
3890 
3891  sc->stts_count = i;
3892 
3893  if (duration > 0 &&
3894  duration <= INT64_MAX - sc->duration_for_fps &&
3895  total_sample_count <= INT_MAX - sc->nb_frames_for_fps) {
3896  sc->duration_for_fps += duration;
3897  sc->nb_frames_for_fps += total_sample_count;
3898  }
3899 
3900  if (pb->eof_reached) {
3901  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STTS atom\n");
3902  return AVERROR_EOF;
3903  }
3904 
3905  st->nb_frames= total_sample_count;
3906  if (duration)
3907  st->duration= FFMIN(st->duration, duration);
3908 
3909  // All samples have zero duration. They have higher chance be chose by
3910  // mov_find_next_sample, which leads to seek again and again.
3911  //
3912  // It's AVERROR_INVALIDDATA actually, but such files exist in the wild.
3913  // So only mark data stream as discarded for safety.
3914  if (!duration && sc->stts_count &&
3916  av_log(c->fc, AV_LOG_WARNING,
3917  "All samples in data stream index:id [%d:%d] have zero "
3918  "duration, stream set to be discarded by default. Override "
3919  "using AVStream->discard or -discard for ffmpeg command.\n",
3920  st->index, sc->id);
3921  st->discard = AVDISCARD_ALL;
3922  }
3923  sc->track_end = duration;
3924  return 0;
3925 }
3926 
3928 {
3929  AVStream *st;
3930  MOVStreamContext *sc;
3931  unsigned int i;
3932  int64_t entries;
3933 
3934  if (c->fc->nb_streams < 1)
3935  return 0;
3936  st = c->fc->streams[c->fc->nb_streams - 1];
3937  sc = st->priv_data;
3938 
3939  avio_r8(pb); /* version */
3940  avio_rb24(pb); /* flags */
3941  entries = atom.size - 4;
3942 
3943  av_log(c->fc, AV_LOG_TRACE, "track[%u].sdtp.entries = %" PRId64 "\n",
3944  c->fc->nb_streams - 1, entries);
3945 
3946  if (sc->sdtp_data)
3947  av_log(c->fc, AV_LOG_WARNING, "Duplicated SDTP atom\n");
3948  av_freep(&sc->sdtp_data);
3949  sc->sdtp_count = 0;
3950 
3951  if (entries < 0 || entries > UINT_MAX)
3952  return AVERROR(ERANGE);
3953 
3954  sc->sdtp_data = av_malloc(entries);
3955  if (!sc->sdtp_data)
3956  return AVERROR(ENOMEM);
3957 
3958  for (i = 0; i < entries && !pb->eof_reached; i++)
3959  sc->sdtp_data[i] = avio_r8(pb);
3960  sc->sdtp_count = i;
3961 
3962  return 0;
3963 }
3964 
3965 static void mov_update_dts_shift(MOVStreamContext *sc, int duration, void *logctx)
3966 {
3967  if (duration < 0) {
3968  if (duration == INT_MIN) {
3969  av_log(logctx, AV_LOG_WARNING, "mov_update_dts_shift(): dts_shift set to %d\n", INT_MAX);
3970  duration++;
3971  }
3972  sc->dts_shift = FFMAX(sc->dts_shift, -duration);
3973  }
3974 }
3975 
3977 {
3978  AVStream *st;
3979  MOVStreamContext *sc;
3980  unsigned int i, entries, ctts_count = 0;
3981 
3982  if (c->trak_index < 0) {
3983  av_log(c->fc, AV_LOG_WARNING, "CTTS outside TRAK\n");
3984  return 0;
3985  }
3986 
3987  if (c->fc->nb_streams < 1)
3988  return 0;
3989  st = c->fc->streams[c->fc->nb_streams-1];
3990  sc = st->priv_data;
3991 
3992  avio_r8(pb); /* version */
3993  avio_rb24(pb); /* flags */
3994  entries = avio_rb32(pb);
3995 
3996  av_log(c->fc, AV_LOG_TRACE, "track[%u].ctts.entries = %u\n", c->fc->nb_streams - 1, entries);
3997 
3998  if (!entries)
3999  return 0;
4000  if (entries >= UINT_MAX / sizeof(*sc->ctts_data))
4001  return AVERROR_INVALIDDATA;
4002  av_freep(&sc->ctts_data);
4003  sc->ctts_data = av_fast_realloc(NULL, &sc->ctts_allocated_size, entries * sizeof(*sc->ctts_data));
4004  if (!sc->ctts_data)
4005  return AVERROR(ENOMEM);
4006 
4007  for (i = 0; i < entries && !pb->eof_reached; i++) {
4008  MOVCtts *ctts_data;
4009  const size_t min_size_needed = (ctts_count + 1) * sizeof(MOVCtts);
4010  const size_t requested_size =
4011  min_size_needed > sc->ctts_allocated_size ?
4012  FFMAX(min_size_needed, 2 * sc->ctts_allocated_size) :
4013  min_size_needed;
4014  int count = avio_rb32(pb);
4015  int duration = avio_rb32(pb);
4016 
4017  if (count <= 0) {
4018  av_log(c->fc, AV_LOG_TRACE,
4019  "ignoring CTTS entry with count=%d duration=%d\n",
4020  count, duration);
4021  continue;
4022  }
4023 
4024  if (ctts_count >= UINT_MAX / sizeof(MOVCtts) - 1)
4025  return AVERROR(ENOMEM);
4026 
4027  ctts_data = av_fast_realloc(sc->ctts_data, &sc->ctts_allocated_size, requested_size);
4028 
4029  if (!ctts_data)
4030  return AVERROR(ENOMEM);
4031 
4032  sc->ctts_data = ctts_data;
4033 
4034  ctts_data[ctts_count].count = count;
4035  ctts_data[ctts_count].offset = duration;
4036  ctts_count++;
4037 
4038  av_log(c->fc, AV_LOG_TRACE, "count=%d, duration=%d\n",
4039  count, duration);
4040 
4041  if (i+2<entries)
4042  mov_update_dts_shift(sc, duration, c->fc);
4043  }
4044 
4045  sc->ctts_count = ctts_count;
4046 
4047  if (pb->eof_reached) {
4048  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted CTTS atom\n");
4049  return AVERROR_EOF;
4050  }
4051 
4052  av_log(c->fc, AV_LOG_TRACE, "dts shift %d\n", sc->dts_shift);
4053 
4054  return 0;
4055 }
4056 
4058 {
4059  AVStream *st;
4060  MOVStreamContext *sc;
4061  uint8_t version;
4062  uint32_t grouping_type;
4063  uint32_t default_length;
4064  av_unused uint32_t default_group_description_index;
4065  uint32_t entry_count;
4066 
4067  if (c->fc->nb_streams < 1)
4068  return 0;
4069  st = c->fc->streams[c->fc->nb_streams - 1];
4070  sc = st->priv_data;
4071 
4072  version = avio_r8(pb); /* version */
4073  avio_rb24(pb); /* flags */
4074  grouping_type = avio_rl32(pb);
4075 
4076  /*
4077  * This function only supports "sync" boxes, but the code is able to parse
4078  * other boxes (such as "tscl", "tsas" and "stsa")
4079  */
4080  if (grouping_type != MKTAG('s','y','n','c'))
4081  return 0;
4082 
4083  default_length = version >= 1 ? avio_rb32(pb) : 0;
4084  default_group_description_index = version >= 2 ? avio_rb32(pb) : 0;
4085  entry_count = avio_rb32(pb);
4086 
4087  if (entry_count > atom.size)
4088  return AVERROR_INVALIDDATA;
4089 
4090  av_freep(&sc->sgpd_sync);
4091  sc->sgpd_sync_count = entry_count;
4092  sc->sgpd_sync = av_calloc(entry_count, sizeof(*sc->sgpd_sync));
4093  if (!sc->sgpd_sync)
4094  return AVERROR(ENOMEM);
4095 
4096  for (uint32_t i = 0; i < entry_count && !pb->eof_reached; i++) {
4097  uint32_t description_length = default_length;
4098  if (version >= 1 && default_length == 0)
4099  description_length = avio_rb32(pb);
4100  if (grouping_type == MKTAG('s','y','n','c')) {
4101  const uint8_t nal_unit_type = avio_r8(pb) & 0x3f;
4102  sc->sgpd_sync[i] = nal_unit_type;
4103  description_length -= 1;
4104  }
4105  avio_skip(pb, description_length);
4106  }
4107 
4108  if (pb->eof_reached) {
4109  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted SGPD atom\n");
4110  return AVERROR_EOF;
4111  }
4112 
4113  return 0;
4114 }
4115 
4117 {
4118  AVStream *st;
4119  MOVStreamContext *sc;
4120  unsigned int i, entries;
4121  uint8_t version;
4122  uint32_t grouping_type;
4123  MOVSbgp *table, **tablep;
4124  int *table_count;
4125 
4126  if (c->fc->nb_streams < 1)
4127  return 0;
4128  st = c->fc->streams[c->fc->nb_streams-1];
4129  sc = st->priv_data;
4130 
4131  version = avio_r8(pb); /* version */
4132  avio_rb24(pb); /* flags */
4133  grouping_type = avio_rl32(pb);
4134 
4135  if (grouping_type == MKTAG('r','a','p',' ')) {
4136  tablep = &sc->rap_group;
4137  table_count = &sc->rap_group_count;
4138  } else if (grouping_type == MKTAG('s','y','n','c')) {
4139  tablep = &sc->sync_group;
4140  table_count = &sc->sync_group_count;
4141  } else {
4142  return 0;
4143  }
4144 
4145  if (version == 1)
4146  avio_rb32(pb); /* grouping_type_parameter */
4147 
4148  entries = avio_rb32(pb);
4149  if (!entries)
4150  return 0;
4151  if (*tablep)
4152  av_log(c->fc, AV_LOG_WARNING, "Duplicated SBGP %s atom\n", av_fourcc2str(grouping_type));
4153  av_freep(tablep);
4154  table = av_malloc_array(entries, sizeof(*table));
4155  if (!table)
4156  return AVERROR(ENOMEM);
4157  *tablep = table;
4158 
4159  for (i = 0; i < entries && !pb->eof_reached; i++) {
4160  table[i].count = avio_rb32(pb); /* sample_count */
4161  table[i].index = avio_rb32(pb); /* group_description_index */
4162  }
4163 
4164  *table_count = i;
4165 
4166  if (pb->eof_reached) {
4167  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted SBGP atom\n");
4168  return AVERROR_EOF;
4169  }
4170 
4171  return 0;
4172 }
4173 
4174 /**
4175  * Get ith edit list entry (media time, duration).
4176  */
4178  const MOVStreamContext *msc,
4179  unsigned int edit_list_index,
4180  int64_t *edit_list_media_time,
4181  int64_t *edit_list_duration,
4182  int64_t global_timescale)
4183 {
4184  if (edit_list_index == msc->elst_count) {
4185  return 0;
4186  }
4187  *edit_list_media_time = msc->elst_data[edit_list_index].time;
4188  *edit_list_duration = msc->elst_data[edit_list_index].duration;
4189 
4190  /* duration is in global timescale units;convert to msc timescale */
4191  if (global_timescale == 0) {
4192  avpriv_request_sample(mov->fc, "Support for mvhd.timescale = 0 with editlists");
4193  return 0;
4194  }
4195  *edit_list_duration = av_rescale(*edit_list_duration, msc->time_scale,
4196  global_timescale);
4197 
4198  if (*edit_list_duration + (uint64_t)*edit_list_media_time > INT64_MAX)
4199  *edit_list_duration = 0;
4200 
4201  return 1;
4202 }
4203 
4204 /**
4205  * Find the closest previous frame to the timestamp_pts, in e_old index
4206  * entries. Searching for just any frame / just key frames can be controlled by
4207  * last argument 'flag'.
4208  * Note that if ctts_data is not NULL, we will always search for a key frame
4209  * irrespective of the value of 'flag'. If we don't find any keyframe, we will
4210  * return the first frame of the video.
4211  *
4212  * Here the timestamp_pts is considered to be a presentation timestamp and
4213  * the timestamp of index entries are considered to be decoding timestamps.
4214  *
4215  * Returns 0 if successful in finding a frame, else returns -1.
4216  * Places the found index corresponding output arg.
4217  *
4218  * If ctts_old is not NULL, then refines the searched entry by searching
4219  * backwards from the found timestamp, to find the frame with correct PTS.
4220  *
4221  * Places the found ctts_index and ctts_sample in corresponding output args.
4222  */
4224  AVIndexEntry *e_old,
4225  int nb_old,
4226  MOVTimeToSample *tts_data,
4227  int64_t tts_count,
4228  int64_t timestamp_pts,
4229  int flag,
4230  int64_t* index,
4231  int64_t* tts_index,
4232  int64_t* tts_sample)
4233 {
4234  MOVStreamContext *msc = st->priv_data;
4235  FFStream *const sti = ffstream(st);
4236  AVIndexEntry *e_keep = sti->index_entries;
4237  int nb_keep = sti->nb_index_entries;
4238  int64_t i = 0;
4239 
4240  av_assert0(index);
4241 
4242  // If dts_shift > 0, then all the index timestamps will have to be offset by
4243  // at least dts_shift amount to obtain PTS.
4244  // Hence we decrement the searched timestamp_pts by dts_shift to find the closest index element.
4245  if (msc->dts_shift > 0) {
4246  timestamp_pts -= msc->dts_shift;
4247  }
4248 
4249  sti->index_entries = e_old;
4250  sti->nb_index_entries = nb_old;
4251  *index = av_index_search_timestamp(st, timestamp_pts, flag | AVSEEK_FLAG_BACKWARD);
4252 
4253  // Keep going backwards in the index entries until the timestamp is the same.
4254  if (*index >= 0) {
4255  for (i = *index; i > 0 && e_old[i].timestamp == e_old[i - 1].timestamp;
4256  i--) {
4257  if ((flag & AVSEEK_FLAG_ANY) ||
4258  (e_old[i - 1].flags & AVINDEX_KEYFRAME)) {
4259  *index = i - 1;
4260  }
4261  }
4262  }
4263 
4264  // If we have CTTS then refine the search, by searching backwards over PTS
4265  // computed by adding corresponding CTTS durations to index timestamps.
4266  if (msc->ctts_count && *index >= 0) {
4267  av_assert0(tts_index);
4268  av_assert0(tts_sample);
4269  // Find out the ctts_index for the found frame.
4270  *tts_index = 0;
4271  *tts_sample = 0;
4272  for (int64_t index_tts_count = 0; index_tts_count < *index; index_tts_count++) {
4273  if (*tts_index < tts_count) {
4274  (*tts_sample)++;
4275  if (tts_data[*tts_index].count == *tts_sample) {
4276  (*tts_index)++;
4277  *tts_sample = 0;
4278  }
4279  }
4280  }
4281 
4282  while (*index >= 0 && (*tts_index) >= 0 && (*tts_index) < tts_count) {
4283  // Find a "key frame" with PTS <= timestamp_pts (So that we can decode B-frames correctly).
4284  // No need to add dts_shift to the timestamp here because timestamp_pts has already been
4285  // compensated by dts_shift above.
4286  if ((e_old[*index].timestamp + tts_data[*tts_index].offset) <= timestamp_pts &&
4287  (e_old[*index].flags & AVINDEX_KEYFRAME)) {
4288  break;
4289  }
4290 
4291  (*index)--;
4292  if (*tts_sample == 0) {
4293  (*tts_index)--;
4294  if (*tts_index >= 0)
4295  *tts_sample = tts_data[*tts_index].count - 1;
4296  } else {
4297  (*tts_sample)--;
4298  }
4299  }
4300  }
4301 
4302  /* restore AVStream state*/
4303  sti->index_entries = e_keep;
4304  sti->nb_index_entries = nb_keep;
4305  return *index >= 0 ? 0 : -1;
4306 }
4307 
4308 /**
4309  * Add index entry with the given values, to the end of ffstream(st)->index_entries.
4310  * Returns the new size ffstream(st)->index_entries if successful, else returns -1.
4311  *
4312  * This function is similar to ff_add_index_entry in libavformat/utils.c
4313  * except that here we are always unconditionally adding an index entry to
4314  * the end, instead of searching the entries list and skipping the add if
4315  * there is an existing entry with the same timestamp.
4316  * This is needed because the mov_fix_index calls this func with the same
4317  * unincremented timestamp for successive discarded frames.
4318  */
4320  int size, int distance, int flags)
4321 {
4322  FFStream *const sti = ffstream(st);
4323  AVIndexEntry *entries, *ie;
4324  int64_t index = -1;
4325  const size_t min_size_needed = (sti->nb_index_entries + 1) * sizeof(AVIndexEntry);
4326 
4327  // Double the allocation each time, to lower memory fragmentation.
4328  // Another difference from ff_add_index_entry function.
4329  const size_t requested_size =
4330  min_size_needed > sti->index_entries_allocated_size ?
4331  FFMAX(min_size_needed, 2 * sti->index_entries_allocated_size) :
4332  min_size_needed;
4333 
4334  if (sti->nb_index_entries + 1U >= UINT_MAX / sizeof(AVIndexEntry))
4335  return -1;
4336 
4337  entries = av_fast_realloc(sti->index_entries,
4339  requested_size);
4340  if (!entries)
4341  return -1;
4342 
4343  sti->index_entries = entries;
4344 
4345  index = sti->nb_index_entries++;
4346  ie= &entries[index];
4347 
4348  ie->pos = pos;
4349  ie->timestamp = timestamp;
4350  ie->min_distance= distance;
4351  ie->size= size;
4352  ie->flags = flags;
4353  return index;
4354 }
4355 
4356 /**
4357  * Rewrite timestamps of index entries in the range [end_index - frame_duration_buffer_size, end_index)
4358  * by subtracting end_ts successively by the amounts given in frame_duration_buffer.
4359  */
4360 static void fix_index_entry_timestamps(AVStream* st, int end_index, int64_t end_ts,
4361  int64_t* frame_duration_buffer,
4362  int frame_duration_buffer_size) {
4363  FFStream *const sti = ffstream(st);
4364  int i = 0;
4365  av_assert0(end_index >= 0 && end_index <= sti->nb_index_entries);
4366  for (i = 0; i < frame_duration_buffer_size; i++) {
4367  end_ts -= frame_duration_buffer[frame_duration_buffer_size - 1 - i];
4368  sti->index_entries[end_index - 1 - i].timestamp = end_ts;
4369  }
4370 }
4371 
4372 static int add_tts_entry(MOVTimeToSample **tts_data, unsigned int *tts_count, unsigned int *allocated_size,
4373  int count, int offset, unsigned int duration)
4374 {
4375  MOVTimeToSample *tts_buf_new;
4376  const size_t min_size_needed = (*tts_count + 1) * sizeof(MOVTimeToSample);
4377  const size_t requested_size =
4378  min_size_needed > *allocated_size ?
4379  FFMAX(min_size_needed, 2 * (*allocated_size)) :
4380  min_size_needed;
4381 
4382  if ((unsigned)(*tts_count) >= UINT_MAX / sizeof(MOVTimeToSample) - 1)
4383  return -1;
4384 
4385  tts_buf_new = av_fast_realloc(*tts_data, allocated_size, requested_size);
4386 
4387  if (!tts_buf_new)
4388  return -1;
4389 
4390  *tts_data = tts_buf_new;
4391 
4392  tts_buf_new[*tts_count].count = count;
4393  tts_buf_new[*tts_count].offset = offset;
4394  tts_buf_new[*tts_count].duration = duration;
4395 
4396  *tts_count = (*tts_count) + 1;
4397  return 0;
4398 }
4399 
4400 #define MAX_REORDER_DELAY 16
4402 {
4403  MOVStreamContext *msc = st->priv_data;
4404  FFStream *const sti = ffstream(st);
4405  int ctts_ind = 0;
4406  int ctts_sample = 0;
4407  int64_t pts_buf[MAX_REORDER_DELAY + 1]; // Circular buffer to sort pts.
4408  int buf_start = 0;
4409  int j, r, num_swaps;
4410 
4411  for (j = 0; j < MAX_REORDER_DELAY + 1; j++)
4412  pts_buf[j] = INT64_MIN;
4413 
4414  if (st->codecpar->video_delay <= 0 && msc->ctts_count &&
4416  st->codecpar->video_delay = 0;
4417  for (int ind = 0; ind < sti->nb_index_entries && ctts_ind < msc->tts_count; ++ind) {
4418  // Point j to the last elem of the buffer and insert the current pts there.
4419  j = buf_start;
4420  buf_start = (buf_start + 1);
4421  if (buf_start == MAX_REORDER_DELAY + 1)
4422  buf_start = 0;
4423 
4424  pts_buf[j] = sti->index_entries[ind].timestamp + msc->tts_data[ctts_ind].offset;
4425 
4426  // The timestamps that are already in the sorted buffer, and are greater than the
4427  // current pts, are exactly the timestamps that need to be buffered to output PTS
4428  // in correct sorted order.
4429  // Hence the video delay (which is the buffer size used to sort DTS and output PTS),
4430  // can be computed as the maximum no. of swaps any particular timestamp needs to
4431  // go through, to keep this buffer in sorted order.
4432  num_swaps = 0;
4433  while (j != buf_start) {
4434  r = j - 1;
4435  if (r < 0) r = MAX_REORDER_DELAY;
4436  if (pts_buf[j] < pts_buf[r]) {
4437  FFSWAP(int64_t, pts_buf[j], pts_buf[r]);
4438  ++num_swaps;
4439  } else {
4440  break;
4441  }
4442  j = r;
4443  }
4444  st->codecpar->video_delay = FFMAX(st->codecpar->video_delay, num_swaps);
4445 
4446  ctts_sample++;
4447  if (ctts_sample == msc->tts_data[ctts_ind].count) {
4448  ctts_ind++;
4449  ctts_sample = 0;
4450  }
4451  }
4452  av_log(c->fc, AV_LOG_DEBUG, "Setting codecpar->delay to %d for stream st: %d\n",
4453  st->codecpar->video_delay, st->index);
4454  }
4455 }
4456 
4458 {
4459  sc->current_sample++;
4460  sc->current_index++;
4461  if (sc->index_ranges &&
4462  sc->current_index >= sc->current_index_range->end &&
4463  sc->current_index_range->end) {
4464  sc->current_index_range++;
4466  }
4467 }
4468 
4470 {
4471  sc->current_sample--;
4472  sc->current_index--;
4473  if (sc->index_ranges &&
4475  sc->current_index_range > sc->index_ranges) {
4476  sc->current_index_range--;
4477  sc->current_index = sc->current_index_range->end - 1;
4478  }
4479 }
4480 
4481 static void mov_current_sample_set(MOVStreamContext *sc, int current_sample)
4482 {
4483  int64_t range_size;
4484 
4485  sc->current_sample = current_sample;
4486  sc->current_index = current_sample;
4487  if (!sc->index_ranges) {
4488  return;
4489  }
4490 
4491  for (sc->current_index_range = sc->index_ranges;
4492  sc->current_index_range->end;
4493  sc->current_index_range++) {
4494  range_size = sc->current_index_range->end - sc->current_index_range->start;
4495  if (range_size > current_sample) {
4496  sc->current_index = sc->current_index_range->start + current_sample;
4497  break;
4498  }
4499  current_sample -= range_size;
4500  }
4501 }
4502 
4503 /**
4504  * Fix ffstream(st)->index_entries, so that it contains only the entries (and the entries
4505  * which are needed to decode them) that fall in the edit list time ranges.
4506  * Also fixes the timestamps of the index entries to match the timeline
4507  * specified the edit lists.
4508  */
4509 static void mov_fix_index(MOVContext *mov, AVStream *st)
4510 {
4511  MOVStreamContext *msc = st->priv_data;
4512  FFStream *const sti = ffstream(st);
4513  AVIndexEntry *e_old = sti->index_entries;
4514  int nb_old = sti->nb_index_entries;
4515  const AVIndexEntry *e_old_end = e_old + nb_old;
4516  const AVIndexEntry *current = NULL;
4517  MOVTimeToSample *tts_data_old = msc->tts_data;
4518  int64_t tts_index_old = 0;
4519  int64_t tts_sample_old = 0;
4520  int64_t tts_count_old = msc->tts_count;
4521  int64_t edit_list_media_time = 0;
4522  int64_t edit_list_duration = 0;
4523  int64_t frame_duration = 0;
4524  int64_t edit_list_dts_counter = 0;
4525  int64_t edit_list_dts_entry_end = 0;
4526  int64_t edit_list_start_tts_sample = 0;
4527  int64_t curr_cts;
4528  int64_t curr_ctts = 0;
4529  int64_t empty_edits_sum_duration = 0;
4530  int64_t edit_list_index = 0;
4531  int64_t index;
4532  int flags;
4533  int64_t start_dts = 0;
4534  int64_t edit_list_start_encountered = 0;
4535  int64_t search_timestamp = 0;
4536  int64_t* frame_duration_buffer = NULL;
4537  int num_discarded_begin = 0;
4538  int first_non_zero_audio_edit = -1;
4539  int packet_skip_samples = 0;
4540  MOVIndexRange *current_index_range = NULL;
4541  int found_keyframe_after_edit = 0;
4542  int found_non_empty_edit = 0;
4543 
4544  if (!msc->elst_data || msc->elst_count <= 0 || nb_old <= 0) {
4545  return;
4546  }
4547 
4548  // allocate the index ranges array
4549  msc->index_ranges = av_malloc_array(msc->elst_count + 1,
4550  sizeof(msc->index_ranges[0]));
4551  if (!msc->index_ranges) {
4552  av_log(mov->fc, AV_LOG_ERROR, "Cannot allocate index ranges buffer\n");
4553  return;
4554  }
4555  msc->current_index_range = msc->index_ranges;
4556 
4557  // Clean AVStream from traces of old index
4558  sti->index_entries = NULL;
4560  sti->nb_index_entries = 0;
4561 
4562  // Clean time to sample fields of MOVStreamContext
4563  msc->tts_data = NULL;
4564  msc->tts_count = 0;
4565  msc->tts_index = 0;
4566  msc->tts_sample = 0;
4567  msc->tts_allocated_size = 0;
4568 
4569  // Reinitialize min_corrected_pts so that it can be computed again.
4570  msc->min_corrected_pts = -1;
4571 
4572  // If the dts_shift is positive (in case of negative ctts values in mov),
4573  // then negate the DTS by dts_shift
4574  if (msc->dts_shift > 0) {
4575  edit_list_dts_entry_end -= msc->dts_shift;
4576  av_log(mov->fc, AV_LOG_DEBUG, "Shifting DTS by %d because of negative CTTS.\n", msc->dts_shift);
4577  }
4578 
4579  start_dts = edit_list_dts_entry_end;
4580 
4581  while (get_edit_list_entry(mov, msc, edit_list_index, &edit_list_media_time,
4582  &edit_list_duration, mov->time_scale)) {
4583  av_log(mov->fc, AV_LOG_DEBUG, "Processing st: %d, edit list %"PRId64" - media time: %"PRId64", duration: %"PRId64"\n",
4584  st->index, edit_list_index, edit_list_media_time, edit_list_duration);
4585  edit_list_index++;
4586  edit_list_dts_counter = edit_list_dts_entry_end;
4587  edit_list_dts_entry_end = av_sat_add64(edit_list_dts_entry_end, edit_list_duration);
4588  if (edit_list_dts_entry_end == INT64_MAX) {
4589  av_log(mov->fc, AV_LOG_ERROR, "Cannot calculate dts entry length with duration %"PRId64"\n",
4590  edit_list_duration);
4591  break;
4592  }
4593  num_discarded_begin = 0;
4594  if (!found_non_empty_edit && edit_list_media_time == -1) {
4595  empty_edits_sum_duration += edit_list_duration;
4596  continue;
4597  }
4598  found_non_empty_edit = 1;
4599 
4600  // If we encounter a non-negative edit list reset the skip_samples/initial_padding fields and set them
4601  // according to the edit list below.
4602  if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
4603  if (first_non_zero_audio_edit < 0) {
4604  first_non_zero_audio_edit = 1;
4605  } else {
4606  first_non_zero_audio_edit = 0;
4607  }
4608 
4609  if (first_non_zero_audio_edit > 0)
4610  sti->skip_samples = st->codecpar->initial_padding = 0;
4611  }
4612 
4613  // While reordering frame index according to edit list we must handle properly
4614  // the scenario when edit list entry starts from none key frame.
4615  // We find closest previous key frame and preserve it and consequent frames in index.
4616  // All frames which are outside edit list entry time boundaries will be dropped after decoding.
4617  search_timestamp = edit_list_media_time;
4618  if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
4619  // Audio decoders like AAC need need a decoder delay samples previous to the current sample,
4620  // to correctly decode this frame. Hence for audio we seek to a frame 1 sec. before the
4621  // edit_list_media_time to cover the decoder delay.
4622  search_timestamp = FFMAX(search_timestamp - msc->time_scale, e_old[0].timestamp);
4623  }
4624 
4625  if (find_prev_closest_index(st, e_old, nb_old, tts_data_old, tts_count_old, search_timestamp, 0,
4626  &index, &tts_index_old, &tts_sample_old) < 0) {
4627  av_log(mov->fc, AV_LOG_WARNING,
4628  "st: %d edit list: %"PRId64" Missing key frame while searching for timestamp: %"PRId64"\n",
4629  st->index, edit_list_index, search_timestamp);
4630  if (find_prev_closest_index(st, e_old, nb_old, tts_data_old, tts_count_old, search_timestamp, AVSEEK_FLAG_ANY,
4631  &index, &tts_index_old, &tts_sample_old) < 0) {
4632  av_log(mov->fc, AV_LOG_WARNING,
4633  "st: %d edit list %"PRId64" Cannot find an index entry before timestamp: %"PRId64".\n",
4634  st->index, edit_list_index, search_timestamp);
4635  index = 0;
4636  tts_index_old = 0;
4637  tts_sample_old = 0;
4638  }
4639  }
4640  current = e_old + index;
4641  edit_list_start_tts_sample = tts_sample_old;
4642 
4643  // Iterate over index and arrange it according to edit list
4644  edit_list_start_encountered = 0;
4645  found_keyframe_after_edit = 0;
4646  for (; current < e_old_end; current++, index++) {
4647  // check if frame outside edit list mark it for discard
4648  frame_duration = (current + 1 < e_old_end) ?
4649  ((current + 1)->timestamp - current->timestamp) : edit_list_duration;
4650 
4651  flags = current->flags;
4652 
4653  // frames (pts) before or after edit list
4654  curr_cts = current->timestamp + msc->dts_shift;
4655  curr_ctts = 0;
4656 
4657  if (tts_data_old && tts_index_old < tts_count_old) {
4658  curr_ctts = tts_data_old[tts_index_old].offset;
4659  av_log(mov->fc, AV_LOG_TRACE, "stts: %"PRId64" ctts: %"PRId64", tts_index: %"PRId64", tts_count: %"PRId64"\n",
4660  curr_cts, curr_ctts, tts_index_old, tts_count_old);
4661  curr_cts += curr_ctts;
4662  tts_sample_old++;
4663  if (tts_sample_old == tts_data_old[tts_index_old].count) {
4664  if (add_tts_entry(&msc->tts_data, &msc->tts_count,
4665  &msc->tts_allocated_size,
4666  tts_data_old[tts_index_old].count - edit_list_start_tts_sample,
4667  tts_data_old[tts_index_old].offset, tts_data_old[tts_index_old].duration) == -1) {
4668  av_log(mov->fc, AV_LOG_ERROR, "Cannot add Time To Sample entry %"PRId64" - {%"PRId64", %d}\n",
4669  tts_index_old,
4670  tts_data_old[tts_index_old].count - edit_list_start_tts_sample,
4671  tts_data_old[tts_index_old].offset);
4672  break;
4673  }
4674  tts_index_old++;
4675  tts_sample_old = 0;
4676  edit_list_start_tts_sample = 0;
4677  }
4678  }
4679 
4680  if (curr_cts < edit_list_media_time || curr_cts >= (edit_list_duration + edit_list_media_time)) {
4682  curr_cts < edit_list_media_time && curr_cts + frame_duration > edit_list_media_time &&
4683  first_non_zero_audio_edit > 0) {
4684  packet_skip_samples = edit_list_media_time - curr_cts;
4685  sti->skip_samples += packet_skip_samples;
4686 
4687  // Shift the index entry timestamp by packet_skip_samples to be correct.
4688  edit_list_dts_counter -= packet_skip_samples;
4689  if (edit_list_start_encountered == 0) {
4690  edit_list_start_encountered = 1;
4691  // Make timestamps strictly monotonically increasing for audio, by rewriting timestamps for
4692  // discarded packets.
4693  if (frame_duration_buffer) {
4694  fix_index_entry_timestamps(st, sti->nb_index_entries, edit_list_dts_counter,
4695  frame_duration_buffer, num_discarded_begin);
4696  av_freep(&frame_duration_buffer);
4697  }
4698  }
4699 
4700  av_log(mov->fc, AV_LOG_DEBUG, "skip %d audio samples from curr_cts: %"PRId64"\n", packet_skip_samples, curr_cts);
4701  } else {
4703  av_log(mov->fc, AV_LOG_DEBUG, "drop a frame at curr_cts: %"PRId64" @ %"PRId64"\n", curr_cts, index);
4704 
4705  if (edit_list_start_encountered == 0) {
4706  num_discarded_begin++;
4707  frame_duration_buffer = av_realloc(frame_duration_buffer,
4708  num_discarded_begin * sizeof(int64_t));
4709  if (!frame_duration_buffer) {
4710  av_log(mov->fc, AV_LOG_ERROR, "Cannot reallocate frame duration buffer\n");
4711  break;
4712  }
4713  frame_duration_buffer[num_discarded_begin - 1] = frame_duration;
4714 
4715  // Increment skip_samples for the first non-zero audio edit list
4716  if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
4717  first_non_zero_audio_edit > 0 && st->codecpar->codec_id != AV_CODEC_ID_VORBIS) {
4718  sti->skip_samples += frame_duration;
4719  }
4720  }
4721  }
4722  } else {
4723  if (msc->min_corrected_pts < 0) {
4724  msc->min_corrected_pts = edit_list_dts_counter + curr_ctts + msc->dts_shift;
4725  } else {
4726  msc->min_corrected_pts = FFMIN(msc->min_corrected_pts, edit_list_dts_counter + curr_ctts + msc->dts_shift);
4727  }
4728  if (edit_list_start_encountered == 0) {
4729  edit_list_start_encountered = 1;
4730  // Make timestamps strictly monotonically increasing by rewriting timestamps for
4731  // discarded packets.
4732  if (frame_duration_buffer) {
4733  fix_index_entry_timestamps(st, sti->nb_index_entries, edit_list_dts_counter,
4734  frame_duration_buffer, num_discarded_begin);
4735  av_freep(&frame_duration_buffer);
4736  }
4737  }
4738  }
4739 
4740  if (add_index_entry(st, current->pos, edit_list_dts_counter, current->size,
4741  current->min_distance, flags) == -1) {
4742  av_log(mov->fc, AV_LOG_ERROR, "Cannot add index entry\n");
4743  break;
4744  }
4745 
4746  // Update the index ranges array
4747  if (!current_index_range || index != current_index_range->end) {
4748  current_index_range = current_index_range ? current_index_range + 1
4749  : msc->index_ranges;
4750  current_index_range->start = index;
4751  }
4752  current_index_range->end = index + 1;
4753 
4754  // Only start incrementing DTS in frame_duration amounts, when we encounter a frame in edit list.
4755  if (edit_list_start_encountered > 0) {
4756  edit_list_dts_counter = edit_list_dts_counter + frame_duration;
4757  }
4758 
4759  // Break when found first key frame after edit entry completion
4760  if ((curr_cts + frame_duration >= (edit_list_duration + edit_list_media_time)) &&
4762  if (msc->ctts_count) {
4763  // If we have CTTS and this is the first keyframe after edit elist,
4764  // wait for one more, because there might be trailing B-frames after this I-frame
4765  // that do belong to the edit.
4766  if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO && found_keyframe_after_edit == 0) {
4767  found_keyframe_after_edit = 1;
4768  continue;
4769  }
4770  if (tts_sample_old != 0) {
4771  if (add_tts_entry(&msc->tts_data, &msc->tts_count,
4772  &msc->tts_allocated_size,
4773  tts_sample_old - edit_list_start_tts_sample,
4774  tts_data_old[tts_index_old].offset, tts_data_old[tts_index_old].duration) == -1) {
4775  av_log(mov->fc, AV_LOG_ERROR, "Cannot add Time To Sample entry %"PRId64" - {%"PRId64", %d}\n",
4776  tts_index_old, tts_sample_old - edit_list_start_tts_sample,
4777  tts_data_old[tts_index_old].offset);
4778  break;
4779  }
4780  }
4781  }
4782  break;
4783  }
4784  }
4785  }
4786  // If there are empty edits, then msc->min_corrected_pts might be positive
4787  // intentionally. So we subtract the sum duration of empty edits here.
4788  msc->min_corrected_pts -= empty_edits_sum_duration;
4789 
4790  // If the minimum pts turns out to be greater than zero after fixing the index, then we subtract the
4791  // dts by that amount to make the first pts zero.
4792  if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
4793  if (msc->min_corrected_pts > 0) {
4794  av_log(mov->fc, AV_LOG_DEBUG, "Offset DTS by %"PRId64" to make first pts zero.\n", msc->min_corrected_pts);
4795  for (int i = 0; i < sti->nb_index_entries; ++i)
4797  }
4798  }
4799  // Start time should be equal to zero or the duration of any empty edits.
4800  st->start_time = empty_edits_sum_duration;
4801 
4802  // Update av stream length, if it ends up shorter than the track's media duration
4803  st->duration = FFMIN(st->duration, edit_list_dts_entry_end - start_dts);
4805 
4806  // Free the old index and the old CTTS structures
4807  av_free(e_old);
4808  av_free(tts_data_old);
4809  av_freep(&frame_duration_buffer);
4810 
4811  // Null terminate the index ranges array
4812  current_index_range = current_index_range ? current_index_range + 1
4813  : msc->index_ranges;
4814  current_index_range->start = 0;
4815  current_index_range->end = 0;
4816  msc->current_index = msc->index_ranges[0].start;
4817 }
4818 
4819 static uint32_t get_sgpd_sync_index(const MOVStreamContext *sc, int nal_unit_type)
4820 {
4821  for (uint32_t i = 0; i < sc->sgpd_sync_count; i++)
4822  if (sc->sgpd_sync[i] == nal_unit_type)
4823  return i + 1;
4824  return 0;
4825 }
4826 
4828 {
4829  int k;
4830  int sample_id = 0;
4831  uint32_t cra_index;
4832  MOVStreamContext *sc = st->priv_data;
4833 
4834  if (st->codecpar->codec_id != AV_CODEC_ID_HEVC || !sc->sync_group_count)
4835  return 0;
4836 
4837  /* Build an unrolled index of the samples */
4838  sc->sample_offsets_count = 0;
4839  for (uint32_t i = 0; i < sc->ctts_count; i++) {
4840  if (sc->ctts_data[i].count > INT_MAX - sc->sample_offsets_count)
4841  return AVERROR(ENOMEM);
4842  sc->sample_offsets_count += sc->ctts_data[i].count;
4843  }
4844  av_freep(&sc->sample_offsets);
4846  if (!sc->sample_offsets)
4847  return AVERROR(ENOMEM);
4848  k = 0;
4849  for (uint32_t i = 0; i < sc->ctts_count; i++)
4850  for (int j = 0; j < sc->ctts_data[i].count; j++)
4851  sc->sample_offsets[k++] = sc->ctts_data[i].offset;
4852 
4853  /* The following HEVC NAL type reveal the use of open GOP sync points
4854  * (TODO: BLA types may also be concerned) */
4855  cra_index = get_sgpd_sync_index(sc, HEVC_NAL_CRA_NUT); /* Clean Random Access */
4856  if (!cra_index)
4857  return 0;
4858 
4859  /* Build a list of open-GOP key samples */
4860  sc->open_key_samples_count = 0;
4861  for (uint32_t i = 0; i < sc->sync_group_count; i++)
4862  if (sc->sync_group[i].index == cra_index) {
4863  if (sc->sync_group[i].count > INT_MAX - sc->open_key_samples_count)
4864  return AVERROR(ENOMEM);
4866  }
4867  av_freep(&sc->open_key_samples);
4869  if (!sc->open_key_samples)
4870  return AVERROR(ENOMEM);
4871  k = 0;
4872  for (uint32_t i = 0; i < sc->sync_group_count; i++) {
4873  const MOVSbgp *sg = &sc->sync_group[i];
4874  if (sg->index == cra_index)
4875  for (uint32_t j = 0; j < sg->count; j++)
4876  sc->open_key_samples[k++] = sample_id;
4877  if (sg->count > INT_MAX - sample_id)
4878  return AVERROR_PATCHWELCOME;
4879  sample_id += sg->count;
4880  }
4881 
4882  /* Identify the minimal time step between samples */
4883  sc->min_sample_duration = UINT_MAX;
4884  for (uint32_t i = 0; i < sc->stts_count; i++)
4886 
4887  return 0;
4888 }
4889 
4890 #define MOV_MERGE_CTTS 1
4891 #define MOV_MERGE_STTS 2
4892 /*
4893  * Merge stts and ctts arrays into a new combined array.
4894  * stts_count and ctts_count may be left untouched as they will be
4895  * used to check for the presence of either of them.
4896  */
4897 static int mov_merge_tts_data(MOVContext *mov, AVStream *st, int flags)
4898 {
4899  MOVStreamContext *sc = st->priv_data;
4900  int ctts = sc->ctts_data && (flags & MOV_MERGE_CTTS);
4901  int stts = sc->stts_data && (flags & MOV_MERGE_STTS);
4902  int idx = 0;
4903 
4904  if (!sc->ctts_data && !sc->stts_data)
4905  return 0;
4906  // Expand time to sample entries such that we have a 1-1 mapping with samples
4907  if (!sc->sample_count || sc->sample_count >= UINT_MAX / sizeof(*sc->tts_data))
4908  return -1;
4909 
4910  if (ctts) {
4912  sc->sample_count * sizeof(*sc->tts_data));
4913  if (!sc->tts_data)
4914  return -1;
4915 
4916  memset(sc->tts_data, 0, sc->tts_allocated_size);
4917 
4918  for (int i = 0; i < sc->ctts_count &&
4919  idx < sc->sample_count; i++)
4920  for (int j = 0; j < sc->ctts_data[i].count &&
4921  idx < sc->sample_count; j++) {
4922  sc->tts_data[idx].offset = sc->ctts_data[i].offset;
4923  sc->tts_data[idx++].count = 1;
4924  }
4925 
4926  sc->tts_count = idx;
4927  } else
4928  sc->ctts_count = 0;
4929  av_freep(&sc->ctts_data);
4930  sc->ctts_allocated_size = 0;
4931 
4932  idx = 0;
4933  if (stts) {
4935  sc->sample_count * sizeof(*sc->tts_data));
4936  if (!tts_data)
4937  return -1;
4938 
4939  if (!sc->tts_data)
4940  memset(tts_data, 0, sc->tts_allocated_size);
4941  sc->tts_data = tts_data;
4942 
4943  for (int i = 0; i < sc->stts_count &&
4944  idx < sc->sample_count; i++)
4945  for (int j = 0; j < sc->stts_data[i].count &&
4946  idx < sc->sample_count; j++) {
4947  sc->tts_data[idx].duration = sc->stts_data[i].duration;
4948  sc->tts_data[idx++].count = 1;
4949  }
4950 
4951  sc->tts_count = FFMAX(sc->tts_count, idx);
4952  } else
4953  sc->stts_count = 0;
4954  av_freep(&sc->stts_data);
4955  sc->stts_allocated_size = 0;
4956 
4957  return 0;
4958 }
4959 
4960 static void mov_build_index(MOVContext *mov, AVStream *st)
4961 {
4962  MOVStreamContext *sc = st->priv_data;
4963  FFStream *const sti = ffstream(st);
4964  int64_t current_offset;
4965  int64_t current_dts = 0;
4966  unsigned int stts_index = 0;
4967  unsigned int stsc_index = 0;
4968  unsigned int stss_index = 0;
4969  unsigned int stps_index = 0;
4970  unsigned int i, j;
4971  uint64_t stream_size = 0;
4972 
4973  int ret = build_open_gop_key_points(st);
4974  if (ret < 0)
4975  return;
4976 
4977  if (sc->elst_count) {
4978  int i, edit_start_index = 0, multiple_edits = 0;
4979  int64_t empty_duration = 0; // empty duration of the first edit list entry
4980  int64_t start_time = 0; // start time of the media
4981 
4982  for (i = 0; i < sc->elst_count; i++) {
4983  const MOVElst *e = &sc->elst_data[i];
4984  if (i == 0 && e->time == -1) {
4985  /* if empty, the first entry is the start time of the stream
4986  * relative to the presentation itself */
4987  empty_duration = e->duration;
4988  edit_start_index = 1;
4989  } else if (i == edit_start_index && e->time >= 0) {
4990  start_time = e->time;
4991  } else {
4992  multiple_edits = 1;
4993  }
4994  }
4995 
4996  if (multiple_edits && !mov->advanced_editlist) {
4998  av_log(mov->fc, AV_LOG_WARNING, "multiple edit list entries, "
4999  "not supported in fragmented MP4 files\n");
5000  else
5001  av_log(mov->fc, AV_LOG_WARNING, "multiple edit list entries, "
5002  "Use -advanced_editlist to correctly decode otherwise "
5003  "a/v desync might occur\n");
5004  }
5005 
5006  /* adjust first dts according to edit list */
5007  if ((empty_duration || start_time) && mov->time_scale > 0) {
5008  if (empty_duration)
5009  empty_duration = av_rescale(empty_duration, sc->time_scale, mov->time_scale);
5010 
5011  if (av_sat_sub64(start_time, empty_duration) != start_time - (uint64_t)empty_duration)
5012  av_log(mov->fc, AV_LOG_WARNING, "start_time - empty_duration is not representable\n");
5013 
5014  sc->time_offset = start_time - (uint64_t)empty_duration;
5016  if (!mov->advanced_editlist)
5017  current_dts = -av_clip64(sc->time_offset, -INT64_MAX, INT64_MAX);
5018  }
5019 
5020  if (!multiple_edits && !mov->advanced_editlist &&
5023  (AVRational){1, st->codecpar->sample_rate});
5024  }
5025 
5026  /* only use old uncompressed audio chunk demuxing when stts specifies it */
5027  if (!(st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
5028  sc->stts_count == 1 && sc->stts_data && sc->stts_data[0].duration == 1)) {
5029  unsigned int current_sample = 0;
5030  unsigned int stts_sample = 0;
5031  unsigned int sample_size;
5032  unsigned int distance = 0;
5033  unsigned int rap_group_index = 0;
5034  unsigned int rap_group_sample = 0;
5035  int rap_group_present = sc->rap_group_count && sc->rap_group;
5036  int key_off = (sc->keyframe_count && sc->keyframes[0] > 0) || (sc->stps_count && sc->stps_data[0] > 0);
5037 
5038  av_assert0(sc->dts_shift >= 0);
5039  if (current_dts < INT64_MIN + sc->dts_shift)
5040  return;
5041  current_dts -= sc->dts_shift;
5042  if (!sc->sample_count || sti->nb_index_entries || sc->tts_count)
5043  return;
5044  if (sc->sample_count >= UINT_MAX / sizeof(*sti->index_entries) - sti->nb_index_entries)
5045  return;
5046  if (av_reallocp_array(&sti->index_entries,
5047  sti->nb_index_entries + sc->sample_count,
5048  sizeof(*sti->index_entries)) < 0) {
5049  sti->nb_index_entries = 0;
5050  return;
5051  }
5052  sti->index_entries_allocated_size = (sti->nb_index_entries + sc->sample_count) * sizeof(*sti->index_entries);
5053 
5055  if (ret < 0)
5056  return;
5057 
5058  for (i = 0; i < sc->chunk_count; i++) {
5059  int64_t next_offset = i+1 < sc->chunk_count ? sc->chunk_offsets[i+1] : INT64_MAX;
5060  current_offset = sc->chunk_offsets[i];
5061  while (mov_stsc_index_valid(stsc_index, sc->stsc_count) &&
5062  i + 1 == sc->stsc_data[stsc_index + 1].first)
5063  stsc_index++;
5064 
5065  if (next_offset > current_offset && sc->sample_size>0 && sc->sample_size < sc->stsz_sample_size &&
5066  sc->stsc_data[stsc_index].count * (int64_t)sc->stsz_sample_size > next_offset - current_offset) {
5067  av_log(mov->fc, AV_LOG_WARNING, "STSZ sample size %d invalid (too large), ignoring\n", sc->stsz_sample_size);
5068  sc->stsz_sample_size = sc->sample_size;
5069  }
5070  if (sc->stsz_sample_size>0 && sc->stsz_sample_size < sc->sample_size) {
5071  av_log(mov->fc, AV_LOG_WARNING, "STSZ sample size %d invalid (too small), ignoring\n", sc->stsz_sample_size);
5072  sc->stsz_sample_size = sc->sample_size;
5073  }
5074 
5075  for (j = 0; j < sc->stsc_data[stsc_index].count; j++) {
5076  int keyframe = 0;
5077  if (current_sample >= sc->sample_count) {
5078  av_log(mov->fc, AV_LOG_ERROR, "wrong sample count\n");
5079  return;
5080  }
5081 
5082  if (!sc->keyframe_absent && (!sc->keyframe_count || current_sample+key_off == sc->keyframes[stss_index])) {
5083  keyframe = 1;
5084  if (stss_index + 1 < sc->keyframe_count)
5085  stss_index++;
5086  } else if (sc->stps_count && current_sample+key_off == sc->stps_data[stps_index]) {
5087  keyframe = 1;
5088  if (stps_index + 1 < sc->stps_count)
5089  stps_index++;
5090  }
5091  if (rap_group_present && rap_group_index < sc->rap_group_count) {
5092  if (sc->rap_group[rap_group_index].index > 0)
5093  keyframe = 1;
5094  if (++rap_group_sample == sc->rap_group[rap_group_index].count) {
5095  rap_group_sample = 0;
5096  rap_group_index++;
5097  }
5098  }
5099  if (sc->keyframe_absent
5100  && !sc->stps_count
5101  && !rap_group_present
5102  && (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO || (i==0 && j==0)))
5103  keyframe = 1;
5104  if (keyframe)
5105  distance = 0;
5106  sample_size = sc->stsz_sample_size > 0 ? sc->stsz_sample_size : sc->sample_sizes[current_sample];
5107  if (current_offset > INT64_MAX - sample_size) {
5108  av_log(mov->fc, AV_LOG_ERROR, "Current offset %"PRId64" or sample size %u is too large\n",
5109  current_offset,
5110  sample_size);
5111  return;
5112  }
5113 
5114  if (sc->pseudo_stream_id == -1 ||
5115  sc->stsc_data[stsc_index].id - 1 == sc->pseudo_stream_id) {
5116  AVIndexEntry *e;
5117  if (sample_size > 0x3FFFFFFF) {
5118  av_log(mov->fc, AV_LOG_ERROR, "Sample size %u is too large\n", sample_size);
5119  return;
5120  }
5121  e = &sti->index_entries[sti->nb_index_entries++];
5122  e->pos = current_offset;
5123  e->timestamp = current_dts;
5124  e->size = sample_size;
5125  e->min_distance = distance;
5126  e->flags = keyframe ? AVINDEX_KEYFRAME : 0;
5127  av_log(mov->fc, AV_LOG_TRACE, "AVIndex stream %d, sample %u, offset %"PRIx64", dts %"PRId64", "
5128  "size %u, distance %u, keyframe %d\n", st->index, current_sample,
5129  current_offset, current_dts, sample_size, distance, keyframe);
5130  if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && sti->nb_index_entries < 100)
5131  ff_rfps_add_frame(mov->fc, st, current_dts);
5132  }
5133 
5134  current_offset += sample_size;
5135  stream_size += sample_size;
5136 
5137  if (current_dts > INT64_MAX - sc->tts_data[stts_index].duration)
5138  return;
5139  current_dts += sc->tts_data[stts_index].duration;
5140 
5141  distance++;
5142  stts_sample++;
5143  current_sample++;
5144  if (stts_index + 1 < sc->tts_count && stts_sample == sc->tts_data[stts_index].count) {
5145  stts_sample = 0;
5146  stts_index++;
5147  }
5148  }
5149  }
5150  if (st->duration > 0)
5151  st->codecpar->bit_rate = stream_size*8*sc->time_scale/st->duration;
5152  } else {
5153  unsigned chunk_samples, total = 0;
5154 
5155  if (!sc->chunk_count || sc->tts_count)
5156  return;
5157 
5158  // compute total chunk count
5159  for (i = 0; i < sc->stsc_count; i++) {
5160  unsigned count, chunk_count;
5161 
5162  chunk_samples = sc->stsc_data[i].count;
5163  if (i != sc->stsc_count - 1 &&
5164  sc->samples_per_frame && chunk_samples % sc->samples_per_frame) {
5165  av_log(mov->fc, AV_LOG_ERROR, "error unaligned chunk\n");
5166  return;
5167  }
5168 
5169  if (sc->samples_per_frame >= 160) { // gsm
5170  count = chunk_samples / sc->samples_per_frame;
5171  } else if (sc->samples_per_frame > 1) {
5172  unsigned samples = (1024/sc->samples_per_frame)*sc->samples_per_frame;
5173  count = (chunk_samples+samples-1) / samples;
5174  } else {
5175  count = (chunk_samples+1023) / 1024;
5176  }
5177 
5178  if (mov_stsc_index_valid(i, sc->stsc_count))
5179  chunk_count = sc->stsc_data[i+1].first - sc->stsc_data[i].first;
5180  else
5181  chunk_count = sc->chunk_count - (sc->stsc_data[i].first - 1);
5182  total += chunk_count * count;
5183  }
5184 
5185  av_log(mov->fc, AV_LOG_TRACE, "chunk count %u\n", total);
5186  if (total >= UINT_MAX / sizeof(*sti->index_entries) - sti->nb_index_entries)
5187  return;
5188  if (av_reallocp_array(&sti->index_entries,
5189  sti->nb_index_entries + total,
5190  sizeof(*sti->index_entries)) < 0) {
5191  sti->nb_index_entries = 0;
5192  return;
5193  }
5194  sti->index_entries_allocated_size = (sti->nb_index_entries + total) * sizeof(*sti->index_entries);
5195 
5196  // populate index
5197  for (i = 0; i < sc->chunk_count; i++) {
5198  current_offset = sc->chunk_offsets[i];
5199  if (mov_stsc_index_valid(stsc_index, sc->stsc_count) &&
5200  i + 1 == sc->stsc_data[stsc_index + 1].first)
5201  stsc_index++;
5202  chunk_samples = sc->stsc_data[stsc_index].count;
5203 
5204  while (chunk_samples > 0) {
5205  AVIndexEntry *e;
5206  unsigned size, samples;
5207 
5208  if (sc->samples_per_frame > 1 && !sc->bytes_per_frame) {
5210  "Zero bytes per frame, but %d samples per frame",
5211  sc->samples_per_frame);
5212  return;
5213  }
5214 
5215  if (sc->samples_per_frame >= 160) { // gsm
5216  samples = sc->samples_per_frame;
5217  size = sc->bytes_per_frame;
5218  } else {
5219  if (sc->samples_per_frame > 1) {
5220  samples = FFMIN((1024 / sc->samples_per_frame)*
5221  sc->samples_per_frame, chunk_samples);
5223  } else {
5224  samples = FFMIN(1024, chunk_samples);
5225  size = samples * sc->sample_size;
5226  }
5227  }
5228 
5229  if (sti->nb_index_entries >= total) {
5230  av_log(mov->fc, AV_LOG_ERROR, "wrong chunk count %u\n", total);
5231  return;
5232  }
5233  if (size > 0x3FFFFFFF) {
5234  av_log(mov->fc, AV_LOG_ERROR, "Sample size %u is too large\n", size);
5235  return;
5236  }
5237  e = &sti->index_entries[sti->nb_index_entries++];
5238  e->pos = current_offset;
5239  e->timestamp = current_dts;
5240  e->size = size;
5241  e->min_distance = 0;
5242  e->flags = AVINDEX_KEYFRAME;
5243  av_log(mov->fc, AV_LOG_TRACE, "AVIndex stream %d, chunk %u, offset %"PRIx64", dts %"PRId64", "
5244  "size %u, duration %u\n", st->index, i, current_offset, current_dts,
5245  size, samples);
5246 
5247  current_offset += size;
5248  if (current_dts > INT64_MAX - samples)
5249  return;
5250  current_dts += samples;
5251  chunk_samples -= samples;
5252  }
5253  }
5254 
5256  if (ret < 0)
5257  return;
5258  }
5259 
5260  if (!mov->ignore_editlist && mov->advanced_editlist) {
5261  // Fix index according to edit lists.
5262  mov_fix_index(mov, st);
5263  }
5264 
5265  // Update start time of the stream.
5268  if (sc->tts_data) {
5269  st->start_time = av_sat_add64(st->start_time, sc->tts_data[0].offset);
5270  }
5271  }
5272 
5273  mov_estimate_video_delay(mov, st);
5274 }
5275 
5276 typedef struct MOVPresentationSample {
5277  int index;
5280 
5281 static int mov_compare_presentation_samples(const void *a, const void *b)
5282 {
5283  const MOVPresentationSample *sa = a;
5284  const MOVPresentationSample *sb = b;
5285 
5286  if (sa->pts != sb->pts)
5287  return (sa->pts > sb->pts) - (sa->pts < sb->pts);
5288  return (sa->index > sb->index) - (sa->index < sb->index);
5289 }
5290 
5291 /*
5292  * Set sample durations from adjacent presentation timestamps.
5293  */
5295 {
5296  MOVStreamContext *sc = st->priv_data;
5297  FFStream *const sti = ffstream(st);
5299  MOVTimeToSample *tts_data = NULL;
5300  unsigned int tts_index = 0, tts_sample = 0;
5301  int count = sti->nb_index_entries;
5302 
5303  /* A single STTS entry describes a fixed sample delta. */
5304  if (st->codecpar->codec_type != AVMEDIA_TYPE_VIDEO ||
5305  !sc->ctts_count || sc->stts_count < 2 ||
5306  !sc->tts_data || count < 2 ||
5307  count >= UINT_MAX / sizeof(*tts_data))
5308  return;
5309 
5310  samples = av_malloc_array(count, sizeof(*samples));
5311  tts_data = av_malloc_array(count, sizeof(*tts_data));
5312  if (!samples || !tts_data)
5313  goto fail;
5314 
5315  for (int i = 0; i < count; i++) {
5316  int64_t dts, offset;
5317 
5318  if (tts_index >= sc->tts_count || !sc->tts_data[tts_index].count)
5319  goto fail;
5320 
5321  tts_data[i] = sc->tts_data[tts_index];
5322  tts_data[i].count = 1;
5323 
5324  dts = sti->index_entries[i].timestamp;
5325  offset = (int64_t)sc->dts_shift + tts_data[i].offset;
5326  if (dts == AV_NOPTS_VALUE ||
5327  (offset > 0 && dts > INT64_MAX - offset) ||
5328  (offset < 0 && dts < INT64_MIN - offset))
5329  goto fail;
5330 
5331  samples[i].index = i;
5332  samples[i].pts = dts + offset;
5333 
5334  if (++tts_sample == sc->tts_data[tts_index].count) {
5335  tts_index++;
5336  tts_sample = 0;
5337  }
5338  }
5339  if (tts_index != sc->tts_count || tts_sample)
5340  goto fail;
5341 
5342  qsort(samples, count, sizeof(*samples), mov_compare_presentation_samples);
5343 
5344  for (int i = 0; i + 1 < count; i++) {
5345  uint64_t duration;
5346 
5347  if (samples[i].pts >= samples[i + 1].pts)
5348  goto fail;
5349 
5350  /*
5351  * In VFR streams with reordered frames, STTS deltas follow decode
5352  * order while AVPacket.duration follows presentation order. CTTS
5353  * may produce presentation intervals that cannot be obtained by
5354  * merely permuting the STTS deltas, so derive each known duration
5355  * from adjacent PTS.
5356  */
5357  duration = (uint64_t)samples[i + 1].pts - samples[i].pts;
5358  if (!duration || duration > UINT_MAX)
5359  goto fail;
5360 
5361  tts_data[samples[i].index].duration = (unsigned int)duration;
5362  }
5363 
5364  av_log(mov->fc, AV_LOG_DEBUG,
5365  "Updated sample durations in presentation order for stream %d\n",
5366  st->index);
5367 
5368  av_freep(&sc->tts_data);
5369  sc->tts_data = tts_data;
5370  sc->tts_count = count;
5371  sc->tts_allocated_size = count * sizeof(*tts_data);
5372  tts_data = NULL;
5373 
5374 fail:
5375  av_free(samples);
5376  av_free(tts_data);
5377 }
5378 
5379 static int test_same_origin(const char *src, const char *ref) {
5380  char src_proto[64];
5381  char ref_proto[64];
5382  char src_auth[256];
5383  char ref_auth[256];
5384  char src_host[256];
5385  char ref_host[256];
5386  int src_port=-1;
5387  int ref_port=-1;
5388 
5389  av_url_split(src_proto, sizeof(src_proto), src_auth, sizeof(src_auth), src_host, sizeof(src_host), &src_port, NULL, 0, src);
5390  av_url_split(ref_proto, sizeof(ref_proto), ref_auth, sizeof(ref_auth), ref_host, sizeof(ref_host), &ref_port, NULL, 0, ref);
5391 
5392  if (strlen(src) == 0) {
5393  return -1;
5394  } else if (strlen(src_auth) + 1 >= sizeof(src_auth) ||
5395  strlen(ref_auth) + 1 >= sizeof(ref_auth) ||
5396  strlen(src_host) + 1 >= sizeof(src_host) ||
5397  strlen(ref_host) + 1 >= sizeof(ref_host)) {
5398  return 0;
5399  } else if (strcmp(src_proto, ref_proto) ||
5400  strcmp(src_auth, ref_auth) ||
5401  strcmp(src_host, ref_host) ||
5402  src_port != ref_port) {
5403  return 0;
5404  } else
5405  return 1;
5406 }
5407 
5408 static int mov_open_dref(MOVContext *c, AVIOContext **pb, const char *src, MOVDref *ref)
5409 {
5410  /* try relative path, we do not try the absolute because it can leak information about our
5411  system to an attacker */
5412  if (ref->nlvl_to > 0 && ref->nlvl_from > 0) {
5413  char filename[1025];
5414  const char *src_path;
5415  int i, l;
5416 
5417  /* find a source dir */
5418  src_path = strrchr(src, '/');
5419  if (src_path)
5420  src_path++;
5421  else
5422  src_path = src;
5423 
5424  /* find a next level down to target */
5425  for (i = 0, l = strlen(ref->path) - 1; l >= 0; l--)
5426  if (ref->path[l] == '/') {
5427  if (i == ref->nlvl_to - 1)
5428  break;
5429  else
5430  i++;
5431  }
5432 
5433  /* compose filename if next level down to target was found */
5434  if (i == ref->nlvl_to - 1 && src_path - src < sizeof(filename)) {
5435  memcpy(filename, src, src_path - src);
5436  filename[src_path - src] = 0;
5437 
5438  for (i = 1; i < ref->nlvl_from; i++)
5439  av_strlcat(filename, "../", sizeof(filename));
5440 
5441  av_strlcat(filename, ref->path + l + 1, sizeof(filename));
5442  if (!c->use_absolute_path) {
5443  int same_origin = test_same_origin(src, filename);
5444 
5445  if (!same_origin) {
5446  av_log(c->fc, AV_LOG_ERROR,
5447  "Reference with mismatching origin, %s not tried for security reasons, "
5448  "set demuxer option use_absolute_path to allow it anyway\n",
5449  ref->path);
5450  return AVERROR(ENOENT);
5451  }
5452 
5453  if (strstr(ref->path + l + 1, "..") ||
5454  strstr(ref->path + l + 1, ":") ||
5455  (ref->nlvl_from > 1 && same_origin < 0) ||
5456  (filename[0] == '/' && src_path == src))
5457  return AVERROR(ENOENT);
5458  }
5459 
5460  if (strlen(filename) + 1 == sizeof(filename))
5461  return AVERROR(ENOENT);
5462  if (!c->fc->io_open(c->fc, pb, filename, AVIO_FLAG_READ, NULL))
5463  return 0;
5464  }
5465  } else if (c->use_absolute_path) {
5466  av_log(c->fc, AV_LOG_WARNING, "Using absolute path on user request, "
5467  "this is a possible security issue\n");
5468  if (!c->fc->io_open(c->fc, pb, ref->path, AVIO_FLAG_READ, NULL))
5469  return 0;
5470  } else {
5471  av_log(c->fc, AV_LOG_ERROR,
5472  "Absolute path %s not tried for security reasons, "
5473  "set demuxer option use_absolute_path to allow absolute paths\n",
5474  ref->path);
5475  }
5476 
5477  return AVERROR(ENOENT);
5478 }
5479 
5481 {
5482  if (sc->time_scale <= 0) {
5483  av_log(c->fc, AV_LOG_WARNING, "stream %d, timescale not set\n", sc->ffindex);
5484  sc->time_scale = c->time_scale;
5485  if (sc->time_scale <= 0)
5486  sc->time_scale = 1;
5487  }
5488 }
5489 
5490 #if CONFIG_IAMFDEC
5491 static int mov_update_iamf_streams(MOVContext *c, const AVStream *st)
5492 {
5493  const MOVStreamContext *sc = st->priv_data;
5494  const IAMFContext *iamf = &sc->iamf->iamf;
5495 
5496  for (int i = 0; i < iamf->nb_audio_elements; i++) {
5497  const AVStreamGroup *stg = NULL;
5498 
5499  for (int j = 0; j < c->fc->nb_stream_groups; j++)
5500  if (c->fc->stream_groups[j]->id == iamf->audio_elements[i]->audio_element_id)
5501  stg = c->fc->stream_groups[j];
5502  av_assert0(stg);
5503 
5504  for (int j = 0; j < stg->nb_streams; j++) {
5505  const FFStream *sti = cffstream(st);
5506  AVStream *out = stg->streams[j];
5507  FFStream *out_sti = ffstream(stg->streams[j]);
5508 
5509  out->codecpar->bit_rate = 0;
5510 
5511  if (out == st)
5512  continue;
5513 
5514  out->time_base = st->time_base;
5515  out->start_time = st->start_time;
5516  out->duration = st->duration;
5517  out->nb_frames = st->nb_frames;
5518  out->discard = st->discard;
5519 
5520  av_assert0(!out_sti->index_entries);
5522  if (!out_sti->index_entries)
5523  return AVERROR(ENOMEM);
5524 
5526  out_sti->nb_index_entries = sti->nb_index_entries;
5527  out_sti->skip_samples = sti->skip_samples;
5528  memcpy(out_sti->index_entries, sti->index_entries, sti->index_entries_allocated_size);
5529  }
5530  }
5531 
5532  return 0;
5533 }
5534 #endif
5535 
5536 static int sanity_checks(void *log_obj, MOVStreamContext *sc, int index)
5537 {
5538  if ((sc->chunk_count && (!sc->stts_count || !sc->stsc_count ||
5539  (!sc->sample_size && !sc->sample_count))) ||
5540  (sc->sample_count && (!sc->chunk_count ||
5541  (!sc->sample_size && !sc->sample_sizes)))) {
5542  av_log(log_obj, AV_LOG_ERROR, "stream %d, missing mandatory atoms, broken header\n",
5543  index);
5544  return 1;
5545  }
5546 
5547  if (sc->stsc_count && sc->stsc_data[ sc->stsc_count - 1 ].first > sc->chunk_count) {
5548  av_log(log_obj, AV_LOG_ERROR, "stream %d, contradictionary STSC and STCO\n",
5549  index);
5550  return 2;
5551  }
5552  return 0;
5553 }
5554 
5556 {
5557  AVStream *st;
5558  MOVStreamContext *sc;
5559  int ret;
5560 
5561  st = avformat_new_stream(c->fc, NULL);
5562  if (!st) return AVERROR(ENOMEM);
5563  st->id = -1;
5564  sc = av_mallocz(sizeof(MOVStreamContext));
5565  if (!sc) return AVERROR(ENOMEM);
5566 
5567  st->priv_data = sc;
5569  sc->ffindex = st->index;
5570  c->trak_index = st->index;
5571  sc->refcount = 1;
5572 
5573  if ((ret = mov_read_default(c, pb, atom)) < 0)
5574  return ret;
5575 
5576  c->trak_index = -1;
5577 
5578  // Here stsc refers to a chunk not described in stco. This is technically invalid,
5579  // but we can overlook it (clearing stsc) whenever stts_count == 0 (indicating no samples).
5580  if (!sc->chunk_count && !sc->stts_count && sc->stsc_count) {
5581  sc->stsc_count = 0;
5582  av_freep(&sc->stsc_data);
5583  }
5584 
5585  ret = sanity_checks(c->fc, sc, st->index);
5586  if (ret)
5587  return ret > 1 ? AVERROR_INVALIDDATA : 0;
5588 
5589  fix_timescale(c, sc);
5590 
5591  avpriv_set_pts_info(st, 64, 1, sc->time_scale);
5592 
5593  /*
5594  * Advanced edit list support does not work with fragemented MP4s, which
5595  * have stsc, stsz, stco, and stts with zero entries in the moov atom.
5596  * In these files, trun atoms may be streamed in.
5597  */
5598  if (!sc->stts_count && c->advanced_editlist) {
5599 
5600  av_log(c->fc, AV_LOG_VERBOSE, "advanced_editlist does not work with fragmented "
5601  "MP4. disabling.\n");
5602  c->advanced_editlist = 0;
5603  c->advanced_editlist_autodisabled = 1;
5604  }
5605 
5606  mov_build_index(c, st);
5607  /*
5608  * Fragment samples are appended later by mov_read_trun() and are not
5609  * covered by this non-fragmented track update.
5610  */
5612 
5613 #if CONFIG_IAMFDEC
5614  if (sc->iamf) {
5615  ret = mov_update_iamf_streams(c, st);
5616  if (ret < 0)
5617  return ret;
5618  }
5619 #endif
5620 
5621  if (sc->dref_id-1 < sc->drefs_count && sc->drefs[sc->dref_id-1].path) {
5622  MOVDref *dref = &sc->drefs[sc->dref_id - 1];
5623  if (c->enable_drefs) {
5624  if (mov_open_dref(c, &sc->pb, c->fc->url, dref) < 0)
5625  av_log(c->fc, AV_LOG_ERROR,
5626  "stream %d, error opening alias: path='%s', dir='%s', "
5627  "filename='%s', volume='%s', nlvl_from=%d, nlvl_to=%d\n",
5628  st->index, dref->path, dref->dir, dref->filename,
5629  dref->volume, dref->nlvl_from, dref->nlvl_to);
5630  } else {
5631  av_log(c->fc, AV_LOG_WARNING,
5632  "Skipped opening external track: "
5633  "stream %d, alias: path='%s', dir='%s', "
5634  "filename='%s', volume='%s', nlvl_from=%d, nlvl_to=%d."
5635  "Set enable_drefs to allow this.\n",
5636  st->index, dref->path, dref->dir, dref->filename,
5637  dref->volume, dref->nlvl_from, dref->nlvl_to);
5638  }
5639  } else {
5640  sc->pb = c->fc->pb;
5641  sc->pb_is_copied = 1;
5642  }
5643 
5644  if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
5645  int stts_constant = sc->stts_count && sc->tts_count;
5646  if (sc->h_spacing && sc->v_spacing)
5648  sc->h_spacing, sc->v_spacing, INT_MAX);
5649  if (!st->sample_aspect_ratio.num && st->codecpar->width && st->codecpar->height &&
5650  sc->height && sc->width &&
5651  (st->codecpar->width != sc->width || st->codecpar->height != sc->height)) {
5653  (int64_t)st->codecpar->height * sc->width,
5654  (int64_t)st->codecpar->width * sc->height, INT_MAX);
5655  }
5656 
5657 #if FF_API_R_FRAME_RATE
5658  for (unsigned int i = 1; sc->stts_count && i + 1 < sc->tts_count; i++) {
5659  if (sc->tts_data[i].duration == sc->tts_data[0].duration)
5660  continue;
5661  stts_constant = 0;
5662  }
5663  if (stts_constant)
5665  sc->time_scale, sc->tts_data[0].duration, INT_MAX);
5666 #endif
5667  }
5668 
5669 #if CONFIG_H261_DECODER || CONFIG_H263_DECODER || CONFIG_MPEG4_DECODER
5670  switch (st->codecpar->codec_id) {
5671 #if CONFIG_H261_DECODER
5672  case AV_CODEC_ID_H261:
5673 #endif
5674 #if CONFIG_H263_DECODER
5675  case AV_CODEC_ID_H263:
5676 #endif
5677 #if CONFIG_MPEG4_DECODER
5678  case AV_CODEC_ID_MPEG4:
5679 #endif
5680  st->codecpar->width = 0; /* let decoder init width/height */
5681  st->codecpar->height= 0;
5682  break;
5683  }
5684 #endif
5685 
5686  // If the duration of the mp3 packets is not constant, then they could need a parser
5687  if (st->codecpar->codec_id == AV_CODEC_ID_MP3
5688  && sc->time_scale == st->codecpar->sample_rate) {
5689  int stts_constant = 1;
5690  for (int i = 1; sc->stts_count && i < sc->tts_count; i++) {
5691  if (sc->tts_data[i].duration == sc->tts_data[0].duration)
5692  continue;
5693  stts_constant = 0;
5694  }
5695  if (!stts_constant)
5697  }
5698  /* Do not need those anymore. */
5699  av_freep(&sc->chunk_offsets);
5700  av_freep(&sc->sample_sizes);
5701  av_freep(&sc->keyframes);
5702  av_freep(&sc->stps_data);
5703  av_freep(&sc->elst_data);
5704  av_freep(&sc->rap_group);
5705  av_freep(&sc->sync_group);
5706  av_freep(&sc->sgpd_sync);
5707 
5708  return 0;
5709 }
5710 
5712 {
5713  int ret;
5714  c->itunes_metadata = 1;
5715  ret = mov_read_default(c, pb, atom);
5716  c->itunes_metadata = 0;
5717  return ret;
5718 }
5719 
5721 {
5722  uint32_t count;
5723  uint32_t i;
5724 
5725  if (atom.size < 8)
5726  return 0;
5727 
5728  avio_skip(pb, 4);
5729  count = avio_rb32(pb);
5730  atom.size -= 8;
5731  if (count >= UINT_MAX / sizeof(*c->meta_keys)) {
5732  av_log(c->fc, AV_LOG_ERROR,
5733  "The 'keys' atom with the invalid key count: %"PRIu32"\n", count);
5734  return AVERROR_INVALIDDATA;
5735  }
5736 
5737  c->meta_keys_count = count + 1;
5738  c->meta_keys = av_mallocz(c->meta_keys_count * sizeof(*c->meta_keys));
5739  if (!c->meta_keys)
5740  return AVERROR(ENOMEM);
5741 
5742  for (i = 1; i <= count; ++i) {
5743  uint32_t key_size = avio_rb32(pb);
5744  uint32_t type = avio_rl32(pb);
5745  if (key_size < 8 || key_size > atom.size) {
5746  av_log(c->fc, AV_LOG_ERROR,
5747  "The key# %"PRIu32" in meta has invalid size:"
5748  "%"PRIu32"\n", i, key_size);
5749  return AVERROR_INVALIDDATA;
5750  }
5751  atom.size -= key_size;
5752  key_size -= 8;
5753  if (type != MKTAG('m','d','t','a')) {
5754  avio_skip(pb, key_size);
5755  continue;
5756  }
5757  c->meta_keys[i] = av_mallocz(key_size + 1);
5758  if (!c->meta_keys[i])
5759  return AVERROR(ENOMEM);
5760  avio_read(pb, c->meta_keys[i], key_size);
5761  }
5762 
5763  return 0;
5764 }
5765 
5767 {
5768  int64_t end = av_sat_add64(avio_tell(pb), atom.size);
5769  uint8_t *key = NULL, *val = NULL, *mean = NULL;
5770  int i;
5771  int ret = 0;
5772  AVStream *st;
5773 
5774  if (c->fc->nb_streams < 1)
5775  return 0;
5776  st = c->fc->streams[c->fc->nb_streams-1];
5777 
5778  for (i = 0; i < 3; i++) {
5779  uint8_t **p;
5780  uint32_t len, tag;
5781 
5782  if (end - avio_tell(pb) <= 12)
5783  break;
5784 
5785  len = avio_rb32(pb);
5786  tag = avio_rl32(pb);
5787  avio_skip(pb, 4); // flags
5788 
5789  if (len < 12 || len - 12 > end - avio_tell(pb))
5790  break;
5791  len -= 12;
5792 
5793  if (tag == MKTAG('m', 'e', 'a', 'n'))
5794  p = &mean;
5795  else if (tag == MKTAG('n', 'a', 'm', 'e'))
5796  p = &key;
5797  else if (tag == MKTAG('d', 'a', 't', 'a') && len > 4) {
5798  avio_skip(pb, 4);
5799  len -= 4;
5800  p = &val;
5801  } else
5802  break;
5803 
5804  if (*p)
5805  break;
5806 
5807  *p = av_malloc(len + 1);
5808  if (!*p) {
5809  ret = AVERROR(ENOMEM);
5810  break;
5811  }
5812  ret = ffio_read_size(pb, *p, len);
5813  if (ret < 0) {
5814  av_freep(p);
5815  break;
5816  }
5817  (*p)[len] = 0;
5818  }
5819 
5820  if (mean && key && val) {
5821  if (strcmp(key, "iTunSMPB") == 0) {
5822  int priming, remainder, samples;
5823  if(sscanf(val, "%*X %X %X %X", &priming, &remainder, &samples) == 3){
5824  if(priming>0 && priming<16384)
5825  st->codecpar->initial_padding = priming = av_rescale_q(priming, st->time_base,
5826  (AVRational){ 1, st->codecpar->sample_rate });
5827  if (remainder > 0) {
5829  (AVRational){ 1, st->codecpar->sample_rate });
5830  remainder = av_rescale_q(remainder, st->time_base,
5831  (AVRational){ 1, st->codecpar->sample_rate });
5833  (AVRational){ 1, st->codecpar->sample_rate });
5834  if (duration > remainder && duration > samples) {
5835  ffstream(st)->first_discard_sample = duration - remainder;
5837  }
5838  }
5839  av_log(c->fc, AV_LOG_DEBUG, "Parsed iTunSMPB: priming %d, remainder %d samples %d\n",
5840  priming, remainder, samples);
5841  }
5842  }
5843  if (strcmp(mean, "com.apple.iTunes") == 0 &&
5844  strcmp(key, "DISCSUBTITLE") == 0) {
5845  av_dict_set(&c->fc->metadata, "disc_subtitle", val,
5847  val = NULL;
5848  }
5849  if (strcmp(key, "cdec") != 0) {
5850  av_dict_set(&c->fc->metadata, key, val,
5852  key = val = NULL;
5853  }
5854  } else {
5855  av_log(c->fc, AV_LOG_VERBOSE,
5856  "Unhandled or malformed custom metadata of size %"PRId64"\n", atom.size);
5857  }
5858 
5859  avio_seek(pb, end, SEEK_SET);
5860  av_freep(&key);
5861  av_freep(&val);
5862  av_freep(&mean);
5863  return ret;
5864 }
5865 
5867 {
5868  MOVStreamContext *sc;
5869  AVStream *st;
5870 
5871  st = avformat_new_stream(c->fc, NULL);
5872  if (!st)
5873  return AVERROR(ENOMEM);
5874  sc = av_mallocz(sizeof(MOVStreamContext));
5875  if (!sc)
5876  goto fail;
5877 
5878  item->st = st;
5879  st->id = item->item_id;
5880  st->priv_data = sc;
5882  st->codecpar->codec_id = mov_codec_id(st, item->type);
5883  sc->id = st->id;
5884  sc->ffindex = st->index;
5885  st->avg_frame_rate.num = st->avg_frame_rate.den = 1;
5886  st->time_base.num = st->time_base.den = 1;
5887  st->nb_frames = 1;
5888  sc->time_scale = 1;
5889  sc->pb = c->fc->pb;
5890  sc->pb_is_copied = 1;
5891  sc->refcount = 1;
5892 
5893  if (item->name)
5894  av_dict_set(&st->metadata, "title", item->name, 0);
5895 
5896  // Populate the necessary fields used by mov_build_index.
5897  sc->stsc_data = av_malloc_array(1, sizeof(*sc->stsc_data));
5898  if (!sc->stsc_data)
5899  goto fail;
5900  sc->stsc_count = 1;
5901  sc->stsc_data[0].first = 1;
5902  sc->stsc_data[0].count = 1;
5903  sc->stsc_data[0].id = 1;
5904  sc->chunk_offsets = av_malloc_array(1, sizeof(*sc->chunk_offsets));
5905  if (!sc->chunk_offsets)
5906  goto fail;
5907  sc->chunk_count = 1;
5908  sc->stts_data = av_malloc_array(1, sizeof(*sc->stts_data));
5909  if (!sc->stts_data)
5910  goto fail;
5911  sc->stts_count = 1;
5912  sc->stts_data[0].count = 1;
5913  // Not used for still images. But needed by mov_build_index.
5914  sc->stts_data[0].duration = 0;
5915 
5916  return 0;
5917 fail:
5918  mov_free_stream_context(c->fc, st);
5919  ff_remove_stream(c->fc, st);
5920  item->st = NULL;
5921 
5922  return AVERROR(ENOMEM);
5923 }
5924 
5926 {
5927  while (atom.size > 8) {
5928  uint32_t tag;
5929  if (avio_feof(pb))
5930  return AVERROR_EOF;
5931  tag = avio_rl32(pb);
5932  atom.size -= 4;
5933  if (tag == MKTAG('h','d','l','r')) {
5934  avio_seek(pb, -8, SEEK_CUR);
5935  atom.size += 8;
5936  return mov_read_default(c, pb, atom);
5937  }
5938  }
5939  return 0;
5940 }
5941 
5942 // return 1 when matrix is identity, 0 otherwise
5943 #define IS_MATRIX_IDENT(matrix) \
5944  ( (matrix)[0][0] == (1 << 16) && \
5945  (matrix)[1][1] == (1 << 16) && \
5946  (matrix)[2][2] == (1 << 30) && \
5947  !(matrix)[0][1] && !(matrix)[0][2] && \
5948  !(matrix)[1][0] && !(matrix)[1][2] && \
5949  !(matrix)[2][0] && !(matrix)[2][1])
5950 
5952 {
5953  int i, j, e;
5954  int width;
5955  int height;
5956  int display_matrix[3][3];
5957  int res_display_matrix[3][3] = { { 0 } };
5958  AVStream *st;
5959  MOVStreamContext *sc;
5960  int version;
5961  int flags;
5962 
5963  if (c->fc->nb_streams < 1)
5964  return 0;
5965  st = c->fc->streams[c->fc->nb_streams-1];
5966  sc = st->priv_data;
5967 
5968  // Each stream (trak) should have exactly 1 tkhd. This catches bad files and
5969  // avoids corrupting AVStreams mapped to an earlier tkhd.
5970  if (st->id != -1)
5971  return AVERROR_INVALIDDATA;
5972 
5973  version = avio_r8(pb);
5974  flags = avio_rb24(pb);
5976 
5977  if (version == 1) {
5978  avio_rb64(pb);
5979  avio_rb64(pb);
5980  } else {
5981  avio_rb32(pb); /* creation time */
5982  avio_rb32(pb); /* modification time */
5983  }
5984  st->id = (int)avio_rb32(pb); /* track id (NOT 0 !)*/
5985  sc->id = st->id;
5986  avio_rb32(pb); /* reserved */
5987 
5988  /* highlevel (considering edits) duration in movie timebase */
5989  (version == 1) ? avio_rb64(pb) : avio_rb32(pb);
5990  avio_rb32(pb); /* reserved */
5991  avio_rb32(pb); /* reserved */
5992 
5993  avio_rb16(pb); /* layer */
5994  avio_rb16(pb); /* alternate group */
5995  avio_rb16(pb); /* volume */
5996  avio_rb16(pb); /* reserved */
5997 
5998  //read in the display matrix (outlined in ISO 14496-12, Section 6.2.2)
5999  // they're kept in fixed point format through all calculations
6000  // save u,v,z to store the whole matrix in the AV_PKT_DATA_DISPLAYMATRIX
6001  // side data, but the scale factor is not needed to calculate aspect ratio
6002  for (i = 0; i < 3; i++) {
6003  display_matrix[i][0] = avio_rb32(pb); // 16.16 fixed point
6004  display_matrix[i][1] = avio_rb32(pb); // 16.16 fixed point
6005  display_matrix[i][2] = avio_rb32(pb); // 2.30 fixed point
6006  }
6007 
6008  width = avio_rb32(pb); // 16.16 fixed point track width
6009  height = avio_rb32(pb); // 16.16 fixed point track height
6010  sc->width = width >> 16;
6011  sc->height = height >> 16;
6012 
6013  // apply the moov display matrix (after the tkhd one)
6014  for (i = 0; i < 3; i++) {
6015  const int sh[3] = { 16, 16, 30 };
6016  for (j = 0; j < 3; j++) {
6017  for (e = 0; e < 3; e++) {
6018  res_display_matrix[i][j] +=
6019  ((int64_t) display_matrix[i][e] *
6020  c->movie_display_matrix[e][j]) >> sh[e];
6021  }
6022  }
6023  }
6024 
6025  // save the matrix when it is not the default identity
6026  if (!IS_MATRIX_IDENT(res_display_matrix)) {
6027  av_freep(&sc->display_matrix);
6028  sc->display_matrix = av_malloc(sizeof(int32_t) * 9);
6029  if (!sc->display_matrix)
6030  return AVERROR(ENOMEM);
6031 
6032  for (i = 0; i < 3; i++)
6033  for (j = 0; j < 3; j++)
6034  sc->display_matrix[i * 3 + j] = res_display_matrix[i][j];
6035  }
6036 
6037  // transform the display width/height according to the matrix
6038  // to keep the same scale, use [width height 1<<16]
6039  if (width && height && sc->display_matrix) {
6040  double disp_transform[2];
6041 
6042  for (i = 0; i < 2; i++)
6043  disp_transform[i] = hypot(sc->display_matrix[0 + i],
6044  sc->display_matrix[3 + i]);
6045 
6046  if (disp_transform[0] > 1 && disp_transform[1] > 1 &&
6047  disp_transform[0] < (1<<24) && disp_transform[1] < (1<<24) &&
6048  fabs((disp_transform[0] / disp_transform[1]) - 1.0) > 0.01)
6050  disp_transform[0] / disp_transform[1],
6051  INT_MAX);
6052  }
6053  return 0;
6054 }
6055 
6057 {
6058  MOVFragment *frag = &c->fragment;
6059  MOVTrackExt *trex = NULL;
6060  int flags, track_id, i;
6061  MOVFragmentStreamInfo * frag_stream_info;
6062 
6063  avio_r8(pb); /* version */
6064  flags = avio_rb24(pb);
6065 
6066  track_id = avio_rb32(pb);
6067  if (!track_id)
6068  return AVERROR_INVALIDDATA;
6069  for (i = 0; i < c->trex_count; i++)
6070  if (c->trex_data[i].track_id == track_id) {
6071  trex = &c->trex_data[i];
6072  break;
6073  }
6074  if (!trex) {
6075  av_log(c->fc, AV_LOG_WARNING, "could not find corresponding trex (id %u)\n", track_id);
6076  return 0;
6077  }
6078  c->fragment.found_tfhd = 1;
6079  frag->track_id = track_id;
6080  set_frag_stream(&c->frag_index, track_id);
6081 
6084  frag->moof_offset : frag->implicit_offset;
6085  frag->stsd_id = flags & MOV_TFHD_STSD_ID ? avio_rb32(pb) : trex->stsd_id;
6086 
6088  avio_rb32(pb) : trex->duration;
6089  frag->size = flags & MOV_TFHD_DEFAULT_SIZE ?
6090  avio_rb32(pb) : trex->size;
6091  frag->flags = flags & MOV_TFHD_DEFAULT_FLAGS ?
6092  avio_rb32(pb) : trex->flags;
6093  av_log(c->fc, AV_LOG_TRACE, "frag flags 0x%x\n", frag->flags);
6094 
6095  frag_stream_info = get_current_frag_stream_info(&c->frag_index);
6096  if (frag_stream_info) {
6097  frag_stream_info->next_trun_dts = AV_NOPTS_VALUE;
6098  frag_stream_info->stsd_id = frag->stsd_id;
6099  }
6100  return 0;
6101 }
6102 
6104 {
6105  unsigned i, num;
6106  void *new_tracks;
6107 
6108  num = atom.size / 4;
6109  if (!(new_tracks = av_malloc_array(num, sizeof(int))))
6110  return AVERROR(ENOMEM);
6111 
6112  av_free(c->chapter_tracks);
6113  c->chapter_tracks = new_tracks;
6114  c->nb_chapter_tracks = num;
6115 
6116  for (i = 0; i < num && !pb->eof_reached; i++)
6117  c->chapter_tracks[i] = avio_rb32(pb);
6118 
6119  c->nb_chapter_tracks = i;
6120 
6121  return 0;
6122 }
6123 
6125 {
6126  MOVTrackExt *trex;
6127  int err;
6128 
6129  if ((uint64_t)c->trex_count+1 >= UINT_MAX / sizeof(*c->trex_data))
6130  return AVERROR_INVALIDDATA;
6131  if ((err = av_reallocp_array(&c->trex_data, c->trex_count + 1,
6132  sizeof(*c->trex_data))) < 0) {
6133  c->trex_count = 0;
6134  return err;
6135  }
6136 
6137  c->fc->duration = AV_NOPTS_VALUE; // the duration from mvhd is not representing the whole file when fragments are used.
6138 
6139  trex = &c->trex_data[c->trex_count++];
6140  avio_r8(pb); /* version */
6141  avio_rb24(pb); /* flags */
6142  trex->track_id = avio_rb32(pb);
6143  trex->stsd_id = avio_rb32(pb);
6144  trex->duration = avio_rb32(pb);
6145  trex->size = avio_rb32(pb);
6146  trex->flags = avio_rb32(pb);
6147  return 0;
6148 }
6149 
6151 {
6152  MOVFragment *frag = &c->fragment;
6153  AVStream *st = NULL;
6154  MOVStreamContext *sc;
6155  int version, i;
6156  MOVFragmentStreamInfo * frag_stream_info;
6157  int64_t base_media_decode_time;
6158 
6159  for (i = 0; i < c->fc->nb_streams; i++) {
6160  sc = c->fc->streams[i]->priv_data;
6161  if (sc->id == frag->track_id) {
6162  st = c->fc->streams[i];
6163  break;
6164  }
6165  }
6166  if (!st) {
6167  av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %u\n", frag->track_id);
6168  return 0;
6169  }
6170  sc = st->priv_data;
6171  if (sc->pseudo_stream_id + 1 != frag->stsd_id && sc->pseudo_stream_id != -1)
6172  return 0;
6173  version = avio_r8(pb);
6174  avio_rb24(pb); /* flags */
6175  if (version) {
6176  base_media_decode_time = avio_rb64(pb);
6177  } else {
6178  base_media_decode_time = avio_rb32(pb);
6179  }
6180 
6181  frag_stream_info = get_current_frag_stream_info(&c->frag_index);
6182  if (frag_stream_info)
6183  frag_stream_info->tfdt_dts = base_media_decode_time;
6184  sc->track_end = base_media_decode_time;
6185 
6186  return 0;
6187 }
6188 
6190 {
6191  MOVFragment *frag = &c->fragment;
6192  AVStream *st = NULL;
6193  FFStream *sti = NULL;
6194  MOVStreamContext *sc;
6195  MOVTimeToSample *tts_data;
6196  uint64_t offset;
6197  int64_t dts, pts = AV_NOPTS_VALUE;
6198  int data_offset = 0;
6199  unsigned entries, first_sample_flags = frag->flags;
6200  int flags, distance, i;
6201  int64_t prev_dts = AV_NOPTS_VALUE;
6202  int next_frag_index = -1, index_entry_pos;
6203  size_t requested_size;
6204  size_t old_allocated_size;
6205  AVIndexEntry *new_entries;
6206  MOVFragmentStreamInfo * frag_stream_info;
6207 
6208  if (!frag->found_tfhd) {
6209  av_log(c->fc, AV_LOG_ERROR, "trun track id unknown, no tfhd was found\n");
6210  return AVERROR_INVALIDDATA;
6211  }
6212 
6213  for (i = 0; i < c->fc->nb_streams; i++) {
6214  sc = c->fc->streams[i]->priv_data;
6215  if (sc->id == frag->track_id) {
6216  st = c->fc->streams[i];
6217  sti = ffstream(st);
6218  break;
6219  }
6220  }
6221  if (!st) {
6222  av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %u\n", frag->track_id);
6223  return 0;
6224  }
6225  sc = st->priv_data;
6226  if (sc->pseudo_stream_id+1 != frag->stsd_id && sc->pseudo_stream_id != -1)
6227  return 0;
6228 
6229  // Find the next frag_index index that has a valid index_entry for
6230  // the current track_id.
6231  //
6232  // A valid index_entry means the trun for the fragment was read
6233  // and it's samples are in index_entries at the given position.
6234  // New index entries will be inserted before the index_entry found.
6235  index_entry_pos = sti->nb_index_entries;
6236  for (i = c->frag_index.current + 1; i < c->frag_index.nb_items; i++) {
6237  frag_stream_info = get_frag_stream_info(&c->frag_index, i, frag->track_id);
6238  if (frag_stream_info && frag_stream_info->index_entry >= 0) {
6239  next_frag_index = i;
6240  index_entry_pos = frag_stream_info->index_entry;
6241  break;
6242  }
6243  }
6244  av_assert0(index_entry_pos <= sti->nb_index_entries);
6245 
6246  avio_r8(pb); /* version */
6247  flags = avio_rb24(pb);
6248  entries = avio_rb32(pb);
6249  av_log(c->fc, AV_LOG_TRACE, "flags 0x%x entries %u\n", flags, entries);
6250 
6251  if ((uint64_t)entries+sc->tts_count >= UINT_MAX/sizeof(*sc->tts_data))
6252  return AVERROR_INVALIDDATA;
6253  if (flags & MOV_TRUN_DATA_OFFSET) data_offset = avio_rb32(pb);
6254  if (flags & MOV_TRUN_FIRST_SAMPLE_FLAGS) first_sample_flags = avio_rb32(pb);
6255 
6256  int entry_size = !!(flags & MOV_TRUN_SAMPLE_DURATION) * 4
6257  + !!(flags & MOV_TRUN_SAMPLE_SIZE) * 4
6258  + !!(flags & MOV_TRUN_SAMPLE_FLAGS) * 4
6259  + !!(flags & MOV_TRUN_SAMPLE_CTS) * 4;
6260  int64_t sample_data_size = avio_size(sc->pb);
6261  int64_t max_entries = INT64_MAX;
6262 
6263  if (sample_data_size > 0)
6264  max_entries = sample_data_size - sti->nb_index_entries;
6265  if (entry_size) {
6266  int64_t size = sc->pb == pb ? sample_data_size : avio_size(pb);
6267  int64_t pos = avio_tell(pb);
6268  int64_t left = atom.size - 8 - !!(flags & MOV_TRUN_DATA_OFFSET) * 4
6269  - !!(flags & MOV_TRUN_FIRST_SAMPLE_FLAGS) * 4;
6270 
6271  if (pos >= 0 && size >= pos)
6272  left = FFMIN(left, size - pos);
6273  max_entries = FFMIN(max_entries, left / entry_size);
6274  }
6275  if (entries > max_entries) {
6276  av_log(c->fc, AV_LOG_ERROR, "trun sample count %u exceeds the %"PRId64" "
6277  "samples the input can hold\n", entries, max_entries);
6278  return AVERROR_INVALIDDATA;
6279  }
6280 
6281  frag_stream_info = get_current_frag_stream_info(&c->frag_index);
6282  if (frag_stream_info) {
6283  if (frag_stream_info->next_trun_dts != AV_NOPTS_VALUE) {
6284  dts = frag_stream_info->next_trun_dts - sc->time_offset;
6285  } else if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE &&
6286  c->use_mfra_for == FF_MOV_FLAG_MFRA_PTS) {
6287  pts = frag_stream_info->first_tfra_pts;
6288  av_log(c->fc, AV_LOG_DEBUG, "found mfra time %"PRId64
6289  ", using it for pts\n", pts);
6290  } else if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE &&
6291  c->use_mfra_for == FF_MOV_FLAG_MFRA_DTS) {
6292  dts = frag_stream_info->first_tfra_pts;
6293  av_log(c->fc, AV_LOG_DEBUG, "found mfra time %"PRId64
6294  ", using it for dts\n", pts);
6295  } else {
6296  int has_tfdt = frag_stream_info->tfdt_dts != AV_NOPTS_VALUE;
6297  int has_sidx = frag_stream_info->sidx_pts != AV_NOPTS_VALUE;
6298  int fallback_tfdt = !c->use_tfdt && !has_sidx && has_tfdt;
6299  int fallback_sidx = c->use_tfdt && !has_tfdt && has_sidx;
6300 
6301  if (fallback_sidx) {
6302  av_log(c->fc, AV_LOG_DEBUG, "use_tfdt set but no tfdt found, using sidx instead\n");
6303  }
6304  if (fallback_tfdt) {
6305  av_log(c->fc, AV_LOG_DEBUG, "use_tfdt not set but no sidx found, using tfdt instead\n");
6306  }
6307 
6308  if (has_tfdt && c->use_tfdt || fallback_tfdt) {
6309  dts = frag_stream_info->tfdt_dts - sc->time_offset;
6310  av_log(c->fc, AV_LOG_DEBUG, "found tfdt time %"PRId64
6311  ", using it for dts\n", dts);
6312  } else if (has_sidx && !c->use_tfdt || fallback_sidx) {
6313  // FIXME: sidx earliest_presentation_time is *PTS*, s.b.
6314  // pts = frag_stream_info->sidx_pts;
6315  dts = frag_stream_info->sidx_pts;
6316  av_log(c->fc, AV_LOG_DEBUG, "found sidx time %"PRId64
6317  ", using it for dts\n", frag_stream_info->sidx_pts);
6318  } else {
6319  dts = sc->track_end - sc->time_offset;
6320  av_log(c->fc, AV_LOG_DEBUG, "found track end time %"PRId64
6321  ", using it for dts\n", dts);
6322  }
6323  }
6324  } else {
6325  dts = sc->track_end - sc->time_offset;
6326  av_log(c->fc, AV_LOG_DEBUG, "found track end time %"PRId64
6327  ", using it for dts\n", dts);
6328  }
6329  offset = frag->base_data_offset + data_offset;
6330  distance = 0;
6331  av_log(c->fc, AV_LOG_TRACE, "first sample flags 0x%x\n", first_sample_flags);
6332 
6333  // realloc space for new index entries
6334  if ((uint64_t)sti->nb_index_entries + entries >= UINT_MAX / sizeof(AVIndexEntry)) {
6335  entries = UINT_MAX / sizeof(AVIndexEntry) - sti->nb_index_entries;
6336  av_log(c->fc, AV_LOG_ERROR, "Failed to add index entry\n");
6337  }
6338  if (entries == 0)
6339  return 0;
6340 
6341  requested_size = (sti->nb_index_entries + entries) * sizeof(AVIndexEntry);
6342  new_entries = av_fast_realloc(sti->index_entries,
6344  requested_size);
6345  if (!new_entries)
6346  return AVERROR(ENOMEM);
6347  sti->index_entries= new_entries;
6348 
6349  requested_size = (sti->nb_index_entries + entries) * sizeof(*sc->tts_data);
6350  old_allocated_size = sc->tts_allocated_size;
6351  tts_data = av_fast_realloc(sc->tts_data, &sc->tts_allocated_size,
6352  requested_size);
6353  if (!tts_data)
6354  return AVERROR(ENOMEM);
6355  sc->tts_data = tts_data;
6356 
6357  // In case there were samples without time to sample entries, ensure they get
6358  // zero valued entries. This ensures clips which mix boxes with and
6359  // without time to sample entries don't pickup uninitialized data.
6360  memset((uint8_t*)(sc->tts_data) + old_allocated_size, 0,
6361  sc->tts_allocated_size - old_allocated_size);
6362 
6363  if (index_entry_pos < sti->nb_index_entries) {
6364  // Make hole in index_entries and tts_data for new samples
6365  memmove(sti->index_entries + index_entry_pos + entries,
6366  sti->index_entries + index_entry_pos,
6367  sizeof(*sti->index_entries) *
6368  (sti->nb_index_entries - index_entry_pos));
6369  memmove(sc->tts_data + index_entry_pos + entries,
6370  sc->tts_data + index_entry_pos,
6371  sizeof(*sc->tts_data) * (sc->tts_count - index_entry_pos));
6372  if (index_entry_pos < sc->current_sample) {
6373  sc->current_sample += entries;
6374  }
6375  }
6376 
6377  sti->nb_index_entries += entries;
6378  sc->tts_count = sti->nb_index_entries;
6379  sc->stts_count = sti->nb_index_entries;
6380  if (flags & MOV_TRUN_SAMPLE_CTS)
6381  sc->ctts_count = sti->nb_index_entries;
6382 
6383  // Record the index_entry position in frag_index of this fragment
6384  if (frag_stream_info) {
6385  frag_stream_info->index_entry = index_entry_pos;
6386  if (frag_stream_info->index_base < 0)
6387  frag_stream_info->index_base = index_entry_pos;
6388  }
6389 
6390  if (index_entry_pos > 0)
6391  prev_dts = sti->index_entries[index_entry_pos-1].timestamp;
6392 
6393  for (i = 0; i < entries && !pb->eof_reached; i++) {
6394  unsigned sample_size = frag->size;
6395  int sample_flags = i ? frag->flags : first_sample_flags;
6396  unsigned sample_duration = frag->duration;
6397  unsigned ctts_duration = 0;
6398  int keyframe = 0;
6399  int index_entry_flags = 0;
6400 
6401  if (flags & MOV_TRUN_SAMPLE_DURATION) sample_duration = avio_rb32(pb);
6402  if (flags & MOV_TRUN_SAMPLE_SIZE) sample_size = avio_rb32(pb);
6403  if (flags & MOV_TRUN_SAMPLE_FLAGS) sample_flags = avio_rb32(pb);
6404  if (flags & MOV_TRUN_SAMPLE_CTS) ctts_duration = avio_rb32(pb);
6405 
6406  mov_update_dts_shift(sc, ctts_duration, c->fc);
6407  if (pts != AV_NOPTS_VALUE) {
6408  dts = pts - sc->dts_shift;
6409  if (flags & MOV_TRUN_SAMPLE_CTS) {
6410  dts -= ctts_duration;
6411  } else {
6412  dts -= sc->time_offset;
6413  }
6414  av_log(c->fc, AV_LOG_DEBUG,
6415  "pts %"PRId64" calculated dts %"PRId64
6416  " sc->dts_shift %d ctts.duration %d"
6417  " sc->time_offset %"PRId64
6418  " flags & MOV_TRUN_SAMPLE_CTS %d\n",
6419  pts, dts,
6420  sc->dts_shift, ctts_duration,
6422  pts = AV_NOPTS_VALUE;
6423  }
6424 
6425  keyframe =
6426  !(sample_flags & (MOV_FRAG_SAMPLE_FLAG_IS_NON_SYNC |
6428  if (keyframe) {
6429  distance = 0;
6430  index_entry_flags |= AVINDEX_KEYFRAME;
6431  }
6432  // Fragments can overlap in time. Discard overlapping frames after
6433  // decoding.
6434  if (prev_dts >= dts)
6435  index_entry_flags |= AVINDEX_DISCARD_FRAME;
6436 
6437  sti->index_entries[index_entry_pos].pos = offset;
6438  sti->index_entries[index_entry_pos].timestamp = dts;
6439  sti->index_entries[index_entry_pos].size = sample_size;
6440  sti->index_entries[index_entry_pos].min_distance = distance;
6441  sti->index_entries[index_entry_pos].flags = index_entry_flags;
6442 
6443  sc->tts_data[index_entry_pos].count = 1;
6444  sc->tts_data[index_entry_pos].offset = ctts_duration;
6445  sc->tts_data[index_entry_pos].duration = sample_duration;
6446  index_entry_pos++;
6447 
6448  av_log(c->fc, AV_LOG_TRACE, "AVIndex stream %d, sample %d, offset %"PRIx64", dts %"PRId64", "
6449  "size %u, distance %d, keyframe %d\n", st->index,
6450  index_entry_pos, offset, dts, sample_size, distance, keyframe);
6451  distance++;
6452  if (av_sat_add64(dts, sample_duration) != dts + (uint64_t)sample_duration)
6453  return AVERROR_INVALIDDATA;
6454  if (!sample_size)
6455  return AVERROR_INVALIDDATA;
6456  dts += sample_duration;
6457  offset += sample_size;
6458  sc->data_size += sample_size;
6459 
6460  if (sample_duration <= INT64_MAX - sc->duration_for_fps &&
6461  1 <= INT_MAX - sc->nb_frames_for_fps
6462  ) {
6463  sc->duration_for_fps += sample_duration;
6464  sc->nb_frames_for_fps ++;
6465  }
6466  }
6467  if (frag_stream_info)
6468  frag_stream_info->next_trun_dts = dts + sc->time_offset;
6469  if (i < entries) {
6470  // EOF found before reading all entries. Fix the hole this would
6471  // leave in index_entries and tts_data
6472  int gap = entries - i;
6473  memmove(sti->index_entries + index_entry_pos,
6474  sti->index_entries + index_entry_pos + gap,
6475  sizeof(*sti->index_entries) *
6476  (sti->nb_index_entries - (index_entry_pos + gap)));
6477  memmove(sc->tts_data + index_entry_pos,
6478  sc->tts_data + index_entry_pos + gap,
6479  sizeof(*sc->tts_data) *
6480  (sc->tts_count - (index_entry_pos + gap)));
6481 
6482  sti->nb_index_entries -= gap;
6483  sc->tts_count -= gap;
6484  if (index_entry_pos < sc->current_sample) {
6485  sc->current_sample -= gap;
6486  }
6487  entries = i;
6488  }
6489 
6490  // The end of this new fragment may overlap in time with the start
6491  // of the next fragment in index_entries. Mark the samples in the next
6492  // fragment that overlap with AVINDEX_DISCARD_FRAME
6493  prev_dts = AV_NOPTS_VALUE;
6494  if (index_entry_pos > 0)
6495  prev_dts = sti->index_entries[index_entry_pos-1].timestamp;
6496  for (int i = index_entry_pos; i < sti->nb_index_entries; i++) {
6497  if (prev_dts < sti->index_entries[i].timestamp)
6498  break;
6500  }
6501 
6502  // If a hole was created to insert the new index_entries into,
6503  // the index_entry recorded for all subsequent moof must
6504  // be incremented by the number of entries inserted.
6505  fix_frag_index_entries(&c->frag_index, next_frag_index,
6506  frag->track_id, entries);
6507 
6508  if (pb->eof_reached) {
6509  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted TRUN atom\n");
6510  return AVERROR_EOF;
6511  }
6512 
6513  frag->implicit_offset = offset;
6514 
6515  sc->track_end = dts + sc->time_offset;
6516  if (st->duration < sc->track_end)
6517  st->duration = sc->track_end;
6518 
6519  return 0;
6520 }
6521 
6523 {
6524  int64_t stream_size = avio_size(pb);
6525  int64_t offset = av_sat_add64(avio_tell(pb), atom.size), pts, timestamp;
6526  uint8_t version, is_complete;
6527  int64_t offadd;
6528  unsigned i, j, track_id, item_count;
6529  AVStream *st = NULL;
6530  AVStream *ref_st = NULL;
6531  MOVStreamContext *sc, *ref_sc = NULL;
6532  AVRational timescale;
6533 
6534  version = avio_r8(pb);
6535  if (version > 1) {
6536  avpriv_request_sample(c->fc, "sidx version %u", version);
6537  return 0;
6538  }
6539 
6540  avio_rb24(pb); // flags
6541 
6542  track_id = avio_rb32(pb); // Reference ID
6543  for (i = 0; i < c->fc->nb_streams; i++) {
6544  sc = c->fc->streams[i]->priv_data;
6545  if (sc->id == track_id) {
6546  st = c->fc->streams[i];
6547  break;
6548  }
6549  }
6550  if (!st) {
6551  av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %d\n", track_id);
6552  return 0;
6553  }
6554 
6555  sc = st->priv_data;
6556 
6557  timescale = av_make_q(1, avio_rb32(pb));
6558 
6559  if (timescale.den <= 0) {
6560  av_log(c->fc, AV_LOG_ERROR, "Invalid sidx timescale 1/%d\n", timescale.den);
6561  return AVERROR_INVALIDDATA;
6562  }
6563 
6564  if (version == 0) {
6565  pts = avio_rb32(pb);
6566  offadd= avio_rb32(pb);
6567  } else {
6568  pts = avio_rb64(pb);
6569  offadd= avio_rb64(pb);
6570  }
6571  if (av_sat_add64(offset, offadd) != offset + (uint64_t)offadd)
6572  return AVERROR_INVALIDDATA;
6573 
6574  offset += (uint64_t)offadd;
6575 
6576  avio_rb16(pb); // reserved
6577 
6578  item_count = avio_rb16(pb);
6579  if (item_count == 0)
6580  return AVERROR_INVALIDDATA;
6581 
6582  for (i = 0; i < item_count; i++) {
6583  int index;
6584  MOVFragmentStreamInfo * frag_stream_info;
6585  uint32_t size = avio_rb32(pb);
6586  uint32_t duration = avio_rb32(pb);
6587  if (size & 0x80000000) {
6588  avpriv_request_sample(c->fc, "sidx reference_type 1");
6589  return AVERROR_PATCHWELCOME;
6590  }
6591  avio_rb32(pb); // sap_flags
6592  timestamp = av_rescale_q(pts, timescale, st->time_base);
6593 
6595  frag_stream_info = get_frag_stream_info(&c->frag_index, index, track_id);
6596  if (frag_stream_info)
6597  frag_stream_info->sidx_pts = timestamp;
6598 
6599  if (av_sat_add64(offset, size) != offset + (uint64_t)size ||
6600  av_sat_add64(pts, duration) != pts + (uint64_t)duration
6601  )
6602  return AVERROR_INVALIDDATA;
6603  offset += size;
6604  pts += duration;
6605  }
6606 
6607  st->duration = sc->track_end = pts;
6608 
6609  sc->has_sidx = 1;
6610 
6611  // See if the remaining bytes are just an mfra which we can ignore.
6612  is_complete = offset == stream_size;
6613  if (!is_complete && (pb->seekable & AVIO_SEEKABLE_NORMAL) && stream_size > 0 ) {
6614  int64_t ret;
6615  int64_t original_pos = avio_tell(pb);
6616  if (!c->have_read_mfra_size) {
6617  if ((ret = avio_seek(pb, stream_size - 4, SEEK_SET)) < 0)
6618  return ret;
6619  c->mfra_size = avio_rb32(pb);
6620  c->have_read_mfra_size = 1;
6621  if ((ret = avio_seek(pb, original_pos, SEEK_SET)) < 0)
6622  return ret;
6623  }
6624  if (offset == stream_size - c->mfra_size)
6625  is_complete = 1;
6626  }
6627 
6628  if (is_complete) {
6629  // Find first entry in fragment index that came from an sidx.
6630  // This will pretty much always be the first entry.
6631  for (i = 0; i < c->frag_index.nb_items; i++) {
6632  MOVFragmentIndexItem * item = &c->frag_index.item[i];
6633  for (j = 0; ref_st == NULL && j < item->nb_stream_info; j++) {
6634  MOVFragmentStreamInfo * si;
6635  si = &item->stream_info[j];
6636  if (si->sidx_pts != AV_NOPTS_VALUE) {
6637  ref_st = c->fc->streams[j];
6638  ref_sc = ref_st->priv_data;
6639  break;
6640  }
6641  }
6642  }
6643  if (ref_st) for (i = 0; i < c->fc->nb_streams; i++) {
6644  st = c->fc->streams[i];
6645  sc = st->priv_data;
6646  if (!sc->has_sidx) {
6647  st->duration = sc->track_end = av_rescale(ref_st->duration, sc->time_scale, ref_sc->time_scale);
6648  }
6649  }
6650 
6651  if (offadd == 0)
6652  c->frag_index.complete = 1;
6653  }
6654 
6655  return 0;
6656 }
6657 
6658 /* this atom should be null (from specs), but some buggy files put the 'moov' atom inside it... */
6659 /* like the files created with Adobe Premiere 5.0, for samples see */
6660 /* http://graphics.tudelft.nl/~wouter/publications/soundtests/ */
6662 {
6663  int err;
6664 
6665  if (atom.size < 8)
6666  return 0; /* continue */
6667  if (avio_rb32(pb) != 0) { /* 0 sized mdat atom... use the 'wide' atom size */
6668  avio_skip(pb, atom.size - 4);
6669  return 0;
6670  }
6671  atom.type = avio_rl32(pb);
6672  atom.size -= 8;
6673  if (atom.type != MKTAG('m','d','a','t')) {
6674  avio_skip(pb, atom.size);
6675  return 0;
6676  }
6677  err = mov_read_mdat(c, pb, atom);
6678  return err;
6679 }
6680 
6682 {
6683 #if CONFIG_ZLIB
6684  FFIOContext ctx;
6685  uint8_t *cmov_data;
6686  uint8_t *moov_data; /* uncompressed data */
6687  long cmov_len, moov_len;
6688  int ret = -1;
6689 
6690  avio_rb32(pb); /* dcom atom */
6691  if (avio_rl32(pb) != MKTAG('d','c','o','m'))
6692  return AVERROR_INVALIDDATA;
6693  if (avio_rl32(pb) != MKTAG('z','l','i','b')) {
6694  av_log(c->fc, AV_LOG_ERROR, "unknown compression for cmov atom !\n");
6695  return AVERROR_INVALIDDATA;
6696  }
6697  avio_rb32(pb); /* cmvd atom */
6698  if (avio_rl32(pb) != MKTAG('c','m','v','d'))
6699  return AVERROR_INVALIDDATA;
6700  moov_len = avio_rb32(pb); /* uncompressed size */
6701  cmov_len = atom.size - 6 * 4;
6702 
6703  cmov_data = av_malloc(cmov_len);
6704  if (!cmov_data)
6705  return AVERROR(ENOMEM);
6706  moov_data = av_malloc(moov_len);
6707  if (!moov_data) {
6708  av_free(cmov_data);
6709  return AVERROR(ENOMEM);
6710  }
6711  ret = ffio_read_size(pb, cmov_data, cmov_len);
6712  if (ret < 0)
6713  goto free_and_return;
6714 
6716  if (uncompress (moov_data, (uLongf *) &moov_len, (const Bytef *)cmov_data, cmov_len) != Z_OK)
6717  goto free_and_return;
6718  ffio_init_read_context(&ctx, moov_data, moov_len);
6719  ctx.pub.seekable = AVIO_SEEKABLE_NORMAL;
6720  atom.type = MKTAG('m','o','o','v');
6721  atom.size = moov_len;
6722  ret = mov_read_default(c, &ctx.pub, atom);
6723 free_and_return:
6724  av_free(moov_data);
6725  av_free(cmov_data);
6726  return ret;
6727 #else
6728  av_log(c->fc, AV_LOG_ERROR, "this file requires zlib support compiled in\n");
6729  return AVERROR(ENOSYS);
6730 #endif
6731 }
6732 
6733 /* edit list atom */
6735 {
6736  MOVStreamContext *sc;
6737  int i, edit_count, version;
6738  int64_t elst_entry_size;
6739 
6740  if (c->fc->nb_streams < 1 || c->ignore_editlist)
6741  return 0;
6742  sc = c->fc->streams[c->fc->nb_streams-1]->priv_data;
6743 
6744  version = avio_r8(pb); /* version */
6745  avio_rb24(pb); /* flags */
6746  edit_count = avio_rb32(pb); /* entries */
6747  atom.size -= 8;
6748 
6749  elst_entry_size = version == 1 ? 20 : 12;
6750  if (atom.size != edit_count * elst_entry_size) {
6751  if (c->fc->strict_std_compliance >= FF_COMPLIANCE_STRICT) {
6752  av_log(c->fc, AV_LOG_ERROR, "Invalid edit list entry_count: %d for elst atom of size: %"PRId64" bytes.\n",
6753  edit_count, atom.size + 8);
6754  return AVERROR_INVALIDDATA;
6755  } else {
6756  edit_count = atom.size / elst_entry_size;
6757  if (edit_count * elst_entry_size != atom.size) {
6758  av_log(c->fc, AV_LOG_WARNING, "ELST atom of %"PRId64" bytes, bigger than %d entries.\n", atom.size, edit_count);
6759  }
6760  }
6761  }
6762 
6763  if (!edit_count)
6764  return 0;
6765  if (sc->elst_data)
6766  av_log(c->fc, AV_LOG_WARNING, "Duplicated ELST atom\n");
6767  av_free(sc->elst_data);
6768  sc->elst_count = 0;
6769  sc->elst_data = av_malloc_array(edit_count, sizeof(*sc->elst_data));
6770  if (!sc->elst_data)
6771  return AVERROR(ENOMEM);
6772 
6773  av_log(c->fc, AV_LOG_TRACE, "track[%u].edit_count = %i\n", c->fc->nb_streams - 1, edit_count);
6774  for (i = 0; i < edit_count && atom.size > 0 && !pb->eof_reached; i++) {
6775  MOVElst *e = &sc->elst_data[i];
6776 
6777  if (version == 1) {
6778  e->duration = avio_rb64(pb);
6779  e->time = avio_rb64(pb);
6780  atom.size -= 16;
6781  } else {
6782  e->duration = avio_rb32(pb); /* segment duration */
6783  e->time = (int32_t)avio_rb32(pb); /* media time */
6784  atom.size -= 8;
6785  }
6786  e->rate = avio_rb32(pb) / 65536.0;
6787  atom.size -= 4;
6788  av_log(c->fc, AV_LOG_TRACE, "duration=%"PRId64" time=%"PRId64" rate=%f\n",
6789  e->duration, e->time, e->rate);
6790 
6791  if (e->time < 0 && e->time != -1 &&
6792  c->fc->strict_std_compliance >= FF_COMPLIANCE_STRICT) {
6793  av_log(c->fc, AV_LOG_ERROR, "Track %d, edit %d: Invalid edit list media time=%"PRId64"\n",
6794  c->fc->nb_streams-1, i, e->time);
6795  return AVERROR_INVALIDDATA;
6796  }
6797  if (e->duration < 0) {
6798  av_log(c->fc, AV_LOG_ERROR, "Track %d, edit %d: Invalid edit list duration=%"PRId64"\n",
6799  c->fc->nb_streams-1, i, e->duration);
6800  return AVERROR_INVALIDDATA;
6801  }
6802  }
6803  sc->elst_count = i;
6804 
6805  return 0;
6806 }
6807 
6809 {
6810  MOVStreamContext *sc;
6811  int err;
6812 
6813  if (c->fc->nb_streams < 1)
6814  return AVERROR_INVALIDDATA;
6815  sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
6816 
6817  if (atom.size % sizeof(uint32_t))
6818  return AVERROR_INVALIDDATA;
6819 
6820  MovTref *tag = mov_add_tref_tag(sc, atom.type);
6821  if (!tag)
6822  return AVERROR(ENOMEM);
6823 
6824  int nb_timecode_track = atom.size >> 2;
6825  for (int i = 0; i < nb_timecode_track; i++) {
6826  if (avio_feof(pb))
6827  return AVERROR_INVALIDDATA;
6828  err = mov_add_tref_id(tag, avio_rb32(pb));
6829  if (err < 0)
6830  return err;
6831  }
6832 
6833  return 0;
6834 }
6835 
6837 {
6838  AVStream *st;
6839  int version, color_range, color_primaries, color_trc, color_space;
6840 
6841  if (c->fc->nb_streams < 1)
6842  return 0;
6843  st = c->fc->streams[c->fc->nb_streams - 1];
6844 
6845  if (atom.size < 5) {
6846  av_log(c->fc, AV_LOG_ERROR, "Empty VP Codec Configuration box\n");
6847  return AVERROR_INVALIDDATA;
6848  }
6849 
6850  version = avio_r8(pb);
6851  if (version != 1) {
6852  av_log(c->fc, AV_LOG_WARNING, "Unsupported VP Codec Configuration box version %d\n", version);
6853  return 0;
6854  }
6855  avio_skip(pb, 3); /* flags */
6856 
6857  avio_skip(pb, 2); /* profile + level */
6858  color_range = avio_r8(pb); /* bitDepth, chromaSubsampling, videoFullRangeFlag */
6859  color_primaries = avio_r8(pb);
6860  color_trc = avio_r8(pb);
6861  color_space = avio_r8(pb);
6862  if (avio_rb16(pb)) /* codecIntializationDataSize */
6863  return AVERROR_INVALIDDATA;
6864 
6867  if (!av_color_transfer_name(color_trc))
6868  color_trc = AVCOL_TRC_UNSPECIFIED;
6869  if (!av_color_space_name(color_space))
6870  color_space = AVCOL_SPC_UNSPECIFIED;
6871 
6874  st->codecpar->color_trc = color_trc;
6875  st->codecpar->color_space = color_space;
6876 
6877  return 0;
6878 }
6879 
6881 {
6882  MOVStreamContext *sc;
6883  int i, version;
6884 
6885  if (c->fc->nb_streams < 1)
6886  return AVERROR_INVALIDDATA;
6887 
6888  sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
6889 
6890  if (atom.size < 5) {
6891  av_log(c->fc, AV_LOG_ERROR, "Empty Mastering Display Metadata box\n");
6892  return AVERROR_INVALIDDATA;
6893  }
6894 
6895  version = avio_r8(pb);
6896  if (version) {
6897  av_log(c->fc, AV_LOG_WARNING, "Unsupported Mastering Display Metadata box version %d\n", version);
6898  return 0;
6899  }
6900  if (sc->mastering) {
6901  av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicate Mastering Display Metadata\n");
6902  return 0;
6903  }
6904 
6905  avio_skip(pb, 3); /* flags */
6906 
6908  if (!sc->mastering)
6909  return AVERROR(ENOMEM);
6910 
6911  for (i = 0; i < 3; i++) {
6912  sc->mastering->display_primaries[i][0] = av_make_q(avio_rb16(pb), 1 << 16);
6913  sc->mastering->display_primaries[i][1] = av_make_q(avio_rb16(pb), 1 << 16);
6914  }
6915  sc->mastering->white_point[0] = av_make_q(avio_rb16(pb), 1 << 16);
6916  sc->mastering->white_point[1] = av_make_q(avio_rb16(pb), 1 << 16);
6917 
6918  sc->mastering->max_luminance = av_make_q(avio_rb32(pb), 1 << 8);
6919  sc->mastering->min_luminance = av_make_q(avio_rb32(pb), 1 << 14);
6920 
6921  sc->mastering->has_primaries = 1;
6922  sc->mastering->has_luminance = 1;
6923 
6924  return 0;
6925 }
6926 
6928 {
6929  MOVStreamContext *sc;
6930  const int mapping[3] = {1, 2, 0};
6931  const int chroma_den = 50000;
6932  const int luma_den = 10000;
6933  int i;
6934 
6935  if (c->fc->nb_streams < 1)
6936  return AVERROR_INVALIDDATA;
6937 
6938  sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
6939 
6940  if (atom.size < 24) {
6941  av_log(c->fc, AV_LOG_ERROR, "Invalid Mastering Display Color Volume box\n");
6942  return AVERROR_INVALIDDATA;
6943  }
6944 
6945  if (sc->mastering) {
6946  av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicate Mastering Display Color Volume\n");
6947  return 0;
6948  }
6949 
6951  if (!sc->mastering)
6952  return AVERROR(ENOMEM);
6953 
6954  for (i = 0; i < 3; i++) {
6955  const int j = mapping[i];
6956  sc->mastering->display_primaries[j][0] = av_make_q(avio_rb16(pb), chroma_den);
6957  sc->mastering->display_primaries[j][1] = av_make_q(avio_rb16(pb), chroma_den);
6958  }
6959  sc->mastering->white_point[0] = av_make_q(avio_rb16(pb), chroma_den);
6960  sc->mastering->white_point[1] = av_make_q(avio_rb16(pb), chroma_den);
6961 
6962  sc->mastering->max_luminance = av_make_q(avio_rb32(pb), luma_den);
6963  sc->mastering->min_luminance = av_make_q(avio_rb32(pb), luma_den);
6964 
6965  sc->mastering->has_luminance = 1;
6966  sc->mastering->has_primaries = 1;
6967 
6968  return 0;
6969 }
6970 
6972 {
6973  MOVStreamContext *sc;
6974  int version;
6975 
6976  if (c->fc->nb_streams < 1)
6977  return AVERROR_INVALIDDATA;
6978 
6979  sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
6980 
6981  if (atom.size < 5) {
6982  av_log(c->fc, AV_LOG_ERROR, "Empty Content Light Level box\n");
6983  return AVERROR_INVALIDDATA;
6984  }
6985 
6986  version = avio_r8(pb);
6987  if (version) {
6988  av_log(c->fc, AV_LOG_WARNING, "Unsupported Content Light Level box version %d\n", version);
6989  return 0;
6990  }
6991  avio_skip(pb, 3); /* flags */
6992 
6993  if (sc->coll){
6994  av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicate COLL\n");
6995  return 0;
6996  }
6997 
6999  if (!sc->coll)
7000  return AVERROR(ENOMEM);
7001 
7002  sc->coll->MaxCLL = avio_rb16(pb);
7003  sc->coll->MaxFALL = avio_rb16(pb);
7004 
7005  return 0;
7006 }
7007 
7009 {
7010  MOVStreamContext *sc;
7011 
7012  if (c->fc->nb_streams < 1)
7013  return AVERROR_INVALIDDATA;
7014 
7015  sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
7016 
7017  if (atom.size < 4) {
7018  av_log(c->fc, AV_LOG_ERROR, "Empty Content Light Level Info box\n");
7019  return AVERROR_INVALIDDATA;
7020  }
7021 
7022  if (sc->coll){
7023  av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicate CLLI/COLL\n");
7024  return 0;
7025  }
7026 
7028  if (!sc->coll)
7029  return AVERROR(ENOMEM);
7030 
7031  sc->coll->MaxCLL = avio_rb16(pb);
7032  sc->coll->MaxFALL = avio_rb16(pb);
7033 
7034  return 0;
7035 }
7036 
7038 {
7039  MOVStreamContext *sc;
7040  const int illuminance_den = 10000;
7041  const int ambient_den = 50000;
7042  if (c->fc->nb_streams < 1)
7043  return AVERROR_INVALIDDATA;
7044  sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
7045  if (atom.size < 6) {
7046  av_log(c->fc, AV_LOG_ERROR, "Empty Ambient Viewing Environment Info box\n");
7047  return AVERROR_INVALIDDATA;
7048  }
7049  if (sc->ambient){
7050  av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicate AMVE\n");
7051  return 0;
7052  }
7054  if (!sc->ambient)
7055  return AVERROR(ENOMEM);
7056  sc->ambient->ambient_illuminance = av_make_q(avio_rb32(pb), illuminance_den);
7057  sc->ambient->ambient_light_x = av_make_q(avio_rb16(pb), ambient_den);
7058  sc->ambient->ambient_light_y = av_make_q(avio_rb16(pb), ambient_den);
7059  return 0;
7060 }
7061 
7063 {
7064  AVStream *st;
7065  MOVStreamContext *sc;
7066  enum AVStereo3DType type;
7067  int mode;
7068 
7069  if (c->fc->nb_streams < 1)
7070  return 0;
7071 
7072  st = c->fc->streams[c->fc->nb_streams - 1];
7073  sc = st->priv_data;
7074 
7075  if (atom.size < 5) {
7076  av_log(c->fc, AV_LOG_ERROR, "Empty stereoscopic video box\n");
7077  return AVERROR_INVALIDDATA;
7078  }
7079 
7080  if (sc->stereo3d)
7081  return AVERROR_INVALIDDATA;
7082 
7083  avio_skip(pb, 4); /* version + flags */
7084 
7085  mode = avio_r8(pb);
7086  switch (mode) {
7087  case 0:
7088  type = AV_STEREO3D_2D;
7089  break;
7090  case 1:
7092  break;
7093  case 2:
7095  break;
7096  default:
7097  av_log(c->fc, AV_LOG_WARNING, "Unknown st3d mode value %d\n", mode);
7098  return 0;
7099  }
7100 
7102  if (!sc->stereo3d)
7103  return AVERROR(ENOMEM);
7104 
7105  sc->stereo3d->type = type;
7106  return 0;
7107 }
7108 
7110 {
7111  AVStream *st;
7112  MOVStreamContext *sc;
7113  int size = 0;
7114  int64_t remaining;
7115  uint32_t tag = 0;
7117 
7118  if (c->fc->nb_streams < 1)
7119  return 0;
7120 
7121  st = c->fc->streams[c->fc->nb_streams - 1];
7122  sc = st->priv_data;
7123 
7124  remaining = atom.size;
7125  while (remaining > 0) {
7126  size = avio_rb32(pb);
7127  if (size < 8 || size > remaining ) {
7128  av_log(c->fc, AV_LOG_ERROR, "Invalid child size in pack box\n");
7129  return AVERROR_INVALIDDATA;
7130  }
7131 
7132  tag = avio_rl32(pb);
7133  switch (tag) {
7134  case MKTAG('p','k','i','n'): {
7135  if (size != 16) {
7136  av_log(c->fc, AV_LOG_ERROR, "Invalid size of pkin box: %d\n", size);
7137  return AVERROR_INVALIDDATA;
7138  }
7139  avio_skip(pb, 1); // version
7140  avio_skip(pb, 3); // flags
7141 
7142  tag = avio_rl32(pb);
7143  switch (tag) {
7144  case MKTAG('s','i','d','e'):
7146  break;
7147  case MKTAG('o','v','e','r'):
7149  break;
7150  case 0:
7151  // This means value will be set in another layer
7152  break;
7153  default:
7154  av_log(c->fc, AV_LOG_WARNING, "Unknown tag in pkin: %s\n",
7155  av_fourcc2str(tag));
7156  avio_skip(pb, size - 8);
7157  break;
7158  }
7159 
7160  break;
7161  }
7162  default:
7163  av_log(c->fc, AV_LOG_WARNING, "Unknown tag in pack: %s\n",
7164  av_fourcc2str(tag));
7165  avio_skip(pb, size - 8);
7166  break;
7167  }
7168  remaining -= size;
7169  }
7170 
7171  if (remaining != 0) {
7172  av_log(c->fc, AV_LOG_ERROR, "Broken pack box\n");
7173  return AVERROR_INVALIDDATA;
7174  }
7175 
7176  if (type == AV_STEREO3D_2D)
7177  return 0;
7178 
7179  if (!sc->stereo3d) {
7181  if (!sc->stereo3d)
7182  return AVERROR(ENOMEM);
7183  }
7184 
7185  sc->stereo3d->type = type;
7186 
7187  return 0;
7188 }
7189 
7191 {
7192  AVStream *st;
7193  MOVStreamContext *sc;
7194  int size, version, layout;
7195  int32_t yaw, pitch, roll;
7196  uint32_t l = 0, t = 0, r = 0, b = 0;
7197  uint32_t tag, padding = 0;
7198  enum AVSphericalProjection projection;
7199 
7200  if (c->fc->nb_streams < 1)
7201  return 0;
7202 
7203  st = c->fc->streams[c->fc->nb_streams - 1];
7204  sc = st->priv_data;
7205 
7206  if (atom.size < 8) {
7207  av_log(c->fc, AV_LOG_ERROR, "Empty spherical video box\n");
7208  return AVERROR_INVALIDDATA;
7209  }
7210 
7211  size = avio_rb32(pb);
7212  if (size <= 12 || size > atom.size)
7213  return AVERROR_INVALIDDATA;
7214 
7215  tag = avio_rl32(pb);
7216  if (tag != MKTAG('s','v','h','d')) {
7217  av_log(c->fc, AV_LOG_ERROR, "Missing spherical video header\n");
7218  return 0;
7219  }
7220  version = avio_r8(pb);
7221  if (version != 0) {
7222  av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
7223  version);
7224  return 0;
7225  }
7226  avio_skip(pb, 3); /* flags */
7227  avio_skip(pb, size - 12); /* metadata_source */
7228 
7229  size = avio_rb32(pb);
7230  if (size > atom.size)
7231  return AVERROR_INVALIDDATA;
7232 
7233  tag = avio_rl32(pb);
7234  if (tag != MKTAG('p','r','o','j')) {
7235  av_log(c->fc, AV_LOG_ERROR, "Missing projection box\n");
7236  return 0;
7237  }
7238 
7239  size = avio_rb32(pb);
7240  if (size > atom.size)
7241  return AVERROR_INVALIDDATA;
7242 
7243  tag = avio_rl32(pb);
7244  if (tag != MKTAG('p','r','h','d')) {
7245  av_log(c->fc, AV_LOG_ERROR, "Missing projection header box\n");
7246  return 0;
7247  }
7248  version = avio_r8(pb);
7249  if (version != 0) {
7250  av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
7251  version);
7252  return 0;
7253  }
7254  avio_skip(pb, 3); /* flags */
7255 
7256  /* 16.16 fixed point */
7257  yaw = avio_rb32(pb);
7258  pitch = avio_rb32(pb);
7259  roll = avio_rb32(pb);
7260 
7261  size = avio_rb32(pb);
7262  if (size > atom.size)
7263  return AVERROR_INVALIDDATA;
7264 
7265  tag = avio_rl32(pb);
7266  version = avio_r8(pb);
7267  if (version != 0) {
7268  av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
7269  version);
7270  return 0;
7271  }
7272  avio_skip(pb, 3); /* flags */
7273  switch (tag) {
7274  case MKTAG('c','b','m','p'):
7275  layout = avio_rb32(pb);
7276  if (layout) {
7277  av_log(c->fc, AV_LOG_WARNING,
7278  "Unsupported cubemap layout %d\n", layout);
7279  return 0;
7280  }
7281  projection = AV_SPHERICAL_CUBEMAP;
7282  padding = avio_rb32(pb);
7283  break;
7284  case MKTAG('e','q','u','i'):
7285  t = avio_rb32(pb);
7286  b = avio_rb32(pb);
7287  l = avio_rb32(pb);
7288  r = avio_rb32(pb);
7289 
7290  if (b >= UINT_MAX - t || r >= UINT_MAX - l) {
7291  av_log(c->fc, AV_LOG_ERROR,
7292  "Invalid bounding rectangle coordinates "
7293  "%"PRIu32",%"PRIu32",%"PRIu32",%"PRIu32"\n", l, t, r, b);
7294  return AVERROR_INVALIDDATA;
7295  }
7296 
7297  if (l || t || r || b)
7298  projection = AV_SPHERICAL_EQUIRECTANGULAR_TILE;
7299  else
7300  projection = AV_SPHERICAL_EQUIRECTANGULAR;
7301  break;
7302  default:
7303  av_log(c->fc, AV_LOG_ERROR, "Unknown projection type: %s\n", av_fourcc2str(tag));
7304  return 0;
7305  }
7306 
7308  if (!sc->spherical)
7309  return AVERROR(ENOMEM);
7310 
7311  sc->spherical->projection = projection;
7312 
7313  sc->spherical->yaw = yaw;
7314  sc->spherical->pitch = pitch;
7315  sc->spherical->roll = roll;
7316 
7317  sc->spherical->padding = padding;
7318 
7319  sc->spherical->bound_left = l;
7320  sc->spherical->bound_top = t;
7321  sc->spherical->bound_right = r;
7322  sc->spherical->bound_bottom = b;
7323 
7324  return 0;
7325 }
7326 
7328 {
7329  AVStream *st;
7330  MOVStreamContext *sc;
7331  int size;
7332  uint32_t tag;
7333  enum AVSphericalProjection projection;
7334 
7335  if (c->fc->nb_streams < 1)
7336  return 0;
7337 
7338  st = c->fc->streams[c->fc->nb_streams - 1];
7339  sc = st->priv_data;
7340 
7341  if (atom.size < 16) {
7342  av_log(c->fc, AV_LOG_ERROR, "Invalid size for proj box: %"PRIu64"\n", atom.size);
7343  return AVERROR_INVALIDDATA;
7344  }
7345 
7346  size = avio_rb32(pb);
7347  if (size < 16) {
7348  av_log(c->fc, AV_LOG_ERROR, "Invalid size for prji box: %d\n", size);
7349  return AVERROR_INVALIDDATA;
7350  } else if (size > 16) {
7351  av_log(c->fc, AV_LOG_WARNING, "Box has more bytes (%d) than prji box required (16) \n", size);
7352  }
7353 
7354  tag = avio_rl32(pb);
7355  if (tag != MKTAG('p','r','j','i')) {
7356  av_log(c->fc, AV_LOG_ERROR, "Invalid child box of proj box: %s\n",
7357  av_fourcc2str(tag));
7358  return AVERROR_INVALIDDATA;
7359  }
7360 
7361  // version and flags, only support (0, 0)
7362  unsigned n = avio_rl32(pb);
7363  if (n != 0) {
7364  av_log(c->fc, AV_LOG_ERROR, "prji version %u, flag %u are not supported\n",
7365  n & 0xFF, n >> 8);
7366  return AVERROR_PATCHWELCOME;
7367  }
7368 
7369  tag = avio_rl32(pb);
7370  switch (tag) {
7371  case MKTAG('r','e','c','t'):
7372  projection = AV_SPHERICAL_RECTILINEAR;
7373  break;
7374  case MKTAG('e','q','u','i'):
7375  projection = AV_SPHERICAL_EQUIRECTANGULAR;
7376  break;
7377  case MKTAG('h','e','q','u'):
7378  projection = AV_SPHERICAL_HALF_EQUIRECTANGULAR;
7379  break;
7380  case MKTAG('f','i','s','h'):
7381  projection = AV_SPHERICAL_FISHEYE;
7382  break;
7383  case MKTAG('p','r','i','m'):
7384  projection = AV_SPHERICAL_PARAMETRIC_IMMERSIVE;
7385  break;
7386  default:
7387  av_log(c->fc, AV_LOG_ERROR, "Invalid projection type in prji box: %s\n", av_fourcc2str(tag));
7388  return AVERROR_INVALIDDATA;
7389  }
7390 
7392  if (!sc->spherical)
7393  return AVERROR(ENOMEM);
7394 
7395  sc->spherical->projection = projection;
7396 
7397  return 0;
7398 }
7399 
7401 {
7402  AVStream *st;
7403  MOVStreamContext *sc;
7404  int size, flags = 0;
7405  int64_t remaining;
7406  uint32_t tag, baseline = 0;
7409  enum AVStereo3DPrimaryEye primary_eye = AV_PRIMARY_EYE_NONE;
7410  AVRational horizontal_disparity_adjustment = { 0, 1 };
7411 
7412  if (c->fc->nb_streams < 1)
7413  return 0;
7414 
7415  st = c->fc->streams[c->fc->nb_streams - 1];
7416  sc = st->priv_data;
7417 
7418  remaining = atom.size;
7419  while (remaining > 0) {
7420  size = avio_rb32(pb);
7421  if (size < 8 || size > remaining ) {
7422  av_log(c->fc, AV_LOG_ERROR, "Invalid child size in eyes box\n");
7423  return AVERROR_INVALIDDATA;
7424  }
7425 
7426  tag = avio_rl32(pb);
7427  switch (tag) {
7428  case MKTAG('s','t','r','i'): {
7429  int has_right, has_left;
7430  uint8_t tmp;
7431  if (size != 13) {
7432  av_log(c->fc, AV_LOG_ERROR, "Invalid size of stri box: %d\n", size);
7433  return AVERROR_INVALIDDATA;
7434  }
7435  avio_skip(pb, 1); // version
7436  avio_skip(pb, 3); // flags
7437 
7438  tmp = avio_r8(pb);
7439 
7440  // eye_views_reversed
7441  if (tmp & 8) {
7443  }
7444  // has_additional_views
7445  if (tmp & 4) {
7446  // skip...
7447  }
7448 
7449  has_right = tmp & 2; // has_right_eye_view
7450  has_left = tmp & 1; // has_left_eye_view
7451 
7452  if (has_left && has_right)
7453  view = AV_STEREO3D_VIEW_PACKED;
7454  else if (has_left)
7455  view = AV_STEREO3D_VIEW_LEFT;
7456  else if (has_right)
7457  view = AV_STEREO3D_VIEW_RIGHT;
7458  if (has_left || has_right)
7460 
7461  break;
7462  }
7463  case MKTAG('h','e','r','o'): {
7464  int tmp;
7465  if (size != 13) {
7466  av_log(c->fc, AV_LOG_ERROR, "Invalid size of hero box: %d\n", size);
7467  return AVERROR_INVALIDDATA;
7468  }
7469  avio_skip(pb, 1); // version
7470  avio_skip(pb, 3); // flags
7471 
7472  tmp = avio_r8(pb);
7473  if (tmp == 0)
7474  primary_eye = AV_PRIMARY_EYE_NONE;
7475  else if (tmp == 1)
7476  primary_eye = AV_PRIMARY_EYE_LEFT;
7477  else if (tmp == 2)
7478  primary_eye = AV_PRIMARY_EYE_RIGHT;
7479  else
7480  av_log(c->fc, AV_LOG_WARNING, "Unknown hero eye type: %d\n", tmp);
7481 
7482  break;
7483  }
7484  case MKTAG('c','a','m','s'): {
7485  uint32_t subtag;
7486  int subsize;
7487  if (size != 24) {
7488  av_log(c->fc, AV_LOG_ERROR, "Invalid size of cams box: %d\n", size);
7489  return AVERROR_INVALIDDATA;
7490  }
7491 
7492  subsize = avio_rb32(pb);
7493  if (subsize != 16) {
7494  av_log(c->fc, AV_LOG_ERROR, "Invalid size of blin box: %d\n", size);
7495  return AVERROR_INVALIDDATA;
7496  }
7497 
7498  subtag = avio_rl32(pb);
7499  if (subtag != MKTAG('b','l','i','n')) {
7500  av_log(c->fc, AV_LOG_ERROR, "Expected blin box, got %s\n",
7501  av_fourcc2str(subtag));
7502  return AVERROR_INVALIDDATA;
7503  }
7504 
7505  avio_skip(pb, 1); // version
7506  avio_skip(pb, 3); // flags
7507 
7508  baseline = avio_rb32(pb);
7509 
7510  break;
7511  }
7512  case MKTAG('c','m','f','y'): {
7513  uint32_t subtag;
7514  int subsize;
7515  int32_t adjustment;
7516  if (size != 24) {
7517  av_log(c->fc, AV_LOG_ERROR, "Invalid size of cmfy box: %d\n", size);
7518  return AVERROR_INVALIDDATA;
7519  }
7520 
7521  subsize = avio_rb32(pb);
7522  if (subsize != 16) {
7523  av_log(c->fc, AV_LOG_ERROR, "Invalid size of dadj box: %d\n", size);
7524  return AVERROR_INVALIDDATA;
7525  }
7526 
7527  subtag = avio_rl32(pb);
7528  if (subtag != MKTAG('d','a','d','j')) {
7529  av_log(c->fc, AV_LOG_ERROR, "Expected dadj box, got %s\n",
7530  av_fourcc2str(subtag));
7531  return AVERROR_INVALIDDATA;
7532  }
7533 
7534  avio_skip(pb, 1); // version
7535  avio_skip(pb, 3); // flags
7536 
7537  adjustment = (int32_t) avio_rb32(pb);
7538 
7539  horizontal_disparity_adjustment.num = (int) adjustment;
7540  horizontal_disparity_adjustment.den = 10000;
7541 
7542  break;
7543  }
7544  default:
7545  av_log(c->fc, AV_LOG_WARNING, "Unknown tag in eyes: %s\n",
7546  av_fourcc2str(tag));
7547  avio_skip(pb, size - 8);
7548  break;
7549  }
7550  remaining -= size;
7551  }
7552 
7553  if (remaining != 0) {
7554  av_log(c->fc, AV_LOG_ERROR, "Broken eyes box\n");
7555  return AVERROR_INVALIDDATA;
7556  }
7557 
7558  if (type == AV_STEREO3D_2D)
7559  return 0;
7560 
7561  if (!sc->stereo3d) {
7563  if (!sc->stereo3d)
7564  return AVERROR(ENOMEM);
7565  }
7566 
7567  sc->stereo3d->flags = flags;
7568  sc->stereo3d->type = type;
7569  sc->stereo3d->view = view;
7570  sc->stereo3d->primary_eye = primary_eye;
7571  sc->stereo3d->baseline = baseline;
7572  sc->stereo3d->horizontal_disparity_adjustment = horizontal_disparity_adjustment;
7573 
7574  return 0;
7575 }
7576 
7578 {
7579  int size;
7580  int64_t remaining;
7581  uint32_t tag;
7582 
7583  if (c->fc->nb_streams < 1)
7584  return 0;
7585 
7586  if (atom.size < 8) {
7587  av_log(c->fc, AV_LOG_ERROR, "Empty video extension usage box\n");
7588  return AVERROR_INVALIDDATA;
7589  }
7590 
7591  remaining = atom.size;
7592  while (remaining > 0) {
7593  size = avio_rb32(pb);
7594  if (size < 8 || size > remaining ) {
7595  av_log(c->fc, AV_LOG_ERROR, "Invalid child size in vexu box\n");
7596  return AVERROR_INVALIDDATA;
7597  }
7598 
7599  tag = avio_rl32(pb);
7600  switch (tag) {
7601  case MKTAG('p','r','o','j'): {
7602  MOVAtom proj = { tag, size - 8 };
7603  int ret = mov_read_vexu_proj(c, pb, proj);
7604  if (ret < 0)
7605  return ret;
7606  break;
7607  }
7608  case MKTAG('e','y','e','s'): {
7609  MOVAtom eyes = { tag, size - 8 };
7610  int ret = mov_read_eyes(c, pb, eyes);
7611  if (ret < 0)
7612  return ret;
7613  break;
7614  }
7615  case MKTAG('p','a','c','k'): {
7616  MOVAtom pack = { tag, size - 8 };
7617  int ret = mov_read_pack(c, pb, pack);
7618  if (ret < 0)
7619  return ret;
7620  break;
7621  }
7622  default:
7623  av_log(c->fc, AV_LOG_WARNING, "Unknown tag in vexu: %s\n",
7624  av_fourcc2str(tag));
7625  avio_skip(pb, size - 8);
7626  break;
7627  }
7628  remaining -= size;
7629  }
7630 
7631  if (remaining != 0) {
7632  av_log(c->fc, AV_LOG_ERROR, "Broken vexu box\n");
7633  return AVERROR_INVALIDDATA;
7634  }
7635 
7636  return 0;
7637 }
7638 
7640 {
7641  AVStream *st;
7642  MOVStreamContext *sc;
7643 
7644  if (c->fc->nb_streams < 1)
7645  return 0;
7646 
7647  st = c->fc->streams[c->fc->nb_streams - 1];
7648  sc = st->priv_data;
7649 
7650  if (atom.size != 4) {
7651  av_log(c->fc, AV_LOG_ERROR, "Invalid size of hfov box: %"PRIu64"\n", atom.size);
7652  return AVERROR_INVALIDDATA;
7653  }
7654 
7655 
7656  if (!sc->stereo3d) {
7658  if (!sc->stereo3d)
7659  return AVERROR(ENOMEM);
7660  }
7661 
7663  sc->stereo3d->horizontal_field_of_view.den = 1000; // thousands of a degree
7664 
7665  return 0;
7666 }
7667 
7669 {
7670  int ret = 0;
7671  uint8_t *buffer = av_malloc(len + 1);
7672  const char *val;
7673 
7674  if (!buffer)
7675  return AVERROR(ENOMEM);
7676  buffer[len] = '\0';
7677 
7678  ret = ffio_read_size(pb, buffer, len);
7679  if (ret < 0)
7680  goto out;
7681 
7682  /* Check for mandatory keys and values, try to support XML as best-effort */
7683  if (!sc->spherical &&
7684  av_stristr(buffer, "<GSpherical:StitchingSoftware>") &&
7685  (val = av_stristr(buffer, "<GSpherical:Spherical>")) &&
7686  av_stristr(val, "true") &&
7687  (val = av_stristr(buffer, "<GSpherical:Stitched>")) &&
7688  av_stristr(val, "true") &&
7689  (val = av_stristr(buffer, "<GSpherical:ProjectionType>")) &&
7690  av_stristr(val, "equirectangular")) {
7692  if (!sc->spherical)
7693  goto out;
7694 
7696 
7697  if (av_stristr(buffer, "<GSpherical:StereoMode>") && !sc->stereo3d) {
7698  enum AVStereo3DType mode;
7699 
7700  if (av_stristr(buffer, "left-right"))
7702  else if (av_stristr(buffer, "top-bottom"))
7704  else
7705  mode = AV_STEREO3D_2D;
7706 
7708  if (!sc->stereo3d)
7709  goto out;
7710 
7711  sc->stereo3d->type = mode;
7712  }
7713 
7714  /* orientation */
7715  val = av_stristr(buffer, "<GSpherical:InitialViewHeadingDegrees>");
7716  if (val)
7717  sc->spherical->yaw = strtol(val, NULL, 10) * (1 << 16);
7718  val = av_stristr(buffer, "<GSpherical:InitialViewPitchDegrees>");
7719  if (val)
7720  sc->spherical->pitch = strtol(val, NULL, 10) * (1 << 16);
7721  val = av_stristr(buffer, "<GSpherical:InitialViewRollDegrees>");
7722  if (val)
7723  sc->spherical->roll = strtol(val, NULL, 10) * (1 << 16);
7724  }
7725 
7726 out:
7727  av_free(buffer);
7728  return ret;
7729 }
7730 
7732 {
7733  AVStream *st;
7734  MOVStreamContext *sc;
7735  int64_t ret;
7736  AVUUID uuid;
7737  static const AVUUID uuid_isml_manifest = {
7738  0xa5, 0xd4, 0x0b, 0x30, 0xe8, 0x14, 0x11, 0xdd,
7739  0xba, 0x2f, 0x08, 0x00, 0x20, 0x0c, 0x9a, 0x66
7740  };
7741  static const AVUUID uuid_xmp = {
7742  0xbe, 0x7a, 0xcf, 0xcb, 0x97, 0xa9, 0x42, 0xe8,
7743  0x9c, 0x71, 0x99, 0x94, 0x91, 0xe3, 0xaf, 0xac
7744  };
7745  static const AVUUID uuid_spherical = {
7746  0xff, 0xcc, 0x82, 0x63, 0xf8, 0x55, 0x4a, 0x93,
7747  0x88, 0x14, 0x58, 0x7a, 0x02, 0x52, 0x1f, 0xdd,
7748  };
7749 
7750  if (atom.size < AV_UUID_LEN || atom.size >= FFMIN(INT_MAX, SIZE_MAX))
7751  return AVERROR_INVALIDDATA;
7752 
7753  if (c->fc->nb_streams < 1)
7754  return 0;
7755  st = c->fc->streams[c->fc->nb_streams - 1];
7756  sc = st->priv_data;
7757 
7758  ret = ffio_read_size(pb, uuid, AV_UUID_LEN);
7759  if (ret < 0)
7760  return ret;
7761  if (av_uuid_equal(uuid, uuid_isml_manifest)) {
7762  uint8_t *buffer, *ptr;
7763  char *endptr;
7764  size_t len = atom.size - AV_UUID_LEN;
7765 
7766  if (len < 4) {
7767  return AVERROR_INVALIDDATA;
7768  }
7769  ret = avio_skip(pb, 4); // zeroes
7770  len -= 4;
7771 
7772  buffer = av_mallocz(len + 1);
7773  if (!buffer) {
7774  return AVERROR(ENOMEM);
7775  }
7776  ret = ffio_read_size(pb, buffer, len);
7777  if (ret < 0) {
7778  av_free(buffer);
7779  return ret;
7780  }
7781 
7782  ptr = buffer;
7783  while ((ptr = av_stristr(ptr, "systemBitrate=\""))) {
7784  ptr += sizeof("systemBitrate=\"") - 1;
7785  c->bitrates_count++;
7786  c->bitrates = av_realloc_f(c->bitrates, c->bitrates_count, sizeof(*c->bitrates));
7787  if (!c->bitrates) {
7788  c->bitrates_count = 0;
7789  av_free(buffer);
7790  return AVERROR(ENOMEM);
7791  }
7792  errno = 0;
7793  ret = strtol(ptr, &endptr, 10);
7794  if (ret < 0 || errno || *endptr != '"') {
7795  c->bitrates[c->bitrates_count - 1] = 0;
7796  } else {
7797  c->bitrates[c->bitrates_count - 1] = ret;
7798  }
7799  }
7800 
7801  av_free(buffer);
7802  } else if (av_uuid_equal(uuid, uuid_xmp)) {
7803  uint8_t *buffer;
7804  size_t len = atom.size - AV_UUID_LEN;
7805  if (c->export_xmp) {
7806  buffer = av_mallocz(len + 1);
7807  if (!buffer) {
7808  return AVERROR(ENOMEM);
7809  }
7810  ret = ffio_read_size(pb, buffer, len);
7811  if (ret < 0) {
7812  av_free(buffer);
7813  return ret;
7814  }
7815  buffer[len] = '\0';
7816  av_dict_set(&c->fc->metadata, "xmp",
7818  } else {
7819  // skip all uuid atom, which makes it fast for long uuid-xmp file
7820  ret = avio_skip(pb, len);
7821  if (ret < 0)
7822  return ret;
7823  }
7824  } else if (av_uuid_equal(uuid, uuid_spherical)) {
7825  size_t len = atom.size - AV_UUID_LEN;
7826  ret = mov_parse_uuid_spherical(sc, pb, len);
7827  if (ret < 0)
7828  return ret;
7829  if (!sc->spherical)
7830  av_log(c->fc, AV_LOG_WARNING, "Invalid spherical metadata found\n");
7831  }
7832 
7833  return 0;
7834 }
7835 
7837 {
7838  int ret;
7839  uint8_t content[16];
7840 
7841  if (atom.size < 8)
7842  return 0;
7843 
7844  ret = ffio_read_size(pb, content, FFMIN(sizeof(content), atom.size));
7845  if (ret < 0)
7846  return ret;
7847 
7848  if ( !c->found_moov
7849  && !c->found_mdat
7850  && !memcmp(content, "Anevia\x1A\x1A", 8)
7851  && c->use_mfra_for == FF_MOV_FLAG_MFRA_AUTO) {
7852  c->use_mfra_for = FF_MOV_FLAG_MFRA_PTS;
7853  }
7854 
7855  return 0;
7856 }
7857 
7859 {
7860  uint32_t format = avio_rl32(pb);
7861  MOVStreamContext *sc;
7862  enum AVCodecID id;
7863  AVStream *st;
7864 
7865  if (c->fc->nb_streams < 1)
7866  return 0;
7867  st = c->fc->streams[c->fc->nb_streams - 1];
7868  sc = st->priv_data;
7869 
7870  switch (sc->format)
7871  {
7872  case MKTAG('e','n','c','v'): // encrypted video
7873  case MKTAG('e','n','c','a'): // encrypted audio
7874  id = mov_codec_id(st, format);
7875  if (st->codecpar->codec_id != AV_CODEC_ID_NONE &&
7876  st->codecpar->codec_id != id) {
7877  av_log(c->fc, AV_LOG_WARNING,
7878  "ignoring 'frma' atom of '%.4s', stream has codec id %d\n",
7879  (char*)&format, st->codecpar->codec_id);
7880  break;
7881  }
7882 
7883  st->codecpar->codec_id = id;
7884  sc->format = format;
7885  break;
7886 
7887  default:
7888  if (format != sc->format) {
7889  av_log(c->fc, AV_LOG_WARNING,
7890  "ignoring 'frma' atom of '%.4s', stream format is '%.4s'\n",
7891  (char*)&format, (char*)&sc->format);
7892  }
7893  break;
7894  }
7895 
7896  return 0;
7897 }
7898 
7899 /**
7900  * Gets the current encryption info and associated current stream context. If
7901  * we are parsing a track fragment, this will return the specific encryption
7902  * info for this fragment; otherwise this will return the global encryption
7903  * info for the current stream.
7904  */
7906 {
7907  MOVFragmentStreamInfo *frag_stream_info;
7908  AVStream *st;
7909  int i;
7910 
7911  frag_stream_info = get_current_frag_stream_info(&c->frag_index);
7912  if (frag_stream_info) {
7913  for (i = 0; i < c->fc->nb_streams; i++) {
7914  *sc = c->fc->streams[i]->priv_data;
7915  if ((*sc)->id == frag_stream_info->id) {
7916  st = c->fc->streams[i];
7917  break;
7918  }
7919  }
7920  if (i == c->fc->nb_streams)
7921  return 0;
7922  *sc = st->priv_data;
7923 
7924  if (!frag_stream_info->encryption_index) {
7925  // If this stream isn't encrypted, don't create the index.
7926  if (!(*sc)->cenc.default_encrypted_sample)
7927  return 0;
7928  frag_stream_info->encryption_index = av_mallocz(sizeof(*frag_stream_info->encryption_index));
7929  if (!frag_stream_info->encryption_index)
7930  return AVERROR(ENOMEM);
7931  }
7932  *encryption_index = frag_stream_info->encryption_index;
7933  return 1;
7934  } else {
7935  // No current track fragment, using stream level encryption info.
7936 
7937  if (c->fc->nb_streams < 1)
7938  return 0;
7939  st = c->fc->streams[c->fc->nb_streams - 1];
7940  *sc = st->priv_data;
7941 
7942  if (!(*sc)->cenc.encryption_index) {
7943  // If this stream isn't encrypted, don't create the index.
7944  if (!(*sc)->cenc.default_encrypted_sample)
7945  return 0;
7946  (*sc)->cenc.encryption_index = av_mallocz(sizeof(*frag_stream_info->encryption_index));
7947  if (!(*sc)->cenc.encryption_index)
7948  return AVERROR(ENOMEM);
7949  }
7950 
7951  *encryption_index = (*sc)->cenc.encryption_index;
7952  return 1;
7953  }
7954 }
7955 
7957 {
7958  int i, ret;
7959  unsigned int subsample_count;
7960  AVSubsampleEncryptionInfo *subsamples;
7961 
7962  if (!sc->cenc.default_encrypted_sample) {
7963  av_log(c->fc, AV_LOG_ERROR, "Missing schm or tenc\n");
7964  return AVERROR_INVALIDDATA;
7965  }
7966 
7967  if (sc->cenc.per_sample_iv_size || use_subsamples) {
7969  if (!*sample)
7970  return AVERROR(ENOMEM);
7971  } else
7972  *sample = NULL;
7973 
7974  if (sc->cenc.per_sample_iv_size != 0) {
7975  if ((ret = ffio_read_size(pb, (*sample)->iv, sc->cenc.per_sample_iv_size)) < 0) {
7976  av_log(c->fc, AV_LOG_ERROR, "failed to read the initialization vector\n");
7978  *sample = NULL;
7979  return ret;
7980  }
7981  }
7982 
7983  if (use_subsamples) {
7984  subsample_count = avio_rb16(pb);
7985  av_free((*sample)->subsamples);
7986  (*sample)->subsamples = av_calloc(subsample_count, sizeof(*subsamples));
7987  if (!(*sample)->subsamples) {
7989  *sample = NULL;
7990  return AVERROR(ENOMEM);
7991  }
7992 
7993  for (i = 0; i < subsample_count && !pb->eof_reached; i++) {
7994  (*sample)->subsamples[i].bytes_of_clear_data = avio_rb16(pb);
7995  (*sample)->subsamples[i].bytes_of_protected_data = avio_rb32(pb);
7996  }
7997 
7998  if (pb->eof_reached) {
7999  av_log(c->fc, AV_LOG_ERROR, "hit EOF while reading sub-sample encryption info\n");
8001  *sample = NULL;
8002  return AVERROR_INVALIDDATA;
8003  }
8004  (*sample)->subsample_count = subsample_count;
8005  }
8006 
8007  return 0;
8008 }
8009 
8011 {
8012  AVEncryptionInfo **encrypted_samples;
8013  MOVEncryptionIndex *encryption_index;
8014  MOVStreamContext *sc;
8015  int use_subsamples, ret;
8016  unsigned int sample_count, i, alloc_size = 0;
8017 
8018  ret = get_current_encryption_info(c, &encryption_index, &sc);
8019  if (ret != 1)
8020  return ret;
8021 
8022  if (encryption_index->nb_encrypted_samples) {
8023  // This can happen if we have both saio/saiz and senc atoms.
8024  av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in senc\n");
8025  return 0;
8026  }
8027 
8028  avio_r8(pb); /* version */
8029  use_subsamples = avio_rb24(pb) & 0x02; /* flags */
8030 
8031  sample_count = avio_rb32(pb);
8032  if (sample_count >= INT_MAX / sizeof(*encrypted_samples))
8033  return AVERROR(ENOMEM);
8034 
8035  for (i = 0; i < sample_count; i++) {
8036  unsigned int min_samples = FFMIN(FFMAX(i + 1, 1024 * 1024), sample_count);
8037  encrypted_samples = av_fast_realloc(encryption_index->encrypted_samples, &alloc_size,
8038  min_samples * sizeof(*encrypted_samples));
8039  if (encrypted_samples) {
8040  encryption_index->encrypted_samples = encrypted_samples;
8041 
8043  c, pb, sc, &encryption_index->encrypted_samples[i], use_subsamples);
8044  } else {
8045  ret = AVERROR(ENOMEM);
8046  }
8047  if (pb->eof_reached) {
8048  av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading senc\n");
8049  if (ret >= 0)
8050  av_encryption_info_free(encryption_index->encrypted_samples[i]);
8052  }
8053 
8054  if (ret < 0) {
8055  for (; i > 0; i--)
8056  av_encryption_info_free(encryption_index->encrypted_samples[i - 1]);
8057  av_freep(&encryption_index->encrypted_samples);
8058  return ret;
8059  }
8060  }
8061  encryption_index->nb_encrypted_samples = sample_count;
8062 
8063  return 0;
8064 }
8065 
8067 {
8068  AVEncryptionInfo **sample, **encrypted_samples;
8069  int64_t prev_pos;
8070  size_t sample_count, sample_info_size, i;
8071  int ret = 0;
8072  unsigned int alloc_size = 0;
8073 
8074  if (encryption_index->nb_encrypted_samples)
8075  return 0;
8076  sample_count = encryption_index->auxiliary_info_sample_count;
8077  if (encryption_index->auxiliary_offsets_count != 1) {
8078  av_log(c->fc, AV_LOG_ERROR, "Multiple auxiliary info chunks are not supported\n");
8079  return AVERROR_PATCHWELCOME;
8080  }
8081  if (sample_count >= INT_MAX / sizeof(*encrypted_samples))
8082  return AVERROR(ENOMEM);
8083 
8084  prev_pos = avio_tell(pb);
8085  if (!(pb->seekable & AVIO_SEEKABLE_NORMAL) ||
8086  avio_seek(pb, encryption_index->auxiliary_offsets[0], SEEK_SET) != encryption_index->auxiliary_offsets[0]) {
8087  av_log(c->fc, AV_LOG_INFO, "Failed to seek for auxiliary info, will only parse senc atoms for encryption info\n");
8088  goto finish;
8089  }
8090 
8091  for (i = 0; i < sample_count && !pb->eof_reached; i++) {
8092  unsigned int min_samples = FFMIN(FFMAX(i + 1, 1024 * 1024), sample_count);
8093  encrypted_samples = av_fast_realloc(encryption_index->encrypted_samples, &alloc_size,
8094  min_samples * sizeof(*encrypted_samples));
8095  if (!encrypted_samples) {
8096  ret = AVERROR(ENOMEM);
8097  goto finish;
8098  }
8099  encryption_index->encrypted_samples = encrypted_samples;
8100 
8101  sample = &encryption_index->encrypted_samples[i];
8102  sample_info_size = encryption_index->auxiliary_info_default_size
8103  ? encryption_index->auxiliary_info_default_size
8104  : encryption_index->auxiliary_info_sizes[i];
8105 
8106  ret = mov_read_sample_encryption_info(c, pb, sc, sample, sample_info_size > sc->cenc.per_sample_iv_size);
8107  if (ret < 0)
8108  goto finish;
8109  }
8110  if (pb->eof_reached) {
8111  av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading auxiliary info\n");
8113  } else {
8114  encryption_index->nb_encrypted_samples = sample_count;
8115  }
8116 
8117 finish:
8118  avio_seek(pb, prev_pos, SEEK_SET);
8119  if (ret < 0) {
8120  for (; i > 0; i--) {
8121  av_encryption_info_free(encryption_index->encrypted_samples[i - 1]);
8122  }
8123  av_freep(&encryption_index->encrypted_samples);
8124  }
8125  return ret;
8126 }
8127 
8129 {
8130  MOVEncryptionIndex *encryption_index;
8131  MOVStreamContext *sc;
8132  int ret;
8133  unsigned int sample_count, aux_info_type, aux_info_param;
8134 
8135  ret = get_current_encryption_info(c, &encryption_index, &sc);
8136  if (ret != 1)
8137  return ret;
8138 
8139  if (encryption_index->nb_encrypted_samples) {
8140  // This can happen if we have both saio/saiz and senc atoms.
8141  av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in saiz\n");
8142  return 0;
8143  }
8144 
8145  if (encryption_index->auxiliary_info_sample_count) {
8146  av_log(c->fc, AV_LOG_ERROR, "Duplicate saiz atom\n");
8147  return AVERROR_INVALIDDATA;
8148  }
8149 
8150  avio_r8(pb); /* version */
8151  if (avio_rb24(pb) & 0x01) { /* flags */
8152  aux_info_type = avio_rb32(pb);
8153  aux_info_param = avio_rb32(pb);
8154  if (sc->cenc.default_encrypted_sample) {
8155  if (aux_info_type != sc->cenc.default_encrypted_sample->scheme) {
8156  av_log(c->fc, AV_LOG_DEBUG, "Ignoring saiz box with non-zero aux_info_type\n");
8157  return 0;
8158  }
8159  if (aux_info_param != 0) {
8160  av_log(c->fc, AV_LOG_DEBUG, "Ignoring saiz box with non-zero aux_info_type_parameter\n");
8161  return 0;
8162  }
8163  } else {
8164  // Didn't see 'schm' or 'tenc', so this isn't encrypted.
8165  if ((aux_info_type == MKBETAG('c','e','n','c') ||
8166  aux_info_type == MKBETAG('c','e','n','s') ||
8167  aux_info_type == MKBETAG('c','b','c','1') ||
8168  aux_info_type == MKBETAG('c','b','c','s')) &&
8169  aux_info_param == 0) {
8170  av_log(c->fc, AV_LOG_ERROR, "Saw encrypted saiz without schm/tenc\n");
8171  return AVERROR_INVALIDDATA;
8172  } else {
8173  return 0;
8174  }
8175  }
8176  } else if (!sc->cenc.default_encrypted_sample) {
8177  // Didn't see 'schm' or 'tenc', so this isn't encrypted.
8178  return 0;
8179  }
8180 
8181  encryption_index->auxiliary_info_default_size = avio_r8(pb);
8182  sample_count = avio_rb32(pb);
8183 
8184  if (encryption_index->auxiliary_info_default_size == 0) {
8185  if (sample_count == 0)
8186  return AVERROR_INVALIDDATA;
8187 
8188  encryption_index->auxiliary_info_sizes = av_malloc(sample_count);
8189  if (!encryption_index->auxiliary_info_sizes)
8190  return AVERROR(ENOMEM);
8191 
8192  ret = avio_read(pb, encryption_index->auxiliary_info_sizes, sample_count);
8193  if (ret != sample_count) {
8194  av_freep(&encryption_index->auxiliary_info_sizes);
8195 
8196  if (ret >= 0)
8198  av_log(c->fc, AV_LOG_ERROR, "Failed to read the auxiliary info, %s\n",
8199  av_err2str(ret));
8200  return ret;
8201  }
8202  }
8203  encryption_index->auxiliary_info_sample_count = sample_count;
8204 
8205  if (encryption_index->auxiliary_offsets_count) {
8206  return mov_parse_auxiliary_info(c, sc, pb, encryption_index);
8207  }
8208 
8209  return 0;
8210 }
8211 
8213 {
8214  uint64_t *auxiliary_offsets;
8215  MOVEncryptionIndex *encryption_index;
8216  MOVStreamContext *sc;
8217  int i, ret;
8218  unsigned int version, entry_count, aux_info_type, aux_info_param;
8219  unsigned int alloc_size = 0;
8220 
8221  ret = get_current_encryption_info(c, &encryption_index, &sc);
8222  if (ret != 1)
8223  return ret;
8224 
8225  if (encryption_index->nb_encrypted_samples) {
8226  // This can happen if we have both saio/saiz and senc atoms.
8227  av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in saio\n");
8228  return 0;
8229  }
8230 
8231  if (encryption_index->auxiliary_offsets_count) {
8232  av_log(c->fc, AV_LOG_ERROR, "Duplicate saio atom\n");
8233  return AVERROR_INVALIDDATA;
8234  }
8235 
8236  version = avio_r8(pb); /* version */
8237  if (avio_rb24(pb) & 0x01) { /* flags */
8238  aux_info_type = avio_rb32(pb);
8239  aux_info_param = avio_rb32(pb);
8240  if (sc->cenc.default_encrypted_sample) {
8241  if (aux_info_type != sc->cenc.default_encrypted_sample->scheme) {
8242  av_log(c->fc, AV_LOG_DEBUG, "Ignoring saio box with non-zero aux_info_type\n");
8243  return 0;
8244  }
8245  if (aux_info_param != 0) {
8246  av_log(c->fc, AV_LOG_DEBUG, "Ignoring saio box with non-zero aux_info_type_parameter\n");
8247  return 0;
8248  }
8249  } else {
8250  // Didn't see 'schm' or 'tenc', so this isn't encrypted.
8251  if ((aux_info_type == MKBETAG('c','e','n','c') ||
8252  aux_info_type == MKBETAG('c','e','n','s') ||
8253  aux_info_type == MKBETAG('c','b','c','1') ||
8254  aux_info_type == MKBETAG('c','b','c','s')) &&
8255  aux_info_param == 0) {
8256  av_log(c->fc, AV_LOG_ERROR, "Saw encrypted saio without schm/tenc\n");
8257  return AVERROR_INVALIDDATA;
8258  } else {
8259  return 0;
8260  }
8261  }
8262  } else if (!sc->cenc.default_encrypted_sample) {
8263  // Didn't see 'schm' or 'tenc', so this isn't encrypted.
8264  return 0;
8265  }
8266 
8267  entry_count = avio_rb32(pb);
8268  if (entry_count >= INT_MAX / sizeof(*auxiliary_offsets))
8269  return AVERROR(ENOMEM);
8270 
8271  for (i = 0; i < entry_count && !pb->eof_reached; i++) {
8272  unsigned int min_offsets = FFMIN(FFMAX(i + 1, 1024), entry_count);
8273  auxiliary_offsets = av_fast_realloc(
8274  encryption_index->auxiliary_offsets, &alloc_size,
8275  min_offsets * sizeof(*auxiliary_offsets));
8276  if (!auxiliary_offsets) {
8277  av_freep(&encryption_index->auxiliary_offsets);
8278  return AVERROR(ENOMEM);
8279  }
8280  encryption_index->auxiliary_offsets = auxiliary_offsets;
8281 
8282  if (version == 0) {
8283  encryption_index->auxiliary_offsets[i] = avio_rb32(pb);
8284  } else {
8285  encryption_index->auxiliary_offsets[i] = avio_rb64(pb);
8286  }
8287  if (c->frag_index.current >= 0) {
8288  encryption_index->auxiliary_offsets[i] += c->fragment.base_data_offset;
8289  }
8290  }
8291 
8292  if (pb->eof_reached) {
8293  av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading saio\n");
8294  av_freep(&encryption_index->auxiliary_offsets);
8295  return AVERROR_INVALIDDATA;
8296  }
8297 
8298  encryption_index->auxiliary_offsets_count = entry_count;
8299 
8300  if (encryption_index->auxiliary_info_sample_count) {
8301  return mov_parse_auxiliary_info(c, sc, pb, encryption_index);
8302  }
8303 
8304  return 0;
8305 }
8306 
8308 {
8309  AVEncryptionInitInfo *info, *old_init_info;
8310  uint8_t **key_ids;
8311  AVStream *st;
8312  const AVPacketSideData *old_side_data;
8313  uint8_t *side_data, *extra_data;
8314  size_t side_data_size;
8315  int ret = 0;
8316  unsigned int version, kid_count, extra_data_size, alloc_size = 0;
8317 
8318  if (c->fc->nb_streams < 1)
8319  return 0;
8320  st = c->fc->streams[c->fc->nb_streams-1];
8321 
8322  version = avio_r8(pb); /* version */
8323  avio_rb24(pb); /* flags */
8324 
8325  info = av_encryption_init_info_alloc(/* system_id_size */ 16, /* num_key_ids */ 0,
8326  /* key_id_size */ 16, /* data_size */ 0);
8327  if (!info)
8328  return AVERROR(ENOMEM);
8329 
8330  if ((ret = ffio_read_size(pb, info->system_id, 16)) < 0) {
8331  av_log(c->fc, AV_LOG_ERROR, "Failed to read the system id\n");
8332  goto finish;
8333  }
8334 
8335  if (version > 0) {
8336  kid_count = avio_rb32(pb);
8337  if (kid_count >= INT_MAX / sizeof(*key_ids)) {
8338  ret = AVERROR(ENOMEM);
8339  goto finish;
8340  }
8341 
8342  for (unsigned int i = 0; i < kid_count && !pb->eof_reached; i++) {
8343  unsigned int min_kid_count = FFMIN(FFMAX(i + 1, 1024), kid_count);
8344  key_ids = av_fast_realloc(info->key_ids, &alloc_size,
8345  min_kid_count * sizeof(*key_ids));
8346  if (!key_ids) {
8347  ret = AVERROR(ENOMEM);
8348  goto finish;
8349  }
8350  info->key_ids = key_ids;
8351 
8352  info->key_ids[i] = av_mallocz(16);
8353  if (!info->key_ids[i]) {
8354  ret = AVERROR(ENOMEM);
8355  goto finish;
8356  }
8357  info->num_key_ids = i + 1;
8358 
8359  if ((ret = ffio_read_size(pb, info->key_ids[i], 16)) < 0) {
8360  av_log(c->fc, AV_LOG_ERROR, "Failed to read the key id\n");
8361  goto finish;
8362  }
8363  }
8364 
8365  if (pb->eof_reached) {
8366  av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading pssh\n");
8368  goto finish;
8369  }
8370  }
8371 
8372  extra_data_size = avio_rb32(pb);
8373  extra_data = av_malloc(extra_data_size);
8374  if (!extra_data) {
8375  ret = AVERROR(ENOMEM);
8376  goto finish;
8377  }
8378  ret = avio_read(pb, extra_data, extra_data_size);
8379  if (ret != extra_data_size) {
8380  av_free(extra_data);
8381 
8382  if (ret >= 0)
8384  goto finish;
8385  }
8386 
8387  av_freep(&info->data); // malloc(0) may still allocate something.
8388  info->data = extra_data;
8389  info->data_size = extra_data_size;
8390 
8391  // If there is existing initialization data, append to the list.
8394  if (old_side_data) {
8395  old_init_info = av_encryption_init_info_get_side_data(old_side_data->data, old_side_data->size);
8396  if (old_init_info) {
8397  // Append to the end of the list.
8398  for (AVEncryptionInitInfo *cur = old_init_info;; cur = cur->next) {
8399  if (!cur->next) {
8400  cur->next = info;
8401  break;
8402  }
8403  }
8404  info = old_init_info;
8405  } else {
8406  // Assume existing side-data will be valid, so the only error we could get is OOM.
8407  ret = AVERROR(ENOMEM);
8408  goto finish;
8409  }
8410  }
8411 
8412  side_data = av_encryption_init_info_add_side_data(info, &side_data_size);
8413  if (!side_data) {
8414  ret = AVERROR(ENOMEM);
8415  goto finish;
8416  }
8420  side_data, side_data_size, 0))
8421  av_free(side_data);
8422 
8423 finish:
8425  return ret;
8426 }
8427 
8429 {
8430  AVStream *st;
8431  MOVStreamContext *sc;
8432 
8433  if (c->fc->nb_streams < 1)
8434  return 0;
8435  st = c->fc->streams[c->fc->nb_streams-1];
8436  sc = st->priv_data;
8437 
8438  if (sc->pseudo_stream_id != 0) {
8439  av_log(c->fc, AV_LOG_ERROR, "schm boxes are only supported in first sample descriptor\n");
8440  return AVERROR_PATCHWELCOME;
8441  }
8442 
8443  if (atom.size < 8)
8444  return AVERROR_INVALIDDATA;
8445 
8446  avio_rb32(pb); /* version and flags */
8447 
8448  if (!sc->cenc.default_encrypted_sample) {
8450  if (!sc->cenc.default_encrypted_sample) {
8451  return AVERROR(ENOMEM);
8452  }
8453  }
8454 
8456  return 0;
8457 }
8458 
8460 {
8461  AVStream *st;
8462  MOVStreamContext *sc;
8463  unsigned int version, pattern, is_protected, iv_size;
8464 
8465  if (c->fc->nb_streams < 1)
8466  return 0;
8467  st = c->fc->streams[c->fc->nb_streams-1];
8468  sc = st->priv_data;
8469 
8470  if (sc->pseudo_stream_id != 0) {
8471  av_log(c->fc, AV_LOG_ERROR, "tenc atom are only supported in first sample descriptor\n");
8472  return AVERROR_PATCHWELCOME;
8473  }
8474 
8475  if (!sc->cenc.default_encrypted_sample) {
8477  if (!sc->cenc.default_encrypted_sample) {
8478  return AVERROR(ENOMEM);
8479  }
8480  }
8481 
8482  if (atom.size < 20)
8483  return AVERROR_INVALIDDATA;
8484 
8485  version = avio_r8(pb); /* version */
8486  avio_rb24(pb); /* flags */
8487 
8488  avio_r8(pb); /* reserved */
8489  pattern = avio_r8(pb);
8490 
8491  if (version > 0) {
8492  sc->cenc.default_encrypted_sample->crypt_byte_block = pattern >> 4;
8493  sc->cenc.default_encrypted_sample->skip_byte_block = pattern & 0xf;
8494  }
8495 
8496  is_protected = avio_r8(pb);
8497  if (is_protected && !sc->cenc.encryption_index) {
8498  // The whole stream should be by-default encrypted.
8500  if (!sc->cenc.encryption_index)
8501  return AVERROR(ENOMEM);
8502  }
8503  sc->cenc.per_sample_iv_size = avio_r8(pb);
8504  if (sc->cenc.per_sample_iv_size != 0 && sc->cenc.per_sample_iv_size != 8 &&
8505  sc->cenc.per_sample_iv_size != 16) {
8506  av_log(c->fc, AV_LOG_ERROR, "invalid per-sample IV size value\n");
8507  return AVERROR_INVALIDDATA;
8508  }
8509  if (avio_read(pb, sc->cenc.default_encrypted_sample->key_id, 16) != 16) {
8510  av_log(c->fc, AV_LOG_ERROR, "failed to read the default key ID\n");
8511  return AVERROR_INVALIDDATA;
8512  }
8513 
8514  if (is_protected && !sc->cenc.per_sample_iv_size) {
8515  iv_size = avio_r8(pb);
8516  if (iv_size != 8 && iv_size != 16) {
8517  av_log(c->fc, AV_LOG_ERROR, "invalid default_constant_IV_size in tenc atom\n");
8518  return AVERROR_INVALIDDATA;
8519  }
8520 
8521  if (avio_read(pb, sc->cenc.default_encrypted_sample->iv, iv_size) != iv_size) {
8522  av_log(c->fc, AV_LOG_ERROR, "failed to read the default IV\n");
8523  return AVERROR_INVALIDDATA;
8524  }
8525  }
8526 
8527  return 0;
8528 }
8529 
8531 {
8532  AVStream *st;
8533  int last, type, size, ret;
8534  uint8_t buf[4];
8535 
8536  if (c->fc->nb_streams < 1)
8537  return 0;
8538  st = c->fc->streams[c->fc->nb_streams-1];
8539 
8540  if ((uint64_t)atom.size > (1<<30) || atom.size < 42)
8541  return AVERROR_INVALIDDATA;
8542 
8543  /* Check FlacSpecificBox version. */
8544  if (avio_r8(pb) != 0)
8545  return AVERROR_INVALIDDATA;
8546 
8547  avio_rb24(pb); /* Flags */
8548 
8549  if (avio_read(pb, buf, sizeof(buf)) != sizeof(buf)) {
8550  av_log(c->fc, AV_LOG_ERROR, "failed to read FLAC metadata block header\n");
8551  return pb->error < 0 ? pb->error : AVERROR_INVALIDDATA;
8552  }
8553  flac_parse_block_header(buf, &last, &type, &size);
8554 
8556  av_log(c->fc, AV_LOG_ERROR, "STREAMINFO must be first FLACMetadataBlock\n");
8557  return AVERROR_INVALIDDATA;
8558  }
8559 
8560  ret = ff_get_extradata(c->fc, st->codecpar, pb, size);
8561  if (ret < 0)
8562  return ret;
8563 
8564  if (!last)
8565  av_log(c->fc, AV_LOG_WARNING, "non-STREAMINFO FLACMetadataBlock(s) ignored\n");
8566 
8567  return 0;
8568 }
8569 
8570 static int get_key_from_kid(uint8_t* out, int len, MOVContext *c, AVEncryptionInfo *sample) {
8571  AVDictionaryEntry *key_entry_hex;
8572  char kid_hex[16*2+1];
8573 
8574  if (c->decryption_default_key && c->decryption_default_key_len != len) {
8575  av_log(c->fc, AV_LOG_ERROR, "invalid default decryption key length: got %d, expected %d\n", c->decryption_default_key_len, len);
8576  return -1;
8577  }
8578 
8579  if (!c->decryption_keys) {
8580  av_assert0(c->decryption_default_key);
8581  memcpy(out, c->decryption_default_key, len);
8582  return 0;
8583  }
8584 
8585  if (sample->key_id_size != 16) {
8586  av_log(c->fc, AV_LOG_ERROR, "invalid key ID size: got %u, expected 16\n", sample->key_id_size);
8587  return -1;
8588  }
8589 
8590  ff_data_to_hex(kid_hex, sample->key_id, 16, 1);
8591  key_entry_hex = av_dict_get(c->decryption_keys, kid_hex, NULL, AV_DICT_DONT_STRDUP_KEY|AV_DICT_DONT_STRDUP_VAL);
8592  if (!key_entry_hex) {
8593  if (!c->decryption_default_key) {
8594  av_log(c->fc, AV_LOG_ERROR, "unable to find KID %s\n", kid_hex);
8595  return -1;
8596  }
8597  memcpy(out, c->decryption_default_key, len);
8598  return 0;
8599  }
8600  if (strlen(key_entry_hex->value) != len*2) {
8601  return -1;
8602  }
8603  ff_hex_to_data(out, key_entry_hex->value);
8604  return 0;
8605 }
8606 
8608 {
8609  int i, ret;
8610  int bytes_of_protected_data;
8611  uint8_t decryption_key[AES_CTR_KEY_SIZE];
8612 
8613  if (!sc->cenc.aes_ctr) {
8614  ret = get_key_from_kid(decryption_key, sizeof(decryption_key), c, sample);
8615  if (ret < 0) {
8616  return ret;
8617  }
8618 
8619  /* initialize the cipher */
8620  sc->cenc.aes_ctr = av_aes_ctr_alloc();
8621  if (!sc->cenc.aes_ctr) {
8622  return AVERROR(ENOMEM);
8623  }
8624 
8625  ret = av_aes_ctr_init(sc->cenc.aes_ctr, decryption_key);
8626  if (ret < 0) {
8627  return ret;
8628  }
8629  }
8630 
8632 
8633  if (!sample->subsample_count) {
8634  /* decrypt the whole packet */
8636  return 0;
8637  }
8638 
8639  for (i = 0; i < sample->subsample_count; i++) {
8640  if (sample->subsamples[i].bytes_of_clear_data + (int64_t)sample->subsamples[i].bytes_of_protected_data > size) {
8641  av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n");
8642  return AVERROR_INVALIDDATA;
8643  }
8644 
8645  /* skip the clear bytes */
8646  input += sample->subsamples[i].bytes_of_clear_data;
8647  size -= sample->subsamples[i].bytes_of_clear_data;
8648 
8649  /* decrypt the encrypted bytes */
8650 
8651  bytes_of_protected_data = sample->subsamples[i].bytes_of_protected_data;
8652  av_aes_ctr_crypt(sc->cenc.aes_ctr, input, input, bytes_of_protected_data);
8653 
8654  input += bytes_of_protected_data;
8655  size -= bytes_of_protected_data;
8656  }
8657 
8658  if (size > 0) {
8659  av_log(c->fc, AV_LOG_ERROR, "leftover packet bytes after subsample processing\n");
8660  return AVERROR_INVALIDDATA;
8661  }
8662 
8663  return 0;
8664 }
8665 
8667 {
8668  int i, ret;
8669  int num_of_encrypted_blocks;
8670  uint8_t iv[16];
8671  uint8_t decryption_key[16];
8672 
8673  if (!sc->cenc.aes_ctx) {
8674  ret = get_key_from_kid(decryption_key, sizeof(decryption_key), c, sample);
8675  if (ret < 0) {
8676  return ret;
8677  }
8678 
8679  /* initialize the cipher */
8680  sc->cenc.aes_ctx = av_aes_alloc();
8681  if (!sc->cenc.aes_ctx) {
8682  return AVERROR(ENOMEM);
8683  }
8684 
8685  ret = av_aes_init(sc->cenc.aes_ctx, decryption_key, 16 * 8, 1);
8686  if (ret < 0) {
8687  return ret;
8688  }
8689  }
8690 
8691  memcpy(iv, sample->iv, 16);
8692 
8693  /* whole-block full sample encryption */
8694  if (!sample->subsample_count) {
8695  /* decrypt the whole packet */
8696  av_aes_crypt(sc->cenc.aes_ctx, input, input, size/16, iv, 1);
8697  return 0;
8698  }
8699 
8700  for (i = 0; i < sample->subsample_count; i++) {
8701  if (sample->subsamples[i].bytes_of_clear_data + (int64_t)sample->subsamples[i].bytes_of_protected_data > size) {
8702  av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n");
8703  return AVERROR_INVALIDDATA;
8704  }
8705 
8706  if (sample->subsamples[i].bytes_of_protected_data % 16) {
8707  av_log(c->fc, AV_LOG_ERROR, "subsample BytesOfProtectedData is not a multiple of 16\n");
8708  return AVERROR_INVALIDDATA;
8709  }
8710 
8711  /* skip the clear bytes */
8712  input += sample->subsamples[i].bytes_of_clear_data;
8713  size -= sample->subsamples[i].bytes_of_clear_data;
8714 
8715  /* decrypt the encrypted bytes */
8716  num_of_encrypted_blocks = sample->subsamples[i].bytes_of_protected_data/16;
8717  if (num_of_encrypted_blocks > 0) {
8718  av_aes_crypt(sc->cenc.aes_ctx, input, input, num_of_encrypted_blocks, iv, 1);
8719  }
8720  input += sample->subsamples[i].bytes_of_protected_data;
8721  size -= sample->subsamples[i].bytes_of_protected_data;
8722  }
8723 
8724  if (size > 0) {
8725  av_log(c->fc, AV_LOG_ERROR, "leftover packet bytes after subsample processing\n");
8726  return AVERROR_INVALIDDATA;
8727  }
8728 
8729  return 0;
8730 }
8731 
8733 {
8734  int i, ret, rem_bytes;
8735  uint8_t *data;
8736  uint8_t decryption_key[AES_CTR_KEY_SIZE];
8737 
8738  if (!sc->cenc.aes_ctr) {
8739  ret = get_key_from_kid(decryption_key, sizeof(decryption_key), c, sample);
8740  if (ret < 0) {
8741  return ret;
8742  }
8743 
8744  /* initialize the cipher */
8745  sc->cenc.aes_ctr = av_aes_ctr_alloc();
8746  if (!sc->cenc.aes_ctr) {
8747  return AVERROR(ENOMEM);
8748  }
8749 
8750  ret = av_aes_ctr_init(sc->cenc.aes_ctr, decryption_key);
8751  if (ret < 0) {
8752  return ret;
8753  }
8754  }
8755 
8757 
8758  /* whole-block full sample encryption */
8759  if (!sample->subsample_count) {
8760  /* decrypt the whole packet */
8762  return 0;
8763  } else if (!sample->crypt_byte_block && !sample->skip_byte_block) {
8764  av_log(c->fc, AV_LOG_ERROR, "pattern encryption is not present in 'cens' scheme\n");
8765  return AVERROR_INVALIDDATA;
8766  }
8767 
8768  for (i = 0; i < sample->subsample_count; i++) {
8769  if (sample->subsamples[i].bytes_of_clear_data + (int64_t)sample->subsamples[i].bytes_of_protected_data > size) {
8770  av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n");
8771  return AVERROR_INVALIDDATA;
8772  }
8773 
8774  /* skip the clear bytes */
8775  input += sample->subsamples[i].bytes_of_clear_data;
8776  size -= sample->subsamples[i].bytes_of_clear_data;
8777 
8778  /* decrypt the encrypted bytes */
8779  data = input;
8780  rem_bytes = sample->subsamples[i].bytes_of_protected_data;
8781  while (rem_bytes > 0) {
8782  if (rem_bytes < 16*sample->crypt_byte_block) {
8783  break;
8784  }
8785  av_aes_ctr_crypt(sc->cenc.aes_ctr, data, data, 16*sample->crypt_byte_block);
8786  data += 16*sample->crypt_byte_block;
8787  rem_bytes -= 16*sample->crypt_byte_block;
8788  data += FFMIN(16*sample->skip_byte_block, rem_bytes);
8789  rem_bytes -= FFMIN(16*sample->skip_byte_block, rem_bytes);
8790  }
8791  input += sample->subsamples[i].bytes_of_protected_data;
8792  size -= sample->subsamples[i].bytes_of_protected_data;
8793  }
8794 
8795  if (size > 0) {
8796  av_log(c->fc, AV_LOG_ERROR, "leftover packet bytes after subsample processing\n");
8797  return AVERROR_INVALIDDATA;
8798  }
8799 
8800  return 0;
8801 }
8802 
8804 {
8805  int i, ret, rem_bytes;
8806  uint8_t iv[16];
8807  uint8_t *data;
8808  uint8_t decryption_key[16];
8809 
8810  if (!sc->cenc.aes_ctx) {
8811  ret = get_key_from_kid(decryption_key, sizeof(decryption_key), c, sample);
8812  if (ret < 0) {
8813  return ret;
8814  }
8815 
8816  /* initialize the cipher */
8817  sc->cenc.aes_ctx = av_aes_alloc();
8818  if (!sc->cenc.aes_ctx) {
8819  return AVERROR(ENOMEM);
8820  }
8821 
8822  ret = av_aes_init(sc->cenc.aes_ctx, decryption_key, 16 * 8, 1);
8823  if (ret < 0) {
8824  return ret;
8825  }
8826  }
8827 
8828  /* whole-block full sample encryption */
8829  if (!sample->subsample_count) {
8830  /* decrypt the whole packet */
8831  memcpy(iv, sample->iv, 16);
8832  av_aes_crypt(sc->cenc.aes_ctx, input, input, size/16, iv, 1);
8833  return 0;
8834  } else if (!sample->crypt_byte_block && !sample->skip_byte_block) {
8835  av_log(c->fc, AV_LOG_ERROR, "pattern encryption is not present in 'cbcs' scheme\n");
8836  return AVERROR_INVALIDDATA;
8837  }
8838 
8839  for (i = 0; i < sample->subsample_count; i++) {
8840  if (sample->subsamples[i].bytes_of_clear_data + (int64_t)sample->subsamples[i].bytes_of_protected_data > size) {
8841  av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n");
8842  return AVERROR_INVALIDDATA;
8843  }
8844 
8845  /* skip the clear bytes */
8846  input += sample->subsamples[i].bytes_of_clear_data;
8847  size -= sample->subsamples[i].bytes_of_clear_data;
8848 
8849  /* decrypt the encrypted bytes */
8850  memcpy(iv, sample->iv, 16);
8851  data = input;
8852  rem_bytes = sample->subsamples[i].bytes_of_protected_data;
8853  while (rem_bytes > 0) {
8854  if (rem_bytes < 16*sample->crypt_byte_block) {
8855  break;
8856  }
8857  av_aes_crypt(sc->cenc.aes_ctx, data, data, sample->crypt_byte_block, iv, 1);
8858  data += 16*sample->crypt_byte_block;
8859  rem_bytes -= 16*sample->crypt_byte_block;
8860  data += FFMIN(16*sample->skip_byte_block, rem_bytes);
8861  rem_bytes -= FFMIN(16*sample->skip_byte_block, rem_bytes);
8862  }
8863  input += sample->subsamples[i].bytes_of_protected_data;
8864  size -= sample->subsamples[i].bytes_of_protected_data;
8865  }
8866 
8867  if (size > 0) {
8868  av_log(c->fc, AV_LOG_ERROR, "leftover packet bytes after subsample processing\n");
8869  return AVERROR_INVALIDDATA;
8870  }
8871 
8872  return 0;
8873 }
8874 
8876 {
8877  if (sample->scheme == MKBETAG('c','e','n','c') && !sample->crypt_byte_block && !sample->skip_byte_block) {
8878  return cenc_scheme_decrypt(c, sc, sample, input, size);
8879  } else if (sample->scheme == MKBETAG('c','b','c','1') && !sample->crypt_byte_block && !sample->skip_byte_block) {
8880  return cbc1_scheme_decrypt(c, sc, sample, input, size);
8881  } else if (sample->scheme == MKBETAG('c','e','n','s')) {
8882  return cens_scheme_decrypt(c, sc, sample, input, size);
8883  } else if (sample->scheme == MKBETAG('c','b','c','s')) {
8884  return cbcs_scheme_decrypt(c, sc, sample, input, size);
8885  } else {
8886  av_log(c->fc, AV_LOG_ERROR, "invalid encryption scheme\n");
8887  return AVERROR_INVALIDDATA;
8888  }
8889 }
8890 
8892 {
8893  int current = frag_index->current;
8894 
8895  if (!frag_index->nb_items)
8896  return NULL;
8897 
8898  // Check frag_index->current is the right one for pkt. It can out of sync.
8899  if (current >= 0 && current < frag_index->nb_items) {
8900  if (frag_index->item[current].moof_offset < pkt->pos &&
8901  (current + 1 == frag_index->nb_items ||
8902  frag_index->item[current + 1].moof_offset > pkt->pos))
8903  return get_frag_stream_info(frag_index, current, id);
8904  }
8905 
8906 
8907  for (int i = 0; i < frag_index->nb_items; i++) {
8908  if (frag_index->item[i].moof_offset > pkt->pos)
8909  break;
8910  current = i;
8911  }
8912  frag_index->current = current;
8913  return get_frag_stream_info(frag_index, current, id);
8914 }
8915 
8916 static int cenc_filter(MOVContext *mov, AVStream* st, MOVStreamContext *sc, AVPacket *pkt, int current_index)
8917 {
8918  MOVFragmentStreamInfo *frag_stream_info;
8919  MOVEncryptionIndex *encryption_index;
8920  AVEncryptionInfo *encrypted_sample;
8921  int encrypted_index, ret;
8922 
8923  frag_stream_info = get_frag_stream_info_from_pkt(&mov->frag_index, pkt, sc->id);
8924  encrypted_index = current_index;
8925  encryption_index = NULL;
8926  if (frag_stream_info) {
8927  // Note this only supports encryption info in the first sample descriptor.
8928  if (frag_stream_info->stsd_id == 1) {
8929  if (frag_stream_info->encryption_index) {
8930  encrypted_index = current_index - frag_stream_info->index_base;
8931  encryption_index = frag_stream_info->encryption_index;
8932  } else {
8933  encryption_index = sc->cenc.encryption_index;
8934  }
8935  }
8936  } else {
8937  encryption_index = sc->cenc.encryption_index;
8938  }
8939 
8940  if (encryption_index) {
8941  if (encryption_index->auxiliary_info_sample_count &&
8942  !encryption_index->nb_encrypted_samples) {
8943  av_log(mov->fc, AV_LOG_ERROR, "saiz atom found without saio\n");
8944  return AVERROR_INVALIDDATA;
8945  }
8946  if (encryption_index->auxiliary_offsets_count &&
8947  !encryption_index->nb_encrypted_samples) {
8948  av_log(mov->fc, AV_LOG_ERROR, "saio atom found without saiz\n");
8949  return AVERROR_INVALIDDATA;
8950  }
8951 
8952  encrypted_sample = NULL;
8953  if (!encryption_index->nb_encrypted_samples) {
8954  // Full-sample encryption with default settings.
8955  encrypted_sample = sc->cenc.default_encrypted_sample;
8956  } else if (encrypted_index >= 0 && encrypted_index < encryption_index->nb_encrypted_samples) {
8957  // Per-sample setting override.
8958  encrypted_sample = encryption_index->encrypted_samples[encrypted_index];
8959  if (!encrypted_sample) {
8960  encrypted_sample = sc->cenc.default_encrypted_sample;
8961  }
8962  }
8963 
8964  if (!encrypted_sample) {
8965  av_log(mov->fc, AV_LOG_ERROR, "Incorrect number of samples in encryption info\n");
8966  return AVERROR_INVALIDDATA;
8967  }
8968 
8969  if (mov->decryption_keys || mov->decryption_default_key) {
8970  return cenc_decrypt(mov, sc, encrypted_sample, pkt->data, pkt->size);
8971  } else {
8972  size_t size;
8973  uint8_t *side_data = av_encryption_info_add_side_data(encrypted_sample, &size);
8974  if (!side_data)
8975  return AVERROR(ENOMEM);
8977  if (ret < 0)
8978  av_free(side_data);
8979  return ret;
8980  }
8981  }
8982 
8983  return 0;
8984 }
8985 
8987 {
8988  const int OPUS_SEEK_PREROLL_MS = 80;
8989  int ret;
8990  AVStream *st;
8991  size_t size;
8992  uint16_t pre_skip;
8993 
8994  if (c->fc->nb_streams < 1)
8995  return 0;
8996  st = c->fc->streams[c->fc->nb_streams-1];
8997 
8998  if ((uint64_t)atom.size > (1<<30) || atom.size < 11 || st->codecpar->extradata)
8999  return AVERROR_INVALIDDATA;
9000 
9001  /* Check OpusSpecificBox version. */
9002  if (avio_r8(pb) != 0) {
9003  av_log(c->fc, AV_LOG_ERROR, "unsupported OpusSpecificBox version\n");
9004  return AVERROR_INVALIDDATA;
9005  }
9006 
9007  /* OpusSpecificBox size plus magic for Ogg OpusHead header. */
9008  size = atom.size + 8;
9009 
9010  if ((ret = ff_alloc_extradata(st->codecpar, size)) < 0)
9011  return ret;
9012 
9013  AV_WL32A(st->codecpar->extradata, MKTAG('O','p','u','s'));
9014  AV_WL32A(st->codecpar->extradata + 4, MKTAG('H','e','a','d'));
9015  AV_WB8(st->codecpar->extradata + 8, 1); /* OpusHead version */
9016  if ((ret = ffio_read_size(pb, st->codecpar->extradata + 9, size - 9)) < 0) {
9017  av_freep(&st->codecpar->extradata);
9018  st->codecpar->extradata_size = 0;
9019  return ret;
9020  }
9021 
9022  /* OpusSpecificBox is stored in big-endian, but OpusHead is
9023  little-endian; aside from the preceding magic and version they're
9024  otherwise currently identical. Data after output gain at offset 16
9025  doesn't need to be bytewapped. */
9026  pre_skip = AV_RB16A(st->codecpar->extradata + 10);
9027  AV_WL16A(st->codecpar->extradata + 10, pre_skip);
9028  AV_WL32A(st->codecpar->extradata + 12, AV_RB32A(st->codecpar->extradata + 12));
9029  AV_WL16A(st->codecpar->extradata + 16, AV_RB16A(st->codecpar->extradata + 16));
9030 
9031  st->codecpar->initial_padding = pre_skip;
9033  (AVRational){1, 1000},
9034  (AVRational){1, 48000});
9035 
9036  return 0;
9037 }
9038 
9040 {
9041  AVStream *st;
9042  unsigned format_info;
9043  int channel_assignment, channel_assignment1, channel_assignment2;
9044  int ratebits;
9045  uint64_t chmask;
9046 
9047  if (c->fc->nb_streams < 1)
9048  return 0;
9049  st = c->fc->streams[c->fc->nb_streams-1];
9050 
9051  if (atom.size < 10)
9052  return AVERROR_INVALIDDATA;
9053 
9054  format_info = avio_rb32(pb);
9055 
9056  ratebits = (format_info >> 28) & 0xF;
9057  channel_assignment1 = (format_info >> 15) & 0x1F;
9058  channel_assignment2 = format_info & 0x1FFF;
9059  if (channel_assignment2)
9060  channel_assignment = channel_assignment2;
9061  else
9062  channel_assignment = channel_assignment1;
9063 
9064  st->codecpar->frame_size = 40 << (ratebits & 0x7);
9065  st->codecpar->sample_rate = mlp_samplerate(ratebits);
9066 
9068  chmask = truehd_layout(channel_assignment);
9070 
9071  return 0;
9072 }
9073 
9075 {
9076  AVStream *st;
9077  uint8_t buf[ISOM_DVCC_DVVC_SIZE];
9078  int ret;
9079  int64_t read_size = atom.size;
9080 
9081  if (c->fc->nb_streams < 1)
9082  return 0;
9083  st = c->fc->streams[c->fc->nb_streams-1];
9084 
9085  // At most 24 bytes
9086  read_size = FFMIN(read_size, ISOM_DVCC_DVVC_SIZE);
9087 
9088  if ((ret = ffio_read_size(pb, buf, read_size)) < 0)
9089  return ret;
9090 
9091  return ff_isom_parse_dvcc_dvvc(c->fc, st, buf, read_size);
9092 }
9093 
9095 {
9096  AVStream *st;
9097  AVPacketSideData *sd;
9098  int ret;
9099 
9100  if (c->fc->nb_streams < 1)
9101  return 0;
9102  st = c->fc->streams[c->fc->nb_streams - 1];
9103 
9104  if (atom.size < 23 || atom.size > INT_MAX - AV_INPUT_BUFFER_PADDING_SIZE)
9105  return AVERROR_INVALIDDATA;
9106 
9110  atom.size, 0);
9111  if (!sd)
9112  return AVERROR(ENOMEM);
9113 
9114  ret = ffio_read_size(pb, sd->data, atom.size);
9115  if (ret < 0)
9116  return ret;
9117 
9118  return 0;
9119 }
9120 
9122 {
9123  AVStream *st;
9124  uint8_t *buf;
9125  int ret, old_size, num_arrays;
9126 
9127  if (c->fc->nb_streams < 1)
9128  return 0;
9129  st = c->fc->streams[c->fc->nb_streams-1];
9130 
9131  if (!st->codecpar->extradata_size)
9132  // TODO: handle lhvC when present before hvcC
9133  return 0;
9134 
9135  if (atom.size < 6 || st->codecpar->extradata_size < 23 ||
9136  atom.size > INT_MAX - AV_INPUT_BUFFER_PADDING_SIZE) {
9137  return AVERROR_INVALIDDATA;
9138  }
9139 
9141  if (!buf)
9142  return AVERROR(ENOMEM);
9143  memset(buf + atom.size, 0, AV_INPUT_BUFFER_PADDING_SIZE);
9144 
9145  ret = ffio_read_size(pb, buf, atom.size);
9146  if (ret < 0) {
9147  av_free(buf);
9148  av_log(c->fc, AV_LOG_WARNING, "lhvC atom truncated\n");
9149  return 0;
9150  }
9151 
9152  num_arrays = buf[5];
9153  old_size = st->codecpar->extradata_size;
9154  atom.size -= 8 /* account for mov_realloc_extradata offsetting */
9155  + 6 /* lhvC bytes before the arrays*/;
9156 
9157  ret = mov_realloc_extradata(st->codecpar, atom);
9158  if (ret < 0) {
9159  av_free(buf);
9160  return ret;
9161  }
9162 
9163  st->codecpar->extradata[22] += num_arrays;
9164  memcpy(st->codecpar->extradata + old_size, buf + 6, atom.size + 8);
9165 
9167 
9168  av_free(buf);
9169  return 0;
9170 }
9171 
9173 {
9174  AVFormatContext *ctx = c->fc;
9175  AVStream *st = NULL;
9176  AVBPrint scheme_buf, value_buf;
9177  int64_t scheme_str_len = 0, value_str_len = 0;
9178  int version, flags, ret = AVERROR_BUG;
9179  int64_t size = atom.size;
9180 
9181  if (atom.size < 6)
9182  // 4 bytes for version + flags, 2x 1 byte for null
9183  return AVERROR_INVALIDDATA;
9184 
9185  if (c->fc->nb_streams < 1)
9186  return 0;
9187  st = c->fc->streams[c->fc->nb_streams-1];
9188 
9189  version = avio_r8(pb);
9190  flags = avio_rb24(pb);
9191  size -= 4;
9192 
9193  if (version != 0 || flags != 0) {
9195  "Unsupported 'kind' box with version %d, flags: %x",
9196  version, flags);
9197  return AVERROR_INVALIDDATA;
9198  }
9199 
9200  av_bprint_init(&scheme_buf, 0, AV_BPRINT_SIZE_UNLIMITED);
9201  av_bprint_init(&value_buf, 0, AV_BPRINT_SIZE_UNLIMITED);
9202 
9203  if ((scheme_str_len = ff_read_string_to_bprint_overwrite(pb, &scheme_buf,
9204  size)) < 0) {
9205  ret = scheme_str_len;
9206  goto cleanup;
9207  }
9208 
9209  if (scheme_str_len + 1 >= size) {
9210  // we need to have another string, even if nullptr.
9211  // we check with + 1 since we expect that if size was not hit,
9212  // an additional null was read.
9214  goto cleanup;
9215  }
9216 
9217  size -= scheme_str_len + 1;
9218 
9219  if ((value_str_len = ff_read_string_to_bprint_overwrite(pb, &value_buf,
9220  size)) < 0) {
9221  ret = value_str_len;
9222  goto cleanup;
9223  }
9224 
9225  if (value_str_len == size) {
9226  // in case of no trailing null, box is not valid.
9228  goto cleanup;
9229  }
9230 
9232  "%s stream %d KindBox(scheme: %s, value: %s)\n",
9234  st->index,
9235  scheme_buf.str, value_buf.str);
9236 
9237  for (int i = 0; ff_mov_track_kind_table[i].scheme_uri; i++) {
9239  if (!av_strstart(scheme_buf.str, map.scheme_uri, NULL))
9240  continue;
9241 
9242  for (int j = 0; map.value_maps[j].disposition; j++) {
9243  const struct MP4TrackKindValueMapping value_map = map.value_maps[j];
9244  if (!av_strstart(value_buf.str, value_map.value, NULL))
9245  continue;
9246 
9247  st->disposition |= value_map.disposition;
9248  }
9249  }
9250 
9251  ret = 0;
9252 
9253 cleanup:
9254 
9255  av_bprint_finalize(&scheme_buf, NULL);
9256  av_bprint_finalize(&value_buf, NULL);
9257 
9258  return ret;
9259 }
9260 
9262 {
9263  AVStream *st;
9264  AVChannelLayout ch_layout = { 0 };
9265  int ret, i, version, type;
9266  int ambisonic_order, channel_order, normalization, channel_count;
9267  int ambi_channels, non_diegetic_channels;
9268 
9269  if (c->fc->nb_streams < 1)
9270  return 0;
9271 
9272  st = c->fc->streams[c->fc->nb_streams - 1];
9273 
9274  if (atom.size < 16) {
9275  av_log(c->fc, AV_LOG_ERROR, "SA3D audio box too small\n");
9276  return AVERROR_INVALIDDATA;
9277  }
9278 
9279  version = avio_r8(pb);
9280  if (version) {
9281  av_log(c->fc, AV_LOG_WARNING, "Unsupported SA3D box version %d\n", version);
9282  return 0;
9283  }
9284 
9285  type = avio_r8(pb);
9286  if (type & 0x7f) {
9287  av_log(c->fc, AV_LOG_WARNING,
9288  "Unsupported ambisonic type %d\n", type & 0x7f);
9289  return 0;
9290  }
9291  non_diegetic_channels = (type >> 7) * 2; // head_locked_stereo
9292 
9293  ambisonic_order = avio_rb32(pb);
9294 
9295  channel_order = avio_r8(pb);
9296  if (channel_order) {
9297  av_log(c->fc, AV_LOG_WARNING,
9298  "Unsupported channel_order %d\n", channel_order);
9299  return 0;
9300  }
9301 
9302  normalization = avio_r8(pb);
9303  if (normalization) {
9304  av_log(c->fc, AV_LOG_WARNING,
9305  "Unsupported normalization %d\n", normalization);
9306  return 0;
9307  }
9308 
9309  channel_count = avio_rb32(pb);
9310  if (ambisonic_order < 0 || ambisonic_order > 31 ||
9311  channel_count != ((ambisonic_order + 1LL) * (ambisonic_order + 1LL) +
9312  non_diegetic_channels)) {
9313  av_log(c->fc, AV_LOG_ERROR,
9314  "Invalid number of channels (%d / %d)\n",
9315  channel_count, ambisonic_order);
9316  return 0;
9317  }
9318  ambi_channels = channel_count - non_diegetic_channels;
9319 
9320  ret = av_channel_layout_custom_init(&ch_layout, channel_count);
9321  if (ret < 0)
9322  return 0;
9323 
9324  for (i = 0; i < channel_count; i++) {
9325  unsigned channel = avio_rb32(pb);
9326 
9327  if (channel >= channel_count) {
9328  av_log(c->fc, AV_LOG_ERROR, "Invalid channel index (%d / %d)\n",
9329  channel, ambisonic_order);
9330  av_channel_layout_uninit(&ch_layout);
9331  return 0;
9332  }
9333  if (channel >= ambi_channels)
9334  ch_layout.u.map[i].id = channel - ambi_channels;
9335  else
9336  ch_layout.u.map[i].id = AV_CHAN_AMBISONIC_BASE + channel;
9337  }
9338 
9340  if (ret < 0) {
9341  av_channel_layout_uninit(&ch_layout);
9342  return 0;
9343  }
9344 
9346  st->codecpar->ch_layout = ch_layout;
9347 
9348  return 0;
9349 }
9350 
9352 {
9353  AVStream *st;
9354  int version;
9355 
9356  if (c->fc->nb_streams < 1)
9357  return 0;
9358 
9359  st = c->fc->streams[c->fc->nb_streams - 1];
9360 
9361  if (atom.size < 5) {
9362  av_log(c->fc, AV_LOG_ERROR, "Empty SAND audio box\n");
9363  return AVERROR_INVALIDDATA;
9364  }
9365 
9366  version = avio_r8(pb);
9367  if (version) {
9368  av_log(c->fc, AV_LOG_WARNING, "Unsupported SAND box version %d\n", version);
9369  return 0;
9370  }
9371 
9373 
9374  return 0;
9375 }
9376 
9377 static int rb_size(AVIOContext *pb, int64_t *value, int size)
9378 {
9379  if (size == 0)
9380  *value = 0;
9381  else if (size == 1)
9382  *value = avio_r8(pb);
9383  else if (size == 2)
9384  *value = avio_rb16(pb);
9385  else if (size == 4)
9386  *value = avio_rb32(pb);
9387  else if (size == 8) {
9388  *value = avio_rb64(pb);
9389  if (*value < 0)
9390  return -1;
9391  } else
9392  return -1;
9393  return size;
9394 }
9395 
9397 {
9398  avio_rb32(pb); // version & flags.
9399  c->primary_item_id = avio_rb16(pb);
9400  av_log(c->fc, AV_LOG_TRACE, "pitm: primary_item_id %d\n", c->primary_item_id);
9401  return atom.size;
9402 }
9403 
9405 {
9406  c->idat_offset = avio_tell(pb);
9407  return 0;
9408 }
9409 
9411 {
9412  HEIFItem **heif_item;
9413  int version, offset_size, length_size, base_offset_size, index_size;
9414  int item_count, extent_count;
9415  int64_t base_offset, extent_offset, extent_length;
9416  uint8_t value;
9417 
9418  if (c->found_iloc) {
9419  av_log(c->fc, AV_LOG_INFO, "Duplicate iloc box found\n");
9420  return 0;
9421  }
9422 
9423  version = avio_r8(pb);
9424  avio_rb24(pb); // flags.
9425 
9426  value = avio_r8(pb);
9427  offset_size = (value >> 4) & 0xF;
9428  length_size = value & 0xF;
9429  value = avio_r8(pb);
9430  base_offset_size = (value >> 4) & 0xF;
9431  index_size = !version ? 0 : (value & 0xF);
9432  if (index_size) {
9433  avpriv_report_missing_feature(c->fc, "iloc: index_size != 0");
9434  return AVERROR_PATCHWELCOME;
9435  }
9436  item_count = (version < 2) ? avio_rb16(pb) : avio_rb32(pb);
9437 
9438  heif_item = av_realloc_array(c->heif_item, FFMAX(item_count, c->nb_heif_item), sizeof(*c->heif_item));
9439  if (!heif_item)
9440  return AVERROR(ENOMEM);
9441  c->heif_item = heif_item;
9442  if (item_count > c->nb_heif_item)
9443  memset(&c->heif_item[c->nb_heif_item], 0,
9444  sizeof(*c->heif_item) * (item_count - c->nb_heif_item));
9445  c->nb_heif_item = FFMAX(c->nb_heif_item, item_count);
9446 
9447  av_log(c->fc, AV_LOG_TRACE, "iloc: item_count %d\n", item_count);
9448  for (int i = 0; i < item_count; i++) {
9449  HEIFItem *item = NULL;
9450  int item_id = (version < 2) ? avio_rb16(pb) : avio_rb32(pb);
9451  int offset_type = (version > 0) ? avio_rb16(pb) & 0xf : 0;
9452  int j;
9453 
9454  if (avio_feof(pb))
9455  return AVERROR_INVALIDDATA;
9456  if (offset_type > 1) {
9457  avpriv_report_missing_feature(c->fc, "iloc offset type %d", offset_type);
9458  return AVERROR_PATCHWELCOME;
9459  }
9460 
9461  avio_rb16(pb); // data_reference_index.
9462  if (rb_size(pb, &base_offset, base_offset_size) < 0)
9463  return AVERROR_INVALIDDATA;
9464  extent_count = avio_rb16(pb);
9465  if (extent_count > 1) {
9466  // For still AVIF images, we only support one extent item.
9467  avpriv_report_missing_feature(c->fc, "iloc: extent_count > 1");
9468  return AVERROR_PATCHWELCOME;
9469  }
9470 
9471  if (rb_size(pb, &extent_offset, offset_size) < 0 ||
9472  rb_size(pb, &extent_length, length_size) < 0 ||
9473  base_offset > INT64_MAX - extent_offset)
9474  return AVERROR_INVALIDDATA;
9475 
9476  for (j = 0; j < c->nb_heif_item; j++) {
9477  item = c->heif_item[j];
9478  if (!item)
9479  item = c->heif_item[j] = av_mallocz(sizeof(*item));
9480  else if (item->item_id != item_id)
9481  continue;
9482  break;
9483  }
9484  if (!item)
9485  return AVERROR(ENOMEM);
9486  if (j == c->nb_heif_item)
9487  return AVERROR_INVALIDDATA;
9488 
9489  item->item_id = item_id;
9490 
9491  if (offset_type == 1)
9492  item->is_idat_relative = 1;
9493  item->extent_length = extent_length;
9494  item->extent_offset = base_offset + extent_offset;
9495  av_log(c->fc, AV_LOG_TRACE, "iloc: item_idx %d, item->item_id %d, offset_type %d, "
9496  "extent_offset %"PRId64", extent_length %"PRId64"\n",
9497  i, item->item_id, offset_type, item->extent_offset, item->extent_length);
9498  }
9499 
9500  c->found_iloc = 1;
9501  return atom.size;
9502 }
9503 
9505 {
9506  HEIFItem *item = NULL;
9507  AVBPrint item_name;
9508  int64_t size = atom.size;
9509  uint32_t item_type;
9510  int item_id;
9511  int i, version, ret;
9512 
9513  version = avio_r8(pb);
9514  avio_rb24(pb); // flags.
9515  size -= 4;
9516  if (size < 0)
9517  return AVERROR_INVALIDDATA;
9518 
9519  if (version < 2) {
9520  avpriv_report_missing_feature(c->fc, "infe version < 2");
9521  avio_skip(pb, size);
9522  return 1;
9523  }
9524 
9525  item_id = version > 2 ? avio_rb32(pb) : avio_rb16(pb);
9526  avio_rb16(pb); // item_protection_index
9527  item_type = avio_rl32(pb);
9528  size -= 8;
9529  if (size < 1)
9530  return AVERROR_INVALIDDATA;
9531 
9534  if (ret < 0) {
9536  return ret;
9537  }
9538 
9539  av_log(c->fc, AV_LOG_TRACE, "infe: item_id %d, item_type %s, item_name %s\n",
9540  item_id, av_fourcc2str(item_type), item_name.str);
9541 
9542  size -= ret + 1;
9543  if (size > 0)
9544  avio_skip(pb, size);
9545 
9546  for (i = 0; i < c->nb_heif_item; i++) {
9547  item = c->heif_item[i];
9548  if (!item)
9549  item = c->heif_item[i] = av_mallocz(sizeof(*item));
9550  else if (item->item_id != item_id)
9551  continue;
9552  break;
9553  }
9554  if (!item) {
9556  return AVERROR(ENOMEM);
9557  }
9558  if (i == c->nb_heif_item) {
9560  return AVERROR_INVALIDDATA;
9561  }
9562 
9563  av_freep(&item->name);
9564  av_bprint_finalize(&item_name, ret ? &item->name : NULL);
9565  item->item_id = item_id;
9566  item->type = item_type;
9567 
9568  switch (item_type) {
9569  case MKTAG('a','v','0','1'):
9570  case MKTAG('j','p','e','g'):
9571  case MKTAG('h','v','c','1'):
9572  ret = heif_add_stream(c, item);
9573  if (ret < 0)
9574  return ret;
9575  break;
9576  }
9577 
9578  return 0;
9579 }
9580 
9582 {
9583  HEIFItem **heif_item;
9584  int entry_count;
9585  int version, got_stream = 0, ret, i;
9586 
9587  if (c->found_iinf) {
9588  av_log(c->fc, AV_LOG_WARNING, "Duplicate iinf box found\n");
9589  return 0;
9590  }
9591 
9592  version = avio_r8(pb);
9593  avio_rb24(pb); // flags.
9594  entry_count = version ? avio_rb32(pb) : avio_rb16(pb);
9595 
9596  heif_item = av_realloc_array(c->heif_item, FFMAX(entry_count, c->nb_heif_item), sizeof(*c->heif_item));
9597  if (!heif_item)
9598  return AVERROR(ENOMEM);
9599  c->heif_item = heif_item;
9600  if (entry_count > c->nb_heif_item)
9601  memset(&c->heif_item[c->nb_heif_item], 0,
9602  sizeof(*c->heif_item) * (entry_count - c->nb_heif_item));
9603  c->nb_heif_item = FFMAX(c->nb_heif_item, entry_count);
9604 
9605  for (i = 0; i < entry_count; i++) {
9606  MOVAtom infe;
9607 
9608  infe.size = avio_rb32(pb) - 8;
9609  infe.type = avio_rl32(pb);
9610  if (avio_feof(pb)) {
9612  goto fail;
9613  }
9614  ret = mov_read_infe(c, pb, infe);
9615  if (ret < 0)
9616  goto fail;
9617  if (!ret)
9618  got_stream = 1;
9619  }
9620 
9621  c->found_iinf = got_stream;
9622  return 0;
9623 fail:
9624  for (; i >= 0; i--) {
9625  HEIFItem *item = c->heif_item[i];
9626 
9627  if (!item)
9628  continue;
9629 
9630  av_freep(&item->name);
9631  }
9632  return ret;
9633 }
9634 
9636 {
9637  HEIFItem *item = NULL;
9638  HEIFGrid *grid;
9639  int entries, i;
9640  int from_item_id = version ? avio_rb32(pb) : avio_rb16(pb);
9641  int ret = 0;
9642 
9643  for (int i = 0; i < c->nb_heif_grid; i++) {
9644  if (c->heif_grid[i].item->item_id == from_item_id) {
9645  av_log(c->fc, AV_LOG_ERROR, "More than one 'dimg' box "
9646  "referencing the same Derived Image item\n");
9647  return AVERROR_INVALIDDATA;
9648  }
9649  }
9650  for (int i = 0; i < c->nb_heif_item; i++) {
9651  if (!c->heif_item[i] || c->heif_item[i]->item_id != from_item_id)
9652  continue;
9653  item = c->heif_item[i];
9654 
9655  switch (item->type) {
9656  case MKTAG('g','r','i','d'):
9657  case MKTAG('i','o','v','l'):
9658  break;
9659  default:
9660  avpriv_report_missing_feature(c->fc, "Derived Image item of type %s",
9661  av_fourcc2str(item->type));
9662  return 0;
9663  }
9664  break;
9665  }
9666  if (!item) {
9667  av_log(c->fc, AV_LOG_ERROR, "Missing grid information\n");
9668  return AVERROR_INVALIDDATA;
9669  }
9670 
9671  entries = avio_rb16(pb);
9672  if (!entries) {
9673  av_log(c->fc, AV_LOG_ERROR,
9674  "Derived image item references no input images\n");
9675  return AVERROR_INVALIDDATA;
9676  }
9677 
9678  grid = av_realloc_array(c->heif_grid, c->nb_heif_grid + 1U,
9679  sizeof(*c->heif_grid));
9680  if (!grid)
9681  return AVERROR(ENOMEM);
9682  c->heif_grid = grid;
9683  grid = &grid[c->nb_heif_grid];
9684 
9685  grid->tile_id_list = av_malloc_array(entries, sizeof(*grid->tile_id_list));
9686  grid->tile_idx_list = av_calloc(entries, sizeof(*grid->tile_idx_list));
9687  grid->tile_item_list = av_calloc(entries, sizeof(*grid->tile_item_list));
9688  if (!grid->tile_id_list || !grid->tile_item_list || !grid->tile_idx_list) {
9689  ret = AVERROR(ENOMEM);
9690  goto fail;
9691  }
9692  /* 'to' item ids */
9693  for (i = 0; i < entries; i++) {
9694  grid->tile_id_list[i] = version ? avio_rb32(pb) : avio_rb16(pb);
9695 
9696  if (avio_feof(pb)) {
9698  goto fail;
9699  }
9700  }
9701 
9702  grid->nb_tiles = entries;
9703  grid->item = item;
9704  ++c->nb_heif_grid;
9705 
9706  av_log(c->fc, AV_LOG_TRACE, "dimg: from_item_id %d, entries %d\n",
9707  from_item_id, entries);
9708 
9709  return 0;
9710 fail:
9711  av_freep(&grid->tile_id_list);
9712  av_freep(&grid->tile_idx_list);
9713  av_freep(&grid->tile_item_list);
9714 
9715  return ret;
9716 }
9717 
9718 static int mov_read_iref_cdsc(MOVContext *c, AVIOContext *pb, uint32_t type, int version, uint32_t size)
9719 {
9720  HEIFItem *from_item = NULL;
9721  int entries;
9722  int item_id_size = version ? 4 : 2;
9723  int from_item_id = version ? avio_rb32(pb) : avio_rb16(pb);
9724  const HEIFItemRef ref = { type, from_item_id };
9725 
9726  from_item = get_heif_item(c, from_item_id);
9727  if (!from_item) {
9728  av_log(c->fc, AV_LOG_ERROR, "Missing stream referenced by thmb item\n");
9729  return AVERROR_INVALIDDATA;
9730  }
9731 
9732  entries = avio_rb16(pb);
9733  if ((int64_t)entries * item_id_size > (int64_t)size - item_id_size - 2) {
9734  av_log(c->fc, AV_LOG_ERROR, "iref %s entry count %d exceeds the sub-box size\n",
9735  av_fourcc2str(type), entries);
9736  return AVERROR_INVALIDDATA;
9737  }
9738  /* 'to' item ids */
9739  for (int i = 0; i < entries; i++) {
9740  HEIFItem *item = get_heif_item(c, version ? avio_rb32(pb) : avio_rb16(pb));
9741 
9742  if (avio_feof(pb))
9743  return AVERROR_INVALIDDATA;
9744 
9745  if (!item) {
9746  av_log(c->fc, AV_LOG_WARNING, "Missing stream referenced by %s item\n",
9747  av_fourcc2str(type));
9748  continue;
9749  }
9750 
9751  if (!av_dynarray2_add((void **)&item->iref_list, &item->nb_iref_list,
9752  sizeof(*item->iref_list), (const uint8_t *)&ref))
9753  return AVERROR(ENOMEM);
9754  }
9755 
9756  av_log(c->fc, AV_LOG_TRACE, "%s: from_item_id %d, entries %d\n",
9757  av_fourcc2str(type), from_item_id, entries);
9758 
9759  return 0;
9760 }
9761 
9763 {
9764  int version = avio_r8(pb);
9765  int ret;
9766 
9767  avio_rb24(pb); // flags
9768  atom.size -= 4;
9769 
9770  if (version > 1) {
9771  av_log(c->fc, AV_LOG_WARNING, "Unknown iref box version %d\n", version);
9772  return 0;
9773  }
9774 
9775  while (atom.size) {
9776  int64_t next = avio_tell(pb);
9777  uint32_t type, size = avio_rb32(pb);
9778 
9779  if (size < 14 || size > atom.size || next > INT64_MAX - size)
9780  return AVERROR_INVALIDDATA;
9781 
9782  next += size;
9783  type = avio_rl32(pb);
9784  switch (type) {
9785  case MKTAG('d','i','m','g'):
9786  ret = mov_read_iref_dimg(c, pb, version);
9787  if (ret < 0)
9788  return ret;
9789  break;
9790  case MKTAG('c','d','s','c'):
9791  case MKTAG('t','h','m','b'):
9792  ret = mov_read_iref_cdsc(c, pb, type, version, size - 8);
9793  if (ret < 0)
9794  return ret;
9795  break;
9796  default:
9797  av_log(c->fc, AV_LOG_DEBUG, "Unknown iref type %s size %"PRIu32"\n",
9798  av_fourcc2str(type), size);
9799  }
9800 
9801  atom.size -= size;
9802  avio_seek(pb, next, SEEK_SET);
9803  }
9804  return 0;
9805 }
9806 
9808 {
9809  HEIFItem *item;
9810  uint32_t width, height;
9811 
9812  avio_r8(pb); /* version */
9813  avio_rb24(pb); /* flags */
9814  width = avio_rb32(pb);
9815  height = avio_rb32(pb);
9816 
9817  av_log(c->fc, AV_LOG_TRACE, "ispe: item_id %d, width %"PRIu32", height %"PRIu32"\n",
9818  c->cur_item_id, width, height);
9819 
9820  if (!width || !height || width > INT_MAX || height > INT_MAX) {
9821  av_log(c->fc, AV_LOG_ERROR, "Invalid ispe dimensions %"PRIu32"x%"PRIu32"\n",
9822  width, height);
9823  return AVERROR_INVALIDDATA;
9824  }
9825 
9826  item = get_heif_item(c, c->cur_item_id);
9827  if (item) {
9828  item->width = width;
9829  item->height = height;
9830  }
9831 
9832  return 0;
9833 }
9834 
9836 {
9837  HEIFItem *item;
9838  int angle;
9839 
9840  angle = avio_r8(pb) & 0x3;
9841 
9842  av_log(c->fc, AV_LOG_TRACE, "irot: item_id %d, angle %u\n",
9843  c->cur_item_id, angle);
9844 
9845  item = get_heif_item(c, c->cur_item_id);
9846  if (item) {
9847  // angle * 90 specifies the angle (in anti-clockwise direction)
9848  // in units of degrees.
9849  item->rotation = angle * 90;
9850  }
9851 
9852  return 0;
9853 }
9854 
9856 {
9857  HEIFItem *item;
9858  int axis;
9859 
9860  axis = avio_r8(pb) & 0x1;
9861 
9862  av_log(c->fc, AV_LOG_TRACE, "imir: item_id %d, axis %u\n",
9863  c->cur_item_id, axis);
9864 
9865  item = get_heif_item(c, c->cur_item_id);
9866  if (item) {
9867  item->hflip = axis;
9868  item->vflip = !axis;
9869  }
9870 
9871  return 0;
9872 }
9873 
9875 {
9876  typedef struct MOVAtoms {
9877  FFIOContext b;
9878  uint32_t type;
9879  int64_t size;
9880  uint8_t *data;
9881  } MOVAtoms;
9882  MOVAtoms *atoms = NULL;
9883  MOVAtom a;
9884  unsigned count;
9885  int nb_atoms = 0;
9886  int version, flags;
9887  int ret;
9888 
9889  a.size = avio_rb32(pb);
9890  a.type = avio_rl32(pb);
9891 
9892  if (a.size < 8 || a.type != MKTAG('i','p','c','o'))
9893  return AVERROR_INVALIDDATA;
9894 
9895  a.size -= 8;
9896  while (a.size >= 8) {
9897  MOVAtoms *ref = av_dynarray2_add((void**)&atoms, &nb_atoms, sizeof(MOVAtoms), NULL);
9898  if (!ref) {
9899  ret = AVERROR(ENOMEM);
9900  goto fail;
9901  }
9902  ref->data = NULL;
9903  ref->size = avio_rb32(pb);
9904  ref->type = avio_rl32(pb);
9905  if (ref->size > a.size || ref->size < 8)
9906  break;
9907  ref->data = av_malloc(ref->size);
9908  if (!ref->data) {
9910  goto fail;
9911  }
9912  av_log(c->fc, AV_LOG_TRACE, "ipco: index %d, box type %s\n", nb_atoms, av_fourcc2str(ref->type));
9913  avio_seek(pb, -8, SEEK_CUR);
9914  if (avio_read(pb, ref->data, ref->size) != ref->size) {
9916  goto fail;
9917  }
9918  ffio_init_read_context(&ref->b, ref->data, ref->size);
9919  a.size -= ref->size;
9920  }
9921 
9922  if (a.size) {
9924  goto fail;
9925  }
9926 
9927  a.size = avio_rb32(pb);
9928  a.type = avio_rl32(pb);
9929 
9930  if (a.size < 8 || a.type != MKTAG('i','p','m','a')) {
9932  goto fail;
9933  }
9934 
9935  version = avio_r8(pb);
9936  flags = avio_rb24(pb);
9937  count = avio_rb32(pb);
9938 
9939  for (int i = 0; i < count; i++) {
9940  int item_id = version ? avio_rb32(pb) : avio_rb16(pb);
9941  int assoc_count = avio_r8(pb);
9942 
9943  if (avio_feof(pb)) {
9945  goto fail;
9946  }
9947 
9948  for (int j = 0; j < assoc_count; j++) {
9949  MOVAtoms *ref;
9950  int index = avio_r8(pb) & 0x7f;
9951  if (flags & 1) {
9952  index <<= 8;
9953  index |= avio_r8(pb);
9954  }
9955  if (index > nb_atoms || index <= 0) {
9957  goto fail;
9958  }
9959  ref = &atoms[--index];
9960 
9961  av_log(c->fc, AV_LOG_TRACE, "ipma: property_index %d, item_id %d, item_type %s\n",
9962  index + 1, item_id, av_fourcc2str(ref->type));
9963 
9964  c->cur_item_id = item_id;
9965 
9966  ret = mov_read_default(c, &ref->b.pub,
9967  (MOVAtom) { .size = ref->size,
9968  .type = MKTAG('i','p','c','o') });
9969  if (ret < 0)
9970  goto fail;
9971  ffio_init_read_context(&ref->b, ref->data, ref->size);
9972  }
9973  }
9974 
9975  ret = 0;
9976 fail:
9977  c->cur_item_id = -1;
9978  for (int i = 0; i < nb_atoms; i++)
9979  av_free(atoms[i].data);
9980  av_free(atoms);
9981 
9982  return ret;
9983 }
9984 
9986 { MKTAG('A','C','L','R'), mov_read_aclr },
9987 { MKTAG('A','P','R','G'), mov_read_avid },
9988 { MKTAG('A','A','L','P'), mov_read_avid },
9989 { MKTAG('A','R','E','S'), mov_read_ares },
9990 { MKTAG('a','v','s','s'), mov_read_avss },
9991 { MKTAG('a','v','1','C'), mov_read_glbl },
9992 { MKTAG('c','h','p','l'), mov_read_chpl },
9993 { MKTAG('c','o','6','4'), mov_read_stco },
9994 { MKTAG('c','o','l','r'), mov_read_colr },
9995 { MKTAG('c','t','t','s'), mov_read_ctts }, /* composition time to sample */
9996 { MKTAG('d','i','n','f'), mov_read_default },
9997 { MKTAG('D','p','x','E'), mov_read_dpxe },
9998 { MKTAG('d','r','e','f'), mov_read_dref },
9999 { MKTAG('e','d','t','s'), mov_read_default },
10000 { MKTAG('e','l','s','t'), mov_read_elst },
10001 { MKTAG('e','n','d','a'), mov_read_enda },
10002 { MKTAG('f','i','e','l'), mov_read_fiel },
10003 { MKTAG('a','d','r','m'), mov_read_adrm },
10004 { MKTAG('f','t','y','p'), mov_read_ftyp },
10005 { MKTAG('g','l','b','l'), mov_read_glbl },
10006 { MKTAG('h','d','l','r'), mov_read_hdlr },
10007 { MKTAG('i','l','s','t'), mov_read_ilst },
10008 { MKTAG('j','p','2','h'), mov_read_jp2h },
10009 { MKTAG('m','d','a','t'), mov_read_mdat },
10010 { MKTAG('m','d','h','d'), mov_read_mdhd },
10011 { MKTAG('m','d','i','a'), mov_read_default },
10012 { MKTAG('m','e','t','a'), mov_read_meta },
10013 { MKTAG('m','i','n','f'), mov_read_default },
10014 { MKTAG('m','o','o','f'), mov_read_moof },
10015 { MKTAG('m','o','o','v'), mov_read_moov },
10016 { MKTAG('m','v','e','x'), mov_read_default },
10017 { MKTAG('m','v','h','d'), mov_read_mvhd },
10018 { MKTAG('S','M','I',' '), mov_read_svq3 },
10019 { MKTAG('a','l','a','c'), mov_read_alac }, /* alac specific atom */
10020 { MKTAG('a','v','c','C'), mov_read_glbl },
10021 { MKTAG('p','a','s','p'), mov_read_pasp },
10022 { MKTAG('c','l','a','p'), mov_read_clap },
10023 { MKTAG('c','d','s','c'), mov_read_cdsc },
10024 { MKTAG('s','b','a','s'), mov_read_sbas },
10025 { MKTAG('v','d','e','p'), mov_read_vdep },
10026 { MKTAG('s','i','d','x'), mov_read_sidx },
10027 { MKTAG('s','t','b','l'), mov_read_default },
10028 { MKTAG('s','t','c','o'), mov_read_stco },
10029 { MKTAG('s','t','p','s'), mov_read_stps },
10030 { MKTAG('s','t','r','f'), mov_read_strf },
10031 { MKTAG('s','t','s','c'), mov_read_stsc },
10032 { MKTAG('s','t','s','d'), mov_read_stsd }, /* sample description */
10033 { MKTAG('s','t','s','s'), mov_read_stss }, /* sync sample */
10034 { MKTAG('s','t','s','z'), mov_read_stsz }, /* sample size */
10035 { MKTAG('s','t','t','s'), mov_read_stts },
10036 { MKTAG('s','t','z','2'), mov_read_stsz }, /* compact sample size */
10037 { MKTAG('s','d','t','p'), mov_read_sdtp }, /* independent and disposable samples */
10038 { MKTAG('t','k','h','d'), mov_read_tkhd }, /* track header */
10039 { MKTAG('t','f','d','t'), mov_read_tfdt },
10040 { MKTAG('t','f','h','d'), mov_read_tfhd }, /* track fragment header */
10041 { MKTAG('t','r','a','k'), mov_read_trak },
10042 { MKTAG('t','r','a','f'), mov_read_default },
10043 { MKTAG('t','r','e','f'), mov_read_default },
10044 { MKTAG('t','m','c','d'), mov_read_tmcd },
10045 { MKTAG('c','h','a','p'), mov_read_chap },
10046 { MKTAG('t','r','e','x'), mov_read_trex },
10047 { MKTAG('t','r','u','n'), mov_read_trun },
10048 { MKTAG('u','d','t','a'), mov_read_default },
10049 { MKTAG('w','a','v','e'), mov_read_wave },
10050 { MKTAG('e','s','d','s'), mov_read_esds },
10051 { MKTAG('d','a','c','3'), mov_read_dac3 }, /* AC-3 info */
10052 { MKTAG('d','e','c','3'), mov_read_dec3 }, /* EAC-3 info */
10053 { MKTAG('d','d','t','s'), mov_read_ddts }, /* DTS audio descriptor */
10054 { MKTAG('w','i','d','e'), mov_read_wide }, /* place holder */
10055 { MKTAG('w','f','e','x'), mov_read_wfex },
10056 { MKTAG('c','m','o','v'), mov_read_cmov },
10057 { MKTAG('c','h','a','n'), mov_read_chan }, /* channel layout from quicktime */
10058 { MKTAG('c','h','n','l'), mov_read_chnl }, /* channel layout from ISO-14496-12 */
10059 { MKTAG('d','v','c','1'), mov_read_dvc1 },
10060 { MKTAG('s','g','p','d'), mov_read_sgpd },
10061 { MKTAG('s','b','g','p'), mov_read_sbgp },
10062 { MKTAG('h','v','c','C'), mov_read_glbl },
10063 { MKTAG('v','v','c','C'), mov_read_glbl },
10064 { MKTAG('u','u','i','d'), mov_read_uuid },
10065 { MKTAG('C','i','n', 0x8e), mov_read_targa_y216 },
10066 { MKTAG('f','r','e','e'), mov_read_free },
10067 { MKTAG('-','-','-','-'), mov_read_custom },
10068 { MKTAG('s','i','n','f'), mov_read_default },
10069 { MKTAG('f','r','m','a'), mov_read_frma },
10070 { MKTAG('s','e','n','c'), mov_read_senc },
10071 { MKTAG('s','a','i','z'), mov_read_saiz },
10072 { MKTAG('s','a','i','o'), mov_read_saio },
10073 { MKTAG('p','s','s','h'), mov_read_pssh },
10074 { MKTAG('s','c','h','m'), mov_read_schm },
10075 { MKTAG('s','c','h','i'), mov_read_default },
10076 { MKTAG('t','e','n','c'), mov_read_tenc },
10077 { MKTAG('d','f','L','a'), mov_read_dfla },
10078 { MKTAG('s','t','3','d'), mov_read_st3d }, /* stereoscopic 3D video box */
10079 { MKTAG('s','v','3','d'), mov_read_sv3d }, /* spherical video box */
10080 { MKTAG('v','e','x','u'), mov_read_vexu }, /* video extension usage */
10081 { MKTAG('h','f','o','v'), mov_read_hfov },
10082 { MKTAG('d','O','p','s'), mov_read_dops },
10083 { MKTAG('d','m','l','p'), mov_read_dmlp },
10084 { MKTAG('S','m','D','m'), mov_read_smdm },
10085 { MKTAG('C','o','L','L'), mov_read_coll },
10086 { MKTAG('v','p','c','C'), mov_read_vpcc },
10087 { MKTAG('m','d','c','v'), mov_read_mdcv },
10088 { MKTAG('c','l','l','i'), mov_read_clli },
10089 { MKTAG('d','v','c','C'), mov_read_dvcc_dvvc },
10090 { MKTAG('d','v','v','C'), mov_read_dvcc_dvvc },
10091 { MKTAG('d','v','w','C'), mov_read_dvcc_dvvc },
10092 { MKTAG('h','v','c','E'), mov_read_hvce },
10093 { MKTAG('k','i','n','d'), mov_read_kind },
10094 { MKTAG('S','A','3','D'), mov_read_SA3D }, /* ambisonic audio box */
10095 { MKTAG('S','A','N','D'), mov_read_SAND }, /* non diegetic audio box */
10096 { MKTAG('i','l','o','c'), mov_read_iloc },
10097 { MKTAG('p','c','m','C'), mov_read_pcmc }, /* PCM configuration box */
10098 { MKTAG('p','i','t','m'), mov_read_pitm },
10099 { MKTAG('e','v','c','C'), mov_read_glbl },
10100 { MKTAG('i','d','a','t'), mov_read_idat },
10101 { MKTAG('i','m','i','r'), mov_read_imir },
10102 { MKTAG('i','r','e','f'), mov_read_iref },
10103 { MKTAG('i','s','p','e'), mov_read_ispe },
10104 { MKTAG('i','r','o','t'), mov_read_irot },
10105 { MKTAG('i','p','r','p'), mov_read_iprp },
10106 { MKTAG('i','i','n','f'), mov_read_iinf },
10107 { MKTAG('a','m','v','e'), mov_read_amve }, /* ambient viewing environment box */
10108 { MKTAG('l','h','v','C'), mov_read_lhvc },
10109 { MKTAG('l','v','c','C'), mov_read_glbl },
10110 { MKTAG('a','p','v','C'), mov_read_glbl },
10111 #if CONFIG_IAMFDEC
10112 { MKTAG('i','a','c','b'), mov_read_iacb },
10113 #endif
10114 { MKTAG('s','r','a','t'), mov_read_srat },
10115 { 0, NULL }
10116 };
10117 
10119 {
10120  int64_t total_size = 0;
10121  MOVAtom a;
10122  int i;
10123 
10124  if (c->atom_depth > 10) {
10125  av_log(c->fc, AV_LOG_ERROR, "Atoms too deeply nested\n");
10126  return AVERROR_INVALIDDATA;
10127  }
10128  c->atom_depth ++;
10129 
10130  if (atom.size < 0)
10131  atom.size = INT64_MAX;
10132  while (total_size <= atom.size - 8) {
10133  int (*parse)(MOVContext*, AVIOContext*, MOVAtom) = NULL;
10134  a.size = avio_rb32(pb);
10135  a.type = avio_rl32(pb);
10136  if (avio_feof(pb))
10137  break;
10138  if (((a.type == MKTAG('f','r','e','e') && c->moov_retry) ||
10139  a.type == MKTAG('h','o','o','v')) &&
10140  a.size >= 8 &&
10141  c->fc->strict_std_compliance < FF_COMPLIANCE_STRICT) {
10142  uint32_t type;
10143  avio_skip(pb, 4);
10144  type = avio_rl32(pb);
10145  if (avio_feof(pb))
10146  break;
10147  avio_seek(pb, -8, SEEK_CUR);
10148  if (type == MKTAG('m','v','h','d') ||
10149  type == MKTAG('c','m','o','v')) {
10150  av_log(c->fc, AV_LOG_ERROR, "Detected moov in a free or hoov atom.\n");
10151  a.type = MKTAG('m','o','o','v');
10152  }
10153  }
10154  if (atom.type != MKTAG('r','o','o','t') &&
10155  atom.type != MKTAG('m','o','o','v')) {
10156  if (a.type == MKTAG('t','r','a','k') ||
10157  a.type == MKTAG('m','d','a','t')) {
10158  av_log(c->fc, AV_LOG_ERROR, "Broken file, trak/mdat not at top-level\n");
10159  avio_skip(pb, -8);
10160  c->atom_depth --;
10161  return 0;
10162  }
10163  }
10164  total_size += 8;
10165  if (a.size == 1 && total_size + 8 <= atom.size) { /* 64 bit extended size */
10166  a.size = avio_rb64(pb) - 8;
10167  total_size += 8;
10168  }
10169  av_log(c->fc, AV_LOG_TRACE, "type:'%s' parent:'%s' sz: %"PRId64" %"PRId64" %"PRId64"\n",
10170  av_fourcc2str(a.type), av_fourcc2str(atom.type), a.size, total_size, atom.size);
10171  if (a.size == 0) {
10172  a.size = atom.size - total_size + 8;
10173  }
10174  if (a.size < 0)
10175  break;
10176  a.size -= 8;
10177  if (a.size < 0)
10178  break;
10179  a.size = FFMIN(a.size, atom.size - total_size);
10180 
10181  for (i = 0; mov_default_parse_table[i].type; i++)
10182  if (mov_default_parse_table[i].type == a.type) {
10184  break;
10185  }
10186 
10187  // container is user data
10188  if (!parse && (atom.type == MKTAG('u','d','t','a') ||
10189  atom.type == MKTAG('i','l','s','t')))
10191 
10192  // Supports parsing the QuickTime Metadata Keys.
10193  // https://developer.apple.com/library/mac/documentation/QuickTime/QTFF/Metadata/Metadata.html
10194  if (!parse && c->found_hdlr_mdta &&
10195  atom.type == MKTAG('m','e','t','a') &&
10196  a.type == MKTAG('k','e','y','s') &&
10197  c->meta_keys_count == 0) {
10198  parse = mov_read_keys;
10199  }
10200 
10201  if (!parse) { /* skip leaf atoms data */
10202  avio_skip(pb, a.size);
10203  } else {
10204  int64_t start_pos = avio_tell(pb);
10205  int64_t left;
10206  int err = parse(c, pb, a);
10207  if (err < 0) {
10208  c->atom_depth --;
10209  return err;
10210  }
10211  if (c->found_moov && c->found_mdat && a.size <= INT64_MAX - start_pos &&
10212  ((!(pb->seekable & AVIO_SEEKABLE_NORMAL) || c->fc->flags & AVFMT_FLAG_IGNIDX || c->frag_index.complete) ||
10213  start_pos + a.size == avio_size(pb))) {
10214  if (!(pb->seekable & AVIO_SEEKABLE_NORMAL) || c->fc->flags & AVFMT_FLAG_IGNIDX || c->frag_index.complete)
10215  c->next_root_atom = start_pos + a.size;
10216  c->atom_depth --;
10217  return 0;
10218  }
10219  left = a.size - avio_tell(pb) + start_pos;
10220  if (left > 0) /* skip garbage at atom end */
10221  avio_skip(pb, left);
10222  else if (left < 0) {
10223  av_log(c->fc, AV_LOG_WARNING,
10224  "overread end of atom '%s' by %"PRId64" bytes\n",
10225  av_fourcc2str(a.type), -left);
10226  avio_seek(pb, left, SEEK_CUR);
10227  }
10228  }
10229 
10230  total_size += a.size;
10231  }
10232 
10233  if (total_size < atom.size && atom.size < 0x7ffff)
10234  avio_skip(pb, atom.size - total_size);
10235 
10236  c->atom_depth --;
10237  return 0;
10238 }
10239 
10240 static int mov_probe(const AVProbeData *p)
10241 {
10242  int64_t offset;
10243  uint32_t tag;
10244  int score = 0;
10245  int moov_offset = -1;
10246 
10247  /* check file header */
10248  offset = 0;
10249  for (;;) {
10250  int64_t size;
10251  int minsize = 8;
10252  /* ignore invalid offset */
10253  if ((offset + 8ULL) > (unsigned int)p->buf_size)
10254  break;
10255  size = AV_RB32(p->buf + offset);
10256  if (size == 1 && offset + 16 <= (unsigned int)p->buf_size) {
10257  size = AV_RB64(p->buf+offset + 8);
10258  minsize = 16;
10259  } else if (size == 0) {
10260  size = p->buf_size - offset;
10261  }
10262  if (size < minsize) {
10263  offset += 4;
10264  continue;
10265  }
10266  tag = AV_RL32(p->buf + offset + 4);
10267  switch(tag) {
10268  /* check for obvious tags */
10269  case MKTAG('m','o','o','v'):
10270  moov_offset = offset + 4;
10272  case MKTAG('m','d','a','t'):
10273  case MKTAG('p','n','o','t'): /* detect movs with preview pics like ew.mov and april.mov */
10274  case MKTAG('u','d','t','a'): /* Packet Video PVAuthor adds this and a lot of more junk */
10275  case MKTAG('f','t','y','p'):
10276  if (tag == MKTAG('f','t','y','p') &&
10277  ( AV_RL32(p->buf + offset + 8) == MKTAG('j','p','2',' ')
10278  || AV_RL32(p->buf + offset + 8) == MKTAG('j','p','x',' ')
10279  || AV_RL32(p->buf + offset + 8) == MKTAG('j','x','l',' ')
10280  )) {
10281  score = FFMAX(score, 5);
10282  } else {
10283  score = AVPROBE_SCORE_MAX;
10284  }
10285  break;
10286  /* those are more common words, so rate then a bit less */
10287  case MKTAG('e','d','i','w'): /* xdcam files have reverted first tags */
10288  case MKTAG('w','i','d','e'):
10289  case MKTAG('f','r','e','e'):
10290  case MKTAG('j','u','n','k'):
10291  case MKTAG('p','i','c','t'):
10292  score = FFMAX(score, AVPROBE_SCORE_MAX - 5);
10293  break;
10294  case MKTAG(0x82,0x82,0x7f,0x7d):
10295  score = FFMAX(score, AVPROBE_SCORE_EXTENSION - 5);
10296  break;
10297  case MKTAG('s','k','i','p'):
10298  case MKTAG('u','u','i','d'):
10299  case MKTAG('p','r','f','l'):
10300  /* if we only find those cause probedata is too small at least rate them */
10301  score = FFMAX(score, AVPROBE_SCORE_EXTENSION);
10302  break;
10303  }
10304  if (size > INT64_MAX - offset)
10305  break;
10306  offset += size;
10307  }
10308  if (score > AVPROBE_SCORE_MAX - 50 && moov_offset != -1) {
10309  /* moov atom in the header - we should make sure that this is not a
10310  * MOV-packed MPEG-PS */
10311  offset = moov_offset;
10312 
10313  while (offset < (p->buf_size - 16)) { /* Sufficient space */
10314  /* We found an actual hdlr atom */
10315  if (AV_RL32(p->buf + offset ) == MKTAG('h','d','l','r') &&
10316  AV_RL32(p->buf + offset + 8) == MKTAG('m','h','l','r') &&
10317  AV_RL32(p->buf + offset + 12) == MKTAG('M','P','E','G')) {
10318  av_log(NULL, AV_LOG_WARNING, "Found media data tag MPEG indicating this is a MOV-packed MPEG-PS.\n");
10319  /* We found a media handler reference atom describing an
10320  * MPEG-PS-in-MOV, return a
10321  * low score to force expanding the probe window until
10322  * mpegps_probe finds what it needs */
10323  return 5;
10324  } else {
10325  /* Keep looking */
10326  offset += 2;
10327  }
10328  }
10329  }
10330 
10331  return score;
10332 }
10333 
10334 // must be done after parsing all trak because there's no order requirement
10336 {
10337  MOVContext *mov = s->priv_data;
10338  MOVStreamContext *sc;
10339  int64_t cur_pos;
10340  int i, j;
10341  int chapter_track;
10342 
10343  for (j = 0; j < mov->nb_chapter_tracks; j++) {
10344  AVStream *st = NULL;
10345  FFStream *sti = NULL;
10346  chapter_track = mov->chapter_tracks[j];
10347  for (i = 0; i < s->nb_streams; i++) {
10348  sc = mov->fc->streams[i]->priv_data;
10349  if (sc->id == chapter_track) {
10350  st = s->streams[i];
10351  break;
10352  }
10353  }
10354  if (!st) {
10355  av_log(s, AV_LOG_ERROR, "Referenced QT chapter track not found\n");
10356  continue;
10357  }
10358  sti = ffstream(st);
10359 
10360  sc = st->priv_data;
10361  cur_pos = avio_tell(sc->pb);
10362 
10363  if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
10365  if (!st->attached_pic.data && sti->nb_index_entries) {
10366  // Retrieve the first frame, if possible
10367  AVIndexEntry *sample = &sti->index_entries[0];
10368  if (avio_seek(sc->pb, sample->pos, SEEK_SET) != sample->pos) {
10369  av_log(s, AV_LOG_ERROR, "Failed to retrieve first frame\n");
10370  goto finish;
10371  }
10372 
10373  if (ff_add_attached_pic(s, st, sc->pb, NULL, sample->size) < 0)
10374  goto finish;
10375  }
10376  } else {
10379  st->discard = AVDISCARD_ALL;
10380  for (int i = 0; i < sti->nb_index_entries; i++) {
10381  AVIndexEntry *sample = &sti->index_entries[i];
10382  int64_t end = i+1 < sti->nb_index_entries ? sti->index_entries[i+1].timestamp : st->duration;
10383  uint8_t *title;
10384  uint16_t ch;
10385  int len, title_len;
10386 
10387  if (end < sample->timestamp) {
10388  av_log(s, AV_LOG_WARNING, "ignoring stream duration which is shorter than chapters\n");
10389  end = AV_NOPTS_VALUE;
10390  }
10391 
10392  if (avio_seek(sc->pb, sample->pos, SEEK_SET) != sample->pos) {
10393  av_log(s, AV_LOG_ERROR, "Chapter %d not found in file\n", i);
10394  goto finish;
10395  }
10396 
10397  // the first two bytes are the length of the title
10398  len = avio_rb16(sc->pb);
10399  if (len > sample->size-2)
10400  continue;
10401  title_len = 2*len + 1;
10402  if (!(title = av_mallocz(title_len)))
10403  goto finish;
10404 
10405  // The samples could theoretically be in any encoding if there's an encd
10406  // atom following, but in practice are only utf-8 or utf-16, distinguished
10407  // instead by the presence of a BOM
10408  if (!len) {
10409  title[0] = 0;
10410  } else {
10411  ch = avio_rb16(sc->pb);
10412  if (ch == 0xfeff)
10413  avio_get_str16be(sc->pb, len, title, title_len);
10414  else if (ch == 0xfffe)
10415  avio_get_str16le(sc->pb, len, title, title_len);
10416  else {
10417  AV_WB16(title, ch);
10418  if (len == 1 || len == 2)
10419  title[len] = 0;
10420  else
10421  avio_get_str(sc->pb, INT_MAX, title + 2, len - 1);
10422  }
10423  }
10424 
10425  avpriv_new_chapter(s, i, st->time_base, sample->timestamp, end, title);
10426  av_freep(&title);
10427  }
10428  }
10429 finish:
10430  avio_seek(sc->pb, cur_pos, SEEK_SET);
10431  }
10432 }
10433 
10435  int64_t value, int flags)
10436 {
10437  AVTimecode tc;
10438  char buf[AV_TIMECODE_STR_SIZE];
10439  AVRational rate = st->avg_frame_rate;
10440  int ret = av_timecode_init(&tc, rate, flags, 0, s);
10441  if (ret < 0)
10442  return ret;
10443  av_dict_set(&st->metadata, "timecode",
10444  av_timecode_make_string(&tc, buf, value), 0);
10445  return 0;
10446 }
10447 
10449 {
10450  MOVStreamContext *sc = st->priv_data;
10451  FFStream *const sti = ffstream(st);
10452  char buf[AV_TIMECODE_STR_SIZE];
10453  int64_t cur_pos = avio_tell(sc->pb);
10454  int hh, mm, ss, ff, drop;
10455 
10456  if (!sti->nb_index_entries)
10457  return -1;
10458 
10459  avio_seek(sc->pb, sti->index_entries->pos, SEEK_SET);
10460  avio_skip(s->pb, 13);
10461  hh = avio_r8(s->pb);
10462  mm = avio_r8(s->pb);
10463  ss = avio_r8(s->pb);
10464  drop = avio_r8(s->pb);
10465  ff = avio_r8(s->pb);
10466  snprintf(buf, AV_TIMECODE_STR_SIZE, "%02d:%02d:%02d%c%02d",
10467  hh, mm, ss, drop ? ';' : ':', ff);
10468  av_dict_set(&st->metadata, "timecode", buf, 0);
10469 
10470  avio_seek(sc->pb, cur_pos, SEEK_SET);
10471  return 0;
10472 }
10473 
10475 {
10476  MOVStreamContext *sc = st->priv_data;
10477  FFStream *const sti = ffstream(st);
10478  int flags = 0;
10479  int64_t cur_pos = avio_tell(sc->pb);
10480  int64_t value;
10481  AVRational tc_rate = st->avg_frame_rate;
10482  int tmcd_nb_frames = sc->tmcd_nb_frames;
10483  int rounded_tc_rate;
10484 
10485  if (!sti->nb_index_entries)
10486  return -1;
10487 
10488  if (!tc_rate.num || !tc_rate.den || !tmcd_nb_frames)
10489  return -1;
10490 
10491  avio_seek(sc->pb, sti->index_entries->pos, SEEK_SET);
10492  value = avio_rb32(s->pb);
10493 
10494  if (sc->tmcd_flags & 0x0001) flags |= AV_TIMECODE_FLAG_DROPFRAME;
10495  if (sc->tmcd_flags & 0x0002) flags |= AV_TIMECODE_FLAG_24HOURSMAX;
10496  if (sc->tmcd_flags & 0x0004) flags |= AV_TIMECODE_FLAG_ALLOWNEGATIVE;
10497 
10498  /* Assume Counter flag is set to 1 in tmcd track (even though it is likely
10499  * not the case) and thus assume "frame number format" instead of QT one.
10500  * No sample with tmcd track can be found with a QT timecode at the moment,
10501  * despite what the tmcd track "suggests" (Counter flag set to 0 means QT
10502  * format). */
10503 
10504  /* 60 fps content have tmcd_nb_frames set to 30 but tc_rate set to 60, so
10505  * we multiply the frame number with the quotient.
10506  * See tickets #9492, #9710. */
10507  rounded_tc_rate = (tc_rate.num + tc_rate.den / 2LL) / tc_rate.den;
10508  /* Work around files where tmcd_nb_frames is rounded down from frame rate
10509  * instead of up. See ticket #5978. */
10510  if (tmcd_nb_frames == tc_rate.num / tc_rate.den &&
10511  s->strict_std_compliance < FF_COMPLIANCE_STRICT)
10512  tmcd_nb_frames = rounded_tc_rate;
10513  value = av_rescale(value, rounded_tc_rate, tmcd_nb_frames);
10514 
10516 
10517  avio_seek(sc->pb, cur_pos, SEEK_SET);
10518  return 0;
10519 }
10520 
10522  int i;
10523  if (!index || !*index) return;
10524  for (i = 0; i < (*index)->nb_encrypted_samples; i++) {
10525  av_encryption_info_free((*index)->encrypted_samples[i]);
10526  }
10527  av_freep(&(*index)->encrypted_samples);
10528  av_freep(&(*index)->auxiliary_info_sizes);
10529  av_freep(&(*index)->auxiliary_offsets);
10530  av_freep(index);
10531 }
10532 
10534 {
10535  MOVStreamContext *sc = st->priv_data;
10536 
10537  if (!sc || --sc->refcount) {
10538  st->priv_data = NULL;
10539  return;
10540  }
10541 
10542  av_freep(&sc->tts_data);
10543  for (int i = 0; i < sc->drefs_count; i++) {
10544  av_freep(&sc->drefs[i].path);
10545  av_freep(&sc->drefs[i].dir);
10546  }
10547  av_freep(&sc->drefs);
10548 
10549  sc->drefs_count = 0;
10550 
10551  if (!sc->pb_is_copied)
10552  ff_format_io_close(s, &sc->pb);
10553 
10554  sc->pb = NULL;
10555  av_freep(&sc->chunk_offsets);
10556  av_freep(&sc->stsc_data);
10557  av_freep(&sc->sample_sizes);
10558  av_freep(&sc->keyframes);
10559  av_freep(&sc->ctts_data);
10560  av_freep(&sc->stts_data);
10561  av_freep(&sc->sdtp_data);
10562  av_freep(&sc->stps_data);
10563  av_freep(&sc->elst_data);
10564  av_freep(&sc->rap_group);
10565  av_freep(&sc->sync_group);
10566  av_freep(&sc->sgpd_sync);
10567  av_freep(&sc->sample_offsets);
10568  av_freep(&sc->open_key_samples);
10569  av_freep(&sc->display_matrix);
10570  av_freep(&sc->index_ranges);
10571  for (int i = 0; i < sc->nb_tref_tags; i++)
10572  av_freep(&sc->tref_tags[i].id);
10573  av_freep(&sc->tref_tags);
10574 
10575  if (sc->extradata)
10576  for (int i = 0; i < sc->stsd_count; i++)
10577  av_free(sc->extradata[i]);
10578  av_freep(&sc->extradata);
10579  av_freep(&sc->extradata_size);
10580 
10584 
10585  av_freep(&sc->stereo3d);
10586  av_freep(&sc->spherical);
10587  av_freep(&sc->mastering);
10588  av_freep(&sc->coll);
10589  av_freep(&sc->ambient);
10590 
10591 #if CONFIG_IAMFDEC
10592  if (sc->iamf)
10594 #endif
10595  av_freep(&sc->iamf);
10596 }
10597 
10599 {
10600  MOVContext *mov = s->priv_data;
10601  int i, j;
10602 
10603  for (i = 0; i < s->nb_streams; i++) {
10604  AVStream *st = s->streams[i];
10605 
10607  }
10608 
10609  av_freep(&mov->dv_demux);
10611  mov->dv_fctx = NULL;
10612 
10613  if (mov->meta_keys) {
10614  for (i = 1; i < mov->meta_keys_count; i++) {
10615  av_freep(&mov->meta_keys[i]);
10616  }
10617  av_freep(&mov->meta_keys);
10618  }
10619 
10620  av_freep(&mov->trex_data);
10621  av_freep(&mov->bitrates);
10622 
10623  for (i = 0; i < mov->frag_index.nb_items; i++) {
10625  for (j = 0; j < mov->frag_index.item[i].nb_stream_info; j++) {
10626  mov_free_encryption_index(&frag[j].encryption_index);
10627  }
10629  }
10630  av_freep(&mov->frag_index.item);
10631 
10632  av_freep(&mov->aes_decrypt);
10633  av_freep(&mov->chapter_tracks);
10634  for (i = 0; i < mov->nb_heif_item; i++) {
10635  if (!mov->heif_item[i])
10636  continue;
10637  av_freep(&mov->heif_item[i]->name);
10638  av_freep(&mov->heif_item[i]->iref_list);
10639  av_freep(&mov->heif_item[i]->icc_profile);
10640  av_freep(&mov->heif_item[i]);
10641  }
10642  av_freep(&mov->heif_item);
10643  for (i = 0; i < mov->nb_heif_grid; i++) {
10644  av_freep(&mov->heif_grid[i].tile_id_list);
10647  }
10648  av_freep(&mov->heif_grid);
10649 
10650  return 0;
10651 }
10652 
10653 static int tmcd_is_referenced(AVFormatContext *s, int tmcd_id)
10654 {
10655  int i;
10656 
10657  for (i = 0; i < s->nb_streams; i++) {
10658  AVStream *st = s->streams[i];
10659  MOVStreamContext *sc = st->priv_data;
10660  MovTref *tag = mov_find_tref_tag(sc, MKTAG('t','m','c','d'));
10661 
10662  if (!tag)
10663  continue;
10664  if (mov_find_tref_id(tag, tmcd_id))
10665  return 1;
10666  }
10667  return 0;
10668 }
10669 
10670 /* look for a tmcd track not referenced by any video track, and export it globally */
10672 {
10673  int i;
10674 
10675  for (i = 0; i < s->nb_streams; i++) {
10676  AVStream *st = s->streams[i];
10677 
10678  if (st->codecpar->codec_tag == MKTAG('t','m','c','d') &&
10679  !tmcd_is_referenced(s, st->id)) {
10680  AVDictionaryEntry *tcr = av_dict_get(st->metadata, "timecode", NULL, 0);
10681  if (tcr) {
10682  av_dict_set(&s->metadata, "timecode", tcr->value, 0);
10683  break;
10684  }
10685  }
10686  }
10687 }
10688 
10689 static int read_tfra(MOVContext *mov, AVIOContext *f)
10690 {
10691  int version, fieldlength, i, j;
10692  int64_t pos = avio_tell(f);
10693  uint32_t size = avio_rb32(f);
10694  unsigned track_id, item_count;
10695 
10696  if (avio_rb32(f) != MKBETAG('t', 'f', 'r', 'a')) {
10697  return 1;
10698  }
10699  av_log(mov->fc, AV_LOG_VERBOSE, "found tfra\n");
10700 
10701  version = avio_r8(f);
10702  avio_rb24(f);
10703  track_id = avio_rb32(f);
10704  fieldlength = avio_rb32(f);
10705  item_count = avio_rb32(f);
10706  for (i = 0; i < item_count; i++) {
10707  int64_t time, offset;
10708  int index;
10709  MOVFragmentStreamInfo * frag_stream_info;
10710 
10711  if (avio_feof(f)) {
10712  return AVERROR_INVALIDDATA;
10713  }
10714 
10715  if (version == 1) {
10716  time = avio_rb64(f);
10717  offset = avio_rb64(f);
10718  } else {
10719  time = avio_rb32(f);
10720  offset = avio_rb32(f);
10721  }
10722 
10723  // The first sample of each stream in a fragment is always a random
10724  // access sample. So it's entry in the tfra can be used as the
10725  // initial PTS of the fragment.
10726  index = update_frag_index(mov, offset);
10727  frag_stream_info = get_frag_stream_info(&mov->frag_index, index, track_id);
10728  if (frag_stream_info &&
10729  frag_stream_info->first_tfra_pts == AV_NOPTS_VALUE)
10730  frag_stream_info->first_tfra_pts = time;
10731 
10732  for (j = 0; j < ((fieldlength >> 4) & 3) + 1; j++)
10733  avio_r8(f);
10734  for (j = 0; j < ((fieldlength >> 2) & 3) + 1; j++)
10735  avio_r8(f);
10736  for (j = 0; j < ((fieldlength >> 0) & 3) + 1; j++)
10737  avio_r8(f);
10738  }
10739 
10740  avio_seek(f, pos + size, SEEK_SET);
10741  return 0;
10742 }
10743 
10745 {
10746  int64_t stream_size = avio_size(f);
10747  int64_t original_pos = avio_tell(f);
10748  int64_t seek_ret;
10749  int ret = -1;
10750  if ((seek_ret = avio_seek(f, stream_size - 4, SEEK_SET)) < 0) {
10751  ret = seek_ret;
10752  goto fail;
10753  }
10754  c->mfra_size = avio_rb32(f);
10755  c->have_read_mfra_size = 1;
10756  if (!c->mfra_size || c->mfra_size > stream_size) {
10757  av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (unreasonable size)\n");
10758  goto fail;
10759  }
10760  if ((seek_ret = avio_seek(f, -((int64_t) c->mfra_size), SEEK_CUR)) < 0) {
10761  ret = seek_ret;
10762  goto fail;
10763  }
10764  if (avio_rb32(f) != c->mfra_size) {
10765  av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (size mismatch)\n");
10766  goto fail;
10767  }
10768  if (avio_rb32(f) != MKBETAG('m', 'f', 'r', 'a')) {
10769  av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (tag mismatch)\n");
10770  goto fail;
10771  }
10772  av_log(c->fc, AV_LOG_VERBOSE, "stream has mfra\n");
10773  do {
10774  ret = read_tfra(c, f);
10775  if (ret < 0)
10776  goto fail;
10777  } while (!ret);
10778  ret = 0;
10779  c->frag_index.complete = 1;
10780 fail:
10781  seek_ret = avio_seek(f, original_pos, SEEK_SET);
10782  if (seek_ret < 0) {
10783  av_log(c->fc, AV_LOG_ERROR,
10784  "failed to seek back after looking for mfra\n");
10785  ret = seek_ret;
10786  }
10787  return ret;
10788 }
10789 
10790 static int set_icc_profile_from_item(AVPacketSideData **coded_side_data, int *nb_coded_side_data,
10791  const HEIFItem *item)
10792 {
10793  AVPacketSideData *sd = av_packet_side_data_new(coded_side_data, nb_coded_side_data,
10795  item->icc_profile_size, 0);
10796  if (!sd)
10797  return AVERROR(ENOMEM);
10798 
10799  memcpy(sd->data, item->icc_profile, item->icc_profile_size);
10800 
10801  return 0;
10802 }
10803 
10804 static int set_display_matrix_from_item(AVPacketSideData **coded_side_data, int *nb_coded_side_data,
10805  const HEIFItem *item)
10806 {
10807  int32_t *matrix;
10808  AVPacketSideData *sd = av_packet_side_data_new(coded_side_data,
10809  nb_coded_side_data,
10811  9 * sizeof(*matrix), 0);
10812  if (!sd)
10813  return AVERROR(ENOMEM);
10814 
10815  matrix = (int32_t*)sd->data;
10816  /* rotation is in the counter-clockwise direction whereas
10817  * av_display_rotation_set() expects its argument to be
10818  * oriented clockwise, so we need to negate it. */
10820  av_display_matrix_flip(matrix, item->hflip, item->vflip);
10821 
10822  return 0;
10823 }
10824 
10825 static int read_image_grid(AVFormatContext *s, const HEIFGrid *grid,
10826  AVStreamGroupTileGrid *tile_grid)
10827 {
10828  MOVContext *c = s->priv_data;
10829  const HEIFItem *item = grid->item;
10830  int64_t coded_width = 0, coded_height = 0;
10831  int64_t offset = 0, pos = avio_tell(s->pb);
10832  int64_t x = 0, y = 0;
10833  int i = 0;
10834  int tile_rows, tile_cols;
10835  int flags, size;
10836 
10837  if (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL)) {
10838  av_log(c->fc, AV_LOG_INFO, "grid box with non seekable input\n");
10839  return AVERROR_PATCHWELCOME;
10840  }
10841  if (item->is_idat_relative) {
10842  if (!c->idat_offset) {
10843  av_log(c->fc, AV_LOG_ERROR, "missing idat box required by the image grid\n");
10844  return AVERROR_INVALIDDATA;
10845  }
10846  offset = c->idat_offset;
10847  }
10848 
10849  if (offset > INT64_MAX - item->extent_offset)
10850  return AVERROR_INVALIDDATA;
10851 
10852  avio_seek(s->pb, item->extent_offset + offset, SEEK_SET);
10853 
10854  avio_r8(s->pb); /* version */
10855  flags = avio_r8(s->pb);
10856 
10857  tile_rows = avio_r8(s->pb) + 1;
10858  tile_cols = avio_r8(s->pb) + 1;
10859  /* actual width and height of output image */
10860  tile_grid->width = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
10861  tile_grid->height = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
10862 
10863  av_log(c->fc, AV_LOG_TRACE, "grid: grid_rows %d grid_cols %d output_width %d output_height %d\n",
10864  tile_rows, tile_cols, tile_grid->width, tile_grid->height);
10865 
10866  avio_seek(s->pb, pos, SEEK_SET);
10867 
10868  size = tile_rows * tile_cols;
10869  tile_grid->nb_tiles = grid->nb_tiles;
10870 
10871  if (tile_grid->nb_tiles != size)
10872  return AVERROR_INVALIDDATA;
10873 
10874  for (int i = 0; i < tile_cols; i++)
10875  coded_width += grid->tile_item_list[i]->width;
10876  for (int i = 0; i < size; i += tile_cols)
10877  coded_height += grid->tile_item_list[i]->height;
10878 
10879  if (coded_width > INT_MAX || coded_height > INT_MAX)
10880  return AVERROR_INVALIDDATA;
10881 
10882  tile_grid->coded_width = coded_width;
10883  tile_grid->coded_height = coded_height;
10884 
10885  tile_grid->offsets = av_calloc(tile_grid->nb_tiles, sizeof(*tile_grid->offsets));
10886  if (!tile_grid->offsets)
10887  return AVERROR(ENOMEM);
10888 
10889  while (y < tile_grid->coded_height) {
10890  int left_col = i;
10891 
10892  while (x < tile_grid->coded_width) {
10893  if (i == tile_grid->nb_tiles)
10894  return AVERROR_INVALIDDATA;
10895 
10896  tile_grid->offsets[i].idx = grid->tile_idx_list[i];
10897  tile_grid->offsets[i].horizontal = x;
10898  tile_grid->offsets[i].vertical = y;
10899 
10900  x += grid->tile_item_list[i++]->width;
10901  }
10902 
10903  if (x > tile_grid->coded_width) {
10904  av_log(c->fc, AV_LOG_ERROR, "Non uniform HEIF tiles\n");
10905  return AVERROR_INVALIDDATA;
10906  }
10907 
10908  x = 0;
10909  y += grid->tile_item_list[left_col]->height;
10910  }
10911 
10912  if (y > tile_grid->coded_height || i != tile_grid->nb_tiles) {
10913  av_log(c->fc, AV_LOG_ERROR, "Non uniform HEIF tiles\n");
10914  return AVERROR_INVALIDDATA;
10915  }
10916 
10917  return 0;
10918 }
10919 
10920 static int read_image_iovl(AVFormatContext *s, const HEIFGrid *grid,
10921  AVStreamGroupTileGrid *tile_grid)
10922 {
10923  MOVContext *c = s->priv_data;
10924  const HEIFItem *item = grid->item;
10925  uint16_t canvas_fill_value[4];
10926  int64_t offset = 0, pos = avio_tell(s->pb);
10927  int ret = 0, flags;
10928 
10929  if (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL)) {
10930  av_log(c->fc, AV_LOG_INFO, "iovl box with non seekable input\n");
10931  return AVERROR_PATCHWELCOME;
10932  }
10933  if (item->is_idat_relative) {
10934  if (!c->idat_offset) {
10935  av_log(c->fc, AV_LOG_ERROR, "missing idat box required by the image overlay\n");
10936  return AVERROR_INVALIDDATA;
10937  }
10938  offset = c->idat_offset;
10939  }
10940 
10941  if (offset > INT64_MAX - item->extent_offset)
10942  return AVERROR_INVALIDDATA;
10943 
10944  avio_seek(s->pb, item->extent_offset + offset, SEEK_SET);
10945 
10946  avio_r8(s->pb); /* version */
10947  flags = avio_r8(s->pb);
10948 
10949  for (int i = 0; i < 4; i++)
10950  canvas_fill_value[i] = avio_rb16(s->pb);
10951  av_log(c->fc, AV_LOG_TRACE, "iovl: canvas_fill_value { %u, %u, %u, %u }\n",
10952  canvas_fill_value[0], canvas_fill_value[1],
10953  canvas_fill_value[2], canvas_fill_value[3]);
10954  for (int i = 0; i < 4; i++)
10955  tile_grid->background[i] = canvas_fill_value[i];
10956 
10957  /* actual width and height of output image */
10958  tile_grid->width =
10959  tile_grid->coded_width = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
10960  tile_grid->height =
10961  tile_grid->coded_height = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
10962 
10963  av_log(c->fc, AV_LOG_TRACE, "iovl: output_width %d, output_height %d\n",
10964  tile_grid->width, tile_grid->height);
10965 
10966  tile_grid->nb_tiles = grid->nb_tiles;
10967  tile_grid->offsets = av_malloc_array(tile_grid->nb_tiles, sizeof(*tile_grid->offsets));
10968  if (!tile_grid->offsets) {
10969  ret = AVERROR(ENOMEM);
10970  goto fail;
10971  }
10972 
10973  for (int i = 0; i < tile_grid->nb_tiles; i++) {
10974  tile_grid->offsets[i].idx = grid->tile_idx_list[i];
10975  tile_grid->offsets[i].horizontal = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
10976  tile_grid->offsets[i].vertical = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
10977  av_log(c->fc, AV_LOG_TRACE, "iovl: stream_idx[%d] %u, "
10978  "horizontal_offset[%d] %d, vertical_offset[%d] %d\n",
10979  i, tile_grid->offsets[i].idx,
10980  i, tile_grid->offsets[i].horizontal, i, tile_grid->offsets[i].vertical);
10981  }
10982 
10983 fail:
10984  avio_seek(s->pb, pos, SEEK_SET);
10985 
10986  return ret;
10987 }
10988 
10990  AVPacketSideData **coded_side_data, int *nb_coded_side_data,
10991  const HEIFItem *ref)
10992 {
10993  MOVContext *c = s->priv_data;
10994  AVPacketSideData *sd;
10995  AVExifMetadata ifd = { 0 };
10996  AVBufferRef *buf;
10997  int64_t offset = 0, pos = avio_tell(s->pb);
10998  unsigned orientation_id = av_exif_get_tag_id("Orientation");
10999  int err;
11000 
11001  if (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL)) {
11002  av_log(c->fc, AV_LOG_WARNING, "Exif metadata with non seekable input\n");
11003  return AVERROR_PATCHWELCOME;
11004  }
11005  if (ref->is_idat_relative) {
11006  if (!c->idat_offset) {
11007  av_log(c->fc, AV_LOG_ERROR, "missing idat box required by the Exif metadata\n");
11008  return AVERROR_INVALIDDATA;
11009  }
11010  offset = c->idat_offset;
11011  }
11012 
11013  buf = av_buffer_alloc(ref->extent_length);
11014  if (!buf)
11015  return AVERROR(ENOMEM);
11016 
11017  if (offset > INT64_MAX - ref->extent_offset) {
11018  err = AVERROR(ENOMEM);
11019  goto fail;
11020  }
11021 
11022  avio_seek(s->pb, ref->extent_offset + offset, SEEK_SET);
11023  err = avio_read(s->pb, buf->data, ref->extent_length);
11024  if (err != ref->extent_length) {
11025  if (err > 0)
11026  err = AVERROR_INVALIDDATA;
11027  goto fail;
11028  }
11029 
11030  // HEIF spec states that Exif metadata is informative. The irot item property is
11031  // the normative source of rotation information. So we remove any Orientation tag
11032  // present in the Exif buffer.
11033  err = av_exif_parse_buffer(s, buf->data, ref->extent_length, &ifd, AV_EXIF_T_OFF);
11034  if (err < 0) {
11035  av_log(s, AV_LOG_ERROR, "Unable to parse Exif metadata\n");
11036  goto fail;
11037  }
11038 
11039  err = av_exif_remove_entry(s, &ifd, orientation_id, 0);
11040  if (err < 0)
11041  goto fail;
11042  else if (!err)
11043  goto finish;
11044 
11045  av_buffer_unref(&buf);
11046  err = av_exif_write(s, &ifd, &buf, AV_EXIF_T_OFF);
11047  if (err < 0)
11048  goto fail;
11049 
11050 finish:
11051  offset = AV_RB32(buf->data) + 4;
11052  if (offset >= buf->size) {
11053  err = AVERROR_INVALIDDATA;
11054  goto fail;
11055  }
11056  sd = av_packet_side_data_new(coded_side_data, nb_coded_side_data,
11057  AV_PKT_DATA_EXIF, buf->size - offset, 0);
11058  if (!sd) {
11059  err = AVERROR(ENOMEM);
11060  goto fail;
11061  }
11062  memcpy(sd->data, buf->data + offset, buf->size - offset);
11063 
11064  err = 0;
11065 fail:
11066  av_buffer_unref(&buf);
11067  av_exif_free(&ifd);
11068  avio_seek(s->pb, pos, SEEK_SET);
11069 
11070  return err;
11071 }
11072 
11074 {
11075  MOVContext *mov = s->priv_data;
11076 
11077  for (int i = 0; i < mov->nb_heif_grid; i++) {
11079  AVStreamGroupTileGrid *tile_grid;
11080  const HEIFGrid *grid = &mov->heif_grid[i];
11081  int err, loop = 1;
11082 
11083  if (!stg)
11084  return AVERROR(ENOMEM);
11085 
11086  stg->id = grid->item->item_id;
11087  tile_grid = stg->params.tile_grid;
11088 
11089  for (int j = 0; j < grid->nb_tiles; j++) {
11090  int tile_id = grid->tile_id_list[j];
11091  int k;
11092 
11093  for (k = 0; k < mov->nb_heif_item; k++) {
11094  HEIFItem *item = mov->heif_item[k];
11095  AVStream *st;
11096 
11097  if (!item || item->item_id != tile_id)
11098  continue;
11099  st = item->st;
11100  if (!st) {
11101  av_log(s, AV_LOG_WARNING, "HEIF item id %d from grid id %d doesn't "
11102  "reference a stream\n",
11103  tile_id, grid->item->item_id);
11104  ff_remove_stream_group(s, stg);
11105  loop = 0;
11106  break;
11107  }
11108 
11109  grid->tile_item_list[j] = item;
11110  grid->tile_idx_list[j] = stg->nb_streams;
11111 
11112  err = avformat_stream_group_add_stream(stg, st);
11113  if (err < 0) {
11114  int l;
11115  if (err != AVERROR(EEXIST))
11116  return err;
11117 
11118  for (l = 0; l < stg->nb_streams; l++)
11119  if (stg->streams[l]->index == st->index)
11120  break;
11121  av_assert0(l < stg->nb_streams);
11122  grid->tile_idx_list[j] = l;
11123  }
11124 
11125  if (item->item_id != mov->primary_item_id)
11127  break;
11128  }
11129 
11130  if (k == mov->nb_heif_item) {
11131  av_assert0(loop);
11132  av_log(s, AV_LOG_WARNING, "HEIF item id %d referenced by grid id %d doesn't "
11133  "exist\n",
11134  tile_id, grid->item->item_id);
11135  ff_remove_stream_group(s, stg);
11136  loop = 0;
11137  }
11138  if (!loop)
11139  break;
11140  }
11141 
11142  if (!loop)
11143  continue;
11144 
11145  switch (grid->item->type) {
11146  case MKTAG('g','r','i','d'):
11147  err = read_image_grid(s, grid, tile_grid);
11148  break;
11149  case MKTAG('i','o','v','l'):
11150  err = read_image_iovl(s, grid, tile_grid);
11151  break;
11152  default:
11153  av_assert0(0);
11154  }
11155  if (err < 0)
11156  return err;
11157 
11158  for (int j = 0; j < grid->item->nb_iref_list; j++) {
11159  HEIFItem *ref = get_heif_item(mov, grid->item->iref_list[j].item_id);
11160 
11161  av_assert0(ref);
11162  switch(ref->type) {
11163  case MKTAG('E','x','i','f'):
11164  err = mov_parse_exif_item(s, &tile_grid->coded_side_data,
11165  &tile_grid->nb_coded_side_data, ref);
11166  if (err < 0 && (s->error_recognition & AV_EF_EXPLODE))
11167  return err;
11168  break;
11169  default:
11170  break;
11171  }
11172  }
11173 
11174  /* rotation */
11175  if (grid->item->rotation || grid->item->hflip || grid->item->vflip) {
11177  &tile_grid->nb_coded_side_data, grid->item);
11178  if (err < 0)
11179  return err;
11180  }
11181 
11182  /* ICC profile */
11183  if (grid->item->icc_profile_size) {
11184  err = set_icc_profile_from_item(&tile_grid->coded_side_data,
11185  &tile_grid->nb_coded_side_data, grid->item);
11186  if (err < 0)
11187  return err;
11188  }
11189 
11190  if (grid->item->name)
11191  av_dict_set(&stg->metadata, "title", grid->item->name, 0);
11192  if (grid->item->item_id == mov->primary_item_id)
11194  }
11195 
11196  return 0;
11197 }
11198 
11200 {
11201  MOVContext *mov = s->priv_data;
11202  int err;
11203 
11204  for (int i = 0; i < mov->nb_heif_item; i++) {
11205  HEIFItem *item = mov->heif_item[i];
11206  MOVStreamContext *sc;
11207  AVStream *st;
11208  int64_t offset = 0;
11209 
11210  if (!item)
11211  continue;
11212  if (!item->st) {
11213  continue;
11214  }
11215  if (item->is_idat_relative) {
11216  if (!mov->idat_offset) {
11217  av_log(s, AV_LOG_ERROR, "Missing idat box for item %d\n", item->item_id);
11218  return AVERROR_INVALIDDATA;
11219  }
11220  offset = mov->idat_offset;
11221  }
11222 
11223  st = item->st;
11224  sc = st->priv_data;
11225  st->codecpar->width = item->width;
11226  st->codecpar->height = item->height;
11227 
11228  sc->sample_size = sc->stsz_sample_size = item->extent_length;
11229  sc->sample_count = 1;
11230 
11231  err = sanity_checks(s, sc, st->index);
11232  if (err)
11233  return AVERROR_INVALIDDATA;
11234 
11235  if (offset > INT64_MAX - item->extent_offset)
11236  return AVERROR_INVALIDDATA;
11237 
11238  sc->chunk_offsets[0] = item->extent_offset + offset;
11239 
11240  if (item->item_id == mov->primary_item_id)
11242 
11243  for (int j = 0; j < item->nb_iref_list; j++) {
11244  HEIFItem *ref = get_heif_item(mov, item->iref_list[j].item_id);
11245 
11246  av_assert0(ref);
11247  switch(ref->type) {
11248  case MKTAG('E','x','i','f'):
11251  if (err < 0 && (s->error_recognition & AV_EF_EXPLODE))
11252  return err;
11253  break;
11254  default:
11255  break;
11256  }
11257  }
11258 
11259  if (item->rotation || item->hflip || item->vflip) {
11261  &st->codecpar->nb_coded_side_data, item);
11262  if (err < 0)
11263  return err;
11264  }
11265 
11266  mov_build_index(mov, st);
11267  }
11268 
11269  if (mov->nb_heif_grid) {
11270  err = mov_parse_tiles(s);
11271  if (err < 0)
11272  return err;
11273  }
11274 
11275  return 0;
11276 }
11277 
11279 {
11280  int err;
11281 
11282  for (int i = 0; i < s->nb_streams; i++) {
11283  AVStreamGroup *stg;
11284  const AVDictionaryEntry *tcr;
11285  AVStream *st = s->streams[i];
11286 
11287  if (st->codecpar->codec_tag != MKTAG('t','m','c','d'))
11288  continue;
11289 
11291  if (!stg)
11292  return AVERROR(ENOMEM);
11293 
11294  stg->id = st->id;
11295  tcr = av_dict_get(st->metadata, "timecode", NULL, 0);
11296 
11297  for (int j = 0; j < s->nb_streams; j++) {
11298  AVStream *st2 = s->streams[j];
11299  MOVStreamContext *sc2 = st2->priv_data;
11300  MovTref *tag = mov_find_tref_tag(sc2, MKTAG('t','m','c','d'));
11301 
11302  if (!tag)
11303  continue;
11304 
11305  for (int k = 0; k < tag->nb_id; k++) {
11306  if (tag->id[k] != st->id)
11307  continue;
11308 
11309  err = avformat_stream_group_add_stream(stg, st2);
11310  if (err < 0)
11311  return err;
11312 
11313  if (tcr)
11314  av_dict_set(&st2->metadata, "timecode", tcr->value, AV_DICT_DONT_OVERWRITE);
11315  }
11316  }
11317 
11318  if (!stg->nb_streams) {
11319  ff_remove_stream_group(s, stg);
11320  continue;
11321  }
11322 
11323  err = avformat_stream_group_add_stream(stg, st);
11324  if (err < 0)
11325  return err;
11326 
11327  stg->params.tref->metadata_index = stg->nb_streams - 1;
11328  }
11330 
11331  return 0;
11332 }
11333 
11335  uint32_t *tref_id, int nb_tref_id, int first_index)
11336 {
11337  if (!nb_tref_id)
11338  return NULL;
11339 
11340  for (int i = first_index; i < s->nb_streams; i++)
11341  for (int j = 0; j < nb_tref_id; j++)
11342  if (s->streams[i]->index != st->index &&
11343  s->streams[i]->id == tref_id[j])
11344  return s->streams[i];
11345 
11346  return NULL;
11347 }
11348 
11350 {
11351  int err;
11352 
11353  // Don't try to add a group if there's only one track
11354  if (s->nb_streams <= 1)
11355  return 0;
11356 
11357  for (int i = 0; i < s->nb_streams; i++) {
11358  AVStreamGroup *stg;
11359  AVStream *st = s->streams[i];
11360  AVStream *st_ref;
11361  MOVStreamContext *sc = st->priv_data;
11362  MovTref *tag = mov_find_tref_tag(sc, MKTAG('c','d','s','c'));
11363 
11364  if (!tag)
11365  continue;
11366 
11367  st_ref = mov_find_reference_track(s, st, tag->id, tag->nb_id, 0);
11368  if (!st_ref) {
11369  int loglevel = (s->error_recognition & AV_EF_EXPLODE) ? AV_LOG_ERROR : AV_LOG_WARNING;
11370  av_log(s, loglevel, "Failed to find referenced stream\n");
11371  if (s->error_recognition & AV_EF_EXPLODE)
11372  return AVERROR_INVALIDDATA;
11373  continue;
11374  }
11375 
11377  if (!stg)
11378  return AVERROR(ENOMEM);
11379 
11380  stg->id = st->id;
11381 
11382  err = avformat_stream_group_add_stream(stg, st_ref);
11383  if (err < 0)
11384  return err;
11385 
11386  err = avformat_stream_group_add_stream(stg, st);
11387  if (err < 0)
11388  return err;
11389 
11390  stg->params.tref->metadata_index = stg->nb_streams - 1;
11391  }
11392 
11393  return 0;
11394 }
11395 
11397 {
11398  int err;
11399 
11400  // Don't try to add a group if there's only one track
11401  if (s->nb_streams <= 1)
11402  return 0;
11403 
11404  for (int i = 0; i < s->nb_streams; i++) {
11405  AVStreamGroup *stg;
11406  AVStream *st = s->streams[i];
11407  AVStream *st_base;
11408  MOVStreamContext *sc = st->priv_data;
11409  MovTref *tag = mov_find_tref_tag(sc, MKTAG('s','b','a','s'));
11410  int j = 0;
11411 
11412  /* Find an enhancement stream. */
11413  if (st->codecpar->codec_id != AV_CODEC_ID_LCEVC || !tag)
11414  continue;
11415 
11417  if (!stg)
11418  return AVERROR(ENOMEM);
11419 
11420  stg->id = st->id;
11421  stg->params.layered_video->width = st->codecpar->width;
11422  stg->params.layered_video->height = st->codecpar->height;
11423 
11424  while (st_base = mov_find_reference_track(s, st, tag->id, tag->nb_id, j)) {
11425  err = avformat_stream_group_add_stream(stg, st_base);
11426  if (err < 0)
11427  return err;
11428 
11429  j = st_base->index + 1;
11430  }
11431  if (!j) {
11432  int loglevel = (s->error_recognition & AV_EF_EXPLODE) ? AV_LOG_ERROR : AV_LOG_WARNING;
11433  av_log(s, loglevel, "Failed to find base stream for LCEVC stream\n");
11434  ff_remove_stream_group(s, stg);
11435  if (s->error_recognition & AV_EF_EXPLODE)
11436  return AVERROR_INVALIDDATA;
11437  continue;
11438  }
11439 
11440  err = avformat_stream_group_add_stream(stg, st);
11441  if (err < 0)
11442  return err;
11443 
11444  stg->params.layered_video->el_index = stg->nb_streams - 1;
11445  }
11446 
11447  return 0;
11448 }
11449 
11451 {
11452  int err;
11453 
11454  if (s->nb_streams <= 1)
11455  return 0;
11456 
11457  /* Identify legacy dual-track Dolby Vision profile 7 carriage per Annex
11458  * C of "Dolby Vision Streams Within the ISO Base Media File Format",
11459  * v2.7.1. The 'vdep' track reference type is shared with depth video
11460  * and multi-view dependencies. The spec-mandated DV-specific sample
11461  * entry combined with the dvcC configuration record disambiguates
11462  * those uses. */
11463  for (int i = 0; i < s->nb_streams; i++) {
11464  AVStreamGroup *stg;
11465  AVStream *st = s->streams[i];
11466  AVStream *st_base;
11467  MOVStreamContext *sc = st->priv_data;
11468  MovTref *tag = mov_find_tref_tag(sc, MKTAG('v','d','e','p'));
11469  const AVPacketSideData *sd;
11471 
11472  if (st->codecpar->codec_id != AV_CODEC_ID_HEVC || !tag)
11473  continue;
11474 
11475  if (st->codecpar->codec_tag != MKTAG('d','v','h','e') &&
11476  st->codecpar->codec_tag != MKTAG('d','v','h','1'))
11477  continue;
11478 
11482  if (!sd)
11483  continue;
11484  dovi = (const AVDOVIDecoderConfigurationRecord *)sd->data;
11485 
11486  /* EL track of a dual-track stream: rpu_present_flag = 1,
11487  * el_present_flag = 1, bl_present_flag = 0, dv_profile = 7. */
11488  if (dovi->dv_profile != 7 || !dovi->rpu_present_flag ||
11489  !dovi->el_present_flag || dovi->bl_present_flag)
11490  continue;
11491 
11492  st_base = mov_find_reference_track(s, st, tag->id, tag->nb_id, 0);
11493  if (!st_base) {
11494  int loglevel = (s->error_recognition & AV_EF_EXPLODE) ? AV_LOG_ERROR : AV_LOG_WARNING;
11495  av_log(s, loglevel, "Failed to find base layer for Dolby Vision EL stream\n");
11496  if (s->error_recognition & AV_EF_EXPLODE)
11497  return AVERROR_INVALIDDATA;
11498  continue;
11499  }
11500 
11502  if (!stg)
11503  return AVERROR(ENOMEM);
11504 
11505  stg->id = st->id;
11506 
11507  err = avformat_stream_group_add_stream(stg, st_base);
11508  if (err < 0)
11509  return err;
11510 
11511  err = avformat_stream_group_add_stream(stg, st);
11512  if (err < 0)
11513  return err;
11514 
11515  stg->params.layered_video->el_index = stg->nb_streams - 1;
11516  stg->params.layered_video->width = st_base->codecpar->width;
11517  stg->params.layered_video->height = st_base->codecpar->height;
11518  }
11519 
11520  return 0;
11521 }
11522 
11524 {
11525  int highest_id = 0, lowest_iamf_id = INT_MAX;
11526 
11527  for (int i = 0; i < s->nb_streams; i++) {
11528  const AVStream *st = s->streams[i];
11529  const MOVStreamContext *sc = st->priv_data;
11530  if (!sc->iamf)
11531  highest_id = FFMAX(highest_id, st->id);
11532  }
11533 
11534  for (int i = 0; i < s->nb_stream_groups; i++) {
11535  AVStreamGroup *stg = s->stream_groups[i];
11537  continue;
11538  for (int j = 0; j < stg->nb_streams; j++) {
11539  AVStream *st = stg->streams[j];
11540  lowest_iamf_id = FFMIN(lowest_iamf_id, st->id);
11541  }
11542  }
11543 
11544  if (highest_id < lowest_iamf_id)
11545  return;
11546 
11547  highest_id += !lowest_iamf_id;
11548  for (int i = 0; highest_id > 1 && i < s->nb_stream_groups; i++) {
11549  AVStreamGroup *stg = s->stream_groups[i];
11551  continue;
11552  for (int j = 0; j < stg->nb_streams; j++) {
11553  AVStream *st = stg->streams[j];
11554  MOVStreamContext *sc = st->priv_data;
11555  st->id += highest_id;
11556  sc->iamf_stream_offset = highest_id;
11557  }
11558  }
11559 }
11560 
11562 {
11563  MOVContext *mov = s->priv_data;
11564  AVIOContext *pb = s->pb;
11565  int j, err;
11566  MOVAtom atom = { AV_RL32("root") };
11567  int i;
11568 
11569  mov->fc = s;
11570  mov->trak_index = -1;
11571  mov->primary_item_id = -1;
11572  mov->cur_item_id = -1;
11573  /* .mov and .mp4 aren't streamable anyway (only progressive download if moov is before mdat) */
11574  if (pb->seekable & AVIO_SEEKABLE_NORMAL)
11575  atom.size = avio_size(pb);
11576  else
11577  atom.size = INT64_MAX;
11578 
11579  /* check MOV header */
11580  do {
11581  if (mov->moov_retry)
11582  avio_seek(pb, 0, SEEK_SET);
11583  if ((err = mov_read_default(mov, pb, atom)) < 0) {
11584  av_log(s, AV_LOG_ERROR, "error reading header\n");
11585  return err;
11586  }
11587  } while ((pb->seekable & AVIO_SEEKABLE_NORMAL) &&
11588  !mov->found_moov && (!mov->found_iloc || !mov->found_iinf) && !mov->moov_retry++);
11589  if (!mov->found_moov && !mov->found_iloc && !mov->found_iinf) {
11590  av_log(s, AV_LOG_ERROR, "moov atom not found\n");
11591  return AVERROR_INVALIDDATA;
11592  }
11593  av_log(mov->fc, AV_LOG_TRACE, "on_parse_exit_offset=%"PRId64"\n", avio_tell(pb));
11594 
11595  if (mov->found_iloc && mov->found_iinf) {
11596  err = mov_parse_heif_items(s);
11597  if (err < 0)
11598  return err;
11599  }
11600  // prevent iloc and iinf boxes from being parsed while reading packets.
11601  // this is needed because an iinf box may have been parsed but ignored
11602  // for having old infe boxes which create no streams.
11603  mov->found_iloc = mov->found_iinf = 1;
11604 
11605  if (pb->seekable & AVIO_SEEKABLE_NORMAL) {
11606  if (mov->nb_chapter_tracks > 0 && !mov->ignore_chapters)
11608  for (i = 0; i < s->nb_streams; i++)
11609  if (s->streams[i]->codecpar->codec_tag == AV_RL32("tmcd")) {
11610  mov_read_timecode_track(s, s->streams[i]);
11611  } else if (s->streams[i]->codecpar->codec_tag == AV_RL32("rtmd")) {
11612  mov_read_rtmd_track(s, s->streams[i]);
11613  }
11614  }
11615 
11616  /* Create metadata stream groups. */
11617  err = mov_parse_cdsc_streams(s);
11618  if (err < 0)
11619  return err;
11620 
11621  /* copy timecode metadata from tmcd tracks to the related video streams */
11622  err = mov_parse_tmcd_streams(s);
11623  if (err < 0)
11624  return err;
11625 
11626  /* Create LCEVC stream groups. */
11627  err = mov_parse_lcevc_streams(s);
11628  if (err < 0)
11629  return err;
11630 
11631  /* Create Dolby Vision Profile 7 stream groups. */
11632  err = mov_parse_dovi_streams(s);
11633  if (err < 0)
11634  return err;
11635 
11636  for (i = 0; i < s->nb_streams; i++) {
11637  AVStream *st = s->streams[i];
11638  FFStream *const sti = ffstream(st);
11639  MOVStreamContext *sc = st->priv_data;
11640  uint32_t dvdsub_clut[FF_DVDCLUT_CLUT_LEN] = {0};
11641  fix_timescale(mov, sc);
11642 
11643  /* Set the primary extradata based on the first Sample if it doesn't reference the first stsd entry. */
11644  if (sc->stsc_count && sc->extradata_size && !sc->iamf &&
11645  sc->stsc_data[0].id > 1 && sc->stsc_data[0].id <= sc->stsd_count) {
11646  sc->last_stsd_index = sc->stsc_data[0].id - 1;
11647  av_freep(&st->codecpar->extradata);
11649  if (sc->extradata_size[sc->last_stsd_index]) {
11651  if (!st->codecpar->extradata)
11652  return AVERROR(ENOMEM);
11653  memcpy(st->codecpar->extradata, sc->extradata[sc->last_stsd_index], sc->extradata_size[sc->last_stsd_index]);
11654  }
11655  }
11656 
11657  if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
11658  st->codecpar->codec_id == AV_CODEC_ID_AAC) {
11660  }
11661  if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && sc->nb_frames_for_fps > 0 && sc->duration_for_fps > 0)
11663  sc->time_scale*(int64_t)sc->nb_frames_for_fps, sc->duration_for_fps, INT_MAX);
11665  if (st->codecpar->width <= 0 || st->codecpar->height <= 0) {
11666  st->codecpar->width = sc->width;
11667  st->codecpar->height = sc->height;
11668  }
11671 
11672  for (j = 0; j < FF_DVDCLUT_CLUT_LEN; j++)
11673  dvdsub_clut[j] = AV_RB32(st->codecpar->extradata + j * 4);
11674 
11675  err = ff_dvdclut_yuv_to_rgb(dvdsub_clut, FF_DVDCLUT_CLUT_SIZE);
11676  if (err < 0)
11677  return err;
11678 
11679  av_freep(&st->codecpar->extradata);
11680  st->codecpar->extradata_size = 0;
11681 
11683  st->codecpar);
11684  if (err < 0)
11685  return err;
11686  }
11687  }
11688  if (mov->handbrake_version &&
11689  mov->handbrake_version <= 1000000*0 + 1000*10 + 2 && // 0.10.2
11690  st->codecpar->codec_id == AV_CODEC_ID_MP3) {
11691  av_log(s, AV_LOG_VERBOSE, "Forcing full parsing for mp3 stream\n");
11693  }
11694  }
11695 
11696  if (mov->trex_data || mov->use_mfra_for > 0) {
11697  for (i = 0; i < s->nb_streams; i++) {
11698  AVStream *st = s->streams[i];
11699  MOVStreamContext *sc = st->priv_data;
11700  if (sc->duration_for_fps > 0) {
11701  /* Akin to sc->data_size * 8 * sc->time_scale / sc->duration_for_fps but accounting for overflows. */
11703  if (st->codecpar->bit_rate == INT64_MIN) {
11704  av_log(s, AV_LOG_WARNING, "Overflow during bit rate calculation %"PRId64" * 8 * %d\n",
11705  sc->data_size, sc->time_scale);
11706  st->codecpar->bit_rate = 0;
11707  if (s->error_recognition & AV_EF_EXPLODE)
11708  return AVERROR_INVALIDDATA;
11709  }
11710  }
11711  }
11712  }
11713 
11714  for (i = 0; i < mov->bitrates_count && i < s->nb_streams; i++) {
11715  if (mov->bitrates[i]) {
11716  s->streams[i]->codecpar->bit_rate = mov->bitrates[i];
11717  }
11718  }
11719 
11721 
11722  for (i = 0; i < s->nb_streams; i++) {
11723  AVStream *st = s->streams[i];
11724  MOVStreamContext *sc = st->priv_data;
11725 
11726  switch (st->codecpar->codec_type) {
11727  case AVMEDIA_TYPE_AUDIO:
11728  err = ff_replaygain_export(st, s->metadata);
11729  if (err < 0)
11730  return err;
11731  break;
11732  case AVMEDIA_TYPE_VIDEO:
11733  if (sc->display_matrix) {
11736  (uint8_t*)sc->display_matrix, sizeof(int32_t) * 9, 0))
11737  return AVERROR(ENOMEM);
11738 
11739  sc->display_matrix = NULL;
11740  }
11741  if (sc->stereo3d) {
11744  (uint8_t *)sc->stereo3d, sc->stereo3d_size, 0))
11745  return AVERROR(ENOMEM);
11746 
11747  sc->stereo3d = NULL;
11748  }
11749  if (sc->spherical) {
11752  (uint8_t *)sc->spherical, sc->spherical_size, 0))
11753  return AVERROR(ENOMEM);
11754 
11755  sc->spherical = NULL;
11756  }
11757  if (sc->mastering) {
11760  (uint8_t *)sc->mastering, sc->mastering_size, 0))
11761  return AVERROR(ENOMEM);
11762 
11763  sc->mastering = NULL;
11764  }
11765  if (sc->coll) {
11768  (uint8_t *)sc->coll, sc->coll_size, 0))
11769  return AVERROR(ENOMEM);
11770 
11771  sc->coll = NULL;
11772  }
11773  if (sc->ambient) {
11776  (uint8_t *) sc->ambient, sc->ambient_size, 0))
11777  return AVERROR(ENOMEM);
11778 
11779  sc->ambient = NULL;
11780  }
11781  break;
11782  }
11783  }
11784 
11785  fix_stream_ids(s);
11786 
11788 
11789  for (i = 0; i < mov->frag_index.nb_items; i++)
11790  if (mov->frag_index.item[i].moof_offset <= mov->fragment.moof_offset)
11791  mov->frag_index.item[i].headers_read = 1;
11792 
11793  return 0;
11794 }
11795 
11797 {
11799  int64_t best_dts = INT64_MAX;
11800  int i;
11801  MOVContext *mov = s->priv_data;
11802  int no_interleave = !mov->interleaved_read || !(s->pb->seekable & AVIO_SEEKABLE_NORMAL);
11803  for (i = 0; i < s->nb_streams; i++) {
11804  AVStream *avst = s->streams[i];
11805  FFStream *const avsti = ffstream(avst);
11806  MOVStreamContext *msc = avst->priv_data;
11807  if (msc->pb && msc->current_sample < avsti->nb_index_entries) {
11808  AVIndexEntry *current_sample = &avsti->index_entries[msc->current_sample];
11809  int64_t dts = av_rescale(current_sample->timestamp, AV_TIME_BASE, msc->time_scale);
11810  uint64_t dtsdiff = best_dts > dts ? best_dts - (uint64_t)dts : ((uint64_t)dts - best_dts);
11811  av_log(s, AV_LOG_TRACE, "stream %d, sample %d, dts %"PRId64"\n", i, msc->current_sample, dts);
11812  if (!sample || (no_interleave && current_sample->pos < sample->pos) ||
11813  ((s->pb->seekable & AVIO_SEEKABLE_NORMAL) &&
11814  ((msc->pb != s->pb && dts < best_dts) || (msc->pb == s->pb && dts != AV_NOPTS_VALUE &&
11815  ((dtsdiff <= AV_TIME_BASE && current_sample->pos < sample->pos) ||
11816  (dtsdiff > AV_TIME_BASE && dts < best_dts && mov->interleaved_read)))))) {
11817  sample = current_sample;
11818  best_dts = dts;
11819  *st = avst;
11820  }
11821  }
11822  }
11823  return sample;
11824 }
11825 
11826 static int should_retry(AVIOContext *pb, int error_code) {
11827  if (error_code == AVERROR_EOF || avio_feof(pb))
11828  return 0;
11829 
11830  return 1;
11831 }
11832 
11833 static int mov_switch_root(AVFormatContext *s, int64_t target, int index)
11834 {
11835  int ret;
11836  MOVContext *mov = s->priv_data;
11837 
11838  if (index >= 0 && index < mov->frag_index.nb_items)
11839  target = mov->frag_index.item[index].moof_offset;
11840  if (target >= 0 && avio_seek(s->pb, target, SEEK_SET) != target) {
11841  av_log(mov->fc, AV_LOG_ERROR, "root atom offset 0x%"PRIx64": partial file\n", target);
11842  return AVERROR_INVALIDDATA;
11843  }
11844 
11845  mov->next_root_atom = 0;
11846  if ((index < 0 && target >= 0) || index >= mov->frag_index.nb_items)
11847  index = search_frag_moof_offset(&mov->frag_index, target);
11848  if (index >= 0 && index < mov->frag_index.nb_items &&
11849  mov->frag_index.item[index].moof_offset == target) {
11850  if (index + 1 < mov->frag_index.nb_items)
11851  mov->next_root_atom = mov->frag_index.item[index + 1].moof_offset;
11852  if (mov->frag_index.item[index].headers_read)
11853  return 0;
11854  mov->frag_index.item[index].headers_read = 1;
11855  }
11856 
11857  mov->found_mdat = 0;
11858 
11859  ret = mov_read_default(mov, s->pb, (MOVAtom){ AV_RL32("root"), INT64_MAX });
11860  if (ret < 0)
11861  return ret;
11862  if (avio_feof(s->pb))
11863  return AVERROR_EOF;
11864  av_log(s, AV_LOG_TRACE, "read fragments, offset 0x%"PRIx64"\n", avio_tell(s->pb));
11865 
11866  return 1;
11867 }
11868 
11870 {
11871  MOVStreamContext *sc = st->priv_data;
11872  uint8_t *side, *extradata;
11873  int extradata_size;
11874 
11875  /* Save the current index. */
11876  sc->last_stsd_index = sc->stsc_data[sc->stsc_index].id - 1;
11877 
11878  /* Notify the decoder that extradata changed. */
11879  extradata_size = sc->extradata_size[sc->last_stsd_index];
11880  extradata = sc->extradata[sc->last_stsd_index];
11881  if (st->discard != AVDISCARD_ALL && extradata_size > 0 && extradata) {
11884  extradata_size);
11885  if (!side)
11886  return AVERROR(ENOMEM);
11887  memcpy(side, extradata, extradata_size);
11888  }
11889 
11890  return 0;
11891 }
11892 
11893 static int get_eia608_packet(AVIOContext *pb, AVPacket *pkt, int src_size)
11894 {
11895  /* We can't make assumptions about the structure of the payload,
11896  because it may include multiple cdat and cdt2 samples. */
11897  const uint32_t cdat = AV_RB32("cdat");
11898  const uint32_t cdt2 = AV_RB32("cdt2");
11899  int ret, out_size = 0;
11900 
11901  /* a valid payload must have size, 4cc, and at least 1 byte pair: */
11902  if (src_size < 10)
11903  return AVERROR_INVALIDDATA;
11904 
11905  /* avoid an int overflow: */
11906  if ((src_size - 8) / 2 >= INT_MAX / 3)
11907  return AVERROR_INVALIDDATA;
11908 
11909  ret = av_new_packet(pkt, ((src_size - 8) / 2) * 3);
11910  if (ret < 0)
11911  return ret;
11912 
11913  /* parse and re-format the c608 payload in one pass. */
11914  while (src_size >= 10) {
11915  const uint32_t atom_size = avio_rb32(pb);
11916  const uint32_t atom_type = avio_rb32(pb);
11917  const uint32_t data_size = atom_size - 8;
11918  const uint8_t cc_field =
11919  atom_type == cdat ? 1 :
11920  atom_type == cdt2 ? 2 :
11921  0;
11922 
11923  /* account for bytes consumed for atom size and type. */
11924  src_size -= 8;
11925 
11926  /* make sure the data size stays within the buffer boundaries. */
11927  if (data_size < 2 || data_size > src_size) {
11929  break;
11930  }
11931 
11932  /* make sure the data size is consistent with N byte pairs. */
11933  if (data_size % 2 != 0) {
11935  break;
11936  }
11937 
11938  if (!cc_field) {
11939  /* neither cdat or cdt2 ... skip it */
11940  avio_skip(pb, data_size);
11941  src_size -= data_size;
11942  continue;
11943  }
11944 
11945  for (uint32_t i = 0; i < data_size; i += 2) {
11946  pkt->data[out_size] = (0x1F << 3) | (1 << 2) | (cc_field - 1);
11947  pkt->data[out_size + 1] = avio_r8(pb);
11948  pkt->data[out_size + 2] = avio_r8(pb);
11949  out_size += 3;
11950  src_size -= 2;
11951  }
11952  }
11953 
11954  if (src_size > 0)
11955  /* skip any remaining unread portion of the input payload */
11956  avio_skip(pb, src_size);
11957 
11959  return ret;
11960 }
11961 
11963  int64_t current_index, AVPacket *pkt)
11964 {
11965  MOVContext *mov = s->priv_data;
11966  MOVStreamContext *sc = st->priv_data;
11967 
11968  pkt->stream_index = sc->ffindex;
11969  pkt->dts = sample->timestamp;
11970  if (sample->flags & AVINDEX_DISCARD_FRAME) {
11972  }
11973  if (sc->stts_count && sc->tts_index < sc->tts_count)
11974  pkt->duration = sc->tts_data[sc->tts_index].duration;
11975  if (sc->ctts_count && sc->tts_index < sc->tts_count) {
11977  } else {
11978  if (pkt->duration == 0) {
11979  int64_t next_dts = (sc->current_sample < ffstream(st)->nb_index_entries) ?
11981  if (next_dts >= pkt->dts)
11982  pkt->duration = next_dts - pkt->dts;
11983  }
11984  pkt->pts = pkt->dts;
11985  }
11986 
11987  if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO && !mov->fragment.found_tfhd &&
11989  int64_t pts = av_rescale_q(pkt->pts, st->time_base, (AVRational){ 1, st->codecpar->sample_rate });
11990  int64_t total = av_rescale_q(st->duration, st->time_base, (AVRational){ 1, st->codecpar->sample_rate });
11992 
11993  if (st->duration < pkt->pts) {
11994  duration = 0;
11995  } else
11996  duration = FFMIN(duration, (uint64_t)st->duration - pkt->pts);
11997 
11998  duration = av_rescale_q(duration, st->time_base, (AVRational){ 1, st->codecpar->sample_rate });
11999 
12000  if (!ffstream(st)->first_discard_sample)
12002  if (!ffstream(st)->last_discard_sample)
12003  ffstream(st)->last_discard_sample = total;
12004  }
12005 
12006  if (sc->tts_data && sc->tts_index < sc->tts_count) {
12007  /* update tts context */
12008  sc->tts_sample++;
12009  if (sc->tts_index < sc->tts_count &&
12010  sc->tts_data[sc->tts_index].count == sc->tts_sample) {
12011  sc->tts_index++;
12012  sc->tts_sample = 0;
12013  }
12014  }
12015 
12016  if (sc->sdtp_data && sc->current_sample <= sc->sdtp_count) {
12017  uint8_t sample_flags = sc->sdtp_data[sc->current_sample - 1];
12018  uint8_t sample_is_depended_on = (sample_flags >> 2) & 0x3;
12019  pkt->flags |= sample_is_depended_on == MOV_SAMPLE_DEPENDENCY_NO ? AV_PKT_FLAG_DISPOSABLE : 0;
12020  }
12021  pkt->flags |= sample->flags & AVINDEX_KEYFRAME ? AV_PKT_FLAG_KEY : 0;
12022  pkt->pos = sample->pos;
12023 
12024  /* Multiple stsd handling. */
12025  if (sc->stsc_data) {
12026  if (sc->stsc_data[sc->stsc_index].id > 0 &&
12027  sc->stsc_data[sc->stsc_index].id - 1 < sc->stsd_count &&
12028  sc->stsc_data[sc->stsc_index].id - 1 != sc->last_stsd_index) {
12029  int ret = mov_change_extradata(st, pkt);
12030  if (ret < 0)
12031  return ret;
12032  }
12033 
12034  /* Update the stsc index for the next sample */
12035  sc->stsc_sample++;
12036  if (mov_stsc_index_valid(sc->stsc_index, sc->stsc_count) &&
12037  mov_get_stsc_samples(sc, sc->stsc_index) == sc->stsc_sample) {
12038  sc->stsc_index++;
12039  sc->stsc_sample = 0;
12040  }
12041  }
12042 
12043  return 0;
12044 }
12045 
12047 {
12048  MOVContext *mov = s->priv_data;
12049  MOVStreamContext *sc;
12051  AVStream *st = NULL;
12052  FFStream *avsti = NULL;
12053  int64_t current_index;
12054  int ret;
12055  int i;
12056  mov->fc = s;
12057  retry:
12058  if (s->pb->pos == 0) {
12059 
12060  // Discard current fragment index
12061  if (mov->frag_index.allocated_size > 0) {
12062  for(int i = 0; i < mov->frag_index.nb_items; i++) {
12064  }
12065  av_freep(&mov->frag_index.item);
12066  mov->frag_index.nb_items = 0;
12067  mov->frag_index.allocated_size = 0;
12068  mov->frag_index.current = -1;
12069  mov->frag_index.complete = 0;
12070  }
12071 
12072  for (i = 0; i < s->nb_streams; i++) {
12073  AVStream *avst = s->streams[i];
12074  MOVStreamContext *msc = avst->priv_data;
12075 
12076  // Clear current sample
12077  mov_current_sample_set(msc, 0);
12078  msc->tts_index = 0;
12079 
12080  // Discard current index entries
12081  avsti = ffstream(avst);
12082  if (avsti->index_entries_allocated_size > 0) {
12083  av_freep(&avsti->index_entries);
12084  avsti->index_entries_allocated_size = 0;
12085  avsti->nb_index_entries = 0;
12086  }
12087  }
12088 
12089  if ((ret = mov_switch_root(s, -1, -1)) < 0)
12090  return ret;
12091  }
12092  sample = mov_find_next_sample(s, &st);
12093  if (!sample || (mov->next_root_atom && sample->pos > mov->next_root_atom)) {
12094  if (!mov->next_root_atom)
12095  return AVERROR_EOF;
12096  if ((ret = mov_switch_root(s, mov->next_root_atom, -1)) < 0)
12097  return ret;
12098  goto retry;
12099  }
12100  sc = st->priv_data;
12101  /* must be done just before reading, to avoid infinite loop on sample */
12102  current_index = sc->current_index;
12104 
12105  if (mov->next_root_atom) {
12106  sample->pos = FFMIN(sample->pos, mov->next_root_atom);
12107  sample->size = FFMIN(sample->size, (mov->next_root_atom - sample->pos));
12108  }
12109 
12110  if (st->discard != AVDISCARD_ALL || sc->iamf) {
12111  int64_t ret64 = avio_seek(sc->pb, sample->pos, SEEK_SET);
12112  if (ret64 != sample->pos) {
12113  av_log(mov->fc, AV_LOG_ERROR, "stream %d, offset 0x%"PRIx64": partial file\n",
12114  sc->ffindex, sample->pos);
12115  if (should_retry(sc->pb, ret64)) {
12117  } else if (ret64 < 0) {
12118  return (int)ret64;
12119  }
12120  return AVERROR_INVALIDDATA;
12121  }
12122 
12123  if (st->discard == AVDISCARD_NONKEY && !(sample->flags & AVINDEX_KEYFRAME)) {
12124  av_log(mov->fc, AV_LOG_DEBUG, "Nonkey frame from stream %d discarded due to AVDISCARD_NONKEY\n", sc->ffindex);
12125  goto retry;
12126  }
12127 
12128  if (st->codecpar->codec_id == AV_CODEC_ID_EIA_608 && sample->size > 8)
12129  ret = get_eia608_packet(sc->pb, pkt, sample->size);
12130 #if CONFIG_IAMFDEC
12131  else if (sc->iamf) {
12132  int64_t pts, dts, pos, duration;
12133  int flags, size = sample->size;
12134  ret = mov_finalize_packet(s, st, sample, current_index, pkt);
12135  pts = pkt->pts; dts = pkt->dts;
12136  pos = pkt->pos; flags = pkt->flags;
12137  duration = pkt->duration;
12138  while (!ret && size > 0) {
12139  ret = ff_iamf_read_packet(s, sc->iamf, sc->pb, size, sc->iamf_stream_offset, pkt);
12140  if (ret < 0) {
12141  if (should_retry(sc->pb, ret))
12143  return ret;
12144  }
12145  size -= ret;
12146 
12147  if (pkt->flags & AV_PKT_FLAG_DISCARD) {
12149  ret = 0;
12150  continue;
12151  }
12152  pkt->pts = pts; pkt->dts = dts;
12153  pkt->pos = pos; pkt->flags |= flags;
12154  pkt->duration = duration;
12155  ret = ff_buffer_packet(s, pkt);
12156  }
12157  if (!ret)
12158  return FFERROR_REDO;
12159  }
12160 #endif
12161  else if (st->codecpar->codec_id == AV_CODEC_ID_APV && sample->size > 4) {
12162  uint32_t au_size = avio_rb32(sc->pb);
12163  int explode = !!(mov->fc->error_recognition & AV_EF_EXPLODE);
12164  if (au_size > sample->size - 4) {
12165  av_log(s, explode ? AV_LOG_ERROR : AV_LOG_WARNING,
12166  "APV au_size %u exceeds sample body %d\n",
12167  au_size, sample->size - 4);
12168  if (explode)
12169  return AVERROR_INVALIDDATA;
12170  au_size = sample->size - 4;
12171  }
12172  ret = av_get_packet(sc->pb, pkt, au_size);
12173  } else
12174  ret = av_get_packet(sc->pb, pkt, sample->size);
12175  if (ret < 0) {
12176  if (should_retry(sc->pb, ret)) {
12178  }
12179  return ret;
12180  }
12181 #if CONFIG_DV_DEMUXER
12182  if (mov->dv_demux && sc->dv_audio_container) {
12185  if (ret < 0)
12186  return ret;
12188  if (ret < 0)
12189  return ret;
12190  }
12191 #endif
12192  if (sc->has_palette) {
12193  uint8_t *pal;
12194 
12196  if (!pal) {
12197  av_log(mov->fc, AV_LOG_ERROR, "Cannot append palette to packet\n");
12198  } else {
12199  memcpy(pal, sc->palette, AVPALETTE_SIZE);
12200  sc->has_palette = 0;
12201  }
12202  }
12203  if (st->codecpar->codec_id == AV_CODEC_ID_MP3 && !ffstream(st)->need_parsing && pkt->size > 4) {
12204  if (ff_mpa_check_header(AV_RB32(pkt->data)) < 0)
12206  }
12207  }
12208 
12209  ret = mov_finalize_packet(s, st, sample, current_index, pkt);
12210  if (ret < 0)
12211  return ret;
12212 
12213  if (st->discard == AVDISCARD_ALL)
12214  goto retry;
12215 
12216  if (mov->aax_mode)
12217  aax_filter(pkt->data, pkt->size, mov);
12218 
12219  ret = cenc_filter(mov, st, sc, pkt, current_index);
12220  if (ret < 0) {
12221  return ret;
12222  }
12223 
12224  return 0;
12225 }
12226 
12228 {
12229  MOVContext *mov = s->priv_data;
12230  int index;
12231 
12232  if (!mov->frag_index.complete)
12233  return 0;
12234 
12235  index = search_frag_timestamp(s, &mov->frag_index, st, timestamp);
12236  if (index < 0)
12237  index = 0;
12238  if (!mov->frag_index.item[index].headers_read)
12239  return mov_switch_root(s, -1, index);
12240  if (index + 1 < mov->frag_index.nb_items)
12241  mov->next_root_atom = mov->frag_index.item[index + 1].moof_offset;
12242 
12243  return 0;
12244 }
12245 
12246 static int is_open_key_sample(const MOVStreamContext *sc, int sample)
12247 {
12248  // TODO: a bisect search would scale much better
12249  for (int i = 0; i < sc->open_key_samples_count; i++) {
12250  const int oks = sc->open_key_samples[i];
12251  if (oks == sample)
12252  return 1;
12253  if (oks > sample) /* list is monotically increasing so we can stop early */
12254  break;
12255  }
12256  return 0;
12257 }
12258 
12259 /*
12260  * Some key sample may be key frames but not IDR frames, so a random access to
12261  * them may not be allowed.
12262  */
12263 static int can_seek_to_key_sample(AVStream *st, int sample, int64_t requested_pts)
12264 {
12265  MOVStreamContext *sc = st->priv_data;
12266  FFStream *const sti = ffstream(st);
12267  int64_t key_sample_dts, key_sample_pts;
12268 
12269  if (st->codecpar->codec_id != AV_CODEC_ID_HEVC)
12270  return 1;
12271 
12272  if (sample >= sc->sample_offsets_count)
12273  return 1;
12274 
12275  av_assert0(sample >= 0);
12276  key_sample_dts = sti->index_entries[sample].timestamp;
12277  key_sample_pts = key_sample_dts + sc->sample_offsets[sample] + sc->dts_shift;
12278 
12279  /*
12280  * If the sample needs to be presented before an open key sample, they may
12281  * not be decodable properly, even though they come after in decoding
12282  * order.
12283  */
12284  if (is_open_key_sample(sc, sample) && key_sample_pts > requested_pts)
12285  return 0;
12286 
12287  return 1;
12288 }
12289 
12290 static int mov_seek_stream(AVFormatContext *s, AVStream *st, int64_t timestamp, int flags)
12291 {
12292  MOVStreamContext *sc = st->priv_data;
12293  FFStream *const sti = ffstream(st);
12294  int sample, time_sample, ret, requested_sample;
12295  int64_t next_ts;
12296  unsigned int i;
12297 
12298  // Here we consider timestamp to be PTS, hence try to offset it so that we
12299  // can search over the DTS timeline.
12300  timestamp -= (sc->min_corrected_pts + sc->dts_shift);
12301 
12302  ret = mov_seek_fragment(s, st, timestamp);
12303  if (ret < 0)
12304  return ret;
12305 
12306  for (;;) {
12307  sample = av_index_search_timestamp(st, timestamp, flags);
12308  av_log(s, AV_LOG_TRACE, "stream %d, timestamp %"PRId64", sample %d\n", st->index, timestamp, sample);
12309  if (sample < 0 && sti->nb_index_entries && timestamp < sti->index_entries[0].timestamp)
12310  sample = 0;
12311  if (sample < 0) /* not sure what to do */
12312  return AVERROR_INVALIDDATA;
12313 
12314  if (!sample || can_seek_to_key_sample(st, sample, timestamp))
12315  break;
12316 
12317  next_ts = timestamp - FFMAX(sc->min_sample_duration, 1);
12318  requested_sample = av_index_search_timestamp(st, next_ts, flags);
12319  if (requested_sample < 0)
12320  return AVERROR_INVALIDDATA;
12321 
12322  // If we've reached a different sample trying to find a good pts to
12323  // seek to, give up searching because we'll end up seeking back to
12324  // sample 0 on every seek.
12325  if (sample != requested_sample && !can_seek_to_key_sample(st, requested_sample, next_ts))
12326  break;
12327 
12328  timestamp = next_ts;
12329  }
12330 
12332  av_log(s, AV_LOG_TRACE, "stream %d, found sample %d\n", st->index, sc->current_sample);
12333  /* adjust time to sample index */
12334  if (sc->tts_data) {
12335  time_sample = 0;
12336  for (i = 0; i < sc->tts_count; i++) {
12337  int next = time_sample + sc->tts_data[i].count;
12338  if (next > sc->current_sample) {
12339  sc->tts_index = i;
12340  sc->tts_sample = sc->current_sample - time_sample;
12341  break;
12342  }
12343  time_sample = next;
12344  }
12345  }
12346 
12347  /* adjust stsd index */
12348  if (sc->chunk_count) {
12349  time_sample = 0;
12350  for (i = 0; i < sc->stsc_count; i++) {
12351  int64_t next = time_sample + mov_get_stsc_samples(sc, i);
12352  if (next > sc->current_sample) {
12353  sc->stsc_index = i;
12354  sc->stsc_sample = sc->current_sample - time_sample;
12355  break;
12356  }
12357  av_assert0(next == (int)next);
12358  time_sample = next;
12359  }
12360  }
12361 
12362  return sample;
12363 }
12364 
12366 {
12367  FFStream *const sti = ffstream(st);
12368  int64_t first_ts = sti->index_entries[0].timestamp;
12370  int64_t off;
12371 
12373  return 0;
12374 
12375  /* compute skip samples according to stream initial_padding, seek ts and first ts */
12376  off = av_rescale_q(ts - first_ts, st->time_base,
12377  (AVRational){1, st->codecpar->sample_rate});
12378  return FFMAX(st->codecpar->initial_padding - off, 0);
12379 }
12380 
12381 static int mov_read_seek(AVFormatContext *s, int stream_index, int64_t sample_time, int flags)
12382 {
12383  MOVContext *mc = s->priv_data;
12384  AVStream *st;
12385  FFStream *sti;
12386  int sample;
12387  int i;
12388 
12389  if (stream_index >= s->nb_streams)
12390  return AVERROR_INVALIDDATA;
12391 
12392  st = s->streams[stream_index];
12393  sti = ffstream(st);
12394  sample = mov_seek_stream(s, st, sample_time, flags);
12395  if (sample < 0)
12396  return sample;
12397 
12398  if (mc->seek_individually) {
12399  /* adjust seek timestamp to found sample timestamp */
12400  int64_t seek_timestamp = sti->index_entries[sample].timestamp;
12402 
12403  for (i = 0; i < s->nb_streams; i++) {
12404  AVStream *const st = s->streams[i];
12405  FFStream *const sti = ffstream(st);
12406  int64_t timestamp;
12407 
12408  if (stream_index == i)
12409  continue;
12410 
12411  timestamp = av_rescale_q(seek_timestamp, s->streams[stream_index]->time_base, st->time_base);
12412  sample = mov_seek_stream(s, st, timestamp, flags);
12413  if (sample >= 0)
12415  }
12416  } else {
12417  for (i = 0; i < s->nb_streams; i++) {
12418  MOVStreamContext *sc;
12419  st = s->streams[i];
12420  sc = st->priv_data;
12421  mov_current_sample_set(sc, 0);
12422  }
12423  while (1) {
12424  MOVStreamContext *sc;
12426  if (!entry)
12427  return AVERROR_INVALIDDATA;
12428  sc = st->priv_data;
12429  if (sc->ffindex == stream_index && sc->current_sample == sample)
12430  break;
12432  }
12433  }
12434  return 0;
12435 }
12436 
12437 #define OFFSET(x) offsetof(MOVContext, x)
12438 #define FLAGS AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM
12439 static const AVOption mov_options[] = {
12440  {"use_absolute_path",
12441  "allow using absolute path when opening alias, this is a possible security issue",
12442  OFFSET(use_absolute_path), AV_OPT_TYPE_BOOL, {.i64 = 0},
12443  0, 1, FLAGS},
12444  {"seek_streams_individually",
12445  "Seek each stream individually to the closest point",
12446  OFFSET(seek_individually), AV_OPT_TYPE_BOOL, { .i64 = 1 },
12447  0, 1, FLAGS},
12448  {"ignore_editlist", "Ignore the edit list atom.", OFFSET(ignore_editlist), AV_OPT_TYPE_BOOL, {.i64 = 0},
12449  0, 1, FLAGS},
12450  {"advanced_editlist",
12451  "Modify the AVIndex according to the editlists. Use this option to decode in the order specified by the edits.",
12452  OFFSET(advanced_editlist), AV_OPT_TYPE_BOOL, {.i64 = 1},
12453  0, 1, FLAGS},
12454  {"ignore_chapters", "", OFFSET(ignore_chapters), AV_OPT_TYPE_BOOL, {.i64 = 0},
12455  0, 1, FLAGS},
12456  {"use_mfra_for",
12457  "use mfra for fragment timestamps",
12458  OFFSET(use_mfra_for), AV_OPT_TYPE_INT, {.i64 = FF_MOV_FLAG_MFRA_AUTO},
12460  .unit = "use_mfra_for"},
12461  {"auto", "auto", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_AUTO}, 0, 0,
12462  FLAGS, .unit = "use_mfra_for" },
12463  {"dts", "dts", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_DTS}, 0, 0,
12464  FLAGS, .unit = "use_mfra_for" },
12465  {"pts", "pts", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_PTS}, 0, 0,
12466  FLAGS, .unit = "use_mfra_for" },
12467  {"use_tfdt", "use tfdt for fragment timestamps", OFFSET(use_tfdt), AV_OPT_TYPE_BOOL, {.i64 = 1},
12468  0, 1, FLAGS},
12469  { "export_all", "Export unrecognized metadata entries", OFFSET(export_all),
12470  AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = FLAGS },
12471  { "export_xmp", "Export full XMP metadata", OFFSET(export_xmp),
12472  AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = FLAGS },
12473  { "activation_bytes", "Secret bytes for Audible AAX files", OFFSET(activation_bytes),
12475  { "audible_key", "AES-128 Key for Audible AAXC files", OFFSET(audible_key),
12477  { "audible_iv", "AES-128 IV for Audible AAXC files", OFFSET(audible_iv),
12479  { "audible_fixed_key", // extracted from libAAX_SDK.so and AAXSDKWin.dll files!
12480  "Fixed key used for handling Audible AAX files", OFFSET(audible_fixed_key),
12481  AV_OPT_TYPE_BINARY, {.str="77214d4b196a87cd520045fd20a51d67"},
12482  .flags = AV_OPT_FLAG_DECODING_PARAM },
12483  { "decryption_key", "The default media decryption key (hex)", OFFSET(decryption_default_key), AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM },
12484  { "decryption_keys", "The media decryption keys by KID (hex)", OFFSET(decryption_keys), AV_OPT_TYPE_DICT, .flags = AV_OPT_FLAG_DECODING_PARAM },
12485  { "enable_drefs", "Enable external track support.", OFFSET(enable_drefs), AV_OPT_TYPE_BOOL,
12486  {.i64 = 0}, 0, 1, FLAGS },
12487  { "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 },
12488  { "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 },
12489 
12490  { NULL },
12491 };
12492 
12493 static const AVClass mov_class = {
12494  .class_name = "mov,mp4,m4a,3gp,3g2,mj2",
12495  .item_name = av_default_item_name,
12496  .option = mov_options,
12497  .version = LIBAVUTIL_VERSION_INT,
12498 };
12499 
12501  .p.name = "mov,mp4,m4a,3gp,3g2,mj2",
12502  .p.long_name = NULL_IF_CONFIG_SMALL("QuickTime / MOV"),
12503  .p.priv_class = &mov_class,
12504  .p.extensions = "mov,mp4,m4a,3gp,3g2,mj2,psp,m4v,m4b,ism,ismv,isma,f4v,avif,heic,heif",
12506  .priv_data_size = sizeof(MOVContext),
12507  .flags_internal = FF_INFMT_FLAG_INIT_CLEANUP,
12508  .read_probe = mov_probe,
12513 };
HEIFItemRef::item_id
int item_id
Definition: isom.h:295
avpriv_new_chapter
AVChapter * avpriv_new_chapter(AVFormatContext *s, int64_t id, AVRational time_base, int64_t start, int64_t end, const char *title)
Add a new chapter.
Definition: demux_utils.c:43
MOVStreamContext::ctts_allocated_size
unsigned int ctts_allocated_size
Definition: isom.h:197
item_name
item_name
Definition: libkvazaar.c:311
AV_CODEC_ID_PCM_S16LE
@ AV_CODEC_ID_PCM_S16LE
Definition: codec_id.h:330
mov_update_sample_durations
static void mov_update_sample_durations(MOVContext *mov, AVStream *st)
Definition: mov.c:5294
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:68
mov_finalize_stsd_entry
static int mov_finalize_stsd_entry(MOVContext *c, AVStream *st)
Definition: mov.c:3329
mov_read_chpl
static int mov_read_chpl(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:615
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:7858
mov_read_meta
static int mov_read_meta(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5925
AV_CODEC_ID_EIA_608
@ AV_CODEC_ID_EIA_608
Definition: codec_id.h:576
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:434
MOVContext::found_iloc
int found_iloc
'iloc' atom has been found
Definition: isom.h:331
AV_CODEC_ID_MACE6
@ AV_CODEC_ID_MACE6
Definition: codec_id.h:463
MOVFragmentStreamInfo::first_tfra_pts
int64_t first_tfra_pts
Definition: isom.h:148
ff_rfps_add_frame
int ff_rfps_add_frame(AVFormatContext *ic, AVStream *st, int64_t ts)
add frame for rfps calculation.
Definition: demux.c:2336
read_image_iovl
static int read_image_iovl(AVFormatContext *s, const HEIFGrid *grid, AVStreamGroupTileGrid *tile_grid)
Definition: mov.c:10920
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:9835
AVMEDIA_TYPE_SUBTITLE
@ AVMEDIA_TYPE_SUBTITLE
Definition: avutil.h:203
AVIAMFSubmix::elements
AVIAMFSubmixElement ** elements
Array of submix elements.
Definition: iamf.h:568
skip_bits_long
static void skip_bits_long(GetBitContext *s, int n)
Skips the specified number of bits.
Definition: get_bits.h:280
AV_LOG_WARNING
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:216
AV_BPRINT_SIZE_UNLIMITED
#define AV_BPRINT_SIZE_UNLIMITED
MOV_TFHD_DEFAULT_FLAGS
#define MOV_TFHD_DEFAULT_FLAGS
Definition: isom.h:412
PUT_UTF8
#define PUT_UTF8(val, tmp, PUT_BYTE)
Definition: common.h:530
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:350
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:215
MOVStreamContext::audio_cid
int16_t audio_cid
stsd audio compression id
Definition: isom.h:227
AVMasteringDisplayMetadata::max_luminance
AVRational max_luminance
Max luminance of mastering display (cd/m^2).
Definition: mastering_display_metadata.h:57
AVSphericalProjection
AVSphericalProjection
Projection of the video surface(s) on a sphere.
Definition: spherical.h:47
AV_CODEC_ID_ADPCM_MS
@ AV_CODEC_ID_ADPCM_MS
Definition: codec_id.h:376
AVCodecParameters::extradata
uint8_t * extradata
Extra binary data needed for initializing the decoder, codec-dependent.
Definition: codec_par.h:71
mov_read_dops
static int mov_read_dops(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:8986
can_seek_to_key_sample
static int can_seek_to_key_sample(AVStream *st, int sample, int64_t requested_pts)
Definition: mov.c:12263
name
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf default minimum maximum flags name is the option name
Definition: writing_filters.txt:88
AV_CODEC_ID_ADPCM_IMA_QT
@ AV_CODEC_ID_ADPCM_IMA_QT
Definition: codec_id.h:370
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:506
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:1178
AV_CODEC_ID_AC3
@ AV_CODEC_ID_AC3
Definition: codec_id.h:456
HEIFItem::name
char * name
Definition: isom.h:302
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:247
MOVStreamContext::height
int height
tkhd height
Definition: isom.h:234
MOVContext::moov_retry
int moov_retry
Definition: isom.h:359
MOV_TRUN_SAMPLE_FLAGS
#define MOV_TRUN_SAMPLE_FLAGS
Definition: isom.h:420
AV_PKT_DATA_AMBIENT_VIEWING_ENVIRONMENT
@ AV_PKT_DATA_AMBIENT_VIEWING_ENVIRONMENT
Ambient viewing environment metadata, as defined by H.274.
Definition: packet.h:327
MOVContext::nb_chapter_tracks
unsigned int nb_chapter_tracks
Definition: isom.h:347
mix
static int mix(int c0, int c1)
Definition: 4xm.c:717
MOVStreamContext::last_stsd_index
int last_stsd_index
Definition: isom.h:262
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
flag
int flag
Definition: cpu.c:40
get_heif_item
static HEIFItem * get_heif_item(MOVContext *c, unsigned id)
Get the requested item.
Definition: mov.c:196
MOV_TKHD_FLAG_ENABLED
#define MOV_TKHD_FLAG_ENABLED
Definition: isom.h:433
AV_CH_TOP_SIDE_LEFT
#define AV_CH_TOP_SIDE_LEFT
Definition: channel_layout.h:200
AVCodecParameters::codec_type
enum AVMediaType codec_type
General type of the encoded data.
Definition: codec_par.h:53
AVStreamGroup::tile_grid
struct AVStreamGroupTileGrid * tile_grid
Definition: avformat.h:1194
AVFMT_SHOW_IDS
#define AVFMT_SHOW_IDS
Show format stream IDs numbers.
Definition: avformat.h:496
AVSphericalMapping::projection
enum AVSphericalProjection projection
Projection type.
Definition: spherical.h:104
AV_WL32
#define AV_WL32(p, v)
Definition: intreadwrite.h:422
av_exif_parse_buffer
int av_exif_parse_buffer(void *logctx, const uint8_t *buf, size_t size, AVExifMetadata *ifd, enum AVExifHeaderMode header_mode)
Decodes the EXIF data provided in the buffer and writes it into the struct *ifd.
Definition: exif.c:882
AV_STREAM_GROUP_PARAMS_LCEVC
@ AV_STREAM_GROUP_PARAMS_LCEVC
Definition: avformat.h:1151
MOVStreamContext::extradata
uint8_t ** extradata
extradata array (and size) for multiple stsd
Definition: isom.h:260
mov_class
static const AVClass mov_class
Definition: mov.c:12493
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:252
AVUUID
uint8_t AVUUID[AV_UUID_LEN]
Definition: uuid.h:60
MovTref
Definition: isom.h:94
mov_parse_tmcd_streams
static int mov_parse_tmcd_streams(AVFormatContext *s)
Definition: mov.c:11278
AV_CH_TOP_FRONT_CENTER
#define AV_CH_TOP_FRONT_CENTER
Definition: channel_layout.h:188
out
static FILE * out
Definition: movenc.c:55
MOVFragmentStreamInfo
Definition: isom.h:145
AV_CHANNEL_LAYOUT_STEREO
#define AV_CHANNEL_LAYOUT_STEREO
Definition: channel_layout.h:395
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:2416
mov_read_chnl
static int mov_read_chnl(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1318
mov_read_moof
static int mov_read_moof(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1946
av_bprint_init
void av_bprint_init(AVBPrint *buf, unsigned size_init, unsigned size_max)
Definition: bprint.c:69
ctype
#define ctype
Definition: afir_template.c:46
AV_PKT_DATA_FRAME_CROPPING
@ AV_PKT_DATA_FRAME_CROPPING
The number of pixels to discard from the top/bottom/left/right border of the decoded frame to obtain ...
Definition: packet.h:340
av_exif_write
int av_exif_write(void *logctx, const AVExifMetadata *ifd, AVBufferRef **buffer, enum AVExifHeaderMode header_mode)
Allocates a buffer using av_malloc of an appropriate size and writes the EXIF data represented by ifd...
Definition: exif.c:753
AVCodecParameters
This struct describes the properties of an encoded stream.
Definition: codec_par.h:49
AV_CH_LOW_FREQUENCY_2
#define AV_CH_LOW_FREQUENCY_2
Definition: channel_layout.h:199
HEIFItem::icc_profile
uint8_t * icc_profile
Definition: isom.h:313
AVFMT_FLAG_IGNIDX
#define AVFMT_FLAG_IGNIDX
Ignore index.
Definition: avformat.h:1486
AVExifMetadata
Definition: exif.h:75
sanity_checks
static int sanity_checks(void *log_obj, MOVStreamContext *sc, int index)
Definition: mov.c:5536
av_stristr
char * av_stristr(const char *s1, const char *s2)
Locate the first case-independent occurrence in the string haystack of the string needle.
Definition: avstring.c:58
AVCodecParameters::color_space
enum AVColorSpace color_space
Definition: codec_par.h:192
avformat_new_stream
AVStream * avformat_new_stream(AVFormatContext *s, const struct AVCodec *c)
Add a new stream to a media file.
ff_replaygain_export
int ff_replaygain_export(AVStream *st, AVDictionary *metadata)
Parse replaygain tags and export them as per-stream side data.
Definition: replaygain.c:94
tmcd_is_referenced
static int tmcd_is_referenced(AVFormatContext *s, int tmcd_id)
Definition: mov.c:10653
HEIFItem::hflip
int hflip
Definition: isom.h:309
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:791
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:692
AVStream::discard
enum AVDiscard discard
Selects which packets can be discarded at will and do not need to be demuxed.
Definition: avformat.h:837
AV_FIELD_PROGRESSIVE
@ AV_FIELD_PROGRESSIVE
Definition: defs.h:213
mov_options
static const AVOption mov_options[]
Definition: mov.c:12439
mov_codec_id
static int mov_codec_id(AVStream *st, uint32_t format)
Definition: mov.c:2885
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:250
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:9410
matrix
Definition: vc1dsp.c:43
AVMasteringDisplayMetadata::display_primaries
AVRational display_primaries[3][2]
CIE 1931 xy chromaticity coords of color primaries (r, g, b order).
Definition: mastering_display_metadata.h:42
AV_PKT_FLAG_DISCARD
#define AV_PKT_FLAG_DISCARD
Flag is used to discard packets which are required to maintain valid decoder state but are not requir...
Definition: packet.h:657
AVMasteringDisplayMetadata::has_luminance
int has_luminance
Flag indicating whether the luminance (min_ and max_) have been set.
Definition: mastering_display_metadata.h:67
get_bits_long
static unsigned int get_bits_long(GetBitContext *s, int n)
Read 0-32 bits.
Definition: get_bits.h:424
int64_t
long long int64_t
Definition: coverity.c:34
output
filter_frame For filters that do not use the this method is called when a frame is pushed to the filter s input It can be called at any time except in a reentrant way If the input frame is enough to produce output
Definition: filter_design.txt:226
mov_read_alac
static int mov_read_alac(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2388
test_same_origin
static int test_same_origin(const char *src, const char *ref)
Definition: mov.c:5379
cbcs_scheme_decrypt
static int cbcs_scheme_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
Definition: mov.c:8803
MOVFragment::base_data_offset
uint64_t base_data_offset
Definition: isom.h:110
MOVStreamContext
Definition: isom.h:179
AVChannelLayout::map
AVChannelCustom * map
This member must be used when the channel order is AV_CHANNEL_ORDER_CUSTOM.
Definition: channel_layout.h:370
MOVStreamContext::stsc_data
MOVStsc * stsc_data
Definition: isom.h:200
ff_buffer_packet
int ff_buffer_packet(AVFormatContext *s, AVPacket *pkt)
Definition: demux.c:622
IS_MATRIX_IDENT
#define IS_MATRIX_IDENT(matrix)
Definition: mov.c:5943
AV_PROFILE_DTS_EXPRESS
#define AV_PROFILE_DTS_EXPRESS
Definition: defs.h:92
AVStreamGroup::disposition
int disposition
Stream group disposition - a combination of AV_DISPOSITION_* flags.
Definition: avformat.h:1244
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:639
mov_update_dts_shift
static void mov_update_dts_shift(MOVStreamContext *sc, int duration, void *logctx)
Definition: mov.c:3965
MOVStreamContext::spherical
AVSphericalMapping * spherical
Definition: isom.h:269
mask
int mask
Definition: mediacodecdec_common.c:154
out_size
static int out_size
Definition: movenc.c:56
AV_CH_TOP_FRONT_RIGHT
#define AV_CH_TOP_FRONT_RIGHT
Definition: channel_layout.h:189
AV_CODEC_ID_MPEG4
@ AV_CODEC_ID_MPEG4
Definition: codec_id.h:62
AVContentLightMetadata::MaxCLL
unsigned MaxCLL
Max content light level (cd/m^2).
Definition: mastering_display_metadata.h:111
avio_get_str16be
int avio_get_str16be(AVIOContext *pb, int maxlen, char *buf, int buflen)
MOVEncryptionIndex
Definition: isom.h:132
av_encryption_init_info_free
void av_encryption_init_info_free(AVEncryptionInitInfo *info)
Frees the given encryption init info object.
Definition: encryption_info.c:216
FFStream::first_discard_sample
int64_t first_discard_sample
If not 0, the first audio sample that should be discarded from the stream.
Definition: internal.h:232
mov_read_avss
static int mov_read_avss(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2393
AV_RB32A
#define AV_RB32A(p)
Definition: intreadwrite.h:575
MOVContext::primary_item_id
int primary_item_id
Definition: isom.h:384
mode
Definition: swscale.c:71
MOVContext::found_moov
int found_moov
'moov' atom has been found
Definition: isom.h:330
ff_iamf_read_packet
int ff_iamf_read_packet(AVFormatContext *s, IAMFDemuxContext *c, AVIOContext *pb, int max_size, int stream_id_offset, AVPacket *pkt)
Definition: iamf_reader.c:308
mov_read_custom
static int mov_read_custom(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5766
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:1401
HEIFGrid::nb_tiles
int nb_tiles
Definition: isom.h:322
ID3v1_GENRE_MAX
#define ID3v1_GENRE_MAX
Definition: id3v1.h:29
MOVSbgp
Definition: isom.h:127
MOVCtts
Definition: isom.h:68
AVPacketSideData
This structure stores auxiliary information for decoding, presenting, or otherwise processing the cod...
Definition: packet.h:424
mov_read_extradata
static int mov_read_extradata(MOVContext *c, AVIOContext *pb, MOVAtom atom, enum AVCodecID codec_id)
Definition: mov.c:2362
AVCOL_RANGE_JPEG
@ AVCOL_RANGE_JPEG
Full range content.
Definition: pixfmt.h:783
AVStreamGroup::params
union AVStreamGroup::@462 params
Group type-specific parameters.
mpegaudiodecheader.h
MOVStreamContext::rap_group_count
unsigned int rap_group_count
Definition: isom.h:244
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
mov_read_iref_cdsc
static int mov_read_iref_cdsc(MOVContext *c, AVIOContext *pb, uint32_t type, int version, uint32_t size)
Definition: mov.c:9718
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:311
mov_read_mvhd
static int mov_read_mvhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2048
mov_read_idat
static int mov_read_idat(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:9404
AVPacket::data
uint8_t * data
Definition: packet.h:603
MOVContext::found_mdat
int found_mdat
'mdat' atom has been found
Definition: isom.h:333
MOVStreamContext::drefs_count
unsigned drefs_count
Definition: isom.h:228
AVEncryptionInfo::crypt_byte_block
uint32_t crypt_byte_block
Only used for pattern encryption.
Definition: encryption_info.h:51
AV_PKT_DATA_ENCRYPTION_INIT_INFO
@ AV_PKT_DATA_ENCRYPTION_INIT_INFO
This side data is encryption initialization data.
Definition: packet.h:246
mov_read_avid
static int mov_read_avid(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2408
AVAmbientViewingEnvironment::ambient_light_x
AVRational ambient_light_x
Normalized x chromaticity coordinate of the environmental ambient light in the nominal viewing enviro...
Definition: ambient_viewing_environment.h:47
AVCodecParameters::seek_preroll
int seek_preroll
Number of audio samples to skip after a discontinuity.
Definition: codec_par.h:256
av_dynarray2_add
void * av_dynarray2_add(void **tab_ptr, int *nb_ptr, size_t elem_size, const uint8_t *elem_data)
Add an element of size elem_size to a dynamic array.
Definition: mem.c:341
AVOption
AVOption.
Definition: opt.h:428
MOVContext::trex_data
MOVTrackExt * trex_data
Definition: isom.h:342
mov_read_stps
static int mov_read_stps(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:3618
MOVContext::bitrates
int * bitrates
bitrates read before streams creation
Definition: isom.h:357
b
#define b
Definition: input.c:43
AVCOL_TRC_UNSPECIFIED
@ AVCOL_TRC_UNSPECIFIED
Definition: pixfmt.h:675
MOVContext::interleaved_read
int interleaved_read
Definition: isom.h:391
mov_read_tkhd
static int mov_read_tkhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5951
MOVElst::rate
float rate
Definition: isom.h:82
AVStream::avg_frame_rate
AVRational avg_frame_rate
Average framerate.
Definition: avformat.h:855
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:2202
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:2087
mov_read_strf
static int mov_read_strf(MOVContext *c, AVIOContext *pb, MOVAtom atom)
An strf atom is a BITMAPINFOHEADER struct.
Definition: mov.c:2798
AV_CODEC_ID_ALAC
@ AV_CODEC_ID_ALAC
Definition: codec_id.h:469
HEIFItem::st
AVStream * st
Definition: isom.h:299
FF_COMPLIANCE_STRICT
#define FF_COMPLIANCE_STRICT
Strictly conform to all the things in the spec no matter what consequences.
Definition: defs.h:59
AV_DICT_APPEND
#define AV_DICT_APPEND
If the entry already exists, append to it.
Definition: dict.h:82
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:434
av_iamf_mix_presentation_free
void av_iamf_mix_presentation_free(AVIAMFMixPresentation **pmix_presentation)
Free an AVIAMFMixPresentation and all its contents.
Definition: iamf.c:536
AVStreamGroupTREF::metadata_index
unsigned int metadata_index
Index of the metadata stream in the AVStreamGroup.
Definition: avformat.h:1143
mov_parse_auxiliary_info
static int mov_parse_auxiliary_info(MOVContext *c, MOVStreamContext *sc, AVIOContext *pb, MOVEncryptionIndex *encryption_index)
Definition: mov.c:8066
mov_seek_stream
static int mov_seek_stream(AVFormatContext *s, AVStream *st, int64_t timestamp, int flags)
Definition: mov.c:12290
mov_read_saio
static int mov_read_saio(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:8212
mov_get_stsc_samples
static int64_t mov_get_stsc_samples(MOVStreamContext *sc, unsigned int index)
Definition: mov.c:3603
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:525
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:4177
MOVFragmentIndexItem::moof_offset
int64_t moof_offset
Definition: isom.h:159
MOVStreamContext::spherical_size
size_t spherical_size
Definition: isom.h:270
mov_change_extradata
static int mov_change_extradata(AVStream *st, AVPacket *pkt)
Definition: mov.c:11869
nb_streams
static unsigned int nb_streams
Definition: ffprobe.c:352
HEIFItemRef
Definition: isom.h:293
AV_CH_TOP_FRONT_LEFT
#define AV_CH_TOP_FRONT_LEFT
Definition: channel_layout.h:187
MP4TrackKindMapping::scheme_uri
const char * scheme_uri
Definition: isom.h:493
AVINDEX_DISCARD_FRAME
#define AVINDEX_DISCARD_FRAME
Definition: avformat.h:629
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:621
AVStreamGroup::tref
struct AVStreamGroupTREF * tref
Definition: avformat.h:1203
AVCodecParameters::codec_tag
uint32_t codec_tag
Additional information about the codec (corresponds to the AVI FOURCC).
Definition: codec_par.h:61
fixed_key
static const uint8_t fixed_key[]
Definition: aes_ctr.c:45
AV_SPHERICAL_EQUIRECTANGULAR_TILE
@ AV_SPHERICAL_EQUIRECTANGULAR_TILE
Video represents a portion of a sphere mapped on a flat surface using equirectangular projection.
Definition: spherical.h:68
AVStereo3D::baseline
uint32_t baseline
The distance between the centres of the lenses of the camera system, in micrometers.
Definition: stereo3d.h:228
MOVDref::dir
char * dir
Definition: isom.h:88
mov_current_sample_set
static void mov_current_sample_set(MOVStreamContext *sc, int current_sample)
Definition: mov.c:4481
mathematics.h
AVDictionary
Definition: dict.c:32
ffio_init_read_context
void ffio_init_read_context(FFIOContext *s, const uint8_t *buffer, int buffer_size)
Wrap a buffer in an AVIOContext for reading.
Definition: aviobuf.c:99
AV_PKT_FLAG_DISPOSABLE
#define AV_PKT_FLAG_DISPOSABLE
Flag is used to indicate packets that contain frames that can be discarded by the decoder.
Definition: packet.h:669
AVChannelLayout::order
enum AVChannelOrder order
Channel order used in this layout.
Definition: channel_layout.h:324
FFMAX
#define FFMAX(a, b)
Definition: macros.h:47
MOVAtom
Definition: isom.h:100
AVStreamGroupTileGrid::vertical
int vertical
Offset in pixels from the top edge of the canvas where the tile should be placed.
Definition: avformat.h:1022
iamf_parse.h
mov_read_moov
static int mov_read_moov(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1696
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:370
mov_read_esds
static int mov_read_esds(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:864
MOVStreamContext::sample_count
unsigned int sample_count
Definition: isom.h:211
MOVFragmentIndex::allocated_size
int allocated_size
Definition: isom.h:167
MOVTrackExt::flags
unsigned flags
Definition: isom.h:124
AVChannelLayout::nb_channels
int nb_channels
Number of channels in this layout.
Definition: channel_layout.h:329
key
const char * key
Definition: ffmpeg_mux_init.c:2971
HEIFItem::height
int height
Definition: isom.h:307
AV_SPHERICAL_EQUIRECTANGULAR
@ AV_SPHERICAL_EQUIRECTANGULAR
Video represents a sphere mapped on a flat surface using equirectangular projection.
Definition: spherical.h:52
intfloat.h
id3v1.h
MOVStreamContext::ctts_data
MOVCtts * ctts_data
Definition: isom.h:198
ff_dvdclut_yuv_to_rgb
int ff_dvdclut_yuv_to_rgb(uint32_t *clut, const size_t clut_size)
Definition: dvdclut.c:50
AV_CODEC_ID_R10K
@ AV_CODEC_ID_R10K
Definition: codec_id.h:195
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_CODEC_ID_ITUT_T35
@ AV_CODEC_ID_ITUT_T35
Definition: codec_id.h:611
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:351
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:2820
AV_CH_WIDE_LEFT
#define AV_CH_WIDE_LEFT
Definition: channel_layout.h:195
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:7577
FFIOContext
Definition: avio_internal.h:30
AV_PKT_FLAG_KEY
#define AV_PKT_FLAG_KEY
The packet contains a keyframe.
Definition: packet.h:650
init_get_bits
static int init_get_bits(GetBitContext *s, const uint8_t *buffer, int bit_size)
Initialize GetBitContext.
Definition: get_bits.h:517
MOVStreamContext::aes_ctr
struct AVAESCTR * aes_ctr
Definition: isom.h:282
cenc_filter
static int cenc_filter(MOVContext *mov, AVStream *st, MOVStreamContext *sc, AVPacket *pkt, int current_index)
Definition: mov.c:8916
mov_read_sdtp
static int mov_read_sdtp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:3927
mov_read_jp2h
static int mov_read_jp2h(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2398
AV_STEREO3D_UNSPEC
@ AV_STEREO3D_UNSPEC
Video is stereoscopic but the packing is unspecified.
Definition: stereo3d.h:143
AVIndexEntry
Definition: avformat.h:620
AV_WB64
#define AV_WB64(p, v)
Definition: intreadwrite.h:429
MOVStreamContext::dv_audio_container
int dv_audio_container
Definition: isom.h:225
MOVStreamContext::cenc
struct MOVStreamContext::@493 cenc
AV_CODEC_ID_AMR_WB
@ AV_CODEC_ID_AMR_WB
Definition: codec_id.h:435
mov_read_tfhd
static int mov_read_tfhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6056
AV_CODEC_ID_BIN_DATA
@ AV_CODEC_ID_BIN_DATA
Definition: codec_id.h:607
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:53
IAMFMixPresentation::cmix
const AVIAMFMixPresentation * cmix
Definition: iamf.h:108
MOVContext::decryption_default_key
uint8_t * decryption_default_key
Definition: isom.h:377
mov_read_wide
static int mov_read_wide(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6661
AVINDEX_KEYFRAME
#define AVINDEX_KEYFRAME
Definition: avformat.h:628
AV_FIELD_BT
@ AV_FIELD_BT
Bottom coded first, top displayed first.
Definition: defs.h:217
AV_CH_WIDE_RIGHT
#define AV_CH_WIDE_RIGHT
Definition: channel_layout.h:196
AV_CH_TOP_BACK_LEFT
#define AV_CH_TOP_BACK_LEFT
Definition: channel_layout.h:190
MOVStreamContext::stsd_count
int stsd_count
Definition: isom.h:263
ff_mov_lang_to_iso639
int ff_mov_lang_to_iso639(unsigned code, char to[4])
Definition: isom.c:261
ff_generate_avci_extradata
int ff_generate_avci_extradata(AVStream *st)
Generate standard extradata for AVC-Intra based on width/height and field order.
Definition: demux_utils.c:205
ff_get_extradata
int ff_get_extradata(void *logctx, AVCodecParameters *par, AVIOContext *pb, int size)
Allocate extradata with additional AV_INPUT_BUFFER_PADDING_SIZE at end which is always set to 0 and f...
Definition: demux_utils.c:340
mov_add_tref_id
static int mov_add_tref_id(MovTref *tag, uint32_t id)
Definition: mov.c:2660
AV_PKT_DATA_DOVI_CONF
@ AV_PKT_DATA_DOVI_CONF
DOVI configuration ref: dolby-vision-bitstreams-within-the-iso-base-media-file-format-v2....
Definition: packet.h:280
AVStereo3D::horizontal_field_of_view
AVRational horizontal_field_of_view
Horizontal field of view, in degrees.
Definition: stereo3d.h:239
skip_bits
static void skip_bits(GetBitContext *s, int n)
Definition: get_bits.h:383
AVCodecParameters::color_primaries
enum AVColorPrimaries color_primaries
Definition: codec_par.h:190
AVEncryptionInfo::scheme
uint32_t scheme
The fourcc encryption scheme, in big-endian byte order.
Definition: encryption_info.h:45
MOVStreamContext::stsc_count
unsigned int stsc_count
Definition: isom.h:199
MOVStreamContext::has_palette
int has_palette
Definition: isom.h:239
AVPROBE_SCORE_MAX
#define AVPROBE_SCORE_MAX
maximum score
Definition: avformat.h:483
AV_STEREO3D_SIDEBYSIDE
@ AV_STEREO3D_SIDEBYSIDE
Views are next to each other.
Definition: stereo3d.h:64
MOVIndexRange::start
int64_t start
Definition: isom.h:175
AVPacketSideData::size
size_t size
Definition: packet.h:426
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:122
OFFSET
#define OFFSET(x)
Definition: mov.c:12437
HEIFGrid::tile_item_list
HEIFItem ** tile_item_list
Definition: isom.h:319
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:10790
AV_CH_TOP_BACK_CENTER
#define AV_CH_TOP_BACK_CENTER
Definition: channel_layout.h:191
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:256
avpriv_dv_produce_packet
int avpriv_dv_produce_packet(DVDemuxContext *c, AVPacket *pkt, uint8_t *buf, int buf_size, int64_t pos)
Definition: dv.c:738
avpriv_set_pts_info
void avpriv_set_pts_info(AVStream *st, int pts_wrap_bits, unsigned int pts_num, unsigned int pts_den)
Set the time base and wrapping info for a given stream.
Definition: avformat.c:834
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
av_realloc
#define av_realloc(p, s)
Definition: ops_static.c:46
aax_filter
static int aax_filter(uint8_t *input, int size, MOVContext *c)
Definition: mov.c:1634
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:285
av_color_space_name
const char * av_color_space_name(enum AVColorSpace space)
Definition: pixdesc.c:3860
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:271
AV_CODEC_ID_SPEEX
@ AV_CODEC_ID_SPEEX
Definition: codec_id.h:488
AV_FOURCC_MAX_STRING_SIZE
#define AV_FOURCC_MAX_STRING_SIZE
Definition: avutil.h:321
AV_PKT_DATA_PALETTE
@ AV_PKT_DATA_PALETTE
An AV_PKT_DATA_PALETTE side data packet contains exactly AVPALETTE_SIZE bytes worth of palette.
Definition: packet.h:47
mov_find_tref_id
static int mov_find_tref_id(const MovTref *tag, uint32_t id)
Definition: mov.c:2651
ffstream
static av_always_inline FFStream * ffstream(AVStream *st)
Definition: internal.h:365
MOVFragmentIndexItem::current
int current
Definition: isom.h:161
mov_add_tref_tag
static MovTref * mov_add_tref_tag(MOVStreamContext *sc, uint32_t name)
Definition: mov.c:2686
AVFMT_SEEK_TO_PTS
#define AVFMT_SEEK_TO_PTS
Seeking is based on PTS.
Definition: avformat.h:520
AV_CODEC_ID_PCM_S16BE
@ AV_CODEC_ID_PCM_S16BE
Definition: codec_id.h:331
mov_read_mdhd
static int mov_read_mdhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2002
mov_read_ctts
static int mov_read_ctts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:3976
MOVTrackExt
Definition: isom.h:119
MOV_FRAG_SAMPLE_FLAG_IS_NON_SYNC
#define MOV_FRAG_SAMPLE_FLAG_IS_NON_SYNC
Definition: isom.h:424
mov_read_aclr
static int mov_read_aclr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2475
AVSEEK_FLAG_ANY
#define AVSEEK_FLAG_ANY
seek to any frame, even non-keyframes
Definition: avformat.h:2603
av_int2float
static av_always_inline float av_int2float(uint32_t i)
Reinterpret a 32-bit integer as a float.
Definition: intfloat.h:40
MOVFragment::found_tfhd
int found_tfhd
Definition: isom.h:108
AVStreamGroupTileGrid
AVStreamGroupTileGrid holds information on how to combine several independent images on a single canv...
Definition: avformat.h:973
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:303
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:1753
GetBitContext
Definition: get_bits.h:109
AV_CH_BACK_LEFT
#define AV_CH_BACK_LEFT
Definition: channel_layout.h:179
MOVStreamContext::mastering_size
size_t mastering_size
Definition: isom.h:272
AVStreamGroupTileGrid::coded_width
int coded_width
Width of the canvas.
Definition: avformat.h:988
av_iamf_audio_element_free
void av_iamf_audio_element_free(AVIAMFAudioElement **paudio_element)
Free an AVIAMFAudioElement and all its contents.
Definition: iamf.c:338
FFStream::index_entries_allocated_size
unsigned int index_entries_allocated_size
Definition: internal.h:194
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:7037
mov_read_enda
static int mov_read_enda(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2116
mov_read_chap
static int mov_read_chap(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6103
MOVParseTableEntry
Definition: mov.c:84
avio_tell
static av_always_inline int64_t avio_tell(AVIOContext *s)
ftell() equivalent for AVIOContext.
Definition: avio.h:494
av_exif_free
void av_exif_free(AVExifMetadata *ifd)
Frees all resources associated with the given EXIF metadata struct.
Definition: exif.c:659
MOV_TRUN_SAMPLE_DURATION
#define MOV_TRUN_SAMPLE_DURATION
Definition: isom.h:418
val
static double val(void *priv, double ch)
Definition: aeval.c:77
set_display_matrix_from_item
static int set_display_matrix_from_item(AVPacketSideData **coded_side_data, int *nb_coded_side_data, const HEIFItem *item)
Definition: mov.c:10804
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:325
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:697
AVStreamGroupTileGrid::coded_height
int coded_height
Width of the canvas.
Definition: avformat.h:994
mov_compare_presentation_samples
static int mov_compare_presentation_samples(const void *a, const void *b)
Definition: mov.c:5281
pts
static int64_t pts
Definition: transcode_aac.c:649
MOVStreamContext::v_spacing
int v_spacing
pasp vSpacing
Definition: isom.h:236
AVEncryptionInfo::iv
uint8_t * iv
The initialization vector.
Definition: encryption_info.h:71
AV_CODEC_ID_MP3
@ AV_CODEC_ID_MP3
preferred ID for decoding MPEG audio layer 1, 2 or 3
Definition: codec_id.h:454
AVStream::duration
int64_t duration
Decoding: duration of the stream, in stream time base.
Definition: avformat.h:825
AVAmbientViewingEnvironment::ambient_illuminance
AVRational ambient_illuminance
Environmental illuminance of the ambient viewing environment in lux.
Definition: ambient_viewing_environment.h:40
ss
#define ss(width, name, subs,...)
Definition: cbs_vp9.c:202
MOVStreamContext::width
int width
tkhd width
Definition: isom.h:233
MOVContext::meta_keys
char ** meta_keys
Definition: isom.h:336
get_key_from_kid
static int get_key_from_kid(uint8_t *out, int len, MOVContext *c, AVEncryptionInfo *sample)
Definition: mov.c:8570
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:261
AVIAMFAudioElement::audio_element_type
enum AVIAMFAudioElementType audio_element_type
Audio element type as defined in section 3.6 of IAMF.
Definition: iamf.h:391
loop
static int loop
Definition: ffplay.c:337
AV_STREAM_GROUP_PARAMS_DOLBY_VISION
@ AV_STREAM_GROUP_PARAMS_DOLBY_VISION
Definition: avformat.h:1153
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:464
update_frag_index
static int update_frag_index(MOVContext *c, int64_t offset)
Definition: mov.c:1870
AV_CODEC_ID_PRORES_RAW
@ AV_CODEC_ID_PRORES_RAW
Definition: codec_id.h:324
AVRational::num
int num
Numerator.
Definition: rational.h:59
av_clip64
#define av_clip64
Definition: common.h:103
MOVStreamContext::keyframes
int * keyframes
Definition: isom.h:215
av_unused
#define av_unused
Definition: attributes.h:164
MOVEncryptionIndex::auxiliary_info_sample_count
size_t auxiliary_info_sample_count
Definition: isom.h:139
AV_FIELD_TB
@ AV_FIELD_TB
Top coded first, bottom displayed first.
Definition: defs.h:216
mov_read_pack
static int mov_read_pack(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:7109
AVStream::attached_pic
AVPacket attached_pic
For streams with AV_DISPOSITION_ATTACHED_PIC disposition, this packet will contain the attached pictu...
Definition: avformat.h:864
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:8128
MOV_FRAG_SAMPLE_FLAG_DEPENDS_YES
#define MOV_FRAG_SAMPLE_FLAG_DEPENDS_YES
Definition: isom.h:431
mov_merge_tts_data
static int mov_merge_tts_data(MOVContext *mov, AVStream *st, int flags)
Definition: mov.c:4897
MOVContext::idat_offset
int64_t idat_offset
Definition: isom.h:390
MOV_TRUN_DATA_OFFSET
#define MOV_TRUN_DATA_OFFSET
Definition: isom.h:416
av_encryption_info_clone
AVEncryptionInfo * av_encryption_info_clone(const AVEncryptionInfo *info)
Allocates an AVEncryptionInfo structure with a copy of the given data.
Definition: encryption_info.c:65
av_ambient_viewing_environment_alloc
AVAmbientViewingEnvironment * av_ambient_viewing_environment_alloc(size_t *size)
Allocate an AVAmbientViewingEnvironment structure.
Definition: ambient_viewing_environment.c:31
AV_DICT_DONT_STRDUP_VAL
#define AV_DICT_DONT_STRDUP_VAL
Take ownership of a value that's been allocated with av_malloc() or another memory allocation functio...
Definition: dict.h:79
IAMFAudioElement::element
AVIAMFAudioElement * element
element backs celement iff the AVIAMFAudioElement is owned by this structure.
Definition: iamf.h:95
MOVStreamContext::elst_data
MOVElst * elst_data
Definition: isom.h:205
mov_read_ares
static int mov_read_ares(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2430
mov_read_adrm
static int mov_read_adrm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1508
av_get_bits_per_sample
int av_get_bits_per_sample(enum AVCodecID codec_id)
Return codec bits per sample.
Definition: utils.c:556
AVCodecParameters::color_trc
enum AVColorTransferCharacteristic color_trc
Definition: codec_par.h:191
IAMFContext::audio_elements
IAMFAudioElement ** audio_elements
Definition: iamf.h:131
MOVFragmentIndex::complete
int complete
Definition: isom.h:168
AV_CODEC_ID_PCM_S8
@ AV_CODEC_ID_PCM_S8
Definition: codec_id.h:334
avassert.h
avio_rb32
unsigned int avio_rb32(AVIOContext *s)
Definition: aviobuf.c:764
AV_LOG_TRACE
#define AV_LOG_TRACE
Extremely verbose debugging, useful for libav* development.
Definition: log.h:236
MOVStreamContext::stsc_sample
int stsc_sample
Definition: isom.h:202
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:210
AV_CODEC_ID_MACE3
@ AV_CODEC_ID_MACE3
Definition: codec_id.h:462
FF_ARRAY_ELEMS
#define FF_ARRAY_ELEMS(a)
Definition: sinewin_tablegen.c:29
AV_PROFILE_UNKNOWN
#define AV_PROFILE_UNKNOWN
Definition: defs.h:65
MOVTrackExt::track_id
unsigned track_id
Definition: isom.h:120
mov_free_encryption_index
static void mov_free_encryption_index(MOVEncryptionIndex **index)
Definition: mov.c:10521
AV_CH_LOW_FREQUENCY
#define AV_CH_LOW_FREQUENCY
Definition: channel_layout.h:178
MOVEncryptionIndex::auxiliary_offsets
uint64_t * auxiliary_offsets
Absolute seek position.
Definition: isom.h:141
read_packet
static int read_packet(void *opaque, uint8_t *buf, int buf_size)
Definition: avio_read_callback.c:42
AV_FIELD_UNKNOWN
@ AV_FIELD_UNKNOWN
Definition: defs.h:212
MOVStreamContext::dts_shift
int dts_shift
dts shift when ctts is negative
Definition: isom.h:237
av_timecode_init
int av_timecode_init(AVTimecode *tc, AVRational rate, int flags, int frame_start, void *log_ctx)
Init a timecode struct with the passed parameters.
Definition: timecode.c:201
AVCodecParameters::frame_size
int frame_size
Audio frame size, if known.
Definition: codec_par.h:227
mov_read_srat
static int mov_read_srat(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1093
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:93
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:264
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:10989
flags
#define flags(name, subs,...)
Definition: cbs_av1.c:504
AV_STREAM_GROUP_PARAMS_IAMF_MIX_PRESENTATION
@ AV_STREAM_GROUP_PARAMS_IAMF_MIX_PRESENTATION
Definition: avformat.h:1149
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:4372
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:495
FF_MOV_FLAG_MFRA_PTS
#define FF_MOV_FLAG_MFRA_PTS
Definition: isom.h:466
MOV_MERGE_STTS
#define MOV_MERGE_STTS
Definition: mov.c:4891
MOVStreamContext::iamf_stream_offset
int iamf_stream_offset
Definition: isom.h:290
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:6971
MOVFragmentStreamInfo::encryption_index
MOVEncryptionIndex * encryption_index
Definition: isom.h:154
mov_read_trak
static int mov_read_trak(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5555
IAMFSubStream::audio_substream_id
unsigned int audio_substream_id
Definition: iamf.h:83
MOVContext::fc
AVFormatContext * fc
Definition: isom.h:327
MOV_TFHD_DEFAULT_BASE_IS_MOOF
#define MOV_TFHD_DEFAULT_BASE_IS_MOOF
Definition: isom.h:414
av_new_packet
int av_new_packet(AVPacket *pkt, int size)
Allocate the payload of a packet and initialize its fields with default values.
Definition: packet.c:98
AV_CODEC_ID_BMP
@ AV_CODEC_ID_BMP
Definition: codec_id.h:128
AV_CODEC_ID_EVC
@ AV_CODEC_ID_EVC
Definition: codec_id.h:316
IAMFLayer::substream_count
unsigned int substream_count
Definition: iamf.h:78
MOV_TFHD_DEFAULT_DURATION
#define MOV_TFHD_DEFAULT_DURATION
Definition: isom.h:410
ALAC_EXTRADATA_SIZE
#define ALAC_EXTRADATA_SIZE
DRM_BLOB_SIZE
#define DRM_BLOB_SIZE
Definition: mov.c:1506
MOVStreamContext::sample_offsets_count
int sample_offsets_count
Definition: isom.h:251
MOVCtts::count
unsigned int count
Definition: isom.h:69
MOVStreamContext::drefs
MOVDref * drefs
Definition: isom.h:229
av_realloc_array
void * av_realloc_array(void *ptr, size_t nmemb, size_t size)
Definition: mem.c:217
AVInputFormat::name
const char * name
A comma separated list of short names for the format.
Definition: avformat.h:570
MOVContext::aes_decrypt
struct AVAES * aes_decrypt
Definition: isom.h:376
AVSphericalMapping::bound_top
uint32_t bound_top
Distance from the top edge.
Definition: spherical.h:186
MOVPresentationSample::pts
int64_t pts
Definition: mov.c:5278
AVMEDIA_TYPE_AUDIO
@ AVMEDIA_TYPE_AUDIO
Definition: avutil.h:201
AV_CODEC_ID_VP9
@ AV_CODEC_ID_VP9
Definition: codec_id.h:217
MOVFragmentIndex::nb_items
int nb_items
Definition: isom.h:170
AVCodecParameters::width
int width
The width of the video frame in pixels.
Definition: codec_par.h:143
MOVTimeToSample
Definition: isom.h:57
AV_CHANNEL_ORDER_UNSPEC
@ AV_CHANNEL_ORDER_UNSPEC
Only the channel count is specified, without any further information about the channel order.
Definition: channel_layout.h:119
AV_CODEC_ID_MP2
@ AV_CODEC_ID_MP2
Definition: codec_id.h:453
HEIFGrid::tile_idx_list
unsigned * tile_idx_list
Definition: isom.h:321
MOV_TRUN_FIRST_SAMPLE_FLAGS
#define MOV_TRUN_FIRST_SAMPLE_FLAGS
Definition: isom.h:417
av_q2d
static double av_q2d(AVRational a)
Convert an AVRational to a double.
Definition: rational.h:104
AVIndexEntry::size
int size
Definition: avformat.h:631
av_channel_layout_from_mask
int av_channel_layout_from_mask(AVChannelLayout *channel_layout, uint64_t mask)
Initialize a native channel layout from a bitmask indicating which channels are present.
Definition: channel_layout.c:253
MOVStreamContext::keyframe_absent
int keyframe_absent
Definition: isom.h:213
info
MIPS optimizations info
Definition: mips.txt:2
MOVStts::duration
unsigned int duration
Definition: isom.h:65
fc
#define fc(width, name, range_min, range_max)
Definition: cbs_av1.c:494
MOVStreamContext::coll_size
size_t coll_size
Definition: isom.h:274
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:4401
AVIndexEntry::timestamp
int64_t timestamp
Timestamp in AVStream.time_base units, preferably the time from which on correctly decoded frames are...
Definition: avformat.h:622
av_assert0
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:42
MOVStreamContext::min_corrected_pts
int64_t min_corrected_pts
minimum Composition time shown by the edits excluding empty edits.
Definition: isom.h:218
ffio_read_leb
unsigned int ffio_read_leb(AVIOContext *s)
Read a unsigned integer coded as a variable number of up to eight little-endian bytes,...
Definition: aviobuf.c:930
tile_cols
int tile_cols
Definition: av1_levels.c:73
MOVStreamContext::sdtp_count
unsigned int sdtp_count
Definition: isom.h:194
dvdclut.h
MOVStreamContext::nb_tref_tags
int nb_tref_tags
Definition: isom.h:231
mov_read_lhvc
static int mov_read_lhvc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:9121
AV_LOG_DEBUG
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:231
AV_CH_TOP_SIDE_RIGHT
#define AV_CH_TOP_SIDE_RIGHT
Definition: channel_layout.h:201
AVPacketSideData::data
uint8_t * data
Definition: packet.h:425
AVDOVIDecoderConfigurationRecord::dv_profile
uint8_t dv_profile
Definition: dovi_meta.h:58
ctx
static AVFormatContext * ctx
Definition: movenc.c:49
hevc.h
get_bits.h
limits.h
mov_read_sidx
static int mov_read_sidx(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6522
AV_PKT_DATA_STEREO3D
@ AV_PKT_DATA_STEREO3D
This side data should be associated with a video stream and contains Stereoscopic 3D information in f...
Definition: packet.h:111
av_rescale_q
int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq)
Rescale a 64-bit integer by 2 rational numbers.
Definition: mathematics.c:142
ff_iamfdec_read_descriptors
int ff_iamfdec_read_descriptors(IAMFContext *c, AVIOContext *pb, int max_size, void *log_ctx)
Definition: iamf_parse.c:1262
FFStream::display_aspect_ratio
AVRational display_aspect_ratio
display aspect ratio (0 if unknown)
Definition: internal.h:303
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:11796
ff_mov_read_chnl
int ff_mov_read_chnl(AVFormatContext *s, AVIOContext *pb, AVStream *st, int version)
Read 'chnl' tag from the input stream.
Definition: mov_chan.c:768
AV_CODEC_ID_TARGA_Y216
@ AV_CODEC_ID_TARGA_Y216
Definition: codec_id.h:253
AVIndexEntry::min_distance
int min_distance
Minimum distance between this and the previous keyframe, used to avoid unneeded searching.
Definition: avformat.h:632
mov_read_dvcc_dvvc
static int mov_read_dvcc_dvvc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:9074
MOVParseTableEntry::parse
int(* parse)(MOVContext *ctx, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:86
MOVPresentationSample
Definition: mov.c:5276
codec_id
enum AVCodecID codec_id
Definition: vaapi_decode.c:410
MOVStreamContext::tref_tags
MovTref * tref_tags
Definition: isom.h:232
AV_CODEC_ID_SVQ3
@ AV_CODEC_ID_SVQ3
Definition: codec_id.h:73
AVCodecParameters::nb_coded_side_data
int nb_coded_side_data
Amount of entries in coded_side_data.
Definition: codec_par.h:88
MOVStreamContext::sdtp_data
uint8_t * sdtp_data
Definition: isom.h:195
color_range
color_range
Definition: vf_selectivecolor.c:43
AVMEDIA_TYPE_DATA
@ AVMEDIA_TYPE_DATA
Opaque data information usually continuous.
Definition: avutil.h:202
mov_read_udta_string
static int mov_read_udta_string(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:347
av_mallocz
#define av_mallocz(s)
Definition: tableprint_vlc.h:31
mov_read_stss
static int mov_read_stss(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:3659
mov_read_ddts
static int mov_read_ddts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1237
mov_read_uuid
static int mov_read_uuid(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:7731
AVCOL_PRI_UNSPECIFIED
@ AVCOL_PRI_UNSPECIFIED
Definition: pixfmt.h:645
MOVTrackExt::duration
unsigned duration
Definition: isom.h:122
AV_CODEC_ID_H264
@ AV_CODEC_ID_H264
Definition: codec_id.h:77
AVStreamGroup::layered_video
struct AVStreamGroupLayeredVideo * layered_video
Definition: avformat.h:1195
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:73
tmp
static uint8_t tmp[40]
Definition: aes_ctr.c:52
av_sha_final
void av_sha_final(AVSHA *ctx, uint8_t *digest)
Finish hashing and output digest value.
Definition: sha.c:347
MOVStreamContext::current_sample
int current_sample
Definition: isom.h:219
MOVFragmentStreamInfo::sidx_pts
int64_t sidx_pts
Definition: isom.h:147
MAX_REORDER_DELAY
#define MAX_REORDER_DELAY
Definition: mov.c:4400
MOVFragmentIndex::current
int current
Definition: isom.h:169
MOVEncryptionIndex::encrypted_samples
AVEncryptionInfo ** encrypted_samples
Definition: isom.h:136
mov_read_close
static int mov_read_close(AVFormatContext *s)
Definition: mov.c:10598
ff_hex_to_data
int ff_hex_to_data(uint8_t *data, const char *p)
Parse a string of hexadecimal strings.
Definition: utils.c:485
MOVAtom::size
int64_t size
Definition: isom.h:102
MOVStreamContext::refcount
int refcount
Definition: isom.h:181
AVStereo3D::flags
int flags
Additional information about the frame packing.
Definition: stereo3d.h:212
ff_mov_get_lpcm_codec_id
static enum AVCodecID ff_mov_get_lpcm_codec_id(int bps, int flags)
Compute codec id for 'lpcm' tag.
Definition: isom.h:472
AV_CODEC_ID_PNG
@ AV_CODEC_ID_PNG
Definition: codec_id.h:111
AV_CODEC_ID_AVUI
@ AV_CODEC_ID_AVUI
Definition: codec_id.h:252
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:6681
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:7956
FFStream::need_parsing
enum AVStreamParseType need_parsing
Definition: internal.h:321
MOVStreamContext::keyframe_count
unsigned int keyframe_count
Definition: isom.h:214
mov_read_SAND
static int mov_read_SAND(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:9351
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:1333
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:3807
MOVStreamContext::index_ranges
MOVIndexRange * index_ranges
Definition: isom.h:221
fail
#define fail
Definition: test.h:478
DDTS_SIZE
#define DDTS_SIZE
internal.h
MOVTrackExt::stsd_id
unsigned stsd_id
Definition: isom.h:121
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:4223
set_frag_stream
static void set_frag_stream(MOVFragmentIndex *frag_index, int id)
Definition: mov.c:1733
mov_read_free
static int mov_read_free(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:7836
mov_realloc_extradata
static int mov_realloc_extradata(AVCodecParameters *par, MOVAtom atom)
Definition: mov.c:2325
AVStream::codecpar
AVCodecParameters * codecpar
Codec parameters associated with this stream.
Definition: avformat.h:789
LIBAVUTIL_VERSION_INT
#define LIBAVUTIL_VERSION_INT
Definition: version.h:85
av_exif_get_tag_id
int32_t av_exif_get_tag_id(const char *name)
Retrieves the tag ID associated with the provided tag string name.
Definition: exif.c:244
AV_PKT_DATA_EXIF
@ AV_PKT_DATA_EXIF
Extensible image file format metadata.
Definition: packet.h:369
AVSEEK_FLAG_BACKWARD
#define AVSEEK_FLAG_BACKWARD
Definition: avformat.h:2601
mov_dts_stream_construction_to_profile
static int mov_dts_stream_construction_to_profile(unsigned int sc)
Definition: mov.c:1176
aes.h
AVClass
Describe the class of an AVClass context structure.
Definition: log.h:76
MOVStreamContext::tts_sample
int tts_sample
Definition: isom.h:208
avpriv_dv_get_packet
int avpriv_dv_get_packet(DVDemuxContext *c, AVPacket *pkt)
Definition: dv.c:733
MOVContext::ignore_editlist
int ignore_editlist
Definition: isom.h:349
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
AV_CH_TOP_CENTER
#define AV_CH_TOP_CENTER
Definition: channel_layout.h:186
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:805
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:275
MOVStreamContext::ctts_count
unsigned int ctts_count
Definition: isom.h:196
AVEncryptionInitInfo
This describes info used to initialize an encryption key system.
Definition: encryption_info.h:88
isom.h
MP4TrackKindValueMapping::disposition
int disposition
Definition: isom.h:488
mov_read_ftyp
static int mov_read_ftyp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1648
AV_WB16
#define AV_WB16(p, v)
Definition: intreadwrite.h:401
MOVContext::nb_heif_grid
int nb_heif_grid
Definition: isom.h:389
read_image_grid
static int read_image_grid(AVFormatContext *s, const HEIFGrid *grid, AVStreamGroupTileGrid *tile_grid)
Definition: mov.c:10825
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:1076
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:4057
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:10240
AVPALETTE_SIZE
#define AVPALETTE_SIZE
Definition: pixfmt.h:32
AV_OPT_TYPE_DICT
@ AV_OPT_TYPE_DICT
Underlying C type is AVDictionary*.
Definition: opt.h:289
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:11893
av_fallthrough
#define av_fallthrough
Definition: attributes.h:67
AV_CODEC_ID_DVD_SUBTITLE
@ AV_CODEC_ID_DVD_SUBTITLE
Definition: codec_id.h:566
AVIndexEntry::flags
int flags
Definition: avformat.h:630
MOVStreamContext::time_offset
int64_t time_offset
time offset of the edit list entries
Definition: isom.h:217
mov_read_smdm
static int mov_read_smdm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6880
av_default_item_name
const char * av_default_item_name(void *ptr)
Return the context name.
Definition: log.c:242
AVStereo3D::horizontal_disparity_adjustment
AVRational horizontal_disparity_adjustment
Relative shift of the left and right images, which changes the zero parallax plane.
Definition: stereo3d.h:234
avio_rb64
uint64_t avio_rb64(AVIOContext *s)
Definition: aviobuf.c:911
av_aes_crypt
void av_aes_crypt(AVAES *a, uint8_t *dst, const uint8_t *src, int count, uint8_t *iv, int decrypt)
Encrypt or decrypt a buffer using a previously initialized context.
Definition: aes.c:171
MOVStreamContext::current_index_range
MOVIndexRange * current_index_range
Definition: isom.h:222
mov_open_dref
static int mov_open_dref(MOVContext *c, AVIOContext **pb, const char *src, MOVDref *ref)
Definition: mov.c:5408
FFStream::nb_index_entries
int nb_index_entries
Definition: internal.h:193
AVProbeData
This structure contains the data a format has to probe a file.
Definition: avformat.h:471
av_aes_alloc
struct AVAES * av_aes_alloc(void)
Allocate an AVAES context.
Definition: aes.c:37
TAG_IS_AVCI
#define TAG_IS_AVCI(tag)
Definition: isom.h:442
IAMFSubStream
Definition: iamf.h:82
IAMFAudioElement::layers
IAMFLayer * layers
Definition: iamf.h:103
mov_read_schm
static int mov_read_schm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:8428
AVStream::metadata
AVDictionary * metadata
Definition: avformat.h:846
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:3794
FF_MOV_FLAG_MFRA_DTS
#define FF_MOV_FLAG_MFRA_DTS
Definition: isom.h:465
MOV_SAMPLE_DEPENDENCY_NO
#define MOV_SAMPLE_DEPENDENCY_NO
Definition: isom.h:440
AV_DICT_DONT_OVERWRITE
#define AV_DICT_DONT_OVERWRITE
Don't overwrite existing entries.
Definition: dict.h:81
ff_codec_movvideo_tags
const AVCodecTag ff_codec_movvideo_tags[]
Definition: isom_tags.c:29
attributes.h
MOVStreamContext::tts_index
int tts_index
Definition: isom.h:207
AV_DISPOSITION_MULTILAYER
#define AV_DISPOSITION_MULTILAYER
The video stream contains multiple layers, e.g.
Definition: avformat.h:736
MOVFragmentStreamInfo::index_base
int index_base
Definition: isom.h:152
MOVStreamContext::rap_group
MOVSbgp * rap_group
Definition: isom.h:245
AV_CODEC_ID_QDM2
@ AV_CODEC_ID_QDM2
Definition: codec_id.h:472
mov_read_ilst
static int mov_read_ilst(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5711
MOVTimeToSample::duration
unsigned int duration
Definition: isom.h:59
AV_CH_FRONT_CENTER
#define AV_CH_FRONT_CENTER
Definition: channel_layout.h:177
AVCodecParameters::ch_layout
AVChannelLayout ch_layout
The channel layout and number of channels.
Definition: codec_par.h:207
get_frag_stream_info_from_pkt
static MOVFragmentStreamInfo * get_frag_stream_info_from_pkt(MOVFragmentIndex *frag_index, AVPacket *pkt, int id)
Definition: mov.c:8891
get_sgpd_sync_index
static uint32_t get_sgpd_sync_index(const MOVStreamContext *sc, int nal_unit_type)
Definition: mov.c:4819
mov_read_fiel
static int mov_read_fiel(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2291
parse
static int parse(AVCodecParserContext *s, AVCodecContext *avctx, const uint8_t **poutbuf, int *poutbuf_size, const uint8_t *buf, int buf_size)
Definition: apv_parser.c:92
AV_CH_FRONT_LEFT_OF_CENTER
#define AV_CH_FRONT_LEFT_OF_CENTER
Definition: channel_layout.h:181
MOV_MP4_TTML_TAG
#define MOV_MP4_TTML_TAG
Definition: isom.h:483
AV_PKT_DATA_CONTENT_LIGHT_LEVEL
@ AV_PKT_DATA_CONTENT_LIGHT_LEVEL
Content light level (based on CTA-861.3).
Definition: packet.h:232
av_encryption_info_add_side_data
uint8_t * av_encryption_info_add_side_data(const AVEncryptionInfo *info, size_t *size)
Allocates and initializes side data that holds a copy of the given encryption info.
Definition: encryption_info.c:127
MOV_TFHD_BASE_DATA_OFFSET
#define MOV_TFHD_BASE_DATA_OFFSET
Definition: isom.h:408
MOVFragmentStreamInfo::stsd_id
int stsd_id
Definition: isom.h:155
av_exif_remove_entry
int av_exif_remove_entry(void *logctx, AVExifMetadata *ifd, uint16_t id, int flags)
Remove an entry from the provided EXIF metadata struct.
Definition: exif.c:1272
MOVStreamContext::open_key_samples_count
int open_key_samples_count
Definition: isom.h:253
HEIFItem
Definition: isom.h:298
ff_codec_movaudio_tags
const AVCodecTag ff_codec_movaudio_tags[]
Definition: isom_tags.c:306
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:1352
av_stereo3d_alloc_size
AVStereo3D * av_stereo3d_alloc_size(size_t *size)
Allocate an AVStereo3D structure and set its fields to default values.
Definition: stereo3d.c:39
index
int index
Definition: gxfenc.c:90
c
Undefined Behavior In the C some operations are like signed integer dereferencing freed accessing outside allocated Undefined Behavior must not occur in a C it is not safe even if the output of undefined operations is unused The unsafety may seem nit picking but Optimizing compilers have in fact optimized code on the assumption that no undefined Behavior occurs Optimizing code based on wrong assumptions can and has in some cases lead to effects beyond the output of computations The signed integer overflow problem in speed critical code Code which is highly optimized and works with signed integers sometimes has the problem that often the output of the computation does not c
Definition: undefined.txt:32
AVPROBE_SCORE_EXTENSION
#define AVPROBE_SCORE_EXTENSION
score for file extension
Definition: avformat.h:481
MOVSbgp::count
unsigned int count
Definition: isom.h:128
AVCodecParameters::sample_rate
int sample_rate
The number of audio samples per second.
Definition: codec_par.h:213
mov_parse_stsd_subtitle
static void mov_parse_stsd_subtitle(MOVContext *c, AVIOContext *pb, AVStream *st, MOVStreamContext *sc, int64_t size)
Definition: mov.c:3110
cid
uint16_t cid
Definition: mxfenc.c:2335
mov_skip_multiple_stsd
static int mov_skip_multiple_stsd(MOVContext *c, AVIOContext *pb, int codec_tag, int format, int64_t size)
Definition: mov.c:3303
MOVStts
Definition: isom.h:63
AVAudioServiceType
AVAudioServiceType
Definition: defs.h:235
AV_CODEC_ID_MPEG1VIDEO
@ AV_CODEC_ID_MPEG1VIDEO
Definition: codec_id.h:51
AV_CODEC_ID_GSM
@ AV_CODEC_ID_GSM
as in Berlin toast format
Definition: codec_id.h:471
AVStream::nb_frames
int64_t nb_frames
number of frames in this stream if known or 0
Definition: avformat.h:827
AVCodecID
AVCodecID
Identify the syntax and semantics of the bitstream.
Definition: codec_id.h:47
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:570
AVIAMFSubmixElement::audio_element_id
unsigned int audio_element_id
The id of the Audio Element this submix element references.
Definition: iamf.h:455
AV_CODEC_ID_EAC3
@ AV_CODEC_ID_EAC3
Definition: codec_id.h:493
should_retry
static int should_retry(AVIOContext *pb, int error_code)
Definition: mov.c:11826
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:558
AV_PKT_DATA_SPHERICAL
@ AV_PKT_DATA_SPHERICAL
This side data should be associated with a video stream and corresponds to the AVSphericalMapping str...
Definition: packet.h:225
AVCodecParameters::extradata_size
int extradata_size
Size of the extradata content in bytes.
Definition: codec_par.h:75
AVIAMFSubmix
Submix layout as defined in section 3.7 of IAMF.
Definition: iamf.h:559
AV_WB32
#define AV_WB32(p, v)
Definition: intreadwrite.h:415
mov_read_pasp
static int mov_read_pasp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1476
MOVContext::dv_demux
DVDemuxContext * dv_demux
Definition: isom.h:338
AV_CODEC_ID_AAC
@ AV_CODEC_ID_AAC
Definition: codec_id.h:455
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:9261
mov_read_elst
static int mov_read_elst(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6734
MOVEncryptionIndex::auxiliary_info_default_size
uint8_t auxiliary_info_default_size
Definition: isom.h:140
AV_STREAM_GROUP_PARAMS_TILE_GRID
@ AV_STREAM_GROUP_PARAMS_TILE_GRID
Definition: avformat.h:1150
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:11561
AV_CODEC_ID_QCELP
@ AV_CODEC_ID_QCELP
Definition: codec_id.h:477
mov_read_vdep
static int mov_read_vdep(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2766
AV_SPHERICAL_HALF_EQUIRECTANGULAR
@ AV_SPHERICAL_HALF_EQUIRECTANGULAR
Video frame displays as a 180 degree equirectangular projection.
Definition: spherical.h:73
AV_PROFILE_DTS_HD_HRA
#define AV_PROFILE_DTS_HD_HRA
Definition: defs.h:90
cbc1_scheme_decrypt
static int cbc1_scheme_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
Definition: mov.c:8666
avio_rl32
unsigned int avio_rl32(AVIOContext *s)
Definition: aviobuf.c:733
AVDISCARD_NONKEY
@ AVDISCARD_NONKEY
discard all frames except keyframes
Definition: defs.h:231
MOVFragment::flags
unsigned flags
Definition: isom.h:116
f
f
Definition: af_crystalizer.c:122
AVIOContext
Bytestream IO Context.
Definition: avio.h:160
AV_CODEC_ID_PCM_S24LE
@ AV_CODEC_ID_PCM_S24LE
Definition: codec_id.h:342
mov_read_wave
static int mov_read_wave(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2523
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:283
cens_scheme_decrypt
static int cens_scheme_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
Definition: mov.c:8732
MOVContext::handbrake_version
int handbrake_version
Definition: isom.h:345
mov_free_stream_context
static void mov_free_stream_context(AVFormatContext *s, AVStream *st)
Definition: mov.c:10533
AVPacket::size
int size
Definition: packet.h:604
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:88
AV_STREAM_GROUP_PARAMS_TREF
@ AV_STREAM_GROUP_PARAMS_TREF
Definition: avformat.h:1152
ff_codec_get_id
enum AVCodecID ff_codec_get_id(const AVCodecTag *tags, unsigned int tag)
Definition: utils.c:143
avformat_alloc_context
AVFormatContext * avformat_alloc_context(void)
Allocate an AVFormatContext.
Definition: options.c:165
MOVFragmentIndexItem
Definition: isom.h:158
get_current_encryption_info
static int get_current_encryption_info(MOVContext *c, MOVEncryptionIndex **encryption_index, MOVStreamContext **sc)
Gets the current encryption info and associated current stream context.
Definition: mov.c:7905
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:135
mov_read_dref
static int mov_read_dref(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:654
mov_current_sample_dec
static void mov_current_sample_dec(MOVStreamContext *sc)
Definition: mov.c:4469
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
FFStream::last_discard_sample
int64_t last_discard_sample
The sample after last sample that is intended to be discarded after first_discard_sample.
Definition: internal.h:239
av_bswap32
#define av_bswap32
Definition: bswap.h:47
i
#define i(width, name, range_min, range_max)
Definition: cbs_h264.c:63
MOVStreamContext::stsz_sample_size
unsigned int stsz_sample_size
always contains sample size from stsz atom
Definition: isom.h:210
FF_MOV_FLAG_MFRA_AUTO
#define FF_MOV_FLAG_MFRA_AUTO
Definition: isom.h:464
ff_dict_set_timestamp
int ff_dict_set_timestamp(AVDictionary **dict, const char *key, int64_t timestamp)
Set a dictionary value to an ISO-8601 compliant timestamp string.
Definition: utils.c:616
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:248
start_time
static int64_t start_time
Definition: ffplay.c:328
uuid.h
ff_dvdclut_palette_extradata_cat
int ff_dvdclut_palette_extradata_cat(const uint32_t *clut, const size_t clut_size, AVCodecParameters *par)
Definition: dvdclut.c:28
mov_read_trun
static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6189
MOVStreamContext::stereo3d_size
size_t stereo3d_size
Definition: isom.h:268
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:9874
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:54
MOV_TFHD_STSD_ID
#define MOV_TFHD_STSD_ID
Definition: isom.h:409
size
int size
Definition: twinvq_data.h:10344
mov_read_chan
static int mov_read_chan(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1299
AV_PROFILE_DTS_ES
#define AV_PROFILE_DTS_ES
Definition: defs.h:88
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:3517
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:503
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:54
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:1192
AVCodecParameters::profile
int profile
Codec-specific bitstream restrictions that the stream conforms to.
Definition: codec_par.h:135
av_malloc
#define av_malloc(s)
Definition: ops_static.c:44
MOVStreamContext::coll
AVContentLightMetadata * coll
Definition: isom.h:273
aes_ctr.h
ff_format_io_close
int ff_format_io_close(AVFormatContext *s, AVIOContext **pb)
Definition: avformat.c:961
mov_parse_heif_items
static int mov_parse_heif_items(AVFormatContext *s)
Definition: mov.c:11199
HEIFItem::is_idat_relative
int is_idat_relative
Definition: isom.h:312
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:4319
MOVDref::path
char * path
Definition: isom.h:87
mov_current_sample_inc
static void mov_current_sample_inc(MOVStreamContext *sc)
Definition: mov.c:4457
AVStream::sample_aspect_ratio
AVRational sample_aspect_ratio
sample aspect ratio (0 if unknown)
Definition: avformat.h:844
FFInputFormat::p
AVInputFormat p
The public AVInputFormat.
Definition: demux.h:70
dovi_isom.h
AVPacket::dts
int64_t dts
Decompression timestamp in AVStream->time_base units; the time at which the packet is decompressed.
Definition: packet.h:602
mov_read_vexu_proj
static int mov_read_vexu_proj(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:7327
fix_timescale
static void fix_timescale(MOVContext *c, MOVStreamContext *sc)
Definition: mov.c:5480
avio_r8
int avio_r8(AVIOContext *s)
Definition: aviobuf.c:606
IAMFAudioElement::substreams
IAMFSubStream * substreams
Definition: iamf.h:98
AVSphericalMapping::padding
uint32_t padding
Number of pixels to pad from the edge of each cube face.
Definition: spherical.h:200
a
The reader does not expect b to be semantically here and if the code is changed by maybe adding a a division or other the signedness will almost certainly be mistaken To avoid this confusion a new type was SUINT is the C unsigned type but it holds a signed int to use the same example SUINT a
Definition: undefined.txt:41
av_channel_layout_retype
int av_channel_layout_retype(AVChannelLayout *channel_layout, enum AVChannelOrder order, int flags)
Change the AVChannelOrder of a channel layout.
Definition: channel_layout.c:887
mov_parse_dovi_streams
static int mov_parse_dovi_streams(AVFormatContext *s)
Definition: mov.c:11450
av_reallocp_array
int av_reallocp_array(void *ptr, size_t nmemb, size_t size)
Allocate, reallocate an array through a pointer to a pointer.
Definition: mem.c:225
AVIAMFAudioElement
Information on how to combine one or more audio streams, as defined in section 3.6 of IAMF.
Definition: iamf.h:359
AV_PRIMARY_EYE_NONE
@ AV_PRIMARY_EYE_NONE
Neither eye.
Definition: stereo3d.h:178
mov_read_default
static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:10118
AV_PROFILE_DTS
#define AV_PROFILE_DTS
Definition: defs.h:87
AV_TIMECODE_FLAG_24HOURSMAX
@ AV_TIMECODE_FLAG_24HOURSMAX
timecode wraps after 24 hours
Definition: timecode.h:37
mov_find_reference_track
static AVStream * mov_find_reference_track(AVFormatContext *s, AVStream *st, uint32_t *tref_id, int nb_tref_id, int first_index)
Definition: mov.c:11334
MOV_MP4_FPCM_TAG
#define MOV_MP4_FPCM_TAG
Definition: isom.h:484
ffio_ensure_seekback
int ffio_ensure_seekback(AVIOContext *s, int64_t buf_size)
Ensures that the requested seekback buffer size will be available.
Definition: aviobuf.c:1026
AVStreamGroupTileGrid::nb_tiles
unsigned int nb_tiles
Amount of tiles in the grid.
Definition: avformat.h:981
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:613
mov_read_packet
static int mov_read_packet(AVFormatContext *s, AVPacket *pkt)
Definition: mov.c:12046
mov_read_infe
static int mov_read_infe(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:9504
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
AV_CODEC_ID_LCEVC
@ AV_CODEC_ID_LCEVC
Definition: codec_id.h:609
AV_CH_TOP_BACK_RIGHT
#define AV_CH_TOP_BACK_RIGHT
Definition: channel_layout.h:192
MOVEncryptionIndex::auxiliary_offsets_count
size_t auxiliary_offsets_count
Definition: isom.h:142
HEIFItem::vflip
int vflip
Definition: isom.h:310
AVPacket::flags
int flags
A combination of AV_PKT_FLAG values.
Definition: packet.h:609
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:578
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
AV_CH_FRONT_RIGHT_OF_CENTER
#define AV_CH_FRONT_RIGHT_OF_CENTER
Definition: channel_layout.h:182
AVSubsampleEncryptionInfo
This file is part of FFmpeg.
Definition: encryption_info.h:25
av_buffer_alloc
AVBufferRef * av_buffer_alloc(size_t size)
Allocate an AVBuffer of the given size using av_malloc().
Definition: buffer.c:77
MOVFragmentIndexItem::stream_info
MOVFragmentStreamInfo * stream_info
Definition: isom.h:163
version
version
Definition: libkvazaar.c:313
AV_STREAM_GROUP_PARAMS_IAMF_AUDIO_ELEMENT
@ AV_STREAM_GROUP_PARAMS_IAMF_AUDIO_ELEMENT
Definition: avformat.h:1148
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:1234
ff_rfps_calculate
void ff_rfps_calculate(AVFormatContext *ic)
Definition: demux.c:2397
input
and forward the test the status of outputs and forward it to the corresponding return FFERROR_NOT_READY If the filters stores internally one or a few frame for some input
Definition: filter_design.txt:172
MOV_MP4_IPCM_TAG
#define MOV_MP4_IPCM_TAG
Definition: isom.h:485
mov_read_clli
static int mov_read_clli(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:7008
MOVStreamContext::chunk_offsets
int64_t * chunk_offsets
Definition: isom.h:187
MovTref::id
uint32_t * id
trackID of the referenced track
Definition: isom.h:97
AVStreamGroup::iamf_mix_presentation
struct AVIAMFMixPresentation * iamf_mix_presentation
Definition: avformat.h:1193
AVBufferRef::size
size_t size
Size of data in bytes.
Definition: buffer.h:94
MOVFragmentIndex::item
MOVFragmentIndexItem * item
Definition: isom.h:171
AV_LOG_INFO
#define AV_LOG_INFO
Standard information.
Definition: log.h:221
MOVStreamContext::iamf
struct IAMFDemuxContext * iamf
Definition: isom.h:289
FFERROR_REDO
#define FFERROR_REDO
Returned by demuxers to indicate that data was consumed but discarded (ignored streams or junk data).
Definition: demux.h:224
av_encryption_init_info_alloc
AVEncryptionInitInfo * av_encryption_init_info_alloc(uint32_t system_id_size, uint32_t num_key_ids, uint32_t key_id_size, uint32_t data_size)
Allocates an AVEncryptionInitInfo structure and sub-pointers to hold the given sizes.
Definition: encryption_info.c:178
av_channel_layout_custom_init
int av_channel_layout_custom_init(AVChannelLayout *channel_layout, int nb_channels)
Initialize a custom channel layout with the specified number of channels.
Definition: channel_layout.c:233
av_aes_ctr_free
void av_aes_ctr_free(struct AVAESCTR *a)
Release an AVAESCTR context.
Definition: aes_ctr.c:84
MOVPresentationSample::index
int index
Definition: mov.c:5277
AVFormatContext::error_recognition
int error_recognition
Error recognition; higher values will detect more errors but may misdetect some more or less valid pa...
Definition: avformat.h:1592
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:8530
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:9985
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:1081
mov_metadata_creation_time
static void mov_metadata_creation_time(MOVContext *c, AVIOContext *pb, AVDictionary **metadata, int version)
Definition: mov.c:1972
mov_metadata_hmmt
static int mov_metadata_hmmt(MOVContext *c, AVIOContext *pb, unsigned len)
Definition: mov.c:326
AV_CODEC_ID_MJPEG
@ AV_CODEC_ID_MJPEG
Definition: codec_id.h:57
MOVFragmentStreamInfo::next_trun_dts
int64_t next_trun_dts
Definition: isom.h:150
MOVStreamContext::stsc_index
unsigned int stsc_index
Definition: isom.h:201
av_sha_alloc
struct AVSHA * av_sha_alloc(void)
Allocate an AVSHA context.
Definition: sha.c:46
mov_read_tenc
static int mov_read_tenc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:8459
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:3597
mov_finalize_packet
static int mov_finalize_packet(AVFormatContext *s, AVStream *st, AVIndexEntry *sample, int64_t current_index, AVPacket *pkt)
Definition: mov.c:11962
MOVIndexRange
Definition: isom.h:174
mov_read_seek
static int mov_read_seek(AVFormatContext *s, int stream_index, int64_t sample_time, int flags)
Definition: mov.c:12381
bprint.h
MOVContext::advanced_editlist
int advanced_editlist
Definition: isom.h:350
MOVStreamContext::time_scale
int time_scale
Definition: isom.h:216
mlp_parse.h
mac_to_unicode
static const uint32_t mac_to_unicode[128]
Definition: mov.c:152
AVStreamGroupTileGrid::width
int width
Width of the final image for presentation.
Definition: avformat.h:1058
MOVStreamContext::bytes_per_frame
unsigned int bytes_per_frame
Definition: isom.h:223
AVSphericalMapping::roll
int32_t roll
Rotation around the forward vector [-180, 180].
Definition: spherical.h:146
current
static struct @602 current
IAMFContext::nb_audio_elements
int nb_audio_elements
Definition: iamf.h:132
MOVIndexRange::end
int64_t end
Definition: isom.h:176
AV_CODEC_ID_NONE
@ AV_CODEC_ID_NONE
Definition: codec_id.h:48
AVPacket::pts
int64_t pts
Presentation timestamp in AVStream->time_base units; the time at which the decompressed packet will b...
Definition: packet.h:596
code
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 it can consider them to be part of the FIFO and delay acknowledging a status change accordingly Example code
Definition: filter_design.txt:178
avio_internal.h
MOVCtts::offset
int offset
Definition: isom.h:70
AV_CH_SIDE_SURROUND_RIGHT
#define AV_CH_SIDE_SURROUND_RIGHT
Definition: channel_layout.h:206
mov_read_trex
static int mov_read_trex(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6124
search_frag_timestamp
static int search_frag_timestamp(AVFormatContext *s, MOVFragmentIndex *frag_index, AVStream *st, int64_t timestamp)
Definition: mov.c:1845
HEIFItem::width
int width
Definition: isom.h:306
FLAGS
#define FLAGS
Definition: mov.c:12438
MOVStreamContext::stereo3d
AVStereo3D * stereo3d
Definition: isom.h:267
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:4509
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:8307
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:3451
internal.h
AV_SPHERICAL_FISHEYE
@ AV_SPHERICAL_FISHEYE
Fisheye projection (Apple).
Definition: spherical.h:84
AVCodecParameters::height
int height
The height of the video frame in pixels.
Definition: codec_par.h:150
AV_TIME_BASE
#define AV_TIME_BASE
Internal time base represented as integer.
Definition: avutil.h:253
MOVStreamContext::stps_count
unsigned int stps_count
Definition: isom.h:203
AVCodecParameters::block_align
int block_align
The number of bytes per coded audio frame, required by some formats.
Definition: codec_par.h:221
AV_CODEC_ID_TTML
@ AV_CODEC_ID_TTML
Definition: codec_id.h:590
rb_size
static int rb_size(AVIOContext *pb, int64_t *value, int size)
Definition: mov.c:9377
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:137
display.h
ff_mov_read_stsd_entries
int ff_mov_read_stsd_entries(MOVContext *c, AVIOContext *pb, int entries)
Definition: mov.c:3350
AV_FIELD_BB
@ AV_FIELD_BB
Bottom coded first, bottom displayed first.
Definition: defs.h:215
AV_PKT_DATA_ICC_PROFILE
@ AV_PKT_DATA_ICC_PROFILE
ICC profile data consisting of an opaque octet buffer following the format described by ISO 15076-1.
Definition: packet.h:271
AV_STEREO3D_TOPBOTTOM
@ AV_STEREO3D_TOPBOTTOM
Views are on top of each other.
Definition: stereo3d.h:76
MOVFragment::duration
unsigned duration
Definition: isom.h:114
AVIAMFMixPresentation
Information on how to render and mix one or more AVIAMFAudioElement to generate the final audio outpu...
Definition: iamf.h:616
ff_id3v1_genre_str
const char *const ff_id3v1_genre_str[ID3v1_GENRE_MAX+1]
ID3v1 genres.
Definition: id3v1.c:26
MOVStreamContext::sample_sizes
unsigned int * sample_sizes
Definition: isom.h:212
s
uint8_t s
Definition: llvidencdsp.c:39
MOVContext::frag_index
MOVFragmentIndex frag_index
Definition: isom.h:363
mov_read_vpcc
static int mov_read_vpcc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6836
AV_CODEC_ID_PCM_F64BE
@ AV_CODEC_ID_PCM_F64BE
Definition: codec_id.h:352
AVStreamGroupLayeredVideo::width
int width
Width of the final stream for presentation.
Definition: avformat.h:1114
AV_CODEC_ID_HEVC
@ AV_CODEC_ID_HEVC
Definition: codec_id.h:223
AV_CH_BACK_CENTER
#define AV_CH_BACK_CENTER
Definition: channel_layout.h:183
value
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf default value
Definition: writing_filters.txt:86
av_url_split
void av_url_split(char *proto, int proto_size, char *authorization, int authorization_size, char *hostname, int hostname_size, int *port_ptr, char *path, int path_size, const char *url)
Split a URL string into components.
Definition: utils.c:361
MOVStreamContext::dref_id
int dref_id
Definition: isom.h:230
FFMIN
#define FFMIN(a, b)
Definition: macros.h:49
av_d2q
AVRational av_d2q(double d, int max)
Convert a double precision floating point number to a rational.
Definition: rational.c:110
fix_frag_index_entries
static void fix_frag_index_entries(MOVFragmentIndex *frag_index, int index, int id, int entries)
Definition: mov.c:1931
mov_finalize_stsd_codec
static int mov_finalize_stsd_codec(MOVContext *c, AVIOContext *pb, AVStream *st, MOVStreamContext *sc)
Definition: mov.c:3199
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:339
mov_read_mdcv
static int mov_read_mdcv(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6927
AVStreamGroupTileGrid::offsets
struct AVStreamGroupTileGrid::@461 * offsets
An nb_tiles sized array of offsets in pixels from the topleft edge of the canvas, indicating where ea...
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:1498
AV_CODEC_ID_VC1
@ AV_CODEC_ID_VC1
Definition: codec_id.h:120
demux.h
AV_DISPOSITION_DEPENDENT
#define AV_DISPOSITION_DEPENDENT
The stream is intended to be mixed with another stream before presentation.
Definition: avformat.h:727
MOVStreamContext::pb
AVIOContext * pb
Definition: isom.h:180
mov_read_keys
static int mov_read_keys(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5720
AVCodecParameters::color_range
enum AVColorRange color_range
Additional colorspace characteristics.
Definition: codec_par.h:189
AV_CH_SIDE_RIGHT
#define AV_CH_SIDE_RIGHT
Definition: channel_layout.h:185
len
int len
Definition: vorbis_enc_data.h:426
AV_CODEC_ID_JPEG2000
@ AV_CODEC_ID_JPEG2000
Definition: codec_id.h:138
exif.h
MOVFragment::size
unsigned size
Definition: isom.h:115
MOV_TFHD_DEFAULT_SIZE
#define MOV_TFHD_DEFAULT_SIZE
Definition: isom.h:411
MOVTimeToSample::count
unsigned int count
Definition: isom.h:58
profile
int profile
Definition: mxfenc.c:2299
ff_get_wav_header
int ff_get_wav_header(AVFormatContext *s, AVIOContext *pb, AVCodecParameters *par, int size, int big_endian)
Definition: riffdec.c:141
AVCOL_SPC_UNSPECIFIED
@ AVCOL_SPC_UNSPECIFIED
Definition: pixfmt.h:709
fix_stream_ids
static void fix_stream_ids(AVFormatContext *s)
Definition: mov.c:11523
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:4960
AVCodecParameters::coded_side_data
AVPacketSideData * coded_side_data
Additional data associated with the entire stream.
Definition: codec_par.h:83
mov_read_svq3
static int mov_read_svq3(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2518
mov_find_tref_tag
static MovTref * mov_find_tref_tag(const MOVStreamContext *sc, uint32_t name)
Definition: mov.c:2675
AVSHA
hash context
Definition: sha.c:35
AVCOL_RANGE_MPEG
@ AVCOL_RANGE_MPEG
Narrow or limited range content.
Definition: pixfmt.h:766
av_calloc
void * av_calloc(size_t nmemb, size_t size)
Definition: mem.c:264
MOVFragmentStreamInfo::tfdt_dts
int64_t tfdt_dts
Definition: isom.h:149
AV_IAMF_AUDIO_ELEMENT_TYPE_SCENE
@ AV_IAMF_AUDIO_ELEMENT_TYPE_SCENE
Definition: iamf.h:349
AVCodecParameters::field_order
enum AVFieldOrder field_order
The order of the fields in interlaced video.
Definition: codec_par.h:182
av_get_packet
int av_get_packet(AVIOContext *s, AVPacket *pkt, int size)
Allocate and read the payload of a packet and initialize its fields with default values.
Definition: utils.c:98
mov_read_iinf
static int mov_read_iinf(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:9581
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:1017
get_stream_info_time
static int64_t get_stream_info_time(MOVFragmentStreamInfo *frag_stream_info)
Definition: mov.c:1793
MP4TrackKindValueMapping
Definition: isom.h:487
fix_index_entry_timestamps
static void fix_index_entry_timestamps(AVStream *st, int end_index, int64_t end_ts, int64_t *frame_duration_buffer, int frame_duration_buffer_size)
Rewrite timestamps of index entries in the range [end_index - frame_duration_buffer_size,...
Definition: mov.c:4360
AV_WB8
#define AV_WB8(p, d)
Definition: intreadwrite.h:392
MOVStreamContext::chunk_count
unsigned int chunk_count
Definition: isom.h:186
av_cmp_q
static int av_cmp_q(AVRational a, AVRational b)
Compare two rationals.
Definition: rational.h:89
MOVStreamContext::data_size
int64_t data_size
Definition: isom.h:240
AV_TIMECODE_FLAG_DROPFRAME
@ AV_TIMECODE_FLAG_DROPFRAME
timecode is drop frame
Definition: timecode.h:36
language
Undefined Behavior In the C language
Definition: undefined.txt:3
MOVStreamContext::ambient
AVAmbientViewingEnvironment * ambient
Definition: isom.h:275
AVCodecParameters::avcodec_parameters_copy
int avcodec_parameters_copy(AVCodecParameters *dst, const AVCodecParameters *src)
Copy the contents of src to dst.
Definition: codec_par.c:107
mov_read_tmcd
static int mov_read_tmcd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6808
AV_PROFILE_DTS_96_24
#define AV_PROFILE_DTS_96_24
Definition: defs.h:89
mov_chan.h
AVStream::disposition
int disposition
Stream disposition - a combination of AV_DISPOSITION_* flags.
Definition: avformat.h:835
MOVStreamContext::ambient_size
size_t ambient_size
Definition: isom.h:276
tag
uint32_t tag
Definition: movenc.c:2073
AVStream::id
int id
Format-specific stream ID.
Definition: avformat.h:778
ret
ret
Definition: filter_design.txt:187
AVStream
Stream structure.
Definition: avformat.h:766
AV_CODEC_ID_APV
@ AV_CODEC_ID_APV
Definition: codec_id.h:323
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:304
MOVEncryptionIndex::nb_encrypted_samples
unsigned int nb_encrypted_samples
Definition: isom.h:135
mov_read_senc
static int mov_read_senc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:8010
avio_seek
int64_t avio_seek(AVIOContext *s, int64_t offset, int whence)
fseek() equivalent for AVIOContext.
Definition: aviobuf.c:236
AVStreamGroupLayeredVideo::height
int height
Height of the final image for presentation.
Definition: avformat.h:1118
FFSWAP
#define FFSWAP(type, a, b)
Definition: macros.h:52
AVClass::class_name
const char * class_name
The name of the class; usually it is the same name as the context structure type to which the AVClass...
Definition: log.h:81
AVEncryptionInfo::key_id
uint8_t * key_id
The ID of the key used to encrypt the packet.
Definition: encryption_info.h:63
av_strlcat
size_t av_strlcat(char *dst, const char *src, size_t size)
Append the string src to the string dst, but to a total length of no more than size - 1 bytes,...
Definition: avstring.c:95
MOVStreamContext::stts_data
MOVStts * stts_data
Definition: isom.h:193
AVSphericalMapping::pitch
int32_t pitch
Rotation around the right vector [-90, 90].
Definition: spherical.h:145
AVStreamGroup::metadata
AVDictionary * metadata
Metadata that applies to the whole group.
Definition: avformat.h:1214
avio_rb16
unsigned int avio_rb16(AVIOContext *s)
Definition: aviobuf.c:749
AVStereo3D::type
enum AVStereo3DType type
How views are packed within the video.
Definition: stereo3d.h:207
MOVSbgp::index
unsigned int index
Definition: isom.h:129
HEIFItem::icc_profile_size
size_t icc_profile_size
Definition: isom.h:314
MOVContext::chapter_tracks
int * chapter_tracks
Definition: isom.h:346
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:612
pos
unsigned int pos
Definition: spdifenc.c:431
avformat.h
dovi_meta.h
MOVFragment::implicit_offset
uint64_t implicit_offset
Definition: isom.h:112
dict.h
av_packet_side_data_new
AVPacketSideData * av_packet_side_data_new(AVPacketSideData **psd, int *pnb_sd, enum AVPacketSideDataType type, size_t size, int flags)
Allocate a new packet side data.
Definition: packet.c:620
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:9039
AV_INPUT_BUFFER_PADDING_SIZE
#define AV_INPUT_BUFFER_PADDING_SIZE
Definition: defs.h:40
MOVStreamContext::pseudo_stream_id
int pseudo_stream_id
-1 means demux all ids
Definition: isom.h:226
MOVContext::time_scale
int time_scale
Definition: isom.h:328
id
enum AVCodecID id
Definition: dts2pts.c:607
mov_read_tfdt
static int mov_read_tfdt(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6150
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:5866
search_frag_moof_offset
static int search_frag_moof_offset(MOVFragmentIndex *frag_index, int64_t offset)
Definition: mov.c:1769
MOVFragment
Definition: isom.h:107
AV_DICT_MATCH_CASE
#define AV_DICT_MATCH_CASE
Only get an entry with exact-case key match.
Definition: dict.h:74
AV_RL32
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_RL32
Definition: bytestream.h:92
U
#define U(x)
Definition: vpx_arith.h:37
mov_switch_root
static int mov_switch_root(AVFormatContext *s, int64_t target, int index)
Definition: mov.c:11833
FLAC_METADATA_TYPE_STREAMINFO
@ FLAC_METADATA_TYPE_STREAMINFO
Definition: flac.h:46
MOVContext::use_mfra_for
int use_mfra_for
Definition: isom.h:360
AVEncryptionInfo
This describes encryption info for a packet.
Definition: encryption_info.h:43
MOVStreamContext::encryption_index
MOVEncryptionIndex * encryption_index
Definition: isom.h:286
MIN_DATA_ENTRY_BOX_SIZE
#define MIN_DATA_ENTRY_BOX_SIZE
Definition: mov.c:653
AVStreamGroup
Definition: avformat.h:1159
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:772
avpriv_dv_init_demux
DVDemuxContext * avpriv_dv_init_demux(AVFormatContext *s)
Definition: dv.c:728
mov_seek_fragment
static int mov_seek_fragment(AVFormatContext *s, AVStream *st, int64_t timestamp)
Definition: mov.c:12227
AV_PROFILE_DTS_HD_MA
#define AV_PROFILE_DTS_HD_MA
Definition: defs.h:91
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:2925
ff_codec_bmp_tags
const AVCodecTag ff_codec_bmp_tags[]
Definition: riff.c:36
MOVStreamContext::h_spacing
int h_spacing
pasp hSpacing
Definition: isom.h:235
mov_read_dec3
static int mov_read_dec3(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1127
get_frag_time
static int64_t get_frag_time(AVFormatContext *s, AVStream *dst_st, MOVFragmentIndex *frag_index, int index)
Definition: mov.c:1803
MOVStreamContext::sample_size
unsigned int sample_size
may contain value calculated from stsd or value from stsz atom
Definition: isom.h:209
HEVC_NAL_CRA_NUT
@ HEVC_NAL_CRA_NUT
Definition: hevc.h:50
AVStreamGroup::nb_streams
unsigned int nb_streams
Number of elements in AVStreamGroup.streams.
Definition: avformat.h:1221
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:257
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:4116
MOVFragment::moof_offset
uint64_t moof_offset
Definition: isom.h:111
AVIO_SEEKABLE_NORMAL
#define AVIO_SEEKABLE_NORMAL
Seeking works like for a local file.
Definition: avio.h:41
av_packet_new_side_data
uint8_t * av_packet_new_side_data(AVPacket *pkt, enum AVPacketSideDataType type, size_t size)
Allocate new information of a packet.
Definition: packet.c:231
buffer
the frame and frame reference mechanism is intended to as much as expensive copies of that data while still allowing the filters to produce correct results The data is stored in buffers represented by AVFrame structures Several references can point to the same frame buffer
Definition: filter_design.txt:49
mov_read_glbl
static int mov_read_glbl(MOVContext *c, AVIOContext *pb, MOVAtom atom)
This function reads atom content and puts data in extradata without tag nor size unlike mov_read_extr...
Definition: mov.c:2580
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:7668
MOVTrackExt::size
unsigned size
Definition: isom.h:123
AVDOVIDecoderConfigurationRecord::bl_present_flag
uint8_t bl_present_flag
Definition: dovi_meta.h:62
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:130
AV_OPT_TYPE_INT
@ AV_OPT_TYPE_INT
Underlying C type is int.
Definition: opt.h:258
MOVContext::dv_fctx
AVFormatContext * dv_fctx
Definition: isom.h:339
av_channel_layout_uninit
void av_channel_layout_uninit(AVChannelLayout *channel_layout)
Free any allocated data in the channel layout and reset the channel count to 0.
Definition: channel_layout.c:443
AV_CODEC_ID_DVAUDIO
@ AV_CODEC_ID_DVAUDIO
Definition: codec_id.h:459
avformat_free_context
void avformat_free_context(AVFormatContext *s)
Free an AVFormatContext and all its streams.
Definition: avformat.c:150
MOVContext::aax_mode
unsigned int aax_mode
'aax' file has been detected
Definition: isom.h:365
mov_read_sv3d
static int mov_read_sv3d(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:7190
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:1609
mov_get_skip_samples
static int64_t mov_get_skip_samples(AVStream *st, int sample)
Definition: mov.c:12365
MOVFragmentIndex
Definition: isom.h:166
AV_RB8
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_WL16 uint64_t_TMPL AV_WB64 unsigned int_TMPL AV_WB32 unsigned int_TMPL AV_WB24 unsigned int_TMPL AV_WB16 unsigned int_TMPL AV_RB8
Definition: bytestream.h:99
ref
static int ref[MAX_W *MAX_W]
Definition: jpeg2000dwt.c:117
mov_read_cdsc
static int mov_read_cdsc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2703
AVStream::r_frame_rate
AVRational r_frame_rate
Real base framerate of the stream.
Definition: avformat.h:900
MOVStreamContext::tts_count
unsigned int tts_count
Definition: isom.h:188
MOVStreamContext::track_end
int64_t track_end
used for dts generation in fragmented movie files
Definition: isom.h:243
MOVStreamContext::sgpd_sync_count
uint32_t sgpd_sync_count
Definition: isom.h:249
MOVContext::fragment
MOVFragment fragment
current fragment in moof atom
Definition: isom.h:341
AVDOVIDecoderConfigurationRecord::rpu_present_flag
uint8_t rpu_present_flag
Definition: dovi_meta.h:60
AVIndexEntry::pos
int64_t pos
Definition: avformat.h:621
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:113
AVDOVIDecoderConfigurationRecord::el_present_flag
uint8_t el_present_flag
Definition: dovi_meta.h:61
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:233
MOVParseTableEntry::type
uint32_t type
Definition: mov.c:85
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:284
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:605
MOVFragmentIndexItem::nb_stream_info
int nb_stream_info
Definition: isom.h:162
avio_skip
int64_t avio_skip(AVIOContext *s, int64_t offset)
Skip given number of bytes forward.
Definition: aviobuf.c:321
export_orphan_timecode
static void export_orphan_timecode(AVFormatContext *s)
Definition: mov.c:10671
mov_read_sbas
static int mov_read_sbas(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2734
MOVStreamContext::has_sidx
int has_sidx
Definition: isom.h:280
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:136
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:4890
FFStream::index_entries
AVIndexEntry * index_entries
Only used if the format does not support seeking natively.
Definition: internal.h:191
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:2403
AVIAMFSubmix::nb_elements
unsigned int nb_elements
Number of elements in the submix.
Definition: iamf.h:575
MOVFragmentStreamInfo::id
int id
Definition: isom.h:146
AVIO_FLAG_READ
#define AVIO_FLAG_READ
read-only
Definition: avio.h:617
AV_PKT_DATA_AUDIO_SERVICE_TYPE
@ AV_PKT_DATA_AUDIO_SERVICE_TYPE
This side data should be associated with an audio stream and corresponds to enum AVAudioServiceType.
Definition: packet.h:117
av_spherical_alloc
AVSphericalMapping * av_spherical_alloc(size_t *size)
Allocate a AVSphericalVideo structure and initialize its fields to default values.
Definition: spherical.c:26
AV_OPT_FLAG_DECODING_PARAM
#define AV_OPT_FLAG_DECODING_PARAM
A generic parameter which can be set by the user for demuxing or decoding.
Definition: opt.h:355
mov_read_rtmd_track
static int mov_read_rtmd_track(AVFormatContext *s, AVStream *st)
Definition: mov.c:10448
AVMEDIA_TYPE_VIDEO
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:200
read_probe
static int read_probe(const AVProbeData *p)
Definition: cdg.c:30
MOVStreamContext::pb_is_copied
int pb_is_copied
Definition: isom.h:182
AV_CODEC_ID_PCM_S32LE
@ AV_CODEC_ID_PCM_S32LE
Definition: codec_id.h:338
AVCodecParameters::bits_per_coded_sample
int bits_per_coded_sample
The number of bits per sample in the codedwords.
Definition: codec_par.h:113
mov_parse_tiles
static int mov_parse_tiles(AVFormatContext *s)
Definition: mov.c:11073
mem.h
AVStreamGroup::type
enum AVStreamGroupParamsType type
Group type.
Definition: avformat.h:1186
MOVElst::time
int64_t time
Definition: isom.h:81
AVBufferRef
A reference to a data buffer.
Definition: buffer.h:82
HEIFGrid
Definition: isom.h:317
mov_read_iref_dimg
static int mov_read_iref_dimg(MOVContext *c, AVIOContext *pb, int version)
Definition: mov.c:9635
mov_read_pcmc
static int mov_read_pcmc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2125
build_open_gop_key_points
static int build_open_gop_key_points(AVStream *st)
Definition: mov.c:4827
mov_parse_stsd_audio
static void mov_parse_stsd_audio(MOVContext *c, AVIOContext *pb, AVStream *st, MOVStreamContext *sc)
Definition: mov.c:2989
IAMFContext::mix_presentations
IAMFMixPresentation ** mix_presentations
Definition: iamf.h:133
AV_CODEC_ID_PCM_U8
@ AV_CODEC_ID_PCM_U8
Definition: codec_id.h:335
MOVContext::trak_index
int trak_index
Index of the current 'trak'.
Definition: isom.h:335
mov_read_timecode_track
static int mov_read_timecode_track(AVFormatContext *s, AVStream *st)
Definition: mov.c:10474
HEIFGrid::item
HEIFItem * item
Definition: isom.h:318
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:171
MOVEncryptionIndex::auxiliary_info_sizes
uint8_t * auxiliary_info_sizes
Definition: isom.h:138
MOVFragment::stsd_id
unsigned stsd_id
Definition: isom.h:113
AVCodecParameters::video_delay
int video_delay
Number of delayed frames.
Definition: codec_par.h:200
HEIFGrid::tile_id_list
int16_t * tile_id_list
Definition: isom.h:320
avpriv_request_sample
#define avpriv_request_sample(...)
Definition: tableprint_vlc.h:37
MOVStreamContext::tts_data
MOVTimeToSample * tts_data
Definition: isom.h:190
map
const VDPAUPixFmtMap * map
Definition: hwcontext_vdpau.c:71
avformat_stream_group_create
AVStreamGroup * avformat_stream_group_create(AVFormatContext *s, enum AVStreamGroupParamsType type, AVDictionary **options)
Add a new empty stream group to a media file.
Definition: options.c:470
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:353
AVStreamGroupTileGrid::height
int height
Height of the final image for presentation.
Definition: avformat.h:1068
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:10689
av_free
#define av_free(p)
Definition: tableprint_vlc.h:34
AVDictionaryEntry
Definition: dict.h:90
mov_read_hvce
static int mov_read_hvce(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:9094
av_add_q
AVRational av_add_q(AVRational b, AVRational c)
Add two rationals.
Definition: rational.c:93
AVCodecParameters::codec_id
enum AVCodecID codec_id
Specific type of the encoded data (the codec used).
Definition: codec_par.h:57
AV_PKT_DATA_HEVC_CONF
@ AV_PKT_DATA_HEVC_CONF
Dolby Vision enhancement-layer HEVC decoder configuration.
Definition: packet.h:384
AVStereo3DView
AVStereo3DView
List of possible view types.
Definition: stereo3d.h:149
AV_CH_SIDE_SURROUND_LEFT
#define AV_CH_SIDE_SURROUND_LEFT
Definition: channel_layout.h:205
AVPacket
This structure stores compressed data.
Definition: packet.h:580
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:11396
mov_read_hfov
static int mov_read_hfov(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:7639
AV_OPT_TYPE_BOOL
@ AV_OPT_TYPE_BOOL
Underlying C type is int.
Definition: opt.h:326
MOVStreamContext::stps_data
unsigned * stps_data
partial sync sample for mpeg-2 open gop
Definition: isom.h:204
AV_CODEC_ID_ADPCM_IMA_WAV
@ AV_CODEC_ID_ADPCM_IMA_WAV
Definition: codec_id.h:371
MOVContext::nb_heif_item
int nb_heif_item
Definition: isom.h:387
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:623
FFInputFormat
Definition: demux.h:66
MOVContext::decryption_keys
AVDictionary * decryption_keys
Definition: isom.h:392
mov_metadata_loci
static int mov_metadata_loci(MOVContext *c, AVIOContext *pb, unsigned len)
Definition: mov.c:276
mov_read_eyes
static int mov_read_eyes(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:7400
AV_CODEC_ID_ILBC
@ AV_CODEC_ID_ILBC
Definition: codec_id.h:512
AV_CHAN_AMBISONIC_BASE
@ AV_CHAN_AMBISONIC_BASE
Range of channels between AV_CHAN_AMBISONIC_BASE and AV_CHAN_AMBISONIC_END represent Ambisonic compon...
Definition: channel_layout.h:108
MOV_TRUN_SAMPLE_SIZE
#define MOV_TRUN_SAMPLE_SIZE
Definition: isom.h:419
MOVStreamContext::tmcd_flags
uint32_t tmcd_flags
tmcd track flags
Definition: isom.h:241
int32_t
int32_t
Definition: audioconvert.c:56
HEIFItem::rotation
int rotation
Definition: isom.h:308
MOVAtom::type
uint32_t type
Definition: isom.h:101
distance
static float distance(float x, float y, int band)
Definition: nellymoserenc.c:231
AVSTREAM_PARSE_FULL
@ AVSTREAM_PARSE_FULL
full parsing and repack
Definition: avformat.h:611
parse_timecode_in_framenum_format
static int parse_timecode_in_framenum_format(AVFormatContext *s, AVStream *st, int64_t value, int flags)
Definition: mov.c:10434
MOVStreamContext::tmcd_nb_frames
uint8_t tmcd_nb_frames
tmcd number of frames per tick / second
Definition: isom.h:242
AVIAMFSubmixElement
Submix element as defined in section 3.7 of IAMF.
Definition: iamf.h:449
replaygain.h
MOVFragmentIndexItem::headers_read
int headers_read
Definition: isom.h:160
AV_CODEC_ID_VP8
@ AV_CODEC_ID_VP8
Definition: codec_id.h:190
AVERROR_BUG
#define AVERROR_BUG
Internal bug, also see AVERROR_BUG2.
Definition: error.h:52
mov_parse_cdsc_streams
static int mov_parse_cdsc_streams(AVFormatContext *s)
Definition: mov.c:11349
MP4TrackKindValueMapping::value
const char * value
Definition: isom.h:489
AVStereo3DType
AVStereo3DType
List of possible 3D Types.
Definition: stereo3d.h:48
MOVDref::filename
char filename[64]
Definition: isom.h:90
MOVStsc::count
int count
Definition: isom.h:75
AV_CODEC_ID_PCM_F32LE
@ AV_CODEC_ID_PCM_F32LE
Definition: codec_id.h:351
ff_mov_demuxer
const FFInputFormat ff_mov_demuxer
Definition: mov.c:12500
AVCodecParameters::bit_rate
int64_t bit_rate
The average bitrate of the encoded data (in bits per second).
Definition: codec_par.h:99
MOVStts::count
unsigned int count
Definition: isom.h:64
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
MOVStreamContext::display_matrix
int32_t * display_matrix
Definition: isom.h:266
MOVContext::heif_grid
HEIFGrid * heif_grid
Definition: isom.h:388
MOVStreamContext::min_sample_duration
uint32_t min_sample_duration
Definition: isom.h:254
MOVStreamContext::current_index
int64_t current_index
Definition: isom.h:220
AVERROR_INVALIDDATA
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:61
ff_mov_track_kind_table
const struct MP4TrackKindMapping ff_mov_track_kind_table[]
Definition: isom.c:465
AV_CH_BACK_RIGHT
#define AV_CH_BACK_RIGHT
Definition: channel_layout.h:180
get_curr_st
static AVStream * get_curr_st(MOVContext *c)
Get the current stream in the parsing process.
Definition: mov.c:215
mov_dts_channel_layout_to_mask
static uint64_t mov_dts_channel_layout_to_mask(unsigned int code)
Definition: mov.c:1209
MOVStreamContext::stts_allocated_size
unsigned int stts_allocated_size
Definition: isom.h:192
MOVFragmentStreamInfo::index_entry
int index_entry
Definition: isom.h:153
cenc_decrypt
static int cenc_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
Definition: mov.c:8875
MOVStreamContext::format
uint32_t format
Definition: isom.h:278
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:246
MOVContext::bitrates_count
int bitrates_count
Definition: isom.h:358
AV_CODEC_ID_VORBIS
@ AV_CODEC_ID_VORBIS
Definition: codec_id.h:458
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:815
MOVStreamContext::id
int id
AVStream id.
Definition: isom.h:183
MOVStreamContext::samples_per_frame
unsigned int samples_per_frame
Definition: isom.h:224
MOVStreamContext::tts_allocated_size
unsigned int tts_allocated_size
Definition: isom.h:189
pkt
static AVPacket * pkt
Definition: demux_decode.c:55
MOVElst::duration
int64_t duration
Definition: isom.h:80
ac3tab.h
avstring.h
mov_read_ispe
static int mov_read_ispe(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:9807
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:9762
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:1367
mov_read_mfra
static int mov_read_mfra(MOVContext *c, AVIOContext *f)
Definition: mov.c:10744
AV_CODEC_ID_FLV1
@ AV_CODEC_ID_FLV1
Definition: codec_id.h:71
mov_metadata_int8_no_padding
static int mov_metadata_int8_no_padding(MOVContext *c, AVIOContext *pb, unsigned len, const char *key)
Definition: mov.c:127
flac.h
AVStreamGroupTileGrid::idx
unsigned int idx
Index of the stream in the group this tile references.
Definition: avformat.h:1012
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:1714
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:9172
MOVContext::heif_item
HEIFItem ** heif_item
Definition: isom.h:386
AVChannelLayout::u
union AVChannelLayout::@530 u
Details about which channels are present in this layout.
MOVStreamContext::stts_count
unsigned int stts_count
Definition: isom.h:191
AVStreamGroupLayeredVideo::el_index
unsigned int el_index
Index of the enhancement layer stream in AVStreamGroup.
Definition: avformat.h:1102
MOV_TRUN_SAMPLE_CTS
#define MOV_TRUN_SAMPLE_CTS
Definition: isom.h:421
HEIFItem::iref_list
HEIFItemRef * iref_list
Definition: isom.h:300
AV_OPT_TYPE_CONST
@ AV_OPT_TYPE_CONST
Special option type for declaring named constants.
Definition: opt.h:298
MOV_ISMV_TTML_TAG
#define MOV_ISMV_TTML_TAG
Definition: isom.h:482
snprintf
#define snprintf
Definition: snprintf.h:34
IAMFMixPresentation::mix_presentation_id
unsigned int mix_presentation_id
Definition: iamf.h:114
AVCodecParameters::initial_padding
int initial_padding
Number of padding audio samples at the start.
Definition: codec_par.h:239
AV_CODEC_ID_PCM_S24BE
@ AV_CODEC_ID_PCM_S24BE
Definition: codec_id.h:343
mov_read_st3d
static int mov_read_st3d(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:7062
mov_read_imir
static int mov_read_imir(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:9855
is_open_key_sample
static int is_open_key_sample(const MOVStreamContext *sc, int sample)
Definition: mov.c:12246
mov_read_dvc1
static int mov_read_dvc1(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2626
MOVStreamContext::elst_count
unsigned int elst_count
Definition: isom.h:206
av_color_transfer_name
const char * av_color_transfer_name(enum AVColorTransferCharacteristic transfer)
Definition: pixdesc.c:3827
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:2340
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:10335
AV_CODEC_ID_DNXHD
@ AV_CODEC_ID_DNXHD
Definition: codec_id.h:149
channel
channel
Definition: ebur128.h:39
MOVStreamContext::default_encrypted_sample
AVEncryptionInfo * default_encrypted_sample
Definition: isom.h:285
duration
static int64_t duration
Definition: ffplay.c:329
MOVContext::cur_item_id
int cur_item_id
Definition: isom.h:385
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:1712
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:354
MOVContext::found_iinf
int found_iinf
'iinf' atom has been found
Definition: isom.h:332
MOVContext::meta_keys_count
unsigned meta_keys_count
Definition: isom.h:337
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:1032
MOVStreamContext::palette
uint32_t palette[256]
Definition: isom.h:238
cenc_scheme_decrypt
static int cenc_scheme_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
Definition: mov.c:8607
MOVFragment::track_id
unsigned track_id
Definition: isom.h:109
mov_read_hdlr
static int mov_read_hdlr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:798
mov_parse_stsd_data
static int mov_parse_stsd_data(MOVContext *c, AVIOContext *pb, AVStream *st, MOVStreamContext *sc, int64_t size)
Definition: mov.c:3126
AV_CH_SIDE_LEFT
#define AV_CH_SIDE_LEFT
Definition: channel_layout.h:184
ff_iamf_read_deinit
void ff_iamf_read_deinit(IAMFDemuxContext *c)
Definition: iamf_reader.c:371
AV_CODEC_ID_PRORES
@ AV_CODEC_ID_PRORES
Definition: codec_id.h:198
AV_RB16
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_WL16 uint64_t_TMPL AV_WB64 unsigned int_TMPL AV_WB32 unsigned int_TMPL AV_WB24 unsigned int_TMPL AV_RB16
Definition: bytestream.h:98
av_encryption_init_info_add_side_data
uint8_t * av_encryption_init_info_add_side_data(const AVEncryptionInitInfo *info, size_t *side_data_size)
Allocates and initializes side data that holds a copy of the given encryption init info.
Definition: encryption_info.c:292
av_fourcc2str
#define av_fourcc2str(fourcc)
Definition: avutil.h:323
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:550
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:9396
MOVContext::ignore_chapters
int ignore_chapters
Definition: isom.h:352
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:869
MP4TrackKindMapping
Definition: isom.h:492
ff_alloc_extradata
int ff_alloc_extradata(AVCodecParameters *par, int size)
Allocate extradata with additional AV_INPUT_BUFFER_PADDING_SIZE at end which is always set to 0.
Definition: utils.c:237
AVDOVIDecoderConfigurationRecord
Definition: dovi_meta.h:55
HEIFItem::nb_iref_list
int nb_iref_list
Definition: isom.h:301
AV_DISPOSITION_NON_DIEGETIC
#define AV_DISPOSITION_NON_DIEGETIC
The stream is intended to be mixed with a spatial audio track.
Definition: avformat.h:704
avio_feof
int avio_feof(AVIOContext *s)
Similar to feof() but also returns nonzero on read errors.
Definition: aviobuf.c:349
mc
#define mc
Definition: vf_colormatrix.c:100
MOVStreamContext::ffindex
int ffindex
AVStream index.
Definition: isom.h:184
HEIFItem::extent_offset
int64_t extent_offset
Definition: isom.h:305
mov_read_stsz
static int mov_read_stsz(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:3714