FFmpeg
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
mov.c
Go to the documentation of this file.
1 /*
2  * MOV demuxer
3  * Copyright (c) 2001 Fabrice Bellard
4  * Copyright (c) 2009 Baptiste Coudurier <baptiste dot coudurier at gmail dot com>
5  *
6  * first version by Francois Revol <revol@free.fr>
7  * seek function by Gael Chardon <gael.dev@4now.net>
8  *
9  * This file is part of FFmpeg.
10  *
11  * FFmpeg is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU Lesser General Public
13  * License as published by the Free Software Foundation; either
14  * version 2.1 of the License, or (at your option) any later version.
15  *
16  * FFmpeg is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19  * Lesser General Public License for more details.
20  *
21  * You should have received a copy of the GNU Lesser General Public
22  * License along with FFmpeg; if not, write to the Free Software
23  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
24  */
25 
26 #include "config_components.h"
27 
28 #include <inttypes.h>
29 #include <limits.h>
30 #include <stdint.h>
31 
32 #include "libavutil/attributes.h"
33 #include "libavutil/bprint.h"
35 #include "libavutil/internal.h"
36 #include "libavutil/intreadwrite.h"
37 #include "libavutil/intfloat.h"
38 #include "libavutil/mathematics.h"
39 #include "libavutil/avassert.h"
40 #include "libavutil/avstring.h"
41 #include "libavutil/dict.h"
42 #include "libavutil/display.h"
43 #include "libavutil/mem.h"
44 #include "libavutil/opt.h"
45 #include "libavutil/aes.h"
46 #include "libavutil/aes_ctr.h"
47 #include "libavutil/pixdesc.h"
48 #include "libavutil/sha.h"
49 #include "libavutil/spherical.h"
50 #include "libavutil/stereo3d.h"
51 #include "libavutil/timecode.h"
52 #include "libavutil/uuid.h"
53 #include "libavcodec/ac3tab.h"
54 #include "libavcodec/flac.h"
55 #include "libavcodec/hevc/hevc.h"
57 #include "libavcodec/mlp_parse.h"
58 #include "avformat.h"
59 #include "internal.h"
60 #include "avio_internal.h"
61 #include "demux.h"
62 #include "dvdclut.h"
63 #include "iamf_parse.h"
64 #include "iamf_reader.h"
65 #include "dovi_isom.h"
66 #include "riff.h"
67 #include "isom.h"
68 #include "libavcodec/get_bits.h"
69 #include "id3v1.h"
70 #include "mov_chan.h"
71 #include "replaygain.h"
72 
73 #if CONFIG_ZLIB
74 #include <zlib.h>
75 #endif
76 
77 #include "qtpalette.h"
78 
79 /* those functions parse an atom */
80 /* links atom IDs to parse functions */
81 typedef struct MOVParseTableEntry {
82  uint32_t type;
83  int (*parse)(MOVContext *ctx, AVIOContext *pb, MOVAtom atom);
85 
86 static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom);
87 static int mov_read_mfra(MOVContext *c, AVIOContext *f);
89 
91  unsigned len, const char *key)
92 {
93  char buf[16];
94 
95  short current, total = 0;
96  avio_rb16(pb); // unknown
97  current = avio_rb16(pb);
98  if (len >= 6)
99  total = avio_rb16(pb);
100  if (!total)
101  snprintf(buf, sizeof(buf), "%d", current);
102  else
103  snprintf(buf, sizeof(buf), "%d/%d", current, total);
104  c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
105  av_dict_set(&c->fc->metadata, key, buf, 0);
106 
107  return 0;
108 }
109 
111  unsigned len, const char *key)
112 {
113  /* bypass padding bytes */
114  avio_r8(pb);
115  avio_r8(pb);
116  avio_r8(pb);
117 
118  c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
119  av_dict_set_int(&c->fc->metadata, key, avio_r8(pb), 0);
120 
121  return 0;
122 }
123 
125  unsigned len, const char *key)
126 {
127  c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
128  av_dict_set_int(&c->fc->metadata, key, avio_r8(pb), 0);
129 
130  return 0;
131 }
132 
134  unsigned len, const char *key)
135 {
136  short genre;
137 
138  avio_r8(pb); // unknown
139 
140  genre = avio_r8(pb);
141  if (genre < 1 || genre > ID3v1_GENRE_MAX)
142  return 0;
143  c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
144  av_dict_set(&c->fc->metadata, key, ff_id3v1_genre_str[genre-1], 0);
145 
146  return 0;
147 }
148 
149 static const uint32_t mac_to_unicode[128] = {
150  0x00C4,0x00C5,0x00C7,0x00C9,0x00D1,0x00D6,0x00DC,0x00E1,
151  0x00E0,0x00E2,0x00E4,0x00E3,0x00E5,0x00E7,0x00E9,0x00E8,
152  0x00EA,0x00EB,0x00ED,0x00EC,0x00EE,0x00EF,0x00F1,0x00F3,
153  0x00F2,0x00F4,0x00F6,0x00F5,0x00FA,0x00F9,0x00FB,0x00FC,
154  0x2020,0x00B0,0x00A2,0x00A3,0x00A7,0x2022,0x00B6,0x00DF,
155  0x00AE,0x00A9,0x2122,0x00B4,0x00A8,0x2260,0x00C6,0x00D8,
156  0x221E,0x00B1,0x2264,0x2265,0x00A5,0x00B5,0x2202,0x2211,
157  0x220F,0x03C0,0x222B,0x00AA,0x00BA,0x03A9,0x00E6,0x00F8,
158  0x00BF,0x00A1,0x00AC,0x221A,0x0192,0x2248,0x2206,0x00AB,
159  0x00BB,0x2026,0x00A0,0x00C0,0x00C3,0x00D5,0x0152,0x0153,
160  0x2013,0x2014,0x201C,0x201D,0x2018,0x2019,0x00F7,0x25CA,
161  0x00FF,0x0178,0x2044,0x20AC,0x2039,0x203A,0xFB01,0xFB02,
162  0x2021,0x00B7,0x201A,0x201E,0x2030,0x00C2,0x00CA,0x00C1,
163  0x00CB,0x00C8,0x00CD,0x00CE,0x00CF,0x00CC,0x00D3,0x00D4,
164  0xF8FF,0x00D2,0x00DA,0x00DB,0x00D9,0x0131,0x02C6,0x02DC,
165  0x00AF,0x02D8,0x02D9,0x02DA,0x00B8,0x02DD,0x02DB,0x02C7,
166 };
167 
169  char *dst, int dstlen)
170 {
171  char *p = dst;
172  char *end = dst+dstlen-1;
173  int i;
174 
175  for (i = 0; i < len; i++) {
176  uint8_t t, c = avio_r8(pb);
177 
178  if (p >= end)
179  continue;
180 
181  if (c < 0x80)
182  *p++ = c;
183  else if (p < end)
184  PUT_UTF8(mac_to_unicode[c-0x80], t, if (p < end) *p++ = t;);
185  }
186  *p = 0;
187  return p - dst;
188 }
189 
190 /**
191  * Get the current item in the parsing process.
192  */
194 {
195  HEIFItem *item = NULL;
196 
197  for (int i = 0; i < c->nb_heif_item; i++) {
198  if (!c->heif_item[i] || c->heif_item[i]->item_id != c->cur_item_id)
199  continue;
200 
201  item = c->heif_item[i];
202  break;
203  }
204 
205  return item;
206 }
207 
208 /**
209  * Get the current stream in the parsing process. This can either be the
210  * latest stream added to the context, or the stream referenced by an item.
211  */
213 {
214  AVStream *st = NULL;
215  HEIFItem *item;
216 
217  if (c->fc->nb_streams < 1)
218  return NULL;
219 
220  if (c->cur_item_id == -1)
221  return c->fc->streams[c->fc->nb_streams-1];
222 
223  item = heif_cur_item(c);
224  if (item)
225  st = item->st;
226 
227  return st;
228 }
229 
230 static int mov_read_covr(MOVContext *c, AVIOContext *pb, int type, int len)
231 {
232  AVStream *st;
233  MOVStreamContext *sc;
234  enum AVCodecID id;
235  int ret;
236 
237  switch (type) {
238  case 0xd: id = AV_CODEC_ID_MJPEG; break;
239  case 0xe: id = AV_CODEC_ID_PNG; break;
240  case 0x1b: id = AV_CODEC_ID_BMP; break;
241  default:
242  av_log(c->fc, AV_LOG_WARNING, "Unknown cover type: 0x%x.\n", type);
243  avio_skip(pb, len);
244  return 0;
245  }
246 
247  sc = av_mallocz(sizeof(*sc));
248  if (!sc)
249  return AVERROR(ENOMEM);
250  ret = ff_add_attached_pic(c->fc, NULL, pb, NULL, len);
251  if (ret < 0) {
252  av_free(sc);
253  return ret;
254  }
255  st = c->fc->streams[c->fc->nb_streams - 1];
256  st->priv_data = sc;
257  sc->id = st->id;
258  sc->refcount = 1;
259 
260  if (st->attached_pic.size >= 8 && id != AV_CODEC_ID_BMP) {
261  if (AV_RB64(st->attached_pic.data) == 0x89504e470d0a1a0a) {
262  id = AV_CODEC_ID_PNG;
263  } else {
264  id = AV_CODEC_ID_MJPEG;
265  }
266  }
267  st->codecpar->codec_id = id;
268 
269  return 0;
270 }
271 
272 // 3GPP TS 26.244
273 static int mov_metadata_loci(MOVContext *c, AVIOContext *pb, unsigned len)
274 {
275  char language[4] = { 0 };
276  char buf[200], place[100];
277  uint16_t langcode = 0;
278  double longitude, latitude, altitude;
279  const char *key = "location";
280 
281  if (len < 4 + 2 + 1 + 1 + 4 + 4 + 4) {
282  av_log(c->fc, AV_LOG_ERROR, "loci too short\n");
283  return AVERROR_INVALIDDATA;
284  }
285 
286  avio_skip(pb, 4); // version+flags
287  langcode = avio_rb16(pb);
288  ff_mov_lang_to_iso639(langcode, language);
289  len -= 6;
290 
291  len -= avio_get_str(pb, len, place, sizeof(place));
292  if (len < 1) {
293  av_log(c->fc, AV_LOG_ERROR, "place name too long\n");
294  return AVERROR_INVALIDDATA;
295  }
296  avio_skip(pb, 1); // role
297  len -= 1;
298 
299  if (len < 12) {
300  av_log(c->fc, AV_LOG_ERROR,
301  "loci too short (%u bytes left, need at least %d)\n", len, 12);
302  return AVERROR_INVALIDDATA;
303  }
304  longitude = ((int32_t) avio_rb32(pb)) / (float) (1 << 16);
305  latitude = ((int32_t) avio_rb32(pb)) / (float) (1 << 16);
306  altitude = ((int32_t) avio_rb32(pb)) / (float) (1 << 16);
307 
308  // Try to output in the same format as the ?xyz field
309  snprintf(buf, sizeof(buf), "%+08.4f%+09.4f", latitude, longitude);
310  if (altitude)
311  av_strlcatf(buf, sizeof(buf), "%+f", altitude);
312  av_strlcatf(buf, sizeof(buf), "/%s", place);
313 
314  if (*language && strcmp(language, "und")) {
315  char key2[16];
316  snprintf(key2, sizeof(key2), "%s-%s", key, language);
317  av_dict_set(&c->fc->metadata, key2, buf, 0);
318  }
319  c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
320  return av_dict_set(&c->fc->metadata, key, buf, 0);
321 }
322 
323 static int mov_metadata_hmmt(MOVContext *c, AVIOContext *pb, unsigned len)
324 {
325  int i, n_hmmt;
326 
327  if (len < 2)
328  return 0;
329  if (c->ignore_chapters)
330  return 0;
331 
332  n_hmmt = avio_rb32(pb);
333  if (n_hmmt > len / 4)
334  return AVERROR_INVALIDDATA;
335  for (i = 0; i < n_hmmt && !pb->eof_reached; i++) {
336  int moment_time = avio_rb32(pb);
337  avpriv_new_chapter(c->fc, i, av_make_q(1, 1000), moment_time, AV_NOPTS_VALUE, NULL);
338  }
339  if (avio_feof(pb))
340  return AVERROR_INVALIDDATA;
341  return 0;
342 }
343 
345 {
346  char tmp_key[AV_FOURCC_MAX_STRING_SIZE] = {0};
347  char key2[32], language[4] = {0};
348  char *str = NULL;
349  const char *key = NULL;
350  uint16_t langcode = 0;
351  uint32_t data_type = 0, str_size_alloc;
352  uint64_t str_size;
353  int (*parse)(MOVContext*, AVIOContext*, unsigned, const char*) = NULL;
354  int raw = 0;
355  int num = 0;
357 
358  if (c->trak_index >= 0 && c->trak_index < c->fc->nb_streams)
359  metadata = &c->fc->streams[c->trak_index]->metadata;
360  else
361  metadata = &c->fc->metadata;
362 
363  switch (atom.type) {
364  case MKTAG( '@','P','R','M'): key = "premiere_version"; raw = 1; break;
365  case MKTAG( '@','P','R','Q'): key = "quicktime_version"; raw = 1; break;
366  case MKTAG( 'X','M','P','_'):
367  if (c->export_xmp) { key = "xmp"; raw = 1; } break;
368  case MKTAG( 'a','A','R','T'): key = "album_artist"; break;
369  case MKTAG( 'a','k','I','D'): key = "account_type";
371  case MKTAG( 'a','p','I','D'): key = "account_id"; break;
372  case MKTAG( 'c','a','t','g'): key = "category"; break;
373  case MKTAG( 'c','p','i','l'): key = "compilation";
375  case MKTAG( 'c','p','r','t'): key = "copyright"; break;
376  case MKTAG( 'd','e','s','c'): key = "description"; break;
377  case MKTAG( 'd','i','s','k'): key = "disc";
379  case MKTAG( 'e','g','i','d'): key = "episode_uid";
381  case MKTAG( 'F','I','R','M'): key = "firmware"; raw = 1; break;
382  case MKTAG( 'g','n','r','e'): key = "genre";
383  parse = mov_metadata_gnre; break;
384  case MKTAG( 'h','d','v','d'): key = "hd_video";
386  case MKTAG( 'H','M','M','T'):
387  return mov_metadata_hmmt(c, pb, atom.size);
388  case MKTAG( 'k','e','y','w'): key = "keywords"; break;
389  case MKTAG( 'l','d','e','s'): key = "synopsis"; break;
390  case MKTAG( 'l','o','c','i'):
391  return mov_metadata_loci(c, pb, atom.size);
392  case MKTAG( 'm','a','n','u'): key = "make"; break;
393  case MKTAG( 'm','o','d','l'): key = "model"; break;
394  case MKTAG( 'p','c','s','t'): key = "podcast";
396  case MKTAG( 'p','g','a','p'): key = "gapless_playback";
398  case MKTAG( 'p','u','r','d'): key = "purchase_date"; break;
399  case MKTAG( 'r','t','n','g'): key = "rating";
401  case MKTAG( 's','o','a','a'): key = "sort_album_artist"; break;
402  case MKTAG( 's','o','a','l'): key = "sort_album"; break;
403  case MKTAG( 's','o','a','r'): key = "sort_artist"; break;
404  case MKTAG( 's','o','c','o'): key = "sort_composer"; break;
405  case MKTAG( 's','o','n','m'): key = "sort_name"; break;
406  case MKTAG( 's','o','s','n'): key = "sort_show"; break;
407  case MKTAG( 's','t','i','k'): key = "media_type";
409  case MKTAG( 't','r','k','n'): key = "track";
411  case MKTAG( 't','v','e','n'): key = "episode_id"; break;
412  case MKTAG( 't','v','e','s'): key = "episode_sort";
414  case MKTAG( 't','v','n','n'): key = "network"; break;
415  case MKTAG( 't','v','s','h'): key = "show"; break;
416  case MKTAG( 't','v','s','n'): key = "season_number";
418  case MKTAG(0xa9,'A','R','T'): key = "artist"; break;
419  case MKTAG(0xa9,'P','R','D'): key = "producer"; break;
420  case MKTAG(0xa9,'a','l','b'): key = "album"; break;
421  case MKTAG(0xa9,'a','u','t'): key = "artist"; break;
422  case MKTAG(0xa9,'c','h','p'): key = "chapter"; break;
423  case MKTAG(0xa9,'c','m','t'): key = "comment"; break;
424  case MKTAG(0xa9,'c','o','m'): key = "composer"; break;
425  case MKTAG(0xa9,'c','p','y'): key = "copyright"; break;
426  case MKTAG(0xa9,'d','a','y'): key = "date"; break;
427  case MKTAG(0xa9,'d','i','r'): key = "director"; break;
428  case MKTAG(0xa9,'d','i','s'): key = "disclaimer"; break;
429  case MKTAG(0xa9,'e','d','1'): key = "edit_date"; break;
430  case MKTAG(0xa9,'e','n','c'): key = "encoder"; break;
431  case MKTAG(0xa9,'f','m','t'): key = "original_format"; break;
432  case MKTAG(0xa9,'g','e','n'): key = "genre"; break;
433  case MKTAG(0xa9,'g','r','p'): key = "grouping"; break;
434  case MKTAG(0xa9,'h','s','t'): key = "host_computer"; break;
435  case MKTAG(0xa9,'i','n','f'): key = "comment"; break;
436  case MKTAG(0xa9,'l','y','r'): key = "lyrics"; break;
437  case MKTAG(0xa9,'m','a','k'): key = "make"; break;
438  case MKTAG(0xa9,'m','o','d'): key = "model"; break;
439  case MKTAG(0xa9,'n','a','m'): key = "title"; break;
440  case MKTAG(0xa9,'o','p','e'): key = "original_artist"; break;
441  case MKTAG(0xa9,'p','r','d'): key = "producer"; break;
442  case MKTAG(0xa9,'p','r','f'): key = "performers"; break;
443  case MKTAG(0xa9,'r','e','q'): key = "playback_requirements"; break;
444  case MKTAG(0xa9,'s','r','c'): key = "original_source"; break;
445  case MKTAG(0xa9,'s','t','3'): key = "subtitle"; break;
446  case MKTAG(0xa9,'s','w','r'): key = "encoder"; break;
447  case MKTAG(0xa9,'t','o','o'): key = "encoder"; break;
448  case MKTAG(0xa9,'t','r','k'): key = "track"; break;
449  case MKTAG(0xa9,'u','r','l'): key = "URL"; break;
450  case MKTAG(0xa9,'w','r','n'): key = "warning"; break;
451  case MKTAG(0xa9,'w','r','t'): key = "composer"; break;
452  case MKTAG(0xa9,'x','y','z'): key = "location"; break;
453  }
454 retry:
455  if (c->itunes_metadata && atom.size > 8) {
456  int data_size = avio_rb32(pb);
457  int tag = avio_rl32(pb);
458  if (tag == MKTAG('d','a','t','a') && data_size <= atom.size && data_size >= 16) {
459  data_type = avio_rb32(pb); // type
460  avio_rb32(pb); // unknown
461  str_size = data_size - 16;
462  atom.size -= 16;
463 
464  if (!key && c->found_hdlr_mdta && c->meta_keys) {
465  uint32_t index = av_bswap32(atom.type); // BE number has been read as LE
466  if (index < c->meta_keys_count && index > 0) {
467  key = c->meta_keys[index];
468  } else if (atom.type != MKTAG('c', 'o', 'v', 'r')) {
469  av_log(c->fc, AV_LOG_WARNING,
470  "The index of 'data' is out of range: %"PRId32" < 1 or >= %d.\n",
471  index, c->meta_keys_count);
472  }
473  }
474  if (atom.type == MKTAG('c', 'o', 'v', 'r') ||
475  (key && !strcmp(key, "com.apple.quicktime.artwork"))) {
476  int ret = mov_read_covr(c, pb, data_type, str_size);
477  if (ret < 0) {
478  av_log(c->fc, AV_LOG_ERROR, "Error parsing cover art.\n");
479  return ret;
480  }
481  atom.size -= str_size;
482  if (atom.size > 8)
483  goto retry;
484  return ret;
485  }
486  } else return 0;
487  } else if (atom.size > 4 && (key || c->export_all) && !c->itunes_metadata && !raw) {
488  str_size = avio_rb16(pb); // string length
489  if (str_size > atom.size) {
490  raw = 1;
491  avio_seek(pb, -2, SEEK_CUR);
492  av_log(c->fc, AV_LOG_WARNING, "UDTA parsing failed retrying raw\n");
493  goto retry;
494  }
495  langcode = avio_rb16(pb);
496  ff_mov_lang_to_iso639(langcode, language);
497  atom.size -= 4;
498  } else
499  str_size = atom.size;
500 
501  if (c->export_all && !key) {
502  key = av_fourcc_make_string(tmp_key, atom.type);
503  }
504 
505  if (!key)
506  return 0;
507  if (atom.size < 0 || str_size >= INT_MAX/2)
508  return AVERROR_INVALIDDATA;
509 
510  // Allocates enough space if data_type is a int32 or float32 number, otherwise
511  // worst-case requirement for output string in case of utf8 coded input
512  num = (data_type >= 21 && data_type <= 23);
513  str_size_alloc = (num ? 512 : (raw ? str_size : str_size * 2)) + 1;
514  str = av_mallocz(str_size_alloc);
515  if (!str)
516  return AVERROR(ENOMEM);
517 
518  if (parse)
519  parse(c, pb, str_size, key);
520  else {
521  if (!raw && (data_type == 3 || (data_type == 0 && (langcode < 0x400 || langcode == 0x7fff)))) { // MAC Encoded
522  mov_read_mac_string(c, pb, str_size, str, str_size_alloc);
523  } else if (data_type == 21) { // BE signed integer, variable size
524  int val = 0;
525  if (str_size == 1)
526  val = (int8_t)avio_r8(pb);
527  else if (str_size == 2)
528  val = (int16_t)avio_rb16(pb);
529  else if (str_size == 3)
530  val = ((int32_t)(avio_rb24(pb)<<8))>>8;
531  else if (str_size == 4)
532  val = (int32_t)avio_rb32(pb);
533  if (snprintf(str, str_size_alloc, "%d", val) >= str_size_alloc) {
534  av_log(c->fc, AV_LOG_ERROR,
535  "Failed to store the number (%d) in string.\n", val);
536  av_free(str);
537  return AVERROR_INVALIDDATA;
538  }
539  } else if (data_type == 22) { // BE unsigned integer, variable size
540  unsigned int val = 0;
541  if (str_size == 1)
542  val = avio_r8(pb);
543  else if (str_size == 2)
544  val = avio_rb16(pb);
545  else if (str_size == 3)
546  val = avio_rb24(pb);
547  else if (str_size == 4)
548  val = avio_rb32(pb);
549  if (snprintf(str, str_size_alloc, "%u", val) >= str_size_alloc) {
550  av_log(c->fc, AV_LOG_ERROR,
551  "Failed to store the number (%u) in string.\n", val);
552  av_free(str);
553  return AVERROR_INVALIDDATA;
554  }
555  } else if (data_type == 23 && str_size >= 4) { // BE float32
556  float val = av_int2float(avio_rb32(pb));
557  if (snprintf(str, str_size_alloc, "%f", val) >= str_size_alloc) {
558  av_log(c->fc, AV_LOG_ERROR,
559  "Failed to store the float32 number (%f) in string.\n", val);
560  av_free(str);
561  return AVERROR_INVALIDDATA;
562  }
563  } else if (data_type > 1 && data_type != 4) {
564  // data_type can be 0 if not set at all above. data_type 1 means
565  // UTF8 and 4 means "UTF8 sort". For any other type (UTF16 or e.g.
566  // a picture), don't return it blindly in a string that is supposed
567  // to be UTF8 text.
568  av_log(c->fc, AV_LOG_WARNING, "Skipping unhandled metadata %s of type %d\n", key, data_type);
569  av_free(str);
570  return 0;
571  } else {
572  int ret = ffio_read_size(pb, str, str_size);
573  if (ret < 0) {
574  av_free(str);
575  return ret;
576  }
577  str[str_size] = 0;
578  }
579  c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
580  av_dict_set(metadata, key, str, 0);
581  if (*language && strcmp(language, "und")) {
582  snprintf(key2, sizeof(key2), "%s-%s", key, language);
583  av_dict_set(metadata, key2, str, 0);
584  }
585  if (!strcmp(key, "encoder")) {
586  int major, minor, micro;
587  if (sscanf(str, "HandBrake %d.%d.%d", &major, &minor, &micro) == 3) {
588  c->handbrake_version = 1000000*major + 1000*minor + micro;
589  }
590  }
591  }
592 
593  av_freep(&str);
594  return 0;
595 }
596 
598 {
599  int64_t start;
600  int i, nb_chapters, str_len, version;
601  char str[256+1];
602  int ret;
603 
604  if (c->ignore_chapters)
605  return 0;
606 
607  if ((atom.size -= 5) < 0)
608  return 0;
609 
610  version = avio_r8(pb);
611  avio_rb24(pb);
612  if (version)
613  avio_rb32(pb); // ???
614  nb_chapters = avio_r8(pb);
615 
616  for (i = 0; i < nb_chapters; i++) {
617  if (atom.size < 9)
618  return 0;
619 
620  start = avio_rb64(pb);
621  str_len = avio_r8(pb);
622 
623  if ((atom.size -= 9+str_len) < 0)
624  return 0;
625 
626  ret = ffio_read_size(pb, str, str_len);
627  if (ret < 0)
628  return ret;
629  str[str_len] = 0;
630  avpriv_new_chapter(c->fc, i, (AVRational){1,10000000}, start, AV_NOPTS_VALUE, str);
631  }
632  return 0;
633 }
634 
635 #define MIN_DATA_ENTRY_BOX_SIZE 12
637 {
638  AVStream *st;
639  MOVStreamContext *sc;
640  int entries, i, j;
641 
642  if (c->fc->nb_streams < 1)
643  return 0;
644  st = c->fc->streams[c->fc->nb_streams-1];
645  sc = st->priv_data;
646 
647  avio_rb32(pb); // version + flags
648  entries = avio_rb32(pb);
649  if (!entries ||
650  entries > (atom.size - 1) / MIN_DATA_ENTRY_BOX_SIZE + 1 ||
651  entries >= UINT_MAX / sizeof(*sc->drefs))
652  return AVERROR_INVALIDDATA;
653 
654  for (i = 0; i < sc->drefs_count; i++) {
655  MOVDref *dref = &sc->drefs[i];
656  av_freep(&dref->path);
657  av_freep(&dref->dir);
658  }
659  av_free(sc->drefs);
660  sc->drefs_count = 0;
661  sc->drefs = av_mallocz(entries * sizeof(*sc->drefs));
662  if (!sc->drefs)
663  return AVERROR(ENOMEM);
664  sc->drefs_count = entries;
665 
666  for (i = 0; i < entries; i++) {
667  MOVDref *dref = &sc->drefs[i];
668  uint32_t size = avio_rb32(pb);
669  int64_t next = avio_tell(pb);
670 
671  if (size < 12 || next < 0 || next > INT64_MAX - size)
672  return AVERROR_INVALIDDATA;
673 
674  next += size - 4;
675 
676  dref->type = avio_rl32(pb);
677  avio_rb32(pb); // version + flags
678 
679  if (dref->type == MKTAG('a','l','i','s') && size > 150) {
680  /* macintosh alias record */
681  uint16_t volume_len, len;
682  int16_t type;
683  int ret;
684 
685  avio_skip(pb, 10);
686 
687  volume_len = avio_r8(pb);
688  volume_len = FFMIN(volume_len, 27);
689  ret = ffio_read_size(pb, dref->volume, 27);
690  if (ret < 0)
691  return ret;
692  dref->volume[volume_len] = 0;
693  av_log(c->fc, AV_LOG_DEBUG, "volume %s, len %d\n", dref->volume, volume_len);
694 
695  avio_skip(pb, 12);
696 
697  len = avio_r8(pb);
698  len = FFMIN(len, 63);
699  ret = ffio_read_size(pb, dref->filename, 63);
700  if (ret < 0)
701  return ret;
702  dref->filename[len] = 0;
703  av_log(c->fc, AV_LOG_DEBUG, "filename %s, len %d\n", dref->filename, len);
704 
705  avio_skip(pb, 16);
706 
707  /* read next level up_from_alias/down_to_target */
708  dref->nlvl_from = avio_rb16(pb);
709  dref->nlvl_to = avio_rb16(pb);
710  av_log(c->fc, AV_LOG_DEBUG, "nlvl from %d, nlvl to %d\n",
711  dref->nlvl_from, dref->nlvl_to);
712 
713  avio_skip(pb, 16);
714 
715  for (type = 0; type != -1 && avio_tell(pb) < next; ) {
716  if (avio_feof(pb))
717  return AVERROR_EOF;
718  type = avio_rb16(pb);
719  len = avio_rb16(pb);
720  av_log(c->fc, AV_LOG_DEBUG, "type %d, len %d\n", type, len);
721  if (len&1)
722  len += 1;
723  if (type == 2) { // absolute path
724  av_free(dref->path);
725  dref->path = av_mallocz(len+1);
726  if (!dref->path)
727  return AVERROR(ENOMEM);
728 
729  ret = ffio_read_size(pb, dref->path, len);
730  if (ret < 0) {
731  av_freep(&dref->path);
732  return ret;
733  }
734  if (len > volume_len && !strncmp(dref->path, dref->volume, volume_len)) {
735  len -= volume_len;
736  memmove(dref->path, dref->path+volume_len, len);
737  dref->path[len] = 0;
738  }
739  // trim string of any ending zeros
740  for (j = len - 1; j >= 0; j--) {
741  if (dref->path[j] == 0)
742  len--;
743  else
744  break;
745  }
746  for (j = 0; j < len; j++)
747  if (dref->path[j] == ':' || dref->path[j] == 0)
748  dref->path[j] = '/';
749  av_log(c->fc, AV_LOG_DEBUG, "path %s\n", dref->path);
750  } else if (type == 0) { // directory name
751  av_free(dref->dir);
752  dref->dir = av_malloc(len+1);
753  if (!dref->dir)
754  return AVERROR(ENOMEM);
755 
756  ret = ffio_read_size(pb, dref->dir, len);
757  if (ret < 0) {
758  av_freep(&dref->dir);
759  return ret;
760  }
761  dref->dir[len] = 0;
762  for (j = 0; j < len; j++)
763  if (dref->dir[j] == ':')
764  dref->dir[j] = '/';
765  av_log(c->fc, AV_LOG_DEBUG, "dir %s\n", dref->dir);
766  } else
767  avio_skip(pb, len);
768  }
769  } else {
770  av_log(c->fc, AV_LOG_DEBUG, "Unknown dref type 0x%08"PRIx32" size %"PRIu32"\n",
771  dref->type, size);
772  entries--;
773  i--;
774  }
775  avio_seek(pb, next, SEEK_SET);
776  }
777  return 0;
778 }
779 
781 {
782  AVStream *st;
783  uint32_t type;
784  uint32_t ctype;
785  int64_t title_size;
786  char *title_str;
787  int ret;
788 
789  avio_r8(pb); /* version */
790  avio_rb24(pb); /* flags */
791 
792  /* component type */
793  ctype = avio_rl32(pb);
794  type = avio_rl32(pb); /* component subtype */
795 
796  av_log(c->fc, AV_LOG_TRACE, "ctype=%s\n", av_fourcc2str(ctype));
797  av_log(c->fc, AV_LOG_TRACE, "stype=%s\n", av_fourcc2str(type));
798 
799  if (c->trak_index < 0) { // meta not inside a trak
800  if (type == MKTAG('m','d','t','a')) {
801  c->found_hdlr_mdta = 1;
802  }
803  return 0;
804  }
805 
806  st = c->fc->streams[c->fc->nb_streams-1];
807 
808  if (type == MKTAG('v','i','d','e'))
810  else if (type == MKTAG('s','o','u','n'))
812  else if (type == MKTAG('m','1','a',' '))
814  else if ((type == MKTAG('s','u','b','p')) || (type == MKTAG('c','l','c','p')))
816 
817  avio_rb32(pb); /* component manufacture */
818  avio_rb32(pb); /* component flags */
819  avio_rb32(pb); /* component flags mask */
820 
821  title_size = atom.size - 24;
822  if (title_size > 0) {
823  if (title_size > FFMIN(INT_MAX, SIZE_MAX-1))
824  return AVERROR_INVALIDDATA;
825  title_str = av_malloc(title_size + 1); /* Add null terminator */
826  if (!title_str)
827  return AVERROR(ENOMEM);
828 
829  ret = ffio_read_size(pb, title_str, title_size);
830  if (ret < 0) {
831  av_freep(&title_str);
832  return ret;
833  }
834  title_str[title_size] = 0;
835  if (title_str[0]) {
836  int off = (!c->isom && title_str[0] == title_size - 1);
837  // flag added so as to not set stream handler name if already set from mdia->hdlr
838  av_dict_set(&st->metadata, "handler_name", title_str + off, AV_DICT_DONT_OVERWRITE);
839  }
840  av_freep(&title_str);
841  }
842 
843  return 0;
844 }
845 
847 {
848  return ff_mov_read_esds(c->fc, pb);
849 }
850 
852 {
853  AVStream *st;
854  AVPacketSideData *sd;
855  enum AVAudioServiceType *ast;
856  int ac3info, acmod, lfeon, bsmod;
857  uint64_t mask;
858 
859  if (c->fc->nb_streams < 1)
860  return 0;
861  st = c->fc->streams[c->fc->nb_streams-1];
862 
866  sizeof(*ast), 0);
867  if (!sd)
868  return AVERROR(ENOMEM);
869 
870  ast = (enum AVAudioServiceType*)sd->data;
871  ac3info = avio_rb24(pb);
872  bsmod = (ac3info >> 14) & 0x7;
873  acmod = (ac3info >> 11) & 0x7;
874  lfeon = (ac3info >> 10) & 0x1;
875 
877  if (lfeon)
881 
882  *ast = bsmod;
883  if (st->codecpar->ch_layout.nb_channels > 1 && bsmod == 0x7)
885 
886  return 0;
887 }
888 
889 #if CONFIG_IAMFDEC
890 static int mov_read_iacb(MOVContext *c, AVIOContext *pb, MOVAtom atom)
891 {
892  AVStream *st;
893  MOVStreamContext *sc;
894  FFIOContext b;
895  AVIOContext *descriptor_pb;
897  IAMFContext *iamf;
899  unsigned descriptors_size;
900  int nb_frames, disposition;
901  int version, ret;
902 
903  if (atom.size < 5)
904  return AVERROR_INVALIDDATA;
905 
906  if (c->fc->nb_streams < 1)
907  return 0;
908 
909  version = avio_r8(pb);
910  if (version != 1) {
911  av_log(c->fc, AV_LOG_ERROR, "%s configurationVersion %d",
912  version < 1 ? "invalid" : "unsupported", version);
913  return AVERROR_INVALIDDATA;
914  }
915 
916  descriptors_size = ffio_read_leb(pb);
917  if (!descriptors_size || descriptors_size > INT_MAX)
918  return AVERROR_INVALIDDATA;
919 
920  st = c->fc->streams[c->fc->nb_streams - 1];
921  sc = st->priv_data;
922 
923  if (st->codecpar->extradata) {
924  av_log(c->fc, AV_LOG_WARNING, "ignoring iacb\n");
925  return 0;
926  }
927 
928  sc->iamf = av_mallocz(sizeof(*sc->iamf));
929  if (!sc->iamf)
930  return AVERROR(ENOMEM);
931  iamf = &sc->iamf->iamf;
932 
933  st->codecpar->extradata = av_malloc(descriptors_size);
934  if (!st->codecpar->extradata)
935  return AVERROR(ENOMEM);
936  st->codecpar->extradata_size = descriptors_size;
937 
938  ret = avio_read(pb, st->codecpar->extradata, descriptors_size);
939  if (ret != descriptors_size)
940  return ret < 0 ? ret : AVERROR_INVALIDDATA;
941 
942  ffio_init_read_context(&b, st->codecpar->extradata, descriptors_size);
943  descriptor_pb = &b.pub;
944 
945  ret = ff_iamfdec_read_descriptors(iamf, descriptor_pb, descriptors_size, c->fc);
946  if (ret < 0)
947  return ret;
948 
949  metadata = st->metadata;
950  st->metadata = NULL;
951  start_time = st->start_time;
952  nb_frames = st->nb_frames;
953  duration = st->duration;
954  disposition = st->disposition;
955 
956  for (int i = 0; i < iamf->nb_audio_elements; i++) {
957  IAMFAudioElement *audio_element = iamf->audio_elements[i];
958  const AVIAMFAudioElement *element;
959  AVStreamGroup *stg =
961 
962  if (!stg) {
963  ret = AVERROR(ENOMEM);
964  goto fail;
965  }
966 
968  stg->id = audio_element->audio_element_id;
969  /* Transfer ownership */
970  element = stg->params.iamf_audio_element = audio_element->element;
971  audio_element->element = NULL;
972 
973  for (int j = 0; j < audio_element->nb_substreams; j++) {
974  IAMFSubStream *substream = &audio_element->substreams[j];
975  AVStream *stream;
976 
977  if (!i && !j) {
978  if (audio_element->layers[0].substream_count != 1)
979  disposition &= ~AV_DISPOSITION_DEFAULT;
980  stream = st;
981  } else
982  stream = avformat_new_stream(c->fc, NULL);
983  if (!stream) {
984  ret = AVERROR(ENOMEM);
985  goto fail;
986  }
987 
988  stream->start_time = start_time;
989  stream->nb_frames = nb_frames;
990  stream->duration = duration;
991  stream->disposition = disposition;
992  if (stream != st) {
993  stream->priv_data = sc;
994  sc->refcount++;
995  }
996 
999  if (i || j) {
1001  if (audio_element->layers[0].substream_count == 1)
1002  stream->disposition &= ~AV_DISPOSITION_DEFAULT;
1003  }
1004 
1005  ret = avcodec_parameters_copy(stream->codecpar, substream->codecpar);
1006  if (ret < 0)
1007  goto fail;
1008 
1009  stream->id = substream->audio_substream_id;
1010 
1011  avpriv_set_pts_info(st, 64, 1, sc->time_scale);
1012 
1013  ret = avformat_stream_group_add_stream(stg, stream);
1014  if (ret < 0)
1015  goto fail;
1016  }
1017 
1018  ret = av_dict_copy(&stg->metadata, metadata, 0);
1019  if (ret < 0)
1020  goto fail;
1021  }
1022 
1023  for (int i = 0; i < iamf->nb_mix_presentations; i++) {
1024  IAMFMixPresentation *mix_presentation = iamf->mix_presentations[i];
1025  const AVIAMFMixPresentation *mix = mix_presentation->cmix;
1026  AVStreamGroup *stg =
1028 
1029  if (!stg) {
1030  ret = AVERROR(ENOMEM);
1031  goto fail;
1032  }
1033 
1035  stg->id = mix_presentation->mix_presentation_id;
1036  /* Transfer ownership */
1037  stg->params.iamf_mix_presentation = mix_presentation->mix;
1038  mix_presentation->mix = NULL;
1039 
1040  for (int j = 0; j < mix->nb_submixes; j++) {
1041  const AVIAMFSubmix *submix = mix->submixes[j];
1042 
1043  for (int k = 0; k < submix->nb_elements; k++) {
1044  const AVIAMFSubmixElement *submix_element = submix->elements[k];
1045  const AVStreamGroup *audio_element = NULL;
1046 
1047  for (int l = 0; l < c->fc->nb_stream_groups; l++)
1048  if (c->fc->stream_groups[l]->type == AV_STREAM_GROUP_PARAMS_IAMF_AUDIO_ELEMENT &&
1049  c->fc->stream_groups[l]->id == submix_element->audio_element_id) {
1050  audio_element = c->fc->stream_groups[l];
1051  break;
1052  }
1053  av_assert0(audio_element);
1054 
1055  for (int l = 0; l < audio_element->nb_streams; l++) {
1056  ret = avformat_stream_group_add_stream(stg, audio_element->streams[l]);
1057  if (ret < 0 && ret != AVERROR(EEXIST))
1058  goto fail;
1059  }
1060  }
1061  }
1062 
1063  ret = av_dict_copy(&stg->metadata, metadata, 0);
1064  if (ret < 0)
1065  goto fail;
1066  }
1067 
1068  ret = 0;
1069 fail:
1071 
1072  return ret;
1073 }
1074 #endif
1075 
1077 {
1078  AVStream *st;
1079  AVPacketSideData *sd;
1080  enum AVAudioServiceType *ast;
1081  int eac3info, acmod, lfeon, bsmod;
1082  uint64_t mask;
1083 
1084  if (c->fc->nb_streams < 1)
1085  return 0;
1086  st = c->fc->streams[c->fc->nb_streams-1];
1087 
1091  sizeof(*ast), 0);
1092  if (!sd)
1093  return AVERROR(ENOMEM);
1094 
1095  ast = (enum AVAudioServiceType*)sd->data;
1096 
1097  /* No need to parse fields for additional independent substreams and its
1098  * associated dependent substreams since libavcodec's E-AC-3 decoder
1099  * does not support them yet. */
1100  avio_rb16(pb); /* data_rate and num_ind_sub */
1101  eac3info = avio_rb24(pb);
1102  bsmod = (eac3info >> 12) & 0x1f;
1103  acmod = (eac3info >> 9) & 0x7;
1104  lfeon = (eac3info >> 8) & 0x1;
1105 
1107  if (lfeon)
1111 
1112  *ast = bsmod;
1113  if (st->codecpar->ch_layout.nb_channels > 1 && bsmod == 0x7)
1115 
1116  return 0;
1117 }
1118 
1120 {
1121 #define DDTS_SIZE 20
1122  uint8_t buf[DDTS_SIZE + AV_INPUT_BUFFER_PADDING_SIZE];
1123  AVStream *st = NULL;
1124  uint32_t frame_duration_code = 0;
1125  uint32_t channel_layout_code = 0;
1126  GetBitContext gb;
1127  int ret;
1128 
1129  if ((ret = ffio_read_size(pb, buf, DDTS_SIZE)) < 0)
1130  return ret;
1131 
1132  init_get_bits(&gb, buf, 8 * DDTS_SIZE);
1133 
1134  if (c->fc->nb_streams < 1) {
1135  return 0;
1136  }
1137  st = c->fc->streams[c->fc->nb_streams-1];
1138 
1139  st->codecpar->sample_rate = get_bits_long(&gb, 32);
1140  if (st->codecpar->sample_rate <= 0) {
1141  av_log(c->fc, AV_LOG_ERROR, "Invalid sample rate %d\n", st->codecpar->sample_rate);
1142  return AVERROR_INVALIDDATA;
1143  }
1144  skip_bits_long(&gb, 32); /* max bitrate */
1145  st->codecpar->bit_rate = get_bits_long(&gb, 32);
1146  st->codecpar->bits_per_coded_sample = get_bits(&gb, 8);
1147  frame_duration_code = get_bits(&gb, 2);
1148  skip_bits(&gb, 30); /* various fields */
1149  channel_layout_code = get_bits(&gb, 16);
1150 
1151  st->codecpar->frame_size =
1152  (frame_duration_code == 0) ? 512 :
1153  (frame_duration_code == 1) ? 1024 :
1154  (frame_duration_code == 2) ? 2048 :
1155  (frame_duration_code == 3) ? 4096 : 0;
1156 
1157  if (channel_layout_code > 0xff) {
1158  av_log(c->fc, AV_LOG_WARNING, "Unsupported DTS audio channel layout\n");
1159  }
1162  ((channel_layout_code & 0x1) ? AV_CH_FRONT_CENTER : 0) |
1163  ((channel_layout_code & 0x2) ? AV_CH_FRONT_LEFT : 0) |
1164  ((channel_layout_code & 0x2) ? AV_CH_FRONT_RIGHT : 0) |
1165  ((channel_layout_code & 0x4) ? AV_CH_SIDE_LEFT : 0) |
1166  ((channel_layout_code & 0x4) ? AV_CH_SIDE_RIGHT : 0) |
1167  ((channel_layout_code & 0x8) ? AV_CH_LOW_FREQUENCY : 0));
1168 
1169  return 0;
1170 }
1171 
1173 {
1174  AVStream *st;
1175 
1176  if (c->fc->nb_streams < 1)
1177  return 0;
1178  st = c->fc->streams[c->fc->nb_streams-1];
1179 
1180  if (atom.size < 16)
1181  return 0;
1182 
1183  /* skip version and flags */
1184  avio_skip(pb, 4);
1185 
1186  ff_mov_read_chan(c->fc, pb, st, atom.size - 4);
1187 
1188  return 0;
1189 }
1190 
1192 {
1193  int64_t end = av_sat_add64(avio_tell(pb), atom.size);
1194  int version, flags;
1195  int ret;
1196  AVStream *st;
1197 
1198  if (c->fc->nb_streams < 1)
1199  return 0;
1200  st = c->fc->streams[c->fc->nb_streams-1];
1201 
1202  version = avio_r8(pb);
1203  flags = avio_rb24(pb);
1204  if (version != 0 || flags != 0) {
1205  av_log(c->fc, AV_LOG_ERROR,
1206  "Unsupported 'chnl' box with version %d, flags: %#x",
1207  version, flags);
1208  return AVERROR_INVALIDDATA;
1209  }
1210 
1211  ret = ff_mov_read_chnl(c->fc, pb, st);
1212  if (ret < 0)
1213  return ret;
1214 
1215  if (avio_tell(pb) != end) {
1216  av_log(c->fc, AV_LOG_WARNING, "skip %" PRId64 " bytes of unknown data inside chnl\n",
1217  end - avio_tell(pb));
1218  avio_seek(pb, end, SEEK_SET);
1219  }
1220  return ret;
1221 }
1222 
1224 {
1225  AVStream *st;
1226  int ret;
1227 
1228  if (c->fc->nb_streams < 1)
1229  return 0;
1230  st = c->fc->streams[c->fc->nb_streams-1];
1231 
1232  if ((ret = ff_get_wav_header(c->fc, pb, st->codecpar, atom.size, 0)) < 0)
1233  av_log(c->fc, AV_LOG_WARNING, "get_wav_header failed\n");
1234 
1235  return ret;
1236 }
1237 
1239 {
1240  AVStream *st;
1241  HEIFItem *item;
1242  AVPacketSideData *sd;
1243  int width, height, err = 0;
1244  AVRational aperture_width, aperture_height, horiz_off, vert_off;
1245  AVRational pc_x, pc_y;
1246  uint64_t top, bottom, left, right;
1247 
1248  item = heif_cur_item(c);
1249  st = get_curr_st(c);
1250  if (!st)
1251  return 0;
1252 
1253  width = st->codecpar->width;
1254  height = st->codecpar->height;
1255  if ((!width || !height) && item) {
1256  width = item->width;
1257  height = item->height;
1258  }
1259  if (!width || !height) {
1260  err = AVERROR_INVALIDDATA;
1261  goto fail;
1262  }
1263 
1264  aperture_width.num = avio_rb32(pb);
1265  aperture_width.den = avio_rb32(pb);
1266  aperture_height.num = avio_rb32(pb);
1267  aperture_height.den = avio_rb32(pb);
1268 
1269  horiz_off.num = avio_rb32(pb);
1270  horiz_off.den = avio_rb32(pb);
1271  vert_off.num = avio_rb32(pb);
1272  vert_off.den = avio_rb32(pb);
1273 
1274  if (aperture_width.num < 0 || aperture_width.den < 0 ||
1275  aperture_height.num < 0 || aperture_height.den < 0 ||
1276  horiz_off.den < 0 || vert_off.den < 0) {
1277  err = AVERROR_INVALIDDATA;
1278  goto fail;
1279  }
1280  if ((av_cmp_q((AVRational) { width, 1 }, aperture_width) < 0) ||
1281  (av_cmp_q((AVRational) { height, 1 }, aperture_height) < 0)) {
1282  err = AVERROR_INVALIDDATA;
1283  goto fail;
1284  }
1285  av_log(c->fc, AV_LOG_TRACE, "clap: apertureWidth %d/%d, apertureHeight %d/%d "
1286  "horizOff %d/%d vertOff %d/%d\n",
1287  aperture_width.num, aperture_width.den, aperture_height.num, aperture_height.den,
1288  horiz_off.num, horiz_off.den, vert_off.num, vert_off.den);
1289 
1290  pc_x = av_mul_q((AVRational) { width - 1, 1 }, (AVRational) { 1, 2 });
1291  pc_x = av_add_q(pc_x, horiz_off);
1292  pc_y = av_mul_q((AVRational) { height - 1, 1 }, (AVRational) { 1, 2 });
1293  pc_y = av_add_q(pc_y, vert_off);
1294 
1295  aperture_width = av_sub_q(aperture_width, (AVRational) { 1, 1 });
1296  aperture_width = av_mul_q(aperture_width, (AVRational) { 1, 2 });
1297  aperture_height = av_sub_q(aperture_height, (AVRational) { 1, 1 });
1298  aperture_height = av_mul_q(aperture_height, (AVRational) { 1, 2 });
1299 
1300  left = av_q2d(av_sub_q(pc_x, aperture_width));
1301  right = av_q2d(av_add_q(pc_x, aperture_width));
1302  top = av_q2d(av_sub_q(pc_y, aperture_height));
1303  bottom = av_q2d(av_add_q(pc_y, aperture_height));
1304 
1305  if (bottom > (height - 1) ||
1306  right > (width - 1)) {
1307  err = AVERROR_INVALIDDATA;
1308  goto fail;
1309  }
1310 
1311  bottom = height - 1 - bottom;
1312  right = width - 1 - right;
1313 
1314  if (!(left | right | top | bottom))
1315  return 0;
1316 
1317  if ((left + right) >= width ||
1318  (top + bottom) >= height) {
1319  err = AVERROR_INVALIDDATA;
1320  goto fail;
1321  }
1322 
1326  sizeof(uint32_t) * 4, 0);
1327  if (!sd)
1328  return AVERROR(ENOMEM);
1329 
1330  AV_WL32A(sd->data, top);
1331  AV_WL32A(sd->data + 4, bottom);
1332  AV_WL32A(sd->data + 8, left);
1333  AV_WL32A(sd->data + 12, right);
1334 
1335 fail:
1336  if (err < 0) {
1337  int explode = !!(c->fc->error_recognition & AV_EF_EXPLODE);
1338  av_log(c->fc, explode ? AV_LOG_ERROR : AV_LOG_WARNING, "Invalid clap box\n");
1339  if (!explode)
1340  err = 0;
1341  }
1342 
1343  return err;
1344 }
1345 
1346 /* This atom overrides any previously set aspect ratio */
1348 {
1349  const int num = avio_rb32(pb);
1350  const int den = avio_rb32(pb);
1351  AVStream *st;
1352  MOVStreamContext *sc;
1353 
1354  if (c->fc->nb_streams < 1)
1355  return 0;
1356  st = c->fc->streams[c->fc->nb_streams-1];
1357  sc = st->priv_data;
1358 
1359  av_log(c->fc, AV_LOG_TRACE, "pasp: hSpacing %d, vSpacing %d\n", num, den);
1360 
1361  if (den != 0) {
1362  sc->h_spacing = num;
1363  sc->v_spacing = den;
1364  }
1365  return 0;
1366 }
1367 
1368 /* this atom contains actual media data */
1370 {
1371  if (atom.size == 0) /* wrong one (MP4) */
1372  return 0;
1373  c->found_mdat=1;
1374  return 0; /* now go for moov */
1375 }
1376 
1377 #define DRM_BLOB_SIZE 56
1378 
1380 {
1381  uint8_t intermediate_key[20];
1382  uint8_t intermediate_iv[20];
1383  uint8_t input[64];
1384  uint8_t output[64];
1385  uint8_t file_checksum[20];
1386  uint8_t calculated_checksum[20];
1387  char checksum_string[2 * sizeof(file_checksum) + 1];
1388  struct AVSHA *sha;
1389  int i;
1390  int ret = 0;
1391  uint8_t *activation_bytes = c->activation_bytes;
1392  uint8_t *fixed_key = c->audible_fixed_key;
1393 
1394  c->aax_mode = 1;
1395 
1396  sha = av_sha_alloc();
1397  if (!sha)
1398  return AVERROR(ENOMEM);
1399  av_free(c->aes_decrypt);
1400  c->aes_decrypt = av_aes_alloc();
1401  if (!c->aes_decrypt) {
1402  ret = AVERROR(ENOMEM);
1403  goto fail;
1404  }
1405 
1406  /* drm blob processing */
1407  avio_read(pb, output, 8); // go to offset 8, absolute position 0x251
1409  avio_read(pb, output, 4); // go to offset 4, absolute position 0x28d
1410  avio_read(pb, file_checksum, 20);
1411 
1412  // required by external tools
1413  ff_data_to_hex(checksum_string, file_checksum, sizeof(file_checksum), 1);
1414  av_log(c->fc, AV_LOG_INFO, "[aax] file checksum == %s\n", checksum_string);
1415 
1416  /* verify activation data */
1417  if (!activation_bytes) {
1418  av_log(c->fc, AV_LOG_WARNING, "[aax] activation_bytes option is missing!\n");
1419  ret = 0; /* allow ffprobe to continue working on .aax files */
1420  goto fail;
1421  }
1422  if (c->activation_bytes_size != 4) {
1423  av_log(c->fc, AV_LOG_FATAL, "[aax] activation_bytes value needs to be 4 bytes!\n");
1424  ret = AVERROR(EINVAL);
1425  goto fail;
1426  }
1427 
1428  /* verify fixed key */
1429  if (c->audible_fixed_key_size != 16) {
1430  av_log(c->fc, AV_LOG_FATAL, "[aax] audible_fixed_key value needs to be 16 bytes!\n");
1431  ret = AVERROR(EINVAL);
1432  goto fail;
1433  }
1434 
1435  /* AAX (and AAX+) key derivation */
1436  av_sha_init(sha, 160);
1437  av_sha_update(sha, fixed_key, 16);
1438  av_sha_update(sha, activation_bytes, 4);
1439  av_sha_final(sha, intermediate_key);
1440  av_sha_init(sha, 160);
1441  av_sha_update(sha, fixed_key, 16);
1442  av_sha_update(sha, intermediate_key, 20);
1443  av_sha_update(sha, activation_bytes, 4);
1444  av_sha_final(sha, intermediate_iv);
1445  av_sha_init(sha, 160);
1446  av_sha_update(sha, intermediate_key, 16);
1447  av_sha_update(sha, intermediate_iv, 16);
1448  av_sha_final(sha, calculated_checksum);
1449  if (memcmp(calculated_checksum, file_checksum, 20)) { // critical error
1450  av_log(c->fc, AV_LOG_ERROR, "[aax] mismatch in checksums!\n");
1452  goto fail;
1453  }
1454  av_aes_init(c->aes_decrypt, intermediate_key, 128, 1);
1455  av_aes_crypt(c->aes_decrypt, output, input, DRM_BLOB_SIZE >> 4, intermediate_iv, 1);
1456  for (i = 0; i < 4; i++) {
1457  // file data (in output) is stored in big-endian mode
1458  if (activation_bytes[i] != output[3 - i]) { // critical error
1459  av_log(c->fc, AV_LOG_ERROR, "[aax] error in drm blob decryption!\n");
1461  goto fail;
1462  }
1463  }
1464  memcpy(c->file_key, output + 8, 16);
1465  memcpy(input, output + 26, 16);
1466  av_sha_init(sha, 160);
1467  av_sha_update(sha, input, 16);
1468  av_sha_update(sha, c->file_key, 16);
1469  av_sha_update(sha, fixed_key, 16);
1470  av_sha_final(sha, c->file_iv);
1471 
1472 fail:
1473  av_free(sha);
1474 
1475  return ret;
1476 }
1477 
1479 {
1480  if (c->audible_key_size != 16) {
1481  av_log(c->fc, AV_LOG_FATAL, "[aaxc] audible_key value needs to be 16 bytes!\n");
1482  return AVERROR(EINVAL);
1483  }
1484 
1485  if (c->audible_iv_size != 16) {
1486  av_log(c->fc, AV_LOG_FATAL, "[aaxc] audible_iv value needs to be 16 bytes!\n");
1487  return AVERROR(EINVAL);
1488  }
1489 
1490  c->aes_decrypt = av_aes_alloc();
1491  if (!c->aes_decrypt) {
1492  return AVERROR(ENOMEM);
1493  }
1494 
1495  memcpy(c->file_key, c->audible_key, 16);
1496  memcpy(c->file_iv, c->audible_iv, 16);
1497  c->aax_mode = 1;
1498 
1499  return 0;
1500 }
1501 
1502 // Audible AAX (and AAX+) bytestream decryption
1503 static int aax_filter(uint8_t *input, int size, MOVContext *c)
1504 {
1505  int blocks = 0;
1506  unsigned char iv[16];
1507 
1508  memcpy(iv, c->file_iv, 16); // iv is overwritten
1509  blocks = size >> 4; // trailing bytes are not encrypted!
1510  av_aes_init(c->aes_decrypt, c->file_key, 128, 1);
1511  av_aes_crypt(c->aes_decrypt, input, input, blocks, iv, 1);
1512 
1513  return 0;
1514 }
1515 
1516 /* read major brand, minor version and compatible brands and store them as metadata */
1518 {
1519  uint32_t minor_ver;
1520  int comp_brand_size;
1521  char* comp_brands_str;
1522  uint8_t type[5] = {0};
1523  int ret = ffio_read_size(pb, type, 4);
1524  if (ret < 0)
1525  return ret;
1526  if (c->fc->nb_streams) {
1527  if (c->fc->strict_std_compliance >= FF_COMPLIANCE_STRICT)
1528  return AVERROR_INVALIDDATA;
1529  av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate FTYP\n");
1530  return 0;
1531  }
1532 
1533  if (strcmp(type, "qt "))
1534  c->isom = 1;
1535  av_log(c->fc, AV_LOG_DEBUG, "ISO: File Type Major Brand: %.4s\n",(char *)&type);
1536  av_dict_set(&c->fc->metadata, "major_brand", type, 0);
1537  minor_ver = avio_rb32(pb); /* minor version */
1538  av_dict_set_int(&c->fc->metadata, "minor_version", minor_ver, 0);
1539 
1540  comp_brand_size = atom.size - 8;
1541  if (comp_brand_size < 0 || comp_brand_size == INT_MAX)
1542  return AVERROR_INVALIDDATA;
1543  comp_brands_str = av_malloc(comp_brand_size + 1); /* Add null terminator */
1544  if (!comp_brands_str)
1545  return AVERROR(ENOMEM);
1546 
1547  ret = ffio_read_size(pb, comp_brands_str, comp_brand_size);
1548  if (ret < 0) {
1549  av_freep(&comp_brands_str);
1550  return ret;
1551  }
1552  comp_brands_str[comp_brand_size] = 0;
1553  av_dict_set(&c->fc->metadata, "compatible_brands",
1554  comp_brands_str, AV_DICT_DONT_STRDUP_VAL);
1555 
1556  // Logic for handling Audible's .aaxc files
1557  if (!strcmp(type, "aaxc")) {
1558  mov_aaxc_crypto(c);
1559  }
1560 
1561  return 0;
1562 }
1563 
1564 /* this atom should contain all header atoms */
1566 {
1567  int ret;
1568 
1569  if (c->found_moov) {
1570  av_log(c->fc, AV_LOG_WARNING, "Found duplicated MOOV Atom. Skipped it\n");
1571  avio_skip(pb, atom.size);
1572  return 0;
1573  }
1574 
1575  if ((ret = mov_read_default(c, pb, atom)) < 0)
1576  return ret;
1577  /* we parsed the 'moov' atom, we can terminate the parsing as soon as we find the 'mdat' */
1578  /* so we don't parse the whole file if over a network */
1579  c->found_moov=1;
1580  return 0; /* now go for mdat */
1581 }
1582 
1584  MOVFragmentIndex *frag_index,
1585  int index,
1586  int id)
1587 {
1588  int i;
1589  MOVFragmentIndexItem * item;
1590 
1591  if (index < 0 || index >= frag_index->nb_items)
1592  return NULL;
1593  item = &frag_index->item[index];
1594  for (i = 0; i < item->nb_stream_info; i++)
1595  if (item->stream_info[i].id == id)
1596  return &item->stream_info[i];
1597 
1598  // This shouldn't happen
1599  return NULL;
1600 }
1601 
1602 static void set_frag_stream(MOVFragmentIndex *frag_index, int id)
1603 {
1604  int i;
1605  MOVFragmentIndexItem * item;
1606 
1607  if (frag_index->current < 0 ||
1608  frag_index->current >= frag_index->nb_items)
1609  return;
1610 
1611  item = &frag_index->item[frag_index->current];
1612  for (i = 0; i < item->nb_stream_info; i++)
1613  if (item->stream_info[i].id == id) {
1614  item->current = i;
1615  return;
1616  }
1617 
1618  // id not found. This shouldn't happen.
1619  item->current = -1;
1620 }
1621 
1623  MOVFragmentIndex *frag_index)
1624 {
1625  MOVFragmentIndexItem *item;
1626  if (frag_index->current < 0 ||
1627  frag_index->current >= frag_index->nb_items)
1628  return NULL;
1629 
1630  item = &frag_index->item[frag_index->current];
1631  if (item->current >= 0 && item->current < item->nb_stream_info)
1632  return &item->stream_info[item->current];
1633 
1634  // This shouldn't happen
1635  return NULL;
1636 }
1637 
1639 {
1640  int a, b, m;
1641  int64_t moof_offset;
1642 
1643  // Optimize for appending new entries
1644  if (!frag_index->nb_items ||
1645  frag_index->item[frag_index->nb_items - 1].moof_offset < offset)
1646  return frag_index->nb_items;
1647 
1648  a = -1;
1649  b = frag_index->nb_items;
1650 
1651  while (b - a > 1) {
1652  m = (a + b) >> 1;
1653  moof_offset = frag_index->item[m].moof_offset;
1654  if (moof_offset >= offset)
1655  b = m;
1656  if (moof_offset <= offset)
1657  a = m;
1658  }
1659  return b;
1660 }
1661 
1663 {
1664  av_assert0(frag_stream_info);
1665  if (frag_stream_info->sidx_pts != AV_NOPTS_VALUE)
1666  return frag_stream_info->sidx_pts;
1667  if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE)
1668  return frag_stream_info->first_tfra_pts;
1669  return frag_stream_info->tfdt_dts;
1670 }
1671 
1673  MOVFragmentIndex *frag_index, int index)
1674 {
1675  MOVFragmentStreamInfo * frag_stream_info;
1676  MOVStreamContext *sc = dst_st->priv_data;
1677  int64_t timestamp;
1678  int i, j;
1679 
1680  // If the stream is referenced by any sidx, limit the search
1681  // to fragments that referenced this stream in the sidx
1682  if (sc->has_sidx) {
1683  frag_stream_info = get_frag_stream_info(frag_index, index, sc->id);
1684  if (!frag_stream_info)
1685  return AV_NOPTS_VALUE;
1686  if (frag_stream_info->sidx_pts != AV_NOPTS_VALUE)
1687  return frag_stream_info->sidx_pts;
1688  if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE)
1689  return frag_stream_info->first_tfra_pts;
1690  return frag_stream_info->sidx_pts;
1691  }
1692 
1693  for (i = 0; i < frag_index->item[index].nb_stream_info; i++) {
1694  AVStream *frag_stream = NULL;
1695  frag_stream_info = &frag_index->item[index].stream_info[i];
1696  for (j = 0; j < s->nb_streams; j++) {
1697  MOVStreamContext *sc2 = s->streams[j]->priv_data;
1698  if (sc2->id == frag_stream_info->id)
1699  frag_stream = s->streams[j];
1700  }
1701  if (!frag_stream) {
1702  av_log(s, AV_LOG_WARNING, "No stream matching sidx ID found.\n");
1703  continue;
1704  }
1705  timestamp = get_stream_info_time(frag_stream_info);
1706  if (timestamp != AV_NOPTS_VALUE)
1707  return av_rescale_q(timestamp, frag_stream->time_base, dst_st->time_base);
1708  }
1709  return AV_NOPTS_VALUE;
1710 }
1711 
1713  AVStream *st, int64_t timestamp)
1714 {
1715  int a, b, m, m0;
1716  int64_t frag_time;
1717 
1718  a = -1;
1719  b = frag_index->nb_items;
1720 
1721  while (b - a > 1) {
1722  m0 = m = (a + b) >> 1;
1723 
1724  while (m < b &&
1725  (frag_time = get_frag_time(s, st, frag_index, m)) == AV_NOPTS_VALUE)
1726  m++;
1727 
1728  if (m < b && frag_time <= timestamp)
1729  a = m;
1730  else
1731  b = m0;
1732  }
1733 
1734  return a;
1735 }
1736 
1738 {
1739  int index, i;
1740  MOVFragmentIndexItem * item;
1741  MOVFragmentStreamInfo * frag_stream_info;
1742 
1743  // If moof_offset already exists in frag_index, return index to it
1744  index = search_frag_moof_offset(&c->frag_index, offset);
1745  if (index < c->frag_index.nb_items &&
1746  c->frag_index.item[index].moof_offset == offset)
1747  return index;
1748 
1749  // offset is not yet in frag index.
1750  // Insert new item at index (sorted by moof offset)
1751  item = av_fast_realloc(c->frag_index.item,
1752  &c->frag_index.allocated_size,
1753  (c->frag_index.nb_items + 1) *
1754  sizeof(*c->frag_index.item));
1755  if (!item)
1756  return -1;
1757  c->frag_index.item = item;
1758 
1759  frag_stream_info = av_realloc_array(NULL, c->fc->nb_streams,
1760  sizeof(*item->stream_info));
1761  if (!frag_stream_info)
1762  return -1;
1763 
1764  for (i = 0; i < c->fc->nb_streams; i++) {
1765  // Avoid building frag index if streams lack track id.
1766  MOVStreamContext *sc = c->fc->streams[i]->priv_data;
1767  if (sc->id < 0) {
1768  av_free(frag_stream_info);
1769  return AVERROR_INVALIDDATA;
1770  }
1771 
1772  frag_stream_info[i].id = sc->id;
1773  frag_stream_info[i].sidx_pts = AV_NOPTS_VALUE;
1774  frag_stream_info[i].tfdt_dts = AV_NOPTS_VALUE;
1775  frag_stream_info[i].next_trun_dts = AV_NOPTS_VALUE;
1776  frag_stream_info[i].first_tfra_pts = AV_NOPTS_VALUE;
1777  frag_stream_info[i].index_base = -1;
1778  frag_stream_info[i].index_entry = -1;
1779  frag_stream_info[i].encryption_index = NULL;
1780  frag_stream_info[i].stsd_id = -1;
1781  }
1782 
1783  if (index < c->frag_index.nb_items)
1784  memmove(c->frag_index.item + index + 1, c->frag_index.item + index,
1785  (c->frag_index.nb_items - index) * sizeof(*c->frag_index.item));
1786 
1787  item = &c->frag_index.item[index];
1788  item->headers_read = 0;
1789  item->current = 0;
1790  item->nb_stream_info = c->fc->nb_streams;
1791  item->moof_offset = offset;
1792  item->stream_info = frag_stream_info;
1793  c->frag_index.nb_items++;
1794 
1795  return index;
1796 }
1797 
1798 static void fix_frag_index_entries(MOVFragmentIndex *frag_index, int index,
1799  int id, int entries)
1800 {
1801  int i;
1802  MOVFragmentStreamInfo * frag_stream_info;
1803 
1804  if (index < 0)
1805  return;
1806  for (i = index; i < frag_index->nb_items; i++) {
1807  frag_stream_info = get_frag_stream_info(frag_index, i, id);
1808  if (frag_stream_info && frag_stream_info->index_entry >= 0)
1809  frag_stream_info->index_entry += entries;
1810  }
1811 }
1812 
1814 {
1815  // Set by mov_read_tfhd(). mov_read_trun() will reject files missing tfhd.
1816  c->fragment.found_tfhd = 0;
1817 
1818  if (!c->has_looked_for_mfra && c->use_mfra_for > 0) {
1819  c->has_looked_for_mfra = 1;
1820  if (pb->seekable & AVIO_SEEKABLE_NORMAL) {
1821  int ret;
1822  av_log(c->fc, AV_LOG_VERBOSE, "stream has moof boxes, will look "
1823  "for a mfra\n");
1824  if ((ret = mov_read_mfra(c, pb)) < 0) {
1825  av_log(c->fc, AV_LOG_VERBOSE, "found a moof box but failed to "
1826  "read the mfra (may be a live ismv)\n");
1827  }
1828  } else {
1829  av_log(c->fc, AV_LOG_VERBOSE, "found a moof box but stream is not "
1830  "seekable, can not look for mfra\n");
1831  }
1832  }
1833  c->fragment.moof_offset = c->fragment.implicit_offset = avio_tell(pb) - 8;
1834  av_log(c->fc, AV_LOG_TRACE, "moof offset %"PRIx64"\n", c->fragment.moof_offset);
1835  c->frag_index.current = update_frag_index(c, c->fragment.moof_offset);
1836  return mov_read_default(c, pb, atom);
1837 }
1838 
1840 {
1841  int64_t time;
1842  if (version == 1) {
1843  time = avio_rb64(pb);
1844  avio_rb64(pb);
1845  if (time < 0) {
1846  av_log(c->fc, AV_LOG_DEBUG, "creation_time is negative\n");
1847  return;
1848  }
1849  } else {
1850  time = avio_rb32(pb);
1851  avio_rb32(pb); /* modification time */
1852  if (time > 0 && time < 2082844800) {
1853  av_log(c->fc, AV_LOG_WARNING, "Detected creation time before 1970, parsing as unix timestamp.\n");
1854  time += 2082844800;
1855  }
1856  }
1857  if (time) {
1858  time -= 2082844800; /* seconds between 1904-01-01 and Epoch */
1859 
1860  if ((int64_t)(time * 1000000ULL) / 1000000 != time) {
1861  av_log(c->fc, AV_LOG_DEBUG, "creation_time is not representable\n");
1862  return;
1863  }
1864 
1865  ff_dict_set_timestamp(metadata, "creation_time", time * 1000000);
1866  }
1867 }
1868 
1870 {
1871  AVStream *st;
1872  MOVStreamContext *sc;
1873  int version;
1874  char language[4] = {0};
1875  unsigned lang;
1876 
1877  if (c->fc->nb_streams < 1)
1878  return 0;
1879  st = c->fc->streams[c->fc->nb_streams-1];
1880  sc = st->priv_data;
1881 
1882  if (sc->time_scale) {
1883  av_log(c->fc, AV_LOG_ERROR, "Multiple mdhd?\n");
1884  return AVERROR_INVALIDDATA;
1885  }
1886 
1887  version = avio_r8(pb);
1888  if (version > 1) {
1889  avpriv_request_sample(c->fc, "Version %d", version);
1890  return AVERROR_PATCHWELCOME;
1891  }
1892  avio_rb24(pb); /* flags */
1894 
1895  sc->time_scale = avio_rb32(pb);
1896  if (sc->time_scale <= 0) {
1897  av_log(c->fc, AV_LOG_ERROR, "Invalid mdhd time scale %d, defaulting to 1\n", sc->time_scale);
1898  sc->time_scale = 1;
1899  }
1900  st->duration = (version == 1) ? avio_rb64(pb) : avio_rb32(pb); /* duration */
1901 
1902  if ((version == 1 && st->duration == UINT64_MAX) ||
1903  (version != 1 && st->duration == UINT32_MAX)) {
1904  st->duration = 0;
1905  }
1906 
1907  lang = avio_rb16(pb); /* language */
1908  if (ff_mov_lang_to_iso639(lang, language))
1909  av_dict_set(&st->metadata, "language", language, 0);
1910  avio_rb16(pb); /* quality */
1911 
1912  return 0;
1913 }
1914 
1916 {
1917  int i;
1918  int version = avio_r8(pb); /* version */
1919  avio_rb24(pb); /* flags */
1920 
1921  mov_metadata_creation_time(c, pb, &c->fc->metadata, version);
1922  c->time_scale = avio_rb32(pb); /* time scale */
1923  if (c->time_scale <= 0) {
1924  av_log(c->fc, AV_LOG_ERROR, "Invalid mvhd time scale %d, defaulting to 1\n", c->time_scale);
1925  c->time_scale = 1;
1926  }
1927  av_log(c->fc, AV_LOG_TRACE, "time scale = %i\n", c->time_scale);
1928 
1929  c->duration = (version == 1) ? avio_rb64(pb) : avio_rb32(pb); /* duration */
1930  avio_rb32(pb); /* preferred scale */
1931 
1932  avio_rb16(pb); /* preferred volume */
1933 
1934  avio_skip(pb, 10); /* reserved */
1935 
1936  /* movie display matrix, store it in main context and use it later on */
1937  for (i = 0; i < 3; i++) {
1938  c->movie_display_matrix[i][0] = avio_rb32(pb); // 16.16 fixed point
1939  c->movie_display_matrix[i][1] = avio_rb32(pb); // 16.16 fixed point
1940  c->movie_display_matrix[i][2] = avio_rb32(pb); // 2.30 fixed point
1941  }
1942 
1943  avio_rb32(pb); /* preview time */
1944  avio_rb32(pb); /* preview duration */
1945  avio_rb32(pb); /* poster time */
1946  avio_rb32(pb); /* selection time */
1947  avio_rb32(pb); /* selection duration */
1948  avio_rb32(pb); /* current time */
1949  avio_rb32(pb); /* next track ID */
1950 
1951  return 0;
1952 }
1953 
1955 {
1956  AVStream *st;
1957 
1958  if (fc->nb_streams < 1)
1959  return;
1960  st = fc->streams[fc->nb_streams-1];
1961 
1962  switch (st->codecpar->codec_id) {
1963  case AV_CODEC_ID_PCM_S16BE:
1965  break;
1966  case AV_CODEC_ID_PCM_S24BE:
1968  break;
1969  case AV_CODEC_ID_PCM_S32BE:
1971  break;
1972  case AV_CODEC_ID_PCM_F32BE:
1974  break;
1975  case AV_CODEC_ID_PCM_F64BE:
1977  break;
1978  default:
1979  break;
1980  }
1981 }
1982 
1984 {
1985  int little_endian = avio_rb16(pb) & 0xFF;
1986  av_log(c->fc, AV_LOG_TRACE, "enda %d\n", little_endian);
1987  if (little_endian == 1)
1989  return 0;
1990 }
1991 
1993 {
1994  int format_flags;
1995  int version, flags;
1996  int pcm_sample_size;
1997  AVFormatContext *fc = c->fc;
1998  AVStream *st;
1999  MOVStreamContext *sc;
2000 
2001  if (atom.size < 6) {
2002  av_log(c->fc, AV_LOG_ERROR, "Empty pcmC box\n");
2003  return AVERROR_INVALIDDATA;
2004  }
2005 
2006  version = avio_r8(pb);
2007  flags = avio_rb24(pb);
2008 
2009  if (version != 0 || flags != 0) {
2010  av_log(c->fc, AV_LOG_ERROR,
2011  "Unsupported 'pcmC' box with version %d, flags: %x",
2012  version, flags);
2013  return AVERROR_INVALIDDATA;
2014  }
2015 
2016  format_flags = avio_r8(pb);
2017  pcm_sample_size = avio_r8(pb);
2018 
2019  if (fc->nb_streams < 1)
2020  return AVERROR_INVALIDDATA;
2021 
2022  st = fc->streams[fc->nb_streams - 1];
2023  sc = st->priv_data;
2024 
2025  if (sc->format == MOV_MP4_FPCM_TAG) {
2026  switch (pcm_sample_size) {
2027  case 32:
2029  break;
2030  case 64:
2032  break;
2033  default:
2034  av_log(fc, AV_LOG_ERROR, "invalid pcm_sample_size %d for %s\n",
2035  pcm_sample_size,
2036  av_fourcc2str(sc->format));
2037  return AVERROR_INVALIDDATA;
2038  }
2039  } else if (sc->format == MOV_MP4_IPCM_TAG) {
2040  switch (pcm_sample_size) {
2041  case 16:
2043  break;
2044  case 24:
2046  break;
2047  case 32:
2049  break;
2050  default:
2051  av_log(fc, AV_LOG_ERROR, "invalid pcm_sample_size %d for %s\n",
2052  pcm_sample_size,
2053  av_fourcc2str(sc->format));
2054  return AVERROR_INVALIDDATA;
2055  }
2056  } else {
2057  av_log(fc, AV_LOG_ERROR, "'pcmC' with invalid sample entry '%s'\n",
2058  av_fourcc2str(sc->format));
2059  return AVERROR_INVALIDDATA;
2060  }
2061 
2062  if (format_flags & 1) // indicates little-endian format. If not present, big-endian format is used
2065 
2066  return 0;
2067 }
2068 
2070 {
2071  AVStream *st;
2072  HEIFItem *item = NULL;
2073  char color_parameter_type[5] = { 0 };
2074  uint16_t color_primaries, color_trc, color_matrix;
2075  int ret;
2076 
2077  st = get_curr_st(c);
2078  if (!st) {
2079  item = heif_cur_item(c);
2080  if (!item)
2081  return 0;
2082  }
2083 
2084  ret = ffio_read_size(pb, color_parameter_type, 4);
2085  if (ret < 0)
2086  return ret;
2087  if (strncmp(color_parameter_type, "nclx", 4) &&
2088  strncmp(color_parameter_type, "nclc", 4) &&
2089  strncmp(color_parameter_type, "prof", 4)) {
2090  av_log(c->fc, AV_LOG_WARNING, "unsupported color_parameter_type %s\n",
2091  color_parameter_type);
2092  return 0;
2093  }
2094 
2095  if (!strncmp(color_parameter_type, "prof", 4)) {
2096  AVPacketSideData *sd;
2097  uint8_t *icc_profile;
2098  if (st) {
2102  atom.size - 4, 0);
2103  if (!sd)
2104  return AVERROR(ENOMEM);
2105  icc_profile = sd->data;
2106  } else {
2107  av_freep(&item->icc_profile);
2108  icc_profile = item->icc_profile = av_malloc(atom.size - 4);
2109  if (!icc_profile) {
2110  item->icc_profile_size = 0;
2111  return AVERROR(ENOMEM);
2112  }
2113  item->icc_profile_size = atom.size - 4;
2114  }
2115  ret = ffio_read_size(pb, icc_profile, atom.size - 4);
2116  if (ret < 0)
2117  return ret;
2118  } else if (st) {
2119  color_primaries = avio_rb16(pb);
2120  color_trc = avio_rb16(pb);
2121  color_matrix = avio_rb16(pb);
2122 
2123  av_log(c->fc, AV_LOG_TRACE,
2124  "%s: pri %d trc %d matrix %d",
2125  color_parameter_type, color_primaries, color_trc, color_matrix);
2126 
2127  if (!strncmp(color_parameter_type, "nclx", 4)) {
2128  uint8_t color_range = avio_r8(pb) >> 7;
2129  av_log(c->fc, AV_LOG_TRACE, " full %"PRIu8"", color_range);
2130  if (color_range)
2132  else
2134  }
2135 
2138  if (!av_color_transfer_name(color_trc))
2139  color_trc = AVCOL_TRC_UNSPECIFIED;
2140  if (!av_color_space_name(color_matrix))
2141  color_matrix = AVCOL_SPC_UNSPECIFIED;
2142 
2144  st->codecpar->color_trc = color_trc;
2145  st->codecpar->color_space = color_matrix;
2146  av_log(c->fc, AV_LOG_TRACE, "\n");
2147  }
2148  return 0;
2149 }
2150 
2152 {
2153  AVStream *st;
2154  unsigned mov_field_order;
2155  enum AVFieldOrder decoded_field_order = AV_FIELD_UNKNOWN;
2156 
2157  if (c->fc->nb_streams < 1) // will happen with jp2 files
2158  return 0;
2159  st = c->fc->streams[c->fc->nb_streams-1];
2160  if (atom.size < 2)
2161  return AVERROR_INVALIDDATA;
2162  mov_field_order = avio_rb16(pb);
2163  if ((mov_field_order & 0xFF00) == 0x0100)
2164  decoded_field_order = AV_FIELD_PROGRESSIVE;
2165  else if ((mov_field_order & 0xFF00) == 0x0200) {
2166  switch (mov_field_order & 0xFF) {
2167  case 0x01: decoded_field_order = AV_FIELD_TT;
2168  break;
2169  case 0x06: decoded_field_order = AV_FIELD_BB;
2170  break;
2171  case 0x09: decoded_field_order = AV_FIELD_TB;
2172  break;
2173  case 0x0E: decoded_field_order = AV_FIELD_BT;
2174  break;
2175  }
2176  }
2177  if (decoded_field_order == AV_FIELD_UNKNOWN && mov_field_order) {
2178  av_log(c->fc, AV_LOG_ERROR, "Unknown MOV field order 0x%04x\n", mov_field_order);
2179  }
2180  st->codecpar->field_order = decoded_field_order;
2181 
2182  return 0;
2183 }
2184 
2186 {
2187  int err = 0;
2188  uint64_t size = (uint64_t)par->extradata_size + atom.size + 8 + AV_INPUT_BUFFER_PADDING_SIZE;
2189  if (size > INT_MAX || (uint64_t)atom.size > INT_MAX)
2190  return AVERROR_INVALIDDATA;
2191  if ((err = av_reallocp(&par->extradata, size)) < 0) {
2192  par->extradata_size = 0;
2193  return err;
2194  }
2196  return 0;
2197 }
2198 
2199 /* Read a whole atom into the extradata return the size of the atom read, possibly truncated if != atom.size */
2201  AVCodecParameters *par, uint8_t *buf)
2202 {
2203  int64_t result = atom.size;
2204  int err;
2205 
2206  AV_WB32(buf , atom.size + 8);
2207  AV_WL32(buf + 4, atom.type);
2208  err = ffio_read_size(pb, buf + 8, atom.size);
2209  if (err < 0) {
2210  par->extradata_size -= atom.size;
2211  return err;
2212  } else if (err < atom.size) {
2213  av_log(c->fc, AV_LOG_WARNING, "truncated extradata\n");
2214  par->extradata_size -= atom.size - err;
2215  result = err;
2216  }
2217  memset(buf + 8 + err, 0, AV_INPUT_BUFFER_PADDING_SIZE);
2218  return result;
2219 }
2220 
2221 /* FIXME modify QDM2/SVQ3/H.264 decoders to take full atom as extradata */
2223  enum AVCodecID codec_id)
2224 {
2225  AVStream *st;
2226  uint64_t original_size;
2227  int err;
2228 
2229  if (c->fc->nb_streams < 1) // will happen with jp2 files
2230  return 0;
2231  st = c->fc->streams[c->fc->nb_streams-1];
2232 
2233  if (st->codecpar->codec_id != codec_id)
2234  return 0; /* unexpected codec_id - don't mess with extradata */
2235 
2236  original_size = st->codecpar->extradata_size;
2237  err = mov_realloc_extradata(st->codecpar, atom);
2238  if (err)
2239  return err;
2240 
2241  err = mov_read_atom_into_extradata(c, pb, atom, st->codecpar, st->codecpar->extradata + original_size);
2242  if (err < 0)
2243  return err;
2244  return 0; // Note: this is the original behavior to ignore truncation.
2245 }
2246 
2247 /* wrapper functions for reading ALAC/AVS/MJPEG/MJPEG2000 extradata atoms only for those codecs */
2249 {
2250  return mov_read_extradata(c, pb, atom, AV_CODEC_ID_ALAC);
2251 }
2252 
2254 {
2255  return mov_read_extradata(c, pb, atom, AV_CODEC_ID_CAVS);
2256 }
2257 
2259 {
2260  return mov_read_extradata(c, pb, atom, AV_CODEC_ID_JPEG2000);
2261 }
2262 
2264 {
2265  return mov_read_extradata(c, pb, atom, AV_CODEC_ID_R10K);
2266 }
2267 
2269 {
2270  int ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_AVUI);
2271  if (!ret)
2272  ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_DNXHD);
2273  return ret;
2274 }
2275 
2277 {
2278  int ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_TARGA_Y216);
2279 
2280  if (!ret && c->fc->nb_streams >= 1) {
2281  AVCodecParameters *par = c->fc->streams[c->fc->nb_streams-1]->codecpar;
2282  if (par->extradata_size >= 40) {
2283  par->height = AV_RB16(&par->extradata[36]);
2284  par->width = AV_RB16(&par->extradata[38]);
2285  }
2286  }
2287  return ret;
2288 }
2289 
2291 {
2292  if (c->fc->nb_streams >= 1) {
2293  AVStream *const st = c->fc->streams[c->fc->nb_streams - 1];
2294  FFStream *const sti = ffstream(st);
2295  AVCodecParameters *par = st->codecpar;
2296 
2297  if (par->codec_tag == MKTAG('A', 'V', 'i', 'n') &&
2298  par->codec_id == AV_CODEC_ID_H264 &&
2299  atom.size > 11) {
2300  int cid;
2301  avio_skip(pb, 10);
2302  cid = avio_rb16(pb);
2303  /* For AVID AVCI50, force width of 1440 to be able to select the correct SPS and PPS */
2304  if (cid == 0xd4d || cid == 0xd4e)
2305  par->width = 1440;
2306  return 0;
2307  } else if ((par->codec_tag == MKTAG('A', 'V', 'd', '1') ||
2308  par->codec_tag == MKTAG('A', 'V', 'j', '2') ||
2309  par->codec_tag == MKTAG('A', 'V', 'd', 'n')) &&
2310  atom.size >= 24) {
2311  int num, den;
2312  avio_skip(pb, 12);
2313  num = avio_rb32(pb);
2314  den = avio_rb32(pb);
2315  if (num <= 0 || den <= 0)
2316  return 0;
2317  switch (avio_rb32(pb)) {
2318  case 2:
2319  if (den >= INT_MAX / 2)
2320  return 0;
2321  den *= 2;
2322  case 1:
2323  sti->display_aspect_ratio = (AVRational){ num, den };
2324  default:
2325  return 0;
2326  }
2327  }
2328  }
2329 
2330  return mov_read_avid(c, pb, atom);
2331 }
2332 
2334 {
2335  int ret = 0;
2336  int length = 0;
2337  uint64_t original_size;
2338  if (c->fc->nb_streams >= 1) {
2339  AVCodecParameters *par = c->fc->streams[c->fc->nb_streams-1]->codecpar;
2340  if (par->codec_id == AV_CODEC_ID_H264)
2341  return 0;
2342  if (atom.size == 16) {
2343  original_size = par->extradata_size;
2344  ret = mov_realloc_extradata(par, atom);
2345  if (!ret) {
2346  length = mov_read_atom_into_extradata(c, pb, atom, par, par->extradata + original_size);
2347  if (length == atom.size) {
2348  const uint8_t range_value = par->extradata[original_size + 19];
2349  switch (range_value) {
2350  case 1:
2352  break;
2353  case 2:
2355  break;
2356  default:
2357  av_log(c->fc, AV_LOG_WARNING, "ignored unknown aclr value (%d)\n", range_value);
2358  break;
2359  }
2360  ff_dlog(c->fc, "color_range: %d\n", par->color_range);
2361  } else {
2362  /* For some reason the whole atom was not added to the extradata */
2363  av_log(c->fc, AV_LOG_ERROR, "aclr not decoded - incomplete atom\n");
2364  }
2365  } else {
2366  av_log(c->fc, AV_LOG_ERROR, "aclr not decoded - unable to add atom to extradata\n");
2367  }
2368  } else {
2369  av_log(c->fc, AV_LOG_WARNING, "aclr not decoded - unexpected size %"PRId64"\n", atom.size);
2370  }
2371  }
2372 
2373  return ret;
2374 }
2375 
2377 {
2378  return mov_read_extradata(c, pb, atom, AV_CODEC_ID_SVQ3);
2379 }
2380 
2382 {
2383  AVStream *st;
2384  int ret;
2385 
2386  if (c->fc->nb_streams < 1)
2387  return 0;
2388  st = c->fc->streams[c->fc->nb_streams-1];
2389 
2390  if ((uint64_t)atom.size > (1<<30))
2391  return AVERROR_INVALIDDATA;
2392 
2393  if (st->codecpar->codec_id == AV_CODEC_ID_QDM2 ||
2396  // pass all frma atom to codec, needed at least for QDMC and QDM2
2397  ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size);
2398  if (ret < 0)
2399  return ret;
2400  } else if (atom.size > 8) { /* to read frma, esds atoms */
2401  if (st->codecpar->codec_id == AV_CODEC_ID_ALAC && atom.size >= 24) {
2402  uint64_t buffer;
2403  ret = ffio_ensure_seekback(pb, 8);
2404  if (ret < 0)
2405  return ret;
2406  buffer = avio_rb64(pb);
2407  atom.size -= 8;
2408  if ( (buffer & 0xFFFFFFFF) == MKBETAG('f','r','m','a')
2409  && buffer >> 32 <= atom.size
2410  && buffer >> 32 >= 8) {
2411  avio_skip(pb, -8);
2412  atom.size += 8;
2413  } else if (!st->codecpar->extradata_size) {
2414 #define ALAC_EXTRADATA_SIZE 36
2416  if (!st->codecpar->extradata)
2417  return AVERROR(ENOMEM);
2420  AV_WB32(st->codecpar->extradata + 4, MKTAG('a','l','a','c'));
2421  AV_WB64(st->codecpar->extradata + 12, buffer);
2422  avio_read(pb, st->codecpar->extradata + 20, 16);
2423  avio_skip(pb, atom.size - 24);
2424  return 0;
2425  }
2426  }
2427  if ((ret = mov_read_default(c, pb, atom)) < 0)
2428  return ret;
2429  } else
2430  avio_skip(pb, atom.size);
2431  return 0;
2432 }
2433 
2434 /**
2435  * This function reads atom content and puts data in extradata without tag
2436  * nor size unlike mov_read_extradata.
2437  */
2439 {
2440  AVStream *st;
2441  int ret;
2442 
2443  st = get_curr_st(c);
2444  if (!st)
2445  return 0;
2446 
2447  if ((uint64_t)atom.size > (1<<30))
2448  return AVERROR_INVALIDDATA;
2449 
2450  if (atom.type == MKTAG('v','v','c','C')) {
2451  avio_skip(pb, 4);
2452  atom.size -= 4;
2453  }
2454 
2455  if (atom.size >= 10) {
2456  // Broken files created by legacy versions of libavformat will
2457  // wrap a whole fiel atom inside of a glbl atom.
2458  unsigned size = avio_rb32(pb);
2459  unsigned type = avio_rl32(pb);
2460  if (avio_feof(pb))
2461  return AVERROR_INVALIDDATA;
2462  avio_seek(pb, -8, SEEK_CUR);
2463  if (type == MKTAG('f','i','e','l') && size == atom.size)
2464  return mov_read_default(c, pb, atom);
2465  }
2466  if (st->codecpar->extradata_size > 1 && st->codecpar->extradata) {
2467  av_log(c->fc, AV_LOG_WARNING, "ignoring multiple glbl\n");
2468  return 0;
2469  }
2470  ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size);
2471  if (ret < 0)
2472  return ret;
2473  if (atom.type == MKTAG('h','v','c','C') && st->codecpar->codec_tag == MKTAG('d','v','h','1'))
2474  /* HEVC-based Dolby Vision derived from hvc1.
2475  Happens to match with an identifier
2476  previously utilized for DV. Thus, if we have
2477  the hvcC extradata box available as specified,
2478  set codec to HEVC */
2480 
2481  return 0;
2482 }
2483 
2485 {
2486  AVStream *st;
2487  uint8_t profile_level;
2488  int ret;
2489 
2490  if (c->fc->nb_streams < 1)
2491  return 0;
2492  st = c->fc->streams[c->fc->nb_streams-1];
2493 
2494  if (atom.size >= (1<<28) || atom.size < 7)
2495  return AVERROR_INVALIDDATA;
2496 
2497  profile_level = avio_r8(pb);
2498  if ((profile_level & 0xf0) != 0xc0)
2499  return 0;
2500 
2501  avio_seek(pb, 6, SEEK_CUR);
2502  ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size - 7);
2503  if (ret < 0)
2504  return ret;
2505 
2506  return 0;
2507 }
2508 
2510 {
2511  AVStream* st;
2512  MOVStreamContext* sc;
2513 
2514  if (c->fc->nb_streams < 1)
2515  return 0;
2516 
2517  /* For SBAS this should be fine - though beware if someone implements a
2518  * tref atom processor that doesn't drop down to default then this may
2519  * be lost. */
2520  if (atom.size > 4) {
2521  av_log(c->fc, AV_LOG_ERROR, "Only a single tref of type sbas is supported\n");
2522  return AVERROR_PATCHWELCOME;
2523  }
2524 
2525  st = c->fc->streams[c->fc->nb_streams - 1];
2526  sc = st->priv_data;
2527  sc->tref_id = avio_rb32(pb);
2529 
2530  return 0;
2531 }
2532 
2533 /**
2534  * An strf atom is a BITMAPINFOHEADER struct. This struct is 40 bytes itself,
2535  * but can have extradata appended at the end after the 40 bytes belonging
2536  * to the struct.
2537  */
2539 {
2540  AVStream *st;
2541  int ret;
2542 
2543  if (c->fc->nb_streams < 1)
2544  return 0;
2545  if (atom.size <= 40)
2546  return 0;
2547  st = c->fc->streams[c->fc->nb_streams-1];
2548 
2549  if ((uint64_t)atom.size > (1<<30))
2550  return AVERROR_INVALIDDATA;
2551 
2552  avio_skip(pb, 40);
2553  ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size - 40);
2554  if (ret < 0)
2555  return ret;
2556 
2557  return 0;
2558 }
2559 
2561 {
2562  AVStream *st;
2563  MOVStreamContext *sc;
2564  unsigned int i, entries;
2565 
2566  if (c->trak_index < 0) {
2567  av_log(c->fc, AV_LOG_WARNING, "STCO outside TRAK\n");
2568  return 0;
2569  }
2570  if (c->fc->nb_streams < 1)
2571  return 0;
2572  st = c->fc->streams[c->fc->nb_streams-1];
2573  sc = st->priv_data;
2574 
2575  avio_r8(pb); /* version */
2576  avio_rb24(pb); /* flags */
2577 
2578  // Clamp allocation size for `chunk_offsets` -- don't throw an error for an
2579  // invalid count since the EOF path doesn't throw either.
2580  entries = avio_rb32(pb);
2581  entries =
2582  FFMIN(entries,
2583  FFMAX(0, (atom.size - 8) /
2584  (atom.type == MKTAG('s', 't', 'c', 'o') ? 4 : 8)));
2585 
2586  if (!entries)
2587  return 0;
2588 
2589  if (sc->chunk_offsets) {
2590  av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicated STCO atom\n");
2591  return 0;
2592  }
2593 
2594  av_free(sc->chunk_offsets);
2595  sc->chunk_count = 0;
2596  sc->chunk_offsets = av_malloc_array(entries, sizeof(*sc->chunk_offsets));
2597  if (!sc->chunk_offsets)
2598  return AVERROR(ENOMEM);
2599  sc->chunk_count = entries;
2600 
2601  if (atom.type == MKTAG('s','t','c','o'))
2602  for (i = 0; i < entries && !pb->eof_reached; i++)
2603  sc->chunk_offsets[i] = avio_rb32(pb);
2604  else if (atom.type == MKTAG('c','o','6','4'))
2605  for (i = 0; i < entries && !pb->eof_reached; i++) {
2606  sc->chunk_offsets[i] = avio_rb64(pb);
2607  if (sc->chunk_offsets[i] < 0) {
2608  av_log(c->fc, AV_LOG_WARNING, "Impossible chunk_offset\n");
2609  sc->chunk_offsets[i] = 0;
2610  }
2611  }
2612  else
2613  return AVERROR_INVALIDDATA;
2614 
2615  sc->chunk_count = i;
2616 
2617  if (pb->eof_reached) {
2618  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STCO atom\n");
2619  return AVERROR_EOF;
2620  }
2621 
2622  return 0;
2623 }
2624 
2625 static int mov_codec_id(AVStream *st, uint32_t format)
2626 {
2628 
2629  if (id <= 0 &&
2630  ((format & 0xFFFF) == 'm' + ('s' << 8) ||
2631  (format & 0xFFFF) == 'T' + ('S' << 8)))
2633 
2634  if (st->codecpar->codec_type != AVMEDIA_TYPE_VIDEO && id > 0) {
2636  } else if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO &&
2637  /* skip old ASF MPEG-4 tag */
2638  format && format != MKTAG('m','p','4','s')) {
2640  if (id <= 0)
2642  if (id > 0)
2644  else if (st->codecpar->codec_type == AVMEDIA_TYPE_DATA ||
2646  st->codecpar->codec_id == AV_CODEC_ID_NONE)) {
2648  if (id <= 0) {
2650  AV_CODEC_ID_TTML : id;
2651  }
2652 
2653  if (id > 0)
2655  else
2657  }
2658  }
2659 
2660  st->codecpar->codec_tag = format;
2661 
2662  return id;
2663 }
2664 
2666  AVStream *st, MOVStreamContext *sc)
2667 {
2668  uint8_t codec_name[32] = { 0 };
2669  int64_t stsd_start;
2670  unsigned int len;
2671  uint32_t id = 0;
2672 
2673  /* The first 16 bytes of the video sample description are already
2674  * read in ff_mov_read_stsd_entries() */
2675  stsd_start = avio_tell(pb) - 16;
2676 
2677  avio_rb16(pb); /* version */
2678  avio_rb16(pb); /* revision level */
2679  id = avio_rl32(pb); /* vendor */
2680  av_dict_set(&st->metadata, "vendor_id", av_fourcc2str(id), 0);
2681  avio_rb32(pb); /* temporal quality */
2682  avio_rb32(pb); /* spatial quality */
2683 
2684  st->codecpar->width = avio_rb16(pb); /* width */
2685  st->codecpar->height = avio_rb16(pb); /* height */
2686 
2687  avio_rb32(pb); /* horiz resolution */
2688  avio_rb32(pb); /* vert resolution */
2689  avio_rb32(pb); /* data size, always 0 */
2690  avio_rb16(pb); /* frames per samples */
2691 
2692  len = avio_r8(pb); /* codec name, pascal string */
2693  if (len > 31)
2694  len = 31;
2695  mov_read_mac_string(c, pb, len, codec_name, sizeof(codec_name));
2696  if (len < 31)
2697  avio_skip(pb, 31 - len);
2698 
2699  if (codec_name[0])
2700  av_dict_set(&st->metadata, "encoder", codec_name, 0);
2701 
2702  /* codec_tag YV12 triggers an UV swap in rawdec.c */
2703  if (!strncmp(codec_name, "Planar Y'CbCr 8-bit 4:2:0", 25)) {
2704  st->codecpar->codec_tag = MKTAG('I', '4', '2', '0');
2705  st->codecpar->width &= ~1;
2706  st->codecpar->height &= ~1;
2707  }
2708  /* Flash Media Server uses tag H.263 with Sorenson Spark */
2709  if (st->codecpar->codec_tag == MKTAG('H','2','6','3') &&
2710  !strncmp(codec_name, "Sorenson H263", 13))
2712 
2713  st->codecpar->bits_per_coded_sample = avio_rb16(pb); /* depth */
2714 
2715  avio_seek(pb, stsd_start, SEEK_SET);
2716 
2717  if (ff_get_qtpalette(st->codecpar->codec_id, pb, sc->palette)) {
2718  st->codecpar->bits_per_coded_sample &= 0x1F;
2719  sc->has_palette = 1;
2720  }
2721 }
2722 
2724  AVStream *st, MOVStreamContext *sc)
2725 {
2726  int bits_per_sample, flags;
2727  uint16_t version = avio_rb16(pb);
2728  uint32_t id = 0;
2729  AVDictionaryEntry *compatible_brands = av_dict_get(c->fc->metadata, "compatible_brands", NULL, AV_DICT_MATCH_CASE);
2730  int channel_count;
2731 
2732  avio_rb16(pb); /* revision level */
2733  id = avio_rl32(pb); /* vendor */
2734  av_dict_set(&st->metadata, "vendor_id", av_fourcc2str(id), 0);
2735 
2736  channel_count = avio_rb16(pb);
2737 
2739  st->codecpar->ch_layout.nb_channels = channel_count;
2740  st->codecpar->bits_per_coded_sample = avio_rb16(pb); /* sample size */
2741  av_log(c->fc, AV_LOG_TRACE, "audio channels %d\n", channel_count);
2742 
2743  sc->audio_cid = avio_rb16(pb);
2744  avio_rb16(pb); /* packet size = 0 */
2745 
2746  st->codecpar->sample_rate = ((avio_rb32(pb) >> 16));
2747 
2748  // Read QT version 1 fields. In version 0 these do not exist.
2749  av_log(c->fc, AV_LOG_TRACE, "version =%d, isom =%d\n", version, c->isom);
2750  if (!c->isom ||
2751  (compatible_brands && strstr(compatible_brands->value, "qt ")) ||
2752  (sc->stsd_version == 0 && version > 0)) {
2753  if (version == 1) {
2754  sc->samples_per_frame = avio_rb32(pb);
2755  avio_rb32(pb); /* bytes per packet */
2756  sc->bytes_per_frame = avio_rb32(pb);
2757  avio_rb32(pb); /* bytes per sample */
2758  } else if (version == 2) {
2759  avio_rb32(pb); /* sizeof struct only */
2761  channel_count = avio_rb32(pb);
2763  st->codecpar->ch_layout.nb_channels = channel_count;
2764  avio_rb32(pb); /* always 0x7F000000 */
2766 
2767  flags = avio_rb32(pb); /* lpcm format specific flag */
2768  sc->bytes_per_frame = avio_rb32(pb);
2769  sc->samples_per_frame = avio_rb32(pb);
2770  if (st->codecpar->codec_tag == MKTAG('l','p','c','m'))
2771  st->codecpar->codec_id =
2773  flags);
2774  }
2775  if (version == 0 || (version == 1 && sc->audio_cid != -2)) {
2776  /* can't correctly handle variable sized packet as audio unit */
2777  switch (st->codecpar->codec_id) {
2778  case AV_CODEC_ID_MP2:
2779  case AV_CODEC_ID_MP3:
2781  break;
2782  }
2783  }
2784  }
2785 
2786  if (sc->format == 0) {
2787  if (st->codecpar->bits_per_coded_sample == 8)
2788  st->codecpar->codec_id = mov_codec_id(st, MKTAG('r','a','w',' '));
2789  else if (st->codecpar->bits_per_coded_sample == 16)
2790  st->codecpar->codec_id = mov_codec_id(st, MKTAG('t','w','o','s'));
2791  }
2792 
2793  switch (st->codecpar->codec_id) {
2794  case AV_CODEC_ID_PCM_S8:
2795  case AV_CODEC_ID_PCM_U8:
2796  if (st->codecpar->bits_per_coded_sample == 16)
2798  break;
2799  case AV_CODEC_ID_PCM_S16LE:
2800  case AV_CODEC_ID_PCM_S16BE:
2801  if (st->codecpar->bits_per_coded_sample == 8)
2803  else if (st->codecpar->bits_per_coded_sample == 24)
2804  st->codecpar->codec_id =
2807  else if (st->codecpar->bits_per_coded_sample == 32)
2808  st->codecpar->codec_id =
2811  break;
2812  /* set values for old format before stsd version 1 appeared */
2813  case AV_CODEC_ID_MACE3:
2814  sc->samples_per_frame = 6;
2816  break;
2817  case AV_CODEC_ID_MACE6:
2818  sc->samples_per_frame = 6;
2820  break;
2822  sc->samples_per_frame = 64;
2824  break;
2825  case AV_CODEC_ID_GSM:
2826  sc->samples_per_frame = 160;
2827  sc->bytes_per_frame = 33;
2828  break;
2829  default:
2830  break;
2831  }
2832 
2833  bits_per_sample = av_get_bits_per_sample(st->codecpar->codec_id);
2834  if (bits_per_sample && (bits_per_sample >> 3) * (uint64_t)st->codecpar->ch_layout.nb_channels <= INT_MAX) {
2835  st->codecpar->bits_per_coded_sample = bits_per_sample;
2836  sc->sample_size = (bits_per_sample >> 3) * st->codecpar->ch_layout.nb_channels;
2837  }
2838 }
2839 
2841  AVStream *st, MOVStreamContext *sc,
2842  int64_t size)
2843 {
2844  // ttxt stsd contains display flags, justification, background
2845  // color, fonts, and default styles, so fake an atom to read it
2846  MOVAtom fake_atom = { .size = size };
2847  // mp4s contains a regular esds atom, dfxp ISMV TTML has no content
2848  // in extradata unlike stpp MP4 TTML.
2849  if (st->codecpar->codec_tag != AV_RL32("mp4s") &&
2851  mov_read_glbl(c, pb, fake_atom);
2852  st->codecpar->width = sc->width;
2853  st->codecpar->height = sc->height;
2854 }
2855 
2857  AVStream *st, MOVStreamContext *sc,
2858  int64_t size)
2859 {
2860  int ret;
2861 
2862  if (st->codecpar->codec_tag == MKTAG('t','m','c','d')) {
2863  if ((int)size != size)
2864  return AVERROR(ENOMEM);
2865 
2866  ret = ff_get_extradata(c->fc, st->codecpar, pb, size);
2867  if (ret < 0)
2868  return ret;
2869  if (size > 16) {
2870  MOVStreamContext *tmcd_ctx = st->priv_data;
2871  int val;
2872  val = AV_RB32(st->codecpar->extradata + 4);
2873  tmcd_ctx->tmcd_flags = val;
2874  st->avg_frame_rate.num = AV_RB32(st->codecpar->extradata + 8); /* timescale */
2875  st->avg_frame_rate.den = AV_RB32(st->codecpar->extradata + 12); /* frameDuration */
2876  tmcd_ctx->tmcd_nb_frames = st->codecpar->extradata[16]; /* number of frames */
2877  if (size > 30) {
2878  uint32_t len = AV_RB32(st->codecpar->extradata + 18); /* name atom length */
2879  uint32_t format = AV_RB32(st->codecpar->extradata + 22);
2880  if (format == AV_RB32("name") && (int64_t)size >= (int64_t)len + 18) {
2881  uint16_t str_size = AV_RB16(st->codecpar->extradata + 26); /* string length */
2882  if (str_size > 0 && size >= (int)str_size + 30 &&
2883  st->codecpar->extradata[30] /* Don't add empty string */) {
2884  char *reel_name = av_malloc(str_size + 1);
2885  if (!reel_name)
2886  return AVERROR(ENOMEM);
2887  memcpy(reel_name, st->codecpar->extradata + 30, str_size);
2888  reel_name[str_size] = 0; /* Add null terminator */
2889  av_dict_set(&st->metadata, "reel_name", reel_name,
2891  }
2892  }
2893  }
2894  }
2895  } else {
2896  /* other codec type, just skip (rtp, mp4s ...) */
2897  avio_skip(pb, size);
2898  }
2899  return 0;
2900 }
2901 
2903  AVStream *st, MOVStreamContext *sc)
2904 {
2905  FFStream *const sti = ffstream(st);
2906 
2907  if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
2908  !st->codecpar->sample_rate && sc->time_scale > 1)
2909  st->codecpar->sample_rate = sc->time_scale;
2910 
2911  /* special codec parameters handling */
2912  switch (st->codecpar->codec_id) {
2913 #if CONFIG_DV_DEMUXER
2914  case AV_CODEC_ID_DVAUDIO:
2915  if (c->dv_fctx) {
2916  avpriv_request_sample(c->fc, "multiple DV audio streams");
2917  return AVERROR(ENOSYS);
2918  }
2919 
2920  c->dv_fctx = avformat_alloc_context();
2921  if (!c->dv_fctx) {
2922  av_log(c->fc, AV_LOG_ERROR, "dv demux context alloc error\n");
2923  return AVERROR(ENOMEM);
2924  }
2925  c->dv_demux = avpriv_dv_init_demux(c->dv_fctx);
2926  if (!c->dv_demux) {
2927  av_log(c->fc, AV_LOG_ERROR, "dv demux context init error\n");
2928  return AVERROR(ENOMEM);
2929  }
2930  sc->dv_audio_container = 1;
2932  break;
2933 #endif
2934  /* no ifdef since parameters are always those */
2935  case AV_CODEC_ID_QCELP:
2938  // force sample rate for qcelp when not stored in mov
2939  if (st->codecpar->codec_tag != MKTAG('Q','c','l','p'))
2940  st->codecpar->sample_rate = 8000;
2941  // FIXME: Why is the following needed for some files?
2942  sc->samples_per_frame = 160;
2943  if (!sc->bytes_per_frame)
2944  sc->bytes_per_frame = 35;
2945  break;
2946  case AV_CODEC_ID_AMR_NB:
2949  /* force sample rate for amr, stsd in 3gp does not store sample rate */
2950  st->codecpar->sample_rate = 8000;
2951  break;
2952  case AV_CODEC_ID_AMR_WB:
2955  st->codecpar->sample_rate = 16000;
2956  break;
2957  case AV_CODEC_ID_MP2:
2958  case AV_CODEC_ID_MP3:
2959  /* force type after stsd for m1a hdlr */
2961  break;
2962  case AV_CODEC_ID_GSM:
2963  case AV_CODEC_ID_ADPCM_MS:
2965  case AV_CODEC_ID_ILBC:
2966  case AV_CODEC_ID_MACE3:
2967  case AV_CODEC_ID_MACE6:
2968  case AV_CODEC_ID_QDM2:
2970  break;
2971  case AV_CODEC_ID_ALAC:
2972  if (st->codecpar->extradata_size == 36) {
2973  int channel_count = AV_RB8(st->codecpar->extradata + 21);
2974  if (st->codecpar->ch_layout.nb_channels != channel_count) {
2977  st->codecpar->ch_layout.nb_channels = channel_count;
2978  }
2979  st->codecpar->sample_rate = AV_RB32(st->codecpar->extradata + 32);
2980  }
2981  break;
2982  case AV_CODEC_ID_AC3:
2983  case AV_CODEC_ID_EAC3:
2985  case AV_CODEC_ID_VC1:
2986  case AV_CODEC_ID_VP8:
2987  case AV_CODEC_ID_VP9:
2989  break;
2990  case AV_CODEC_ID_APV:
2991  case AV_CODEC_ID_EVC:
2992  case AV_CODEC_ID_AV1:
2993  /* field_order detection of H264 requires parsing */
2994  case AV_CODEC_ID_H264:
2996  break;
2997  default:
2998  break;
2999  }
3000  return 0;
3001 }
3002 
3004  int codec_tag, int format,
3005  int64_t size)
3006 {
3007  if (codec_tag &&
3008  (codec_tag != format &&
3009  // AVID 1:1 samples with differing data format and codec tag exist
3010  (codec_tag != AV_RL32("AV1x") || format != AV_RL32("AVup")) &&
3011  // prores is allowed to have differing data format and codec tag
3012  codec_tag != AV_RL32("apcn") && codec_tag != AV_RL32("apch") &&
3013  // so is dv (sigh)
3014  codec_tag != AV_RL32("dvpp") && codec_tag != AV_RL32("dvcp") &&
3015  (c->fc->video_codec_id ? ff_codec_get_id(ff_codec_movvideo_tags, format) != c->fc->video_codec_id
3016  : codec_tag != MKTAG('j','p','e','g')))) {
3017  /* Multiple fourcc, we skip JPEG. This is not correct, we should
3018  * export it as a separate AVStream but this needs a few changes
3019  * in the MOV demuxer, patch welcome. */
3020 
3021  av_log(c->fc, AV_LOG_WARNING, "multiple fourcc not supported\n");
3022  avio_skip(pb, size);
3023  return 1;
3024  }
3025 
3026  return 0;
3027 }
3028 
3030 {
3031  AVStream *st;
3032  MOVStreamContext *sc;
3033  int pseudo_stream_id;
3034 
3035  av_assert0 (c->fc->nb_streams >= 1);
3036  st = c->fc->streams[c->fc->nb_streams-1];
3037  sc = st->priv_data;
3038 
3039  for (pseudo_stream_id = 0;
3040  pseudo_stream_id < entries && !pb->eof_reached;
3041  pseudo_stream_id++) {
3042  //Parsing Sample description table
3043  enum AVCodecID id;
3044  int ret, dref_id = 1;
3045  MOVAtom a = { AV_RL32("stsd") };
3046  int64_t start_pos = avio_tell(pb);
3047  int64_t size = avio_rb32(pb); /* size */
3048  uint32_t format = avio_rl32(pb); /* data format */
3049 
3050  if (size >= 16) {
3051  avio_rb32(pb); /* reserved */
3052  avio_rb16(pb); /* reserved */
3053  dref_id = avio_rb16(pb);
3054  } else if (size <= 7) {
3055  av_log(c->fc, AV_LOG_ERROR,
3056  "invalid size %"PRId64" in stsd\n", size);
3057  return AVERROR_INVALIDDATA;
3058  }
3059 
3061  size - (avio_tell(pb) - start_pos))) {
3062  sc->stsd_count++;
3063  continue;
3064  }
3065 
3066  sc->pseudo_stream_id = st->codecpar->codec_tag ? -1 : pseudo_stream_id;
3067  sc->dref_id= dref_id;
3068  sc->format = format;
3069 
3070  id = mov_codec_id(st, format);
3071 
3072  av_log(c->fc, AV_LOG_TRACE,
3073  "size=%"PRId64" 4CC=%s codec_type=%d\n", size,
3075 
3076  st->codecpar->codec_id = id;
3078  mov_parse_stsd_video(c, pb, st, sc);
3079  } else if (st->codecpar->codec_type==AVMEDIA_TYPE_AUDIO) {
3080  mov_parse_stsd_audio(c, pb, st, sc);
3081  if (st->codecpar->sample_rate < 0) {
3082  av_log(c->fc, AV_LOG_ERROR, "Invalid sample rate %d\n", st->codecpar->sample_rate);
3083  return AVERROR_INVALIDDATA;
3084  }
3085  if (st->codecpar->ch_layout.nb_channels < 0) {
3086  av_log(c->fc, AV_LOG_ERROR, "Invalid channels %d\n", st->codecpar->ch_layout.nb_channels);
3087  return AVERROR_INVALIDDATA;
3088  }
3089  } else if (st->codecpar->codec_type==AVMEDIA_TYPE_SUBTITLE){
3090  mov_parse_stsd_subtitle(c, pb, st, sc,
3091  size - (avio_tell(pb) - start_pos));
3092  } else {
3093  ret = mov_parse_stsd_data(c, pb, st, sc,
3094  size - (avio_tell(pb) - start_pos));
3095  if (ret < 0)
3096  return ret;
3097  }
3098  /* this will read extra atoms at the end (wave, alac, damr, avcC, hvcC, SMI ...) */
3099  a.size = size - (avio_tell(pb) - start_pos);
3100  if (a.size > 8) {
3101  if ((ret = mov_read_default(c, pb, a)) < 0)
3102  return ret;
3103  } else if (a.size > 0)
3104  avio_skip(pb, a.size);
3105 
3106  if (sc->extradata && st->codecpar->extradata) {
3107  int extra_size = st->codecpar->extradata_size;
3108 
3109  /* Move the current stream extradata to the stream context one. */
3110  sc->extradata_size[pseudo_stream_id] = extra_size;
3111  sc->extradata[pseudo_stream_id] = st->codecpar->extradata;
3112  st->codecpar->extradata = NULL;
3113  st->codecpar->extradata_size = 0;
3114  }
3115  sc->stsd_count++;
3116  }
3117 
3118  if (pb->eof_reached) {
3119  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSD atom\n");
3120  return AVERROR_EOF;
3121  }
3122 
3123  return 0;
3124 }
3125 
3127 {
3128  AVStream *st;
3129  MOVStreamContext *sc;
3130  int ret, entries;
3131 
3132  if (c->fc->nb_streams < 1)
3133  return 0;
3134  st = c->fc->streams[c->fc->nb_streams - 1];
3135  sc = st->priv_data;
3136 
3137  sc->stsd_version = avio_r8(pb);
3138  avio_rb24(pb); /* flags */
3139  entries = avio_rb32(pb);
3140 
3141  /* Each entry contains a size (4 bytes) and format (4 bytes). */
3142  if (entries <= 0 || entries > atom.size / 8 || entries > 1024) {
3143  av_log(c->fc, AV_LOG_ERROR, "invalid STSD entries %d\n", entries);
3144  return AVERROR_INVALIDDATA;
3145  }
3146 
3147  if (sc->extradata) {
3148  av_log(c->fc, AV_LOG_ERROR,
3149  "Duplicate stsd found in this track.\n");
3150  return AVERROR_INVALIDDATA;
3151  }
3152 
3153  /* Prepare space for hosting multiple extradata. */
3154  sc->extradata = av_calloc(entries, sizeof(*sc->extradata));
3155  if (!sc->extradata)
3156  return AVERROR(ENOMEM);
3157 
3158  sc->extradata_size = av_calloc(entries, sizeof(*sc->extradata_size));
3159  if (!sc->extradata_size) {
3160  ret = AVERROR(ENOMEM);
3161  goto fail;
3162  }
3163 
3164  ret = ff_mov_read_stsd_entries(c, pb, entries);
3165  if (ret < 0)
3166  goto fail;
3167 
3168  /* Restore back the primary extradata. */
3169  av_freep(&st->codecpar->extradata);
3170  st->codecpar->extradata_size = sc->extradata_size[0];
3171  if (sc->extradata_size[0]) {
3173  if (!st->codecpar->extradata)
3174  return AVERROR(ENOMEM);
3175  memcpy(st->codecpar->extradata, sc->extradata[0], sc->extradata_size[0]);
3176  }
3177 
3178  return mov_finalize_stsd_codec(c, pb, st, sc);
3179 fail:
3180  if (sc->extradata) {
3181  int j;
3182  for (j = 0; j < sc->stsd_count; j++)
3183  av_freep(&sc->extradata[j]);
3184  }
3185 
3186  av_freep(&sc->extradata);
3187  av_freep(&sc->extradata_size);
3188  return ret;
3189 }
3190 
3192 {
3193  AVStream *st;
3194  MOVStreamContext *sc;
3195  unsigned int i, entries;
3196 
3197  if (c->trak_index < 0) {
3198  av_log(c->fc, AV_LOG_WARNING, "STSC outside TRAK\n");
3199  return 0;
3200  }
3201 
3202  if (c->fc->nb_streams < 1)
3203  return 0;
3204  st = c->fc->streams[c->fc->nb_streams-1];
3205  sc = st->priv_data;
3206 
3207  avio_r8(pb); /* version */
3208  avio_rb24(pb); /* flags */
3209 
3210  entries = avio_rb32(pb);
3211  if ((uint64_t)entries * 12 + 4 > atom.size)
3212  return AVERROR_INVALIDDATA;
3213 
3214  av_log(c->fc, AV_LOG_TRACE, "track[%u].stsc.entries = %u\n", c->fc->nb_streams - 1, entries);
3215 
3216  if (!entries)
3217  return 0;
3218  if (sc->stsc_data) {
3219  av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicated STSC atom\n");
3220  return 0;
3221  }
3222  av_free(sc->stsc_data);
3223  sc->stsc_count = 0;
3224  sc->stsc_data = av_malloc_array(entries, sizeof(*sc->stsc_data));
3225  if (!sc->stsc_data)
3226  return AVERROR(ENOMEM);
3227 
3228  for (i = 0; i < entries && !pb->eof_reached; i++) {
3229  sc->stsc_data[i].first = avio_rb32(pb);
3230  sc->stsc_data[i].count = avio_rb32(pb);
3231  sc->stsc_data[i].id = avio_rb32(pb);
3232  }
3233 
3234  sc->stsc_count = i;
3235  for (i = sc->stsc_count - 1; i < UINT_MAX; i--) {
3236  int64_t first_min = i + 1;
3237  if ((i+1 < sc->stsc_count && sc->stsc_data[i].first >= sc->stsc_data[i+1].first) ||
3238  (i > 0 && sc->stsc_data[i].first <= sc->stsc_data[i-1].first) ||
3239  sc->stsc_data[i].first < first_min ||
3240  sc->stsc_data[i].count < 1 ||
3241  sc->stsc_data[i].id < 1) {
3242  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);
3243  if (i+1 >= sc->stsc_count) {
3244  if (sc->stsc_data[i].count == 0 && i > 0) {
3245  sc->stsc_count --;
3246  continue;
3247  }
3248  sc->stsc_data[i].first = FFMAX(sc->stsc_data[i].first, first_min);
3249  if (i > 0 && sc->stsc_data[i].first <= sc->stsc_data[i-1].first)
3250  sc->stsc_data[i].first = FFMIN(sc->stsc_data[i-1].first + 1LL, INT_MAX);
3251  sc->stsc_data[i].count = FFMAX(sc->stsc_data[i].count, 1);
3252  sc->stsc_data[i].id = FFMAX(sc->stsc_data[i].id, 1);
3253  continue;
3254  }
3255  av_assert0(sc->stsc_data[i+1].first >= 2);
3256  // We replace this entry by the next valid
3257  sc->stsc_data[i].first = sc->stsc_data[i+1].first - 1;
3258  sc->stsc_data[i].count = sc->stsc_data[i+1].count;
3259  sc->stsc_data[i].id = sc->stsc_data[i+1].id;
3260  }
3261  }
3262 
3263  if (pb->eof_reached) {
3264  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSC atom\n");
3265  return AVERROR_EOF;
3266  }
3267 
3268  return 0;
3269 }
3270 
3271 static inline int mov_stsc_index_valid(unsigned int index, unsigned int count)
3272 {
3273  return index < count - 1;
3274 }
3275 
3276 /* Compute the samples value for the stsc entry at the given index. */
3277 static inline int64_t mov_get_stsc_samples(MOVStreamContext *sc, unsigned int index)
3278 {
3279  int chunk_count;
3280 
3282  chunk_count = sc->stsc_data[index + 1].first - sc->stsc_data[index].first;
3283  else {
3284  // Validation for stsc / stco happens earlier in mov_read_stsc + mov_read_trak.
3286  chunk_count = sc->chunk_count - (sc->stsc_data[index].first - 1);
3287  }
3288 
3289  return sc->stsc_data[index].count * (int64_t)chunk_count;
3290 }
3291 
3293 {
3294  AVStream *st;
3295  MOVStreamContext *sc;
3296  unsigned i, entries;
3297 
3298  if (c->trak_index < 0) {
3299  av_log(c->fc, AV_LOG_WARNING, "STPS outside TRAK\n");
3300  return 0;
3301  }
3302 
3303  if (c->fc->nb_streams < 1)
3304  return 0;
3305  st = c->fc->streams[c->fc->nb_streams-1];
3306  sc = st->priv_data;
3307 
3308  avio_rb32(pb); // version + flags
3309 
3310  entries = avio_rb32(pb);
3311  if (sc->stps_data)
3312  av_log(c->fc, AV_LOG_WARNING, "Duplicated STPS atom\n");
3313  av_free(sc->stps_data);
3314  sc->stps_count = 0;
3315  sc->stps_data = av_malloc_array(entries, sizeof(*sc->stps_data));
3316  if (!sc->stps_data)
3317  return AVERROR(ENOMEM);
3318 
3319  for (i = 0; i < entries && !pb->eof_reached; i++) {
3320  sc->stps_data[i] = avio_rb32(pb);
3321  }
3322 
3323  sc->stps_count = i;
3324 
3325  if (pb->eof_reached) {
3326  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STPS atom\n");
3327  return AVERROR_EOF;
3328  }
3329 
3330  return 0;
3331 }
3332 
3334 {
3335  AVStream *st;
3336  FFStream *sti;
3337  MOVStreamContext *sc;
3338  unsigned int i, entries;
3339 
3340  if (c->trak_index < 0) {
3341  av_log(c->fc, AV_LOG_WARNING, "STSS outside TRAK\n");
3342  return 0;
3343  }
3344 
3345  if (c->fc->nb_streams < 1)
3346  return 0;
3347  st = c->fc->streams[c->fc->nb_streams-1];
3348  sti = ffstream(st);
3349  sc = st->priv_data;
3350 
3351  avio_r8(pb); /* version */
3352  avio_rb24(pb); /* flags */
3353 
3354  entries = avio_rb32(pb);
3355 
3356  av_log(c->fc, AV_LOG_TRACE, "keyframe_count = %u\n", entries);
3357 
3358  if (!entries) {
3359  sc->keyframe_absent = 1;
3360  if (!sti->need_parsing && st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
3362  return 0;
3363  }
3364  if (sc->keyframes)
3365  av_log(c->fc, AV_LOG_WARNING, "Duplicated STSS atom\n");
3366  if (entries >= UINT_MAX / sizeof(int))
3367  return AVERROR_INVALIDDATA;
3368  av_freep(&sc->keyframes);
3369  sc->keyframe_count = 0;
3370  sc->keyframes = av_malloc_array(entries, sizeof(*sc->keyframes));
3371  if (!sc->keyframes)
3372  return AVERROR(ENOMEM);
3373 
3374  for (i = 0; i < entries && !pb->eof_reached; i++) {
3375  sc->keyframes[i] = avio_rb32(pb);
3376  }
3377 
3378  sc->keyframe_count = i;
3379 
3380  if (pb->eof_reached) {
3381  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSS atom\n");
3382  return AVERROR_EOF;
3383  }
3384 
3385  return 0;
3386 }
3387 
3389 {
3390  AVStream *st;
3391  MOVStreamContext *sc;
3392  unsigned int i, entries, sample_size, field_size, num_bytes;
3393  GetBitContext gb;
3394  unsigned char* buf;
3395  int ret;
3396 
3397  if (c->trak_index < 0) {
3398  av_log(c->fc, AV_LOG_WARNING, "STSZ outside TRAK\n");
3399  return 0;
3400  }
3401 
3402  if (c->fc->nb_streams < 1)
3403  return 0;
3404  st = c->fc->streams[c->fc->nb_streams-1];
3405  sc = st->priv_data;
3406 
3407  avio_r8(pb); /* version */
3408  avio_rb24(pb); /* flags */
3409 
3410  if (atom.type == MKTAG('s','t','s','z')) {
3411  sample_size = avio_rb32(pb);
3412  if (!sc->sample_size) /* do not overwrite value computed in stsd */
3413  sc->sample_size = sample_size;
3414  sc->stsz_sample_size = sample_size;
3415  field_size = 32;
3416  } else {
3417  sample_size = 0;
3418  avio_rb24(pb); /* reserved */
3419  field_size = avio_r8(pb);
3420  }
3421  entries = avio_rb32(pb);
3422 
3423  av_log(c->fc, AV_LOG_TRACE, "sample_size = %u sample_count = %u\n", sc->sample_size, entries);
3424 
3425  sc->sample_count = entries;
3426  if (sample_size)
3427  return 0;
3428 
3429  if (field_size != 4 && field_size != 8 && field_size != 16 && field_size != 32) {
3430  av_log(c->fc, AV_LOG_ERROR, "Invalid sample field size %u\n", field_size);
3431  return AVERROR_INVALIDDATA;
3432  }
3433 
3434  if (!entries)
3435  return 0;
3436  if (entries >= (INT_MAX - 4 - 8 * AV_INPUT_BUFFER_PADDING_SIZE) / field_size)
3437  return AVERROR_INVALIDDATA;
3438  if (sc->sample_sizes)
3439  av_log(c->fc, AV_LOG_WARNING, "Duplicated STSZ atom\n");
3440  av_free(sc->sample_sizes);
3441  sc->sample_count = 0;
3442  sc->sample_sizes = av_malloc_array(entries, sizeof(*sc->sample_sizes));
3443  if (!sc->sample_sizes)
3444  return AVERROR(ENOMEM);
3445 
3446  num_bytes = (entries*field_size+4)>>3;
3447 
3448  buf = av_malloc(num_bytes+AV_INPUT_BUFFER_PADDING_SIZE);
3449  if (!buf) {
3450  av_freep(&sc->sample_sizes);
3451  return AVERROR(ENOMEM);
3452  }
3453 
3454  ret = ffio_read_size(pb, buf, num_bytes);
3455  if (ret < 0) {
3456  av_freep(&sc->sample_sizes);
3457  av_free(buf);
3458  av_log(c->fc, AV_LOG_WARNING, "STSZ atom truncated\n");
3459  return 0;
3460  }
3461 
3462  init_get_bits(&gb, buf, 8*num_bytes);
3463 
3464  for (i = 0; i < entries; i++) {
3465  sc->sample_sizes[i] = get_bits_long(&gb, field_size);
3466  if (sc->sample_sizes[i] > INT64_MAX - sc->data_size) {
3467  av_free(buf);
3468  av_log(c->fc, AV_LOG_ERROR, "Sample size overflow in STSZ\n");
3469  return AVERROR_INVALIDDATA;
3470  }
3471  sc->data_size += sc->sample_sizes[i];
3472  }
3473 
3474  sc->sample_count = i;
3475 
3476  av_free(buf);
3477 
3478  return 0;
3479 }
3480 
3482 {
3483  AVStream *st;
3484  MOVStreamContext *sc;
3485  unsigned int i, entries;
3486  int64_t duration = 0;
3487  int64_t total_sample_count = 0;
3488  int64_t current_dts = 0;
3489  int64_t corrected_dts = 0;
3490 
3491  if (c->trak_index < 0) {
3492  av_log(c->fc, AV_LOG_WARNING, "STTS outside TRAK\n");
3493  return 0;
3494  }
3495 
3496  if (c->fc->nb_streams < 1)
3497  return 0;
3498  st = c->fc->streams[c->fc->nb_streams-1];
3499  sc = st->priv_data;
3500 
3501  avio_r8(pb); /* version */
3502  avio_rb24(pb); /* flags */
3503  entries = avio_rb32(pb);
3504 
3505  av_log(c->fc, AV_LOG_TRACE, "track[%u].stts.entries = %u\n",
3506  c->fc->nb_streams-1, entries);
3507 
3508  if (sc->stts_data)
3509  av_log(c->fc, AV_LOG_WARNING, "Duplicated STTS atom\n");
3510  av_freep(&sc->stts_data);
3511  sc->stts_count = 0;
3512  if (entries >= INT_MAX / sizeof(*sc->stts_data))
3513  return AVERROR(ENOMEM);
3514 
3515  for (i = 0; i < entries && !pb->eof_reached; i++) {
3516  unsigned int sample_duration;
3517  unsigned int sample_count;
3518  unsigned int min_entries = FFMIN(FFMAX(i + 1, 1024 * 1024), entries);
3519  MOVStts *stts_data = av_fast_realloc(sc->stts_data, &sc->stts_allocated_size,
3520  min_entries * sizeof(*sc->stts_data));
3521  if (!stts_data) {
3522  av_freep(&sc->stts_data);
3523  sc->stts_count = 0;
3524  return AVERROR(ENOMEM);
3525  }
3526  sc->stts_count = min_entries;
3527  sc->stts_data = stts_data;
3528 
3529  sample_count = avio_rb32(pb);
3530  sample_duration = avio_rb32(pb);
3531 
3532  sc->stts_data[i].count= sample_count;
3533  sc->stts_data[i].duration= sample_duration;
3534 
3535  av_log(c->fc, AV_LOG_TRACE, "sample_count=%u, sample_duration=%u\n",
3536  sample_count, sample_duration);
3537 
3538  /* STTS sample offsets are uint32 but some files store it as int32
3539  * with negative values used to correct DTS delays.
3540  There may be abnormally large values as well. */
3541  if (sample_duration > c->max_stts_delta) {
3542  // assume high delta is a correction if negative when cast as int32
3543  int32_t delta_magnitude = (int32_t)sample_duration;
3544  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",
3545  sample_duration, i, sample_count, st->index);
3546  sc->stts_data[i].duration = 1;
3547  corrected_dts = av_sat_add64(corrected_dts, (delta_magnitude < 0 ? (int64_t)delta_magnitude : 1) * sample_count);
3548  } else {
3549  corrected_dts += sample_duration * (uint64_t)sample_count;
3550  }
3551 
3552  current_dts += sc->stts_data[i].duration * (uint64_t)sample_count;
3553 
3554  if (current_dts > corrected_dts) {
3555  int64_t drift = av_sat_sub64(current_dts, corrected_dts) / FFMAX(sample_count, 1);
3556  uint32_t correction = (sc->stts_data[i].duration > drift) ? drift : sc->stts_data[i].duration - 1;
3557  current_dts -= correction * (uint64_t)sample_count;
3558  sc->stts_data[i].duration -= correction;
3559  }
3560 
3561  duration+=(int64_t)sc->stts_data[i].duration*(uint64_t)sc->stts_data[i].count;
3562  total_sample_count+=sc->stts_data[i].count;
3563  }
3564 
3565  sc->stts_count = i;
3566 
3567  if (duration > 0 &&
3568  duration <= INT64_MAX - sc->duration_for_fps &&
3569  total_sample_count <= INT_MAX - sc->nb_frames_for_fps) {
3570  sc->duration_for_fps += duration;
3571  sc->nb_frames_for_fps += total_sample_count;
3572  }
3573 
3574  if (pb->eof_reached) {
3575  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STTS atom\n");
3576  return AVERROR_EOF;
3577  }
3578 
3579  st->nb_frames= total_sample_count;
3580  if (duration)
3581  st->duration= FFMIN(st->duration, duration);
3582 
3583  // All samples have zero duration. They have higher chance be chose by
3584  // mov_find_next_sample, which leads to seek again and again.
3585  //
3586  // It's AVERROR_INVALIDDATA actually, but such files exist in the wild.
3587  // So only mark data stream as discarded for safety.
3588  if (!duration && sc->stts_count &&
3590  av_log(c->fc, AV_LOG_WARNING,
3591  "All samples in data stream index:id [%d:%d] have zero "
3592  "duration, stream set to be discarded by default. Override "
3593  "using AVStream->discard or -discard for ffmpeg command.\n",
3594  st->index, sc->id);
3595  st->discard = AVDISCARD_ALL;
3596  }
3597  sc->track_end = duration;
3598  return 0;
3599 }
3600 
3602 {
3603  AVStream *st;
3604  MOVStreamContext *sc;
3605  int64_t i, entries;
3606 
3607  if (c->fc->nb_streams < 1)
3608  return 0;
3609  st = c->fc->streams[c->fc->nb_streams - 1];
3610  sc = st->priv_data;
3611 
3612  avio_r8(pb); /* version */
3613  avio_rb24(pb); /* flags */
3614  entries = atom.size - 4;
3615 
3616  av_log(c->fc, AV_LOG_TRACE, "track[%u].sdtp.entries = %" PRId64 "\n",
3617  c->fc->nb_streams - 1, entries);
3618 
3619  if (sc->sdtp_data)
3620  av_log(c->fc, AV_LOG_WARNING, "Duplicated SDTP atom\n");
3621  av_freep(&sc->sdtp_data);
3622  sc->sdtp_count = 0;
3623 
3624  sc->sdtp_data = av_malloc(entries);
3625  if (!sc->sdtp_data)
3626  return AVERROR(ENOMEM);
3627 
3628  for (i = 0; i < entries && !pb->eof_reached; i++)
3629  sc->sdtp_data[i] = avio_r8(pb);
3630  sc->sdtp_count = i;
3631 
3632  return 0;
3633 }
3634 
3635 static void mov_update_dts_shift(MOVStreamContext *sc, int duration, void *logctx)
3636 {
3637  if (duration < 0) {
3638  if (duration == INT_MIN) {
3639  av_log(logctx, AV_LOG_WARNING, "mov_update_dts_shift(): dts_shift set to %d\n", INT_MAX);
3640  duration++;
3641  }
3642  sc->dts_shift = FFMAX(sc->dts_shift, -duration);
3643  }
3644 }
3645 
3647 {
3648  AVStream *st;
3649  MOVStreamContext *sc;
3650  unsigned int i, entries, ctts_count = 0;
3651 
3652  if (c->trak_index < 0) {
3653  av_log(c->fc, AV_LOG_WARNING, "CTTS outside TRAK\n");
3654  return 0;
3655  }
3656 
3657  if (c->fc->nb_streams < 1)
3658  return 0;
3659  st = c->fc->streams[c->fc->nb_streams-1];
3660  sc = st->priv_data;
3661 
3662  avio_r8(pb); /* version */
3663  avio_rb24(pb); /* flags */
3664  entries = avio_rb32(pb);
3665 
3666  av_log(c->fc, AV_LOG_TRACE, "track[%u].ctts.entries = %u\n", c->fc->nb_streams - 1, entries);
3667 
3668  if (!entries)
3669  return 0;
3670  if (entries >= UINT_MAX / sizeof(*sc->ctts_data))
3671  return AVERROR_INVALIDDATA;
3672  av_freep(&sc->ctts_data);
3673  sc->ctts_data = av_fast_realloc(NULL, &sc->ctts_allocated_size, entries * sizeof(*sc->ctts_data));
3674  if (!sc->ctts_data)
3675  return AVERROR(ENOMEM);
3676 
3677  for (i = 0; i < entries && !pb->eof_reached; i++) {
3678  MOVCtts *ctts_data;
3679  const size_t min_size_needed = (ctts_count + 1) * sizeof(MOVCtts);
3680  const size_t requested_size =
3681  min_size_needed > sc->ctts_allocated_size ?
3682  FFMAX(min_size_needed, 2 * sc->ctts_allocated_size) :
3683  min_size_needed;
3684  int count = avio_rb32(pb);
3685  int duration = avio_rb32(pb);
3686 
3687  if (count <= 0) {
3688  av_log(c->fc, AV_LOG_TRACE,
3689  "ignoring CTTS entry with count=%d duration=%d\n",
3690  count, duration);
3691  continue;
3692  }
3693 
3694  if (ctts_count >= UINT_MAX / sizeof(MOVCtts) - 1)
3695  return AVERROR(ENOMEM);
3696 
3697  ctts_data = av_fast_realloc(sc->ctts_data, &sc->ctts_allocated_size, requested_size);
3698 
3699  if (!ctts_data)
3700  return AVERROR(ENOMEM);
3701 
3702  sc->ctts_data = ctts_data;
3703 
3704  ctts_data[ctts_count].count = count;
3705  ctts_data[ctts_count].offset = duration;
3706  ctts_count++;
3707 
3708  av_log(c->fc, AV_LOG_TRACE, "count=%d, duration=%d\n",
3709  count, duration);
3710 
3711  if (i+2<entries)
3712  mov_update_dts_shift(sc, duration, c->fc);
3713  }
3714 
3715  sc->ctts_count = ctts_count;
3716 
3717  if (pb->eof_reached) {
3718  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted CTTS atom\n");
3719  return AVERROR_EOF;
3720  }
3721 
3722  av_log(c->fc, AV_LOG_TRACE, "dts shift %d\n", sc->dts_shift);
3723 
3724  return 0;
3725 }
3726 
3728 {
3729  AVStream *st;
3730  MOVStreamContext *sc;
3731  uint8_t version;
3732  uint32_t grouping_type;
3733  uint32_t default_length;
3734  av_unused uint32_t default_group_description_index;
3735  uint32_t entry_count;
3736 
3737  if (c->fc->nb_streams < 1)
3738  return 0;
3739  st = c->fc->streams[c->fc->nb_streams - 1];
3740  sc = st->priv_data;
3741 
3742  version = avio_r8(pb); /* version */
3743  avio_rb24(pb); /* flags */
3744  grouping_type = avio_rl32(pb);
3745 
3746  /*
3747  * This function only supports "sync" boxes, but the code is able to parse
3748  * other boxes (such as "tscl", "tsas" and "stsa")
3749  */
3750  if (grouping_type != MKTAG('s','y','n','c'))
3751  return 0;
3752 
3753  default_length = version >= 1 ? avio_rb32(pb) : 0;
3754  default_group_description_index = version >= 2 ? avio_rb32(pb) : 0;
3755  entry_count = avio_rb32(pb);
3756 
3757  av_freep(&sc->sgpd_sync);
3758  sc->sgpd_sync_count = entry_count;
3759  sc->sgpd_sync = av_calloc(entry_count, sizeof(*sc->sgpd_sync));
3760  if (!sc->sgpd_sync)
3761  return AVERROR(ENOMEM);
3762 
3763  for (uint32_t i = 0; i < entry_count && !pb->eof_reached; i++) {
3764  uint32_t description_length = default_length;
3765  if (version >= 1 && default_length == 0)
3766  description_length = avio_rb32(pb);
3767  if (grouping_type == MKTAG('s','y','n','c')) {
3768  const uint8_t nal_unit_type = avio_r8(pb) & 0x3f;
3769  sc->sgpd_sync[i] = nal_unit_type;
3770  description_length -= 1;
3771  }
3772  avio_skip(pb, description_length);
3773  }
3774 
3775  if (pb->eof_reached) {
3776  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted SGPD atom\n");
3777  return AVERROR_EOF;
3778  }
3779 
3780  return 0;
3781 }
3782 
3784 {
3785  AVStream *st;
3786  MOVStreamContext *sc;
3787  unsigned int i, entries;
3788  uint8_t version;
3789  uint32_t grouping_type;
3790  MOVSbgp *table, **tablep;
3791  int *table_count;
3792 
3793  if (c->fc->nb_streams < 1)
3794  return 0;
3795  st = c->fc->streams[c->fc->nb_streams-1];
3796  sc = st->priv_data;
3797 
3798  version = avio_r8(pb); /* version */
3799  avio_rb24(pb); /* flags */
3800  grouping_type = avio_rl32(pb);
3801 
3802  if (grouping_type == MKTAG('r','a','p',' ')) {
3803  tablep = &sc->rap_group;
3804  table_count = &sc->rap_group_count;
3805  } else if (grouping_type == MKTAG('s','y','n','c')) {
3806  tablep = &sc->sync_group;
3807  table_count = &sc->sync_group_count;
3808  } else {
3809  return 0;
3810  }
3811 
3812  if (version == 1)
3813  avio_rb32(pb); /* grouping_type_parameter */
3814 
3815  entries = avio_rb32(pb);
3816  if (!entries)
3817  return 0;
3818  if (*tablep)
3819  av_log(c->fc, AV_LOG_WARNING, "Duplicated SBGP %s atom\n", av_fourcc2str(grouping_type));
3820  av_freep(tablep);
3821  table = av_malloc_array(entries, sizeof(*table));
3822  if (!table)
3823  return AVERROR(ENOMEM);
3824  *tablep = table;
3825 
3826  for (i = 0; i < entries && !pb->eof_reached; i++) {
3827  table[i].count = avio_rb32(pb); /* sample_count */
3828  table[i].index = avio_rb32(pb); /* group_description_index */
3829  }
3830 
3831  *table_count = i;
3832 
3833  if (pb->eof_reached) {
3834  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted SBGP atom\n");
3835  return AVERROR_EOF;
3836  }
3837 
3838  return 0;
3839 }
3840 
3841 /**
3842  * Get ith edit list entry (media time, duration).
3843  */
3845  const MOVStreamContext *msc,
3846  unsigned int edit_list_index,
3847  int64_t *edit_list_media_time,
3848  int64_t *edit_list_duration,
3849  int64_t global_timescale)
3850 {
3851  if (edit_list_index == msc->elst_count) {
3852  return 0;
3853  }
3854  *edit_list_media_time = msc->elst_data[edit_list_index].time;
3855  *edit_list_duration = msc->elst_data[edit_list_index].duration;
3856 
3857  /* duration is in global timescale units;convert to msc timescale */
3858  if (global_timescale == 0) {
3859  avpriv_request_sample(mov->fc, "Support for mvhd.timescale = 0 with editlists");
3860  return 0;
3861  }
3862  *edit_list_duration = av_rescale(*edit_list_duration, msc->time_scale,
3863  global_timescale);
3864 
3865  if (*edit_list_duration + (uint64_t)*edit_list_media_time > INT64_MAX)
3866  *edit_list_duration = 0;
3867 
3868  return 1;
3869 }
3870 
3871 /**
3872  * Find the closest previous frame to the timestamp_pts, in e_old index
3873  * entries. Searching for just any frame / just key frames can be controlled by
3874  * last argument 'flag'.
3875  * Note that if ctts_data is not NULL, we will always search for a key frame
3876  * irrespective of the value of 'flag'. If we don't find any keyframe, we will
3877  * return the first frame of the video.
3878  *
3879  * Here the timestamp_pts is considered to be a presentation timestamp and
3880  * the timestamp of index entries are considered to be decoding timestamps.
3881  *
3882  * Returns 0 if successful in finding a frame, else returns -1.
3883  * Places the found index corresponding output arg.
3884  *
3885  * If ctts_old is not NULL, then refines the searched entry by searching
3886  * backwards from the found timestamp, to find the frame with correct PTS.
3887  *
3888  * Places the found ctts_index and ctts_sample in corresponding output args.
3889  */
3891  AVIndexEntry *e_old,
3892  int nb_old,
3893  MOVTimeToSample *tts_data,
3894  int64_t tts_count,
3895  int64_t timestamp_pts,
3896  int flag,
3897  int64_t* index,
3898  int64_t* tts_index,
3899  int64_t* tts_sample)
3900 {
3901  MOVStreamContext *msc = st->priv_data;
3902  FFStream *const sti = ffstream(st);
3903  AVIndexEntry *e_keep = sti->index_entries;
3904  int nb_keep = sti->nb_index_entries;
3905  int64_t i = 0;
3906 
3907  av_assert0(index);
3908 
3909  // If dts_shift > 0, then all the index timestamps will have to be offset by
3910  // at least dts_shift amount to obtain PTS.
3911  // Hence we decrement the searched timestamp_pts by dts_shift to find the closest index element.
3912  if (msc->dts_shift > 0) {
3913  timestamp_pts -= msc->dts_shift;
3914  }
3915 
3916  sti->index_entries = e_old;
3917  sti->nb_index_entries = nb_old;
3918  *index = av_index_search_timestamp(st, timestamp_pts, flag | AVSEEK_FLAG_BACKWARD);
3919 
3920  // Keep going backwards in the index entries until the timestamp is the same.
3921  if (*index >= 0) {
3922  for (i = *index; i > 0 && e_old[i].timestamp == e_old[i - 1].timestamp;
3923  i--) {
3924  if ((flag & AVSEEK_FLAG_ANY) ||
3925  (e_old[i - 1].flags & AVINDEX_KEYFRAME)) {
3926  *index = i - 1;
3927  }
3928  }
3929  }
3930 
3931  // If we have CTTS then refine the search, by searching backwards over PTS
3932  // computed by adding corresponding CTTS durations to index timestamps.
3933  if (msc->ctts_count && *index >= 0) {
3934  av_assert0(tts_index);
3935  av_assert0(tts_sample);
3936  // Find out the ctts_index for the found frame.
3937  *tts_index = 0;
3938  *tts_sample = 0;
3939  for (int64_t index_tts_count = 0; index_tts_count < *index; index_tts_count++) {
3940  if (*tts_index < tts_count) {
3941  (*tts_sample)++;
3942  if (tts_data[*tts_index].count == *tts_sample) {
3943  (*tts_index)++;
3944  *tts_sample = 0;
3945  }
3946  }
3947  }
3948 
3949  while (*index >= 0 && (*tts_index) >= 0 && (*tts_index) < tts_count) {
3950  // Find a "key frame" with PTS <= timestamp_pts (So that we can decode B-frames correctly).
3951  // No need to add dts_shift to the timestamp here becase timestamp_pts has already been
3952  // compensated by dts_shift above.
3953  if ((e_old[*index].timestamp + tts_data[*tts_index].offset) <= timestamp_pts &&
3954  (e_old[*index].flags & AVINDEX_KEYFRAME)) {
3955  break;
3956  }
3957 
3958  (*index)--;
3959  if (*tts_sample == 0) {
3960  (*tts_index)--;
3961  if (*tts_index >= 0)
3962  *tts_sample = tts_data[*tts_index].count - 1;
3963  } else {
3964  (*tts_sample)--;
3965  }
3966  }
3967  }
3968 
3969  /* restore AVStream state*/
3970  sti->index_entries = e_keep;
3971  sti->nb_index_entries = nb_keep;
3972  return *index >= 0 ? 0 : -1;
3973 }
3974 
3975 /**
3976  * Add index entry with the given values, to the end of ffstream(st)->index_entries.
3977  * Returns the new size ffstream(st)->index_entries if successful, else returns -1.
3978  *
3979  * This function is similar to ff_add_index_entry in libavformat/utils.c
3980  * except that here we are always unconditionally adding an index entry to
3981  * the end, instead of searching the entries list and skipping the add if
3982  * there is an existing entry with the same timestamp.
3983  * This is needed because the mov_fix_index calls this func with the same
3984  * unincremented timestamp for successive discarded frames.
3985  */
3987  int size, int distance, int flags)
3988 {
3989  FFStream *const sti = ffstream(st);
3990  AVIndexEntry *entries, *ie;
3991  int64_t index = -1;
3992  const size_t min_size_needed = (sti->nb_index_entries + 1) * sizeof(AVIndexEntry);
3993 
3994  // Double the allocation each time, to lower memory fragmentation.
3995  // Another difference from ff_add_index_entry function.
3996  const size_t requested_size =
3997  min_size_needed > sti->index_entries_allocated_size ?
3998  FFMAX(min_size_needed, 2 * sti->index_entries_allocated_size) :
3999  min_size_needed;
4000 
4001  if (sti->nb_index_entries + 1U >= UINT_MAX / sizeof(AVIndexEntry))
4002  return -1;
4003 
4004  entries = av_fast_realloc(sti->index_entries,
4006  requested_size);
4007  if (!entries)
4008  return -1;
4009 
4010  sti->index_entries = entries;
4011 
4012  index = sti->nb_index_entries++;
4013  ie= &entries[index];
4014 
4015  ie->pos = pos;
4016  ie->timestamp = timestamp;
4017  ie->min_distance= distance;
4018  ie->size= size;
4019  ie->flags = flags;
4020  return index;
4021 }
4022 
4023 /**
4024  * Rewrite timestamps of index entries in the range [end_index - frame_duration_buffer_size, end_index)
4025  * by subtracting end_ts successively by the amounts given in frame_duration_buffer.
4026  */
4027 static void fix_index_entry_timestamps(AVStream* st, int end_index, int64_t end_ts,
4028  int64_t* frame_duration_buffer,
4029  int frame_duration_buffer_size) {
4030  FFStream *const sti = ffstream(st);
4031  int i = 0;
4032  av_assert0(end_index >= 0 && end_index <= sti->nb_index_entries);
4033  for (i = 0; i < frame_duration_buffer_size; i++) {
4034  end_ts -= frame_duration_buffer[frame_duration_buffer_size - 1 - i];
4035  sti->index_entries[end_index - 1 - i].timestamp = end_ts;
4036  }
4037 }
4038 
4039 static int add_tts_entry(MOVTimeToSample **tts_data, unsigned int *tts_count, unsigned int *allocated_size,
4040  int count, int offset, unsigned int duration)
4041 {
4042  MOVTimeToSample *tts_buf_new;
4043  const size_t min_size_needed = (*tts_count + 1) * sizeof(MOVTimeToSample);
4044  const size_t requested_size =
4045  min_size_needed > *allocated_size ?
4046  FFMAX(min_size_needed, 2 * (*allocated_size)) :
4047  min_size_needed;
4048 
4049  if ((unsigned)(*tts_count) >= UINT_MAX / sizeof(MOVTimeToSample) - 1)
4050  return -1;
4051 
4052  tts_buf_new = av_fast_realloc(*tts_data, allocated_size, requested_size);
4053 
4054  if (!tts_buf_new)
4055  return -1;
4056 
4057  *tts_data = tts_buf_new;
4058 
4059  tts_buf_new[*tts_count].count = count;
4060  tts_buf_new[*tts_count].offset = offset;
4061  tts_buf_new[*tts_count].duration = duration;
4062 
4063  *tts_count = (*tts_count) + 1;
4064  return 0;
4065 }
4066 
4067 #define MAX_REORDER_DELAY 16
4069 {
4070  MOVStreamContext *msc = st->priv_data;
4071  FFStream *const sti = ffstream(st);
4072  int ctts_ind = 0;
4073  int ctts_sample = 0;
4074  int64_t pts_buf[MAX_REORDER_DELAY + 1]; // Circular buffer to sort pts.
4075  int buf_start = 0;
4076  int j, r, num_swaps;
4077 
4078  for (j = 0; j < MAX_REORDER_DELAY + 1; j++)
4079  pts_buf[j] = INT64_MIN;
4080 
4081  if (st->codecpar->video_delay <= 0 && msc->ctts_count &&
4083  st->codecpar->video_delay = 0;
4084  for (int ind = 0; ind < sti->nb_index_entries && ctts_ind < msc->tts_count; ++ind) {
4085  // Point j to the last elem of the buffer and insert the current pts there.
4086  j = buf_start;
4087  buf_start = (buf_start + 1);
4088  if (buf_start == MAX_REORDER_DELAY + 1)
4089  buf_start = 0;
4090 
4091  pts_buf[j] = sti->index_entries[ind].timestamp + msc->tts_data[ctts_ind].offset;
4092 
4093  // The timestamps that are already in the sorted buffer, and are greater than the
4094  // current pts, are exactly the timestamps that need to be buffered to output PTS
4095  // in correct sorted order.
4096  // Hence the video delay (which is the buffer size used to sort DTS and output PTS),
4097  // can be computed as the maximum no. of swaps any particular timestamp needs to
4098  // go through, to keep this buffer in sorted order.
4099  num_swaps = 0;
4100  while (j != buf_start) {
4101  r = j - 1;
4102  if (r < 0) r = MAX_REORDER_DELAY;
4103  if (pts_buf[j] < pts_buf[r]) {
4104  FFSWAP(int64_t, pts_buf[j], pts_buf[r]);
4105  ++num_swaps;
4106  } else {
4107  break;
4108  }
4109  j = r;
4110  }
4111  st->codecpar->video_delay = FFMAX(st->codecpar->video_delay, num_swaps);
4112 
4113  ctts_sample++;
4114  if (ctts_sample == msc->tts_data[ctts_ind].count) {
4115  ctts_ind++;
4116  ctts_sample = 0;
4117  }
4118  }
4119  av_log(c->fc, AV_LOG_DEBUG, "Setting codecpar->delay to %d for stream st: %d\n",
4120  st->codecpar->video_delay, st->index);
4121  }
4122 }
4123 
4125 {
4126  sc->current_sample++;
4127  sc->current_index++;
4128  if (sc->index_ranges &&
4129  sc->current_index >= sc->current_index_range->end &&
4130  sc->current_index_range->end) {
4131  sc->current_index_range++;
4133  }
4134 }
4135 
4137 {
4138  sc->current_sample--;
4139  sc->current_index--;
4140  if (sc->index_ranges &&
4142  sc->current_index_range > sc->index_ranges) {
4143  sc->current_index_range--;
4144  sc->current_index = sc->current_index_range->end - 1;
4145  }
4146 }
4147 
4148 static void mov_current_sample_set(MOVStreamContext *sc, int current_sample)
4149 {
4150  int64_t range_size;
4151 
4152  sc->current_sample = current_sample;
4153  sc->current_index = current_sample;
4154  if (!sc->index_ranges) {
4155  return;
4156  }
4157 
4158  for (sc->current_index_range = sc->index_ranges;
4159  sc->current_index_range->end;
4160  sc->current_index_range++) {
4161  range_size = sc->current_index_range->end - sc->current_index_range->start;
4162  if (range_size > current_sample) {
4163  sc->current_index = sc->current_index_range->start + current_sample;
4164  break;
4165  }
4166  current_sample -= range_size;
4167  }
4168 }
4169 
4170 /**
4171  * Fix ffstream(st)->index_entries, so that it contains only the entries (and the entries
4172  * which are needed to decode them) that fall in the edit list time ranges.
4173  * Also fixes the timestamps of the index entries to match the timeline
4174  * specified the edit lists.
4175  */
4176 static void mov_fix_index(MOVContext *mov, AVStream *st)
4177 {
4178  MOVStreamContext *msc = st->priv_data;
4179  FFStream *const sti = ffstream(st);
4180  AVIndexEntry *e_old = sti->index_entries;
4181  int nb_old = sti->nb_index_entries;
4182  const AVIndexEntry *e_old_end = e_old + nb_old;
4183  const AVIndexEntry *current = NULL;
4184  MOVTimeToSample *tts_data_old = msc->tts_data;
4185  int64_t tts_index_old = 0;
4186  int64_t tts_sample_old = 0;
4187  int64_t tts_count_old = msc->tts_count;
4188  int64_t edit_list_media_time = 0;
4189  int64_t edit_list_duration = 0;
4190  int64_t frame_duration = 0;
4191  int64_t edit_list_dts_counter = 0;
4192  int64_t edit_list_dts_entry_end = 0;
4193  int64_t edit_list_start_tts_sample = 0;
4194  int64_t curr_cts;
4195  int64_t curr_ctts = 0;
4196  int64_t empty_edits_sum_duration = 0;
4197  int64_t edit_list_index = 0;
4198  int64_t index;
4199  int flags;
4200  int64_t start_dts = 0;
4201  int64_t edit_list_start_encountered = 0;
4202  int64_t search_timestamp = 0;
4203  int64_t* frame_duration_buffer = NULL;
4204  int num_discarded_begin = 0;
4205  int first_non_zero_audio_edit = -1;
4206  int packet_skip_samples = 0;
4207  MOVIndexRange *current_index_range = NULL;
4208  int found_keyframe_after_edit = 0;
4209  int found_non_empty_edit = 0;
4210 
4211  if (!msc->elst_data || msc->elst_count <= 0 || nb_old <= 0) {
4212  return;
4213  }
4214 
4215  // allocate the index ranges array
4216  msc->index_ranges = av_malloc_array(msc->elst_count + 1,
4217  sizeof(msc->index_ranges[0]));
4218  if (!msc->index_ranges) {
4219  av_log(mov->fc, AV_LOG_ERROR, "Cannot allocate index ranges buffer\n");
4220  return;
4221  }
4222  msc->current_index_range = msc->index_ranges;
4223 
4224  // Clean AVStream from traces of old index
4225  sti->index_entries = NULL;
4227  sti->nb_index_entries = 0;
4228 
4229  // Clean time to sample fields of MOVStreamContext
4230  msc->tts_data = NULL;
4231  msc->tts_count = 0;
4232  msc->tts_index = 0;
4233  msc->tts_sample = 0;
4234  msc->tts_allocated_size = 0;
4235 
4236  // Reinitialize min_corrected_pts so that it can be computed again.
4237  msc->min_corrected_pts = -1;
4238 
4239  // If the dts_shift is positive (in case of negative ctts values in mov),
4240  // then negate the DTS by dts_shift
4241  if (msc->dts_shift > 0) {
4242  edit_list_dts_entry_end -= msc->dts_shift;
4243  av_log(mov->fc, AV_LOG_DEBUG, "Shifting DTS by %d because of negative CTTS.\n", msc->dts_shift);
4244  }
4245 
4246  start_dts = edit_list_dts_entry_end;
4247 
4248  while (get_edit_list_entry(mov, msc, edit_list_index, &edit_list_media_time,
4249  &edit_list_duration, mov->time_scale)) {
4250  av_log(mov->fc, AV_LOG_DEBUG, "Processing st: %d, edit list %"PRId64" - media time: %"PRId64", duration: %"PRId64"\n",
4251  st->index, edit_list_index, edit_list_media_time, edit_list_duration);
4252  edit_list_index++;
4253  edit_list_dts_counter = edit_list_dts_entry_end;
4254  edit_list_dts_entry_end += edit_list_duration;
4255  num_discarded_begin = 0;
4256  if (!found_non_empty_edit && edit_list_media_time == -1) {
4257  empty_edits_sum_duration += edit_list_duration;
4258  continue;
4259  }
4260  found_non_empty_edit = 1;
4261 
4262  // If we encounter a non-negative edit list reset the skip_samples/start_pad fields and set them
4263  // according to the edit list below.
4264  if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
4265  if (first_non_zero_audio_edit < 0) {
4266  first_non_zero_audio_edit = 1;
4267  } else {
4268  first_non_zero_audio_edit = 0;
4269  }
4270 
4271  if (first_non_zero_audio_edit > 0)
4272  sti->skip_samples = msc->start_pad = 0;
4273  }
4274 
4275  // While reordering frame index according to edit list we must handle properly
4276  // the scenario when edit list entry starts from none key frame.
4277  // We find closest previous key frame and preserve it and consequent frames in index.
4278  // All frames which are outside edit list entry time boundaries will be dropped after decoding.
4279  search_timestamp = edit_list_media_time;
4280  if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
4281  // Audio decoders like AAC need need a decoder delay samples previous to the current sample,
4282  // to correctly decode this frame. Hence for audio we seek to a frame 1 sec. before the
4283  // edit_list_media_time to cover the decoder delay.
4284  search_timestamp = FFMAX(search_timestamp - msc->time_scale, e_old[0].timestamp);
4285  }
4286 
4287  if (find_prev_closest_index(st, e_old, nb_old, tts_data_old, tts_count_old, search_timestamp, 0,
4288  &index, &tts_index_old, &tts_sample_old) < 0) {
4289  av_log(mov->fc, AV_LOG_WARNING,
4290  "st: %d edit list: %"PRId64" Missing key frame while searching for timestamp: %"PRId64"\n",
4291  st->index, edit_list_index, search_timestamp);
4292  if (find_prev_closest_index(st, e_old, nb_old, tts_data_old, tts_count_old, search_timestamp, AVSEEK_FLAG_ANY,
4293  &index, &tts_index_old, &tts_sample_old) < 0) {
4294  av_log(mov->fc, AV_LOG_WARNING,
4295  "st: %d edit list %"PRId64" Cannot find an index entry before timestamp: %"PRId64".\n",
4296  st->index, edit_list_index, search_timestamp);
4297  index = 0;
4298  tts_index_old = 0;
4299  tts_sample_old = 0;
4300  }
4301  }
4302  current = e_old + index;
4303  edit_list_start_tts_sample = tts_sample_old;
4304 
4305  // Iterate over index and arrange it according to edit list
4306  edit_list_start_encountered = 0;
4307  found_keyframe_after_edit = 0;
4308  for (; current < e_old_end; current++, index++) {
4309  // check if frame outside edit list mark it for discard
4310  frame_duration = (current + 1 < e_old_end) ?
4311  ((current + 1)->timestamp - current->timestamp) : edit_list_duration;
4312 
4313  flags = current->flags;
4314 
4315  // frames (pts) before or after edit list
4316  curr_cts = current->timestamp + msc->dts_shift;
4317  curr_ctts = 0;
4318 
4319  if (tts_data_old && tts_index_old < tts_count_old) {
4320  curr_ctts = tts_data_old[tts_index_old].offset;
4321  av_log(mov->fc, AV_LOG_TRACE, "stts: %"PRId64" ctts: %"PRId64", tts_index: %"PRId64", tts_count: %"PRId64"\n",
4322  curr_cts, curr_ctts, tts_index_old, tts_count_old);
4323  curr_cts += curr_ctts;
4324  tts_sample_old++;
4325  if (tts_sample_old == tts_data_old[tts_index_old].count) {
4326  if (add_tts_entry(&msc->tts_data, &msc->tts_count,
4327  &msc->tts_allocated_size,
4328  tts_data_old[tts_index_old].count - edit_list_start_tts_sample,
4329  tts_data_old[tts_index_old].offset, tts_data_old[tts_index_old].duration) == -1) {
4330  av_log(mov->fc, AV_LOG_ERROR, "Cannot add Time To Sample entry %"PRId64" - {%"PRId64", %d}\n",
4331  tts_index_old,
4332  tts_data_old[tts_index_old].count - edit_list_start_tts_sample,
4333  tts_data_old[tts_index_old].offset);
4334  break;
4335  }
4336  tts_index_old++;
4337  tts_sample_old = 0;
4338  edit_list_start_tts_sample = 0;
4339  }
4340  }
4341 
4342  if (curr_cts < edit_list_media_time || curr_cts >= (edit_list_duration + edit_list_media_time)) {
4344  curr_cts < edit_list_media_time && curr_cts + frame_duration > edit_list_media_time &&
4345  first_non_zero_audio_edit > 0) {
4346  packet_skip_samples = edit_list_media_time - curr_cts;
4347  sti->skip_samples += packet_skip_samples;
4348 
4349  // Shift the index entry timestamp by packet_skip_samples to be correct.
4350  edit_list_dts_counter -= packet_skip_samples;
4351  if (edit_list_start_encountered == 0) {
4352  edit_list_start_encountered = 1;
4353  // Make timestamps strictly monotonically increasing for audio, by rewriting timestamps for
4354  // discarded packets.
4355  if (frame_duration_buffer) {
4356  fix_index_entry_timestamps(st, sti->nb_index_entries, edit_list_dts_counter,
4357  frame_duration_buffer, num_discarded_begin);
4358  av_freep(&frame_duration_buffer);
4359  }
4360  }
4361 
4362  av_log(mov->fc, AV_LOG_DEBUG, "skip %d audio samples from curr_cts: %"PRId64"\n", packet_skip_samples, curr_cts);
4363  } else {
4365  av_log(mov->fc, AV_LOG_DEBUG, "drop a frame at curr_cts: %"PRId64" @ %"PRId64"\n", curr_cts, index);
4366 
4367  if (edit_list_start_encountered == 0) {
4368  num_discarded_begin++;
4369  frame_duration_buffer = av_realloc(frame_duration_buffer,
4370  num_discarded_begin * sizeof(int64_t));
4371  if (!frame_duration_buffer) {
4372  av_log(mov->fc, AV_LOG_ERROR, "Cannot reallocate frame duration buffer\n");
4373  break;
4374  }
4375  frame_duration_buffer[num_discarded_begin - 1] = frame_duration;
4376 
4377  // Increment skip_samples for the first non-zero audio edit list
4378  if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
4379  first_non_zero_audio_edit > 0 && st->codecpar->codec_id != AV_CODEC_ID_VORBIS) {
4380  sti->skip_samples += frame_duration;
4381  }
4382  }
4383  }
4384  } else {
4385  if (msc->min_corrected_pts < 0) {
4386  msc->min_corrected_pts = edit_list_dts_counter + curr_ctts + msc->dts_shift;
4387  } else {
4388  msc->min_corrected_pts = FFMIN(msc->min_corrected_pts, edit_list_dts_counter + curr_ctts + msc->dts_shift);
4389  }
4390  if (edit_list_start_encountered == 0) {
4391  edit_list_start_encountered = 1;
4392  // Make timestamps strictly monotonically increasing by rewriting timestamps for
4393  // discarded packets.
4394  if (frame_duration_buffer) {
4395  fix_index_entry_timestamps(st, sti->nb_index_entries, edit_list_dts_counter,
4396  frame_duration_buffer, num_discarded_begin);
4397  av_freep(&frame_duration_buffer);
4398  }
4399  }
4400  }
4401 
4402  if (add_index_entry(st, current->pos, edit_list_dts_counter, current->size,
4403  current->min_distance, flags) == -1) {
4404  av_log(mov->fc, AV_LOG_ERROR, "Cannot add index entry\n");
4405  break;
4406  }
4407 
4408  // Update the index ranges array
4409  if (!current_index_range || index != current_index_range->end) {
4410  current_index_range = current_index_range ? current_index_range + 1
4411  : msc->index_ranges;
4412  current_index_range->start = index;
4413  }
4414  current_index_range->end = index + 1;
4415 
4416  // Only start incrementing DTS in frame_duration amounts, when we encounter a frame in edit list.
4417  if (edit_list_start_encountered > 0) {
4418  edit_list_dts_counter = edit_list_dts_counter + frame_duration;
4419  }
4420 
4421  // Break when found first key frame after edit entry completion
4422  if ((curr_cts + frame_duration >= (edit_list_duration + edit_list_media_time)) &&
4424  if (msc->ctts_count) {
4425  // If we have CTTS and this is the first keyframe after edit elist,
4426  // wait for one more, because there might be trailing B-frames after this I-frame
4427  // that do belong to the edit.
4428  if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO && found_keyframe_after_edit == 0) {
4429  found_keyframe_after_edit = 1;
4430  continue;
4431  }
4432  if (tts_sample_old != 0) {
4433  if (add_tts_entry(&msc->tts_data, &msc->tts_count,
4434  &msc->tts_allocated_size,
4435  tts_sample_old - edit_list_start_tts_sample,
4436  tts_data_old[tts_index_old].offset, tts_data_old[tts_index_old].duration) == -1) {
4437  av_log(mov->fc, AV_LOG_ERROR, "Cannot add Time To Sample entry %"PRId64" - {%"PRId64", %d}\n",
4438  tts_index_old, tts_sample_old - edit_list_start_tts_sample,
4439  tts_data_old[tts_index_old].offset);
4440  break;
4441  }
4442  }
4443  }
4444  break;
4445  }
4446  }
4447  }
4448  // If there are empty edits, then msc->min_corrected_pts might be positive
4449  // intentionally. So we subtract the sum duration of emtpy edits here.
4450  msc->min_corrected_pts -= empty_edits_sum_duration;
4451 
4452  // If the minimum pts turns out to be greater than zero after fixing the index, then we subtract the
4453  // dts by that amount to make the first pts zero.
4454  if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
4455  if (msc->min_corrected_pts > 0) {
4456  av_log(mov->fc, AV_LOG_DEBUG, "Offset DTS by %"PRId64" to make first pts zero.\n", msc->min_corrected_pts);
4457  for (int i = 0; i < sti->nb_index_entries; ++i)
4459  }
4460  }
4461  // Start time should be equal to zero or the duration of any empty edits.
4462  st->start_time = empty_edits_sum_duration;
4463 
4464  // Update av stream length, if it ends up shorter than the track's media duration
4465  st->duration = FFMIN(st->duration, edit_list_dts_entry_end - start_dts);
4466  msc->start_pad = sti->skip_samples;
4467 
4468  // Free the old index and the old CTTS structures
4469  av_free(e_old);
4470  av_free(tts_data_old);
4471  av_freep(&frame_duration_buffer);
4472 
4473  // Null terminate the index ranges array
4474  current_index_range = current_index_range ? current_index_range + 1
4475  : msc->index_ranges;
4476  current_index_range->start = 0;
4477  current_index_range->end = 0;
4478  msc->current_index = msc->index_ranges[0].start;
4479 }
4480 
4481 static uint32_t get_sgpd_sync_index(const MOVStreamContext *sc, int nal_unit_type)
4482 {
4483  for (uint32_t i = 0; i < sc->sgpd_sync_count; i++)
4484  if (sc->sgpd_sync[i] == nal_unit_type)
4485  return i + 1;
4486  return 0;
4487 }
4488 
4490 {
4491  int k;
4492  int sample_id = 0;
4493  uint32_t cra_index;
4494  MOVStreamContext *sc = st->priv_data;
4495 
4496  if (st->codecpar->codec_id != AV_CODEC_ID_HEVC || !sc->sync_group_count)
4497  return 0;
4498 
4499  /* Build an unrolled index of the samples */
4500  sc->sample_offsets_count = 0;
4501  for (uint32_t i = 0; i < sc->ctts_count; i++) {
4502  if (sc->ctts_data[i].count > INT_MAX - sc->sample_offsets_count)
4503  return AVERROR(ENOMEM);
4504  sc->sample_offsets_count += sc->ctts_data[i].count;
4505  }
4506  av_freep(&sc->sample_offsets);
4508  if (!sc->sample_offsets)
4509  return AVERROR(ENOMEM);
4510  k = 0;
4511  for (uint32_t i = 0; i < sc->ctts_count; i++)
4512  for (int j = 0; j < sc->ctts_data[i].count; j++)
4513  sc->sample_offsets[k++] = sc->ctts_data[i].offset;
4514 
4515  /* The following HEVC NAL type reveal the use of open GOP sync points
4516  * (TODO: BLA types may also be concerned) */
4517  cra_index = get_sgpd_sync_index(sc, HEVC_NAL_CRA_NUT); /* Clean Random Access */
4518  if (!cra_index)
4519  return 0;
4520 
4521  /* Build a list of open-GOP key samples */
4522  sc->open_key_samples_count = 0;
4523  for (uint32_t i = 0; i < sc->sync_group_count; i++)
4524  if (sc->sync_group[i].index == cra_index) {
4525  if (sc->sync_group[i].count > INT_MAX - sc->open_key_samples_count)
4526  return AVERROR(ENOMEM);
4528  }
4529  av_freep(&sc->open_key_samples);
4531  if (!sc->open_key_samples)
4532  return AVERROR(ENOMEM);
4533  k = 0;
4534  for (uint32_t i = 0; i < sc->sync_group_count; i++) {
4535  const MOVSbgp *sg = &sc->sync_group[i];
4536  if (sg->index == cra_index)
4537  for (uint32_t j = 0; j < sg->count; j++)
4538  sc->open_key_samples[k++] = sample_id;
4539  if (sg->count > INT_MAX - sample_id)
4540  return AVERROR_PATCHWELCOME;
4541  sample_id += sg->count;
4542  }
4543 
4544  /* Identify the minimal time step between samples */
4545  sc->min_sample_duration = UINT_MAX;
4546  for (uint32_t i = 0; i < sc->stts_count; i++)
4548 
4549  return 0;
4550 }
4551 
4552 #define MOV_MERGE_CTTS 1
4553 #define MOV_MERGE_STTS 2
4554 /*
4555  * Merge stts and ctts arrays into a new combined array.
4556  * stts_count and ctts_count may be left untouched as they will be
4557  * used to check for the presence of either of them.
4558  */
4559 static int mov_merge_tts_data(MOVContext *mov, AVStream *st, int flags)
4560 {
4561  MOVStreamContext *sc = st->priv_data;
4562  int ctts = sc->ctts_data && (flags & MOV_MERGE_CTTS);
4563  int stts = sc->stts_data && (flags & MOV_MERGE_STTS);
4564  int idx = 0;
4565 
4566  if (!sc->ctts_data && !sc->stts_data)
4567  return 0;
4568  // Expand time to sample entries such that we have a 1-1 mapping with samples
4569  if (!sc->sample_count || sc->sample_count >= UINT_MAX / sizeof(*sc->tts_data))
4570  return -1;
4571 
4572  if (ctts) {
4574  sc->sample_count * sizeof(*sc->tts_data));
4575  if (!sc->tts_data)
4576  return -1;
4577 
4578  memset(sc->tts_data, 0, sc->tts_allocated_size);
4579 
4580  for (int i = 0; i < sc->ctts_count &&
4581  idx < sc->sample_count; i++)
4582  for (int j = 0; j < sc->ctts_data[i].count &&
4583  idx < sc->sample_count; j++) {
4584  sc->tts_data[idx].offset = sc->ctts_data[i].offset;
4585  sc->tts_data[idx++].count = 1;
4586  }
4587 
4588  sc->tts_count = idx;
4589  } else
4590  sc->ctts_count = 0;
4591  av_freep(&sc->ctts_data);
4592  sc->ctts_allocated_size = 0;
4593 
4594  idx = 0;
4595  if (stts) {
4597  sc->sample_count * sizeof(*sc->tts_data));
4598  if (!tts_data)
4599  return -1;
4600 
4601  if (!sc->tts_data)
4602  memset(tts_data, 0, sc->tts_allocated_size);
4603  sc->tts_data = tts_data;
4604 
4605  for (int i = 0; i < sc->stts_count &&
4606  idx < sc->sample_count; i++)
4607  for (int j = 0; j < sc->stts_data[i].count &&
4608  idx < sc->sample_count; j++) {
4609  sc->tts_data[idx].duration = sc->stts_data[i].duration;
4610  sc->tts_data[idx++].count = 1;
4611  }
4612 
4613  sc->tts_count = FFMAX(sc->tts_count, idx);
4614  } else
4615  sc->stts_count = 0;
4616  av_freep(&sc->stts_data);
4617  sc->stts_allocated_size = 0;
4618 
4619  return 0;
4620 }
4621 
4622 static void mov_build_index(MOVContext *mov, AVStream *st)
4623 {
4624  MOVStreamContext *sc = st->priv_data;
4625  FFStream *const sti = ffstream(st);
4626  int64_t current_offset;
4627  int64_t current_dts = 0;
4628  unsigned int stts_index = 0;
4629  unsigned int stsc_index = 0;
4630  unsigned int stss_index = 0;
4631  unsigned int stps_index = 0;
4632  unsigned int i, j;
4633  uint64_t stream_size = 0;
4634 
4635  int ret = build_open_gop_key_points(st);
4636  if (ret < 0)
4637  return;
4638 
4639  if (sc->elst_count) {
4640  int i, edit_start_index = 0, multiple_edits = 0;
4641  int64_t empty_duration = 0; // empty duration of the first edit list entry
4642  int64_t start_time = 0; // start time of the media
4643 
4644  for (i = 0; i < sc->elst_count; i++) {
4645  const MOVElst *e = &sc->elst_data[i];
4646  if (i == 0 && e->time == -1) {
4647  /* if empty, the first entry is the start time of the stream
4648  * relative to the presentation itself */
4649  empty_duration = e->duration;
4650  edit_start_index = 1;
4651  } else if (i == edit_start_index && e->time >= 0) {
4652  start_time = e->time;
4653  } else {
4654  multiple_edits = 1;
4655  }
4656  }
4657 
4658  if (multiple_edits && !mov->advanced_editlist) {
4660  av_log(mov->fc, AV_LOG_WARNING, "multiple edit list entries, "
4661  "not supported in fragmented MP4 files\n");
4662  else
4663  av_log(mov->fc, AV_LOG_WARNING, "multiple edit list entries, "
4664  "Use -advanced_editlist to correctly decode otherwise "
4665  "a/v desync might occur\n");
4666  }
4667 
4668  /* adjust first dts according to edit list */
4669  if ((empty_duration || start_time) && mov->time_scale > 0) {
4670  if (empty_duration)
4671  empty_duration = av_rescale(empty_duration, sc->time_scale, mov->time_scale);
4672 
4673  if (av_sat_sub64(start_time, empty_duration) != start_time - (uint64_t)empty_duration)
4674  av_log(mov->fc, AV_LOG_WARNING, "start_time - empty_duration is not representable\n");
4675 
4676  sc->time_offset = start_time - (uint64_t)empty_duration;
4678  if (!mov->advanced_editlist)
4679  current_dts = -sc->time_offset;
4680  }
4681 
4682  if (!multiple_edits && !mov->advanced_editlist &&
4684  sc->start_pad = start_time;
4685  }
4686 
4687  /* only use old uncompressed audio chunk demuxing when stts specifies it */
4688  if (!(st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
4689  sc->stts_count == 1 && sc->stts_data && sc->stts_data[0].duration == 1)) {
4690  unsigned int current_sample = 0;
4691  unsigned int stts_sample = 0;
4692  unsigned int sample_size;
4693  unsigned int distance = 0;
4694  unsigned int rap_group_index = 0;
4695  unsigned int rap_group_sample = 0;
4696  int rap_group_present = sc->rap_group_count && sc->rap_group;
4697  int key_off = (sc->keyframe_count && sc->keyframes[0] > 0) || (sc->stps_count && sc->stps_data[0] > 0);
4698 
4699  current_dts -= sc->dts_shift;
4700 
4701  if (!sc->sample_count || sti->nb_index_entries || sc->tts_count)
4702  return;
4703  if (sc->sample_count >= UINT_MAX / sizeof(*sti->index_entries) - sti->nb_index_entries)
4704  return;
4705  if (av_reallocp_array(&sti->index_entries,
4706  sti->nb_index_entries + sc->sample_count,
4707  sizeof(*sti->index_entries)) < 0) {
4708  sti->nb_index_entries = 0;
4709  return;
4710  }
4711  sti->index_entries_allocated_size = (sti->nb_index_entries + sc->sample_count) * sizeof(*sti->index_entries);
4712 
4714  if (ret < 0)
4715  return;
4716 
4717  for (i = 0; i < sc->chunk_count; i++) {
4718  int64_t next_offset = i+1 < sc->chunk_count ? sc->chunk_offsets[i+1] : INT64_MAX;
4719  current_offset = sc->chunk_offsets[i];
4720  while (mov_stsc_index_valid(stsc_index, sc->stsc_count) &&
4721  i + 1 == sc->stsc_data[stsc_index + 1].first)
4722  stsc_index++;
4723 
4724  if (next_offset > current_offset && sc->sample_size>0 && sc->sample_size < sc->stsz_sample_size &&
4725  sc->stsc_data[stsc_index].count * (int64_t)sc->stsz_sample_size > next_offset - current_offset) {
4726  av_log(mov->fc, AV_LOG_WARNING, "STSZ sample size %d invalid (too large), ignoring\n", sc->stsz_sample_size);
4727  sc->stsz_sample_size = sc->sample_size;
4728  }
4729  if (sc->stsz_sample_size>0 && sc->stsz_sample_size < sc->sample_size) {
4730  av_log(mov->fc, AV_LOG_WARNING, "STSZ sample size %d invalid (too small), ignoring\n", sc->stsz_sample_size);
4731  sc->stsz_sample_size = sc->sample_size;
4732  }
4733 
4734  for (j = 0; j < sc->stsc_data[stsc_index].count; j++) {
4735  int keyframe = 0;
4736  if (current_sample >= sc->sample_count) {
4737  av_log(mov->fc, AV_LOG_ERROR, "wrong sample count\n");
4738  return;
4739  }
4740 
4741  if (!sc->keyframe_absent && (!sc->keyframe_count || current_sample+key_off == sc->keyframes[stss_index])) {
4742  keyframe = 1;
4743  if (stss_index + 1 < sc->keyframe_count)
4744  stss_index++;
4745  } else if (sc->stps_count && current_sample+key_off == sc->stps_data[stps_index]) {
4746  keyframe = 1;
4747  if (stps_index + 1 < sc->stps_count)
4748  stps_index++;
4749  }
4750  if (rap_group_present && rap_group_index < sc->rap_group_count) {
4751  if (sc->rap_group[rap_group_index].index > 0)
4752  keyframe = 1;
4753  if (++rap_group_sample == sc->rap_group[rap_group_index].count) {
4754  rap_group_sample = 0;
4755  rap_group_index++;
4756  }
4757  }
4758  if (sc->keyframe_absent
4759  && !sc->stps_count
4760  && !rap_group_present
4761  && (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO || (i==0 && j==0)))
4762  keyframe = 1;
4763  if (keyframe)
4764  distance = 0;
4765  sample_size = sc->stsz_sample_size > 0 ? sc->stsz_sample_size : sc->sample_sizes[current_sample];
4766  if (current_offset > INT64_MAX - sample_size) {
4767  av_log(mov->fc, AV_LOG_ERROR, "Current offset %"PRId64" or sample size %u is too large\n",
4768  current_offset,
4769  sample_size);
4770  return;
4771  }
4772 
4773  if (sc->pseudo_stream_id == -1 ||
4774  sc->stsc_data[stsc_index].id - 1 == sc->pseudo_stream_id) {
4775  AVIndexEntry *e;
4776  if (sample_size > 0x3FFFFFFF) {
4777  av_log(mov->fc, AV_LOG_ERROR, "Sample size %u is too large\n", sample_size);
4778  return;
4779  }
4780  e = &sti->index_entries[sti->nb_index_entries++];
4781  e->pos = current_offset;
4782  e->timestamp = current_dts;
4783  e->size = sample_size;
4784  e->min_distance = distance;
4785  e->flags = keyframe ? AVINDEX_KEYFRAME : 0;
4786  av_log(mov->fc, AV_LOG_TRACE, "AVIndex stream %d, sample %u, offset %"PRIx64", dts %"PRId64", "
4787  "size %u, distance %u, keyframe %d\n", st->index, current_sample,
4788  current_offset, current_dts, sample_size, distance, keyframe);
4789  if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && sti->nb_index_entries < 100)
4790  ff_rfps_add_frame(mov->fc, st, current_dts);
4791  }
4792 
4793  current_offset += sample_size;
4794  stream_size += sample_size;
4795 
4796  current_dts += sc->tts_data[stts_index].duration;
4797 
4798  distance++;
4799  stts_sample++;
4800  current_sample++;
4801  if (stts_index + 1 < sc->tts_count && stts_sample == sc->tts_data[stts_index].count) {
4802  stts_sample = 0;
4803  stts_index++;
4804  }
4805  }
4806  }
4807  if (st->duration > 0)
4808  st->codecpar->bit_rate = stream_size*8*sc->time_scale/st->duration;
4809  } else {
4810  unsigned chunk_samples, total = 0;
4811 
4812  if (!sc->chunk_count || sc->tts_count)
4813  return;
4814 
4816  if (ret < 0)
4817  return;
4818 
4819  // compute total chunk count
4820  for (i = 0; i < sc->stsc_count; i++) {
4821  unsigned count, chunk_count;
4822 
4823  chunk_samples = sc->stsc_data[i].count;
4824  if (i != sc->stsc_count - 1 &&
4825  sc->samples_per_frame && chunk_samples % sc->samples_per_frame) {
4826  av_log(mov->fc, AV_LOG_ERROR, "error unaligned chunk\n");
4827  return;
4828  }
4829 
4830  if (sc->samples_per_frame >= 160) { // gsm
4831  count = chunk_samples / sc->samples_per_frame;
4832  } else if (sc->samples_per_frame > 1) {
4833  unsigned samples = (1024/sc->samples_per_frame)*sc->samples_per_frame;
4834  count = (chunk_samples+samples-1) / samples;
4835  } else {
4836  count = (chunk_samples+1023) / 1024;
4837  }
4838 
4839  if (mov_stsc_index_valid(i, sc->stsc_count))
4840  chunk_count = sc->stsc_data[i+1].first - sc->stsc_data[i].first;
4841  else
4842  chunk_count = sc->chunk_count - (sc->stsc_data[i].first - 1);
4843  total += chunk_count * count;
4844  }
4845 
4846  av_log(mov->fc, AV_LOG_TRACE, "chunk count %u\n", total);
4847  if (total >= UINT_MAX / sizeof(*sti->index_entries) - sti->nb_index_entries)
4848  return;
4849  if (av_reallocp_array(&sti->index_entries,
4850  sti->nb_index_entries + total,
4851  sizeof(*sti->index_entries)) < 0) {
4852  sti->nb_index_entries = 0;
4853  return;
4854  }
4855  sti->index_entries_allocated_size = (sti->nb_index_entries + total) * sizeof(*sti->index_entries);
4856 
4857  // populate index
4858  for (i = 0; i < sc->chunk_count; i++) {
4859  current_offset = sc->chunk_offsets[i];
4860  if (mov_stsc_index_valid(stsc_index, sc->stsc_count) &&
4861  i + 1 == sc->stsc_data[stsc_index + 1].first)
4862  stsc_index++;
4863  chunk_samples = sc->stsc_data[stsc_index].count;
4864 
4865  while (chunk_samples > 0) {
4866  AVIndexEntry *e;
4867  unsigned size, samples;
4868 
4869  if (sc->samples_per_frame > 1 && !sc->bytes_per_frame) {
4871  "Zero bytes per frame, but %d samples per frame",
4872  sc->samples_per_frame);
4873  return;
4874  }
4875 
4876  if (sc->samples_per_frame >= 160) { // gsm
4877  samples = sc->samples_per_frame;
4878  size = sc->bytes_per_frame;
4879  } else {
4880  if (sc->samples_per_frame > 1) {
4881  samples = FFMIN((1024 / sc->samples_per_frame)*
4882  sc->samples_per_frame, chunk_samples);
4884  } else {
4885  samples = FFMIN(1024, chunk_samples);
4886  size = samples * sc->sample_size;
4887  }
4888  }
4889 
4890  if (sti->nb_index_entries >= total) {
4891  av_log(mov->fc, AV_LOG_ERROR, "wrong chunk count %u\n", total);
4892  return;
4893  }
4894  if (size > 0x3FFFFFFF) {
4895  av_log(mov->fc, AV_LOG_ERROR, "Sample size %u is too large\n", size);
4896  return;
4897  }
4898  e = &sti->index_entries[sti->nb_index_entries++];
4899  e->pos = current_offset;
4900  e->timestamp = current_dts;
4901  e->size = size;
4902  e->min_distance = 0;
4903  e->flags = AVINDEX_KEYFRAME;
4904  av_log(mov->fc, AV_LOG_TRACE, "AVIndex stream %d, chunk %u, offset %"PRIx64", dts %"PRId64", "
4905  "size %u, duration %u\n", st->index, i, current_offset, current_dts,
4906  size, samples);
4907 
4908  current_offset += size;
4909  current_dts += samples;
4910  chunk_samples -= samples;
4911  }
4912  }
4913  }
4914 
4915  if (!mov->ignore_editlist && mov->advanced_editlist) {
4916  // Fix index according to edit lists.
4917  mov_fix_index(mov, st);
4918  }
4919 
4920  // Update start time of the stream.
4922  st->start_time = sti->index_entries[0].timestamp + sc->dts_shift;
4923  if (sc->tts_data) {
4924  st->start_time += sc->tts_data[0].offset;
4925  }
4926  }
4927 
4928  mov_estimate_video_delay(mov, st);
4929 }
4930 
4931 static int test_same_origin(const char *src, const char *ref) {
4932  char src_proto[64];
4933  char ref_proto[64];
4934  char src_auth[256];
4935  char ref_auth[256];
4936  char src_host[256];
4937  char ref_host[256];
4938  int src_port=-1;
4939  int ref_port=-1;
4940 
4941  av_url_split(src_proto, sizeof(src_proto), src_auth, sizeof(src_auth), src_host, sizeof(src_host), &src_port, NULL, 0, src);
4942  av_url_split(ref_proto, sizeof(ref_proto), ref_auth, sizeof(ref_auth), ref_host, sizeof(ref_host), &ref_port, NULL, 0, ref);
4943 
4944  if (strlen(src) == 0) {
4945  return -1;
4946  } else if (strlen(src_auth) + 1 >= sizeof(src_auth) ||
4947  strlen(ref_auth) + 1 >= sizeof(ref_auth) ||
4948  strlen(src_host) + 1 >= sizeof(src_host) ||
4949  strlen(ref_host) + 1 >= sizeof(ref_host)) {
4950  return 0;
4951  } else if (strcmp(src_proto, ref_proto) ||
4952  strcmp(src_auth, ref_auth) ||
4953  strcmp(src_host, ref_host) ||
4954  src_port != ref_port) {
4955  return 0;
4956  } else
4957  return 1;
4958 }
4959 
4960 static int mov_open_dref(MOVContext *c, AVIOContext **pb, const char *src, MOVDref *ref)
4961 {
4962  /* try relative path, we do not try the absolute because it can leak information about our
4963  system to an attacker */
4964  if (ref->nlvl_to > 0 && ref->nlvl_from > 0) {
4965  char filename[1025];
4966  const char *src_path;
4967  int i, l;
4968 
4969  /* find a source dir */
4970  src_path = strrchr(src, '/');
4971  if (src_path)
4972  src_path++;
4973  else
4974  src_path = src;
4975 
4976  /* find a next level down to target */
4977  for (i = 0, l = strlen(ref->path) - 1; l >= 0; l--)
4978  if (ref->path[l] == '/') {
4979  if (i == ref->nlvl_to - 1)
4980  break;
4981  else
4982  i++;
4983  }
4984 
4985  /* compose filename if next level down to target was found */
4986  if (i == ref->nlvl_to - 1 && src_path - src < sizeof(filename)) {
4987  memcpy(filename, src, src_path - src);
4988  filename[src_path - src] = 0;
4989 
4990  for (i = 1; i < ref->nlvl_from; i++)
4991  av_strlcat(filename, "../", sizeof(filename));
4992 
4993  av_strlcat(filename, ref->path + l + 1, sizeof(filename));
4994  if (!c->use_absolute_path) {
4995  int same_origin = test_same_origin(src, filename);
4996 
4997  if (!same_origin) {
4998  av_log(c->fc, AV_LOG_ERROR,
4999  "Reference with mismatching origin, %s not tried for security reasons, "
5000  "set demuxer option use_absolute_path to allow it anyway\n",
5001  ref->path);
5002  return AVERROR(ENOENT);
5003  }
5004 
5005  if (strstr(ref->path + l + 1, "..") ||
5006  strstr(ref->path + l + 1, ":") ||
5007  (ref->nlvl_from > 1 && same_origin < 0) ||
5008  (filename[0] == '/' && src_path == src))
5009  return AVERROR(ENOENT);
5010  }
5011 
5012  if (strlen(filename) + 1 == sizeof(filename))
5013  return AVERROR(ENOENT);
5014  if (!c->fc->io_open(c->fc, pb, filename, AVIO_FLAG_READ, NULL))
5015  return 0;
5016  }
5017  } else if (c->use_absolute_path) {
5018  av_log(c->fc, AV_LOG_WARNING, "Using absolute path on user request, "
5019  "this is a possible security issue\n");
5020  if (!c->fc->io_open(c->fc, pb, ref->path, AVIO_FLAG_READ, NULL))
5021  return 0;
5022  } else {
5023  av_log(c->fc, AV_LOG_ERROR,
5024  "Absolute path %s not tried for security reasons, "
5025  "set demuxer option use_absolute_path to allow absolute paths\n",
5026  ref->path);
5027  }
5028 
5029  return AVERROR(ENOENT);
5030 }
5031 
5033 {
5034  if (sc->time_scale <= 0) {
5035  av_log(c->fc, AV_LOG_WARNING, "stream %d, timescale not set\n", sc->ffindex);
5036  sc->time_scale = c->time_scale;
5037  if (sc->time_scale <= 0)
5038  sc->time_scale = 1;
5039  }
5040 }
5041 
5042 #if CONFIG_IAMFDEC
5043 static int mov_update_iamf_streams(MOVContext *c, const AVStream *st)
5044 {
5045  const MOVStreamContext *sc = st->priv_data;
5046  const IAMFContext *iamf = &sc->iamf->iamf;
5047 
5048  for (int i = 0; i < iamf->nb_audio_elements; i++) {
5049  const AVStreamGroup *stg = NULL;
5050 
5051  for (int j = 0; j < c->fc->nb_stream_groups; j++)
5052  if (c->fc->stream_groups[j]->id == iamf->audio_elements[i]->audio_element_id)
5053  stg = c->fc->stream_groups[j];
5054  av_assert0(stg);
5055 
5056  for (int j = 0; j < stg->nb_streams; j++) {
5057  const FFStream *sti = cffstream(st);
5058  AVStream *out = stg->streams[j];
5059  FFStream *out_sti = ffstream(stg->streams[j]);
5060 
5061  out->codecpar->bit_rate = 0;
5062 
5063  if (out == st)
5064  continue;
5065 
5066  out->time_base = st->time_base;
5067  out->start_time = st->start_time;
5068  out->duration = st->duration;
5069  out->nb_frames = st->nb_frames;
5070  out->discard = st->discard;
5071 
5072  av_assert0(!out_sti->index_entries);
5074  if (!out_sti->index_entries)
5075  return AVERROR(ENOMEM);
5076 
5078  out_sti->nb_index_entries = sti->nb_index_entries;
5079  out_sti->skip_samples = sti->skip_samples;
5080  memcpy(out_sti->index_entries, sti->index_entries, sti->index_entries_allocated_size);
5081  }
5082  }
5083 
5084  return 0;
5085 }
5086 #endif
5087 
5088 static int sanity_checks(void *log_obj, MOVStreamContext *sc, int index)
5089 {
5090  if ((sc->chunk_count && (!sc->stts_count || !sc->stsc_count ||
5091  (!sc->sample_size && !sc->sample_count))) ||
5092  (!sc->chunk_count && sc->sample_count)) {
5093  av_log(log_obj, AV_LOG_ERROR, "stream %d, missing mandatory atoms, broken header\n",
5094  index);
5095  return 1;
5096  }
5097 
5098  if (sc->stsc_count && sc->stsc_data[ sc->stsc_count - 1 ].first > sc->chunk_count) {
5099  av_log(log_obj, AV_LOG_ERROR, "stream %d, contradictionary STSC and STCO\n",
5100  index);
5101  return 2;
5102  }
5103  return 0;
5104 }
5105 
5107 {
5108  AVStream *st;
5109  MOVStreamContext *sc;
5110  int ret;
5111 
5112  st = avformat_new_stream(c->fc, NULL);
5113  if (!st) return AVERROR(ENOMEM);
5114  st->id = -1;
5115  sc = av_mallocz(sizeof(MOVStreamContext));
5116  if (!sc) return AVERROR(ENOMEM);
5117 
5118  st->priv_data = sc;
5120  sc->ffindex = st->index;
5121  c->trak_index = st->index;
5122  sc->tref_flags = 0;
5123  sc->tref_id = -1;
5124  sc->refcount = 1;
5125 
5126  if ((ret = mov_read_default(c, pb, atom)) < 0)
5127  return ret;
5128 
5129  c->trak_index = -1;
5130 
5131  // Here stsc refers to a chunk not described in stco. This is technically invalid,
5132  // but we can overlook it (clearing stsc) whenever stts_count == 0 (indicating no samples).
5133  if (!sc->chunk_count && !sc->stts_count && sc->stsc_count) {
5134  sc->stsc_count = 0;
5135  av_freep(&sc->stsc_data);
5136  }
5137 
5138  ret = sanity_checks(c->fc, sc, st->index);
5139  if (ret)
5140  return ret > 1 ? AVERROR_INVALIDDATA : 0;
5141 
5142  fix_timescale(c, sc);
5143 
5144  avpriv_set_pts_info(st, 64, 1, sc->time_scale);
5145 
5146  /*
5147  * Advanced edit list support does not work with fragemented MP4s, which
5148  * have stsc, stsz, stco, and stts with zero entries in the moov atom.
5149  * In these files, trun atoms may be streamed in.
5150  */
5151  if (!sc->stts_count && c->advanced_editlist) {
5152 
5153  av_log(c->fc, AV_LOG_VERBOSE, "advanced_editlist does not work with fragmented "
5154  "MP4. disabling.\n");
5155  c->advanced_editlist = 0;
5156  c->advanced_editlist_autodisabled = 1;
5157  }
5158 
5159  mov_build_index(c, st);
5160 
5161 #if CONFIG_IAMFDEC
5162  if (sc->iamf) {
5163  ret = mov_update_iamf_streams(c, st);
5164  if (ret < 0)
5165  return ret;
5166  }
5167 #endif
5168 
5169  if (sc->dref_id-1 < sc->drefs_count && sc->drefs[sc->dref_id-1].path) {
5170  MOVDref *dref = &sc->drefs[sc->dref_id - 1];
5171  if (c->enable_drefs) {
5172  if (mov_open_dref(c, &sc->pb, c->fc->url, dref) < 0)
5173  av_log(c->fc, AV_LOG_ERROR,
5174  "stream %d, error opening alias: path='%s', dir='%s', "
5175  "filename='%s', volume='%s', nlvl_from=%d, nlvl_to=%d\n",
5176  st->index, dref->path, dref->dir, dref->filename,
5177  dref->volume, dref->nlvl_from, dref->nlvl_to);
5178  } else {
5179  av_log(c->fc, AV_LOG_WARNING,
5180  "Skipped opening external track: "
5181  "stream %d, alias: path='%s', dir='%s', "
5182  "filename='%s', volume='%s', nlvl_from=%d, nlvl_to=%d."
5183  "Set enable_drefs to allow this.\n",
5184  st->index, dref->path, dref->dir, dref->filename,
5185  dref->volume, dref->nlvl_from, dref->nlvl_to);
5186  }
5187  } else {
5188  sc->pb = c->fc->pb;
5189  sc->pb_is_copied = 1;
5190  }
5191 
5192  if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
5193  int stts_constant = sc->stts_count && sc->tts_count;
5194  if (sc->h_spacing && sc->v_spacing)
5196  sc->h_spacing, sc->v_spacing, INT_MAX);
5197  if (!st->sample_aspect_ratio.num && st->codecpar->width && st->codecpar->height &&
5198  sc->height && sc->width &&
5199  (st->codecpar->width != sc->width || st->codecpar->height != sc->height)) {
5201  (int64_t)st->codecpar->height * sc->width,
5202  (int64_t)st->codecpar->width * sc->height, INT_MAX);
5203  }
5204 
5205 #if FF_API_R_FRAME_RATE
5206  for (unsigned int i = 1; sc->stts_count && i + 1 < sc->tts_count; i++) {
5207  if (sc->tts_data[i].duration == sc->tts_data[0].duration)
5208  continue;
5209  stts_constant = 0;
5210  }
5211  if (stts_constant)
5213  sc->time_scale, sc->tts_data[0].duration, INT_MAX);
5214 #endif
5215  }
5216 
5217  // done for ai5q, ai52, ai55, ai1q, ai12 and ai15.
5218  if (!st->codecpar->extradata_size && st->codecpar->codec_id == AV_CODEC_ID_H264 &&
5219  TAG_IS_AVCI(st->codecpar->codec_tag)) {
5221  if (ret < 0)
5222  return ret;
5223  }
5224 
5225  switch (st->codecpar->codec_id) {
5226 #if CONFIG_H261_DECODER
5227  case AV_CODEC_ID_H261:
5228 #endif
5229 #if CONFIG_H263_DECODER
5230  case AV_CODEC_ID_H263:
5231 #endif
5232 #if CONFIG_MPEG4_DECODER
5233  case AV_CODEC_ID_MPEG4:
5234 #endif
5235  st->codecpar->width = 0; /* let decoder init width/height */
5236  st->codecpar->height= 0;
5237  break;
5238  }
5239 
5240  // If the duration of the mp3 packets is not constant, then they could need a parser
5241  if (st->codecpar->codec_id == AV_CODEC_ID_MP3
5242  && sc->time_scale == st->codecpar->sample_rate) {
5243  int stts_constant = 1;
5244  for (int i = 1; sc->stts_count && i < sc->tts_count; i++) {
5245  if (sc->tts_data[i].duration == sc->tts_data[0].duration)
5246  continue;
5247  stts_constant = 0;
5248  }
5249  if (!stts_constant)
5251  }
5252  /* Do not need those anymore. */
5253  av_freep(&sc->chunk_offsets);
5254  av_freep(&sc->sample_sizes);
5255  av_freep(&sc->keyframes);
5256  av_freep(&sc->stps_data);
5257  av_freep(&sc->elst_data);
5258  av_freep(&sc->rap_group);
5259  av_freep(&sc->sync_group);
5260  av_freep(&sc->sgpd_sync);
5261 
5262  return 0;
5263 }
5264 
5266 {
5267  int ret;
5268  c->itunes_metadata = 1;
5269  ret = mov_read_default(c, pb, atom);
5270  c->itunes_metadata = 0;
5271  return ret;
5272 }
5273 
5275 {
5276  uint32_t count;
5277  uint32_t i;
5278 
5279  if (atom.size < 8)
5280  return 0;
5281 
5282  avio_skip(pb, 4);
5283  count = avio_rb32(pb);
5284  atom.size -= 8;
5285  if (count >= UINT_MAX / sizeof(*c->meta_keys)) {
5286  av_log(c->fc, AV_LOG_ERROR,
5287  "The 'keys' atom with the invalid key count: %"PRIu32"\n", count);
5288  return AVERROR_INVALIDDATA;
5289  }
5290 
5291  c->meta_keys_count = count + 1;
5292  c->meta_keys = av_mallocz(c->meta_keys_count * sizeof(*c->meta_keys));
5293  if (!c->meta_keys)
5294  return AVERROR(ENOMEM);
5295 
5296  for (i = 1; i <= count; ++i) {
5297  uint32_t key_size = avio_rb32(pb);
5298  uint32_t type = avio_rl32(pb);
5299  if (key_size < 8 || key_size > atom.size) {
5300  av_log(c->fc, AV_LOG_ERROR,
5301  "The key# %"PRIu32" in meta has invalid size:"
5302  "%"PRIu32"\n", i, key_size);
5303  return AVERROR_INVALIDDATA;
5304  }
5305  atom.size -= key_size;
5306  key_size -= 8;
5307  if (type != MKTAG('m','d','t','a')) {
5308  avio_skip(pb, key_size);
5309  continue;
5310  }
5311  c->meta_keys[i] = av_mallocz(key_size + 1);
5312  if (!c->meta_keys[i])
5313  return AVERROR(ENOMEM);
5314  avio_read(pb, c->meta_keys[i], key_size);
5315  }
5316 
5317  return 0;
5318 }
5319 
5321 {
5322  int64_t end = av_sat_add64(avio_tell(pb), atom.size);
5323  uint8_t *key = NULL, *val = NULL, *mean = NULL;
5324  int i;
5325  int ret = 0;
5326  AVStream *st;
5327  MOVStreamContext *sc;
5328 
5329  if (c->fc->nb_streams < 1)
5330  return 0;
5331  st = c->fc->streams[c->fc->nb_streams-1];
5332  sc = st->priv_data;
5333 
5334  for (i = 0; i < 3; i++) {
5335  uint8_t **p;
5336  uint32_t len, tag;
5337 
5338  if (end - avio_tell(pb) <= 12)
5339  break;
5340 
5341  len = avio_rb32(pb);
5342  tag = avio_rl32(pb);
5343  avio_skip(pb, 4); // flags
5344 
5345  if (len < 12 || len - 12 > end - avio_tell(pb))
5346  break;
5347  len -= 12;
5348 
5349  if (tag == MKTAG('m', 'e', 'a', 'n'))
5350  p = &mean;
5351  else if (tag == MKTAG('n', 'a', 'm', 'e'))
5352  p = &key;
5353  else if (tag == MKTAG('d', 'a', 't', 'a') && len > 4) {
5354  avio_skip(pb, 4);
5355  len -= 4;
5356  p = &val;
5357  } else
5358  break;
5359 
5360  if (*p)
5361  break;
5362 
5363  *p = av_malloc(len + 1);
5364  if (!*p) {
5365  ret = AVERROR(ENOMEM);
5366  break;
5367  }
5368  ret = ffio_read_size(pb, *p, len);
5369  if (ret < 0) {
5370  av_freep(p);
5371  break;
5372  }
5373  (*p)[len] = 0;
5374  }
5375 
5376  if (mean && key && val) {
5377  if (strcmp(key, "iTunSMPB") == 0) {
5378  int priming, remainder, samples;
5379  if(sscanf(val, "%*X %X %X %X", &priming, &remainder, &samples) == 3){
5380  if(priming>0 && priming<16384)
5381  sc->start_pad = priming;
5382  }
5383  }
5384  if (strcmp(key, "cdec") != 0) {
5385  av_dict_set(&c->fc->metadata, key, val,
5387  key = val = NULL;
5388  }
5389  } else {
5390  av_log(c->fc, AV_LOG_VERBOSE,
5391  "Unhandled or malformed custom metadata of size %"PRId64"\n", atom.size);
5392  }
5393 
5394  avio_seek(pb, end, SEEK_SET);
5395  av_freep(&key);
5396  av_freep(&val);
5397  av_freep(&mean);
5398  return ret;
5399 }
5400 
5402 {
5403  MOVStreamContext *sc;
5404  AVStream *st;
5405 
5406  st = avformat_new_stream(c->fc, NULL);
5407  if (!st)
5408  return AVERROR(ENOMEM);
5409  sc = av_mallocz(sizeof(MOVStreamContext));
5410  if (!sc)
5411  return AVERROR(ENOMEM);
5412 
5413  item->st = st;
5414  st->id = item->item_id;
5415  st->priv_data = sc;
5417  st->codecpar->codec_id = mov_codec_id(st, item->type);
5418  sc->id = st->id;
5419  sc->ffindex = st->index;
5420  st->avg_frame_rate.num = st->avg_frame_rate.den = 1;
5421  st->time_base.num = st->time_base.den = 1;
5422  st->nb_frames = 1;
5423  sc->time_scale = 1;
5424  sc->pb = c->fc->pb;
5425  sc->pb_is_copied = 1;
5426  sc->refcount = 1;
5427 
5428  if (item->name)
5429  av_dict_set(&st->metadata, "title", item->name, 0);
5430 
5431  // Populate the necessary fields used by mov_build_index.
5432  sc->stsc_count = 1;
5433  sc->stsc_data = av_malloc_array(1, sizeof(*sc->stsc_data));
5434  if (!sc->stsc_data)
5435  return AVERROR(ENOMEM);
5436  sc->stsc_data[0].first = 1;
5437  sc->stsc_data[0].count = 1;
5438  sc->stsc_data[0].id = 1;
5439  sc->chunk_offsets = av_malloc_array(1, sizeof(*sc->chunk_offsets));
5440  if (!sc->chunk_offsets)
5441  return AVERROR(ENOMEM);
5442  sc->chunk_count = 1;
5443  sc->sample_sizes = av_malloc_array(1, sizeof(*sc->sample_sizes));
5444  if (!sc->sample_sizes)
5445  return AVERROR(ENOMEM);
5446  sc->sample_count = 1;
5447  sc->stts_data = av_malloc_array(1, sizeof(*sc->stts_data));
5448  if (!sc->stts_data)
5449  return AVERROR(ENOMEM);
5450  sc->stts_count = 1;
5451  sc->stts_data[0].count = 1;
5452  // Not used for still images. But needed by mov_build_index.
5453  sc->stts_data[0].duration = 0;
5454 
5455  return 0;
5456 }
5457 
5459 {
5460  while (atom.size > 8) {
5461  uint32_t tag;
5462  if (avio_feof(pb))
5463  return AVERROR_EOF;
5464  tag = avio_rl32(pb);
5465  atom.size -= 4;
5466  if (tag == MKTAG('h','d','l','r')) {
5467  avio_seek(pb, -8, SEEK_CUR);
5468  atom.size += 8;
5469  return mov_read_default(c, pb, atom);
5470  }
5471  }
5472  return 0;
5473 }
5474 
5475 // return 1 when matrix is identity, 0 otherwise
5476 #define IS_MATRIX_IDENT(matrix) \
5477  ( (matrix)[0][0] == (1 << 16) && \
5478  (matrix)[1][1] == (1 << 16) && \
5479  (matrix)[2][2] == (1 << 30) && \
5480  !(matrix)[0][1] && !(matrix)[0][2] && \
5481  !(matrix)[1][0] && !(matrix)[1][2] && \
5482  !(matrix)[2][0] && !(matrix)[2][1])
5483 
5485 {
5486  int i, j, e;
5487  int width;
5488  int height;
5489  int display_matrix[3][3];
5490  int res_display_matrix[3][3] = { { 0 } };
5491  AVStream *st;
5492  MOVStreamContext *sc;
5493  int version;
5494  int flags;
5495 
5496  if (c->fc->nb_streams < 1)
5497  return 0;
5498  st = c->fc->streams[c->fc->nb_streams-1];
5499  sc = st->priv_data;
5500 
5501  // Each stream (trak) should have exactly 1 tkhd. This catches bad files and
5502  // avoids corrupting AVStreams mapped to an earlier tkhd.
5503  if (st->id != -1)
5504  return AVERROR_INVALIDDATA;
5505 
5506  version = avio_r8(pb);
5507  flags = avio_rb24(pb);
5509 
5510  if (version == 1) {
5511  avio_rb64(pb);
5512  avio_rb64(pb);
5513  } else {
5514  avio_rb32(pb); /* creation time */
5515  avio_rb32(pb); /* modification time */
5516  }
5517  st->id = (int)avio_rb32(pb); /* track id (NOT 0 !)*/
5518  sc->id = st->id;
5519  avio_rb32(pb); /* reserved */
5520 
5521  /* highlevel (considering edits) duration in movie timebase */
5522  (version == 1) ? avio_rb64(pb) : avio_rb32(pb);
5523  avio_rb32(pb); /* reserved */
5524  avio_rb32(pb); /* reserved */
5525 
5526  avio_rb16(pb); /* layer */
5527  avio_rb16(pb); /* alternate group */
5528  avio_rb16(pb); /* volume */
5529  avio_rb16(pb); /* reserved */
5530 
5531  //read in the display matrix (outlined in ISO 14496-12, Section 6.2.2)
5532  // they're kept in fixed point format through all calculations
5533  // save u,v,z to store the whole matrix in the AV_PKT_DATA_DISPLAYMATRIX
5534  // side data, but the scale factor is not needed to calculate aspect ratio
5535  for (i = 0; i < 3; i++) {
5536  display_matrix[i][0] = avio_rb32(pb); // 16.16 fixed point
5537  display_matrix[i][1] = avio_rb32(pb); // 16.16 fixed point
5538  display_matrix[i][2] = avio_rb32(pb); // 2.30 fixed point
5539  }
5540 
5541  width = avio_rb32(pb); // 16.16 fixed point track width
5542  height = avio_rb32(pb); // 16.16 fixed point track height
5543  sc->width = width >> 16;
5544  sc->height = height >> 16;
5545 
5546  // apply the moov display matrix (after the tkhd one)
5547  for (i = 0; i < 3; i++) {
5548  const int sh[3] = { 16, 16, 30 };
5549  for (j = 0; j < 3; j++) {
5550  for (e = 0; e < 3; e++) {
5551  res_display_matrix[i][j] +=
5552  ((int64_t) display_matrix[i][e] *
5553  c->movie_display_matrix[e][j]) >> sh[e];
5554  }
5555  }
5556  }
5557 
5558  // save the matrix when it is not the default identity
5559  if (!IS_MATRIX_IDENT(res_display_matrix)) {
5560  av_freep(&sc->display_matrix);
5561  sc->display_matrix = av_malloc(sizeof(int32_t) * 9);
5562  if (!sc->display_matrix)
5563  return AVERROR(ENOMEM);
5564 
5565  for (i = 0; i < 3; i++)
5566  for (j = 0; j < 3; j++)
5567  sc->display_matrix[i * 3 + j] = res_display_matrix[i][j];
5568  }
5569 
5570  // transform the display width/height according to the matrix
5571  // to keep the same scale, use [width height 1<<16]
5572  if (width && height && sc->display_matrix) {
5573  double disp_transform[2];
5574 
5575  for (i = 0; i < 2; i++)
5576  disp_transform[i] = hypot(sc->display_matrix[0 + i],
5577  sc->display_matrix[3 + i]);
5578 
5579  if (disp_transform[0] > 1 && disp_transform[1] > 1 &&
5580  disp_transform[0] < (1<<24) && disp_transform[1] < (1<<24) &&
5581  fabs((disp_transform[0] / disp_transform[1]) - 1.0) > 0.01)
5583  disp_transform[0] / disp_transform[1],
5584  INT_MAX);
5585  }
5586  return 0;
5587 }
5588 
5590 {
5591  MOVFragment *frag = &c->fragment;
5592  MOVTrackExt *trex = NULL;
5593  int flags, track_id, i;
5594  MOVFragmentStreamInfo * frag_stream_info;
5595 
5596  avio_r8(pb); /* version */
5597  flags = avio_rb24(pb);
5598 
5599  track_id = avio_rb32(pb);
5600  if (!track_id)
5601  return AVERROR_INVALIDDATA;
5602  for (i = 0; i < c->trex_count; i++)
5603  if (c->trex_data[i].track_id == track_id) {
5604  trex = &c->trex_data[i];
5605  break;
5606  }
5607  if (!trex) {
5608  av_log(c->fc, AV_LOG_WARNING, "could not find corresponding trex (id %u)\n", track_id);
5609  return 0;
5610  }
5611  c->fragment.found_tfhd = 1;
5612  frag->track_id = track_id;
5613  set_frag_stream(&c->frag_index, track_id);
5614 
5617  frag->moof_offset : frag->implicit_offset;
5618  frag->stsd_id = flags & MOV_TFHD_STSD_ID ? avio_rb32(pb) : trex->stsd_id;
5619 
5621  avio_rb32(pb) : trex->duration;
5622  frag->size = flags & MOV_TFHD_DEFAULT_SIZE ?
5623  avio_rb32(pb) : trex->size;
5624  frag->flags = flags & MOV_TFHD_DEFAULT_FLAGS ?
5625  avio_rb32(pb) : trex->flags;
5626  av_log(c->fc, AV_LOG_TRACE, "frag flags 0x%x\n", frag->flags);
5627 
5628  frag_stream_info = get_current_frag_stream_info(&c->frag_index);
5629  if (frag_stream_info) {
5630  frag_stream_info->next_trun_dts = AV_NOPTS_VALUE;
5631  frag_stream_info->stsd_id = frag->stsd_id;
5632  }
5633  return 0;
5634 }
5635 
5637 {
5638  unsigned i, num;
5639  void *new_tracks;
5640 
5641  num = atom.size / 4;
5642  if (!(new_tracks = av_malloc_array(num, sizeof(int))))
5643  return AVERROR(ENOMEM);
5644 
5645  av_free(c->chapter_tracks);
5646  c->chapter_tracks = new_tracks;
5647  c->nb_chapter_tracks = num;
5648 
5649  for (i = 0; i < num && !pb->eof_reached; i++)
5650  c->chapter_tracks[i] = avio_rb32(pb);
5651 
5652  c->nb_chapter_tracks = i;
5653 
5654  return 0;
5655 }
5656 
5658 {
5659  MOVTrackExt *trex;
5660  int err;
5661 
5662  if ((uint64_t)c->trex_count+1 >= UINT_MAX / sizeof(*c->trex_data))
5663  return AVERROR_INVALIDDATA;
5664  if ((err = av_reallocp_array(&c->trex_data, c->trex_count + 1,
5665  sizeof(*c->trex_data))) < 0) {
5666  c->trex_count = 0;
5667  return err;
5668  }
5669 
5670  c->fc->duration = AV_NOPTS_VALUE; // the duration from mvhd is not representing the whole file when fragments are used.
5671 
5672  trex = &c->trex_data[c->trex_count++];
5673  avio_r8(pb); /* version */
5674  avio_rb24(pb); /* flags */
5675  trex->track_id = avio_rb32(pb);
5676  trex->stsd_id = avio_rb32(pb);
5677  trex->duration = avio_rb32(pb);
5678  trex->size = avio_rb32(pb);
5679  trex->flags = avio_rb32(pb);
5680  return 0;
5681 }
5682 
5684 {
5685  MOVFragment *frag = &c->fragment;
5686  AVStream *st = NULL;
5687  MOVStreamContext *sc;
5688  int version, i;
5689  MOVFragmentStreamInfo * frag_stream_info;
5690  int64_t base_media_decode_time;
5691 
5692  for (i = 0; i < c->fc->nb_streams; i++) {
5693  sc = c->fc->streams[i]->priv_data;
5694  if (sc->id == frag->track_id) {
5695  st = c->fc->streams[i];
5696  break;
5697  }
5698  }
5699  if (!st) {
5700  av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %u\n", frag->track_id);
5701  return 0;
5702  }
5703  sc = st->priv_data;
5704  if (sc->pseudo_stream_id + 1 != frag->stsd_id && sc->pseudo_stream_id != -1)
5705  return 0;
5706  version = avio_r8(pb);
5707  avio_rb24(pb); /* flags */
5708  if (version) {
5709  base_media_decode_time = avio_rb64(pb);
5710  } else {
5711  base_media_decode_time = avio_rb32(pb);
5712  }
5713 
5714  frag_stream_info = get_current_frag_stream_info(&c->frag_index);
5715  if (frag_stream_info)
5716  frag_stream_info->tfdt_dts = base_media_decode_time;
5717  sc->track_end = base_media_decode_time;
5718 
5719  return 0;
5720 }
5721 
5723 {
5724  MOVFragment *frag = &c->fragment;
5725  AVStream *st = NULL;
5726  FFStream *sti = NULL;
5727  MOVStreamContext *sc;
5728  MOVTimeToSample *tts_data;
5729  uint64_t offset;
5730  int64_t dts, pts = AV_NOPTS_VALUE;
5731  int data_offset = 0;
5732  unsigned entries, first_sample_flags = frag->flags;
5733  int flags, distance, i;
5734  int64_t prev_dts = AV_NOPTS_VALUE;
5735  int next_frag_index = -1, index_entry_pos;
5736  size_t requested_size;
5737  size_t old_allocated_size;
5738  AVIndexEntry *new_entries;
5739  MOVFragmentStreamInfo * frag_stream_info;
5740 
5741  if (!frag->found_tfhd) {
5742  av_log(c->fc, AV_LOG_ERROR, "trun track id unknown, no tfhd was found\n");
5743  return AVERROR_INVALIDDATA;
5744  }
5745 
5746  for (i = 0; i < c->fc->nb_streams; i++) {
5747  sc = c->fc->streams[i]->priv_data;
5748  if (sc->id == frag->track_id) {
5749  st = c->fc->streams[i];
5750  sti = ffstream(st);
5751  break;
5752  }
5753  }
5754  if (!st) {
5755  av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %u\n", frag->track_id);
5756  return 0;
5757  }
5758  sc = st->priv_data;
5759  if (sc->pseudo_stream_id+1 != frag->stsd_id && sc->pseudo_stream_id != -1)
5760  return 0;
5761 
5762  // Find the next frag_index index that has a valid index_entry for
5763  // the current track_id.
5764  //
5765  // A valid index_entry means the trun for the fragment was read
5766  // and it's samples are in index_entries at the given position.
5767  // New index entries will be inserted before the index_entry found.
5768  index_entry_pos = sti->nb_index_entries;
5769  for (i = c->frag_index.current + 1; i < c->frag_index.nb_items; i++) {
5770  frag_stream_info = get_frag_stream_info(&c->frag_index, i, frag->track_id);
5771  if (frag_stream_info && frag_stream_info->index_entry >= 0) {
5772  next_frag_index = i;
5773  index_entry_pos = frag_stream_info->index_entry;
5774  break;
5775  }
5776  }
5777  av_assert0(index_entry_pos <= sti->nb_index_entries);
5778 
5779  avio_r8(pb); /* version */
5780  flags = avio_rb24(pb);
5781  entries = avio_rb32(pb);
5782  av_log(c->fc, AV_LOG_TRACE, "flags 0x%x entries %u\n", flags, entries);
5783 
5784  if ((uint64_t)entries+sc->tts_count >= UINT_MAX/sizeof(*sc->tts_data))
5785  return AVERROR_INVALIDDATA;
5786  if (flags & MOV_TRUN_DATA_OFFSET) data_offset = avio_rb32(pb);
5787  if (flags & MOV_TRUN_FIRST_SAMPLE_FLAGS) first_sample_flags = avio_rb32(pb);
5788 
5789  frag_stream_info = get_current_frag_stream_info(&c->frag_index);
5790  if (frag_stream_info) {
5791  if (frag_stream_info->next_trun_dts != AV_NOPTS_VALUE) {
5792  dts = frag_stream_info->next_trun_dts - sc->time_offset;
5793  } else if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE &&
5794  c->use_mfra_for == FF_MOV_FLAG_MFRA_PTS) {
5795  pts = frag_stream_info->first_tfra_pts;
5796  av_log(c->fc, AV_LOG_DEBUG, "found mfra time %"PRId64
5797  ", using it for pts\n", pts);
5798  } else if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE &&
5799  c->use_mfra_for == FF_MOV_FLAG_MFRA_DTS) {
5800  dts = frag_stream_info->first_tfra_pts;
5801  av_log(c->fc, AV_LOG_DEBUG, "found mfra time %"PRId64
5802  ", using it for dts\n", pts);
5803  } else {
5804  int has_tfdt = frag_stream_info->tfdt_dts != AV_NOPTS_VALUE;
5805  int has_sidx = frag_stream_info->sidx_pts != AV_NOPTS_VALUE;
5806  int fallback_tfdt = !c->use_tfdt && !has_sidx && has_tfdt;
5807  int fallback_sidx = c->use_tfdt && !has_tfdt && has_sidx;
5808 
5809  if (fallback_sidx) {
5810  av_log(c->fc, AV_LOG_DEBUG, "use_tfdt set but no tfdt found, using sidx instead\n");
5811  }
5812  if (fallback_tfdt) {
5813  av_log(c->fc, AV_LOG_DEBUG, "use_tfdt not set but no sidx found, using tfdt instead\n");
5814  }
5815 
5816  if (has_tfdt && c->use_tfdt || fallback_tfdt) {
5817  dts = frag_stream_info->tfdt_dts - sc->time_offset;
5818  av_log(c->fc, AV_LOG_DEBUG, "found tfdt time %"PRId64
5819  ", using it for dts\n", dts);
5820  } else if (has_sidx && !c->use_tfdt || fallback_sidx) {
5821  // FIXME: sidx earliest_presentation_time is *PTS*, s.b.
5822  // pts = frag_stream_info->sidx_pts;
5823  dts = frag_stream_info->sidx_pts - sc->time_offset;
5824  av_log(c->fc, AV_LOG_DEBUG, "found sidx time %"PRId64
5825  ", using it for dts\n", frag_stream_info->sidx_pts);
5826  } else {
5827  dts = sc->track_end - sc->time_offset;
5828  av_log(c->fc, AV_LOG_DEBUG, "found track end time %"PRId64
5829  ", using it for dts\n", dts);
5830  }
5831  }
5832  } else {
5833  dts = sc->track_end - sc->time_offset;
5834  av_log(c->fc, AV_LOG_DEBUG, "found track end time %"PRId64
5835  ", using it for dts\n", dts);
5836  }
5837  offset = frag->base_data_offset + data_offset;
5838  distance = 0;
5839  av_log(c->fc, AV_LOG_TRACE, "first sample flags 0x%x\n", first_sample_flags);
5840 
5841  // realloc space for new index entries
5842  if ((uint64_t)sti->nb_index_entries + entries >= UINT_MAX / sizeof(AVIndexEntry)) {
5843  entries = UINT_MAX / sizeof(AVIndexEntry) - sti->nb_index_entries;
5844  av_log(c->fc, AV_LOG_ERROR, "Failed to add index entry\n");
5845  }
5846  if (entries == 0)
5847  return 0;
5848 
5849  requested_size = (sti->nb_index_entries + entries) * sizeof(AVIndexEntry);
5850  new_entries = av_fast_realloc(sti->index_entries,
5852  requested_size);
5853  if (!new_entries)
5854  return AVERROR(ENOMEM);
5855  sti->index_entries= new_entries;
5856 
5857  requested_size = (sti->nb_index_entries + entries) * sizeof(*sc->tts_data);
5858  old_allocated_size = sc->tts_allocated_size;
5859  tts_data = av_fast_realloc(sc->tts_data, &sc->tts_allocated_size,
5860  requested_size);
5861  if (!tts_data)
5862  return AVERROR(ENOMEM);
5863  sc->tts_data = tts_data;
5864 
5865  // In case there were samples without time to sample entries, ensure they get
5866  // zero valued entries. This ensures clips which mix boxes with and
5867  // without time to sample entries don't pickup uninitialized data.
5868  memset((uint8_t*)(sc->tts_data) + old_allocated_size, 0,
5869  sc->tts_allocated_size - old_allocated_size);
5870 
5871  if (index_entry_pos < sti->nb_index_entries) {
5872  // Make hole in index_entries and tts_data for new samples
5873  memmove(sti->index_entries + index_entry_pos + entries,
5874  sti->index_entries + index_entry_pos,
5875  sizeof(*sti->index_entries) *
5876  (sti->nb_index_entries - index_entry_pos));
5877  memmove(sc->tts_data + index_entry_pos + entries,
5878  sc->tts_data + index_entry_pos,
5879  sizeof(*sc->tts_data) * (sc->tts_count - index_entry_pos));
5880  if (index_entry_pos < sc->current_sample) {
5881  sc->current_sample += entries;
5882  }
5883  }
5884 
5885  sti->nb_index_entries += entries;
5886  sc->tts_count = sti->nb_index_entries;
5887  sc->stts_count = sti->nb_index_entries;
5888  if (flags & MOV_TRUN_SAMPLE_CTS)
5889  sc->ctts_count = sti->nb_index_entries;
5890 
5891  // Record the index_entry position in frag_index of this fragment
5892  if (frag_stream_info) {
5893  frag_stream_info->index_entry = index_entry_pos;
5894  if (frag_stream_info->index_base < 0)
5895  frag_stream_info->index_base = index_entry_pos;
5896  }
5897 
5898  if (index_entry_pos > 0)
5899  prev_dts = sti->index_entries[index_entry_pos-1].timestamp;
5900 
5901  for (i = 0; i < entries && !pb->eof_reached; i++) {
5902  unsigned sample_size = frag->size;
5903  int sample_flags = i ? frag->flags : first_sample_flags;
5904  unsigned sample_duration = frag->duration;
5905  unsigned ctts_duration = 0;
5906  int keyframe = 0;
5907  int index_entry_flags = 0;
5908 
5909  if (flags & MOV_TRUN_SAMPLE_DURATION) sample_duration = avio_rb32(pb);
5910  if (flags & MOV_TRUN_SAMPLE_SIZE) sample_size = avio_rb32(pb);
5911  if (flags & MOV_TRUN_SAMPLE_FLAGS) sample_flags = avio_rb32(pb);
5912  if (flags & MOV_TRUN_SAMPLE_CTS) ctts_duration = avio_rb32(pb);
5913 
5914  mov_update_dts_shift(sc, ctts_duration, c->fc);
5915  if (pts != AV_NOPTS_VALUE) {
5916  dts = pts - sc->dts_shift;
5917  if (flags & MOV_TRUN_SAMPLE_CTS) {
5918  dts -= ctts_duration;
5919  } else {
5920  dts -= sc->time_offset;
5921  }
5922  av_log(c->fc, AV_LOG_DEBUG,
5923  "pts %"PRId64" calculated dts %"PRId64
5924  " sc->dts_shift %d ctts.duration %d"
5925  " sc->time_offset %"PRId64
5926  " flags & MOV_TRUN_SAMPLE_CTS %d\n",
5927  pts, dts,
5928  sc->dts_shift, ctts_duration,
5930  pts = AV_NOPTS_VALUE;
5931  }
5932 
5933  keyframe =
5934  !(sample_flags & (MOV_FRAG_SAMPLE_FLAG_IS_NON_SYNC |
5936  if (keyframe) {
5937  distance = 0;
5938  index_entry_flags |= AVINDEX_KEYFRAME;
5939  }
5940  // Fragments can overlap in time. Discard overlapping frames after
5941  // decoding.
5942  if (prev_dts >= dts)
5943  index_entry_flags |= AVINDEX_DISCARD_FRAME;
5944 
5945  sti->index_entries[index_entry_pos].pos = offset;
5946  sti->index_entries[index_entry_pos].timestamp = dts;
5947  sti->index_entries[index_entry_pos].size = sample_size;
5948  sti->index_entries[index_entry_pos].min_distance = distance;
5949  sti->index_entries[index_entry_pos].flags = index_entry_flags;
5950 
5951  sc->tts_data[index_entry_pos].count = 1;
5952  sc->tts_data[index_entry_pos].offset = ctts_duration;
5953  sc->tts_data[index_entry_pos].duration = sample_duration;
5954  index_entry_pos++;
5955 
5956  av_log(c->fc, AV_LOG_TRACE, "AVIndex stream %d, sample %d, offset %"PRIx64", dts %"PRId64", "
5957  "size %u, distance %d, keyframe %d\n", st->index,
5958  index_entry_pos, offset, dts, sample_size, distance, keyframe);
5959  distance++;
5960  if (av_sat_add64(dts, sample_duration) != dts + (uint64_t)sample_duration)
5961  return AVERROR_INVALIDDATA;
5962  if (!sample_size)
5963  return AVERROR_INVALIDDATA;
5964  dts += sample_duration;
5965  offset += sample_size;
5966  sc->data_size += sample_size;
5967 
5968  if (sample_duration <= INT64_MAX - sc->duration_for_fps &&
5969  1 <= INT_MAX - sc->nb_frames_for_fps
5970  ) {
5971  sc->duration_for_fps += sample_duration;
5972  sc->nb_frames_for_fps ++;
5973  }
5974  }
5975  if (frag_stream_info)
5976  frag_stream_info->next_trun_dts = dts + sc->time_offset;
5977  if (i < entries) {
5978  // EOF found before reading all entries. Fix the hole this would
5979  // leave in index_entries and tts_data
5980  int gap = entries - i;
5981  memmove(sti->index_entries + index_entry_pos,
5982  sti->index_entries + index_entry_pos + gap,
5983  sizeof(*sti->index_entries) *
5984  (sti->nb_index_entries - (index_entry_pos + gap)));
5985  memmove(sc->tts_data + index_entry_pos,
5986  sc->tts_data + index_entry_pos + gap,
5987  sizeof(*sc->tts_data) *
5988  (sc->tts_count - (index_entry_pos + gap)));
5989 
5990  sti->nb_index_entries -= gap;
5991  sc->tts_count -= gap;
5992  if (index_entry_pos < sc->current_sample) {
5993  sc->current_sample -= gap;
5994  }
5995  entries = i;
5996  }
5997 
5998  // The end of this new fragment may overlap in time with the start
5999  // of the next fragment in index_entries. Mark the samples in the next
6000  // fragment that overlap with AVINDEX_DISCARD_FRAME
6001  prev_dts = AV_NOPTS_VALUE;
6002  if (index_entry_pos > 0)
6003  prev_dts = sti->index_entries[index_entry_pos-1].timestamp;
6004  for (int i = index_entry_pos; i < sti->nb_index_entries; i++) {
6005  if (prev_dts < sti->index_entries[i].timestamp)
6006  break;
6008  }
6009 
6010  // If a hole was created to insert the new index_entries into,
6011  // the index_entry recorded for all subsequent moof must
6012  // be incremented by the number of entries inserted.
6013  fix_frag_index_entries(&c->frag_index, next_frag_index,
6014  frag->track_id, entries);
6015 
6016  if (pb->eof_reached) {
6017  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted TRUN atom\n");
6018  return AVERROR_EOF;
6019  }
6020 
6021  frag->implicit_offset = offset;
6022 
6023  sc->track_end = dts + sc->time_offset;
6024  if (st->duration < sc->track_end)
6025  st->duration = sc->track_end;
6026 
6027  return 0;
6028 }
6029 
6031 {
6032  int64_t stream_size = avio_size(pb);
6033  int64_t offset = av_sat_add64(avio_tell(pb), atom.size), pts, timestamp;
6034  uint8_t version, is_complete;
6035  int64_t offadd;
6036  unsigned i, j, track_id, item_count;
6037  AVStream *st = NULL;
6038  AVStream *ref_st = NULL;
6039  MOVStreamContext *sc, *ref_sc = NULL;
6040  AVRational timescale;
6041 
6042  version = avio_r8(pb);
6043  if (version > 1) {
6044  avpriv_request_sample(c->fc, "sidx version %u", version);
6045  return 0;
6046  }
6047 
6048  avio_rb24(pb); // flags
6049 
6050  track_id = avio_rb32(pb); // Reference ID
6051  for (i = 0; i < c->fc->nb_streams; i++) {
6052  sc = c->fc->streams[i]->priv_data;
6053  if (sc->id == track_id) {
6054  st = c->fc->streams[i];
6055  break;
6056  }
6057  }
6058  if (!st) {
6059  av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %d\n", track_id);
6060  return 0;
6061  }
6062 
6063  sc = st->priv_data;
6064 
6065  timescale = av_make_q(1, avio_rb32(pb));
6066 
6067  if (timescale.den <= 0) {
6068  av_log(c->fc, AV_LOG_ERROR, "Invalid sidx timescale 1/%d\n", timescale.den);
6069  return AVERROR_INVALIDDATA;
6070  }
6071 
6072  if (version == 0) {
6073  pts = avio_rb32(pb);
6074  offadd= avio_rb32(pb);
6075  } else {
6076  pts = avio_rb64(pb);
6077  offadd= avio_rb64(pb);
6078  }
6079  if (av_sat_add64(offset, offadd) != offset + (uint64_t)offadd)
6080  return AVERROR_INVALIDDATA;
6081 
6082  offset += (uint64_t)offadd;
6083 
6084  avio_rb16(pb); // reserved
6085 
6086  item_count = avio_rb16(pb);
6087  if (item_count == 0)
6088  return AVERROR_INVALIDDATA;
6089 
6090  for (i = 0; i < item_count; i++) {
6091  int index;
6092  MOVFragmentStreamInfo * frag_stream_info;
6093  uint32_t size = avio_rb32(pb);
6094  uint32_t duration = avio_rb32(pb);
6095  if (size & 0x80000000) {
6096  avpriv_request_sample(c->fc, "sidx reference_type 1");
6097  return AVERROR_PATCHWELCOME;
6098  }
6099  avio_rb32(pb); // sap_flags
6100  timestamp = av_rescale_q(pts, timescale, st->time_base);
6101 
6103  frag_stream_info = get_frag_stream_info(&c->frag_index, index, track_id);
6104  if (frag_stream_info)
6105  frag_stream_info->sidx_pts = timestamp;
6106 
6107  if (av_sat_add64(offset, size) != offset + (uint64_t)size ||
6108  av_sat_add64(pts, duration) != pts + (uint64_t)duration
6109  )
6110  return AVERROR_INVALIDDATA;
6111  offset += size;
6112  pts += duration;
6113  }
6114 
6115  st->duration = sc->track_end = pts;
6116 
6117  sc->has_sidx = 1;
6118 
6119  // See if the remaining bytes are just an mfra which we can ignore.
6120  is_complete = offset == stream_size;
6121  if (!is_complete && (pb->seekable & AVIO_SEEKABLE_NORMAL) && stream_size > 0 ) {
6122  int64_t ret;
6123  int64_t original_pos = avio_tell(pb);
6124  if (!c->have_read_mfra_size) {
6125  if ((ret = avio_seek(pb, stream_size - 4, SEEK_SET)) < 0)
6126  return ret;
6127  c->mfra_size = avio_rb32(pb);
6128  c->have_read_mfra_size = 1;
6129  if ((ret = avio_seek(pb, original_pos, SEEK_SET)) < 0)
6130  return ret;
6131  }
6132  if (offset == stream_size - c->mfra_size)
6133  is_complete = 1;
6134  }
6135 
6136  if (is_complete) {
6137  // Find first entry in fragment index that came from an sidx.
6138  // This will pretty much always be the first entry.
6139  for (i = 0; i < c->frag_index.nb_items; i++) {
6140  MOVFragmentIndexItem * item = &c->frag_index.item[i];
6141  for (j = 0; ref_st == NULL && j < item->nb_stream_info; j++) {
6142  MOVFragmentStreamInfo * si;
6143  si = &item->stream_info[j];
6144  if (si->sidx_pts != AV_NOPTS_VALUE) {
6145  ref_st = c->fc->streams[j];
6146  ref_sc = ref_st->priv_data;
6147  break;
6148  }
6149  }
6150  }
6151  if (ref_st) for (i = 0; i < c->fc->nb_streams; i++) {
6152  st = c->fc->streams[i];
6153  sc = st->priv_data;
6154  if (!sc->has_sidx) {
6155  st->duration = sc->track_end = av_rescale(ref_st->duration, sc->time_scale, ref_sc->time_scale);
6156  }
6157  }
6158 
6159  c->frag_index.complete = 1;
6160  }
6161 
6162  return 0;
6163 }
6164 
6165 /* this atom should be null (from specs), but some buggy files put the 'moov' atom inside it... */
6166 /* like the files created with Adobe Premiere 5.0, for samples see */
6167 /* http://graphics.tudelft.nl/~wouter/publications/soundtests/ */
6169 {
6170  int err;
6171 
6172  if (atom.size < 8)
6173  return 0; /* continue */
6174  if (avio_rb32(pb) != 0) { /* 0 sized mdat atom... use the 'wide' atom size */
6175  avio_skip(pb, atom.size - 4);
6176  return 0;
6177  }
6178  atom.type = avio_rl32(pb);
6179  atom.size -= 8;
6180  if (atom.type != MKTAG('m','d','a','t')) {
6181  avio_skip(pb, atom.size);
6182  return 0;
6183  }
6184  err = mov_read_mdat(c, pb, atom);
6185  return err;
6186 }
6187 
6189 {
6190 #if CONFIG_ZLIB
6191  FFIOContext ctx;
6192  uint8_t *cmov_data;
6193  uint8_t *moov_data; /* uncompressed data */
6194  long cmov_len, moov_len;
6195  int ret = -1;
6196 
6197  avio_rb32(pb); /* dcom atom */
6198  if (avio_rl32(pb) != MKTAG('d','c','o','m'))
6199  return AVERROR_INVALIDDATA;
6200  if (avio_rl32(pb) != MKTAG('z','l','i','b')) {
6201  av_log(c->fc, AV_LOG_ERROR, "unknown compression for cmov atom !\n");
6202  return AVERROR_INVALIDDATA;
6203  }
6204  avio_rb32(pb); /* cmvd atom */
6205  if (avio_rl32(pb) != MKTAG('c','m','v','d'))
6206  return AVERROR_INVALIDDATA;
6207  moov_len = avio_rb32(pb); /* uncompressed size */
6208  cmov_len = atom.size - 6 * 4;
6209 
6210  cmov_data = av_malloc(cmov_len);
6211  if (!cmov_data)
6212  return AVERROR(ENOMEM);
6213  moov_data = av_malloc(moov_len);
6214  if (!moov_data) {
6215  av_free(cmov_data);
6216  return AVERROR(ENOMEM);
6217  }
6218  ret = ffio_read_size(pb, cmov_data, cmov_len);
6219  if (ret < 0)
6220  goto free_and_return;
6221 
6223  if (uncompress (moov_data, (uLongf *) &moov_len, (const Bytef *)cmov_data, cmov_len) != Z_OK)
6224  goto free_and_return;
6225  ffio_init_read_context(&ctx, moov_data, moov_len);
6226  ctx.pub.seekable = AVIO_SEEKABLE_NORMAL;
6227  atom.type = MKTAG('m','o','o','v');
6228  atom.size = moov_len;
6229  ret = mov_read_default(c, &ctx.pub, atom);
6230 free_and_return:
6231  av_free(moov_data);
6232  av_free(cmov_data);
6233  return ret;
6234 #else
6235  av_log(c->fc, AV_LOG_ERROR, "this file requires zlib support compiled in\n");
6236  return AVERROR(ENOSYS);
6237 #endif
6238 }
6239 
6240 /* edit list atom */
6242 {
6243  MOVStreamContext *sc;
6244  int i, edit_count, version;
6245  int64_t elst_entry_size;
6246 
6247  if (c->fc->nb_streams < 1 || c->ignore_editlist)
6248  return 0;
6249  sc = c->fc->streams[c->fc->nb_streams-1]->priv_data;
6250 
6251  version = avio_r8(pb); /* version */
6252  avio_rb24(pb); /* flags */
6253  edit_count = avio_rb32(pb); /* entries */
6254  atom.size -= 8;
6255 
6256  elst_entry_size = version == 1 ? 20 : 12;
6257  if (atom.size != edit_count * elst_entry_size) {
6258  if (c->fc->strict_std_compliance >= FF_COMPLIANCE_STRICT) {
6259  av_log(c->fc, AV_LOG_ERROR, "Invalid edit list entry_count: %d for elst atom of size: %"PRId64" bytes.\n",
6260  edit_count, atom.size + 8);
6261  return AVERROR_INVALIDDATA;
6262  } else {
6263  edit_count = atom.size / elst_entry_size;
6264  if (edit_count * elst_entry_size != atom.size) {
6265  av_log(c->fc, AV_LOG_WARNING, "ELST atom of %"PRId64" bytes, bigger than %d entries.\n", atom.size, edit_count);
6266  }
6267  }
6268  }
6269 
6270  if (!edit_count)
6271  return 0;
6272  if (sc->elst_data)
6273  av_log(c->fc, AV_LOG_WARNING, "Duplicated ELST atom\n");
6274  av_free(sc->elst_data);
6275  sc->elst_count = 0;
6276  sc->elst_data = av_malloc_array(edit_count, sizeof(*sc->elst_data));
6277  if (!sc->elst_data)
6278  return AVERROR(ENOMEM);
6279 
6280  av_log(c->fc, AV_LOG_TRACE, "track[%u].edit_count = %i\n", c->fc->nb_streams - 1, edit_count);
6281  for (i = 0; i < edit_count && atom.size > 0 && !pb->eof_reached; i++) {
6282  MOVElst *e = &sc->elst_data[i];
6283 
6284  if (version == 1) {
6285  e->duration = avio_rb64(pb);
6286  e->time = avio_rb64(pb);
6287  atom.size -= 16;
6288  } else {
6289  e->duration = avio_rb32(pb); /* segment duration */
6290  e->time = (int32_t)avio_rb32(pb); /* media time */
6291  atom.size -= 8;
6292  }
6293  e->rate = avio_rb32(pb) / 65536.0;
6294  atom.size -= 4;
6295  av_log(c->fc, AV_LOG_TRACE, "duration=%"PRId64" time=%"PRId64" rate=%f\n",
6296  e->duration, e->time, e->rate);
6297 
6298  if (e->time < 0 && e->time != -1 &&
6299  c->fc->strict_std_compliance >= FF_COMPLIANCE_STRICT) {
6300  av_log(c->fc, AV_LOG_ERROR, "Track %d, edit %d: Invalid edit list media time=%"PRId64"\n",
6301  c->fc->nb_streams-1, i, e->time);
6302  return AVERROR_INVALIDDATA;
6303  }
6304  if (e->duration < 0) {
6305  av_log(c->fc, AV_LOG_ERROR, "Track %d, edit %d: Invalid edit list duration=%"PRId64"\n",
6306  c->fc->nb_streams-1, i, e->duration);
6307  return AVERROR_INVALIDDATA;
6308  }
6309  }
6310  sc->elst_count = i;
6311 
6312  return 0;
6313 }
6314 
6316 {
6317  MOVStreamContext *sc;
6318 
6319  if (c->fc->nb_streams < 1)
6320  return AVERROR_INVALIDDATA;
6321  sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
6322  sc->timecode_track = avio_rb32(pb);
6323  return 0;
6324 }
6325 
6327 {
6328  AVStream *st;
6329  int version, color_range, color_primaries, color_trc, color_space;
6330 
6331  if (c->fc->nb_streams < 1)
6332  return 0;
6333  st = c->fc->streams[c->fc->nb_streams - 1];
6334 
6335  if (atom.size < 5) {
6336  av_log(c->fc, AV_LOG_ERROR, "Empty VP Codec Configuration box\n");
6337  return AVERROR_INVALIDDATA;
6338  }
6339 
6340  version = avio_r8(pb);
6341  if (version != 1) {
6342  av_log(c->fc, AV_LOG_WARNING, "Unsupported VP Codec Configuration box version %d\n", version);
6343  return 0;
6344  }
6345  avio_skip(pb, 3); /* flags */
6346 
6347  avio_skip(pb, 2); /* profile + level */
6348  color_range = avio_r8(pb); /* bitDepth, chromaSubsampling, videoFullRangeFlag */
6349  color_primaries = avio_r8(pb);
6350  color_trc = avio_r8(pb);
6351  color_space = avio_r8(pb);
6352  if (avio_rb16(pb)) /* codecIntializationDataSize */
6353  return AVERROR_INVALIDDATA;
6354 
6357  if (!av_color_transfer_name(color_trc))
6358  color_trc = AVCOL_TRC_UNSPECIFIED;
6359  if (!av_color_space_name(color_space))
6360  color_space = AVCOL_SPC_UNSPECIFIED;
6361 
6364  st->codecpar->color_trc = color_trc;
6365  st->codecpar->color_space = color_space;
6366 
6367  return 0;
6368 }
6369 
6371 {
6372  MOVStreamContext *sc;
6373  int i, version;
6374 
6375  if (c->fc->nb_streams < 1)
6376  return AVERROR_INVALIDDATA;
6377 
6378  sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
6379 
6380  if (atom.size < 5) {
6381  av_log(c->fc, AV_LOG_ERROR, "Empty Mastering Display Metadata box\n");
6382  return AVERROR_INVALIDDATA;
6383  }
6384 
6385  version = avio_r8(pb);
6386  if (version) {
6387  av_log(c->fc, AV_LOG_WARNING, "Unsupported Mastering Display Metadata box version %d\n", version);
6388  return 0;
6389  }
6390  if (sc->mastering) {
6391  av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicate Mastering Display Metadata\n");
6392  return 0;
6393  }
6394 
6395  avio_skip(pb, 3); /* flags */
6396 
6398  if (!sc->mastering)
6399  return AVERROR(ENOMEM);
6400 
6401  for (i = 0; i < 3; i++) {
6402  sc->mastering->display_primaries[i][0] = av_make_q(avio_rb16(pb), 1 << 16);
6403  sc->mastering->display_primaries[i][1] = av_make_q(avio_rb16(pb), 1 << 16);
6404  }
6405  sc->mastering->white_point[0] = av_make_q(avio_rb16(pb), 1 << 16);
6406  sc->mastering->white_point[1] = av_make_q(avio_rb16(pb), 1 << 16);
6407 
6408  sc->mastering->max_luminance = av_make_q(avio_rb32(pb), 1 << 8);
6409  sc->mastering->min_luminance = av_make_q(avio_rb32(pb), 1 << 14);
6410 
6411  sc->mastering->has_primaries = 1;
6412  sc->mastering->has_luminance = 1;
6413 
6414  return 0;
6415 }
6416 
6418 {
6419  MOVStreamContext *sc;
6420  const int mapping[3] = {1, 2, 0};
6421  const int chroma_den = 50000;
6422  const int luma_den = 10000;
6423  int i;
6424 
6425  if (c->fc->nb_streams < 1)
6426  return AVERROR_INVALIDDATA;
6427 
6428  sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
6429 
6430  if (atom.size < 24) {
6431  av_log(c->fc, AV_LOG_ERROR, "Invalid Mastering Display Color Volume box\n");
6432  return AVERROR_INVALIDDATA;
6433  }
6434 
6435  if (sc->mastering) {
6436  av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicate Mastering Display Color Volume\n");
6437  return 0;
6438  }
6439 
6441  if (!sc->mastering)
6442  return AVERROR(ENOMEM);
6443 
6444  for (i = 0; i < 3; i++) {
6445  const int j = mapping[i];
6446  sc->mastering->display_primaries[j][0] = av_make_q(avio_rb16(pb), chroma_den);
6447  sc->mastering->display_primaries[j][1] = av_make_q(avio_rb16(pb), chroma_den);
6448  }
6449  sc->mastering->white_point[0] = av_make_q(avio_rb16(pb), chroma_den);
6450  sc->mastering->white_point[1] = av_make_q(avio_rb16(pb), chroma_den);
6451 
6452  sc->mastering->max_luminance = av_make_q(avio_rb32(pb), luma_den);
6453  sc->mastering->min_luminance = av_make_q(avio_rb32(pb), luma_den);
6454 
6455  sc->mastering->has_luminance = 1;
6456  sc->mastering->has_primaries = 1;
6457 
6458  return 0;
6459 }
6460 
6462 {
6463  MOVStreamContext *sc;
6464  int version;
6465 
6466  if (c->fc->nb_streams < 1)
6467  return AVERROR_INVALIDDATA;
6468 
6469  sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
6470 
6471  if (atom.size < 5) {
6472  av_log(c->fc, AV_LOG_ERROR, "Empty Content Light Level box\n");
6473  return AVERROR_INVALIDDATA;
6474  }
6475 
6476  version = avio_r8(pb);
6477  if (version) {
6478  av_log(c->fc, AV_LOG_WARNING, "Unsupported Content Light Level box version %d\n", version);
6479  return 0;
6480  }
6481  avio_skip(pb, 3); /* flags */
6482 
6483  if (sc->coll){
6484  av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicate COLL\n");
6485  return 0;
6486  }
6487 
6489  if (!sc->coll)
6490  return AVERROR(ENOMEM);
6491 
6492  sc->coll->MaxCLL = avio_rb16(pb);
6493  sc->coll->MaxFALL = avio_rb16(pb);
6494 
6495  return 0;
6496 }
6497 
6499 {
6500  MOVStreamContext *sc;
6501 
6502  if (c->fc->nb_streams < 1)
6503  return AVERROR_INVALIDDATA;
6504 
6505  sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
6506 
6507  if (atom.size < 4) {
6508  av_log(c->fc, AV_LOG_ERROR, "Empty Content Light Level Info box\n");
6509  return AVERROR_INVALIDDATA;
6510  }
6511 
6512  if (sc->coll){
6513  av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicate CLLI/COLL\n");
6514  return 0;
6515  }
6516 
6518  if (!sc->coll)
6519  return AVERROR(ENOMEM);
6520 
6521  sc->coll->MaxCLL = avio_rb16(pb);
6522  sc->coll->MaxFALL = avio_rb16(pb);
6523 
6524  return 0;
6525 }
6526 
6528 {
6529  MOVStreamContext *sc;
6530  const int illuminance_den = 10000;
6531  const int ambient_den = 50000;
6532  if (c->fc->nb_streams < 1)
6533  return AVERROR_INVALIDDATA;
6534  sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
6535  if (atom.size < 6) {
6536  av_log(c->fc, AV_LOG_ERROR, "Empty Ambient Viewing Environment Info box\n");
6537  return AVERROR_INVALIDDATA;
6538  }
6539  if (sc->ambient){
6540  av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicate AMVE\n");
6541  return 0;
6542  }
6544  if (!sc->ambient)
6545  return AVERROR(ENOMEM);
6546  sc->ambient->ambient_illuminance = av_make_q(avio_rb32(pb), illuminance_den);
6547  sc->ambient->ambient_light_x = av_make_q(avio_rb16(pb), ambient_den);
6548  sc->ambient->ambient_light_y = av_make_q(avio_rb16(pb), ambient_den);
6549  return 0;
6550 }
6551 
6553 {
6554  AVStream *st;
6555  MOVStreamContext *sc;
6556  enum AVStereo3DType type;
6557  int mode;
6558 
6559  if (c->fc->nb_streams < 1)
6560  return 0;
6561 
6562  st = c->fc->streams[c->fc->nb_streams - 1];
6563  sc = st->priv_data;
6564 
6565  if (atom.size < 5) {
6566  av_log(c->fc, AV_LOG_ERROR, "Empty stereoscopic video box\n");
6567  return AVERROR_INVALIDDATA;
6568  }
6569 
6570  if (sc->stereo3d)
6571  return AVERROR_INVALIDDATA;
6572 
6573  avio_skip(pb, 4); /* version + flags */
6574 
6575  mode = avio_r8(pb);
6576  switch (mode) {
6577  case 0:
6578  type = AV_STEREO3D_2D;
6579  break;
6580  case 1:
6582  break;
6583  case 2:
6585  break;
6586  default:
6587  av_log(c->fc, AV_LOG_WARNING, "Unknown st3d mode value %d\n", mode);
6588  return 0;
6589  }
6590 
6592  if (!sc->stereo3d)
6593  return AVERROR(ENOMEM);
6594 
6595  sc->stereo3d->type = type;
6596  return 0;
6597 }
6598 
6600 {
6601  AVStream *st;
6602  MOVStreamContext *sc;
6603  int size, version, layout;
6604  int32_t yaw, pitch, roll;
6605  uint32_t l = 0, t = 0, r = 0, b = 0;
6606  uint32_t tag, padding = 0;
6607  enum AVSphericalProjection projection;
6608 
6609  if (c->fc->nb_streams < 1)
6610  return 0;
6611 
6612  st = c->fc->streams[c->fc->nb_streams - 1];
6613  sc = st->priv_data;
6614 
6615  if (atom.size < 8) {
6616  av_log(c->fc, AV_LOG_ERROR, "Empty spherical video box\n");
6617  return AVERROR_INVALIDDATA;
6618  }
6619 
6620  size = avio_rb32(pb);
6621  if (size <= 12 || size > atom.size)
6622  return AVERROR_INVALIDDATA;
6623 
6624  tag = avio_rl32(pb);
6625  if (tag != MKTAG('s','v','h','d')) {
6626  av_log(c->fc, AV_LOG_ERROR, "Missing spherical video header\n");
6627  return 0;
6628  }
6629  version = avio_r8(pb);
6630  if (version != 0) {
6631  av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
6632  version);
6633  return 0;
6634  }
6635  avio_skip(pb, 3); /* flags */
6636  avio_skip(pb, size - 12); /* metadata_source */
6637 
6638  size = avio_rb32(pb);
6639  if (size > atom.size)
6640  return AVERROR_INVALIDDATA;
6641 
6642  tag = avio_rl32(pb);
6643  if (tag != MKTAG('p','r','o','j')) {
6644  av_log(c->fc, AV_LOG_ERROR, "Missing projection box\n");
6645  return 0;
6646  }
6647 
6648  size = avio_rb32(pb);
6649  if (size > atom.size)
6650  return AVERROR_INVALIDDATA;
6651 
6652  tag = avio_rl32(pb);
6653  if (tag != MKTAG('p','r','h','d')) {
6654  av_log(c->fc, AV_LOG_ERROR, "Missing projection header box\n");
6655  return 0;
6656  }
6657  version = avio_r8(pb);
6658  if (version != 0) {
6659  av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
6660  version);
6661  return 0;
6662  }
6663  avio_skip(pb, 3); /* flags */
6664 
6665  /* 16.16 fixed point */
6666  yaw = avio_rb32(pb);
6667  pitch = avio_rb32(pb);
6668  roll = avio_rb32(pb);
6669 
6670  size = avio_rb32(pb);
6671  if (size > atom.size)
6672  return AVERROR_INVALIDDATA;
6673 
6674  tag = avio_rl32(pb);
6675  version = avio_r8(pb);
6676  if (version != 0) {
6677  av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
6678  version);
6679  return 0;
6680  }
6681  avio_skip(pb, 3); /* flags */
6682  switch (tag) {
6683  case MKTAG('c','b','m','p'):
6684  layout = avio_rb32(pb);
6685  if (layout) {
6686  av_log(c->fc, AV_LOG_WARNING,
6687  "Unsupported cubemap layout %d\n", layout);
6688  return 0;
6689  }
6690  projection = AV_SPHERICAL_CUBEMAP;
6691  padding = avio_rb32(pb);
6692  break;
6693  case MKTAG('e','q','u','i'):
6694  t = avio_rb32(pb);
6695  b = avio_rb32(pb);
6696  l = avio_rb32(pb);
6697  r = avio_rb32(pb);
6698 
6699  if (b >= UINT_MAX - t || r >= UINT_MAX - l) {
6700  av_log(c->fc, AV_LOG_ERROR,
6701  "Invalid bounding rectangle coordinates "
6702  "%"PRIu32",%"PRIu32",%"PRIu32",%"PRIu32"\n", l, t, r, b);
6703  return AVERROR_INVALIDDATA;
6704  }
6705 
6706  if (l || t || r || b)
6707  projection = AV_SPHERICAL_EQUIRECTANGULAR_TILE;
6708  else
6709  projection = AV_SPHERICAL_EQUIRECTANGULAR;
6710  break;
6711  default:
6712  av_log(c->fc, AV_LOG_ERROR, "Unknown projection type: %s\n", av_fourcc2str(tag));
6713  return 0;
6714  }
6715 
6717  if (!sc->spherical)
6718  return AVERROR(ENOMEM);
6719 
6720  sc->spherical->projection = projection;
6721 
6722  sc->spherical->yaw = yaw;
6723  sc->spherical->pitch = pitch;
6724  sc->spherical->roll = roll;
6725 
6726  sc->spherical->padding = padding;
6727 
6728  sc->spherical->bound_left = l;
6729  sc->spherical->bound_top = t;
6730  sc->spherical->bound_right = r;
6731  sc->spherical->bound_bottom = b;
6732 
6733  return 0;
6734 }
6735 
6737 {
6738  AVStream *st;
6739  MOVStreamContext *sc;
6740  int size;
6741  uint32_t tag;
6742  enum AVSphericalProjection projection;
6743 
6744  if (c->fc->nb_streams < 1)
6745  return 0;
6746 
6747  st = c->fc->streams[c->fc->nb_streams - 1];
6748  sc = st->priv_data;
6749 
6750  if (atom.size != 16) {
6751  av_log(c->fc, AV_LOG_ERROR, "Invalid size for proj box: %"PRIu64"\n", atom.size);
6752  return AVERROR_INVALIDDATA;
6753  }
6754 
6755  size = avio_rb32(pb);
6756  if (size != 16) {
6757  av_log(c->fc, AV_LOG_ERROR, "Invalid size for prji box: %d\n", size);
6758  return AVERROR_INVALIDDATA;
6759  }
6760 
6761  tag = avio_rl32(pb);
6762  if (tag != MKTAG('p','r','j','i')) {
6763  av_log(c->fc, AV_LOG_ERROR, "Invalid child box of proj box: 0x%08X\n", tag);
6764  return AVERROR_INVALIDDATA;
6765  }
6766 
6767  avio_skip(pb, 1); // version
6768  avio_skip(pb, 3); // flags
6769 
6770  tag = avio_rl32(pb);
6771  switch (tag) {
6772  case MKTAG('r','e','c','t'):
6773  projection = AV_SPHERICAL_RECTILINEAR;
6774  break;
6775  case MKTAG('e','q','u','i'):
6776  projection = AV_SPHERICAL_EQUIRECTANGULAR;
6777  break;
6778  case MKTAG('h','e','q','u'):
6779  projection = AV_SPHERICAL_HALF_EQUIRECTANGULAR;
6780  break;
6781  case MKTAG('f','i','s','h'):
6782  projection = AV_SPHERICAL_FISHEYE;
6783  break;
6784  default:
6785  av_log(c->fc, AV_LOG_ERROR, "Invalid projection type in prji box: 0x%08X\n", tag);
6786  return AVERROR_INVALIDDATA;
6787  }
6788 
6790  if (!sc->spherical)
6791  return AVERROR(ENOMEM);
6792 
6793  sc->spherical->projection = projection;
6794 
6795  return 0;
6796 }
6797 
6799 {
6800  AVStream *st;
6801  MOVStreamContext *sc;
6802  int size, flags = 0;
6803  int64_t remaining;
6804  uint32_t tag, baseline = 0;
6807  enum AVStereo3DPrimaryEye primary_eye = AV_PRIMARY_EYE_NONE;
6808  AVRational horizontal_disparity_adjustment = { 0, 1 };
6809 
6810  if (c->fc->nb_streams < 1)
6811  return 0;
6812 
6813  st = c->fc->streams[c->fc->nb_streams - 1];
6814  sc = st->priv_data;
6815 
6816  remaining = atom.size;
6817  while (remaining > 0) {
6818  size = avio_rb32(pb);
6819  if (size < 8 || size > remaining ) {
6820  av_log(c->fc, AV_LOG_ERROR, "Invalid child size in eyes box\n");
6821  return AVERROR_INVALIDDATA;
6822  }
6823 
6824  tag = avio_rl32(pb);
6825  switch (tag) {
6826  case MKTAG('s','t','r','i'): {
6827  int has_right, has_left;
6828  uint8_t tmp;
6829  if (size != 13) {
6830  av_log(c->fc, AV_LOG_ERROR, "Invalid size of stri box: %d\n", size);
6831  return AVERROR_INVALIDDATA;
6832  }
6833  avio_skip(pb, 1); // version
6834  avio_skip(pb, 3); // flags
6835 
6836  tmp = avio_r8(pb);
6837 
6838  // eye_views_reversed
6839  if (tmp & 8) {
6841  }
6842  // has_additional_views
6843  if (tmp & 4) {
6844  // skip...
6845  }
6846 
6847  has_right = tmp & 2; // has_right_eye_view
6848  has_left = tmp & 1; // has_left_eye_view
6849 
6850  if (has_left && has_right)
6851  view = AV_STEREO3D_VIEW_PACKED;
6852  else if (has_left)
6853  view = AV_STEREO3D_VIEW_LEFT;
6854  else if (has_right)
6855  view = AV_STEREO3D_VIEW_RIGHT;
6856  if (has_left || has_right)
6858 
6859  break;
6860  }
6861  case MKTAG('h','e','r','o'): {
6862  int tmp;
6863  if (size != 13) {
6864  av_log(c->fc, AV_LOG_ERROR, "Invalid size of hero box: %d\n", size);
6865  return AVERROR_INVALIDDATA;
6866  }
6867  avio_skip(pb, 1); // version
6868  avio_skip(pb, 3); // flags
6869 
6870  tmp = avio_r8(pb);
6871  if (tmp == 0)
6872  primary_eye = AV_PRIMARY_EYE_NONE;
6873  else if (tmp == 1)
6874  primary_eye = AV_PRIMARY_EYE_LEFT;
6875  else if (tmp == 2)
6876  primary_eye = AV_PRIMARY_EYE_RIGHT;
6877  else
6878  av_log(c->fc, AV_LOG_WARNING, "Unknown hero eye type: %d\n", tmp);
6879 
6880  break;
6881  }
6882  case MKTAG('c','a','m','s'): {
6883  uint32_t subtag;
6884  int subsize;
6885  if (size != 24) {
6886  av_log(c->fc, AV_LOG_ERROR, "Invalid size of cams box: %d\n", size);
6887  return AVERROR_INVALIDDATA;
6888  }
6889 
6890  subsize = avio_rb32(pb);
6891  if (subsize != 16) {
6892  av_log(c->fc, AV_LOG_ERROR, "Invalid size of blin box: %d\n", size);
6893  return AVERROR_INVALIDDATA;
6894  }
6895 
6896  subtag = avio_rl32(pb);
6897  if (subtag != MKTAG('b','l','i','n')) {
6898  av_log(c->fc, AV_LOG_ERROR, "Expected blin box, got 0x%08X\n", subtag);
6899  return AVERROR_INVALIDDATA;
6900  }
6901 
6902  avio_skip(pb, 1); // version
6903  avio_skip(pb, 3); // flags
6904 
6905  baseline = avio_rb32(pb);
6906 
6907  break;
6908  }
6909  case MKTAG('c','m','f','y'): {
6910  uint32_t subtag;
6911  int subsize;
6912  int32_t adjustment;
6913  if (size != 24) {
6914  av_log(c->fc, AV_LOG_ERROR, "Invalid size of cmfy box: %d\n", size);
6915  return AVERROR_INVALIDDATA;
6916  }
6917 
6918  subsize = avio_rb32(pb);
6919  if (subsize != 16) {
6920  av_log(c->fc, AV_LOG_ERROR, "Invalid size of dadj box: %d\n", size);
6921  return AVERROR_INVALIDDATA;
6922  }
6923 
6924  subtag = avio_rl32(pb);
6925  if (subtag != MKTAG('d','a','d','j')) {
6926  av_log(c->fc, AV_LOG_ERROR, "Expected dadj box, got 0x%08X\n", subtag);
6927  return AVERROR_INVALIDDATA;
6928  }
6929 
6930  avio_skip(pb, 1); // version
6931  avio_skip(pb, 3); // flags
6932 
6933  adjustment = (int32_t) avio_rb32(pb);
6934 
6935  horizontal_disparity_adjustment.num = (int) adjustment;
6936  horizontal_disparity_adjustment.den = 10000;
6937 
6938  break;
6939  }
6940  default:
6941  av_log(c->fc, AV_LOG_WARNING, "Unknown tag in eyes: 0x%08X\n", tag);
6942  avio_skip(pb, size - 8);
6943  break;
6944  }
6945  remaining -= size;
6946  }
6947 
6948  if (remaining != 0) {
6949  av_log(c->fc, AV_LOG_ERROR, "Broken eyes box\n");
6950  return AVERROR_INVALIDDATA;
6951  }
6952 
6953  if (type == AV_STEREO3D_2D)
6954  return 0;
6955 
6956  if (!sc->stereo3d) {
6958  if (!sc->stereo3d)
6959  return AVERROR(ENOMEM);
6960  }
6961 
6962  sc->stereo3d->flags = flags;
6963  sc->stereo3d->type = type;
6964  sc->stereo3d->view = view;
6965  sc->stereo3d->primary_eye = primary_eye;
6966  sc->stereo3d->baseline = baseline;
6967  sc->stereo3d->horizontal_disparity_adjustment = horizontal_disparity_adjustment;
6968 
6969  return 0;
6970 }
6971 
6973 {
6974  int size;
6975  int64_t remaining;
6976  uint32_t tag;
6977 
6978  if (c->fc->nb_streams < 1)
6979  return 0;
6980 
6981  if (atom.size < 8) {
6982  av_log(c->fc, AV_LOG_ERROR, "Empty video extension usage box\n");
6983  return AVERROR_INVALIDDATA;
6984  }
6985 
6986  remaining = atom.size;
6987  while (remaining > 0) {
6988  size = avio_rb32(pb);
6989  if (size < 8 || size > remaining ) {
6990  av_log(c->fc, AV_LOG_ERROR, "Invalid child size in vexu box\n");
6991  return AVERROR_INVALIDDATA;
6992  }
6993 
6994  tag = avio_rl32(pb);
6995  switch (tag) {
6996  case MKTAG('p','r','o','j'): {
6997  MOVAtom proj = { tag, size - 8 };
6998  int ret = mov_read_vexu_proj(c, pb, proj);
6999  if (ret < 0)
7000  return ret;
7001  break;
7002  }
7003  case MKTAG('e','y','e','s'): {
7004  MOVAtom eyes = { tag, size - 8 };
7005  int ret = mov_read_eyes(c, pb, eyes);
7006  if (ret < 0)
7007  return ret;
7008  break;
7009  }
7010  default:
7011  av_log(c->fc, AV_LOG_WARNING, "Unknown tag in vexu: 0x%08X\n", tag);
7012  avio_skip(pb, size - 8);
7013  break;
7014  }
7015  remaining -= size;
7016  }
7017 
7018  if (remaining != 0) {
7019  av_log(c->fc, AV_LOG_ERROR, "Broken vexu box\n");
7020  return AVERROR_INVALIDDATA;
7021  }
7022 
7023  return 0;
7024 }
7025 
7027 {
7028  AVStream *st;
7029  MOVStreamContext *sc;
7030 
7031  if (c->fc->nb_streams < 1)
7032  return 0;
7033 
7034  st = c->fc->streams[c->fc->nb_streams - 1];
7035  sc = st->priv_data;
7036 
7037  if (atom.size != 4) {
7038  av_log(c->fc, AV_LOG_ERROR, "Invalid size of hfov box: %"PRIu64"\n", atom.size);
7039  return AVERROR_INVALIDDATA;
7040  }
7041 
7042 
7043  if (!sc->stereo3d) {
7045  if (!sc->stereo3d)
7046  return AVERROR(ENOMEM);
7047  }
7048 
7050  sc->stereo3d->horizontal_field_of_view.den = 1000; // thousands of a degree
7051 
7052  return 0;
7053 }
7054 
7056 {
7057  int ret = 0;
7058  uint8_t *buffer = av_malloc(len + 1);
7059  const char *val;
7060 
7061  if (!buffer)
7062  return AVERROR(ENOMEM);
7063  buffer[len] = '\0';
7064 
7065  ret = ffio_read_size(pb, buffer, len);
7066  if (ret < 0)
7067  goto out;
7068 
7069  /* Check for mandatory keys and values, try to support XML as best-effort */
7070  if (!sc->spherical &&
7071  av_stristr(buffer, "<GSpherical:StitchingSoftware>") &&
7072  (val = av_stristr(buffer, "<GSpherical:Spherical>")) &&
7073  av_stristr(val, "true") &&
7074  (val = av_stristr(buffer, "<GSpherical:Stitched>")) &&
7075  av_stristr(val, "true") &&
7076  (val = av_stristr(buffer, "<GSpherical:ProjectionType>")) &&
7077  av_stristr(val, "equirectangular")) {
7079  if (!sc->spherical)
7080  goto out;
7081 
7083 
7084  if (av_stristr(buffer, "<GSpherical:StereoMode>") && !sc->stereo3d) {
7085  enum AVStereo3DType mode;
7086 
7087  if (av_stristr(buffer, "left-right"))
7089  else if (av_stristr(buffer, "top-bottom"))
7091  else
7092  mode = AV_STEREO3D_2D;
7093 
7095  if (!sc->stereo3d)
7096  goto out;
7097 
7098  sc->stereo3d->type = mode;
7099  }
7100 
7101  /* orientation */
7102  val = av_stristr(buffer, "<GSpherical:InitialViewHeadingDegrees>");
7103  if (val)
7104  sc->spherical->yaw = strtol(val, NULL, 10) * (1 << 16);
7105  val = av_stristr(buffer, "<GSpherical:InitialViewPitchDegrees>");
7106  if (val)
7107  sc->spherical->pitch = strtol(val, NULL, 10) * (1 << 16);
7108  val = av_stristr(buffer, "<GSpherical:InitialViewRollDegrees>");
7109  if (val)
7110  sc->spherical->roll = strtol(val, NULL, 10) * (1 << 16);
7111  }
7112 
7113 out:
7114  av_free(buffer);
7115  return ret;
7116 }
7117 
7119 {
7120  AVStream *st;
7121  MOVStreamContext *sc;
7122  int64_t ret;
7123  AVUUID uuid;
7124  static const AVUUID uuid_isml_manifest = {
7125  0xa5, 0xd4, 0x0b, 0x30, 0xe8, 0x14, 0x11, 0xdd,
7126  0xba, 0x2f, 0x08, 0x00, 0x20, 0x0c, 0x9a, 0x66
7127  };
7128  static const AVUUID uuid_xmp = {
7129  0xbe, 0x7a, 0xcf, 0xcb, 0x97, 0xa9, 0x42, 0xe8,
7130  0x9c, 0x71, 0x99, 0x94, 0x91, 0xe3, 0xaf, 0xac
7131  };
7132  static const AVUUID uuid_spherical = {
7133  0xff, 0xcc, 0x82, 0x63, 0xf8, 0x55, 0x4a, 0x93,
7134  0x88, 0x14, 0x58, 0x7a, 0x02, 0x52, 0x1f, 0xdd,
7135  };
7136 
7137  if (atom.size < AV_UUID_LEN || atom.size >= FFMIN(INT_MAX, SIZE_MAX))
7138  return AVERROR_INVALIDDATA;
7139 
7140  if (c->fc->nb_streams < 1)
7141  return 0;
7142  st = c->fc->streams[c->fc->nb_streams - 1];
7143  sc = st->priv_data;
7144 
7145  ret = ffio_read_size(pb, uuid, AV_UUID_LEN);
7146  if (ret < 0)
7147  return ret;
7148  if (av_uuid_equal(uuid, uuid_isml_manifest)) {
7149  uint8_t *buffer, *ptr;
7150  char *endptr;
7151  size_t len = atom.size - AV_UUID_LEN;
7152 
7153  if (len < 4) {
7154  return AVERROR_INVALIDDATA;
7155  }
7156  ret = avio_skip(pb, 4); // zeroes
7157  len -= 4;
7158 
7159  buffer = av_mallocz(len + 1);
7160  if (!buffer) {
7161  return AVERROR(ENOMEM);
7162  }
7163  ret = ffio_read_size(pb, buffer, len);
7164  if (ret < 0) {
7165  av_free(buffer);
7166  return ret;
7167  }
7168 
7169  ptr = buffer;
7170  while ((ptr = av_stristr(ptr, "systemBitrate=\""))) {
7171  ptr += sizeof("systemBitrate=\"") - 1;
7172  c->bitrates_count++;
7173  c->bitrates = av_realloc_f(c->bitrates, c->bitrates_count, sizeof(*c->bitrates));
7174  if (!c->bitrates) {
7175  c->bitrates_count = 0;
7176  av_free(buffer);
7177  return AVERROR(ENOMEM);
7178  }
7179  errno = 0;
7180  ret = strtol(ptr, &endptr, 10);
7181  if (ret < 0 || errno || *endptr != '"') {
7182  c->bitrates[c->bitrates_count - 1] = 0;
7183  } else {
7184  c->bitrates[c->bitrates_count - 1] = ret;
7185  }
7186  }
7187 
7188  av_free(buffer);
7189  } else if (av_uuid_equal(uuid, uuid_xmp)) {
7190  uint8_t *buffer;
7191  size_t len = atom.size - AV_UUID_LEN;
7192  if (c->export_xmp) {
7193  buffer = av_mallocz(len + 1);
7194  if (!buffer) {
7195  return AVERROR(ENOMEM);
7196  }
7197  ret = ffio_read_size(pb, buffer, len);
7198  if (ret < 0) {
7199  av_free(buffer);
7200  return ret;
7201  }
7202  buffer[len] = '\0';
7203  av_dict_set(&c->fc->metadata, "xmp",
7205  } else {
7206  // skip all uuid atom, which makes it fast for long uuid-xmp file
7207  ret = avio_skip(pb, len);
7208  if (ret < 0)
7209  return ret;
7210  }
7211  } else if (av_uuid_equal(uuid, uuid_spherical)) {
7212  size_t len = atom.size - AV_UUID_LEN;
7213  ret = mov_parse_uuid_spherical(sc, pb, len);
7214  if (ret < 0)
7215  return ret;
7216  if (!sc->spherical)
7217  av_log(c->fc, AV_LOG_WARNING, "Invalid spherical metadata found\n");
7218  }
7219 
7220  return 0;
7221 }
7222 
7224 {
7225  int ret;
7226  uint8_t content[16];
7227 
7228  if (atom.size < 8)
7229  return 0;
7230 
7231  ret = ffio_read_size(pb, content, FFMIN(sizeof(content), atom.size));
7232  if (ret < 0)
7233  return ret;
7234 
7235  if ( !c->found_moov
7236  && !c->found_mdat
7237  && !memcmp(content, "Anevia\x1A\x1A", 8)
7238  && c->use_mfra_for == FF_MOV_FLAG_MFRA_AUTO) {
7239  c->use_mfra_for = FF_MOV_FLAG_MFRA_PTS;
7240  }
7241 
7242  return 0;
7243 }
7244 
7246 {
7247  uint32_t format = avio_rl32(pb);
7248  MOVStreamContext *sc;
7249  enum AVCodecID id;
7250  AVStream *st;
7251 
7252  if (c->fc->nb_streams < 1)
7253  return 0;
7254  st = c->fc->streams[c->fc->nb_streams - 1];
7255  sc = st->priv_data;
7256 
7257  switch (sc->format)
7258  {
7259  case MKTAG('e','n','c','v'): // encrypted video
7260  case MKTAG('e','n','c','a'): // encrypted audio
7261  id = mov_codec_id(st, format);
7262  if (st->codecpar->codec_id != AV_CODEC_ID_NONE &&
7263  st->codecpar->codec_id != id) {
7264  av_log(c->fc, AV_LOG_WARNING,
7265  "ignoring 'frma' atom of '%.4s', stream has codec id %d\n",
7266  (char*)&format, st->codecpar->codec_id);
7267  break;
7268  }
7269 
7270  st->codecpar->codec_id = id;
7271  sc->format = format;
7272  break;
7273 
7274  default:
7275  if (format != sc->format) {
7276  av_log(c->fc, AV_LOG_WARNING,
7277  "ignoring 'frma' atom of '%.4s', stream format is '%.4s'\n",
7278  (char*)&format, (char*)&sc->format);
7279  }
7280  break;
7281  }
7282 
7283  return 0;
7284 }
7285 
7286 /**
7287  * Gets the current encryption info and associated current stream context. If
7288  * we are parsing a track fragment, this will return the specific encryption
7289  * info for this fragment; otherwise this will return the global encryption
7290  * info for the current stream.
7291  */
7293 {
7294  MOVFragmentStreamInfo *frag_stream_info;
7295  AVStream *st;
7296  int i;
7297 
7298  frag_stream_info = get_current_frag_stream_info(&c->frag_index);
7299  if (frag_stream_info) {
7300  for (i = 0; i < c->fc->nb_streams; i++) {
7301  *sc = c->fc->streams[i]->priv_data;
7302  if ((*sc)->id == frag_stream_info->id) {
7303  st = c->fc->streams[i];
7304  break;
7305  }
7306  }
7307  if (i == c->fc->nb_streams)
7308  return 0;
7309  *sc = st->priv_data;
7310 
7311  if (!frag_stream_info->encryption_index) {
7312  // If this stream isn't encrypted, don't create the index.
7313  if (!(*sc)->cenc.default_encrypted_sample)
7314  return 0;
7315  frag_stream_info->encryption_index = av_mallocz(sizeof(*frag_stream_info->encryption_index));
7316  if (!frag_stream_info->encryption_index)
7317  return AVERROR(ENOMEM);
7318  }
7319  *encryption_index = frag_stream_info->encryption_index;
7320  return 1;
7321  } else {
7322  // No current track fragment, using stream level encryption info.
7323 
7324  if (c->fc->nb_streams < 1)
7325  return 0;
7326  st = c->fc->streams[c->fc->nb_streams - 1];
7327  *sc = st->priv_data;
7328 
7329  if (!(*sc)->cenc.encryption_index) {
7330  // If this stream isn't encrypted, don't create the index.
7331  if (!(*sc)->cenc.default_encrypted_sample)
7332  return 0;
7333  (*sc)->cenc.encryption_index = av_mallocz(sizeof(*frag_stream_info->encryption_index));
7334  if (!(*sc)->cenc.encryption_index)
7335  return AVERROR(ENOMEM);
7336  }
7337 
7338  *encryption_index = (*sc)->cenc.encryption_index;
7339  return 1;
7340  }
7341 }
7342 
7344 {
7345  int i, ret;
7346  unsigned int subsample_count;
7347  AVSubsampleEncryptionInfo *subsamples;
7348 
7349  if (!sc->cenc.default_encrypted_sample) {
7350  av_log(c->fc, AV_LOG_ERROR, "Missing schm or tenc\n");
7351  return AVERROR_INVALIDDATA;
7352  }
7353 
7354  if (sc->cenc.per_sample_iv_size || use_subsamples) {
7356  if (!*sample)
7357  return AVERROR(ENOMEM);
7358  } else
7359  *sample = NULL;
7360 
7361  if (sc->cenc.per_sample_iv_size != 0) {
7362  if ((ret = ffio_read_size(pb, (*sample)->iv, sc->cenc.per_sample_iv_size)) < 0) {
7363  av_log(c->fc, AV_LOG_ERROR, "failed to read the initialization vector\n");
7365  *sample = NULL;
7366  return ret;
7367  }
7368  }
7369 
7370  if (use_subsamples) {
7371  subsample_count = avio_rb16(pb);
7372  av_free((*sample)->subsamples);
7373  (*sample)->subsamples = av_calloc(subsample_count, sizeof(*subsamples));
7374  if (!(*sample)->subsamples) {
7376  *sample = NULL;
7377  return AVERROR(ENOMEM);
7378  }
7379 
7380  for (i = 0; i < subsample_count && !pb->eof_reached; i++) {
7381  (*sample)->subsamples[i].bytes_of_clear_data = avio_rb16(pb);
7382  (*sample)->subsamples[i].bytes_of_protected_data = avio_rb32(pb);
7383  }
7384 
7385  if (pb->eof_reached) {
7386  av_log(c->fc, AV_LOG_ERROR, "hit EOF while reading sub-sample encryption info\n");
7388  *sample = NULL;
7389  return AVERROR_INVALIDDATA;
7390  }
7391  (*sample)->subsample_count = subsample_count;
7392  }
7393 
7394  return 0;
7395 }
7396 
7398 {
7399  AVEncryptionInfo **encrypted_samples;
7400  MOVEncryptionIndex *encryption_index;
7401  MOVStreamContext *sc;
7402  int use_subsamples, ret;
7403  unsigned int sample_count, i, alloc_size = 0;
7404 
7405  ret = get_current_encryption_info(c, &encryption_index, &sc);
7406  if (ret != 1)
7407  return ret;
7408 
7409  if (encryption_index->nb_encrypted_samples) {
7410  // This can happen if we have both saio/saiz and senc atoms.
7411  av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in senc\n");
7412  return 0;
7413  }
7414 
7415  avio_r8(pb); /* version */
7416  use_subsamples = avio_rb24(pb) & 0x02; /* flags */
7417 
7418  sample_count = avio_rb32(pb);
7419  if (sample_count >= INT_MAX / sizeof(*encrypted_samples))
7420  return AVERROR(ENOMEM);
7421 
7422  for (i = 0; i < sample_count; i++) {
7423  unsigned int min_samples = FFMIN(FFMAX(i + 1, 1024 * 1024), sample_count);
7424  encrypted_samples = av_fast_realloc(encryption_index->encrypted_samples, &alloc_size,
7425  min_samples * sizeof(*encrypted_samples));
7426  if (encrypted_samples) {
7427  encryption_index->encrypted_samples = encrypted_samples;
7428 
7430  c, pb, sc, &encryption_index->encrypted_samples[i], use_subsamples);
7431  } else {
7432  ret = AVERROR(ENOMEM);
7433  }
7434  if (pb->eof_reached) {
7435  av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading senc\n");
7436  if (ret >= 0)
7437  av_encryption_info_free(encryption_index->encrypted_samples[i]);
7439  }
7440 
7441  if (ret < 0) {
7442  for (; i > 0; i--)
7443  av_encryption_info_free(encryption_index->encrypted_samples[i - 1]);
7444  av_freep(&encryption_index->encrypted_samples);
7445  return ret;
7446  }
7447  }
7448  encryption_index->nb_encrypted_samples = sample_count;
7449 
7450  return 0;
7451 }
7452 
7454 {
7455  AVEncryptionInfo **sample, **encrypted_samples;
7456  int64_t prev_pos;
7457  size_t sample_count, sample_info_size, i;
7458  int ret = 0;
7459  unsigned int alloc_size = 0;
7460 
7461  if (encryption_index->nb_encrypted_samples)
7462  return 0;
7463  sample_count = encryption_index->auxiliary_info_sample_count;
7464  if (encryption_index->auxiliary_offsets_count != 1) {
7465  av_log(c->fc, AV_LOG_ERROR, "Multiple auxiliary info chunks are not supported\n");
7466  return AVERROR_PATCHWELCOME;
7467  }
7468  if (sample_count >= INT_MAX / sizeof(*encrypted_samples))
7469  return AVERROR(ENOMEM);
7470 
7471  prev_pos = avio_tell(pb);
7472  if (!(pb->seekable & AVIO_SEEKABLE_NORMAL) ||
7473  avio_seek(pb, encryption_index->auxiliary_offsets[0], SEEK_SET) != encryption_index->auxiliary_offsets[0]) {
7474  av_log(c->fc, AV_LOG_INFO, "Failed to seek for auxiliary info, will only parse senc atoms for encryption info\n");
7475  goto finish;
7476  }
7477 
7478  for (i = 0; i < sample_count && !pb->eof_reached; i++) {
7479  unsigned int min_samples = FFMIN(FFMAX(i + 1, 1024 * 1024), sample_count);
7480  encrypted_samples = av_fast_realloc(encryption_index->encrypted_samples, &alloc_size,
7481  min_samples * sizeof(*encrypted_samples));
7482  if (!encrypted_samples) {
7483  ret = AVERROR(ENOMEM);
7484  goto finish;
7485  }
7486  encryption_index->encrypted_samples = encrypted_samples;
7487 
7488  sample = &encryption_index->encrypted_samples[i];
7489  sample_info_size = encryption_index->auxiliary_info_default_size
7490  ? encryption_index->auxiliary_info_default_size
7491  : encryption_index->auxiliary_info_sizes[i];
7492 
7493  ret = mov_read_sample_encryption_info(c, pb, sc, sample, sample_info_size > sc->cenc.per_sample_iv_size);
7494  if (ret < 0)
7495  goto finish;
7496  }
7497  if (pb->eof_reached) {
7498  av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading auxiliary info\n");
7500  } else {
7501  encryption_index->nb_encrypted_samples = sample_count;
7502  }
7503 
7504 finish:
7505  avio_seek(pb, prev_pos, SEEK_SET);
7506  if (ret < 0) {
7507  for (; i > 0; i--) {
7508  av_encryption_info_free(encryption_index->encrypted_samples[i - 1]);
7509  }
7510  av_freep(&encryption_index->encrypted_samples);
7511  }
7512  return ret;
7513 }
7514 
7516 {
7517  MOVEncryptionIndex *encryption_index;
7518  MOVStreamContext *sc;
7519  int ret;
7520  unsigned int sample_count, aux_info_type, aux_info_param;
7521 
7522  ret = get_current_encryption_info(c, &encryption_index, &sc);
7523  if (ret != 1)
7524  return ret;
7525 
7526  if (encryption_index->nb_encrypted_samples) {
7527  // This can happen if we have both saio/saiz and senc atoms.
7528  av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in saiz\n");
7529  return 0;
7530  }
7531 
7532  if (encryption_index->auxiliary_info_sample_count) {
7533  av_log(c->fc, AV_LOG_ERROR, "Duplicate saiz atom\n");
7534  return AVERROR_INVALIDDATA;
7535  }
7536 
7537  avio_r8(pb); /* version */
7538  if (avio_rb24(pb) & 0x01) { /* flags */
7539  aux_info_type = avio_rb32(pb);
7540  aux_info_param = avio_rb32(pb);
7541  if (sc->cenc.default_encrypted_sample) {
7542  if (aux_info_type != sc->cenc.default_encrypted_sample->scheme) {
7543  av_log(c->fc, AV_LOG_DEBUG, "Ignoring saiz box with non-zero aux_info_type\n");
7544  return 0;
7545  }
7546  if (aux_info_param != 0) {
7547  av_log(c->fc, AV_LOG_DEBUG, "Ignoring saiz box with non-zero aux_info_type_parameter\n");
7548  return 0;
7549  }
7550  } else {
7551  // Didn't see 'schm' or 'tenc', so this isn't encrypted.
7552  if ((aux_info_type == MKBETAG('c','e','n','c') ||
7553  aux_info_type == MKBETAG('c','e','n','s') ||
7554  aux_info_type == MKBETAG('c','b','c','1') ||
7555  aux_info_type == MKBETAG('c','b','c','s')) &&
7556  aux_info_param == 0) {
7557  av_log(c->fc, AV_LOG_ERROR, "Saw encrypted saiz without schm/tenc\n");
7558  return AVERROR_INVALIDDATA;
7559  } else {
7560  return 0;
7561  }
7562  }
7563  } else if (!sc->cenc.default_encrypted_sample) {
7564  // Didn't see 'schm' or 'tenc', so this isn't encrypted.
7565  return 0;
7566  }
7567 
7568  encryption_index->auxiliary_info_default_size = avio_r8(pb);
7569  sample_count = avio_rb32(pb);
7570 
7571  if (encryption_index->auxiliary_info_default_size == 0) {
7572  if (sample_count == 0)
7573  return AVERROR_INVALIDDATA;
7574 
7575  encryption_index->auxiliary_info_sizes = av_malloc(sample_count);
7576  if (!encryption_index->auxiliary_info_sizes)
7577  return AVERROR(ENOMEM);
7578 
7579  ret = avio_read(pb, encryption_index->auxiliary_info_sizes, sample_count);
7580  if (ret != sample_count) {
7581  av_freep(&encryption_index->auxiliary_info_sizes);
7582 
7583  if (ret >= 0)
7585  av_log(c->fc, AV_LOG_ERROR, "Failed to read the auxiliary info, %s\n",
7586  av_err2str(ret));
7587  return ret;
7588  }
7589  }
7590  encryption_index->auxiliary_info_sample_count = sample_count;
7591 
7592  if (encryption_index->auxiliary_offsets_count) {
7593  return mov_parse_auxiliary_info(c, sc, pb, encryption_index);
7594  }
7595 
7596  return 0;
7597 }
7598 
7600 {
7601  uint64_t *auxiliary_offsets;
7602  MOVEncryptionIndex *encryption_index;
7603  MOVStreamContext *sc;
7604  int i, ret;
7605  unsigned int version, entry_count, aux_info_type, aux_info_param;
7606  unsigned int alloc_size = 0;
7607 
7608  ret = get_current_encryption_info(c, &encryption_index, &sc);
7609  if (ret != 1)
7610  return ret;
7611 
7612  if (encryption_index->nb_encrypted_samples) {
7613  // This can happen if we have both saio/saiz and senc atoms.
7614  av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in saio\n");
7615  return 0;
7616  }
7617 
7618  if (encryption_index->auxiliary_offsets_count) {
7619  av_log(c->fc, AV_LOG_ERROR, "Duplicate saio atom\n");
7620  return AVERROR_INVALIDDATA;
7621  }
7622 
7623  version = avio_r8(pb); /* version */
7624  if (avio_rb24(pb) & 0x01) { /* flags */
7625  aux_info_type = avio_rb32(pb);
7626  aux_info_param = avio_rb32(pb);
7627  if (sc->cenc.default_encrypted_sample) {
7628  if (aux_info_type != sc->cenc.default_encrypted_sample->scheme) {
7629  av_log(c->fc, AV_LOG_DEBUG, "Ignoring saio box with non-zero aux_info_type\n");
7630  return 0;
7631  }
7632  if (aux_info_param != 0) {
7633  av_log(c->fc, AV_LOG_DEBUG, "Ignoring saio box with non-zero aux_info_type_parameter\n");
7634  return 0;
7635  }
7636  } else {
7637  // Didn't see 'schm' or 'tenc', so this isn't encrypted.
7638  if ((aux_info_type == MKBETAG('c','e','n','c') ||
7639  aux_info_type == MKBETAG('c','e','n','s') ||
7640  aux_info_type == MKBETAG('c','b','c','1') ||
7641  aux_info_type == MKBETAG('c','b','c','s')) &&
7642  aux_info_param == 0) {
7643  av_log(c->fc, AV_LOG_ERROR, "Saw encrypted saio without schm/tenc\n");
7644  return AVERROR_INVALIDDATA;
7645  } else {
7646  return 0;
7647  }
7648  }
7649  } else if (!sc->cenc.default_encrypted_sample) {
7650  // Didn't see 'schm' or 'tenc', so this isn't encrypted.
7651  return 0;
7652  }
7653 
7654  entry_count = avio_rb32(pb);
7655  if (entry_count >= INT_MAX / sizeof(*auxiliary_offsets))
7656  return AVERROR(ENOMEM);
7657 
7658  for (i = 0; i < entry_count && !pb->eof_reached; i++) {
7659  unsigned int min_offsets = FFMIN(FFMAX(i + 1, 1024), entry_count);
7660  auxiliary_offsets = av_fast_realloc(
7661  encryption_index->auxiliary_offsets, &alloc_size,
7662  min_offsets * sizeof(*auxiliary_offsets));
7663  if (!auxiliary_offsets) {
7664  av_freep(&encryption_index->auxiliary_offsets);
7665  return AVERROR(ENOMEM);
7666  }
7667  encryption_index->auxiliary_offsets = auxiliary_offsets;
7668 
7669  if (version == 0) {
7670  encryption_index->auxiliary_offsets[i] = avio_rb32(pb);
7671  } else {
7672  encryption_index->auxiliary_offsets[i] = avio_rb64(pb);
7673  }
7674  if (c->frag_index.current >= 0) {
7675  encryption_index->auxiliary_offsets[i] += c->fragment.base_data_offset;
7676  }
7677  }
7678 
7679  if (pb->eof_reached) {
7680  av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading saio\n");
7681  av_freep(&encryption_index->auxiliary_offsets);
7682  return AVERROR_INVALIDDATA;
7683  }
7684 
7685  encryption_index->auxiliary_offsets_count = entry_count;
7686 
7687  if (encryption_index->auxiliary_info_sample_count) {
7688  return mov_parse_auxiliary_info(c, sc, pb, encryption_index);
7689  }
7690 
7691  return 0;
7692 }
7693 
7695 {
7696  AVEncryptionInitInfo *info, *old_init_info;
7697  uint8_t **key_ids;
7698  AVStream *st;
7699  const AVPacketSideData *old_side_data;
7700  uint8_t *side_data, *extra_data;
7701  size_t side_data_size;
7702  int ret = 0;
7703  unsigned int version, kid_count, extra_data_size, alloc_size = 0;
7704 
7705  if (c->fc->nb_streams < 1)
7706  return 0;
7707  st = c->fc->streams[c->fc->nb_streams-1];
7708 
7709  version = avio_r8(pb); /* version */
7710  avio_rb24(pb); /* flags */
7711 
7712  info = av_encryption_init_info_alloc(/* system_id_size */ 16, /* num_key_ids */ 0,
7713  /* key_id_size */ 16, /* data_size */ 0);
7714  if (!info)
7715  return AVERROR(ENOMEM);
7716 
7717  if ((ret = ffio_read_size(pb, info->system_id, 16)) < 0) {
7718  av_log(c->fc, AV_LOG_ERROR, "Failed to read the system id\n");
7719  goto finish;
7720  }
7721 
7722  if (version > 0) {
7723  kid_count = avio_rb32(pb);
7724  if (kid_count >= INT_MAX / sizeof(*key_ids)) {
7725  ret = AVERROR(ENOMEM);
7726  goto finish;
7727  }
7728 
7729  for (unsigned int i = 0; i < kid_count && !pb->eof_reached; i++) {
7730  unsigned int min_kid_count = FFMIN(FFMAX(i + 1, 1024), kid_count);
7731  key_ids = av_fast_realloc(info->key_ids, &alloc_size,
7732  min_kid_count * sizeof(*key_ids));
7733  if (!key_ids) {
7734  ret = AVERROR(ENOMEM);
7735  goto finish;
7736  }
7737  info->key_ids = key_ids;
7738 
7739  info->key_ids[i] = av_mallocz(16);
7740  if (!info->key_ids[i]) {
7741  ret = AVERROR(ENOMEM);
7742  goto finish;
7743  }
7744  info->num_key_ids = i + 1;
7745 
7746  if ((ret = ffio_read_size(pb, info->key_ids[i], 16)) < 0) {
7747  av_log(c->fc, AV_LOG_ERROR, "Failed to read the key id\n");
7748  goto finish;
7749  }
7750  }
7751 
7752  if (pb->eof_reached) {
7753  av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading pssh\n");
7755  goto finish;
7756  }
7757  }
7758 
7759  extra_data_size = avio_rb32(pb);
7760  extra_data = av_malloc(extra_data_size);
7761  if (!extra_data) {
7762  ret = AVERROR(ENOMEM);
7763  goto finish;
7764  }
7765  ret = avio_read(pb, extra_data, extra_data_size);
7766  if (ret != extra_data_size) {
7767  av_free(extra_data);
7768 
7769  if (ret >= 0)
7771  goto finish;
7772  }
7773 
7774  av_freep(&info->data); // malloc(0) may still allocate something.
7775  info->data = extra_data;
7776  info->data_size = extra_data_size;
7777 
7778  // If there is existing initialization data, append to the list.
7781  if (old_side_data) {
7782  old_init_info = av_encryption_init_info_get_side_data(old_side_data->data, old_side_data->size);
7783  if (old_init_info) {
7784  // Append to the end of the list.
7785  for (AVEncryptionInitInfo *cur = old_init_info;; cur = cur->next) {
7786  if (!cur->next) {
7787  cur->next = info;
7788  break;
7789  }
7790  }
7791  info = old_init_info;
7792  } else {
7793  // Assume existing side-data will be valid, so the only error we could get is OOM.
7794  ret = AVERROR(ENOMEM);
7795  goto finish;
7796  }
7797  }
7798 
7799  side_data = av_encryption_init_info_add_side_data(info, &side_data_size);
7800  if (!side_data) {
7801  ret = AVERROR(ENOMEM);
7802  goto finish;
7803  }
7807  side_data, side_data_size, 0))
7808  av_free(side_data);
7809 
7810 finish:
7812  return ret;
7813 }
7814 
7816 {
7817  AVStream *st;
7818  MOVStreamContext *sc;
7819 
7820  if (c->fc->nb_streams < 1)
7821  return 0;
7822  st = c->fc->streams[c->fc->nb_streams-1];
7823  sc = st->priv_data;
7824 
7825  if (sc->pseudo_stream_id != 0) {
7826  av_log(c->fc, AV_LOG_ERROR, "schm boxes are only supported in first sample descriptor\n");
7827  return AVERROR_PATCHWELCOME;
7828  }
7829 
7830  if (atom.size < 8)
7831  return AVERROR_INVALIDDATA;
7832 
7833  avio_rb32(pb); /* version and flags */
7834 
7835  if (!sc->cenc.default_encrypted_sample) {
7837  if (!sc->cenc.default_encrypted_sample) {
7838  return AVERROR(ENOMEM);
7839  }
7840  }
7841 
7843  return 0;
7844 }
7845 
7847 {
7848  AVStream *st;
7849  MOVStreamContext *sc;
7850  unsigned int version, pattern, is_protected, iv_size;
7851 
7852  if (c->fc->nb_streams < 1)
7853  return 0;
7854  st = c->fc->streams[c->fc->nb_streams-1];
7855  sc = st->priv_data;
7856 
7857  if (sc->pseudo_stream_id != 0) {
7858  av_log(c->fc, AV_LOG_ERROR, "tenc atom are only supported in first sample descriptor\n");
7859  return AVERROR_PATCHWELCOME;
7860  }
7861 
7862  if (!sc->cenc.default_encrypted_sample) {
7864  if (!sc->cenc.default_encrypted_sample) {
7865  return AVERROR(ENOMEM);
7866  }
7867  }
7868 
7869  if (atom.size < 20)
7870  return AVERROR_INVALIDDATA;
7871 
7872  version = avio_r8(pb); /* version */
7873  avio_rb24(pb); /* flags */
7874 
7875  avio_r8(pb); /* reserved */
7876  pattern = avio_r8(pb);
7877 
7878  if (version > 0) {
7879  sc->cenc.default_encrypted_sample->crypt_byte_block = pattern >> 4;
7880  sc->cenc.default_encrypted_sample->skip_byte_block = pattern & 0xf;
7881  }
7882 
7883  is_protected = avio_r8(pb);
7884  if (is_protected && !sc->cenc.encryption_index) {
7885  // The whole stream should be by-default encrypted.
7887  if (!sc->cenc.encryption_index)
7888  return AVERROR(ENOMEM);
7889  }
7890  sc->cenc.per_sample_iv_size = avio_r8(pb);
7891  if (sc->cenc.per_sample_iv_size != 0 && sc->cenc.per_sample_iv_size != 8 &&
7892  sc->cenc.per_sample_iv_size != 16) {
7893  av_log(c->fc, AV_LOG_ERROR, "invalid per-sample IV size value\n");
7894  return AVERROR_INVALIDDATA;
7895  }
7896  if (avio_read(pb, sc->cenc.default_encrypted_sample->key_id, 16) != 16) {
7897  av_log(c->fc, AV_LOG_ERROR, "failed to read the default key ID\n");
7898  return AVERROR_INVALIDDATA;
7899  }
7900 
7901  if (is_protected && !sc->cenc.per_sample_iv_size) {
7902  iv_size = avio_r8(pb);
7903  if (iv_size != 8 && iv_size != 16) {
7904  av_log(c->fc, AV_LOG_ERROR, "invalid default_constant_IV_size in tenc atom\n");
7905  return AVERROR_INVALIDDATA;
7906  }
7907 
7908  if (avio_read(pb, sc->cenc.default_encrypted_sample->iv, iv_size) != iv_size) {
7909  av_log(c->fc, AV_LOG_ERROR, "failed to read the default IV\n");
7910  return AVERROR_INVALIDDATA;
7911  }
7912  }
7913 
7914  return 0;
7915 }
7916 
7918 {
7919  AVStream *st;
7920  int last, type, size, ret;
7921  uint8_t buf[4];
7922 
7923  if (c->fc->nb_streams < 1)
7924  return 0;
7925  st = c->fc->streams[c->fc->nb_streams-1];
7926 
7927  if ((uint64_t)atom.size > (1<<30) || atom.size < 42)
7928  return AVERROR_INVALIDDATA;
7929 
7930  /* Check FlacSpecificBox version. */
7931  if (avio_r8(pb) != 0)
7932  return AVERROR_INVALIDDATA;
7933 
7934  avio_rb24(pb); /* Flags */
7935 
7936  if (avio_read(pb, buf, sizeof(buf)) != sizeof(buf)) {
7937  av_log(c->fc, AV_LOG_ERROR, "failed to read FLAC metadata block header\n");
7938  return pb->error < 0 ? pb->error : AVERROR_INVALIDDATA;
7939  }
7940  flac_parse_block_header(buf, &last, &type, &size);
7941 
7943  av_log(c->fc, AV_LOG_ERROR, "STREAMINFO must be first FLACMetadataBlock\n");
7944  return AVERROR_INVALIDDATA;
7945  }
7946 
7947  ret = ff_get_extradata(c->fc, st->codecpar, pb, size);
7948  if (ret < 0)
7949  return ret;
7950 
7951  if (!last)
7952  av_log(c->fc, AV_LOG_WARNING, "non-STREAMINFO FLACMetadataBlock(s) ignored\n");
7953 
7954  return 0;
7955 }
7956 
7958 {
7959  int i, ret;
7960  int bytes_of_protected_data;
7961 
7962  if (!sc->cenc.aes_ctr) {
7963  /* initialize the cipher */
7964  sc->cenc.aes_ctr = av_aes_ctr_alloc();
7965  if (!sc->cenc.aes_ctr) {
7966  return AVERROR(ENOMEM);
7967  }
7968 
7969  ret = av_aes_ctr_init(sc->cenc.aes_ctr, c->decryption_key);
7970  if (ret < 0) {
7971  return ret;
7972  }
7973  }
7974 
7976 
7977  if (!sample->subsample_count) {
7978  /* decrypt the whole packet */
7980  return 0;
7981  }
7982 
7983  for (i = 0; i < sample->subsample_count; i++) {
7984  if (sample->subsamples[i].bytes_of_clear_data + sample->subsamples[i].bytes_of_protected_data > size) {
7985  av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n");
7986  return AVERROR_INVALIDDATA;
7987  }
7988 
7989  /* skip the clear bytes */
7990  input += sample->subsamples[i].bytes_of_clear_data;
7991  size -= sample->subsamples[i].bytes_of_clear_data;
7992 
7993  /* decrypt the encrypted bytes */
7994 
7995  bytes_of_protected_data = sample->subsamples[i].bytes_of_protected_data;
7996  av_aes_ctr_crypt(sc->cenc.aes_ctr, input, input, bytes_of_protected_data);
7997 
7998  input += bytes_of_protected_data;
7999  size -= bytes_of_protected_data;
8000  }
8001 
8002  if (size > 0) {
8003  av_log(c->fc, AV_LOG_ERROR, "leftover packet bytes after subsample processing\n");
8004  return AVERROR_INVALIDDATA;
8005  }
8006 
8007  return 0;
8008 }
8009 
8011 {
8012  int i, ret;
8013  int num_of_encrypted_blocks;
8014  uint8_t iv[16];
8015 
8016  if (!sc->cenc.aes_ctx) {
8017  /* initialize the cipher */
8018  sc->cenc.aes_ctx = av_aes_alloc();
8019  if (!sc->cenc.aes_ctx) {
8020  return AVERROR(ENOMEM);
8021  }
8022 
8023  ret = av_aes_init(sc->cenc.aes_ctx, c->decryption_key, 16 * 8, 1);
8024  if (ret < 0) {
8025  return ret;
8026  }
8027  }
8028 
8029  memcpy(iv, sample->iv, 16);
8030 
8031  /* whole-block full sample encryption */
8032  if (!sample->subsample_count) {
8033  /* decrypt the whole packet */
8034  av_aes_crypt(sc->cenc.aes_ctx, input, input, size/16, iv, 1);
8035  return 0;
8036  }
8037 
8038  for (i = 0; i < sample->subsample_count; i++) {
8039  if (sample->subsamples[i].bytes_of_clear_data + sample->subsamples[i].bytes_of_protected_data > size) {
8040  av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n");
8041  return AVERROR_INVALIDDATA;
8042  }
8043 
8044  if (sample->subsamples[i].bytes_of_protected_data % 16) {
8045  av_log(c->fc, AV_LOG_ERROR, "subsample BytesOfProtectedData is not a multiple of 16\n");
8046  return AVERROR_INVALIDDATA;
8047  }
8048 
8049  /* skip the clear bytes */
8050  input += sample->subsamples[i].bytes_of_clear_data;
8051  size -= sample->subsamples[i].bytes_of_clear_data;
8052 
8053  /* decrypt the encrypted bytes */
8054  num_of_encrypted_blocks = sample->subsamples[i].bytes_of_protected_data/16;
8055  if (num_of_encrypted_blocks > 0) {
8056  av_aes_crypt(sc->cenc.aes_ctx, input, input, num_of_encrypted_blocks, iv, 1);
8057  }
8058  input += sample->subsamples[i].bytes_of_protected_data;
8059  size -= sample->subsamples[i].bytes_of_protected_data;
8060  }
8061 
8062  if (size > 0) {
8063  av_log(c->fc, AV_LOG_ERROR, "leftover packet bytes after subsample processing\n");
8064  return AVERROR_INVALIDDATA;
8065  }
8066 
8067  return 0;
8068 }
8069 
8071 {
8072  int i, ret, rem_bytes;
8073  uint8_t *data;
8074 
8075  if (!sc->cenc.aes_ctr) {
8076  /* initialize the cipher */
8077  sc->cenc.aes_ctr = av_aes_ctr_alloc();
8078  if (!sc->cenc.aes_ctr) {
8079  return AVERROR(ENOMEM);
8080  }
8081 
8082  ret = av_aes_ctr_init(sc->cenc.aes_ctr, c->decryption_key);
8083  if (ret < 0) {
8084  return ret;
8085  }
8086  }
8087 
8089 
8090  /* whole-block full sample encryption */
8091  if (!sample->subsample_count) {
8092  /* decrypt the whole packet */
8094  return 0;
8095  } else if (!sample->crypt_byte_block && !sample->skip_byte_block) {
8096  av_log(c->fc, AV_LOG_ERROR, "pattern encryption is not present in 'cens' scheme\n");
8097  return AVERROR_INVALIDDATA;
8098  }
8099 
8100  for (i = 0; i < sample->subsample_count; i++) {
8101  if (sample->subsamples[i].bytes_of_clear_data + sample->subsamples[i].bytes_of_protected_data > size) {
8102  av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n");
8103  return AVERROR_INVALIDDATA;
8104  }
8105 
8106  /* skip the clear bytes */
8107  input += sample->subsamples[i].bytes_of_clear_data;
8108  size -= sample->subsamples[i].bytes_of_clear_data;
8109 
8110  /* decrypt the encrypted bytes */
8111  data = input;
8112  rem_bytes = sample->subsamples[i].bytes_of_protected_data;
8113  while (rem_bytes > 0) {
8114  if (rem_bytes < 16*sample->crypt_byte_block) {
8115  break;
8116  }
8117  av_aes_ctr_crypt(sc->cenc.aes_ctr, data, data, 16*sample->crypt_byte_block);
8118  data += 16*sample->crypt_byte_block;
8119  rem_bytes -= 16*sample->crypt_byte_block;
8120  data += FFMIN(16*sample->skip_byte_block, rem_bytes);
8121  rem_bytes -= FFMIN(16*sample->skip_byte_block, rem_bytes);
8122  }
8123  input += sample->subsamples[i].bytes_of_protected_data;
8124  size -= sample->subsamples[i].bytes_of_protected_data;
8125  }
8126 
8127  if (size > 0) {
8128  av_log(c->fc, AV_LOG_ERROR, "leftover packet bytes after subsample processing\n");
8129  return AVERROR_INVALIDDATA;
8130  }
8131 
8132  return 0;
8133 }
8134 
8136 {
8137  int i, ret, rem_bytes;
8138  uint8_t iv[16];
8139  uint8_t *data;
8140 
8141  if (!sc->cenc.aes_ctx) {
8142  /* initialize the cipher */
8143  sc->cenc.aes_ctx = av_aes_alloc();
8144  if (!sc->cenc.aes_ctx) {
8145  return AVERROR(ENOMEM);
8146  }
8147 
8148  ret = av_aes_init(sc->cenc.aes_ctx, c->decryption_key, 16 * 8, 1);
8149  if (ret < 0) {
8150  return ret;
8151  }
8152  }
8153 
8154  /* whole-block full sample encryption */
8155  if (!sample->subsample_count) {
8156  /* decrypt the whole packet */
8157  memcpy(iv, sample->iv, 16);
8158  av_aes_crypt(sc->cenc.aes_ctx, input, input, size/16, iv, 1);
8159  return 0;
8160  } else if (!sample->crypt_byte_block && !sample->skip_byte_block) {
8161  av_log(c->fc, AV_LOG_ERROR, "pattern encryption is not present in 'cbcs' scheme\n");
8162  return AVERROR_INVALIDDATA;
8163  }
8164 
8165  for (i = 0; i < sample->subsample_count; i++) {
8166  if (sample->subsamples[i].bytes_of_clear_data + sample->subsamples[i].bytes_of_protected_data > size) {
8167  av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n");
8168  return AVERROR_INVALIDDATA;
8169  }
8170 
8171  /* skip the clear bytes */
8172  input += sample->subsamples[i].bytes_of_clear_data;
8173  size -= sample->subsamples[i].bytes_of_clear_data;
8174 
8175  /* decrypt the encrypted bytes */
8176  memcpy(iv, sample->iv, 16);
8177  data = input;
8178  rem_bytes = sample->subsamples[i].bytes_of_protected_data;
8179  while (rem_bytes > 0) {
8180  if (rem_bytes < 16*sample->crypt_byte_block) {
8181  break;
8182  }
8183  av_aes_crypt(sc->cenc.aes_ctx, data, data, sample->crypt_byte_block, iv, 1);
8184  data += 16*sample->crypt_byte_block;
8185  rem_bytes -= 16*sample->crypt_byte_block;
8186  data += FFMIN(16*sample->skip_byte_block, rem_bytes);
8187  rem_bytes -= FFMIN(16*sample->skip_byte_block, rem_bytes);
8188  }
8189  input += sample->subsamples[i].bytes_of_protected_data;
8190  size -= sample->subsamples[i].bytes_of_protected_data;
8191  }
8192 
8193  if (size > 0) {
8194  av_log(c->fc, AV_LOG_ERROR, "leftover packet bytes after subsample processing\n");
8195  return AVERROR_INVALIDDATA;
8196  }
8197 
8198  return 0;
8199 }
8200 
8202 {
8203  if (sample->scheme == MKBETAG('c','e','n','c') && !sample->crypt_byte_block && !sample->skip_byte_block) {
8204  return cenc_scheme_decrypt(c, sc, sample, input, size);
8205  } else if (sample->scheme == MKBETAG('c','b','c','1') && !sample->crypt_byte_block && !sample->skip_byte_block) {
8206  return cbc1_scheme_decrypt(c, sc, sample, input, size);
8207  } else if (sample->scheme == MKBETAG('c','e','n','s')) {
8208  return cens_scheme_decrypt(c, sc, sample, input, size);
8209  } else if (sample->scheme == MKBETAG('c','b','c','s')) {
8210  return cbcs_scheme_decrypt(c, sc, sample, input, size);
8211  } else {
8212  av_log(c->fc, AV_LOG_ERROR, "invalid encryption scheme\n");
8213  return AVERROR_INVALIDDATA;
8214  }
8215 }
8216 
8218 {
8219  int current = frag_index->current;
8220 
8221  if (!frag_index->nb_items)
8222  return NULL;
8223 
8224  // Check frag_index->current is the right one for pkt. It can out of sync.
8225  if (current >= 0 && current < frag_index->nb_items) {
8226  if (frag_index->item[current].moof_offset < pkt->pos &&
8227  (current + 1 == frag_index->nb_items ||
8228  frag_index->item[current + 1].moof_offset > pkt->pos))
8229  return get_frag_stream_info(frag_index, current, id);
8230  }
8231 
8232 
8233  for (int i = 0; i < frag_index->nb_items; i++) {
8234  if (frag_index->item[i].moof_offset > pkt->pos)
8235  break;
8236  current = i;
8237  }
8238  frag_index->current = current;
8239  return get_frag_stream_info(frag_index, current, id);
8240 }
8241 
8242 static int cenc_filter(MOVContext *mov, AVStream* st, MOVStreamContext *sc, AVPacket *pkt, int current_index)
8243 {
8244  MOVFragmentStreamInfo *frag_stream_info;
8245  MOVEncryptionIndex *encryption_index;
8246  AVEncryptionInfo *encrypted_sample;
8247  int encrypted_index, ret;
8248 
8249  frag_stream_info = get_frag_stream_info_from_pkt(&mov->frag_index, pkt, sc->id);
8250  encrypted_index = current_index;
8251  encryption_index = NULL;
8252  if (frag_stream_info) {
8253  // Note this only supports encryption info in the first sample descriptor.
8254  if (frag_stream_info->stsd_id == 1) {
8255  if (frag_stream_info->encryption_index) {
8256  encrypted_index = current_index - frag_stream_info->index_base;
8257  encryption_index = frag_stream_info->encryption_index;
8258  } else {
8259  encryption_index = sc->cenc.encryption_index;
8260  }
8261  }
8262  } else {
8263  encryption_index = sc->cenc.encryption_index;
8264  }
8265 
8266  if (encryption_index) {
8267  if (encryption_index->auxiliary_info_sample_count &&
8268  !encryption_index->nb_encrypted_samples) {
8269  av_log(mov->fc, AV_LOG_ERROR, "saiz atom found without saio\n");
8270  return AVERROR_INVALIDDATA;
8271  }
8272  if (encryption_index->auxiliary_offsets_count &&
8273  !encryption_index->nb_encrypted_samples) {
8274  av_log(mov->fc, AV_LOG_ERROR, "saio atom found without saiz\n");
8275  return AVERROR_INVALIDDATA;
8276  }
8277 
8278  encrypted_sample = NULL;
8279  if (!encryption_index->nb_encrypted_samples) {
8280  // Full-sample encryption with default settings.
8281  encrypted_sample = sc->cenc.default_encrypted_sample;
8282  } else if (encrypted_index >= 0 && encrypted_index < encryption_index->nb_encrypted_samples) {
8283  // Per-sample setting override.
8284  encrypted_sample = encryption_index->encrypted_samples[encrypted_index];
8285  if (!encrypted_sample) {
8286  encrypted_sample = sc->cenc.default_encrypted_sample;
8287  }
8288  }
8289 
8290  if (!encrypted_sample) {
8291  av_log(mov->fc, AV_LOG_ERROR, "Incorrect number of samples in encryption info\n");
8292  return AVERROR_INVALIDDATA;
8293  }
8294 
8295  if (mov->decryption_key) {
8296  return cenc_decrypt(mov, sc, encrypted_sample, pkt->data, pkt->size);
8297  } else {
8298  size_t size;
8299  uint8_t *side_data = av_encryption_info_add_side_data(encrypted_sample, &size);
8300  if (!side_data)
8301  return AVERROR(ENOMEM);
8303  if (ret < 0)
8304  av_free(side_data);
8305  return ret;
8306  }
8307  }
8308 
8309  return 0;
8310 }
8311 
8313 {
8314  const int OPUS_SEEK_PREROLL_MS = 80;
8315  int ret;
8316  AVStream *st;
8317  size_t size;
8318  uint16_t pre_skip;
8319 
8320  if (c->fc->nb_streams < 1)
8321  return 0;
8322  st = c->fc->streams[c->fc->nb_streams-1];
8323 
8324  if ((uint64_t)atom.size > (1<<30) || atom.size < 11)
8325  return AVERROR_INVALIDDATA;
8326 
8327  /* Check OpusSpecificBox version. */
8328  if (avio_r8(pb) != 0) {
8329  av_log(c->fc, AV_LOG_ERROR, "unsupported OpusSpecificBox version\n");
8330  return AVERROR_INVALIDDATA;
8331  }
8332 
8333  /* OpusSpecificBox size plus magic for Ogg OpusHead header. */
8334  size = atom.size + 8;
8335 
8336  if ((ret = ff_alloc_extradata(st->codecpar, size)) < 0)
8337  return ret;
8338 
8339  AV_WL32A(st->codecpar->extradata, MKTAG('O','p','u','s'));
8340  AV_WL32A(st->codecpar->extradata + 4, MKTAG('H','e','a','d'));
8341  AV_WB8(st->codecpar->extradata + 8, 1); /* OpusHead version */
8342  avio_read(pb, st->codecpar->extradata + 9, size - 9);
8343 
8344  /* OpusSpecificBox is stored in big-endian, but OpusHead is
8345  little-endian; aside from the preceeding magic and version they're
8346  otherwise currently identical. Data after output gain at offset 16
8347  doesn't need to be bytewapped. */
8348  pre_skip = AV_RB16A(st->codecpar->extradata + 10);
8349  AV_WL16A(st->codecpar->extradata + 10, pre_skip);
8350  AV_WL32A(st->codecpar->extradata + 12, AV_RB32A(st->codecpar->extradata + 12));
8351  AV_WL16A(st->codecpar->extradata + 16, AV_RB16A(st->codecpar->extradata + 16));
8352 
8353  st->codecpar->initial_padding = pre_skip;
8355  (AVRational){1, 1000},
8356  (AVRational){1, 48000});
8357 
8358  return 0;
8359 }
8360 
8362 {
8363  AVStream *st;
8364  unsigned format_info;
8365  int channel_assignment, channel_assignment1, channel_assignment2;
8366  int ratebits;
8367  uint64_t chmask;
8368 
8369  if (c->fc->nb_streams < 1)
8370  return 0;
8371  st = c->fc->streams[c->fc->nb_streams-1];
8372 
8373  if (atom.size < 10)
8374  return AVERROR_INVALIDDATA;
8375 
8376  format_info = avio_rb32(pb);
8377 
8378  ratebits = (format_info >> 28) & 0xF;
8379  channel_assignment1 = (format_info >> 15) & 0x1F;
8380  channel_assignment2 = format_info & 0x1FFF;
8381  if (channel_assignment2)
8382  channel_assignment = channel_assignment2;
8383  else
8384  channel_assignment = channel_assignment1;
8385 
8386  st->codecpar->frame_size = 40 << (ratebits & 0x7);
8387  st->codecpar->sample_rate = mlp_samplerate(ratebits);
8388 
8390  chmask = truehd_layout(channel_assignment);
8392 
8393  return 0;
8394 }
8395 
8397 {
8398  AVStream *st;
8399  uint8_t buf[ISOM_DVCC_DVVC_SIZE];
8400  int ret;
8401  int64_t read_size = atom.size;
8402 
8403  if (c->fc->nb_streams < 1)
8404  return 0;
8405  st = c->fc->streams[c->fc->nb_streams-1];
8406 
8407  // At most 24 bytes
8408  read_size = FFMIN(read_size, ISOM_DVCC_DVVC_SIZE);
8409 
8410  if ((ret = ffio_read_size(pb, buf, read_size)) < 0)
8411  return ret;
8412 
8413  return ff_isom_parse_dvcc_dvvc(c->fc, st, buf, read_size);
8414 }
8415 
8417 {
8418  AVStream *st;
8419  uint8_t *buf;
8420  int ret, old_size, num_arrays;
8421 
8422  if (c->fc->nb_streams < 1)
8423  return 0;
8424  st = c->fc->streams[c->fc->nb_streams-1];
8425 
8426  if (!st->codecpar->extradata_size)
8427  // TODO: handle lhvC when present before hvcC
8428  return 0;
8429 
8430  if (atom.size < 6 || st->codecpar->extradata_size < 23)
8431  return AVERROR_INVALIDDATA;
8432 
8434  if (!buf)
8435  return AVERROR(ENOMEM);
8436  memset(buf + atom.size, 0, AV_INPUT_BUFFER_PADDING_SIZE);
8437 
8438  ret = ffio_read_size(pb, buf, atom.size);
8439  if (ret < 0) {
8440  av_free(buf);
8441  av_log(c->fc, AV_LOG_WARNING, "lhvC atom truncated\n");
8442  return 0;
8443  }
8444 
8445  num_arrays = buf[5];
8446  old_size = st->codecpar->extradata_size;
8447  atom.size -= 8 /* account for mov_realloc_extradata offseting */
8448  + 6 /* lhvC bytes before the arrays*/;
8449 
8450  ret = mov_realloc_extradata(st->codecpar, atom);
8451  if (ret < 0) {
8452  av_free(buf);
8453  return ret;
8454  }
8455 
8456  st->codecpar->extradata[22] += num_arrays;
8457  memcpy(st->codecpar->extradata + old_size, buf + 6, atom.size + 8);
8458 
8460 
8461  av_free(buf);
8462  return 0;
8463 }
8464 
8466 {
8467  AVFormatContext *ctx = c->fc;
8468  AVStream *st = NULL;
8469  AVBPrint scheme_buf, value_buf;
8470  int64_t scheme_str_len = 0, value_str_len = 0;
8471  int version, flags, ret = AVERROR_BUG;
8472  int64_t size = atom.size;
8473 
8474  if (atom.size < 6)
8475  // 4 bytes for version + flags, 2x 1 byte for null
8476  return AVERROR_INVALIDDATA;
8477 
8478  if (c->fc->nb_streams < 1)
8479  return 0;
8480  st = c->fc->streams[c->fc->nb_streams-1];
8481 
8482  version = avio_r8(pb);
8483  flags = avio_rb24(pb);
8484  size -= 4;
8485 
8486  if (version != 0 || flags != 0) {
8488  "Unsupported 'kind' box with version %d, flags: %x",
8489  version, flags);
8490  return AVERROR_INVALIDDATA;
8491  }
8492 
8493  av_bprint_init(&scheme_buf, 0, AV_BPRINT_SIZE_UNLIMITED);
8494  av_bprint_init(&value_buf, 0, AV_BPRINT_SIZE_UNLIMITED);
8495 
8496  if ((scheme_str_len = ff_read_string_to_bprint_overwrite(pb, &scheme_buf,
8497  size)) < 0) {
8498  ret = scheme_str_len;
8499  goto cleanup;
8500  }
8501 
8502  if (scheme_str_len + 1 >= size) {
8503  // we need to have another string, even if nullptr.
8504  // we check with + 1 since we expect that if size was not hit,
8505  // an additional null was read.
8507  goto cleanup;
8508  }
8509 
8510  size -= scheme_str_len + 1;
8511 
8512  if ((value_str_len = ff_read_string_to_bprint_overwrite(pb, &value_buf,
8513  size)) < 0) {
8514  ret = value_str_len;
8515  goto cleanup;
8516  }
8517 
8518  if (value_str_len == size) {
8519  // in case of no trailing null, box is not valid.
8521  goto cleanup;
8522  }
8523 
8525  "%s stream %d KindBox(scheme: %s, value: %s)\n",
8527  st->index,
8528  scheme_buf.str, value_buf.str);
8529 
8530  for (int i = 0; ff_mov_track_kind_table[i].scheme_uri; i++) {
8532  if (!av_strstart(scheme_buf.str, map.scheme_uri, NULL))
8533  continue;
8534 
8535  for (int j = 0; map.value_maps[j].disposition; j++) {
8536  const struct MP4TrackKindValueMapping value_map = map.value_maps[j];
8537  if (!av_strstart(value_buf.str, value_map.value, NULL))
8538  continue;
8539 
8540  st->disposition |= value_map.disposition;
8541  }
8542  }
8543 
8544  ret = 0;
8545 
8546 cleanup:
8547 
8548  av_bprint_finalize(&scheme_buf, NULL);
8549  av_bprint_finalize(&value_buf, NULL);
8550 
8551  return ret;
8552 }
8553 
8555 {
8556  AVStream *st;
8557  AVChannelLayout ch_layout = { 0 };
8558  int ret, i, version, type;
8559  int ambisonic_order, channel_order, normalization, channel_count;
8560  int ambi_channels, non_diegetic_channels;
8561 
8562  if (c->fc->nb_streams < 1)
8563  return 0;
8564 
8565  st = c->fc->streams[c->fc->nb_streams - 1];
8566 
8567  if (atom.size < 16) {
8568  av_log(c->fc, AV_LOG_ERROR, "SA3D audio box too small\n");
8569  return AVERROR_INVALIDDATA;
8570  }
8571 
8572  version = avio_r8(pb);
8573  if (version) {
8574  av_log(c->fc, AV_LOG_WARNING, "Unsupported SA3D box version %d\n", version);
8575  return 0;
8576  }
8577 
8578  type = avio_r8(pb);
8579  if (type & 0x7f) {
8580  av_log(c->fc, AV_LOG_WARNING,
8581  "Unsupported ambisonic type %d\n", type & 0x7f);
8582  return 0;
8583  }
8584  non_diegetic_channels = (type >> 7) * 2; // head_locked_stereo
8585 
8586  ambisonic_order = avio_rb32(pb);
8587 
8588  channel_order = avio_r8(pb);
8589  if (channel_order) {
8590  av_log(c->fc, AV_LOG_WARNING,
8591  "Unsupported channel_order %d\n", channel_order);
8592  return 0;
8593  }
8594 
8595  normalization = avio_r8(pb);
8596  if (normalization) {
8597  av_log(c->fc, AV_LOG_WARNING,
8598  "Unsupported normalization %d\n", normalization);
8599  return 0;
8600  }
8601 
8602  channel_count = avio_rb32(pb);
8603  if (ambisonic_order < 0 || ambisonic_order > 31 ||
8604  channel_count != ((ambisonic_order + 1LL) * (ambisonic_order + 1LL) +
8605  non_diegetic_channels)) {
8606  av_log(c->fc, AV_LOG_ERROR,
8607  "Invalid number of channels (%d / %d)\n",
8608  channel_count, ambisonic_order);
8609  return 0;
8610  }
8611  ambi_channels = channel_count - non_diegetic_channels;
8612 
8613  ret = av_channel_layout_custom_init(&ch_layout, channel_count);
8614  if (ret < 0)
8615  return 0;
8616 
8617  for (i = 0; i < channel_count; i++) {
8618  unsigned channel = avio_rb32(pb);
8619 
8620  if (channel >= channel_count) {
8621  av_log(c->fc, AV_LOG_ERROR, "Invalid channel index (%d / %d)\n",
8622  channel, ambisonic_order);
8623  av_channel_layout_uninit(&ch_layout);
8624  return 0;
8625  }
8626  if (channel >= ambi_channels)
8627  ch_layout.u.map[i].id = channel - ambi_channels;
8628  else
8629  ch_layout.u.map[i].id = AV_CHAN_AMBISONIC_BASE + channel;
8630  }
8631 
8633  if (ret < 0) {
8634  av_channel_layout_uninit(&ch_layout);
8635  return 0;
8636  }
8637 
8639  st->codecpar->ch_layout = ch_layout;
8640 
8641  return 0;
8642 }
8643 
8645 {
8646  AVStream *st;
8647  int version;
8648 
8649  if (c->fc->nb_streams < 1)
8650  return 0;
8651 
8652  st = c->fc->streams[c->fc->nb_streams - 1];
8653 
8654  if (atom.size < 5) {
8655  av_log(c->fc, AV_LOG_ERROR, "Empty SAND audio box\n");
8656  return AVERROR_INVALIDDATA;
8657  }
8658 
8659  version = avio_r8(pb);
8660  if (version) {
8661  av_log(c->fc, AV_LOG_WARNING, "Unsupported SAND box version %d\n", version);
8662  return 0;
8663  }
8664 
8666 
8667  return 0;
8668 }
8669 
8670 static int rb_size(AVIOContext *pb, int64_t *value, int size)
8671 {
8672  if (size == 0)
8673  *value = 0;
8674  else if (size == 1)
8675  *value = avio_r8(pb);
8676  else if (size == 2)
8677  *value = avio_rb16(pb);
8678  else if (size == 4)
8679  *value = avio_rb32(pb);
8680  else if (size == 8) {
8681  *value = avio_rb64(pb);
8682  if (*value < 0)
8683  return -1;
8684  } else
8685  return -1;
8686  return size;
8687 }
8688 
8690 {
8691  avio_rb32(pb); // version & flags.
8692  c->primary_item_id = avio_rb16(pb);
8693  av_log(c->fc, AV_LOG_TRACE, "pitm: primary_item_id %d\n", c->primary_item_id);
8694  return atom.size;
8695 }
8696 
8698 {
8699  c->idat_offset = avio_tell(pb);
8700  return 0;
8701 }
8702 
8704 {
8705  HEIFItem **heif_item;
8706  int version, offset_size, length_size, base_offset_size, index_size;
8707  int item_count, extent_count;
8708  int64_t base_offset, extent_offset, extent_length;
8709  uint8_t value;
8710 
8711  if (c->found_iloc) {
8712  av_log(c->fc, AV_LOG_INFO, "Duplicate iloc box found\n");
8713  return 0;
8714  }
8715 
8716  version = avio_r8(pb);
8717  avio_rb24(pb); // flags.
8718 
8719  value = avio_r8(pb);
8720  offset_size = (value >> 4) & 0xF;
8721  length_size = value & 0xF;
8722  value = avio_r8(pb);
8723  base_offset_size = (value >> 4) & 0xF;
8724  index_size = !version ? 0 : (value & 0xF);
8725  if (index_size) {
8726  avpriv_report_missing_feature(c->fc, "iloc: index_size != 0");
8727  return AVERROR_PATCHWELCOME;
8728  }
8729  item_count = (version < 2) ? avio_rb16(pb) : avio_rb32(pb);
8730 
8731  heif_item = av_realloc_array(c->heif_item, FFMAX(item_count, c->nb_heif_item), sizeof(*c->heif_item));
8732  if (!heif_item)
8733  return AVERROR(ENOMEM);
8734  c->heif_item = heif_item;
8735  if (item_count > c->nb_heif_item)
8736  memset(&c->heif_item[c->nb_heif_item], 0,
8737  sizeof(*c->heif_item) * (item_count - c->nb_heif_item));
8738  c->nb_heif_item = FFMAX(c->nb_heif_item, item_count);
8739 
8740  av_log(c->fc, AV_LOG_TRACE, "iloc: item_count %d\n", item_count);
8741  for (int i = 0; i < item_count; i++) {
8742  HEIFItem *item = c->heif_item[i];
8743  int item_id = (version < 2) ? avio_rb16(pb) : avio_rb32(pb);
8744  int offset_type = (version > 0) ? avio_rb16(pb) & 0xf : 0;
8745 
8746  if (avio_feof(pb))
8747  return AVERROR_INVALIDDATA;
8748  if (offset_type > 1) {
8749  avpriv_report_missing_feature(c->fc, "iloc offset type %d", offset_type);
8750  return AVERROR_PATCHWELCOME;
8751  }
8752 
8753  avio_rb16(pb); // data_reference_index.
8754  if (rb_size(pb, &base_offset, base_offset_size) < 0)
8755  return AVERROR_INVALIDDATA;
8756  extent_count = avio_rb16(pb);
8757  if (extent_count > 1) {
8758  // For still AVIF images, we only support one extent item.
8759  avpriv_report_missing_feature(c->fc, "iloc: extent_count > 1");
8760  return AVERROR_PATCHWELCOME;
8761  }
8762 
8763  if (rb_size(pb, &extent_offset, offset_size) < 0 ||
8764  rb_size(pb, &extent_length, length_size) < 0 ||
8765  base_offset > INT64_MAX - extent_offset)
8766  return AVERROR_INVALIDDATA;
8767 
8768  if (!item)
8769  item = c->heif_item[i] = av_mallocz(sizeof(*item));
8770  if (!item)
8771  return AVERROR(ENOMEM);
8772 
8773  item->item_id = item_id;
8774 
8775  if (offset_type == 1)
8776  item->is_idat_relative = 1;
8777  item->extent_length = extent_length;
8778  item->extent_offset = base_offset + extent_offset;
8779  av_log(c->fc, AV_LOG_TRACE, "iloc: item_idx %d, offset_type %d, "
8780  "extent_offset %"PRId64", extent_length %"PRId64"\n",
8781  i, offset_type, item->extent_offset, item->extent_length);
8782  }
8783 
8784  c->found_iloc = 1;
8785  return atom.size;
8786 }
8787 
8788 static int mov_read_infe(MOVContext *c, AVIOContext *pb, MOVAtom atom, int idx)
8789 {
8790  HEIFItem *item;
8791  AVBPrint item_name;
8792  int64_t size = atom.size;
8793  uint32_t item_type;
8794  int item_id;
8795  int version, ret;
8796 
8797  version = avio_r8(pb);
8798  avio_rb24(pb); // flags.
8799  size -= 4;
8800  if (size < 0)
8801  return AVERROR_INVALIDDATA;
8802 
8803  if (version < 2) {
8804  avpriv_report_missing_feature(c->fc, "infe version < 2");
8805  avio_skip(pb, size);
8806  return 1;
8807  }
8808 
8809  item_id = version > 2 ? avio_rb32(pb) : avio_rb16(pb);
8810  avio_rb16(pb); // item_protection_index
8811  item_type = avio_rl32(pb);
8812  size -= 8;
8813  if (size < 1)
8814  return AVERROR_INVALIDDATA;
8815 
8818  if (ret < 0) {
8820  return ret;
8821  }
8822 
8823  av_log(c->fc, AV_LOG_TRACE, "infe: item_id %d, item_type %s, item_name %s\n",
8824  item_id, av_fourcc2str(item_type), item_name.str);
8825 
8826  size -= ret + 1;
8827  if (size > 0)
8828  avio_skip(pb, size);
8829 
8830  item = c->heif_item[idx];
8831  if (!item)
8832  item = c->heif_item[idx] = av_mallocz(sizeof(*item));
8833  if (!item)
8834  return AVERROR(ENOMEM);
8835 
8836  if (ret)
8837  av_bprint_finalize(&item_name, &c->heif_item[idx]->name);
8838  c->heif_item[idx]->item_id = item_id;
8839  c->heif_item[idx]->type = item_type;
8840 
8841  switch (item_type) {
8842  case MKTAG('a','v','0','1'):
8843  case MKTAG('h','v','c','1'):
8844  ret = heif_add_stream(c, c->heif_item[idx]);
8845  if (ret < 0)
8846  return ret;
8847  break;
8848  }
8849 
8850  return 0;
8851 }
8852 
8854 {
8855  HEIFItem **heif_item;
8856  int entry_count;
8857  int version, got_stream = 0, ret, i;
8858 
8859  if (c->found_iinf) {
8860  av_log(c->fc, AV_LOG_WARNING, "Duplicate iinf box found\n");
8861  return 0;
8862  }
8863 
8864  version = avio_r8(pb);
8865  avio_rb24(pb); // flags.
8866  entry_count = version ? avio_rb32(pb) : avio_rb16(pb);
8867 
8868  heif_item = av_realloc_array(c->heif_item, FFMAX(entry_count, c->nb_heif_item), sizeof(*c->heif_item));
8869  if (!heif_item)
8870  return AVERROR(ENOMEM);
8871  c->heif_item = heif_item;
8872  if (entry_count > c->nb_heif_item)
8873  memset(&c->heif_item[c->nb_heif_item], 0,
8874  sizeof(*c->heif_item) * (entry_count - c->nb_heif_item));
8875  c->nb_heif_item = FFMAX(c->nb_heif_item, entry_count);
8876 
8877  for (i = 0; i < entry_count; i++) {
8878  MOVAtom infe;
8879 
8880  infe.size = avio_rb32(pb) - 8;
8881  infe.type = avio_rl32(pb);
8882  if (avio_feof(pb)) {
8884  goto fail;
8885  }
8886  ret = mov_read_infe(c, pb, infe, i);
8887  if (ret < 0)
8888  goto fail;
8889  if (!ret)
8890  got_stream = 1;
8891  }
8892 
8893  c->found_iinf = got_stream;
8894  return 0;
8895 fail:
8896  for (; i >= 0; i--) {
8897  HEIFItem *item = c->heif_item[i];
8898 
8899  if (!item)
8900  continue;
8901 
8902  av_freep(&item->name);
8903  if (!item->st)
8904  continue;
8905 
8906  mov_free_stream_context(c->fc, item->st);
8907  ff_remove_stream(c->fc, item->st);
8908  item->st = NULL;
8909  }
8910  return ret;
8911 }
8912 
8914 {
8915  HEIFItem *item = NULL;
8916  HEIFGrid *grid;
8917  int entries, i;
8918  int from_item_id = version ? avio_rb32(pb) : avio_rb16(pb);
8919 
8920  for (int i = 0; i < c->nb_heif_grid; i++) {
8921  if (c->heif_grid[i].item->item_id == from_item_id) {
8922  av_log(c->fc, AV_LOG_ERROR, "More than one 'dimg' box "
8923  "referencing the same Derived Image item\n");
8924  return AVERROR_INVALIDDATA;
8925  }
8926  }
8927  for (int i = 0; i < c->nb_heif_item; i++) {
8928  if (!c->heif_item[i] || c->heif_item[i]->item_id != from_item_id)
8929  continue;
8930  item = c->heif_item[i];
8931 
8932  switch (item->type) {
8933  case MKTAG('g','r','i','d'):
8934  case MKTAG('i','o','v','l'):
8935  break;
8936  default:
8937  avpriv_report_missing_feature(c->fc, "Derived Image item of type %s",
8938  av_fourcc2str(item->type));
8939  return 0;
8940  }
8941  break;
8942  }
8943  if (!item) {
8944  av_log(c->fc, AV_LOG_ERROR, "Missing grid information\n");
8945  return AVERROR_INVALIDDATA;
8946  }
8947 
8948  grid = av_realloc_array(c->heif_grid, c->nb_heif_grid + 1U,
8949  sizeof(*c->heif_grid));
8950  if (!grid)
8951  return AVERROR(ENOMEM);
8952  c->heif_grid = grid;
8953  grid = &grid[c->nb_heif_grid++];
8954 
8955  entries = avio_rb16(pb);
8956  grid->tile_id_list = av_malloc_array(entries, sizeof(*grid->tile_id_list));
8957  grid->tile_idx_list = av_calloc(entries, sizeof(*grid->tile_idx_list));
8958  grid->tile_item_list = av_calloc(entries, sizeof(*grid->tile_item_list));
8959  if (!grid->tile_id_list || !grid->tile_item_list || !grid->tile_idx_list)
8960  return AVERROR(ENOMEM);
8961  /* 'to' item ids */
8962  for (i = 0; i < entries; i++)
8963  grid->tile_id_list[i] = version ? avio_rb32(pb) : avio_rb16(pb);
8964  grid->nb_tiles = entries;
8965  grid->item = item;
8966 
8967  av_log(c->fc, AV_LOG_TRACE, "dimg: from_item_id %d, entries %d\n",
8968  from_item_id, entries);
8969 
8970  return 0;
8971 }
8972 
8974 {
8975  int entries;
8976  int to_item_id, from_item_id = version ? avio_rb32(pb) : avio_rb16(pb);
8977 
8978  entries = avio_rb16(pb);
8979  if (entries > 1) {
8980  avpriv_request_sample(c->fc, "thmb in iref referencing several items");
8981  return AVERROR_PATCHWELCOME;
8982  }
8983  /* 'to' item ids */
8984  to_item_id = version ? avio_rb32(pb) : avio_rb16(pb);
8985 
8986  if (to_item_id != c->primary_item_id)
8987  return 0;
8988 
8989  c->thmb_item_id = from_item_id;
8990 
8991  av_log(c->fc, AV_LOG_TRACE, "thmb: from_item_id %d, entries %d\n",
8992  from_item_id, entries);
8993 
8994  return 0;
8995 }
8996 
8998 {
8999  int version = avio_r8(pb);
9000  avio_rb24(pb); // flags
9001  atom.size -= 4;
9002 
9003  if (version > 1) {
9004  av_log(c->fc, AV_LOG_WARNING, "Unknown iref box version %d\n", version);
9005  return 0;
9006  }
9007 
9008  while (atom.size) {
9009  uint32_t type, size = avio_rb32(pb);
9010  int64_t next = avio_tell(pb);
9011 
9012  if (size < 14 || next < 0 || next > INT64_MAX - size)
9013  return AVERROR_INVALIDDATA;
9014 
9015  next += size - 4;
9016  type = avio_rl32(pb);
9017  switch (type) {
9018  case MKTAG('d','i','m','g'):
9020  break;
9021  case MKTAG('t','h','m','b'):
9023  break;
9024  default:
9025  av_log(c->fc, AV_LOG_DEBUG, "Unknown iref type %s size %"PRIu32"\n",
9026  av_fourcc2str(type), size);
9027  }
9028 
9029  atom.size -= size;
9030  avio_seek(pb, next, SEEK_SET);
9031  }
9032  return 0;
9033 }
9034 
9036 {
9037  HEIFItem *item;
9038  uint32_t width, height;
9039 
9040  avio_r8(pb); /* version */
9041  avio_rb24(pb); /* flags */
9042  width = avio_rb32(pb);
9043  height = avio_rb32(pb);
9044 
9045  av_log(c->fc, AV_LOG_TRACE, "ispe: item_id %d, width %u, height %u\n",
9046  c->cur_item_id, width, height);
9047 
9048  item = heif_cur_item(c);
9049  if (item) {
9050  item->width = width;
9051  item->height = height;
9052  }
9053 
9054  return 0;
9055 }
9056 
9058 {
9059  HEIFItem *item;
9060  int angle;
9061 
9062  angle = avio_r8(pb) & 0x3;
9063 
9064  av_log(c->fc, AV_LOG_TRACE, "irot: item_id %d, angle %u\n",
9065  c->cur_item_id, angle);
9066 
9067  item = heif_cur_item(c);
9068  if (item) {
9069  // angle * 90 specifies the angle (in anti-clockwise direction)
9070  // in units of degrees.
9071  item->rotation = angle * 90;
9072  }
9073 
9074  return 0;
9075 }
9076 
9078 {
9079  HEIFItem *item;
9080  int axis;
9081 
9082  axis = avio_r8(pb) & 0x1;
9083 
9084  av_log(c->fc, AV_LOG_TRACE, "imir: item_id %d, axis %u\n",
9085  c->cur_item_id, axis);
9086 
9087  item = heif_cur_item(c);
9088  if (item) {
9089  item->hflip = axis;
9090  item->vflip = !axis;
9091  }
9092 
9093  return 0;
9094 }
9095 
9097 {
9098  typedef struct MOVAtoms {
9099  FFIOContext b;
9100  uint32_t type;
9101  int64_t size;
9102  uint8_t *data;
9103  } MOVAtoms;
9104  MOVAtoms *atoms = NULL;
9105  MOVAtom a;
9106  unsigned count;
9107  int nb_atoms = 0;
9108  int version, flags;
9109  int ret;
9110 
9111  a.size = avio_rb32(pb);
9112  a.type = avio_rl32(pb);
9113 
9114  if (a.size < 8 || a.type != MKTAG('i','p','c','o'))
9115  return AVERROR_INVALIDDATA;
9116 
9117  a.size -= 8;
9118  while (a.size >= 8) {
9119  MOVAtoms *ref = av_dynarray2_add((void**)&atoms, &nb_atoms, sizeof(MOVAtoms), NULL);
9120  if (!ref) {
9121  ret = AVERROR(ENOMEM);
9122  goto fail;
9123  }
9124  ref->data = NULL;
9125  ref->size = avio_rb32(pb);
9126  ref->type = avio_rl32(pb);
9127  if (ref->size > a.size || ref->size < 8)
9128  break;
9129  ref->data = av_malloc(ref->size);
9130  if (!ref->data) {
9132  goto fail;
9133  }
9134  av_log(c->fc, AV_LOG_TRACE, "ipco: index %d, box type %s\n", nb_atoms, av_fourcc2str(ref->type));
9135  avio_seek(pb, -8, SEEK_CUR);
9136  if (avio_read(pb, ref->data, ref->size) != ref->size) {
9138  goto fail;
9139  }
9140  ffio_init_read_context(&ref->b, ref->data, ref->size);
9141  a.size -= ref->size;
9142  }
9143 
9144  if (a.size) {
9146  goto fail;
9147  }
9148 
9149  a.size = avio_rb32(pb);
9150  a.type = avio_rl32(pb);
9151 
9152  if (a.size < 8 || a.type != MKTAG('i','p','m','a')) {
9154  goto fail;
9155  }
9156 
9157  version = avio_r8(pb);
9158  flags = avio_rb24(pb);
9159  count = avio_rb32(pb);
9160 
9161  for (int i = 0; i < count; i++) {
9162  int item_id = version ? avio_rb32(pb) : avio_rb16(pb);
9163  int assoc_count = avio_r8(pb);
9164 
9165  if (avio_feof(pb)) {
9167  goto fail;
9168  }
9169 
9170  for (int j = 0; j < assoc_count; j++) {
9171  MOVAtoms *ref;
9172  int index = avio_r8(pb) & 0x7f;
9173  if (flags & 1) {
9174  index <<= 8;
9175  index |= avio_r8(pb);
9176  }
9177  if (index > nb_atoms || index <= 0) {
9179  goto fail;
9180  }
9181  ref = &atoms[--index];
9182 
9183  av_log(c->fc, AV_LOG_TRACE, "ipma: property_index %d, item_id %d, item_type %s\n",
9184  index + 1, item_id, av_fourcc2str(ref->type));
9185 
9186  c->cur_item_id = item_id;
9187 
9188  ret = mov_read_default(c, &ref->b.pub,
9189  (MOVAtom) { .size = ref->size,
9190  .type = MKTAG('i','p','c','o') });
9191  if (ret < 0)
9192  goto fail;
9193  ffio_init_read_context(&ref->b, ref->data, ref->size);
9194  }
9195  }
9196 
9197  ret = 0;
9198 fail:
9199  c->cur_item_id = -1;
9200  for (int i = 0; i < nb_atoms; i++)
9201  av_free(atoms[i].data);
9202  av_free(atoms);
9203 
9204  return ret;
9205 }
9206 
9208 { MKTAG('A','C','L','R'), mov_read_aclr },
9209 { MKTAG('A','P','R','G'), mov_read_avid },
9210 { MKTAG('A','A','L','P'), mov_read_avid },
9211 { MKTAG('A','R','E','S'), mov_read_ares },
9212 { MKTAG('a','v','s','s'), mov_read_avss },
9213 { MKTAG('a','v','1','C'), mov_read_glbl },
9214 { MKTAG('c','h','p','l'), mov_read_chpl },
9215 { MKTAG('c','o','6','4'), mov_read_stco },
9216 { MKTAG('c','o','l','r'), mov_read_colr },
9217 { MKTAG('c','t','t','s'), mov_read_ctts }, /* composition time to sample */
9218 { MKTAG('d','i','n','f'), mov_read_default },
9219 { MKTAG('D','p','x','E'), mov_read_dpxe },
9220 { MKTAG('d','r','e','f'), mov_read_dref },
9221 { MKTAG('e','d','t','s'), mov_read_default },
9222 { MKTAG('e','l','s','t'), mov_read_elst },
9223 { MKTAG('e','n','d','a'), mov_read_enda },
9224 { MKTAG('f','i','e','l'), mov_read_fiel },
9225 { MKTAG('a','d','r','m'), mov_read_adrm },
9226 { MKTAG('f','t','y','p'), mov_read_ftyp },
9227 { MKTAG('g','l','b','l'), mov_read_glbl },
9228 { MKTAG('h','d','l','r'), mov_read_hdlr },
9229 { MKTAG('i','l','s','t'), mov_read_ilst },
9230 { MKTAG('j','p','2','h'), mov_read_jp2h },
9231 { MKTAG('m','d','a','t'), mov_read_mdat },
9232 { MKTAG('m','d','h','d'), mov_read_mdhd },
9233 { MKTAG('m','d','i','a'), mov_read_default },
9234 { MKTAG('m','e','t','a'), mov_read_meta },
9235 { MKTAG('m','i','n','f'), mov_read_default },
9236 { MKTAG('m','o','o','f'), mov_read_moof },
9237 { MKTAG('m','o','o','v'), mov_read_moov },
9238 { MKTAG('m','v','e','x'), mov_read_default },
9239 { MKTAG('m','v','h','d'), mov_read_mvhd },
9240 { MKTAG('S','M','I',' '), mov_read_svq3 },
9241 { MKTAG('a','l','a','c'), mov_read_alac }, /* alac specific atom */
9242 { MKTAG('a','v','c','C'), mov_read_glbl },
9243 { MKTAG('p','a','s','p'), mov_read_pasp },
9244 { MKTAG('c','l','a','p'), mov_read_clap },
9245 { MKTAG('s','b','a','s'), mov_read_sbas },
9246 { MKTAG('s','i','d','x'), mov_read_sidx },
9247 { MKTAG('s','t','b','l'), mov_read_default },
9248 { MKTAG('s','t','c','o'), mov_read_stco },
9249 { MKTAG('s','t','p','s'), mov_read_stps },
9250 { MKTAG('s','t','r','f'), mov_read_strf },
9251 { MKTAG('s','t','s','c'), mov_read_stsc },
9252 { MKTAG('s','t','s','d'), mov_read_stsd }, /* sample description */
9253 { MKTAG('s','t','s','s'), mov_read_stss }, /* sync sample */
9254 { MKTAG('s','t','s','z'), mov_read_stsz }, /* sample size */
9255 { MKTAG('s','t','t','s'), mov_read_stts },
9256 { MKTAG('s','t','z','2'), mov_read_stsz }, /* compact sample size */
9257 { MKTAG('s','d','t','p'), mov_read_sdtp }, /* independent and disposable samples */
9258 { MKTAG('t','k','h','d'), mov_read_tkhd }, /* track header */
9259 { MKTAG('t','f','d','t'), mov_read_tfdt },
9260 { MKTAG('t','f','h','d'), mov_read_tfhd }, /* track fragment header */
9261 { MKTAG('t','r','a','k'), mov_read_trak },
9262 { MKTAG('t','r','a','f'), mov_read_default },
9263 { MKTAG('t','r','e','f'), mov_read_default },
9264 { MKTAG('t','m','c','d'), mov_read_tmcd },
9265 { MKTAG('c','h','a','p'), mov_read_chap },
9266 { MKTAG('t','r','e','x'), mov_read_trex },
9267 { MKTAG('t','r','u','n'), mov_read_trun },
9268 { MKTAG('u','d','t','a'), mov_read_default },
9269 { MKTAG('w','a','v','e'), mov_read_wave },
9270 { MKTAG('e','s','d','s'), mov_read_esds },
9271 { MKTAG('d','a','c','3'), mov_read_dac3 }, /* AC-3 info */
9272 { MKTAG('d','e','c','3'), mov_read_dec3 }, /* EAC-3 info */
9273 { MKTAG('d','d','t','s'), mov_read_ddts }, /* DTS audio descriptor */
9274 { MKTAG('w','i','d','e'), mov_read_wide }, /* place holder */
9275 { MKTAG('w','f','e','x'), mov_read_wfex },
9276 { MKTAG('c','m','o','v'), mov_read_cmov },
9277 { MKTAG('c','h','a','n'), mov_read_chan }, /* channel layout from quicktime */
9278 { MKTAG('c','h','n','l'), mov_read_chnl }, /* channel layout from ISO-14496-12 */
9279 { MKTAG('d','v','c','1'), mov_read_dvc1 },
9280 { MKTAG('s','g','p','d'), mov_read_sgpd },
9281 { MKTAG('s','b','g','p'), mov_read_sbgp },
9282 { MKTAG('h','v','c','C'), mov_read_glbl },
9283 { MKTAG('v','v','c','C'), mov_read_glbl },
9284 { MKTAG('u','u','i','d'), mov_read_uuid },
9285 { MKTAG('C','i','n', 0x8e), mov_read_targa_y216 },
9286 { MKTAG('f','r','e','e'), mov_read_free },
9287 { MKTAG('-','-','-','-'), mov_read_custom },
9288 { MKTAG('s','i','n','f'), mov_read_default },
9289 { MKTAG('f','r','m','a'), mov_read_frma },
9290 { MKTAG('s','e','n','c'), mov_read_senc },
9291 { MKTAG('s','a','i','z'), mov_read_saiz },
9292 { MKTAG('s','a','i','o'), mov_read_saio },
9293 { MKTAG('p','s','s','h'), mov_read_pssh },
9294 { MKTAG('s','c','h','m'), mov_read_schm },
9295 { MKTAG('s','c','h','i'), mov_read_default },
9296 { MKTAG('t','e','n','c'), mov_read_tenc },
9297 { MKTAG('d','f','L','a'), mov_read_dfla },
9298 { MKTAG('s','t','3','d'), mov_read_st3d }, /* stereoscopic 3D video box */
9299 { MKTAG('s','v','3','d'), mov_read_sv3d }, /* spherical video box */
9300 { MKTAG('v','e','x','u'), mov_read_vexu }, /* video extension usage */
9301 { MKTAG('h','f','o','v'), mov_read_hfov },
9302 { MKTAG('d','O','p','s'), mov_read_dops },
9303 { MKTAG('d','m','l','p'), mov_read_dmlp },
9304 { MKTAG('S','m','D','m'), mov_read_smdm },
9305 { MKTAG('C','o','L','L'), mov_read_coll },
9306 { MKTAG('v','p','c','C'), mov_read_vpcc },
9307 { MKTAG('m','d','c','v'), mov_read_mdcv },
9308 { MKTAG('c','l','l','i'), mov_read_clli },
9309 { MKTAG('d','v','c','C'), mov_read_dvcc_dvvc },
9310 { MKTAG('d','v','v','C'), mov_read_dvcc_dvvc },
9311 { MKTAG('d','v','w','C'), mov_read_dvcc_dvvc },
9312 { MKTAG('k','i','n','d'), mov_read_kind },
9313 { MKTAG('S','A','3','D'), mov_read_SA3D }, /* ambisonic audio box */
9314 { MKTAG('S','A','N','D'), mov_read_SAND }, /* non diegetic audio box */
9315 { MKTAG('i','l','o','c'), mov_read_iloc },
9316 { MKTAG('p','c','m','C'), mov_read_pcmc }, /* PCM configuration box */
9317 { MKTAG('p','i','t','m'), mov_read_pitm },
9318 { MKTAG('e','v','c','C'), mov_read_glbl },
9319 { MKTAG('i','d','a','t'), mov_read_idat },
9320 { MKTAG('i','m','i','r'), mov_read_imir },
9321 { MKTAG('i','r','e','f'), mov_read_iref },
9322 { MKTAG('i','s','p','e'), mov_read_ispe },
9323 { MKTAG('i','r','o','t'), mov_read_irot },
9324 { MKTAG('i','p','r','p'), mov_read_iprp },
9325 { MKTAG('i','i','n','f'), mov_read_iinf },
9326 { MKTAG('a','m','v','e'), mov_read_amve }, /* ambient viewing environment box */
9327 { MKTAG('l','h','v','C'), mov_read_lhvc },
9328 { MKTAG('l','v','c','C'), mov_read_glbl },
9329 { MKTAG('a','p','v','C'), mov_read_glbl },
9330 #if CONFIG_IAMFDEC
9331 { MKTAG('i','a','c','b'), mov_read_iacb },
9332 #endif
9333 { 0, NULL }
9334 };
9335 
9337 {
9338  int64_t total_size = 0;
9339  MOVAtom a;
9340  int i;
9341 
9342  if (c->atom_depth > 10) {
9343  av_log(c->fc, AV_LOG_ERROR, "Atoms too deeply nested\n");
9344  return AVERROR_INVALIDDATA;
9345  }
9346  c->atom_depth ++;
9347 
9348  if (atom.size < 0)
9349  atom.size = INT64_MAX;
9350  while (total_size <= atom.size - 8) {
9351  int (*parse)(MOVContext*, AVIOContext*, MOVAtom) = NULL;
9352  a.size = avio_rb32(pb);
9353  a.type = avio_rl32(pb);
9354  if (avio_feof(pb))
9355  break;
9356  if (((a.type == MKTAG('f','r','e','e') && c->moov_retry) ||
9357  a.type == MKTAG('h','o','o','v')) &&
9358  a.size >= 8 &&
9359  c->fc->strict_std_compliance < FF_COMPLIANCE_STRICT) {
9360  uint32_t type;
9361  avio_skip(pb, 4);
9362  type = avio_rl32(pb);
9363  if (avio_feof(pb))
9364  break;
9365  avio_seek(pb, -8, SEEK_CUR);
9366  if (type == MKTAG('m','v','h','d') ||
9367  type == MKTAG('c','m','o','v')) {
9368  av_log(c->fc, AV_LOG_ERROR, "Detected moov in a free or hoov atom.\n");
9369  a.type = MKTAG('m','o','o','v');
9370  }
9371  }
9372  if (atom.type != MKTAG('r','o','o','t') &&
9373  atom.type != MKTAG('m','o','o','v')) {
9374  if (a.type == MKTAG('t','r','a','k') ||
9375  a.type == MKTAG('m','d','a','t')) {
9376  av_log(c->fc, AV_LOG_ERROR, "Broken file, trak/mdat not at top-level\n");
9377  avio_skip(pb, -8);
9378  c->atom_depth --;
9379  return 0;
9380  }
9381  }
9382  total_size += 8;
9383  if (a.size == 1 && total_size + 8 <= atom.size) { /* 64 bit extended size */
9384  a.size = avio_rb64(pb) - 8;
9385  total_size += 8;
9386  }
9387  av_log(c->fc, AV_LOG_TRACE, "type:'%s' parent:'%s' sz: %"PRId64" %"PRId64" %"PRId64"\n",
9388  av_fourcc2str(a.type), av_fourcc2str(atom.type), a.size, total_size, atom.size);
9389  if (a.size == 0) {
9390  a.size = atom.size - total_size + 8;
9391  }
9392  if (a.size < 0)
9393  break;
9394  a.size -= 8;
9395  if (a.size < 0)
9396  break;
9397  a.size = FFMIN(a.size, atom.size - total_size);
9398 
9399  for (i = 0; mov_default_parse_table[i].type; i++)
9400  if (mov_default_parse_table[i].type == a.type) {
9402  break;
9403  }
9404 
9405  // container is user data
9406  if (!parse && (atom.type == MKTAG('u','d','t','a') ||
9407  atom.type == MKTAG('i','l','s','t')))
9409 
9410  // Supports parsing the QuickTime Metadata Keys.
9411  // https://developer.apple.com/library/mac/documentation/QuickTime/QTFF/Metadata/Metadata.html
9412  if (!parse && c->found_hdlr_mdta &&
9413  atom.type == MKTAG('m','e','t','a') &&
9414  a.type == MKTAG('k','e','y','s') &&
9415  c->meta_keys_count == 0) {
9416  parse = mov_read_keys;
9417  }
9418 
9419  if (!parse) { /* skip leaf atoms data */
9420  avio_skip(pb, a.size);
9421  } else {
9422  int64_t start_pos = avio_tell(pb);
9423  int64_t left;
9424  int err = parse(c, pb, a);
9425  if (err < 0) {
9426  c->atom_depth --;
9427  return err;
9428  }
9429  if (c->found_moov && c->found_mdat && a.size <= INT64_MAX - start_pos &&
9430  ((!(pb->seekable & AVIO_SEEKABLE_NORMAL) || c->fc->flags & AVFMT_FLAG_IGNIDX || c->frag_index.complete) ||
9431  start_pos + a.size == avio_size(pb))) {
9432  if (!(pb->seekable & AVIO_SEEKABLE_NORMAL) || c->fc->flags & AVFMT_FLAG_IGNIDX || c->frag_index.complete)
9433  c->next_root_atom = start_pos + a.size;
9434  c->atom_depth --;
9435  return 0;
9436  }
9437  left = a.size - avio_tell(pb) + start_pos;
9438  if (left > 0) /* skip garbage at atom end */
9439  avio_skip(pb, left);
9440  else if (left < 0) {
9441  av_log(c->fc, AV_LOG_WARNING,
9442  "overread end of atom '%s' by %"PRId64" bytes\n",
9443  av_fourcc2str(a.type), -left);
9444  avio_seek(pb, left, SEEK_CUR);
9445  }
9446  }
9447 
9448  total_size += a.size;
9449  }
9450 
9451  if (total_size < atom.size && atom.size < 0x7ffff)
9452  avio_skip(pb, atom.size - total_size);
9453 
9454  c->atom_depth --;
9455  return 0;
9456 }
9457 
9458 static int mov_probe(const AVProbeData *p)
9459 {
9460  int64_t offset;
9461  uint32_t tag;
9462  int score = 0;
9463  int moov_offset = -1;
9464 
9465  /* check file header */
9466  offset = 0;
9467  for (;;) {
9468  int64_t size;
9469  int minsize = 8;
9470  /* ignore invalid offset */
9471  if ((offset + 8ULL) > (unsigned int)p->buf_size)
9472  break;
9473  size = AV_RB32(p->buf + offset);
9474  if (size == 1 && offset + 16 <= (unsigned int)p->buf_size) {
9475  size = AV_RB64(p->buf+offset + 8);
9476  minsize = 16;
9477  } else if (size == 0) {
9478  size = p->buf_size - offset;
9479  }
9480  if (size < minsize) {
9481  offset += 4;
9482  continue;
9483  }
9484  tag = AV_RL32(p->buf + offset + 4);
9485  switch(tag) {
9486  /* check for obvious tags */
9487  case MKTAG('m','o','o','v'):
9488  moov_offset = offset + 4;
9489  case MKTAG('m','d','a','t'):
9490  case MKTAG('p','n','o','t'): /* detect movs with preview pics like ew.mov and april.mov */
9491  case MKTAG('u','d','t','a'): /* Packet Video PVAuthor adds this and a lot of more junk */
9492  case MKTAG('f','t','y','p'):
9493  if (tag == MKTAG('f','t','y','p') &&
9494  ( AV_RL32(p->buf + offset + 8) == MKTAG('j','p','2',' ')
9495  || AV_RL32(p->buf + offset + 8) == MKTAG('j','p','x',' ')
9496  || AV_RL32(p->buf + offset + 8) == MKTAG('j','x','l',' ')
9497  )) {
9498  score = FFMAX(score, 5);
9499  } else {
9500  score = AVPROBE_SCORE_MAX;
9501  }
9502  break;
9503  /* those are more common words, so rate then a bit less */
9504  case MKTAG('e','d','i','w'): /* xdcam files have reverted first tags */
9505  case MKTAG('w','i','d','e'):
9506  case MKTAG('f','r','e','e'):
9507  case MKTAG('j','u','n','k'):
9508  case MKTAG('p','i','c','t'):
9509  score = FFMAX(score, AVPROBE_SCORE_MAX - 5);
9510  break;
9511  case MKTAG(0x82,0x82,0x7f,0x7d):
9512  score = FFMAX(score, AVPROBE_SCORE_EXTENSION - 5);
9513  break;
9514  case MKTAG('s','k','i','p'):
9515  case MKTAG('u','u','i','d'):
9516  case MKTAG('p','r','f','l'):
9517  /* if we only find those cause probedata is too small at least rate them */
9518  score = FFMAX(score, AVPROBE_SCORE_EXTENSION);
9519  break;
9520  }
9521  if (size > INT64_MAX - offset)
9522  break;
9523  offset += size;
9524  }
9525  if (score > AVPROBE_SCORE_MAX - 50 && moov_offset != -1) {
9526  /* moov atom in the header - we should make sure that this is not a
9527  * MOV-packed MPEG-PS */
9528  offset = moov_offset;
9529 
9530  while (offset < (p->buf_size - 16)) { /* Sufficient space */
9531  /* We found an actual hdlr atom */
9532  if (AV_RL32(p->buf + offset ) == MKTAG('h','d','l','r') &&
9533  AV_RL32(p->buf + offset + 8) == MKTAG('m','h','l','r') &&
9534  AV_RL32(p->buf + offset + 12) == MKTAG('M','P','E','G')) {
9535  av_log(NULL, AV_LOG_WARNING, "Found media data tag MPEG indicating this is a MOV-packed MPEG-PS.\n");
9536  /* We found a media handler reference atom describing an
9537  * MPEG-PS-in-MOV, return a
9538  * low score to force expanding the probe window until
9539  * mpegps_probe finds what it needs */
9540  return 5;
9541  } else {
9542  /* Keep looking */
9543  offset += 2;
9544  }
9545  }
9546  }
9547 
9548  return score;
9549 }
9550 
9551 // must be done after parsing all trak because there's no order requirement
9553 {
9554  MOVContext *mov = s->priv_data;
9555  MOVStreamContext *sc;
9556  int64_t cur_pos;
9557  int i, j;
9558  int chapter_track;
9559 
9560  for (j = 0; j < mov->nb_chapter_tracks; j++) {
9561  AVStream *st = NULL;
9562  FFStream *sti = NULL;
9563  chapter_track = mov->chapter_tracks[j];
9564  for (i = 0; i < s->nb_streams; i++) {
9565  sc = mov->fc->streams[i]->priv_data;
9566  if (sc->id == chapter_track) {
9567  st = s->streams[i];
9568  break;
9569  }
9570  }
9571  if (!st) {
9572  av_log(s, AV_LOG_ERROR, "Referenced QT chapter track not found\n");
9573  continue;
9574  }
9575  sti = ffstream(st);
9576 
9577  sc = st->priv_data;
9578  cur_pos = avio_tell(sc->pb);
9579 
9580  if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
9582  if (!st->attached_pic.data && sti->nb_index_entries) {
9583  // Retrieve the first frame, if possible
9584  AVIndexEntry *sample = &sti->index_entries[0];
9585  if (avio_seek(sc->pb, sample->pos, SEEK_SET) != sample->pos) {
9586  av_log(s, AV_LOG_ERROR, "Failed to retrieve first frame\n");
9587  goto finish;
9588  }
9589 
9590  if (ff_add_attached_pic(s, st, sc->pb, NULL, sample->size) < 0)
9591  goto finish;
9592  }
9593  } else {
9596  st->discard = AVDISCARD_ALL;
9597  for (int i = 0; i < sti->nb_index_entries; i++) {
9598  AVIndexEntry *sample = &sti->index_entries[i];
9599  int64_t end = i+1 < sti->nb_index_entries ? sti->index_entries[i+1].timestamp : st->duration;
9600  uint8_t *title;
9601  uint16_t ch;
9602  int len, title_len;
9603 
9604  if (end < sample->timestamp) {
9605  av_log(s, AV_LOG_WARNING, "ignoring stream duration which is shorter than chapters\n");
9606  end = AV_NOPTS_VALUE;
9607  }
9608 
9609  if (avio_seek(sc->pb, sample->pos, SEEK_SET) != sample->pos) {
9610  av_log(s, AV_LOG_ERROR, "Chapter %d not found in file\n", i);
9611  goto finish;
9612  }
9613 
9614  // the first two bytes are the length of the title
9615  len = avio_rb16(sc->pb);
9616  if (len > sample->size-2)
9617  continue;
9618  title_len = 2*len + 1;
9619  if (!(title = av_mallocz(title_len)))
9620  goto finish;
9621 
9622  // The samples could theoretically be in any encoding if there's an encd
9623  // atom following, but in practice are only utf-8 or utf-16, distinguished
9624  // instead by the presence of a BOM
9625  if (!len) {
9626  title[0] = 0;
9627  } else {
9628  ch = avio_rb16(sc->pb);
9629  if (ch == 0xfeff)
9630  avio_get_str16be(sc->pb, len, title, title_len);
9631  else if (ch == 0xfffe)
9632  avio_get_str16le(sc->pb, len, title, title_len);
9633  else {
9634  AV_WB16(title, ch);
9635  if (len == 1 || len == 2)
9636  title[len] = 0;
9637  else
9638  avio_get_str(sc->pb, INT_MAX, title + 2, len - 1);
9639  }
9640  }
9641 
9642  avpriv_new_chapter(s, i, st->time_base, sample->timestamp, end, title);
9643  av_freep(&title);
9644  }
9645  }
9646 finish:
9647  avio_seek(sc->pb, cur_pos, SEEK_SET);
9648  }
9649 }
9650 
9652  int64_t value, int flags)
9653 {
9654  AVTimecode tc;
9655  char buf[AV_TIMECODE_STR_SIZE];
9656  AVRational rate = st->avg_frame_rate;
9657  int ret = av_timecode_init(&tc, rate, flags, 0, s);
9658  if (ret < 0)
9659  return ret;
9660  av_dict_set(&st->metadata, "timecode",
9661  av_timecode_make_string(&tc, buf, value), 0);
9662  return 0;
9663 }
9664 
9666 {
9667  MOVStreamContext *sc = st->priv_data;
9668  FFStream *const sti = ffstream(st);
9669  char buf[AV_TIMECODE_STR_SIZE];
9670  int64_t cur_pos = avio_tell(sc->pb);
9671  int hh, mm, ss, ff, drop;
9672 
9673  if (!sti->nb_index_entries)
9674  return -1;
9675 
9676  avio_seek(sc->pb, sti->index_entries->pos, SEEK_SET);
9677  avio_skip(s->pb, 13);
9678  hh = avio_r8(s->pb);
9679  mm = avio_r8(s->pb);
9680  ss = avio_r8(s->pb);
9681  drop = avio_r8(s->pb);
9682  ff = avio_r8(s->pb);
9683  snprintf(buf, AV_TIMECODE_STR_SIZE, "%02d:%02d:%02d%c%02d",
9684  hh, mm, ss, drop ? ';' : ':', ff);
9685  av_dict_set(&st->metadata, "timecode", buf, 0);
9686 
9687  avio_seek(sc->pb, cur_pos, SEEK_SET);
9688  return 0;
9689 }
9690 
9692 {
9693  MOVStreamContext *sc = st->priv_data;
9694  FFStream *const sti = ffstream(st);
9695  int flags = 0;
9696  int64_t cur_pos = avio_tell(sc->pb);
9697  int64_t value;
9698  AVRational tc_rate = st->avg_frame_rate;
9699  int tmcd_nb_frames = sc->tmcd_nb_frames;
9700  int rounded_tc_rate;
9701 
9702  if (!sti->nb_index_entries)
9703  return -1;
9704 
9705  if (!tc_rate.num || !tc_rate.den || !tmcd_nb_frames)
9706  return -1;
9707 
9708  avio_seek(sc->pb, sti->index_entries->pos, SEEK_SET);
9709  value = avio_rb32(s->pb);
9710 
9711  if (sc->tmcd_flags & 0x0001) flags |= AV_TIMECODE_FLAG_DROPFRAME;
9712  if (sc->tmcd_flags & 0x0002) flags |= AV_TIMECODE_FLAG_24HOURSMAX;
9713  if (sc->tmcd_flags & 0x0004) flags |= AV_TIMECODE_FLAG_ALLOWNEGATIVE;
9714 
9715  /* Assume Counter flag is set to 1 in tmcd track (even though it is likely
9716  * not the case) and thus assume "frame number format" instead of QT one.
9717  * No sample with tmcd track can be found with a QT timecode at the moment,
9718  * despite what the tmcd track "suggests" (Counter flag set to 0 means QT
9719  * format). */
9720 
9721  /* 60 fps content have tmcd_nb_frames set to 30 but tc_rate set to 60, so
9722  * we multiply the frame number with the quotient.
9723  * See tickets #9492, #9710. */
9724  rounded_tc_rate = (tc_rate.num + tc_rate.den / 2LL) / tc_rate.den;
9725  /* Work around files where tmcd_nb_frames is rounded down from frame rate
9726  * instead of up. See ticket #5978. */
9727  if (tmcd_nb_frames == tc_rate.num / tc_rate.den &&
9728  s->strict_std_compliance < FF_COMPLIANCE_STRICT)
9729  tmcd_nb_frames = rounded_tc_rate;
9730  value = av_rescale(value, rounded_tc_rate, tmcd_nb_frames);
9731 
9733 
9734  avio_seek(sc->pb, cur_pos, SEEK_SET);
9735  return 0;
9736 }
9737 
9739  int i;
9740  if (!index || !*index) return;
9741  for (i = 0; i < (*index)->nb_encrypted_samples; i++) {
9742  av_encryption_info_free((*index)->encrypted_samples[i]);
9743  }
9744  av_freep(&(*index)->encrypted_samples);
9745  av_freep(&(*index)->auxiliary_info_sizes);
9746  av_freep(&(*index)->auxiliary_offsets);
9747  av_freep(index);
9748 }
9749 
9751 {
9752  MOVStreamContext *sc = st->priv_data;
9753 
9754  if (!sc || --sc->refcount) {
9755  st->priv_data = NULL;
9756  return;
9757  }
9758 
9759  av_freep(&sc->tts_data);
9760  for (int i = 0; i < sc->drefs_count; i++) {
9761  av_freep(&sc->drefs[i].path);
9762  av_freep(&sc->drefs[i].dir);
9763  }
9764  av_freep(&sc->drefs);
9765 
9766  sc->drefs_count = 0;
9767 
9768  if (!sc->pb_is_copied)
9769  ff_format_io_close(s, &sc->pb);
9770 
9771  sc->pb = NULL;
9772  av_freep(&sc->chunk_offsets);
9773  av_freep(&sc->stsc_data);
9774  av_freep(&sc->sample_sizes);
9775  av_freep(&sc->keyframes);
9776  av_freep(&sc->ctts_data);
9777  av_freep(&sc->stts_data);
9778  av_freep(&sc->sdtp_data);
9779  av_freep(&sc->stps_data);
9780  av_freep(&sc->elst_data);
9781  av_freep(&sc->rap_group);
9782  av_freep(&sc->sync_group);
9783  av_freep(&sc->sgpd_sync);
9784  av_freep(&sc->sample_offsets);
9785  av_freep(&sc->open_key_samples);
9786  av_freep(&sc->display_matrix);
9787  av_freep(&sc->index_ranges);
9788 
9789  if (sc->extradata)
9790  for (int i = 0; i < sc->stsd_count; i++)
9791  av_free(sc->extradata[i]);
9792  av_freep(&sc->extradata);
9793  av_freep(&sc->extradata_size);
9794 
9798 
9799  av_freep(&sc->stereo3d);
9800  av_freep(&sc->spherical);
9801  av_freep(&sc->mastering);
9802  av_freep(&sc->coll);
9803  av_freep(&sc->ambient);
9804 
9805 #if CONFIG_IAMFDEC
9806  if (sc->iamf)
9808 #endif
9809  av_freep(&sc->iamf);
9810 }
9811 
9813 {
9814  MOVContext *mov = s->priv_data;
9815  int i, j;
9816 
9817  for (i = 0; i < s->nb_streams; i++) {
9818  AVStream *st = s->streams[i];
9819 
9821  }
9822 
9823  av_freep(&mov->dv_demux);
9825  mov->dv_fctx = NULL;
9826 
9827  if (mov->meta_keys) {
9828  for (i = 1; i < mov->meta_keys_count; i++) {
9829  av_freep(&mov->meta_keys[i]);
9830  }
9831  av_freep(&mov->meta_keys);
9832  }
9833 
9834  av_freep(&mov->trex_data);
9835  av_freep(&mov->bitrates);
9836 
9837  for (i = 0; i < mov->frag_index.nb_items; i++) {
9839  for (j = 0; j < mov->frag_index.item[i].nb_stream_info; j++) {
9840  mov_free_encryption_index(&frag[j].encryption_index);
9841  }
9843  }
9844  av_freep(&mov->frag_index.item);
9845 
9846  av_freep(&mov->aes_decrypt);
9847  av_freep(&mov->chapter_tracks);
9848  for (i = 0; i < mov->nb_heif_item; i++) {
9849  if (!mov->heif_item[i])
9850  continue;
9851  av_freep(&mov->heif_item[i]->name);
9852  av_freep(&mov->heif_item[i]->icc_profile);
9853  av_freep(&mov->heif_item[i]);
9854  }
9855  av_freep(&mov->heif_item);
9856  for (i = 0; i < mov->nb_heif_grid; i++) {
9857  av_freep(&mov->heif_grid[i].tile_id_list);
9860  }
9861  av_freep(&mov->heif_grid);
9862 
9863  return 0;
9864 }
9865 
9866 static int tmcd_is_referenced(AVFormatContext *s, int tmcd_id)
9867 {
9868  int i;
9869 
9870  for (i = 0; i < s->nb_streams; i++) {
9871  AVStream *st = s->streams[i];
9872  MOVStreamContext *sc = st->priv_data;
9873 
9874  if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO &&
9875  sc->timecode_track == tmcd_id)
9876  return 1;
9877  }
9878  return 0;
9879 }
9880 
9881 /* look for a tmcd track not referenced by any video track, and export it globally */
9883 {
9884  int i;
9885 
9886  for (i = 0; i < s->nb_streams; i++) {
9887  AVStream *st = s->streams[i];
9888 
9889  if (st->codecpar->codec_tag == MKTAG('t','m','c','d') &&
9890  !tmcd_is_referenced(s, i + 1)) {
9891  AVDictionaryEntry *tcr = av_dict_get(st->metadata, "timecode", NULL, 0);
9892  if (tcr) {
9893  av_dict_set(&s->metadata, "timecode", tcr->value, 0);
9894  break;
9895  }
9896  }
9897  }
9898 }
9899 
9900 static int read_tfra(MOVContext *mov, AVIOContext *f)
9901 {
9902  int version, fieldlength, i, j;
9903  int64_t pos = avio_tell(f);
9904  uint32_t size = avio_rb32(f);
9905  unsigned track_id, item_count;
9906 
9907  if (avio_rb32(f) != MKBETAG('t', 'f', 'r', 'a')) {
9908  return 1;
9909  }
9910  av_log(mov->fc, AV_LOG_VERBOSE, "found tfra\n");
9911 
9912  version = avio_r8(f);
9913  avio_rb24(f);
9914  track_id = avio_rb32(f);
9915  fieldlength = avio_rb32(f);
9916  item_count = avio_rb32(f);
9917  for (i = 0; i < item_count; i++) {
9918  int64_t time, offset;
9919  int index;
9920  MOVFragmentStreamInfo * frag_stream_info;
9921 
9922  if (avio_feof(f)) {
9923  return AVERROR_INVALIDDATA;
9924  }
9925 
9926  if (version == 1) {
9927  time = avio_rb64(f);
9928  offset = avio_rb64(f);
9929  } else {
9930  time = avio_rb32(f);
9931  offset = avio_rb32(f);
9932  }
9933 
9934  // The first sample of each stream in a fragment is always a random
9935  // access sample. So it's entry in the tfra can be used as the
9936  // initial PTS of the fragment.
9937  index = update_frag_index(mov, offset);
9938  frag_stream_info = get_frag_stream_info(&mov->frag_index, index, track_id);
9939  if (frag_stream_info &&
9940  frag_stream_info->first_tfra_pts == AV_NOPTS_VALUE)
9941  frag_stream_info->first_tfra_pts = time;
9942 
9943  for (j = 0; j < ((fieldlength >> 4) & 3) + 1; j++)
9944  avio_r8(f);
9945  for (j = 0; j < ((fieldlength >> 2) & 3) + 1; j++)
9946  avio_r8(f);
9947  for (j = 0; j < ((fieldlength >> 0) & 3) + 1; j++)
9948  avio_r8(f);
9949  }
9950 
9951  avio_seek(f, pos + size, SEEK_SET);
9952  return 0;
9953 }
9954 
9956 {
9957  int64_t stream_size = avio_size(f);
9958  int64_t original_pos = avio_tell(f);
9959  int64_t seek_ret;
9960  int ret = -1;
9961  if ((seek_ret = avio_seek(f, stream_size - 4, SEEK_SET)) < 0) {
9962  ret = seek_ret;
9963  goto fail;
9964  }
9965  c->mfra_size = avio_rb32(f);
9966  c->have_read_mfra_size = 1;
9967  if (!c->mfra_size || c->mfra_size > stream_size) {
9968  av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (unreasonable size)\n");
9969  goto fail;
9970  }
9971  if ((seek_ret = avio_seek(f, -((int64_t) c->mfra_size), SEEK_CUR)) < 0) {
9972  ret = seek_ret;
9973  goto fail;
9974  }
9975  if (avio_rb32(f) != c->mfra_size) {
9976  av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (size mismatch)\n");
9977  goto fail;
9978  }
9979  if (avio_rb32(f) != MKBETAG('m', 'f', 'r', 'a')) {
9980  av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (tag mismatch)\n");
9981  goto fail;
9982  }
9983  av_log(c->fc, AV_LOG_VERBOSE, "stream has mfra\n");
9984  do {
9985  ret = read_tfra(c, f);
9986  if (ret < 0)
9987  goto fail;
9988  } while (!ret);
9989  ret = 0;
9990  c->frag_index.complete = 1;
9991 fail:
9992  seek_ret = avio_seek(f, original_pos, SEEK_SET);
9993  if (seek_ret < 0) {
9994  av_log(c->fc, AV_LOG_ERROR,
9995  "failed to seek back after looking for mfra\n");
9996  ret = seek_ret;
9997  }
9998  return ret;
9999 }
10000 
10001 static int set_icc_profile_from_item(AVPacketSideData **coded_side_data, int *nb_coded_side_data,
10002  const HEIFItem *item)
10003 {
10004  AVPacketSideData *sd = av_packet_side_data_new(coded_side_data, nb_coded_side_data,
10006  item->icc_profile_size, 0);
10007  if (!sd)
10008  return AVERROR(ENOMEM);
10009 
10010  memcpy(sd->data, item->icc_profile, item->icc_profile_size);
10011 
10012  return 0;
10013 }
10014 
10015 static int set_display_matrix_from_item(AVPacketSideData **coded_side_data, int *nb_coded_side_data,
10016  const HEIFItem *item)
10017 {
10018  int32_t *matrix;
10019  AVPacketSideData *sd = av_packet_side_data_new(coded_side_data,
10020  nb_coded_side_data,
10022  9 * sizeof(*matrix), 0);
10023  if (!sd)
10024  return AVERROR(ENOMEM);
10025 
10026  matrix = (int32_t*)sd->data;
10027  /* rotation is in the counter-clockwise direction whereas
10028  * av_display_rotation_set() expects its argument to be
10029  * oriented clockwise, so we need to negate it. */
10031  av_display_matrix_flip(matrix, item->hflip, item->vflip);
10032 
10033  return 0;
10034 }
10035 
10036 static int read_image_grid(AVFormatContext *s, const HEIFGrid *grid,
10037  AVStreamGroupTileGrid *tile_grid)
10038 {
10039  MOVContext *c = s->priv_data;
10040  const HEIFItem *item = grid->item;
10041  int64_t offset = 0, pos = avio_tell(s->pb);
10042  int x = 0, y = 0, i = 0;
10043  int tile_rows, tile_cols;
10044  int flags, size;
10045 
10046  if (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL)) {
10047  av_log(c->fc, AV_LOG_INFO, "grid box with non seekable input\n");
10048  return AVERROR_PATCHWELCOME;
10049  }
10050  if (item->is_idat_relative) {
10051  if (!c->idat_offset) {
10052  av_log(c->fc, AV_LOG_ERROR, "missing idat box required by the image grid\n");
10053  return AVERROR_INVALIDDATA;
10054  }
10055  offset = c->idat_offset;
10056  }
10057 
10058  avio_seek(s->pb, item->extent_offset + offset, SEEK_SET);
10059 
10060  avio_r8(s->pb); /* version */
10061  flags = avio_r8(s->pb);
10062 
10063  tile_rows = avio_r8(s->pb) + 1;
10064  tile_cols = avio_r8(s->pb) + 1;
10065  /* actual width and height of output image */
10066  tile_grid->width = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
10067  tile_grid->height = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
10068 
10069  /* ICC profile */
10070  if (item->icc_profile_size) {
10071  int ret = set_icc_profile_from_item(&tile_grid->coded_side_data,
10072  &tile_grid->nb_coded_side_data, item);
10073  if (ret < 0)
10074  return ret;
10075  }
10076  /* rotation */
10077  if (item->rotation || item->hflip || item->vflip) {
10079  &tile_grid->nb_coded_side_data, item);
10080  if (ret < 0)
10081  return ret;
10082  }
10083 
10084  av_log(c->fc, AV_LOG_TRACE, "grid: grid_rows %d grid_cols %d output_width %d output_height %d\n",
10085  tile_rows, tile_cols, tile_grid->width, tile_grid->height);
10086 
10087  avio_seek(s->pb, pos, SEEK_SET);
10088 
10089  size = tile_rows * tile_cols;
10090  tile_grid->nb_tiles = grid->nb_tiles;
10091 
10092  if (tile_grid->nb_tiles != size)
10093  return AVERROR_INVALIDDATA;
10094 
10095  for (int i = 0; i < tile_cols; i++)
10096  tile_grid->coded_width += grid->tile_item_list[i]->width;
10097  for (int i = 0; i < size; i += tile_cols)
10098  tile_grid->coded_height += grid->tile_item_list[i]->height;
10099 
10100  tile_grid->offsets = av_calloc(tile_grid->nb_tiles, sizeof(*tile_grid->offsets));
10101  if (!tile_grid->offsets)
10102  return AVERROR(ENOMEM);
10103 
10104  while (y < tile_grid->coded_height) {
10105  int left_col = i;
10106 
10107  while (x < tile_grid->coded_width) {
10108  if (i == tile_grid->nb_tiles)
10109  return AVERROR_INVALIDDATA;
10110 
10111  tile_grid->offsets[i].idx = grid->tile_idx_list[i];
10112  tile_grid->offsets[i].horizontal = x;
10113  tile_grid->offsets[i].vertical = y;
10114 
10115  x += grid->tile_item_list[i++]->width;
10116  }
10117 
10118  if (x > tile_grid->coded_width) {
10119  av_log(c->fc, AV_LOG_ERROR, "Non uniform HEIF tiles\n");
10120  return AVERROR_INVALIDDATA;
10121  }
10122 
10123  x = 0;
10124  y += grid->tile_item_list[left_col]->height;
10125  }
10126 
10127  if (y > tile_grid->coded_height || i != tile_grid->nb_tiles) {
10128  av_log(c->fc, AV_LOG_ERROR, "Non uniform HEIF tiles\n");
10129  return AVERROR_INVALIDDATA;
10130  }
10131 
10132  return 0;
10133 }
10134 
10135 static int read_image_iovl(AVFormatContext *s, const HEIFGrid *grid,
10136  AVStreamGroupTileGrid *tile_grid)
10137 {
10138  MOVContext *c = s->priv_data;
10139  const HEIFItem *item = grid->item;
10140  uint16_t canvas_fill_value[4];
10141  int64_t offset = 0, pos = avio_tell(s->pb);
10142  int ret = 0, flags;
10143 
10144  if (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL)) {
10145  av_log(c->fc, AV_LOG_INFO, "iovl box with non seekable input\n");
10146  return AVERROR_PATCHWELCOME;
10147  }
10148  if (item->is_idat_relative) {
10149  if (!c->idat_offset) {
10150  av_log(c->fc, AV_LOG_ERROR, "missing idat box required by the image overlay\n");
10151  return AVERROR_INVALIDDATA;
10152  }
10153  offset = c->idat_offset;
10154  }
10155 
10156  avio_seek(s->pb, item->extent_offset + offset, SEEK_SET);
10157 
10158  avio_r8(s->pb); /* version */
10159  flags = avio_r8(s->pb);
10160 
10161  for (int i = 0; i < 4; i++)
10162  canvas_fill_value[i] = avio_rb16(s->pb);
10163  av_log(c->fc, AV_LOG_TRACE, "iovl: canvas_fill_value { %u, %u, %u, %u }\n",
10164  canvas_fill_value[0], canvas_fill_value[1],
10165  canvas_fill_value[2], canvas_fill_value[3]);
10166  for (int i = 0; i < 4; i++)
10167  tile_grid->background[i] = canvas_fill_value[i];
10168 
10169  /* actual width and height of output image */
10170  tile_grid->width =
10171  tile_grid->coded_width = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
10172  tile_grid->height =
10173  tile_grid->coded_height = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
10174 
10175  /* rotation */
10176  if (item->rotation || item->hflip || item->vflip) {
10178  &tile_grid->nb_coded_side_data, item);
10179  if (ret < 0)
10180  return ret;
10181  }
10182 
10183  /* ICC profile */
10184  if (item->icc_profile_size) {
10185  int ret = set_icc_profile_from_item(&tile_grid->coded_side_data,
10186  &tile_grid->nb_coded_side_data, item);
10187  if (ret < 0)
10188  return ret;
10189  }
10190 
10191  av_log(c->fc, AV_LOG_TRACE, "iovl: output_width %d, output_height %d\n",
10192  tile_grid->width, tile_grid->height);
10193 
10194  tile_grid->nb_tiles = grid->nb_tiles;
10195  tile_grid->offsets = av_malloc_array(tile_grid->nb_tiles, sizeof(*tile_grid->offsets));
10196  if (!tile_grid->offsets) {
10197  ret = AVERROR(ENOMEM);
10198  goto fail;
10199  }
10200 
10201  for (int i = 0; i < tile_grid->nb_tiles; i++) {
10202  tile_grid->offsets[i].idx = grid->tile_idx_list[i];
10203  tile_grid->offsets[i].horizontal = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
10204  tile_grid->offsets[i].vertical = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
10205  av_log(c->fc, AV_LOG_TRACE, "iovl: stream_idx[%d] %u, "
10206  "horizontal_offset[%d] %d, vertical_offset[%d] %d\n",
10207  i, tile_grid->offsets[i].idx,
10208  i, tile_grid->offsets[i].horizontal, i, tile_grid->offsets[i].vertical);
10209  }
10210 
10211 fail:
10212  avio_seek(s->pb, pos, SEEK_SET);
10213 
10214  return ret;
10215 }
10216 
10218 {
10219  MOVContext *mov = s->priv_data;
10220 
10221  for (int i = 0; i < mov->nb_heif_grid; i++) {
10223  AVStreamGroupTileGrid *tile_grid;
10224  const HEIFGrid *grid = &mov->heif_grid[i];
10225  int err, loop = 1;
10226 
10227  if (!stg)
10228  return AVERROR(ENOMEM);
10229 
10230  stg->id = grid->item->item_id;
10231  tile_grid = stg->params.tile_grid;
10232 
10233  for (int j = 0; j < grid->nb_tiles; j++) {
10234  int tile_id = grid->tile_id_list[j];
10235  int k;
10236 
10237  for (k = 0; k < mov->nb_heif_item; k++) {
10238  HEIFItem *item = mov->heif_item[k];
10239  AVStream *st;
10240 
10241  if (!item || item->item_id != tile_id)
10242  continue;
10243  st = item->st;
10244  if (!st) {
10245  av_log(s, AV_LOG_WARNING, "HEIF item id %d from grid id %d doesn't "
10246  "reference a stream\n",
10247  tile_id, grid->item->item_id);
10248  ff_remove_stream_group(s, stg);
10249  loop = 0;
10250  break;
10251  }
10252 
10253  grid->tile_item_list[j] = item;
10254  grid->tile_idx_list[j] = stg->nb_streams;
10255 
10256  err = avformat_stream_group_add_stream(stg, st);
10257  if (err < 0) {
10258  int l;
10259  if (err != AVERROR(EEXIST))
10260  return err;
10261 
10262  for (l = 0; l < stg->nb_streams; l++)
10263  if (stg->streams[l]->index == st->index)
10264  break;
10265  av_assert0(l < stg->nb_streams);
10266  grid->tile_idx_list[j] = l;
10267  }
10268 
10269  if (item->item_id != mov->primary_item_id)
10271  break;
10272  }
10273 
10274  if (k == mov->nb_heif_item) {
10275  av_assert0(loop);
10276  av_log(s, AV_LOG_WARNING, "HEIF item id %d referenced by grid id %d doesn't "
10277  "exist\n",
10278  tile_id, grid->item->item_id);
10279  ff_remove_stream_group(s, stg);
10280  loop = 0;
10281  }
10282  if (!loop)
10283  break;
10284  }
10285 
10286  if (!loop)
10287  continue;
10288 
10289  switch (grid->item->type) {
10290  case MKTAG('g','r','i','d'):
10291  err = read_image_grid(s, grid, tile_grid);
10292  break;
10293  case MKTAG('i','o','v','l'):
10294  err = read_image_iovl(s, grid, tile_grid);
10295  break;
10296  default:
10297  av_assert0(0);
10298  }
10299  if (err < 0)
10300  return err;
10301 
10302 
10303  if (grid->item->name)
10304  av_dict_set(&stg->metadata, "title", grid->item->name, 0);
10305  if (grid->item->item_id == mov->primary_item_id)
10307  }
10308 
10309  return 0;
10310 }
10311 
10313 {
10314  MOVContext *mov = s->priv_data;
10315  int err;
10316 
10317  for (int i = 0; i < mov->nb_heif_item; i++) {
10318  HEIFItem *item = mov->heif_item[i];
10319  MOVStreamContext *sc;
10320  AVStream *st;
10321  int64_t offset = 0;
10322 
10323  if (!item)
10324  continue;
10325  if (!item->st) {
10326  if (item->item_id == mov->thmb_item_id) {
10327  av_log(s, AV_LOG_ERROR, "HEIF thumbnail doesn't reference a stream\n");
10328  return AVERROR_INVALIDDATA;
10329  }
10330  continue;
10331  }
10332  if (item->is_idat_relative) {
10333  if (!mov->idat_offset) {
10334  av_log(s, AV_LOG_ERROR, "Missing idat box for item %d\n", item->item_id);
10335  return AVERROR_INVALIDDATA;
10336  }
10337  offset = mov->idat_offset;
10338  }
10339 
10340  st = item->st;
10341  sc = st->priv_data;
10342  st->codecpar->width = item->width;
10343  st->codecpar->height = item->height;
10344 
10345  err = sanity_checks(s, sc, item->item_id);
10346  if (err || !sc->sample_count)
10347  return AVERROR_INVALIDDATA;
10348 
10349  sc->sample_sizes[0] = item->extent_length;
10350  sc->chunk_offsets[0] = item->extent_offset + offset;
10351 
10352  if (item->item_id == mov->primary_item_id)
10354 
10355  if (item->rotation || item->hflip || item->vflip) {
10357  &st->codecpar->nb_coded_side_data, item);
10358  if (err < 0)
10359  return err;
10360  }
10361 
10362  mov_build_index(mov, st);
10363  }
10364 
10365  if (mov->nb_heif_grid) {
10366  err = mov_parse_tiles(s);
10367  if (err < 0)
10368  return err;
10369  }
10370 
10371  return 0;
10372 }
10373 
10375  int first_index)
10376 {
10377  MOVStreamContext *sc = st->priv_data;
10378 
10379  if (sc->tref_id < 0)
10380  return NULL;
10381 
10382  for (int i = first_index; i < s->nb_streams; i++)
10383  if (s->streams[i]->id == sc->tref_id)
10384  return s->streams[i];
10385 
10386  return NULL;
10387 }
10388 
10390 {
10391  int err;
10392 
10393  for (int i = 0; i < s->nb_streams; i++) {
10394  AVStreamGroup *stg;
10395  AVStream *st = s->streams[i];
10396  AVStream *st_base;
10397  MOVStreamContext *sc = st->priv_data;
10398  int j = 0;
10399 
10400  /* Find an enhancement stream. */
10401  if (st->codecpar->codec_id != AV_CODEC_ID_LCEVC ||
10403  continue;
10404 
10406 
10408  if (!stg)
10409  return AVERROR(ENOMEM);
10410 
10411  stg->id = st->id;
10412  stg->params.lcevc->width = st->codecpar->width;
10413  stg->params.lcevc->height = st->codecpar->height;
10414  st->codecpar->width = 0;
10415  st->codecpar->height = 0;
10416 
10417  while (st_base = mov_find_reference_track(s, st, j)) {
10418  err = avformat_stream_group_add_stream(stg, st_base);
10419  if (err < 0)
10420  return err;
10421 
10422  j = st_base->index + 1;
10423  }
10424  if (!j) {
10425  av_log(s, AV_LOG_ERROR, "Failed to find base stream for enhancement stream\n");
10426  return AVERROR_INVALIDDATA;
10427  }
10428 
10429  err = avformat_stream_group_add_stream(stg, st);
10430  if (err < 0)
10431  return err;
10432 
10433  stg->params.lcevc->lcevc_index = stg->nb_streams - 1;
10434  }
10435 
10436  return 0;
10437 }
10438 
10440 {
10441  int highest_id = 0;
10442 
10443  for (int i = 0; i < s->nb_streams; i++) {
10444  const AVStream *st = s->streams[i];
10445  const MOVStreamContext *sc = st->priv_data;
10446  if (!sc->iamf)
10447  highest_id = FFMAX(highest_id, st->id);
10448  }
10449  highest_id += !highest_id;
10450  for (int i = 0; highest_id > 1 && i < s->nb_stream_groups; i++) {
10451  AVStreamGroup *stg = s->stream_groups[i];
10453  continue;
10454  for (int j = 0; j < stg->nb_streams; j++) {
10455  AVStream *st = stg->streams[j];
10456  MOVStreamContext *sc = st->priv_data;
10457  st->id += highest_id;
10458  sc->iamf_stream_offset = highest_id;
10459  }
10460  }
10461 }
10462 
10464 {
10465  MOVContext *mov = s->priv_data;
10466  AVIOContext *pb = s->pb;
10467  int j, err;
10468  MOVAtom atom = { AV_RL32("root") };
10469  int i;
10470 
10471  if (mov->decryption_key_len != 0 && mov->decryption_key_len != AES_CTR_KEY_SIZE) {
10472  av_log(s, AV_LOG_ERROR, "Invalid decryption key len %d expected %d\n",
10474  return AVERROR(EINVAL);
10475  }
10476 
10477  mov->fc = s;
10478  mov->trak_index = -1;
10479  mov->thmb_item_id = -1;
10480  mov->primary_item_id = -1;
10481  mov->cur_item_id = -1;
10482  /* .mov and .mp4 aren't streamable anyway (only progressive download if moov is before mdat) */
10483  if (pb->seekable & AVIO_SEEKABLE_NORMAL)
10484  atom.size = avio_size(pb);
10485  else
10486  atom.size = INT64_MAX;
10487 
10488  /* check MOV header */
10489  do {
10490  if (mov->moov_retry)
10491  avio_seek(pb, 0, SEEK_SET);
10492  if ((err = mov_read_default(mov, pb, atom)) < 0) {
10493  av_log(s, AV_LOG_ERROR, "error reading header\n");
10494  return err;
10495  }
10496  } while ((pb->seekable & AVIO_SEEKABLE_NORMAL) &&
10497  !mov->found_moov && (!mov->found_iloc || !mov->found_iinf) && !mov->moov_retry++);
10498  if (!mov->found_moov && !mov->found_iloc && !mov->found_iinf) {
10499  av_log(s, AV_LOG_ERROR, "moov atom not found\n");
10500  return AVERROR_INVALIDDATA;
10501  }
10502  av_log(mov->fc, AV_LOG_TRACE, "on_parse_exit_offset=%"PRId64"\n", avio_tell(pb));
10503 
10504  if (mov->found_iloc && mov->found_iinf) {
10505  err = mov_parse_heif_items(s);
10506  if (err < 0)
10507  return err;
10508  }
10509  // prevent iloc and iinf boxes from being parsed while reading packets.
10510  // this is needed because an iinf box may have been parsed but ignored
10511  // for having old infe boxes which create no streams.
10512  mov->found_iloc = mov->found_iinf = 1;
10513 
10514  if (pb->seekable & AVIO_SEEKABLE_NORMAL) {
10515  if (mov->nb_chapter_tracks > 0 && !mov->ignore_chapters)
10517  for (i = 0; i < s->nb_streams; i++)
10518  if (s->streams[i]->codecpar->codec_tag == AV_RL32("tmcd")) {
10519  mov_read_timecode_track(s, s->streams[i]);
10520  } else if (s->streams[i]->codecpar->codec_tag == AV_RL32("rtmd")) {
10521  mov_read_rtmd_track(s, s->streams[i]);
10522  }
10523  }
10524 
10525  /* copy timecode metadata from tmcd tracks to the related video streams */
10526  for (i = 0; i < s->nb_streams; i++) {
10527  AVStream *st = s->streams[i];
10528  MOVStreamContext *sc = st->priv_data;
10529  if (sc->timecode_track > 0) {
10530  AVDictionaryEntry *tcr;
10531  int tmcd_st_id = -1;
10532 
10533  for (j = 0; j < s->nb_streams; j++) {
10534  MOVStreamContext *sc2 = s->streams[j]->priv_data;
10535  if (sc2->id == sc->timecode_track)
10536  tmcd_st_id = j;
10537  }
10538 
10539  if (tmcd_st_id < 0 || tmcd_st_id == i)
10540  continue;
10541  tcr = av_dict_get(s->streams[tmcd_st_id]->metadata, "timecode", NULL, 0);
10542  if (tcr)
10543  av_dict_set(&st->metadata, "timecode", tcr->value, 0);
10544  }
10545  }
10547 
10548  /* Create LCEVC stream groups. */
10549  err = mov_parse_lcevc_streams(s);
10550  if (err < 0)
10551  return err;
10552 
10553  for (i = 0; i < s->nb_streams; i++) {
10554  AVStream *st = s->streams[i];
10555  FFStream *const sti = ffstream(st);
10556  MOVStreamContext *sc = st->priv_data;
10557  uint32_t dvdsub_clut[FF_DVDCLUT_CLUT_LEN] = {0};
10558  fix_timescale(mov, sc);
10559  if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
10560  st->codecpar->codec_id == AV_CODEC_ID_AAC) {
10561  sti->skip_samples = sc->start_pad;
10562  }
10563  if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && sc->nb_frames_for_fps > 0 && sc->duration_for_fps > 0)
10565  sc->time_scale*(int64_t)sc->nb_frames_for_fps, sc->duration_for_fps, INT_MAX);
10567  if (st->codecpar->width <= 0 || st->codecpar->height <= 0) {
10568  st->codecpar->width = sc->width;
10569  st->codecpar->height = sc->height;
10570  }
10573 
10574  for (j = 0; j < FF_DVDCLUT_CLUT_LEN; j++)
10575  dvdsub_clut[j] = AV_RB32(st->codecpar->extradata + j * 4);
10576 
10577  err = ff_dvdclut_yuv_to_rgb(dvdsub_clut, FF_DVDCLUT_CLUT_SIZE);
10578  if (err < 0)
10579  return err;
10580 
10581  av_freep(&st->codecpar->extradata);
10582  st->codecpar->extradata_size = 0;
10583 
10585  st->codecpar);
10586  if (err < 0)
10587  return err;
10588  }
10589  }
10590  if (mov->handbrake_version &&
10591  mov->handbrake_version <= 1000000*0 + 1000*10 + 2 && // 0.10.2
10592  st->codecpar->codec_id == AV_CODEC_ID_MP3) {
10593  av_log(s, AV_LOG_VERBOSE, "Forcing full parsing for mp3 stream\n");
10595  }
10596  }
10597 
10598  if (mov->trex_data || mov->use_mfra_for > 0) {
10599  for (i = 0; i < s->nb_streams; i++) {
10600  AVStream *st = s->streams[i];
10601  MOVStreamContext *sc = st->priv_data;
10602  if (sc->duration_for_fps > 0) {
10603  /* Akin to sc->data_size * 8 * sc->time_scale / sc->duration_for_fps but accounting for overflows. */
10605  if (st->codecpar->bit_rate == INT64_MIN) {
10606  av_log(s, AV_LOG_WARNING, "Overflow during bit rate calculation %"PRId64" * 8 * %d\n",
10607  sc->data_size, sc->time_scale);
10608  st->codecpar->bit_rate = 0;
10609  if (s->error_recognition & AV_EF_EXPLODE)
10610  return AVERROR_INVALIDDATA;
10611  }
10612  }
10613  }
10614  }
10615 
10616  for (i = 0; i < mov->bitrates_count && i < s->nb_streams; i++) {
10617  if (mov->bitrates[i]) {
10618  s->streams[i]->codecpar->bit_rate = mov->bitrates[i];
10619  }
10620  }
10621 
10623 
10624  for (i = 0; i < s->nb_streams; i++) {
10625  AVStream *st = s->streams[i];
10626  MOVStreamContext *sc = st->priv_data;
10627 
10628  switch (st->codecpar->codec_type) {
10629  case AVMEDIA_TYPE_AUDIO:
10630  err = ff_replaygain_export(st, s->metadata);
10631  if (err < 0)
10632  return err;
10633  break;
10634  case AVMEDIA_TYPE_VIDEO:
10635  if (sc->display_matrix) {
10638  (uint8_t*)sc->display_matrix, sizeof(int32_t) * 9, 0))
10639  return AVERROR(ENOMEM);
10640 
10641  sc->display_matrix = NULL;
10642  }
10643  if (sc->stereo3d) {
10646  (uint8_t *)sc->stereo3d, sc->stereo3d_size, 0))
10647  return AVERROR(ENOMEM);
10648 
10649  sc->stereo3d = NULL;
10650  }
10651  if (sc->spherical) {
10654  (uint8_t *)sc->spherical, sc->spherical_size, 0))
10655  return AVERROR(ENOMEM);
10656 
10657  sc->spherical = NULL;
10658  }
10659  if (sc->mastering) {
10662  (uint8_t *)sc->mastering, sc->mastering_size, 0))
10663  return AVERROR(ENOMEM);
10664 
10665  sc->mastering = NULL;
10666  }
10667  if (sc->coll) {
10670  (uint8_t *)sc->coll, sc->coll_size, 0))
10671  return AVERROR(ENOMEM);
10672 
10673  sc->coll = NULL;
10674  }
10675  if (sc->ambient) {
10678  (uint8_t *) sc->ambient, sc->ambient_size, 0))
10679  return AVERROR(ENOMEM);
10680 
10681  sc->ambient = NULL;
10682  }
10683  break;
10684  }
10685  }
10686 
10687  fix_stream_ids(s);
10688 
10690 
10691  for (i = 0; i < mov->frag_index.nb_items; i++)
10692  if (mov->frag_index.item[i].moof_offset <= mov->fragment.moof_offset)
10693  mov->frag_index.item[i].headers_read = 1;
10694 
10695  return 0;
10696 }
10697 
10699 {
10701  int64_t best_dts = INT64_MAX;
10702  int i;
10703  MOVContext *mov = s->priv_data;
10704  int no_interleave = !mov->interleaved_read || !(s->pb->seekable & AVIO_SEEKABLE_NORMAL);
10705  for (i = 0; i < s->nb_streams; i++) {
10706  AVStream *avst = s->streams[i];
10707  FFStream *const avsti = ffstream(avst);
10708  MOVStreamContext *msc = avst->priv_data;
10709  if (msc->pb && msc->current_sample < avsti->nb_index_entries) {
10710  AVIndexEntry *current_sample = &avsti->index_entries[msc->current_sample];
10711  int64_t dts = av_rescale(current_sample->timestamp, AV_TIME_BASE, msc->time_scale);
10712  uint64_t dtsdiff = best_dts > dts ? best_dts - (uint64_t)dts : ((uint64_t)dts - best_dts);
10713  av_log(s, AV_LOG_TRACE, "stream %d, sample %d, dts %"PRId64"\n", i, msc->current_sample, dts);
10714  if (!sample || (no_interleave && current_sample->pos < sample->pos) ||
10715  ((s->pb->seekable & AVIO_SEEKABLE_NORMAL) &&
10716  ((msc->pb != s->pb && dts < best_dts) || (msc->pb == s->pb && dts != AV_NOPTS_VALUE &&
10717  ((dtsdiff <= AV_TIME_BASE && current_sample->pos < sample->pos) ||
10718  (dtsdiff > AV_TIME_BASE && dts < best_dts && mov->interleaved_read)))))) {
10719  sample = current_sample;
10720  best_dts = dts;
10721  *st = avst;
10722  }
10723  }
10724  }
10725  return sample;
10726 }
10727 
10728 static int should_retry(AVIOContext *pb, int error_code) {
10729  if (error_code == AVERROR_EOF || avio_feof(pb))
10730  return 0;
10731 
10732  return 1;
10733 }
10734 
10735 static int mov_switch_root(AVFormatContext *s, int64_t target, int index)
10736 {
10737  int ret;
10738  MOVContext *mov = s->priv_data;
10739 
10740  if (index >= 0 && index < mov->frag_index.nb_items)
10741  target = mov->frag_index.item[index].moof_offset;
10742  if (target >= 0 && avio_seek(s->pb, target, SEEK_SET) != target) {
10743  av_log(mov->fc, AV_LOG_ERROR, "root atom offset 0x%"PRIx64": partial file\n", target);
10744  return AVERROR_INVALIDDATA;
10745  }
10746 
10747  mov->next_root_atom = 0;
10748  if ((index < 0 && target >= 0) || index >= mov->frag_index.nb_items)
10749  index = search_frag_moof_offset(&mov->frag_index, target);
10750  if (index >= 0 && index < mov->frag_index.nb_items &&
10751  mov->frag_index.item[index].moof_offset == target) {
10752  if (index + 1 < mov->frag_index.nb_items)
10753  mov->next_root_atom = mov->frag_index.item[index + 1].moof_offset;
10754  if (mov->frag_index.item[index].headers_read)
10755  return 0;
10756  mov->frag_index.item[index].headers_read = 1;
10757  }
10758 
10759  mov->found_mdat = 0;
10760 
10761  ret = mov_read_default(mov, s->pb, (MOVAtom){ AV_RL32("root"), INT64_MAX });
10762  if (ret < 0)
10763  return ret;
10764  if (avio_feof(s->pb))
10765  return AVERROR_EOF;
10766  av_log(s, AV_LOG_TRACE, "read fragments, offset 0x%"PRIx64"\n", avio_tell(s->pb));
10767 
10768  return 1;
10769 }
10770 
10772 {
10773  MOVStreamContext *sc = st->priv_data;
10774  uint8_t *side, *extradata;
10775  int extradata_size;
10776 
10777  /* Save the current index. */
10778  sc->last_stsd_index = sc->stsc_data[sc->stsc_index].id - 1;
10779 
10780  /* Notify the decoder that extradata changed. */
10781  extradata_size = sc->extradata_size[sc->last_stsd_index];
10782  extradata = sc->extradata[sc->last_stsd_index];
10783  if (st->discard != AVDISCARD_ALL && extradata_size > 0 && extradata) {
10786  extradata_size);
10787  if (!side)
10788  return AVERROR(ENOMEM);
10789  memcpy(side, extradata, extradata_size);
10790  }
10791 
10792  return 0;
10793 }
10794 
10795 static int get_eia608_packet(AVIOContext *pb, AVPacket *pkt, int src_size)
10796 {
10797  /* We can't make assumptions about the structure of the payload,
10798  because it may include multiple cdat and cdt2 samples. */
10799  const uint32_t cdat = AV_RB32("cdat");
10800  const uint32_t cdt2 = AV_RB32("cdt2");
10801  int ret, out_size = 0;
10802 
10803  /* a valid payload must have size, 4cc, and at least 1 byte pair: */
10804  if (src_size < 10)
10805  return AVERROR_INVALIDDATA;
10806 
10807  /* avoid an int overflow: */
10808  if ((src_size - 8) / 2 >= INT_MAX / 3)
10809  return AVERROR_INVALIDDATA;
10810 
10811  ret = av_new_packet(pkt, ((src_size - 8) / 2) * 3);
10812  if (ret < 0)
10813  return ret;
10814 
10815  /* parse and re-format the c608 payload in one pass. */
10816  while (src_size >= 10) {
10817  const uint32_t atom_size = avio_rb32(pb);
10818  const uint32_t atom_type = avio_rb32(pb);
10819  const uint32_t data_size = atom_size - 8;
10820  const uint8_t cc_field =
10821  atom_type == cdat ? 1 :
10822  atom_type == cdt2 ? 2 :
10823  0;
10824 
10825  /* account for bytes consumed for atom size and type. */
10826  src_size -= 8;
10827 
10828  /* make sure the data size stays within the buffer boundaries. */
10829  if (data_size < 2 || data_size > src_size) {
10831  break;
10832  }
10833 
10834  /* make sure the data size is consistent with N byte pairs. */
10835  if (data_size % 2 != 0) {
10837  break;
10838  }
10839 
10840  if (!cc_field) {
10841  /* neither cdat or cdt2 ... skip it */
10842  avio_skip(pb, data_size);
10843  src_size -= data_size;
10844  continue;
10845  }
10846 
10847  for (uint32_t i = 0; i < data_size; i += 2) {
10848  pkt->data[out_size] = (0x1F << 3) | (1 << 2) | (cc_field - 1);
10849  pkt->data[out_size + 1] = avio_r8(pb);
10850  pkt->data[out_size + 2] = avio_r8(pb);
10851  out_size += 3;
10852  src_size -= 2;
10853  }
10854  }
10855 
10856  if (src_size > 0)
10857  /* skip any remaining unread portion of the input payload */
10858  avio_skip(pb, src_size);
10859 
10861  return ret;
10862 }
10863 
10865  int64_t current_index, AVPacket *pkt)
10866 {
10867  MOVStreamContext *sc = st->priv_data;
10868 
10869  pkt->stream_index = sc->ffindex;
10870  pkt->dts = sample->timestamp;
10871  if (sample->flags & AVINDEX_DISCARD_FRAME) {
10873  }
10874  if (sc->stts_count && sc->tts_index < sc->tts_count)
10875  pkt->duration = sc->tts_data[sc->tts_index].duration;
10876  if (sc->ctts_count && sc->tts_index < sc->tts_count) {
10878  } else {
10879  if (pkt->duration == 0) {
10880  int64_t next_dts = (sc->current_sample < ffstream(st)->nb_index_entries) ?
10882  if (next_dts >= pkt->dts)
10883  pkt->duration = next_dts - pkt->dts;
10884  }
10885  pkt->pts = pkt->dts;
10886  }
10887 
10888  if (sc->tts_data && sc->tts_index < sc->tts_count) {
10889  /* update tts context */
10890  sc->tts_sample++;
10891  if (sc->tts_index < sc->tts_count &&
10892  sc->tts_data[sc->tts_index].count == sc->tts_sample) {
10893  sc->tts_index++;
10894  sc->tts_sample = 0;
10895  }
10896  }
10897 
10898  if (sc->sdtp_data && sc->current_sample <= sc->sdtp_count) {
10899  uint8_t sample_flags = sc->sdtp_data[sc->current_sample - 1];
10900  uint8_t sample_is_depended_on = (sample_flags >> 2) & 0x3;
10901  pkt->flags |= sample_is_depended_on == MOV_SAMPLE_DEPENDENCY_NO ? AV_PKT_FLAG_DISPOSABLE : 0;
10902  }
10903  pkt->flags |= sample->flags & AVINDEX_KEYFRAME ? AV_PKT_FLAG_KEY : 0;
10904  pkt->pos = sample->pos;
10905 
10906  /* Multiple stsd handling. */
10907  if (sc->stsc_data) {
10908  if (sc->stsc_data[sc->stsc_index].id > 0 &&
10909  sc->stsc_data[sc->stsc_index].id - 1 < sc->stsd_count &&
10910  sc->stsc_data[sc->stsc_index].id - 1 != sc->last_stsd_index) {
10911  int ret = mov_change_extradata(st, pkt);
10912  if (ret < 0)
10913  return ret;
10914  }
10915 
10916  /* Update the stsc index for the next sample */
10917  sc->stsc_sample++;
10918  if (mov_stsc_index_valid(sc->stsc_index, sc->stsc_count) &&
10919  mov_get_stsc_samples(sc, sc->stsc_index) == sc->stsc_sample) {
10920  sc->stsc_index++;
10921  sc->stsc_sample = 0;
10922  }
10923  }
10924 
10925  return 0;
10926 }
10927 
10929 {
10930  MOVContext *mov = s->priv_data;
10931  MOVStreamContext *sc;
10933  AVStream *st = NULL;
10934  FFStream *avsti = NULL;
10935  int64_t current_index;
10936  int ret;
10937  int i;
10938  mov->fc = s;
10939  retry:
10940  if (s->pb->pos == 0) {
10941 
10942  // Discard current fragment index
10943  if (mov->frag_index.allocated_size > 0) {
10944  for(int i = 0; i < mov->frag_index.nb_items; i++) {
10946  }
10947  av_freep(&mov->frag_index.item);
10948  mov->frag_index.nb_items = 0;
10949  mov->frag_index.allocated_size = 0;
10950  mov->frag_index.current = -1;
10951  mov->frag_index.complete = 0;
10952  }
10953 
10954  for (i = 0; i < s->nb_streams; i++) {
10955  AVStream *avst = s->streams[i];
10956  MOVStreamContext *msc = avst->priv_data;
10957 
10958  // Clear current sample
10959  mov_current_sample_set(msc, 0);
10960  msc->tts_index = 0;
10961 
10962  // Discard current index entries
10963  avsti = ffstream(avst);
10964  if (avsti->index_entries_allocated_size > 0) {
10965  av_freep(&avsti->index_entries);
10966  avsti->index_entries_allocated_size = 0;
10967  avsti->nb_index_entries = 0;
10968  }
10969  }
10970 
10971  if ((ret = mov_switch_root(s, -1, -1)) < 0)
10972  return ret;
10973  }
10974  sample = mov_find_next_sample(s, &st);
10975  if (!sample || (mov->next_root_atom && sample->pos > mov->next_root_atom)) {
10976  if (!mov->next_root_atom)
10977  return AVERROR_EOF;
10978  if ((ret = mov_switch_root(s, mov->next_root_atom, -1)) < 0)
10979  return ret;
10980  goto retry;
10981  }
10982  sc = st->priv_data;
10983  /* must be done just before reading, to avoid infinite loop on sample */
10984  current_index = sc->current_index;
10986 
10987  if (mov->next_root_atom) {
10988  sample->pos = FFMIN(sample->pos, mov->next_root_atom);
10989  sample->size = FFMIN(sample->size, (mov->next_root_atom - sample->pos));
10990  }
10991 
10992  if (st->discard != AVDISCARD_ALL) {
10993  int64_t ret64 = avio_seek(sc->pb, sample->pos, SEEK_SET);
10994  if (ret64 != sample->pos) {
10995  av_log(mov->fc, AV_LOG_ERROR, "stream %d, offset 0x%"PRIx64": partial file\n",
10996  sc->ffindex, sample->pos);
10997  if (should_retry(sc->pb, ret64)) {
10999  } else if (ret64 < 0) {
11000  return (int)ret64;
11001  }
11002  return AVERROR_INVALIDDATA;
11003  }
11004 
11005  if (st->discard == AVDISCARD_NONKEY && !(sample->flags & AVINDEX_KEYFRAME)) {
11006  av_log(mov->fc, AV_LOG_DEBUG, "Nonkey frame from stream %d discarded due to AVDISCARD_NONKEY\n", sc->ffindex);
11007  goto retry;
11008  }
11009 
11010  if (st->codecpar->codec_id == AV_CODEC_ID_EIA_608 && sample->size > 8)
11011  ret = get_eia608_packet(sc->pb, pkt, sample->size);
11012 #if CONFIG_IAMFDEC
11013  else if (sc->iamf) {
11014  int64_t pts, dts, pos, duration;
11015  int flags, size = sample->size;
11016  ret = mov_finalize_packet(s, st, sample, current_index, pkt);
11017  pts = pkt->pts; dts = pkt->dts;
11018  pos = pkt->pos; flags = pkt->flags;
11019  duration = pkt->duration;
11020  while (!ret && size > 0) {
11021  ret = ff_iamf_read_packet(s, sc->iamf, sc->pb, size, sc->iamf_stream_offset, pkt);
11022  if (ret < 0) {
11023  if (should_retry(sc->pb, ret))
11025  return ret;
11026  }
11027  size -= ret;
11028  pkt->pts = pts; pkt->dts = dts;
11029  pkt->pos = pos; pkt->flags |= flags;
11030  pkt->duration = duration;
11031  ret = ff_buffer_packet(s, pkt);
11032  }
11033  if (!ret)
11034  return FFERROR_REDO;
11035  }
11036 #endif
11037  else if (st->codecpar->codec_id == AV_CODEC_ID_APV && sample->size > 4) {
11038  const uint32_t au_size = avio_rb32(sc->pb);
11039  ret = av_get_packet(sc->pb, pkt, au_size);
11040  } else
11041  ret = av_get_packet(sc->pb, pkt, sample->size);
11042  if (ret < 0) {
11043  if (should_retry(sc->pb, ret)) {
11045  }
11046  return ret;
11047  }
11048 #if CONFIG_DV_DEMUXER
11049  if (mov->dv_demux && sc->dv_audio_container) {
11052  if (ret < 0)
11053  return ret;
11055  if (ret < 0)
11056  return ret;
11057  }
11058 #endif
11059  if (sc->has_palette) {
11060  uint8_t *pal;
11061 
11063  if (!pal) {
11064  av_log(mov->fc, AV_LOG_ERROR, "Cannot append palette to packet\n");
11065  } else {
11066  memcpy(pal, sc->palette, AVPALETTE_SIZE);
11067  sc->has_palette = 0;
11068  }
11069  }
11070  if (st->codecpar->codec_id == AV_CODEC_ID_MP3 && !ffstream(st)->need_parsing && pkt->size > 4) {
11071  if (ff_mpa_check_header(AV_RB32(pkt->data)) < 0)
11073  }
11074  }
11075 
11076  ret = mov_finalize_packet(s, st, sample, current_index, pkt);
11077  if (ret < 0)
11078  return ret;
11079 
11080  if (st->discard == AVDISCARD_ALL)
11081  goto retry;
11082 
11083  if (mov->aax_mode)
11084  aax_filter(pkt->data, pkt->size, mov);
11085 
11086  ret = cenc_filter(mov, st, sc, pkt, current_index);
11087  if (ret < 0) {
11088  return ret;
11089  }
11090 
11091  return 0;
11092 }
11093 
11095 {
11096  MOVContext *mov = s->priv_data;
11097  int index;
11098 
11099  if (!mov->frag_index.complete)
11100  return 0;
11101 
11102  index = search_frag_timestamp(s, &mov->frag_index, st, timestamp);
11103  if (index < 0)
11104  index = 0;
11105  if (!mov->frag_index.item[index].headers_read)
11106  return mov_switch_root(s, -1, index);
11107  if (index + 1 < mov->frag_index.nb_items)
11108  mov->next_root_atom = mov->frag_index.item[index + 1].moof_offset;
11109 
11110  return 0;
11111 }
11112 
11113 static int is_open_key_sample(const MOVStreamContext *sc, int sample)
11114 {
11115  // TODO: a bisect search would scale much better
11116  for (int i = 0; i < sc->open_key_samples_count; i++) {
11117  const int oks = sc->open_key_samples[i];
11118  if (oks == sample)
11119  return 1;
11120  if (oks > sample) /* list is monotically increasing so we can stop early */
11121  break;
11122  }
11123  return 0;
11124 }
11125 
11126 /*
11127  * Some key sample may be key frames but not IDR frames, so a random access to
11128  * them may not be allowed.
11129  */
11130 static int can_seek_to_key_sample(AVStream *st, int sample, int64_t requested_pts)
11131 {
11132  MOVStreamContext *sc = st->priv_data;
11133  FFStream *const sti = ffstream(st);
11134  int64_t key_sample_dts, key_sample_pts;
11135 
11136  if (st->codecpar->codec_id != AV_CODEC_ID_HEVC)
11137  return 1;
11138 
11139  if (sample >= sc->sample_offsets_count)
11140  return 1;
11141 
11142  key_sample_dts = sti->index_entries[sample].timestamp;
11143  key_sample_pts = key_sample_dts + sc->sample_offsets[sample] + sc->dts_shift;
11144 
11145  /*
11146  * If the sample needs to be presented before an open key sample, they may
11147  * not be decodable properly, even though they come after in decoding
11148  * order.
11149  */
11150  if (is_open_key_sample(sc, sample) && key_sample_pts > requested_pts)
11151  return 0;
11152 
11153  return 1;
11154 }
11155 
11156 static int mov_seek_stream(AVFormatContext *s, AVStream *st, int64_t timestamp, int flags)
11157 {
11158  MOVStreamContext *sc = st->priv_data;
11159  FFStream *const sti = ffstream(st);
11160  int sample, time_sample, ret, next_ts, requested_sample;
11161  unsigned int i;
11162 
11163  // Here we consider timestamp to be PTS, hence try to offset it so that we
11164  // can search over the DTS timeline.
11165  timestamp -= (sc->min_corrected_pts + sc->dts_shift);
11166 
11167  ret = mov_seek_fragment(s, st, timestamp);
11168  if (ret < 0)
11169  return ret;
11170 
11171  for (;;) {
11172  sample = av_index_search_timestamp(st, timestamp, flags);
11173  av_log(s, AV_LOG_TRACE, "stream %d, timestamp %"PRId64", sample %d\n", st->index, timestamp, sample);
11174  if (sample < 0 && sti->nb_index_entries && timestamp < sti->index_entries[0].timestamp)
11175  sample = 0;
11176  if (sample < 0) /* not sure what to do */
11177  return AVERROR_INVALIDDATA;
11178 
11179  if (!sample || can_seek_to_key_sample(st, sample, timestamp))
11180  break;
11181 
11182  next_ts = timestamp - FFMAX(sc->min_sample_duration, 1);
11183  requested_sample = av_index_search_timestamp(st, next_ts, flags);
11184 
11185  // If we've reached a different sample trying to find a good pts to
11186  // seek to, give up searching because we'll end up seeking back to
11187  // sample 0 on every seek.
11188  if (sample != requested_sample && !can_seek_to_key_sample(st, requested_sample, next_ts))
11189  break;
11190 
11191  timestamp = next_ts;
11192  }
11193 
11195  av_log(s, AV_LOG_TRACE, "stream %d, found sample %d\n", st->index, sc->current_sample);
11196  /* adjust time to sample index */
11197  if (sc->tts_data) {
11198  time_sample = 0;
11199  for (i = 0; i < sc->tts_count; i++) {
11200  int next = time_sample + sc->tts_data[i].count;
11201  if (next > sc->current_sample) {
11202  sc->tts_index = i;
11203  sc->tts_sample = sc->current_sample - time_sample;
11204  break;
11205  }
11206  time_sample = next;
11207  }
11208  }
11209 
11210  /* adjust stsd index */
11211  if (sc->chunk_count) {
11212  time_sample = 0;
11213  for (i = 0; i < sc->stsc_count; i++) {
11214  int64_t next = time_sample + mov_get_stsc_samples(sc, i);
11215  if (next > sc->current_sample) {
11216  sc->stsc_index = i;
11217  sc->stsc_sample = sc->current_sample - time_sample;
11218  break;
11219  }
11220  av_assert0(next == (int)next);
11221  time_sample = next;
11222  }
11223  }
11224 
11225  return sample;
11226 }
11227 
11229 {
11230  MOVStreamContext *sc = st->priv_data;
11231  FFStream *const sti = ffstream(st);
11232  int64_t first_ts = sti->index_entries[0].timestamp;
11234  int64_t off;
11235 
11237  return 0;
11238 
11239  /* compute skip samples according to stream start_pad, seek ts and first ts */
11240  off = av_rescale_q(ts - first_ts, st->time_base,
11241  (AVRational){1, st->codecpar->sample_rate});
11242  return FFMAX(sc->start_pad - off, 0);
11243 }
11244 
11245 static int mov_read_seek(AVFormatContext *s, int stream_index, int64_t sample_time, int flags)
11246 {
11247  MOVContext *mc = s->priv_data;
11248  AVStream *st;
11249  FFStream *sti;
11250  int sample;
11251  int i;
11252 
11253  if (stream_index >= s->nb_streams)
11254  return AVERROR_INVALIDDATA;
11255 
11256  st = s->streams[stream_index];
11257  sti = ffstream(st);
11258  sample = mov_seek_stream(s, st, sample_time, flags);
11259  if (sample < 0)
11260  return sample;
11261 
11262  if (mc->seek_individually) {
11263  /* adjust seek timestamp to found sample timestamp */
11264  int64_t seek_timestamp = sti->index_entries[sample].timestamp;
11266 
11267  for (i = 0; i < s->nb_streams; i++) {
11268  AVStream *const st = s->streams[i];
11269  FFStream *const sti = ffstream(st);
11270  int64_t timestamp;
11271 
11272  if (stream_index == i)
11273  continue;
11274 
11275  timestamp = av_rescale_q(seek_timestamp, s->streams[stream_index]->time_base, st->time_base);
11276  sample = mov_seek_stream(s, st, timestamp, flags);
11277  if (sample >= 0)
11279  }
11280  } else {
11281  for (i = 0; i < s->nb_streams; i++) {
11282  MOVStreamContext *sc;
11283  st = s->streams[i];
11284  sc = st->priv_data;
11285  mov_current_sample_set(sc, 0);
11286  }
11287  while (1) {
11288  MOVStreamContext *sc;
11290  if (!entry)
11291  return AVERROR_INVALIDDATA;
11292  sc = st->priv_data;
11293  if (sc->ffindex == stream_index && sc->current_sample == sample)
11294  break;
11296  }
11297  }
11298  return 0;
11299 }
11300 
11301 #define OFFSET(x) offsetof(MOVContext, x)
11302 #define FLAGS AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM
11303 static const AVOption mov_options[] = {
11304  {"use_absolute_path",
11305  "allow using absolute path when opening alias, this is a possible security issue",
11306  OFFSET(use_absolute_path), AV_OPT_TYPE_BOOL, {.i64 = 0},
11307  0, 1, FLAGS},
11308  {"seek_streams_individually",
11309  "Seek each stream individually to the closest point",
11310  OFFSET(seek_individually), AV_OPT_TYPE_BOOL, { .i64 = 1 },
11311  0, 1, FLAGS},
11312  {"ignore_editlist", "Ignore the edit list atom.", OFFSET(ignore_editlist), AV_OPT_TYPE_BOOL, {.i64 = 0},
11313  0, 1, FLAGS},
11314  {"advanced_editlist",
11315  "Modify the AVIndex according to the editlists. Use this option to decode in the order specified by the edits.",
11316  OFFSET(advanced_editlist), AV_OPT_TYPE_BOOL, {.i64 = 1},
11317  0, 1, FLAGS},
11318  {"ignore_chapters", "", OFFSET(ignore_chapters), AV_OPT_TYPE_BOOL, {.i64 = 0},
11319  0, 1, FLAGS},
11320  {"use_mfra_for",
11321  "use mfra for fragment timestamps",
11322  OFFSET(use_mfra_for), AV_OPT_TYPE_INT, {.i64 = FF_MOV_FLAG_MFRA_AUTO},
11324  .unit = "use_mfra_for"},
11325  {"auto", "auto", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_AUTO}, 0, 0,
11326  FLAGS, .unit = "use_mfra_for" },
11327  {"dts", "dts", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_DTS}, 0, 0,
11328  FLAGS, .unit = "use_mfra_for" },
11329  {"pts", "pts", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_PTS}, 0, 0,
11330  FLAGS, .unit = "use_mfra_for" },
11331  {"use_tfdt", "use tfdt for fragment timestamps", OFFSET(use_tfdt), AV_OPT_TYPE_BOOL, {.i64 = 1},
11332  0, 1, FLAGS},
11333  { "export_all", "Export unrecognized metadata entries", OFFSET(export_all),
11334  AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = FLAGS },
11335  { "export_xmp", "Export full XMP metadata", OFFSET(export_xmp),
11336  AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = FLAGS },
11337  { "activation_bytes", "Secret bytes for Audible AAX files", OFFSET(activation_bytes),
11339  { "audible_key", "AES-128 Key for Audible AAXC files", OFFSET(audible_key),
11341  { "audible_iv", "AES-128 IV for Audible AAXC files", OFFSET(audible_iv),
11343  { "audible_fixed_key", // extracted from libAAX_SDK.so and AAXSDKWin.dll files!
11344  "Fixed key used for handling Audible AAX files", OFFSET(audible_fixed_key),
11345  AV_OPT_TYPE_BINARY, {.str="77214d4b196a87cd520045fd20a51d67"},
11346  .flags = AV_OPT_FLAG_DECODING_PARAM },
11347  { "decryption_key", "The media decryption key (hex)", OFFSET(decryption_key), AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM },
11348  { "enable_drefs", "Enable external track support.", OFFSET(enable_drefs), AV_OPT_TYPE_BOOL,
11349  {.i64 = 0}, 0, 1, FLAGS },
11350  { "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 },
11351  { "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 },
11352 
11353  { NULL },
11354 };
11355 
11356 static const AVClass mov_class = {
11357  .class_name = "mov,mp4,m4a,3gp,3g2,mj2",
11358  .item_name = av_default_item_name,
11359  .option = mov_options,
11360  .version = LIBAVUTIL_VERSION_INT,
11361 };
11362 
11364  .p.name = "mov,mp4,m4a,3gp,3g2,mj2",
11365  .p.long_name = NULL_IF_CONFIG_SMALL("QuickTime / MOV"),
11366  .p.priv_class = &mov_class,
11367  .p.extensions = "mov,mp4,m4a,3gp,3g2,mj2,psp,m4b,ism,ismv,isma,f4v,avif,heic,heif",
11369  .priv_data_size = sizeof(MOVContext),
11370  .flags_internal = FF_INFMT_FLAG_INIT_CLEANUP,
11371  .read_probe = mov_probe,
11376 };
avpriv_new_chapter
AVChapter * avpriv_new_chapter(AVFormatContext *s, int64_t id, AVRational time_base, int64_t start, int64_t end, const char *title)
Add a new chapter.
Definition: demux_utils.c:43
MOVStreamContext::ctts_allocated_size
unsigned int ctts_allocated_size
Definition: isom.h:191
item_name
item_name
Definition: libkvazaar.c:313
AV_CODEC_ID_PCM_S16LE
@ AV_CODEC_ID_PCM_S16LE
Definition: codec_id.h:336
flags
const SwsFlags flags[]
Definition: swscale.c:61
mov_read_chpl
static int mov_read_chpl(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:597
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:7245
mov_read_meta
static int mov_read_meta(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5458
AV_CODEC_ID_EIA_608
@ AV_CODEC_ID_EIA_608
Definition: codec_id.h:571
AV_PKT_DATA_DISPLAYMATRIX
@ AV_PKT_DATA_DISPLAYMATRIX
This side data contains a 3x3 transformation matrix describing an affine transformation that needs to...
Definition: packet.h:105
av_packet_unref
void av_packet_unref(AVPacket *pkt)
Wipe the packet.
Definition: packet.c:432
MOVContext::found_iloc
int found_iloc
'iloc' atom has been found
Definition: isom.h:320
AV_CODEC_ID_MACE6
@ AV_CODEC_ID_MACE6
Definition: codec_id.h:460
MOVFragmentStreamInfo::first_tfra_pts
int64_t first_tfra_pts
Definition: isom.h:142
ff_rfps_add_frame
int ff_rfps_add_frame(AVFormatContext *ic, AVStream *st, int64_t ts)
add frame for rfps calculation.
Definition: demux.c:2282
read_image_iovl
static int read_image_iovl(AVFormatContext *s, const HEIFGrid *grid, AVStreamGroupTileGrid *tile_grid)
Definition: mov.c:10135
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:9057
AVMEDIA_TYPE_SUBTITLE
@ AVMEDIA_TYPE_SUBTITLE
Definition: avutil.h:203
AVIAMFSubmix::elements
AVIAMFSubmixElement ** elements
Array of submix elements.
Definition: iamf.h:565
skip_bits_long
static void skip_bits_long(GetBitContext *s, int n)
Skips the specified number of bits.
Definition: get_bits.h:261
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:400
PUT_UTF8
#define PUT_UTF8(val, tmp, PUT_BYTE)
Definition: common.h:541
AV_TIMECODE_STR_SIZE
#define AV_TIMECODE_STR_SIZE
Definition: timecode.h:33
av_aes_init
int av_aes_init(AVAES *a, const uint8_t *key, int key_bits, int decrypt)
Initialize an AVAES context.
Definition: aes.c:231
AV_CODEC_ID_PCM_F32BE
@ AV_CODEC_ID_PCM_F32BE
Definition: codec_id.h:356
FFStream::skip_samples
int skip_samples
Number of samples to skip at the start of the frame decoded from the next packet.
Definition: internal.h:208
MOVStreamContext::audio_cid
int16_t audio_cid
stsd audio compression id
Definition: isom.h:221
AVMasteringDisplayMetadata::max_luminance
AVRational max_luminance
Max luminance of mastering display (cd/m^2).
Definition: mastering_display_metadata.h:57
AVSphericalProjection
AVSphericalProjection
Projection of the video surface(s) on a sphere.
Definition: spherical.h:47
AV_CODEC_ID_ADPCM_MS
@ AV_CODEC_ID_ADPCM_MS
Definition: codec_id.h:381
AVCodecParameters::extradata
uint8_t * extradata
Extra binary data needed for initializing the decoder, codec-dependent.
Definition: codec_par.h:69
mov_read_dops
static int mov_read_dops(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:8312
can_seek_to_key_sample
static int can_seek_to_key_sample(AVStream *st, int sample, int64_t requested_pts)
Definition: mov.c:11130
AV_CODEC_ID_ADPCM_IMA_QT
@ AV_CODEC_ID_ADPCM_IMA_QT
Definition: codec_id.h:375
entry
#define entry
Definition: aom_film_grain_template.c:66
AVFMT_NO_BYTE_SEEK
#define AVFMT_NO_BYTE_SEEK
Format does not allow seeking by bytes.
Definition: avformat.h:486
AV_EF_EXPLODE
#define AV_EF_EXPLODE
abort decoding on minor error detection
Definition: defs.h:51
AVStreamGroup::id
int64_t id
Group type-specific group ID.
Definition: avformat.h:1117
AV_CODEC_ID_AC3
@ AV_CODEC_ID_AC3
Definition: codec_id.h:453
HEIFItem::name
char * name
Definition: isom.h:291
AV_STEREO3D_VIEW_LEFT
@ AV_STEREO3D_VIEW_LEFT
Frame contains only the left view.
Definition: stereo3d.h:158
MOVStreamContext::sync_group
MOVSbgp * sync_group
Definition: isom.h:243
MOVStreamContext::height
int height
tkhd height
Definition: isom.h:229
MOVContext::moov_retry
int moov_retry
Definition: isom.h:348
MOV_TRUN_SAMPLE_FLAGS
#define MOV_TRUN_SAMPLE_FLAGS
Definition: isom.h:408
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:336
mix
static int mix(int c0, int c1)
Definition: 4xm.c:717
MOVStreamContext::last_stsd_index
int last_stsd_index
Definition: isom.h:258
ff_ac3_channel_layout_tab
const uint16_t ff_ac3_channel_layout_tab[8]
Map audio coding mode (acmod) to channel layout mask.
Definition: ac3_channel_layout_tab.h:31
r
const char * r
Definition: vf_curves.c:127
AVERROR
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later. That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another. Frame references ownership and permissions
opt.h
MOV_TKHD_FLAG_ENABLED
#define MOV_TKHD_FLAG_ENABLED
Definition: isom.h:421
AVCodecParameters::codec_type
enum AVMediaType codec_type
General type of the encoded data.
Definition: codec_par.h:51
AVStreamGroup::tile_grid
struct AVStreamGroupTileGrid * tile_grid
Definition: avformat.h:1133
AVFMT_SHOW_IDS
#define AVFMT_SHOW_IDS
Show format stream IDs numbers.
Definition: avformat.h:476
AVSphericalMapping::projection
enum AVSphericalProjection projection
Projection type.
Definition: spherical.h:98
AV_WL32
#define AV_WL32(p, v)
Definition: intreadwrite.h:422
AV_STREAM_GROUP_PARAMS_LCEVC
@ AV_STREAM_GROUP_PARAMS_LCEVC
Definition: avformat.h:1092
MOVStreamContext::extradata
uint8_t ** extradata
extradata array (and size) for multiple stsd
Definition: isom.h:256
mov_class
static const AVClass mov_class
Definition: mov.c:11356
AVSphericalMapping::bound_bottom
uint32_t bound_bottom
Distance from the bottom edge.
Definition: spherical.h:182
MOVStreamContext::open_key_samples
int * open_key_samples
Definition: isom.h:248
AVUUID
uint8_t AVUUID[AV_UUID_LEN]
Definition: uuid.h:60
out
FILE * out
Definition: movenc.c:55
MOVFragmentStreamInfo
Definition: isom.h:139
AVFieldOrder
AVFieldOrder
Definition: defs.h:208
mov_read_targa_y216
static int mov_read_targa_y216(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2276
mov_read_chnl
static int mov_read_chnl(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1191
mov_read_moof
static int mov_read_moof(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1813
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
AVCodecParameters
This struct describes the properties of an encoded stream.
Definition: codec_par.h:47
HEIFItem::icc_profile
uint8_t * icc_profile
Definition: isom.h:302
AVFMT_FLAG_IGNIDX
#define AVFMT_FLAG_IGNIDX
Ignore index.
Definition: avformat.h:1417
sanity_checks
static int sanity_checks(void *log_obj, MOVStreamContext *sc, int index)
Definition: mov.c:5088
av_stristr
char * av_stristr(const char *s1, const char *s2)
Locate the first case-independent occurrence in the string haystack of the string needle.
Definition: avstring.c:58
AVCodecParameters::color_space
enum AVColorSpace color_space
Definition: codec_par.h:169
avformat_new_stream
AVStream * avformat_new_stream(AVFormatContext *s, const struct AVCodec *c)
Add a new stream to a media file.
ff_replaygain_export
int ff_replaygain_export(AVStream *st, AVDictionary *metadata)
Parse replaygain tags and export them as per-stream side data.
Definition: replaygain.c:94
tmcd_is_referenced
static int tmcd_is_referenced(AVFormatContext *s, int tmcd_id)
Definition: mov.c:9866
HEIFItem::hflip
int hflip
Definition: isom.h:298
AV_PKT_DATA_NEW_EXTRADATA
@ AV_PKT_DATA_NEW_EXTRADATA
The AV_PKT_DATA_NEW_EXTRADATA is used to notify the codec or the format that the extradata buffer was...
Definition: packet.h:56
IAMFAudioElement::nb_substreams
unsigned int nb_substreams
Definition: iamf.h:99
AVStream::priv_data
void * priv_data
Definition: avformat.h:769
AVERROR_EOF
#define AVERROR_EOF
End of file.
Definition: error.h:57
AV_DISPOSITION_ATTACHED_PIC
#define AV_DISPOSITION_ATTACHED_PIC
The stream is stored in the file as an attached picture/"cover art" (e.g.
Definition: avformat.h:670
AVStream::discard
enum AVDiscard discard
Selects which packets can be discarded at will and do not need to be demuxed.
Definition: avformat.h:815
AV_FIELD_PROGRESSIVE
@ AV_FIELD_PROGRESSIVE
Definition: defs.h:210
mov_options
static const AVOption mov_options[]
Definition: mov.c:11303
mov_codec_id
static int mov_codec_id(AVStream *st, uint32_t format)
Definition: mov.c:2625
AV_PKT_DATA_MASTERING_DISPLAY_METADATA
@ AV_PKT_DATA_MASTERING_DISPLAY_METADATA
Mastering display metadata (based on SMPTE-2086:2014).
Definition: packet.h:219
MOVStreamContext::sample_offsets
int32_t * sample_offsets
Definition: isom.h:246
av_int2double
static av_always_inline double av_int2double(uint64_t i)
Reinterpret a 64-bit integer as a double.
Definition: intfloat.h:60
mov_read_iloc
static int mov_read_iloc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:8703
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:614
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:404
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:2248
test_same_origin
static int test_same_origin(const char *src, const char *ref)
Definition: mov.c:4931
metadata
Stream codec metadata
Definition: ogg-flac-chained-meta.txt:2
cbcs_scheme_decrypt
static int cbcs_scheme_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
Definition: mov.c:8135
MOVFragment::base_data_offset
uint64_t base_data_offset
Definition: isom.h:104
MOVStreamContext
Definition: isom.h:173
AVChannelLayout::map
AVChannelCustom * map
This member must be used when the channel order is AV_CHANNEL_ORDER_CUSTOM.
Definition: channel_layout.h:370
MOVStreamContext::stsc_data
MOVStsc * stsc_data
Definition: isom.h:194
ff_buffer_packet
int ff_buffer_packet(AVFormatContext *s, AVPacket *pkt)
Definition: demux.c:612
IS_MATRIX_IDENT
#define IS_MATRIX_IDENT(matrix)
Definition: mov.c:5476
AVStreamGroup::disposition
int disposition
Stream group disposition - a combination of AV_DISPOSITION_* flags.
Definition: avformat.h:1175
av_unused
#define av_unused
Definition: attributes.h:131
AV_DISPOSITION_DEFAULT
#define AV_DISPOSITION_DEFAULT
The stream should be chosen by default among other streams of the same type, unless the user has expl...
Definition: avformat.h:617
mov_update_dts_shift
static void mov_update_dts_shift(MOVStreamContext *sc, int duration, void *logctx)
Definition: mov.c:3635
MOVStreamContext::spherical
AVSphericalMapping * spherical
Definition: isom.h:265
mask
int mask
Definition: mediacodecdec_common.c:154
out_size
int out_size
Definition: movenc.c:56
AV_CODEC_ID_MPEG4
@ AV_CODEC_ID_MPEG4
Definition: codec_id.h:64
AVContentLightMetadata::MaxCLL
unsigned MaxCLL
Max content light level (cd/m^2).
Definition: mastering_display_metadata.h:111
avio_get_str16be
int avio_get_str16be(AVIOContext *pb, int maxlen, char *buf, int buflen)
MOVEncryptionIndex
Definition: isom.h:126
av_encryption_init_info_free
void av_encryption_init_info_free(AVEncryptionInitInfo *info)
Frees the given encryption init info object.
Definition: encryption_info.c:216
mov_read_avss
static int mov_read_avss(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2253
AV_RB32A
#define AV_RB32A(p)
Definition: intreadwrite.h:575
MOVContext::primary_item_id
int primary_item_id
Definition: isom.h:373
mode
Definition: swscale.c:56
MOVContext::found_moov
int found_moov
'moov' atom has been found
Definition: isom.h:319
ff_iamf_read_packet
int ff_iamf_read_packet(AVFormatContext *s, IAMFDemuxContext *c, AVIOContext *pb, int max_size, int stream_id_offset, AVPacket *pkt)
Definition: iamf_reader.c:279
mov_read_custom
static int mov_read_custom(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5320
pixdesc.h
cleanup
static av_cold void cleanup(FlashSV2Context *s)
Definition: flashsv2enc.c:130
AVFormatContext::streams
AVStream ** streams
A list of all streams in the file.
Definition: avformat.h:1332
HEIFGrid::nb_tiles
int nb_tiles
Definition: isom.h:311
ID3v1_GENRE_MAX
#define ID3v1_GENRE_MAX
Definition: id3v1.h:29
MOVSbgp
Definition: isom.h:121
MOVCtts
Definition: isom.h:68
AVPacketSideData
This structure stores auxiliary information for decoding, presenting, or otherwise processing the cod...
Definition: packet.h:403
mov_read_extradata
static int mov_read_extradata(MOVContext *c, AVIOContext *pb, MOVAtom atom, enum AVCodecID codec_id)
Definition: mov.c:2222
AVCOL_RANGE_JPEG
@ AVCOL_RANGE_JPEG
Full range content.
Definition: pixfmt.h:750
mpegaudiodecheader.h
MOVStreamContext::rap_group_count
unsigned int rap_group_count
Definition: isom.h:240
av_display_matrix_flip
void av_display_matrix_flip(int32_t matrix[9], int hflip, int vflip)
Flip the input matrix horizontally and/or vertically.
Definition: display.c:66
av_sha_init
av_cold int av_sha_init(AVSHA *ctx, int bits)
Initialize SHA-1 or SHA-2 hashing.
Definition: sha.c:274
HEIFItem::type
int type
Definition: isom.h:300
mov_read_mvhd
static int mov_read_mvhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1915
mov_read_idat
static int mov_read_idat(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:8697
AVPacket::data
uint8_t * data
Definition: packet.h:552
MOVContext::found_mdat
int found_mdat
'mdat' atom has been found
Definition: isom.h:322
MOVStreamContext::drefs_count
unsigned drefs_count
Definition: isom.h:222
AVEncryptionInfo::crypt_byte_block
uint32_t crypt_byte_block
Only used for pattern encryption.
Definition: encryption_info.h:51
AV_PKT_DATA_ENCRYPTION_INIT_INFO
@ AV_PKT_DATA_ENCRYPTION_INIT_INFO
This side data is encryption initialization data.
Definition: packet.h:246
mov_read_avid
static int mov_read_avid(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2268
AVAmbientViewingEnvironment::ambient_light_x
AVRational ambient_light_x
Normalized x chromaticity coordinate of the environmental ambient light in the nominal viewing enviro...
Definition: ambient_viewing_environment.h:47
AVCodecParameters::seek_preroll
int seek_preroll
Audio only.
Definition: codec_par.h:214
av_dynarray2_add
void * av_dynarray2_add(void **tab_ptr, int *nb_ptr, size_t elem_size, const uint8_t *elem_data)
Add an element of size elem_size to a dynamic array.
Definition: mem.c:343
AVOption
AVOption.
Definition: opt.h:429
MOVContext::trex_data
MOVTrackExt * trex_data
Definition: isom.h:331
mov_read_stps
static int mov_read_stps(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:3292
MOVContext::bitrates
int * bitrates
bitrates read before streams creation
Definition: isom.h:346
b
#define b
Definition: input.c:42
AVCOL_TRC_UNSPECIFIED
@ AVCOL_TRC_UNSPECIFIED
Definition: pixfmt.h:647
MOVContext::interleaved_read
int interleaved_read
Definition: isom.h:381
mov_read_tkhd
static int mov_read_tkhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5484
MOVElst::rate
float rate
Definition: isom.h:82
AVStream::avg_frame_rate
AVRational avg_frame_rate
Average framerate.
Definition: avformat.h:833
table
static const uint16_t table[]
Definition: prosumer.c:203
spherical.h
mov_read_colr
static int mov_read_colr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2069
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:1954
mov_read_strf
static int mov_read_strf(MOVContext *c, AVIOContext *pb, MOVAtom atom)
An strf atom is a BITMAPINFOHEADER struct.
Definition: mov.c:2538
AV_CODEC_ID_ALAC
@ AV_CODEC_ID_ALAC
Definition: codec_id.h:466
HEIFItem::st
AVStream * st
Definition: isom.h:290
FF_COMPLIANCE_STRICT
#define FF_COMPLIANCE_STRICT
Strictly conform to all the things in the spec no matter what consequences.
Definition: defs.h:59
AVIOContext::error
int error
contains the error code or 0 if no error happened
Definition: avio.h:239
AV_CODEC_ID_AMR_NB
@ AV_CODEC_ID_AMR_NB
Definition: codec_id.h:431
av_iamf_mix_presentation_free
void av_iamf_mix_presentation_free(AVIAMFMixPresentation **pmix_presentation)
Free an AVIAMFMixPresentation and all its contents.
Definition: iamf.c:534
mov_parse_auxiliary_info
static int mov_parse_auxiliary_info(MOVContext *c, MOVStreamContext *sc, AVIOContext *pb, MOVEncryptionIndex *encryption_index)
Definition: mov.c:7453
mov_seek_stream
static int mov_seek_stream(AVFormatContext *s, AVStream *st, int64_t timestamp, int flags)
Definition: mov.c:11156
mov_read_saio
static int mov_read_saio(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:7599
mov_get_stsc_samples
static int64_t mov_get_stsc_samples(MOVStreamContext *sc, unsigned int index)
Definition: mov.c:3277
AV_LOG_VERBOSE
#define AV_LOG_VERBOSE
Detailed information.
Definition: log.h:226
ff_codec_wav_tags
const AVCodecTag ff_codec_wav_tags[]
Definition: riff.c:530
get_edit_list_entry
static int get_edit_list_entry(MOVContext *mov, const MOVStreamContext *msc, unsigned int edit_list_index, int64_t *edit_list_media_time, int64_t *edit_list_duration, int64_t global_timescale)
Get ith edit list entry (media time, duration).
Definition: mov.c:3844
MOVFragmentIndexItem::moof_offset
int64_t moof_offset
Definition: isom.h:153
MOVStreamContext::spherical_size
size_t spherical_size
Definition: isom.h:266
mov_change_extradata
static int mov_change_extradata(AVStream *st, AVPacket *pkt)
Definition: mov.c:10771
MOVStreamContext::tref_id
int tref_id
Definition: isom.h:226
MP4TrackKindMapping::scheme_uri
const char * scheme_uri
Definition: isom.h:483
AVINDEX_DISCARD_FRAME
#define AVINDEX_DISCARD_FRAME
Definition: avformat.h:607
av_display_rotation_set
void av_display_rotation_set(int32_t matrix[9], double angle)
Initialize a transformation matrix describing a pure clockwise rotation by the specified angle (in de...
Definition: display.c:51
AVPacket::duration
int64_t duration
Duration of this packet in AVStream->time_base units, 0 if unknown.
Definition: packet.h:570
AVCodecParameters::codec_tag
uint32_t codec_tag
Additional information about the codec (corresponds to the AVI FOURCC).
Definition: codec_par.h:59
fixed_key
static const uint8_t fixed_key[]
Definition: aes_ctr.c:40
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:4148
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:626
AVProbeData::buf_size
int buf_size
Size of buf except extra allocated bytes.
Definition: avformat.h:454
AVChannelLayout::order
enum AVChannelOrder order
Channel order used in this layout.
Definition: channel_layout.h:324
FFMAX
#define FFMAX(a, b)
Definition: macros.h:47
MOVAtom
Definition: isom.h:94
AVStreamGroupTileGrid::vertical
int vertical
Offset in pixels from the top edge of the canvas where the tile should be placed.
Definition: avformat.h:1000
iamf_parse.h
mov_read_moov
static int mov_read_moov(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1565
av_sub_q
AVRational av_sub_q(AVRational b, AVRational c)
Subtract one rational from another.
Definition: rational.c:101
cffstream
static const av_always_inline FFStream * cffstream(const AVStream *st)
Definition: internal.h:352
mov_read_esds
static int mov_read_esds(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:846
MOVStreamContext::sample_count
unsigned int sample_count
Definition: isom.h:205
MOVFragmentIndex::allocated_size
int allocated_size
Definition: isom.h:161
MOVTrackExt::flags
unsigned flags
Definition: isom.h:118
AVChannelLayout::nb_channels
int nb_channels
Number of channels in this layout.
Definition: channel_layout.h:329
HEIFItem::height
int height
Definition: isom.h:296
AV_SPHERICAL_EQUIRECTANGULAR
@ AV_SPHERICAL_EQUIRECTANGULAR
Video represents a sphere mapped on a flat surface using equirectangular projection.
Definition: spherical.h:52
intfloat.h
id3v1.h
MOVStreamContext::ctts_data
MOVCtts * ctts_data
Definition: isom.h:192
ff_dvdclut_yuv_to_rgb
int ff_dvdclut_yuv_to_rgb(uint32_t *clut, const size_t clut_size)
Definition: dvdclut.c:50
AV_CODEC_ID_R10K
@ AV_CODEC_ID_R10K
Definition: codec_id.h:197
heif_cur_item
static HEIFItem * heif_cur_item(MOVContext *c)
Get the current item in the parsing process.
Definition: mov.c:193
av_encryption_init_info_get_side_data
AVEncryptionInitInfo * av_encryption_init_info_get_side_data(const uint8_t *side_data, size_t side_data_size)
Creates a copy of the AVEncryptionInitInfo that is contained in the given side data.
Definition: encryption_info.c:231
AV_STEREO3D_VIEW_RIGHT
@ AV_STEREO3D_VIEW_RIGHT
Frame contains only the right view.
Definition: stereo3d.h:163
MOVContext::advanced_editlist_autodisabled
int advanced_editlist_autodisabled
Definition: isom.h:340
avio_size
int64_t avio_size(AVIOContext *s)
Get the filesize.
Definition: aviobuf.c:323
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:2560
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:6972
FFIOContext
Definition: avio_internal.h:28
AV_PKT_FLAG_KEY
#define AV_PKT_FLAG_KEY
The packet contains a keyframe.
Definition: packet.h:607
init_get_bits
static int init_get_bits(GetBitContext *s, const uint8_t *buffer, int bit_size)
Initialize GetBitContext.
Definition: get_bits.h:497
MOVStreamContext::aes_ctr
struct AVAESCTR * aes_ctr
Definition: isom.h:278
cenc_filter
static int cenc_filter(MOVContext *mov, AVStream *st, MOVStreamContext *sc, AVPacket *pkt, int current_index)
Definition: mov.c:8242
mov_read_sdtp
static int mov_read_sdtp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:3601
mov_read_jp2h
static int mov_read_jp2h(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2258
AV_STEREO3D_UNSPEC
@ AV_STEREO3D_UNSPEC
Video is stereoscopic but the packing is unspecified.
Definition: stereo3d.h:143
AVIndexEntry
Definition: avformat.h:598
AV_WB64
#define AV_WB64(p, v)
Definition: intreadwrite.h:429
MOVStreamContext::dv_audio_container
int dv_audio_container
Definition: isom.h:219
AV_CODEC_ID_AMR_WB
@ AV_CODEC_ID_AMR_WB
Definition: codec_id.h:432
mov_read_tfhd
static int mov_read_tfhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5589
AV_CODEC_ID_BIN_DATA
@ AV_CODEC_ID_BIN_DATA
Definition: codec_id.h:602
av_malloc
#define av_malloc(s)
Definition: tableprint_vlc.h:31
OPUS_SEEK_PREROLL_MS
#define OPUS_SEEK_PREROLL_MS
Definition: oggparseopus.c:36
AV_CODEC_ID_H261
@ AV_CODEC_ID_H261
Definition: codec_id.h:55
IAMFMixPresentation::cmix
const AVIAMFMixPresentation * cmix
Definition: iamf.h:108
mov_read_wide
static int mov_read_wide(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6168
AVINDEX_KEYFRAME
#define AVINDEX_KEYFRAME
Definition: avformat.h:606
AV_FIELD_BT
@ AV_FIELD_BT
Bottom coded first, top displayed first.
Definition: defs.h:214
MOVStreamContext::stsd_count
int stsd_count
Definition: isom.h:259
ff_mov_lang_to_iso639
int ff_mov_lang_to_iso639(unsigned code, char to[4])
Definition: isom.c:260
ff_generate_avci_extradata
int ff_generate_avci_extradata(AVStream *st)
Generate standard extradata for AVC-Intra based on width/height and field order.
Definition: demux_utils.c:191
ff_get_extradata
int ff_get_extradata(void *logctx, AVCodecParameters *par, AVIOContext *pb, int size)
Allocate extradata with additional AV_INPUT_BUFFER_PADDING_SIZE at end which is always set to 0 and f...
Definition: demux_utils.c:326
AVStereo3D::horizontal_field_of_view
AVRational horizontal_field_of_view
Horizontal field of view, in degrees.
Definition: stereo3d.h:239
skip_bits
static void skip_bits(GetBitContext *s, int n)
Definition: get_bits.h:364
AVCodecParameters::color_primaries
enum AVColorPrimaries color_primaries
Definition: codec_par.h:167
AVEncryptionInfo::scheme
uint32_t scheme
The fourcc encryption scheme, in big-endian byte order.
Definition: encryption_info.h:45
MOVStreamContext::stsc_count
unsigned int stsc_count
Definition: isom.h:193
MOVStreamContext::has_palette
int has_palette
Definition: isom.h:234
AVPROBE_SCORE_MAX
#define AVPROBE_SCORE_MAX
maximum score
Definition: avformat.h:463
AV_STEREO3D_SIDEBYSIDE
@ AV_STEREO3D_SIDEBYSIDE
Views are next to each other.
Definition: stereo3d.h:64
MOVIndexRange::start
int64_t start
Definition: isom.h:169
AVPacketSideData::size
size_t size
Definition: packet.h:405
get_bits
static unsigned int get_bits(GetBitContext *s, int n)
Read 1-25 bits.
Definition: get_bits.h:318
ff_remove_stream
void ff_remove_stream(AVFormatContext *s, AVStream *st)
Remove a stream from its AVFormatContext and free it.
Definition: avformat.c:113
OFFSET
#define OFFSET(x)
Definition: mov.c:11301
HEIFGrid::tile_item_list
HEIFItem ** tile_item_list
Definition: isom.h:308
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:10001
AV_FIELD_TT
@ AV_FIELD_TT
Top coded_first, top displayed first.
Definition: defs.h:211
AV_STEREO3D_VIEW_PACKED
@ AV_STEREO3D_VIEW_PACKED
Frame contains two packed views.
Definition: stereo3d.h:153
MOVStreamContext::nb_frames_for_fps
int nb_frames_for_fps
Definition: isom.h:252
avpriv_dv_produce_packet
int avpriv_dv_produce_packet(DVDemuxContext *c, AVPacket *pkt, uint8_t *buf, int buf_size, int64_t pos)
Definition: dv.c:736
avpriv_set_pts_info
void avpriv_set_pts_info(AVStream *st, int pts_wrap_bits, unsigned int pts_num, unsigned int pts_den)
Set the time base and wrapping info for a given stream.
Definition: avformat.c:777
FF_DVDCLUT_CLUT_LEN
#define FF_DVDCLUT_CLUT_LEN
Definition: dvdclut.h:28
AVEncryptionInfo::skip_byte_block
uint32_t skip_byte_block
Only used for pattern encryption.
Definition: encryption_info.h:57
finish
static void finish(void)
Definition: movenc.c:374
aax_filter
static int aax_filter(uint8_t *input, int size, MOVContext *c)
Definition: mov.c:1503
AV_OPT_TYPE_BINARY
@ AV_OPT_TYPE_BINARY
Underlying C type is a uint8_t* that is either NULL or points to an array allocated with the av_mallo...
Definition: opt.h:286
av_color_space_name
const char * av_color_space_name(enum AVColorSpace space)
Definition: pixdesc.c:3717
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:198
MOVStreamContext::mastering
AVMasteringDisplayMetadata * mastering
Definition: isom.h:267
AV_CODEC_ID_SPEEX
@ AV_CODEC_ID_SPEEX
Definition: codec_id.h:485
AV_FOURCC_MAX_STRING_SIZE
#define AV_FOURCC_MAX_STRING_SIZE
Definition: avutil.h:345
AV_PKT_DATA_PALETTE
@ AV_PKT_DATA_PALETTE
An AV_PKT_DATA_PALETTE side data packet contains exactly AVPALETTE_SIZE bytes worth of palette.
Definition: packet.h:47
ffstream
static av_always_inline FFStream * ffstream(AVStream *st)
Definition: internal.h:347
MOVFragmentIndexItem::current
int current
Definition: isom.h:155
AVFMT_SEEK_TO_PTS
#define AVFMT_SEEK_TO_PTS
Seeking is based on PTS.
Definition: avformat.h:499
AV_CODEC_ID_PCM_S16BE
@ AV_CODEC_ID_PCM_S16BE
Definition: codec_id.h:337
mov_read_mdhd
static int mov_read_mdhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1869
mov_read_ctts
static int mov_read_ctts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:3646
MOVTrackExt
Definition: isom.h:113
MOV_FRAG_SAMPLE_FLAG_IS_NON_SYNC
#define MOV_FRAG_SAMPLE_FLAG_IS_NON_SYNC
Definition: isom.h:412
fail
#define fail()
Definition: checkasm.h:196
mov_read_aclr
static int mov_read_aclr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2333
AVSEEK_FLAG_ANY
#define AVSEEK_FLAG_ANY
seek to any frame, even non-keyframes
Definition: avformat.h:2376
av_int2float
static av_always_inline float av_int2float(uint32_t i)
Reinterpret a 32-bit integer as a float.
Definition: intfloat.h:40
MOVFragment::found_tfhd
int found_tfhd
Definition: isom.h:102
AVStreamGroupTileGrid
AVStreamGroupTileGrid holds information on how to combine several independent images on a single canv...
Definition: avformat.h:951
MOVContext::decryption_key
uint8_t * decryption_key
Definition: isom.h:366
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:292
av_shrink_packet
void av_shrink_packet(AVPacket *pkt, int size)
Reduce packet size, correctly zeroing padding.
Definition: packet.c:114
timecode.h
get_current_frag_stream_info
static MOVFragmentStreamInfo * get_current_frag_stream_info(MOVFragmentIndex *frag_index)
Definition: mov.c:1622
GetBitContext
Definition: get_bits.h:108
MOVStreamContext::mastering_size
size_t mastering_size
Definition: isom.h:268
AVStreamGroupTileGrid::coded_width
int coded_width
Width of the canvas.
Definition: avformat.h:966
av_iamf_audio_element_free
void av_iamf_audio_element_free(AVIAMFAudioElement **paudio_element)
Free an AVIAMFAudioElement and all its contents.
Definition: iamf.c:336
FFStream::index_entries_allocated_size
unsigned int index_entries_allocated_size
Definition: internal.h:187
read_close
static av_cold int read_close(AVFormatContext *ctx)
Definition: libcdio.c:143
mov_read_amve
static int mov_read_amve(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6527
mov_read_enda
static int mov_read_enda(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1983
mov_read_chap
static int mov_read_chap(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5636
MOVParseTableEntry
Definition: mov.c:81
avio_tell
static av_always_inline int64_t avio_tell(AVIOContext *s)
ftell() equivalent for AVIOContext.
Definition: avio.h:494
MOV_TRUN_SAMPLE_DURATION
#define MOV_TRUN_SAMPLE_DURATION
Definition: isom.h:406
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:10015
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:314
AV_DISPOSITION_TIMED_THUMBNAILS
#define AV_DISPOSITION_TIMED_THUMBNAILS
The stream is sparse, and contains thumbnail images, often corresponding to chapter markers.
Definition: avformat.h:675
AVStreamGroupTileGrid::coded_height
int coded_height
Width of the canvas.
Definition: avformat.h:972
pts
static int64_t pts
Definition: transcode_aac.c:644
MOVStreamContext::v_spacing
int v_spacing
pasp vSpacing
Definition: isom.h:231
AVEncryptionInfo::iv
uint8_t * iv
The initialization vector.
Definition: encryption_info.h:71
AV_CODEC_ID_MP3
@ AV_CODEC_ID_MP3
preferred ID for decoding MPEG audio layer 1, 2 or 3
Definition: codec_id.h:451
AVStream::duration
int64_t duration
Decoding: duration of the stream, in stream time base.
Definition: avformat.h:803
AVAmbientViewingEnvironment::ambient_illuminance
AVRational ambient_illuminance
Environmental illuminance of the ambient viewing environment in lux.
Definition: ambient_viewing_environment.h:40
ss
#define ss(width, name, subs,...)
Definition: cbs_vp9.c:202
MOVStreamContext::width
int width
tkhd width
Definition: isom.h:228
MOVContext::meta_keys
char ** meta_keys
Definition: isom.h:325
av_reduce
int av_reduce(int *dst_num, int *dst_den, int64_t num, int64_t den, int64_t max)
Reduce a fraction.
Definition: rational.c:35
MOVStreamContext::extradata_size
int * extradata_size
Definition: isom.h:257
AVIAMFAudioElement::audio_element_type
enum AVIAMFAudioElementType audio_element_type
Audio element type as defined in section 3.6 of IAMF.
Definition: iamf.h:388
loop
static int loop
Definition: ffplay.c:335
ff_data_to_hex
char * ff_data_to_hex(char *buf, const uint8_t *src, int size, int lowercase)
Write hexadecimal string corresponding to given binary data.
Definition: utils.c:451
update_frag_index
static int update_frag_index(MOVContext *c, int64_t offset)
Definition: mov.c:1737
AVRational::num
int num
Numerator.
Definition: rational.h:59
MOVStreamContext::keyframes
int * keyframes
Definition: isom.h:209
MOVEncryptionIndex::auxiliary_info_sample_count
size_t auxiliary_info_sample_count
Definition: isom.h:133
AV_FIELD_TB
@ AV_FIELD_TB
Top coded first, bottom displayed first.
Definition: defs.h:213
AVStream::attached_pic
AVPacket attached_pic
For streams with AV_DISPOSITION_ATTACHED_PIC disposition, this packet will contain the attached pictu...
Definition: avformat.h:842
MOVStsc::id
int id
Definition: isom.h:76
mov_read_saiz
static int mov_read_saiz(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:7515
MOV_FRAG_SAMPLE_FLAG_DEPENDS_YES
#define MOV_FRAG_SAMPLE_FLAG_DEPENDS_YES
Definition: isom.h:419
mov_merge_tts_data
static int mov_merge_tts_data(MOVContext *mov, AVStream *st, int flags)
Definition: mov.c:4559
MOVContext::idat_offset
int64_t idat_offset
Definition: isom.h:380
MOV_TRUN_DATA_OFFSET
#define MOV_TRUN_DATA_OFFSET
Definition: isom.h:404
av_encryption_info_clone
AVEncryptionInfo * av_encryption_info_clone(const AVEncryptionInfo *info)
Allocates an AVEncryptionInfo structure with a copy of the given data.
Definition: encryption_info.c:65
av_ambient_viewing_environment_alloc
AVAmbientViewingEnvironment * av_ambient_viewing_environment_alloc(size_t *size)
Allocate an AVAmbientViewingEnvironment structure.
Definition: ambient_viewing_environment.c:31
AV_DICT_DONT_STRDUP_VAL
#define AV_DICT_DONT_STRDUP_VAL
Take ownership of a value that's been allocated with av_malloc() or another memory allocation functio...
Definition: dict.h:79
IAMFAudioElement::element
AVIAMFAudioElement * element
element backs celement iff the AVIAMFAudioElement is owned by this structure.
Definition: iamf.h:95
MOVStreamContext::elst_data
MOVElst * elst_data
Definition: isom.h:199
mov_read_ares
static int mov_read_ares(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2290
mov_read_adrm
static int mov_read_adrm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1379
av_get_bits_per_sample
int av_get_bits_per_sample(enum AVCodecID codec_id)
Return codec bits per sample.
Definition: utils.c:547
AVCodecParameters::color_trc
enum AVColorTransferCharacteristic color_trc
Definition: codec_par.h:168
IAMFContext::audio_elements
IAMFAudioElement ** audio_elements
Definition: iamf.h:131
MOVFragmentIndex::complete
int complete
Definition: isom.h:162
AV_CODEC_ID_PCM_S8
@ AV_CODEC_ID_PCM_S8
Definition: codec_id.h:340
avassert.h
avio_rb32
unsigned int avio_rb32(AVIOContext *s)
Definition: aviobuf.c:761
AV_LOG_TRACE
#define AV_LOG_TRACE
Extremely verbose debugging, useful for libav* development.
Definition: log.h:236
MOVStreamContext::stsc_sample
int stsc_sample
Definition: isom.h:196
pkt
AVPacket * pkt
Definition: movenc.c:60
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:210
AV_CODEC_ID_MACE3
@ AV_CODEC_ID_MACE3
Definition: codec_id.h:459
MOVTrackExt::track_id
unsigned track_id
Definition: isom.h:114
mov_free_encryption_index
static void mov_free_encryption_index(MOVEncryptionIndex **index)
Definition: mov.c:9738
AV_CH_LOW_FREQUENCY
#define AV_CH_LOW_FREQUENCY
Definition: channel_layout.h:178
duration
int64_t duration
Definition: movenc.c:65
MOVEncryptionIndex::auxiliary_offsets
uint64_t * auxiliary_offsets
Absolute seek position.
Definition: isom.h:135
read_packet
static int read_packet(void *opaque, uint8_t *buf, int buf_size)
Definition: avio_read_callback.c:42
AV_FIELD_UNKNOWN
@ AV_FIELD_UNKNOWN
Definition: defs.h:209
MOVStreamContext::dts_shift
int dts_shift
dts shift when ctts is negative
Definition: isom.h:232
av_timecode_init
int av_timecode_init(AVTimecode *tc, AVRational rate, int flags, int frame_start, void *log_ctx)
Init a timecode struct with the passed parameters.
Definition: timecode.c:201
AVCodecParameters::frame_size
int frame_size
Audio only.
Definition: codec_par.h:195
avio_get_str16le
int avio_get_str16le(AVIOContext *pb, int maxlen, char *buf, int buflen)
Read a UTF-16 string from pb and convert it to UTF-8.
mov_metadata_track_or_disc_number
static int mov_metadata_track_or_disc_number(MOVContext *c, AVIOContext *pb, unsigned len, const char *key)
Definition: mov.c:90
av_dict_get
AVDictionaryEntry * av_dict_get(const AVDictionary *m, const char *key, const AVDictionaryEntry *prev, int flags)
Get a dictionary entry with matching key.
Definition: dict.c:60
AES_CTR_KEY_SIZE
#define AES_CTR_KEY_SIZE
Definition: aes_ctr.h:35
MOVStreamContext::stsd_version
int stsd_version
Definition: isom.h:260
AV_STREAM_GROUP_PARAMS_IAMF_MIX_PRESENTATION
@ AV_STREAM_GROUP_PARAMS_IAMF_MIX_PRESENTATION
Definition: avformat.h:1090
ff_add_attached_pic
int ff_add_attached_pic(AVFormatContext *s, AVStream *st, AVIOContext *pb, AVBufferRef **buf, int size)
Add an attached pic to an AVStream.
Definition: demux_utils.c:107
add_tts_entry
static int add_tts_entry(MOVTimeToSample **tts_data, unsigned int *tts_count, unsigned int *allocated_size, int count, int offset, unsigned int duration)
Definition: mov.c:4039
av_fast_realloc
void * av_fast_realloc(void *ptr, unsigned int *size, size_t min_size)
Reallocate the given buffer if it is not large enough, otherwise do nothing.
Definition: mem.c:497
FF_MOV_FLAG_MFRA_PTS
#define FF_MOV_FLAG_MFRA_PTS
Definition: isom.h:456
MOV_MERGE_STTS
#define MOV_MERGE_STTS
Definition: mov.c:4553
MOVStreamContext::iamf_stream_offset
int iamf_stream_offset
Definition: isom.h:286
ff_mov_read_esds
int ff_mov_read_esds(AVFormatContext *fc, AVIOContext *pb)
Definition: mov_esds.c:23
stereo3d.h
AVMasteringDisplayMetadata::white_point
AVRational white_point[2]
CIE 1931 xy chromaticity coords of white point.
Definition: mastering_display_metadata.h:47
intreadwrite.h
mov_read_coll
static int mov_read_coll(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6461
s
#define s(width, name)
Definition: cbs_vp9.c:198
MOVFragmentStreamInfo::encryption_index
MOVEncryptionIndex * encryption_index
Definition: isom.h:148
mov_read_trak
static int mov_read_trak(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5106
IAMFSubStream::audio_substream_id
unsigned int audio_substream_id
Definition: iamf.h:83
MOVContext::fc
AVFormatContext * fc
Definition: isom.h:316
MOV_TFHD_DEFAULT_BASE_IS_MOOF
#define MOV_TFHD_DEFAULT_BASE_IS_MOOF
Definition: isom.h:402
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:99
AV_CODEC_ID_BMP
@ AV_CODEC_ID_BMP
Definition: codec_id.h:130
AV_CODEC_ID_EVC
@ AV_CODEC_ID_EVC
Definition: codec_id.h:325
IAMFLayer::substream_count
unsigned int substream_count
Definition: iamf.h:78
MOV_TFHD_DEFAULT_DURATION
#define MOV_TFHD_DEFAULT_DURATION
Definition: isom.h:398
ALAC_EXTRADATA_SIZE
#define ALAC_EXTRADATA_SIZE
DRM_BLOB_SIZE
#define DRM_BLOB_SIZE
Definition: mov.c:1377
MOVStreamContext::sample_offsets_count
int sample_offsets_count
Definition: isom.h:247
MOVCtts::count
unsigned int count
Definition: isom.h:69
MOVStreamContext::drefs
MOVDref * drefs
Definition: isom.h:223
av_realloc_array
void * av_realloc_array(void *ptr, size_t nmemb, size_t size)
Definition: mem.c:217
AVInputFormat::name
const char * name
A comma separated list of short names for the format.
Definition: avformat.h:549
MOVContext::aes_decrypt
struct AVAES * aes_decrypt
Definition: isom.h:365
AVProbeData::buf
unsigned char * buf
Buffer must have AVPROBE_PADDING_SIZE of extra allocated bytes filled with zero.
Definition: avformat.h:453
AVSphericalMapping::bound_top
uint32_t bound_top
Distance from the top edge.
Definition: spherical.h:180
AVMEDIA_TYPE_AUDIO
@ AVMEDIA_TYPE_AUDIO
Definition: avutil.h:201
AV_CODEC_ID_VP9
@ AV_CODEC_ID_VP9
Definition: codec_id.h:222
MOVFragmentIndex::nb_items
int nb_items
Definition: isom.h:164
AVCodecParameters::width
int width
Video only.
Definition: codec_par.h:134
MOVTimeToSample
Definition: isom.h:57
AV_CHANNEL_ORDER_UNSPEC
@ AV_CHANNEL_ORDER_UNSPEC
Only the channel count is specified, without any further information about the channel order.
Definition: channel_layout.h:119
AV_CODEC_ID_MP2
@ AV_CODEC_ID_MP2
Definition: codec_id.h:450
HEIFGrid::tile_idx_list
unsigned * tile_idx_list
Definition: isom.h:310
MOV_TRUN_FIRST_SAMPLE_FLAGS
#define MOV_TRUN_FIRST_SAMPLE_FLAGS
Definition: isom.h:405
av_q2d
static double av_q2d(AVRational a)
Convert an AVRational to a double.
Definition: rational.h:104
AVIndexEntry::size
int size
Definition: avformat.h:609
av_channel_layout_from_mask
int av_channel_layout_from_mask(AVChannelLayout *channel_layout, uint64_t mask)
Initialize a native channel layout from a bitmask indicating which channels are present.
Definition: channel_layout.c:252
MOVStreamContext::keyframe_absent
int keyframe_absent
Definition: isom.h:207
info
MIPS optimizations info
Definition: mips.txt:2
MOVStts::duration
unsigned int duration
Definition: isom.h:65
fc
#define fc(width, name, range_min, range_max)
Definition: cbs_av1.c:493
MOVStreamContext::coll_size
size_t coll_size
Definition: isom.h:270
tile_rows
int tile_rows
Definition: h265_levels.c:217
mov_estimate_video_delay
static void mov_estimate_video_delay(MOVContext *c, AVStream *st)
Definition: mov.c:4068
AVIndexEntry::timestamp
int64_t timestamp
Timestamp in AVStream.time_base units, preferably the time from which on correctly decoded frames are...
Definition: avformat.h:600
av_assert0
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:41
MOVStreamContext::min_corrected_pts
int64_t min_corrected_pts
minimum Composition time shown by the edits excluding empty edits.
Definition: isom.h:212
ffio_read_leb
unsigned int ffio_read_leb(AVIOContext *s)
Read a unsigned integer coded as a variable number of up to eight little-endian bytes,...
Definition: aviobuf.c:927
tile_cols
int tile_cols
Definition: av1_levels.c:73
MOVStreamContext::sdtp_count
unsigned int sdtp_count
Definition: isom.h:188
dvdclut.h
mov_read_lhvc
static int mov_read_lhvc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:8416
AV_LOG_DEBUG
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:231
AVPacketSideData::data
uint8_t * data
Definition: packet.h:404
ctx
AVFormatContext * ctx
Definition: movenc.c:49
hevc.h
get_bits.h
limits.h
mov_read_sidx
static int mov_read_sidx(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6030
AV_PKT_DATA_STEREO3D
@ AV_PKT_DATA_STEREO3D
This side data should be associated with a video stream and contains Stereoscopic 3D information in f...
Definition: packet.h:111
nb_streams
static int nb_streams
Definition: ffprobe.c:334
av_rescale_q
int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq)
Rescale a 64-bit integer by 2 rational numbers.
Definition: mathematics.c:142
ff_iamfdec_read_descriptors
int ff_iamfdec_read_descriptors(IAMFContext *c, AVIOContext *pb, int max_size, void *log_ctx)
Definition: iamf_parse.c:1165
FFStream::display_aspect_ratio
AVRational display_aspect_ratio
display aspect ratio (0 if unknown)
Definition: internal.h:296
IAMFContext::nb_mix_presentations
int nb_mix_presentations
Definition: iamf.h:134
mov_find_next_sample
static AVIndexEntry * mov_find_next_sample(AVFormatContext *s, AVStream **st)
Definition: mov.c:10698
AV_CODEC_ID_TARGA_Y216
@ AV_CODEC_ID_TARGA_Y216
Definition: codec_id.h:258
AVIndexEntry::min_distance
int min_distance
Minimum distance between this and the previous keyframe, used to avoid unneeded searching.
Definition: avformat.h:610
mov_read_dvcc_dvvc
static int mov_read_dvcc_dvvc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:8396
MOVParseTableEntry::parse
int(* parse)(MOVContext *ctx, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:83
codec_id
enum AVCodecID codec_id
Definition: vaapi_decode.c:410
AV_CODEC_ID_SVQ3
@ AV_CODEC_ID_SVQ3
Definition: codec_id.h:75
key
const char * key
Definition: hwcontext_opencl.c:189
AVCodecParameters::nb_coded_side_data
int nb_coded_side_data
Amount of entries in coded_side_data.
Definition: codec_par.h:86
MOVStreamContext::sdtp_data
uint8_t * sdtp_data
Definition: isom.h:189
color_range
color_range
Definition: vf_selectivecolor.c:43
AVMEDIA_TYPE_DATA
@ AVMEDIA_TYPE_DATA
Opaque data information usually continuous.
Definition: avutil.h:202
mov_read_udta_string
static int mov_read_udta_string(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:344
mov_read_stss
static int mov_read_stss(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:3333
mov_read_ddts
static int mov_read_ddts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1119
mov_read_uuid
static int mov_read_uuid(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:7118
AVCOL_PRI_UNSPECIFIED
@ AVCOL_PRI_UNSPECIFIED
Definition: pixfmt.h:622
MOVTrackExt::duration
unsigned duration
Definition: isom.h:116
AV_CODEC_ID_H264
@ AV_CODEC_ID_H264
Definition: codec_id.h:79
av_content_light_metadata_alloc
AVContentLightMetadata * av_content_light_metadata_alloc(size_t *size)
Allocate an AVContentLightMetadata structure and set its fields to default values.
Definition: mastering_display_metadata.c:72
av_sha_final
void av_sha_final(AVSHA *ctx, uint8_t *digest)
Finish hashing and output digest value.
Definition: sha.c:347
MOVStreamContext::current_sample
int current_sample
Definition: isom.h:213
MOVFragmentStreamInfo::sidx_pts
int64_t sidx_pts
Definition: isom.h:141
MAX_REORDER_DELAY
#define MAX_REORDER_DELAY
Definition: mov.c:4067
MOVFragmentIndex::current
int current
Definition: isom.h:163
MOVEncryptionIndex::encrypted_samples
AVEncryptionInfo ** encrypted_samples
Definition: isom.h:130
mov_read_close
static int mov_read_close(AVFormatContext *s)
Definition: mov.c:9812
MOVAtom::size
int64_t size
Definition: isom.h:96
MOVStreamContext::refcount
int refcount
Definition: isom.h:175
AVStereo3D::flags
int flags
Additional information about the frame packing.
Definition: stereo3d.h:212
ff_mov_get_lpcm_codec_id
static enum AVCodecID ff_mov_get_lpcm_codec_id(int bps, int flags)
Compute codec id for 'lpcm' tag.
Definition: isom.h:462
AV_CODEC_ID_PNG
@ AV_CODEC_ID_PNG
Definition: codec_id.h:113
AV_CODEC_ID_AVUI
@ AV_CODEC_ID_AVUI
Definition: codec_id.h:257
if
if(ret)
Definition: filter_design.txt:179
mov_read_cmov
static int mov_read_cmov(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6188
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:7343
FFStream::need_parsing
enum AVStreamParseType need_parsing
Definition: internal.h:314
MOVStreamContext::keyframe_count
unsigned int keyframe_count
Definition: isom.h:208
mov_read_SAND
static int mov_read_SAND(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:8644
IAMFAudioElement::audio_element_id
unsigned int audio_element_id
Definition: iamf.h:96
AVDISCARD_ALL
@ AVDISCARD_ALL
discard all
Definition: defs.h:229
AVFormatContext
Format I/O context.
Definition: avformat.h:1264
av_realloc_f
#define av_realloc_f(p, o, n)
Definition: tableprint_vlc.h:33
mov_read_stts
static int mov_read_stts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:3481
MOVStreamContext::index_ranges
MOVIndexRange * index_ranges
Definition: isom.h:215
DDTS_SIZE
#define DDTS_SIZE
internal.h
MOVTrackExt::stsd_id
unsigned stsd_id
Definition: isom.h:115
AVStreamGroupLCEVC::height
int height
Height of the final image for presentation.
Definition: avformat.h:1084
find_prev_closest_index
static int find_prev_closest_index(AVStream *st, AVIndexEntry *e_old, int nb_old, MOVTimeToSample *tts_data, int64_t tts_count, int64_t timestamp_pts, int flag, int64_t *index, int64_t *tts_index, int64_t *tts_sample)
Find the closest previous frame to the timestamp_pts, in e_old index entries.
Definition: mov.c:3890
set_frag_stream
static void set_frag_stream(MOVFragmentIndex *frag_index, int id)
Definition: mov.c:1602
mov_read_free
static int mov_read_free(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:7223
mov_realloc_extradata
static int mov_realloc_extradata(AVCodecParameters *par, MOVAtom atom)
Definition: mov.c:2185
AVStream::codecpar
AVCodecParameters * codecpar
Codec parameters associated with this stream.
Definition: avformat.h:767
LIBAVUTIL_VERSION_INT
#define LIBAVUTIL_VERSION_INT
Definition: version.h:85
AVSEEK_FLAG_BACKWARD
#define AVSEEK_FLAG_BACKWARD
Definition: avformat.h:2374
aes.h
AVClass
Describe the class of an AVClass context structure.
Definition: log.h:76
MOVStreamContext::tts_sample
int tts_sample
Definition: isom.h:202
avpriv_dv_get_packet
int avpriv_dv_get_packet(DVDemuxContext *c, AVPacket *pkt)
Definition: dv.c:731
MOVContext::ignore_editlist
int ignore_editlist
Definition: isom.h:338
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
AVStream::time_base
AVRational time_base
This is the fundamental unit of time (in seconds) in terms of which frame timestamps are represented.
Definition: avformat.h:783
NULL
#define NULL
Definition: coverity.c:32
sha.h
truehd_layout
static uint64_t truehd_layout(int chanmap)
Definition: mlp_parse.h:105
MOVDref
Definition: isom.h:85
AVERROR_PATCHWELCOME
#define AVERROR_PATCHWELCOME
Not yet implemented in FFmpeg, patches welcome.
Definition: error.h:64
format
New swscale design to change SwsGraph is what coordinates multiple passes These can include cascaded scaling error diffusion and so on Or we could have separate passes for the vertical and horizontal scaling In between each SwsPass lies a fully allocated image buffer Graph passes may have different levels of e g we can have a single threaded error diffusion pass following a multi threaded scaling pass SwsGraph is internally recreated whenever the image format
Definition: swscale-v2.txt:14
AV_CODEC_ID_AV1
@ AV_CODEC_ID_AV1
Definition: codec_id.h:284
MOVStreamContext::ctts_count
unsigned int ctts_count
Definition: isom.h:190
AVEncryptionInitInfo
This describes info used to initialize an encryption key system.
Definition: encryption_info.h:88
isom.h
tmp
static uint8_t tmp[20]
Definition: aes_ctr.c:47
MP4TrackKindValueMapping::disposition
int disposition
Definition: isom.h:478
mov_read_ftyp
static int mov_read_ftyp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1517
AV_WB16
#define AV_WB16(p, v)
Definition: intreadwrite.h:401
MOVContext::nb_heif_grid
int nb_heif_grid
Definition: isom.h:378
read_image_grid
static int read_image_grid(AVFormatContext *s, const HEIFGrid *grid, AVStreamGroupTileGrid *tile_grid)
Definition: mov.c:10036
MOVElst
Definition: isom.h:79
av_aes_ctr_alloc
struct AVAESCTR * av_aes_ctr_alloc(void)
Allocate an AVAESCTR context.
Definition: aes_ctr.c:40
flac_parse_block_header
static av_always_inline void flac_parse_block_header(const uint8_t *block_header, int *last, int *type, int *size)
Parse the metadata block parameters from the header.
Definition: flac.h:63
AVStreamGroupTileGrid::coded_side_data
AVPacketSideData * coded_side_data
Additional data associated with the grid.
Definition: avformat.h:1054
AVRational
Rational number (pair of numerator and denominator).
Definition: rational.h:58
AV_PRIMARY_EYE_LEFT
@ AV_PRIMARY_EYE_LEFT
Left eye.
Definition: stereo3d.h:183
mov_read_sgpd
static int mov_read_sgpd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:3727
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:9458
AVPALETTE_SIZE
#define AVPALETTE_SIZE
Definition: pixfmt.h:32
MOVDref::nlvl_to
int16_t nlvl_to
Definition: isom.h:91
get_eia608_packet
static int get_eia608_packet(AVIOContext *pb, AVPacket *pkt, int src_size)
Definition: mov.c:10795
AV_CODEC_ID_DVD_SUBTITLE
@ AV_CODEC_ID_DVD_SUBTITLE
Definition: codec_id.h:561
AVIndexEntry::flags
int flags
Definition: avformat.h:608
MOVStreamContext::time_offset
int64_t time_offset
time offset of the edit list entries
Definition: isom.h:211
mov_read_smdm
static int mov_read_smdm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6370
av_default_item_name
const char * av_default_item_name(void *ptr)
Return the context name.
Definition: log.c:240
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:908
av_aes_crypt
void av_aes_crypt(AVAES *a, uint8_t *dst, const uint8_t *src, int count, uint8_t *iv, int decrypt)
Encrypt or decrypt a buffer using a previously initialized context.
Definition: aes.c:171
MOVStreamContext::current_index_range
MOVIndexRange * current_index_range
Definition: isom.h:216
mov_open_dref
static int mov_open_dref(MOVContext *c, AVIOContext **pb, const char *src, MOVDref *ref)
Definition: mov.c:4960
FFStream::nb_index_entries
int nb_index_entries
Definition: internal.h:186
AVProbeData
This structure contains the data a format has to probe a file.
Definition: avformat.h:451
av_aes_alloc
struct AVAES * av_aes_alloc(void)
Allocate an AVAES context.
Definition: aes.c:37
TAG_IS_AVCI
#define TAG_IS_AVCI(tag)
Definition: isom.h:432
IAMFSubStream
Definition: iamf.h:82
MOVStreamContext::timecode_track
int timecode_track
Definition: isom.h:227
IAMFAudioElement::layers
IAMFLayer * layers
Definition: iamf.h:103
mov_read_schm
static int mov_read_schm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:7815
AVStream::metadata
AVDictionary * metadata
Definition: avformat.h:824
FLAC_STREAMINFO_SIZE
#define FLAC_STREAMINFO_SIZE
Definition: flac.h:32
av_color_primaries_name
const char * av_color_primaries_name(enum AVColorPrimaries primaries)
Definition: pixdesc.c:3675
FF_MOV_FLAG_MFRA_DTS
#define FF_MOV_FLAG_MFRA_DTS
Definition: isom.h:455
MOV_SAMPLE_DEPENDENCY_NO
#define MOV_SAMPLE_DEPENDENCY_NO
Definition: isom.h:428
mov_read_iref_thmb
static int mov_read_iref_thmb(MOVContext *c, AVIOContext *pb, int version)
Definition: mov.c:8973
AV_DICT_DONT_OVERWRITE
#define AV_DICT_DONT_OVERWRITE
Don't overwrite existing entries.
Definition: dict.h:81
ff_codec_movvideo_tags
const AVCodecTag ff_codec_movvideo_tags[]
Definition: isom_tags.c:29
MOVStreamContext::tts_index
int tts_index
Definition: isom.h:201
AV_DISPOSITION_MULTILAYER
#define AV_DISPOSITION_MULTILAYER
The video stream contains multiple layers, e.g.
Definition: avformat.h:714
MOVFragmentStreamInfo::index_base
int index_base
Definition: isom.h:146
MOVStreamContext::rap_group
MOVSbgp * rap_group
Definition: isom.h:241
AV_CODEC_ID_QDM2
@ AV_CODEC_ID_QDM2
Definition: codec_id.h:469
mov_read_ilst
static int mov_read_ilst(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5265
MOVTimeToSample::duration
unsigned int duration
Definition: isom.h:59
AV_CH_FRONT_CENTER
#define AV_CH_FRONT_CENTER
Definition: channel_layout.h:177
AVCodecParameters::ch_layout
AVChannelLayout ch_layout
Audio only.
Definition: codec_par.h:180
get_frag_stream_info_from_pkt
static MOVFragmentStreamInfo * get_frag_stream_info_from_pkt(MOVFragmentIndex *frag_index, AVPacket *pkt, int id)
Definition: mov.c:8217
get_sgpd_sync_index
static uint32_t get_sgpd_sync_index(const MOVStreamContext *sc, int nal_unit_type)
Definition: mov.c:4481
mov_read_fiel
static int mov_read_fiel(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2151
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:45
MOV_MP4_TTML_TAG
#define MOV_MP4_TTML_TAG
Definition: isom.h:473
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:396
MOVFragmentStreamInfo::stsd_id
int stsd_id
Definition: isom.h:149
MOVStreamContext::open_key_samples_count
int open_key_samples_count
Definition: isom.h:249
HEIFItem
Definition: isom.h:289
ff_codec_movaudio_tags
const AVCodecTag ff_codec_movaudio_tags[]
Definition: isom_tags.c:307
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:1223
av_stereo3d_alloc_size
AVStereo3D * av_stereo3d_alloc_size(size_t *size)
Allocate an AVStereo3D structure and set its fields to default values.
Definition: stereo3d.c:40
index
int index
Definition: gxfenc.c:90
c
Undefined Behavior In the C some operations are like signed integer dereferencing freed accessing outside allocated Undefined Behavior must not occur in a C it is not safe even if the output of undefined operations is unused The unsafety may seem nit picking but Optimizing compilers have in fact optimized code on the assumption that no undefined Behavior occurs Optimizing code based on wrong assumptions can and has in some cases lead to effects beyond the output of computations The signed integer overflow problem in speed critical code Code which is highly optimized and works with signed integers sometimes has the problem that often the output of the computation does not c
Definition: undefined.txt:32
AVPROBE_SCORE_EXTENSION
#define AVPROBE_SCORE_EXTENSION
score for file extension
Definition: avformat.h:461
MOVSbgp::count
unsigned int count
Definition: isom.h:122
AVCodecParameters::sample_rate
int sample_rate
Audio only.
Definition: codec_par.h:184
mov_parse_stsd_subtitle
static void mov_parse_stsd_subtitle(MOVContext *c, AVIOContext *pb, AVStream *st, MOVStreamContext *sc, int64_t size)
Definition: mov.c:2840
cid
uint16_t cid
Definition: mxfenc.c:2286
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:3003
MOVStts
Definition: isom.h:63
AVAudioServiceType
AVAudioServiceType
Definition: defs.h:232
AV_CODEC_ID_MPEG1VIDEO
@ AV_CODEC_ID_MPEG1VIDEO
Definition: codec_id.h:53
AV_CODEC_ID_GSM
@ AV_CODEC_ID_GSM
as in Berlin toast format
Definition: codec_id.h:468
AVStream::nb_frames
int64_t nb_frames
number of frames in this stream if known or 0
Definition: avformat.h:805
AVCodecID
AVCodecID
Identify the syntax and semantics of the bitstream.
Definition: codec_id.h:49
av_packet_side_data_get
const AVPacketSideData * av_packet_side_data_get(const AVPacketSideData *sd, int nb_sd, enum AVPacketSideDataType type)
Get side information from a side data array.
Definition: packet.c:659
AVIAMFSubmixElement::audio_element_id
unsigned int audio_element_id
The id of the Audio Element this submix element references.
Definition: iamf.h:452
AV_CODEC_ID_EAC3
@ AV_CODEC_ID_EAC3
Definition: codec_id.h:490
should_retry
static int should_retry(AVIOContext *pb, int error_code)
Definition: mov.c:10728
avformat_stream_group_add_stream
int avformat_stream_group_add_stream(AVStreamGroup *stg, AVStream *st)
Add an already allocated stream to a stream group.
Definition: options.c:513
AV_PKT_DATA_SPHERICAL
@ AV_PKT_DATA_SPHERICAL
This side data should be associated with a video stream and corresponds to the AVSphericalMapping str...
Definition: packet.h:225
AVCodecParameters::extradata_size
int extradata_size
Size of the extradata content in bytes.
Definition: codec_par.h:73
AVIAMFSubmix
Submix layout as defined in section 3.7 of IAMF.
Definition: iamf.h:556
AV_WB32
#define AV_WB32(p, v)
Definition: intreadwrite.h:415
mov_read_pasp
static int mov_read_pasp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1347
MOVContext::dv_demux
DVDemuxContext * dv_demux
Definition: isom.h:327
AV_CODEC_ID_AAC
@ AV_CODEC_ID_AAC
Definition: codec_id.h:452
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:8554
mov_read_elst
static int mov_read_elst(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6241
MOVEncryptionIndex::auxiliary_info_default_size
uint8_t auxiliary_info_default_size
Definition: isom.h:134
AV_STREAM_GROUP_PARAMS_TILE_GRID
@ AV_STREAM_GROUP_PARAMS_TILE_GRID
Definition: avformat.h:1091
IAMFAudioElement
Definition: iamf.h:89
AV_UUID_LEN
#define AV_UUID_LEN
Definition: uuid.h:57
av_sat_sub64
#define av_sat_sub64
Definition: common.h:142
mov_read_header
static int mov_read_header(AVFormatContext *s)
Definition: mov.c:10463
AV_CODEC_ID_QCELP
@ AV_CODEC_ID_QCELP
Definition: codec_id.h:474
AV_SPHERICAL_HALF_EQUIRECTANGULAR
@ AV_SPHERICAL_HALF_EQUIRECTANGULAR
Video frame displays as a 180 degree equirectangular projection.
Definition: spherical.h:73
cbc1_scheme_decrypt
static int cbc1_scheme_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
Definition: mov.c:8010
avio_rl32
unsigned int avio_rl32(AVIOContext *s)
Definition: aviobuf.c:730
MOVStreamContext::tref_flags
unsigned tref_flags
Definition: isom.h:225
AVDISCARD_NONKEY
@ AVDISCARD_NONKEY
discard all frames except keyframes
Definition: defs.h:228
MOVFragment::flags
unsigned flags
Definition: isom.h:110
f
f
Definition: af_crystalizer.c:122
AVIOContext
Bytestream IO Context.
Definition: avio.h:160
AV_CODEC_ID_PCM_S24LE
@ AV_CODEC_ID_PCM_S24LE
Definition: codec_id.h:348
mov_read_wave
static int mov_read_wave(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2381
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:754
ff_mpa_check_header
static int ff_mpa_check_header(uint32_t header)
Definition: mpegaudiodecheader.h:62
MOVStreamContext::aes_ctx
struct AVAES * aes_ctx
Definition: isom.h:279
MOV_TREF_FLAG_ENHANCEMENT
#define MOV_TREF_FLAG_ENHANCEMENT
Definition: isom.h:430
cens_scheme_decrypt
static int cens_scheme_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
Definition: mov.c:8070
MOVContext::handbrake_version
int handbrake_version
Definition: isom.h:334
mov_free_stream_context
static void mov_free_stream_context(AVFormatContext *s, AVStream *st)
Definition: mov.c:9750
AVPacket::size
int size
Definition: packet.h:553
NULL_IF_CONFIG_SMALL
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
Definition: internal.h:94
ff_codec_get_id
enum AVCodecID ff_codec_get_id(const AVCodecTag *tags, unsigned int tag)
Definition: utils.c:136
avformat_alloc_context
AVFormatContext * avformat_alloc_context(void)
Allocate an AVFormatContext.
Definition: options.c:162
MOVFragmentIndexItem
Definition: isom.h:152
get_current_encryption_info
static int get_current_encryption_info(MOVContext *c, MOVEncryptionIndex **encryption_index, MOVStreamContext **sc)
Gets the current encryption info and associated current stream context.
Definition: mov.c:7292
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:71
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:240
AVChannelLayout
An AVChannelLayout holds information about the channel layout of audio data.
Definition: channel_layout.h:319
FFStream
Definition: internal.h:128
mov_read_dref
static int mov_read_dref(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:636
mov_current_sample_dec
static void mov_current_sample_dec(MOVStreamContext *sc)
Definition: mov.c:4136
AVSphericalMapping::bound_right
uint32_t bound_right
Distance from the right edge.
Definition: spherical.h:181
MOVStsc::first
int first
Definition: isom.h:74
dst
uint8_t ptrdiff_t const uint8_t ptrdiff_t int intptr_t intptr_t int int16_t * dst
Definition: dsp.h:87
av_bswap32
#define av_bswap32
Definition: bswap.h:47
MOVStreamContext::stsz_sample_size
unsigned int stsz_sample_size
always contains sample size from stsz atom
Definition: isom.h:204
FF_MOV_FLAG_MFRA_AUTO
#define FF_MOV_FLAG_MFRA_AUTO
Definition: isom.h:454
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:603
av_err2str
#define av_err2str(errnum)
Convenience macro, the return value should be used only directly in function arguments but never stan...
Definition: error.h:122
for
for(k=2;k<=8;++k)
Definition: h264pred_template.c:424
MOVStreamContext::sgpd_sync
uint8_t * sgpd_sync
Definition: isom.h:244
start_time
static int64_t start_time
Definition: ffplay.c:326
uuid.h
ff_dvdclut_palette_extradata_cat
int ff_dvdclut_palette_extradata_cat(const uint32_t *clut, const size_t clut_size, AVCodecParameters *par)
Definition: dvdclut.c:28
mov_read_trun
static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5722
MOVStreamContext::stereo3d_size
size_t stereo3d_size
Definition: isom.h:264
avio_get_str
int avio_get_str(AVIOContext *pb, int maxlen, char *buf, int buflen)
Read a string from pb into buf.
Definition: aviobuf.c:866
mov_read_iprp
static int mov_read_iprp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:9096
av_sha_update
void av_sha_update(struct AVSHA *ctx, const uint8_t *data, size_t len)
Update hash value.
Definition: sha.c:315
sample
#define sample
Definition: flacdsp_template.c:44
hypot
static av_const double hypot(double x, double y)
Definition: libm.h:368
AV_CODEC_ID_H263
@ AV_CODEC_ID_H263
Definition: codec_id.h:56
MOV_TFHD_STSD_ID
#define MOV_TFHD_STSD_ID
Definition: isom.h:397
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:1172
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:3191
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:500
av_fourcc_make_string
char * av_fourcc_make_string(char *buf, uint32_t fourcc)
Fill the provided buffer with a string containing a FourCC (four-character code) representation.
Definition: utils.c:75
AV_RB32
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_WL16 uint64_t_TMPL AV_WB64 unsigned int_TMPL AV_RB32
Definition: bytestream.h:96
avpriv_report_missing_feature
void avpriv_report_missing_feature(void *avc, const char *msg,...) av_printf_format(2
Log a generic warning message about a missing feature.
av_aes_ctr_set_full_iv
void av_aes_ctr_set_full_iv(struct AVAESCTR *a, const uint8_t *iv)
Forcefully change the "full" 16-byte iv, including the counter.
Definition: aes_ctr.c:51
AVStreamGroup::iamf_audio_element
struct AVIAMFAudioElement * iamf_audio_element
Definition: avformat.h:1131
MOVStreamContext::coll
AVContentLightMetadata * coll
Definition: isom.h:269
aes_ctr.h
ff_format_io_close
int ff_format_io_close(AVFormatContext *s, AVIOContext **pb)
Definition: avformat.c:868
mov_parse_heif_items
static int mov_parse_heif_items(AVFormatContext *s)
Definition: mov.c:10312
HEIFItem::is_idat_relative
int is_idat_relative
Definition: isom.h:301
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:3986
MOVDref::path
char * path
Definition: isom.h:87
mov_current_sample_inc
static void mov_current_sample_inc(MOVStreamContext *sc)
Definition: mov.c:4124
AVStream::sample_aspect_ratio
AVRational sample_aspect_ratio
sample aspect ratio (0 if unknown)
Definition: avformat.h:822
FFInputFormat::p
AVInputFormat p
The public AVInputFormat.
Definition: demux.h:46
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:551
mov_read_vexu_proj
static int mov_read_vexu_proj(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6736
fix_timescale
static void fix_timescale(MOVContext *c, MOVStreamContext *sc)
Definition: mov.c:5032
avio_r8
int avio_r8(AVIOContext *s)
Definition: aviobuf.c:603
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:194
a
The reader does not expect b to be semantically here and if the code is changed by maybe adding a a division or other the signedness will almost certainly be mistaken To avoid this confusion a new type was SUINT is the C unsigned type but it holds a signed int to use the same example SUINT a
Definition: undefined.txt:41
av_channel_layout_retype
int av_channel_layout_retype(AVChannelLayout *channel_layout, enum AVChannelOrder order, int flags)
Change the AVChannelOrder of a channel layout.
Definition: channel_layout.c:885
av_reallocp_array
int av_reallocp_array(void *ptr, size_t nmemb, size_t size)
Allocate, reallocate an array through a pointer to a pointer.
Definition: mem.c:225
AVIAMFAudioElement
Information on how to combine one or more audio streams, as defined in section 3.6 of IAMF.
Definition: iamf.h:356
AV_PRIMARY_EYE_NONE
@ AV_PRIMARY_EYE_NONE
Neither eye.
Definition: stereo3d.h:178
mov_read_default
static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:9336
AV_TIMECODE_FLAG_24HOURSMAX
@ AV_TIMECODE_FLAG_24HOURSMAX
timecode wraps after 24 hours
Definition: timecode.h:37
MOV_MP4_FPCM_TAG
#define MOV_MP4_FPCM_TAG
Definition: isom.h:474
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:1023
AVStreamGroupTileGrid::nb_tiles
unsigned int nb_tiles
Amount of tiles in the grid.
Definition: avformat.h:959
av_packet_side_data_add
AVPacketSideData * av_packet_side_data_add(AVPacketSideData **psd, int *pnb_sd, enum AVPacketSideDataType type, void *data, size_t size, int flags)
Wrap existing data as packet side data.
Definition: packet.c:702
mov_read_packet
static int mov_read_packet(AVFormatContext *s, AVPacket *pkt)
Definition: mov.c:10928
offset
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf offset
Definition: writing_filters.txt:86
AVStreamGroupLCEVC::lcevc_index
unsigned int lcevc_index
Index of the LCEVC data stream in AVStreamGroup.
Definition: avformat.h:1076
AVStreamGroup::lcevc
struct AVStreamGroupLCEVC * lcevc
Definition: avformat.h:1134
attributes.h
AV_CODEC_ID_LCEVC
@ AV_CODEC_ID_LCEVC
Definition: codec_id.h:604
MOVEncryptionIndex::auxiliary_offsets_count
size_t auxiliary_offsets_count
Definition: isom.h:136
HEIFItem::vflip
int vflip
Definition: isom.h:299
AVPacket::flags
int flags
A combination of AV_PKT_FLAG values.
Definition: packet.h:558
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:489
av_strstart
int av_strstart(const char *str, const char *pfx, const char **ptr)
Return non-zero if pfx is a prefix of str.
Definition: avstring.c:36
mov_find_reference_track
static AVStream * mov_find_reference_track(AVFormatContext *s, AVStream *st, int first_index)
Definition: mov.c:10374
AVSubsampleEncryptionInfo
This file is part of FFmpeg.
Definition: encryption_info.h:25
MOVFragmentIndexItem::stream_info
MOVFragmentStreamInfo * stream_info
Definition: isom.h:157
version
version
Definition: libkvazaar.c:315
AV_STREAM_GROUP_PARAMS_IAMF_AUDIO_ELEMENT
@ AV_STREAM_GROUP_PARAMS_IAMF_AUDIO_ELEMENT
Definition: avformat.h:1089
AVEncryptionInitInfo::next
struct AVEncryptionInitInfo * next
An optional pointer to the next initialization info in the list.
Definition: encryption_info.h:122
AV_STEREO3D_FLAG_INVERT
#define AV_STEREO3D_FLAG_INVERT
Inverted views, Right/Bottom represents the left view.
Definition: stereo3d.h:194
AVStreamGroup::streams
AVStream ** streams
A list of streams in the group.
Definition: avformat.h:1165
ff_rfps_calculate
void ff_rfps_calculate(AVFormatContext *ic)
Definition: demux.c:2343
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:475
mov_read_clli
static int mov_read_clli(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6498
MOVStreamContext::chunk_offsets
int64_t * chunk_offsets
Definition: isom.h:181
AVStreamGroup::iamf_mix_presentation
struct AVIAMFMixPresentation * iamf_mix_presentation
Definition: avformat.h:1132
MOVFragmentIndex::item
MOVFragmentIndexItem * item
Definition: isom.h:165
AV_LOG_INFO
#define AV_LOG_INFO
Standard information.
Definition: log.h:221
MOVStreamContext::iamf
struct IAMFDemuxContext * iamf
Definition: isom.h:285
FFERROR_REDO
#define FFERROR_REDO
Returned by demuxers to indicate that data was consumed but discarded (ignored streams or junk data).
Definition: demux.h:176
av_encryption_init_info_alloc
AVEncryptionInitInfo * av_encryption_init_info_alloc(uint32_t system_id_size, uint32_t num_key_ids, uint32_t key_id_size, uint32_t data_size)
Allocates an AVEncryptionInitInfo structure and sub-pointers to hold the given sizes.
Definition: encryption_info.c:178
av_channel_layout_custom_init
int av_channel_layout_custom_init(AVChannelLayout *channel_layout, int nb_channels)
Initialize a custom channel layout with the specified number of channels.
Definition: channel_layout.c:232
MOVContext::decryption_key_len
int decryption_key_len
Definition: isom.h:367
av_aes_ctr_free
void av_aes_ctr_free(struct AVAESCTR *a)
Release an AVAESCTR context.
Definition: aes_ctr.c:80
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:7917
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:9207
layout
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel layout
Definition: filter_design.txt:18
MOVDref::nlvl_from
int16_t nlvl_from
Definition: isom.h:91
AVStreamGroupTileGrid::nb_coded_side_data
int nb_coded_side_data
Amount of entries in coded_side_data.
Definition: avformat.h:1059
mov_metadata_creation_time
static void mov_metadata_creation_time(MOVContext *c, AVIOContext *pb, AVDictionary **metadata, int version)
Definition: mov.c:1839
mov_metadata_hmmt
static int mov_metadata_hmmt(MOVContext *c, AVIOContext *pb, unsigned len)
Definition: mov.c:323
AV_CODEC_ID_MJPEG
@ AV_CODEC_ID_MJPEG
Definition: codec_id.h:59
MOVFragmentStreamInfo::next_trun_dts
int64_t next_trun_dts
Definition: isom.h:144
MOVStreamContext::stsc_index
unsigned int stsc_index
Definition: isom.h:195
av_sha_alloc
struct AVSHA * av_sha_alloc(void)
Allocate an AVSHA context.
Definition: sha.c:46
mov_read_tenc
static int mov_read_tenc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:7846
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:3271
mov_finalize_packet
static int mov_finalize_packet(AVFormatContext *s, AVStream *st, AVIndexEntry *sample, int64_t current_index, AVPacket *pkt)
Definition: mov.c:10864
MOVIndexRange
Definition: isom.h:168
mov_read_seek
static int mov_read_seek(AVFormatContext *s, int stream_index, int64_t sample_time, int flags)
Definition: mov.c:11245
bprint.h
MOVContext::advanced_editlist
int advanced_editlist
Definition: isom.h:339
MOVStreamContext::time_scale
int time_scale
Definition: isom.h:210
mlp_parse.h
mac_to_unicode
static const uint32_t mac_to_unicode[128]
Definition: mov.c:149
AVStreamGroupTileGrid::width
int width
Width of the final image for presentation.
Definition: avformat.h:1036
MOVStreamContext::bytes_per_frame
unsigned int bytes_per_frame
Definition: isom.h:217
AVSphericalMapping::roll
int32_t roll
Rotation around the forward vector [-180, 180].
Definition: spherical.h:140
IAMFContext::nb_audio_elements
int nb_audio_elements
Definition: iamf.h:132
MOVIndexRange::end
int64_t end
Definition: isom.h:170
AV_CODEC_ID_NONE
@ AV_CODEC_ID_NONE
Definition: codec_id.h:50
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:256
AVPacket::pts
int64_t pts
Presentation timestamp in AVStream->time_base units; the time at which the decompressed packet will b...
Definition: packet.h:545
avio_internal.h
MOVCtts::offset
int offset
Definition: isom.h:70
mov_read_trex
static int mov_read_trex(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5657
search_frag_timestamp
static int search_frag_timestamp(AVFormatContext *s, MOVFragmentIndex *frag_index, AVStream *st, int64_t timestamp)
Definition: mov.c:1712
HEIFItem::width
int width
Definition: isom.h:295
FLAGS
#define FLAGS
Definition: mov.c:11302
MOVStreamContext::stereo3d
AVStereo3D * stereo3d
Definition: isom.h:263
mov_fix_index
static void mov_fix_index(MOVContext *mov, AVStream *st)
Fix ffstream(st)->index_entries, so that it contains only the entries (and the entries which are need...
Definition: mov.c:4176
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:7694
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:3126
internal.h
AV_SPHERICAL_FISHEYE
@ AV_SPHERICAL_FISHEYE
Fisheye projection (Apple).
Definition: spherical.h:84
AVCodecParameters::height
int height
Definition: codec_par.h:135
AV_TIME_BASE
#define AV_TIME_BASE
Internal time base represented as integer.
Definition: avutil.h:253
MOVStreamContext::stps_count
unsigned int stps_count
Definition: isom.h:197
AVCodecParameters::block_align
int block_align
Audio only.
Definition: codec_par.h:191
AV_CODEC_ID_TTML
@ AV_CODEC_ID_TTML
Definition: codec_id.h:585
rb_size
static int rb_size(AVIOContext *pb, int64_t *value, int size)
Definition: mov.c:8670
AVStereo3DPrimaryEye
AVStereo3DPrimaryEye
List of possible primary eyes.
Definition: stereo3d.h:174
av_malloc_array
#define av_malloc_array(a, b)
Definition: tableprint_vlc.h:32
AV_CODEC_ID_CAVS
@ AV_CODEC_ID_CAVS
Definition: codec_id.h:139
display.h
ff_mov_read_stsd_entries
int ff_mov_read_stsd_entries(MOVContext *c, AVIOContext *pb, int entries)
Definition: mov.c:3029
AV_FIELD_BB
@ AV_FIELD_BB
Bottom coded first, bottom displayed first.
Definition: defs.h:212
AV_PKT_DATA_ICC_PROFILE
@ AV_PKT_DATA_ICC_PROFILE
ICC profile data consisting of an opaque octet buffer following the format described by ISO 15076-1.
Definition: packet.h:271
AV_STEREO3D_TOPBOTTOM
@ AV_STEREO3D_TOPBOTTOM
Views are on top of each other.
Definition: stereo3d.h:76
MOVFragment::duration
unsigned duration
Definition: isom.h:108
AVIAMFMixPresentation
Information on how to render and mix one or more AVIAMFAudioElement to generate the final audio outpu...
Definition: iamf.h:613
ff_id3v1_genre_str
const char *const ff_id3v1_genre_str[ID3v1_GENRE_MAX+1]
ID3v1 genres.
Definition: id3v1.c:26
MOVStreamContext::sample_sizes
unsigned int * sample_sizes
Definition: isom.h:206
MOVContext::frag_index
MOVFragmentIndex frag_index
Definition: isom.h:352
mov_read_vpcc
static int mov_read_vpcc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6326
AV_CODEC_ID_PCM_F64BE
@ AV_CODEC_ID_PCM_F64BE
Definition: codec_id.h:358
AV_CODEC_ID_HEVC
@ AV_CODEC_ID_HEVC
Definition: codec_id.h:228
value
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf default value
Definition: writing_filters.txt:86
av_url_split
void av_url_split(char *proto, int proto_size, char *authorization, int authorization_size, char *hostname, int hostname_size, int *port_ptr, char *path, int path_size, const char *url)
Split a URL string into components.
Definition: utils.c:354
MOVStreamContext::dref_id
int dref_id
Definition: isom.h:224
FFMIN
#define FFMIN(a, b)
Definition: macros.h:49
av_d2q
AVRational av_d2q(double d, int max)
Convert a double precision floating point number to a rational.
Definition: rational.c:106
fix_frag_index_entries
static void fix_frag_index_entries(MOVFragmentIndex *frag_index, int index, int id, int entries)
Definition: mov.c:1798
mov_finalize_stsd_codec
static int mov_finalize_stsd_codec(MOVContext *c, AVIOContext *pb, AVStream *st, MOVStreamContext *sc)
Definition: mov.c:2902
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:345
mov_read_mdcv
static int mov_read_mdcv(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6417
av_mallocz
void * av_mallocz(size_t size)
Allocate a memory block with alignment suitable for all memory accesses (including vectors if availab...
Definition: mem.c:256
AV_TIMECODE_FLAG_ALLOWNEGATIVE
@ AV_TIMECODE_FLAG_ALLOWNEGATIVE
negative time values are allowed
Definition: timecode.h:38
mov_read_mdat
static int mov_read_mdat(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1369
AV_CODEC_ID_VC1
@ AV_CODEC_ID_VC1
Definition: codec_id.h:122
demux.h
AV_DISPOSITION_DEPENDENT
#define AV_DISPOSITION_DEPENDENT
The stream is intended to be mixed with another stream before presentation.
Definition: avformat.h:705
MOVStreamContext::pb
AVIOContext * pb
Definition: isom.h:174
mov_read_keys
static int mov_read_keys(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5274
AVCodecParameters::color_range
enum AVColorRange color_range
Video only.
Definition: codec_par.h:166
AV_CH_SIDE_RIGHT
#define AV_CH_SIDE_RIGHT
Definition: channel_layout.h:185
len
int len
Definition: vorbis_enc_data.h:426
AV_CODEC_ID_JPEG2000
@ AV_CODEC_ID_JPEG2000
Definition: codec_id.h:140
MOVFragment::size
unsigned size
Definition: isom.h:109
MOV_TFHD_DEFAULT_SIZE
#define MOV_TFHD_DEFAULT_SIZE
Definition: isom.h:399
MOVTimeToSample::count
unsigned int count
Definition: isom.h:58
ff_get_wav_header
int ff_get_wav_header(AVFormatContext *s, AVIOContext *pb, AVCodecParameters *par, int size, int big_endian)
Definition: riffdec.c:95
AVCOL_SPC_UNSPECIFIED
@ AVCOL_SPC_UNSPECIFIED
Definition: pixfmt.h:676
fix_stream_ids
static void fix_stream_ids(AVFormatContext *s)
Definition: mov.c:10439
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:4622
AVCodecParameters::coded_side_data
AVPacketSideData * coded_side_data
Additional data associated with the entire stream.
Definition: codec_par.h:81
mov_read_svq3
static int mov_read_svq3(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2376
AVSHA
hash context
Definition: sha.c:35
AVCOL_RANGE_MPEG
@ AVCOL_RANGE_MPEG
Narrow or limited range content.
Definition: pixfmt.h:733
av_calloc
void * av_calloc(size_t nmemb, size_t size)
Definition: mem.c:264
MOVFragmentStreamInfo::tfdt_dts
int64_t tfdt_dts
Definition: isom.h:143
AV_IAMF_AUDIO_ELEMENT_TYPE_SCENE
@ AV_IAMF_AUDIO_ELEMENT_TYPE_SCENE
Definition: iamf.h:346
AVCodecParameters::field_order
enum AVFieldOrder field_order
Video only.
Definition: codec_par.h:161
av_get_packet
int av_get_packet(AVIOContext *s, AVPacket *pkt, int size)
Allocate and read the payload of a packet and initialize its fields with default values.
Definition: utils.c:94
mov_read_iinf
static int mov_read_iinf(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:8853
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:860
AVStreamGroupTileGrid::horizontal
int horizontal
Offset in pixels from the left edge of the canvas where the tile should be placed.
Definition: avformat.h:995
get_stream_info_time
static int64_t get_stream_info_time(MOVFragmentStreamInfo *frag_stream_info)
Definition: mov.c:1662
MP4TrackKindValueMapping
Definition: isom.h:477
MOVStreamContext::cenc
struct MOVStreamContext::@434 cenc
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:4027
AV_WB8
#define AV_WB8(p, d)
Definition: intreadwrite.h:392
MOVStreamContext::chunk_count
unsigned int chunk_count
Definition: isom.h:180
av_cmp_q
static int av_cmp_q(AVRational a, AVRational b)
Compare two rationals.
Definition: rational.h:89
MOVStreamContext::data_size
int64_t data_size
Definition: isom.h:235
AV_TIMECODE_FLAG_DROPFRAME
@ AV_TIMECODE_FLAG_DROPFRAME
timecode is drop frame
Definition: timecode.h:36
language
Undefined Behavior In the C language
Definition: undefined.txt:3
MOVStreamContext::ambient
AVAmbientViewingEnvironment * ambient
Definition: isom.h:271
mov_read_tmcd
static int mov_read_tmcd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6315
mov_chan.h
AVStream::disposition
int disposition
Stream disposition - a combination of AV_DISPOSITION_* flags.
Definition: avformat.h:813
MOVStreamContext::ambient_size
size_t ambient_size
Definition: isom.h:272
tag
uint32_t tag
Definition: movenc.c:1907
AVStream::id
int id
Format-specific stream ID.
Definition: avformat.h:756
ret
ret
Definition: filter_design.txt:187
AVStream
Stream structure.
Definition: avformat.h:744
AV_CODEC_ID_APV
@ AV_CODEC_ID_APV
Definition: codec_id.h:332
AV_LOG_FATAL
#define AV_LOG_FATAL
Something went wrong and recovery is not possible.
Definition: log.h:204
HEIFItem::extent_length
int64_t extent_length
Definition: isom.h:293
MOVEncryptionIndex::nb_encrypted_samples
unsigned int nb_encrypted_samples
Definition: isom.h:129
mov_read_senc
static int mov_read_senc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:7397
avio_seek
int64_t avio_seek(AVIOContext *s, int64_t offset, int whence)
fseek() equivalent for AVIOContext.
Definition: aviobuf.c:231
FFSWAP
#define FFSWAP(type, a, b)
Definition: macros.h:52
AVClass::class_name
const char * class_name
The name of the class; usually it is the same name as the context structure type to which the AVClass...
Definition: log.h:81
AVEncryptionInfo::key_id
uint8_t * key_id
The ID of the key used to encrypt the packet.
Definition: encryption_info.h:63
av_strlcat
size_t av_strlcat(char *dst, const char *src, size_t size)
Append the string src to the string dst, but to a total length of no more than size - 1 bytes,...
Definition: avstring.c:95
MOVStreamContext::stts_data
MOVStts * stts_data
Definition: isom.h:187
AVSphericalMapping::pitch
int32_t pitch
Rotation around the right vector [-90, 90].
Definition: spherical.h:139
AVStreamGroup::metadata
AVDictionary * metadata
Metadata that applies to the whole group.
Definition: avformat.h:1145
avio_rb16
unsigned int avio_rb16(AVIOContext *s)
Definition: aviobuf.c:746
AVStereo3D::type
enum AVStereo3DType type
How views are packed within the video.
Definition: stereo3d.h:207
MOVSbgp::index
unsigned int index
Definition: isom.h:123
HEIFItem::icc_profile_size
size_t icc_profile_size
Definition: isom.h:303
MOVContext::chapter_tracks
int * chapter_tracks
Definition: isom.h:335
cdt2
static const int16_t cdt2[8]
Definition: truemotion1data.h:43
AVSTREAM_PARSE_HEADERS
@ AVSTREAM_PARSE_HEADERS
Only parse headers, do not repack.
Definition: avformat.h:590
pos
unsigned int pos
Definition: spdifenc.c:414
avformat.h
MOVFragment::implicit_offset
uint64_t implicit_offset
Definition: isom.h:106
dict.h
av_packet_side_data_new
AVPacketSideData * av_packet_side_data_new(AVPacketSideData **psd, int *pnb_sd, enum AVPacketSideDataType type, size_t size, int flags)
Allocate a new packet side data.
Definition: packet.c:709
AV_AUDIO_SERVICE_TYPE_KARAOKE
@ AV_AUDIO_SERVICE_TYPE_KARAOKE
Definition: defs.h:241
mov_read_dmlp
static int mov_read_dmlp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:8361
flag
#define flag(name)
Definition: cbs_av1.c:495
AV_INPUT_BUFFER_PADDING_SIZE
#define AV_INPUT_BUFFER_PADDING_SIZE
Definition: defs.h:40
MOVStreamContext::pseudo_stream_id
int pseudo_stream_id
-1 means demux all ids
Definition: isom.h:220
MOVContext::time_scale
int time_scale
Definition: isom.h:317
id
enum AVCodecID id
Definition: dts2pts.c:367
mov_read_tfdt
static int mov_read_tfdt(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5683
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:5401
search_frag_moof_offset
static int search_frag_moof_offset(MOVFragmentIndex *frag_index, int64_t offset)
Definition: mov.c:1638
MOVFragment
Definition: isom.h:101
AV_DICT_MATCH_CASE
#define AV_DICT_MATCH_CASE
Only get an entry with exact-case key match.
Definition: dict.h:74
AV_RL32
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_RL32
Definition: bytestream.h:92
U
#define U(x)
Definition: vpx_arith.h:37
mov_switch_root
static int mov_switch_root(AVFormatContext *s, int64_t target, int index)
Definition: mov.c:10735
MOVContext::use_mfra_for
int use_mfra_for
Definition: isom.h:349
AVEncryptionInfo
This describes encryption info for a packet.
Definition: encryption_info.h:43
MOVStreamContext::encryption_index
MOVEncryptionIndex * encryption_index
Definition: isom.h:282
MIN_DATA_ENTRY_BOX_SIZE
#define MIN_DATA_ENTRY_BOX_SIZE
Definition: mov.c:635
AVStreamGroup
Definition: avformat.h:1098
av_get_media_type_string
const char * av_get_media_type_string(enum AVMediaType media_type)
Return a string describing the media_type enum, NULL if media_type is unknown.
Definition: utils.c:28
IAMFMixPresentation
Definition: iamf.h:107
AVStream::index
int index
stream index in AVFormatContext
Definition: avformat.h:750
avpriv_dv_init_demux
DVDemuxContext * avpriv_dv_init_demux(AVFormatContext *s)
Definition: dv.c:726
mov_seek_fragment
static int mov_seek_fragment(AVFormatContext *s, AVStream *st, int64_t timestamp)
Definition: mov.c:11094
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:2665
ff_codec_bmp_tags
const AVCodecTag ff_codec_bmp_tags[]
Definition: riff.c:36
MOVStreamContext::h_spacing
int h_spacing
pasp hSpacing
Definition: isom.h:230
mov_read_dec3
static int mov_read_dec3(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1076
get_frag_time
static int64_t get_frag_time(AVFormatContext *s, AVStream *dst_st, MOVFragmentIndex *frag_index, int index)
Definition: mov.c:1672
MOVStreamContext::sample_size
unsigned int sample_size
may contain value calculated from stsd or value from stsz atom
Definition: isom.h:203
HEVC_NAL_CRA_NUT
@ HEVC_NAL_CRA_NUT
Definition: hevc.h:50
AVStreamGroup::nb_streams
unsigned int nb_streams
Number of elements in AVStreamGroup.streams.
Definition: avformat.h:1152
mlp_samplerate
static int mlp_samplerate(int in)
Definition: mlp_parse.h:87
channel_layout.h
MOVStreamContext::duration_for_fps
int64_t duration_for_fps
Definition: isom.h:253
ISOM_DVCC_DVVC_SIZE
#define ISOM_DVCC_DVVC_SIZE
Definition: dovi_isom.h:29
mov_read_sbgp
static int mov_read_sbgp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:3783
MOVFragment::moof_offset
uint64_t moof_offset
Definition: isom.h:105
AVIO_SEEKABLE_NORMAL
#define AVIO_SEEKABLE_NORMAL
Seeking works like for a local file.
Definition: avio.h:41
av_packet_new_side_data
uint8_t * av_packet_new_side_data(AVPacket *pkt, enum AVPacketSideDataType type, size_t size)
Allocate new information of a packet.
Definition: packet.c:232
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:2438
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:7055
MOVTrackExt::size
unsigned size
Definition: isom.h:117
ff_remove_stream_group
void ff_remove_stream_group(AVFormatContext *s, AVStreamGroup *stg)
Remove a stream group from its AVFormatContext and free it.
Definition: avformat.c:121
AV_OPT_TYPE_INT
@ AV_OPT_TYPE_INT
Underlying C type is int.
Definition: opt.h:259
MOVContext::dv_fctx
AVFormatContext * dv_fctx
Definition: isom.h:328
av_channel_layout_uninit
void av_channel_layout_uninit(AVChannelLayout *channel_layout)
Free any allocated data in the channel layout and reset the channel count to 0.
Definition: channel_layout.c:442
AV_CODEC_ID_DVAUDIO
@ AV_CODEC_ID_DVAUDIO
Definition: codec_id.h:456
avformat_free_context
void avformat_free_context(AVFormatContext *s)
Free an AVFormatContext and all its streams.
Definition: avformat.c:141
MOVContext::aax_mode
unsigned int aax_mode
'aax' file has been detected
Definition: isom.h:354
mov_read_sv3d
static int mov_read_sv3d(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6599
avio_read
int avio_read(AVIOContext *s, unsigned char *buf, int size)
Read size bytes from AVIOContext into buf.
Definition: aviobuf.c:612
mov_aaxc_crypto
static int mov_aaxc_crypto(MOVContext *c)
Definition: mov.c:1478
mov_get_skip_samples
static int64_t mov_get_skip_samples(AVStream *st, int sample)
Definition: mov.c:11228
MOVFragmentIndex
Definition: isom.h:160
mov_read_infe
static int mov_read_infe(MOVContext *c, AVIOContext *pb, MOVAtom atom, int idx)
Definition: mov.c:8788
AV_RB8
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_WL16 uint64_t_TMPL AV_WB64 unsigned int_TMPL AV_WB32 unsigned int_TMPL AV_WB24 unsigned int_TMPL AV_WB16 unsigned int_TMPL AV_RB8
Definition: bytestream.h:99
ref
static int ref[MAX_W *MAX_W]
Definition: jpeg2000dwt.c:117
AVStream::r_frame_rate
AVRational r_frame_rate
Real base framerate of the stream.
Definition: avformat.h:878
MOVStreamContext::tts_count
unsigned int tts_count
Definition: isom.h:182
MOVStreamContext::track_end
int64_t track_end
used for dts generation in fragmented movie files
Definition: isom.h:238
MOVStreamContext::sgpd_sync_count
uint32_t sgpd_sync_count
Definition: isom.h:245
MOVContext::fragment
MOVFragment fragment
current fragment in moof atom
Definition: isom.h:330
AVIndexEntry::pos
int64_t pos
Definition: avformat.h:599
AVIOContext::eof_reached
int eof_reached
true if was unable to read due to error or eof
Definition: avio.h:238
mov_metadata_int8_bypass_padding
static int mov_metadata_int8_bypass_padding(MOVContext *c, AVIOContext *pb, unsigned len, const char *key)
Definition: mov.c:110
AVStreamGroupLCEVC::width
int width
Width of the final stream for presentation.
Definition: avformat.h:1080
MOVDref::type
uint32_t type
Definition: isom.h:86
samples
Filter the word “frame” indicates either a video frame or a group of audio samples
Definition: filter_design.txt:8
mean
static float mean(const float *input, int size)
Definition: vf_nnedi.c:861
mov_read_covr
static int mov_read_covr(MOVContext *c, AVIOContext *pb, int type, int len)
Definition: mov.c:230
MOVParseTableEntry::type
uint32_t type
Definition: mov.c:82
AVMasteringDisplayMetadata::min_luminance
AVRational min_luminance
Min luminance of mastering display (cd/m^2).
Definition: mastering_display_metadata.h:52
MOVStreamContext::per_sample_iv_size
unsigned int per_sample_iv_size
Definition: isom.h:280
ff_codec_movsubtitle_tags
const AVCodecTag ff_codec_movsubtitle_tags[]
Definition: isom.c:75
av_mul_q
AVRational av_mul_q(AVRational b, AVRational c)
Multiply two rationals.
Definition: rational.c:80
AVPacket::stream_index
int stream_index
Definition: packet.h:554
AVChannelLayout::u
union AVChannelLayout::@470 u
Details about which channels are present in this layout.
MOVFragmentIndexItem::nb_stream_info
int nb_stream_info
Definition: isom.h:156
avio_skip
int64_t avio_skip(AVIOContext *s, int64_t offset)
Skip given number of bytes forward.
Definition: aviobuf.c:318
export_orphan_timecode
static void export_orphan_timecode(AVFormatContext *s)
Definition: mov.c:9882
mov_read_sbas
static int mov_read_sbas(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2509
MOVStreamContext::has_sidx
int has_sidx
Definition: isom.h:276
AV_CH_FRONT_RIGHT
#define AV_CH_FRONT_RIGHT
Definition: channel_layout.h:176
av_aes_ctr_crypt
void av_aes_ctr_crypt(struct AVAESCTR *a, uint8_t *dst, const uint8_t *src, int count)
Process a buffer using a previously initialized context.
Definition: aes_ctr.c:97
mov_metadata_gnre
static int mov_metadata_gnre(MOVContext *c, AVIOContext *pb, unsigned len, const char *key)
Definition: mov.c:133
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:4552
FFStream::index_entries
AVIndexEntry * index_entries
Only used if the format does not support seeking natively.
Definition: internal.h:184
av_dict_set_int
int av_dict_set_int(AVDictionary **pm, const char *key, int64_t value, int flags)
Convenience wrapper for av_dict_set() that converts the value to a string and stores it.
Definition: dict.c:177
mov_read_dpxe
static int mov_read_dpxe(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2263
AVIAMFSubmix::nb_elements
unsigned int nb_elements
Number of elements in the submix.
Definition: iamf.h:572
MOVFragmentStreamInfo::id
int id
Definition: isom.h:140
AVIO_FLAG_READ
#define AVIO_FLAG_READ
read-only
Definition: avio.h:617
AV_PKT_DATA_AUDIO_SERVICE_TYPE
@ AV_PKT_DATA_AUDIO_SERVICE_TYPE
This side data should be associated with an audio stream and corresponds to enum AVAudioServiceType.
Definition: packet.h:117
av_spherical_alloc
AVSphericalMapping * av_spherical_alloc(size_t *size)
Allocate a AVSphericalVideo structure and initialize its fields to default values.
Definition: spherical.c:26
AV_OPT_FLAG_DECODING_PARAM
#define AV_OPT_FLAG_DECODING_PARAM
A generic parameter which can be set by the user for demuxing or decoding.
Definition: opt.h:356
MOVContext::thmb_item_id
int thmb_item_id
Definition: isom.h:379
mov_read_rtmd_track
static int mov_read_rtmd_track(AVFormatContext *s, AVStream *st)
Definition: mov.c:9665
AVMEDIA_TYPE_VIDEO
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:200
read_probe
static int read_probe(const AVProbeData *p)
Definition: cdg.c:30
MOVStreamContext::pb_is_copied
int pb_is_copied
Definition: isom.h:176
AV_CODEC_ID_PCM_S32LE
@ AV_CODEC_ID_PCM_S32LE
Definition: codec_id.h:344
AVCodecParameters::bits_per_coded_sample
int bits_per_coded_sample
The number of bits per sample in the codedwords.
Definition: codec_par.h:110
mov_parse_tiles
static int mov_parse_tiles(AVFormatContext *s)
Definition: mov.c:10217
mem.h
AVStreamGroup::type
enum AVStreamGroupParamsType type
Group type.
Definition: avformat.h:1125
MOVElst::time
int64_t time
Definition: isom.h:81
HEIFGrid
Definition: isom.h:306
mov_read_iref_dimg
static int mov_read_iref_dimg(MOVContext *c, AVIOContext *pb, int version)
Definition: mov.c:8913
mov_read_pcmc
static int mov_read_pcmc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1992
build_open_gop_key_points
static int build_open_gop_key_points(AVStream *st)
Definition: mov.c:4489
mov_parse_stsd_audio
static void mov_parse_stsd_audio(MOVContext *c, AVIOContext *pb, AVStream *st, MOVStreamContext *sc)
Definition: mov.c:2723
IAMFContext::mix_presentations
IAMFMixPresentation ** mix_presentations
Definition: iamf.h:133
AV_CODEC_ID_PCM_U8
@ AV_CODEC_ID_PCM_U8
Definition: codec_id.h:341
MOVContext::trak_index
int trak_index
Index of the current 'trak'.
Definition: isom.h:324
mov_read_timecode_track
static int mov_read_timecode_track(AVFormatContext *s, AVStream *st)
Definition: mov.c:9691
HEIFGrid::item
HEIFItem * item
Definition: isom.h:307
AVStreamGroupTileGrid::offsets
struct AVStreamGroupTileGrid::@402 * offsets
An nb_tiles sized array of offsets in pixels from the topleft edge of the canvas, indicating where ea...
AVSphericalMapping::bound_left
uint32_t bound_left
Distance from the left edge.
Definition: spherical.h:179
mov_read_mac_string
static int mov_read_mac_string(MOVContext *c, AVIOContext *pb, int len, char *dst, int dstlen)
Definition: mov.c:168
MOVEncryptionIndex::auxiliary_info_sizes
uint8_t * auxiliary_info_sizes
Definition: isom.h:132
MOVFragment::stsd_id
unsigned stsd_id
Definition: isom.h:107
AVCodecParameters::video_delay
int video_delay
Video only.
Definition: codec_par.h:175
HEIFGrid::tile_id_list
int16_t * tile_id_list
Definition: isom.h:309
avpriv_request_sample
#define avpriv_request_sample(...)
Definition: tableprint_vlc.h:37
MOVStreamContext::tts_data
MOVTimeToSample * tts_data
Definition: isom.h:184
map
const VDPAUPixFmtMap * map
Definition: hwcontext_vdpau.c:71
avformat_stream_group_create
AVStreamGroup * avformat_stream_group_create(AVFormatContext *s, enum AVStreamGroupParamsType type, AVDictionary **options)
Add a new empty stream group to a media file.
Definition: options.c:433
AV_CHANNEL_LAYOUT_MONO
#define AV_CHANNEL_LAYOUT_MONO
Definition: channel_layout.h:394
AV_CODEC_ID_PCM_F64LE
@ AV_CODEC_ID_PCM_F64LE
Definition: codec_id.h:359
AVStreamGroupTileGrid::height
int height
Height of the final image for presentation.
Definition: avformat.h:1046
AVStereo3D::view
enum AVStereo3DView view
Determines which views are packed.
Definition: stereo3d.h:217
AVStreamGroup::params
union AVStreamGroup::@403 params
Group type-specific parameters.
read_tfra
static int read_tfra(MOVContext *mov, AVIOContext *f)
Definition: mov.c:9900
av_free
#define av_free(p)
Definition: tableprint_vlc.h:34
AVDictionaryEntry
Definition: dict.h:90
av_add_q
AVRational av_add_q(AVRational b, AVRational c)
Add two rationals.
Definition: rational.c:93
AVCodecParameters::codec_id
enum AVCodecID codec_id
Specific type of the encoded data (the codec used).
Definition: codec_par.h:55
AVStereo3DView
AVStereo3DView
List of possible view types.
Definition: stereo3d.h:149
AVPacket
This structure stores compressed data.
Definition: packet.h:529
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:10389
mov_read_hfov
static int mov_read_hfov(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:7026
AV_OPT_TYPE_BOOL
@ AV_OPT_TYPE_BOOL
Underlying C type is int.
Definition: opt.h:327
MOVStreamContext::stps_data
unsigned * stps_data
partial sync sample for mpeg-2 open gop
Definition: isom.h:198
AV_CODEC_ID_ADPCM_IMA_WAV
@ AV_CODEC_ID_ADPCM_IMA_WAV
Definition: codec_id.h:376
MOVContext::nb_heif_item
int nb_heif_item
Definition: isom.h:376
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:572
FFInputFormat
Definition: demux.h:42
mov_metadata_loci
static int mov_metadata_loci(MOVContext *c, AVIOContext *pb, unsigned len)
Definition: mov.c:273
mov_read_eyes
static int mov_read_eyes(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6798
AV_CODEC_ID_ILBC
@ AV_CODEC_ID_ILBC
Definition: codec_id.h:509
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:407
MOVStreamContext::tmcd_flags
uint32_t tmcd_flags
tmcd track flags
Definition: isom.h:236
int32_t
int32_t
Definition: audioconvert.c:56
HEIFItem::rotation
int rotation
Definition: isom.h:297
MOVAtom::type
uint32_t type
Definition: isom.h:95
distance
static float distance(float x, float y, int band)
Definition: nellymoserenc.c:231
AVSTREAM_PARSE_FULL
@ AVSTREAM_PARSE_FULL
full parsing and repack
Definition: avformat.h:589
parse_timecode_in_framenum_format
static int parse_timecode_in_framenum_format(AVFormatContext *s, AVStream *st, int64_t value, int flags)
Definition: mov.c:9651
MOVStreamContext::tmcd_nb_frames
uint8_t tmcd_nb_frames
tmcd number of frames per tick / second
Definition: isom.h:237
AVIAMFSubmixElement
Submix element as defined in section 3.7 of IAMF.
Definition: iamf.h:446
replaygain.h
MOVFragmentIndexItem::headers_read
int headers_read
Definition: isom.h:154
AV_CODEC_ID_VP8
@ AV_CODEC_ID_VP8
Definition: codec_id.h:192
AVERROR_BUG
#define AVERROR_BUG
Internal bug, also see AVERROR_BUG2.
Definition: error.h:52
MOVStreamContext::start_pad
int start_pad
amount of samples to skip due to enc-dec delay
Definition: isom.h:239
MP4TrackKindValueMapping::value
const char * value
Definition: isom.h:479
AVStereo3DType
AVStereo3DType
List of possible 3D Types.
Definition: stereo3d.h:48
MOVDref::filename
char filename[64]
Definition: isom.h:90
ff_mov_read_chnl
int ff_mov_read_chnl(AVFormatContext *s, AVIOContext *pb, AVStream *st)
Read 'chnl' tag from the input stream.
Definition: mov_chan.c:729
MOVStsc::count
int count
Definition: isom.h:75
AV_CODEC_ID_PCM_F32LE
@ AV_CODEC_ID_PCM_F32LE
Definition: codec_id.h:357
ff_mov_demuxer
const FFInputFormat ff_mov_demuxer
Definition: mov.c:11363
AVCodecParameters::bit_rate
int64_t bit_rate
The average bitrate of the encoded data (in bits per second).
Definition: codec_par.h:97
MOVStts::count
unsigned int count
Definition: isom.h:64
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
MOVStreamContext::display_matrix
int32_t * display_matrix
Definition: isom.h:262
MOVContext::heif_grid
HEIFGrid * heif_grid
Definition: isom.h:377
MOVStreamContext::min_sample_duration
uint32_t min_sample_duration
Definition: isom.h:250
MOVStreamContext::current_index
int64_t current_index
Definition: isom.h:214
AVERROR_INVALIDDATA
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:61
ff_mov_track_kind_table
const struct MP4TrackKindMapping ff_mov_track_kind_table[]
Definition: isom.c:451
get_curr_st
static AVStream * get_curr_st(MOVContext *c)
Get the current stream in the parsing process.
Definition: mov.c:212
MOVStreamContext::stts_allocated_size
unsigned int stts_allocated_size
Definition: isom.h:186
MOVFragmentStreamInfo::index_entry
int index_entry
Definition: isom.h:147
cenc_decrypt
static int cenc_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
Definition: mov.c:8201
MOVStreamContext::format
uint32_t format
Definition: isom.h:274
MKTAG
#define MKTAG(a, b, c, d)
Definition: macros.h:55
ffio_read_size
int ffio_read_size(AVIOContext *s, unsigned char *buf, int size)
Read size bytes from AVIOContext into buf.
Definition: aviobuf.c:662
MOVStreamContext::sync_group_count
unsigned int sync_group_count
Definition: isom.h:242
MOVContext::bitrates_count
int bitrates_count
Definition: isom.h:347
AV_CODEC_ID_VORBIS
@ AV_CODEC_ID_VORBIS
Definition: codec_id.h:455
AVDictionaryEntry::value
char * value
Definition: dict.h:92
AVStream::start_time
int64_t start_time
Decoding: pts of the first frame of the stream in presentation order, in stream time base.
Definition: avformat.h:793
MOVStreamContext::id
int id
AVStream id.
Definition: isom.h:177
MOVStreamContext::samples_per_frame
unsigned int samples_per_frame
Definition: isom.h:218
MOVStreamContext::tts_allocated_size
unsigned int tts_allocated_size
Definition: isom.h:183
MOVElst::duration
int64_t duration
Definition: isom.h:80
ac3tab.h
avstring.h
mov_read_ispe
static int mov_read_ispe(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:9035
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:8997
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:1238
mov_read_mfra
static int mov_read_mfra(MOVContext *c, AVIOContext *f)
Definition: mov.c:9955
AV_CODEC_ID_FLV1
@ AV_CODEC_ID_FLV1
Definition: codec_id.h:73
mov_metadata_int8_no_padding
static int mov_metadata_int8_no_padding(MOVContext *c, AVIOContext *pb, unsigned len, const char *key)
Definition: mov.c:124
flac.h
AVStreamGroupTileGrid::idx
unsigned int idx
Index of the stream in the group this tile references.
Definition: avformat.h:990
AVTimecode
Definition: timecode.h:41
get_frag_stream_info
static MOVFragmentStreamInfo * get_frag_stream_info(MOVFragmentIndex *frag_index, int index, int id)
Definition: mov.c:1583
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:8465
MOVContext::heif_item
HEIFItem ** heif_item
Definition: isom.h:375
MOVStreamContext::stts_count
unsigned int stts_count
Definition: isom.h:185
MOV_TRUN_SAMPLE_CTS
#define MOV_TRUN_SAMPLE_CTS
Definition: isom.h:409
AV_OPT_TYPE_CONST
@ AV_OPT_TYPE_CONST
Special option type for declaring named constants.
Definition: opt.h:299
MOV_ISMV_TTML_TAG
#define MOV_ISMV_TTML_TAG
Definition: isom.h:472
snprintf
#define snprintf
Definition: snprintf.h:34
IAMFMixPresentation::mix_presentation_id
unsigned int mix_presentation_id
Definition: iamf.h:114
AVCodecParameters::initial_padding
int initial_padding
Audio only.
Definition: codec_par.h:203
AV_CODEC_ID_PCM_S24BE
@ AV_CODEC_ID_PCM_S24BE
Definition: codec_id.h:349
mov_read_st3d
static int mov_read_st3d(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6552
mov_read_imir
static int mov_read_imir(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:9077
is_open_key_sample
static int is_open_key_sample(const MOVStreamContext *sc, int sample)
Definition: mov.c:11113
mov_read_dvc1
static int mov_read_dvc1(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2484
MOVStreamContext::elst_count
unsigned int elst_count
Definition: isom.h:200
av_color_transfer_name
const char * av_color_transfer_name(enum AVColorTransferCharacteristic transfer)
Definition: pixdesc.c:3696
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:2200
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:138
src
#define src
Definition: vp8dsp.c:248
mov_read_chapters
static void mov_read_chapters(AVFormatContext *s)
Definition: mov.c:9552
AV_CODEC_ID_DNXHD
@ AV_CODEC_ID_DNXHD
Definition: codec_id.h:151
channel
channel
Definition: ebur128.h:39
MOVStreamContext::default_encrypted_sample
AVEncryptionInfo * default_encrypted_sample
Definition: isom.h:281
MOVContext::cur_item_id
int cur_item_id
Definition: isom.h:374
av_timecode_make_string
char * av_timecode_make_string(const AVTimecode *tc, char *buf, int framenum_arg)
Load timecode string in buf.
Definition: timecode.c:104
AVFMT_EVENT_FLAG_METADATA_UPDATED
#define AVFMT_EVENT_FLAG_METADATA_UPDATED
Definition: avformat.h:1638
AV_DICT_DONT_STRDUP_KEY
#define AV_DICT_DONT_STRDUP_KEY
Take ownership of a key that's been allocated with av_malloc() or another memory allocation function.
Definition: dict.h:77
MOVContext::next_root_atom
int64_t next_root_atom
offset of the next root atom
Definition: isom.h:343
MOVContext::found_iinf
int found_iinf
'iinf' atom has been found
Definition: isom.h:321
MOVContext::meta_keys_count
unsigned meta_keys_count
Definition: isom.h:326
avcodec_parameters_copy
int avcodec_parameters_copy(AVCodecParameters *dst, const AVCodecParameters *src)
Copy the contents of src to dst.
Definition: codec_par.c:106
iamf_reader.h
AVStreamGroupTileGrid::background
uint8_t background[4]
The pixel value per channel in RGBA format used if no pixel of any tile is located at a particular pi...
Definition: avformat.h:1010
MOVStreamContext::palette
uint32_t palette[256]
Definition: isom.h:233
cenc_scheme_decrypt
static int cenc_scheme_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
Definition: mov.c:7957
MOVFragment::track_id
unsigned track_id
Definition: isom.h:103
mov_read_hdlr
static int mov_read_hdlr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:780
mov_parse_stsd_data
static int mov_parse_stsd_data(MOVContext *c, AVIOContext *pb, AVStream *st, MOVStreamContext *sc, int64_t size)
Definition: mov.c:2856
AV_CH_SIDE_LEFT
#define AV_CH_SIDE_LEFT
Definition: channel_layout.h:184
ff_iamf_read_deinit
void ff_iamf_read_deinit(IAMFDemuxContext *c)
Definition: iamf_reader.c:342
AV_RB16
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_WL16 uint64_t_TMPL AV_WB64 unsigned int_TMPL AV_WB32 unsigned int_TMPL AV_WB24 unsigned int_TMPL AV_RB16
Definition: bytestream.h:98
av_realloc
void * av_realloc(void *ptr, size_t size)
Allocate, reallocate, or free a block of memory.
Definition: mem.c:155
av_encryption_init_info_add_side_data
uint8_t * av_encryption_init_info_add_side_data(const AVEncryptionInitInfo *info, size_t *side_data_size)
Allocates and initializes side data that holds a copy of the given encryption init info.
Definition: encryption_info.c:292
av_fourcc2str
#define av_fourcc2str(fourcc)
Definition: avutil.h:347
ff_mov_read_chan
int ff_mov_read_chan(AVFormatContext *s, AVIOContext *pb, AVStream *st, int64_t size)
Read 'chan' tag from the input stream.
Definition: mov_chan.c:524
av_index_search_timestamp
int av_index_search_timestamp(AVStream *st, int64_t timestamp, int flags)
Get the index for a specific timestamp.
Definition: seek.c:245
mov_read_pitm
static int mov_read_pitm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:8689
FLAC_METADATA_TYPE_STREAMINFO
@ FLAC_METADATA_TYPE_STREAMINFO
Definition: flac.h:46
MOVContext::ignore_chapters
int ignore_chapters
Definition: isom.h:341
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:851
MP4TrackKindMapping
Definition: isom.h:482
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:230
AV_DISPOSITION_NON_DIEGETIC
#define AV_DISPOSITION_NON_DIEGETIC
The stream is intended to be mixed with a spatial audio track.
Definition: avformat.h:682
avio_feof
int avio_feof(AVIOContext *s)
Similar to feof() but also returns nonzero on read errors.
Definition: aviobuf.c:346
mc
#define mc
Definition: vf_colormatrix.c:100
MOVStreamContext::ffindex
int ffindex
AVStream index.
Definition: isom.h:178
HEIFItem::extent_offset
int64_t extent_offset
Definition: isom.h:294
mov_read_stsz
static int mov_read_stsz(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:3388