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"
36 #include "libavutil/internal.h"
37 #include "libavutil/intreadwrite.h"
38 #include "libavutil/intfloat.h"
39 #include "libavutil/mathematics.h"
40 #include "libavutil/avassert.h"
41 #include "libavutil/avstring.h"
42 #include "libavutil/dict.h"
43 #include "libavutil/display.h"
44 #include "libavutil/mem.h"
45 #include "libavutil/opt.h"
46 #include "libavutil/aes.h"
47 #include "libavutil/aes_ctr.h"
48 #include "libavutil/pixdesc.h"
49 #include "libavutil/sha.h"
50 #include "libavutil/spherical.h"
51 #include "libavutil/stereo3d.h"
52 #include "libavutil/timecode.h"
53 #include "libavutil/uuid.h"
54 #include "libavcodec/ac3tab.h"
55 #include "libavcodec/flac.h"
56 #include "libavcodec/hevc/hevc.h"
58 #include "libavcodec/mlp_parse.h"
59 #include "avformat.h"
60 #include "internal.h"
61 #include "avio_internal.h"
62 #include "demux.h"
63 #include "dvdclut.h"
64 #include "iamf_parse.h"
65 #include "iamf_reader.h"
66 #include "dovi_isom.h"
67 #include "riff.h"
68 #include "isom.h"
69 #include "libavcodec/get_bits.h"
70 #include "id3v1.h"
71 #include "mov_chan.h"
72 #include "replaygain.h"
73 
74 #if CONFIG_ZLIB
75 #include <zlib.h>
76 #endif
77 
78 #include "qtpalette.h"
79 
80 /* those functions parse an atom */
81 /* links atom IDs to parse functions */
82 typedef struct MOVParseTableEntry {
83  uint32_t type;
84  int (*parse)(MOVContext *ctx, AVIOContext *pb, MOVAtom atom);
86 
87 static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom);
88 static int mov_read_mfra(MOVContext *c, AVIOContext *f);
90 
92  unsigned len, const char *key)
93 {
94  char buf[16];
95 
96  short current, total = 0;
97  avio_rb16(pb); // unknown
98  current = avio_rb16(pb);
99  if (len >= 6)
100  total = avio_rb16(pb);
101  if (!total)
102  snprintf(buf, sizeof(buf), "%d", current);
103  else
104  snprintf(buf, sizeof(buf), "%d/%d", current, total);
105  c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
106  av_dict_set(&c->fc->metadata, key, buf, 0);
107 
108  return 0;
109 }
110 
112  unsigned len, const char *key)
113 {
114  /* bypass padding bytes */
115  avio_r8(pb);
116  avio_r8(pb);
117  avio_r8(pb);
118 
119  c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
120  av_dict_set_int(&c->fc->metadata, key, avio_r8(pb), 0);
121 
122  return 0;
123 }
124 
126  unsigned len, const char *key)
127 {
128  c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
129  av_dict_set_int(&c->fc->metadata, key, avio_r8(pb), 0);
130 
131  return 0;
132 }
133 
135  unsigned len, const char *key)
136 {
137  short genre;
138 
139  avio_r8(pb); // unknown
140 
141  genre = avio_r8(pb);
142  if (genre < 1 || genre > ID3v1_GENRE_MAX)
143  return 0;
144  c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
145  av_dict_set(&c->fc->metadata, key, ff_id3v1_genre_str[genre-1], 0);
146 
147  return 0;
148 }
149 
150 static const uint32_t mac_to_unicode[128] = {
151  0x00C4,0x00C5,0x00C7,0x00C9,0x00D1,0x00D6,0x00DC,0x00E1,
152  0x00E0,0x00E2,0x00E4,0x00E3,0x00E5,0x00E7,0x00E9,0x00E8,
153  0x00EA,0x00EB,0x00ED,0x00EC,0x00EE,0x00EF,0x00F1,0x00F3,
154  0x00F2,0x00F4,0x00F6,0x00F5,0x00FA,0x00F9,0x00FB,0x00FC,
155  0x2020,0x00B0,0x00A2,0x00A3,0x00A7,0x2022,0x00B6,0x00DF,
156  0x00AE,0x00A9,0x2122,0x00B4,0x00A8,0x2260,0x00C6,0x00D8,
157  0x221E,0x00B1,0x2264,0x2265,0x00A5,0x00B5,0x2202,0x2211,
158  0x220F,0x03C0,0x222B,0x00AA,0x00BA,0x03A9,0x00E6,0x00F8,
159  0x00BF,0x00A1,0x00AC,0x221A,0x0192,0x2248,0x2206,0x00AB,
160  0x00BB,0x2026,0x00A0,0x00C0,0x00C3,0x00D5,0x0152,0x0153,
161  0x2013,0x2014,0x201C,0x201D,0x2018,0x2019,0x00F7,0x25CA,
162  0x00FF,0x0178,0x2044,0x20AC,0x2039,0x203A,0xFB01,0xFB02,
163  0x2021,0x00B7,0x201A,0x201E,0x2030,0x00C2,0x00CA,0x00C1,
164  0x00CB,0x00C8,0x00CD,0x00CE,0x00CF,0x00CC,0x00D3,0x00D4,
165  0xF8FF,0x00D2,0x00DA,0x00DB,0x00D9,0x0131,0x02C6,0x02DC,
166  0x00AF,0x02D8,0x02D9,0x02DA,0x00B8,0x02DD,0x02DB,0x02C7,
167 };
168 
170  char *dst, int dstlen)
171 {
172  char *p = dst;
173  char *end = dst+dstlen-1;
174  int i;
175 
176  for (i = 0; i < len; i++) {
177  uint8_t t, c = avio_r8(pb);
178 
179  if (p >= end)
180  continue;
181 
182  if (c < 0x80)
183  *p++ = c;
184  else if (p < end)
185  PUT_UTF8(mac_to_unicode[c-0x80], t, if (p < end) *p++ = t;);
186  }
187  *p = 0;
188  return p - dst;
189 }
190 
191 /**
192  * Get the current item in the parsing process.
193  */
195 {
196  HEIFItem *item = NULL;
197 
198  for (int i = 0; i < c->nb_heif_item; i++) {
199  if (!c->heif_item[i] || c->heif_item[i]->item_id != c->cur_item_id)
200  continue;
201 
202  item = c->heif_item[i];
203  break;
204  }
205 
206  return item;
207 }
208 
209 /**
210  * Get the current stream in the parsing process. This can either be the
211  * latest stream added to the context, or the stream referenced by an item.
212  */
214 {
215  AVStream *st = NULL;
216  HEIFItem *item;
217 
218  if (c->fc->nb_streams < 1)
219  return NULL;
220 
221  if (c->cur_item_id == -1)
222  return c->fc->streams[c->fc->nb_streams-1];
223 
224  item = heif_cur_item(c);
225  if (item)
226  st = item->st;
227 
228  return st;
229 }
230 
231 static int mov_read_covr(MOVContext *c, AVIOContext *pb, int type, int len)
232 {
233  AVStream *st;
234  MOVStreamContext *sc;
235  enum AVCodecID id;
236  int ret;
237 
238  switch (type) {
239  case 0xd: id = AV_CODEC_ID_MJPEG; break;
240  case 0xe: id = AV_CODEC_ID_PNG; break;
241  case 0x1b: id = AV_CODEC_ID_BMP; break;
242  default:
243  av_log(c->fc, AV_LOG_WARNING, "Unknown cover type: 0x%x.\n", type);
244  avio_skip(pb, len);
245  return 0;
246  }
247 
248  sc = av_mallocz(sizeof(*sc));
249  if (!sc)
250  return AVERROR(ENOMEM);
251  ret = ff_add_attached_pic(c->fc, NULL, pb, NULL, len);
252  if (ret < 0) {
253  av_free(sc);
254  return ret;
255  }
256  st = c->fc->streams[c->fc->nb_streams - 1];
257  st->priv_data = sc;
258  sc->id = st->id;
259  sc->refcount = 1;
260 
261  if (st->attached_pic.size >= 8 && id != AV_CODEC_ID_BMP) {
262  if (AV_RB64(st->attached_pic.data) == 0x89504e470d0a1a0a) {
263  id = AV_CODEC_ID_PNG;
264  } else {
265  id = AV_CODEC_ID_MJPEG;
266  }
267  }
268  st->codecpar->codec_id = id;
269 
270  return 0;
271 }
272 
273 // 3GPP TS 26.244
274 static int mov_metadata_loci(MOVContext *c, AVIOContext *pb, unsigned len)
275 {
276  char language[4] = { 0 };
277  char buf[200], place[100];
278  uint16_t langcode = 0;
279  double longitude, latitude, altitude;
280  const char *key = "location";
281 
282  if (len < 4 + 2 + 1 + 1 + 4 + 4 + 4) {
283  av_log(c->fc, AV_LOG_ERROR, "loci too short\n");
284  return AVERROR_INVALIDDATA;
285  }
286 
287  avio_skip(pb, 4); // version+flags
288  langcode = avio_rb16(pb);
289  ff_mov_lang_to_iso639(langcode, language);
290  len -= 6;
291 
292  len -= avio_get_str(pb, len, place, sizeof(place));
293  if (len < 1) {
294  av_log(c->fc, AV_LOG_ERROR, "place name too long\n");
295  return AVERROR_INVALIDDATA;
296  }
297  avio_skip(pb, 1); // role
298  len -= 1;
299 
300  if (len < 12) {
301  av_log(c->fc, AV_LOG_ERROR,
302  "loci too short (%u bytes left, need at least %d)\n", len, 12);
303  return AVERROR_INVALIDDATA;
304  }
305  longitude = ((int32_t) avio_rb32(pb)) / (float) (1 << 16);
306  latitude = ((int32_t) avio_rb32(pb)) / (float) (1 << 16);
307  altitude = ((int32_t) avio_rb32(pb)) / (float) (1 << 16);
308 
309  // Try to output in the same format as the ?xyz field
310  snprintf(buf, sizeof(buf), "%+08.4f%+09.4f", latitude, longitude);
311  if (altitude)
312  av_strlcatf(buf, sizeof(buf), "%+f", altitude);
313  av_strlcatf(buf, sizeof(buf), "/%s", place);
314 
315  if (*language && strcmp(language, "und")) {
316  char key2[16];
317  snprintf(key2, sizeof(key2), "%s-%s", key, language);
318  av_dict_set(&c->fc->metadata, key2, buf, 0);
319  }
320  c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
321  return av_dict_set(&c->fc->metadata, key, buf, 0);
322 }
323 
324 static int mov_metadata_hmmt(MOVContext *c, AVIOContext *pb, unsigned len)
325 {
326  int i, n_hmmt;
327 
328  if (len < 2)
329  return 0;
330  if (c->ignore_chapters)
331  return 0;
332 
333  n_hmmt = avio_rb32(pb);
334  if (n_hmmt > len / 4)
335  return AVERROR_INVALIDDATA;
336  for (i = 0; i < n_hmmt && !pb->eof_reached; i++) {
337  int moment_time = avio_rb32(pb);
338  avpriv_new_chapter(c->fc, i, av_make_q(1, 1000), moment_time, AV_NOPTS_VALUE, NULL);
339  }
340  if (avio_feof(pb))
341  return AVERROR_INVALIDDATA;
342  return 0;
343 }
344 
346 {
347  char tmp_key[AV_FOURCC_MAX_STRING_SIZE] = {0};
348  char key2[32], language[4] = {0};
349  char *str = NULL;
350  const char *key = NULL;
351  uint16_t langcode = 0;
352  uint32_t data_type = 0, str_size_alloc;
353  uint64_t str_size;
354  int (*parse)(MOVContext*, AVIOContext*, unsigned, const char*) = NULL;
355  int raw = 0;
356  int num = 0;
357  AVDictionary **metadata;
358 
359  if (c->trak_index >= 0 && c->trak_index < c->fc->nb_streams)
360  metadata = &c->fc->streams[c->trak_index]->metadata;
361  else
362  metadata = &c->fc->metadata;
363 
364  switch (atom.type) {
365  case MKTAG( '@','P','R','M'): key = "premiere_version"; raw = 1; break;
366  case MKTAG( '@','P','R','Q'): key = "quicktime_version"; raw = 1; break;
367  case MKTAG( 'X','M','P','_'):
368  if (c->export_xmp) { key = "xmp"; raw = 1; } break;
369  case MKTAG( 'a','A','R','T'): key = "album_artist"; break;
370  case MKTAG( 'a','k','I','D'): key = "account_type";
372  case MKTAG( 'a','p','I','D'): key = "account_id"; break;
373  case MKTAG( 'c','a','t','g'): key = "category"; break;
374  case MKTAG( 'c','p','i','l'): key = "compilation";
376  case MKTAG( 'c','p','r','t'): key = "copyright"; break;
377  case MKTAG( 'd','e','s','c'): key = "description"; break;
378  case MKTAG( 'd','i','s','k'): key = "disc";
380  case MKTAG( 'e','g','i','d'): key = "episode_uid";
382  case MKTAG( 'F','I','R','M'): key = "firmware"; raw = 1; break;
383  case MKTAG( 'g','n','r','e'): key = "genre";
384  parse = mov_metadata_gnre; break;
385  case MKTAG( 'h','d','v','d'): key = "hd_video";
387  case MKTAG( 'H','M','M','T'):
388  return mov_metadata_hmmt(c, pb, atom.size);
389  case MKTAG( 'k','e','y','w'): key = "keywords"; break;
390  case MKTAG( 'l','d','e','s'): key = "synopsis"; break;
391  case MKTAG( 'l','o','c','i'):
392  return mov_metadata_loci(c, pb, atom.size);
393  case MKTAG( 'm','a','n','u'): key = "make"; break;
394  case MKTAG( 'm','o','d','l'): key = "model"; break;
395  case MKTAG( 'p','c','s','t'): key = "podcast";
397  case MKTAG( 'p','g','a','p'): key = "gapless_playback";
399  case MKTAG( 'p','u','r','d'): key = "purchase_date"; break;
400  case MKTAG( 'r','t','n','g'): key = "rating";
402  case MKTAG( 's','o','a','a'): key = "sort_album_artist"; break;
403  case MKTAG( 's','o','a','l'): key = "sort_album"; break;
404  case MKTAG( 's','o','a','r'): key = "sort_artist"; break;
405  case MKTAG( 's','o','c','o'): key = "sort_composer"; break;
406  case MKTAG( 's','o','n','m'): key = "sort_name"; break;
407  case MKTAG( 's','o','s','n'): key = "sort_show"; break;
408  case MKTAG( 's','t','i','k'): key = "media_type";
410  case MKTAG( 't','r','k','n'): key = "track";
412  case MKTAG( 't','v','e','n'): key = "episode_id"; break;
413  case MKTAG( 't','v','e','s'): key = "episode_sort";
415  case MKTAG( 't','v','n','n'): key = "network"; break;
416  case MKTAG( 't','v','s','h'): key = "show"; break;
417  case MKTAG( 't','v','s','n'): key = "season_number";
419  case MKTAG(0xa9,'A','R','T'): key = "artist"; break;
420  case MKTAG(0xa9,'P','R','D'): key = "producer"; break;
421  case MKTAG(0xa9,'a','l','b'): key = "album"; break;
422  case MKTAG(0xa9,'a','u','t'): key = "artist"; break;
423  case MKTAG(0xa9,'c','h','p'): key = "chapter"; break;
424  case MKTAG(0xa9,'c','m','t'): key = "comment"; break;
425  case MKTAG(0xa9,'c','o','m'): key = "composer"; break;
426  case MKTAG(0xa9,'c','p','y'): key = "copyright"; break;
427  case MKTAG(0xa9,'d','a','y'): key = "date"; break;
428  case MKTAG(0xa9,'d','i','r'): key = "director"; break;
429  case MKTAG(0xa9,'d','i','s'): key = "disclaimer"; break;
430  case MKTAG(0xa9,'e','d','1'): key = "edit_date"; break;
431  case MKTAG(0xa9,'e','n','c'): key = "encoder"; break;
432  case MKTAG(0xa9,'f','m','t'): key = "original_format"; break;
433  case MKTAG(0xa9,'g','e','n'): key = "genre"; break;
434  case MKTAG(0xa9,'g','r','p'): key = "grouping"; break;
435  case MKTAG(0xa9,'h','s','t'): key = "host_computer"; break;
436  case MKTAG(0xa9,'i','n','f'): key = "comment"; break;
437  case MKTAG(0xa9,'l','y','r'): key = "lyrics"; break;
438  case MKTAG(0xa9,'m','a','k'): key = "make"; break;
439  case MKTAG(0xa9,'m','o','d'): key = "model"; break;
440  case MKTAG(0xa9,'n','a','m'): key = "title"; break;
441  case MKTAG(0xa9,'o','p','e'): key = "original_artist"; break;
442  case MKTAG(0xa9,'p','r','d'): key = "producer"; break;
443  case MKTAG(0xa9,'p','r','f'): key = "performers"; break;
444  case MKTAG(0xa9,'r','e','q'): key = "playback_requirements"; break;
445  case MKTAG(0xa9,'s','r','c'): key = "original_source"; break;
446  case MKTAG(0xa9,'s','t','3'): key = "subtitle"; break;
447  case MKTAG(0xa9,'s','w','r'): key = "encoder"; break;
448  case MKTAG(0xa9,'t','o','o'): key = "encoder"; break;
449  case MKTAG(0xa9,'t','r','k'): key = "track"; break;
450  case MKTAG(0xa9,'u','r','l'): key = "URL"; break;
451  case MKTAG(0xa9,'w','r','n'): key = "warning"; break;
452  case MKTAG(0xa9,'w','r','t'): key = "composer"; break;
453  case MKTAG(0xa9,'x','y','z'): key = "location"; break;
454  }
455 retry:
456  if (c->itunes_metadata && atom.size > 8) {
457  int data_size = avio_rb32(pb);
458  int tag = avio_rl32(pb);
459  if (tag == MKTAG('d','a','t','a') && data_size <= atom.size && data_size >= 16) {
460  data_type = avio_rb32(pb); // type
461  avio_rb32(pb); // unknown
462  str_size = data_size - 16;
463  atom.size -= 16;
464 
465  if (!key && c->found_hdlr_mdta && c->meta_keys) {
466  uint32_t index = av_bswap32(atom.type); // BE number has been read as LE
467  if (index < c->meta_keys_count && index > 0) {
468  key = c->meta_keys[index];
469  } else if (atom.type != MKTAG('c', 'o', 'v', 'r')) {
470  av_log(c->fc, AV_LOG_WARNING,
471  "The index of 'data' is out of range: %"PRId32" < 1 or >= %d.\n",
472  index, c->meta_keys_count);
473  }
474  }
475  if (atom.type == MKTAG('c', 'o', 'v', 'r') ||
476  (key && !strcmp(key, "com.apple.quicktime.artwork"))) {
477  int ret = mov_read_covr(c, pb, data_type, str_size);
478  if (ret < 0) {
479  av_log(c->fc, AV_LOG_ERROR, "Error parsing cover art.\n");
480  return ret;
481  }
482  atom.size -= str_size;
483  if (atom.size > 8)
484  goto retry;
485  return ret;
486  }
487  } else return 0;
488  } else if (atom.size > 4 && key && !c->itunes_metadata && !raw) {
489  str_size = avio_rb16(pb); // string length
490  if (str_size > atom.size) {
491  raw = 1;
492  avio_seek(pb, -2, SEEK_CUR);
493  av_log(c->fc, AV_LOG_WARNING, "UDTA parsing failed retrying raw\n");
494  goto retry;
495  }
496  langcode = avio_rb16(pb);
497  ff_mov_lang_to_iso639(langcode, language);
498  atom.size -= 4;
499  } else
500  str_size = atom.size;
501 
502  if (c->export_all && !key) {
503  key = av_fourcc_make_string(tmp_key, atom.type);
504  }
505 
506  if (!key)
507  return 0;
508  if (atom.size < 0 || str_size >= INT_MAX/2)
509  return AVERROR_INVALIDDATA;
510 
511  // Allocates enough space if data_type is a int32 or float32 number, otherwise
512  // worst-case requirement for output string in case of utf8 coded input
513  num = (data_type >= 21 && data_type <= 23);
514  str_size_alloc = (num ? 512 : (raw ? str_size : str_size * 2)) + 1;
515  str = av_mallocz(str_size_alloc);
516  if (!str)
517  return AVERROR(ENOMEM);
518 
519  if (parse)
520  parse(c, pb, str_size, key);
521  else {
522  if (!raw && (data_type == 3 || (data_type == 0 && (langcode < 0x400 || langcode == 0x7fff)))) { // MAC Encoded
523  mov_read_mac_string(c, pb, str_size, str, str_size_alloc);
524  } else if (data_type == 21) { // BE signed integer, variable size
525  int val = 0;
526  if (str_size == 1)
527  val = (int8_t)avio_r8(pb);
528  else if (str_size == 2)
529  val = (int16_t)avio_rb16(pb);
530  else if (str_size == 3)
531  val = ((int32_t)(avio_rb24(pb)<<8))>>8;
532  else if (str_size == 4)
533  val = (int32_t)avio_rb32(pb);
534  if (snprintf(str, str_size_alloc, "%d", val) >= str_size_alloc) {
535  av_log(c->fc, AV_LOG_ERROR,
536  "Failed to store the number (%d) in string.\n", val);
537  av_free(str);
538  return AVERROR_INVALIDDATA;
539  }
540  } else if (data_type == 22) { // BE unsigned integer, variable size
541  unsigned int val = 0;
542  if (str_size == 1)
543  val = avio_r8(pb);
544  else if (str_size == 2)
545  val = avio_rb16(pb);
546  else if (str_size == 3)
547  val = avio_rb24(pb);
548  else if (str_size == 4)
549  val = avio_rb32(pb);
550  if (snprintf(str, str_size_alloc, "%u", val) >= str_size_alloc) {
551  av_log(c->fc, AV_LOG_ERROR,
552  "Failed to store the number (%u) in string.\n", val);
553  av_free(str);
554  return AVERROR_INVALIDDATA;
555  }
556  } else if (data_type == 23 && str_size >= 4) { // BE float32
557  float val = av_int2float(avio_rb32(pb));
558  if (snprintf(str, str_size_alloc, "%f", val) >= str_size_alloc) {
559  av_log(c->fc, AV_LOG_ERROR,
560  "Failed to store the float32 number (%f) in string.\n", val);
561  av_free(str);
562  return AVERROR_INVALIDDATA;
563  }
564  } else if (data_type > 1 && data_type != 4) {
565  // data_type can be 0 if not set at all above. data_type 1 means
566  // UTF8 and 4 means "UTF8 sort". For any other type (UTF16 or e.g.
567  // a picture), don't return it blindly in a string that is supposed
568  // to be UTF8 text.
569  av_log(c->fc, AV_LOG_WARNING, "Skipping unhandled metadata %s of type %d\n", key, data_type);
570  av_free(str);
571  return 0;
572  } else {
573  int ret = ffio_read_size(pb, str, str_size);
574  if (ret < 0) {
575  av_free(str);
576  return ret;
577  }
578  str[str_size] = 0;
579  }
580  c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
581  av_dict_set(metadata, key, str, 0);
582  if (*language && strcmp(language, "und")) {
583  snprintf(key2, sizeof(key2), "%s-%s", key, language);
584  av_dict_set(metadata, key2, str, 0);
585  }
586  if (!strcmp(key, "encoder")) {
587  int major, minor, micro;
588  if (sscanf(str, "HandBrake %d.%d.%d", &major, &minor, &micro) == 3) {
589  c->handbrake_version = 1000000*major + 1000*minor + micro;
590  }
591  }
592  }
593 
594  av_freep(&str);
595  return 0;
596 }
597 
599 {
600  int64_t start;
601  int i, nb_chapters, str_len, version;
602  char str[256+1];
603  int ret;
604 
605  if (c->ignore_chapters)
606  return 0;
607 
608  if ((atom.size -= 5) < 0)
609  return 0;
610 
611  version = avio_r8(pb);
612  avio_rb24(pb);
613  if (version)
614  avio_rb32(pb); // ???
615  nb_chapters = avio_r8(pb);
616 
617  for (i = 0; i < nb_chapters; i++) {
618  if (atom.size < 9)
619  return 0;
620 
621  start = avio_rb64(pb);
622  str_len = avio_r8(pb);
623 
624  if ((atom.size -= 9+str_len) < 0)
625  return 0;
626 
627  ret = ffio_read_size(pb, str, str_len);
628  if (ret < 0)
629  return ret;
630  str[str_len] = 0;
631  avpriv_new_chapter(c->fc, i, (AVRational){1,10000000}, start, AV_NOPTS_VALUE, str);
632  }
633  return 0;
634 }
635 
636 #define MIN_DATA_ENTRY_BOX_SIZE 12
638 {
639  AVStream *st;
640  MOVStreamContext *sc;
641  int entries, i, j;
642 
643  if (c->fc->nb_streams < 1)
644  return 0;
645  st = c->fc->streams[c->fc->nb_streams-1];
646  sc = st->priv_data;
647 
648  avio_rb32(pb); // version + flags
649  entries = avio_rb32(pb);
650  if (!entries ||
651  entries > (atom.size - 1) / MIN_DATA_ENTRY_BOX_SIZE + 1 ||
652  entries >= UINT_MAX / sizeof(*sc->drefs))
653  return AVERROR_INVALIDDATA;
654 
655  for (i = 0; i < sc->drefs_count; i++) {
656  MOVDref *dref = &sc->drefs[i];
657  av_freep(&dref->path);
658  av_freep(&dref->dir);
659  }
660  av_free(sc->drefs);
661  sc->drefs_count = 0;
662  sc->drefs = av_mallocz(entries * sizeof(*sc->drefs));
663  if (!sc->drefs)
664  return AVERROR(ENOMEM);
665  sc->drefs_count = entries;
666 
667  for (i = 0; i < entries; i++) {
668  MOVDref *dref = &sc->drefs[i];
669  uint32_t size = avio_rb32(pb);
670  int64_t next = avio_tell(pb);
671 
672  if (size < 12 || next < 0 || next > INT64_MAX - size)
673  return AVERROR_INVALIDDATA;
674 
675  next += size - 4;
676 
677  dref->type = avio_rl32(pb);
678  avio_rb32(pb); // version + flags
679 
680  if (dref->type == MKTAG('a','l','i','s') && size > 150) {
681  /* macintosh alias record */
682  uint16_t volume_len, len;
683  int16_t type;
684  int ret;
685 
686  avio_skip(pb, 10);
687 
688  volume_len = avio_r8(pb);
689  volume_len = FFMIN(volume_len, 27);
690  ret = ffio_read_size(pb, dref->volume, 27);
691  if (ret < 0)
692  return ret;
693  dref->volume[volume_len] = 0;
694  av_log(c->fc, AV_LOG_DEBUG, "volume %s, len %d\n", dref->volume, volume_len);
695 
696  avio_skip(pb, 12);
697 
698  len = avio_r8(pb);
699  len = FFMIN(len, 63);
700  ret = ffio_read_size(pb, dref->filename, 63);
701  if (ret < 0)
702  return ret;
703  dref->filename[len] = 0;
704  av_log(c->fc, AV_LOG_DEBUG, "filename %s, len %d\n", dref->filename, len);
705 
706  avio_skip(pb, 16);
707 
708  /* read next level up_from_alias/down_to_target */
709  dref->nlvl_from = avio_rb16(pb);
710  dref->nlvl_to = avio_rb16(pb);
711  av_log(c->fc, AV_LOG_DEBUG, "nlvl from %d, nlvl to %d\n",
712  dref->nlvl_from, dref->nlvl_to);
713 
714  avio_skip(pb, 16);
715 
716  for (type = 0; type != -1 && avio_tell(pb) < next; ) {
717  if (avio_feof(pb))
718  return AVERROR_EOF;
719  type = avio_rb16(pb);
720  len = avio_rb16(pb);
721  av_log(c->fc, AV_LOG_DEBUG, "type %d, len %d\n", type, len);
722  if (len&1)
723  len += 1;
724  if (type == 2) { // absolute path
725  av_free(dref->path);
726  dref->path = av_mallocz(len+1);
727  if (!dref->path)
728  return AVERROR(ENOMEM);
729 
730  ret = ffio_read_size(pb, dref->path, len);
731  if (ret < 0) {
732  av_freep(&dref->path);
733  return ret;
734  }
735  if (len > volume_len && !strncmp(dref->path, dref->volume, volume_len)) {
736  len -= volume_len;
737  memmove(dref->path, dref->path+volume_len, len);
738  dref->path[len] = 0;
739  }
740  // trim string of any ending zeros
741  for (j = len - 1; j >= 0; j--) {
742  if (dref->path[j] == 0)
743  len--;
744  else
745  break;
746  }
747  for (j = 0; j < len; j++)
748  if (dref->path[j] == ':' || dref->path[j] == 0)
749  dref->path[j] = '/';
750  av_log(c->fc, AV_LOG_DEBUG, "path %s\n", dref->path);
751  } else if (type == 0) { // directory name
752  av_free(dref->dir);
753  dref->dir = av_malloc(len+1);
754  if (!dref->dir)
755  return AVERROR(ENOMEM);
756 
757  ret = ffio_read_size(pb, dref->dir, len);
758  if (ret < 0) {
759  av_freep(&dref->dir);
760  return ret;
761  }
762  dref->dir[len] = 0;
763  for (j = 0; j < len; j++)
764  if (dref->dir[j] == ':')
765  dref->dir[j] = '/';
766  av_log(c->fc, AV_LOG_DEBUG, "dir %s\n", dref->dir);
767  } else
768  avio_skip(pb, len);
769  }
770  } else {
771  av_log(c->fc, AV_LOG_DEBUG, "Unknown dref type 0x%08"PRIx32" size %"PRIu32"\n",
772  dref->type, size);
773  entries--;
774  i--;
775  }
776  avio_seek(pb, next, SEEK_SET);
777  }
778  return 0;
779 }
780 
782 {
783  AVStream *st;
784  uint32_t type;
785  uint32_t ctype;
786  int64_t title_size;
787  char *title_str;
788  int ret;
789 
790  avio_r8(pb); /* version */
791  avio_rb24(pb); /* flags */
792 
793  /* component type */
794  ctype = avio_rl32(pb);
795  type = avio_rl32(pb); /* component subtype */
796 
797  av_log(c->fc, AV_LOG_TRACE, "ctype=%s\n", av_fourcc2str(ctype));
798  av_log(c->fc, AV_LOG_TRACE, "stype=%s\n", av_fourcc2str(type));
799 
800  if (c->trak_index < 0) { // meta not inside a trak
801  if (type == MKTAG('m','d','t','a')) {
802  c->found_hdlr_mdta = 1;
803  }
804  return 0;
805  }
806 
807  st = c->fc->streams[c->fc->nb_streams-1];
808 
809  if (type == MKTAG('v','i','d','e'))
811  else if (type == MKTAG('s','o','u','n'))
813  else if (type == MKTAG('m','1','a',' '))
815  else if ((type == MKTAG('s','u','b','p')) || (type == MKTAG('c','l','c','p')))
817 
818  avio_rb32(pb); /* component manufacture */
819  avio_rb32(pb); /* component flags */
820  avio_rb32(pb); /* component flags mask */
821 
822  title_size = atom.size - 24;
823  if (title_size > 0) {
824  if (title_size > FFMIN(INT_MAX, SIZE_MAX-1))
825  return AVERROR_INVALIDDATA;
826  title_str = av_malloc(title_size + 1); /* Add null terminator */
827  if (!title_str)
828  return AVERROR(ENOMEM);
829 
830  ret = ffio_read_size(pb, title_str, title_size);
831  if (ret < 0) {
832  av_freep(&title_str);
833  return ret;
834  }
835  title_str[title_size] = 0;
836  if (title_str[0]) {
837  int off = (!c->isom && title_str[0] == title_size - 1);
838  // flag added so as to not set stream handler name if already set from mdia->hdlr
839  av_dict_set(&st->metadata, "handler_name", title_str + off, AV_DICT_DONT_OVERWRITE);
840  }
841  av_freep(&title_str);
842  }
843 
844  return 0;
845 }
846 
848 {
849  return ff_mov_read_esds(c->fc, pb);
850 }
851 
853 {
854  AVStream *st;
855  AVPacketSideData *sd;
856  enum AVAudioServiceType *ast;
857  int ac3info, acmod, lfeon, bsmod;
858  uint64_t mask;
859 
860  if (c->fc->nb_streams < 1)
861  return 0;
862  st = c->fc->streams[c->fc->nb_streams-1];
863 
867  sizeof(*ast), 0);
868  if (!sd)
869  return AVERROR(ENOMEM);
870 
871  ast = (enum AVAudioServiceType*)sd->data;
872  ac3info = avio_rb24(pb);
873  bsmod = (ac3info >> 14) & 0x7;
874  acmod = (ac3info >> 11) & 0x7;
875  lfeon = (ac3info >> 10) & 0x1;
876 
878  if (lfeon)
882 
883  *ast = bsmod;
884  if (st->codecpar->ch_layout.nb_channels > 1 && bsmod == 0x7)
886 
887  return 0;
888 }
889 
890 #if CONFIG_IAMFDEC
891 static int mov_read_iacb(MOVContext *c, AVIOContext *pb, MOVAtom atom)
892 {
893  AVStream *st;
894  MOVStreamContext *sc;
895  FFIOContext b;
896  AVIOContext *descriptor_pb;
897  AVDictionary *metadata;
898  IAMFContext *iamf;
900  unsigned descriptors_size;
901  int nb_frames, disposition;
902  int version, ret;
903 
904  if (atom.size < 5)
905  return AVERROR_INVALIDDATA;
906 
907  if (c->fc->nb_streams < 1)
908  return 0;
909 
910  version = avio_r8(pb);
911  if (version != 1) {
912  av_log(c->fc, AV_LOG_ERROR, "%s configurationVersion %d",
913  version < 1 ? "invalid" : "unsupported", version);
914  return AVERROR_INVALIDDATA;
915  }
916 
917  descriptors_size = ffio_read_leb(pb);
918  if (!descriptors_size || descriptors_size > INT_MAX)
919  return AVERROR_INVALIDDATA;
920 
921  st = c->fc->streams[c->fc->nb_streams - 1];
922  sc = st->priv_data;
923 
924  if (st->codecpar->extradata) {
925  av_log(c->fc, AV_LOG_WARNING, "ignoring iacb\n");
926  return 0;
927  }
928 
929  sc->iamf = av_mallocz(sizeof(*sc->iamf));
930  if (!sc->iamf)
931  return AVERROR(ENOMEM);
932  iamf = &sc->iamf->iamf;
933 
934  st->codecpar->extradata = av_malloc(descriptors_size);
935  if (!st->codecpar->extradata)
936  return AVERROR(ENOMEM);
937  st->codecpar->extradata_size = descriptors_size;
938 
939  ret = avio_read(pb, st->codecpar->extradata, descriptors_size);
940  if (ret != descriptors_size)
941  return ret < 0 ? ret : AVERROR_INVALIDDATA;
942 
943  ffio_init_read_context(&b, st->codecpar->extradata, descriptors_size);
944  descriptor_pb = &b.pub;
945 
946  ret = ff_iamfdec_read_descriptors(iamf, descriptor_pb, descriptors_size, c->fc);
947  if (ret < 0)
948  return ret;
949 
950  metadata = st->metadata;
951  st->metadata = NULL;
952  start_time = st->start_time;
953  nb_frames = st->nb_frames;
954  duration = st->duration;
955  disposition = st->disposition;
956 
957  for (int i = 0; i < iamf->nb_audio_elements; i++) {
958  IAMFAudioElement *audio_element = iamf->audio_elements[i];
959  const AVIAMFAudioElement *element;
960  AVStreamGroup *stg =
962 
963  if (!stg) {
964  ret = AVERROR(ENOMEM);
965  goto fail;
966  }
967 
969  stg->id = audio_element->audio_element_id;
970  /* Transfer ownership */
971  element = stg->params.iamf_audio_element = audio_element->element;
972  audio_element->element = NULL;
973 
974  for (int j = 0; j < audio_element->nb_substreams; j++) {
975  IAMFSubStream *substream = &audio_element->substreams[j];
976  AVStream *stream;
977 
978  if (!i && !j) {
979  if (audio_element->layers[0].substream_count != 1)
980  disposition &= ~AV_DISPOSITION_DEFAULT;
981  stream = st;
982  } else
983  stream = avformat_new_stream(c->fc, NULL);
984  if (!stream) {
985  ret = AVERROR(ENOMEM);
986  goto fail;
987  }
988 
989  stream->start_time = start_time;
990  stream->nb_frames = nb_frames;
991  stream->duration = duration;
992  stream->disposition = disposition;
993  if (stream != st) {
994  stream->priv_data = sc;
995  sc->refcount++;
996  }
997 
1000  if (i || j) {
1002  if (audio_element->layers[0].substream_count == 1)
1003  stream->disposition &= ~AV_DISPOSITION_DEFAULT;
1004  }
1005 
1006  ret = avcodec_parameters_copy(stream->codecpar, substream->codecpar);
1007  if (ret < 0)
1008  goto fail;
1009 
1010  stream->id = substream->audio_substream_id;
1011 
1012  avpriv_set_pts_info(st, 64, 1, sc->time_scale);
1013 
1014  ret = avformat_stream_group_add_stream(stg, stream);
1015  if (ret < 0)
1016  goto fail;
1017  }
1018 
1019  ret = av_dict_copy(&stg->metadata, metadata, 0);
1020  if (ret < 0)
1021  goto fail;
1022  }
1023 
1024  for (int i = 0; i < iamf->nb_mix_presentations; i++) {
1025  IAMFMixPresentation *mix_presentation = iamf->mix_presentations[i];
1026  const AVIAMFMixPresentation *mix = mix_presentation->cmix;
1027  AVStreamGroup *stg =
1029 
1030  if (!stg) {
1031  ret = AVERROR(ENOMEM);
1032  goto fail;
1033  }
1034 
1036  stg->id = mix_presentation->mix_presentation_id;
1037  /* Transfer ownership */
1038  stg->params.iamf_mix_presentation = mix_presentation->mix;
1039  mix_presentation->mix = NULL;
1040 
1041  for (int j = 0; j < mix->nb_submixes; j++) {
1042  const AVIAMFSubmix *submix = mix->submixes[j];
1043 
1044  for (int k = 0; k < submix->nb_elements; k++) {
1045  const AVIAMFSubmixElement *submix_element = submix->elements[k];
1046  const AVStreamGroup *audio_element = NULL;
1047 
1048  for (int l = 0; l < c->fc->nb_stream_groups; l++)
1049  if (c->fc->stream_groups[l]->type == AV_STREAM_GROUP_PARAMS_IAMF_AUDIO_ELEMENT &&
1050  c->fc->stream_groups[l]->id == submix_element->audio_element_id) {
1051  audio_element = c->fc->stream_groups[l];
1052  break;
1053  }
1054  av_assert0(audio_element);
1055 
1056  for (int l = 0; l < audio_element->nb_streams; l++) {
1057  ret = avformat_stream_group_add_stream(stg, audio_element->streams[l]);
1058  if (ret < 0 && ret != AVERROR(EEXIST))
1059  goto fail;
1060  }
1061  }
1062  }
1063 
1064  ret = av_dict_copy(&stg->metadata, metadata, 0);
1065  if (ret < 0)
1066  goto fail;
1067  }
1068 
1069  ret = 0;
1070 fail:
1071  av_dict_free(&metadata);
1072 
1073  return ret;
1074 }
1075 #endif
1076 
1078 {
1079  AVStream *st;
1080  AVPacketSideData *sd;
1081  enum AVAudioServiceType *ast;
1082  int eac3info, acmod, lfeon, bsmod;
1083  uint64_t mask;
1084 
1085  if (c->fc->nb_streams < 1)
1086  return 0;
1087  st = c->fc->streams[c->fc->nb_streams-1];
1088 
1092  sizeof(*ast), 0);
1093  if (!sd)
1094  return AVERROR(ENOMEM);
1095 
1096  ast = (enum AVAudioServiceType*)sd->data;
1097 
1098  /* No need to parse fields for additional independent substreams and its
1099  * associated dependent substreams since libavcodec's E-AC-3 decoder
1100  * does not support them yet. */
1101  avio_rb16(pb); /* data_rate and num_ind_sub */
1102  eac3info = avio_rb24(pb);
1103  bsmod = (eac3info >> 12) & 0x1f;
1104  acmod = (eac3info >> 9) & 0x7;
1105  lfeon = (eac3info >> 8) & 0x1;
1106 
1108  if (lfeon)
1112 
1113  *ast = bsmod;
1114  if (st->codecpar->ch_layout.nb_channels > 1 && bsmod == 0x7)
1116 
1117  return 0;
1118 }
1119 
1121 {
1122 #define DDTS_SIZE 20
1123  uint8_t buf[DDTS_SIZE + AV_INPUT_BUFFER_PADDING_SIZE];
1124  AVStream *st = NULL;
1125  uint32_t frame_duration_code = 0;
1126  uint32_t channel_layout_code = 0;
1127  GetBitContext gb;
1128  int ret;
1129 
1130  if ((ret = ffio_read_size(pb, buf, DDTS_SIZE)) < 0)
1131  return ret;
1132 
1133  init_get_bits(&gb, buf, 8 * DDTS_SIZE);
1134 
1135  if (c->fc->nb_streams < 1) {
1136  return 0;
1137  }
1138  st = c->fc->streams[c->fc->nb_streams-1];
1139 
1140  st->codecpar->sample_rate = get_bits_long(&gb, 32);
1141  if (st->codecpar->sample_rate <= 0) {
1142  av_log(c->fc, AV_LOG_ERROR, "Invalid sample rate %d\n", st->codecpar->sample_rate);
1143  return AVERROR_INVALIDDATA;
1144  }
1145  skip_bits_long(&gb, 32); /* max bitrate */
1146  st->codecpar->bit_rate = get_bits_long(&gb, 32);
1147  st->codecpar->bits_per_coded_sample = get_bits(&gb, 8);
1148  frame_duration_code = get_bits(&gb, 2);
1149  skip_bits(&gb, 30); /* various fields */
1150  channel_layout_code = get_bits(&gb, 16);
1151 
1152  st->codecpar->frame_size =
1153  (frame_duration_code == 0) ? 512 :
1154  (frame_duration_code == 1) ? 1024 :
1155  (frame_duration_code == 2) ? 2048 :
1156  (frame_duration_code == 3) ? 4096 : 0;
1157 
1158  if (channel_layout_code > 0xff) {
1159  av_log(c->fc, AV_LOG_WARNING, "Unsupported DTS audio channel layout\n");
1160  }
1163  ((channel_layout_code & 0x1) ? AV_CH_FRONT_CENTER : 0) |
1164  ((channel_layout_code & 0x2) ? AV_CH_FRONT_LEFT : 0) |
1165  ((channel_layout_code & 0x2) ? AV_CH_FRONT_RIGHT : 0) |
1166  ((channel_layout_code & 0x4) ? AV_CH_SIDE_LEFT : 0) |
1167  ((channel_layout_code & 0x4) ? AV_CH_SIDE_RIGHT : 0) |
1168  ((channel_layout_code & 0x8) ? AV_CH_LOW_FREQUENCY : 0));
1169 
1170  return 0;
1171 }
1172 
1174 {
1175  AVStream *st;
1176 
1177  if (c->fc->nb_streams < 1)
1178  return 0;
1179  st = c->fc->streams[c->fc->nb_streams-1];
1180 
1181  if (atom.size < 16)
1182  return 0;
1183 
1184  /* skip version and flags */
1185  avio_skip(pb, 4);
1186 
1187  ff_mov_read_chan(c->fc, pb, st, atom.size - 4);
1188 
1189  return 0;
1190 }
1191 
1193 {
1194  int64_t end = av_sat_add64(avio_tell(pb), atom.size);
1195  int version, flags;
1196  int ret;
1197  AVStream *st;
1198 
1199  if (c->fc->nb_streams < 1)
1200  return 0;
1201  st = c->fc->streams[c->fc->nb_streams-1];
1202 
1203  version = avio_r8(pb);
1204  flags = avio_rb24(pb);
1205  if (version != 0 || flags != 0) {
1206  av_log(c->fc, AV_LOG_ERROR,
1207  "Unsupported 'chnl' box with version %d, flags: %#x",
1208  version, flags);
1209  return AVERROR_INVALIDDATA;
1210  }
1211 
1212  ret = ff_mov_read_chnl(c->fc, pb, st);
1213  if (ret < 0)
1214  return ret;
1215 
1216  if (avio_tell(pb) != end) {
1217  av_log(c->fc, AV_LOG_WARNING, "skip %" PRId64 " bytes of unknown data inside chnl\n",
1218  end - avio_tell(pb));
1219  avio_seek(pb, end, SEEK_SET);
1220  }
1221  return ret;
1222 }
1223 
1225 {
1226  AVStream *st;
1227  int ret;
1228 
1229  if (c->fc->nb_streams < 1)
1230  return 0;
1231  st = c->fc->streams[c->fc->nb_streams-1];
1232 
1233  if ((ret = ff_get_wav_header(c->fc, pb, st->codecpar, atom.size, 0)) < 0)
1234  av_log(c->fc, AV_LOG_WARNING, "get_wav_header failed\n");
1235 
1236  return ret;
1237 }
1238 
1240 {
1241  AVStream *st;
1242  HEIFItem *item;
1243  AVPacketSideData *sd;
1244  int width, height, err = 0;
1245  AVRational aperture_width, aperture_height, horiz_off, vert_off;
1246  AVRational pc_x, pc_y;
1247  uint64_t top, bottom, left, right;
1248 
1249  item = heif_cur_item(c);
1250  st = get_curr_st(c);
1251  if (!st)
1252  return 0;
1253 
1254  width = st->codecpar->width;
1255  height = st->codecpar->height;
1256  if ((!width || !height) && item) {
1257  width = item->width;
1258  height = item->height;
1259  }
1260  if (!width || !height) {
1261  err = AVERROR_INVALIDDATA;
1262  goto fail;
1263  }
1264 
1265  aperture_width.num = avio_rb32(pb);
1266  aperture_width.den = avio_rb32(pb);
1267  aperture_height.num = avio_rb32(pb);
1268  aperture_height.den = avio_rb32(pb);
1269 
1270  horiz_off.num = avio_rb32(pb);
1271  horiz_off.den = avio_rb32(pb);
1272  vert_off.num = avio_rb32(pb);
1273  vert_off.den = avio_rb32(pb);
1274 
1275  if (aperture_width.num < 0 || aperture_width.den < 0 ||
1276  aperture_height.num < 0 || aperture_height.den < 0 ||
1277  horiz_off.den < 0 || vert_off.den < 0) {
1278  err = AVERROR_INVALIDDATA;
1279  goto fail;
1280  }
1281  av_log(c->fc, AV_LOG_TRACE, "clap: apertureWidth %d/%d, apertureHeight %d/%d "
1282  "horizOff %d/%d vertOff %d/%d\n",
1283  aperture_width.num, aperture_width.den, aperture_height.num, aperture_height.den,
1284  horiz_off.num, horiz_off.den, vert_off.num, vert_off.den);
1285 
1286  pc_x = av_mul_q((AVRational) { width - 1, 1 }, (AVRational) { 1, 2 });
1287  pc_x = av_add_q(pc_x, horiz_off);
1288  pc_y = av_mul_q((AVRational) { height - 1, 1 }, (AVRational) { 1, 2 });
1289  pc_y = av_add_q(pc_y, vert_off);
1290 
1291  aperture_width = av_sub_q(aperture_width, (AVRational) { 1, 1 });
1292  aperture_width = av_mul_q(aperture_width, (AVRational) { 1, 2 });
1293  aperture_height = av_sub_q(aperture_height, (AVRational) { 1, 1 });
1294  aperture_height = av_mul_q(aperture_height, (AVRational) { 1, 2 });
1295 
1296  left = av_q2d(av_sub_q(pc_x, aperture_width));
1297  right = av_q2d(av_add_q(pc_x, aperture_width));
1298  top = av_q2d(av_sub_q(pc_y, aperture_height));
1299  bottom = av_q2d(av_add_q(pc_y, aperture_height));
1300 
1301  if (bottom > (height - 1) ||
1302  right > (width - 1)) {
1303  err = AVERROR_INVALIDDATA;
1304  goto fail;
1305  }
1306 
1307  bottom = height - 1 - bottom;
1308  right = width - 1 - right;
1309 
1310  if (!(left | right | top | bottom))
1311  return 0;
1312 
1313  if ((left + right) >= width ||
1314  (top + bottom) >= height) {
1315  err = AVERROR_INVALIDDATA;
1316  goto fail;
1317  }
1318 
1322  sizeof(uint32_t) * 4, 0);
1323  if (!sd)
1324  return AVERROR(ENOMEM);
1325 
1326  AV_WL32A(sd->data, top);
1327  AV_WL32A(sd->data + 4, bottom);
1328  AV_WL32A(sd->data + 8, left);
1329  AV_WL32A(sd->data + 12, right);
1330 
1331 fail:
1332  if (err < 0) {
1333  int explode = !!(c->fc->error_recognition & AV_EF_EXPLODE);
1334  av_log(c->fc, explode ? AV_LOG_ERROR : AV_LOG_WARNING, "Invalid clap box\n");
1335  if (!explode)
1336  err = 0;
1337  }
1338 
1339  return err;
1340 }
1341 
1342 /* This atom overrides any previously set aspect ratio */
1344 {
1345  const int num = avio_rb32(pb);
1346  const int den = avio_rb32(pb);
1347  AVStream *st;
1348  MOVStreamContext *sc;
1349 
1350  if (c->fc->nb_streams < 1)
1351  return 0;
1352  st = c->fc->streams[c->fc->nb_streams-1];
1353  sc = st->priv_data;
1354 
1355  av_log(c->fc, AV_LOG_TRACE, "pasp: hSpacing %d, vSpacing %d\n", num, den);
1356 
1357  if (den != 0) {
1358  sc->h_spacing = num;
1359  sc->v_spacing = den;
1360  }
1361  return 0;
1362 }
1363 
1364 /* this atom contains actual media data */
1366 {
1367  if (atom.size == 0) /* wrong one (MP4) */
1368  return 0;
1369  c->found_mdat=1;
1370  return 0; /* now go for moov */
1371 }
1372 
1373 #define DRM_BLOB_SIZE 56
1374 
1376 {
1377  uint8_t intermediate_key[20];
1378  uint8_t intermediate_iv[20];
1379  uint8_t input[64];
1380  uint8_t output[64];
1381  uint8_t file_checksum[20];
1382  uint8_t calculated_checksum[20];
1383  char checksum_string[2 * sizeof(file_checksum) + 1];
1384  struct AVSHA *sha;
1385  int i;
1386  int ret = 0;
1387  uint8_t *activation_bytes = c->activation_bytes;
1388  uint8_t *fixed_key = c->audible_fixed_key;
1389 
1390  c->aax_mode = 1;
1391 
1392  sha = av_sha_alloc();
1393  if (!sha)
1394  return AVERROR(ENOMEM);
1395  av_free(c->aes_decrypt);
1396  c->aes_decrypt = av_aes_alloc();
1397  if (!c->aes_decrypt) {
1398  ret = AVERROR(ENOMEM);
1399  goto fail;
1400  }
1401 
1402  /* drm blob processing */
1403  avio_read(pb, output, 8); // go to offset 8, absolute position 0x251
1405  avio_read(pb, output, 4); // go to offset 4, absolute position 0x28d
1406  avio_read(pb, file_checksum, 20);
1407 
1408  // required by external tools
1409  ff_data_to_hex(checksum_string, file_checksum, sizeof(file_checksum), 1);
1410  av_log(c->fc, AV_LOG_INFO, "[aax] file checksum == %s\n", checksum_string);
1411 
1412  /* verify activation data */
1413  if (!activation_bytes) {
1414  av_log(c->fc, AV_LOG_WARNING, "[aax] activation_bytes option is missing!\n");
1415  ret = 0; /* allow ffprobe to continue working on .aax files */
1416  goto fail;
1417  }
1418  if (c->activation_bytes_size != 4) {
1419  av_log(c->fc, AV_LOG_FATAL, "[aax] activation_bytes value needs to be 4 bytes!\n");
1420  ret = AVERROR(EINVAL);
1421  goto fail;
1422  }
1423 
1424  /* verify fixed key */
1425  if (c->audible_fixed_key_size != 16) {
1426  av_log(c->fc, AV_LOG_FATAL, "[aax] audible_fixed_key value needs to be 16 bytes!\n");
1427  ret = AVERROR(EINVAL);
1428  goto fail;
1429  }
1430 
1431  /* AAX (and AAX+) key derivation */
1432  av_sha_init(sha, 160);
1433  av_sha_update(sha, fixed_key, 16);
1434  av_sha_update(sha, activation_bytes, 4);
1435  av_sha_final(sha, intermediate_key);
1436  av_sha_init(sha, 160);
1437  av_sha_update(sha, fixed_key, 16);
1438  av_sha_update(sha, intermediate_key, 20);
1439  av_sha_update(sha, activation_bytes, 4);
1440  av_sha_final(sha, intermediate_iv);
1441  av_sha_init(sha, 160);
1442  av_sha_update(sha, intermediate_key, 16);
1443  av_sha_update(sha, intermediate_iv, 16);
1444  av_sha_final(sha, calculated_checksum);
1445  if (memcmp(calculated_checksum, file_checksum, 20)) { // critical error
1446  av_log(c->fc, AV_LOG_ERROR, "[aax] mismatch in checksums!\n");
1448  goto fail;
1449  }
1450  av_aes_init(c->aes_decrypt, intermediate_key, 128, 1);
1451  av_aes_crypt(c->aes_decrypt, output, input, DRM_BLOB_SIZE >> 4, intermediate_iv, 1);
1452  for (i = 0; i < 4; i++) {
1453  // file data (in output) is stored in big-endian mode
1454  if (activation_bytes[i] != output[3 - i]) { // critical error
1455  av_log(c->fc, AV_LOG_ERROR, "[aax] error in drm blob decryption!\n");
1457  goto fail;
1458  }
1459  }
1460  memcpy(c->file_key, output + 8, 16);
1461  memcpy(input, output + 26, 16);
1462  av_sha_init(sha, 160);
1463  av_sha_update(sha, input, 16);
1464  av_sha_update(sha, c->file_key, 16);
1465  av_sha_update(sha, fixed_key, 16);
1466  av_sha_final(sha, c->file_iv);
1467 
1468 fail:
1469  av_free(sha);
1470 
1471  return ret;
1472 }
1473 
1475 {
1476  if (c->audible_key_size != 16) {
1477  av_log(c->fc, AV_LOG_FATAL, "[aaxc] audible_key value needs to be 16 bytes!\n");
1478  return AVERROR(EINVAL);
1479  }
1480 
1481  if (c->audible_iv_size != 16) {
1482  av_log(c->fc, AV_LOG_FATAL, "[aaxc] audible_iv value needs to be 16 bytes!\n");
1483  return AVERROR(EINVAL);
1484  }
1485 
1486  c->aes_decrypt = av_aes_alloc();
1487  if (!c->aes_decrypt) {
1488  return AVERROR(ENOMEM);
1489  }
1490 
1491  memcpy(c->file_key, c->audible_key, 16);
1492  memcpy(c->file_iv, c->audible_iv, 16);
1493  c->aax_mode = 1;
1494 
1495  return 0;
1496 }
1497 
1498 // Audible AAX (and AAX+) bytestream decryption
1499 static int aax_filter(uint8_t *input, int size, MOVContext *c)
1500 {
1501  int blocks = 0;
1502  unsigned char iv[16];
1503 
1504  memcpy(iv, c->file_iv, 16); // iv is overwritten
1505  blocks = size >> 4; // trailing bytes are not encrypted!
1506  av_aes_init(c->aes_decrypt, c->file_key, 128, 1);
1507  av_aes_crypt(c->aes_decrypt, input, input, blocks, iv, 1);
1508 
1509  return 0;
1510 }
1511 
1512 /* read major brand, minor version and compatible brands and store them as metadata */
1514 {
1515  uint32_t minor_ver;
1516  int comp_brand_size;
1517  char* comp_brands_str;
1518  uint8_t type[5] = {0};
1519  int ret = ffio_read_size(pb, type, 4);
1520  if (ret < 0)
1521  return ret;
1522  if (c->fc->nb_streams) {
1523  if (c->fc->strict_std_compliance >= FF_COMPLIANCE_STRICT)
1524  return AVERROR_INVALIDDATA;
1525  av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate FTYP\n");
1526  return 0;
1527  }
1528 
1529  if (strcmp(type, "qt "))
1530  c->isom = 1;
1531  av_log(c->fc, AV_LOG_DEBUG, "ISO: File Type Major Brand: %.4s\n",(char *)&type);
1532  av_dict_set(&c->fc->metadata, "major_brand", type, 0);
1533  minor_ver = avio_rb32(pb); /* minor version */
1534  av_dict_set_int(&c->fc->metadata, "minor_version", minor_ver, 0);
1535 
1536  comp_brand_size = atom.size - 8;
1537  if (comp_brand_size < 0 || comp_brand_size == INT_MAX)
1538  return AVERROR_INVALIDDATA;
1539  comp_brands_str = av_malloc(comp_brand_size + 1); /* Add null terminator */
1540  if (!comp_brands_str)
1541  return AVERROR(ENOMEM);
1542 
1543  ret = ffio_read_size(pb, comp_brands_str, comp_brand_size);
1544  if (ret < 0) {
1545  av_freep(&comp_brands_str);
1546  return ret;
1547  }
1548  comp_brands_str[comp_brand_size] = 0;
1549  av_dict_set(&c->fc->metadata, "compatible_brands",
1550  comp_brands_str, AV_DICT_DONT_STRDUP_VAL);
1551 
1552  // Logic for handling Audible's .aaxc files
1553  if (!strcmp(type, "aaxc")) {
1554  mov_aaxc_crypto(c);
1555  }
1556 
1557  return 0;
1558 }
1559 
1560 /* this atom should contain all header atoms */
1562 {
1563  int ret;
1564 
1565  if (c->found_moov) {
1566  av_log(c->fc, AV_LOG_WARNING, "Found duplicated MOOV Atom. Skipped it\n");
1567  avio_skip(pb, atom.size);
1568  return 0;
1569  }
1570 
1571  if ((ret = mov_read_default(c, pb, atom)) < 0)
1572  return ret;
1573  /* we parsed the 'moov' atom, we can terminate the parsing as soon as we find the 'mdat' */
1574  /* so we don't parse the whole file if over a network */
1575  c->found_moov=1;
1576  return 0; /* now go for mdat */
1577 }
1578 
1580  MOVFragmentIndex *frag_index,
1581  int index,
1582  int id)
1583 {
1584  int i;
1585  MOVFragmentIndexItem * item;
1586 
1587  if (index < 0 || index >= frag_index->nb_items)
1588  return NULL;
1589  item = &frag_index->item[index];
1590  for (i = 0; i < item->nb_stream_info; i++)
1591  if (item->stream_info[i].id == id)
1592  return &item->stream_info[i];
1593 
1594  // This shouldn't happen
1595  return NULL;
1596 }
1597 
1598 static void set_frag_stream(MOVFragmentIndex *frag_index, int id)
1599 {
1600  int i;
1601  MOVFragmentIndexItem * item;
1602 
1603  if (frag_index->current < 0 ||
1604  frag_index->current >= frag_index->nb_items)
1605  return;
1606 
1607  item = &frag_index->item[frag_index->current];
1608  for (i = 0; i < item->nb_stream_info; i++)
1609  if (item->stream_info[i].id == id) {
1610  item->current = i;
1611  return;
1612  }
1613 
1614  // id not found. This shouldn't happen.
1615  item->current = -1;
1616 }
1617 
1619  MOVFragmentIndex *frag_index)
1620 {
1621  MOVFragmentIndexItem *item;
1622  if (frag_index->current < 0 ||
1623  frag_index->current >= frag_index->nb_items)
1624  return NULL;
1625 
1626  item = &frag_index->item[frag_index->current];
1627  if (item->current >= 0 && item->current < item->nb_stream_info)
1628  return &item->stream_info[item->current];
1629 
1630  // This shouldn't happen
1631  return NULL;
1632 }
1633 
1635 {
1636  int a, b, m;
1637  int64_t moof_offset;
1638 
1639  // Optimize for appending new entries
1640  if (!frag_index->nb_items ||
1641  frag_index->item[frag_index->nb_items - 1].moof_offset < offset)
1642  return frag_index->nb_items;
1643 
1644  a = -1;
1645  b = frag_index->nb_items;
1646 
1647  while (b - a > 1) {
1648  m = (a + b) >> 1;
1649  moof_offset = frag_index->item[m].moof_offset;
1650  if (moof_offset >= offset)
1651  b = m;
1652  if (moof_offset <= offset)
1653  a = m;
1654  }
1655  return b;
1656 }
1657 
1659 {
1660  av_assert0(frag_stream_info);
1661  if (frag_stream_info->sidx_pts != AV_NOPTS_VALUE)
1662  return frag_stream_info->sidx_pts;
1663  if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE)
1664  return frag_stream_info->first_tfra_pts;
1665  return frag_stream_info->tfdt_dts;
1666 }
1667 
1669  MOVFragmentIndex *frag_index, int index)
1670 {
1671  MOVFragmentStreamInfo * frag_stream_info;
1672  MOVStreamContext *sc = dst_st->priv_data;
1673  int64_t timestamp;
1674  int i, j;
1675 
1676  // If the stream is referenced by any sidx, limit the search
1677  // to fragments that referenced this stream in the sidx
1678  if (sc->has_sidx) {
1679  frag_stream_info = get_frag_stream_info(frag_index, index, sc->id);
1680  if (!frag_stream_info)
1681  return AV_NOPTS_VALUE;
1682  if (frag_stream_info->sidx_pts != AV_NOPTS_VALUE)
1683  return frag_stream_info->sidx_pts;
1684  if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE)
1685  return frag_stream_info->first_tfra_pts;
1686  return frag_stream_info->sidx_pts;
1687  }
1688 
1689  for (i = 0; i < frag_index->item[index].nb_stream_info; i++) {
1690  AVStream *frag_stream = NULL;
1691  frag_stream_info = &frag_index->item[index].stream_info[i];
1692  for (j = 0; j < s->nb_streams; j++) {
1693  MOVStreamContext *sc2 = s->streams[j]->priv_data;
1694  if (sc2->id == frag_stream_info->id)
1695  frag_stream = s->streams[j];
1696  }
1697  if (!frag_stream) {
1698  av_log(s, AV_LOG_WARNING, "No stream matching sidx ID found.\n");
1699  continue;
1700  }
1701  timestamp = get_stream_info_time(frag_stream_info);
1702  if (timestamp != AV_NOPTS_VALUE)
1703  return av_rescale_q(timestamp, frag_stream->time_base, dst_st->time_base);
1704  }
1705  return AV_NOPTS_VALUE;
1706 }
1707 
1709  AVStream *st, int64_t timestamp)
1710 {
1711  int a, b, m, m0;
1712  int64_t frag_time;
1713 
1714  a = -1;
1715  b = frag_index->nb_items;
1716 
1717  while (b - a > 1) {
1718  m0 = m = (a + b) >> 1;
1719 
1720  while (m < b &&
1721  (frag_time = get_frag_time(s, st, frag_index, m)) == AV_NOPTS_VALUE)
1722  m++;
1723 
1724  if (m < b && frag_time <= timestamp)
1725  a = m;
1726  else
1727  b = m0;
1728  }
1729 
1730  return a;
1731 }
1732 
1734 {
1735  int index, i;
1736  MOVFragmentIndexItem * item;
1737  MOVFragmentStreamInfo * frag_stream_info;
1738 
1739  // If moof_offset already exists in frag_index, return index to it
1740  index = search_frag_moof_offset(&c->frag_index, offset);
1741  if (index < c->frag_index.nb_items &&
1742  c->frag_index.item[index].moof_offset == offset)
1743  return index;
1744 
1745  // offset is not yet in frag index.
1746  // Insert new item at index (sorted by moof offset)
1747  item = av_fast_realloc(c->frag_index.item,
1748  &c->frag_index.allocated_size,
1749  (c->frag_index.nb_items + 1) *
1750  sizeof(*c->frag_index.item));
1751  if (!item)
1752  return -1;
1753  c->frag_index.item = item;
1754 
1755  frag_stream_info = av_realloc_array(NULL, c->fc->nb_streams,
1756  sizeof(*item->stream_info));
1757  if (!frag_stream_info)
1758  return -1;
1759 
1760  for (i = 0; i < c->fc->nb_streams; i++) {
1761  // Avoid building frag index if streams lack track id.
1762  MOVStreamContext *sc = c->fc->streams[i]->priv_data;
1763  if (sc->id < 0) {
1764  av_free(frag_stream_info);
1765  return AVERROR_INVALIDDATA;
1766  }
1767 
1768  frag_stream_info[i].id = sc->id;
1769  frag_stream_info[i].sidx_pts = AV_NOPTS_VALUE;
1770  frag_stream_info[i].tfdt_dts = AV_NOPTS_VALUE;
1771  frag_stream_info[i].next_trun_dts = AV_NOPTS_VALUE;
1772  frag_stream_info[i].first_tfra_pts = AV_NOPTS_VALUE;
1773  frag_stream_info[i].index_base = -1;
1774  frag_stream_info[i].index_entry = -1;
1775  frag_stream_info[i].encryption_index = NULL;
1776  frag_stream_info[i].stsd_id = -1;
1777  }
1778 
1779  if (index < c->frag_index.nb_items)
1780  memmove(c->frag_index.item + index + 1, c->frag_index.item + index,
1781  (c->frag_index.nb_items - index) * sizeof(*c->frag_index.item));
1782 
1783  item = &c->frag_index.item[index];
1784  item->headers_read = 0;
1785  item->current = 0;
1786  item->nb_stream_info = c->fc->nb_streams;
1787  item->moof_offset = offset;
1788  item->stream_info = frag_stream_info;
1789  c->frag_index.nb_items++;
1790 
1791  return index;
1792 }
1793 
1794 static void fix_frag_index_entries(MOVFragmentIndex *frag_index, int index,
1795  int id, int entries)
1796 {
1797  int i;
1798  MOVFragmentStreamInfo * frag_stream_info;
1799 
1800  if (index < 0)
1801  return;
1802  for (i = index; i < frag_index->nb_items; i++) {
1803  frag_stream_info = get_frag_stream_info(frag_index, i, id);
1804  if (frag_stream_info && frag_stream_info->index_entry >= 0)
1805  frag_stream_info->index_entry += entries;
1806  }
1807 }
1808 
1810 {
1811  // Set by mov_read_tfhd(). mov_read_trun() will reject files missing tfhd.
1812  c->fragment.found_tfhd = 0;
1813 
1814  if (!c->has_looked_for_mfra && c->use_mfra_for > 0) {
1815  c->has_looked_for_mfra = 1;
1816  if (pb->seekable & AVIO_SEEKABLE_NORMAL) {
1817  int ret;
1818  av_log(c->fc, AV_LOG_VERBOSE, "stream has moof boxes, will look "
1819  "for a mfra\n");
1820  if ((ret = mov_read_mfra(c, pb)) < 0) {
1821  av_log(c->fc, AV_LOG_VERBOSE, "found a moof box but failed to "
1822  "read the mfra (may be a live ismv)\n");
1823  }
1824  } else {
1825  av_log(c->fc, AV_LOG_VERBOSE, "found a moof box but stream is not "
1826  "seekable, can not look for mfra\n");
1827  }
1828  }
1829  c->fragment.moof_offset = c->fragment.implicit_offset = avio_tell(pb) - 8;
1830  av_log(c->fc, AV_LOG_TRACE, "moof offset %"PRIx64"\n", c->fragment.moof_offset);
1831  c->frag_index.current = update_frag_index(c, c->fragment.moof_offset);
1832  return mov_read_default(c, pb, atom);
1833 }
1834 
1836 {
1837  int64_t time;
1838  if (version == 1) {
1839  time = avio_rb64(pb);
1840  avio_rb64(pb);
1841  if (time < 0) {
1842  av_log(c->fc, AV_LOG_DEBUG, "creation_time is negative\n");
1843  return;
1844  }
1845  } else {
1846  time = avio_rb32(pb);
1847  avio_rb32(pb); /* modification time */
1848  if (time > 0 && time < 2082844800) {
1849  av_log(c->fc, AV_LOG_WARNING, "Detected creation time before 1970, parsing as unix timestamp.\n");
1850  time += 2082844800;
1851  }
1852  }
1853  if (time) {
1854  time -= 2082844800; /* seconds between 1904-01-01 and Epoch */
1855 
1856  if ((int64_t)(time * 1000000ULL) / 1000000 != time) {
1857  av_log(c->fc, AV_LOG_DEBUG, "creation_time is not representable\n");
1858  return;
1859  }
1860 
1861  avpriv_dict_set_timestamp(metadata, "creation_time", time * 1000000);
1862  }
1863 }
1864 
1866 {
1867  AVStream *st;
1868  MOVStreamContext *sc;
1869  int version;
1870  char language[4] = {0};
1871  unsigned lang;
1872 
1873  if (c->fc->nb_streams < 1)
1874  return 0;
1875  st = c->fc->streams[c->fc->nb_streams-1];
1876  sc = st->priv_data;
1877 
1878  if (sc->time_scale) {
1879  av_log(c->fc, AV_LOG_ERROR, "Multiple mdhd?\n");
1880  return AVERROR_INVALIDDATA;
1881  }
1882 
1883  version = avio_r8(pb);
1884  if (version > 1) {
1885  avpriv_request_sample(c->fc, "Version %d", version);
1886  return AVERROR_PATCHWELCOME;
1887  }
1888  avio_rb24(pb); /* flags */
1890 
1891  sc->time_scale = avio_rb32(pb);
1892  if (sc->time_scale <= 0) {
1893  av_log(c->fc, AV_LOG_ERROR, "Invalid mdhd time scale %d, defaulting to 1\n", sc->time_scale);
1894  sc->time_scale = 1;
1895  }
1896  st->duration = (version == 1) ? avio_rb64(pb) : avio_rb32(pb); /* duration */
1897 
1898  if ((version == 1 && st->duration == UINT64_MAX) ||
1899  (version != 1 && st->duration == UINT32_MAX)) {
1900  st->duration = 0;
1901  }
1902 
1903  lang = avio_rb16(pb); /* language */
1904  if (ff_mov_lang_to_iso639(lang, language))
1905  av_dict_set(&st->metadata, "language", language, 0);
1906  avio_rb16(pb); /* quality */
1907 
1908  return 0;
1909 }
1910 
1912 {
1913  int i;
1914  int version = avio_r8(pb); /* version */
1915  avio_rb24(pb); /* flags */
1916 
1917  mov_metadata_creation_time(c, pb, &c->fc->metadata, version);
1918  c->time_scale = avio_rb32(pb); /* time scale */
1919  if (c->time_scale <= 0) {
1920  av_log(c->fc, AV_LOG_ERROR, "Invalid mvhd time scale %d, defaulting to 1\n", c->time_scale);
1921  c->time_scale = 1;
1922  }
1923  av_log(c->fc, AV_LOG_TRACE, "time scale = %i\n", c->time_scale);
1924 
1925  c->duration = (version == 1) ? avio_rb64(pb) : avio_rb32(pb); /* duration */
1926  avio_rb32(pb); /* preferred scale */
1927 
1928  avio_rb16(pb); /* preferred volume */
1929 
1930  avio_skip(pb, 10); /* reserved */
1931 
1932  /* movie display matrix, store it in main context and use it later on */
1933  for (i = 0; i < 3; i++) {
1934  c->movie_display_matrix[i][0] = avio_rb32(pb); // 16.16 fixed point
1935  c->movie_display_matrix[i][1] = avio_rb32(pb); // 16.16 fixed point
1936  c->movie_display_matrix[i][2] = avio_rb32(pb); // 2.30 fixed point
1937  }
1938 
1939  avio_rb32(pb); /* preview time */
1940  avio_rb32(pb); /* preview duration */
1941  avio_rb32(pb); /* poster time */
1942  avio_rb32(pb); /* selection time */
1943  avio_rb32(pb); /* selection duration */
1944  avio_rb32(pb); /* current time */
1945  avio_rb32(pb); /* next track ID */
1946 
1947  return 0;
1948 }
1949 
1951 {
1952  AVStream *st;
1953 
1954  if (fc->nb_streams < 1)
1955  return;
1956  st = fc->streams[fc->nb_streams-1];
1957 
1958  switch (st->codecpar->codec_id) {
1959  case AV_CODEC_ID_PCM_S16BE:
1961  break;
1962  case AV_CODEC_ID_PCM_S24BE:
1964  break;
1965  case AV_CODEC_ID_PCM_S32BE:
1967  break;
1968  case AV_CODEC_ID_PCM_F32BE:
1970  break;
1971  case AV_CODEC_ID_PCM_F64BE:
1973  break;
1974  default:
1975  break;
1976  }
1977 }
1978 
1980 {
1981  int little_endian = avio_rb16(pb) & 0xFF;
1982  av_log(c->fc, AV_LOG_TRACE, "enda %d\n", little_endian);
1983  if (little_endian == 1)
1985  return 0;
1986 }
1987 
1989 {
1990  int format_flags;
1991  int version, flags;
1992  int pcm_sample_size;
1993  AVFormatContext *fc = c->fc;
1994  AVStream *st;
1995  MOVStreamContext *sc;
1996 
1997  if (atom.size < 6) {
1998  av_log(c->fc, AV_LOG_ERROR, "Empty pcmC box\n");
1999  return AVERROR_INVALIDDATA;
2000  }
2001 
2002  version = avio_r8(pb);
2003  flags = avio_rb24(pb);
2004 
2005  if (version != 0 || flags != 0) {
2006  av_log(c->fc, AV_LOG_ERROR,
2007  "Unsupported 'pcmC' box with version %d, flags: %x",
2008  version, flags);
2009  return AVERROR_INVALIDDATA;
2010  }
2011 
2012  format_flags = avio_r8(pb);
2013  pcm_sample_size = avio_r8(pb);
2014 
2015  if (fc->nb_streams < 1)
2016  return AVERROR_INVALIDDATA;
2017 
2018  st = fc->streams[fc->nb_streams - 1];
2019  sc = st->priv_data;
2020 
2021  if (sc->format == MOV_MP4_FPCM_TAG) {
2022  switch (pcm_sample_size) {
2023  case 32:
2025  break;
2026  case 64:
2028  break;
2029  default:
2030  av_log(fc, AV_LOG_ERROR, "invalid pcm_sample_size %d for %s\n",
2031  pcm_sample_size,
2032  av_fourcc2str(sc->format));
2033  return AVERROR_INVALIDDATA;
2034  }
2035  } else if (sc->format == MOV_MP4_IPCM_TAG) {
2036  switch (pcm_sample_size) {
2037  case 16:
2039  break;
2040  case 24:
2042  break;
2043  case 32:
2045  break;
2046  default:
2047  av_log(fc, AV_LOG_ERROR, "invalid pcm_sample_size %d for %s\n",
2048  pcm_sample_size,
2049  av_fourcc2str(sc->format));
2050  return AVERROR_INVALIDDATA;
2051  }
2052  } else {
2053  av_log(fc, AV_LOG_ERROR, "'pcmC' with invalid sample entry '%s'\n",
2054  av_fourcc2str(sc->format));
2055  return AVERROR_INVALIDDATA;
2056  }
2057 
2058  if (format_flags & 1) // indicates little-endian format. If not present, big-endian format is used
2061 
2062  return 0;
2063 }
2064 
2066 {
2067  AVStream *st;
2068  HEIFItem *item = NULL;
2069  char color_parameter_type[5] = { 0 };
2070  uint16_t color_primaries, color_trc, color_matrix;
2071  int ret;
2072 
2073  st = get_curr_st(c);
2074  if (!st) {
2075  item = heif_cur_item(c);
2076  if (!item)
2077  return 0;
2078  }
2079 
2080  ret = ffio_read_size(pb, color_parameter_type, 4);
2081  if (ret < 0)
2082  return ret;
2083  if (strncmp(color_parameter_type, "nclx", 4) &&
2084  strncmp(color_parameter_type, "nclc", 4) &&
2085  strncmp(color_parameter_type, "prof", 4)) {
2086  av_log(c->fc, AV_LOG_WARNING, "unsupported color_parameter_type %s\n",
2087  color_parameter_type);
2088  return 0;
2089  }
2090 
2091  if (!strncmp(color_parameter_type, "prof", 4)) {
2092  AVPacketSideData *sd;
2093  uint8_t *icc_profile;
2094  if (st) {
2098  atom.size - 4, 0);
2099  if (!sd)
2100  return AVERROR(ENOMEM);
2101  icc_profile = sd->data;
2102  } else {
2103  av_freep(&item->icc_profile);
2104  icc_profile = item->icc_profile = av_malloc(atom.size - 4);
2105  if (!icc_profile) {
2106  item->icc_profile_size = 0;
2107  return AVERROR(ENOMEM);
2108  }
2109  item->icc_profile_size = atom.size - 4;
2110  }
2111  ret = ffio_read_size(pb, icc_profile, atom.size - 4);
2112  if (ret < 0)
2113  return ret;
2114  } else if (st) {
2115  color_primaries = avio_rb16(pb);
2116  color_trc = avio_rb16(pb);
2117  color_matrix = avio_rb16(pb);
2118 
2119  av_log(c->fc, AV_LOG_TRACE,
2120  "%s: pri %d trc %d matrix %d",
2121  color_parameter_type, color_primaries, color_trc, color_matrix);
2122 
2123  if (!strncmp(color_parameter_type, "nclx", 4)) {
2124  uint8_t color_range = avio_r8(pb) >> 7;
2125  av_log(c->fc, AV_LOG_TRACE, " full %"PRIu8"", color_range);
2126  if (color_range)
2128  else
2130  }
2131 
2134  if (!av_color_transfer_name(color_trc))
2135  color_trc = AVCOL_TRC_UNSPECIFIED;
2136  if (!av_color_space_name(color_matrix))
2137  color_matrix = AVCOL_SPC_UNSPECIFIED;
2138 
2140  st->codecpar->color_trc = color_trc;
2141  st->codecpar->color_space = color_matrix;
2142  av_log(c->fc, AV_LOG_TRACE, "\n");
2143  }
2144  return 0;
2145 }
2146 
2148 {
2149  AVStream *st;
2150  unsigned mov_field_order;
2151  enum AVFieldOrder decoded_field_order = AV_FIELD_UNKNOWN;
2152 
2153  if (c->fc->nb_streams < 1) // will happen with jp2 files
2154  return 0;
2155  st = c->fc->streams[c->fc->nb_streams-1];
2156  if (atom.size < 2)
2157  return AVERROR_INVALIDDATA;
2158  mov_field_order = avio_rb16(pb);
2159  if ((mov_field_order & 0xFF00) == 0x0100)
2160  decoded_field_order = AV_FIELD_PROGRESSIVE;
2161  else if ((mov_field_order & 0xFF00) == 0x0200) {
2162  switch (mov_field_order & 0xFF) {
2163  case 0x01: decoded_field_order = AV_FIELD_TT;
2164  break;
2165  case 0x06: decoded_field_order = AV_FIELD_BB;
2166  break;
2167  case 0x09: decoded_field_order = AV_FIELD_TB;
2168  break;
2169  case 0x0E: decoded_field_order = AV_FIELD_BT;
2170  break;
2171  }
2172  }
2173  if (decoded_field_order == AV_FIELD_UNKNOWN && mov_field_order) {
2174  av_log(c->fc, AV_LOG_ERROR, "Unknown MOV field order 0x%04x\n", mov_field_order);
2175  }
2176  st->codecpar->field_order = decoded_field_order;
2177 
2178  return 0;
2179 }
2180 
2182 {
2183  int err = 0;
2184  uint64_t size = (uint64_t)par->extradata_size + atom.size + 8 + AV_INPUT_BUFFER_PADDING_SIZE;
2185  if (size > INT_MAX || (uint64_t)atom.size > INT_MAX)
2186  return AVERROR_INVALIDDATA;
2187  if ((err = av_reallocp(&par->extradata, size)) < 0) {
2188  par->extradata_size = 0;
2189  return err;
2190  }
2192  return 0;
2193 }
2194 
2195 /* Read a whole atom into the extradata return the size of the atom read, possibly truncated if != atom.size */
2197  AVCodecParameters *par, uint8_t *buf)
2198 {
2199  int64_t result = atom.size;
2200  int err;
2201 
2202  AV_WB32(buf , atom.size + 8);
2203  AV_WL32(buf + 4, atom.type);
2204  err = ffio_read_size(pb, buf + 8, atom.size);
2205  if (err < 0) {
2206  par->extradata_size -= atom.size;
2207  return err;
2208  } else if (err < atom.size) {
2209  av_log(c->fc, AV_LOG_WARNING, "truncated extradata\n");
2210  par->extradata_size -= atom.size - err;
2211  result = err;
2212  }
2213  memset(buf + 8 + err, 0, AV_INPUT_BUFFER_PADDING_SIZE);
2214  return result;
2215 }
2216 
2217 /* FIXME modify QDM2/SVQ3/H.264 decoders to take full atom as extradata */
2219  enum AVCodecID codec_id)
2220 {
2221  AVStream *st;
2222  uint64_t original_size;
2223  int err;
2224 
2225  if (c->fc->nb_streams < 1) // will happen with jp2 files
2226  return 0;
2227  st = c->fc->streams[c->fc->nb_streams-1];
2228 
2229  if (st->codecpar->codec_id != codec_id)
2230  return 0; /* unexpected codec_id - don't mess with extradata */
2231 
2232  original_size = st->codecpar->extradata_size;
2233  err = mov_realloc_extradata(st->codecpar, atom);
2234  if (err)
2235  return err;
2236 
2237  err = mov_read_atom_into_extradata(c, pb, atom, st->codecpar, st->codecpar->extradata + original_size);
2238  if (err < 0)
2239  return err;
2240  return 0; // Note: this is the original behavior to ignore truncation.
2241 }
2242 
2243 /* wrapper functions for reading ALAC/AVS/MJPEG/MJPEG2000 extradata atoms only for those codecs */
2245 {
2246  return mov_read_extradata(c, pb, atom, AV_CODEC_ID_ALAC);
2247 }
2248 
2250 {
2251  return mov_read_extradata(c, pb, atom, AV_CODEC_ID_CAVS);
2252 }
2253 
2255 {
2256  return mov_read_extradata(c, pb, atom, AV_CODEC_ID_JPEG2000);
2257 }
2258 
2260 {
2261  return mov_read_extradata(c, pb, atom, AV_CODEC_ID_R10K);
2262 }
2263 
2265 {
2266  int ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_AVUI);
2267  if (!ret)
2268  ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_DNXHD);
2269  return ret;
2270 }
2271 
2273 {
2274  int ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_TARGA_Y216);
2275 
2276  if (!ret && c->fc->nb_streams >= 1) {
2277  AVCodecParameters *par = c->fc->streams[c->fc->nb_streams-1]->codecpar;
2278  if (par->extradata_size >= 40) {
2279  par->height = AV_RB16(&par->extradata[36]);
2280  par->width = AV_RB16(&par->extradata[38]);
2281  }
2282  }
2283  return ret;
2284 }
2285 
2287 {
2288  if (c->fc->nb_streams >= 1) {
2289  AVStream *const st = c->fc->streams[c->fc->nb_streams - 1];
2290  FFStream *const sti = ffstream(st);
2291  AVCodecParameters *par = st->codecpar;
2292 
2293  if (par->codec_tag == MKTAG('A', 'V', 'i', 'n') &&
2294  par->codec_id == AV_CODEC_ID_H264 &&
2295  atom.size > 11) {
2296  int cid;
2297  avio_skip(pb, 10);
2298  cid = avio_rb16(pb);
2299  /* For AVID AVCI50, force width of 1440 to be able to select the correct SPS and PPS */
2300  if (cid == 0xd4d || cid == 0xd4e)
2301  par->width = 1440;
2302  return 0;
2303  } else if ((par->codec_tag == MKTAG('A', 'V', 'd', '1') ||
2304  par->codec_tag == MKTAG('A', 'V', 'j', '2') ||
2305  par->codec_tag == MKTAG('A', 'V', 'd', 'n')) &&
2306  atom.size >= 24) {
2307  int num, den;
2308  avio_skip(pb, 12);
2309  num = avio_rb32(pb);
2310  den = avio_rb32(pb);
2311  if (num <= 0 || den <= 0)
2312  return 0;
2313  switch (avio_rb32(pb)) {
2314  case 2:
2315  if (den >= INT_MAX / 2)
2316  return 0;
2317  den *= 2;
2318  case 1:
2319  sti->display_aspect_ratio = (AVRational){ num, den };
2320  default:
2321  return 0;
2322  }
2323  }
2324  }
2325 
2326  return mov_read_avid(c, pb, atom);
2327 }
2328 
2330 {
2331  int ret = 0;
2332  int length = 0;
2333  uint64_t original_size;
2334  if (c->fc->nb_streams >= 1) {
2335  AVCodecParameters *par = c->fc->streams[c->fc->nb_streams-1]->codecpar;
2336  if (par->codec_id == AV_CODEC_ID_H264)
2337  return 0;
2338  if (atom.size == 16) {
2339  original_size = par->extradata_size;
2340  ret = mov_realloc_extradata(par, atom);
2341  if (!ret) {
2342  length = mov_read_atom_into_extradata(c, pb, atom, par, par->extradata + original_size);
2343  if (length == atom.size) {
2344  const uint8_t range_value = par->extradata[original_size + 19];
2345  switch (range_value) {
2346  case 1:
2348  break;
2349  case 2:
2351  break;
2352  default:
2353  av_log(c->fc, AV_LOG_WARNING, "ignored unknown aclr value (%d)\n", range_value);
2354  break;
2355  }
2356  ff_dlog(c->fc, "color_range: %d\n", par->color_range);
2357  } else {
2358  /* For some reason the whole atom was not added to the extradata */
2359  av_log(c->fc, AV_LOG_ERROR, "aclr not decoded - incomplete atom\n");
2360  }
2361  } else {
2362  av_log(c->fc, AV_LOG_ERROR, "aclr not decoded - unable to add atom to extradata\n");
2363  }
2364  } else {
2365  av_log(c->fc, AV_LOG_WARNING, "aclr not decoded - unexpected size %"PRId64"\n", atom.size);
2366  }
2367  }
2368 
2369  return ret;
2370 }
2371 
2373 {
2374  return mov_read_extradata(c, pb, atom, AV_CODEC_ID_SVQ3);
2375 }
2376 
2378 {
2379  AVStream *st;
2380  int ret;
2381 
2382  if (c->fc->nb_streams < 1)
2383  return 0;
2384  st = c->fc->streams[c->fc->nb_streams-1];
2385 
2386  if ((uint64_t)atom.size > (1<<30))
2387  return AVERROR_INVALIDDATA;
2388 
2389  if (st->codecpar->codec_id == AV_CODEC_ID_QDM2 ||
2392  // pass all frma atom to codec, needed at least for QDMC and QDM2
2393  ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size);
2394  if (ret < 0)
2395  return ret;
2396  } else if (atom.size > 8) { /* to read frma, esds atoms */
2397  if (st->codecpar->codec_id == AV_CODEC_ID_ALAC && atom.size >= 24) {
2398  uint64_t buffer;
2399  ret = ffio_ensure_seekback(pb, 8);
2400  if (ret < 0)
2401  return ret;
2402  buffer = avio_rb64(pb);
2403  atom.size -= 8;
2404  if ( (buffer & 0xFFFFFFFF) == MKBETAG('f','r','m','a')
2405  && buffer >> 32 <= atom.size
2406  && buffer >> 32 >= 8) {
2407  avio_skip(pb, -8);
2408  atom.size += 8;
2409  } else if (!st->codecpar->extradata_size) {
2410 #define ALAC_EXTRADATA_SIZE 36
2412  if (!st->codecpar->extradata)
2413  return AVERROR(ENOMEM);
2416  AV_WB32(st->codecpar->extradata + 4, MKTAG('a','l','a','c'));
2417  AV_WB64(st->codecpar->extradata + 12, buffer);
2418  avio_read(pb, st->codecpar->extradata + 20, 16);
2419  avio_skip(pb, atom.size - 24);
2420  return 0;
2421  }
2422  }
2423  if ((ret = mov_read_default(c, pb, atom)) < 0)
2424  return ret;
2425  } else
2426  avio_skip(pb, atom.size);
2427  return 0;
2428 }
2429 
2430 /**
2431  * This function reads atom content and puts data in extradata without tag
2432  * nor size unlike mov_read_extradata.
2433  */
2435 {
2436  AVStream *st;
2437  int ret;
2438 
2439  st = get_curr_st(c);
2440  if (!st)
2441  return 0;
2442 
2443  if ((uint64_t)atom.size > (1<<30))
2444  return AVERROR_INVALIDDATA;
2445 
2446  if (atom.type == MKTAG('v','v','c','C')) {
2447  avio_skip(pb, 4);
2448  atom.size -= 4;
2449  }
2450 
2451  if (atom.size >= 10) {
2452  // Broken files created by legacy versions of libavformat will
2453  // wrap a whole fiel atom inside of a glbl atom.
2454  unsigned size = avio_rb32(pb);
2455  unsigned type = avio_rl32(pb);
2456  if (avio_feof(pb))
2457  return AVERROR_INVALIDDATA;
2458  avio_seek(pb, -8, SEEK_CUR);
2459  if (type == MKTAG('f','i','e','l') && size == atom.size)
2460  return mov_read_default(c, pb, atom);
2461  }
2462  if (st->codecpar->extradata_size > 1 && st->codecpar->extradata) {
2463  av_log(c->fc, AV_LOG_WARNING, "ignoring multiple glbl\n");
2464  return 0;
2465  }
2466  ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size);
2467  if (ret < 0)
2468  return ret;
2469  if (atom.type == MKTAG('h','v','c','C') && st->codecpar->codec_tag == MKTAG('d','v','h','1'))
2470  /* HEVC-based Dolby Vision derived from hvc1.
2471  Happens to match with an identifier
2472  previously utilized for DV. Thus, if we have
2473  the hvcC extradata box available as specified,
2474  set codec to HEVC */
2476 
2477  return 0;
2478 }
2479 
2481 {
2482  AVStream *st;
2483  uint8_t profile_level;
2484  int ret;
2485 
2486  if (c->fc->nb_streams < 1)
2487  return 0;
2488  st = c->fc->streams[c->fc->nb_streams-1];
2489 
2490  if (atom.size >= (1<<28) || atom.size < 7)
2491  return AVERROR_INVALIDDATA;
2492 
2493  profile_level = avio_r8(pb);
2494  if ((profile_level & 0xf0) != 0xc0)
2495  return 0;
2496 
2497  avio_seek(pb, 6, SEEK_CUR);
2498  ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size - 7);
2499  if (ret < 0)
2500  return ret;
2501 
2502  return 0;
2503 }
2504 
2506 {
2507  AVStream* st;
2508  MOVStreamContext* sc;
2509 
2510  if (c->fc->nb_streams < 1)
2511  return 0;
2512 
2513  /* For SBAS this should be fine - though beware if someone implements a
2514  * tref atom processor that doesn't drop down to default then this may
2515  * be lost. */
2516  if (atom.size > 4) {
2517  av_log(c->fc, AV_LOG_ERROR, "Only a single tref of type sbas is supported\n");
2518  return AVERROR_PATCHWELCOME;
2519  }
2520 
2521  st = c->fc->streams[c->fc->nb_streams - 1];
2522  sc = st->priv_data;
2523  sc->tref_id = avio_rb32(pb);
2525 
2526  return 0;
2527 }
2528 
2529 /**
2530  * An strf atom is a BITMAPINFOHEADER struct. This struct is 40 bytes itself,
2531  * but can have extradata appended at the end after the 40 bytes belonging
2532  * to the struct.
2533  */
2535 {
2536  AVStream *st;
2537  int ret;
2538 
2539  if (c->fc->nb_streams < 1)
2540  return 0;
2541  if (atom.size <= 40)
2542  return 0;
2543  st = c->fc->streams[c->fc->nb_streams-1];
2544 
2545  if ((uint64_t)atom.size > (1<<30))
2546  return AVERROR_INVALIDDATA;
2547 
2548  avio_skip(pb, 40);
2549  ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size - 40);
2550  if (ret < 0)
2551  return ret;
2552 
2553  return 0;
2554 }
2555 
2557 {
2558  AVStream *st;
2559  MOVStreamContext *sc;
2560  unsigned int i, entries;
2561 
2562  if (c->trak_index < 0) {
2563  av_log(c->fc, AV_LOG_WARNING, "STCO outside TRAK\n");
2564  return 0;
2565  }
2566  if (c->fc->nb_streams < 1)
2567  return 0;
2568  st = c->fc->streams[c->fc->nb_streams-1];
2569  sc = st->priv_data;
2570 
2571  avio_r8(pb); /* version */
2572  avio_rb24(pb); /* flags */
2573 
2574  // Clamp allocation size for `chunk_offsets` -- don't throw an error for an
2575  // invalid count since the EOF path doesn't throw either.
2576  entries = avio_rb32(pb);
2577  entries =
2578  FFMIN(entries,
2579  FFMAX(0, (atom.size - 8) /
2580  (atom.type == MKTAG('s', 't', 'c', 'o') ? 4 : 8)));
2581 
2582  if (!entries)
2583  return 0;
2584 
2585  if (sc->chunk_offsets) {
2586  av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicated STCO atom\n");
2587  return 0;
2588  }
2589 
2590  av_free(sc->chunk_offsets);
2591  sc->chunk_count = 0;
2592  sc->chunk_offsets = av_malloc_array(entries, sizeof(*sc->chunk_offsets));
2593  if (!sc->chunk_offsets)
2594  return AVERROR(ENOMEM);
2595  sc->chunk_count = entries;
2596 
2597  if (atom.type == MKTAG('s','t','c','o'))
2598  for (i = 0; i < entries && !pb->eof_reached; i++)
2599  sc->chunk_offsets[i] = avio_rb32(pb);
2600  else if (atom.type == MKTAG('c','o','6','4'))
2601  for (i = 0; i < entries && !pb->eof_reached; i++) {
2602  sc->chunk_offsets[i] = avio_rb64(pb);
2603  if (sc->chunk_offsets[i] < 0) {
2604  av_log(c->fc, AV_LOG_WARNING, "Impossible chunk_offset\n");
2605  sc->chunk_offsets[i] = 0;
2606  }
2607  }
2608  else
2609  return AVERROR_INVALIDDATA;
2610 
2611  sc->chunk_count = i;
2612 
2613  if (pb->eof_reached) {
2614  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STCO atom\n");
2615  return AVERROR_EOF;
2616  }
2617 
2618  return 0;
2619 }
2620 
2621 static int mov_codec_id(AVStream *st, uint32_t format)
2622 {
2624 
2625  if (id <= 0 &&
2626  ((format & 0xFFFF) == 'm' + ('s' << 8) ||
2627  (format & 0xFFFF) == 'T' + ('S' << 8)))
2629 
2630  if (st->codecpar->codec_type != AVMEDIA_TYPE_VIDEO && id > 0) {
2632  } else if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO &&
2633  /* skip old ASF MPEG-4 tag */
2634  format && format != MKTAG('m','p','4','s')) {
2636  if (id <= 0)
2638  if (id > 0)
2640  else if (st->codecpar->codec_type == AVMEDIA_TYPE_DATA ||
2642  st->codecpar->codec_id == AV_CODEC_ID_NONE)) {
2644  if (id <= 0) {
2646  AV_CODEC_ID_TTML : id;
2647  }
2648 
2649  if (id > 0)
2651  else
2653  }
2654  }
2655 
2656  st->codecpar->codec_tag = format;
2657 
2658  return id;
2659 }
2660 
2662  AVStream *st, MOVStreamContext *sc)
2663 {
2664  uint8_t codec_name[32] = { 0 };
2665  int64_t stsd_start;
2666  unsigned int len;
2667  uint32_t id = 0;
2668 
2669  /* The first 16 bytes of the video sample description are already
2670  * read in ff_mov_read_stsd_entries() */
2671  stsd_start = avio_tell(pb) - 16;
2672 
2673  avio_rb16(pb); /* version */
2674  avio_rb16(pb); /* revision level */
2675  id = avio_rl32(pb); /* vendor */
2676  av_dict_set(&st->metadata, "vendor_id", av_fourcc2str(id), 0);
2677  avio_rb32(pb); /* temporal quality */
2678  avio_rb32(pb); /* spatial quality */
2679 
2680  st->codecpar->width = avio_rb16(pb); /* width */
2681  st->codecpar->height = avio_rb16(pb); /* height */
2682 
2683  avio_rb32(pb); /* horiz resolution */
2684  avio_rb32(pb); /* vert resolution */
2685  avio_rb32(pb); /* data size, always 0 */
2686  avio_rb16(pb); /* frames per samples */
2687 
2688  len = avio_r8(pb); /* codec name, pascal string */
2689  if (len > 31)
2690  len = 31;
2691  mov_read_mac_string(c, pb, len, codec_name, sizeof(codec_name));
2692  if (len < 31)
2693  avio_skip(pb, 31 - len);
2694 
2695  if (codec_name[0])
2696  av_dict_set(&st->metadata, "encoder", codec_name, 0);
2697 
2698  /* codec_tag YV12 triggers an UV swap in rawdec.c */
2699  if (!strncmp(codec_name, "Planar Y'CbCr 8-bit 4:2:0", 25)) {
2700  st->codecpar->codec_tag = MKTAG('I', '4', '2', '0');
2701  st->codecpar->width &= ~1;
2702  st->codecpar->height &= ~1;
2703  }
2704  /* Flash Media Server uses tag H.263 with Sorenson Spark */
2705  if (st->codecpar->codec_tag == MKTAG('H','2','6','3') &&
2706  !strncmp(codec_name, "Sorenson H263", 13))
2708 
2709  st->codecpar->bits_per_coded_sample = avio_rb16(pb); /* depth */
2710 
2711  avio_seek(pb, stsd_start, SEEK_SET);
2712 
2713  if (ff_get_qtpalette(st->codecpar->codec_id, pb, sc->palette)) {
2714  st->codecpar->bits_per_coded_sample &= 0x1F;
2715  sc->has_palette = 1;
2716  }
2717 }
2718 
2720  AVStream *st, MOVStreamContext *sc)
2721 {
2722  int bits_per_sample, flags;
2723  uint16_t version = avio_rb16(pb);
2724  uint32_t id = 0;
2725  AVDictionaryEntry *compatible_brands = av_dict_get(c->fc->metadata, "compatible_brands", NULL, AV_DICT_MATCH_CASE);
2726  int channel_count;
2727 
2728  avio_rb16(pb); /* revision level */
2729  id = avio_rl32(pb); /* vendor */
2730  av_dict_set(&st->metadata, "vendor_id", av_fourcc2str(id), 0);
2731 
2732  channel_count = avio_rb16(pb);
2733 
2735  st->codecpar->ch_layout.nb_channels = channel_count;
2736  st->codecpar->bits_per_coded_sample = avio_rb16(pb); /* sample size */
2737  av_log(c->fc, AV_LOG_TRACE, "audio channels %d\n", channel_count);
2738 
2739  sc->audio_cid = avio_rb16(pb);
2740  avio_rb16(pb); /* packet size = 0 */
2741 
2742  st->codecpar->sample_rate = ((avio_rb32(pb) >> 16));
2743 
2744  // Read QT version 1 fields. In version 0 these do not exist.
2745  av_log(c->fc, AV_LOG_TRACE, "version =%d, isom =%d\n", version, c->isom);
2746  if (!c->isom ||
2747  (compatible_brands && strstr(compatible_brands->value, "qt ")) ||
2748  (sc->stsd_version == 0 && version > 0)) {
2749  if (version == 1) {
2750  sc->samples_per_frame = avio_rb32(pb);
2751  avio_rb32(pb); /* bytes per packet */
2752  sc->bytes_per_frame = avio_rb32(pb);
2753  avio_rb32(pb); /* bytes per sample */
2754  } else if (version == 2) {
2755  avio_rb32(pb); /* sizeof struct only */
2757  channel_count = avio_rb32(pb);
2759  st->codecpar->ch_layout.nb_channels = channel_count;
2760  avio_rb32(pb); /* always 0x7F000000 */
2762 
2763  flags = avio_rb32(pb); /* lpcm format specific flag */
2764  sc->bytes_per_frame = avio_rb32(pb);
2765  sc->samples_per_frame = avio_rb32(pb);
2766  if (st->codecpar->codec_tag == MKTAG('l','p','c','m'))
2767  st->codecpar->codec_id =
2769  flags);
2770  }
2771  if (version == 0 || (version == 1 && sc->audio_cid != -2)) {
2772  /* can't correctly handle variable sized packet as audio unit */
2773  switch (st->codecpar->codec_id) {
2774  case AV_CODEC_ID_MP2:
2775  case AV_CODEC_ID_MP3:
2777  break;
2778  }
2779  }
2780  }
2781 
2782  if (sc->format == 0) {
2783  if (st->codecpar->bits_per_coded_sample == 8)
2784  st->codecpar->codec_id = mov_codec_id(st, MKTAG('r','a','w',' '));
2785  else if (st->codecpar->bits_per_coded_sample == 16)
2786  st->codecpar->codec_id = mov_codec_id(st, MKTAG('t','w','o','s'));
2787  }
2788 
2789  switch (st->codecpar->codec_id) {
2790  case AV_CODEC_ID_PCM_S8:
2791  case AV_CODEC_ID_PCM_U8:
2792  if (st->codecpar->bits_per_coded_sample == 16)
2794  break;
2795  case AV_CODEC_ID_PCM_S16LE:
2796  case AV_CODEC_ID_PCM_S16BE:
2797  if (st->codecpar->bits_per_coded_sample == 8)
2799  else if (st->codecpar->bits_per_coded_sample == 24)
2800  st->codecpar->codec_id =
2803  else if (st->codecpar->bits_per_coded_sample == 32)
2804  st->codecpar->codec_id =
2807  break;
2808  /* set values for old format before stsd version 1 appeared */
2809  case AV_CODEC_ID_MACE3:
2810  sc->samples_per_frame = 6;
2812  break;
2813  case AV_CODEC_ID_MACE6:
2814  sc->samples_per_frame = 6;
2816  break;
2818  sc->samples_per_frame = 64;
2820  break;
2821  case AV_CODEC_ID_GSM:
2822  sc->samples_per_frame = 160;
2823  sc->bytes_per_frame = 33;
2824  break;
2825  default:
2826  break;
2827  }
2828 
2829  bits_per_sample = av_get_bits_per_sample(st->codecpar->codec_id);
2830  if (bits_per_sample && (bits_per_sample >> 3) * (uint64_t)st->codecpar->ch_layout.nb_channels <= INT_MAX) {
2831  st->codecpar->bits_per_coded_sample = bits_per_sample;
2832  sc->sample_size = (bits_per_sample >> 3) * st->codecpar->ch_layout.nb_channels;
2833  }
2834 }
2835 
2837  AVStream *st, MOVStreamContext *sc,
2838  int64_t size)
2839 {
2840  // ttxt stsd contains display flags, justification, background
2841  // color, fonts, and default styles, so fake an atom to read it
2842  MOVAtom fake_atom = { .size = size };
2843  // mp4s contains a regular esds atom, dfxp ISMV TTML has no content
2844  // in extradata unlike stpp MP4 TTML.
2845  if (st->codecpar->codec_tag != AV_RL32("mp4s") &&
2847  mov_read_glbl(c, pb, fake_atom);
2848  st->codecpar->width = sc->width;
2849  st->codecpar->height = sc->height;
2850 }
2851 
2853  AVStream *st, MOVStreamContext *sc,
2854  int64_t size)
2855 {
2856  int ret;
2857 
2858  if (st->codecpar->codec_tag == MKTAG('t','m','c','d')) {
2859  if ((int)size != size)
2860  return AVERROR(ENOMEM);
2861 
2862  ret = ff_get_extradata(c->fc, st->codecpar, pb, size);
2863  if (ret < 0)
2864  return ret;
2865  if (size > 16) {
2866  MOVStreamContext *tmcd_ctx = st->priv_data;
2867  int val;
2868  val = AV_RB32(st->codecpar->extradata + 4);
2869  tmcd_ctx->tmcd_flags = val;
2870  st->avg_frame_rate.num = AV_RB32(st->codecpar->extradata + 8); /* timescale */
2871  st->avg_frame_rate.den = AV_RB32(st->codecpar->extradata + 12); /* frameDuration */
2872  tmcd_ctx->tmcd_nb_frames = st->codecpar->extradata[16]; /* number of frames */
2873  if (size > 30) {
2874  uint32_t len = AV_RB32(st->codecpar->extradata + 18); /* name atom length */
2875  uint32_t format = AV_RB32(st->codecpar->extradata + 22);
2876  if (format == AV_RB32("name") && (int64_t)size >= (int64_t)len + 18) {
2877  uint16_t str_size = AV_RB16(st->codecpar->extradata + 26); /* string length */
2878  if (str_size > 0 && size >= (int)str_size + 30 &&
2879  st->codecpar->extradata[30] /* Don't add empty string */) {
2880  char *reel_name = av_malloc(str_size + 1);
2881  if (!reel_name)
2882  return AVERROR(ENOMEM);
2883  memcpy(reel_name, st->codecpar->extradata + 30, str_size);
2884  reel_name[str_size] = 0; /* Add null terminator */
2885  av_dict_set(&st->metadata, "reel_name", reel_name,
2887  }
2888  }
2889  }
2890  }
2891  } else {
2892  /* other codec type, just skip (rtp, mp4s ...) */
2893  avio_skip(pb, size);
2894  }
2895  return 0;
2896 }
2897 
2899  AVStream *st, MOVStreamContext *sc)
2900 {
2901  FFStream *const sti = ffstream(st);
2902 
2903  if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
2904  !st->codecpar->sample_rate && sc->time_scale > 1)
2905  st->codecpar->sample_rate = sc->time_scale;
2906 
2907  /* special codec parameters handling */
2908  switch (st->codecpar->codec_id) {
2909 #if CONFIG_DV_DEMUXER
2910  case AV_CODEC_ID_DVAUDIO:
2911  if (c->dv_fctx) {
2912  avpriv_request_sample(c->fc, "multiple DV audio streams");
2913  return AVERROR(ENOSYS);
2914  }
2915 
2916  c->dv_fctx = avformat_alloc_context();
2917  if (!c->dv_fctx) {
2918  av_log(c->fc, AV_LOG_ERROR, "dv demux context alloc error\n");
2919  return AVERROR(ENOMEM);
2920  }
2921  c->dv_demux = avpriv_dv_init_demux(c->dv_fctx);
2922  if (!c->dv_demux) {
2923  av_log(c->fc, AV_LOG_ERROR, "dv demux context init error\n");
2924  return AVERROR(ENOMEM);
2925  }
2926  sc->dv_audio_container = 1;
2928  break;
2929 #endif
2930  /* no ifdef since parameters are always those */
2931  case AV_CODEC_ID_QCELP:
2934  // force sample rate for qcelp when not stored in mov
2935  if (st->codecpar->codec_tag != MKTAG('Q','c','l','p'))
2936  st->codecpar->sample_rate = 8000;
2937  // FIXME: Why is the following needed for some files?
2938  sc->samples_per_frame = 160;
2939  if (!sc->bytes_per_frame)
2940  sc->bytes_per_frame = 35;
2941  break;
2942  case AV_CODEC_ID_AMR_NB:
2945  /* force sample rate for amr, stsd in 3gp does not store sample rate */
2946  st->codecpar->sample_rate = 8000;
2947  break;
2948  case AV_CODEC_ID_AMR_WB:
2951  st->codecpar->sample_rate = 16000;
2952  break;
2953  case AV_CODEC_ID_MP2:
2954  case AV_CODEC_ID_MP3:
2955  /* force type after stsd for m1a hdlr */
2957  break;
2958  case AV_CODEC_ID_GSM:
2959  case AV_CODEC_ID_ADPCM_MS:
2961  case AV_CODEC_ID_ILBC:
2962  case AV_CODEC_ID_MACE3:
2963  case AV_CODEC_ID_MACE6:
2964  case AV_CODEC_ID_QDM2:
2966  break;
2967  case AV_CODEC_ID_ALAC:
2968  if (st->codecpar->extradata_size == 36) {
2969  int channel_count = AV_RB8(st->codecpar->extradata + 21);
2970  if (st->codecpar->ch_layout.nb_channels != channel_count) {
2973  st->codecpar->ch_layout.nb_channels = channel_count;
2974  }
2975  st->codecpar->sample_rate = AV_RB32(st->codecpar->extradata + 32);
2976  }
2977  break;
2978  case AV_CODEC_ID_AC3:
2979  case AV_CODEC_ID_EAC3:
2981  case AV_CODEC_ID_VC1:
2982  case AV_CODEC_ID_VP8:
2983  case AV_CODEC_ID_VP9:
2985  break;
2986  case AV_CODEC_ID_EVC:
2987  case AV_CODEC_ID_AV1:
2988  /* field_order detection of H264 requires parsing */
2989  case AV_CODEC_ID_H264:
2991  break;
2992  default:
2993  break;
2994  }
2995  return 0;
2996 }
2997 
2999  int codec_tag, int format,
3000  int64_t size)
3001 {
3002  if (codec_tag &&
3003  (codec_tag != format &&
3004  // AVID 1:1 samples with differing data format and codec tag exist
3005  (codec_tag != AV_RL32("AV1x") || format != AV_RL32("AVup")) &&
3006  // prores is allowed to have differing data format and codec tag
3007  codec_tag != AV_RL32("apcn") && codec_tag != AV_RL32("apch") &&
3008  // so is dv (sigh)
3009  codec_tag != AV_RL32("dvpp") && codec_tag != AV_RL32("dvcp") &&
3010  (c->fc->video_codec_id ? ff_codec_get_id(ff_codec_movvideo_tags, format) != c->fc->video_codec_id
3011  : codec_tag != MKTAG('j','p','e','g')))) {
3012  /* Multiple fourcc, we skip JPEG. This is not correct, we should
3013  * export it as a separate AVStream but this needs a few changes
3014  * in the MOV demuxer, patch welcome. */
3015 
3016  av_log(c->fc, AV_LOG_WARNING, "multiple fourcc not supported\n");
3017  avio_skip(pb, size);
3018  return 1;
3019  }
3020 
3021  return 0;
3022 }
3023 
3025 {
3026  AVStream *st;
3027  MOVStreamContext *sc;
3028  int pseudo_stream_id;
3029 
3030  av_assert0 (c->fc->nb_streams >= 1);
3031  st = c->fc->streams[c->fc->nb_streams-1];
3032  sc = st->priv_data;
3033 
3034  for (pseudo_stream_id = 0;
3035  pseudo_stream_id < entries && !pb->eof_reached;
3036  pseudo_stream_id++) {
3037  //Parsing Sample description table
3038  enum AVCodecID id;
3039  int ret, dref_id = 1;
3040  MOVAtom a = { AV_RL32("stsd") };
3041  int64_t start_pos = avio_tell(pb);
3042  int64_t size = avio_rb32(pb); /* size */
3043  uint32_t format = avio_rl32(pb); /* data format */
3044 
3045  if (size >= 16) {
3046  avio_rb32(pb); /* reserved */
3047  avio_rb16(pb); /* reserved */
3048  dref_id = avio_rb16(pb);
3049  } else if (size <= 7) {
3050  av_log(c->fc, AV_LOG_ERROR,
3051  "invalid size %"PRId64" in stsd\n", size);
3052  return AVERROR_INVALIDDATA;
3053  }
3054 
3056  size - (avio_tell(pb) - start_pos))) {
3057  sc->stsd_count++;
3058  continue;
3059  }
3060 
3061  sc->pseudo_stream_id = st->codecpar->codec_tag ? -1 : pseudo_stream_id;
3062  sc->dref_id= dref_id;
3063  sc->format = format;
3064 
3065  id = mov_codec_id(st, format);
3066 
3067  av_log(c->fc, AV_LOG_TRACE,
3068  "size=%"PRId64" 4CC=%s codec_type=%d\n", size,
3070 
3071  st->codecpar->codec_id = id;
3073  mov_parse_stsd_video(c, pb, st, sc);
3074  } else if (st->codecpar->codec_type==AVMEDIA_TYPE_AUDIO) {
3075  mov_parse_stsd_audio(c, pb, st, sc);
3076  if (st->codecpar->sample_rate < 0) {
3077  av_log(c->fc, AV_LOG_ERROR, "Invalid sample rate %d\n", st->codecpar->sample_rate);
3078  return AVERROR_INVALIDDATA;
3079  }
3080  if (st->codecpar->ch_layout.nb_channels < 0) {
3081  av_log(c->fc, AV_LOG_ERROR, "Invalid channels %d\n", st->codecpar->ch_layout.nb_channels);
3082  return AVERROR_INVALIDDATA;
3083  }
3084  } else if (st->codecpar->codec_type==AVMEDIA_TYPE_SUBTITLE){
3085  mov_parse_stsd_subtitle(c, pb, st, sc,
3086  size - (avio_tell(pb) - start_pos));
3087  } else {
3088  ret = mov_parse_stsd_data(c, pb, st, sc,
3089  size - (avio_tell(pb) - start_pos));
3090  if (ret < 0)
3091  return ret;
3092  }
3093  /* this will read extra atoms at the end (wave, alac, damr, avcC, hvcC, SMI ...) */
3094  a.size = size - (avio_tell(pb) - start_pos);
3095  if (a.size > 8) {
3096  if ((ret = mov_read_default(c, pb, a)) < 0)
3097  return ret;
3098  } else if (a.size > 0)
3099  avio_skip(pb, a.size);
3100 
3101  if (sc->extradata && st->codecpar->extradata) {
3102  int extra_size = st->codecpar->extradata_size;
3103 
3104  /* Move the current stream extradata to the stream context one. */
3105  sc->extradata_size[pseudo_stream_id] = extra_size;
3106  sc->extradata[pseudo_stream_id] = st->codecpar->extradata;
3107  st->codecpar->extradata = NULL;
3108  st->codecpar->extradata_size = 0;
3109  }
3110  sc->stsd_count++;
3111  }
3112 
3113  if (pb->eof_reached) {
3114  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSD atom\n");
3115  return AVERROR_EOF;
3116  }
3117 
3118  return 0;
3119 }
3120 
3122 {
3123  AVStream *st;
3124  MOVStreamContext *sc;
3125  int ret, entries;
3126 
3127  if (c->fc->nb_streams < 1)
3128  return 0;
3129  st = c->fc->streams[c->fc->nb_streams - 1];
3130  sc = st->priv_data;
3131 
3132  sc->stsd_version = avio_r8(pb);
3133  avio_rb24(pb); /* flags */
3134  entries = avio_rb32(pb);
3135 
3136  /* Each entry contains a size (4 bytes) and format (4 bytes). */
3137  if (entries <= 0 || entries > atom.size / 8 || entries > 1024) {
3138  av_log(c->fc, AV_LOG_ERROR, "invalid STSD entries %d\n", entries);
3139  return AVERROR_INVALIDDATA;
3140  }
3141 
3142  if (sc->extradata) {
3143  av_log(c->fc, AV_LOG_ERROR,
3144  "Duplicate stsd found in this track.\n");
3145  return AVERROR_INVALIDDATA;
3146  }
3147 
3148  /* Prepare space for hosting multiple extradata. */
3149  sc->extradata = av_calloc(entries, sizeof(*sc->extradata));
3150  if (!sc->extradata)
3151  return AVERROR(ENOMEM);
3152 
3153  sc->extradata_size = av_calloc(entries, sizeof(*sc->extradata_size));
3154  if (!sc->extradata_size) {
3155  ret = AVERROR(ENOMEM);
3156  goto fail;
3157  }
3158 
3159  ret = ff_mov_read_stsd_entries(c, pb, entries);
3160  if (ret < 0)
3161  goto fail;
3162 
3163  /* Restore back the primary extradata. */
3164  av_freep(&st->codecpar->extradata);
3165  st->codecpar->extradata_size = sc->extradata_size[0];
3166  if (sc->extradata_size[0]) {
3168  if (!st->codecpar->extradata)
3169  return AVERROR(ENOMEM);
3170  memcpy(st->codecpar->extradata, sc->extradata[0], sc->extradata_size[0]);
3171  }
3172 
3173  return mov_finalize_stsd_codec(c, pb, st, sc);
3174 fail:
3175  if (sc->extradata) {
3176  int j;
3177  for (j = 0; j < sc->stsd_count; j++)
3178  av_freep(&sc->extradata[j]);
3179  }
3180 
3181  av_freep(&sc->extradata);
3182  av_freep(&sc->extradata_size);
3183  return ret;
3184 }
3185 
3187 {
3188  AVStream *st;
3189  MOVStreamContext *sc;
3190  unsigned int i, entries;
3191 
3192  if (c->trak_index < 0) {
3193  av_log(c->fc, AV_LOG_WARNING, "STSC outside TRAK\n");
3194  return 0;
3195  }
3196 
3197  if (c->fc->nb_streams < 1)
3198  return 0;
3199  st = c->fc->streams[c->fc->nb_streams-1];
3200  sc = st->priv_data;
3201 
3202  avio_r8(pb); /* version */
3203  avio_rb24(pb); /* flags */
3204 
3205  entries = avio_rb32(pb);
3206  if ((uint64_t)entries * 12 + 4 > atom.size)
3207  return AVERROR_INVALIDDATA;
3208 
3209  av_log(c->fc, AV_LOG_TRACE, "track[%u].stsc.entries = %u\n", c->fc->nb_streams - 1, entries);
3210 
3211  if (!entries)
3212  return 0;
3213  if (sc->stsc_data) {
3214  av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicated STSC atom\n");
3215  return 0;
3216  }
3217  av_free(sc->stsc_data);
3218  sc->stsc_count = 0;
3219  sc->stsc_data = av_malloc_array(entries, sizeof(*sc->stsc_data));
3220  if (!sc->stsc_data)
3221  return AVERROR(ENOMEM);
3222 
3223  for (i = 0; i < entries && !pb->eof_reached; i++) {
3224  sc->stsc_data[i].first = avio_rb32(pb);
3225  sc->stsc_data[i].count = avio_rb32(pb);
3226  sc->stsc_data[i].id = avio_rb32(pb);
3227  }
3228 
3229  sc->stsc_count = i;
3230  for (i = sc->stsc_count - 1; i < UINT_MAX; i--) {
3231  int64_t first_min = i + 1;
3232  if ((i+1 < sc->stsc_count && sc->stsc_data[i].first >= sc->stsc_data[i+1].first) ||
3233  (i > 0 && sc->stsc_data[i].first <= sc->stsc_data[i-1].first) ||
3234  sc->stsc_data[i].first < first_min ||
3235  sc->stsc_data[i].count < 1 ||
3236  sc->stsc_data[i].id < 1) {
3237  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);
3238  if (i+1 >= sc->stsc_count) {
3239  if (sc->stsc_data[i].count == 0 && i > 0) {
3240  sc->stsc_count --;
3241  continue;
3242  }
3243  sc->stsc_data[i].first = FFMAX(sc->stsc_data[i].first, first_min);
3244  if (i > 0 && sc->stsc_data[i].first <= sc->stsc_data[i-1].first)
3245  sc->stsc_data[i].first = FFMIN(sc->stsc_data[i-1].first + 1LL, INT_MAX);
3246  sc->stsc_data[i].count = FFMAX(sc->stsc_data[i].count, 1);
3247  sc->stsc_data[i].id = FFMAX(sc->stsc_data[i].id, 1);
3248  continue;
3249  }
3250  av_assert0(sc->stsc_data[i+1].first >= 2);
3251  // We replace this entry by the next valid
3252  sc->stsc_data[i].first = sc->stsc_data[i+1].first - 1;
3253  sc->stsc_data[i].count = sc->stsc_data[i+1].count;
3254  sc->stsc_data[i].id = sc->stsc_data[i+1].id;
3255  }
3256  }
3257 
3258  if (pb->eof_reached) {
3259  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSC atom\n");
3260  return AVERROR_EOF;
3261  }
3262 
3263  return 0;
3264 }
3265 
3266 static inline int mov_stsc_index_valid(unsigned int index, unsigned int count)
3267 {
3268  return index < count - 1;
3269 }
3270 
3271 /* Compute the samples value for the stsc entry at the given index. */
3272 static inline int64_t mov_get_stsc_samples(MOVStreamContext *sc, unsigned int index)
3273 {
3274  int chunk_count;
3275 
3277  chunk_count = sc->stsc_data[index + 1].first - sc->stsc_data[index].first;
3278  else {
3279  // Validation for stsc / stco happens earlier in mov_read_stsc + mov_read_trak.
3281  chunk_count = sc->chunk_count - (sc->stsc_data[index].first - 1);
3282  }
3283 
3284  return sc->stsc_data[index].count * (int64_t)chunk_count;
3285 }
3286 
3288 {
3289  AVStream *st;
3290  MOVStreamContext *sc;
3291  unsigned i, entries;
3292 
3293  if (c->trak_index < 0) {
3294  av_log(c->fc, AV_LOG_WARNING, "STPS outside TRAK\n");
3295  return 0;
3296  }
3297 
3298  if (c->fc->nb_streams < 1)
3299  return 0;
3300  st = c->fc->streams[c->fc->nb_streams-1];
3301  sc = st->priv_data;
3302 
3303  avio_rb32(pb); // version + flags
3304 
3305  entries = avio_rb32(pb);
3306  if (sc->stps_data)
3307  av_log(c->fc, AV_LOG_WARNING, "Duplicated STPS atom\n");
3308  av_free(sc->stps_data);
3309  sc->stps_count = 0;
3310  sc->stps_data = av_malloc_array(entries, sizeof(*sc->stps_data));
3311  if (!sc->stps_data)
3312  return AVERROR(ENOMEM);
3313 
3314  for (i = 0; i < entries && !pb->eof_reached; i++) {
3315  sc->stps_data[i] = avio_rb32(pb);
3316  }
3317 
3318  sc->stps_count = i;
3319 
3320  if (pb->eof_reached) {
3321  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STPS atom\n");
3322  return AVERROR_EOF;
3323  }
3324 
3325  return 0;
3326 }
3327 
3329 {
3330  AVStream *st;
3331  FFStream *sti;
3332  MOVStreamContext *sc;
3333  unsigned int i, entries;
3334 
3335  if (c->trak_index < 0) {
3336  av_log(c->fc, AV_LOG_WARNING, "STSS outside TRAK\n");
3337  return 0;
3338  }
3339 
3340  if (c->fc->nb_streams < 1)
3341  return 0;
3342  st = c->fc->streams[c->fc->nb_streams-1];
3343  sti = ffstream(st);
3344  sc = st->priv_data;
3345 
3346  avio_r8(pb); /* version */
3347  avio_rb24(pb); /* flags */
3348 
3349  entries = avio_rb32(pb);
3350 
3351  av_log(c->fc, AV_LOG_TRACE, "keyframe_count = %u\n", entries);
3352 
3353  if (!entries) {
3354  sc->keyframe_absent = 1;
3355  if (!sti->need_parsing && st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
3357  return 0;
3358  }
3359  if (sc->keyframes)
3360  av_log(c->fc, AV_LOG_WARNING, "Duplicated STSS atom\n");
3361  if (entries >= UINT_MAX / sizeof(int))
3362  return AVERROR_INVALIDDATA;
3363  av_freep(&sc->keyframes);
3364  sc->keyframe_count = 0;
3365  sc->keyframes = av_malloc_array(entries, sizeof(*sc->keyframes));
3366  if (!sc->keyframes)
3367  return AVERROR(ENOMEM);
3368 
3369  for (i = 0; i < entries && !pb->eof_reached; i++) {
3370  sc->keyframes[i] = avio_rb32(pb);
3371  }
3372 
3373  sc->keyframe_count = i;
3374 
3375  if (pb->eof_reached) {
3376  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSS atom\n");
3377  return AVERROR_EOF;
3378  }
3379 
3380  return 0;
3381 }
3382 
3384 {
3385  AVStream *st;
3386  MOVStreamContext *sc;
3387  unsigned int i, entries, sample_size, field_size, num_bytes;
3388  GetBitContext gb;
3389  unsigned char* buf;
3390  int ret;
3391 
3392  if (c->trak_index < 0) {
3393  av_log(c->fc, AV_LOG_WARNING, "STSZ outside TRAK\n");
3394  return 0;
3395  }
3396 
3397  if (c->fc->nb_streams < 1)
3398  return 0;
3399  st = c->fc->streams[c->fc->nb_streams-1];
3400  sc = st->priv_data;
3401 
3402  avio_r8(pb); /* version */
3403  avio_rb24(pb); /* flags */
3404 
3405  if (atom.type == MKTAG('s','t','s','z')) {
3406  sample_size = avio_rb32(pb);
3407  if (!sc->sample_size) /* do not overwrite value computed in stsd */
3408  sc->sample_size = sample_size;
3409  sc->stsz_sample_size = sample_size;
3410  field_size = 32;
3411  } else {
3412  sample_size = 0;
3413  avio_rb24(pb); /* reserved */
3414  field_size = avio_r8(pb);
3415  }
3416  entries = avio_rb32(pb);
3417 
3418  av_log(c->fc, AV_LOG_TRACE, "sample_size = %u sample_count = %u\n", sc->sample_size, entries);
3419 
3420  sc->sample_count = entries;
3421  if (sample_size)
3422  return 0;
3423 
3424  if (field_size != 4 && field_size != 8 && field_size != 16 && field_size != 32) {
3425  av_log(c->fc, AV_LOG_ERROR, "Invalid sample field size %u\n", field_size);
3426  return AVERROR_INVALIDDATA;
3427  }
3428 
3429  if (!entries)
3430  return 0;
3431  if (entries >= (INT_MAX - 4 - 8 * AV_INPUT_BUFFER_PADDING_SIZE) / field_size)
3432  return AVERROR_INVALIDDATA;
3433  if (sc->sample_sizes)
3434  av_log(c->fc, AV_LOG_WARNING, "Duplicated STSZ atom\n");
3435  av_free(sc->sample_sizes);
3436  sc->sample_count = 0;
3437  sc->sample_sizes = av_malloc_array(entries, sizeof(*sc->sample_sizes));
3438  if (!sc->sample_sizes)
3439  return AVERROR(ENOMEM);
3440 
3441  num_bytes = (entries*field_size+4)>>3;
3442 
3443  buf = av_malloc(num_bytes+AV_INPUT_BUFFER_PADDING_SIZE);
3444  if (!buf) {
3445  av_freep(&sc->sample_sizes);
3446  return AVERROR(ENOMEM);
3447  }
3448 
3449  ret = ffio_read_size(pb, buf, num_bytes);
3450  if (ret < 0) {
3451  av_freep(&sc->sample_sizes);
3452  av_free(buf);
3453  av_log(c->fc, AV_LOG_WARNING, "STSZ atom truncated\n");
3454  return 0;
3455  }
3456 
3457  init_get_bits(&gb, buf, 8*num_bytes);
3458 
3459  for (i = 0; i < entries; i++) {
3460  sc->sample_sizes[i] = get_bits_long(&gb, field_size);
3461  if (sc->sample_sizes[i] > INT64_MAX - sc->data_size) {
3462  av_free(buf);
3463  av_log(c->fc, AV_LOG_ERROR, "Sample size overflow in STSZ\n");
3464  return AVERROR_INVALIDDATA;
3465  }
3466  sc->data_size += sc->sample_sizes[i];
3467  }
3468 
3469  sc->sample_count = i;
3470 
3471  av_free(buf);
3472 
3473  return 0;
3474 }
3475 
3477 {
3478  AVStream *st;
3479  MOVStreamContext *sc;
3480  unsigned int i, entries;
3481  int64_t duration = 0;
3482  int64_t total_sample_count = 0;
3483  int64_t current_dts = 0;
3484  int64_t corrected_dts = 0;
3485 
3486  if (c->trak_index < 0) {
3487  av_log(c->fc, AV_LOG_WARNING, "STTS outside TRAK\n");
3488  return 0;
3489  }
3490 
3491  if (c->fc->nb_streams < 1)
3492  return 0;
3493  st = c->fc->streams[c->fc->nb_streams-1];
3494  sc = st->priv_data;
3495 
3496  avio_r8(pb); /* version */
3497  avio_rb24(pb); /* flags */
3498  entries = avio_rb32(pb);
3499 
3500  av_log(c->fc, AV_LOG_TRACE, "track[%u].stts.entries = %u\n",
3501  c->fc->nb_streams-1, entries);
3502 
3503  if (sc->stts_data)
3504  av_log(c->fc, AV_LOG_WARNING, "Duplicated STTS atom\n");
3505  av_freep(&sc->stts_data);
3506  sc->stts_count = 0;
3507  if (entries >= INT_MAX / sizeof(*sc->stts_data))
3508  return AVERROR(ENOMEM);
3509 
3510  for (i = 0; i < entries && !pb->eof_reached; i++) {
3511  unsigned int sample_duration;
3512  unsigned int sample_count;
3513  unsigned int min_entries = FFMIN(FFMAX(i + 1, 1024 * 1024), entries);
3514  MOVStts *stts_data = av_fast_realloc(sc->stts_data, &sc->stts_allocated_size,
3515  min_entries * sizeof(*sc->stts_data));
3516  if (!stts_data) {
3517  av_freep(&sc->stts_data);
3518  sc->stts_count = 0;
3519  return AVERROR(ENOMEM);
3520  }
3521  sc->stts_count = min_entries;
3522  sc->stts_data = stts_data;
3523 
3524  sample_count = avio_rb32(pb);
3525  sample_duration = avio_rb32(pb);
3526 
3527  sc->stts_data[i].count= sample_count;
3528  sc->stts_data[i].duration= sample_duration;
3529 
3530  av_log(c->fc, AV_LOG_TRACE, "sample_count=%u, sample_duration=%u\n",
3531  sample_count, sample_duration);
3532 
3533  /* STTS sample offsets are uint32 but some files store it as int32
3534  * with negative values used to correct DTS delays.
3535  There may be abnormally large values as well. */
3536  if (sample_duration > c->max_stts_delta) {
3537  // assume high delta is a correction if negative when cast as int32
3538  int32_t delta_magnitude = (int32_t)sample_duration;
3539  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",
3540  sample_duration, i, sample_count, st->index);
3541  sc->stts_data[i].duration = 1;
3542  corrected_dts = av_sat_add64(corrected_dts, (delta_magnitude < 0 ? (int64_t)delta_magnitude : 1) * sample_count);
3543  } else {
3544  corrected_dts += sample_duration * (uint64_t)sample_count;
3545  }
3546 
3547  current_dts += sc->stts_data[i].duration * (uint64_t)sample_count;
3548 
3549  if (current_dts > corrected_dts) {
3550  int64_t drift = av_sat_sub64(current_dts, corrected_dts) / FFMAX(sample_count, 1);
3551  uint32_t correction = (sc->stts_data[i].duration > drift) ? drift : sc->stts_data[i].duration - 1;
3552  current_dts -= correction * (uint64_t)sample_count;
3553  sc->stts_data[i].duration -= correction;
3554  }
3555 
3556  duration+=(int64_t)sc->stts_data[i].duration*(uint64_t)sc->stts_data[i].count;
3557  total_sample_count+=sc->stts_data[i].count;
3558  }
3559 
3560  sc->stts_count = i;
3561 
3562  if (duration > 0 &&
3563  duration <= INT64_MAX - sc->duration_for_fps &&
3564  total_sample_count <= INT_MAX - sc->nb_frames_for_fps) {
3565  sc->duration_for_fps += duration;
3566  sc->nb_frames_for_fps += total_sample_count;
3567  }
3568 
3569  if (pb->eof_reached) {
3570  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STTS atom\n");
3571  return AVERROR_EOF;
3572  }
3573 
3574  st->nb_frames= total_sample_count;
3575  if (duration)
3576  st->duration= FFMIN(st->duration, duration);
3577 
3578  // All samples have zero duration. They have higher chance be chose by
3579  // mov_find_next_sample, which leads to seek again and again.
3580  //
3581  // It's AVERROR_INVALIDDATA actually, but such files exist in the wild.
3582  // So only mark data stream as discarded for safety.
3583  if (!duration && sc->stts_count &&
3585  av_log(c->fc, AV_LOG_WARNING,
3586  "All samples in data stream index:id [%d:%d] have zero "
3587  "duration, stream set to be discarded by default. Override "
3588  "using AVStream->discard or -discard for ffmpeg command.\n",
3589  st->index, sc->id);
3590  st->discard = AVDISCARD_ALL;
3591  }
3592  sc->track_end = duration;
3593  return 0;
3594 }
3595 
3597 {
3598  AVStream *st;
3599  MOVStreamContext *sc;
3600  int64_t i, entries;
3601 
3602  if (c->fc->nb_streams < 1)
3603  return 0;
3604  st = c->fc->streams[c->fc->nb_streams - 1];
3605  sc = st->priv_data;
3606 
3607  avio_r8(pb); /* version */
3608  avio_rb24(pb); /* flags */
3609  entries = atom.size - 4;
3610 
3611  av_log(c->fc, AV_LOG_TRACE, "track[%u].sdtp.entries = %" PRId64 "\n",
3612  c->fc->nb_streams - 1, entries);
3613 
3614  if (sc->sdtp_data)
3615  av_log(c->fc, AV_LOG_WARNING, "Duplicated SDTP atom\n");
3616  av_freep(&sc->sdtp_data);
3617  sc->sdtp_count = 0;
3618 
3619  sc->sdtp_data = av_malloc(entries);
3620  if (!sc->sdtp_data)
3621  return AVERROR(ENOMEM);
3622 
3623  for (i = 0; i < entries && !pb->eof_reached; i++)
3624  sc->sdtp_data[i] = avio_r8(pb);
3625  sc->sdtp_count = i;
3626 
3627  return 0;
3628 }
3629 
3630 static void mov_update_dts_shift(MOVStreamContext *sc, int duration, void *logctx)
3631 {
3632  if (duration < 0) {
3633  if (duration == INT_MIN) {
3634  av_log(logctx, AV_LOG_WARNING, "mov_update_dts_shift(): dts_shift set to %d\n", INT_MAX);
3635  duration++;
3636  }
3637  sc->dts_shift = FFMAX(sc->dts_shift, -duration);
3638  }
3639 }
3640 
3642 {
3643  AVStream *st;
3644  MOVStreamContext *sc;
3645  unsigned int i, entries, ctts_count = 0;
3646 
3647  if (c->trak_index < 0) {
3648  av_log(c->fc, AV_LOG_WARNING, "CTTS outside TRAK\n");
3649  return 0;
3650  }
3651 
3652  if (c->fc->nb_streams < 1)
3653  return 0;
3654  st = c->fc->streams[c->fc->nb_streams-1];
3655  sc = st->priv_data;
3656 
3657  avio_r8(pb); /* version */
3658  avio_rb24(pb); /* flags */
3659  entries = avio_rb32(pb);
3660 
3661  av_log(c->fc, AV_LOG_TRACE, "track[%u].ctts.entries = %u\n", c->fc->nb_streams - 1, entries);
3662 
3663  if (!entries)
3664  return 0;
3665  if (entries >= UINT_MAX / sizeof(*sc->ctts_data))
3666  return AVERROR_INVALIDDATA;
3667  av_freep(&sc->ctts_data);
3668  sc->ctts_data = av_fast_realloc(NULL, &sc->ctts_allocated_size, entries * sizeof(*sc->ctts_data));
3669  if (!sc->ctts_data)
3670  return AVERROR(ENOMEM);
3671 
3672  for (i = 0; i < entries && !pb->eof_reached; i++) {
3673  MOVCtts *ctts_data;
3674  const size_t min_size_needed = (ctts_count + 1) * sizeof(MOVCtts);
3675  const size_t requested_size =
3676  min_size_needed > sc->ctts_allocated_size ?
3677  FFMAX(min_size_needed, 2 * sc->ctts_allocated_size) :
3678  min_size_needed;
3679  int count = avio_rb32(pb);
3680  int duration = avio_rb32(pb);
3681 
3682  if (count <= 0) {
3683  av_log(c->fc, AV_LOG_TRACE,
3684  "ignoring CTTS entry with count=%d duration=%d\n",
3685  count, duration);
3686  continue;
3687  }
3688 
3689  if (ctts_count >= UINT_MAX / sizeof(MOVCtts) - 1)
3690  return AVERROR(ENOMEM);
3691 
3692  ctts_data = av_fast_realloc(sc->ctts_data, &sc->ctts_allocated_size, requested_size);
3693 
3694  if (!ctts_data)
3695  return AVERROR(ENOMEM);
3696 
3697  sc->ctts_data = ctts_data;
3698 
3699  ctts_data[ctts_count].count = count;
3700  ctts_data[ctts_count].offset = duration;
3701  ctts_count++;
3702 
3703  av_log(c->fc, AV_LOG_TRACE, "count=%d, duration=%d\n",
3704  count, duration);
3705 
3706  if (i+2<entries)
3707  mov_update_dts_shift(sc, duration, c->fc);
3708  }
3709 
3710  sc->ctts_count = ctts_count;
3711 
3712  if (pb->eof_reached) {
3713  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted CTTS atom\n");
3714  return AVERROR_EOF;
3715  }
3716 
3717  av_log(c->fc, AV_LOG_TRACE, "dts shift %d\n", sc->dts_shift);
3718 
3719  return 0;
3720 }
3721 
3723 {
3724  AVStream *st;
3725  MOVStreamContext *sc;
3726  uint8_t version;
3727  uint32_t grouping_type;
3728  uint32_t default_length;
3729  av_unused uint32_t default_group_description_index;
3730  uint32_t entry_count;
3731 
3732  if (c->fc->nb_streams < 1)
3733  return 0;
3734  st = c->fc->streams[c->fc->nb_streams - 1];
3735  sc = st->priv_data;
3736 
3737  version = avio_r8(pb); /* version */
3738  avio_rb24(pb); /* flags */
3739  grouping_type = avio_rl32(pb);
3740 
3741  /*
3742  * This function only supports "sync" boxes, but the code is able to parse
3743  * other boxes (such as "tscl", "tsas" and "stsa")
3744  */
3745  if (grouping_type != MKTAG('s','y','n','c'))
3746  return 0;
3747 
3748  default_length = version >= 1 ? avio_rb32(pb) : 0;
3749  default_group_description_index = version >= 2 ? avio_rb32(pb) : 0;
3750  entry_count = avio_rb32(pb);
3751 
3752  av_freep(&sc->sgpd_sync);
3753  sc->sgpd_sync_count = entry_count;
3754  sc->sgpd_sync = av_calloc(entry_count, sizeof(*sc->sgpd_sync));
3755  if (!sc->sgpd_sync)
3756  return AVERROR(ENOMEM);
3757 
3758  for (uint32_t i = 0; i < entry_count && !pb->eof_reached; i++) {
3759  uint32_t description_length = default_length;
3760  if (version >= 1 && default_length == 0)
3761  description_length = avio_rb32(pb);
3762  if (grouping_type == MKTAG('s','y','n','c')) {
3763  const uint8_t nal_unit_type = avio_r8(pb) & 0x3f;
3764  sc->sgpd_sync[i] = nal_unit_type;
3765  description_length -= 1;
3766  }
3767  avio_skip(pb, description_length);
3768  }
3769 
3770  if (pb->eof_reached) {
3771  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted SGPD atom\n");
3772  return AVERROR_EOF;
3773  }
3774 
3775  return 0;
3776 }
3777 
3779 {
3780  AVStream *st;
3781  MOVStreamContext *sc;
3782  unsigned int i, entries;
3783  uint8_t version;
3784  uint32_t grouping_type;
3785  MOVSbgp *table, **tablep;
3786  int *table_count;
3787 
3788  if (c->fc->nb_streams < 1)
3789  return 0;
3790  st = c->fc->streams[c->fc->nb_streams-1];
3791  sc = st->priv_data;
3792 
3793  version = avio_r8(pb); /* version */
3794  avio_rb24(pb); /* flags */
3795  grouping_type = avio_rl32(pb);
3796 
3797  if (grouping_type == MKTAG('r','a','p',' ')) {
3798  tablep = &sc->rap_group;
3799  table_count = &sc->rap_group_count;
3800  } else if (grouping_type == MKTAG('s','y','n','c')) {
3801  tablep = &sc->sync_group;
3802  table_count = &sc->sync_group_count;
3803  } else {
3804  return 0;
3805  }
3806 
3807  if (version == 1)
3808  avio_rb32(pb); /* grouping_type_parameter */
3809 
3810  entries = avio_rb32(pb);
3811  if (!entries)
3812  return 0;
3813  if (*tablep)
3814  av_log(c->fc, AV_LOG_WARNING, "Duplicated SBGP %s atom\n", av_fourcc2str(grouping_type));
3815  av_freep(tablep);
3816  table = av_malloc_array(entries, sizeof(*table));
3817  if (!table)
3818  return AVERROR(ENOMEM);
3819  *tablep = table;
3820 
3821  for (i = 0; i < entries && !pb->eof_reached; i++) {
3822  table[i].count = avio_rb32(pb); /* sample_count */
3823  table[i].index = avio_rb32(pb); /* group_description_index */
3824  }
3825 
3826  *table_count = i;
3827 
3828  if (pb->eof_reached) {
3829  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted SBGP atom\n");
3830  return AVERROR_EOF;
3831  }
3832 
3833  return 0;
3834 }
3835 
3836 /**
3837  * Get ith edit list entry (media time, duration).
3838  */
3840  const MOVStreamContext *msc,
3841  unsigned int edit_list_index,
3842  int64_t *edit_list_media_time,
3843  int64_t *edit_list_duration,
3844  int64_t global_timescale)
3845 {
3846  if (edit_list_index == msc->elst_count) {
3847  return 0;
3848  }
3849  *edit_list_media_time = msc->elst_data[edit_list_index].time;
3850  *edit_list_duration = msc->elst_data[edit_list_index].duration;
3851 
3852  /* duration is in global timescale units;convert to msc timescale */
3853  if (global_timescale == 0) {
3854  avpriv_request_sample(mov->fc, "Support for mvhd.timescale = 0 with editlists");
3855  return 0;
3856  }
3857  *edit_list_duration = av_rescale(*edit_list_duration, msc->time_scale,
3858  global_timescale);
3859 
3860  if (*edit_list_duration + (uint64_t)*edit_list_media_time > INT64_MAX)
3861  *edit_list_duration = 0;
3862 
3863  return 1;
3864 }
3865 
3866 /**
3867  * Find the closest previous frame to the timestamp_pts, in e_old index
3868  * entries. Searching for just any frame / just key frames can be controlled by
3869  * last argument 'flag'.
3870  * Note that if ctts_data is not NULL, we will always search for a key frame
3871  * irrespective of the value of 'flag'. If we don't find any keyframe, we will
3872  * return the first frame of the video.
3873  *
3874  * Here the timestamp_pts is considered to be a presentation timestamp and
3875  * the timestamp of index entries are considered to be decoding timestamps.
3876  *
3877  * Returns 0 if successful in finding a frame, else returns -1.
3878  * Places the found index corresponding output arg.
3879  *
3880  * If ctts_old is not NULL, then refines the searched entry by searching
3881  * backwards from the found timestamp, to find the frame with correct PTS.
3882  *
3883  * Places the found ctts_index and ctts_sample in corresponding output args.
3884  */
3886  AVIndexEntry *e_old,
3887  int nb_old,
3888  MOVTimeToSample *tts_data,
3889  int64_t tts_count,
3890  int64_t timestamp_pts,
3891  int flag,
3892  int64_t* index,
3893  int64_t* tts_index,
3894  int64_t* tts_sample)
3895 {
3896  MOVStreamContext *msc = st->priv_data;
3897  FFStream *const sti = ffstream(st);
3898  AVIndexEntry *e_keep = sti->index_entries;
3899  int nb_keep = sti->nb_index_entries;
3900  int64_t i = 0;
3901 
3902  av_assert0(index);
3903 
3904  // If dts_shift > 0, then all the index timestamps will have to be offset by
3905  // at least dts_shift amount to obtain PTS.
3906  // Hence we decrement the searched timestamp_pts by dts_shift to find the closest index element.
3907  if (msc->dts_shift > 0) {
3908  timestamp_pts -= msc->dts_shift;
3909  }
3910 
3911  sti->index_entries = e_old;
3912  sti->nb_index_entries = nb_old;
3913  *index = av_index_search_timestamp(st, timestamp_pts, flag | AVSEEK_FLAG_BACKWARD);
3914 
3915  // Keep going backwards in the index entries until the timestamp is the same.
3916  if (*index >= 0) {
3917  for (i = *index; i > 0 && e_old[i].timestamp == e_old[i - 1].timestamp;
3918  i--) {
3919  if ((flag & AVSEEK_FLAG_ANY) ||
3920  (e_old[i - 1].flags & AVINDEX_KEYFRAME)) {
3921  *index = i - 1;
3922  }
3923  }
3924  }
3925 
3926  // If we have CTTS then refine the search, by searching backwards over PTS
3927  // computed by adding corresponding CTTS durations to index timestamps.
3928  if (msc->ctts_count && *index >= 0) {
3929  av_assert0(tts_index);
3930  av_assert0(tts_sample);
3931  // Find out the ctts_index for the found frame.
3932  *tts_index = 0;
3933  *tts_sample = 0;
3934  for (int64_t index_tts_count = 0; index_tts_count < *index; index_tts_count++) {
3935  if (*tts_index < tts_count) {
3936  (*tts_sample)++;
3937  if (tts_data[*tts_index].count == *tts_sample) {
3938  (*tts_index)++;
3939  *tts_sample = 0;
3940  }
3941  }
3942  }
3943 
3944  while (*index >= 0 && (*tts_index) >= 0 && (*tts_index) < tts_count) {
3945  // Find a "key frame" with PTS <= timestamp_pts (So that we can decode B-frames correctly).
3946  // No need to add dts_shift to the timestamp here becase timestamp_pts has already been
3947  // compensated by dts_shift above.
3948  if ((e_old[*index].timestamp + tts_data[*tts_index].offset) <= timestamp_pts &&
3949  (e_old[*index].flags & AVINDEX_KEYFRAME)) {
3950  break;
3951  }
3952 
3953  (*index)--;
3954  if (*tts_sample == 0) {
3955  (*tts_index)--;
3956  if (*tts_index >= 0)
3957  *tts_sample = tts_data[*tts_index].count - 1;
3958  } else {
3959  (*tts_sample)--;
3960  }
3961  }
3962  }
3963 
3964  /* restore AVStream state*/
3965  sti->index_entries = e_keep;
3966  sti->nb_index_entries = nb_keep;
3967  return *index >= 0 ? 0 : -1;
3968 }
3969 
3970 /**
3971  * Add index entry with the given values, to the end of ffstream(st)->index_entries.
3972  * Returns the new size ffstream(st)->index_entries if successful, else returns -1.
3973  *
3974  * This function is similar to ff_add_index_entry in libavformat/utils.c
3975  * except that here we are always unconditionally adding an index entry to
3976  * the end, instead of searching the entries list and skipping the add if
3977  * there is an existing entry with the same timestamp.
3978  * This is needed because the mov_fix_index calls this func with the same
3979  * unincremented timestamp for successive discarded frames.
3980  */
3982  int size, int distance, int flags)
3983 {
3984  FFStream *const sti = ffstream(st);
3985  AVIndexEntry *entries, *ie;
3986  int64_t index = -1;
3987  const size_t min_size_needed = (sti->nb_index_entries + 1) * sizeof(AVIndexEntry);
3988 
3989  // Double the allocation each time, to lower memory fragmentation.
3990  // Another difference from ff_add_index_entry function.
3991  const size_t requested_size =
3992  min_size_needed > sti->index_entries_allocated_size ?
3993  FFMAX(min_size_needed, 2 * sti->index_entries_allocated_size) :
3994  min_size_needed;
3995 
3996  if (sti->nb_index_entries + 1U >= UINT_MAX / sizeof(AVIndexEntry))
3997  return -1;
3998 
3999  entries = av_fast_realloc(sti->index_entries,
4001  requested_size);
4002  if (!entries)
4003  return -1;
4004 
4005  sti->index_entries = entries;
4006 
4007  index = sti->nb_index_entries++;
4008  ie= &entries[index];
4009 
4010  ie->pos = pos;
4011  ie->timestamp = timestamp;
4012  ie->min_distance= distance;
4013  ie->size= size;
4014  ie->flags = flags;
4015  return index;
4016 }
4017 
4018 /**
4019  * Rewrite timestamps of index entries in the range [end_index - frame_duration_buffer_size, end_index)
4020  * by subtracting end_ts successively by the amounts given in frame_duration_buffer.
4021  */
4022 static void fix_index_entry_timestamps(AVStream* st, int end_index, int64_t end_ts,
4023  int64_t* frame_duration_buffer,
4024  int frame_duration_buffer_size) {
4025  FFStream *const sti = ffstream(st);
4026  int i = 0;
4027  av_assert0(end_index >= 0 && end_index <= sti->nb_index_entries);
4028  for (i = 0; i < frame_duration_buffer_size; i++) {
4029  end_ts -= frame_duration_buffer[frame_duration_buffer_size - 1 - i];
4030  sti->index_entries[end_index - 1 - i].timestamp = end_ts;
4031  }
4032 }
4033 
4034 static int add_tts_entry(MOVTimeToSample **tts_data, unsigned int *tts_count, unsigned int *allocated_size,
4035  int count, int offset, unsigned int duration)
4036 {
4037  MOVTimeToSample *tts_buf_new;
4038  const size_t min_size_needed = (*tts_count + 1) * sizeof(MOVTimeToSample);
4039  const size_t requested_size =
4040  min_size_needed > *allocated_size ?
4041  FFMAX(min_size_needed, 2 * (*allocated_size)) :
4042  min_size_needed;
4043 
4044  if ((unsigned)(*tts_count) >= UINT_MAX / sizeof(MOVTimeToSample) - 1)
4045  return -1;
4046 
4047  tts_buf_new = av_fast_realloc(*tts_data, allocated_size, requested_size);
4048 
4049  if (!tts_buf_new)
4050  return -1;
4051 
4052  *tts_data = tts_buf_new;
4053 
4054  tts_buf_new[*tts_count].count = count;
4055  tts_buf_new[*tts_count].offset = offset;
4056  tts_buf_new[*tts_count].duration = duration;
4057 
4058  *tts_count = (*tts_count) + 1;
4059  return 0;
4060 }
4061 
4062 #define MAX_REORDER_DELAY 16
4064 {
4065  MOVStreamContext *msc = st->priv_data;
4066  FFStream *const sti = ffstream(st);
4067  int ctts_ind = 0;
4068  int ctts_sample = 0;
4069  int64_t pts_buf[MAX_REORDER_DELAY + 1]; // Circular buffer to sort pts.
4070  int buf_start = 0;
4071  int j, r, num_swaps;
4072 
4073  for (j = 0; j < MAX_REORDER_DELAY + 1; j++)
4074  pts_buf[j] = INT64_MIN;
4075 
4076  if (st->codecpar->video_delay <= 0 && msc->ctts_count &&
4078  st->codecpar->video_delay = 0;
4079  for (int ind = 0; ind < sti->nb_index_entries && ctts_ind < msc->tts_count; ++ind) {
4080  // Point j to the last elem of the buffer and insert the current pts there.
4081  j = buf_start;
4082  buf_start = (buf_start + 1);
4083  if (buf_start == MAX_REORDER_DELAY + 1)
4084  buf_start = 0;
4085 
4086  pts_buf[j] = sti->index_entries[ind].timestamp + msc->tts_data[ctts_ind].offset;
4087 
4088  // The timestamps that are already in the sorted buffer, and are greater than the
4089  // current pts, are exactly the timestamps that need to be buffered to output PTS
4090  // in correct sorted order.
4091  // Hence the video delay (which is the buffer size used to sort DTS and output PTS),
4092  // can be computed as the maximum no. of swaps any particular timestamp needs to
4093  // go through, to keep this buffer in sorted order.
4094  num_swaps = 0;
4095  while (j != buf_start) {
4096  r = j - 1;
4097  if (r < 0) r = MAX_REORDER_DELAY;
4098  if (pts_buf[j] < pts_buf[r]) {
4099  FFSWAP(int64_t, pts_buf[j], pts_buf[r]);
4100  ++num_swaps;
4101  } else {
4102  break;
4103  }
4104  j = r;
4105  }
4106  st->codecpar->video_delay = FFMAX(st->codecpar->video_delay, num_swaps);
4107 
4108  ctts_sample++;
4109  if (ctts_sample == msc->tts_data[ctts_ind].count) {
4110  ctts_ind++;
4111  ctts_sample = 0;
4112  }
4113  }
4114  av_log(c->fc, AV_LOG_DEBUG, "Setting codecpar->delay to %d for stream st: %d\n",
4115  st->codecpar->video_delay, st->index);
4116  }
4117 }
4118 
4120 {
4121  sc->current_sample++;
4122  sc->current_index++;
4123  if (sc->index_ranges &&
4124  sc->current_index >= sc->current_index_range->end &&
4125  sc->current_index_range->end) {
4126  sc->current_index_range++;
4128  }
4129 }
4130 
4132 {
4133  sc->current_sample--;
4134  sc->current_index--;
4135  if (sc->index_ranges &&
4137  sc->current_index_range > sc->index_ranges) {
4138  sc->current_index_range--;
4139  sc->current_index = sc->current_index_range->end - 1;
4140  }
4141 }
4142 
4143 static void mov_current_sample_set(MOVStreamContext *sc, int current_sample)
4144 {
4145  int64_t range_size;
4146 
4147  sc->current_sample = current_sample;
4148  sc->current_index = current_sample;
4149  if (!sc->index_ranges) {
4150  return;
4151  }
4152 
4153  for (sc->current_index_range = sc->index_ranges;
4154  sc->current_index_range->end;
4155  sc->current_index_range++) {
4156  range_size = sc->current_index_range->end - sc->current_index_range->start;
4157  if (range_size > current_sample) {
4158  sc->current_index = sc->current_index_range->start + current_sample;
4159  break;
4160  }
4161  current_sample -= range_size;
4162  }
4163 }
4164 
4165 /**
4166  * Fix ffstream(st)->index_entries, so that it contains only the entries (and the entries
4167  * which are needed to decode them) that fall in the edit list time ranges.
4168  * Also fixes the timestamps of the index entries to match the timeline
4169  * specified the edit lists.
4170  */
4171 static void mov_fix_index(MOVContext *mov, AVStream *st)
4172 {
4173  MOVStreamContext *msc = st->priv_data;
4174  FFStream *const sti = ffstream(st);
4175  AVIndexEntry *e_old = sti->index_entries;
4176  int nb_old = sti->nb_index_entries;
4177  const AVIndexEntry *e_old_end = e_old + nb_old;
4178  const AVIndexEntry *current = NULL;
4179  MOVTimeToSample *tts_data_old = msc->tts_data;
4180  int64_t tts_index_old = 0;
4181  int64_t tts_sample_old = 0;
4182  int64_t tts_count_old = msc->tts_count;
4183  int64_t edit_list_media_time = 0;
4184  int64_t edit_list_duration = 0;
4185  int64_t frame_duration = 0;
4186  int64_t edit_list_dts_counter = 0;
4187  int64_t edit_list_dts_entry_end = 0;
4188  int64_t edit_list_start_tts_sample = 0;
4189  int64_t curr_cts;
4190  int64_t curr_ctts = 0;
4191  int64_t empty_edits_sum_duration = 0;
4192  int64_t edit_list_index = 0;
4193  int64_t index;
4194  int flags;
4195  int64_t start_dts = 0;
4196  int64_t edit_list_start_encountered = 0;
4197  int64_t search_timestamp = 0;
4198  int64_t* frame_duration_buffer = NULL;
4199  int num_discarded_begin = 0;
4200  int first_non_zero_audio_edit = -1;
4201  int packet_skip_samples = 0;
4202  MOVIndexRange *current_index_range = NULL;
4203  int found_keyframe_after_edit = 0;
4204  int found_non_empty_edit = 0;
4205 
4206  if (!msc->elst_data || msc->elst_count <= 0 || nb_old <= 0) {
4207  return;
4208  }
4209 
4210  // allocate the index ranges array
4211  msc->index_ranges = av_malloc_array(msc->elst_count + 1,
4212  sizeof(msc->index_ranges[0]));
4213  if (!msc->index_ranges) {
4214  av_log(mov->fc, AV_LOG_ERROR, "Cannot allocate index ranges buffer\n");
4215  return;
4216  }
4217  msc->current_index_range = msc->index_ranges;
4218 
4219  // Clean AVStream from traces of old index
4220  sti->index_entries = NULL;
4222  sti->nb_index_entries = 0;
4223 
4224  // Clean time to sample fields of MOVStreamContext
4225  msc->tts_data = NULL;
4226  msc->tts_count = 0;
4227  msc->tts_index = 0;
4228  msc->tts_sample = 0;
4229  msc->tts_allocated_size = 0;
4230 
4231  // Reinitialize min_corrected_pts so that it can be computed again.
4232  msc->min_corrected_pts = -1;
4233 
4234  // If the dts_shift is positive (in case of negative ctts values in mov),
4235  // then negate the DTS by dts_shift
4236  if (msc->dts_shift > 0) {
4237  edit_list_dts_entry_end -= msc->dts_shift;
4238  av_log(mov->fc, AV_LOG_DEBUG, "Shifting DTS by %d because of negative CTTS.\n", msc->dts_shift);
4239  }
4240 
4241  start_dts = edit_list_dts_entry_end;
4242 
4243  while (get_edit_list_entry(mov, msc, edit_list_index, &edit_list_media_time,
4244  &edit_list_duration, mov->time_scale)) {
4245  av_log(mov->fc, AV_LOG_DEBUG, "Processing st: %d, edit list %"PRId64" - media time: %"PRId64", duration: %"PRId64"\n",
4246  st->index, edit_list_index, edit_list_media_time, edit_list_duration);
4247  edit_list_index++;
4248  edit_list_dts_counter = edit_list_dts_entry_end;
4249  edit_list_dts_entry_end += edit_list_duration;
4250  num_discarded_begin = 0;
4251  if (!found_non_empty_edit && edit_list_media_time == -1) {
4252  empty_edits_sum_duration += edit_list_duration;
4253  continue;
4254  }
4255  found_non_empty_edit = 1;
4256 
4257  // If we encounter a non-negative edit list reset the skip_samples/start_pad fields and set them
4258  // according to the edit list below.
4259  if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
4260  if (first_non_zero_audio_edit < 0) {
4261  first_non_zero_audio_edit = 1;
4262  } else {
4263  first_non_zero_audio_edit = 0;
4264  }
4265 
4266  if (first_non_zero_audio_edit > 0)
4267  sti->skip_samples = msc->start_pad = 0;
4268  }
4269 
4270  // While reordering frame index according to edit list we must handle properly
4271  // the scenario when edit list entry starts from none key frame.
4272  // We find closest previous key frame and preserve it and consequent frames in index.
4273  // All frames which are outside edit list entry time boundaries will be dropped after decoding.
4274  search_timestamp = edit_list_media_time;
4275  if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
4276  // Audio decoders like AAC need need a decoder delay samples previous to the current sample,
4277  // to correctly decode this frame. Hence for audio we seek to a frame 1 sec. before the
4278  // edit_list_media_time to cover the decoder delay.
4279  search_timestamp = FFMAX(search_timestamp - msc->time_scale, e_old[0].timestamp);
4280  }
4281 
4282  if (find_prev_closest_index(st, e_old, nb_old, tts_data_old, tts_count_old, search_timestamp, 0,
4283  &index, &tts_index_old, &tts_sample_old) < 0) {
4284  av_log(mov->fc, AV_LOG_WARNING,
4285  "st: %d edit list: %"PRId64" Missing key frame while searching for timestamp: %"PRId64"\n",
4286  st->index, edit_list_index, search_timestamp);
4287  if (find_prev_closest_index(st, e_old, nb_old, tts_data_old, tts_count_old, search_timestamp, AVSEEK_FLAG_ANY,
4288  &index, &tts_index_old, &tts_sample_old) < 0) {
4289  av_log(mov->fc, AV_LOG_WARNING,
4290  "st: %d edit list %"PRId64" Cannot find an index entry before timestamp: %"PRId64".\n",
4291  st->index, edit_list_index, search_timestamp);
4292  index = 0;
4293  tts_index_old = 0;
4294  tts_sample_old = 0;
4295  }
4296  }
4297  current = e_old + index;
4298  edit_list_start_tts_sample = tts_sample_old;
4299 
4300  // Iterate over index and arrange it according to edit list
4301  edit_list_start_encountered = 0;
4302  found_keyframe_after_edit = 0;
4303  for (; current < e_old_end; current++, index++) {
4304  // check if frame outside edit list mark it for discard
4305  frame_duration = (current + 1 < e_old_end) ?
4306  ((current + 1)->timestamp - current->timestamp) : edit_list_duration;
4307 
4308  flags = current->flags;
4309 
4310  // frames (pts) before or after edit list
4311  curr_cts = current->timestamp + msc->dts_shift;
4312  curr_ctts = 0;
4313 
4314  if (tts_data_old && tts_index_old < tts_count_old) {
4315  curr_ctts = tts_data_old[tts_index_old].offset;
4316  av_log(mov->fc, AV_LOG_TRACE, "stts: %"PRId64" ctts: %"PRId64", tts_index: %"PRId64", tts_count: %"PRId64"\n",
4317  curr_cts, curr_ctts, tts_index_old, tts_count_old);
4318  curr_cts += curr_ctts;
4319  tts_sample_old++;
4320  if (tts_sample_old == tts_data_old[tts_index_old].count) {
4321  if (add_tts_entry(&msc->tts_data, &msc->tts_count,
4322  &msc->tts_allocated_size,
4323  tts_data_old[tts_index_old].count - edit_list_start_tts_sample,
4324  tts_data_old[tts_index_old].offset, tts_data_old[tts_index_old].duration) == -1) {
4325  av_log(mov->fc, AV_LOG_ERROR, "Cannot add Time To Sample entry %"PRId64" - {%"PRId64", %d}\n",
4326  tts_index_old,
4327  tts_data_old[tts_index_old].count - edit_list_start_tts_sample,
4328  tts_data_old[tts_index_old].offset);
4329  break;
4330  }
4331  tts_index_old++;
4332  tts_sample_old = 0;
4333  edit_list_start_tts_sample = 0;
4334  }
4335  }
4336 
4337  if (curr_cts < edit_list_media_time || curr_cts >= (edit_list_duration + edit_list_media_time)) {
4339  curr_cts < edit_list_media_time && curr_cts + frame_duration > edit_list_media_time &&
4340  first_non_zero_audio_edit > 0) {
4341  packet_skip_samples = edit_list_media_time - curr_cts;
4342  sti->skip_samples += packet_skip_samples;
4343 
4344  // Shift the index entry timestamp by packet_skip_samples to be correct.
4345  edit_list_dts_counter -= packet_skip_samples;
4346  if (edit_list_start_encountered == 0) {
4347  edit_list_start_encountered = 1;
4348  // Make timestamps strictly monotonically increasing for audio, by rewriting timestamps for
4349  // discarded packets.
4350  if (frame_duration_buffer) {
4351  fix_index_entry_timestamps(st, sti->nb_index_entries, edit_list_dts_counter,
4352  frame_duration_buffer, num_discarded_begin);
4353  av_freep(&frame_duration_buffer);
4354  }
4355  }
4356 
4357  av_log(mov->fc, AV_LOG_DEBUG, "skip %d audio samples from curr_cts: %"PRId64"\n", packet_skip_samples, curr_cts);
4358  } else {
4360  av_log(mov->fc, AV_LOG_DEBUG, "drop a frame at curr_cts: %"PRId64" @ %"PRId64"\n", curr_cts, index);
4361 
4362  if (edit_list_start_encountered == 0) {
4363  num_discarded_begin++;
4364  frame_duration_buffer = av_realloc(frame_duration_buffer,
4365  num_discarded_begin * sizeof(int64_t));
4366  if (!frame_duration_buffer) {
4367  av_log(mov->fc, AV_LOG_ERROR, "Cannot reallocate frame duration buffer\n");
4368  break;
4369  }
4370  frame_duration_buffer[num_discarded_begin - 1] = frame_duration;
4371 
4372  // Increment skip_samples for the first non-zero audio edit list
4373  if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
4374  first_non_zero_audio_edit > 0 && st->codecpar->codec_id != AV_CODEC_ID_VORBIS) {
4375  sti->skip_samples += frame_duration;
4376  }
4377  }
4378  }
4379  } else {
4380  if (msc->min_corrected_pts < 0) {
4381  msc->min_corrected_pts = edit_list_dts_counter + curr_ctts + msc->dts_shift;
4382  } else {
4383  msc->min_corrected_pts = FFMIN(msc->min_corrected_pts, edit_list_dts_counter + curr_ctts + msc->dts_shift);
4384  }
4385  if (edit_list_start_encountered == 0) {
4386  edit_list_start_encountered = 1;
4387  // Make timestamps strictly monotonically increasing by rewriting timestamps for
4388  // discarded packets.
4389  if (frame_duration_buffer) {
4390  fix_index_entry_timestamps(st, sti->nb_index_entries, edit_list_dts_counter,
4391  frame_duration_buffer, num_discarded_begin);
4392  av_freep(&frame_duration_buffer);
4393  }
4394  }
4395  }
4396 
4397  if (add_index_entry(st, current->pos, edit_list_dts_counter, current->size,
4398  current->min_distance, flags) == -1) {
4399  av_log(mov->fc, AV_LOG_ERROR, "Cannot add index entry\n");
4400  break;
4401  }
4402 
4403  // Update the index ranges array
4404  if (!current_index_range || index != current_index_range->end) {
4405  current_index_range = current_index_range ? current_index_range + 1
4406  : msc->index_ranges;
4407  current_index_range->start = index;
4408  }
4409  current_index_range->end = index + 1;
4410 
4411  // Only start incrementing DTS in frame_duration amounts, when we encounter a frame in edit list.
4412  if (edit_list_start_encountered > 0) {
4413  edit_list_dts_counter = edit_list_dts_counter + frame_duration;
4414  }
4415 
4416  // Break when found first key frame after edit entry completion
4417  if ((curr_cts + frame_duration >= (edit_list_duration + edit_list_media_time)) &&
4419  if (msc->ctts_count) {
4420  // If we have CTTS and this is the first keyframe after edit elist,
4421  // wait for one more, because there might be trailing B-frames after this I-frame
4422  // that do belong to the edit.
4423  if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO && found_keyframe_after_edit == 0) {
4424  found_keyframe_after_edit = 1;
4425  continue;
4426  }
4427  if (tts_sample_old != 0) {
4428  if (add_tts_entry(&msc->tts_data, &msc->tts_count,
4429  &msc->tts_allocated_size,
4430  tts_sample_old - edit_list_start_tts_sample,
4431  tts_data_old[tts_index_old].offset, tts_data_old[tts_index_old].duration) == -1) {
4432  av_log(mov->fc, AV_LOG_ERROR, "Cannot add Time To Sample entry %"PRId64" - {%"PRId64", %d}\n",
4433  tts_index_old, tts_sample_old - edit_list_start_tts_sample,
4434  tts_data_old[tts_index_old].offset);
4435  break;
4436  }
4437  }
4438  }
4439  break;
4440  }
4441  }
4442  }
4443  // If there are empty edits, then msc->min_corrected_pts might be positive
4444  // intentionally. So we subtract the sum duration of emtpy edits here.
4445  msc->min_corrected_pts -= empty_edits_sum_duration;
4446 
4447  // If the minimum pts turns out to be greater than zero after fixing the index, then we subtract the
4448  // dts by that amount to make the first pts zero.
4449  if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
4450  if (msc->min_corrected_pts > 0) {
4451  av_log(mov->fc, AV_LOG_DEBUG, "Offset DTS by %"PRId64" to make first pts zero.\n", msc->min_corrected_pts);
4452  for (int i = 0; i < sti->nb_index_entries; ++i)
4454  }
4455  }
4456  // Start time should be equal to zero or the duration of any empty edits.
4457  st->start_time = empty_edits_sum_duration;
4458 
4459  // Update av stream length, if it ends up shorter than the track's media duration
4460  st->duration = FFMIN(st->duration, edit_list_dts_entry_end - start_dts);
4461  msc->start_pad = sti->skip_samples;
4462 
4463  // Free the old index and the old CTTS structures
4464  av_free(e_old);
4465  av_free(tts_data_old);
4466  av_freep(&frame_duration_buffer);
4467 
4468  // Null terminate the index ranges array
4469  current_index_range = current_index_range ? current_index_range + 1
4470  : msc->index_ranges;
4471  current_index_range->start = 0;
4472  current_index_range->end = 0;
4473  msc->current_index = msc->index_ranges[0].start;
4474 }
4475 
4476 static uint32_t get_sgpd_sync_index(const MOVStreamContext *sc, int nal_unit_type)
4477 {
4478  for (uint32_t i = 0; i < sc->sgpd_sync_count; i++)
4479  if (sc->sgpd_sync[i] == HEVC_NAL_CRA_NUT)
4480  return i + 1;
4481  return 0;
4482 }
4483 
4485 {
4486  int k;
4487  int sample_id = 0;
4488  uint32_t cra_index;
4489  MOVStreamContext *sc = st->priv_data;
4490 
4491  if (st->codecpar->codec_id != AV_CODEC_ID_HEVC || !sc->sync_group_count)
4492  return 0;
4493 
4494  /* Build an unrolled index of the samples */
4495  sc->sample_offsets_count = 0;
4496  for (uint32_t i = 0; i < sc->ctts_count; i++) {
4497  if (sc->ctts_data[i].count > INT_MAX - sc->sample_offsets_count)
4498  return AVERROR(ENOMEM);
4499  sc->sample_offsets_count += sc->ctts_data[i].count;
4500  }
4501  av_freep(&sc->sample_offsets);
4503  if (!sc->sample_offsets)
4504  return AVERROR(ENOMEM);
4505  k = 0;
4506  for (uint32_t i = 0; i < sc->ctts_count; i++)
4507  for (int j = 0; j < sc->ctts_data[i].count; j++)
4508  sc->sample_offsets[k++] = sc->ctts_data[i].offset;
4509 
4510  /* The following HEVC NAL type reveal the use of open GOP sync points
4511  * (TODO: BLA types may also be concerned) */
4512  cra_index = get_sgpd_sync_index(sc, HEVC_NAL_CRA_NUT); /* Clean Random Access */
4513  if (!cra_index)
4514  return 0;
4515 
4516  /* Build a list of open-GOP key samples */
4517  sc->open_key_samples_count = 0;
4518  for (uint32_t i = 0; i < sc->sync_group_count; i++)
4519  if (sc->sync_group[i].index == cra_index) {
4520  if (sc->sync_group[i].count > INT_MAX - sc->open_key_samples_count)
4521  return AVERROR(ENOMEM);
4523  }
4524  av_freep(&sc->open_key_samples);
4526  if (!sc->open_key_samples)
4527  return AVERROR(ENOMEM);
4528  k = 0;
4529  for (uint32_t i = 0; i < sc->sync_group_count; i++) {
4530  const MOVSbgp *sg = &sc->sync_group[i];
4531  if (sg->index == cra_index)
4532  for (uint32_t j = 0; j < sg->count; j++)
4533  sc->open_key_samples[k++] = sample_id;
4534  if (sg->count > INT_MAX - sample_id)
4535  return AVERROR_PATCHWELCOME;
4536  sample_id += sg->count;
4537  }
4538 
4539  /* Identify the minimal time step between samples */
4540  sc->min_sample_duration = UINT_MAX;
4541  for (uint32_t i = 0; i < sc->stts_count; i++)
4543 
4544  return 0;
4545 }
4546 
4547 #define MOV_MERGE_CTTS 1
4548 #define MOV_MERGE_STTS 2
4549 /*
4550  * Merge stts and ctts arrays into a new combined array.
4551  * stts_count and ctts_count may be left untouched as they will be
4552  * used to check for the presence of either of them.
4553  */
4554 static int mov_merge_tts_data(MOVContext *mov, AVStream *st, int flags)
4555 {
4556  MOVStreamContext *sc = st->priv_data;
4557  int ctts = sc->ctts_data && (flags & MOV_MERGE_CTTS);
4558  int stts = sc->stts_data && (flags & MOV_MERGE_STTS);
4559  int idx = 0;
4560 
4561  if (!sc->ctts_data && !sc->stts_data)
4562  return 0;
4563  // Expand time to sample entries such that we have a 1-1 mapping with samples
4564  if (!sc->sample_count || sc->sample_count >= UINT_MAX / sizeof(*sc->tts_data))
4565  return -1;
4566 
4567  if (ctts) {
4569  sc->sample_count * sizeof(*sc->tts_data));
4570  if (!sc->tts_data)
4571  return -1;
4572 
4573  memset(sc->tts_data, 0, sc->tts_allocated_size);
4574 
4575  for (int i = 0; i < sc->ctts_count &&
4576  idx < sc->sample_count; i++)
4577  for (int j = 0; j < sc->ctts_data[i].count &&
4578  idx < sc->sample_count; j++) {
4579  sc->tts_data[idx].offset = sc->ctts_data[i].offset;
4580  sc->tts_data[idx++].count = 1;
4581  }
4582 
4583  sc->tts_count = idx;
4584  } else
4585  sc->ctts_count = 0;
4586  av_freep(&sc->ctts_data);
4587  sc->ctts_allocated_size = 0;
4588 
4589  idx = 0;
4590  if (stts) {
4592  sc->sample_count * sizeof(*sc->tts_data));
4593  if (!tts_data)
4594  return -1;
4595 
4596  if (!sc->tts_data)
4597  memset(tts_data, 0, sc->tts_allocated_size);
4598  sc->tts_data = tts_data;
4599 
4600  for (int i = 0; i < sc->stts_count &&
4601  idx < sc->sample_count; i++)
4602  for (int j = 0; j < sc->stts_data[i].count &&
4603  idx < sc->sample_count; j++) {
4604  sc->tts_data[idx].duration = sc->stts_data[i].duration;
4605  sc->tts_data[idx++].count = 1;
4606  }
4607 
4608  sc->tts_count = FFMAX(sc->tts_count, idx);
4609  } else
4610  sc->stts_count = 0;
4611  av_freep(&sc->stts_data);
4612  sc->stts_allocated_size = 0;
4613 
4614  return 0;
4615 }
4616 
4617 static void mov_build_index(MOVContext *mov, AVStream *st)
4618 {
4619  MOVStreamContext *sc = st->priv_data;
4620  FFStream *const sti = ffstream(st);
4621  int64_t current_offset;
4622  int64_t current_dts = 0;
4623  unsigned int stts_index = 0;
4624  unsigned int stsc_index = 0;
4625  unsigned int stss_index = 0;
4626  unsigned int stps_index = 0;
4627  unsigned int i, j;
4628  uint64_t stream_size = 0;
4629 
4630  int ret = build_open_gop_key_points(st);
4631  if (ret < 0)
4632  return;
4633 
4634  if (sc->elst_count) {
4635  int i, edit_start_index = 0, multiple_edits = 0;
4636  int64_t empty_duration = 0; // empty duration of the first edit list entry
4637  int64_t start_time = 0; // start time of the media
4638 
4639  for (i = 0; i < sc->elst_count; i++) {
4640  const MOVElst *e = &sc->elst_data[i];
4641  if (i == 0 && e->time == -1) {
4642  /* if empty, the first entry is the start time of the stream
4643  * relative to the presentation itself */
4644  empty_duration = e->duration;
4645  edit_start_index = 1;
4646  } else if (i == edit_start_index && e->time >= 0) {
4647  start_time = e->time;
4648  } else {
4649  multiple_edits = 1;
4650  }
4651  }
4652 
4653  if (multiple_edits && !mov->advanced_editlist) {
4655  av_log(mov->fc, AV_LOG_WARNING, "multiple edit list entries, "
4656  "not supported in fragmented MP4 files\n");
4657  else
4658  av_log(mov->fc, AV_LOG_WARNING, "multiple edit list entries, "
4659  "Use -advanced_editlist to correctly decode otherwise "
4660  "a/v desync might occur\n");
4661  }
4662 
4663  /* adjust first dts according to edit list */
4664  if ((empty_duration || start_time) && mov->time_scale > 0) {
4665  if (empty_duration)
4666  empty_duration = av_rescale(empty_duration, sc->time_scale, mov->time_scale);
4667 
4668  if (av_sat_sub64(start_time, empty_duration) != start_time - (uint64_t)empty_duration)
4669  av_log(mov->fc, AV_LOG_WARNING, "start_time - empty_duration is not representable\n");
4670 
4671  sc->time_offset = start_time - (uint64_t)empty_duration;
4673  if (!mov->advanced_editlist)
4674  current_dts = -sc->time_offset;
4675  }
4676 
4677  if (!multiple_edits && !mov->advanced_editlist &&
4679  sc->start_pad = start_time;
4680  }
4681 
4682  /* only use old uncompressed audio chunk demuxing when stts specifies it */
4683  if (!(st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
4684  sc->stts_count == 1 && sc->stts_data && sc->stts_data[0].duration == 1)) {
4685  unsigned int current_sample = 0;
4686  unsigned int stts_sample = 0;
4687  unsigned int sample_size;
4688  unsigned int distance = 0;
4689  unsigned int rap_group_index = 0;
4690  unsigned int rap_group_sample = 0;
4691  int rap_group_present = sc->rap_group_count && sc->rap_group;
4692  int key_off = (sc->keyframe_count && sc->keyframes[0] > 0) || (sc->stps_count && sc->stps_data[0] > 0);
4693 
4694  current_dts -= sc->dts_shift;
4695 
4696  if (!sc->sample_count || sti->nb_index_entries || sc->tts_count)
4697  return;
4698  if (sc->sample_count >= UINT_MAX / sizeof(*sti->index_entries) - sti->nb_index_entries)
4699  return;
4700  if (av_reallocp_array(&sti->index_entries,
4701  sti->nb_index_entries + sc->sample_count,
4702  sizeof(*sti->index_entries)) < 0) {
4703  sti->nb_index_entries = 0;
4704  return;
4705  }
4706  sti->index_entries_allocated_size = (sti->nb_index_entries + sc->sample_count) * sizeof(*sti->index_entries);
4707 
4709  if (ret < 0)
4710  return;
4711 
4712  for (i = 0; i < sc->chunk_count; i++) {
4713  int64_t next_offset = i+1 < sc->chunk_count ? sc->chunk_offsets[i+1] : INT64_MAX;
4714  current_offset = sc->chunk_offsets[i];
4715  while (mov_stsc_index_valid(stsc_index, sc->stsc_count) &&
4716  i + 1 == sc->stsc_data[stsc_index + 1].first)
4717  stsc_index++;
4718 
4719  if (next_offset > current_offset && sc->sample_size>0 && sc->sample_size < sc->stsz_sample_size &&
4720  sc->stsc_data[stsc_index].count * (int64_t)sc->stsz_sample_size > next_offset - current_offset) {
4721  av_log(mov->fc, AV_LOG_WARNING, "STSZ sample size %d invalid (too large), ignoring\n", sc->stsz_sample_size);
4722  sc->stsz_sample_size = sc->sample_size;
4723  }
4724  if (sc->stsz_sample_size>0 && sc->stsz_sample_size < sc->sample_size) {
4725  av_log(mov->fc, AV_LOG_WARNING, "STSZ sample size %d invalid (too small), ignoring\n", sc->stsz_sample_size);
4726  sc->stsz_sample_size = sc->sample_size;
4727  }
4728 
4729  for (j = 0; j < sc->stsc_data[stsc_index].count; j++) {
4730  int keyframe = 0;
4731  if (current_sample >= sc->sample_count) {
4732  av_log(mov->fc, AV_LOG_ERROR, "wrong sample count\n");
4733  return;
4734  }
4735 
4736  if (!sc->keyframe_absent && (!sc->keyframe_count || current_sample+key_off == sc->keyframes[stss_index])) {
4737  keyframe = 1;
4738  if (stss_index + 1 < sc->keyframe_count)
4739  stss_index++;
4740  } else if (sc->stps_count && current_sample+key_off == sc->stps_data[stps_index]) {
4741  keyframe = 1;
4742  if (stps_index + 1 < sc->stps_count)
4743  stps_index++;
4744  }
4745  if (rap_group_present && rap_group_index < sc->rap_group_count) {
4746  if (sc->rap_group[rap_group_index].index > 0)
4747  keyframe = 1;
4748  if (++rap_group_sample == sc->rap_group[rap_group_index].count) {
4749  rap_group_sample = 0;
4750  rap_group_index++;
4751  }
4752  }
4753  if (sc->keyframe_absent
4754  && !sc->stps_count
4755  && !rap_group_present
4756  && (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO || (i==0 && j==0)))
4757  keyframe = 1;
4758  if (keyframe)
4759  distance = 0;
4760  sample_size = sc->stsz_sample_size > 0 ? sc->stsz_sample_size : sc->sample_sizes[current_sample];
4761  if (current_offset > INT64_MAX - sample_size) {
4762  av_log(mov->fc, AV_LOG_ERROR, "Current offset %"PRId64" or sample size %u is too large\n",
4763  current_offset,
4764  sample_size);
4765  return;
4766  }
4767 
4768  if (sc->pseudo_stream_id == -1 ||
4769  sc->stsc_data[stsc_index].id - 1 == sc->pseudo_stream_id) {
4770  AVIndexEntry *e;
4771  if (sample_size > 0x3FFFFFFF) {
4772  av_log(mov->fc, AV_LOG_ERROR, "Sample size %u is too large\n", sample_size);
4773  return;
4774  }
4775  e = &sti->index_entries[sti->nb_index_entries++];
4776  e->pos = current_offset;
4777  e->timestamp = current_dts;
4778  e->size = sample_size;
4779  e->min_distance = distance;
4780  e->flags = keyframe ? AVINDEX_KEYFRAME : 0;
4781  av_log(mov->fc, AV_LOG_TRACE, "AVIndex stream %d, sample %u, offset %"PRIx64", dts %"PRId64", "
4782  "size %u, distance %u, keyframe %d\n", st->index, current_sample,
4783  current_offset, current_dts, sample_size, distance, keyframe);
4784  if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && sti->nb_index_entries < 100)
4785  ff_rfps_add_frame(mov->fc, st, current_dts);
4786  }
4787 
4788  current_offset += sample_size;
4789  stream_size += sample_size;
4790 
4791  current_dts += sc->tts_data[stts_index].duration;
4792 
4793  distance++;
4794  stts_sample++;
4795  current_sample++;
4796  if (stts_index + 1 < sc->tts_count && stts_sample == sc->tts_data[stts_index].count) {
4797  stts_sample = 0;
4798  stts_index++;
4799  }
4800  }
4801  }
4802  if (st->duration > 0)
4803  st->codecpar->bit_rate = stream_size*8*sc->time_scale/st->duration;
4804  } else {
4805  unsigned chunk_samples, total = 0;
4806 
4807  if (!sc->chunk_count || sc->tts_count)
4808  return;
4809 
4811  if (ret < 0)
4812  return;
4813 
4814  // compute total chunk count
4815  for (i = 0; i < sc->stsc_count; i++) {
4816  unsigned count, chunk_count;
4817 
4818  chunk_samples = sc->stsc_data[i].count;
4819  if (i != sc->stsc_count - 1 &&
4820  sc->samples_per_frame && chunk_samples % sc->samples_per_frame) {
4821  av_log(mov->fc, AV_LOG_ERROR, "error unaligned chunk\n");
4822  return;
4823  }
4824 
4825  if (sc->samples_per_frame >= 160) { // gsm
4826  count = chunk_samples / sc->samples_per_frame;
4827  } else if (sc->samples_per_frame > 1) {
4828  unsigned samples = (1024/sc->samples_per_frame)*sc->samples_per_frame;
4829  count = (chunk_samples+samples-1) / samples;
4830  } else {
4831  count = (chunk_samples+1023) / 1024;
4832  }
4833 
4834  if (mov_stsc_index_valid(i, sc->stsc_count))
4835  chunk_count = sc->stsc_data[i+1].first - sc->stsc_data[i].first;
4836  else
4837  chunk_count = sc->chunk_count - (sc->stsc_data[i].first - 1);
4838  total += chunk_count * count;
4839  }
4840 
4841  av_log(mov->fc, AV_LOG_TRACE, "chunk count %u\n", total);
4842  if (total >= UINT_MAX / sizeof(*sti->index_entries) - sti->nb_index_entries)
4843  return;
4844  if (av_reallocp_array(&sti->index_entries,
4845  sti->nb_index_entries + total,
4846  sizeof(*sti->index_entries)) < 0) {
4847  sti->nb_index_entries = 0;
4848  return;
4849  }
4850  sti->index_entries_allocated_size = (sti->nb_index_entries + total) * sizeof(*sti->index_entries);
4851 
4852  // populate index
4853  for (i = 0; i < sc->chunk_count; i++) {
4854  current_offset = sc->chunk_offsets[i];
4855  if (mov_stsc_index_valid(stsc_index, sc->stsc_count) &&
4856  i + 1 == sc->stsc_data[stsc_index + 1].first)
4857  stsc_index++;
4858  chunk_samples = sc->stsc_data[stsc_index].count;
4859 
4860  while (chunk_samples > 0) {
4861  AVIndexEntry *e;
4862  unsigned size, samples;
4863 
4864  if (sc->samples_per_frame > 1 && !sc->bytes_per_frame) {
4866  "Zero bytes per frame, but %d samples per frame",
4867  sc->samples_per_frame);
4868  return;
4869  }
4870 
4871  if (sc->samples_per_frame >= 160) { // gsm
4872  samples = sc->samples_per_frame;
4873  size = sc->bytes_per_frame;
4874  } else {
4875  if (sc->samples_per_frame > 1) {
4876  samples = FFMIN((1024 / sc->samples_per_frame)*
4877  sc->samples_per_frame, chunk_samples);
4879  } else {
4880  samples = FFMIN(1024, chunk_samples);
4881  size = samples * sc->sample_size;
4882  }
4883  }
4884 
4885  if (sti->nb_index_entries >= total) {
4886  av_log(mov->fc, AV_LOG_ERROR, "wrong chunk count %u\n", total);
4887  return;
4888  }
4889  if (size > 0x3FFFFFFF) {
4890  av_log(mov->fc, AV_LOG_ERROR, "Sample size %u is too large\n", size);
4891  return;
4892  }
4893  e = &sti->index_entries[sti->nb_index_entries++];
4894  e->pos = current_offset;
4895  e->timestamp = current_dts;
4896  e->size = size;
4897  e->min_distance = 0;
4898  e->flags = AVINDEX_KEYFRAME;
4899  av_log(mov->fc, AV_LOG_TRACE, "AVIndex stream %d, chunk %u, offset %"PRIx64", dts %"PRId64", "
4900  "size %u, duration %u\n", st->index, i, current_offset, current_dts,
4901  size, samples);
4902 
4903  current_offset += size;
4904  current_dts += samples;
4905  chunk_samples -= samples;
4906  }
4907  }
4908  }
4909 
4910  if (!mov->ignore_editlist && mov->advanced_editlist) {
4911  // Fix index according to edit lists.
4912  mov_fix_index(mov, st);
4913  }
4914 
4915  // Update start time of the stream.
4917  st->start_time = sti->index_entries[0].timestamp + sc->dts_shift;
4918  if (sc->tts_data) {
4919  st->start_time += sc->tts_data[0].offset;
4920  }
4921  }
4922 
4923  mov_estimate_video_delay(mov, st);
4924 }
4925 
4926 static int test_same_origin(const char *src, const char *ref) {
4927  char src_proto[64];
4928  char ref_proto[64];
4929  char src_auth[256];
4930  char ref_auth[256];
4931  char src_host[256];
4932  char ref_host[256];
4933  int src_port=-1;
4934  int ref_port=-1;
4935 
4936  av_url_split(src_proto, sizeof(src_proto), src_auth, sizeof(src_auth), src_host, sizeof(src_host), &src_port, NULL, 0, src);
4937  av_url_split(ref_proto, sizeof(ref_proto), ref_auth, sizeof(ref_auth), ref_host, sizeof(ref_host), &ref_port, NULL, 0, ref);
4938 
4939  if (strlen(src) == 0) {
4940  return -1;
4941  } else if (strlen(src_auth) + 1 >= sizeof(src_auth) ||
4942  strlen(ref_auth) + 1 >= sizeof(ref_auth) ||
4943  strlen(src_host) + 1 >= sizeof(src_host) ||
4944  strlen(ref_host) + 1 >= sizeof(ref_host)) {
4945  return 0;
4946  } else if (strcmp(src_proto, ref_proto) ||
4947  strcmp(src_auth, ref_auth) ||
4948  strcmp(src_host, ref_host) ||
4949  src_port != ref_port) {
4950  return 0;
4951  } else
4952  return 1;
4953 }
4954 
4955 static int mov_open_dref(MOVContext *c, AVIOContext **pb, const char *src, MOVDref *ref)
4956 {
4957  /* try relative path, we do not try the absolute because it can leak information about our
4958  system to an attacker */
4959  if (ref->nlvl_to > 0 && ref->nlvl_from > 0) {
4960  char filename[1025];
4961  const char *src_path;
4962  int i, l;
4963 
4964  /* find a source dir */
4965  src_path = strrchr(src, '/');
4966  if (src_path)
4967  src_path++;
4968  else
4969  src_path = src;
4970 
4971  /* find a next level down to target */
4972  for (i = 0, l = strlen(ref->path) - 1; l >= 0; l--)
4973  if (ref->path[l] == '/') {
4974  if (i == ref->nlvl_to - 1)
4975  break;
4976  else
4977  i++;
4978  }
4979 
4980  /* compose filename if next level down to target was found */
4981  if (i == ref->nlvl_to - 1 && src_path - src < sizeof(filename)) {
4982  memcpy(filename, src, src_path - src);
4983  filename[src_path - src] = 0;
4984 
4985  for (i = 1; i < ref->nlvl_from; i++)
4986  av_strlcat(filename, "../", sizeof(filename));
4987 
4988  av_strlcat(filename, ref->path + l + 1, sizeof(filename));
4989  if (!c->use_absolute_path) {
4990  int same_origin = test_same_origin(src, filename);
4991 
4992  if (!same_origin) {
4993  av_log(c->fc, AV_LOG_ERROR,
4994  "Reference with mismatching origin, %s not tried for security reasons, "
4995  "set demuxer option use_absolute_path to allow it anyway\n",
4996  ref->path);
4997  return AVERROR(ENOENT);
4998  }
4999 
5000  if (strstr(ref->path + l + 1, "..") ||
5001  strstr(ref->path + l + 1, ":") ||
5002  (ref->nlvl_from > 1 && same_origin < 0) ||
5003  (filename[0] == '/' && src_path == src))
5004  return AVERROR(ENOENT);
5005  }
5006 
5007  if (strlen(filename) + 1 == sizeof(filename))
5008  return AVERROR(ENOENT);
5009  if (!c->fc->io_open(c->fc, pb, filename, AVIO_FLAG_READ, NULL))
5010  return 0;
5011  }
5012  } else if (c->use_absolute_path) {
5013  av_log(c->fc, AV_LOG_WARNING, "Using absolute path on user request, "
5014  "this is a possible security issue\n");
5015  if (!c->fc->io_open(c->fc, pb, ref->path, AVIO_FLAG_READ, NULL))
5016  return 0;
5017  } else {
5018  av_log(c->fc, AV_LOG_ERROR,
5019  "Absolute path %s not tried for security reasons, "
5020  "set demuxer option use_absolute_path to allow absolute paths\n",
5021  ref->path);
5022  }
5023 
5024  return AVERROR(ENOENT);
5025 }
5026 
5028 {
5029  if (sc->time_scale <= 0) {
5030  av_log(c->fc, AV_LOG_WARNING, "stream %d, timescale not set\n", sc->ffindex);
5031  sc->time_scale = c->time_scale;
5032  if (sc->time_scale <= 0)
5033  sc->time_scale = 1;
5034  }
5035 }
5036 
5037 #if CONFIG_IAMFDEC
5038 static int mov_update_iamf_streams(MOVContext *c, const AVStream *st)
5039 {
5040  const MOVStreamContext *sc = st->priv_data;
5041  const IAMFContext *iamf = &sc->iamf->iamf;
5042 
5043  for (int i = 0; i < iamf->nb_audio_elements; i++) {
5044  const AVStreamGroup *stg = NULL;
5045 
5046  for (int j = 0; j < c->fc->nb_stream_groups; j++)
5047  if (c->fc->stream_groups[j]->id == iamf->audio_elements[i]->audio_element_id)
5048  stg = c->fc->stream_groups[j];
5049  av_assert0(stg);
5050 
5051  for (int j = 0; j < stg->nb_streams; j++) {
5052  const FFStream *sti = cffstream(st);
5053  AVStream *out = stg->streams[j];
5054  FFStream *out_sti = ffstream(stg->streams[j]);
5055 
5056  out->codecpar->bit_rate = 0;
5057 
5058  if (out == st)
5059  continue;
5060 
5061  out->time_base = st->time_base;
5062  out->start_time = st->start_time;
5063  out->duration = st->duration;
5064  out->nb_frames = st->nb_frames;
5065  out->discard = st->discard;
5066 
5067  av_assert0(!out_sti->index_entries);
5069  if (!out_sti->index_entries)
5070  return AVERROR(ENOMEM);
5071 
5073  out_sti->nb_index_entries = sti->nb_index_entries;
5074  out_sti->skip_samples = sti->skip_samples;
5075  memcpy(out_sti->index_entries, sti->index_entries, sti->index_entries_allocated_size);
5076  }
5077  }
5078 
5079  return 0;
5080 }
5081 #endif
5082 
5083 static int sanity_checks(void *log_obj, MOVStreamContext *sc, int index)
5084 {
5085  if ((sc->chunk_count && (!sc->stts_count || !sc->stsc_count ||
5086  (!sc->sample_size && !sc->sample_count))) ||
5087  (!sc->chunk_count && sc->sample_count)) {
5088  av_log(log_obj, AV_LOG_ERROR, "stream %d, missing mandatory atoms, broken header\n",
5089  index);
5090  return 1;
5091  }
5092 
5093  if (sc->stsc_count && sc->stsc_data[ sc->stsc_count - 1 ].first > sc->chunk_count) {
5094  av_log(log_obj, AV_LOG_ERROR, "stream %d, contradictionary STSC and STCO\n",
5095  index);
5096  return 2;
5097  }
5098  return 0;
5099 }
5100 
5102 {
5103  AVStream *st;
5104  MOVStreamContext *sc;
5105  int ret;
5106 
5107  st = avformat_new_stream(c->fc, NULL);
5108  if (!st) return AVERROR(ENOMEM);
5109  st->id = -1;
5110  sc = av_mallocz(sizeof(MOVStreamContext));
5111  if (!sc) return AVERROR(ENOMEM);
5112 
5113  st->priv_data = sc;
5115  sc->ffindex = st->index;
5116  c->trak_index = st->index;
5117  sc->tref_flags = 0;
5118  sc->tref_id = -1;
5119  sc->refcount = 1;
5120 
5121  if ((ret = mov_read_default(c, pb, atom)) < 0)
5122  return ret;
5123 
5124  c->trak_index = -1;
5125 
5126  // Here stsc refers to a chunk not described in stco. This is technically invalid,
5127  // but we can overlook it (clearing stsc) whenever stts_count == 0 (indicating no samples).
5128  if (!sc->chunk_count && !sc->stts_count && sc->stsc_count) {
5129  sc->stsc_count = 0;
5130  av_freep(&sc->stsc_data);
5131  }
5132 
5133  ret = sanity_checks(c->fc, sc, st->index);
5134  if (ret)
5135  return ret > 1 ? AVERROR_INVALIDDATA : 0;
5136 
5137  fix_timescale(c, sc);
5138 
5139  avpriv_set_pts_info(st, 64, 1, sc->time_scale);
5140 
5141  /*
5142  * Advanced edit list support does not work with fragemented MP4s, which
5143  * have stsc, stsz, stco, and stts with zero entries in the moov atom.
5144  * In these files, trun atoms may be streamed in.
5145  */
5146  if (!sc->stts_count && c->advanced_editlist) {
5147 
5148  av_log(c->fc, AV_LOG_VERBOSE, "advanced_editlist does not work with fragmented "
5149  "MP4. disabling.\n");
5150  c->advanced_editlist = 0;
5151  c->advanced_editlist_autodisabled = 1;
5152  }
5153 
5154  mov_build_index(c, st);
5155 
5156 #if CONFIG_IAMFDEC
5157  if (sc->iamf) {
5158  ret = mov_update_iamf_streams(c, st);
5159  if (ret < 0)
5160  return ret;
5161  }
5162 #endif
5163 
5164  if (sc->dref_id-1 < sc->drefs_count && sc->drefs[sc->dref_id-1].path) {
5165  MOVDref *dref = &sc->drefs[sc->dref_id - 1];
5166  if (c->enable_drefs) {
5167  if (mov_open_dref(c, &sc->pb, c->fc->url, dref) < 0)
5168  av_log(c->fc, AV_LOG_ERROR,
5169  "stream %d, error opening alias: path='%s', dir='%s', "
5170  "filename='%s', volume='%s', nlvl_from=%d, nlvl_to=%d\n",
5171  st->index, dref->path, dref->dir, dref->filename,
5172  dref->volume, dref->nlvl_from, dref->nlvl_to);
5173  } else {
5174  av_log(c->fc, AV_LOG_WARNING,
5175  "Skipped opening external track: "
5176  "stream %d, alias: path='%s', dir='%s', "
5177  "filename='%s', volume='%s', nlvl_from=%d, nlvl_to=%d."
5178  "Set enable_drefs to allow this.\n",
5179  st->index, dref->path, dref->dir, dref->filename,
5180  dref->volume, dref->nlvl_from, dref->nlvl_to);
5181  }
5182  } else {
5183  sc->pb = c->fc->pb;
5184  sc->pb_is_copied = 1;
5185  }
5186 
5187  if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
5188  int stts_constant = sc->stts_count && sc->tts_count;
5189  if (sc->h_spacing && sc->v_spacing)
5191  sc->h_spacing, sc->v_spacing, INT_MAX);
5192  if (!st->sample_aspect_ratio.num && st->codecpar->width && st->codecpar->height &&
5193  sc->height && sc->width &&
5194  (st->codecpar->width != sc->width || st->codecpar->height != sc->height)) {
5196  (int64_t)st->codecpar->height * sc->width,
5197  (int64_t)st->codecpar->width * sc->height, INT_MAX);
5198  }
5199 
5200 #if FF_API_R_FRAME_RATE
5201  for (unsigned int i = 1; sc->stts_count && i + 1 < sc->tts_count; i++) {
5202  if (sc->tts_data[i].duration == sc->tts_data[0].duration)
5203  continue;
5204  stts_constant = 0;
5205  }
5206  if (stts_constant)
5208  sc->time_scale, sc->tts_data[0].duration, INT_MAX);
5209 #endif
5210  }
5211 
5212  // done for ai5q, ai52, ai55, ai1q, ai12 and ai15.
5213  if (!st->codecpar->extradata_size && st->codecpar->codec_id == AV_CODEC_ID_H264 &&
5214  TAG_IS_AVCI(st->codecpar->codec_tag)) {
5216  if (ret < 0)
5217  return ret;
5218  }
5219 
5220  switch (st->codecpar->codec_id) {
5221 #if CONFIG_H261_DECODER
5222  case AV_CODEC_ID_H261:
5223 #endif
5224 #if CONFIG_H263_DECODER
5225  case AV_CODEC_ID_H263:
5226 #endif
5227 #if CONFIG_MPEG4_DECODER
5228  case AV_CODEC_ID_MPEG4:
5229 #endif
5230  st->codecpar->width = 0; /* let decoder init width/height */
5231  st->codecpar->height= 0;
5232  break;
5233  }
5234 
5235  // If the duration of the mp3 packets is not constant, then they could need a parser
5236  if (st->codecpar->codec_id == AV_CODEC_ID_MP3
5237  && sc->time_scale == st->codecpar->sample_rate) {
5238  int stts_constant = 1;
5239  for (int i = 1; sc->stts_count && i < sc->tts_count; i++) {
5240  if (sc->tts_data[i].duration == sc->tts_data[0].duration)
5241  continue;
5242  stts_constant = 0;
5243  }
5244  if (!stts_constant)
5246  }
5247  /* Do not need those anymore. */
5248  av_freep(&sc->chunk_offsets);
5249  av_freep(&sc->sample_sizes);
5250  av_freep(&sc->keyframes);
5251  av_freep(&sc->stps_data);
5252  av_freep(&sc->elst_data);
5253  av_freep(&sc->rap_group);
5254  av_freep(&sc->sync_group);
5255  av_freep(&sc->sgpd_sync);
5256 
5257  return 0;
5258 }
5259 
5261 {
5262  int ret;
5263  c->itunes_metadata = 1;
5264  ret = mov_read_default(c, pb, atom);
5265  c->itunes_metadata = 0;
5266  return ret;
5267 }
5268 
5270 {
5271  uint32_t count;
5272  uint32_t i;
5273 
5274  if (atom.size < 8)
5275  return 0;
5276 
5277  avio_skip(pb, 4);
5278  count = avio_rb32(pb);
5279  atom.size -= 8;
5280  if (count >= UINT_MAX / sizeof(*c->meta_keys)) {
5281  av_log(c->fc, AV_LOG_ERROR,
5282  "The 'keys' atom with the invalid key count: %"PRIu32"\n", count);
5283  return AVERROR_INVALIDDATA;
5284  }
5285 
5286  c->meta_keys_count = count + 1;
5287  c->meta_keys = av_mallocz(c->meta_keys_count * sizeof(*c->meta_keys));
5288  if (!c->meta_keys)
5289  return AVERROR(ENOMEM);
5290 
5291  for (i = 1; i <= count; ++i) {
5292  uint32_t key_size = avio_rb32(pb);
5293  uint32_t type = avio_rl32(pb);
5294  if (key_size < 8 || key_size > atom.size) {
5295  av_log(c->fc, AV_LOG_ERROR,
5296  "The key# %"PRIu32" in meta has invalid size:"
5297  "%"PRIu32"\n", i, key_size);
5298  return AVERROR_INVALIDDATA;
5299  }
5300  atom.size -= key_size;
5301  key_size -= 8;
5302  if (type != MKTAG('m','d','t','a')) {
5303  avio_skip(pb, key_size);
5304  continue;
5305  }
5306  c->meta_keys[i] = av_mallocz(key_size + 1);
5307  if (!c->meta_keys[i])
5308  return AVERROR(ENOMEM);
5309  avio_read(pb, c->meta_keys[i], key_size);
5310  }
5311 
5312  return 0;
5313 }
5314 
5316 {
5317  int64_t end = av_sat_add64(avio_tell(pb), atom.size);
5318  uint8_t *key = NULL, *val = NULL, *mean = NULL;
5319  int i;
5320  int ret = 0;
5321  AVStream *st;
5322  MOVStreamContext *sc;
5323 
5324  if (c->fc->nb_streams < 1)
5325  return 0;
5326  st = c->fc->streams[c->fc->nb_streams-1];
5327  sc = st->priv_data;
5328 
5329  for (i = 0; i < 3; i++) {
5330  uint8_t **p;
5331  uint32_t len, tag;
5332 
5333  if (end - avio_tell(pb) <= 12)
5334  break;
5335 
5336  len = avio_rb32(pb);
5337  tag = avio_rl32(pb);
5338  avio_skip(pb, 4); // flags
5339 
5340  if (len < 12 || len - 12 > end - avio_tell(pb))
5341  break;
5342  len -= 12;
5343 
5344  if (tag == MKTAG('m', 'e', 'a', 'n'))
5345  p = &mean;
5346  else if (tag == MKTAG('n', 'a', 'm', 'e'))
5347  p = &key;
5348  else if (tag == MKTAG('d', 'a', 't', 'a') && len > 4) {
5349  avio_skip(pb, 4);
5350  len -= 4;
5351  p = &val;
5352  } else
5353  break;
5354 
5355  if (*p)
5356  break;
5357 
5358  *p = av_malloc(len + 1);
5359  if (!*p) {
5360  ret = AVERROR(ENOMEM);
5361  break;
5362  }
5363  ret = ffio_read_size(pb, *p, len);
5364  if (ret < 0) {
5365  av_freep(p);
5366  break;
5367  }
5368  (*p)[len] = 0;
5369  }
5370 
5371  if (mean && key && val) {
5372  if (strcmp(key, "iTunSMPB") == 0) {
5373  int priming, remainder, samples;
5374  if(sscanf(val, "%*X %X %X %X", &priming, &remainder, &samples) == 3){
5375  if(priming>0 && priming<16384)
5376  sc->start_pad = priming;
5377  }
5378  }
5379  if (strcmp(key, "cdec") != 0) {
5380  av_dict_set(&c->fc->metadata, key, val,
5382  key = val = NULL;
5383  }
5384  } else {
5385  av_log(c->fc, AV_LOG_VERBOSE,
5386  "Unhandled or malformed custom metadata of size %"PRId64"\n", atom.size);
5387  }
5388 
5389  avio_seek(pb, end, SEEK_SET);
5390  av_freep(&key);
5391  av_freep(&val);
5392  av_freep(&mean);
5393  return ret;
5394 }
5395 
5397 {
5398  MOVStreamContext *sc;
5399  AVStream *st;
5400 
5401  st = avformat_new_stream(c->fc, NULL);
5402  if (!st)
5403  return AVERROR(ENOMEM);
5404  sc = av_mallocz(sizeof(MOVStreamContext));
5405  if (!sc)
5406  return AVERROR(ENOMEM);
5407 
5408  item->st = st;
5409  st->id = item->item_id;
5410  st->priv_data = sc;
5412  st->codecpar->codec_id = mov_codec_id(st, item->type);
5413  sc->id = st->id;
5414  sc->ffindex = st->index;
5415  st->avg_frame_rate.num = st->avg_frame_rate.den = 1;
5416  st->time_base.num = st->time_base.den = 1;
5417  st->nb_frames = 1;
5418  sc->time_scale = 1;
5419  sc->pb = c->fc->pb;
5420  sc->pb_is_copied = 1;
5421  sc->refcount = 1;
5422 
5423  if (item->name)
5424  av_dict_set(&st->metadata, "title", item->name, 0);
5425 
5426  // Populate the necessary fields used by mov_build_index.
5427  sc->stsc_count = 1;
5428  sc->stsc_data = av_malloc_array(1, sizeof(*sc->stsc_data));
5429  if (!sc->stsc_data)
5430  return AVERROR(ENOMEM);
5431  sc->stsc_data[0].first = 1;
5432  sc->stsc_data[0].count = 1;
5433  sc->stsc_data[0].id = 1;
5434  sc->chunk_count = 1;
5435  sc->chunk_offsets = av_malloc_array(1, sizeof(*sc->chunk_offsets));
5436  if (!sc->chunk_offsets)
5437  return AVERROR(ENOMEM);
5438  sc->sample_count = 1;
5439  sc->sample_sizes = av_malloc_array(1, sizeof(*sc->sample_sizes));
5440  if (!sc->sample_sizes)
5441  return AVERROR(ENOMEM);
5442  sc->stts_count = 1;
5443  sc->stts_data = av_malloc_array(1, sizeof(*sc->stts_data));
5444  if (!sc->stts_data)
5445  return AVERROR(ENOMEM);
5446  sc->stts_data[0].count = 1;
5447  // Not used for still images. But needed by mov_build_index.
5448  sc->stts_data[0].duration = 0;
5449 
5450  return 0;
5451 }
5452 
5454 {
5455  while (atom.size > 8) {
5456  uint32_t tag;
5457  if (avio_feof(pb))
5458  return AVERROR_EOF;
5459  tag = avio_rl32(pb);
5460  atom.size -= 4;
5461  if (tag == MKTAG('h','d','l','r')) {
5462  avio_seek(pb, -8, SEEK_CUR);
5463  atom.size += 8;
5464  return mov_read_default(c, pb, atom);
5465  }
5466  }
5467  return 0;
5468 }
5469 
5470 // return 1 when matrix is identity, 0 otherwise
5471 #define IS_MATRIX_IDENT(matrix) \
5472  ( (matrix)[0][0] == (1 << 16) && \
5473  (matrix)[1][1] == (1 << 16) && \
5474  (matrix)[2][2] == (1 << 30) && \
5475  !(matrix)[0][1] && !(matrix)[0][2] && \
5476  !(matrix)[1][0] && !(matrix)[1][2] && \
5477  !(matrix)[2][0] && !(matrix)[2][1])
5478 
5480 {
5481  int i, j, e;
5482  int width;
5483  int height;
5484  int display_matrix[3][3];
5485  int res_display_matrix[3][3] = { { 0 } };
5486  AVStream *st;
5487  MOVStreamContext *sc;
5488  int version;
5489  int flags;
5490 
5491  if (c->fc->nb_streams < 1)
5492  return 0;
5493  st = c->fc->streams[c->fc->nb_streams-1];
5494  sc = st->priv_data;
5495 
5496  // Each stream (trak) should have exactly 1 tkhd. This catches bad files and
5497  // avoids corrupting AVStreams mapped to an earlier tkhd.
5498  if (st->id != -1)
5499  return AVERROR_INVALIDDATA;
5500 
5501  version = avio_r8(pb);
5502  flags = avio_rb24(pb);
5504 
5505  if (version == 1) {
5506  avio_rb64(pb);
5507  avio_rb64(pb);
5508  } else {
5509  avio_rb32(pb); /* creation time */
5510  avio_rb32(pb); /* modification time */
5511  }
5512  st->id = (int)avio_rb32(pb); /* track id (NOT 0 !)*/
5513  sc->id = st->id;
5514  avio_rb32(pb); /* reserved */
5515 
5516  /* highlevel (considering edits) duration in movie timebase */
5517  (version == 1) ? avio_rb64(pb) : avio_rb32(pb);
5518  avio_rb32(pb); /* reserved */
5519  avio_rb32(pb); /* reserved */
5520 
5521  avio_rb16(pb); /* layer */
5522  avio_rb16(pb); /* alternate group */
5523  avio_rb16(pb); /* volume */
5524  avio_rb16(pb); /* reserved */
5525 
5526  //read in the display matrix (outlined in ISO 14496-12, Section 6.2.2)
5527  // they're kept in fixed point format through all calculations
5528  // save u,v,z to store the whole matrix in the AV_PKT_DATA_DISPLAYMATRIX
5529  // side data, but the scale factor is not needed to calculate aspect ratio
5530  for (i = 0; i < 3; i++) {
5531  display_matrix[i][0] = avio_rb32(pb); // 16.16 fixed point
5532  display_matrix[i][1] = avio_rb32(pb); // 16.16 fixed point
5533  display_matrix[i][2] = avio_rb32(pb); // 2.30 fixed point
5534  }
5535 
5536  width = avio_rb32(pb); // 16.16 fixed point track width
5537  height = avio_rb32(pb); // 16.16 fixed point track height
5538  sc->width = width >> 16;
5539  sc->height = height >> 16;
5540 
5541  // apply the moov display matrix (after the tkhd one)
5542  for (i = 0; i < 3; i++) {
5543  const int sh[3] = { 16, 16, 30 };
5544  for (j = 0; j < 3; j++) {
5545  for (e = 0; e < 3; e++) {
5546  res_display_matrix[i][j] +=
5547  ((int64_t) display_matrix[i][e] *
5548  c->movie_display_matrix[e][j]) >> sh[e];
5549  }
5550  }
5551  }
5552 
5553  // save the matrix when it is not the default identity
5554  if (!IS_MATRIX_IDENT(res_display_matrix)) {
5555  av_freep(&sc->display_matrix);
5556  sc->display_matrix = av_malloc(sizeof(int32_t) * 9);
5557  if (!sc->display_matrix)
5558  return AVERROR(ENOMEM);
5559 
5560  for (i = 0; i < 3; i++)
5561  for (j = 0; j < 3; j++)
5562  sc->display_matrix[i * 3 + j] = res_display_matrix[i][j];
5563  }
5564 
5565  // transform the display width/height according to the matrix
5566  // to keep the same scale, use [width height 1<<16]
5567  if (width && height && sc->display_matrix) {
5568  double disp_transform[2];
5569 
5570  for (i = 0; i < 2; i++)
5571  disp_transform[i] = hypot(sc->display_matrix[0 + i],
5572  sc->display_matrix[3 + i]);
5573 
5574  if (disp_transform[0] > 1 && disp_transform[1] > 1 &&
5575  disp_transform[0] < (1<<24) && disp_transform[1] < (1<<24) &&
5576  fabs((disp_transform[0] / disp_transform[1]) - 1.0) > 0.01)
5578  disp_transform[0] / disp_transform[1],
5579  INT_MAX);
5580  }
5581  return 0;
5582 }
5583 
5585 {
5586  MOVFragment *frag = &c->fragment;
5587  MOVTrackExt *trex = NULL;
5588  int flags, track_id, i;
5589  MOVFragmentStreamInfo * frag_stream_info;
5590 
5591  avio_r8(pb); /* version */
5592  flags = avio_rb24(pb);
5593 
5594  track_id = avio_rb32(pb);
5595  if (!track_id)
5596  return AVERROR_INVALIDDATA;
5597  for (i = 0; i < c->trex_count; i++)
5598  if (c->trex_data[i].track_id == track_id) {
5599  trex = &c->trex_data[i];
5600  break;
5601  }
5602  if (!trex) {
5603  av_log(c->fc, AV_LOG_WARNING, "could not find corresponding trex (id %u)\n", track_id);
5604  return 0;
5605  }
5606  c->fragment.found_tfhd = 1;
5607  frag->track_id = track_id;
5608  set_frag_stream(&c->frag_index, track_id);
5609 
5612  frag->moof_offset : frag->implicit_offset;
5613  frag->stsd_id = flags & MOV_TFHD_STSD_ID ? avio_rb32(pb) : trex->stsd_id;
5614 
5616  avio_rb32(pb) : trex->duration;
5617  frag->size = flags & MOV_TFHD_DEFAULT_SIZE ?
5618  avio_rb32(pb) : trex->size;
5619  frag->flags = flags & MOV_TFHD_DEFAULT_FLAGS ?
5620  avio_rb32(pb) : trex->flags;
5621  av_log(c->fc, AV_LOG_TRACE, "frag flags 0x%x\n", frag->flags);
5622 
5623  frag_stream_info = get_current_frag_stream_info(&c->frag_index);
5624  if (frag_stream_info) {
5625  frag_stream_info->next_trun_dts = AV_NOPTS_VALUE;
5626  frag_stream_info->stsd_id = frag->stsd_id;
5627  }
5628  return 0;
5629 }
5630 
5632 {
5633  unsigned i, num;
5634  void *new_tracks;
5635 
5636  num = atom.size / 4;
5637  if (!(new_tracks = av_malloc_array(num, sizeof(int))))
5638  return AVERROR(ENOMEM);
5639 
5640  av_free(c->chapter_tracks);
5641  c->chapter_tracks = new_tracks;
5642  c->nb_chapter_tracks = num;
5643 
5644  for (i = 0; i < num && !pb->eof_reached; i++)
5645  c->chapter_tracks[i] = avio_rb32(pb);
5646 
5647  c->nb_chapter_tracks = i;
5648 
5649  return 0;
5650 }
5651 
5653 {
5654  MOVTrackExt *trex;
5655  int err;
5656 
5657  if ((uint64_t)c->trex_count+1 >= UINT_MAX / sizeof(*c->trex_data))
5658  return AVERROR_INVALIDDATA;
5659  if ((err = av_reallocp_array(&c->trex_data, c->trex_count + 1,
5660  sizeof(*c->trex_data))) < 0) {
5661  c->trex_count = 0;
5662  return err;
5663  }
5664 
5665  c->fc->duration = AV_NOPTS_VALUE; // the duration from mvhd is not representing the whole file when fragments are used.
5666 
5667  trex = &c->trex_data[c->trex_count++];
5668  avio_r8(pb); /* version */
5669  avio_rb24(pb); /* flags */
5670  trex->track_id = avio_rb32(pb);
5671  trex->stsd_id = avio_rb32(pb);
5672  trex->duration = avio_rb32(pb);
5673  trex->size = avio_rb32(pb);
5674  trex->flags = avio_rb32(pb);
5675  return 0;
5676 }
5677 
5679 {
5680  MOVFragment *frag = &c->fragment;
5681  AVStream *st = NULL;
5682  MOVStreamContext *sc;
5683  int version, i;
5684  MOVFragmentStreamInfo * frag_stream_info;
5685  int64_t base_media_decode_time;
5686 
5687  for (i = 0; i < c->fc->nb_streams; i++) {
5688  sc = c->fc->streams[i]->priv_data;
5689  if (sc->id == frag->track_id) {
5690  st = c->fc->streams[i];
5691  break;
5692  }
5693  }
5694  if (!st) {
5695  av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %u\n", frag->track_id);
5696  return 0;
5697  }
5698  sc = st->priv_data;
5699  if (sc->pseudo_stream_id + 1 != frag->stsd_id && sc->pseudo_stream_id != -1)
5700  return 0;
5701  version = avio_r8(pb);
5702  avio_rb24(pb); /* flags */
5703  if (version) {
5704  base_media_decode_time = avio_rb64(pb);
5705  } else {
5706  base_media_decode_time = avio_rb32(pb);
5707  }
5708 
5709  frag_stream_info = get_current_frag_stream_info(&c->frag_index);
5710  if (frag_stream_info)
5711  frag_stream_info->tfdt_dts = base_media_decode_time;
5712  sc->track_end = base_media_decode_time;
5713 
5714  return 0;
5715 }
5716 
5718 {
5719  MOVFragment *frag = &c->fragment;
5720  AVStream *st = NULL;
5721  FFStream *sti = NULL;
5722  MOVStreamContext *sc;
5723  MOVTimeToSample *tts_data;
5724  uint64_t offset;
5725  int64_t dts, pts = AV_NOPTS_VALUE;
5726  int data_offset = 0;
5727  unsigned entries, first_sample_flags = frag->flags;
5728  int flags, distance, i;
5729  int64_t prev_dts = AV_NOPTS_VALUE;
5730  int next_frag_index = -1, index_entry_pos;
5731  size_t requested_size;
5732  size_t old_allocated_size;
5733  AVIndexEntry *new_entries;
5734  MOVFragmentStreamInfo * frag_stream_info;
5735 
5736  if (!frag->found_tfhd) {
5737  av_log(c->fc, AV_LOG_ERROR, "trun track id unknown, no tfhd was found\n");
5738  return AVERROR_INVALIDDATA;
5739  }
5740 
5741  for (i = 0; i < c->fc->nb_streams; i++) {
5742  sc = c->fc->streams[i]->priv_data;
5743  if (sc->id == frag->track_id) {
5744  st = c->fc->streams[i];
5745  sti = ffstream(st);
5746  break;
5747  }
5748  }
5749  if (!st) {
5750  av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %u\n", frag->track_id);
5751  return 0;
5752  }
5753  sc = st->priv_data;
5754  if (sc->pseudo_stream_id+1 != frag->stsd_id && sc->pseudo_stream_id != -1)
5755  return 0;
5756 
5757  // Find the next frag_index index that has a valid index_entry for
5758  // the current track_id.
5759  //
5760  // A valid index_entry means the trun for the fragment was read
5761  // and it's samples are in index_entries at the given position.
5762  // New index entries will be inserted before the index_entry found.
5763  index_entry_pos = sti->nb_index_entries;
5764  for (i = c->frag_index.current + 1; i < c->frag_index.nb_items; i++) {
5765  frag_stream_info = get_frag_stream_info(&c->frag_index, i, frag->track_id);
5766  if (frag_stream_info && frag_stream_info->index_entry >= 0) {
5767  next_frag_index = i;
5768  index_entry_pos = frag_stream_info->index_entry;
5769  break;
5770  }
5771  }
5772  av_assert0(index_entry_pos <= sti->nb_index_entries);
5773 
5774  avio_r8(pb); /* version */
5775  flags = avio_rb24(pb);
5776  entries = avio_rb32(pb);
5777  av_log(c->fc, AV_LOG_TRACE, "flags 0x%x entries %u\n", flags, entries);
5778 
5779  if ((uint64_t)entries+sc->tts_count >= UINT_MAX/sizeof(*sc->tts_data))
5780  return AVERROR_INVALIDDATA;
5781  if (flags & MOV_TRUN_DATA_OFFSET) data_offset = avio_rb32(pb);
5782  if (flags & MOV_TRUN_FIRST_SAMPLE_FLAGS) first_sample_flags = avio_rb32(pb);
5783 
5784  frag_stream_info = get_current_frag_stream_info(&c->frag_index);
5785  if (frag_stream_info) {
5786  if (frag_stream_info->next_trun_dts != AV_NOPTS_VALUE) {
5787  dts = frag_stream_info->next_trun_dts - sc->time_offset;
5788  } else if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE &&
5789  c->use_mfra_for == FF_MOV_FLAG_MFRA_PTS) {
5790  pts = frag_stream_info->first_tfra_pts;
5791  av_log(c->fc, AV_LOG_DEBUG, "found mfra time %"PRId64
5792  ", using it for pts\n", pts);
5793  } else if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE &&
5794  c->use_mfra_for == FF_MOV_FLAG_MFRA_DTS) {
5795  dts = frag_stream_info->first_tfra_pts;
5796  av_log(c->fc, AV_LOG_DEBUG, "found mfra time %"PRId64
5797  ", using it for dts\n", pts);
5798  } else {
5799  int has_tfdt = frag_stream_info->tfdt_dts != AV_NOPTS_VALUE;
5800  int has_sidx = frag_stream_info->sidx_pts != AV_NOPTS_VALUE;
5801  int fallback_tfdt = !c->use_tfdt && !has_sidx && has_tfdt;
5802  int fallback_sidx = c->use_tfdt && !has_tfdt && has_sidx;
5803 
5804  if (fallback_sidx) {
5805  av_log(c->fc, AV_LOG_DEBUG, "use_tfdt set but no tfdt found, using sidx instead\n");
5806  }
5807  if (fallback_tfdt) {
5808  av_log(c->fc, AV_LOG_DEBUG, "use_tfdt not set but no sidx found, using tfdt instead\n");
5809  }
5810 
5811  if (has_tfdt && c->use_tfdt || fallback_tfdt) {
5812  dts = frag_stream_info->tfdt_dts - sc->time_offset;
5813  av_log(c->fc, AV_LOG_DEBUG, "found tfdt time %"PRId64
5814  ", using it for dts\n", dts);
5815  } else if (has_sidx && !c->use_tfdt || fallback_sidx) {
5816  // FIXME: sidx earliest_presentation_time is *PTS*, s.b.
5817  // pts = frag_stream_info->sidx_pts;
5818  dts = frag_stream_info->sidx_pts - sc->time_offset;
5819  av_log(c->fc, AV_LOG_DEBUG, "found sidx time %"PRId64
5820  ", using it for dts\n", frag_stream_info->sidx_pts);
5821  } else {
5822  dts = sc->track_end - sc->time_offset;
5823  av_log(c->fc, AV_LOG_DEBUG, "found track end time %"PRId64
5824  ", using it for dts\n", dts);
5825  }
5826  }
5827  } else {
5828  dts = sc->track_end - sc->time_offset;
5829  av_log(c->fc, AV_LOG_DEBUG, "found track end time %"PRId64
5830  ", using it for dts\n", dts);
5831  }
5832  offset = frag->base_data_offset + data_offset;
5833  distance = 0;
5834  av_log(c->fc, AV_LOG_TRACE, "first sample flags 0x%x\n", first_sample_flags);
5835 
5836  // realloc space for new index entries
5837  if ((uint64_t)sti->nb_index_entries + entries >= UINT_MAX / sizeof(AVIndexEntry)) {
5838  entries = UINT_MAX / sizeof(AVIndexEntry) - sti->nb_index_entries;
5839  av_log(c->fc, AV_LOG_ERROR, "Failed to add index entry\n");
5840  }
5841  if (entries == 0)
5842  return 0;
5843 
5844  requested_size = (sti->nb_index_entries + entries) * sizeof(AVIndexEntry);
5845  new_entries = av_fast_realloc(sti->index_entries,
5847  requested_size);
5848  if (!new_entries)
5849  return AVERROR(ENOMEM);
5850  sti->index_entries= new_entries;
5851 
5852  requested_size = (sti->nb_index_entries + entries) * sizeof(*sc->tts_data);
5853  old_allocated_size = sc->tts_allocated_size;
5854  tts_data = av_fast_realloc(sc->tts_data, &sc->tts_allocated_size,
5855  requested_size);
5856  if (!tts_data)
5857  return AVERROR(ENOMEM);
5858  sc->tts_data = tts_data;
5859 
5860  // In case there were samples without time to sample entries, ensure they get
5861  // zero valued entries. This ensures clips which mix boxes with and
5862  // without time to sample entries don't pickup uninitialized data.
5863  memset((uint8_t*)(sc->tts_data) + old_allocated_size, 0,
5864  sc->tts_allocated_size - old_allocated_size);
5865 
5866  if (index_entry_pos < sti->nb_index_entries) {
5867  // Make hole in index_entries and tts_data for new samples
5868  memmove(sti->index_entries + index_entry_pos + entries,
5869  sti->index_entries + index_entry_pos,
5870  sizeof(*sti->index_entries) *
5871  (sti->nb_index_entries - index_entry_pos));
5872  memmove(sc->tts_data + index_entry_pos + entries,
5873  sc->tts_data + index_entry_pos,
5874  sizeof(*sc->tts_data) * (sc->tts_count - index_entry_pos));
5875  if (index_entry_pos < sc->current_sample) {
5876  sc->current_sample += entries;
5877  }
5878  }
5879 
5880  sti->nb_index_entries += entries;
5881  sc->tts_count = sti->nb_index_entries;
5882  sc->stts_count = sti->nb_index_entries;
5883  if (flags & MOV_TRUN_SAMPLE_CTS)
5884  sc->ctts_count = sti->nb_index_entries;
5885 
5886  // Record the index_entry position in frag_index of this fragment
5887  if (frag_stream_info) {
5888  frag_stream_info->index_entry = index_entry_pos;
5889  if (frag_stream_info->index_base < 0)
5890  frag_stream_info->index_base = index_entry_pos;
5891  }
5892 
5893  if (index_entry_pos > 0)
5894  prev_dts = sti->index_entries[index_entry_pos-1].timestamp;
5895 
5896  for (i = 0; i < entries && !pb->eof_reached; i++) {
5897  unsigned sample_size = frag->size;
5898  int sample_flags = i ? frag->flags : first_sample_flags;
5899  unsigned sample_duration = frag->duration;
5900  unsigned ctts_duration = 0;
5901  int keyframe = 0;
5902  int index_entry_flags = 0;
5903 
5904  if (flags & MOV_TRUN_SAMPLE_DURATION) sample_duration = avio_rb32(pb);
5905  if (flags & MOV_TRUN_SAMPLE_SIZE) sample_size = avio_rb32(pb);
5906  if (flags & MOV_TRUN_SAMPLE_FLAGS) sample_flags = avio_rb32(pb);
5907  if (flags & MOV_TRUN_SAMPLE_CTS) ctts_duration = avio_rb32(pb);
5908 
5909  mov_update_dts_shift(sc, ctts_duration, c->fc);
5910  if (pts != AV_NOPTS_VALUE) {
5911  dts = pts - sc->dts_shift;
5912  if (flags & MOV_TRUN_SAMPLE_CTS) {
5913  dts -= ctts_duration;
5914  } else {
5915  dts -= sc->time_offset;
5916  }
5917  av_log(c->fc, AV_LOG_DEBUG,
5918  "pts %"PRId64" calculated dts %"PRId64
5919  " sc->dts_shift %d ctts.duration %d"
5920  " sc->time_offset %"PRId64
5921  " flags & MOV_TRUN_SAMPLE_CTS %d\n",
5922  pts, dts,
5923  sc->dts_shift, ctts_duration,
5925  pts = AV_NOPTS_VALUE;
5926  }
5927 
5928  keyframe =
5929  !(sample_flags & (MOV_FRAG_SAMPLE_FLAG_IS_NON_SYNC |
5931  if (keyframe) {
5932  distance = 0;
5933  index_entry_flags |= AVINDEX_KEYFRAME;
5934  }
5935  // Fragments can overlap in time. Discard overlapping frames after
5936  // decoding.
5937  if (prev_dts >= dts)
5938  index_entry_flags |= AVINDEX_DISCARD_FRAME;
5939 
5940  sti->index_entries[index_entry_pos].pos = offset;
5941  sti->index_entries[index_entry_pos].timestamp = dts;
5942  sti->index_entries[index_entry_pos].size = sample_size;
5943  sti->index_entries[index_entry_pos].min_distance = distance;
5944  sti->index_entries[index_entry_pos].flags = index_entry_flags;
5945 
5946  sc->tts_data[index_entry_pos].count = 1;
5947  sc->tts_data[index_entry_pos].offset = ctts_duration;
5948  sc->tts_data[index_entry_pos].duration = sample_duration;
5949  index_entry_pos++;
5950 
5951  av_log(c->fc, AV_LOG_TRACE, "AVIndex stream %d, sample %d, offset %"PRIx64", dts %"PRId64", "
5952  "size %u, distance %d, keyframe %d\n", st->index,
5953  index_entry_pos, offset, dts, sample_size, distance, keyframe);
5954  distance++;
5955  if (av_sat_add64(dts, sample_duration) != dts + (uint64_t)sample_duration)
5956  return AVERROR_INVALIDDATA;
5957  if (!sample_size)
5958  return AVERROR_INVALIDDATA;
5959  dts += sample_duration;
5960  offset += sample_size;
5961  sc->data_size += sample_size;
5962 
5963  if (sample_duration <= INT64_MAX - sc->duration_for_fps &&
5964  1 <= INT_MAX - sc->nb_frames_for_fps
5965  ) {
5966  sc->duration_for_fps += sample_duration;
5967  sc->nb_frames_for_fps ++;
5968  }
5969  }
5970  if (frag_stream_info)
5971  frag_stream_info->next_trun_dts = dts + sc->time_offset;
5972  if (i < entries) {
5973  // EOF found before reading all entries. Fix the hole this would
5974  // leave in index_entries and tts_data
5975  int gap = entries - i;
5976  memmove(sti->index_entries + index_entry_pos,
5977  sti->index_entries + index_entry_pos + gap,
5978  sizeof(*sti->index_entries) *
5979  (sti->nb_index_entries - (index_entry_pos + gap)));
5980  memmove(sc->tts_data + index_entry_pos,
5981  sc->tts_data + index_entry_pos + gap,
5982  sizeof(*sc->tts_data) *
5983  (sc->tts_count - (index_entry_pos + gap)));
5984 
5985  sti->nb_index_entries -= gap;
5986  sc->tts_count -= gap;
5987  if (index_entry_pos < sc->current_sample) {
5988  sc->current_sample -= gap;
5989  }
5990  entries = i;
5991  }
5992 
5993  // The end of this new fragment may overlap in time with the start
5994  // of the next fragment in index_entries. Mark the samples in the next
5995  // fragment that overlap with AVINDEX_DISCARD_FRAME
5996  prev_dts = AV_NOPTS_VALUE;
5997  if (index_entry_pos > 0)
5998  prev_dts = sti->index_entries[index_entry_pos-1].timestamp;
5999  for (int i = index_entry_pos; i < sti->nb_index_entries; i++) {
6000  if (prev_dts < sti->index_entries[i].timestamp)
6001  break;
6003  }
6004 
6005  // If a hole was created to insert the new index_entries into,
6006  // the index_entry recorded for all subsequent moof must
6007  // be incremented by the number of entries inserted.
6008  fix_frag_index_entries(&c->frag_index, next_frag_index,
6009  frag->track_id, entries);
6010 
6011  if (pb->eof_reached) {
6012  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted TRUN atom\n");
6013  return AVERROR_EOF;
6014  }
6015 
6016  frag->implicit_offset = offset;
6017 
6018  sc->track_end = dts + sc->time_offset;
6019  if (st->duration < sc->track_end)
6020  st->duration = sc->track_end;
6021 
6022  return 0;
6023 }
6024 
6026 {
6027  int64_t stream_size = avio_size(pb);
6028  int64_t offset = av_sat_add64(avio_tell(pb), atom.size), pts, timestamp;
6029  uint8_t version, is_complete;
6030  int64_t offadd;
6031  unsigned i, j, track_id, item_count;
6032  AVStream *st = NULL;
6033  AVStream *ref_st = NULL;
6034  MOVStreamContext *sc, *ref_sc = NULL;
6035  AVRational timescale;
6036 
6037  version = avio_r8(pb);
6038  if (version > 1) {
6039  avpriv_request_sample(c->fc, "sidx version %u", version);
6040  return 0;
6041  }
6042 
6043  avio_rb24(pb); // flags
6044 
6045  track_id = avio_rb32(pb); // Reference ID
6046  for (i = 0; i < c->fc->nb_streams; i++) {
6047  sc = c->fc->streams[i]->priv_data;
6048  if (sc->id == track_id) {
6049  st = c->fc->streams[i];
6050  break;
6051  }
6052  }
6053  if (!st) {
6054  av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %d\n", track_id);
6055  return 0;
6056  }
6057 
6058  sc = st->priv_data;
6059 
6060  timescale = av_make_q(1, avio_rb32(pb));
6061 
6062  if (timescale.den <= 0) {
6063  av_log(c->fc, AV_LOG_ERROR, "Invalid sidx timescale 1/%d\n", timescale.den);
6064  return AVERROR_INVALIDDATA;
6065  }
6066 
6067  if (version == 0) {
6068  pts = avio_rb32(pb);
6069  offadd= avio_rb32(pb);
6070  } else {
6071  pts = avio_rb64(pb);
6072  offadd= avio_rb64(pb);
6073  }
6074  if (av_sat_add64(offset, offadd) != offset + (uint64_t)offadd)
6075  return AVERROR_INVALIDDATA;
6076 
6077  offset += (uint64_t)offadd;
6078 
6079  avio_rb16(pb); // reserved
6080 
6081  item_count = avio_rb16(pb);
6082  if (item_count == 0)
6083  return AVERROR_INVALIDDATA;
6084 
6085  for (i = 0; i < item_count; i++) {
6086  int index;
6087  MOVFragmentStreamInfo * frag_stream_info;
6088  uint32_t size = avio_rb32(pb);
6089  uint32_t duration = avio_rb32(pb);
6090  if (size & 0x80000000) {
6091  avpriv_request_sample(c->fc, "sidx reference_type 1");
6092  return AVERROR_PATCHWELCOME;
6093  }
6094  avio_rb32(pb); // sap_flags
6095  timestamp = av_rescale_q(pts, timescale, st->time_base);
6096 
6098  frag_stream_info = get_frag_stream_info(&c->frag_index, index, track_id);
6099  if (frag_stream_info)
6100  frag_stream_info->sidx_pts = timestamp;
6101 
6102  if (av_sat_add64(offset, size) != offset + (uint64_t)size ||
6103  av_sat_add64(pts, duration) != pts + (uint64_t)duration
6104  )
6105  return AVERROR_INVALIDDATA;
6106  offset += size;
6107  pts += duration;
6108  }
6109 
6110  st->duration = sc->track_end = pts;
6111 
6112  sc->has_sidx = 1;
6113 
6114  // See if the remaining bytes are just an mfra which we can ignore.
6115  is_complete = offset == stream_size;
6116  if (!is_complete && (pb->seekable & AVIO_SEEKABLE_NORMAL) && stream_size > 0 ) {
6117  int64_t ret;
6118  int64_t original_pos = avio_tell(pb);
6119  if (!c->have_read_mfra_size) {
6120  if ((ret = avio_seek(pb, stream_size - 4, SEEK_SET)) < 0)
6121  return ret;
6122  c->mfra_size = avio_rb32(pb);
6123  c->have_read_mfra_size = 1;
6124  if ((ret = avio_seek(pb, original_pos, SEEK_SET)) < 0)
6125  return ret;
6126  }
6127  if (offset == stream_size - c->mfra_size)
6128  is_complete = 1;
6129  }
6130 
6131  if (is_complete) {
6132  // Find first entry in fragment index that came from an sidx.
6133  // This will pretty much always be the first entry.
6134  for (i = 0; i < c->frag_index.nb_items; i++) {
6135  MOVFragmentIndexItem * item = &c->frag_index.item[i];
6136  for (j = 0; ref_st == NULL && j < item->nb_stream_info; j++) {
6137  MOVFragmentStreamInfo * si;
6138  si = &item->stream_info[j];
6139  if (si->sidx_pts != AV_NOPTS_VALUE) {
6140  ref_st = c->fc->streams[j];
6141  ref_sc = ref_st->priv_data;
6142  break;
6143  }
6144  }
6145  }
6146  if (ref_st) for (i = 0; i < c->fc->nb_streams; i++) {
6147  st = c->fc->streams[i];
6148  sc = st->priv_data;
6149  if (!sc->has_sidx) {
6150  st->duration = sc->track_end = av_rescale(ref_st->duration, sc->time_scale, ref_sc->time_scale);
6151  }
6152  }
6153 
6154  c->frag_index.complete = 1;
6155  }
6156 
6157  return 0;
6158 }
6159 
6160 /* this atom should be null (from specs), but some buggy files put the 'moov' atom inside it... */
6161 /* like the files created with Adobe Premiere 5.0, for samples see */
6162 /* http://graphics.tudelft.nl/~wouter/publications/soundtests/ */
6164 {
6165  int err;
6166 
6167  if (atom.size < 8)
6168  return 0; /* continue */
6169  if (avio_rb32(pb) != 0) { /* 0 sized mdat atom... use the 'wide' atom size */
6170  avio_skip(pb, atom.size - 4);
6171  return 0;
6172  }
6173  atom.type = avio_rl32(pb);
6174  atom.size -= 8;
6175  if (atom.type != MKTAG('m','d','a','t')) {
6176  avio_skip(pb, atom.size);
6177  return 0;
6178  }
6179  err = mov_read_mdat(c, pb, atom);
6180  return err;
6181 }
6182 
6184 {
6185 #if CONFIG_ZLIB
6186  FFIOContext ctx;
6187  uint8_t *cmov_data;
6188  uint8_t *moov_data; /* uncompressed data */
6189  long cmov_len, moov_len;
6190  int ret = -1;
6191 
6192  avio_rb32(pb); /* dcom atom */
6193  if (avio_rl32(pb) != MKTAG('d','c','o','m'))
6194  return AVERROR_INVALIDDATA;
6195  if (avio_rl32(pb) != MKTAG('z','l','i','b')) {
6196  av_log(c->fc, AV_LOG_ERROR, "unknown compression for cmov atom !\n");
6197  return AVERROR_INVALIDDATA;
6198  }
6199  avio_rb32(pb); /* cmvd atom */
6200  if (avio_rl32(pb) != MKTAG('c','m','v','d'))
6201  return AVERROR_INVALIDDATA;
6202  moov_len = avio_rb32(pb); /* uncompressed size */
6203  cmov_len = atom.size - 6 * 4;
6204 
6205  cmov_data = av_malloc(cmov_len);
6206  if (!cmov_data)
6207  return AVERROR(ENOMEM);
6208  moov_data = av_malloc(moov_len);
6209  if (!moov_data) {
6210  av_free(cmov_data);
6211  return AVERROR(ENOMEM);
6212  }
6213  ret = ffio_read_size(pb, cmov_data, cmov_len);
6214  if (ret < 0)
6215  goto free_and_return;
6216 
6218  if (uncompress (moov_data, (uLongf *) &moov_len, (const Bytef *)cmov_data, cmov_len) != Z_OK)
6219  goto free_and_return;
6220  ffio_init_read_context(&ctx, moov_data, moov_len);
6221  ctx.pub.seekable = AVIO_SEEKABLE_NORMAL;
6222  atom.type = MKTAG('m','o','o','v');
6223  atom.size = moov_len;
6224  ret = mov_read_default(c, &ctx.pub, atom);
6225 free_and_return:
6226  av_free(moov_data);
6227  av_free(cmov_data);
6228  return ret;
6229 #else
6230  av_log(c->fc, AV_LOG_ERROR, "this file requires zlib support compiled in\n");
6231  return AVERROR(ENOSYS);
6232 #endif
6233 }
6234 
6235 /* edit list atom */
6237 {
6238  MOVStreamContext *sc;
6239  int i, edit_count, version;
6240  int64_t elst_entry_size;
6241 
6242  if (c->fc->nb_streams < 1 || c->ignore_editlist)
6243  return 0;
6244  sc = c->fc->streams[c->fc->nb_streams-1]->priv_data;
6245 
6246  version = avio_r8(pb); /* version */
6247  avio_rb24(pb); /* flags */
6248  edit_count = avio_rb32(pb); /* entries */
6249  atom.size -= 8;
6250 
6251  elst_entry_size = version == 1 ? 20 : 12;
6252  if (atom.size != edit_count * elst_entry_size) {
6253  if (c->fc->strict_std_compliance >= FF_COMPLIANCE_STRICT) {
6254  av_log(c->fc, AV_LOG_ERROR, "Invalid edit list entry_count: %d for elst atom of size: %"PRId64" bytes.\n",
6255  edit_count, atom.size + 8);
6256  return AVERROR_INVALIDDATA;
6257  } else {
6258  edit_count = atom.size / elst_entry_size;
6259  if (edit_count * elst_entry_size != atom.size) {
6260  av_log(c->fc, AV_LOG_WARNING, "ELST atom of %"PRId64" bytes, bigger than %d entries.\n", atom.size, edit_count);
6261  }
6262  }
6263  }
6264 
6265  if (!edit_count)
6266  return 0;
6267  if (sc->elst_data)
6268  av_log(c->fc, AV_LOG_WARNING, "Duplicated ELST atom\n");
6269  av_free(sc->elst_data);
6270  sc->elst_count = 0;
6271  sc->elst_data = av_malloc_array(edit_count, sizeof(*sc->elst_data));
6272  if (!sc->elst_data)
6273  return AVERROR(ENOMEM);
6274 
6275  av_log(c->fc, AV_LOG_TRACE, "track[%u].edit_count = %i\n", c->fc->nb_streams - 1, edit_count);
6276  for (i = 0; i < edit_count && atom.size > 0 && !pb->eof_reached; i++) {
6277  MOVElst *e = &sc->elst_data[i];
6278 
6279  if (version == 1) {
6280  e->duration = avio_rb64(pb);
6281  e->time = avio_rb64(pb);
6282  atom.size -= 16;
6283  } else {
6284  e->duration = avio_rb32(pb); /* segment duration */
6285  e->time = (int32_t)avio_rb32(pb); /* media time */
6286  atom.size -= 8;
6287  }
6288  e->rate = avio_rb32(pb) / 65536.0;
6289  atom.size -= 4;
6290  av_log(c->fc, AV_LOG_TRACE, "duration=%"PRId64" time=%"PRId64" rate=%f\n",
6291  e->duration, e->time, e->rate);
6292 
6293  if (e->time < 0 && e->time != -1 &&
6294  c->fc->strict_std_compliance >= FF_COMPLIANCE_STRICT) {
6295  av_log(c->fc, AV_LOG_ERROR, "Track %d, edit %d: Invalid edit list media time=%"PRId64"\n",
6296  c->fc->nb_streams-1, i, e->time);
6297  return AVERROR_INVALIDDATA;
6298  }
6299  }
6300  sc->elst_count = i;
6301 
6302  return 0;
6303 }
6304 
6306 {
6307  MOVStreamContext *sc;
6308 
6309  if (c->fc->nb_streams < 1)
6310  return AVERROR_INVALIDDATA;
6311  sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
6312  sc->timecode_track = avio_rb32(pb);
6313  return 0;
6314 }
6315 
6317 {
6318  AVStream *st;
6319  int version, color_range, color_primaries, color_trc, color_space;
6320 
6321  if (c->fc->nb_streams < 1)
6322  return 0;
6323  st = c->fc->streams[c->fc->nb_streams - 1];
6324 
6325  if (atom.size < 5) {
6326  av_log(c->fc, AV_LOG_ERROR, "Empty VP Codec Configuration box\n");
6327  return AVERROR_INVALIDDATA;
6328  }
6329 
6330  version = avio_r8(pb);
6331  if (version != 1) {
6332  av_log(c->fc, AV_LOG_WARNING, "Unsupported VP Codec Configuration box version %d\n", version);
6333  return 0;
6334  }
6335  avio_skip(pb, 3); /* flags */
6336 
6337  avio_skip(pb, 2); /* profile + level */
6338  color_range = avio_r8(pb); /* bitDepth, chromaSubsampling, videoFullRangeFlag */
6339  color_primaries = avio_r8(pb);
6340  color_trc = avio_r8(pb);
6341  color_space = avio_r8(pb);
6342  if (avio_rb16(pb)) /* codecIntializationDataSize */
6343  return AVERROR_INVALIDDATA;
6344 
6347  if (!av_color_transfer_name(color_trc))
6348  color_trc = AVCOL_TRC_UNSPECIFIED;
6349  if (!av_color_space_name(color_space))
6350  color_space = AVCOL_SPC_UNSPECIFIED;
6351 
6354  st->codecpar->color_trc = color_trc;
6355  st->codecpar->color_space = color_space;
6356 
6357  return 0;
6358 }
6359 
6361 {
6362  MOVStreamContext *sc;
6363  int i, version;
6364 
6365  if (c->fc->nb_streams < 1)
6366  return AVERROR_INVALIDDATA;
6367 
6368  sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
6369 
6370  if (atom.size < 5) {
6371  av_log(c->fc, AV_LOG_ERROR, "Empty Mastering Display Metadata box\n");
6372  return AVERROR_INVALIDDATA;
6373  }
6374 
6375  version = avio_r8(pb);
6376  if (version) {
6377  av_log(c->fc, AV_LOG_WARNING, "Unsupported Mastering Display Metadata box version %d\n", version);
6378  return 0;
6379  }
6380  if (sc->mastering) {
6381  av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicate Mastering Display Metadata\n");
6382  return 0;
6383  }
6384 
6385  avio_skip(pb, 3); /* flags */
6386 
6388  if (!sc->mastering)
6389  return AVERROR(ENOMEM);
6390 
6391  for (i = 0; i < 3; i++) {
6392  sc->mastering->display_primaries[i][0] = av_make_q(avio_rb16(pb), 1 << 16);
6393  sc->mastering->display_primaries[i][1] = av_make_q(avio_rb16(pb), 1 << 16);
6394  }
6395  sc->mastering->white_point[0] = av_make_q(avio_rb16(pb), 1 << 16);
6396  sc->mastering->white_point[1] = av_make_q(avio_rb16(pb), 1 << 16);
6397 
6398  sc->mastering->max_luminance = av_make_q(avio_rb32(pb), 1 << 8);
6399  sc->mastering->min_luminance = av_make_q(avio_rb32(pb), 1 << 14);
6400 
6401  sc->mastering->has_primaries = 1;
6402  sc->mastering->has_luminance = 1;
6403 
6404  return 0;
6405 }
6406 
6408 {
6409  MOVStreamContext *sc;
6410  const int mapping[3] = {1, 2, 0};
6411  const int chroma_den = 50000;
6412  const int luma_den = 10000;
6413  int i;
6414 
6415  if (c->fc->nb_streams < 1)
6416  return AVERROR_INVALIDDATA;
6417 
6418  sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
6419 
6420  if (atom.size < 24) {
6421  av_log(c->fc, AV_LOG_ERROR, "Invalid Mastering Display Color Volume box\n");
6422  return AVERROR_INVALIDDATA;
6423  }
6424 
6425  if (sc->mastering) {
6426  av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicate Mastering Display Color Volume\n");
6427  return 0;
6428  }
6429 
6431  if (!sc->mastering)
6432  return AVERROR(ENOMEM);
6433 
6434  for (i = 0; i < 3; i++) {
6435  const int j = mapping[i];
6436  sc->mastering->display_primaries[j][0] = av_make_q(avio_rb16(pb), chroma_den);
6437  sc->mastering->display_primaries[j][1] = av_make_q(avio_rb16(pb), chroma_den);
6438  }
6439  sc->mastering->white_point[0] = av_make_q(avio_rb16(pb), chroma_den);
6440  sc->mastering->white_point[1] = av_make_q(avio_rb16(pb), chroma_den);
6441 
6442  sc->mastering->max_luminance = av_make_q(avio_rb32(pb), luma_den);
6443  sc->mastering->min_luminance = av_make_q(avio_rb32(pb), luma_den);
6444 
6445  sc->mastering->has_luminance = 1;
6446  sc->mastering->has_primaries = 1;
6447 
6448  return 0;
6449 }
6450 
6452 {
6453  MOVStreamContext *sc;
6454  int version;
6455 
6456  if (c->fc->nb_streams < 1)
6457  return AVERROR_INVALIDDATA;
6458 
6459  sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
6460 
6461  if (atom.size < 5) {
6462  av_log(c->fc, AV_LOG_ERROR, "Empty Content Light Level box\n");
6463  return AVERROR_INVALIDDATA;
6464  }
6465 
6466  version = avio_r8(pb);
6467  if (version) {
6468  av_log(c->fc, AV_LOG_WARNING, "Unsupported Content Light Level box version %d\n", version);
6469  return 0;
6470  }
6471  avio_skip(pb, 3); /* flags */
6472 
6473  if (sc->coll){
6474  av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicate COLL\n");
6475  return 0;
6476  }
6477 
6479  if (!sc->coll)
6480  return AVERROR(ENOMEM);
6481 
6482  sc->coll->MaxCLL = avio_rb16(pb);
6483  sc->coll->MaxFALL = avio_rb16(pb);
6484 
6485  return 0;
6486 }
6487 
6489 {
6490  MOVStreamContext *sc;
6491 
6492  if (c->fc->nb_streams < 1)
6493  return AVERROR_INVALIDDATA;
6494 
6495  sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
6496 
6497  if (atom.size < 4) {
6498  av_log(c->fc, AV_LOG_ERROR, "Empty Content Light Level Info box\n");
6499  return AVERROR_INVALIDDATA;
6500  }
6501 
6502  if (sc->coll){
6503  av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicate CLLI/COLL\n");
6504  return 0;
6505  }
6506 
6508  if (!sc->coll)
6509  return AVERROR(ENOMEM);
6510 
6511  sc->coll->MaxCLL = avio_rb16(pb);
6512  sc->coll->MaxFALL = avio_rb16(pb);
6513 
6514  return 0;
6515 }
6516 
6518 {
6519  MOVStreamContext *sc;
6520  const int illuminance_den = 10000;
6521  const int ambient_den = 50000;
6522  if (c->fc->nb_streams < 1)
6523  return AVERROR_INVALIDDATA;
6524  sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
6525  if (atom.size < 6) {
6526  av_log(c->fc, AV_LOG_ERROR, "Empty Ambient Viewing Environment Info box\n");
6527  return AVERROR_INVALIDDATA;
6528  }
6529  if (sc->ambient){
6530  av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicate AMVE\n");
6531  return 0;
6532  }
6534  if (!sc->ambient)
6535  return AVERROR(ENOMEM);
6536  sc->ambient->ambient_illuminance = av_make_q(avio_rb32(pb), illuminance_den);
6537  sc->ambient->ambient_light_x = av_make_q(avio_rb16(pb), ambient_den);
6538  sc->ambient->ambient_light_y = av_make_q(avio_rb16(pb), ambient_den);
6539  return 0;
6540 }
6541 
6543 {
6544  AVStream *st;
6545  MOVStreamContext *sc;
6546  enum AVStereo3DType type;
6547  int mode;
6548 
6549  if (c->fc->nb_streams < 1)
6550  return 0;
6551 
6552  st = c->fc->streams[c->fc->nb_streams - 1];
6553  sc = st->priv_data;
6554 
6555  if (atom.size < 5) {
6556  av_log(c->fc, AV_LOG_ERROR, "Empty stereoscopic video box\n");
6557  return AVERROR_INVALIDDATA;
6558  }
6559 
6560  if (sc->stereo3d)
6561  return AVERROR_INVALIDDATA;
6562 
6563  avio_skip(pb, 4); /* version + flags */
6564 
6565  mode = avio_r8(pb);
6566  switch (mode) {
6567  case 0:
6568  type = AV_STEREO3D_2D;
6569  break;
6570  case 1:
6572  break;
6573  case 2:
6575  break;
6576  default:
6577  av_log(c->fc, AV_LOG_WARNING, "Unknown st3d mode value %d\n", mode);
6578  return 0;
6579  }
6580 
6582  if (!sc->stereo3d)
6583  return AVERROR(ENOMEM);
6584 
6585  sc->stereo3d->type = type;
6586  return 0;
6587 }
6588 
6590 {
6591  AVStream *st;
6592  MOVStreamContext *sc;
6593  int size, version, layout;
6594  int32_t yaw, pitch, roll;
6595  uint32_t l = 0, t = 0, r = 0, b = 0;
6596  uint32_t tag, padding = 0;
6597  enum AVSphericalProjection projection;
6598 
6599  if (c->fc->nb_streams < 1)
6600  return 0;
6601 
6602  st = c->fc->streams[c->fc->nb_streams - 1];
6603  sc = st->priv_data;
6604 
6605  if (atom.size < 8) {
6606  av_log(c->fc, AV_LOG_ERROR, "Empty spherical video box\n");
6607  return AVERROR_INVALIDDATA;
6608  }
6609 
6610  size = avio_rb32(pb);
6611  if (size <= 12 || size > atom.size)
6612  return AVERROR_INVALIDDATA;
6613 
6614  tag = avio_rl32(pb);
6615  if (tag != MKTAG('s','v','h','d')) {
6616  av_log(c->fc, AV_LOG_ERROR, "Missing spherical video header\n");
6617  return 0;
6618  }
6619  version = avio_r8(pb);
6620  if (version != 0) {
6621  av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
6622  version);
6623  return 0;
6624  }
6625  avio_skip(pb, 3); /* flags */
6626  avio_skip(pb, size - 12); /* metadata_source */
6627 
6628  size = avio_rb32(pb);
6629  if (size > atom.size)
6630  return AVERROR_INVALIDDATA;
6631 
6632  tag = avio_rl32(pb);
6633  if (tag != MKTAG('p','r','o','j')) {
6634  av_log(c->fc, AV_LOG_ERROR, "Missing projection box\n");
6635  return 0;
6636  }
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','h','d')) {
6644  av_log(c->fc, AV_LOG_ERROR, "Missing projection header box\n");
6645  return 0;
6646  }
6647  version = avio_r8(pb);
6648  if (version != 0) {
6649  av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
6650  version);
6651  return 0;
6652  }
6653  avio_skip(pb, 3); /* flags */
6654 
6655  /* 16.16 fixed point */
6656  yaw = avio_rb32(pb);
6657  pitch = avio_rb32(pb);
6658  roll = avio_rb32(pb);
6659 
6660  size = avio_rb32(pb);
6661  if (size > atom.size)
6662  return AVERROR_INVALIDDATA;
6663 
6664  tag = avio_rl32(pb);
6665  version = avio_r8(pb);
6666  if (version != 0) {
6667  av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
6668  version);
6669  return 0;
6670  }
6671  avio_skip(pb, 3); /* flags */
6672  switch (tag) {
6673  case MKTAG('c','b','m','p'):
6674  layout = avio_rb32(pb);
6675  if (layout) {
6676  av_log(c->fc, AV_LOG_WARNING,
6677  "Unsupported cubemap layout %d\n", layout);
6678  return 0;
6679  }
6680  projection = AV_SPHERICAL_CUBEMAP;
6681  padding = avio_rb32(pb);
6682  break;
6683  case MKTAG('e','q','u','i'):
6684  t = avio_rb32(pb);
6685  b = avio_rb32(pb);
6686  l = avio_rb32(pb);
6687  r = avio_rb32(pb);
6688 
6689  if (b >= UINT_MAX - t || r >= UINT_MAX - l) {
6690  av_log(c->fc, AV_LOG_ERROR,
6691  "Invalid bounding rectangle coordinates "
6692  "%"PRIu32",%"PRIu32",%"PRIu32",%"PRIu32"\n", l, t, r, b);
6693  return AVERROR_INVALIDDATA;
6694  }
6695 
6696  if (l || t || r || b)
6697  projection = AV_SPHERICAL_EQUIRECTANGULAR_TILE;
6698  else
6699  projection = AV_SPHERICAL_EQUIRECTANGULAR;
6700  break;
6701  default:
6702  av_log(c->fc, AV_LOG_ERROR, "Unknown projection type: %s\n", av_fourcc2str(tag));
6703  return 0;
6704  }
6705 
6707  if (!sc->spherical)
6708  return AVERROR(ENOMEM);
6709 
6710  sc->spherical->projection = projection;
6711 
6712  sc->spherical->yaw = yaw;
6713  sc->spherical->pitch = pitch;
6714  sc->spherical->roll = roll;
6715 
6716  sc->spherical->padding = padding;
6717 
6718  sc->spherical->bound_left = l;
6719  sc->spherical->bound_top = t;
6720  sc->spherical->bound_right = r;
6721  sc->spherical->bound_bottom = b;
6722 
6723  return 0;
6724 }
6725 
6727 {
6728  AVStream *st;
6729  MOVStreamContext *sc;
6730  int size;
6731  uint32_t tag;
6732  enum AVSphericalProjection projection;
6733 
6734  if (c->fc->nb_streams < 1)
6735  return 0;
6736 
6737  st = c->fc->streams[c->fc->nb_streams - 1];
6738  sc = st->priv_data;
6739 
6740  if (atom.size != 16) {
6741  av_log(c->fc, AV_LOG_ERROR, "Invalid size for proj box: %"PRIu64"\n", atom.size);
6742  return AVERROR_INVALIDDATA;
6743  }
6744 
6745  size = avio_rb32(pb);
6746  if (size != 16) {
6747  av_log(c->fc, AV_LOG_ERROR, "Invalid size for prji box: %d\n", size);
6748  return AVERROR_INVALIDDATA;
6749  }
6750 
6751  tag = avio_rl32(pb);
6752  if (tag != MKTAG('p','r','j','i')) {
6753  av_log(c->fc, AV_LOG_ERROR, "Invalid child box of proj box: 0x%08X\n", tag);
6754  return AVERROR_INVALIDDATA;
6755  }
6756 
6757  avio_skip(pb, 1); // version
6758  avio_skip(pb, 3); // flags
6759 
6760  tag = avio_rl32(pb);
6761  switch (tag) {
6762  case MKTAG('r','e','c','t'):
6763  projection = AV_SPHERICAL_RECTILINEAR;
6764  break;
6765  case MKTAG('e','q','u','i'):
6766  projection = AV_SPHERICAL_EQUIRECTANGULAR;
6767  break;
6768  case MKTAG('h','e','q','u'):
6769  projection = AV_SPHERICAL_HALF_EQUIRECTANGULAR;
6770  break;
6771  case MKTAG('f','i','s','h'):
6772  projection = AV_SPHERICAL_FISHEYE;
6773  break;
6774  default:
6775  av_log(c->fc, AV_LOG_ERROR, "Invalid projection type in prji box: 0x%08X\n", tag);
6776  return AVERROR_INVALIDDATA;
6777  }
6778 
6780  if (!sc->spherical)
6781  return AVERROR(ENOMEM);
6782 
6783  sc->spherical->projection = projection;
6784 
6785  return 0;
6786 }
6787 
6789 {
6790  AVStream *st;
6791  MOVStreamContext *sc;
6792  int size, flags = 0;
6793  int64_t remaining;
6794  uint32_t tag, baseline = 0;
6797  enum AVStereo3DPrimaryEye primary_eye = AV_PRIMARY_EYE_NONE;
6798  AVRational horizontal_disparity_adjustment = { 0, 1 };
6799 
6800  if (c->fc->nb_streams < 1)
6801  return 0;
6802 
6803  st = c->fc->streams[c->fc->nb_streams - 1];
6804  sc = st->priv_data;
6805 
6806  remaining = atom.size;
6807  while (remaining > 0) {
6808  size = avio_rb32(pb);
6809  if (size < 8 || size > remaining ) {
6810  av_log(c->fc, AV_LOG_ERROR, "Invalid child size in eyes box\n");
6811  return AVERROR_INVALIDDATA;
6812  }
6813 
6814  tag = avio_rl32(pb);
6815  switch (tag) {
6816  case MKTAG('s','t','r','i'): {
6817  int has_right, has_left;
6818  uint8_t tmp;
6819  if (size != 13) {
6820  av_log(c->fc, AV_LOG_ERROR, "Invalid size of stri box: %d\n", size);
6821  return AVERROR_INVALIDDATA;
6822  }
6823  avio_skip(pb, 1); // version
6824  avio_skip(pb, 3); // flags
6825 
6826  tmp = avio_r8(pb);
6827 
6828  // eye_views_reversed
6829  if (tmp & 8) {
6831  }
6832  // has_additional_views
6833  if (tmp & 4) {
6834  // skip...
6835  }
6836 
6837  has_right = tmp & 2; // has_right_eye_view
6838  has_left = tmp & 1; // has_left_eye_view
6839 
6840  if (has_left && has_right)
6841  view = AV_STEREO3D_VIEW_PACKED;
6842  else if (has_left)
6843  view = AV_STEREO3D_VIEW_LEFT;
6844  else if (has_right)
6845  view = AV_STEREO3D_VIEW_RIGHT;
6846  if (has_left || has_right)
6848 
6849  break;
6850  }
6851  case MKTAG('h','e','r','o'): {
6852  int tmp;
6853  if (size != 13) {
6854  av_log(c->fc, AV_LOG_ERROR, "Invalid size of hero box: %d\n", size);
6855  return AVERROR_INVALIDDATA;
6856  }
6857  avio_skip(pb, 1); // version
6858  avio_skip(pb, 3); // flags
6859 
6860  tmp = avio_r8(pb);
6861  if (tmp == 0)
6862  primary_eye = AV_PRIMARY_EYE_NONE;
6863  else if (tmp == 1)
6864  primary_eye = AV_PRIMARY_EYE_LEFT;
6865  else if (tmp == 2)
6866  primary_eye = AV_PRIMARY_EYE_RIGHT;
6867  else
6868  av_log(c->fc, AV_LOG_WARNING, "Unknown hero eye type: %d\n", tmp);
6869 
6870  break;
6871  }
6872  case MKTAG('c','a','m','s'): {
6873  uint32_t subtag;
6874  int subsize;
6875  if (size != 24) {
6876  av_log(c->fc, AV_LOG_ERROR, "Invalid size of cams box: %d\n", size);
6877  return AVERROR_INVALIDDATA;
6878  }
6879 
6880  subsize = avio_rb32(pb);
6881  if (subsize != 16) {
6882  av_log(c->fc, AV_LOG_ERROR, "Invalid size of blin box: %d\n", size);
6883  return AVERROR_INVALIDDATA;
6884  }
6885 
6886  subtag = avio_rl32(pb);
6887  if (subtag != MKTAG('b','l','i','n')) {
6888  av_log(c->fc, AV_LOG_ERROR, "Expected blin box, got 0x%08X\n", subtag);
6889  return AVERROR_INVALIDDATA;
6890  }
6891 
6892  avio_skip(pb, 1); // version
6893  avio_skip(pb, 3); // flags
6894 
6895  baseline = avio_rb32(pb);
6896 
6897  break;
6898  }
6899  case MKTAG('c','m','f','y'): {
6900  uint32_t subtag;
6901  int subsize;
6902  int32_t adjustment;
6903  if (size != 24) {
6904  av_log(c->fc, AV_LOG_ERROR, "Invalid size of cmfy box: %d\n", size);
6905  return AVERROR_INVALIDDATA;
6906  }
6907 
6908  subsize = avio_rb32(pb);
6909  if (subsize != 16) {
6910  av_log(c->fc, AV_LOG_ERROR, "Invalid size of dadj box: %d\n", size);
6911  return AVERROR_INVALIDDATA;
6912  }
6913 
6914  subtag = avio_rl32(pb);
6915  if (subtag != MKTAG('d','a','d','j')) {
6916  av_log(c->fc, AV_LOG_ERROR, "Expected dadj box, got 0x%08X\n", subtag);
6917  return AVERROR_INVALIDDATA;
6918  }
6919 
6920  avio_skip(pb, 1); // version
6921  avio_skip(pb, 3); // flags
6922 
6923  adjustment = (int32_t) avio_rb32(pb);
6924 
6925  horizontal_disparity_adjustment.num = (int) adjustment;
6926  horizontal_disparity_adjustment.den = 10000;
6927 
6928  break;
6929  }
6930  default:
6931  av_log(c->fc, AV_LOG_WARNING, "Unknown tag in eyes: 0x%08X\n", tag);
6932  avio_skip(pb, size - 8);
6933  break;
6934  }
6935  remaining -= size;
6936  }
6937 
6938  if (remaining != 0) {
6939  av_log(c->fc, AV_LOG_ERROR, "Broken eyes box\n");
6940  return AVERROR_INVALIDDATA;
6941  }
6942 
6943  if (type == AV_STEREO3D_2D)
6944  return 0;
6945 
6946  if (!sc->stereo3d) {
6948  if (!sc->stereo3d)
6949  return AVERROR(ENOMEM);
6950  }
6951 
6952  sc->stereo3d->flags = flags;
6953  sc->stereo3d->type = type;
6954  sc->stereo3d->view = view;
6955  sc->stereo3d->primary_eye = primary_eye;
6956  sc->stereo3d->baseline = baseline;
6957  sc->stereo3d->horizontal_disparity_adjustment = horizontal_disparity_adjustment;
6958 
6959  return 0;
6960 }
6961 
6963 {
6964  int size;
6965  int64_t remaining;
6966  uint32_t tag;
6967 
6968  if (c->fc->nb_streams < 1)
6969  return 0;
6970 
6971  if (atom.size < 8) {
6972  av_log(c->fc, AV_LOG_ERROR, "Empty video extension usage box\n");
6973  return AVERROR_INVALIDDATA;
6974  }
6975 
6976  remaining = atom.size;
6977  while (remaining > 0) {
6978  size = avio_rb32(pb);
6979  if (size < 8 || size > remaining ) {
6980  av_log(c->fc, AV_LOG_ERROR, "Invalid child size in vexu box\n");
6981  return AVERROR_INVALIDDATA;
6982  }
6983 
6984  tag = avio_rl32(pb);
6985  switch (tag) {
6986  case MKTAG('p','r','o','j'): {
6987  MOVAtom proj = { tag, size - 8 };
6988  int ret = mov_read_vexu_proj(c, pb, proj);
6989  if (ret < 0)
6990  return ret;
6991  break;
6992  }
6993  case MKTAG('e','y','e','s'): {
6994  MOVAtom eyes = { tag, size - 8 };
6995  int ret = mov_read_eyes(c, pb, eyes);
6996  if (ret < 0)
6997  return ret;
6998  break;
6999  }
7000  default:
7001  av_log(c->fc, AV_LOG_WARNING, "Unknown tag in vexu: 0x%08X\n", tag);
7002  avio_skip(pb, size - 8);
7003  break;
7004  }
7005  remaining -= size;
7006  }
7007 
7008  if (remaining != 0) {
7009  av_log(c->fc, AV_LOG_ERROR, "Broken vexu box\n");
7010  return AVERROR_INVALIDDATA;
7011  }
7012 
7013  return 0;
7014 }
7015 
7017 {
7018  AVStream *st;
7019  MOVStreamContext *sc;
7020 
7021  if (c->fc->nb_streams < 1)
7022  return 0;
7023 
7024  st = c->fc->streams[c->fc->nb_streams - 1];
7025  sc = st->priv_data;
7026 
7027  if (atom.size != 4) {
7028  av_log(c->fc, AV_LOG_ERROR, "Invalid size of hfov box: %"PRIu64"\n", atom.size);
7029  return AVERROR_INVALIDDATA;
7030  }
7031 
7032 
7033  if (!sc->stereo3d) {
7035  if (!sc->stereo3d)
7036  return AVERROR(ENOMEM);
7037  }
7038 
7040  sc->stereo3d->horizontal_field_of_view.den = 1000; // thousands of a degree
7041 
7042  return 0;
7043 }
7044 
7046 {
7047  int ret = 0;
7048  uint8_t *buffer = av_malloc(len + 1);
7049  const char *val;
7050 
7051  if (!buffer)
7052  return AVERROR(ENOMEM);
7053  buffer[len] = '\0';
7054 
7055  ret = ffio_read_size(pb, buffer, len);
7056  if (ret < 0)
7057  goto out;
7058 
7059  /* Check for mandatory keys and values, try to support XML as best-effort */
7060  if (!sc->spherical &&
7061  av_stristr(buffer, "<GSpherical:StitchingSoftware>") &&
7062  (val = av_stristr(buffer, "<GSpherical:Spherical>")) &&
7063  av_stristr(val, "true") &&
7064  (val = av_stristr(buffer, "<GSpherical:Stitched>")) &&
7065  av_stristr(val, "true") &&
7066  (val = av_stristr(buffer, "<GSpherical:ProjectionType>")) &&
7067  av_stristr(val, "equirectangular")) {
7069  if (!sc->spherical)
7070  goto out;
7071 
7073 
7074  if (av_stristr(buffer, "<GSpherical:StereoMode>") && !sc->stereo3d) {
7075  enum AVStereo3DType mode;
7076 
7077  if (av_stristr(buffer, "left-right"))
7079  else if (av_stristr(buffer, "top-bottom"))
7081  else
7082  mode = AV_STEREO3D_2D;
7083 
7085  if (!sc->stereo3d)
7086  goto out;
7087 
7088  sc->stereo3d->type = mode;
7089  }
7090 
7091  /* orientation */
7092  val = av_stristr(buffer, "<GSpherical:InitialViewHeadingDegrees>");
7093  if (val)
7094  sc->spherical->yaw = strtol(val, NULL, 10) * (1 << 16);
7095  val = av_stristr(buffer, "<GSpherical:InitialViewPitchDegrees>");
7096  if (val)
7097  sc->spherical->pitch = strtol(val, NULL, 10) * (1 << 16);
7098  val = av_stristr(buffer, "<GSpherical:InitialViewRollDegrees>");
7099  if (val)
7100  sc->spherical->roll = strtol(val, NULL, 10) * (1 << 16);
7101  }
7102 
7103 out:
7104  av_free(buffer);
7105  return ret;
7106 }
7107 
7109 {
7110  AVStream *st;
7111  MOVStreamContext *sc;
7112  int64_t ret;
7113  AVUUID uuid;
7114  static const AVUUID uuid_isml_manifest = {
7115  0xa5, 0xd4, 0x0b, 0x30, 0xe8, 0x14, 0x11, 0xdd,
7116  0xba, 0x2f, 0x08, 0x00, 0x20, 0x0c, 0x9a, 0x66
7117  };
7118  static const AVUUID uuid_xmp = {
7119  0xbe, 0x7a, 0xcf, 0xcb, 0x97, 0xa9, 0x42, 0xe8,
7120  0x9c, 0x71, 0x99, 0x94, 0x91, 0xe3, 0xaf, 0xac
7121  };
7122  static const AVUUID uuid_spherical = {
7123  0xff, 0xcc, 0x82, 0x63, 0xf8, 0x55, 0x4a, 0x93,
7124  0x88, 0x14, 0x58, 0x7a, 0x02, 0x52, 0x1f, 0xdd,
7125  };
7126 
7127  if (atom.size < AV_UUID_LEN || atom.size >= FFMIN(INT_MAX, SIZE_MAX))
7128  return AVERROR_INVALIDDATA;
7129 
7130  if (c->fc->nb_streams < 1)
7131  return 0;
7132  st = c->fc->streams[c->fc->nb_streams - 1];
7133  sc = st->priv_data;
7134 
7135  ret = ffio_read_size(pb, uuid, AV_UUID_LEN);
7136  if (ret < 0)
7137  return ret;
7138  if (av_uuid_equal(uuid, uuid_isml_manifest)) {
7139  uint8_t *buffer, *ptr;
7140  char *endptr;
7141  size_t len = atom.size - AV_UUID_LEN;
7142 
7143  if (len < 4) {
7144  return AVERROR_INVALIDDATA;
7145  }
7146  ret = avio_skip(pb, 4); // zeroes
7147  len -= 4;
7148 
7149  buffer = av_mallocz(len + 1);
7150  if (!buffer) {
7151  return AVERROR(ENOMEM);
7152  }
7153  ret = ffio_read_size(pb, buffer, len);
7154  if (ret < 0) {
7155  av_free(buffer);
7156  return ret;
7157  }
7158 
7159  ptr = buffer;
7160  while ((ptr = av_stristr(ptr, "systemBitrate=\""))) {
7161  ptr += sizeof("systemBitrate=\"") - 1;
7162  c->bitrates_count++;
7163  c->bitrates = av_realloc_f(c->bitrates, c->bitrates_count, sizeof(*c->bitrates));
7164  if (!c->bitrates) {
7165  c->bitrates_count = 0;
7166  av_free(buffer);
7167  return AVERROR(ENOMEM);
7168  }
7169  errno = 0;
7170  ret = strtol(ptr, &endptr, 10);
7171  if (ret < 0 || errno || *endptr != '"') {
7172  c->bitrates[c->bitrates_count - 1] = 0;
7173  } else {
7174  c->bitrates[c->bitrates_count - 1] = ret;
7175  }
7176  }
7177 
7178  av_free(buffer);
7179  } else if (av_uuid_equal(uuid, uuid_xmp)) {
7180  uint8_t *buffer;
7181  size_t len = atom.size - AV_UUID_LEN;
7182  if (c->export_xmp) {
7183  buffer = av_mallocz(len + 1);
7184  if (!buffer) {
7185  return AVERROR(ENOMEM);
7186  }
7187  ret = ffio_read_size(pb, buffer, len);
7188  if (ret < 0) {
7189  av_free(buffer);
7190  return ret;
7191  }
7192  buffer[len] = '\0';
7193  av_dict_set(&c->fc->metadata, "xmp",
7195  } else {
7196  // skip all uuid atom, which makes it fast for long uuid-xmp file
7197  ret = avio_skip(pb, len);
7198  if (ret < 0)
7199  return ret;
7200  }
7201  } else if (av_uuid_equal(uuid, uuid_spherical)) {
7202  size_t len = atom.size - AV_UUID_LEN;
7203  ret = mov_parse_uuid_spherical(sc, pb, len);
7204  if (ret < 0)
7205  return ret;
7206  if (!sc->spherical)
7207  av_log(c->fc, AV_LOG_WARNING, "Invalid spherical metadata found\n");
7208  }
7209 
7210  return 0;
7211 }
7212 
7214 {
7215  int ret;
7216  uint8_t content[16];
7217 
7218  if (atom.size < 8)
7219  return 0;
7220 
7221  ret = ffio_read_size(pb, content, FFMIN(sizeof(content), atom.size));
7222  if (ret < 0)
7223  return ret;
7224 
7225  if ( !c->found_moov
7226  && !c->found_mdat
7227  && !memcmp(content, "Anevia\x1A\x1A", 8)
7228  && c->use_mfra_for == FF_MOV_FLAG_MFRA_AUTO) {
7229  c->use_mfra_for = FF_MOV_FLAG_MFRA_PTS;
7230  }
7231 
7232  return 0;
7233 }
7234 
7236 {
7237  uint32_t format = avio_rl32(pb);
7238  MOVStreamContext *sc;
7239  enum AVCodecID id;
7240  AVStream *st;
7241 
7242  if (c->fc->nb_streams < 1)
7243  return 0;
7244  st = c->fc->streams[c->fc->nb_streams - 1];
7245  sc = st->priv_data;
7246 
7247  switch (sc->format)
7248  {
7249  case MKTAG('e','n','c','v'): // encrypted video
7250  case MKTAG('e','n','c','a'): // encrypted audio
7251  id = mov_codec_id(st, format);
7252  if (st->codecpar->codec_id != AV_CODEC_ID_NONE &&
7253  st->codecpar->codec_id != id) {
7254  av_log(c->fc, AV_LOG_WARNING,
7255  "ignoring 'frma' atom of '%.4s', stream has codec id %d\n",
7256  (char*)&format, st->codecpar->codec_id);
7257  break;
7258  }
7259 
7260  st->codecpar->codec_id = id;
7261  sc->format = format;
7262  break;
7263 
7264  default:
7265  if (format != sc->format) {
7266  av_log(c->fc, AV_LOG_WARNING,
7267  "ignoring 'frma' atom of '%.4s', stream format is '%.4s'\n",
7268  (char*)&format, (char*)&sc->format);
7269  }
7270  break;
7271  }
7272 
7273  return 0;
7274 }
7275 
7276 /**
7277  * Gets the current encryption info and associated current stream context. If
7278  * we are parsing a track fragment, this will return the specific encryption
7279  * info for this fragment; otherwise this will return the global encryption
7280  * info for the current stream.
7281  */
7283 {
7284  MOVFragmentStreamInfo *frag_stream_info;
7285  AVStream *st;
7286  int i;
7287 
7288  frag_stream_info = get_current_frag_stream_info(&c->frag_index);
7289  if (frag_stream_info) {
7290  for (i = 0; i < c->fc->nb_streams; i++) {
7291  *sc = c->fc->streams[i]->priv_data;
7292  if ((*sc)->id == frag_stream_info->id) {
7293  st = c->fc->streams[i];
7294  break;
7295  }
7296  }
7297  if (i == c->fc->nb_streams)
7298  return 0;
7299  *sc = st->priv_data;
7300 
7301  if (!frag_stream_info->encryption_index) {
7302  // If this stream isn't encrypted, don't create the index.
7303  if (!(*sc)->cenc.default_encrypted_sample)
7304  return 0;
7305  frag_stream_info->encryption_index = av_mallocz(sizeof(*frag_stream_info->encryption_index));
7306  if (!frag_stream_info->encryption_index)
7307  return AVERROR(ENOMEM);
7308  }
7309  *encryption_index = frag_stream_info->encryption_index;
7310  return 1;
7311  } else {
7312  // No current track fragment, using stream level encryption info.
7313 
7314  if (c->fc->nb_streams < 1)
7315  return 0;
7316  st = c->fc->streams[c->fc->nb_streams - 1];
7317  *sc = st->priv_data;
7318 
7319  if (!(*sc)->cenc.encryption_index) {
7320  // If this stream isn't encrypted, don't create the index.
7321  if (!(*sc)->cenc.default_encrypted_sample)
7322  return 0;
7323  (*sc)->cenc.encryption_index = av_mallocz(sizeof(*frag_stream_info->encryption_index));
7324  if (!(*sc)->cenc.encryption_index)
7325  return AVERROR(ENOMEM);
7326  }
7327 
7328  *encryption_index = (*sc)->cenc.encryption_index;
7329  return 1;
7330  }
7331 }
7332 
7334 {
7335  int i, ret;
7336  unsigned int subsample_count;
7337  AVSubsampleEncryptionInfo *subsamples;
7338 
7339  if (!sc->cenc.default_encrypted_sample) {
7340  av_log(c->fc, AV_LOG_ERROR, "Missing schm or tenc\n");
7341  return AVERROR_INVALIDDATA;
7342  }
7343 
7344  if (sc->cenc.per_sample_iv_size || use_subsamples) {
7346  if (!*sample)
7347  return AVERROR(ENOMEM);
7348  } else
7349  *sample = NULL;
7350 
7351  if (sc->cenc.per_sample_iv_size != 0) {
7352  if ((ret = ffio_read_size(pb, (*sample)->iv, sc->cenc.per_sample_iv_size)) < 0) {
7353  av_log(c->fc, AV_LOG_ERROR, "failed to read the initialization vector\n");
7355  *sample = NULL;
7356  return ret;
7357  }
7358  }
7359 
7360  if (use_subsamples) {
7361  subsample_count = avio_rb16(pb);
7362  av_free((*sample)->subsamples);
7363  (*sample)->subsamples = av_calloc(subsample_count, sizeof(*subsamples));
7364  if (!(*sample)->subsamples) {
7366  *sample = NULL;
7367  return AVERROR(ENOMEM);
7368  }
7369 
7370  for (i = 0; i < subsample_count && !pb->eof_reached; i++) {
7371  (*sample)->subsamples[i].bytes_of_clear_data = avio_rb16(pb);
7372  (*sample)->subsamples[i].bytes_of_protected_data = avio_rb32(pb);
7373  }
7374 
7375  if (pb->eof_reached) {
7376  av_log(c->fc, AV_LOG_ERROR, "hit EOF while reading sub-sample encryption info\n");
7378  *sample = NULL;
7379  return AVERROR_INVALIDDATA;
7380  }
7381  (*sample)->subsample_count = subsample_count;
7382  }
7383 
7384  return 0;
7385 }
7386 
7388 {
7389  AVEncryptionInfo **encrypted_samples;
7390  MOVEncryptionIndex *encryption_index;
7391  MOVStreamContext *sc;
7392  int use_subsamples, ret;
7393  unsigned int sample_count, i, alloc_size = 0;
7394 
7395  ret = get_current_encryption_info(c, &encryption_index, &sc);
7396  if (ret != 1)
7397  return ret;
7398 
7399  if (encryption_index->nb_encrypted_samples) {
7400  // This can happen if we have both saio/saiz and senc atoms.
7401  av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in senc\n");
7402  return 0;
7403  }
7404 
7405  avio_r8(pb); /* version */
7406  use_subsamples = avio_rb24(pb) & 0x02; /* flags */
7407 
7408  sample_count = avio_rb32(pb);
7409  if (sample_count >= INT_MAX / sizeof(*encrypted_samples))
7410  return AVERROR(ENOMEM);
7411 
7412  for (i = 0; i < sample_count; i++) {
7413  unsigned int min_samples = FFMIN(FFMAX(i + 1, 1024 * 1024), sample_count);
7414  encrypted_samples = av_fast_realloc(encryption_index->encrypted_samples, &alloc_size,
7415  min_samples * sizeof(*encrypted_samples));
7416  if (encrypted_samples) {
7417  encryption_index->encrypted_samples = encrypted_samples;
7418 
7420  c, pb, sc, &encryption_index->encrypted_samples[i], use_subsamples);
7421  } else {
7422  ret = AVERROR(ENOMEM);
7423  }
7424  if (pb->eof_reached) {
7425  av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading senc\n");
7426  if (ret >= 0)
7427  av_encryption_info_free(encryption_index->encrypted_samples[i]);
7429  }
7430 
7431  if (ret < 0) {
7432  for (; i > 0; i--)
7433  av_encryption_info_free(encryption_index->encrypted_samples[i - 1]);
7434  av_freep(&encryption_index->encrypted_samples);
7435  return ret;
7436  }
7437  }
7438  encryption_index->nb_encrypted_samples = sample_count;
7439 
7440  return 0;
7441 }
7442 
7444 {
7445  AVEncryptionInfo **sample, **encrypted_samples;
7446  int64_t prev_pos;
7447  size_t sample_count, sample_info_size, i;
7448  int ret = 0;
7449  unsigned int alloc_size = 0;
7450 
7451  if (encryption_index->nb_encrypted_samples)
7452  return 0;
7453  sample_count = encryption_index->auxiliary_info_sample_count;
7454  if (encryption_index->auxiliary_offsets_count != 1) {
7455  av_log(c->fc, AV_LOG_ERROR, "Multiple auxiliary info chunks are not supported\n");
7456  return AVERROR_PATCHWELCOME;
7457  }
7458  if (sample_count >= INT_MAX / sizeof(*encrypted_samples))
7459  return AVERROR(ENOMEM);
7460 
7461  prev_pos = avio_tell(pb);
7462  if (!(pb->seekable & AVIO_SEEKABLE_NORMAL) ||
7463  avio_seek(pb, encryption_index->auxiliary_offsets[0], SEEK_SET) != encryption_index->auxiliary_offsets[0]) {
7464  av_log(c->fc, AV_LOG_INFO, "Failed to seek for auxiliary info, will only parse senc atoms for encryption info\n");
7465  goto finish;
7466  }
7467 
7468  for (i = 0; i < sample_count && !pb->eof_reached; i++) {
7469  unsigned int min_samples = FFMIN(FFMAX(i + 1, 1024 * 1024), sample_count);
7470  encrypted_samples = av_fast_realloc(encryption_index->encrypted_samples, &alloc_size,
7471  min_samples * sizeof(*encrypted_samples));
7472  if (!encrypted_samples) {
7473  ret = AVERROR(ENOMEM);
7474  goto finish;
7475  }
7476  encryption_index->encrypted_samples = encrypted_samples;
7477 
7478  sample = &encryption_index->encrypted_samples[i];
7479  sample_info_size = encryption_index->auxiliary_info_default_size
7480  ? encryption_index->auxiliary_info_default_size
7481  : encryption_index->auxiliary_info_sizes[i];
7482 
7483  ret = mov_read_sample_encryption_info(c, pb, sc, sample, sample_info_size > sc->cenc.per_sample_iv_size);
7484  if (ret < 0)
7485  goto finish;
7486  }
7487  if (pb->eof_reached) {
7488  av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading auxiliary info\n");
7490  } else {
7491  encryption_index->nb_encrypted_samples = sample_count;
7492  }
7493 
7494 finish:
7495  avio_seek(pb, prev_pos, SEEK_SET);
7496  if (ret < 0) {
7497  for (; i > 0; i--) {
7498  av_encryption_info_free(encryption_index->encrypted_samples[i - 1]);
7499  }
7500  av_freep(&encryption_index->encrypted_samples);
7501  }
7502  return ret;
7503 }
7504 
7506 {
7507  MOVEncryptionIndex *encryption_index;
7508  MOVStreamContext *sc;
7509  int ret;
7510  unsigned int sample_count, aux_info_type, aux_info_param;
7511 
7512  ret = get_current_encryption_info(c, &encryption_index, &sc);
7513  if (ret != 1)
7514  return ret;
7515 
7516  if (encryption_index->nb_encrypted_samples) {
7517  // This can happen if we have both saio/saiz and senc atoms.
7518  av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in saiz\n");
7519  return 0;
7520  }
7521 
7522  if (encryption_index->auxiliary_info_sample_count) {
7523  av_log(c->fc, AV_LOG_ERROR, "Duplicate saiz atom\n");
7524  return AVERROR_INVALIDDATA;
7525  }
7526 
7527  avio_r8(pb); /* version */
7528  if (avio_rb24(pb) & 0x01) { /* flags */
7529  aux_info_type = avio_rb32(pb);
7530  aux_info_param = avio_rb32(pb);
7531  if (sc->cenc.default_encrypted_sample) {
7532  if (aux_info_type != sc->cenc.default_encrypted_sample->scheme) {
7533  av_log(c->fc, AV_LOG_DEBUG, "Ignoring saiz box with non-zero aux_info_type\n");
7534  return 0;
7535  }
7536  if (aux_info_param != 0) {
7537  av_log(c->fc, AV_LOG_DEBUG, "Ignoring saiz box with non-zero aux_info_type_parameter\n");
7538  return 0;
7539  }
7540  } else {
7541  // Didn't see 'schm' or 'tenc', so this isn't encrypted.
7542  if ((aux_info_type == MKBETAG('c','e','n','c') ||
7543  aux_info_type == MKBETAG('c','e','n','s') ||
7544  aux_info_type == MKBETAG('c','b','c','1') ||
7545  aux_info_type == MKBETAG('c','b','c','s')) &&
7546  aux_info_param == 0) {
7547  av_log(c->fc, AV_LOG_ERROR, "Saw encrypted saiz without schm/tenc\n");
7548  return AVERROR_INVALIDDATA;
7549  } else {
7550  return 0;
7551  }
7552  }
7553  } else if (!sc->cenc.default_encrypted_sample) {
7554  // Didn't see 'schm' or 'tenc', so this isn't encrypted.
7555  return 0;
7556  }
7557 
7558  encryption_index->auxiliary_info_default_size = avio_r8(pb);
7559  sample_count = avio_rb32(pb);
7560 
7561  if (encryption_index->auxiliary_info_default_size == 0) {
7562  if (sample_count == 0)
7563  return AVERROR_INVALIDDATA;
7564 
7565  encryption_index->auxiliary_info_sizes = av_malloc(sample_count);
7566  if (!encryption_index->auxiliary_info_sizes)
7567  return AVERROR(ENOMEM);
7568 
7569  ret = avio_read(pb, encryption_index->auxiliary_info_sizes, sample_count);
7570  if (ret != sample_count) {
7571  av_freep(&encryption_index->auxiliary_info_sizes);
7572 
7573  if (ret >= 0)
7575  av_log(c->fc, AV_LOG_ERROR, "Failed to read the auxiliary info, %s\n",
7576  av_err2str(ret));
7577  return ret;
7578  }
7579  }
7580  encryption_index->auxiliary_info_sample_count = sample_count;
7581 
7582  if (encryption_index->auxiliary_offsets_count) {
7583  return mov_parse_auxiliary_info(c, sc, pb, encryption_index);
7584  }
7585 
7586  return 0;
7587 }
7588 
7590 {
7591  uint64_t *auxiliary_offsets;
7592  MOVEncryptionIndex *encryption_index;
7593  MOVStreamContext *sc;
7594  int i, ret;
7595  unsigned int version, entry_count, aux_info_type, aux_info_param;
7596  unsigned int alloc_size = 0;
7597 
7598  ret = get_current_encryption_info(c, &encryption_index, &sc);
7599  if (ret != 1)
7600  return ret;
7601 
7602  if (encryption_index->nb_encrypted_samples) {
7603  // This can happen if we have both saio/saiz and senc atoms.
7604  av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in saio\n");
7605  return 0;
7606  }
7607 
7608  if (encryption_index->auxiliary_offsets_count) {
7609  av_log(c->fc, AV_LOG_ERROR, "Duplicate saio atom\n");
7610  return AVERROR_INVALIDDATA;
7611  }
7612 
7613  version = avio_r8(pb); /* version */
7614  if (avio_rb24(pb) & 0x01) { /* flags */
7615  aux_info_type = avio_rb32(pb);
7616  aux_info_param = avio_rb32(pb);
7617  if (sc->cenc.default_encrypted_sample) {
7618  if (aux_info_type != sc->cenc.default_encrypted_sample->scheme) {
7619  av_log(c->fc, AV_LOG_DEBUG, "Ignoring saio box with non-zero aux_info_type\n");
7620  return 0;
7621  }
7622  if (aux_info_param != 0) {
7623  av_log(c->fc, AV_LOG_DEBUG, "Ignoring saio box with non-zero aux_info_type_parameter\n");
7624  return 0;
7625  }
7626  } else {
7627  // Didn't see 'schm' or 'tenc', so this isn't encrypted.
7628  if ((aux_info_type == MKBETAG('c','e','n','c') ||
7629  aux_info_type == MKBETAG('c','e','n','s') ||
7630  aux_info_type == MKBETAG('c','b','c','1') ||
7631  aux_info_type == MKBETAG('c','b','c','s')) &&
7632  aux_info_param == 0) {
7633  av_log(c->fc, AV_LOG_ERROR, "Saw encrypted saio without schm/tenc\n");
7634  return AVERROR_INVALIDDATA;
7635  } else {
7636  return 0;
7637  }
7638  }
7639  } else if (!sc->cenc.default_encrypted_sample) {
7640  // Didn't see 'schm' or 'tenc', so this isn't encrypted.
7641  return 0;
7642  }
7643 
7644  entry_count = avio_rb32(pb);
7645  if (entry_count >= INT_MAX / sizeof(*auxiliary_offsets))
7646  return AVERROR(ENOMEM);
7647 
7648  for (i = 0; i < entry_count && !pb->eof_reached; i++) {
7649  unsigned int min_offsets = FFMIN(FFMAX(i + 1, 1024), entry_count);
7650  auxiliary_offsets = av_fast_realloc(
7651  encryption_index->auxiliary_offsets, &alloc_size,
7652  min_offsets * sizeof(*auxiliary_offsets));
7653  if (!auxiliary_offsets) {
7654  av_freep(&encryption_index->auxiliary_offsets);
7655  return AVERROR(ENOMEM);
7656  }
7657  encryption_index->auxiliary_offsets = auxiliary_offsets;
7658 
7659  if (version == 0) {
7660  encryption_index->auxiliary_offsets[i] = avio_rb32(pb);
7661  } else {
7662  encryption_index->auxiliary_offsets[i] = avio_rb64(pb);
7663  }
7664  if (c->frag_index.current >= 0) {
7665  encryption_index->auxiliary_offsets[i] += c->fragment.base_data_offset;
7666  }
7667  }
7668 
7669  if (pb->eof_reached) {
7670  av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading saio\n");
7671  av_freep(&encryption_index->auxiliary_offsets);
7672  return AVERROR_INVALIDDATA;
7673  }
7674 
7675  encryption_index->auxiliary_offsets_count = entry_count;
7676 
7677  if (encryption_index->auxiliary_info_sample_count) {
7678  return mov_parse_auxiliary_info(c, sc, pb, encryption_index);
7679  }
7680 
7681  return 0;
7682 }
7683 
7685 {
7686  AVEncryptionInitInfo *info, *old_init_info;
7687  uint8_t **key_ids;
7688  AVStream *st;
7689  const AVPacketSideData *old_side_data;
7690  uint8_t *side_data, *extra_data;
7691  size_t side_data_size;
7692  int ret = 0;
7693  unsigned int version, kid_count, extra_data_size, alloc_size = 0;
7694 
7695  if (c->fc->nb_streams < 1)
7696  return 0;
7697  st = c->fc->streams[c->fc->nb_streams-1];
7698 
7699  version = avio_r8(pb); /* version */
7700  avio_rb24(pb); /* flags */
7701 
7702  info = av_encryption_init_info_alloc(/* system_id_size */ 16, /* num_key_ids */ 0,
7703  /* key_id_size */ 16, /* data_size */ 0);
7704  if (!info)
7705  return AVERROR(ENOMEM);
7706 
7707  if ((ret = ffio_read_size(pb, info->system_id, 16)) < 0) {
7708  av_log(c->fc, AV_LOG_ERROR, "Failed to read the system id\n");
7709  goto finish;
7710  }
7711 
7712  if (version > 0) {
7713  kid_count = avio_rb32(pb);
7714  if (kid_count >= INT_MAX / sizeof(*key_ids)) {
7715  ret = AVERROR(ENOMEM);
7716  goto finish;
7717  }
7718 
7719  for (unsigned int i = 0; i < kid_count && !pb->eof_reached; i++) {
7720  unsigned int min_kid_count = FFMIN(FFMAX(i + 1, 1024), kid_count);
7721  key_ids = av_fast_realloc(info->key_ids, &alloc_size,
7722  min_kid_count * sizeof(*key_ids));
7723  if (!key_ids) {
7724  ret = AVERROR(ENOMEM);
7725  goto finish;
7726  }
7727  info->key_ids = key_ids;
7728 
7729  info->key_ids[i] = av_mallocz(16);
7730  if (!info->key_ids[i]) {
7731  ret = AVERROR(ENOMEM);
7732  goto finish;
7733  }
7734  info->num_key_ids = i + 1;
7735 
7736  if ((ret = ffio_read_size(pb, info->key_ids[i], 16)) < 0) {
7737  av_log(c->fc, AV_LOG_ERROR, "Failed to read the key id\n");
7738  goto finish;
7739  }
7740  }
7741 
7742  if (pb->eof_reached) {
7743  av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading pssh\n");
7745  goto finish;
7746  }
7747  }
7748 
7749  extra_data_size = avio_rb32(pb);
7750  extra_data = av_malloc(extra_data_size);
7751  if (!extra_data) {
7752  ret = AVERROR(ENOMEM);
7753  goto finish;
7754  }
7755  ret = avio_read(pb, extra_data, extra_data_size);
7756  if (ret != extra_data_size) {
7757  av_free(extra_data);
7758 
7759  if (ret >= 0)
7761  goto finish;
7762  }
7763 
7764  av_freep(&info->data); // malloc(0) may still allocate something.
7765  info->data = extra_data;
7766  info->data_size = extra_data_size;
7767 
7768  // If there is existing initialization data, append to the list.
7771  if (old_side_data) {
7772  old_init_info = av_encryption_init_info_get_side_data(old_side_data->data, old_side_data->size);
7773  if (old_init_info) {
7774  // Append to the end of the list.
7775  for (AVEncryptionInitInfo *cur = old_init_info;; cur = cur->next) {
7776  if (!cur->next) {
7777  cur->next = info;
7778  break;
7779  }
7780  }
7781  info = old_init_info;
7782  } else {
7783  // Assume existing side-data will be valid, so the only error we could get is OOM.
7784  ret = AVERROR(ENOMEM);
7785  goto finish;
7786  }
7787  }
7788 
7789  side_data = av_encryption_init_info_add_side_data(info, &side_data_size);
7790  if (!side_data) {
7791  ret = AVERROR(ENOMEM);
7792  goto finish;
7793  }
7797  side_data, side_data_size, 0))
7798  av_free(side_data);
7799 
7800 finish:
7802  return ret;
7803 }
7804 
7806 {
7807  AVStream *st;
7808  MOVStreamContext *sc;
7809 
7810  if (c->fc->nb_streams < 1)
7811  return 0;
7812  st = c->fc->streams[c->fc->nb_streams-1];
7813  sc = st->priv_data;
7814 
7815  if (sc->pseudo_stream_id != 0) {
7816  av_log(c->fc, AV_LOG_ERROR, "schm boxes are only supported in first sample descriptor\n");
7817  return AVERROR_PATCHWELCOME;
7818  }
7819 
7820  if (atom.size < 8)
7821  return AVERROR_INVALIDDATA;
7822 
7823  avio_rb32(pb); /* version and flags */
7824 
7825  if (!sc->cenc.default_encrypted_sample) {
7827  if (!sc->cenc.default_encrypted_sample) {
7828  return AVERROR(ENOMEM);
7829  }
7830  }
7831 
7833  return 0;
7834 }
7835 
7837 {
7838  AVStream *st;
7839  MOVStreamContext *sc;
7840  unsigned int version, pattern, is_protected, iv_size;
7841 
7842  if (c->fc->nb_streams < 1)
7843  return 0;
7844  st = c->fc->streams[c->fc->nb_streams-1];
7845  sc = st->priv_data;
7846 
7847  if (sc->pseudo_stream_id != 0) {
7848  av_log(c->fc, AV_LOG_ERROR, "tenc atom are only supported in first sample descriptor\n");
7849  return AVERROR_PATCHWELCOME;
7850  }
7851 
7852  if (!sc->cenc.default_encrypted_sample) {
7854  if (!sc->cenc.default_encrypted_sample) {
7855  return AVERROR(ENOMEM);
7856  }
7857  }
7858 
7859  if (atom.size < 20)
7860  return AVERROR_INVALIDDATA;
7861 
7862  version = avio_r8(pb); /* version */
7863  avio_rb24(pb); /* flags */
7864 
7865  avio_r8(pb); /* reserved */
7866  pattern = avio_r8(pb);
7867 
7868  if (version > 0) {
7869  sc->cenc.default_encrypted_sample->crypt_byte_block = pattern >> 4;
7870  sc->cenc.default_encrypted_sample->skip_byte_block = pattern & 0xf;
7871  }
7872 
7873  is_protected = avio_r8(pb);
7874  if (is_protected && !sc->cenc.encryption_index) {
7875  // The whole stream should be by-default encrypted.
7877  if (!sc->cenc.encryption_index)
7878  return AVERROR(ENOMEM);
7879  }
7880  sc->cenc.per_sample_iv_size = avio_r8(pb);
7881  if (sc->cenc.per_sample_iv_size != 0 && sc->cenc.per_sample_iv_size != 8 &&
7882  sc->cenc.per_sample_iv_size != 16) {
7883  av_log(c->fc, AV_LOG_ERROR, "invalid per-sample IV size value\n");
7884  return AVERROR_INVALIDDATA;
7885  }
7886  if (avio_read(pb, sc->cenc.default_encrypted_sample->key_id, 16) != 16) {
7887  av_log(c->fc, AV_LOG_ERROR, "failed to read the default key ID\n");
7888  return AVERROR_INVALIDDATA;
7889  }
7890 
7891  if (is_protected && !sc->cenc.per_sample_iv_size) {
7892  iv_size = avio_r8(pb);
7893  if (iv_size != 8 && iv_size != 16) {
7894  av_log(c->fc, AV_LOG_ERROR, "invalid default_constant_IV_size in tenc atom\n");
7895  return AVERROR_INVALIDDATA;
7896  }
7897 
7898  if (avio_read(pb, sc->cenc.default_encrypted_sample->iv, iv_size) != iv_size) {
7899  av_log(c->fc, AV_LOG_ERROR, "failed to read the default IV\n");
7900  return AVERROR_INVALIDDATA;
7901  }
7902  }
7903 
7904  return 0;
7905 }
7906 
7908 {
7909  AVStream *st;
7910  int last, type, size, ret;
7911  uint8_t buf[4];
7912 
7913  if (c->fc->nb_streams < 1)
7914  return 0;
7915  st = c->fc->streams[c->fc->nb_streams-1];
7916 
7917  if ((uint64_t)atom.size > (1<<30) || atom.size < 42)
7918  return AVERROR_INVALIDDATA;
7919 
7920  /* Check FlacSpecificBox version. */
7921  if (avio_r8(pb) != 0)
7922  return AVERROR_INVALIDDATA;
7923 
7924  avio_rb24(pb); /* Flags */
7925 
7926  if (avio_read(pb, buf, sizeof(buf)) != sizeof(buf)) {
7927  av_log(c->fc, AV_LOG_ERROR, "failed to read FLAC metadata block header\n");
7928  return pb->error < 0 ? pb->error : AVERROR_INVALIDDATA;
7929  }
7930  flac_parse_block_header(buf, &last, &type, &size);
7931 
7933  av_log(c->fc, AV_LOG_ERROR, "STREAMINFO must be first FLACMetadataBlock\n");
7934  return AVERROR_INVALIDDATA;
7935  }
7936 
7937  ret = ff_get_extradata(c->fc, st->codecpar, pb, size);
7938  if (ret < 0)
7939  return ret;
7940 
7941  if (!last)
7942  av_log(c->fc, AV_LOG_WARNING, "non-STREAMINFO FLACMetadataBlock(s) ignored\n");
7943 
7944  return 0;
7945 }
7946 
7948 {
7949  int i, ret;
7950  int bytes_of_protected_data;
7951 
7952  if (!sc->cenc.aes_ctr) {
7953  /* initialize the cipher */
7954  sc->cenc.aes_ctr = av_aes_ctr_alloc();
7955  if (!sc->cenc.aes_ctr) {
7956  return AVERROR(ENOMEM);
7957  }
7958 
7959  ret = av_aes_ctr_init(sc->cenc.aes_ctr, c->decryption_key);
7960  if (ret < 0) {
7961  return ret;
7962  }
7963  }
7964 
7966 
7967  if (!sample->subsample_count) {
7968  /* decrypt the whole packet */
7970  return 0;
7971  }
7972 
7973  for (i = 0; i < sample->subsample_count; i++) {
7974  if (sample->subsamples[i].bytes_of_clear_data + sample->subsamples[i].bytes_of_protected_data > size) {
7975  av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n");
7976  return AVERROR_INVALIDDATA;
7977  }
7978 
7979  /* skip the clear bytes */
7980  input += sample->subsamples[i].bytes_of_clear_data;
7981  size -= sample->subsamples[i].bytes_of_clear_data;
7982 
7983  /* decrypt the encrypted bytes */
7984 
7985  bytes_of_protected_data = sample->subsamples[i].bytes_of_protected_data;
7986  av_aes_ctr_crypt(sc->cenc.aes_ctr, input, input, bytes_of_protected_data);
7987 
7988  input += bytes_of_protected_data;
7989  size -= bytes_of_protected_data;
7990  }
7991 
7992  if (size > 0) {
7993  av_log(c->fc, AV_LOG_ERROR, "leftover packet bytes after subsample processing\n");
7994  return AVERROR_INVALIDDATA;
7995  }
7996 
7997  return 0;
7998 }
7999 
8001 {
8002  int i, ret;
8003  int num_of_encrypted_blocks;
8004  uint8_t iv[16];
8005 
8006  if (!sc->cenc.aes_ctx) {
8007  /* initialize the cipher */
8008  sc->cenc.aes_ctx = av_aes_alloc();
8009  if (!sc->cenc.aes_ctx) {
8010  return AVERROR(ENOMEM);
8011  }
8012 
8013  ret = av_aes_init(sc->cenc.aes_ctx, c->decryption_key, 16 * 8, 1);
8014  if (ret < 0) {
8015  return ret;
8016  }
8017  }
8018 
8019  memcpy(iv, sample->iv, 16);
8020 
8021  /* whole-block full sample encryption */
8022  if (!sample->subsample_count) {
8023  /* decrypt the whole packet */
8024  av_aes_crypt(sc->cenc.aes_ctx, input, input, size/16, iv, 1);
8025  return 0;
8026  }
8027 
8028  for (i = 0; i < sample->subsample_count; i++) {
8029  if (sample->subsamples[i].bytes_of_clear_data + sample->subsamples[i].bytes_of_protected_data > size) {
8030  av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n");
8031  return AVERROR_INVALIDDATA;
8032  }
8033 
8034  if (sample->subsamples[i].bytes_of_protected_data % 16) {
8035  av_log(c->fc, AV_LOG_ERROR, "subsample BytesOfProtectedData is not a multiple of 16\n");
8036  return AVERROR_INVALIDDATA;
8037  }
8038 
8039  /* skip the clear bytes */
8040  input += sample->subsamples[i].bytes_of_clear_data;
8041  size -= sample->subsamples[i].bytes_of_clear_data;
8042 
8043  /* decrypt the encrypted bytes */
8044  num_of_encrypted_blocks = sample->subsamples[i].bytes_of_protected_data/16;
8045  if (num_of_encrypted_blocks > 0) {
8046  av_aes_crypt(sc->cenc.aes_ctx, input, input, num_of_encrypted_blocks, iv, 1);
8047  }
8048  input += sample->subsamples[i].bytes_of_protected_data;
8049  size -= sample->subsamples[i].bytes_of_protected_data;
8050  }
8051 
8052  if (size > 0) {
8053  av_log(c->fc, AV_LOG_ERROR, "leftover packet bytes after subsample processing\n");
8054  return AVERROR_INVALIDDATA;
8055  }
8056 
8057  return 0;
8058 }
8059 
8061 {
8062  int i, ret, rem_bytes;
8063  uint8_t *data;
8064 
8065  if (!sc->cenc.aes_ctr) {
8066  /* initialize the cipher */
8067  sc->cenc.aes_ctr = av_aes_ctr_alloc();
8068  if (!sc->cenc.aes_ctr) {
8069  return AVERROR(ENOMEM);
8070  }
8071 
8072  ret = av_aes_ctr_init(sc->cenc.aes_ctr, c->decryption_key);
8073  if (ret < 0) {
8074  return ret;
8075  }
8076  }
8077 
8079 
8080  /* whole-block full sample encryption */
8081  if (!sample->subsample_count) {
8082  /* decrypt the whole packet */
8084  return 0;
8085  } else if (!sample->crypt_byte_block && !sample->skip_byte_block) {
8086  av_log(c->fc, AV_LOG_ERROR, "pattern encryption is not present in 'cens' scheme\n");
8087  return AVERROR_INVALIDDATA;
8088  }
8089 
8090  for (i = 0; i < sample->subsample_count; i++) {
8091  if (sample->subsamples[i].bytes_of_clear_data + sample->subsamples[i].bytes_of_protected_data > size) {
8092  av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n");
8093  return AVERROR_INVALIDDATA;
8094  }
8095 
8096  /* skip the clear bytes */
8097  input += sample->subsamples[i].bytes_of_clear_data;
8098  size -= sample->subsamples[i].bytes_of_clear_data;
8099 
8100  /* decrypt the encrypted bytes */
8101  data = input;
8102  rem_bytes = sample->subsamples[i].bytes_of_protected_data;
8103  while (rem_bytes > 0) {
8104  if (rem_bytes < 16*sample->crypt_byte_block) {
8105  break;
8106  }
8107  av_aes_ctr_crypt(sc->cenc.aes_ctr, data, data, 16*sample->crypt_byte_block);
8108  data += 16*sample->crypt_byte_block;
8109  rem_bytes -= 16*sample->crypt_byte_block;
8110  data += FFMIN(16*sample->skip_byte_block, rem_bytes);
8111  rem_bytes -= FFMIN(16*sample->skip_byte_block, rem_bytes);
8112  }
8113  input += sample->subsamples[i].bytes_of_protected_data;
8114  size -= sample->subsamples[i].bytes_of_protected_data;
8115  }
8116 
8117  if (size > 0) {
8118  av_log(c->fc, AV_LOG_ERROR, "leftover packet bytes after subsample processing\n");
8119  return AVERROR_INVALIDDATA;
8120  }
8121 
8122  return 0;
8123 }
8124 
8126 {
8127  int i, ret, rem_bytes;
8128  uint8_t iv[16];
8129  uint8_t *data;
8130 
8131  if (!sc->cenc.aes_ctx) {
8132  /* initialize the cipher */
8133  sc->cenc.aes_ctx = av_aes_alloc();
8134  if (!sc->cenc.aes_ctx) {
8135  return AVERROR(ENOMEM);
8136  }
8137 
8138  ret = av_aes_init(sc->cenc.aes_ctx, c->decryption_key, 16 * 8, 1);
8139  if (ret < 0) {
8140  return ret;
8141  }
8142  }
8143 
8144  /* whole-block full sample encryption */
8145  if (!sample->subsample_count) {
8146  /* decrypt the whole packet */
8147  memcpy(iv, sample->iv, 16);
8148  av_aes_crypt(sc->cenc.aes_ctx, input, input, size/16, iv, 1);
8149  return 0;
8150  } else if (!sample->crypt_byte_block && !sample->skip_byte_block) {
8151  av_log(c->fc, AV_LOG_ERROR, "pattern encryption is not present in 'cbcs' scheme\n");
8152  return AVERROR_INVALIDDATA;
8153  }
8154 
8155  for (i = 0; i < sample->subsample_count; i++) {
8156  if (sample->subsamples[i].bytes_of_clear_data + sample->subsamples[i].bytes_of_protected_data > size) {
8157  av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n");
8158  return AVERROR_INVALIDDATA;
8159  }
8160 
8161  /* skip the clear bytes */
8162  input += sample->subsamples[i].bytes_of_clear_data;
8163  size -= sample->subsamples[i].bytes_of_clear_data;
8164 
8165  /* decrypt the encrypted bytes */
8166  memcpy(iv, sample->iv, 16);
8167  data = input;
8168  rem_bytes = sample->subsamples[i].bytes_of_protected_data;
8169  while (rem_bytes > 0) {
8170  if (rem_bytes < 16*sample->crypt_byte_block) {
8171  break;
8172  }
8173  av_aes_crypt(sc->cenc.aes_ctx, data, data, sample->crypt_byte_block, iv, 1);
8174  data += 16*sample->crypt_byte_block;
8175  rem_bytes -= 16*sample->crypt_byte_block;
8176  data += FFMIN(16*sample->skip_byte_block, rem_bytes);
8177  rem_bytes -= FFMIN(16*sample->skip_byte_block, rem_bytes);
8178  }
8179  input += sample->subsamples[i].bytes_of_protected_data;
8180  size -= sample->subsamples[i].bytes_of_protected_data;
8181  }
8182 
8183  if (size > 0) {
8184  av_log(c->fc, AV_LOG_ERROR, "leftover packet bytes after subsample processing\n");
8185  return AVERROR_INVALIDDATA;
8186  }
8187 
8188  return 0;
8189 }
8190 
8192 {
8193  if (sample->scheme == MKBETAG('c','e','n','c') && !sample->crypt_byte_block && !sample->skip_byte_block) {
8194  return cenc_scheme_decrypt(c, sc, sample, input, size);
8195  } else if (sample->scheme == MKBETAG('c','b','c','1') && !sample->crypt_byte_block && !sample->skip_byte_block) {
8196  return cbc1_scheme_decrypt(c, sc, sample, input, size);
8197  } else if (sample->scheme == MKBETAG('c','e','n','s')) {
8198  return cens_scheme_decrypt(c, sc, sample, input, size);
8199  } else if (sample->scheme == MKBETAG('c','b','c','s')) {
8200  return cbcs_scheme_decrypt(c, sc, sample, input, size);
8201  } else {
8202  av_log(c->fc, AV_LOG_ERROR, "invalid encryption scheme\n");
8203  return AVERROR_INVALIDDATA;
8204  }
8205 }
8206 
8208 {
8209  int current = frag_index->current;
8210 
8211  if (!frag_index->nb_items)
8212  return NULL;
8213 
8214  // Check frag_index->current is the right one for pkt. It can out of sync.
8215  if (current >= 0 && current < frag_index->nb_items) {
8216  if (frag_index->item[current].moof_offset < pkt->pos &&
8217  (current + 1 == frag_index->nb_items ||
8218  frag_index->item[current + 1].moof_offset > pkt->pos))
8219  return get_frag_stream_info(frag_index, current, id);
8220  }
8221 
8222 
8223  for (int i = 0; i < frag_index->nb_items; i++) {
8224  if (frag_index->item[i].moof_offset > pkt->pos)
8225  break;
8226  current = i;
8227  }
8228  frag_index->current = current;
8229  return get_frag_stream_info(frag_index, current, id);
8230 }
8231 
8232 static int cenc_filter(MOVContext *mov, AVStream* st, MOVStreamContext *sc, AVPacket *pkt, int current_index)
8233 {
8234  MOVFragmentStreamInfo *frag_stream_info;
8235  MOVEncryptionIndex *encryption_index;
8236  AVEncryptionInfo *encrypted_sample;
8237  int encrypted_index, ret;
8238 
8239  frag_stream_info = get_frag_stream_info_from_pkt(&mov->frag_index, pkt, sc->id);
8240  encrypted_index = current_index;
8241  encryption_index = NULL;
8242  if (frag_stream_info) {
8243  // Note this only supports encryption info in the first sample descriptor.
8244  if (frag_stream_info->stsd_id == 1) {
8245  if (frag_stream_info->encryption_index) {
8246  encrypted_index = current_index - frag_stream_info->index_base;
8247  encryption_index = frag_stream_info->encryption_index;
8248  } else {
8249  encryption_index = sc->cenc.encryption_index;
8250  }
8251  }
8252  } else {
8253  encryption_index = sc->cenc.encryption_index;
8254  }
8255 
8256  if (encryption_index) {
8257  if (encryption_index->auxiliary_info_sample_count &&
8258  !encryption_index->nb_encrypted_samples) {
8259  av_log(mov->fc, AV_LOG_ERROR, "saiz atom found without saio\n");
8260  return AVERROR_INVALIDDATA;
8261  }
8262  if (encryption_index->auxiliary_offsets_count &&
8263  !encryption_index->nb_encrypted_samples) {
8264  av_log(mov->fc, AV_LOG_ERROR, "saio atom found without saiz\n");
8265  return AVERROR_INVALIDDATA;
8266  }
8267 
8268  encrypted_sample = NULL;
8269  if (!encryption_index->nb_encrypted_samples) {
8270  // Full-sample encryption with default settings.
8271  encrypted_sample = sc->cenc.default_encrypted_sample;
8272  } else if (encrypted_index >= 0 && encrypted_index < encryption_index->nb_encrypted_samples) {
8273  // Per-sample setting override.
8274  encrypted_sample = encryption_index->encrypted_samples[encrypted_index];
8275  if (!encrypted_sample) {
8276  encrypted_sample = sc->cenc.default_encrypted_sample;
8277  }
8278  }
8279 
8280  if (!encrypted_sample) {
8281  av_log(mov->fc, AV_LOG_ERROR, "Incorrect number of samples in encryption info\n");
8282  return AVERROR_INVALIDDATA;
8283  }
8284 
8285  if (mov->decryption_key) {
8286  return cenc_decrypt(mov, sc, encrypted_sample, pkt->data, pkt->size);
8287  } else {
8288  size_t size;
8289  uint8_t *side_data = av_encryption_info_add_side_data(encrypted_sample, &size);
8290  if (!side_data)
8291  return AVERROR(ENOMEM);
8293  if (ret < 0)
8294  av_free(side_data);
8295  return ret;
8296  }
8297  }
8298 
8299  return 0;
8300 }
8301 
8303 {
8304  const int OPUS_SEEK_PREROLL_MS = 80;
8305  int ret;
8306  AVStream *st;
8307  size_t size;
8308  uint16_t pre_skip;
8309 
8310  if (c->fc->nb_streams < 1)
8311  return 0;
8312  st = c->fc->streams[c->fc->nb_streams-1];
8313 
8314  if ((uint64_t)atom.size > (1<<30) || atom.size < 11)
8315  return AVERROR_INVALIDDATA;
8316 
8317  /* Check OpusSpecificBox version. */
8318  if (avio_r8(pb) != 0) {
8319  av_log(c->fc, AV_LOG_ERROR, "unsupported OpusSpecificBox version\n");
8320  return AVERROR_INVALIDDATA;
8321  }
8322 
8323  /* OpusSpecificBox size plus magic for Ogg OpusHead header. */
8324  size = atom.size + 8;
8325 
8326  if ((ret = ff_alloc_extradata(st->codecpar, size)) < 0)
8327  return ret;
8328 
8329  AV_WL32A(st->codecpar->extradata, MKTAG('O','p','u','s'));
8330  AV_WL32A(st->codecpar->extradata + 4, MKTAG('H','e','a','d'));
8331  AV_WB8(st->codecpar->extradata + 8, 1); /* OpusHead version */
8332  avio_read(pb, st->codecpar->extradata + 9, size - 9);
8333 
8334  /* OpusSpecificBox is stored in big-endian, but OpusHead is
8335  little-endian; aside from the preceeding magic and version they're
8336  otherwise currently identical. Data after output gain at offset 16
8337  doesn't need to be bytewapped. */
8338  pre_skip = AV_RB16A(st->codecpar->extradata + 10);
8339  AV_WL16A(st->codecpar->extradata + 10, pre_skip);
8340  AV_WL32A(st->codecpar->extradata + 12, AV_RB32A(st->codecpar->extradata + 12));
8341  AV_WL16A(st->codecpar->extradata + 16, AV_RB16A(st->codecpar->extradata + 16));
8342 
8343  st->codecpar->initial_padding = pre_skip;
8345  (AVRational){1, 1000},
8346  (AVRational){1, 48000});
8347 
8348  return 0;
8349 }
8350 
8352 {
8353  AVStream *st;
8354  unsigned format_info;
8355  int channel_assignment, channel_assignment1, channel_assignment2;
8356  int ratebits;
8357  uint64_t chmask;
8358 
8359  if (c->fc->nb_streams < 1)
8360  return 0;
8361  st = c->fc->streams[c->fc->nb_streams-1];
8362 
8363  if (atom.size < 10)
8364  return AVERROR_INVALIDDATA;
8365 
8366  format_info = avio_rb32(pb);
8367 
8368  ratebits = (format_info >> 28) & 0xF;
8369  channel_assignment1 = (format_info >> 15) & 0x1F;
8370  channel_assignment2 = format_info & 0x1FFF;
8371  if (channel_assignment2)
8372  channel_assignment = channel_assignment2;
8373  else
8374  channel_assignment = channel_assignment1;
8375 
8376  st->codecpar->frame_size = 40 << (ratebits & 0x7);
8377  st->codecpar->sample_rate = mlp_samplerate(ratebits);
8378 
8380  chmask = truehd_layout(channel_assignment);
8382 
8383  return 0;
8384 }
8385 
8387 {
8388  AVStream *st;
8389  uint8_t buf[ISOM_DVCC_DVVC_SIZE];
8390  int ret;
8391  int64_t read_size = atom.size;
8392 
8393  if (c->fc->nb_streams < 1)
8394  return 0;
8395  st = c->fc->streams[c->fc->nb_streams-1];
8396 
8397  // At most 24 bytes
8398  read_size = FFMIN(read_size, ISOM_DVCC_DVVC_SIZE);
8399 
8400  if ((ret = ffio_read_size(pb, buf, read_size)) < 0)
8401  return ret;
8402 
8403  return ff_isom_parse_dvcc_dvvc(c->fc, st, buf, read_size);
8404 }
8405 
8407 {
8408  AVStream *st;
8409  uint8_t *buf;
8410  int ret, old_size, num_arrays;
8411 
8412  if (c->fc->nb_streams < 1)
8413  return 0;
8414  st = c->fc->streams[c->fc->nb_streams-1];
8415 
8416  if (!st->codecpar->extradata_size)
8417  // TODO: handle lhvC when present before hvcC
8418  return 0;
8419 
8420  if (atom.size < 6 || st->codecpar->extradata_size < 23)
8421  return AVERROR_INVALIDDATA;
8422 
8424  if (!buf)
8425  return AVERROR(ENOMEM);
8426  memset(buf + atom.size, 0, AV_INPUT_BUFFER_PADDING_SIZE);
8427 
8428  ret = ffio_read_size(pb, buf, atom.size);
8429  if (ret < 0) {
8430  av_free(buf);
8431  av_log(c->fc, AV_LOG_WARNING, "lhvC atom truncated\n");
8432  return 0;
8433  }
8434 
8435  num_arrays = buf[5];
8436  old_size = st->codecpar->extradata_size;
8437  atom.size -= 8 /* account for mov_realloc_extradata offseting */
8438  + 6 /* lhvC bytes before the arrays*/;
8439 
8440  ret = mov_realloc_extradata(st->codecpar, atom);
8441  if (ret < 0) {
8442  av_free(buf);
8443  return ret;
8444  }
8445 
8446  st->codecpar->extradata[22] += num_arrays;
8447  memcpy(st->codecpar->extradata + old_size, buf + 6, atom.size + 8);
8448 
8450 
8451  av_free(buf);
8452  return 0;
8453 }
8454 
8456 {
8457  AVFormatContext *ctx = c->fc;
8458  AVStream *st = NULL;
8459  AVBPrint scheme_buf, value_buf;
8460  int64_t scheme_str_len = 0, value_str_len = 0;
8461  int version, flags, ret = AVERROR_BUG;
8462  int64_t size = atom.size;
8463 
8464  if (atom.size < 6)
8465  // 4 bytes for version + flags, 2x 1 byte for null
8466  return AVERROR_INVALIDDATA;
8467 
8468  if (c->fc->nb_streams < 1)
8469  return 0;
8470  st = c->fc->streams[c->fc->nb_streams-1];
8471 
8472  version = avio_r8(pb);
8473  flags = avio_rb24(pb);
8474  size -= 4;
8475 
8476  if (version != 0 || flags != 0) {
8478  "Unsupported 'kind' box with version %d, flags: %x",
8479  version, flags);
8480  return AVERROR_INVALIDDATA;
8481  }
8482 
8483  av_bprint_init(&scheme_buf, 0, AV_BPRINT_SIZE_UNLIMITED);
8484  av_bprint_init(&value_buf, 0, AV_BPRINT_SIZE_UNLIMITED);
8485 
8486  if ((scheme_str_len = ff_read_string_to_bprint_overwrite(pb, &scheme_buf,
8487  size)) < 0) {
8488  ret = scheme_str_len;
8489  goto cleanup;
8490  }
8491 
8492  if (scheme_str_len + 1 >= size) {
8493  // we need to have another string, even if nullptr.
8494  // we check with + 1 since we expect that if size was not hit,
8495  // an additional null was read.
8497  goto cleanup;
8498  }
8499 
8500  size -= scheme_str_len + 1;
8501 
8502  if ((value_str_len = ff_read_string_to_bprint_overwrite(pb, &value_buf,
8503  size)) < 0) {
8504  ret = value_str_len;
8505  goto cleanup;
8506  }
8507 
8508  if (value_str_len == size) {
8509  // in case of no trailing null, box is not valid.
8511  goto cleanup;
8512  }
8513 
8515  "%s stream %d KindBox(scheme: %s, value: %s)\n",
8517  st->index,
8518  scheme_buf.str, value_buf.str);
8519 
8520  for (int i = 0; ff_mov_track_kind_table[i].scheme_uri; i++) {
8522  if (!av_strstart(scheme_buf.str, map.scheme_uri, NULL))
8523  continue;
8524 
8525  for (int j = 0; map.value_maps[j].disposition; j++) {
8526  const struct MP4TrackKindValueMapping value_map = map.value_maps[j];
8527  if (!av_strstart(value_buf.str, value_map.value, NULL))
8528  continue;
8529 
8530  st->disposition |= value_map.disposition;
8531  }
8532  }
8533 
8534  ret = 0;
8535 
8536 cleanup:
8537 
8538  av_bprint_finalize(&scheme_buf, NULL);
8539  av_bprint_finalize(&value_buf, NULL);
8540 
8541  return ret;
8542 }
8543 
8545 {
8546  AVStream *st;
8547  AVChannelLayout ch_layout = { 0 };
8548  int ret, i, version, type;
8549  int ambisonic_order, channel_order, normalization, channel_count;
8550  int ambi_channels, non_diegetic_channels;
8551 
8552  if (c->fc->nb_streams < 1)
8553  return 0;
8554 
8555  st = c->fc->streams[c->fc->nb_streams - 1];
8556 
8557  if (atom.size < 16) {
8558  av_log(c->fc, AV_LOG_ERROR, "SA3D audio box too small\n");
8559  return AVERROR_INVALIDDATA;
8560  }
8561 
8562  version = avio_r8(pb);
8563  if (version) {
8564  av_log(c->fc, AV_LOG_WARNING, "Unsupported SA3D box version %d\n", version);
8565  return 0;
8566  }
8567 
8568  type = avio_r8(pb);
8569  if (type & 0x7f) {
8570  av_log(c->fc, AV_LOG_WARNING,
8571  "Unsupported ambisonic type %d\n", type & 0x7f);
8572  return 0;
8573  }
8574  non_diegetic_channels = (type >> 7) * 2; // head_locked_stereo
8575 
8576  ambisonic_order = avio_rb32(pb);
8577 
8578  channel_order = avio_r8(pb);
8579  if (channel_order) {
8580  av_log(c->fc, AV_LOG_WARNING,
8581  "Unsupported channel_order %d\n", channel_order);
8582  return 0;
8583  }
8584 
8585  normalization = avio_r8(pb);
8586  if (normalization) {
8587  av_log(c->fc, AV_LOG_WARNING,
8588  "Unsupported normalization %d\n", normalization);
8589  return 0;
8590  }
8591 
8592  channel_count = avio_rb32(pb);
8593  if (ambisonic_order < 0 || ambisonic_order > 31 ||
8594  channel_count != ((ambisonic_order + 1LL) * (ambisonic_order + 1LL) +
8595  non_diegetic_channels)) {
8596  av_log(c->fc, AV_LOG_ERROR,
8597  "Invalid number of channels (%d / %d)\n",
8598  channel_count, ambisonic_order);
8599  return 0;
8600  }
8601  ambi_channels = channel_count - non_diegetic_channels;
8602 
8603  ret = av_channel_layout_custom_init(&ch_layout, channel_count);
8604  if (ret < 0)
8605  return 0;
8606 
8607  for (i = 0; i < channel_count; i++) {
8608  unsigned channel = avio_rb32(pb);
8609 
8610  if (channel >= channel_count) {
8611  av_log(c->fc, AV_LOG_ERROR, "Invalid channel index (%d / %d)\n",
8612  channel, ambisonic_order);
8613  av_channel_layout_uninit(&ch_layout);
8614  return 0;
8615  }
8616  if (channel >= ambi_channels)
8617  ch_layout.u.map[i].id = channel - ambi_channels;
8618  else
8619  ch_layout.u.map[i].id = AV_CHAN_AMBISONIC_BASE + channel;
8620  }
8621 
8623  if (ret < 0) {
8624  av_channel_layout_uninit(&ch_layout);
8625  return 0;
8626  }
8627 
8629  st->codecpar->ch_layout = ch_layout;
8630 
8631  return 0;
8632 }
8633 
8635 {
8636  AVStream *st;
8637  int version;
8638 
8639  if (c->fc->nb_streams < 1)
8640  return 0;
8641 
8642  st = c->fc->streams[c->fc->nb_streams - 1];
8643 
8644  if (atom.size < 5) {
8645  av_log(c->fc, AV_LOG_ERROR, "Empty SAND audio box\n");
8646  return AVERROR_INVALIDDATA;
8647  }
8648 
8649  version = avio_r8(pb);
8650  if (version) {
8651  av_log(c->fc, AV_LOG_WARNING, "Unsupported SAND box version %d\n", version);
8652  return 0;
8653  }
8654 
8656 
8657  return 0;
8658 }
8659 
8660 static int rb_size(AVIOContext *pb, int64_t *value, int size)
8661 {
8662  if (size == 0)
8663  *value = 0;
8664  else if (size == 1)
8665  *value = avio_r8(pb);
8666  else if (size == 2)
8667  *value = avio_rb16(pb);
8668  else if (size == 4)
8669  *value = avio_rb32(pb);
8670  else if (size == 8) {
8671  *value = avio_rb64(pb);
8672  if (*value < 0)
8673  return -1;
8674  } else
8675  return -1;
8676  return size;
8677 }
8678 
8680 {
8681  avio_rb32(pb); // version & flags.
8682  c->primary_item_id = avio_rb16(pb);
8683  av_log(c->fc, AV_LOG_TRACE, "pitm: primary_item_id %d\n", c->primary_item_id);
8684  return atom.size;
8685 }
8686 
8688 {
8689  c->idat_offset = avio_tell(pb);
8690  return 0;
8691 }
8692 
8694 {
8695  HEIFItem **heif_item;
8696  int version, offset_size, length_size, base_offset_size, index_size;
8697  int item_count, extent_count;
8698  int64_t base_offset, extent_offset, extent_length;
8699  uint8_t value;
8700 
8701  if (c->found_iloc) {
8702  av_log(c->fc, AV_LOG_INFO, "Duplicate iloc box found\n");
8703  return 0;
8704  }
8705 
8706  version = avio_r8(pb);
8707  avio_rb24(pb); // flags.
8708 
8709  value = avio_r8(pb);
8710  offset_size = (value >> 4) & 0xF;
8711  length_size = value & 0xF;
8712  value = avio_r8(pb);
8713  base_offset_size = (value >> 4) & 0xF;
8714  index_size = !version ? 0 : (value & 0xF);
8715  if (index_size) {
8716  avpriv_report_missing_feature(c->fc, "iloc: index_size != 0");
8717  return AVERROR_PATCHWELCOME;
8718  }
8719  item_count = (version < 2) ? avio_rb16(pb) : avio_rb32(pb);
8720 
8721  heif_item = av_realloc_array(c->heif_item, FFMAX(item_count, c->nb_heif_item), sizeof(*c->heif_item));
8722  if (!heif_item)
8723  return AVERROR(ENOMEM);
8724  c->heif_item = heif_item;
8725  if (item_count > c->nb_heif_item)
8726  memset(&c->heif_item[c->nb_heif_item], 0,
8727  sizeof(*c->heif_item) * (item_count - c->nb_heif_item));
8728  c->nb_heif_item = FFMAX(c->nb_heif_item, item_count);
8729 
8730  av_log(c->fc, AV_LOG_TRACE, "iloc: item_count %d\n", item_count);
8731  for (int i = 0; i < item_count; i++) {
8732  HEIFItem *item = c->heif_item[i];
8733  int item_id = (version < 2) ? avio_rb16(pb) : avio_rb32(pb);
8734  int offset_type = (version > 0) ? avio_rb16(pb) & 0xf : 0;
8735 
8736  if (avio_feof(pb))
8737  return AVERROR_INVALIDDATA;
8738  if (offset_type > 1) {
8739  avpriv_report_missing_feature(c->fc, "iloc offset type %d", offset_type);
8740  return AVERROR_PATCHWELCOME;
8741  }
8742 
8743  avio_rb16(pb); // data_reference_index.
8744  if (rb_size(pb, &base_offset, base_offset_size) < 0)
8745  return AVERROR_INVALIDDATA;
8746  extent_count = avio_rb16(pb);
8747  if (extent_count > 1) {
8748  // For still AVIF images, we only support one extent item.
8749  avpriv_report_missing_feature(c->fc, "iloc: extent_count > 1");
8750  return AVERROR_PATCHWELCOME;
8751  }
8752 
8753  if (rb_size(pb, &extent_offset, offset_size) < 0 ||
8754  rb_size(pb, &extent_length, length_size) < 0 ||
8755  base_offset > INT64_MAX - extent_offset)
8756  return AVERROR_INVALIDDATA;
8757 
8758  if (!item)
8759  item = c->heif_item[i] = av_mallocz(sizeof(*item));
8760  if (!item)
8761  return AVERROR(ENOMEM);
8762 
8763  item->item_id = item_id;
8764 
8765  if (offset_type == 1)
8766  item->is_idat_relative = 1;
8767  item->extent_length = extent_length;
8768  item->extent_offset = base_offset + extent_offset;
8769  av_log(c->fc, AV_LOG_TRACE, "iloc: item_idx %d, offset_type %d, "
8770  "extent_offset %"PRId64", extent_length %"PRId64"\n",
8771  i, offset_type, item->extent_offset, item->extent_length);
8772  }
8773 
8774  c->found_iloc = 1;
8775  return atom.size;
8776 }
8777 
8778 static int mov_read_infe(MOVContext *c, AVIOContext *pb, MOVAtom atom, int idx)
8779 {
8780  HEIFItem *item;
8781  AVBPrint item_name;
8782  int64_t size = atom.size;
8783  uint32_t item_type;
8784  int item_id;
8785  int version, ret;
8786 
8787  version = avio_r8(pb);
8788  avio_rb24(pb); // flags.
8789  size -= 4;
8790  if (size < 0)
8791  return AVERROR_INVALIDDATA;
8792 
8793  if (version < 2) {
8794  avpriv_report_missing_feature(c->fc, "infe version < 2");
8795  avio_skip(pb, size);
8796  return 1;
8797  }
8798 
8799  item_id = version > 2 ? avio_rb32(pb) : avio_rb16(pb);
8800  avio_rb16(pb); // item_protection_index
8801  item_type = avio_rl32(pb);
8802  size -= 8;
8803  if (size < 1)
8804  return AVERROR_INVALIDDATA;
8805 
8808  if (ret < 0) {
8810  return ret;
8811  }
8812 
8813  av_log(c->fc, AV_LOG_TRACE, "infe: item_id %d, item_type %s, item_name %s\n",
8814  item_id, av_fourcc2str(item_type), item_name.str);
8815 
8816  size -= ret + 1;
8817  if (size > 0)
8818  avio_skip(pb, size);
8819 
8820  item = c->heif_item[idx];
8821  if (!item)
8822  item = c->heif_item[idx] = av_mallocz(sizeof(*item));
8823  if (!item)
8824  return AVERROR(ENOMEM);
8825 
8826  if (ret)
8827  av_bprint_finalize(&item_name, &c->heif_item[idx]->name);
8828  c->heif_item[idx]->item_id = item_id;
8829  c->heif_item[idx]->type = item_type;
8830 
8831  switch (item_type) {
8832  case MKTAG('a','v','0','1'):
8833  case MKTAG('h','v','c','1'):
8834  ret = heif_add_stream(c, c->heif_item[idx]);
8835  if (ret < 0)
8836  return ret;
8837  break;
8838  }
8839 
8840  return 0;
8841 }
8842 
8844 {
8845  HEIFItem **heif_item;
8846  int entry_count;
8847  int version, got_stream = 0, ret, i;
8848 
8849  if (c->found_iinf) {
8850  av_log(c->fc, AV_LOG_WARNING, "Duplicate iinf box found\n");
8851  return 0;
8852  }
8853 
8854  version = avio_r8(pb);
8855  avio_rb24(pb); // flags.
8856  entry_count = version ? avio_rb32(pb) : avio_rb16(pb);
8857 
8858  heif_item = av_realloc_array(c->heif_item, FFMAX(entry_count, c->nb_heif_item), sizeof(*c->heif_item));
8859  if (!heif_item)
8860  return AVERROR(ENOMEM);
8861  c->heif_item = heif_item;
8862  if (entry_count > c->nb_heif_item)
8863  memset(&c->heif_item[c->nb_heif_item], 0,
8864  sizeof(*c->heif_item) * (entry_count - c->nb_heif_item));
8865  c->nb_heif_item = FFMAX(c->nb_heif_item, entry_count);
8866 
8867  for (i = 0; i < entry_count; i++) {
8868  MOVAtom infe;
8869 
8870  infe.size = avio_rb32(pb) - 8;
8871  infe.type = avio_rl32(pb);
8872  if (avio_feof(pb)) {
8874  goto fail;
8875  }
8876  ret = mov_read_infe(c, pb, infe, i);
8877  if (ret < 0)
8878  goto fail;
8879  if (!ret)
8880  got_stream = 1;
8881  }
8882 
8883  c->found_iinf = got_stream;
8884  return 0;
8885 fail:
8886  for (; i >= 0; i--) {
8887  HEIFItem *item = c->heif_item[i];
8888 
8889  if (!item)
8890  continue;
8891 
8892  av_freep(&item->name);
8893  if (!item->st)
8894  continue;
8895 
8896  mov_free_stream_context(c->fc, item->st);
8897  ff_remove_stream(c->fc, item->st);
8898  item->st = NULL;
8899  }
8900  return ret;
8901 }
8902 
8904 {
8905  HEIFItem *item = NULL;
8906  HEIFGrid *grid;
8907  int entries, i;
8908  int from_item_id = version ? avio_rb32(pb) : avio_rb16(pb);
8909 
8910  for (int i = 0; i < c->nb_heif_grid; i++) {
8911  if (c->heif_grid[i].item->item_id == from_item_id) {
8912  av_log(c->fc, AV_LOG_ERROR, "More than one 'dimg' box "
8913  "referencing the same Derived Image item\n");
8914  return AVERROR_INVALIDDATA;
8915  }
8916  }
8917  for (int i = 0; i < c->nb_heif_item; i++) {
8918  if (!c->heif_item[i] || c->heif_item[i]->item_id != from_item_id)
8919  continue;
8920  item = c->heif_item[i];
8921 
8922  switch (item->type) {
8923  case MKTAG('g','r','i','d'):
8924  case MKTAG('i','o','v','l'):
8925  break;
8926  default:
8927  avpriv_report_missing_feature(c->fc, "Derived Image item of type %s",
8928  av_fourcc2str(item->type));
8929  return 0;
8930  }
8931  break;
8932  }
8933  if (!item) {
8934  av_log(c->fc, AV_LOG_ERROR, "Missing grid information\n");
8935  return AVERROR_INVALIDDATA;
8936  }
8937 
8938  grid = av_realloc_array(c->heif_grid, c->nb_heif_grid + 1U,
8939  sizeof(*c->heif_grid));
8940  if (!grid)
8941  return AVERROR(ENOMEM);
8942  c->heif_grid = grid;
8943  grid = &grid[c->nb_heif_grid++];
8944 
8945  entries = avio_rb16(pb);
8946  grid->tile_id_list = av_malloc_array(entries, sizeof(*grid->tile_id_list));
8947  grid->tile_idx_list = av_calloc(entries, sizeof(*grid->tile_idx_list));
8948  grid->tile_item_list = av_calloc(entries, sizeof(*grid->tile_item_list));
8949  if (!grid->tile_id_list || !grid->tile_item_list || !grid->tile_idx_list)
8950  return AVERROR(ENOMEM);
8951  /* 'to' item ids */
8952  for (i = 0; i < entries; i++)
8953  grid->tile_id_list[i] = version ? avio_rb32(pb) : avio_rb16(pb);
8954  grid->nb_tiles = entries;
8955  grid->item = item;
8956 
8957  av_log(c->fc, AV_LOG_TRACE, "dimg: from_item_id %d, entries %d\n",
8958  from_item_id, entries);
8959 
8960  return 0;
8961 }
8962 
8964 {
8965  int entries;
8966  int to_item_id, from_item_id = version ? avio_rb32(pb) : avio_rb16(pb);
8967 
8968  entries = avio_rb16(pb);
8969  if (entries > 1) {
8970  avpriv_request_sample(c->fc, "thmb in iref referencing several items");
8971  return AVERROR_PATCHWELCOME;
8972  }
8973  /* 'to' item ids */
8974  to_item_id = version ? avio_rb32(pb) : avio_rb16(pb);
8975 
8976  if (to_item_id != c->primary_item_id)
8977  return 0;
8978 
8979  c->thmb_item_id = from_item_id;
8980 
8981  av_log(c->fc, AV_LOG_TRACE, "thmb: from_item_id %d, entries %d\n",
8982  from_item_id, entries);
8983 
8984  return 0;
8985 }
8986 
8988 {
8989  int version = avio_r8(pb);
8990  avio_rb24(pb); // flags
8991  atom.size -= 4;
8992 
8993  if (version > 1) {
8994  av_log(c->fc, AV_LOG_WARNING, "Unknown iref box version %d\n", version);
8995  return 0;
8996  }
8997 
8998  while (atom.size) {
8999  uint32_t type, size = avio_rb32(pb);
9000  int64_t next = avio_tell(pb);
9001 
9002  if (size < 14 || next < 0 || next > INT64_MAX - size)
9003  return AVERROR_INVALIDDATA;
9004 
9005  next += size - 4;
9006  type = avio_rl32(pb);
9007  switch (type) {
9008  case MKTAG('d','i','m','g'):
9010  break;
9011  case MKTAG('t','h','m','b'):
9013  break;
9014  default:
9015  av_log(c->fc, AV_LOG_DEBUG, "Unknown iref type %s size %"PRIu32"\n",
9016  av_fourcc2str(type), size);
9017  }
9018 
9019  atom.size -= size;
9020  avio_seek(pb, next, SEEK_SET);
9021  }
9022  return 0;
9023 }
9024 
9026 {
9027  HEIFItem *item;
9028  uint32_t width, height;
9029 
9030  avio_r8(pb); /* version */
9031  avio_rb24(pb); /* flags */
9032  width = avio_rb32(pb);
9033  height = avio_rb32(pb);
9034 
9035  av_log(c->fc, AV_LOG_TRACE, "ispe: item_id %d, width %u, height %u\n",
9036  c->cur_item_id, width, height);
9037 
9038  item = heif_cur_item(c);
9039  if (item) {
9040  item->width = width;
9041  item->height = height;
9042  }
9043 
9044  return 0;
9045 }
9046 
9048 {
9049  HEIFItem *item;
9050  int angle;
9051 
9052  angle = avio_r8(pb) & 0x3;
9053 
9054  av_log(c->fc, AV_LOG_TRACE, "irot: item_id %d, angle %u\n",
9055  c->cur_item_id, angle);
9056 
9057  item = heif_cur_item(c);
9058  if (item) {
9059  // angle * 90 specifies the angle (in anti-clockwise direction)
9060  // in units of degrees.
9061  item->rotation = angle * 90;
9062  }
9063 
9064  return 0;
9065 }
9066 
9068 {
9069  HEIFItem *item;
9070  int axis;
9071 
9072  axis = avio_r8(pb) & 0x1;
9073 
9074  av_log(c->fc, AV_LOG_TRACE, "imir: item_id %d, axis %u\n",
9075  c->cur_item_id, axis);
9076 
9077  item = heif_cur_item(c);
9078  if (item) {
9079  item->hflip = axis;
9080  item->vflip = !axis;
9081  }
9082 
9083  return 0;
9084 }
9085 
9087 {
9088  typedef struct MOVAtoms {
9089  FFIOContext b;
9090  uint32_t type;
9091  int64_t size;
9092  uint8_t *data;
9093  } MOVAtoms;
9094  MOVAtoms *atoms = NULL;
9095  MOVAtom a;
9096  unsigned count;
9097  int nb_atoms = 0;
9098  int version, flags;
9099  int ret;
9100 
9101  a.size = avio_rb32(pb);
9102  a.type = avio_rl32(pb);
9103 
9104  if (a.size < 8 || a.type != MKTAG('i','p','c','o'))
9105  return AVERROR_INVALIDDATA;
9106 
9107  a.size -= 8;
9108  while (a.size >= 8) {
9109  MOVAtoms *ref = av_dynarray2_add((void**)&atoms, &nb_atoms, sizeof(MOVAtoms), NULL);
9110  if (!ref) {
9111  ret = AVERROR(ENOMEM);
9112  goto fail;
9113  }
9114  ref->data = NULL;
9115  ref->size = avio_rb32(pb);
9116  ref->type = avio_rl32(pb);
9117  if (ref->size > a.size || ref->size < 8)
9118  break;
9119  ref->data = av_malloc(ref->size);
9120  if (!ref->data) {
9122  goto fail;
9123  }
9124  av_log(c->fc, AV_LOG_TRACE, "ipco: index %d, box type %s\n", nb_atoms, av_fourcc2str(ref->type));
9125  avio_seek(pb, -8, SEEK_CUR);
9126  if (avio_read(pb, ref->data, ref->size) != ref->size) {
9128  goto fail;
9129  }
9130  ffio_init_read_context(&ref->b, ref->data, ref->size);
9131  a.size -= ref->size;
9132  }
9133 
9134  if (a.size) {
9136  goto fail;
9137  }
9138 
9139  a.size = avio_rb32(pb);
9140  a.type = avio_rl32(pb);
9141 
9142  if (a.size < 8 || a.type != MKTAG('i','p','m','a')) {
9144  goto fail;
9145  }
9146 
9147  version = avio_r8(pb);
9148  flags = avio_rb24(pb);
9149  count = avio_rb32(pb);
9150 
9151  for (int i = 0; i < count; i++) {
9152  int item_id = version ? avio_rb32(pb) : avio_rb16(pb);
9153  int assoc_count = avio_r8(pb);
9154 
9155  if (avio_feof(pb)) {
9157  goto fail;
9158  }
9159 
9160  for (int j = 0; j < assoc_count; j++) {
9161  MOVAtoms *ref;
9162  int index = avio_r8(pb) & 0x7f;
9163  if (flags & 1) {
9164  index <<= 8;
9165  index |= avio_r8(pb);
9166  }
9167  if (index > nb_atoms || index <= 0) {
9169  goto fail;
9170  }
9171  ref = &atoms[--index];
9172 
9173  av_log(c->fc, AV_LOG_TRACE, "ipma: property_index %d, item_id %d, item_type %s\n",
9174  index + 1, item_id, av_fourcc2str(ref->type));
9175 
9176  c->cur_item_id = item_id;
9177 
9178  ret = mov_read_default(c, &ref->b.pub,
9179  (MOVAtom) { .size = ref->size,
9180  .type = MKTAG('i','p','c','o') });
9181  if (ret < 0)
9182  goto fail;
9183  ffio_init_read_context(&ref->b, ref->data, ref->size);
9184  }
9185  }
9186 
9187  ret = 0;
9188 fail:
9189  c->cur_item_id = -1;
9190  for (int i = 0; i < nb_atoms; i++)
9191  av_free(atoms[i].data);
9192  av_free(atoms);
9193 
9194  return ret;
9195 }
9196 
9198 { MKTAG('A','C','L','R'), mov_read_aclr },
9199 { MKTAG('A','P','R','G'), mov_read_avid },
9200 { MKTAG('A','A','L','P'), mov_read_avid },
9201 { MKTAG('A','R','E','S'), mov_read_ares },
9202 { MKTAG('a','v','s','s'), mov_read_avss },
9203 { MKTAG('a','v','1','C'), mov_read_glbl },
9204 { MKTAG('c','h','p','l'), mov_read_chpl },
9205 { MKTAG('c','o','6','4'), mov_read_stco },
9206 { MKTAG('c','o','l','r'), mov_read_colr },
9207 { MKTAG('c','t','t','s'), mov_read_ctts }, /* composition time to sample */
9208 { MKTAG('d','i','n','f'), mov_read_default },
9209 { MKTAG('D','p','x','E'), mov_read_dpxe },
9210 { MKTAG('d','r','e','f'), mov_read_dref },
9211 { MKTAG('e','d','t','s'), mov_read_default },
9212 { MKTAG('e','l','s','t'), mov_read_elst },
9213 { MKTAG('e','n','d','a'), mov_read_enda },
9214 { MKTAG('f','i','e','l'), mov_read_fiel },
9215 { MKTAG('a','d','r','m'), mov_read_adrm },
9216 { MKTAG('f','t','y','p'), mov_read_ftyp },
9217 { MKTAG('g','l','b','l'), mov_read_glbl },
9218 { MKTAG('h','d','l','r'), mov_read_hdlr },
9219 { MKTAG('i','l','s','t'), mov_read_ilst },
9220 { MKTAG('j','p','2','h'), mov_read_jp2h },
9221 { MKTAG('m','d','a','t'), mov_read_mdat },
9222 { MKTAG('m','d','h','d'), mov_read_mdhd },
9223 { MKTAG('m','d','i','a'), mov_read_default },
9224 { MKTAG('m','e','t','a'), mov_read_meta },
9225 { MKTAG('m','i','n','f'), mov_read_default },
9226 { MKTAG('m','o','o','f'), mov_read_moof },
9227 { MKTAG('m','o','o','v'), mov_read_moov },
9228 { MKTAG('m','v','e','x'), mov_read_default },
9229 { MKTAG('m','v','h','d'), mov_read_mvhd },
9230 { MKTAG('S','M','I',' '), mov_read_svq3 },
9231 { MKTAG('a','l','a','c'), mov_read_alac }, /* alac specific atom */
9232 { MKTAG('a','v','c','C'), mov_read_glbl },
9233 { MKTAG('p','a','s','p'), mov_read_pasp },
9234 { MKTAG('c','l','a','p'), mov_read_clap },
9235 { MKTAG('s','b','a','s'), mov_read_sbas },
9236 { MKTAG('s','i','d','x'), mov_read_sidx },
9237 { MKTAG('s','t','b','l'), mov_read_default },
9238 { MKTAG('s','t','c','o'), mov_read_stco },
9239 { MKTAG('s','t','p','s'), mov_read_stps },
9240 { MKTAG('s','t','r','f'), mov_read_strf },
9241 { MKTAG('s','t','s','c'), mov_read_stsc },
9242 { MKTAG('s','t','s','d'), mov_read_stsd }, /* sample description */
9243 { MKTAG('s','t','s','s'), mov_read_stss }, /* sync sample */
9244 { MKTAG('s','t','s','z'), mov_read_stsz }, /* sample size */
9245 { MKTAG('s','t','t','s'), mov_read_stts },
9246 { MKTAG('s','t','z','2'), mov_read_stsz }, /* compact sample size */
9247 { MKTAG('s','d','t','p'), mov_read_sdtp }, /* independent and disposable samples */
9248 { MKTAG('t','k','h','d'), mov_read_tkhd }, /* track header */
9249 { MKTAG('t','f','d','t'), mov_read_tfdt },
9250 { MKTAG('t','f','h','d'), mov_read_tfhd }, /* track fragment header */
9251 { MKTAG('t','r','a','k'), mov_read_trak },
9252 { MKTAG('t','r','a','f'), mov_read_default },
9253 { MKTAG('t','r','e','f'), mov_read_default },
9254 { MKTAG('t','m','c','d'), mov_read_tmcd },
9255 { MKTAG('c','h','a','p'), mov_read_chap },
9256 { MKTAG('t','r','e','x'), mov_read_trex },
9257 { MKTAG('t','r','u','n'), mov_read_trun },
9258 { MKTAG('u','d','t','a'), mov_read_default },
9259 { MKTAG('w','a','v','e'), mov_read_wave },
9260 { MKTAG('e','s','d','s'), mov_read_esds },
9261 { MKTAG('d','a','c','3'), mov_read_dac3 }, /* AC-3 info */
9262 { MKTAG('d','e','c','3'), mov_read_dec3 }, /* EAC-3 info */
9263 { MKTAG('d','d','t','s'), mov_read_ddts }, /* DTS audio descriptor */
9264 { MKTAG('w','i','d','e'), mov_read_wide }, /* place holder */
9265 { MKTAG('w','f','e','x'), mov_read_wfex },
9266 { MKTAG('c','m','o','v'), mov_read_cmov },
9267 { MKTAG('c','h','a','n'), mov_read_chan }, /* channel layout from quicktime */
9268 { MKTAG('c','h','n','l'), mov_read_chnl }, /* channel layout from ISO-14496-12 */
9269 { MKTAG('d','v','c','1'), mov_read_dvc1 },
9270 { MKTAG('s','g','p','d'), mov_read_sgpd },
9271 { MKTAG('s','b','g','p'), mov_read_sbgp },
9272 { MKTAG('h','v','c','C'), mov_read_glbl },
9273 { MKTAG('v','v','c','C'), mov_read_glbl },
9274 { MKTAG('u','u','i','d'), mov_read_uuid },
9275 { MKTAG('C','i','n', 0x8e), mov_read_targa_y216 },
9276 { MKTAG('f','r','e','e'), mov_read_free },
9277 { MKTAG('-','-','-','-'), mov_read_custom },
9278 { MKTAG('s','i','n','f'), mov_read_default },
9279 { MKTAG('f','r','m','a'), mov_read_frma },
9280 { MKTAG('s','e','n','c'), mov_read_senc },
9281 { MKTAG('s','a','i','z'), mov_read_saiz },
9282 { MKTAG('s','a','i','o'), mov_read_saio },
9283 { MKTAG('p','s','s','h'), mov_read_pssh },
9284 { MKTAG('s','c','h','m'), mov_read_schm },
9285 { MKTAG('s','c','h','i'), mov_read_default },
9286 { MKTAG('t','e','n','c'), mov_read_tenc },
9287 { MKTAG('d','f','L','a'), mov_read_dfla },
9288 { MKTAG('s','t','3','d'), mov_read_st3d }, /* stereoscopic 3D video box */
9289 { MKTAG('s','v','3','d'), mov_read_sv3d }, /* spherical video box */
9290 { MKTAG('v','e','x','u'), mov_read_vexu }, /* video extension usage */
9291 { MKTAG('h','f','o','v'), mov_read_hfov },
9292 { MKTAG('d','O','p','s'), mov_read_dops },
9293 { MKTAG('d','m','l','p'), mov_read_dmlp },
9294 { MKTAG('S','m','D','m'), mov_read_smdm },
9295 { MKTAG('C','o','L','L'), mov_read_coll },
9296 { MKTAG('v','p','c','C'), mov_read_vpcc },
9297 { MKTAG('m','d','c','v'), mov_read_mdcv },
9298 { MKTAG('c','l','l','i'), mov_read_clli },
9299 { MKTAG('d','v','c','C'), mov_read_dvcc_dvvc },
9300 { MKTAG('d','v','v','C'), mov_read_dvcc_dvvc },
9301 { MKTAG('d','v','w','C'), mov_read_dvcc_dvvc },
9302 { MKTAG('k','i','n','d'), mov_read_kind },
9303 { MKTAG('S','A','3','D'), mov_read_SA3D }, /* ambisonic audio box */
9304 { MKTAG('S','A','N','D'), mov_read_SAND }, /* non diegetic audio box */
9305 { MKTAG('i','l','o','c'), mov_read_iloc },
9306 { MKTAG('p','c','m','C'), mov_read_pcmc }, /* PCM configuration box */
9307 { MKTAG('p','i','t','m'), mov_read_pitm },
9308 { MKTAG('e','v','c','C'), mov_read_glbl },
9309 { MKTAG('i','d','a','t'), mov_read_idat },
9310 { MKTAG('i','m','i','r'), mov_read_imir },
9311 { MKTAG('i','r','e','f'), mov_read_iref },
9312 { MKTAG('i','s','p','e'), mov_read_ispe },
9313 { MKTAG('i','r','o','t'), mov_read_irot },
9314 { MKTAG('i','p','r','p'), mov_read_iprp },
9315 { MKTAG('i','i','n','f'), mov_read_iinf },
9316 { MKTAG('a','m','v','e'), mov_read_amve }, /* ambient viewing environment box */
9317 { MKTAG('l','h','v','C'), mov_read_lhvc },
9318 { MKTAG('l','v','c','C'), mov_read_glbl },
9319 #if CONFIG_IAMFDEC
9320 { MKTAG('i','a','c','b'), mov_read_iacb },
9321 #endif
9322 { 0, NULL }
9323 };
9324 
9326 {
9327  int64_t total_size = 0;
9328  MOVAtom a;
9329  int i;
9330 
9331  if (c->atom_depth > 10) {
9332  av_log(c->fc, AV_LOG_ERROR, "Atoms too deeply nested\n");
9333  return AVERROR_INVALIDDATA;
9334  }
9335  c->atom_depth ++;
9336 
9337  if (atom.size < 0)
9338  atom.size = INT64_MAX;
9339  while (total_size <= atom.size - 8) {
9340  int (*parse)(MOVContext*, AVIOContext*, MOVAtom) = NULL;
9341  a.size = avio_rb32(pb);
9342  a.type = avio_rl32(pb);
9343  if (avio_feof(pb))
9344  break;
9345  if (((a.type == MKTAG('f','r','e','e') && c->moov_retry) ||
9346  a.type == MKTAG('h','o','o','v')) &&
9347  a.size >= 8 &&
9348  c->fc->strict_std_compliance < FF_COMPLIANCE_STRICT) {
9349  uint32_t type;
9350  avio_skip(pb, 4);
9351  type = avio_rl32(pb);
9352  if (avio_feof(pb))
9353  break;
9354  avio_seek(pb, -8, SEEK_CUR);
9355  if (type == MKTAG('m','v','h','d') ||
9356  type == MKTAG('c','m','o','v')) {
9357  av_log(c->fc, AV_LOG_ERROR, "Detected moov in a free or hoov atom.\n");
9358  a.type = MKTAG('m','o','o','v');
9359  }
9360  }
9361  if (atom.type != MKTAG('r','o','o','t') &&
9362  atom.type != MKTAG('m','o','o','v')) {
9363  if (a.type == MKTAG('t','r','a','k') ||
9364  a.type == MKTAG('m','d','a','t')) {
9365  av_log(c->fc, AV_LOG_ERROR, "Broken file, trak/mdat not at top-level\n");
9366  avio_skip(pb, -8);
9367  c->atom_depth --;
9368  return 0;
9369  }
9370  }
9371  total_size += 8;
9372  if (a.size == 1 && total_size + 8 <= atom.size) { /* 64 bit extended size */
9373  a.size = avio_rb64(pb) - 8;
9374  total_size += 8;
9375  }
9376  av_log(c->fc, AV_LOG_TRACE, "type:'%s' parent:'%s' sz: %"PRId64" %"PRId64" %"PRId64"\n",
9377  av_fourcc2str(a.type), av_fourcc2str(atom.type), a.size, total_size, atom.size);
9378  if (a.size == 0) {
9379  a.size = atom.size - total_size + 8;
9380  }
9381  if (a.size < 0)
9382  break;
9383  a.size -= 8;
9384  if (a.size < 0)
9385  break;
9386  a.size = FFMIN(a.size, atom.size - total_size);
9387 
9388  for (i = 0; mov_default_parse_table[i].type; i++)
9389  if (mov_default_parse_table[i].type == a.type) {
9391  break;
9392  }
9393 
9394  // container is user data
9395  if (!parse && (atom.type == MKTAG('u','d','t','a') ||
9396  atom.type == MKTAG('i','l','s','t')))
9398 
9399  // Supports parsing the QuickTime Metadata Keys.
9400  // https://developer.apple.com/library/mac/documentation/QuickTime/QTFF/Metadata/Metadata.html
9401  if (!parse && c->found_hdlr_mdta &&
9402  atom.type == MKTAG('m','e','t','a') &&
9403  a.type == MKTAG('k','e','y','s') &&
9404  c->meta_keys_count == 0) {
9405  parse = mov_read_keys;
9406  }
9407 
9408  if (!parse) { /* skip leaf atoms data */
9409  avio_skip(pb, a.size);
9410  } else {
9411  int64_t start_pos = avio_tell(pb);
9412  int64_t left;
9413  int err = parse(c, pb, a);
9414  if (err < 0) {
9415  c->atom_depth --;
9416  return err;
9417  }
9418  if (c->found_moov && c->found_mdat && a.size <= INT64_MAX - start_pos &&
9419  ((!(pb->seekable & AVIO_SEEKABLE_NORMAL) || c->fc->flags & AVFMT_FLAG_IGNIDX || c->frag_index.complete) ||
9420  start_pos + a.size == avio_size(pb))) {
9421  if (!(pb->seekable & AVIO_SEEKABLE_NORMAL) || c->fc->flags & AVFMT_FLAG_IGNIDX || c->frag_index.complete)
9422  c->next_root_atom = start_pos + a.size;
9423  c->atom_depth --;
9424  return 0;
9425  }
9426  left = a.size - avio_tell(pb) + start_pos;
9427  if (left > 0) /* skip garbage at atom end */
9428  avio_skip(pb, left);
9429  else if (left < 0) {
9430  av_log(c->fc, AV_LOG_WARNING,
9431  "overread end of atom '%s' by %"PRId64" bytes\n",
9432  av_fourcc2str(a.type), -left);
9433  avio_seek(pb, left, SEEK_CUR);
9434  }
9435  }
9436 
9437  total_size += a.size;
9438  }
9439 
9440  if (total_size < atom.size && atom.size < 0x7ffff)
9441  avio_skip(pb, atom.size - total_size);
9442 
9443  c->atom_depth --;
9444  return 0;
9445 }
9446 
9447 static int mov_probe(const AVProbeData *p)
9448 {
9449  int64_t offset;
9450  uint32_t tag;
9451  int score = 0;
9452  int moov_offset = -1;
9453 
9454  /* check file header */
9455  offset = 0;
9456  for (;;) {
9457  int64_t size;
9458  int minsize = 8;
9459  /* ignore invalid offset */
9460  if ((offset + 8ULL) > (unsigned int)p->buf_size)
9461  break;
9462  size = AV_RB32(p->buf + offset);
9463  if (size == 1 && offset + 16 <= (unsigned int)p->buf_size) {
9464  size = AV_RB64(p->buf+offset + 8);
9465  minsize = 16;
9466  } else if (size == 0) {
9467  size = p->buf_size - offset;
9468  }
9469  if (size < minsize) {
9470  offset += 4;
9471  continue;
9472  }
9473  tag = AV_RL32(p->buf + offset + 4);
9474  switch(tag) {
9475  /* check for obvious tags */
9476  case MKTAG('m','o','o','v'):
9477  moov_offset = offset + 4;
9478  case MKTAG('m','d','a','t'):
9479  case MKTAG('p','n','o','t'): /* detect movs with preview pics like ew.mov and april.mov */
9480  case MKTAG('u','d','t','a'): /* Packet Video PVAuthor adds this and a lot of more junk */
9481  case MKTAG('f','t','y','p'):
9482  if (tag == MKTAG('f','t','y','p') &&
9483  ( AV_RL32(p->buf + offset + 8) == MKTAG('j','p','2',' ')
9484  || AV_RL32(p->buf + offset + 8) == MKTAG('j','p','x',' ')
9485  || AV_RL32(p->buf + offset + 8) == MKTAG('j','x','l',' ')
9486  )) {
9487  score = FFMAX(score, 5);
9488  } else {
9489  score = AVPROBE_SCORE_MAX;
9490  }
9491  break;
9492  /* those are more common words, so rate then a bit less */
9493  case MKTAG('e','d','i','w'): /* xdcam files have reverted first tags */
9494  case MKTAG('w','i','d','e'):
9495  case MKTAG('f','r','e','e'):
9496  case MKTAG('j','u','n','k'):
9497  case MKTAG('p','i','c','t'):
9498  score = FFMAX(score, AVPROBE_SCORE_MAX - 5);
9499  break;
9500  case MKTAG(0x82,0x82,0x7f,0x7d):
9501  score = FFMAX(score, AVPROBE_SCORE_EXTENSION - 5);
9502  break;
9503  case MKTAG('s','k','i','p'):
9504  case MKTAG('u','u','i','d'):
9505  case MKTAG('p','r','f','l'):
9506  /* if we only find those cause probedata is too small at least rate them */
9507  score = FFMAX(score, AVPROBE_SCORE_EXTENSION);
9508  break;
9509  }
9510  if (size > INT64_MAX - offset)
9511  break;
9512  offset += size;
9513  }
9514  if (score > AVPROBE_SCORE_MAX - 50 && moov_offset != -1) {
9515  /* moov atom in the header - we should make sure that this is not a
9516  * MOV-packed MPEG-PS */
9517  offset = moov_offset;
9518 
9519  while (offset < (p->buf_size - 16)) { /* Sufficient space */
9520  /* We found an actual hdlr atom */
9521  if (AV_RL32(p->buf + offset ) == MKTAG('h','d','l','r') &&
9522  AV_RL32(p->buf + offset + 8) == MKTAG('m','h','l','r') &&
9523  AV_RL32(p->buf + offset + 12) == MKTAG('M','P','E','G')) {
9524  av_log(NULL, AV_LOG_WARNING, "Found media data tag MPEG indicating this is a MOV-packed MPEG-PS.\n");
9525  /* We found a media handler reference atom describing an
9526  * MPEG-PS-in-MOV, return a
9527  * low score to force expanding the probe window until
9528  * mpegps_probe finds what it needs */
9529  return 5;
9530  } else {
9531  /* Keep looking */
9532  offset += 2;
9533  }
9534  }
9535  }
9536 
9537  return score;
9538 }
9539 
9540 // must be done after parsing all trak because there's no order requirement
9542 {
9543  MOVContext *mov = s->priv_data;
9544  MOVStreamContext *sc;
9545  int64_t cur_pos;
9546  int i, j;
9547  int chapter_track;
9548 
9549  for (j = 0; j < mov->nb_chapter_tracks; j++) {
9550  AVStream *st = NULL;
9551  FFStream *sti = NULL;
9552  chapter_track = mov->chapter_tracks[j];
9553  for (i = 0; i < s->nb_streams; i++) {
9554  sc = mov->fc->streams[i]->priv_data;
9555  if (sc->id == chapter_track) {
9556  st = s->streams[i];
9557  break;
9558  }
9559  }
9560  if (!st) {
9561  av_log(s, AV_LOG_ERROR, "Referenced QT chapter track not found\n");
9562  continue;
9563  }
9564  sti = ffstream(st);
9565 
9566  sc = st->priv_data;
9567  cur_pos = avio_tell(sc->pb);
9568 
9569  if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
9571  if (!st->attached_pic.data && sti->nb_index_entries) {
9572  // Retrieve the first frame, if possible
9573  AVIndexEntry *sample = &sti->index_entries[0];
9574  if (avio_seek(sc->pb, sample->pos, SEEK_SET) != sample->pos) {
9575  av_log(s, AV_LOG_ERROR, "Failed to retrieve first frame\n");
9576  goto finish;
9577  }
9578 
9579  if (ff_add_attached_pic(s, st, sc->pb, NULL, sample->size) < 0)
9580  goto finish;
9581  }
9582  } else {
9585  st->discard = AVDISCARD_ALL;
9586  for (int i = 0; i < sti->nb_index_entries; i++) {
9587  AVIndexEntry *sample = &sti->index_entries[i];
9588  int64_t end = i+1 < sti->nb_index_entries ? sti->index_entries[i+1].timestamp : st->duration;
9589  uint8_t *title;
9590  uint16_t ch;
9591  int len, title_len;
9592 
9593  if (end < sample->timestamp) {
9594  av_log(s, AV_LOG_WARNING, "ignoring stream duration which is shorter than chapters\n");
9595  end = AV_NOPTS_VALUE;
9596  }
9597 
9598  if (avio_seek(sc->pb, sample->pos, SEEK_SET) != sample->pos) {
9599  av_log(s, AV_LOG_ERROR, "Chapter %d not found in file\n", i);
9600  goto finish;
9601  }
9602 
9603  // the first two bytes are the length of the title
9604  len = avio_rb16(sc->pb);
9605  if (len > sample->size-2)
9606  continue;
9607  title_len = 2*len + 1;
9608  if (!(title = av_mallocz(title_len)))
9609  goto finish;
9610 
9611  // The samples could theoretically be in any encoding if there's an encd
9612  // atom following, but in practice are only utf-8 or utf-16, distinguished
9613  // instead by the presence of a BOM
9614  if (!len) {
9615  title[0] = 0;
9616  } else {
9617  ch = avio_rb16(sc->pb);
9618  if (ch == 0xfeff)
9619  avio_get_str16be(sc->pb, len, title, title_len);
9620  else if (ch == 0xfffe)
9621  avio_get_str16le(sc->pb, len, title, title_len);
9622  else {
9623  AV_WB16(title, ch);
9624  if (len == 1 || len == 2)
9625  title[len] = 0;
9626  else
9627  avio_get_str(sc->pb, INT_MAX, title + 2, len - 1);
9628  }
9629  }
9630 
9631  avpriv_new_chapter(s, i, st->time_base, sample->timestamp, end, title);
9632  av_freep(&title);
9633  }
9634  }
9635 finish:
9636  avio_seek(sc->pb, cur_pos, SEEK_SET);
9637  }
9638 }
9639 
9641  int64_t value, int flags)
9642 {
9643  AVTimecode tc;
9644  char buf[AV_TIMECODE_STR_SIZE];
9645  AVRational rate = st->avg_frame_rate;
9646  int ret = av_timecode_init(&tc, rate, flags, 0, s);
9647  if (ret < 0)
9648  return ret;
9649  av_dict_set(&st->metadata, "timecode",
9650  av_timecode_make_string(&tc, buf, value), 0);
9651  return 0;
9652 }
9653 
9655 {
9656  MOVStreamContext *sc = st->priv_data;
9657  FFStream *const sti = ffstream(st);
9658  char buf[AV_TIMECODE_STR_SIZE];
9659  int64_t cur_pos = avio_tell(sc->pb);
9660  int hh, mm, ss, ff, drop;
9661 
9662  if (!sti->nb_index_entries)
9663  return -1;
9664 
9665  avio_seek(sc->pb, sti->index_entries->pos, SEEK_SET);
9666  avio_skip(s->pb, 13);
9667  hh = avio_r8(s->pb);
9668  mm = avio_r8(s->pb);
9669  ss = avio_r8(s->pb);
9670  drop = avio_r8(s->pb);
9671  ff = avio_r8(s->pb);
9672  snprintf(buf, AV_TIMECODE_STR_SIZE, "%02d:%02d:%02d%c%02d",
9673  hh, mm, ss, drop ? ';' : ':', ff);
9674  av_dict_set(&st->metadata, "timecode", buf, 0);
9675 
9676  avio_seek(sc->pb, cur_pos, SEEK_SET);
9677  return 0;
9678 }
9679 
9681 {
9682  MOVStreamContext *sc = st->priv_data;
9683  FFStream *const sti = ffstream(st);
9684  int flags = 0;
9685  int64_t cur_pos = avio_tell(sc->pb);
9686  int64_t value;
9687  AVRational tc_rate = st->avg_frame_rate;
9688  int tmcd_nb_frames = sc->tmcd_nb_frames;
9689  int rounded_tc_rate;
9690 
9691  if (!sti->nb_index_entries)
9692  return -1;
9693 
9694  if (!tc_rate.num || !tc_rate.den || !tmcd_nb_frames)
9695  return -1;
9696 
9697  avio_seek(sc->pb, sti->index_entries->pos, SEEK_SET);
9698  value = avio_rb32(s->pb);
9699 
9700  if (sc->tmcd_flags & 0x0001) flags |= AV_TIMECODE_FLAG_DROPFRAME;
9701  if (sc->tmcd_flags & 0x0002) flags |= AV_TIMECODE_FLAG_24HOURSMAX;
9702  if (sc->tmcd_flags & 0x0004) flags |= AV_TIMECODE_FLAG_ALLOWNEGATIVE;
9703 
9704  /* Assume Counter flag is set to 1 in tmcd track (even though it is likely
9705  * not the case) and thus assume "frame number format" instead of QT one.
9706  * No sample with tmcd track can be found with a QT timecode at the moment,
9707  * despite what the tmcd track "suggests" (Counter flag set to 0 means QT
9708  * format). */
9709 
9710  /* 60 fps content have tmcd_nb_frames set to 30 but tc_rate set to 60, so
9711  * we multiply the frame number with the quotient.
9712  * See tickets #9492, #9710. */
9713  rounded_tc_rate = (tc_rate.num + tc_rate.den / 2LL) / tc_rate.den;
9714  /* Work around files where tmcd_nb_frames is rounded down from frame rate
9715  * instead of up. See ticket #5978. */
9716  if (tmcd_nb_frames == tc_rate.num / tc_rate.den &&
9717  s->strict_std_compliance < FF_COMPLIANCE_STRICT)
9718  tmcd_nb_frames = rounded_tc_rate;
9719  value = av_rescale(value, rounded_tc_rate, tmcd_nb_frames);
9720 
9722 
9723  avio_seek(sc->pb, cur_pos, SEEK_SET);
9724  return 0;
9725 }
9726 
9728  int i;
9729  if (!index || !*index) return;
9730  for (i = 0; i < (*index)->nb_encrypted_samples; i++) {
9731  av_encryption_info_free((*index)->encrypted_samples[i]);
9732  }
9733  av_freep(&(*index)->encrypted_samples);
9734  av_freep(&(*index)->auxiliary_info_sizes);
9735  av_freep(&(*index)->auxiliary_offsets);
9736  av_freep(index);
9737 }
9738 
9740 {
9741  MOVStreamContext *sc = st->priv_data;
9742 
9743  if (!sc || --sc->refcount) {
9744  st->priv_data = NULL;
9745  return;
9746  }
9747 
9748  av_freep(&sc->tts_data);
9749  for (int i = 0; i < sc->drefs_count; i++) {
9750  av_freep(&sc->drefs[i].path);
9751  av_freep(&sc->drefs[i].dir);
9752  }
9753  av_freep(&sc->drefs);
9754 
9755  sc->drefs_count = 0;
9756 
9757  if (!sc->pb_is_copied)
9758  ff_format_io_close(s, &sc->pb);
9759 
9760  sc->pb = NULL;
9761  av_freep(&sc->chunk_offsets);
9762  av_freep(&sc->stsc_data);
9763  av_freep(&sc->sample_sizes);
9764  av_freep(&sc->keyframes);
9765  av_freep(&sc->ctts_data);
9766  av_freep(&sc->stts_data);
9767  av_freep(&sc->sdtp_data);
9768  av_freep(&sc->stps_data);
9769  av_freep(&sc->elst_data);
9770  av_freep(&sc->rap_group);
9771  av_freep(&sc->sync_group);
9772  av_freep(&sc->sgpd_sync);
9773  av_freep(&sc->sample_offsets);
9774  av_freep(&sc->open_key_samples);
9775  av_freep(&sc->display_matrix);
9776  av_freep(&sc->index_ranges);
9777 
9778  if (sc->extradata)
9779  for (int i = 0; i < sc->stsd_count; i++)
9780  av_free(sc->extradata[i]);
9781  av_freep(&sc->extradata);
9782  av_freep(&sc->extradata_size);
9783 
9787 
9788  av_freep(&sc->stereo3d);
9789  av_freep(&sc->spherical);
9790  av_freep(&sc->mastering);
9791  av_freep(&sc->coll);
9792  av_freep(&sc->ambient);
9793 
9794 #if CONFIG_IAMFDEC
9795  if (sc->iamf)
9797 #endif
9798  av_freep(&sc->iamf);
9799 }
9800 
9802 {
9803  MOVContext *mov = s->priv_data;
9804  int i, j;
9805 
9806  for (i = 0; i < s->nb_streams; i++) {
9807  AVStream *st = s->streams[i];
9808 
9810  }
9811 
9812  av_freep(&mov->dv_demux);
9814  mov->dv_fctx = NULL;
9815 
9816  if (mov->meta_keys) {
9817  for (i = 1; i < mov->meta_keys_count; i++) {
9818  av_freep(&mov->meta_keys[i]);
9819  }
9820  av_freep(&mov->meta_keys);
9821  }
9822 
9823  av_freep(&mov->trex_data);
9824  av_freep(&mov->bitrates);
9825 
9826  for (i = 0; i < mov->frag_index.nb_items; i++) {
9828  for (j = 0; j < mov->frag_index.item[i].nb_stream_info; j++) {
9829  mov_free_encryption_index(&frag[j].encryption_index);
9830  }
9832  }
9833  av_freep(&mov->frag_index.item);
9834 
9835  av_freep(&mov->aes_decrypt);
9836  av_freep(&mov->chapter_tracks);
9837  for (i = 0; i < mov->nb_heif_item; i++) {
9838  if (!mov->heif_item[i])
9839  continue;
9840  av_freep(&mov->heif_item[i]->name);
9841  av_freep(&mov->heif_item[i]->icc_profile);
9842  av_freep(&mov->heif_item[i]);
9843  }
9844  av_freep(&mov->heif_item);
9845  for (i = 0; i < mov->nb_heif_grid; i++) {
9846  av_freep(&mov->heif_grid[i].tile_id_list);
9849  }
9850  av_freep(&mov->heif_grid);
9851 
9852  return 0;
9853 }
9854 
9855 static int tmcd_is_referenced(AVFormatContext *s, int tmcd_id)
9856 {
9857  int i;
9858 
9859  for (i = 0; i < s->nb_streams; i++) {
9860  AVStream *st = s->streams[i];
9861  MOVStreamContext *sc = st->priv_data;
9862 
9863  if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO &&
9864  sc->timecode_track == tmcd_id)
9865  return 1;
9866  }
9867  return 0;
9868 }
9869 
9870 /* look for a tmcd track not referenced by any video track, and export it globally */
9872 {
9873  int i;
9874 
9875  for (i = 0; i < s->nb_streams; i++) {
9876  AVStream *st = s->streams[i];
9877 
9878  if (st->codecpar->codec_tag == MKTAG('t','m','c','d') &&
9879  !tmcd_is_referenced(s, i + 1)) {
9880  AVDictionaryEntry *tcr = av_dict_get(st->metadata, "timecode", NULL, 0);
9881  if (tcr) {
9882  av_dict_set(&s->metadata, "timecode", tcr->value, 0);
9883  break;
9884  }
9885  }
9886  }
9887 }
9888 
9889 static int read_tfra(MOVContext *mov, AVIOContext *f)
9890 {
9891  int version, fieldlength, i, j;
9892  int64_t pos = avio_tell(f);
9893  uint32_t size = avio_rb32(f);
9894  unsigned track_id, item_count;
9895 
9896  if (avio_rb32(f) != MKBETAG('t', 'f', 'r', 'a')) {
9897  return 1;
9898  }
9899  av_log(mov->fc, AV_LOG_VERBOSE, "found tfra\n");
9900 
9901  version = avio_r8(f);
9902  avio_rb24(f);
9903  track_id = avio_rb32(f);
9904  fieldlength = avio_rb32(f);
9905  item_count = avio_rb32(f);
9906  for (i = 0; i < item_count; i++) {
9907  int64_t time, offset;
9908  int index;
9909  MOVFragmentStreamInfo * frag_stream_info;
9910 
9911  if (avio_feof(f)) {
9912  return AVERROR_INVALIDDATA;
9913  }
9914 
9915  if (version == 1) {
9916  time = avio_rb64(f);
9917  offset = avio_rb64(f);
9918  } else {
9919  time = avio_rb32(f);
9920  offset = avio_rb32(f);
9921  }
9922 
9923  // The first sample of each stream in a fragment is always a random
9924  // access sample. So it's entry in the tfra can be used as the
9925  // initial PTS of the fragment.
9926  index = update_frag_index(mov, offset);
9927  frag_stream_info = get_frag_stream_info(&mov->frag_index, index, track_id);
9928  if (frag_stream_info &&
9929  frag_stream_info->first_tfra_pts == AV_NOPTS_VALUE)
9930  frag_stream_info->first_tfra_pts = time;
9931 
9932  for (j = 0; j < ((fieldlength >> 4) & 3) + 1; j++)
9933  avio_r8(f);
9934  for (j = 0; j < ((fieldlength >> 2) & 3) + 1; j++)
9935  avio_r8(f);
9936  for (j = 0; j < ((fieldlength >> 0) & 3) + 1; j++)
9937  avio_r8(f);
9938  }
9939 
9940  avio_seek(f, pos + size, SEEK_SET);
9941  return 0;
9942 }
9943 
9945 {
9946  int64_t stream_size = avio_size(f);
9947  int64_t original_pos = avio_tell(f);
9948  int64_t seek_ret;
9949  int ret = -1;
9950  if ((seek_ret = avio_seek(f, stream_size - 4, SEEK_SET)) < 0) {
9951  ret = seek_ret;
9952  goto fail;
9953  }
9954  c->mfra_size = avio_rb32(f);
9955  c->have_read_mfra_size = 1;
9956  if (!c->mfra_size || c->mfra_size > stream_size) {
9957  av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (unreasonable size)\n");
9958  goto fail;
9959  }
9960  if ((seek_ret = avio_seek(f, -((int64_t) c->mfra_size), SEEK_CUR)) < 0) {
9961  ret = seek_ret;
9962  goto fail;
9963  }
9964  if (avio_rb32(f) != c->mfra_size) {
9965  av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (size mismatch)\n");
9966  goto fail;
9967  }
9968  if (avio_rb32(f) != MKBETAG('m', 'f', 'r', 'a')) {
9969  av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (tag mismatch)\n");
9970  goto fail;
9971  }
9972  av_log(c->fc, AV_LOG_VERBOSE, "stream has mfra\n");
9973  do {
9974  ret = read_tfra(c, f);
9975  if (ret < 0)
9976  goto fail;
9977  } while (!ret);
9978  ret = 0;
9979  c->frag_index.complete = 1;
9980 fail:
9981  seek_ret = avio_seek(f, original_pos, SEEK_SET);
9982  if (seek_ret < 0) {
9983  av_log(c->fc, AV_LOG_ERROR,
9984  "failed to seek back after looking for mfra\n");
9985  ret = seek_ret;
9986  }
9987  return ret;
9988 }
9989 
9990 static int set_icc_profile_from_item(AVPacketSideData **coded_side_data, int *nb_coded_side_data,
9991  const HEIFItem *item)
9992 {
9993  AVPacketSideData *sd = av_packet_side_data_new(coded_side_data, nb_coded_side_data,
9995  item->icc_profile_size, 0);
9996  if (!sd)
9997  return AVERROR(ENOMEM);
9998 
9999  memcpy(sd->data, item->icc_profile, item->icc_profile_size);
10000 
10001  return 0;
10002 }
10003 
10004 static int set_display_matrix_from_item(AVPacketSideData **coded_side_data, int *nb_coded_side_data,
10005  const HEIFItem *item)
10006 {
10007  int32_t *matrix;
10008  AVPacketSideData *sd = av_packet_side_data_new(coded_side_data,
10009  nb_coded_side_data,
10011  9 * sizeof(*matrix), 0);
10012  if (!sd)
10013  return AVERROR(ENOMEM);
10014 
10015  matrix = (int32_t*)sd->data;
10016  /* rotation is in the counter-clockwise direction whereas
10017  * av_display_rotation_set() expects its argument to be
10018  * oriented clockwise, so we need to negate it. */
10020  av_display_matrix_flip(matrix, item->hflip, item->vflip);
10021 
10022  return 0;
10023 }
10024 
10025 static int read_image_grid(AVFormatContext *s, const HEIFGrid *grid,
10026  AVStreamGroupTileGrid *tile_grid)
10027 {
10028  MOVContext *c = s->priv_data;
10029  const HEIFItem *item = grid->item;
10030  int64_t offset = 0, pos = avio_tell(s->pb);
10031  int x = 0, y = 0, i = 0;
10032  int tile_rows, tile_cols;
10033  int flags, size;
10034 
10035  if (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL)) {
10036  av_log(c->fc, AV_LOG_INFO, "grid box with non seekable input\n");
10037  return AVERROR_PATCHWELCOME;
10038  }
10039  if (item->is_idat_relative) {
10040  if (!c->idat_offset) {
10041  av_log(c->fc, AV_LOG_ERROR, "missing idat box required by the image grid\n");
10042  return AVERROR_INVALIDDATA;
10043  }
10044  offset = c->idat_offset;
10045  }
10046 
10047  avio_seek(s->pb, item->extent_offset + offset, SEEK_SET);
10048 
10049  avio_r8(s->pb); /* version */
10050  flags = avio_r8(s->pb);
10051 
10052  tile_rows = avio_r8(s->pb) + 1;
10053  tile_cols = avio_r8(s->pb) + 1;
10054  /* actual width and height of output image */
10055  tile_grid->width = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
10056  tile_grid->height = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
10057 
10058  /* ICC profile */
10059  if (item->icc_profile_size) {
10060  int ret = set_icc_profile_from_item(&tile_grid->coded_side_data,
10061  &tile_grid->nb_coded_side_data, item);
10062  if (ret < 0)
10063  return ret;
10064  }
10065  /* rotation */
10066  if (item->rotation || item->hflip || item->vflip) {
10068  &tile_grid->nb_coded_side_data, item);
10069  if (ret < 0)
10070  return ret;
10071  }
10072 
10073  av_log(c->fc, AV_LOG_TRACE, "grid: grid_rows %d grid_cols %d output_width %d output_height %d\n",
10074  tile_rows, tile_cols, tile_grid->width, tile_grid->height);
10075 
10076  avio_seek(s->pb, pos, SEEK_SET);
10077 
10078  size = tile_rows * tile_cols;
10079  tile_grid->nb_tiles = grid->nb_tiles;
10080 
10081  if (tile_grid->nb_tiles != size)
10082  return AVERROR_INVALIDDATA;
10083 
10084  for (int i = 0; i < tile_cols; i++)
10085  tile_grid->coded_width += grid->tile_item_list[i]->width;
10086  for (int i = 0; i < size; i += tile_cols)
10087  tile_grid->coded_height += grid->tile_item_list[i]->height;
10088 
10089  tile_grid->offsets = av_calloc(tile_grid->nb_tiles, sizeof(*tile_grid->offsets));
10090  if (!tile_grid->offsets)
10091  return AVERROR(ENOMEM);
10092 
10093  while (y < tile_grid->coded_height) {
10094  int left_col = i;
10095 
10096  while (x < tile_grid->coded_width) {
10097  if (i == tile_grid->nb_tiles)
10098  return AVERROR_INVALIDDATA;
10099 
10100  tile_grid->offsets[i].idx = grid->tile_idx_list[i];
10101  tile_grid->offsets[i].horizontal = x;
10102  tile_grid->offsets[i].vertical = y;
10103 
10104  x += grid->tile_item_list[i++]->width;
10105  }
10106 
10107  if (x > tile_grid->coded_width) {
10108  av_log(c->fc, AV_LOG_ERROR, "Non uniform HEIF tiles\n");
10109  return AVERROR_INVALIDDATA;
10110  }
10111 
10112  x = 0;
10113  y += grid->tile_item_list[left_col]->height;
10114  }
10115 
10116  if (y > tile_grid->coded_height || i != tile_grid->nb_tiles) {
10117  av_log(c->fc, AV_LOG_ERROR, "Non uniform HEIF tiles\n");
10118  return AVERROR_INVALIDDATA;
10119  }
10120 
10121  return 0;
10122 }
10123 
10124 static int read_image_iovl(AVFormatContext *s, const HEIFGrid *grid,
10125  AVStreamGroupTileGrid *tile_grid)
10126 {
10127  MOVContext *c = s->priv_data;
10128  const HEIFItem *item = grid->item;
10129  uint16_t canvas_fill_value[4];
10130  int64_t offset = 0, pos = avio_tell(s->pb);
10131  int ret = 0, flags;
10132 
10133  if (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL)) {
10134  av_log(c->fc, AV_LOG_INFO, "iovl box with non seekable input\n");
10135  return AVERROR_PATCHWELCOME;
10136  }
10137  if (item->is_idat_relative) {
10138  if (!c->idat_offset) {
10139  av_log(c->fc, AV_LOG_ERROR, "missing idat box required by the image overlay\n");
10140  return AVERROR_INVALIDDATA;
10141  }
10142  offset = c->idat_offset;
10143  }
10144 
10145  avio_seek(s->pb, item->extent_offset + offset, SEEK_SET);
10146 
10147  avio_r8(s->pb); /* version */
10148  flags = avio_r8(s->pb);
10149 
10150  for (int i = 0; i < 4; i++)
10151  canvas_fill_value[i] = avio_rb16(s->pb);
10152  av_log(c->fc, AV_LOG_TRACE, "iovl: canvas_fill_value { %u, %u, %u, %u }\n",
10153  canvas_fill_value[0], canvas_fill_value[1],
10154  canvas_fill_value[2], canvas_fill_value[3]);
10155  for (int i = 0; i < 4; i++)
10156  tile_grid->background[i] = canvas_fill_value[i];
10157 
10158  /* actual width and height of output image */
10159  tile_grid->width =
10160  tile_grid->coded_width = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
10161  tile_grid->height =
10162  tile_grid->coded_height = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
10163 
10164  /* rotation */
10165  if (item->rotation || item->hflip || item->vflip) {
10167  &tile_grid->nb_coded_side_data, item);
10168  if (ret < 0)
10169  return ret;
10170  }
10171 
10172  /* ICC profile */
10173  if (item->icc_profile_size) {
10174  int ret = set_icc_profile_from_item(&tile_grid->coded_side_data,
10175  &tile_grid->nb_coded_side_data, item);
10176  if (ret < 0)
10177  return ret;
10178  }
10179 
10180  av_log(c->fc, AV_LOG_TRACE, "iovl: output_width %d, output_height %d\n",
10181  tile_grid->width, tile_grid->height);
10182 
10183  tile_grid->nb_tiles = grid->nb_tiles;
10184  tile_grid->offsets = av_malloc_array(tile_grid->nb_tiles, sizeof(*tile_grid->offsets));
10185  if (!tile_grid->offsets) {
10186  ret = AVERROR(ENOMEM);
10187  goto fail;
10188  }
10189 
10190  for (int i = 0; i < tile_grid->nb_tiles; i++) {
10191  tile_grid->offsets[i].idx = grid->tile_idx_list[i];
10192  tile_grid->offsets[i].horizontal = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
10193  tile_grid->offsets[i].vertical = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
10194  av_log(c->fc, AV_LOG_TRACE, "iovl: stream_idx[%d] %u, "
10195  "horizontal_offset[%d] %d, vertical_offset[%d] %d\n",
10196  i, tile_grid->offsets[i].idx,
10197  i, tile_grid->offsets[i].horizontal, i, tile_grid->offsets[i].vertical);
10198  }
10199 
10200 fail:
10201  avio_seek(s->pb, pos, SEEK_SET);
10202 
10203  return ret;
10204 }
10205 
10207 {
10208  MOVContext *mov = s->priv_data;
10209 
10210  for (int i = 0; i < mov->nb_heif_grid; i++) {
10212  AVStreamGroupTileGrid *tile_grid;
10213  const HEIFGrid *grid = &mov->heif_grid[i];
10214  int err, loop = 1;
10215 
10216  if (!stg)
10217  return AVERROR(ENOMEM);
10218 
10219  stg->id = grid->item->item_id;
10220  tile_grid = stg->params.tile_grid;
10221 
10222  for (int j = 0; j < grid->nb_tiles; j++) {
10223  int tile_id = grid->tile_id_list[j];
10224  int k;
10225 
10226  for (k = 0; k < mov->nb_heif_item; k++) {
10227  HEIFItem *item = mov->heif_item[k];
10228  AVStream *st;
10229 
10230  if (!item || item->item_id != tile_id)
10231  continue;
10232  st = item->st;
10233  if (!st) {
10234  av_log(s, AV_LOG_WARNING, "HEIF item id %d from grid id %d doesn't "
10235  "reference a stream\n",
10236  tile_id, grid->item->item_id);
10237  ff_remove_stream_group(s, stg);
10238  loop = 0;
10239  break;
10240  }
10241 
10242  grid->tile_item_list[j] = item;
10243  grid->tile_idx_list[j] = stg->nb_streams;
10244 
10245  err = avformat_stream_group_add_stream(stg, st);
10246  if (err < 0) {
10247  int l;
10248  if (err != AVERROR(EEXIST))
10249  return err;
10250 
10251  for (l = 0; l < stg->nb_streams; l++)
10252  if (stg->streams[l]->index == st->index)
10253  break;
10254  av_assert0(l < stg->nb_streams);
10255  grid->tile_idx_list[j] = l;
10256  }
10257 
10258  if (item->item_id != mov->primary_item_id)
10260  break;
10261  }
10262 
10263  if (k == mov->nb_heif_item) {
10264  av_assert0(loop);
10265  av_log(s, AV_LOG_WARNING, "HEIF item id %d referenced by grid id %d doesn't "
10266  "exist\n",
10267  tile_id, grid->item->item_id);
10268  ff_remove_stream_group(s, stg);
10269  loop = 0;
10270  }
10271  if (!loop)
10272  break;
10273  }
10274 
10275  if (!loop)
10276  continue;
10277 
10278  switch (grid->item->type) {
10279  case MKTAG('g','r','i','d'):
10280  err = read_image_grid(s, grid, tile_grid);
10281  break;
10282  case MKTAG('i','o','v','l'):
10283  err = read_image_iovl(s, grid, tile_grid);
10284  break;
10285  default:
10286  av_assert0(0);
10287  }
10288  if (err < 0)
10289  return err;
10290 
10291 
10292  if (grid->item->name)
10293  av_dict_set(&stg->metadata, "title", grid->item->name, 0);
10294  if (grid->item->item_id == mov->primary_item_id)
10296  }
10297 
10298  return 0;
10299 }
10300 
10302 {
10303  MOVContext *mov = s->priv_data;
10304  int err;
10305 
10306  for (int i = 0; i < mov->nb_heif_item; i++) {
10307  HEIFItem *item = mov->heif_item[i];
10308  MOVStreamContext *sc;
10309  AVStream *st;
10310  int64_t offset = 0;
10311 
10312  if (!item)
10313  continue;
10314  if (!item->st) {
10315  if (item->item_id == mov->thmb_item_id) {
10316  av_log(s, AV_LOG_ERROR, "HEIF thumbnail doesn't reference a stream\n");
10317  return AVERROR_INVALIDDATA;
10318  }
10319  continue;
10320  }
10321  if (item->is_idat_relative) {
10322  if (!mov->idat_offset) {
10323  av_log(s, AV_LOG_ERROR, "Missing idat box for item %d\n", item->item_id);
10324  return AVERROR_INVALIDDATA;
10325  }
10326  offset = mov->idat_offset;
10327  }
10328 
10329  st = item->st;
10330  sc = st->priv_data;
10331  st->codecpar->width = item->width;
10332  st->codecpar->height = item->height;
10333 
10334  err = sanity_checks(s, sc, item->item_id);
10335  if (err)
10336  return AVERROR_INVALIDDATA;
10337 
10338  sc->sample_sizes[0] = item->extent_length;
10339  sc->chunk_offsets[0] = item->extent_offset + offset;
10340 
10341  if (item->item_id == mov->primary_item_id)
10343 
10344  if (item->rotation || item->hflip || item->vflip) {
10346  &st->codecpar->nb_coded_side_data, item);
10347  if (err < 0)
10348  return err;
10349  }
10350 
10351  mov_build_index(mov, st);
10352  }
10353 
10354  if (mov->nb_heif_grid) {
10355  err = mov_parse_tiles(s);
10356  if (err < 0)
10357  return err;
10358  }
10359 
10360  return 0;
10361 }
10362 
10364  int first_index)
10365 {
10366  MOVStreamContext *sc = st->priv_data;
10367 
10368  if (sc->tref_id < 0)
10369  return NULL;
10370 
10371  for (int i = first_index; i < s->nb_streams; i++)
10372  if (s->streams[i]->id == sc->tref_id)
10373  return s->streams[i];
10374 
10375  return NULL;
10376 }
10377 
10379 {
10380  int err;
10381 
10382  for (int i = 0; i < s->nb_streams; i++) {
10383  AVStreamGroup *stg;
10384  AVStream *st = s->streams[i];
10385  AVStream *st_base;
10386  MOVStreamContext *sc = st->priv_data;
10387  int j = 0;
10388 
10389  /* Find an enhancement stream. */
10390  if (st->codecpar->codec_id != AV_CODEC_ID_LCEVC ||
10392  continue;
10393 
10395 
10397  if (!stg)
10398  return AVERROR(ENOMEM);
10399 
10400  stg->id = st->id;
10401  stg->params.lcevc->width = st->codecpar->width;
10402  stg->params.lcevc->height = st->codecpar->height;
10403  st->codecpar->width = 0;
10404  st->codecpar->height = 0;
10405 
10406  while (st_base = mov_find_reference_track(s, st, j)) {
10407  err = avformat_stream_group_add_stream(stg, st_base);
10408  if (err < 0)
10409  return err;
10410 
10411  j = st_base->index + 1;
10412  }
10413  if (!j) {
10414  av_log(s, AV_LOG_ERROR, "Failed to find base stream for enhancement stream\n");
10415  return AVERROR_INVALIDDATA;
10416  }
10417 
10418  err = avformat_stream_group_add_stream(stg, st);
10419  if (err < 0)
10420  return err;
10421 
10422  stg->params.lcevc->lcevc_index = stg->nb_streams - 1;
10423  }
10424 
10425  return 0;
10426 }
10427 
10429 {
10430  int highest_id = 0;
10431 
10432  for (int i = 0; i < s->nb_streams; i++) {
10433  const AVStream *st = s->streams[i];
10434  const MOVStreamContext *sc = st->priv_data;
10435  if (!sc->iamf)
10436  highest_id = FFMAX(highest_id, st->id);
10437  }
10438  highest_id += !highest_id;
10439  for (int i = 0; highest_id > 1 && i < s->nb_stream_groups; i++) {
10440  AVStreamGroup *stg = s->stream_groups[i];
10442  continue;
10443  for (int j = 0; j < stg->nb_streams; j++) {
10444  AVStream *st = stg->streams[j];
10445  MOVStreamContext *sc = st->priv_data;
10446  st->id += highest_id;
10447  sc->iamf_stream_offset = highest_id;
10448  }
10449  }
10450 }
10451 
10453 {
10454  MOVContext *mov = s->priv_data;
10455  AVIOContext *pb = s->pb;
10456  int j, err;
10457  MOVAtom atom = { AV_RL32("root") };
10458  int i;
10459 
10460  if (mov->decryption_key_len != 0 && mov->decryption_key_len != AES_CTR_KEY_SIZE) {
10461  av_log(s, AV_LOG_ERROR, "Invalid decryption key len %d expected %d\n",
10463  return AVERROR(EINVAL);
10464  }
10465 
10466  mov->fc = s;
10467  mov->trak_index = -1;
10468  mov->thmb_item_id = -1;
10469  mov->primary_item_id = -1;
10470  mov->cur_item_id = -1;
10471  /* .mov and .mp4 aren't streamable anyway (only progressive download if moov is before mdat) */
10472  if (pb->seekable & AVIO_SEEKABLE_NORMAL)
10473  atom.size = avio_size(pb);
10474  else
10475  atom.size = INT64_MAX;
10476 
10477  /* check MOV header */
10478  do {
10479  if (mov->moov_retry)
10480  avio_seek(pb, 0, SEEK_SET);
10481  if ((err = mov_read_default(mov, pb, atom)) < 0) {
10482  av_log(s, AV_LOG_ERROR, "error reading header\n");
10483  return err;
10484  }
10485  } while ((pb->seekable & AVIO_SEEKABLE_NORMAL) &&
10486  !mov->found_moov && (!mov->found_iloc || !mov->found_iinf) && !mov->moov_retry++);
10487  if (!mov->found_moov && !mov->found_iloc && !mov->found_iinf) {
10488  av_log(s, AV_LOG_ERROR, "moov atom not found\n");
10489  return AVERROR_INVALIDDATA;
10490  }
10491  av_log(mov->fc, AV_LOG_TRACE, "on_parse_exit_offset=%"PRId64"\n", avio_tell(pb));
10492 
10493  if (mov->found_iloc && mov->found_iinf) {
10494  err = mov_parse_heif_items(s);
10495  if (err < 0)
10496  return err;
10497  }
10498  // prevent iloc and iinf boxes from being parsed while reading packets.
10499  // this is needed because an iinf box may have been parsed but ignored
10500  // for having old infe boxes which create no streams.
10501  mov->found_iloc = mov->found_iinf = 1;
10502 
10503  if (pb->seekable & AVIO_SEEKABLE_NORMAL) {
10504  if (mov->nb_chapter_tracks > 0 && !mov->ignore_chapters)
10506  for (i = 0; i < s->nb_streams; i++)
10507  if (s->streams[i]->codecpar->codec_tag == AV_RL32("tmcd")) {
10508  mov_read_timecode_track(s, s->streams[i]);
10509  } else if (s->streams[i]->codecpar->codec_tag == AV_RL32("rtmd")) {
10510  mov_read_rtmd_track(s, s->streams[i]);
10511  }
10512  }
10513 
10514  /* copy timecode metadata from tmcd tracks to the related video streams */
10515  for (i = 0; i < s->nb_streams; i++) {
10516  AVStream *st = s->streams[i];
10517  MOVStreamContext *sc = st->priv_data;
10518  if (sc->timecode_track > 0) {
10519  AVDictionaryEntry *tcr;
10520  int tmcd_st_id = -1;
10521 
10522  for (j = 0; j < s->nb_streams; j++) {
10523  MOVStreamContext *sc2 = s->streams[j]->priv_data;
10524  if (sc2->id == sc->timecode_track)
10525  tmcd_st_id = j;
10526  }
10527 
10528  if (tmcd_st_id < 0 || tmcd_st_id == i)
10529  continue;
10530  tcr = av_dict_get(s->streams[tmcd_st_id]->metadata, "timecode", NULL, 0);
10531  if (tcr)
10532  av_dict_set(&st->metadata, "timecode", tcr->value, 0);
10533  }
10534  }
10536 
10537  /* Create LCEVC stream groups. */
10538  err = mov_parse_lcevc_streams(s);
10539  if (err < 0)
10540  return err;
10541 
10542  for (i = 0; i < s->nb_streams; i++) {
10543  AVStream *st = s->streams[i];
10544  FFStream *const sti = ffstream(st);
10545  MOVStreamContext *sc = st->priv_data;
10546  uint32_t dvdsub_clut[FF_DVDCLUT_CLUT_LEN] = {0};
10547  fix_timescale(mov, sc);
10548  if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
10549  st->codecpar->codec_id == AV_CODEC_ID_AAC) {
10550  sti->skip_samples = sc->start_pad;
10551  }
10552  if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && sc->nb_frames_for_fps > 0 && sc->duration_for_fps > 0)
10554  sc->time_scale*(int64_t)sc->nb_frames_for_fps, sc->duration_for_fps, INT_MAX);
10556  if (st->codecpar->width <= 0 || st->codecpar->height <= 0) {
10557  st->codecpar->width = sc->width;
10558  st->codecpar->height = sc->height;
10559  }
10562 
10563  for (j = 0; j < FF_DVDCLUT_CLUT_LEN; j++)
10564  dvdsub_clut[j] = AV_RB32(st->codecpar->extradata + j * 4);
10565 
10566  err = ff_dvdclut_yuv_to_rgb(dvdsub_clut, FF_DVDCLUT_CLUT_SIZE);
10567  if (err < 0)
10568  return err;
10569 
10570  av_freep(&st->codecpar->extradata);
10571  st->codecpar->extradata_size = 0;
10572 
10574  st->codecpar);
10575  if (err < 0)
10576  return err;
10577  }
10578  }
10579  if (mov->handbrake_version &&
10580  mov->handbrake_version <= 1000000*0 + 1000*10 + 2 && // 0.10.2
10581  st->codecpar->codec_id == AV_CODEC_ID_MP3) {
10582  av_log(s, AV_LOG_VERBOSE, "Forcing full parsing for mp3 stream\n");
10584  }
10585  }
10586 
10587  if (mov->trex_data || mov->use_mfra_for > 0) {
10588  for (i = 0; i < s->nb_streams; i++) {
10589  AVStream *st = s->streams[i];
10590  MOVStreamContext *sc = st->priv_data;
10591  if (sc->duration_for_fps > 0) {
10592  /* Akin to sc->data_size * 8 * sc->time_scale / sc->duration_for_fps but accounting for overflows. */
10594  if (st->codecpar->bit_rate == INT64_MIN) {
10595  av_log(s, AV_LOG_WARNING, "Overflow during bit rate calculation %"PRId64" * 8 * %d\n",
10596  sc->data_size, sc->time_scale);
10597  st->codecpar->bit_rate = 0;
10598  if (s->error_recognition & AV_EF_EXPLODE)
10599  return AVERROR_INVALIDDATA;
10600  }
10601  }
10602  }
10603  }
10604 
10605  for (i = 0; i < mov->bitrates_count && i < s->nb_streams; i++) {
10606  if (mov->bitrates[i]) {
10607  s->streams[i]->codecpar->bit_rate = mov->bitrates[i];
10608  }
10609  }
10610 
10612 
10613  for (i = 0; i < s->nb_streams; i++) {
10614  AVStream *st = s->streams[i];
10615  MOVStreamContext *sc = st->priv_data;
10616 
10617  switch (st->codecpar->codec_type) {
10618  case AVMEDIA_TYPE_AUDIO:
10619  err = ff_replaygain_export(st, s->metadata);
10620  if (err < 0)
10621  return err;
10622  break;
10623  case AVMEDIA_TYPE_VIDEO:
10624  if (sc->display_matrix) {
10627  (uint8_t*)sc->display_matrix, sizeof(int32_t) * 9, 0))
10628  return AVERROR(ENOMEM);
10629 
10630  sc->display_matrix = NULL;
10631  }
10632  if (sc->stereo3d) {
10635  (uint8_t *)sc->stereo3d, sc->stereo3d_size, 0))
10636  return AVERROR(ENOMEM);
10637 
10638  sc->stereo3d = NULL;
10639  }
10640  if (sc->spherical) {
10643  (uint8_t *)sc->spherical, sc->spherical_size, 0))
10644  return AVERROR(ENOMEM);
10645 
10646  sc->spherical = NULL;
10647  }
10648  if (sc->mastering) {
10651  (uint8_t *)sc->mastering, sc->mastering_size, 0))
10652  return AVERROR(ENOMEM);
10653 
10654  sc->mastering = NULL;
10655  }
10656  if (sc->coll) {
10659  (uint8_t *)sc->coll, sc->coll_size, 0))
10660  return AVERROR(ENOMEM);
10661 
10662  sc->coll = NULL;
10663  }
10664  if (sc->ambient) {
10667  (uint8_t *) sc->ambient, sc->ambient_size, 0))
10668  return AVERROR(ENOMEM);
10669 
10670  sc->ambient = NULL;
10671  }
10672  break;
10673  }
10674  }
10675 
10676  fix_stream_ids(s);
10677 
10679 
10680  for (i = 0; i < mov->frag_index.nb_items; i++)
10681  if (mov->frag_index.item[i].moof_offset <= mov->fragment.moof_offset)
10682  mov->frag_index.item[i].headers_read = 1;
10683 
10684  return 0;
10685 }
10686 
10688 {
10690  int64_t best_dts = INT64_MAX;
10691  int i;
10692  MOVContext *mov = s->priv_data;
10693  int no_interleave = !mov->interleaved_read || !(s->pb->seekable & AVIO_SEEKABLE_NORMAL);
10694  for (i = 0; i < s->nb_streams; i++) {
10695  AVStream *avst = s->streams[i];
10696  FFStream *const avsti = ffstream(avst);
10697  MOVStreamContext *msc = avst->priv_data;
10698  if (msc->pb && msc->current_sample < avsti->nb_index_entries) {
10699  AVIndexEntry *current_sample = &avsti->index_entries[msc->current_sample];
10700  int64_t dts = av_rescale(current_sample->timestamp, AV_TIME_BASE, msc->time_scale);
10701  uint64_t dtsdiff = best_dts > dts ? best_dts - (uint64_t)dts : ((uint64_t)dts - best_dts);
10702  av_log(s, AV_LOG_TRACE, "stream %d, sample %d, dts %"PRId64"\n", i, msc->current_sample, dts);
10703  if (!sample || (no_interleave && current_sample->pos < sample->pos) ||
10704  ((s->pb->seekable & AVIO_SEEKABLE_NORMAL) &&
10705  ((msc->pb != s->pb && dts < best_dts) || (msc->pb == s->pb && dts != AV_NOPTS_VALUE &&
10706  ((dtsdiff <= AV_TIME_BASE && current_sample->pos < sample->pos) ||
10707  (dtsdiff > AV_TIME_BASE && dts < best_dts)))))) {
10708  sample = current_sample;
10709  best_dts = dts;
10710  *st = avst;
10711  }
10712  }
10713  }
10714  return sample;
10715 }
10716 
10717 static int should_retry(AVIOContext *pb, int error_code) {
10718  if (error_code == AVERROR_EOF || avio_feof(pb))
10719  return 0;
10720 
10721  return 1;
10722 }
10723 
10724 static int mov_switch_root(AVFormatContext *s, int64_t target, int index)
10725 {
10726  int ret;
10727  MOVContext *mov = s->priv_data;
10728 
10729  if (index >= 0 && index < mov->frag_index.nb_items)
10730  target = mov->frag_index.item[index].moof_offset;
10731  if (target >= 0 && avio_seek(s->pb, target, SEEK_SET) != target) {
10732  av_log(mov->fc, AV_LOG_ERROR, "root atom offset 0x%"PRIx64": partial file\n", target);
10733  return AVERROR_INVALIDDATA;
10734  }
10735 
10736  mov->next_root_atom = 0;
10737  if ((index < 0 && target >= 0) || index >= mov->frag_index.nb_items)
10738  index = search_frag_moof_offset(&mov->frag_index, target);
10739  if (index >= 0 && index < mov->frag_index.nb_items &&
10740  mov->frag_index.item[index].moof_offset == target) {
10741  if (index + 1 < mov->frag_index.nb_items)
10742  mov->next_root_atom = mov->frag_index.item[index + 1].moof_offset;
10743  if (mov->frag_index.item[index].headers_read)
10744  return 0;
10745  mov->frag_index.item[index].headers_read = 1;
10746  }
10747 
10748  mov->found_mdat = 0;
10749 
10750  ret = mov_read_default(mov, s->pb, (MOVAtom){ AV_RL32("root"), INT64_MAX });
10751  if (ret < 0)
10752  return ret;
10753  if (avio_feof(s->pb))
10754  return AVERROR_EOF;
10755  av_log(s, AV_LOG_TRACE, "read fragments, offset 0x%"PRIx64"\n", avio_tell(s->pb));
10756 
10757  return 1;
10758 }
10759 
10761 {
10762  MOVStreamContext *sc = st->priv_data;
10763  uint8_t *side, *extradata;
10764  int extradata_size;
10765 
10766  /* Save the current index. */
10767  sc->last_stsd_index = sc->stsc_data[sc->stsc_index].id - 1;
10768 
10769  /* Notify the decoder that extradata changed. */
10770  extradata_size = sc->extradata_size[sc->last_stsd_index];
10771  extradata = sc->extradata[sc->last_stsd_index];
10772  if (st->discard != AVDISCARD_ALL && extradata_size > 0 && extradata) {
10775  extradata_size);
10776  if (!side)
10777  return AVERROR(ENOMEM);
10778  memcpy(side, extradata, extradata_size);
10779  }
10780 
10781  return 0;
10782 }
10783 
10784 static int get_eia608_packet(AVIOContext *pb, AVPacket *pkt, int src_size)
10785 {
10786  /* We can't make assumptions about the structure of the payload,
10787  because it may include multiple cdat and cdt2 samples. */
10788  const uint32_t cdat = AV_RB32("cdat");
10789  const uint32_t cdt2 = AV_RB32("cdt2");
10790  int ret, out_size = 0;
10791 
10792  /* a valid payload must have size, 4cc, and at least 1 byte pair: */
10793  if (src_size < 10)
10794  return AVERROR_INVALIDDATA;
10795 
10796  /* avoid an int overflow: */
10797  if ((src_size - 8) / 2 >= INT_MAX / 3)
10798  return AVERROR_INVALIDDATA;
10799 
10800  ret = av_new_packet(pkt, ((src_size - 8) / 2) * 3);
10801  if (ret < 0)
10802  return ret;
10803 
10804  /* parse and re-format the c608 payload in one pass. */
10805  while (src_size >= 10) {
10806  const uint32_t atom_size = avio_rb32(pb);
10807  const uint32_t atom_type = avio_rb32(pb);
10808  const uint32_t data_size = atom_size - 8;
10809  const uint8_t cc_field =
10810  atom_type == cdat ? 1 :
10811  atom_type == cdt2 ? 2 :
10812  0;
10813 
10814  /* account for bytes consumed for atom size and type. */
10815  src_size -= 8;
10816 
10817  /* make sure the data size stays within the buffer boundaries. */
10818  if (data_size < 2 || data_size > src_size) {
10820  break;
10821  }
10822 
10823  /* make sure the data size is consistent with N byte pairs. */
10824  if (data_size % 2 != 0) {
10826  break;
10827  }
10828 
10829  if (!cc_field) {
10830  /* neither cdat or cdt2 ... skip it */
10831  avio_skip(pb, data_size);
10832  src_size -= data_size;
10833  continue;
10834  }
10835 
10836  for (uint32_t i = 0; i < data_size; i += 2) {
10837  pkt->data[out_size] = (0x1F << 3) | (1 << 2) | (cc_field - 1);
10838  pkt->data[out_size + 1] = avio_r8(pb);
10839  pkt->data[out_size + 2] = avio_r8(pb);
10840  out_size += 3;
10841  src_size -= 2;
10842  }
10843  }
10844 
10845  if (src_size > 0)
10846  /* skip any remaining unread portion of the input payload */
10847  avio_skip(pb, src_size);
10848 
10850  return ret;
10851 }
10852 
10854  int64_t current_index, AVPacket *pkt)
10855 {
10856  MOVStreamContext *sc = st->priv_data;
10857 
10858  pkt->stream_index = sc->ffindex;
10859  pkt->dts = sample->timestamp;
10860  if (sample->flags & AVINDEX_DISCARD_FRAME) {
10862  }
10863  if (sc->stts_count && sc->tts_index < sc->tts_count)
10864  pkt->duration = sc->tts_data[sc->tts_index].duration;
10865  if (sc->ctts_count && sc->tts_index < sc->tts_count) {
10867  } else {
10868  if (pkt->duration == 0) {
10869  int64_t next_dts = (sc->current_sample < ffstream(st)->nb_index_entries) ?
10871  if (next_dts >= pkt->dts)
10872  pkt->duration = next_dts - pkt->dts;
10873  }
10874  pkt->pts = pkt->dts;
10875  }
10876 
10877  if (sc->tts_data && sc->tts_index < sc->tts_count) {
10878  /* update tts context */
10879  sc->tts_sample++;
10880  if (sc->tts_index < sc->tts_count &&
10881  sc->tts_data[sc->tts_index].count == sc->tts_sample) {
10882  sc->tts_index++;
10883  sc->tts_sample = 0;
10884  }
10885  }
10886 
10887  if (sc->sdtp_data && sc->current_sample <= sc->sdtp_count) {
10888  uint8_t sample_flags = sc->sdtp_data[sc->current_sample - 1];
10889  uint8_t sample_is_depended_on = (sample_flags >> 2) & 0x3;
10890  pkt->flags |= sample_is_depended_on == MOV_SAMPLE_DEPENDENCY_NO ? AV_PKT_FLAG_DISPOSABLE : 0;
10891  }
10892  pkt->flags |= sample->flags & AVINDEX_KEYFRAME ? AV_PKT_FLAG_KEY : 0;
10893  pkt->pos = sample->pos;
10894 
10895  /* Multiple stsd handling. */
10896  if (sc->stsc_data) {
10897  if (sc->stsc_data[sc->stsc_index].id > 0 &&
10898  sc->stsc_data[sc->stsc_index].id - 1 < sc->stsd_count &&
10899  sc->stsc_data[sc->stsc_index].id - 1 != sc->last_stsd_index) {
10900  int ret = mov_change_extradata(st, pkt);
10901  if (ret < 0)
10902  return ret;
10903  }
10904 
10905  /* Update the stsc index for the next sample */
10906  sc->stsc_sample++;
10907  if (mov_stsc_index_valid(sc->stsc_index, sc->stsc_count) &&
10908  mov_get_stsc_samples(sc, sc->stsc_index) == sc->stsc_sample) {
10909  sc->stsc_index++;
10910  sc->stsc_sample = 0;
10911  }
10912  }
10913 
10914  return 0;
10915 }
10916 
10918 {
10919  MOVContext *mov = s->priv_data;
10920  MOVStreamContext *sc;
10922  AVStream *st = NULL;
10923  FFStream *avsti = NULL;
10924  int64_t current_index;
10925  int ret;
10926  int i;
10927  mov->fc = s;
10928  retry:
10929  if (s->pb->pos == 0) {
10930 
10931  // Discard current fragment index
10932  if (mov->frag_index.allocated_size > 0) {
10933  for(int i = 0; i < mov->frag_index.nb_items; i++) {
10935  }
10936  av_freep(&mov->frag_index.item);
10937  mov->frag_index.nb_items = 0;
10938  mov->frag_index.allocated_size = 0;
10939  mov->frag_index.current = -1;
10940  mov->frag_index.complete = 0;
10941  }
10942 
10943  for (i = 0; i < s->nb_streams; i++) {
10944  AVStream *avst = s->streams[i];
10945  MOVStreamContext *msc = avst->priv_data;
10946 
10947  // Clear current sample
10948  mov_current_sample_set(msc, 0);
10949  msc->tts_index = 0;
10950 
10951  // Discard current index entries
10952  avsti = ffstream(avst);
10953  if (avsti->index_entries_allocated_size > 0) {
10954  av_freep(&avsti->index_entries);
10955  avsti->index_entries_allocated_size = 0;
10956  avsti->nb_index_entries = 0;
10957  }
10958  }
10959 
10960  if ((ret = mov_switch_root(s, -1, -1)) < 0)
10961  return ret;
10962  }
10963  sample = mov_find_next_sample(s, &st);
10964  if (!sample || (mov->next_root_atom && sample->pos > mov->next_root_atom)) {
10965  if (!mov->next_root_atom)
10966  return AVERROR_EOF;
10967  if ((ret = mov_switch_root(s, mov->next_root_atom, -1)) < 0)
10968  return ret;
10969  goto retry;
10970  }
10971  sc = st->priv_data;
10972  /* must be done just before reading, to avoid infinite loop on sample */
10973  current_index = sc->current_index;
10975 
10976  if (mov->next_root_atom) {
10977  sample->pos = FFMIN(sample->pos, mov->next_root_atom);
10978  sample->size = FFMIN(sample->size, (mov->next_root_atom - sample->pos));
10979  }
10980 
10981  if (st->discard != AVDISCARD_ALL) {
10982  int64_t ret64 = avio_seek(sc->pb, sample->pos, SEEK_SET);
10983  if (ret64 != sample->pos) {
10984  av_log(mov->fc, AV_LOG_ERROR, "stream %d, offset 0x%"PRIx64": partial file\n",
10985  sc->ffindex, sample->pos);
10986  if (should_retry(sc->pb, ret64)) {
10988  } else if (ret64 < 0) {
10989  return (int)ret64;
10990  }
10991  return AVERROR_INVALIDDATA;
10992  }
10993 
10994  if (st->discard == AVDISCARD_NONKEY && !(sample->flags & AVINDEX_KEYFRAME)) {
10995  av_log(mov->fc, AV_LOG_DEBUG, "Nonkey frame from stream %d discarded due to AVDISCARD_NONKEY\n", sc->ffindex);
10996  goto retry;
10997  }
10998 
10999  if (st->codecpar->codec_id == AV_CODEC_ID_EIA_608 && sample->size > 8)
11000  ret = get_eia608_packet(sc->pb, pkt, sample->size);
11001 #if CONFIG_IAMFDEC
11002  else if (sc->iamf) {
11003  int64_t pts, dts, pos, duration;
11004  int flags, size = sample->size;
11005  ret = mov_finalize_packet(s, st, sample, current_index, pkt);
11006  pts = pkt->pts; dts = pkt->dts;
11007  pos = pkt->pos; flags = pkt->flags;
11008  duration = pkt->duration;
11009  while (!ret && size > 0) {
11010  ret = ff_iamf_read_packet(s, sc->iamf, sc->pb, size, sc->iamf_stream_offset, pkt);
11011  if (ret < 0) {
11012  if (should_retry(sc->pb, ret))
11014  return ret;
11015  }
11016  size -= ret;
11017  pkt->pts = pts; pkt->dts = dts;
11018  pkt->pos = pos; pkt->flags |= flags;
11019  pkt->duration = duration;
11020  ret = ff_buffer_packet(s, pkt);
11021  }
11022  if (!ret)
11023  return FFERROR_REDO;
11024  }
11025 #endif
11026  else
11027  ret = av_get_packet(sc->pb, pkt, sample->size);
11028  if (ret < 0) {
11029  if (should_retry(sc->pb, ret)) {
11031  }
11032  return ret;
11033  }
11034 #if CONFIG_DV_DEMUXER
11035  if (mov->dv_demux && sc->dv_audio_container) {
11038  if (ret < 0)
11039  return ret;
11041  if (ret < 0)
11042  return ret;
11043  }
11044 #endif
11045  if (sc->has_palette) {
11046  uint8_t *pal;
11047 
11049  if (!pal) {
11050  av_log(mov->fc, AV_LOG_ERROR, "Cannot append palette to packet\n");
11051  } else {
11052  memcpy(pal, sc->palette, AVPALETTE_SIZE);
11053  sc->has_palette = 0;
11054  }
11055  }
11056  if (st->codecpar->codec_id == AV_CODEC_ID_MP3 && !ffstream(st)->need_parsing && pkt->size > 4) {
11057  if (ff_mpa_check_header(AV_RB32(pkt->data)) < 0)
11059  }
11060  }
11061 
11062  ret = mov_finalize_packet(s, st, sample, current_index, pkt);
11063  if (ret < 0)
11064  return ret;
11065 
11066  if (st->discard == AVDISCARD_ALL)
11067  goto retry;
11068 
11069  if (mov->aax_mode)
11070  aax_filter(pkt->data, pkt->size, mov);
11071 
11072  ret = cenc_filter(mov, st, sc, pkt, current_index);
11073  if (ret < 0) {
11074  return ret;
11075  }
11076 
11077  return 0;
11078 }
11079 
11081 {
11082  MOVContext *mov = s->priv_data;
11083  int index;
11084 
11085  if (!mov->frag_index.complete)
11086  return 0;
11087 
11088  index = search_frag_timestamp(s, &mov->frag_index, st, timestamp);
11089  if (index < 0)
11090  index = 0;
11091  if (!mov->frag_index.item[index].headers_read)
11092  return mov_switch_root(s, -1, index);
11093  if (index + 1 < mov->frag_index.nb_items)
11094  mov->next_root_atom = mov->frag_index.item[index + 1].moof_offset;
11095 
11096  return 0;
11097 }
11098 
11099 static int is_open_key_sample(const MOVStreamContext *sc, int sample)
11100 {
11101  // TODO: a bisect search would scale much better
11102  for (int i = 0; i < sc->open_key_samples_count; i++) {
11103  const int oks = sc->open_key_samples[i];
11104  if (oks == sample)
11105  return 1;
11106  if (oks > sample) /* list is monotically increasing so we can stop early */
11107  break;
11108  }
11109  return 0;
11110 }
11111 
11112 /*
11113  * Some key sample may be key frames but not IDR frames, so a random access to
11114  * them may not be allowed.
11115  */
11116 static int can_seek_to_key_sample(AVStream *st, int sample, int64_t requested_pts)
11117 {
11118  MOVStreamContext *sc = st->priv_data;
11119  FFStream *const sti = ffstream(st);
11120  int64_t key_sample_dts, key_sample_pts;
11121 
11122  if (st->codecpar->codec_id != AV_CODEC_ID_HEVC)
11123  return 1;
11124 
11125  if (sample >= sc->sample_offsets_count)
11126  return 1;
11127 
11128  key_sample_dts = sti->index_entries[sample].timestamp;
11129  key_sample_pts = key_sample_dts + sc->sample_offsets[sample] + sc->dts_shift;
11130 
11131  /*
11132  * If the sample needs to be presented before an open key sample, they may
11133  * not be decodable properly, even though they come after in decoding
11134  * order.
11135  */
11136  if (is_open_key_sample(sc, sample) && key_sample_pts > requested_pts)
11137  return 0;
11138 
11139  return 1;
11140 }
11141 
11142 static int mov_seek_stream(AVFormatContext *s, AVStream *st, int64_t timestamp, int flags)
11143 {
11144  MOVStreamContext *sc = st->priv_data;
11145  FFStream *const sti = ffstream(st);
11146  int sample, time_sample, ret, next_ts, requested_sample;
11147  unsigned int i;
11148 
11149  // Here we consider timestamp to be PTS, hence try to offset it so that we
11150  // can search over the DTS timeline.
11151  timestamp -= (sc->min_corrected_pts + sc->dts_shift);
11152 
11153  ret = mov_seek_fragment(s, st, timestamp);
11154  if (ret < 0)
11155  return ret;
11156 
11157  for (;;) {
11158  sample = av_index_search_timestamp(st, timestamp, flags);
11159  av_log(s, AV_LOG_TRACE, "stream %d, timestamp %"PRId64", sample %d\n", st->index, timestamp, sample);
11160  if (sample < 0 && sti->nb_index_entries && timestamp < sti->index_entries[0].timestamp)
11161  sample = 0;
11162  if (sample < 0) /* not sure what to do */
11163  return AVERROR_INVALIDDATA;
11164 
11165  if (!sample || can_seek_to_key_sample(st, sample, timestamp))
11166  break;
11167 
11168  next_ts = timestamp - FFMAX(sc->min_sample_duration, 1);
11169  requested_sample = av_index_search_timestamp(st, next_ts, flags);
11170 
11171  // If we've reached a different sample trying to find a good pts to
11172  // seek to, give up searching because we'll end up seeking back to
11173  // sample 0 on every seek.
11174  if (sample != requested_sample && !can_seek_to_key_sample(st, requested_sample, next_ts))
11175  break;
11176 
11177  timestamp = next_ts;
11178  }
11179 
11181  av_log(s, AV_LOG_TRACE, "stream %d, found sample %d\n", st->index, sc->current_sample);
11182  /* adjust time to sample index */
11183  if (sc->tts_data) {
11184  time_sample = 0;
11185  for (i = 0; i < sc->tts_count; i++) {
11186  int next = time_sample + sc->tts_data[i].count;
11187  if (next > sc->current_sample) {
11188  sc->tts_index = i;
11189  sc->tts_sample = sc->current_sample - time_sample;
11190  break;
11191  }
11192  time_sample = next;
11193  }
11194  }
11195 
11196  /* adjust stsd index */
11197  if (sc->chunk_count) {
11198  time_sample = 0;
11199  for (i = 0; i < sc->stsc_count; i++) {
11200  int64_t next = time_sample + mov_get_stsc_samples(sc, i);
11201  if (next > sc->current_sample) {
11202  sc->stsc_index = i;
11203  sc->stsc_sample = sc->current_sample - time_sample;
11204  break;
11205  }
11206  av_assert0(next == (int)next);
11207  time_sample = next;
11208  }
11209  }
11210 
11211  return sample;
11212 }
11213 
11215 {
11216  MOVStreamContext *sc = st->priv_data;
11217  FFStream *const sti = ffstream(st);
11218  int64_t first_ts = sti->index_entries[0].timestamp;
11220  int64_t off;
11221 
11223  return 0;
11224 
11225  /* compute skip samples according to stream start_pad, seek ts and first ts */
11226  off = av_rescale_q(ts - first_ts, st->time_base,
11227  (AVRational){1, st->codecpar->sample_rate});
11228  return FFMAX(sc->start_pad - off, 0);
11229 }
11230 
11231 static int mov_read_seek(AVFormatContext *s, int stream_index, int64_t sample_time, int flags)
11232 {
11233  MOVContext *mc = s->priv_data;
11234  AVStream *st;
11235  FFStream *sti;
11236  int sample;
11237  int i;
11238 
11239  if (stream_index >= s->nb_streams)
11240  return AVERROR_INVALIDDATA;
11241 
11242  st = s->streams[stream_index];
11243  sti = ffstream(st);
11244  sample = mov_seek_stream(s, st, sample_time, flags);
11245  if (sample < 0)
11246  return sample;
11247 
11248  if (mc->seek_individually) {
11249  /* adjust seek timestamp to found sample timestamp */
11250  int64_t seek_timestamp = sti->index_entries[sample].timestamp;
11252 
11253  for (i = 0; i < s->nb_streams; i++) {
11254  AVStream *const st = s->streams[i];
11255  FFStream *const sti = ffstream(st);
11256  int64_t timestamp;
11257 
11258  if (stream_index == i)
11259  continue;
11260 
11261  timestamp = av_rescale_q(seek_timestamp, s->streams[stream_index]->time_base, st->time_base);
11262  sample = mov_seek_stream(s, st, timestamp, flags);
11263  if (sample >= 0)
11265  }
11266  } else {
11267  for (i = 0; i < s->nb_streams; i++) {
11268  MOVStreamContext *sc;
11269  st = s->streams[i];
11270  sc = st->priv_data;
11271  mov_current_sample_set(sc, 0);
11272  }
11273  while (1) {
11274  MOVStreamContext *sc;
11276  if (!entry)
11277  return AVERROR_INVALIDDATA;
11278  sc = st->priv_data;
11279  if (sc->ffindex == stream_index && sc->current_sample == sample)
11280  break;
11282  }
11283  }
11284  return 0;
11285 }
11286 
11287 #define OFFSET(x) offsetof(MOVContext, x)
11288 #define FLAGS AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM
11289 static const AVOption mov_options[] = {
11290  {"use_absolute_path",
11291  "allow using absolute path when opening alias, this is a possible security issue",
11292  OFFSET(use_absolute_path), AV_OPT_TYPE_BOOL, {.i64 = 0},
11293  0, 1, FLAGS},
11294  {"seek_streams_individually",
11295  "Seek each stream individually to the closest point",
11296  OFFSET(seek_individually), AV_OPT_TYPE_BOOL, { .i64 = 1 },
11297  0, 1, FLAGS},
11298  {"ignore_editlist", "Ignore the edit list atom.", OFFSET(ignore_editlist), AV_OPT_TYPE_BOOL, {.i64 = 0},
11299  0, 1, FLAGS},
11300  {"advanced_editlist",
11301  "Modify the AVIndex according to the editlists. Use this option to decode in the order specified by the edits.",
11302  OFFSET(advanced_editlist), AV_OPT_TYPE_BOOL, {.i64 = 1},
11303  0, 1, FLAGS},
11304  {"ignore_chapters", "", OFFSET(ignore_chapters), AV_OPT_TYPE_BOOL, {.i64 = 0},
11305  0, 1, FLAGS},
11306  {"use_mfra_for",
11307  "use mfra for fragment timestamps",
11308  OFFSET(use_mfra_for), AV_OPT_TYPE_INT, {.i64 = FF_MOV_FLAG_MFRA_AUTO},
11310  .unit = "use_mfra_for"},
11311  {"auto", "auto", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_AUTO}, 0, 0,
11312  FLAGS, .unit = "use_mfra_for" },
11313  {"dts", "dts", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_DTS}, 0, 0,
11314  FLAGS, .unit = "use_mfra_for" },
11315  {"pts", "pts", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_PTS}, 0, 0,
11316  FLAGS, .unit = "use_mfra_for" },
11317  {"use_tfdt", "use tfdt for fragment timestamps", OFFSET(use_tfdt), AV_OPT_TYPE_BOOL, {.i64 = 1},
11318  0, 1, FLAGS},
11319  { "export_all", "Export unrecognized metadata entries", OFFSET(export_all),
11320  AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = FLAGS },
11321  { "export_xmp", "Export full XMP metadata", OFFSET(export_xmp),
11322  AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = FLAGS },
11323  { "activation_bytes", "Secret bytes for Audible AAX files", OFFSET(activation_bytes),
11325  { "audible_key", "AES-128 Key for Audible AAXC files", OFFSET(audible_key),
11327  { "audible_iv", "AES-128 IV for Audible AAXC files", OFFSET(audible_iv),
11329  { "audible_fixed_key", // extracted from libAAX_SDK.so and AAXSDKWin.dll files!
11330  "Fixed key used for handling Audible AAX files", OFFSET(audible_fixed_key),
11331  AV_OPT_TYPE_BINARY, {.str="77214d4b196a87cd520045fd20a51d67"},
11332  .flags = AV_OPT_FLAG_DECODING_PARAM },
11333  { "decryption_key", "The media decryption key (hex)", OFFSET(decryption_key), AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM },
11334  { "enable_drefs", "Enable external track support.", OFFSET(enable_drefs), AV_OPT_TYPE_BOOL,
11335  {.i64 = 0}, 0, 1, FLAGS },
11336  { "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 },
11337  { "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 },
11338 
11339  { NULL },
11340 };
11341 
11342 static const AVClass mov_class = {
11343  .class_name = "mov,mp4,m4a,3gp,3g2,mj2",
11344  .item_name = av_default_item_name,
11345  .option = mov_options,
11346  .version = LIBAVUTIL_VERSION_INT,
11347 };
11348 
11350  .p.name = "mov,mp4,m4a,3gp,3g2,mj2",
11351  .p.long_name = NULL_IF_CONFIG_SMALL("QuickTime / MOV"),
11352  .p.priv_class = &mov_class,
11353  .p.extensions = "mov,mp4,m4a,3gp,3g2,mj2,psp,m4b,ism,ismv,isma,f4v,avif,heic,heif",
11355  .priv_data_size = sizeof(MOVContext),
11356  .flags_internal = FF_INFMT_FLAG_INIT_CLEANUP,
11357  .read_probe = mov_probe,
11362 };
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:319
AV_CODEC_ID_PCM_S16LE
@ AV_CODEC_ID_PCM_S16LE
Definition: codec_id.h:335
mov_read_chpl
static int mov_read_chpl(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:598
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:7235
mov_read_meta
static int mov_read_meta(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5453
AV_CODEC_ID_EIA_608
@ AV_CODEC_ID_EIA_608
Definition: codec_id.h:568
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:430
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:458
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:2304
read_image_iovl
static int read_image_iovl(AVFormatContext *s, const HEIFGrid *grid, AVStreamGroupTileGrid *tile_grid)
Definition: mov.c:10124
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:9047
AVMEDIA_TYPE_SUBTITLE
@ AVMEDIA_TYPE_SUBTITLE
Definition: avutil.h:204
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:215
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:201
AV_CODEC_ID_PCM_F32BE
@ AV_CODEC_ID_PCM_F32BE
Definition: codec_id.h:355
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:212
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:380
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:8302
can_seek_to_key_sample
static int can_seek_to_key_sample(AVStream *st, int sample, int64_t requested_pts)
Definition: mov.c:11116
AV_CODEC_ID_ADPCM_IMA_QT
@ AV_CODEC_ID_ADPCM_IMA_QT
Definition: codec_id.h:374
entry
#define entry
Definition: aom_film_grain_template.c:66
AVFMT_NO_BYTE_SEEK
#define AVFMT_NO_BYTE_SEEK
Format does not allow seeking by bytes.
Definition: avformat.h:487
AV_EF_EXPLODE
#define AV_EF_EXPLODE
abort decoding on minor error detection
Definition: defs.h:51
AVStreamGroup::id
int64_t id
Group type-specific group ID.
Definition: avformat.h:1153
AV_CODEC_ID_AC3
@ AV_CODEC_ID_AC3
Definition: codec_id.h:451
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:716
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:1169
AVFMT_SHOW_IDS
#define AVFMT_SHOW_IDS
Show format stream IDs numbers.
Definition: avformat.h:477
AVSphericalMapping::projection
enum AVSphericalProjection projection
Projection type.
Definition: spherical.h: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:1128
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:11342
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:200
mov_read_targa_y216
static int mov_read_targa_y216(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2272
mov_read_chnl
static int mov_read_chnl(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1192
mov_read_moof
static int mov_read_moof(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1809
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:1453
sanity_checks
static int sanity_checks(void *log_obj, MOVStreamContext *sc, int index)
Definition: mov.c:5083
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:9855
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:773
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:674
AVStream::discard
enum AVDiscard discard
Selects which packets can be discarded at will and do not need to be demuxed.
Definition: avformat.h:819
AV_FIELD_PROGRESSIVE
@ AV_FIELD_PROGRESSIVE
Definition: defs.h:202
mov_options
static const AVOption mov_options[]
Definition: mov.c:11289
mov_codec_id
static int mov_codec_id(AVStream *st, uint32_t format)
Definition: mov.c:2621
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:8693
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:601
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:225
mov_read_alac
static int mov_read_alac(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2244
test_same_origin
static int test_same_origin(const char *src, const char *ref)
Definition: mov.c:4926
cbcs_scheme_decrypt
static int cbcs_scheme_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
Definition: mov.c:8125
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:613
IS_MATRIX_IDENT
#define IS_MATRIX_IDENT(matrix)
Definition: mov.c:5471
AVStreamGroup::disposition
int disposition
Stream group disposition - a combination of AV_DISPOSITION_* flags.
Definition: avformat.h:1211
dict_internal.h
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:621
mov_update_dts_shift
static void mov_update_dts_shift(MOVStreamContext *sc, int duration, void *logctx)
Definition: mov.c:3630
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:2249
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:52
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
tmp
static uint8_t tmp[11]
Definition: aes_ctr.c:28
mov_read_custom
static int mov_read_custom(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5315
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:1368
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:390
mov_read_extradata
static int mov_read_extradata(MOVContext *c, AVIOContext *pb, MOVAtom atom, enum AVCodecID codec_id)
Definition: mov.c:2218
AVCOL_RANGE_JPEG
@ AVCOL_RANGE_JPEG
Full range content.
Definition: pixfmt.h:746
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:1911
mov_read_idat
static int mov_read_idat(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:8687
AVPacket::data
uint8_t * data
Definition: packet.h:539
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:2264
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:3287
MOVContext::bitrates
int * bitrates
bitrates read before streams creation
Definition: isom.h:346
b
#define b
Definition: input.c:41
AVCOL_TRC_UNSPECIFIED
@ AVCOL_TRC_UNSPECIFIED
Definition: pixfmt.h:643
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:5479
MOVElst::rate
float rate
Definition: isom.h:82
AVStream::avg_frame_rate
AVRational avg_frame_rate
Average framerate.
Definition: avformat.h:837
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:2065
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:1950
mov_read_strf
static int mov_read_strf(MOVContext *c, AVIOContext *pb, MOVAtom atom)
An strf atom is a BITMAPINFOHEADER struct.
Definition: mov.c:2534
AV_CODEC_ID_ALAC
@ AV_CODEC_ID_ALAC
Definition: codec_id.h:464
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:429
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:7443
mov_seek_stream
static int mov_seek_stream(AVFormatContext *s, AVStream *st, int64_t timestamp, int flags)
Definition: mov.c:11142
mov_read_saio
static int mov_read_saio(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:7589
mov_get_stsc_samples
static int64_t mov_get_stsc_samples(MOVStreamContext *sc, unsigned int index)
Definition: mov.c:3272
AV_LOG_VERBOSE
#define AV_LOG_VERBOSE
Detailed information.
Definition: log.h:225
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:3839
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:10760
fc
#define fc(width, name, range_min, range_max)
Definition: cbs_av1.c:472
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:611
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:557
AVCodecParameters::codec_tag
uint32_t codec_tag
Additional information about the codec (corresponds to the AVI FOURCC).
Definition: codec_par.h:59
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:4143
mathematics.h
AVDictionary
Definition: dict.c:34
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:613
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:1036
iamf_parse.h
mov_read_moov
static int mov_read_moov(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1561
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:363
mov_read_esds
static int mov_read_esds(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:847
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:194
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:2556
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:6962
FFIOContext
Definition: avio_internal.h:28
AV_PKT_FLAG_KEY
#define AV_PKT_FLAG_KEY
The packet contains a keyframe.
Definition: packet.h:594
AVStreamGroup::params
union AVStreamGroup::@368 params
Group type-specific parameters.
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:8232
mov_read_sdtp
static int mov_read_sdtp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:3596
mov_read_jp2h
static int mov_read_jp2h(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2254
AV_STEREO3D_UNSPEC
@ AV_STEREO3D_UNSPEC
Video is stereoscopic but the packing is unspecified.
Definition: stereo3d.h:143
AVIndexEntry
Definition: avformat.h:602
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:430
mov_read_tfhd
static int mov_read_tfhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5584
AV_CODEC_ID_BIN_DATA
@ AV_CODEC_ID_BIN_DATA
Definition: codec_id.h:599
av_malloc
#define av_malloc(s)
Definition: tableprint_vlc.h:30
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:6163
AVINDEX_KEYFRAME
#define AVINDEX_KEYFRAME
Definition: avformat.h:610
AV_FIELD_BT
@ AV_FIELD_BT
Bottom coded first, top displayed first.
Definition: defs.h:206
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:203
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:338
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:392
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:121
OFFSET
#define OFFSET(x)
Definition: mov.c:11287
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:9990
AV_FIELD_TT
@ AV_FIELD_TT
Top coded_first, top displayed first.
Definition: defs.h:203
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:868
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:1499
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:3689
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:483
AV_FOURCC_MAX_STRING_SIZE
#define AV_FOURCC_MAX_STRING_SIZE
Definition: avutil.h:346
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:358
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:503
AV_CODEC_ID_PCM_S16BE
@ AV_CODEC_ID_PCM_S16BE
Definition: codec_id.h:336
mov_read_mdhd
static int mov_read_mdhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1865
mov_read_ctts
static int mov_read_ctts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:3641
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:193
mov_read_aclr
static int mov_read_aclr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2329
AVSEEK_FLAG_ANY
#define AVSEEK_FLAG_ANY
seek to any frame, even non-keyframes
Definition: avformat.h:2501
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:987
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:1618
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:1002
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:191
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:6517
mov_read_enda
static int mov_read_enda(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1979
mov_read_chap
static int mov_read_chap(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5631
MOVParseTableEntry
Definition: mov.c:82
avio_tell
static av_always_inline int64_t avio_tell(AVIOContext *s)
ftell() equivalent for AVIOContext.
Definition: avio.h:494
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:10004
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:679
AVStreamGroupTileGrid::coded_height
int coded_height
Width of the canvas.
Definition: avformat.h:1008
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:449
AVStream::duration
int64_t duration
Decoding: duration of the stream, in stream time base.
Definition: avformat.h:807
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:448
update_frag_index
static int update_frag_index(MOVContext *c, int64_t offset)
Definition: mov.c:1733
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:205
AVStream::attached_pic
AVPacket attached_pic
For streams with AV_DISPOSITION_ATTACHED_PIC disposition, this packet will contain the attached pictu...
Definition: avformat.h:846
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:7505
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:4554
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
AVStreamGroupTileGrid::offsets
struct AVStreamGroupTileGrid::@367 * offsets
An nb_tiles sized array of offsets in pixels from the topleft edge of the canvas, indicating where ea...
mov_read_ares
static int mov_read_ares(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2286
mov_read_adrm
static int mov_read_adrm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1375
av_get_bits_per_sample
int av_get_bits_per_sample(enum AVCodecID codec_id)
Return codec bits per sample.
Definition: utils.c:551
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:339
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:235
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:209
AV_CODEC_ID_MACE3
@ AV_CODEC_ID_MACE3
Definition: codec_id.h:457
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:9727
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:201
MOVStreamContext::dts_shift
int dts_shift
dts shift when ctts is negative
Definition: isom.h:232
av_timecode_init
int av_timecode_init(AVTimecode *tc, AVRational rate, int flags, int frame_start, void *log_ctx)
Init a timecode struct with the passed parameters.
Definition: timecode.c:201
AVCodecParameters::frame_size
int frame_size
Audio only.
Definition: codec_par.h:195
avio_get_str16le
int avio_get_str16le(AVIOContext *pb, int maxlen, char *buf, int buflen)
Read a UTF-16 string from pb and convert it to UTF-8.
mov_metadata_track_or_disc_number
static int mov_metadata_track_or_disc_number(MOVContext *c, AVIOContext *pb, unsigned len, const char *key)
Definition: mov.c:91
av_dict_get
AVDictionaryEntry * av_dict_get(const AVDictionary *m, const char *key, const AVDictionaryEntry *prev, int flags)
Get a dictionary entry with matching key.
Definition: dict.c:62
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:1126
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:119
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:4034
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:4548
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:6451
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:5101
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:1373
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
format
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 format(the sample packing is implied by the sample format) and sample rate. The lists are not just lists
AVInputFormat::name
const char * name
A comma separated list of short names for the format.
Definition: avformat.h:553
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:202
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:448
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:613
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
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:4063
AVIndexEntry::timestamp
int64_t timestamp
Timestamp in AVStream.time_base units, preferably the time from which on correctly decoded frames are...
Definition: avformat.h:604
av_assert0
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:40
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:8406
AV_LOG_DEBUG
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:230
AVPacketSideData::data
uint8_t * data
Definition: packet.h:391
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:6025
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:374
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:1090
FFStream::display_aspect_ratio
AVRational display_aspect_ratio
display aspect ratio (0 if unknown)
Definition: internal.h:307
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:10687
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:614
mov_read_dvcc_dvvc
static int mov_read_dvcc_dvvc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:8386
MOVParseTableEntry::parse
int(* parse)(MOVContext *ctx, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:84
codec_id
enum AVCodecID codec_id
Definition: vaapi_decode.c:410
AV_CODEC_ID_SVQ3
@ AV_CODEC_ID_SVQ3
Definition: codec_id.h:75
key
const char * key
Definition: hwcontext_opencl.c:189
AVCodecParameters::nb_coded_side_data
int nb_coded_side_data
Amount of entries in coded_side_data.
Definition: codec_par.h:86
MOVStreamContext::sdtp_data
uint8_t * sdtp_data
Definition: isom.h:189
color_range
color_range
Definition: vf_selectivecolor.c:43
AVMEDIA_TYPE_DATA
@ AVMEDIA_TYPE_DATA
Opaque data information usually continuous.
Definition: avutil.h:203
mov_read_udta_string
static int mov_read_udta_string(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:345
mov_read_stss
static int mov_read_stss(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:3328
mov_read_ddts
static int mov_read_ddts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1120
mov_read_uuid
static int mov_read_uuid(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:7108
AVCOL_PRI_UNSPECIFIED
@ AVCOL_PRI_UNSPECIFIED
Definition: pixfmt.h:618
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:4062
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:9801
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:6183
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:7333
FFStream::need_parsing
enum AVStreamParseType need_parsing
Definition: internal.h:325
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:8634
IAMFAudioElement::audio_element_id
unsigned int audio_element_id
Definition: iamf.h:96
AVDISCARD_ALL
@ AVDISCARD_ALL
discard all
Definition: defs.h:221
AVFormatContext
Format I/O context.
Definition: avformat.h:1300
av_realloc_f
#define av_realloc_f(p, o, n)
Definition: tableprint_vlc.h:32
mov_read_stts
static int mov_read_stts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:3476
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:1120
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:3885
set_frag_stream
static void set_frag_stream(MOVFragmentIndex *frag_index, int id)
Definition: mov.c:1598
mov_read_free
static int mov_read_free(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:7213
mov_realloc_extradata
static int mov_realloc_extradata(AVCodecParameters *par, MOVAtom atom)
Definition: mov.c:2181
AVStream::codecpar
AVCodecParameters * codecpar
Codec parameters associated with this stream.
Definition: avformat.h:771
LIBAVUTIL_VERSION_INT
#define LIBAVUTIL_VERSION_INT
Definition: version.h:85
AVSEEK_FLAG_BACKWARD
#define AVSEEK_FLAG_BACKWARD
Definition: avformat.h:2499
aes.h
AVClass
Describe the class of an AVClass context structure.
Definition: log.h:75
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:787
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
AV_CODEC_ID_AV1
@ AV_CODEC_ID_AV1
Definition: codec_id.h:284
MOVStreamContext::ctts_count
unsigned int ctts_count
Definition: isom.h:190
AVEncryptionInitInfo
This describes info used to initialize an encryption key system.
Definition: encryption_info.h:88
isom.h
MP4TrackKindValueMapping::disposition
int disposition
Definition: isom.h:478
mov_read_ftyp
static int mov_read_ftyp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1513
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:10025
MOVElst
Definition: isom.h:79
parse
static int parse(AVCodecParserContext *s, AVCodecContext *avctx, const uint8_t **poutbuf, int *poutbuf_size, const uint8_t *buf, int buf_size)
Definition: ffv1_parser.c:28
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:1090
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:3722
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:9447
AVPALETTE_SIZE
#define AVPALETTE_SIZE
Definition: pixfmt.h:32
FLAC_METADATA_TYPE_STREAMINFO
@ FLAC_METADATA_TYPE_STREAMINFO
Definition: flac.h:46
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:10784
AV_CODEC_ID_DVD_SUBTITLE
@ AV_CODEC_ID_DVD_SUBTITLE
Definition: codec_id.h:558
AVIndexEntry::flags
int flags
Definition: avformat.h:612
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:6360
av_default_item_name
const char * av_default_item_name(void *ptr)
Return the context name.
Definition: log.c:239
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:169
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:4955
FFStream::nb_index_entries
int nb_index_entries
Definition: internal.h:190
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:35
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:7805
AVStream::metadata
AVDictionary * metadata
Definition: avformat.h:828
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:3647
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:8963
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:718
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:467
mov_read_ilst
static int mov_read_ilst(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5260
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:8207
get_sgpd_sync_index
static uint32_t get_sgpd_sync_index(const MOVStreamContext *sc, int nal_unit_type)
Definition: mov.c:4476
mov_read_fiel
static int mov_read_fiel(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2147
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:305
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:1224
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:2836
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:2998
MOVStts
Definition: isom.h:63
AVAudioServiceType
AVAudioServiceType
Definition: defs.h:224
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:466
AVStream::nb_frames
int64_t nb_frames
number of frames in this stream if known or 0
Definition: avformat.h:809
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:657
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:488
should_retry
static int should_retry(AVIOContext *pb, int error_code)
Definition: mov.c:10717
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:529
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:1343
MOVContext::dv_demux
DVDemuxContext * dv_demux
Definition: isom.h:327
AV_CODEC_ID_AAC
@ AV_CODEC_ID_AAC
Definition: codec_id.h:450
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:8544
mov_read_elst
static int mov_read_elst(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6236
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:1127
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:10452
AV_CODEC_ID_QCELP
@ AV_CODEC_ID_QCELP
Definition: codec_id.h:472
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:8000
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:220
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:347
mov_read_wave
static int mov_read_wave(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2377
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:8060
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:9739
AVPacket::size
int size
Definition: packet.h:540
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:133
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:7282
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:73
height
#define height
Definition: dsp.h:85
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:132
mov_read_dref
static int mov_read_dref(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:637
mov_current_sample_dec
static void mov_current_sample_dec(MOVStreamContext *sc)
Definition: mov.c:4131
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:83
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
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:5717
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:9086
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:366
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:1173
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:3186
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:248
MKBETAG
#define MKBETAG(a, b, c, d)
Definition: macros.h:56
AV_CODEC_ID_QDMC
@ AV_CODEC_ID_QDMC
Definition: codec_id.h:498
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:52
AVStreamGroup::iamf_audio_element
struct AVIAMFAudioElement * iamf_audio_element
Definition: avformat.h:1167
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:959
mov_parse_heif_items
static int mov_parse_heif_items(AVFormatContext *s)
Definition: mov.c:10301
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:3981
MOVDref::path
char * path
Definition: isom.h:87
mov_current_sample_inc
static void mov_current_sample_inc(MOVStreamContext *sc)
Definition: mov.c:4119
AVStream::sample_aspect_ratio
AVRational sample_aspect_ratio
sample aspect ratio (0 if unknown)
Definition: avformat.h:826
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:538
mov_read_vexu_proj
static int mov_read_vexu_proj(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6726
fix_timescale
static void fix_timescale(MOVContext *c, MOVStreamContext *sc)
Definition: mov.c:5027
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:9325
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:995
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:700
mov_read_packet
static int mov_read_packet(AVFormatContext *s, AVPacket *pkt)
Definition: mov.c:10917
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:1112
AVStreamGroup::lcevc
struct AVStreamGroupLCEVC * lcevc
Definition: avformat.h:1170
attributes.h
AV_CODEC_ID_LCEVC
@ AV_CODEC_ID_LCEVC
Definition: codec_id.h:601
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:545
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:223
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:393
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:10363
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:321
AV_STREAM_GROUP_PARAMS_IAMF_AUDIO_ELEMENT
@ AV_STREAM_GROUP_PARAMS_IAMF_AUDIO_ELEMENT
Definition: avformat.h:1125
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:1201
ff_rfps_calculate
void ff_rfps_calculate(AVFormatContext *ic)
Definition: demux.c:2365
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:6488
MOVStreamContext::chunk_offsets
int64_t * chunk_offsets
Definition: isom.h:181
AVStreamGroup::iamf_mix_presentation
struct AVIAMFMixPresentation * iamf_mix_presentation
Definition: avformat.h:1168
MOVFragmentIndex::item
MOVFragmentIndexItem * item
Definition: isom.h:165
AV_LOG_INFO
#define AV_LOG_INFO
Standard information.
Definition: log.h:220
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:83
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:7907
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:9197
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
flag
#define flag(name)
Definition: cbs_av1.c:474
AVStreamGroupTileGrid::nb_coded_side_data
int nb_coded_side_data
Amount of entries in coded_side_data.
Definition: avformat.h:1095
mov_metadata_creation_time
static void mov_metadata_creation_time(MOVContext *c, AVIOContext *pb, AVDictionary **metadata, int version)
Definition: mov.c:1835
mov_metadata_hmmt
static int mov_metadata_hmmt(MOVContext *c, AVIOContext *pb, unsigned len)
Definition: mov.c:324
AV_CODEC_ID_MJPEG
@ AV_CODEC_ID_MJPEG
Definition: codec_id.h:59
MOVFragmentStreamInfo::next_trun_dts
int64_t next_trun_dts
Definition: isom.h:144
MOVStreamContext::stsc_index
unsigned int stsc_index
Definition: isom.h:195
av_sha_alloc
struct AVSHA * av_sha_alloc(void)
Allocate an AVSHA context.
Definition: sha.c:46
mov_read_tenc
static int mov_read_tenc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:7836
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:3266
mov_finalize_packet
static int mov_finalize_packet(AVFormatContext *s, AVStream *st, AVIndexEntry *sample, int64_t current_index, AVPacket *pkt)
Definition: mov.c:10853
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:11231
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:150
AVStreamGroupTileGrid::width
int width
Width of the final image for presentation.
Definition: avformat.h:1072
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:532
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:5652
search_frag_timestamp
static int search_frag_timestamp(AVFormatContext *s, MOVFragmentIndex *frag_index, AVStream *st, int64_t timestamp)
Definition: mov.c:1708
HEIFItem::width
int width
Definition: isom.h:295
FLAGS
#define FLAGS
Definition: mov.c:11288
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:4171
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:7684
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:3121
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:254
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:582
rb_size
static int rb_size(AVIOContext *pb, int64_t *value, int size)
Definition: mov.c:8660
AVStereo3DPrimaryEye
AVStereo3DPrimaryEye
List of possible primary eyes.
Definition: stereo3d.h:174
av_malloc_array
#define av_malloc_array(a, b)
Definition: tableprint_vlc.h:31
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:3024
AV_FIELD_BB
@ AV_FIELD_BB
Bottom coded first, bottom displayed first.
Definition: defs.h:204
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:6316
AV_CODEC_ID_PCM_F64BE
@ AV_CODEC_ID_PCM_F64BE
Definition: codec_id.h:357
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:351
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:1794
mov_finalize_stsd_codec
static int mov_finalize_stsd_codec(MOVContext *c, AVIOContext *pb, AVStream *st, MOVStreamContext *sc)
Definition: mov.c:2898
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:344
mov_read_mdcv
static int mov_read_mdcv(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6407
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:1365
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:709
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:5269
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:672
fix_stream_ids
static void fix_stream_ids(AVFormatContext *s)
Definition: mov.c:10428
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:4617
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:2372
AVSHA
hash context
Definition: sha.c:35
AVCOL_RANGE_MPEG
@ AVCOL_RANGE_MPEG
Narrow or limited range content.
Definition: pixfmt.h:729
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:91
mov_read_iinf
static int mov_read_iinf(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:8843
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:1031
get_stream_info_time
static int64_t get_stream_info_time(MOVFragmentStreamInfo *frag_stream_info)
Definition: mov.c:1658
MP4TrackKindValueMapping
Definition: isom.h:477
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:4022
AV_WB8
#define AV_WB8(p, d)
Definition: intreadwrite.h:392
MOVStreamContext::chunk_count
unsigned int chunk_count
Definition: isom.h:180
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:6305
mov_chan.h
AVStream::disposition
int disposition
Stream disposition - a combination of AV_DISPOSITION_* flags.
Definition: avformat.h:817
MOVStreamContext::ambient_size
size_t ambient_size
Definition: isom.h:272
tag
uint32_t tag
Definition: movenc.c:1911
AVStream::id
int id
Format-specific stream ID.
Definition: avformat.h:760
ret
ret
Definition: filter_design.txt:187
AVStream
Stream structure.
Definition: avformat.h:748
AV_LOG_FATAL
#define AV_LOG_FATAL
Something went wrong and recovery is not possible.
Definition: log.h:203
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:7387
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:80
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:1181
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:594
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:707
AV_AUDIO_SERVICE_TYPE_KARAOKE
@ AV_AUDIO_SERVICE_TYPE_KARAOKE
Definition: defs.h:233
mov_read_dmlp
static int mov_read_dmlp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:8351
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:5678
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:5396
search_frag_moof_offset
static int search_frag_moof_offset(MOVFragmentIndex *frag_index, int64_t offset)
Definition: mov.c:1634
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:10724
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:636
AVStreamGroup
Definition: avformat.h:1134
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:754
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:11080
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:2661
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:1077
get_frag_time
static int64_t get_frag_time(AVFormatContext *s, AVStream *dst_st, MOVFragmentIndex *frag_index, int index)
Definition: mov.c:1668
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:1188
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:3778
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:2434
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:7045
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:129
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:454
avformat_free_context
void avformat_free_context(AVFormatContext *s)
Free an AVFormatContext and all its streams.
Definition: avformat.c:149
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:6589
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:1474
mov_get_skip_samples
static int64_t mov_get_skip_samples(AVStream *st, int sample)
Definition: mov.c:11214
MOVFragmentIndex
Definition: isom.h:160
mov_read_infe
static int mov_read_infe(MOVContext *c, AVIOContext *pb, MOVAtom atom, int idx)
Definition: mov.c:8778
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:914
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:603
AVIOContext::eof_reached
int eof_reached
true if was unable to read due to error or eof
Definition: avio.h:238
mov_metadata_int8_bypass_padding
static int mov_metadata_int8_bypass_padding(MOVContext *c, AVIOContext *pb, unsigned len, const char *key)
Definition: mov.c:111
AVStreamGroupLCEVC::width
int width
Width of the final stream for presentation.
Definition: avformat.h:1116
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:866
mov_read_covr
static int mov_read_covr(MOVContext *c, AVIOContext *pb, int type, int len)
Definition: mov.c:231
MOVParseTableEntry::type
uint32_t type
Definition: mov.c:83
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:541
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:9871
mov_read_sbas
static int mov_read_sbas(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2505
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:107
mov_metadata_gnre
static int mov_metadata_gnre(MOVContext *c, AVIOContext *pb, unsigned len, const char *key)
Definition: mov.c:134
AV_PKT_DATA_ENCRYPTION_INFO
@ AV_PKT_DATA_ENCRYPTION_INFO
This side data contains encryption info for how to decrypt the packet.
Definition: packet.h:252
MOV_MERGE_CTTS
#define MOV_MERGE_CTTS
Definition: mov.c:4547
FFStream::index_entries
AVIndexEntry * index_entries
Only used if the format does not support seeking natively.
Definition: internal.h:188
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:167
mov_read_dpxe
static int mov_read_dpxe(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2259
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:9654
AVMEDIA_TYPE_VIDEO
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:201
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:343
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:10206
MOVStreamContext::cenc
struct MOVStreamContext::@399 cenc
mem.h
AVStreamGroup::type
enum AVStreamGroupParamsType type
Group type.
Definition: avformat.h:1161
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:8903
mov_read_pcmc
static int mov_read_pcmc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1988
build_open_gop_key_points
static int build_open_gop_key_points(AVStream *st)
Definition: mov.c:4484
mov_parse_stsd_audio
static void mov_parse_stsd_audio(MOVContext *c, AVIOContext *pb, AVStream *st, MOVStreamContext *sc)
Definition: mov.c:2719
IAMFContext::mix_presentations
IAMFMixPresentation ** mix_presentations
Definition: iamf.h:133
AV_CODEC_ID_PCM_U8
@ AV_CODEC_ID_PCM_U8
Definition: codec_id.h:340
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:9680
HEIFGrid::item
HEIFItem * item
Definition: isom.h:307
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:169
MOVEncryptionIndex::auxiliary_info_sizes
uint8_t * auxiliary_info_sizes
Definition: isom.h:132
MOVFragment::stsd_id
unsigned stsd_id
Definition: isom.h:107
AVCodecParameters::video_delay
int video_delay
Video only.
Definition: codec_par.h:175
HEIFGrid::tile_id_list
int16_t * tile_id_list
Definition: isom.h:309
avpriv_request_sample
#define avpriv_request_sample(...)
Definition: tableprint_vlc.h:36
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:449
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:358
AVStreamGroupTileGrid::height
int height
Height of the final image for presentation.
Definition: avformat.h:1082
AVStereo3D::view
enum AVStereo3DView view
Determines which views are packed.
Definition: stereo3d.h:217
read_tfra
static int read_tfra(MOVContext *mov, AVIOContext *f)
Definition: mov.c:9889
av_free
#define av_free(p)
Definition: tableprint_vlc.h:33
AVDictionaryEntry
Definition: dict.h:89
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:516
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:10378
mov_read_hfov
static int mov_read_hfov(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:7016
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:375
MOVContext::nb_heif_item
int nb_heif_item
Definition: isom.h:376
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:34
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:88
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:237
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:559
FFInputFormat
Definition: demux.h:42
mov_metadata_loci
static int mov_metadata_loci(MOVContext *c, AVIOContext *pb, unsigned len)
Definition: mov.c:274
mov_read_eyes
static int mov_read_eyes(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6788
AV_CODEC_ID_ILBC
@ AV_CODEC_ID_ILBC
Definition: codec_id.h:507
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:593
AVChannelLayout::u
union AVChannelLayout::@434 u
Details about which channels are present in this layout.
parse_timecode_in_framenum_format
static int parse_timecode_in_framenum_format(AVFormatContext *s, AVStream *st, int64_t value, int flags)
Definition: mov.c:9640
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
flags
#define flags(name, subs,...)
Definition: cbs_av1.c:482
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:356
ff_mov_demuxer
const FFInputFormat ff_mov_demuxer
Definition: mov.c:11349
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:213
MOVStreamContext::stts_allocated_size
unsigned int stts_allocated_size
Definition: isom.h:186
MOVFragmentStreamInfo::index_entry
int index_entry
Definition: isom.h:147
cenc_decrypt
static int cenc_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
Definition: mov.c:8191
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:453
AVDictionaryEntry::value
char * value
Definition: dict.h:91
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:797
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:9025
width
#define width
Definition: dsp.h:85
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:8987
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:1239
mov_read_mfra
static int mov_read_mfra(MOVContext *c, AVIOContext *f)
Definition: mov.c:9944
AV_CODEC_ID_FLV1
@ AV_CODEC_ID_FLV1
Definition: codec_id.h:73
mov_metadata_int8_no_padding
static int mov_metadata_int8_no_padding(MOVContext *c, AVIOContext *pb, unsigned len, const char *key)
Definition: mov.c:125
flac.h
AVStreamGroupTileGrid::idx
unsigned int idx
Index of the stream in the group this tile references.
Definition: avformat.h:1026
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:1579
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:8455
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:348
mov_read_st3d
static int mov_read_st3d(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6542
mov_read_imir
static int mov_read_imir(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:9067
is_open_key_sample
static int is_open_key_sample(const MOVStreamContext *sc, int sample)
Definition: mov.c:11099
mov_read_dvc1
static int mov_read_dvc1(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2480
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:3668
avpriv_dict_set_timestamp
int avpriv_dict_set_timestamp(AVDictionary **dict, const char *key, int64_t timestamp)
Set a dictionary value to an ISO-8601 compliant timestamp string.
Definition: dict.c:278
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:2196
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:9541
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:1677
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:1046
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:7947
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:781
mov_parse_stsd_data
static int mov_parse_stsd_data(MOVContext *c, AVIOContext *pb, AVStream *st, MOVStreamContext *sc, int64_t size)
Definition: mov.c:2852
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:348
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:8679
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:852
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:227
AV_DISPOSITION_NON_DIEGETIC
#define AV_DISPOSITION_NON_DIEGETIC
The stream is intended to be mixed with a spatial audio track.
Definition: avformat.h:686
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:3383