FFmpeg
mov.c
Go to the documentation of this file.
1 /*
2  * MOV demuxer
3  * Copyright (c) 2001 Fabrice Bellard
4  * Copyright (c) 2009 Baptiste Coudurier <baptiste dot coudurier at gmail dot com>
5  *
6  * first version by Francois Revol <revol@free.fr>
7  * seek function by Gael Chardon <gael.dev@4now.net>
8  *
9  * This file is part of FFmpeg.
10  *
11  * FFmpeg is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU Lesser General Public
13  * License as published by the Free Software Foundation; either
14  * version 2.1 of the License, or (at your option) any later version.
15  *
16  * FFmpeg is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19  * Lesser General Public License for more details.
20  *
21  * You should have received a copy of the GNU Lesser General Public
22  * License along with FFmpeg; if not, write to the Free Software
23  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
24  */
25 
26 #include "config_components.h"
27 
28 #include <inttypes.h>
29 #include <limits.h>
30 #include <stdint.h>
31 
32 #include "libavutil/attributes.h"
33 #include "libavutil/bprint.h"
35 #include "libavutil/internal.h"
36 #include "libavutil/intreadwrite.h"
37 #include "libavutil/intfloat.h"
38 #include "libavutil/mathematics.h"
39 #include "libavutil/avassert.h"
40 #include "libavutil/avstring.h"
41 #include "libavutil/dict.h"
42 #include "libavutil/display.h"
43 #include "libavutil/mem.h"
44 #include "libavutil/opt.h"
45 #include "libavutil/aes.h"
46 #include "libavutil/aes_ctr.h"
47 #include "libavutil/pixdesc.h"
48 #include "libavutil/sha.h"
49 #include "libavutil/spherical.h"
50 #include "libavutil/stereo3d.h"
51 #include "libavutil/timecode.h"
52 #include "libavutil/uuid.h"
53 #include "libavcodec/ac3tab.h"
54 #include "libavcodec/exif.h"
55 #include "libavcodec/flac.h"
56 #include "libavcodec/hevc/hevc.h"
58 #include "libavcodec/mlp_parse.h"
59 #include "avformat.h"
60 #include "internal.h"
61 #include "avio_internal.h"
62 #include "demux.h"
63 #include "dvdclut.h"
64 #include "iamf_parse.h"
65 #include "iamf_reader.h"
66 #include "dovi_isom.h"
67 #include "riff.h"
68 #include "isom.h"
69 #include "libavcodec/get_bits.h"
70 #include "id3v1.h"
71 #include "mov_chan.h"
72 #include "replaygain.h"
73 
74 #if CONFIG_ZLIB
75 #include <zlib.h>
76 #endif
77 
78 #include "qtpalette.h"
79 
80 /* those functions parse an atom */
81 /* links atom IDs to parse functions */
82 typedef struct MOVParseTableEntry {
83  uint32_t type;
84  int (*parse)(MOVContext *ctx, AVIOContext *pb, MOVAtom atom);
86 
87 static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom);
88 static int mov_read_mfra(MOVContext *c, AVIOContext *f);
90 
92  unsigned len, const char *key)
93 {
94  char buf[16];
95 
96  short current, total = 0;
97  avio_rb16(pb); // unknown
98  current = avio_rb16(pb);
99  if (len >= 6)
100  total = avio_rb16(pb);
101  if (!total)
102  snprintf(buf, sizeof(buf), "%d", current);
103  else
104  snprintf(buf, sizeof(buf), "%d/%d", current, total);
105  c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
106  av_dict_set(&c->fc->metadata, key, buf, 0);
107 
108  return 0;
109 }
110 
112  unsigned len, const char *key)
113 {
114  /* bypass padding bytes */
115  avio_r8(pb);
116  avio_r8(pb);
117  avio_r8(pb);
118 
119  c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
120  av_dict_set_int(&c->fc->metadata, key, avio_r8(pb), 0);
121 
122  return 0;
123 }
124 
126  unsigned len, const char *key)
127 {
128  c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
129  av_dict_set_int(&c->fc->metadata, key, avio_r8(pb), 0);
130 
131  return 0;
132 }
133 
135  unsigned len, const char *key)
136 {
137  short genre;
138 
139  avio_r8(pb); // unknown
140 
141  genre = avio_r8(pb);
142  if (genre < 1 || genre > ID3v1_GENRE_MAX)
143  return 0;
144  c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
145  av_dict_set(&c->fc->metadata, key, ff_id3v1_genre_str[genre-1], 0);
146 
147  return 0;
148 }
149 
150 static const uint32_t mac_to_unicode[128] = {
151  0x00C4,0x00C5,0x00C7,0x00C9,0x00D1,0x00D6,0x00DC,0x00E1,
152  0x00E0,0x00E2,0x00E4,0x00E3,0x00E5,0x00E7,0x00E9,0x00E8,
153  0x00EA,0x00EB,0x00ED,0x00EC,0x00EE,0x00EF,0x00F1,0x00F3,
154  0x00F2,0x00F4,0x00F6,0x00F5,0x00FA,0x00F9,0x00FB,0x00FC,
155  0x2020,0x00B0,0x00A2,0x00A3,0x00A7,0x2022,0x00B6,0x00DF,
156  0x00AE,0x00A9,0x2122,0x00B4,0x00A8,0x2260,0x00C6,0x00D8,
157  0x221E,0x00B1,0x2264,0x2265,0x00A5,0x00B5,0x2202,0x2211,
158  0x220F,0x03C0,0x222B,0x00AA,0x00BA,0x03A9,0x00E6,0x00F8,
159  0x00BF,0x00A1,0x00AC,0x221A,0x0192,0x2248,0x2206,0x00AB,
160  0x00BB,0x2026,0x00A0,0x00C0,0x00C3,0x00D5,0x0152,0x0153,
161  0x2013,0x2014,0x201C,0x201D,0x2018,0x2019,0x00F7,0x25CA,
162  0x00FF,0x0178,0x2044,0x20AC,0x2039,0x203A,0xFB01,0xFB02,
163  0x2021,0x00B7,0x201A,0x201E,0x2030,0x00C2,0x00CA,0x00C1,
164  0x00CB,0x00C8,0x00CD,0x00CE,0x00CF,0x00CC,0x00D3,0x00D4,
165  0xF8FF,0x00D2,0x00DA,0x00DB,0x00D9,0x0131,0x02C6,0x02DC,
166  0x00AF,0x02D8,0x02D9,0x02DA,0x00B8,0x02DD,0x02DB,0x02C7,
167 };
168 
170  char *dst, int dstlen)
171 {
172  char *p = dst;
173  char *end = dst+dstlen-1;
174  int i;
175 
176  for (i = 0; i < len; i++) {
177  uint8_t t, c = avio_r8(pb);
178 
179  if (p >= end)
180  continue;
181 
182  if (c < 0x80)
183  *p++ = c;
184  else if (p < end)
185  PUT_UTF8(mac_to_unicode[c-0x80], t, if (p < end) *p++ = t;);
186  }
187  *p = 0;
188  return p - dst;
189 }
190 
191 /**
192  * Get the requested item.
193  */
194 static HEIFItem *get_heif_item(MOVContext *c, unsigned id)
195 {
196  HEIFItem *item = NULL;
197 
198  for (int i = 0; i < c->nb_heif_item; i++) {
199  if (!c->heif_item[i] || c->heif_item[i]->item_id != id)
200  continue;
201 
202  item = c->heif_item[i];
203  break;
204  }
205 
206  return item;
207 }
208 
209 /**
210  * Get the current stream in the parsing process. This can either be the
211  * latest stream added to the context, or the stream referenced by an item.
212  */
214 {
215  AVStream *st = NULL;
216  HEIFItem *item;
217 
218  if (c->fc->nb_streams < 1)
219  return NULL;
220 
221  if (c->cur_item_id == -1)
222  return c->fc->streams[c->fc->nb_streams-1];
223 
224  item = get_heif_item(c, c->cur_item_id);
225  if (item)
226  st = item->st;
227 
228  return st;
229 }
230 
231 static int mov_read_covr(MOVContext *c, AVIOContext *pb, int type, int len)
232 {
233  AVStream *st;
234  MOVStreamContext *sc;
235  enum AVCodecID id;
236  int ret;
237 
238  switch (type) {
239  case 0xd: id = AV_CODEC_ID_MJPEG; break;
240  case 0xe: id = AV_CODEC_ID_PNG; break;
241  case 0x1b: id = AV_CODEC_ID_BMP; break;
242  default:
243  av_log(c->fc, AV_LOG_WARNING, "Unknown cover type: 0x%x.\n", type);
244  avio_skip(pb, len);
245  return 0;
246  }
247 
248  sc = av_mallocz(sizeof(*sc));
249  if (!sc)
250  return AVERROR(ENOMEM);
251  ret = ff_add_attached_pic(c->fc, NULL, pb, NULL, len);
252  if (ret < 0) {
253  av_free(sc);
254  return ret;
255  }
256  st = c->fc->streams[c->fc->nb_streams - 1];
257  st->priv_data = sc;
258  sc->id = st->id;
259  sc->refcount = 1;
260 
261  if (st->attached_pic.size >= 8 && id != AV_CODEC_ID_BMP) {
262  if (AV_RB64(st->attached_pic.data) == 0x89504e470d0a1a0a) {
263  id = AV_CODEC_ID_PNG;
264  } else {
265  id = AV_CODEC_ID_MJPEG;
266  }
267  }
268  st->codecpar->codec_id = id;
269 
270  return 0;
271 }
272 
273 // 3GPP TS 26.244
274 static int mov_metadata_loci(MOVContext *c, AVIOContext *pb, unsigned len)
275 {
276  char language[4] = { 0 };
277  char buf[200], place[100];
278  uint16_t langcode = 0;
279  double longitude, latitude, altitude;
280  const char *key = "location";
281 
282  if (len < 4 + 2 + 1 + 1 + 4 + 4 + 4) {
283  av_log(c->fc, AV_LOG_ERROR, "loci too short\n");
284  return AVERROR_INVALIDDATA;
285  }
286 
287  avio_skip(pb, 4); // version+flags
288  langcode = avio_rb16(pb);
289  ff_mov_lang_to_iso639(langcode, language);
290  len -= 6;
291 
292  len -= avio_get_str(pb, len, place, sizeof(place));
293  if (len < 1) {
294  av_log(c->fc, AV_LOG_ERROR, "place name too long\n");
295  return AVERROR_INVALIDDATA;
296  }
297  avio_skip(pb, 1); // role
298  len -= 1;
299 
300  if (len < 12) {
301  av_log(c->fc, AV_LOG_ERROR,
302  "loci too short (%u bytes left, need at least %d)\n", len, 12);
303  return AVERROR_INVALIDDATA;
304  }
305  longitude = ((int32_t) avio_rb32(pb)) / (float) (1 << 16);
306  latitude = ((int32_t) avio_rb32(pb)) / (float) (1 << 16);
307  altitude = ((int32_t) avio_rb32(pb)) / (float) (1 << 16);
308 
309  // Try to output in the same format as the ?xyz field
310  snprintf(buf, sizeof(buf), "%+08.4f%+09.4f", latitude, longitude);
311  if (altitude)
312  av_strlcatf(buf, sizeof(buf), "%+f", altitude);
313  av_strlcatf(buf, sizeof(buf), "/%s", place);
314 
315  if (*language && strcmp(language, "und")) {
316  char key2[16];
317  snprintf(key2, sizeof(key2), "%s-%s", key, language);
318  av_dict_set(&c->fc->metadata, key2, buf, 0);
319  }
320  c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
321  return av_dict_set(&c->fc->metadata, key, buf, 0);
322 }
323 
324 static int mov_metadata_hmmt(MOVContext *c, AVIOContext *pb, unsigned len)
325 {
326  int i, n_hmmt;
327 
328  if (len < 2)
329  return 0;
330  if (c->ignore_chapters)
331  return 0;
332 
333  n_hmmt = avio_rb32(pb);
334  if (n_hmmt > len / 4)
335  return AVERROR_INVALIDDATA;
336  for (i = 0; i < n_hmmt && !pb->eof_reached; i++) {
337  int moment_time = avio_rb32(pb);
338  avpriv_new_chapter(c->fc, i, av_make_q(1, 1000), moment_time, AV_NOPTS_VALUE, NULL);
339  }
340  if (avio_feof(pb))
341  return AVERROR_INVALIDDATA;
342  return 0;
343 }
344 
346 {
347  char tmp_key[AV_FOURCC_MAX_STRING_SIZE] = {0};
348  char key2[32], language[4] = {0};
349  char *str = NULL;
350  const char *key = NULL;
351  uint16_t langcode = 0;
352  uint32_t data_type = 0, str_size_alloc;
353  uint64_t str_size;
354  int (*parse)(MOVContext*, AVIOContext*, unsigned, const char*) = NULL;
355  int raw = 0;
356  int num = 0;
358 
359  if (c->trak_index >= 0 && c->trak_index < c->fc->nb_streams)
360  metadata = &c->fc->streams[c->trak_index]->metadata;
361  else
362  metadata = &c->fc->metadata;
363 
364  switch (atom.type) {
365  case MKTAG( '@','P','R','M'): key = "premiere_version"; raw = 1; break;
366  case MKTAG( '@','P','R','Q'): key = "quicktime_version"; raw = 1; break;
367  case MKTAG( 'X','M','P','_'):
368  if (c->export_xmp) { key = "xmp"; raw = 1; } break;
369  case MKTAG( 'a','A','R','T'): key = "album_artist"; break;
370  case MKTAG( 'a','k','I','D'): key = "account_type";
372  case MKTAG( 'a','p','I','D'): key = "account_id"; break;
373  case MKTAG( 'c','a','t','g'): key = "category"; break;
374  case MKTAG( 'c','p','i','l'): key = "compilation";
376  case MKTAG( 'c','p','r','t'): key = "copyright"; break;
377  case MKTAG( 'd','e','s','c'): key = "description"; break;
378  case MKTAG( 'd','i','s','k'): key = "disc";
380  case MKTAG( 'e','g','i','d'): key = "episode_uid";
382  case MKTAG( 'F','I','R','M'): key = "firmware"; raw = 1; break;
383  case MKTAG( 'g','n','r','e'): key = "genre";
384  parse = mov_metadata_gnre; break;
385  case MKTAG( 'h','d','v','d'): key = "hd_video";
387  case MKTAG( 'H','M','M','T'):
388  return mov_metadata_hmmt(c, pb, atom.size);
389  case MKTAG( 'k','e','y','w'): key = "keywords"; break;
390  case MKTAG( 'l','d','e','s'): key = "synopsis"; break;
391  case MKTAG( 'l','o','c','i'):
392  return mov_metadata_loci(c, pb, atom.size);
393  case MKTAG( 'm','a','n','u'): key = "make"; break;
394  case MKTAG( 'm','o','d','l'): key = "model"; break;
395  case MKTAG( 'n','a','m','e'): key = "name"; break;
396  case MKTAG( 'p','c','s','t'): key = "podcast";
398  case MKTAG( 'p','g','a','p'): key = "gapless_playback";
400  case MKTAG( 'p','u','r','d'): key = "purchase_date"; break;
401  case MKTAG( 'r','t','n','g'): key = "rating";
403  case MKTAG( 's','o','a','a'): key = "sort_album_artist"; break;
404  case MKTAG( 's','o','a','l'): key = "sort_album"; break;
405  case MKTAG( 's','o','a','r'): key = "sort_artist"; break;
406  case MKTAG( 's','o','c','o'): key = "sort_composer"; break;
407  case MKTAG( 's','o','n','m'): key = "sort_name"; break;
408  case MKTAG( 's','o','s','n'): key = "sort_show"; break;
409  case MKTAG( 's','t','i','k'): key = "media_type";
411  case MKTAG( 't','r','k','n'): key = "track";
413  case MKTAG( 't','v','e','n'): key = "episode_id"; break;
414  case MKTAG( 't','v','e','s'): key = "episode_sort";
416  case MKTAG( 't','v','n','n'): key = "network"; break;
417  case MKTAG( 't','v','s','h'): key = "show"; break;
418  case MKTAG( 't','v','s','n'): key = "season_number";
420  case MKTAG(0xa9,'A','R','T'): key = "artist"; break;
421  case MKTAG(0xa9,'P','R','D'): key = "producer"; break;
422  case MKTAG(0xa9,'a','l','b'): key = "album"; break;
423  case MKTAG(0xa9,'a','u','t'): key = "artist"; break;
424  case MKTAG(0xa9,'c','h','p'): key = "chapter"; break;
425  case MKTAG(0xa9,'c','m','t'): key = "comment"; break;
426  case MKTAG(0xa9,'c','o','m'): key = "composer"; break;
427  case MKTAG(0xa9,'c','p','y'): key = "copyright"; break;
428  case MKTAG(0xa9,'d','a','y'): key = "date"; break;
429  case MKTAG(0xa9,'d','i','r'): key = "director"; break;
430  case MKTAG(0xa9,'d','i','s'): key = "disclaimer"; break;
431  case MKTAG(0xa9,'e','d','1'): key = "edit_date"; break;
432  case MKTAG(0xa9,'e','n','c'): key = "encoder"; break;
433  case MKTAG(0xa9,'f','m','t'): key = "original_format"; break;
434  case MKTAG(0xa9,'g','e','n'): key = "genre"; break;
435  case MKTAG(0xa9,'g','r','p'): key = "grouping"; break;
436  case MKTAG(0xa9,'h','s','t'): key = "host_computer"; break;
437  case MKTAG(0xa9,'i','n','f'): key = "comment"; break;
438  case MKTAG(0xa9,'l','y','r'): key = "lyrics"; break;
439  case MKTAG(0xa9,'m','a','k'): key = "make"; break;
440  case MKTAG(0xa9,'m','o','d'): key = "model"; break;
441  case MKTAG(0xa9,'n','a','m'): key = "title"; break;
442  case MKTAG(0xa9,'o','p','e'): key = "original_artist"; break;
443  case MKTAG(0xa9,'p','r','d'): key = "producer"; break;
444  case MKTAG(0xa9,'p','r','f'): key = "performers"; break;
445  case MKTAG(0xa9,'r','e','q'): key = "playback_requirements"; break;
446  case MKTAG(0xa9,'s','r','c'): key = "original_source"; break;
447  case MKTAG(0xa9,'s','t','3'): key = "subtitle"; break;
448  case MKTAG(0xa9,'s','w','r'): key = "encoder"; break;
449  case MKTAG(0xa9,'t','o','o'): key = "encoder"; break;
450  case MKTAG(0xa9,'t','r','k'): key = "track"; break;
451  case MKTAG(0xa9,'u','r','l'): key = "URL"; break;
452  case MKTAG(0xa9,'w','r','n'): key = "warning"; break;
453  case MKTAG(0xa9,'w','r','t'): key = "composer"; break;
454  case MKTAG(0xa9,'x','y','z'): key = "location"; break;
455  }
456 retry:
457  if (c->itunes_metadata && atom.size > 8) {
458  int data_size = avio_rb32(pb);
459  int tag = avio_rl32(pb);
460  if (tag == MKTAG('d','a','t','a') && data_size <= atom.size && data_size >= 16) {
461  data_type = avio_rb32(pb); // type
462  avio_rb32(pb); // unknown
463  str_size = data_size - 16;
464  atom.size -= 16;
465 
466  if (!key && c->found_hdlr_mdta && c->meta_keys) {
467  uint32_t index = av_bswap32(atom.type); // BE number has been read as LE
468  if (index < c->meta_keys_count && index > 0) {
469  key = c->meta_keys[index];
470  } else if (atom.type != MKTAG('c', 'o', 'v', 'r')) {
471  av_log(c->fc, AV_LOG_WARNING,
472  "The index of 'data' is out of range: %"PRId32" < 1 or >= %d.\n",
473  index, c->meta_keys_count);
474  }
475  }
476  if (atom.type == MKTAG('c', 'o', 'v', 'r') ||
477  (key && !strcmp(key, "com.apple.quicktime.artwork"))) {
478  int ret = mov_read_covr(c, pb, data_type, str_size);
479  if (ret < 0) {
480  av_log(c->fc, AV_LOG_ERROR, "Error parsing cover art.\n");
481  return ret;
482  }
483  atom.size -= str_size;
484  if (atom.size > 8)
485  goto retry;
486  return ret;
487  }
488  } else return 0;
489  } else if (atom.size > 4 && (key || c->export_all) && !c->itunes_metadata && !raw) {
490  str_size = avio_rb16(pb); // string length
491  if (str_size > atom.size) {
492  raw = 1;
493  avio_seek(pb, -2, SEEK_CUR);
494  av_log(c->fc, AV_LOG_WARNING, "UDTA parsing failed retrying raw\n");
495  goto retry;
496  }
497  langcode = avio_rb16(pb);
498  ff_mov_lang_to_iso639(langcode, language);
499  atom.size -= 4;
500  } else
501  str_size = atom.size;
502 
503  if (c->export_all && !key) {
504  key = av_fourcc_make_string(tmp_key, atom.type);
505  }
506 
507  if (!key)
508  return 0;
509  if (atom.size < 0 || str_size >= INT_MAX/2)
510  return AVERROR_INVALIDDATA;
511 
512  // Allocates enough space if data_type is a int32 or float32 number, otherwise
513  // worst-case requirement for output string in case of utf8 coded input
514  num = (data_type >= 21 && data_type <= 23);
515  str_size_alloc = (num ? 512 : (raw ? str_size : str_size * 2)) + 1;
516  str = av_mallocz(str_size_alloc);
517  if (!str)
518  return AVERROR(ENOMEM);
519 
520  if (parse)
521  parse(c, pb, str_size, key);
522  else {
523  if (!raw && (data_type == 3 || (data_type == 0 && (langcode < 0x400 || langcode == 0x7fff)))) { // MAC Encoded
524  mov_read_mac_string(c, pb, str_size, str, str_size_alloc);
525  } else if (data_type == 21) { // BE signed integer, variable size
526  int val = 0;
527  if (str_size == 1)
528  val = (int8_t)avio_r8(pb);
529  else if (str_size == 2)
530  val = (int16_t)avio_rb16(pb);
531  else if (str_size == 3)
532  val = ((int32_t)(avio_rb24(pb)<<8))>>8;
533  else if (str_size == 4)
534  val = (int32_t)avio_rb32(pb);
535  if (snprintf(str, str_size_alloc, "%d", val) >= str_size_alloc) {
536  av_log(c->fc, AV_LOG_ERROR,
537  "Failed to store the number (%d) in string.\n", val);
538  av_free(str);
539  return AVERROR_INVALIDDATA;
540  }
541  } else if (data_type == 22) { // BE unsigned integer, variable size
542  unsigned int val = 0;
543  if (str_size == 1)
544  val = avio_r8(pb);
545  else if (str_size == 2)
546  val = avio_rb16(pb);
547  else if (str_size == 3)
548  val = avio_rb24(pb);
549  else if (str_size == 4)
550  val = avio_rb32(pb);
551  if (snprintf(str, str_size_alloc, "%u", val) >= str_size_alloc) {
552  av_log(c->fc, AV_LOG_ERROR,
553  "Failed to store the number (%u) in string.\n", val);
554  av_free(str);
555  return AVERROR_INVALIDDATA;
556  }
557  } else if (data_type == 23 && str_size >= 4) { // BE float32
558  float val = av_int2float(avio_rb32(pb));
559  if (snprintf(str, str_size_alloc, "%f", val) >= str_size_alloc) {
560  av_log(c->fc, AV_LOG_ERROR,
561  "Failed to store the float32 number (%f) in string.\n", val);
562  av_free(str);
563  return AVERROR_INVALIDDATA;
564  }
565  } else if (data_type > 1 && data_type != 4) {
566  // data_type can be 0 if not set at all above. data_type 1 means
567  // UTF8 and 4 means "UTF8 sort". For any other type (UTF16 or e.g.
568  // a picture), don't return it blindly in a string that is supposed
569  // to be UTF8 text.
570  av_log(c->fc, AV_LOG_WARNING, "Skipping unhandled metadata %s of type %"PRIu32"\n", key, data_type);
571  av_free(str);
572  return 0;
573  } else {
574  int ret = ffio_read_size(pb, str, str_size);
575  if (ret < 0) {
576  av_free(str);
577  return ret;
578  }
579  str[str_size] = 0;
580  }
581  c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
582  av_dict_set(metadata, key, str, 0);
583  if (*language && strcmp(language, "und")) {
584  snprintf(key2, sizeof(key2), "%s-%s", key, language);
585  av_dict_set(metadata, key2, str, 0);
586  }
587  if (!strcmp(key, "encoder")) {
588  int major, minor, micro;
589  if (sscanf(str, "HandBrake %d.%d.%d", &major, &minor, &micro) == 3) {
590  c->handbrake_version = 1000000*major + 1000*minor + micro;
591  }
592  }
593  }
594 
595  av_freep(&str);
596  return 0;
597 }
598 
600 {
601  int64_t start;
602  int i, nb_chapters, str_len, version;
603  char str[256+1];
604  int ret;
605 
606  if (c->ignore_chapters)
607  return 0;
608 
609  if ((atom.size -= 5) < 0)
610  return 0;
611 
612  version = avio_r8(pb);
613  avio_rb24(pb);
614  if (version)
615  avio_rb32(pb); // ???
616  nb_chapters = avio_r8(pb);
617 
618  for (i = 0; i < nb_chapters; i++) {
619  if (atom.size < 9)
620  return 0;
621 
622  start = avio_rb64(pb);
623  str_len = avio_r8(pb);
624 
625  if ((atom.size -= 9+str_len) < 0)
626  return 0;
627 
628  ret = ffio_read_size(pb, str, str_len);
629  if (ret < 0)
630  return ret;
631  str[str_len] = 0;
632  avpriv_new_chapter(c->fc, i, (AVRational){1,10000000}, start, AV_NOPTS_VALUE, str);
633  }
634  return 0;
635 }
636 
637 #define MIN_DATA_ENTRY_BOX_SIZE 12
639 {
640  AVStream *st;
641  MOVStreamContext *sc;
642  int entries, i, j;
643 
644  if (c->fc->nb_streams < 1)
645  return 0;
646  st = c->fc->streams[c->fc->nb_streams-1];
647  sc = st->priv_data;
648 
649  avio_rb32(pb); // version + flags
650  entries = avio_rb32(pb);
651  if (!entries ||
652  entries > (atom.size - 1) / MIN_DATA_ENTRY_BOX_SIZE + 1 ||
653  entries >= UINT_MAX / sizeof(*sc->drefs))
654  return AVERROR_INVALIDDATA;
655 
656  for (i = 0; i < sc->drefs_count; i++) {
657  MOVDref *dref = &sc->drefs[i];
658  av_freep(&dref->path);
659  av_freep(&dref->dir);
660  }
661  av_free(sc->drefs);
662  sc->drefs_count = 0;
663  sc->drefs = av_mallocz(entries * sizeof(*sc->drefs));
664  if (!sc->drefs)
665  return AVERROR(ENOMEM);
666  sc->drefs_count = entries;
667 
668  for (i = 0; i < entries; i++) {
669  MOVDref *dref = &sc->drefs[i];
670  uint32_t size = avio_rb32(pb);
671  int64_t next = avio_tell(pb);
672 
673  if (size < 12 || next < 0 || next > INT64_MAX - size)
674  return AVERROR_INVALIDDATA;
675 
676  next += size - 4;
677 
678  dref->type = avio_rl32(pb);
679  avio_rb32(pb); // version + flags
680 
681  if (dref->type == MKTAG('a','l','i','s') && size > 150) {
682  /* macintosh alias record */
683  uint16_t volume_len, len;
684  int16_t type;
685  int ret;
686 
687  avio_skip(pb, 10);
688 
689  volume_len = avio_r8(pb);
690  volume_len = FFMIN(volume_len, 27);
691  ret = ffio_read_size(pb, dref->volume, 27);
692  if (ret < 0)
693  return ret;
694  dref->volume[volume_len] = 0;
695  av_log(c->fc, AV_LOG_DEBUG, "volume %s, len %d\n", dref->volume, volume_len);
696 
697  avio_skip(pb, 12);
698 
699  len = avio_r8(pb);
700  len = FFMIN(len, 63);
701  ret = ffio_read_size(pb, dref->filename, 63);
702  if (ret < 0)
703  return ret;
704  dref->filename[len] = 0;
705  av_log(c->fc, AV_LOG_DEBUG, "filename %s, len %d\n", dref->filename, len);
706 
707  avio_skip(pb, 16);
708 
709  /* read next level up_from_alias/down_to_target */
710  dref->nlvl_from = avio_rb16(pb);
711  dref->nlvl_to = avio_rb16(pb);
712  av_log(c->fc, AV_LOG_DEBUG, "nlvl from %d, nlvl to %d\n",
713  dref->nlvl_from, dref->nlvl_to);
714 
715  avio_skip(pb, 16);
716 
717  for (type = 0; type != -1 && avio_tell(pb) < next; ) {
718  if (avio_feof(pb))
719  return AVERROR_EOF;
720  type = avio_rb16(pb);
721  len = avio_rb16(pb);
722  av_log(c->fc, AV_LOG_DEBUG, "type %d, len %d\n", type, len);
723  if (len&1)
724  len += 1;
725  if (type == 2) { // absolute path
726  av_free(dref->path);
727  dref->path = av_mallocz(len+1);
728  if (!dref->path)
729  return AVERROR(ENOMEM);
730 
731  ret = ffio_read_size(pb, dref->path, len);
732  if (ret < 0) {
733  av_freep(&dref->path);
734  return ret;
735  }
736  if (len > volume_len && !strncmp(dref->path, dref->volume, volume_len)) {
737  len -= volume_len;
738  memmove(dref->path, dref->path+volume_len, len);
739  dref->path[len] = 0;
740  }
741  // trim string of any ending zeros
742  for (j = len - 1; j >= 0; j--) {
743  if (dref->path[j] == 0)
744  len--;
745  else
746  break;
747  }
748  for (j = 0; j < len; j++)
749  if (dref->path[j] == ':' || dref->path[j] == 0)
750  dref->path[j] = '/';
751  av_log(c->fc, AV_LOG_DEBUG, "path %s\n", dref->path);
752  } else if (type == 0) { // directory name
753  av_free(dref->dir);
754  dref->dir = av_malloc(len+1);
755  if (!dref->dir)
756  return AVERROR(ENOMEM);
757 
758  ret = ffio_read_size(pb, dref->dir, len);
759  if (ret < 0) {
760  av_freep(&dref->dir);
761  return ret;
762  }
763  dref->dir[len] = 0;
764  for (j = 0; j < len; j++)
765  if (dref->dir[j] == ':')
766  dref->dir[j] = '/';
767  av_log(c->fc, AV_LOG_DEBUG, "dir %s\n", dref->dir);
768  } else
769  avio_skip(pb, len);
770  }
771  } else {
772  av_log(c->fc, AV_LOG_DEBUG, "Unknown dref type 0x%08"PRIx32" size %"PRIu32"\n",
773  dref->type, size);
774  entries--;
775  i--;
776  }
777  avio_seek(pb, next, SEEK_SET);
778  }
779  return 0;
780 }
781 
783 {
784  AVStream *st;
785  uint32_t type;
786  uint32_t ctype;
787  int64_t title_size;
788  char *title_str;
789  int ret;
790 
791  avio_r8(pb); /* version */
792  avio_rb24(pb); /* flags */
793 
794  /* component type */
795  ctype = avio_rl32(pb);
796  type = avio_rl32(pb); /* component subtype */
797 
798  av_log(c->fc, AV_LOG_TRACE, "ctype=%s\n", av_fourcc2str(ctype));
799  av_log(c->fc, AV_LOG_TRACE, "stype=%s\n", av_fourcc2str(type));
800 
801  if (c->trak_index < 0) { // meta not inside a trak
802  if (type == MKTAG('m','d','t','a')) {
803  c->found_hdlr_mdta = 1;
804  }
805  return 0;
806  }
807 
808  st = c->fc->streams[c->fc->nb_streams-1];
809 
810  if (type == MKTAG('v','i','d','e'))
812  else if (type == MKTAG('s','o','u','n'))
814  else if (type == MKTAG('m','1','a',' '))
816  else if ((type == MKTAG('s','u','b','p')) || (type == MKTAG('c','l','c','p')))
818 
819  avio_rb32(pb); /* component manufacture */
820  avio_rb32(pb); /* component flags */
821  avio_rb32(pb); /* component flags mask */
822 
823  title_size = atom.size - 24;
824  if (title_size > 0) {
825  if (title_size > FFMIN(INT_MAX, SIZE_MAX-1))
826  return AVERROR_INVALIDDATA;
827  title_str = av_malloc(title_size + 1); /* Add null terminator */
828  if (!title_str)
829  return AVERROR(ENOMEM);
830 
831  ret = ffio_read_size(pb, title_str, title_size);
832  if (ret < 0) {
833  av_freep(&title_str);
834  return ret;
835  }
836  title_str[title_size] = 0;
837  if (title_str[0]) {
838  int off = (!c->isom && title_str[0] == title_size - 1);
839  // flag added so as to not set stream handler name if already set from mdia->hdlr
840  av_dict_set(&st->metadata, "handler_name", title_str + off, AV_DICT_DONT_OVERWRITE);
841  }
842  av_freep(&title_str);
843  }
844 
845  return 0;
846 }
847 
849 {
850  return ff_mov_read_esds(c->fc, pb);
851 }
852 
854 {
855  AVStream *st;
856  AVPacketSideData *sd;
857  enum AVAudioServiceType *ast;
858  int ac3info, acmod, lfeon, bsmod;
859  uint64_t mask;
860 
861  if (c->fc->nb_streams < 1)
862  return 0;
863  st = c->fc->streams[c->fc->nb_streams-1];
864 
868  sizeof(*ast), 0);
869  if (!sd)
870  return AVERROR(ENOMEM);
871 
872  ast = (enum AVAudioServiceType*)sd->data;
873  ac3info = avio_rb24(pb);
874  bsmod = (ac3info >> 14) & 0x7;
875  acmod = (ac3info >> 11) & 0x7;
876  lfeon = (ac3info >> 10) & 0x1;
877 
879  if (lfeon)
883 
884  *ast = bsmod;
885  if (st->codecpar->ch_layout.nb_channels > 1 && bsmod == 0x7)
887 
888  return 0;
889 }
890 
891 #if CONFIG_IAMFDEC
892 static int mov_read_iacb(MOVContext *c, AVIOContext *pb, MOVAtom atom)
893 {
894  AVStream *st;
895  MOVStreamContext *sc;
896  FFIOContext b;
897  AVIOContext *descriptor_pb;
899  IAMFContext *iamf;
901  unsigned descriptors_size;
902  int nb_frames, disposition;
903  int version, ret;
904 
905  if (atom.size < 5)
906  return AVERROR_INVALIDDATA;
907 
908  if (c->fc->nb_streams < 1)
909  return 0;
910 
911  version = avio_r8(pb);
912  if (version != 1) {
913  av_log(c->fc, AV_LOG_ERROR, "%s configurationVersion %d",
914  version < 1 ? "invalid" : "unsupported", version);
915  return AVERROR_INVALIDDATA;
916  }
917 
918  descriptors_size = ffio_read_leb(pb);
919  if (!descriptors_size || descriptors_size > INT_MAX)
920  return AVERROR_INVALIDDATA;
921 
922  st = c->fc->streams[c->fc->nb_streams - 1];
923  sc = st->priv_data;
924 
925  if (st->codecpar->extradata) {
926  av_log(c->fc, AV_LOG_WARNING, "ignoring iacb\n");
927  return 0;
928  }
929 
930  sc->iamf = av_mallocz(sizeof(*sc->iamf));
931  if (!sc->iamf)
932  return AVERROR(ENOMEM);
933  iamf = &sc->iamf->iamf;
934 
935  st->codecpar->extradata = av_malloc(descriptors_size);
936  if (!st->codecpar->extradata)
937  return AVERROR(ENOMEM);
938  st->codecpar->extradata_size = descriptors_size;
939 
940  ret = avio_read(pb, st->codecpar->extradata, descriptors_size);
941  if (ret != descriptors_size)
942  return ret < 0 ? ret : AVERROR_INVALIDDATA;
943 
944  ffio_init_read_context(&b, st->codecpar->extradata, descriptors_size);
945  descriptor_pb = &b.pub;
946 
947  ret = ff_iamfdec_read_descriptors(iamf, descriptor_pb, descriptors_size, c->fc);
948  if (ret < 0)
949  return ret;
950 
951  metadata = st->metadata;
952  st->metadata = NULL;
953  start_time = st->start_time;
954  nb_frames = st->nb_frames;
955  duration = st->duration;
956  disposition = st->disposition;
957 
958  for (int i = 0; i < iamf->nb_audio_elements; i++) {
959  IAMFAudioElement *audio_element = iamf->audio_elements[i];
960  const AVIAMFAudioElement *element;
961  AVStreamGroup *stg =
963 
964  if (!stg) {
965  ret = AVERROR(ENOMEM);
966  goto fail;
967  }
968 
970  stg->id = audio_element->audio_element_id;
971  /* Transfer ownership */
972  element = stg->params.iamf_audio_element = audio_element->element;
973  audio_element->element = NULL;
974 
975  for (int j = 0; j < audio_element->nb_substreams; j++) {
976  IAMFSubStream *substream = &audio_element->substreams[j];
977  AVStream *stream;
978 
979  if (!i && !j) {
980  if (audio_element->layers[0].substream_count != 1)
981  disposition &= ~AV_DISPOSITION_DEFAULT;
982  stream = st;
983  } else
984  stream = avformat_new_stream(c->fc, NULL);
985  if (!stream) {
986  ret = AVERROR(ENOMEM);
987  goto fail;
988  }
989 
990  stream->start_time = start_time;
991  stream->nb_frames = nb_frames;
992  stream->duration = duration;
993  stream->disposition = disposition;
994  if (stream != st) {
995  stream->priv_data = sc;
996  sc->refcount++;
997  }
998 
1001  if (i || j) {
1003  if (audio_element->layers[0].substream_count == 1)
1004  stream->disposition &= ~AV_DISPOSITION_DEFAULT;
1005  }
1006 
1007  ret = avcodec_parameters_copy(stream->codecpar, substream->codecpar);
1008  if (ret < 0)
1009  goto fail;
1010 
1011  stream->id = substream->audio_substream_id;
1012 
1013  avpriv_set_pts_info(st, 64, 1, sc->time_scale);
1014 
1015  ret = avformat_stream_group_add_stream(stg, stream);
1016  if (ret < 0)
1017  goto fail;
1018  }
1019 
1020  ret = av_dict_copy(&stg->metadata, metadata, 0);
1021  if (ret < 0)
1022  goto fail;
1023  }
1024 
1025  for (int i = 0; i < iamf->nb_mix_presentations; i++) {
1026  IAMFMixPresentation *mix_presentation = iamf->mix_presentations[i];
1027  const AVIAMFMixPresentation *mix = mix_presentation->cmix;
1028  AVStreamGroup *stg =
1030 
1031  if (!stg) {
1032  ret = AVERROR(ENOMEM);
1033  goto fail;
1034  }
1035 
1037  stg->id = mix_presentation->mix_presentation_id;
1038  /* Transfer ownership */
1039  stg->params.iamf_mix_presentation = mix_presentation->mix;
1040  mix_presentation->mix = NULL;
1041 
1042  for (int j = 0; j < mix->nb_submixes; j++) {
1043  const AVIAMFSubmix *submix = mix->submixes[j];
1044 
1045  for (int k = 0; k < submix->nb_elements; k++) {
1046  const AVIAMFSubmixElement *submix_element = submix->elements[k];
1047  const AVStreamGroup *audio_element = NULL;
1048 
1049  for (int l = 0; l < c->fc->nb_stream_groups; l++)
1050  if (c->fc->stream_groups[l]->type == AV_STREAM_GROUP_PARAMS_IAMF_AUDIO_ELEMENT &&
1051  c->fc->stream_groups[l]->id == submix_element->audio_element_id) {
1052  audio_element = c->fc->stream_groups[l];
1053  break;
1054  }
1055  av_assert0(audio_element);
1056 
1057  for (int l = 0; l < audio_element->nb_streams; l++) {
1058  ret = avformat_stream_group_add_stream(stg, audio_element->streams[l]);
1059  if (ret < 0 && ret != AVERROR(EEXIST))
1060  goto fail;
1061  }
1062  }
1063  }
1064 
1065  ret = av_dict_copy(&stg->metadata, metadata, 0);
1066  if (ret < 0)
1067  goto fail;
1068  }
1069 
1070  ret = 0;
1071 fail:
1073 
1074  return ret;
1075 }
1076 #endif
1077 
1079 {
1080  AVStream *st;
1081  int32_t sample_rate;
1082 
1083  if (atom.size < 8 || c->fc->nb_streams < 1)
1084  return 0;
1085 
1086  st = c->fc->streams[c->fc->nb_streams-1];
1087  if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO) {
1088  av_log(c->fc, AV_LOG_WARNING, "'srat' within non-audio sample entry, skip\n");
1089  return 0;
1090  }
1091 
1092  if (!c->isom) {
1093  av_log(c->fc, AV_LOG_WARNING, "'srat' within non-isom, skip\n");
1094  return 0;
1095  }
1096 
1097  avio_skip(pb, 4); // version+flags
1098  sample_rate = avio_rb32(pb);
1099  if (sample_rate > 0) {
1100  av_log(c->fc, AV_LOG_DEBUG,
1101  "overwrite sample rate from %d to %d by 'srat'\n",
1102  st->codecpar->sample_rate, sample_rate);
1103  st->codecpar->sample_rate = sample_rate;
1104  } else {
1105  av_log(c->fc, AV_LOG_WARNING,
1106  "ignore invalid sample rate %d in 'srat'\n", sample_rate);
1107  }
1108 
1109  return 0;
1110 }
1111 
1113 {
1114  AVStream *st;
1115  AVPacketSideData *sd;
1116  enum AVAudioServiceType *ast;
1117  int eac3info, acmod, lfeon, bsmod;
1118  uint64_t mask;
1119 
1120  if (c->fc->nb_streams < 1)
1121  return 0;
1122  st = c->fc->streams[c->fc->nb_streams-1];
1123 
1127  sizeof(*ast), 0);
1128  if (!sd)
1129  return AVERROR(ENOMEM);
1130 
1131  ast = (enum AVAudioServiceType*)sd->data;
1132 
1133  /* No need to parse fields for additional independent substreams and its
1134  * associated dependent substreams since libavcodec's E-AC-3 decoder
1135  * does not support them yet. */
1136  avio_rb16(pb); /* data_rate and num_ind_sub */
1137  eac3info = avio_rb24(pb);
1138  bsmod = (eac3info >> 12) & 0x1f;
1139  acmod = (eac3info >> 9) & 0x7;
1140  lfeon = (eac3info >> 8) & 0x1;
1141 
1143  if (lfeon)
1147 
1148  *ast = bsmod;
1149  if (st->codecpar->ch_layout.nb_channels > 1 && bsmod == 0x7)
1151 
1152  return 0;
1153 }
1154 
1156 {
1157 #define DDTS_SIZE 20
1158  uint8_t buf[DDTS_SIZE + AV_INPUT_BUFFER_PADDING_SIZE];
1159  AVStream *st = NULL;
1160  uint32_t frame_duration_code = 0;
1161  uint32_t channel_layout_code = 0;
1162  GetBitContext gb;
1163  int ret;
1164 
1165  if ((ret = ffio_read_size(pb, buf, DDTS_SIZE)) < 0)
1166  return ret;
1167 
1168  init_get_bits(&gb, buf, 8 * DDTS_SIZE);
1169 
1170  if (c->fc->nb_streams < 1) {
1171  return 0;
1172  }
1173  st = c->fc->streams[c->fc->nb_streams-1];
1174 
1175  st->codecpar->sample_rate = get_bits_long(&gb, 32);
1176  if (st->codecpar->sample_rate <= 0) {
1177  av_log(c->fc, AV_LOG_ERROR, "Invalid sample rate %d\n", st->codecpar->sample_rate);
1178  return AVERROR_INVALIDDATA;
1179  }
1180  skip_bits_long(&gb, 32); /* max bitrate */
1181  st->codecpar->bit_rate = get_bits_long(&gb, 32);
1182  st->codecpar->bits_per_coded_sample = get_bits(&gb, 8);
1183  frame_duration_code = get_bits(&gb, 2);
1184  skip_bits(&gb, 30); /* various fields */
1185  channel_layout_code = get_bits(&gb, 16);
1186 
1187  st->codecpar->frame_size =
1188  (frame_duration_code == 0) ? 512 :
1189  (frame_duration_code == 1) ? 1024 :
1190  (frame_duration_code == 2) ? 2048 :
1191  (frame_duration_code == 3) ? 4096 : 0;
1192 
1193  if (channel_layout_code > 0xff) {
1194  av_log(c->fc, AV_LOG_WARNING, "Unsupported DTS audio channel layout\n");
1195  }
1198  ((channel_layout_code & 0x1) ? AV_CH_FRONT_CENTER : 0) |
1199  ((channel_layout_code & 0x2) ? AV_CH_FRONT_LEFT : 0) |
1200  ((channel_layout_code & 0x2) ? AV_CH_FRONT_RIGHT : 0) |
1201  ((channel_layout_code & 0x4) ? AV_CH_SIDE_LEFT : 0) |
1202  ((channel_layout_code & 0x4) ? AV_CH_SIDE_RIGHT : 0) |
1203  ((channel_layout_code & 0x8) ? AV_CH_LOW_FREQUENCY : 0));
1204 
1205  return 0;
1206 }
1207 
1209 {
1210  AVStream *st;
1211 
1212  if (c->fc->nb_streams < 1)
1213  return 0;
1214  st = c->fc->streams[c->fc->nb_streams-1];
1215 
1216  if (atom.size < 16)
1217  return 0;
1218 
1219  /* skip version and flags */
1220  avio_skip(pb, 4);
1221 
1222  ff_mov_read_chan(c->fc, pb, st, atom.size - 4);
1223 
1224  return 0;
1225 }
1226 
1228 {
1229  int64_t end = av_sat_add64(avio_tell(pb), atom.size);
1230  int version, flags;
1231  int ret;
1232  AVStream *st;
1233 
1234  if (c->fc->nb_streams < 1)
1235  return 0;
1236  st = c->fc->streams[c->fc->nb_streams-1];
1237 
1238  version = avio_r8(pb);
1239  flags = avio_rb24(pb);
1240  if (version != 0 || flags != 0) {
1241  av_log(c->fc, AV_LOG_ERROR,
1242  "Unsupported 'chnl' box with version %d, flags: %#x",
1243  version, flags);
1244  return AVERROR_INVALIDDATA;
1245  }
1246 
1247  ret = ff_mov_read_chnl(c->fc, pb, st);
1248  if (ret < 0)
1249  return ret;
1250 
1251  if (avio_tell(pb) != end) {
1252  av_log(c->fc, AV_LOG_WARNING, "skip %" PRId64 " bytes of unknown data inside chnl\n",
1253  end - avio_tell(pb));
1254  avio_seek(pb, end, SEEK_SET);
1255  }
1256  return ret;
1257 }
1258 
1260 {
1261  AVStream *st;
1262  int ret;
1263 
1264  if (c->fc->nb_streams < 1)
1265  return 0;
1266  st = c->fc->streams[c->fc->nb_streams-1];
1267 
1268  if ((ret = ff_get_wav_header(c->fc, pb, st->codecpar, atom.size, 0)) < 0)
1269  av_log(c->fc, AV_LOG_WARNING, "get_wav_header failed\n");
1270 
1271  return ret;
1272 }
1273 
1275 {
1276  AVStream *st;
1277  HEIFItem *item;
1278  AVPacketSideData *sd;
1279  int width, height, err = 0;
1280  AVRational aperture_width, aperture_height, horiz_off, vert_off;
1281  AVRational pc_x, pc_y;
1282  uint64_t top, bottom, left, right;
1283 
1284  item = get_heif_item(c, c->cur_item_id);
1285  st = get_curr_st(c);
1286  if (!st)
1287  return 0;
1288 
1289  width = st->codecpar->width;
1290  height = st->codecpar->height;
1291  if ((!width || !height) && item) {
1292  width = item->width;
1293  height = item->height;
1294  }
1295  if (!width || !height) {
1296  err = AVERROR_INVALIDDATA;
1297  goto fail;
1298  }
1299 
1300  aperture_width.num = avio_rb32(pb);
1301  aperture_width.den = avio_rb32(pb);
1302  aperture_height.num = avio_rb32(pb);
1303  aperture_height.den = avio_rb32(pb);
1304 
1305  horiz_off.num = avio_rb32(pb);
1306  horiz_off.den = avio_rb32(pb);
1307  vert_off.num = avio_rb32(pb);
1308  vert_off.den = avio_rb32(pb);
1309 
1310  if (aperture_width.num < 0 || aperture_width.den < 0 ||
1311  aperture_height.num < 0 || aperture_height.den < 0 ||
1312  horiz_off.den < 0 || vert_off.den < 0) {
1313  err = AVERROR_INVALIDDATA;
1314  goto fail;
1315  }
1316  if ((av_cmp_q((AVRational) { width, 1 }, aperture_width) < 0) ||
1317  (av_cmp_q((AVRational) { height, 1 }, aperture_height) < 0)) {
1318  err = AVERROR_INVALIDDATA;
1319  goto fail;
1320  }
1321  av_log(c->fc, AV_LOG_TRACE, "clap: apertureWidth %d/%d, apertureHeight %d/%d "
1322  "horizOff %d/%d vertOff %d/%d\n",
1323  aperture_width.num, aperture_width.den, aperture_height.num, aperture_height.den,
1324  horiz_off.num, horiz_off.den, vert_off.num, vert_off.den);
1325 
1326  pc_x = av_mul_q((AVRational) { width - 1, 1 }, (AVRational) { 1, 2 });
1327  pc_x = av_add_q(pc_x, horiz_off);
1328  pc_y = av_mul_q((AVRational) { height - 1, 1 }, (AVRational) { 1, 2 });
1329  pc_y = av_add_q(pc_y, vert_off);
1330 
1331  aperture_width = av_sub_q(aperture_width, (AVRational) { 1, 1 });
1332  aperture_width = av_mul_q(aperture_width, (AVRational) { 1, 2 });
1333  aperture_height = av_sub_q(aperture_height, (AVRational) { 1, 1 });
1334  aperture_height = av_mul_q(aperture_height, (AVRational) { 1, 2 });
1335 
1336  left = av_q2d(av_sub_q(pc_x, aperture_width));
1337  right = av_q2d(av_add_q(pc_x, aperture_width));
1338  top = av_q2d(av_sub_q(pc_y, aperture_height));
1339  bottom = av_q2d(av_add_q(pc_y, aperture_height));
1340 
1341  if (bottom > (height - 1) ||
1342  right > (width - 1)) {
1343  err = AVERROR_INVALIDDATA;
1344  goto fail;
1345  }
1346 
1347  bottom = height - 1 - bottom;
1348  right = width - 1 - right;
1349 
1350  if (!(left | right | top | bottom))
1351  return 0;
1352 
1353  if ((left + right) >= width ||
1354  (top + bottom) >= height) {
1355  err = AVERROR_INVALIDDATA;
1356  goto fail;
1357  }
1358 
1362  sizeof(uint32_t) * 4, 0);
1363  if (!sd)
1364  return AVERROR(ENOMEM);
1365 
1366  AV_WL32A(sd->data, top);
1367  AV_WL32A(sd->data + 4, bottom);
1368  AV_WL32A(sd->data + 8, left);
1369  AV_WL32A(sd->data + 12, right);
1370 
1371 fail:
1372  if (err < 0) {
1373  int explode = !!(c->fc->error_recognition & AV_EF_EXPLODE);
1374  av_log(c->fc, explode ? AV_LOG_ERROR : AV_LOG_WARNING, "Invalid clap box\n");
1375  if (!explode)
1376  err = 0;
1377  }
1378 
1379  return err;
1380 }
1381 
1382 /* This atom overrides any previously set aspect ratio */
1384 {
1385  const int num = avio_rb32(pb);
1386  const int den = avio_rb32(pb);
1387  AVStream *st;
1388  MOVStreamContext *sc;
1389 
1390  if (c->fc->nb_streams < 1)
1391  return 0;
1392  st = c->fc->streams[c->fc->nb_streams-1];
1393  sc = st->priv_data;
1394 
1395  av_log(c->fc, AV_LOG_TRACE, "pasp: hSpacing %d, vSpacing %d\n", num, den);
1396 
1397  if (den != 0) {
1398  sc->h_spacing = num;
1399  sc->v_spacing = den;
1400  }
1401  return 0;
1402 }
1403 
1404 /* this atom contains actual media data */
1406 {
1407  if (atom.size == 0) /* wrong one (MP4) */
1408  return 0;
1409  c->found_mdat=1;
1410  return 0; /* now go for moov */
1411 }
1412 
1413 #define DRM_BLOB_SIZE 56
1414 
1416 {
1417  uint8_t intermediate_key[20];
1418  uint8_t intermediate_iv[20];
1419  uint8_t input[64];
1420  uint8_t output[64];
1421  uint8_t file_checksum[20];
1422  uint8_t calculated_checksum[20];
1423  char checksum_string[2 * sizeof(file_checksum) + 1];
1424  struct AVSHA *sha;
1425  int i;
1426  int ret = 0;
1427  uint8_t *activation_bytes = c->activation_bytes;
1428  uint8_t *fixed_key = c->audible_fixed_key;
1429 
1430  c->aax_mode = 1;
1431 
1432  sha = av_sha_alloc();
1433  if (!sha)
1434  return AVERROR(ENOMEM);
1435  av_free(c->aes_decrypt);
1436  c->aes_decrypt = av_aes_alloc();
1437  if (!c->aes_decrypt) {
1438  ret = AVERROR(ENOMEM);
1439  goto fail;
1440  }
1441 
1442  /* drm blob processing */
1443  avio_read(pb, output, 8); // go to offset 8, absolute position 0x251
1445  avio_read(pb, output, 4); // go to offset 4, absolute position 0x28d
1446  ret = ffio_read_size(pb, file_checksum, 20);
1447  if (ret < 0)
1448  goto fail;
1449 
1450  // required by external tools
1451  ff_data_to_hex(checksum_string, file_checksum, sizeof(file_checksum), 1);
1452  av_log(c->fc, AV_LOG_INFO, "[aax] file checksum == %s\n", checksum_string);
1453 
1454  /* verify activation data */
1455  if (!activation_bytes) {
1456  av_log(c->fc, AV_LOG_WARNING, "[aax] activation_bytes option is missing!\n");
1457  ret = 0; /* allow ffprobe to continue working on .aax files */
1458  goto fail;
1459  }
1460  if (c->activation_bytes_size != 4) {
1461  av_log(c->fc, AV_LOG_FATAL, "[aax] activation_bytes value needs to be 4 bytes!\n");
1462  ret = AVERROR(EINVAL);
1463  goto fail;
1464  }
1465 
1466  /* verify fixed key */
1467  if (c->audible_fixed_key_size != 16) {
1468  av_log(c->fc, AV_LOG_FATAL, "[aax] audible_fixed_key value needs to be 16 bytes!\n");
1469  ret = AVERROR(EINVAL);
1470  goto fail;
1471  }
1472 
1473  /* AAX (and AAX+) key derivation */
1474  av_sha_init(sha, 160);
1475  av_sha_update(sha, fixed_key, 16);
1476  av_sha_update(sha, activation_bytes, 4);
1477  av_sha_final(sha, intermediate_key);
1478  av_sha_init(sha, 160);
1479  av_sha_update(sha, fixed_key, 16);
1480  av_sha_update(sha, intermediate_key, 20);
1481  av_sha_update(sha, activation_bytes, 4);
1482  av_sha_final(sha, intermediate_iv);
1483  av_sha_init(sha, 160);
1484  av_sha_update(sha, intermediate_key, 16);
1485  av_sha_update(sha, intermediate_iv, 16);
1486  av_sha_final(sha, calculated_checksum);
1487  if (memcmp(calculated_checksum, file_checksum, 20)) { // critical error
1488  av_log(c->fc, AV_LOG_ERROR, "[aax] mismatch in checksums!\n");
1490  goto fail;
1491  }
1492  av_aes_init(c->aes_decrypt, intermediate_key, 128, 1);
1493  av_aes_crypt(c->aes_decrypt, output, input, DRM_BLOB_SIZE >> 4, intermediate_iv, 1);
1494  for (i = 0; i < 4; i++) {
1495  // file data (in output) is stored in big-endian mode
1496  if (activation_bytes[i] != output[3 - i]) { // critical error
1497  av_log(c->fc, AV_LOG_ERROR, "[aax] error in drm blob decryption!\n");
1499  goto fail;
1500  }
1501  }
1502  memcpy(c->file_key, output + 8, 16);
1503  memcpy(input, output + 26, 16);
1504  av_sha_init(sha, 160);
1505  av_sha_update(sha, input, 16);
1506  av_sha_update(sha, c->file_key, 16);
1507  av_sha_update(sha, fixed_key, 16);
1508  av_sha_final(sha, c->file_iv);
1509 
1510 fail:
1511  av_free(sha);
1512 
1513  return ret;
1514 }
1515 
1517 {
1518  if (c->audible_key_size != 16) {
1519  av_log(c->fc, AV_LOG_FATAL, "[aaxc] audible_key value needs to be 16 bytes!\n");
1520  return AVERROR(EINVAL);
1521  }
1522 
1523  if (c->audible_iv_size != 16) {
1524  av_log(c->fc, AV_LOG_FATAL, "[aaxc] audible_iv value needs to be 16 bytes!\n");
1525  return AVERROR(EINVAL);
1526  }
1527 
1528  c->aes_decrypt = av_aes_alloc();
1529  if (!c->aes_decrypt) {
1530  return AVERROR(ENOMEM);
1531  }
1532 
1533  memcpy(c->file_key, c->audible_key, 16);
1534  memcpy(c->file_iv, c->audible_iv, 16);
1535  c->aax_mode = 1;
1536 
1537  return 0;
1538 }
1539 
1540 // Audible AAX (and AAX+) bytestream decryption
1541 static int aax_filter(uint8_t *input, int size, MOVContext *c)
1542 {
1543  int blocks = 0;
1544  unsigned char iv[16];
1545 
1546  memcpy(iv, c->file_iv, 16); // iv is overwritten
1547  blocks = size >> 4; // trailing bytes are not encrypted!
1548  av_aes_init(c->aes_decrypt, c->file_key, 128, 1);
1549  av_aes_crypt(c->aes_decrypt, input, input, blocks, iv, 1);
1550 
1551  return 0;
1552 }
1553 
1554 /* read major brand, minor version and compatible brands and store them as metadata */
1556 {
1557  uint32_t minor_ver;
1558  int comp_brand_size;
1559  char* comp_brands_str;
1560  uint8_t type[5] = {0};
1561  int ret = ffio_read_size(pb, type, 4);
1562  if (ret < 0)
1563  return ret;
1564  if (c->fc->nb_streams) {
1565  if (c->fc->strict_std_compliance >= FF_COMPLIANCE_STRICT)
1566  return AVERROR_INVALIDDATA;
1567  av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate FTYP\n");
1568  return 0;
1569  }
1570 
1571  if (strcmp(type, "qt "))
1572  c->isom = 1;
1573  av_log(c->fc, AV_LOG_DEBUG, "ISO: File Type Major Brand: %.4s\n",(char *)&type);
1574  av_dict_set(&c->fc->metadata, "major_brand", type, 0);
1575  minor_ver = avio_rb32(pb); /* minor version */
1576  av_dict_set_int(&c->fc->metadata, "minor_version", minor_ver, 0);
1577 
1578  comp_brand_size = atom.size - 8;
1579  if (comp_brand_size < 0 || comp_brand_size == INT_MAX)
1580  return AVERROR_INVALIDDATA;
1581  comp_brands_str = av_malloc(comp_brand_size + 1); /* Add null terminator */
1582  if (!comp_brands_str)
1583  return AVERROR(ENOMEM);
1584 
1585  ret = ffio_read_size(pb, comp_brands_str, comp_brand_size);
1586  if (ret < 0) {
1587  av_freep(&comp_brands_str);
1588  return ret;
1589  }
1590  comp_brands_str[comp_brand_size] = 0;
1591  av_dict_set(&c->fc->metadata, "compatible_brands",
1592  comp_brands_str, AV_DICT_DONT_STRDUP_VAL);
1593 
1594  // Logic for handling Audible's .aaxc files
1595  if (!strcmp(type, "aaxc")) {
1596  mov_aaxc_crypto(c);
1597  }
1598 
1599  return 0;
1600 }
1601 
1602 /* this atom should contain all header atoms */
1604 {
1605  int ret;
1606 
1607  if (c->found_moov) {
1608  av_log(c->fc, AV_LOG_WARNING, "Found duplicated MOOV Atom. Skipped it\n");
1609  avio_skip(pb, atom.size);
1610  return 0;
1611  }
1612 
1613  if ((ret = mov_read_default(c, pb, atom)) < 0)
1614  return ret;
1615  /* we parsed the 'moov' atom, we can terminate the parsing as soon as we find the 'mdat' */
1616  /* so we don't parse the whole file if over a network */
1617  c->found_moov=1;
1618  return 0; /* now go for mdat */
1619 }
1620 
1622  MOVFragmentIndex *frag_index,
1623  int index,
1624  int id)
1625 {
1626  int i;
1627  MOVFragmentIndexItem * item;
1628 
1629  if (index < 0 || index >= frag_index->nb_items)
1630  return NULL;
1631  item = &frag_index->item[index];
1632  for (i = 0; i < item->nb_stream_info; i++)
1633  if (item->stream_info[i].id == id)
1634  return &item->stream_info[i];
1635 
1636  // This shouldn't happen
1637  return NULL;
1638 }
1639 
1640 static void set_frag_stream(MOVFragmentIndex *frag_index, int id)
1641 {
1642  int i;
1643  MOVFragmentIndexItem * item;
1644 
1645  if (frag_index->current < 0 ||
1646  frag_index->current >= frag_index->nb_items)
1647  return;
1648 
1649  item = &frag_index->item[frag_index->current];
1650  for (i = 0; i < item->nb_stream_info; i++)
1651  if (item->stream_info[i].id == id) {
1652  item->current = i;
1653  return;
1654  }
1655 
1656  // id not found. This shouldn't happen.
1657  item->current = -1;
1658 }
1659 
1661  MOVFragmentIndex *frag_index)
1662 {
1663  MOVFragmentIndexItem *item;
1664  if (frag_index->current < 0 ||
1665  frag_index->current >= frag_index->nb_items)
1666  return NULL;
1667 
1668  item = &frag_index->item[frag_index->current];
1669  if (item->current >= 0 && item->current < item->nb_stream_info)
1670  return &item->stream_info[item->current];
1671 
1672  // This shouldn't happen
1673  return NULL;
1674 }
1675 
1677 {
1678  int a, b, m;
1679  int64_t moof_offset;
1680 
1681  // Optimize for appending new entries
1682  if (!frag_index->nb_items ||
1683  frag_index->item[frag_index->nb_items - 1].moof_offset < offset)
1684  return frag_index->nb_items;
1685 
1686  a = -1;
1687  b = frag_index->nb_items;
1688 
1689  while (b - a > 1) {
1690  m = (a + b) >> 1;
1691  moof_offset = frag_index->item[m].moof_offset;
1692  if (moof_offset >= offset)
1693  b = m;
1694  if (moof_offset <= offset)
1695  a = m;
1696  }
1697  return b;
1698 }
1699 
1701 {
1702  av_assert0(frag_stream_info);
1703  if (frag_stream_info->sidx_pts != AV_NOPTS_VALUE)
1704  return frag_stream_info->sidx_pts;
1705  if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE)
1706  return frag_stream_info->first_tfra_pts;
1707  return frag_stream_info->tfdt_dts;
1708 }
1709 
1711  MOVFragmentIndex *frag_index, int index)
1712 {
1713  MOVFragmentStreamInfo * frag_stream_info;
1714  MOVStreamContext *sc = dst_st->priv_data;
1715  int64_t timestamp;
1716  int i, j;
1717 
1718  // If the stream is referenced by any sidx, limit the search
1719  // to fragments that referenced this stream in the sidx
1720  if (sc->has_sidx) {
1721  frag_stream_info = get_frag_stream_info(frag_index, index, sc->id);
1722  if (!frag_stream_info)
1723  return AV_NOPTS_VALUE;
1724  if (frag_stream_info->sidx_pts != AV_NOPTS_VALUE)
1725  return frag_stream_info->sidx_pts;
1726  if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE)
1727  return frag_stream_info->first_tfra_pts;
1728  return frag_stream_info->sidx_pts;
1729  }
1730 
1731  for (i = 0; i < frag_index->item[index].nb_stream_info; i++) {
1732  if (dst_st->id != frag_index->item[index].stream_info[i].id)
1733  continue;
1734  AVStream *frag_stream = NULL;
1735  frag_stream_info = &frag_index->item[index].stream_info[i];
1736  for (j = 0; j < s->nb_streams; j++) {
1737  MOVStreamContext *sc2 = s->streams[j]->priv_data;
1738  if (sc2->id == frag_stream_info->id)
1739  frag_stream = s->streams[j];
1740  }
1741  if (!frag_stream) {
1742  av_log(s, AV_LOG_WARNING, "No stream matching sidx ID found.\n");
1743  continue;
1744  }
1745  timestamp = get_stream_info_time(frag_stream_info);
1746  if (timestamp != AV_NOPTS_VALUE)
1747  return av_rescale_q(timestamp, frag_stream->time_base, dst_st->time_base);
1748  }
1749  return AV_NOPTS_VALUE;
1750 }
1751 
1753  AVStream *st, int64_t timestamp)
1754 {
1755  int a, b, m, m0;
1756  int64_t frag_time;
1757 
1758  a = -1;
1759  b = frag_index->nb_items;
1760 
1761  while (b - a > 1) {
1762  m0 = m = (a + b) >> 1;
1763 
1764  while (m < b &&
1765  (frag_time = get_frag_time(s, st, frag_index, m)) == AV_NOPTS_VALUE)
1766  m++;
1767 
1768  if (m < b && frag_time <= timestamp)
1769  a = m;
1770  else
1771  b = m0;
1772  }
1773 
1774  return a;
1775 }
1776 
1778 {
1779  int index, i;
1780  MOVFragmentIndexItem * item;
1781  MOVFragmentStreamInfo * frag_stream_info;
1782 
1783  // If moof_offset already exists in frag_index, return index to it
1784  index = search_frag_moof_offset(&c->frag_index, offset);
1785  if (index < c->frag_index.nb_items &&
1786  c->frag_index.item[index].moof_offset == offset)
1787  return index;
1788 
1789  // offset is not yet in frag index.
1790  // Insert new item at index (sorted by moof offset)
1791  item = av_fast_realloc(c->frag_index.item,
1792  &c->frag_index.allocated_size,
1793  (c->frag_index.nb_items + 1) *
1794  sizeof(*c->frag_index.item));
1795  if (!item)
1796  return -1;
1797  c->frag_index.item = item;
1798 
1799  frag_stream_info = av_realloc_array(NULL, c->fc->nb_streams,
1800  sizeof(*item->stream_info));
1801  if (!frag_stream_info)
1802  return -1;
1803 
1804  for (i = 0; i < c->fc->nb_streams; i++) {
1805  // Avoid building frag index if streams lack track id.
1806  MOVStreamContext *sc = c->fc->streams[i]->priv_data;
1807  if (sc->id < 0) {
1808  av_free(frag_stream_info);
1809  return AVERROR_INVALIDDATA;
1810  }
1811 
1812  frag_stream_info[i].id = sc->id;
1813  frag_stream_info[i].sidx_pts = AV_NOPTS_VALUE;
1814  frag_stream_info[i].tfdt_dts = AV_NOPTS_VALUE;
1815  frag_stream_info[i].next_trun_dts = AV_NOPTS_VALUE;
1816  frag_stream_info[i].first_tfra_pts = AV_NOPTS_VALUE;
1817  frag_stream_info[i].index_base = -1;
1818  frag_stream_info[i].index_entry = -1;
1819  frag_stream_info[i].encryption_index = NULL;
1820  frag_stream_info[i].stsd_id = -1;
1821  }
1822 
1823  if (index < c->frag_index.nb_items)
1824  memmove(c->frag_index.item + index + 1, c->frag_index.item + index,
1825  (c->frag_index.nb_items - index) * sizeof(*c->frag_index.item));
1826 
1827  item = &c->frag_index.item[index];
1828  item->headers_read = 0;
1829  item->current = 0;
1830  item->nb_stream_info = c->fc->nb_streams;
1831  item->moof_offset = offset;
1832  item->stream_info = frag_stream_info;
1833  c->frag_index.nb_items++;
1834 
1835  return index;
1836 }
1837 
1838 static void fix_frag_index_entries(MOVFragmentIndex *frag_index, int index,
1839  int id, int entries)
1840 {
1841  int i;
1842  MOVFragmentStreamInfo * frag_stream_info;
1843 
1844  if (index < 0)
1845  return;
1846  for (i = index; i < frag_index->nb_items; i++) {
1847  frag_stream_info = get_frag_stream_info(frag_index, i, id);
1848  if (frag_stream_info && frag_stream_info->index_entry >= 0)
1849  frag_stream_info->index_entry += entries;
1850  }
1851 }
1852 
1854 {
1855  // Set by mov_read_tfhd(). mov_read_trun() will reject files missing tfhd.
1856  c->fragment.found_tfhd = 0;
1857 
1858  if (!c->has_looked_for_mfra && c->use_mfra_for > 0) {
1859  c->has_looked_for_mfra = 1;
1860  if (pb->seekable & AVIO_SEEKABLE_NORMAL) {
1861  int ret;
1862  av_log(c->fc, AV_LOG_VERBOSE, "stream has moof boxes, will look "
1863  "for a mfra\n");
1864  if ((ret = mov_read_mfra(c, pb)) < 0) {
1865  av_log(c->fc, AV_LOG_VERBOSE, "found a moof box but failed to "
1866  "read the mfra (may be a live ismv)\n");
1867  }
1868  } else {
1869  av_log(c->fc, AV_LOG_VERBOSE, "found a moof box but stream is not "
1870  "seekable, can not look for mfra\n");
1871  }
1872  }
1873  c->fragment.moof_offset = c->fragment.implicit_offset = avio_tell(pb) - 8;
1874  av_log(c->fc, AV_LOG_TRACE, "moof offset %"PRIx64"\n", c->fragment.moof_offset);
1875  c->frag_index.current = update_frag_index(c, c->fragment.moof_offset);
1876  return mov_read_default(c, pb, atom);
1877 }
1878 
1880 {
1881  int64_t time;
1882  if (version == 1) {
1883  time = avio_rb64(pb);
1884  avio_rb64(pb);
1885  if (time < 0) {
1886  av_log(c->fc, AV_LOG_DEBUG, "creation_time is negative\n");
1887  return;
1888  }
1889  } else {
1890  time = avio_rb32(pb);
1891  avio_rb32(pb); /* modification time */
1892  if (time > 0 && time < 2082844800) {
1893  av_log(c->fc, AV_LOG_WARNING, "Detected creation time before 1970, parsing as unix timestamp.\n");
1894  time += 2082844800;
1895  }
1896  }
1897  if (time) {
1898  time -= 2082844800; /* seconds between 1904-01-01 and Epoch */
1899 
1900  if ((int64_t)(time * 1000000ULL) / 1000000 != time) {
1901  av_log(c->fc, AV_LOG_DEBUG, "creation_time is not representable\n");
1902  return;
1903  }
1904 
1905  ff_dict_set_timestamp(metadata, "creation_time", time * 1000000);
1906  }
1907 }
1908 
1910 {
1911  AVStream *st;
1912  MOVStreamContext *sc;
1913  int version;
1914  char language[4] = {0};
1915  unsigned lang;
1916 
1917  if (c->fc->nb_streams < 1)
1918  return 0;
1919  st = c->fc->streams[c->fc->nb_streams-1];
1920  sc = st->priv_data;
1921 
1922  if (sc->time_scale) {
1923  av_log(c->fc, AV_LOG_ERROR, "Multiple mdhd?\n");
1924  return AVERROR_INVALIDDATA;
1925  }
1926 
1927  version = avio_r8(pb);
1928  if (version > 1) {
1929  avpriv_request_sample(c->fc, "Version %d", version);
1930  return AVERROR_PATCHWELCOME;
1931  }
1932  avio_rb24(pb); /* flags */
1934 
1935  sc->time_scale = avio_rb32(pb);
1936  if (sc->time_scale <= 0) {
1937  av_log(c->fc, AV_LOG_ERROR, "Invalid mdhd time scale %d, defaulting to 1\n", sc->time_scale);
1938  sc->time_scale = 1;
1939  }
1940  st->duration = (version == 1) ? avio_rb64(pb) : avio_rb32(pb); /* duration */
1941 
1942  if ((version == 1 && st->duration == UINT64_MAX) ||
1943  (version != 1 && st->duration == UINT32_MAX)) {
1944  st->duration = 0;
1945  }
1946 
1947  lang = avio_rb16(pb); /* language */
1948  if (ff_mov_lang_to_iso639(lang, language))
1949  av_dict_set(&st->metadata, "language", language, 0);
1950  avio_rb16(pb); /* quality */
1951 
1952  return 0;
1953 }
1954 
1956 {
1957  int i;
1958  int version = avio_r8(pb); /* version */
1959  avio_rb24(pb); /* flags */
1960 
1961  mov_metadata_creation_time(c, pb, &c->fc->metadata, version);
1962  c->time_scale = avio_rb32(pb); /* time scale */
1963  if (c->time_scale <= 0) {
1964  av_log(c->fc, AV_LOG_ERROR, "Invalid mvhd time scale %d, defaulting to 1\n", c->time_scale);
1965  c->time_scale = 1;
1966  }
1967  av_log(c->fc, AV_LOG_TRACE, "time scale = %i\n", c->time_scale);
1968 
1969  c->duration = (version == 1) ? avio_rb64(pb) : avio_rb32(pb); /* duration */
1970  avio_rb32(pb); /* preferred scale */
1971 
1972  avio_rb16(pb); /* preferred volume */
1973 
1974  avio_skip(pb, 10); /* reserved */
1975 
1976  /* movie display matrix, store it in main context and use it later on */
1977  for (i = 0; i < 3; i++) {
1978  c->movie_display_matrix[i][0] = avio_rb32(pb); // 16.16 fixed point
1979  c->movie_display_matrix[i][1] = avio_rb32(pb); // 16.16 fixed point
1980  c->movie_display_matrix[i][2] = avio_rb32(pb); // 2.30 fixed point
1981  }
1982 
1983  avio_rb32(pb); /* preview time */
1984  avio_rb32(pb); /* preview duration */
1985  avio_rb32(pb); /* poster time */
1986  avio_rb32(pb); /* selection time */
1987  avio_rb32(pb); /* selection duration */
1988  avio_rb32(pb); /* current time */
1989  avio_rb32(pb); /* next track ID */
1990 
1991  return 0;
1992 }
1993 
1995 {
1996  AVStream *st;
1997 
1998  if (fc->nb_streams < 1)
1999  return;
2000  st = fc->streams[fc->nb_streams-1];
2001 
2002  switch (st->codecpar->codec_id) {
2003  case AV_CODEC_ID_PCM_S16BE:
2005  break;
2006  case AV_CODEC_ID_PCM_S24BE:
2008  break;
2009  case AV_CODEC_ID_PCM_S32BE:
2011  break;
2012  case AV_CODEC_ID_PCM_F32BE:
2014  break;
2015  case AV_CODEC_ID_PCM_F64BE:
2017  break;
2018  default:
2019  break;
2020  }
2021 }
2022 
2024 {
2025  int little_endian = avio_rb16(pb) & 0xFF;
2026  av_log(c->fc, AV_LOG_TRACE, "enda %d\n", little_endian);
2027  if (little_endian == 1)
2029  return 0;
2030 }
2031 
2033 {
2034  int format_flags;
2035  int version, flags;
2036  int pcm_sample_size;
2037  AVFormatContext *fc = c->fc;
2038  AVStream *st;
2039  MOVStreamContext *sc;
2040 
2041  if (atom.size < 6) {
2042  av_log(c->fc, AV_LOG_ERROR, "Empty pcmC box\n");
2043  return AVERROR_INVALIDDATA;
2044  }
2045 
2046  version = avio_r8(pb);
2047  flags = avio_rb24(pb);
2048 
2049  if (version != 0 || flags != 0) {
2050  av_log(c->fc, AV_LOG_ERROR,
2051  "Unsupported 'pcmC' box with version %d, flags: %x",
2052  version, flags);
2053  return AVERROR_INVALIDDATA;
2054  }
2055 
2056  format_flags = avio_r8(pb);
2057  pcm_sample_size = avio_r8(pb);
2058 
2059  if (fc->nb_streams < 1)
2060  return AVERROR_INVALIDDATA;
2061 
2062  st = fc->streams[fc->nb_streams - 1];
2063  sc = st->priv_data;
2064 
2065  if (sc->format == MOV_MP4_FPCM_TAG) {
2066  switch (pcm_sample_size) {
2067  case 32:
2069  break;
2070  case 64:
2072  break;
2073  default:
2074  av_log(fc, AV_LOG_ERROR, "invalid pcm_sample_size %d for %s\n",
2075  pcm_sample_size,
2076  av_fourcc2str(sc->format));
2077  return AVERROR_INVALIDDATA;
2078  }
2079  } else if (sc->format == MOV_MP4_IPCM_TAG) {
2080  switch (pcm_sample_size) {
2081  case 16:
2083  break;
2084  case 24:
2086  break;
2087  case 32:
2089  break;
2090  default:
2091  av_log(fc, AV_LOG_ERROR, "invalid pcm_sample_size %d for %s\n",
2092  pcm_sample_size,
2093  av_fourcc2str(sc->format));
2094  return AVERROR_INVALIDDATA;
2095  }
2096  } else {
2097  av_log(fc, AV_LOG_ERROR, "'pcmC' with invalid sample entry '%s'\n",
2098  av_fourcc2str(sc->format));
2099  return AVERROR_INVALIDDATA;
2100  }
2101 
2102  if (format_flags & 1) // indicates little-endian format. If not present, big-endian format is used
2105 
2106  return 0;
2107 }
2108 
2110 {
2111  AVStream *st;
2112  HEIFItem *item = NULL;
2113  char color_parameter_type[5] = { 0 };
2114  uint16_t color_primaries, color_trc, color_matrix;
2115  int ret;
2116 
2117  st = get_curr_st(c);
2118  if (!st) {
2119  item = get_heif_item(c, c->cur_item_id);
2120  if (!item)
2121  return 0;
2122  }
2123 
2124  ret = ffio_read_size(pb, color_parameter_type, 4);
2125  if (ret < 0)
2126  return ret;
2127  if (strncmp(color_parameter_type, "nclx", 4) &&
2128  strncmp(color_parameter_type, "nclc", 4) &&
2129  strncmp(color_parameter_type, "prof", 4)) {
2130  av_log(c->fc, AV_LOG_WARNING, "unsupported color_parameter_type %s\n",
2131  color_parameter_type);
2132  return 0;
2133  }
2134 
2135  if (!strncmp(color_parameter_type, "prof", 4)) {
2136  AVPacketSideData *sd;
2137  uint8_t *icc_profile;
2138  if (st) {
2142  atom.size - 4, 0);
2143  if (!sd)
2144  return AVERROR(ENOMEM);
2145  icc_profile = sd->data;
2146  } else {
2147  av_freep(&item->icc_profile);
2148  icc_profile = item->icc_profile = av_malloc(atom.size - 4);
2149  if (!icc_profile) {
2150  item->icc_profile_size = 0;
2151  return AVERROR(ENOMEM);
2152  }
2153  item->icc_profile_size = atom.size - 4;
2154  }
2155  ret = ffio_read_size(pb, icc_profile, atom.size - 4);
2156  if (ret < 0)
2157  return ret;
2158  } else if (st) {
2159  color_primaries = avio_rb16(pb);
2160  color_trc = avio_rb16(pb);
2161  color_matrix = avio_rb16(pb);
2162 
2163  av_log(c->fc, AV_LOG_TRACE,
2164  "%s: pri %d trc %d matrix %d",
2165  color_parameter_type, color_primaries, color_trc, color_matrix);
2166 
2167  if (!strncmp(color_parameter_type, "nclx", 4)) {
2168  uint8_t color_range = avio_r8(pb) >> 7;
2169  av_log(c->fc, AV_LOG_TRACE, " full %"PRIu8"", color_range);
2170  if (color_range)
2172  else
2174  }
2175 
2178  if (!av_color_transfer_name(color_trc))
2179  color_trc = AVCOL_TRC_UNSPECIFIED;
2180  if (!av_color_space_name(color_matrix))
2181  color_matrix = AVCOL_SPC_UNSPECIFIED;
2182 
2184  st->codecpar->color_trc = color_trc;
2185  st->codecpar->color_space = color_matrix;
2186  av_log(c->fc, AV_LOG_TRACE, "\n");
2187  }
2188  return 0;
2189 }
2190 
2192 {
2193  AVStream *st;
2194  unsigned mov_field_order;
2195  enum AVFieldOrder decoded_field_order = AV_FIELD_UNKNOWN;
2196 
2197  if (c->fc->nb_streams < 1) // will happen with jp2 files
2198  return 0;
2199  st = c->fc->streams[c->fc->nb_streams-1];
2200  if (atom.size < 2)
2201  return AVERROR_INVALIDDATA;
2202  mov_field_order = avio_rb16(pb);
2203  if ((mov_field_order & 0xFF00) == 0x0100)
2204  decoded_field_order = AV_FIELD_PROGRESSIVE;
2205  else if ((mov_field_order & 0xFF00) == 0x0200) {
2206  switch (mov_field_order & 0xFF) {
2207  case 0x01: decoded_field_order = AV_FIELD_TT;
2208  break;
2209  case 0x06: decoded_field_order = AV_FIELD_BB;
2210  break;
2211  case 0x09: decoded_field_order = AV_FIELD_TB;
2212  break;
2213  case 0x0E: decoded_field_order = AV_FIELD_BT;
2214  break;
2215  }
2216  }
2217  if (decoded_field_order == AV_FIELD_UNKNOWN && mov_field_order) {
2218  av_log(c->fc, AV_LOG_ERROR, "Unknown MOV field order 0x%04x\n", mov_field_order);
2219  }
2220  st->codecpar->field_order = decoded_field_order;
2221 
2222  return 0;
2223 }
2224 
2226 {
2227  int err = 0;
2228  uint64_t size = (uint64_t)par->extradata_size + atom.size + 8 + AV_INPUT_BUFFER_PADDING_SIZE;
2229  if (size > INT_MAX || (uint64_t)atom.size > INT_MAX)
2230  return AVERROR_INVALIDDATA;
2231  if ((err = av_reallocp(&par->extradata, size)) < 0) {
2232  par->extradata_size = 0;
2233  return err;
2234  }
2236  return 0;
2237 }
2238 
2239 /* Read a whole atom into the extradata return the size of the atom read, possibly truncated if != atom.size */
2241  AVCodecParameters *par, uint8_t *buf)
2242 {
2243  int64_t result = atom.size;
2244  int err;
2245 
2246  AV_WB32(buf , atom.size + 8);
2247  AV_WL32(buf + 4, atom.type);
2248  err = ffio_read_size(pb, buf + 8, atom.size);
2249  if (err < 0) {
2250  par->extradata_size -= atom.size;
2251  return err;
2252  } else if (err < atom.size) {
2253  av_log(c->fc, AV_LOG_WARNING, "truncated extradata\n");
2254  par->extradata_size -= atom.size - err;
2255  result = err;
2256  }
2257  memset(buf + 8 + err, 0, AV_INPUT_BUFFER_PADDING_SIZE);
2258  return result;
2259 }
2260 
2261 /* FIXME modify QDM2/SVQ3/H.264 decoders to take full atom as extradata */
2263  enum AVCodecID codec_id)
2264 {
2265  AVStream *st;
2266  uint64_t original_size;
2267  int err;
2268 
2269  if (c->fc->nb_streams < 1) // will happen with jp2 files
2270  return 0;
2271  st = c->fc->streams[c->fc->nb_streams-1];
2272 
2273  if (st->codecpar->codec_id != codec_id)
2274  return 0; /* unexpected codec_id - don't mess with extradata */
2275 
2276  original_size = st->codecpar->extradata_size;
2277  err = mov_realloc_extradata(st->codecpar, atom);
2278  if (err)
2279  return err;
2280 
2281  err = mov_read_atom_into_extradata(c, pb, atom, st->codecpar, st->codecpar->extradata + original_size);
2282  if (err < 0)
2283  return err;
2284  return 0; // Note: this is the original behavior to ignore truncation.
2285 }
2286 
2287 /* wrapper functions for reading ALAC/AVS/MJPEG/MJPEG2000 extradata atoms only for those codecs */
2289 {
2290  return mov_read_extradata(c, pb, atom, AV_CODEC_ID_ALAC);
2291 }
2292 
2294 {
2295  return mov_read_extradata(c, pb, atom, AV_CODEC_ID_CAVS);
2296 }
2297 
2299 {
2300  return mov_read_extradata(c, pb, atom, AV_CODEC_ID_JPEG2000);
2301 }
2302 
2304 {
2305  return mov_read_extradata(c, pb, atom, AV_CODEC_ID_R10K);
2306 }
2307 
2309 {
2310  int ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_AVUI);
2311  if (!ret)
2312  ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_DNXHD);
2313  return ret;
2314 }
2315 
2317 {
2318  int ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_TARGA_Y216);
2319 
2320  if (!ret && c->fc->nb_streams >= 1) {
2321  AVCodecParameters *par = c->fc->streams[c->fc->nb_streams-1]->codecpar;
2322  if (par->extradata_size >= 40) {
2323  par->height = AV_RB16(&par->extradata[36]);
2324  par->width = AV_RB16(&par->extradata[38]);
2325  }
2326  }
2327  return ret;
2328 }
2329 
2331 {
2332  if (c->fc->nb_streams >= 1) {
2333  AVStream *const st = c->fc->streams[c->fc->nb_streams - 1];
2334  FFStream *const sti = ffstream(st);
2335  AVCodecParameters *par = st->codecpar;
2336 
2337  if (par->codec_tag == MKTAG('A', 'V', 'i', 'n') &&
2338  par->codec_id == AV_CODEC_ID_H264 &&
2339  atom.size > 11) {
2340  int cid;
2341  avio_skip(pb, 10);
2342  cid = avio_rb16(pb);
2343  /* For AVID AVCI50, force width of 1440 to be able to select the correct SPS and PPS */
2344  if (cid == 0xd4d || cid == 0xd4e)
2345  par->width = 1440;
2346  return 0;
2347  } else if ((par->codec_tag == MKTAG('A', 'V', 'd', '1') ||
2348  par->codec_tag == MKTAG('A', 'V', 'j', '2') ||
2349  par->codec_tag == MKTAG('A', 'V', 'd', 'n')) &&
2350  atom.size >= 24) {
2351  int num, den;
2352  avio_skip(pb, 12);
2353  num = avio_rb32(pb);
2354  den = avio_rb32(pb);
2355  if (num <= 0 || den <= 0)
2356  return 0;
2357  switch (avio_rb32(pb)) {
2358  case 2:
2359  if (den >= INT_MAX / 2)
2360  return 0;
2361  den *= 2;
2362  case 1:
2363  sti->display_aspect_ratio = (AVRational){ num, den };
2364  default:
2365  return 0;
2366  }
2367  }
2368  }
2369 
2370  return mov_read_avid(c, pb, atom);
2371 }
2372 
2374 {
2375  int ret = 0;
2376  int length = 0;
2377  uint64_t original_size;
2378  if (c->fc->nb_streams >= 1) {
2379  AVCodecParameters *par = c->fc->streams[c->fc->nb_streams-1]->codecpar;
2380  if (par->codec_id == AV_CODEC_ID_H264)
2381  return 0;
2382  if (atom.size == 16) {
2383  original_size = par->extradata_size;
2384  ret = mov_realloc_extradata(par, atom);
2385  if (!ret) {
2386  length = mov_read_atom_into_extradata(c, pb, atom, par, par->extradata + original_size);
2387  if (length == atom.size) {
2388  const uint8_t range_value = par->extradata[original_size + 19];
2389  switch (range_value) {
2390  case 1:
2392  break;
2393  case 2:
2395  break;
2396  default:
2397  av_log(c->fc, AV_LOG_WARNING, "ignored unknown aclr value (%d)\n", range_value);
2398  break;
2399  }
2400  ff_dlog(c->fc, "color_range: %d\n", par->color_range);
2401  } else {
2402  /* For some reason the whole atom was not added to the extradata */
2403  av_log(c->fc, AV_LOG_ERROR, "aclr not decoded - incomplete atom\n");
2404  }
2405  } else {
2406  av_log(c->fc, AV_LOG_ERROR, "aclr not decoded - unable to add atom to extradata\n");
2407  }
2408  } else {
2409  av_log(c->fc, AV_LOG_WARNING, "aclr not decoded - unexpected size %"PRId64"\n", atom.size);
2410  }
2411  }
2412 
2413  return ret;
2414 }
2415 
2417 {
2418  return mov_read_extradata(c, pb, atom, AV_CODEC_ID_SVQ3);
2419 }
2420 
2422 {
2423  AVStream *st;
2424  int ret;
2425 
2426  if (c->fc->nb_streams < 1)
2427  return 0;
2428  st = c->fc->streams[c->fc->nb_streams-1];
2429 
2430  if ((uint64_t)atom.size > (1<<30))
2431  return AVERROR_INVALIDDATA;
2432 
2433  if (st->codecpar->codec_id == AV_CODEC_ID_QDM2 ||
2436  // pass all frma atom to codec, needed at least for QDMC and QDM2
2437  ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size);
2438  if (ret < 0)
2439  return ret;
2440  } else if (atom.size > 8) { /* to read frma, esds atoms */
2441  if (st->codecpar->codec_id == AV_CODEC_ID_ALAC && atom.size >= 24) {
2442  uint64_t buffer;
2443  ret = ffio_ensure_seekback(pb, 8);
2444  if (ret < 0)
2445  return ret;
2446  buffer = avio_rb64(pb);
2447  atom.size -= 8;
2448  if ( (buffer & 0xFFFFFFFF) == MKBETAG('f','r','m','a')
2449  && buffer >> 32 <= atom.size
2450  && buffer >> 32 >= 8) {
2451  avio_skip(pb, -8);
2452  atom.size += 8;
2453  } else if (!st->codecpar->extradata_size) {
2454 #define ALAC_EXTRADATA_SIZE 36
2456  if (!st->codecpar->extradata)
2457  return AVERROR(ENOMEM);
2460  AV_WB32(st->codecpar->extradata + 4, MKTAG('a','l','a','c'));
2461  AV_WB64(st->codecpar->extradata + 12, buffer);
2462  avio_read(pb, st->codecpar->extradata + 20, 16);
2463  avio_skip(pb, atom.size - 24);
2464  return 0;
2465  }
2466  }
2467  if ((ret = mov_read_default(c, pb, atom)) < 0)
2468  return ret;
2469  } else
2470  avio_skip(pb, atom.size);
2471  return 0;
2472 }
2473 
2474 /**
2475  * This function reads atom content and puts data in extradata without tag
2476  * nor size unlike mov_read_extradata.
2477  */
2479 {
2480  AVStream *st;
2481  int ret;
2482 
2483  st = get_curr_st(c);
2484  if (!st)
2485  return 0;
2486 
2487  if ((uint64_t)atom.size > (1<<30))
2488  return AVERROR_INVALIDDATA;
2489 
2490  if (atom.type == MKTAG('v','v','c','C')) {
2491  avio_skip(pb, 4);
2492  atom.size -= 4;
2493  }
2494 
2495  if (atom.size >= 10) {
2496  // Broken files created by legacy versions of libavformat will
2497  // wrap a whole fiel atom inside of a glbl atom.
2498  unsigned size = avio_rb32(pb);
2499  unsigned type = avio_rl32(pb);
2500  if (avio_feof(pb))
2501  return AVERROR_INVALIDDATA;
2502  avio_seek(pb, -8, SEEK_CUR);
2503  if (type == MKTAG('f','i','e','l') && size == atom.size)
2504  return mov_read_default(c, pb, atom);
2505  }
2506  if (st->codecpar->extradata_size > 1 && st->codecpar->extradata) {
2507  av_log(c->fc, AV_LOG_WARNING, "ignoring multiple glbl\n");
2508  return 0;
2509  }
2510  ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size);
2511  if (ret < 0)
2512  return ret;
2513  if (atom.type == MKTAG('h','v','c','C') && st->codecpar->codec_tag == MKTAG('d','v','h','1'))
2514  /* HEVC-based Dolby Vision derived from hvc1.
2515  Happens to match with an identifier
2516  previously utilized for DV. Thus, if we have
2517  the hvcC extradata box available as specified,
2518  set codec to HEVC */
2520 
2521  return 0;
2522 }
2523 
2525 {
2526  AVStream *st;
2527  uint8_t profile_level;
2528  int ret;
2529 
2530  if (c->fc->nb_streams < 1)
2531  return 0;
2532  st = c->fc->streams[c->fc->nb_streams-1];
2533 
2534  if (atom.size >= (1<<28) || atom.size < 7)
2535  return AVERROR_INVALIDDATA;
2536 
2537  profile_level = avio_r8(pb);
2538  if ((profile_level & 0xf0) != 0xc0)
2539  return 0;
2540 
2541  avio_seek(pb, 6, SEEK_CUR);
2542  ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size - 7);
2543  if (ret < 0)
2544  return ret;
2545 
2546  return 0;
2547 }
2548 
2550 {
2551  AVStream* st;
2552  MOVStreamContext* sc;
2553 
2554  if (c->fc->nb_streams < 1)
2555  return 0;
2556 
2557  /* For SBAS this should be fine - though beware if someone implements a
2558  * tref atom processor that doesn't drop down to default then this may
2559  * be lost. */
2560  if (atom.size > 4) {
2561  av_log(c->fc, AV_LOG_ERROR, "Only a single tref of type sbas is supported\n");
2562  return AVERROR_PATCHWELCOME;
2563  }
2564 
2565  st = c->fc->streams[c->fc->nb_streams - 1];
2566  sc = st->priv_data;
2567  sc->tref_id = avio_rb32(pb);
2569 
2570  return 0;
2571 }
2572 
2573 /**
2574  * An strf atom is a BITMAPINFOHEADER struct. This struct is 40 bytes itself,
2575  * but can have extradata appended at the end after the 40 bytes belonging
2576  * to the struct.
2577  */
2579 {
2580  AVStream *st;
2581  int ret;
2582 
2583  if (c->fc->nb_streams < 1)
2584  return 0;
2585  if (atom.size <= 40)
2586  return 0;
2587  st = c->fc->streams[c->fc->nb_streams-1];
2588 
2589  if ((uint64_t)atom.size > (1<<30))
2590  return AVERROR_INVALIDDATA;
2591 
2592  avio_skip(pb, 40);
2593  ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size - 40);
2594  if (ret < 0)
2595  return ret;
2596 
2597  return 0;
2598 }
2599 
2601 {
2602  AVStream *st;
2603  MOVStreamContext *sc;
2604  unsigned int i, entries;
2605 
2606  if (c->trak_index < 0) {
2607  av_log(c->fc, AV_LOG_WARNING, "STCO outside TRAK\n");
2608  return 0;
2609  }
2610  if (c->fc->nb_streams < 1)
2611  return 0;
2612  st = c->fc->streams[c->fc->nb_streams-1];
2613  sc = st->priv_data;
2614 
2615  avio_r8(pb); /* version */
2616  avio_rb24(pb); /* flags */
2617 
2618  // Clamp allocation size for `chunk_offsets` -- don't throw an error for an
2619  // invalid count since the EOF path doesn't throw either.
2620  entries = avio_rb32(pb);
2621  entries =
2622  FFMIN(entries,
2623  FFMAX(0, (atom.size - 8) /
2624  (atom.type == MKTAG('s', 't', 'c', 'o') ? 4 : 8)));
2625 
2626  if (!entries)
2627  return 0;
2628 
2629  if (sc->chunk_offsets) {
2630  av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicated STCO atom\n");
2631  return 0;
2632  }
2633 
2634  av_free(sc->chunk_offsets);
2635  sc->chunk_count = 0;
2636  sc->chunk_offsets = av_malloc_array(entries, sizeof(*sc->chunk_offsets));
2637  if (!sc->chunk_offsets)
2638  return AVERROR(ENOMEM);
2639  sc->chunk_count = entries;
2640 
2641  if (atom.type == MKTAG('s','t','c','o'))
2642  for (i = 0; i < entries && !pb->eof_reached; i++)
2643  sc->chunk_offsets[i] = avio_rb32(pb);
2644  else if (atom.type == MKTAG('c','o','6','4'))
2645  for (i = 0; i < entries && !pb->eof_reached; i++) {
2646  sc->chunk_offsets[i] = avio_rb64(pb);
2647  if (sc->chunk_offsets[i] < 0) {
2648  av_log(c->fc, AV_LOG_WARNING, "Impossible chunk_offset\n");
2649  sc->chunk_offsets[i] = 0;
2650  }
2651  }
2652  else
2653  return AVERROR_INVALIDDATA;
2654 
2655  sc->chunk_count = i;
2656 
2657  if (pb->eof_reached) {
2658  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STCO atom\n");
2659  return AVERROR_EOF;
2660  }
2661 
2662  return 0;
2663 }
2664 
2665 static int mov_codec_id(AVStream *st, uint32_t format)
2666 {
2668 
2669  if (id <= 0 &&
2670  ((format & 0xFFFF) == 'm' + ('s' << 8) ||
2671  (format & 0xFFFF) == 'T' + ('S' << 8)))
2673 
2674  if (st->codecpar->codec_type != AVMEDIA_TYPE_VIDEO && id > 0) {
2676  } else if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO &&
2677  /* skip old ASF MPEG-4 tag */
2678  format && format != MKTAG('m','p','4','s')) {
2680  if (id <= 0)
2682  if (id > 0)
2684  else if (st->codecpar->codec_type == AVMEDIA_TYPE_DATA ||
2686  st->codecpar->codec_id == AV_CODEC_ID_NONE)) {
2688  if (id <= 0) {
2690  AV_CODEC_ID_TTML : id;
2691  }
2692 
2693  if (id > 0)
2695  else
2697  }
2698  }
2699 
2700  st->codecpar->codec_tag = format;
2701 
2702  return id;
2703 }
2704 
2706  AVStream *st, MOVStreamContext *sc)
2707 {
2708  uint8_t codec_name[32] = { 0 };
2709  int64_t stsd_start;
2710  unsigned int len;
2711  uint32_t id = 0;
2712 
2713  /* The first 16 bytes of the video sample description are already
2714  * read in ff_mov_read_stsd_entries() */
2715  stsd_start = avio_tell(pb) - 16;
2716 
2717  if (c->isom) {
2718  avio_skip(pb, 2); /* pre_defined */
2719  avio_skip(pb, 2); /* reserved */
2720  avio_skip(pb, 12); /* pre_defined */
2721  } else {
2722  avio_rb16(pb); /* version */
2723  avio_rb16(pb); /* revision level */
2724  id = avio_rl32(pb); /* vendor */
2725  av_dict_set(&st->metadata, "vendor_id", av_fourcc2str(id), 0);
2726  avio_rb32(pb); /* temporal quality */
2727  avio_rb32(pb); /* spatial quality */
2728  }
2729 
2730  st->codecpar->width = avio_rb16(pb); /* width */
2731  st->codecpar->height = avio_rb16(pb); /* height */
2732 
2733  avio_rb32(pb); /* horiz resolution */
2734  avio_rb32(pb); /* vert resolution */
2735  avio_rb32(pb); /* data size, always 0 */
2736  avio_rb16(pb); /* frames per samples */
2737 
2738  len = avio_r8(pb); /* codec name, pascal string */
2739  if (len > 31)
2740  len = 31;
2741  mov_read_mac_string(c, pb, len, codec_name, sizeof(codec_name));
2742  if (len < 31)
2743  avio_skip(pb, 31 - len);
2744 
2745  if (codec_name[0])
2746  av_dict_set(&st->metadata, "encoder", codec_name, 0);
2747 
2748  /* codec_tag YV12 triggers an UV swap in rawdec.c */
2749  if (!strncmp(codec_name, "Planar Y'CbCr 8-bit 4:2:0", 25)) {
2750  st->codecpar->codec_tag = MKTAG('I', '4', '2', '0');
2751  st->codecpar->width &= ~1;
2752  st->codecpar->height &= ~1;
2753  }
2754  /* Flash Media Server uses tag H.263 with Sorenson Spark */
2755  if (st->codecpar->codec_tag == MKTAG('H','2','6','3') &&
2756  !strncmp(codec_name, "Sorenson H263", 13))
2758 
2759  st->codecpar->bits_per_coded_sample = avio_rb16(pb); /* depth */
2760 
2761  avio_seek(pb, stsd_start, SEEK_SET);
2762 
2763  if (ff_get_qtpalette(st->codecpar->codec_id, pb, sc->palette)) {
2764  st->codecpar->bits_per_coded_sample &= 0x1F;
2765  sc->has_palette = 1;
2766  }
2767 }
2768 
2770  AVStream *st, MOVStreamContext *sc)
2771 {
2772  int bits_per_sample, flags;
2773  uint16_t version = avio_rb16(pb);
2774  uint32_t id = 0;
2775  AVDictionaryEntry *compatible_brands = av_dict_get(c->fc->metadata, "compatible_brands", NULL, AV_DICT_MATCH_CASE);
2776  int channel_count;
2777 
2778  if (c->isom)
2779  avio_skip(pb, 6); /* reserved */
2780  else {
2781  avio_rb16(pb); /* revision level */
2782  id = avio_rl32(pb); /* vendor */
2783  av_dict_set(&st->metadata, "vendor_id", av_fourcc2str(id), 0);
2784  }
2785 
2786  channel_count = avio_rb16(pb);
2787 
2789  st->codecpar->ch_layout.nb_channels = channel_count;
2790  st->codecpar->bits_per_coded_sample = avio_rb16(pb); /* sample size */
2791  av_log(c->fc, AV_LOG_TRACE, "audio channels %d\n", channel_count);
2792 
2793  sc->audio_cid = avio_rb16(pb);
2794  avio_rb16(pb); /* packet size = 0 */
2795 
2796  st->codecpar->sample_rate = ((avio_rb32(pb) >> 16));
2797 
2798  // Read QT version 1 fields. In version 0 these do not exist.
2799  av_log(c->fc, AV_LOG_TRACE, "version =%d, isom =%d\n", version, c->isom);
2800  if (!c->isom ||
2801  (compatible_brands && strstr(compatible_brands->value, "qt ")) ||
2802  (sc->stsd_version == 0 && version > 0)) {
2803  if (version == 1) {
2804  sc->samples_per_frame = avio_rb32(pb);
2805  avio_rb32(pb); /* bytes per packet */
2806  sc->bytes_per_frame = avio_rb32(pb);
2807  avio_rb32(pb); /* bytes per sample */
2808  } else if (version == 2) {
2809  avio_rb32(pb); /* sizeof struct only */
2811  channel_count = avio_rb32(pb);
2813  st->codecpar->ch_layout.nb_channels = channel_count;
2814  avio_rb32(pb); /* always 0x7F000000 */
2816 
2817  flags = avio_rb32(pb); /* lpcm format specific flag */
2818  sc->bytes_per_frame = avio_rb32(pb);
2819  sc->samples_per_frame = avio_rb32(pb);
2820  if (st->codecpar->codec_tag == MKTAG('l','p','c','m'))
2821  st->codecpar->codec_id =
2823  flags);
2824  }
2825  if (version == 0 || (version == 1 && sc->audio_cid != -2)) {
2826  /* can't correctly handle variable sized packet as audio unit */
2827  switch (st->codecpar->codec_id) {
2828  case AV_CODEC_ID_MP2:
2829  case AV_CODEC_ID_MP3:
2831  break;
2832  }
2833  }
2834  }
2835 
2836  if (sc->format == 0) {
2837  if (st->codecpar->bits_per_coded_sample == 8)
2838  st->codecpar->codec_id = mov_codec_id(st, MKTAG('r','a','w',' '));
2839  else if (st->codecpar->bits_per_coded_sample == 16)
2840  st->codecpar->codec_id = mov_codec_id(st, MKTAG('t','w','o','s'));
2841  }
2842 
2843  switch (st->codecpar->codec_id) {
2844  case AV_CODEC_ID_PCM_S8:
2845  case AV_CODEC_ID_PCM_U8:
2846  if (st->codecpar->bits_per_coded_sample == 16)
2848  break;
2849  case AV_CODEC_ID_PCM_S16LE:
2850  case AV_CODEC_ID_PCM_S16BE:
2851  if (st->codecpar->bits_per_coded_sample == 8)
2853  else if (st->codecpar->bits_per_coded_sample == 24)
2854  st->codecpar->codec_id =
2857  else if (st->codecpar->bits_per_coded_sample == 32)
2858  st->codecpar->codec_id =
2861  break;
2862  /* set values for old format before stsd version 1 appeared */
2863  case AV_CODEC_ID_MACE3:
2864  sc->samples_per_frame = 6;
2866  break;
2867  case AV_CODEC_ID_MACE6:
2868  sc->samples_per_frame = 6;
2870  break;
2872  sc->samples_per_frame = 64;
2874  break;
2875  case AV_CODEC_ID_GSM:
2876  sc->samples_per_frame = 160;
2877  sc->bytes_per_frame = 33;
2878  break;
2879  default:
2880  break;
2881  }
2882 
2883  bits_per_sample = av_get_bits_per_sample(st->codecpar->codec_id);
2884  if (bits_per_sample && (bits_per_sample >> 3) * (uint64_t)st->codecpar->ch_layout.nb_channels <= INT_MAX) {
2885  st->codecpar->bits_per_coded_sample = bits_per_sample;
2886  sc->sample_size = (bits_per_sample >> 3) * st->codecpar->ch_layout.nb_channels;
2887  }
2888 }
2889 
2891  AVStream *st, MOVStreamContext *sc,
2892  int64_t size)
2893 {
2894  // ttxt stsd contains display flags, justification, background
2895  // color, fonts, and default styles, so fake an atom to read it
2896  MOVAtom fake_atom = { .size = size };
2897  // mp4s contains a regular esds atom, dfxp ISMV TTML has no content
2898  // in extradata unlike stpp MP4 TTML.
2899  if (st->codecpar->codec_tag != AV_RL32("mp4s") &&
2901  mov_read_glbl(c, pb, fake_atom);
2902  st->codecpar->width = sc->width;
2903  st->codecpar->height = sc->height;
2904 }
2905 
2907  AVStream *st, MOVStreamContext *sc,
2908  int64_t size)
2909 {
2910  int ret;
2911 
2912  if (st->codecpar->codec_tag == MKTAG('t','m','c','d')) {
2913  if ((int)size != size)
2914  return AVERROR(ENOMEM);
2915 
2916  ret = ff_get_extradata(c->fc, st->codecpar, pb, size);
2917  if (ret < 0)
2918  return ret;
2919  if (size > 16) {
2920  MOVStreamContext *tmcd_ctx = st->priv_data;
2921  int val;
2922  val = AV_RB32(st->codecpar->extradata + 4);
2923  tmcd_ctx->tmcd_flags = val;
2924  st->avg_frame_rate.num = AV_RB32(st->codecpar->extradata + 8); /* timescale */
2925  st->avg_frame_rate.den = AV_RB32(st->codecpar->extradata + 12); /* frameDuration */
2926  tmcd_ctx->tmcd_nb_frames = st->codecpar->extradata[16]; /* number of frames */
2927  if (size > 30) {
2928  uint32_t len = AV_RB32(st->codecpar->extradata + 18); /* name atom length */
2929  uint32_t format = AV_RB32(st->codecpar->extradata + 22);
2930  if (format == AV_RB32("name") && (int64_t)size >= (int64_t)len + 18) {
2931  uint16_t str_size = AV_RB16(st->codecpar->extradata + 26); /* string length */
2932  if (str_size > 0 && size >= (int)str_size + 30 &&
2933  st->codecpar->extradata[30] /* Don't add empty string */) {
2934  char *reel_name = av_malloc(str_size + 1);
2935  if (!reel_name)
2936  return AVERROR(ENOMEM);
2937  memcpy(reel_name, st->codecpar->extradata + 30, str_size);
2938  reel_name[str_size] = 0; /* Add null terminator */
2939  av_dict_set(&st->metadata, "reel_name", reel_name,
2941  }
2942  }
2943  }
2944  }
2945  } else {
2946  /* other codec type, just skip (rtp, mp4s ...) */
2947  avio_skip(pb, size);
2948  }
2949  return 0;
2950 }
2951 
2953  AVStream *st, MOVStreamContext *sc)
2954 {
2955  FFStream *const sti = ffstream(st);
2956 
2957  if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
2958  !st->codecpar->sample_rate && sc->time_scale > 1)
2959  st->codecpar->sample_rate = sc->time_scale;
2960 
2961  /* special codec parameters handling */
2962  switch (st->codecpar->codec_id) {
2963 #if CONFIG_DV_DEMUXER
2964  case AV_CODEC_ID_DVAUDIO:
2965  if (c->dv_fctx) {
2966  avpriv_request_sample(c->fc, "multiple DV audio streams");
2967  return AVERROR(ENOSYS);
2968  }
2969 
2970  c->dv_fctx = avformat_alloc_context();
2971  if (!c->dv_fctx) {
2972  av_log(c->fc, AV_LOG_ERROR, "dv demux context alloc error\n");
2973  return AVERROR(ENOMEM);
2974  }
2975  c->dv_demux = avpriv_dv_init_demux(c->dv_fctx);
2976  if (!c->dv_demux) {
2977  av_log(c->fc, AV_LOG_ERROR, "dv demux context init error\n");
2978  return AVERROR(ENOMEM);
2979  }
2980  sc->dv_audio_container = 1;
2982  break;
2983 #endif
2984  /* no ifdef since parameters are always those */
2985  case AV_CODEC_ID_QCELP:
2988  // force sample rate for qcelp when not stored in mov
2989  if (st->codecpar->codec_tag != MKTAG('Q','c','l','p'))
2990  st->codecpar->sample_rate = 8000;
2991  // FIXME: Why is the following needed for some files?
2992  sc->samples_per_frame = 160;
2993  if (!sc->bytes_per_frame)
2994  sc->bytes_per_frame = 35;
2995  break;
2996  case AV_CODEC_ID_AMR_NB:
2999  /* force sample rate for amr, stsd in 3gp does not store sample rate */
3000  st->codecpar->sample_rate = 8000;
3001  break;
3002  case AV_CODEC_ID_AMR_WB:
3005  st->codecpar->sample_rate = 16000;
3006  break;
3007  case AV_CODEC_ID_MP2:
3008  case AV_CODEC_ID_MP3:
3009  /* force type after stsd for m1a hdlr */
3011  break;
3012  case AV_CODEC_ID_GSM:
3013  case AV_CODEC_ID_ADPCM_MS:
3015  case AV_CODEC_ID_ILBC:
3016  case AV_CODEC_ID_MACE3:
3017  case AV_CODEC_ID_MACE6:
3018  case AV_CODEC_ID_QDM2:
3020  break;
3021  case AV_CODEC_ID_ALAC:
3022  if (st->codecpar->extradata_size == 36) {
3023  int channel_count = AV_RB8(st->codecpar->extradata + 21);
3024  if (st->codecpar->ch_layout.nb_channels != channel_count) {
3027  st->codecpar->ch_layout.nb_channels = channel_count;
3028  }
3029  st->codecpar->sample_rate = AV_RB32(st->codecpar->extradata + 32);
3030  }
3031  break;
3032  case AV_CODEC_ID_AC3:
3033  case AV_CODEC_ID_EAC3:
3035  case AV_CODEC_ID_VC1:
3036  case AV_CODEC_ID_VP8:
3037  case AV_CODEC_ID_VP9:
3039  break;
3041  case AV_CODEC_ID_PRORES:
3042  case AV_CODEC_ID_APV:
3043  case AV_CODEC_ID_EVC:
3044  case AV_CODEC_ID_AV1:
3045  /* field_order detection of H264 requires parsing */
3046  case AV_CODEC_ID_H264:
3048  break;
3049  default:
3050  break;
3051  }
3052  return 0;
3053 }
3054 
3056  int codec_tag, int format,
3057  int64_t size)
3058 {
3059  if (codec_tag &&
3060  (codec_tag != format &&
3061  // AVID 1:1 samples with differing data format and codec tag exist
3062  (codec_tag != AV_RL32("AV1x") || format != AV_RL32("AVup")) &&
3063  // prores is allowed to have differing data format and codec tag
3064  codec_tag != AV_RL32("apcn") && codec_tag != AV_RL32("apch") &&
3065  // so is dv (sigh)
3066  codec_tag != AV_RL32("dvpp") && codec_tag != AV_RL32("dvcp") &&
3067  (c->fc->video_codec_id ? ff_codec_get_id(ff_codec_movvideo_tags, format) != c->fc->video_codec_id
3068  : codec_tag != MKTAG('j','p','e','g')))) {
3069  /* Multiple fourcc, we skip JPEG. This is not correct, we should
3070  * export it as a separate AVStream but this needs a few changes
3071  * in the MOV demuxer, patch welcome. */
3072 
3073  av_log(c->fc, AV_LOG_WARNING, "multiple fourcc not supported\n");
3074  avio_skip(pb, size);
3075  return 1;
3076  }
3077 
3078  return 0;
3079 }
3080 
3082 {
3083  int ret;
3084 
3085  /* special codec parameters handling */
3086  switch (st->codecpar->codec_id) {
3087  case AV_CODEC_ID_H264:
3088  // done for ai5q, ai52, ai55, ai1q, ai12 and ai15.
3089  if (!st->codecpar->extradata_size && TAG_IS_AVCI(st->codecpar->codec_tag)) {
3091  if (ret < 0)
3092  return ret;
3093  }
3094  break;
3095  default:
3096  break;
3097  }
3098 
3099  return 0;
3100 }
3101 
3103 {
3104  AVStream *st;
3105  MOVStreamContext *sc;
3106  int pseudo_stream_id;
3107 
3108  av_assert0 (c->fc->nb_streams >= 1);
3109  st = c->fc->streams[c->fc->nb_streams-1];
3110  sc = st->priv_data;
3111 
3112  for (pseudo_stream_id = 0;
3113  pseudo_stream_id < entries && !pb->eof_reached;
3114  pseudo_stream_id++) {
3115  //Parsing Sample description table
3116  enum AVCodecID id;
3117  int ret, dref_id = 1;
3118  MOVAtom a = { AV_RL32("stsd") };
3119  int64_t start_pos = avio_tell(pb);
3120  int64_t size = avio_rb32(pb); /* size */
3121  uint32_t format = avio_rl32(pb); /* data format */
3122 
3123  if (size >= 16) {
3124  avio_rb32(pb); /* reserved */
3125  avio_rb16(pb); /* reserved */
3126  dref_id = avio_rb16(pb);
3127  } else if (size <= 7) {
3128  av_log(c->fc, AV_LOG_ERROR,
3129  "invalid size %"PRId64" in stsd\n", size);
3130  return AVERROR_INVALIDDATA;
3131  }
3132 
3134  size - (avio_tell(pb) - start_pos))) {
3135  sc->stsd_count++;
3136  continue;
3137  }
3138 
3139  sc->pseudo_stream_id = st->codecpar->codec_tag ? -1 : pseudo_stream_id;
3140  sc->dref_id= dref_id;
3141  sc->format = format;
3142 
3143  id = mov_codec_id(st, format);
3144 
3145  av_log(c->fc, AV_LOG_TRACE,
3146  "size=%"PRId64" 4CC=%s codec_type=%d\n", size,
3148 
3149  st->codecpar->codec_id = id;
3151  mov_parse_stsd_video(c, pb, st, sc);
3152  } else if (st->codecpar->codec_type==AVMEDIA_TYPE_AUDIO) {
3153  mov_parse_stsd_audio(c, pb, st, sc);
3154  if (st->codecpar->sample_rate < 0) {
3155  av_log(c->fc, AV_LOG_ERROR, "Invalid sample rate %d\n", st->codecpar->sample_rate);
3156  return AVERROR_INVALIDDATA;
3157  }
3158  if (st->codecpar->ch_layout.nb_channels < 0) {
3159  av_log(c->fc, AV_LOG_ERROR, "Invalid channels %d\n", st->codecpar->ch_layout.nb_channels);
3160  return AVERROR_INVALIDDATA;
3161  }
3162  } else if (st->codecpar->codec_type==AVMEDIA_TYPE_SUBTITLE){
3163  mov_parse_stsd_subtitle(c, pb, st, sc,
3164  size - (avio_tell(pb) - start_pos));
3165  } else {
3166  ret = mov_parse_stsd_data(c, pb, st, sc,
3167  size - (avio_tell(pb) - start_pos));
3168  if (ret < 0)
3169  return ret;
3170  }
3171  /* this will read extra atoms at the end (wave, alac, damr, avcC, hvcC, SMI ...) */
3172  a.size = size - (avio_tell(pb) - start_pos);
3173  if (a.size > 8) {
3174  if ((ret = mov_read_default(c, pb, a)) < 0)
3175  return ret;
3176  } else if (a.size > 0)
3177  avio_skip(pb, a.size);
3178 
3179  ret = mov_finalize_stsd_entry(c, st);
3180  if (ret < 0)
3181  return ret;
3182 
3183  if (sc->extradata && st->codecpar->extradata) {
3184  int extra_size = st->codecpar->extradata_size;
3185 
3186  /* Move the current stream extradata to the stream context one. */
3187  sc->extradata_size[pseudo_stream_id] = extra_size;
3188  sc->extradata[pseudo_stream_id] = st->codecpar->extradata;
3189  st->codecpar->extradata = NULL;
3190  st->codecpar->extradata_size = 0;
3191  }
3192  sc->stsd_count++;
3193  }
3194 
3195  if (pb->eof_reached) {
3196  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSD atom\n");
3197  return AVERROR_EOF;
3198  }
3199 
3200  return 0;
3201 }
3202 
3204 {
3205  AVStream *st;
3206  MOVStreamContext *sc;
3207  int ret, entries;
3208 
3209  if (c->fc->nb_streams < 1)
3210  return 0;
3211  st = c->fc->streams[c->fc->nb_streams - 1];
3212  sc = st->priv_data;
3213 
3214  if (sc->extradata) {
3215  av_log(c->fc, AV_LOG_ERROR,
3216  "Duplicate stsd found in this track.\n");
3217  return AVERROR_INVALIDDATA;
3218  }
3219 
3220  sc->stsd_version = avio_r8(pb);
3221  avio_rb24(pb); /* flags */
3222  entries = avio_rb32(pb);
3223 
3224  /* Each entry contains a size (4 bytes) and format (4 bytes). */
3225  if (entries <= 0 || entries > atom.size / 8 || entries > 1024) {
3226  av_log(c->fc, AV_LOG_ERROR, "invalid STSD entries %d\n", entries);
3227  return AVERROR_INVALIDDATA;
3228  }
3229 
3230  /* Prepare space for hosting multiple extradata. */
3231  sc->extradata = av_calloc(entries, sizeof(*sc->extradata));
3232  if (!sc->extradata)
3233  return AVERROR(ENOMEM);
3234 
3235  sc->extradata_size = av_calloc(entries, sizeof(*sc->extradata_size));
3236  if (!sc->extradata_size) {
3237  ret = AVERROR(ENOMEM);
3238  goto fail;
3239  }
3240 
3241  ret = ff_mov_read_stsd_entries(c, pb, entries);
3242  if (ret < 0)
3243  goto fail;
3244 
3245  /* Restore back the primary extradata. */
3246  av_freep(&st->codecpar->extradata);
3247  st->codecpar->extradata_size = sc->extradata_size[0];
3248  if (sc->extradata_size[0]) {
3250  if (!st->codecpar->extradata)
3251  return AVERROR(ENOMEM);
3252  memcpy(st->codecpar->extradata, sc->extradata[0], sc->extradata_size[0]);
3253  }
3254 
3255  return mov_finalize_stsd_codec(c, pb, st, sc);
3256 fail:
3257  if (sc->extradata) {
3258  int j;
3259  for (j = 0; j < sc->stsd_count; j++)
3260  av_freep(&sc->extradata[j]);
3261  }
3262 
3263  sc->stsd_count = 0;
3264  av_freep(&sc->extradata);
3265  av_freep(&sc->extradata_size);
3266  return ret;
3267 }
3268 
3270 {
3271  AVStream *st;
3272  MOVStreamContext *sc;
3273  unsigned int i, entries;
3274 
3275  if (c->trak_index < 0) {
3276  av_log(c->fc, AV_LOG_WARNING, "STSC outside TRAK\n");
3277  return 0;
3278  }
3279 
3280  if (c->fc->nb_streams < 1)
3281  return 0;
3282  st = c->fc->streams[c->fc->nb_streams-1];
3283  sc = st->priv_data;
3284 
3285  avio_r8(pb); /* version */
3286  avio_rb24(pb); /* flags */
3287 
3288  entries = avio_rb32(pb);
3289  if ((uint64_t)entries * 12 + 4 > atom.size)
3290  return AVERROR_INVALIDDATA;
3291 
3292  av_log(c->fc, AV_LOG_TRACE, "track[%u].stsc.entries = %u\n", c->fc->nb_streams - 1, entries);
3293 
3294  if (!entries)
3295  return 0;
3296  if (sc->stsc_data) {
3297  av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicated STSC atom\n");
3298  return 0;
3299  }
3300  av_free(sc->stsc_data);
3301  sc->stsc_count = 0;
3302  sc->stsc_data = av_malloc_array(entries, sizeof(*sc->stsc_data));
3303  if (!sc->stsc_data)
3304  return AVERROR(ENOMEM);
3305 
3306  for (i = 0; i < entries && !pb->eof_reached; i++) {
3307  sc->stsc_data[i].first = avio_rb32(pb);
3308  sc->stsc_data[i].count = avio_rb32(pb);
3309  sc->stsc_data[i].id = avio_rb32(pb);
3310  }
3311 
3312  sc->stsc_count = i;
3313  for (i = sc->stsc_count - 1; i < UINT_MAX; i--) {
3314  int64_t first_min = i + 1;
3315  if ((i+1 < sc->stsc_count && sc->stsc_data[i].first >= sc->stsc_data[i+1].first) ||
3316  (i > 0 && sc->stsc_data[i].first <= sc->stsc_data[i-1].first) ||
3317  sc->stsc_data[i].first < first_min ||
3318  sc->stsc_data[i].count < 1 ||
3319  sc->stsc_data[i].id < 1) {
3320  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);
3321  if (i+1 >= sc->stsc_count) {
3322  if (sc->stsc_data[i].count == 0 && i > 0) {
3323  sc->stsc_count --;
3324  continue;
3325  }
3326  sc->stsc_data[i].first = FFMAX(sc->stsc_data[i].first, first_min);
3327  if (i > 0 && sc->stsc_data[i].first <= sc->stsc_data[i-1].first)
3328  sc->stsc_data[i].first = FFMIN(sc->stsc_data[i-1].first + 1LL, INT_MAX);
3329  sc->stsc_data[i].count = FFMAX(sc->stsc_data[i].count, 1);
3330  sc->stsc_data[i].id = FFMAX(sc->stsc_data[i].id, 1);
3331  continue;
3332  }
3333  av_assert0(sc->stsc_data[i+1].first >= 2);
3334  // We replace this entry by the next valid
3335  sc->stsc_data[i].first = sc->stsc_data[i+1].first - 1;
3336  sc->stsc_data[i].count = sc->stsc_data[i+1].count;
3337  sc->stsc_data[i].id = sc->stsc_data[i+1].id;
3338  }
3339  }
3340 
3341  if (pb->eof_reached) {
3342  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSC atom\n");
3343  return AVERROR_EOF;
3344  }
3345 
3346  return 0;
3347 }
3348 
3349 static inline int mov_stsc_index_valid(unsigned int index, unsigned int count)
3350 {
3351  return index < count - 1;
3352 }
3353 
3354 /* Compute the samples value for the stsc entry at the given index. */
3355 static inline int64_t mov_get_stsc_samples(MOVStreamContext *sc, unsigned int index)
3356 {
3357  int chunk_count;
3358 
3360  chunk_count = sc->stsc_data[index + 1].first - sc->stsc_data[index].first;
3361  else {
3362  // Validation for stsc / stco happens earlier in mov_read_stsc + mov_read_trak.
3364  chunk_count = sc->chunk_count - (sc->stsc_data[index].first - 1);
3365  }
3366 
3367  return sc->stsc_data[index].count * (int64_t)chunk_count;
3368 }
3369 
3371 {
3372  AVStream *st;
3373  MOVStreamContext *sc;
3374  unsigned i, entries;
3375 
3376  if (c->trak_index < 0) {
3377  av_log(c->fc, AV_LOG_WARNING, "STPS outside TRAK\n");
3378  return 0;
3379  }
3380 
3381  if (c->fc->nb_streams < 1)
3382  return 0;
3383  st = c->fc->streams[c->fc->nb_streams-1];
3384  sc = st->priv_data;
3385 
3386  avio_rb32(pb); // version + flags
3387 
3388  entries = avio_rb32(pb);
3389  if (sc->stps_data)
3390  av_log(c->fc, AV_LOG_WARNING, "Duplicated STPS atom\n");
3391  av_free(sc->stps_data);
3392  sc->stps_count = 0;
3393  sc->stps_data = av_malloc_array(entries, sizeof(*sc->stps_data));
3394  if (!sc->stps_data)
3395  return AVERROR(ENOMEM);
3396 
3397  for (i = 0; i < entries && !pb->eof_reached; i++) {
3398  sc->stps_data[i] = avio_rb32(pb);
3399  }
3400 
3401  sc->stps_count = i;
3402 
3403  if (pb->eof_reached) {
3404  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STPS atom\n");
3405  return AVERROR_EOF;
3406  }
3407 
3408  return 0;
3409 }
3410 
3412 {
3413  AVStream *st;
3414  FFStream *sti;
3415  MOVStreamContext *sc;
3416  unsigned int i, entries;
3417 
3418  if (c->trak_index < 0) {
3419  av_log(c->fc, AV_LOG_WARNING, "STSS outside TRAK\n");
3420  return 0;
3421  }
3422 
3423  if (c->fc->nb_streams < 1)
3424  return 0;
3425  st = c->fc->streams[c->fc->nb_streams-1];
3426  sti = ffstream(st);
3427  sc = st->priv_data;
3428 
3429  avio_r8(pb); /* version */
3430  avio_rb24(pb); /* flags */
3431 
3432  entries = avio_rb32(pb);
3433 
3434  av_log(c->fc, AV_LOG_TRACE, "keyframe_count = %u\n", entries);
3435 
3436  if (!entries) {
3437  sc->keyframe_absent = 1;
3438  if (!sti->need_parsing && st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
3440  return 0;
3441  }
3442  if (sc->keyframes)
3443  av_log(c->fc, AV_LOG_WARNING, "Duplicated STSS atom\n");
3444  if (entries >= UINT_MAX / sizeof(int))
3445  return AVERROR_INVALIDDATA;
3446  av_freep(&sc->keyframes);
3447  sc->keyframe_count = 0;
3448  sc->keyframes = av_malloc_array(entries, sizeof(*sc->keyframes));
3449  if (!sc->keyframes)
3450  return AVERROR(ENOMEM);
3451 
3452  for (i = 0; i < entries && !pb->eof_reached; i++) {
3453  sc->keyframes[i] = avio_rb32(pb);
3454  }
3455 
3456  sc->keyframe_count = i;
3457 
3458  if (pb->eof_reached) {
3459  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSS atom\n");
3460  return AVERROR_EOF;
3461  }
3462 
3463  return 0;
3464 }
3465 
3467 {
3468  AVStream *st;
3469  MOVStreamContext *sc;
3470  unsigned int i, entries, sample_size, field_size, num_bytes;
3471  GetBitContext gb;
3472  unsigned char* buf;
3473  int ret;
3474 
3475  if (c->trak_index < 0) {
3476  av_log(c->fc, AV_LOG_WARNING, "STSZ outside TRAK\n");
3477  return 0;
3478  }
3479 
3480  if (c->fc->nb_streams < 1)
3481  return 0;
3482  st = c->fc->streams[c->fc->nb_streams-1];
3483  sc = st->priv_data;
3484 
3485  avio_r8(pb); /* version */
3486  avio_rb24(pb); /* flags */
3487 
3488  if (atom.type == MKTAG('s','t','s','z')) {
3489  sample_size = avio_rb32(pb);
3490  if (!sc->sample_size) /* do not overwrite value computed in stsd */
3491  sc->sample_size = sample_size;
3492  sc->stsz_sample_size = sample_size;
3493  field_size = 32;
3494  } else {
3495  sample_size = 0;
3496  avio_rb24(pb); /* reserved */
3497  field_size = avio_r8(pb);
3498  }
3499  entries = avio_rb32(pb);
3500 
3501  av_log(c->fc, AV_LOG_TRACE, "sample_size = %u sample_count = %u\n", sc->sample_size, entries);
3502 
3503  sc->sample_count = entries;
3504  if (sample_size)
3505  return 0;
3506 
3507  if (field_size != 4 && field_size != 8 && field_size != 16 && field_size != 32) {
3508  av_log(c->fc, AV_LOG_ERROR, "Invalid sample field size %u\n", field_size);
3509  return AVERROR_INVALIDDATA;
3510  }
3511 
3512  if (!entries)
3513  return 0;
3514  if (entries >= (INT_MAX - 4 - 8 * AV_INPUT_BUFFER_PADDING_SIZE) / field_size)
3515  return AVERROR_INVALIDDATA;
3516  if (sc->sample_sizes)
3517  av_log(c->fc, AV_LOG_WARNING, "Duplicated STSZ atom\n");
3518  av_free(sc->sample_sizes);
3519  sc->sample_count = 0;
3520  sc->sample_sizes = av_malloc_array(entries, sizeof(*sc->sample_sizes));
3521  if (!sc->sample_sizes)
3522  return AVERROR(ENOMEM);
3523 
3524  num_bytes = (entries*field_size+4)>>3;
3525 
3526  buf = av_malloc(num_bytes+AV_INPUT_BUFFER_PADDING_SIZE);
3527  if (!buf) {
3528  av_freep(&sc->sample_sizes);
3529  return AVERROR(ENOMEM);
3530  }
3531 
3532  ret = ffio_read_size(pb, buf, num_bytes);
3533  if (ret < 0) {
3534  av_freep(&sc->sample_sizes);
3535  av_free(buf);
3536  av_log(c->fc, AV_LOG_WARNING, "STSZ atom truncated\n");
3537  return 0;
3538  }
3539 
3540  init_get_bits(&gb, buf, 8*num_bytes);
3541 
3542  for (i = 0; i < entries; i++) {
3543  sc->sample_sizes[i] = get_bits_long(&gb, field_size);
3544  if (sc->sample_sizes[i] > INT64_MAX - sc->data_size) {
3545  av_free(buf);
3546  av_log(c->fc, AV_LOG_ERROR, "Sample size overflow in STSZ\n");
3547  return AVERROR_INVALIDDATA;
3548  }
3549  sc->data_size += sc->sample_sizes[i];
3550  }
3551 
3552  sc->sample_count = i;
3553 
3554  av_free(buf);
3555 
3556  return 0;
3557 }
3558 
3560 {
3561  AVStream *st;
3562  MOVStreamContext *sc;
3563  unsigned int i, entries;
3564  int64_t duration = 0;
3565  int64_t total_sample_count = 0;
3566  int64_t current_dts = 0;
3567  int64_t corrected_dts = 0;
3568 
3569  if (c->trak_index < 0) {
3570  av_log(c->fc, AV_LOG_WARNING, "STTS outside TRAK\n");
3571  return 0;
3572  }
3573 
3574  if (c->fc->nb_streams < 1)
3575  return 0;
3576  st = c->fc->streams[c->fc->nb_streams-1];
3577  sc = st->priv_data;
3578 
3579  avio_r8(pb); /* version */
3580  avio_rb24(pb); /* flags */
3581  entries = avio_rb32(pb);
3582 
3583  av_log(c->fc, AV_LOG_TRACE, "track[%u].stts.entries = %u\n",
3584  c->fc->nb_streams-1, entries);
3585 
3586  if (sc->stts_data)
3587  av_log(c->fc, AV_LOG_WARNING, "Duplicated STTS atom\n");
3588  av_freep(&sc->stts_data);
3589  sc->stts_count = 0;
3590  if (entries >= INT_MAX / sizeof(*sc->stts_data))
3591  return AVERROR(ENOMEM);
3592 
3593  for (i = 0; i < entries && !pb->eof_reached; i++) {
3594  unsigned int sample_duration;
3595  unsigned int sample_count;
3596  unsigned int min_entries = FFMIN(FFMAX(i + 1, 1024 * 1024), entries);
3597  MOVStts *stts_data = av_fast_realloc(sc->stts_data, &sc->stts_allocated_size,
3598  min_entries * sizeof(*sc->stts_data));
3599  if (!stts_data) {
3600  av_freep(&sc->stts_data);
3601  sc->stts_count = 0;
3602  return AVERROR(ENOMEM);
3603  }
3604  sc->stts_count = min_entries;
3605  sc->stts_data = stts_data;
3606 
3607  sample_count = avio_rb32(pb);
3608  sample_duration = avio_rb32(pb);
3609 
3610  sc->stts_data[i].count= sample_count;
3611  sc->stts_data[i].duration= sample_duration;
3612 
3613  av_log(c->fc, AV_LOG_TRACE, "sample_count=%u, sample_duration=%u\n",
3614  sample_count, sample_duration);
3615 
3616  /* STTS sample offsets are uint32 but some files store it as int32
3617  * with negative values used to correct DTS delays.
3618  There may be abnormally large values as well. */
3619  if (sample_duration > c->max_stts_delta) {
3620  // assume high delta is a correction if negative when cast as int32
3621  int32_t delta_magnitude = (int32_t)sample_duration;
3622  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",
3623  sample_duration, i, sample_count, st->index);
3624  sc->stts_data[i].duration = 1;
3625  corrected_dts = av_sat_add64(corrected_dts, (delta_magnitude < 0 ? (int64_t)delta_magnitude : 1) * sample_count);
3626  } else {
3627  corrected_dts += sample_duration * (uint64_t)sample_count;
3628  }
3629 
3630  current_dts += sc->stts_data[i].duration * (uint64_t)sample_count;
3631 
3632  if (current_dts > corrected_dts) {
3633  int64_t drift = av_sat_sub64(current_dts, corrected_dts) / FFMAX(sample_count, 1);
3634  uint32_t correction = (sc->stts_data[i].duration > drift) ? drift : sc->stts_data[i].duration - 1;
3635  current_dts -= correction * (uint64_t)sample_count;
3636  sc->stts_data[i].duration -= correction;
3637  }
3638 
3639  duration+=(int64_t)sc->stts_data[i].duration*(uint64_t)sc->stts_data[i].count;
3640  total_sample_count+=sc->stts_data[i].count;
3641  }
3642 
3643  sc->stts_count = i;
3644 
3645  if (duration > 0 &&
3646  duration <= INT64_MAX - sc->duration_for_fps &&
3647  total_sample_count <= INT_MAX - sc->nb_frames_for_fps) {
3648  sc->duration_for_fps += duration;
3649  sc->nb_frames_for_fps += total_sample_count;
3650  }
3651 
3652  if (pb->eof_reached) {
3653  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STTS atom\n");
3654  return AVERROR_EOF;
3655  }
3656 
3657  st->nb_frames= total_sample_count;
3658  if (duration)
3659  st->duration= FFMIN(st->duration, duration);
3660 
3661  // All samples have zero duration. They have higher chance be chose by
3662  // mov_find_next_sample, which leads to seek again and again.
3663  //
3664  // It's AVERROR_INVALIDDATA actually, but such files exist in the wild.
3665  // So only mark data stream as discarded for safety.
3666  if (!duration && sc->stts_count &&
3668  av_log(c->fc, AV_LOG_WARNING,
3669  "All samples in data stream index:id [%d:%d] have zero "
3670  "duration, stream set to be discarded by default. Override "
3671  "using AVStream->discard or -discard for ffmpeg command.\n",
3672  st->index, sc->id);
3673  st->discard = AVDISCARD_ALL;
3674  }
3675  sc->track_end = duration;
3676  return 0;
3677 }
3678 
3680 {
3681  AVStream *st;
3682  MOVStreamContext *sc;
3683  unsigned int i;
3684  int64_t entries;
3685 
3686  if (c->fc->nb_streams < 1)
3687  return 0;
3688  st = c->fc->streams[c->fc->nb_streams - 1];
3689  sc = st->priv_data;
3690 
3691  avio_r8(pb); /* version */
3692  avio_rb24(pb); /* flags */
3693  entries = atom.size - 4;
3694 
3695  av_log(c->fc, AV_LOG_TRACE, "track[%u].sdtp.entries = %" PRId64 "\n",
3696  c->fc->nb_streams - 1, entries);
3697 
3698  if (sc->sdtp_data)
3699  av_log(c->fc, AV_LOG_WARNING, "Duplicated SDTP atom\n");
3700  av_freep(&sc->sdtp_data);
3701  sc->sdtp_count = 0;
3702 
3703  if (entries < 0 || entries > UINT_MAX)
3704  return AVERROR(ERANGE);
3705 
3706  sc->sdtp_data = av_malloc(entries);
3707  if (!sc->sdtp_data)
3708  return AVERROR(ENOMEM);
3709 
3710  for (i = 0; i < entries && !pb->eof_reached; i++)
3711  sc->sdtp_data[i] = avio_r8(pb);
3712  sc->sdtp_count = i;
3713 
3714  return 0;
3715 }
3716 
3717 static void mov_update_dts_shift(MOVStreamContext *sc, int duration, void *logctx)
3718 {
3719  if (duration < 0) {
3720  if (duration == INT_MIN) {
3721  av_log(logctx, AV_LOG_WARNING, "mov_update_dts_shift(): dts_shift set to %d\n", INT_MAX);
3722  duration++;
3723  }
3724  sc->dts_shift = FFMAX(sc->dts_shift, -duration);
3725  }
3726 }
3727 
3729 {
3730  AVStream *st;
3731  MOVStreamContext *sc;
3732  unsigned int i, entries, ctts_count = 0;
3733 
3734  if (c->trak_index < 0) {
3735  av_log(c->fc, AV_LOG_WARNING, "CTTS outside TRAK\n");
3736  return 0;
3737  }
3738 
3739  if (c->fc->nb_streams < 1)
3740  return 0;
3741  st = c->fc->streams[c->fc->nb_streams-1];
3742  sc = st->priv_data;
3743 
3744  avio_r8(pb); /* version */
3745  avio_rb24(pb); /* flags */
3746  entries = avio_rb32(pb);
3747 
3748  av_log(c->fc, AV_LOG_TRACE, "track[%u].ctts.entries = %u\n", c->fc->nb_streams - 1, entries);
3749 
3750  if (!entries)
3751  return 0;
3752  if (entries >= UINT_MAX / sizeof(*sc->ctts_data))
3753  return AVERROR_INVALIDDATA;
3754  av_freep(&sc->ctts_data);
3755  sc->ctts_data = av_fast_realloc(NULL, &sc->ctts_allocated_size, entries * sizeof(*sc->ctts_data));
3756  if (!sc->ctts_data)
3757  return AVERROR(ENOMEM);
3758 
3759  for (i = 0; i < entries && !pb->eof_reached; i++) {
3760  MOVCtts *ctts_data;
3761  const size_t min_size_needed = (ctts_count + 1) * sizeof(MOVCtts);
3762  const size_t requested_size =
3763  min_size_needed > sc->ctts_allocated_size ?
3764  FFMAX(min_size_needed, 2 * sc->ctts_allocated_size) :
3765  min_size_needed;
3766  int count = avio_rb32(pb);
3767  int duration = avio_rb32(pb);
3768 
3769  if (count <= 0) {
3770  av_log(c->fc, AV_LOG_TRACE,
3771  "ignoring CTTS entry with count=%d duration=%d\n",
3772  count, duration);
3773  continue;
3774  }
3775 
3776  if (ctts_count >= UINT_MAX / sizeof(MOVCtts) - 1)
3777  return AVERROR(ENOMEM);
3778 
3779  ctts_data = av_fast_realloc(sc->ctts_data, &sc->ctts_allocated_size, requested_size);
3780 
3781  if (!ctts_data)
3782  return AVERROR(ENOMEM);
3783 
3784  sc->ctts_data = ctts_data;
3785 
3786  ctts_data[ctts_count].count = count;
3787  ctts_data[ctts_count].offset = duration;
3788  ctts_count++;
3789 
3790  av_log(c->fc, AV_LOG_TRACE, "count=%d, duration=%d\n",
3791  count, duration);
3792 
3793  if (i+2<entries)
3794  mov_update_dts_shift(sc, duration, c->fc);
3795  }
3796 
3797  sc->ctts_count = ctts_count;
3798 
3799  if (pb->eof_reached) {
3800  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted CTTS atom\n");
3801  return AVERROR_EOF;
3802  }
3803 
3804  av_log(c->fc, AV_LOG_TRACE, "dts shift %d\n", sc->dts_shift);
3805 
3806  return 0;
3807 }
3808 
3810 {
3811  AVStream *st;
3812  MOVStreamContext *sc;
3813  uint8_t version;
3814  uint32_t grouping_type;
3815  uint32_t default_length;
3816  av_unused uint32_t default_group_description_index;
3817  uint32_t entry_count;
3818 
3819  if (c->fc->nb_streams < 1)
3820  return 0;
3821  st = c->fc->streams[c->fc->nb_streams - 1];
3822  sc = st->priv_data;
3823 
3824  version = avio_r8(pb); /* version */
3825  avio_rb24(pb); /* flags */
3826  grouping_type = avio_rl32(pb);
3827 
3828  /*
3829  * This function only supports "sync" boxes, but the code is able to parse
3830  * other boxes (such as "tscl", "tsas" and "stsa")
3831  */
3832  if (grouping_type != MKTAG('s','y','n','c'))
3833  return 0;
3834 
3835  default_length = version >= 1 ? avio_rb32(pb) : 0;
3836  default_group_description_index = version >= 2 ? avio_rb32(pb) : 0;
3837  entry_count = avio_rb32(pb);
3838 
3839  av_freep(&sc->sgpd_sync);
3840  sc->sgpd_sync_count = entry_count;
3841  sc->sgpd_sync = av_calloc(entry_count, sizeof(*sc->sgpd_sync));
3842  if (!sc->sgpd_sync)
3843  return AVERROR(ENOMEM);
3844 
3845  for (uint32_t i = 0; i < entry_count && !pb->eof_reached; i++) {
3846  uint32_t description_length = default_length;
3847  if (version >= 1 && default_length == 0)
3848  description_length = avio_rb32(pb);
3849  if (grouping_type == MKTAG('s','y','n','c')) {
3850  const uint8_t nal_unit_type = avio_r8(pb) & 0x3f;
3851  sc->sgpd_sync[i] = nal_unit_type;
3852  description_length -= 1;
3853  }
3854  avio_skip(pb, description_length);
3855  }
3856 
3857  if (pb->eof_reached) {
3858  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted SGPD atom\n");
3859  return AVERROR_EOF;
3860  }
3861 
3862  return 0;
3863 }
3864 
3866 {
3867  AVStream *st;
3868  MOVStreamContext *sc;
3869  unsigned int i, entries;
3870  uint8_t version;
3871  uint32_t grouping_type;
3872  MOVSbgp *table, **tablep;
3873  int *table_count;
3874 
3875  if (c->fc->nb_streams < 1)
3876  return 0;
3877  st = c->fc->streams[c->fc->nb_streams-1];
3878  sc = st->priv_data;
3879 
3880  version = avio_r8(pb); /* version */
3881  avio_rb24(pb); /* flags */
3882  grouping_type = avio_rl32(pb);
3883 
3884  if (grouping_type == MKTAG('r','a','p',' ')) {
3885  tablep = &sc->rap_group;
3886  table_count = &sc->rap_group_count;
3887  } else if (grouping_type == MKTAG('s','y','n','c')) {
3888  tablep = &sc->sync_group;
3889  table_count = &sc->sync_group_count;
3890  } else {
3891  return 0;
3892  }
3893 
3894  if (version == 1)
3895  avio_rb32(pb); /* grouping_type_parameter */
3896 
3897  entries = avio_rb32(pb);
3898  if (!entries)
3899  return 0;
3900  if (*tablep)
3901  av_log(c->fc, AV_LOG_WARNING, "Duplicated SBGP %s atom\n", av_fourcc2str(grouping_type));
3902  av_freep(tablep);
3903  table = av_malloc_array(entries, sizeof(*table));
3904  if (!table)
3905  return AVERROR(ENOMEM);
3906  *tablep = table;
3907 
3908  for (i = 0; i < entries && !pb->eof_reached; i++) {
3909  table[i].count = avio_rb32(pb); /* sample_count */
3910  table[i].index = avio_rb32(pb); /* group_description_index */
3911  }
3912 
3913  *table_count = i;
3914 
3915  if (pb->eof_reached) {
3916  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted SBGP atom\n");
3917  return AVERROR_EOF;
3918  }
3919 
3920  return 0;
3921 }
3922 
3923 /**
3924  * Get ith edit list entry (media time, duration).
3925  */
3927  const MOVStreamContext *msc,
3928  unsigned int edit_list_index,
3929  int64_t *edit_list_media_time,
3930  int64_t *edit_list_duration,
3931  int64_t global_timescale)
3932 {
3933  if (edit_list_index == msc->elst_count) {
3934  return 0;
3935  }
3936  *edit_list_media_time = msc->elst_data[edit_list_index].time;
3937  *edit_list_duration = msc->elst_data[edit_list_index].duration;
3938 
3939  /* duration is in global timescale units;convert to msc timescale */
3940  if (global_timescale == 0) {
3941  avpriv_request_sample(mov->fc, "Support for mvhd.timescale = 0 with editlists");
3942  return 0;
3943  }
3944  *edit_list_duration = av_rescale(*edit_list_duration, msc->time_scale,
3945  global_timescale);
3946 
3947  if (*edit_list_duration + (uint64_t)*edit_list_media_time > INT64_MAX)
3948  *edit_list_duration = 0;
3949 
3950  return 1;
3951 }
3952 
3953 /**
3954  * Find the closest previous frame to the timestamp_pts, in e_old index
3955  * entries. Searching for just any frame / just key frames can be controlled by
3956  * last argument 'flag'.
3957  * Note that if ctts_data is not NULL, we will always search for a key frame
3958  * irrespective of the value of 'flag'. If we don't find any keyframe, we will
3959  * return the first frame of the video.
3960  *
3961  * Here the timestamp_pts is considered to be a presentation timestamp and
3962  * the timestamp of index entries are considered to be decoding timestamps.
3963  *
3964  * Returns 0 if successful in finding a frame, else returns -1.
3965  * Places the found index corresponding output arg.
3966  *
3967  * If ctts_old is not NULL, then refines the searched entry by searching
3968  * backwards from the found timestamp, to find the frame with correct PTS.
3969  *
3970  * Places the found ctts_index and ctts_sample in corresponding output args.
3971  */
3973  AVIndexEntry *e_old,
3974  int nb_old,
3975  MOVTimeToSample *tts_data,
3976  int64_t tts_count,
3977  int64_t timestamp_pts,
3978  int flag,
3979  int64_t* index,
3980  int64_t* tts_index,
3981  int64_t* tts_sample)
3982 {
3983  MOVStreamContext *msc = st->priv_data;
3984  FFStream *const sti = ffstream(st);
3985  AVIndexEntry *e_keep = sti->index_entries;
3986  int nb_keep = sti->nb_index_entries;
3987  int64_t i = 0;
3988 
3989  av_assert0(index);
3990 
3991  // If dts_shift > 0, then all the index timestamps will have to be offset by
3992  // at least dts_shift amount to obtain PTS.
3993  // Hence we decrement the searched timestamp_pts by dts_shift to find the closest index element.
3994  if (msc->dts_shift > 0) {
3995  timestamp_pts -= msc->dts_shift;
3996  }
3997 
3998  sti->index_entries = e_old;
3999  sti->nb_index_entries = nb_old;
4000  *index = av_index_search_timestamp(st, timestamp_pts, flag | AVSEEK_FLAG_BACKWARD);
4001 
4002  // Keep going backwards in the index entries until the timestamp is the same.
4003  if (*index >= 0) {
4004  for (i = *index; i > 0 && e_old[i].timestamp == e_old[i - 1].timestamp;
4005  i--) {
4006  if ((flag & AVSEEK_FLAG_ANY) ||
4007  (e_old[i - 1].flags & AVINDEX_KEYFRAME)) {
4008  *index = i - 1;
4009  }
4010  }
4011  }
4012 
4013  // If we have CTTS then refine the search, by searching backwards over PTS
4014  // computed by adding corresponding CTTS durations to index timestamps.
4015  if (msc->ctts_count && *index >= 0) {
4016  av_assert0(tts_index);
4017  av_assert0(tts_sample);
4018  // Find out the ctts_index for the found frame.
4019  *tts_index = 0;
4020  *tts_sample = 0;
4021  for (int64_t index_tts_count = 0; index_tts_count < *index; index_tts_count++) {
4022  if (*tts_index < tts_count) {
4023  (*tts_sample)++;
4024  if (tts_data[*tts_index].count == *tts_sample) {
4025  (*tts_index)++;
4026  *tts_sample = 0;
4027  }
4028  }
4029  }
4030 
4031  while (*index >= 0 && (*tts_index) >= 0 && (*tts_index) < tts_count) {
4032  // Find a "key frame" with PTS <= timestamp_pts (So that we can decode B-frames correctly).
4033  // No need to add dts_shift to the timestamp here because timestamp_pts has already been
4034  // compensated by dts_shift above.
4035  if ((e_old[*index].timestamp + tts_data[*tts_index].offset) <= timestamp_pts &&
4036  (e_old[*index].flags & AVINDEX_KEYFRAME)) {
4037  break;
4038  }
4039 
4040  (*index)--;
4041  if (*tts_sample == 0) {
4042  (*tts_index)--;
4043  if (*tts_index >= 0)
4044  *tts_sample = tts_data[*tts_index].count - 1;
4045  } else {
4046  (*tts_sample)--;
4047  }
4048  }
4049  }
4050 
4051  /* restore AVStream state*/
4052  sti->index_entries = e_keep;
4053  sti->nb_index_entries = nb_keep;
4054  return *index >= 0 ? 0 : -1;
4055 }
4056 
4057 /**
4058  * Add index entry with the given values, to the end of ffstream(st)->index_entries.
4059  * Returns the new size ffstream(st)->index_entries if successful, else returns -1.
4060  *
4061  * This function is similar to ff_add_index_entry in libavformat/utils.c
4062  * except that here we are always unconditionally adding an index entry to
4063  * the end, instead of searching the entries list and skipping the add if
4064  * there is an existing entry with the same timestamp.
4065  * This is needed because the mov_fix_index calls this func with the same
4066  * unincremented timestamp for successive discarded frames.
4067  */
4069  int size, int distance, int flags)
4070 {
4071  FFStream *const sti = ffstream(st);
4072  AVIndexEntry *entries, *ie;
4073  int64_t index = -1;
4074  const size_t min_size_needed = (sti->nb_index_entries + 1) * sizeof(AVIndexEntry);
4075 
4076  // Double the allocation each time, to lower memory fragmentation.
4077  // Another difference from ff_add_index_entry function.
4078  const size_t requested_size =
4079  min_size_needed > sti->index_entries_allocated_size ?
4080  FFMAX(min_size_needed, 2 * sti->index_entries_allocated_size) :
4081  min_size_needed;
4082 
4083  if (sti->nb_index_entries + 1U >= UINT_MAX / sizeof(AVIndexEntry))
4084  return -1;
4085 
4086  entries = av_fast_realloc(sti->index_entries,
4088  requested_size);
4089  if (!entries)
4090  return -1;
4091 
4092  sti->index_entries = entries;
4093 
4094  index = sti->nb_index_entries++;
4095  ie= &entries[index];
4096 
4097  ie->pos = pos;
4098  ie->timestamp = timestamp;
4099  ie->min_distance= distance;
4100  ie->size= size;
4101  ie->flags = flags;
4102  return index;
4103 }
4104 
4105 /**
4106  * Rewrite timestamps of index entries in the range [end_index - frame_duration_buffer_size, end_index)
4107  * by subtracting end_ts successively by the amounts given in frame_duration_buffer.
4108  */
4109 static void fix_index_entry_timestamps(AVStream* st, int end_index, int64_t end_ts,
4110  int64_t* frame_duration_buffer,
4111  int frame_duration_buffer_size) {
4112  FFStream *const sti = ffstream(st);
4113  int i = 0;
4114  av_assert0(end_index >= 0 && end_index <= sti->nb_index_entries);
4115  for (i = 0; i < frame_duration_buffer_size; i++) {
4116  end_ts -= frame_duration_buffer[frame_duration_buffer_size - 1 - i];
4117  sti->index_entries[end_index - 1 - i].timestamp = end_ts;
4118  }
4119 }
4120 
4121 static int add_tts_entry(MOVTimeToSample **tts_data, unsigned int *tts_count, unsigned int *allocated_size,
4122  int count, int offset, unsigned int duration)
4123 {
4124  MOVTimeToSample *tts_buf_new;
4125  const size_t min_size_needed = (*tts_count + 1) * sizeof(MOVTimeToSample);
4126  const size_t requested_size =
4127  min_size_needed > *allocated_size ?
4128  FFMAX(min_size_needed, 2 * (*allocated_size)) :
4129  min_size_needed;
4130 
4131  if ((unsigned)(*tts_count) >= UINT_MAX / sizeof(MOVTimeToSample) - 1)
4132  return -1;
4133 
4134  tts_buf_new = av_fast_realloc(*tts_data, allocated_size, requested_size);
4135 
4136  if (!tts_buf_new)
4137  return -1;
4138 
4139  *tts_data = tts_buf_new;
4140 
4141  tts_buf_new[*tts_count].count = count;
4142  tts_buf_new[*tts_count].offset = offset;
4143  tts_buf_new[*tts_count].duration = duration;
4144 
4145  *tts_count = (*tts_count) + 1;
4146  return 0;
4147 }
4148 
4149 #define MAX_REORDER_DELAY 16
4151 {
4152  MOVStreamContext *msc = st->priv_data;
4153  FFStream *const sti = ffstream(st);
4154  int ctts_ind = 0;
4155  int ctts_sample = 0;
4156  int64_t pts_buf[MAX_REORDER_DELAY + 1]; // Circular buffer to sort pts.
4157  int buf_start = 0;
4158  int j, r, num_swaps;
4159 
4160  for (j = 0; j < MAX_REORDER_DELAY + 1; j++)
4161  pts_buf[j] = INT64_MIN;
4162 
4163  if (st->codecpar->video_delay <= 0 && msc->ctts_count &&
4165  st->codecpar->video_delay = 0;
4166  for (int ind = 0; ind < sti->nb_index_entries && ctts_ind < msc->tts_count; ++ind) {
4167  // Point j to the last elem of the buffer and insert the current pts there.
4168  j = buf_start;
4169  buf_start = (buf_start + 1);
4170  if (buf_start == MAX_REORDER_DELAY + 1)
4171  buf_start = 0;
4172 
4173  pts_buf[j] = sti->index_entries[ind].timestamp + msc->tts_data[ctts_ind].offset;
4174 
4175  // The timestamps that are already in the sorted buffer, and are greater than the
4176  // current pts, are exactly the timestamps that need to be buffered to output PTS
4177  // in correct sorted order.
4178  // Hence the video delay (which is the buffer size used to sort DTS and output PTS),
4179  // can be computed as the maximum no. of swaps any particular timestamp needs to
4180  // go through, to keep this buffer in sorted order.
4181  num_swaps = 0;
4182  while (j != buf_start) {
4183  r = j - 1;
4184  if (r < 0) r = MAX_REORDER_DELAY;
4185  if (pts_buf[j] < pts_buf[r]) {
4186  FFSWAP(int64_t, pts_buf[j], pts_buf[r]);
4187  ++num_swaps;
4188  } else {
4189  break;
4190  }
4191  j = r;
4192  }
4193  st->codecpar->video_delay = FFMAX(st->codecpar->video_delay, num_swaps);
4194 
4195  ctts_sample++;
4196  if (ctts_sample == msc->tts_data[ctts_ind].count) {
4197  ctts_ind++;
4198  ctts_sample = 0;
4199  }
4200  }
4201  av_log(c->fc, AV_LOG_DEBUG, "Setting codecpar->delay to %d for stream st: %d\n",
4202  st->codecpar->video_delay, st->index);
4203  }
4204 }
4205 
4207 {
4208  sc->current_sample++;
4209  sc->current_index++;
4210  if (sc->index_ranges &&
4211  sc->current_index >= sc->current_index_range->end &&
4212  sc->current_index_range->end) {
4213  sc->current_index_range++;
4215  }
4216 }
4217 
4219 {
4220  sc->current_sample--;
4221  sc->current_index--;
4222  if (sc->index_ranges &&
4224  sc->current_index_range > sc->index_ranges) {
4225  sc->current_index_range--;
4226  sc->current_index = sc->current_index_range->end - 1;
4227  }
4228 }
4229 
4230 static void mov_current_sample_set(MOVStreamContext *sc, int current_sample)
4231 {
4232  int64_t range_size;
4233 
4234  sc->current_sample = current_sample;
4235  sc->current_index = current_sample;
4236  if (!sc->index_ranges) {
4237  return;
4238  }
4239 
4240  for (sc->current_index_range = sc->index_ranges;
4241  sc->current_index_range->end;
4242  sc->current_index_range++) {
4243  range_size = sc->current_index_range->end - sc->current_index_range->start;
4244  if (range_size > current_sample) {
4245  sc->current_index = sc->current_index_range->start + current_sample;
4246  break;
4247  }
4248  current_sample -= range_size;
4249  }
4250 }
4251 
4252 /**
4253  * Fix ffstream(st)->index_entries, so that it contains only the entries (and the entries
4254  * which are needed to decode them) that fall in the edit list time ranges.
4255  * Also fixes the timestamps of the index entries to match the timeline
4256  * specified the edit lists.
4257  */
4258 static void mov_fix_index(MOVContext *mov, AVStream *st)
4259 {
4260  MOVStreamContext *msc = st->priv_data;
4261  FFStream *const sti = ffstream(st);
4262  AVIndexEntry *e_old = sti->index_entries;
4263  int nb_old = sti->nb_index_entries;
4264  const AVIndexEntry *e_old_end = e_old + nb_old;
4265  const AVIndexEntry *current = NULL;
4266  MOVTimeToSample *tts_data_old = msc->tts_data;
4267  int64_t tts_index_old = 0;
4268  int64_t tts_sample_old = 0;
4269  int64_t tts_count_old = msc->tts_count;
4270  int64_t edit_list_media_time = 0;
4271  int64_t edit_list_duration = 0;
4272  int64_t frame_duration = 0;
4273  int64_t edit_list_dts_counter = 0;
4274  int64_t edit_list_dts_entry_end = 0;
4275  int64_t edit_list_start_tts_sample = 0;
4276  int64_t curr_cts;
4277  int64_t curr_ctts = 0;
4278  int64_t empty_edits_sum_duration = 0;
4279  int64_t edit_list_index = 0;
4280  int64_t index;
4281  int flags;
4282  int64_t start_dts = 0;
4283  int64_t edit_list_start_encountered = 0;
4284  int64_t search_timestamp = 0;
4285  int64_t* frame_duration_buffer = NULL;
4286  int num_discarded_begin = 0;
4287  int first_non_zero_audio_edit = -1;
4288  int packet_skip_samples = 0;
4289  MOVIndexRange *current_index_range = NULL;
4290  int found_keyframe_after_edit = 0;
4291  int found_non_empty_edit = 0;
4292 
4293  if (!msc->elst_data || msc->elst_count <= 0 || nb_old <= 0) {
4294  return;
4295  }
4296 
4297  // allocate the index ranges array
4298  msc->index_ranges = av_malloc_array(msc->elst_count + 1,
4299  sizeof(msc->index_ranges[0]));
4300  if (!msc->index_ranges) {
4301  av_log(mov->fc, AV_LOG_ERROR, "Cannot allocate index ranges buffer\n");
4302  return;
4303  }
4304  msc->current_index_range = msc->index_ranges;
4305 
4306  // Clean AVStream from traces of old index
4307  sti->index_entries = NULL;
4309  sti->nb_index_entries = 0;
4310 
4311  // Clean time to sample fields of MOVStreamContext
4312  msc->tts_data = NULL;
4313  msc->tts_count = 0;
4314  msc->tts_index = 0;
4315  msc->tts_sample = 0;
4316  msc->tts_allocated_size = 0;
4317 
4318  // Reinitialize min_corrected_pts so that it can be computed again.
4319  msc->min_corrected_pts = -1;
4320 
4321  // If the dts_shift is positive (in case of negative ctts values in mov),
4322  // then negate the DTS by dts_shift
4323  if (msc->dts_shift > 0) {
4324  edit_list_dts_entry_end -= msc->dts_shift;
4325  av_log(mov->fc, AV_LOG_DEBUG, "Shifting DTS by %d because of negative CTTS.\n", msc->dts_shift);
4326  }
4327 
4328  start_dts = edit_list_dts_entry_end;
4329 
4330  while (get_edit_list_entry(mov, msc, edit_list_index, &edit_list_media_time,
4331  &edit_list_duration, mov->time_scale)) {
4332  av_log(mov->fc, AV_LOG_DEBUG, "Processing st: %d, edit list %"PRId64" - media time: %"PRId64", duration: %"PRId64"\n",
4333  st->index, edit_list_index, edit_list_media_time, edit_list_duration);
4334  edit_list_index++;
4335  edit_list_dts_counter = edit_list_dts_entry_end;
4336  edit_list_dts_entry_end = av_sat_add64(edit_list_dts_entry_end, edit_list_duration);
4337  if (edit_list_dts_entry_end == INT64_MAX) {
4338  av_log(mov->fc, AV_LOG_ERROR, "Cannot calculate dts entry length with duration %"PRId64"\n",
4339  edit_list_duration);
4340  break;
4341  }
4342  num_discarded_begin = 0;
4343  if (!found_non_empty_edit && edit_list_media_time == -1) {
4344  empty_edits_sum_duration += edit_list_duration;
4345  continue;
4346  }
4347  found_non_empty_edit = 1;
4348 
4349  // If we encounter a non-negative edit list reset the skip_samples/start_pad fields and set them
4350  // according to the edit list below.
4351  if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
4352  if (first_non_zero_audio_edit < 0) {
4353  first_non_zero_audio_edit = 1;
4354  } else {
4355  first_non_zero_audio_edit = 0;
4356  }
4357 
4358  if (first_non_zero_audio_edit > 0)
4359  sti->skip_samples = msc->start_pad = 0;
4360  }
4361 
4362  // While reordering frame index according to edit list we must handle properly
4363  // the scenario when edit list entry starts from none key frame.
4364  // We find closest previous key frame and preserve it and consequent frames in index.
4365  // All frames which are outside edit list entry time boundaries will be dropped after decoding.
4366  search_timestamp = edit_list_media_time;
4367  if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
4368  // Audio decoders like AAC need need a decoder delay samples previous to the current sample,
4369  // to correctly decode this frame. Hence for audio we seek to a frame 1 sec. before the
4370  // edit_list_media_time to cover the decoder delay.
4371  search_timestamp = FFMAX(search_timestamp - msc->time_scale, e_old[0].timestamp);
4372  }
4373 
4374  if (find_prev_closest_index(st, e_old, nb_old, tts_data_old, tts_count_old, search_timestamp, 0,
4375  &index, &tts_index_old, &tts_sample_old) < 0) {
4376  av_log(mov->fc, AV_LOG_WARNING,
4377  "st: %d edit list: %"PRId64" Missing key frame while searching for timestamp: %"PRId64"\n",
4378  st->index, edit_list_index, search_timestamp);
4379  if (find_prev_closest_index(st, e_old, nb_old, tts_data_old, tts_count_old, search_timestamp, AVSEEK_FLAG_ANY,
4380  &index, &tts_index_old, &tts_sample_old) < 0) {
4381  av_log(mov->fc, AV_LOG_WARNING,
4382  "st: %d edit list %"PRId64" Cannot find an index entry before timestamp: %"PRId64".\n",
4383  st->index, edit_list_index, search_timestamp);
4384  index = 0;
4385  tts_index_old = 0;
4386  tts_sample_old = 0;
4387  }
4388  }
4389  current = e_old + index;
4390  edit_list_start_tts_sample = tts_sample_old;
4391 
4392  // Iterate over index and arrange it according to edit list
4393  edit_list_start_encountered = 0;
4394  found_keyframe_after_edit = 0;
4395  for (; current < e_old_end; current++, index++) {
4396  // check if frame outside edit list mark it for discard
4397  frame_duration = (current + 1 < e_old_end) ?
4398  ((current + 1)->timestamp - current->timestamp) : edit_list_duration;
4399 
4400  flags = current->flags;
4401 
4402  // frames (pts) before or after edit list
4403  curr_cts = current->timestamp + msc->dts_shift;
4404  curr_ctts = 0;
4405 
4406  if (tts_data_old && tts_index_old < tts_count_old) {
4407  curr_ctts = tts_data_old[tts_index_old].offset;
4408  av_log(mov->fc, AV_LOG_TRACE, "stts: %"PRId64" ctts: %"PRId64", tts_index: %"PRId64", tts_count: %"PRId64"\n",
4409  curr_cts, curr_ctts, tts_index_old, tts_count_old);
4410  curr_cts += curr_ctts;
4411  tts_sample_old++;
4412  if (tts_sample_old == tts_data_old[tts_index_old].count) {
4413  if (add_tts_entry(&msc->tts_data, &msc->tts_count,
4414  &msc->tts_allocated_size,
4415  tts_data_old[tts_index_old].count - edit_list_start_tts_sample,
4416  tts_data_old[tts_index_old].offset, tts_data_old[tts_index_old].duration) == -1) {
4417  av_log(mov->fc, AV_LOG_ERROR, "Cannot add Time To Sample entry %"PRId64" - {%"PRId64", %d}\n",
4418  tts_index_old,
4419  tts_data_old[tts_index_old].count - edit_list_start_tts_sample,
4420  tts_data_old[tts_index_old].offset);
4421  break;
4422  }
4423  tts_index_old++;
4424  tts_sample_old = 0;
4425  edit_list_start_tts_sample = 0;
4426  }
4427  }
4428 
4429  if (curr_cts < edit_list_media_time || curr_cts >= (edit_list_duration + edit_list_media_time)) {
4431  curr_cts < edit_list_media_time && curr_cts + frame_duration > edit_list_media_time &&
4432  first_non_zero_audio_edit > 0) {
4433  packet_skip_samples = edit_list_media_time - curr_cts;
4434  sti->skip_samples += packet_skip_samples;
4435 
4436  // Shift the index entry timestamp by packet_skip_samples to be correct.
4437  edit_list_dts_counter -= packet_skip_samples;
4438  if (edit_list_start_encountered == 0) {
4439  edit_list_start_encountered = 1;
4440  // Make timestamps strictly monotonically increasing for audio, by rewriting timestamps for
4441  // discarded packets.
4442  if (frame_duration_buffer) {
4443  fix_index_entry_timestamps(st, sti->nb_index_entries, edit_list_dts_counter,
4444  frame_duration_buffer, num_discarded_begin);
4445  av_freep(&frame_duration_buffer);
4446  }
4447  }
4448 
4449  av_log(mov->fc, AV_LOG_DEBUG, "skip %d audio samples from curr_cts: %"PRId64"\n", packet_skip_samples, curr_cts);
4450  } else {
4452  av_log(mov->fc, AV_LOG_DEBUG, "drop a frame at curr_cts: %"PRId64" @ %"PRId64"\n", curr_cts, index);
4453 
4454  if (edit_list_start_encountered == 0) {
4455  num_discarded_begin++;
4456  frame_duration_buffer = av_realloc(frame_duration_buffer,
4457  num_discarded_begin * sizeof(int64_t));
4458  if (!frame_duration_buffer) {
4459  av_log(mov->fc, AV_LOG_ERROR, "Cannot reallocate frame duration buffer\n");
4460  break;
4461  }
4462  frame_duration_buffer[num_discarded_begin - 1] = frame_duration;
4463 
4464  // Increment skip_samples for the first non-zero audio edit list
4465  if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
4466  first_non_zero_audio_edit > 0 && st->codecpar->codec_id != AV_CODEC_ID_VORBIS) {
4467  sti->skip_samples += frame_duration;
4468  }
4469  }
4470  }
4471  } else {
4472  if (msc->min_corrected_pts < 0) {
4473  msc->min_corrected_pts = edit_list_dts_counter + curr_ctts + msc->dts_shift;
4474  } else {
4475  msc->min_corrected_pts = FFMIN(msc->min_corrected_pts, edit_list_dts_counter + curr_ctts + msc->dts_shift);
4476  }
4477  if (edit_list_start_encountered == 0) {
4478  edit_list_start_encountered = 1;
4479  // Make timestamps strictly monotonically increasing by rewriting timestamps for
4480  // discarded packets.
4481  if (frame_duration_buffer) {
4482  fix_index_entry_timestamps(st, sti->nb_index_entries, edit_list_dts_counter,
4483  frame_duration_buffer, num_discarded_begin);
4484  av_freep(&frame_duration_buffer);
4485  }
4486  }
4487  }
4488 
4489  if (add_index_entry(st, current->pos, edit_list_dts_counter, current->size,
4490  current->min_distance, flags) == -1) {
4491  av_log(mov->fc, AV_LOG_ERROR, "Cannot add index entry\n");
4492  break;
4493  }
4494 
4495  // Update the index ranges array
4496  if (!current_index_range || index != current_index_range->end) {
4497  current_index_range = current_index_range ? current_index_range + 1
4498  : msc->index_ranges;
4499  current_index_range->start = index;
4500  }
4501  current_index_range->end = index + 1;
4502 
4503  // Only start incrementing DTS in frame_duration amounts, when we encounter a frame in edit list.
4504  if (edit_list_start_encountered > 0) {
4505  edit_list_dts_counter = edit_list_dts_counter + frame_duration;
4506  }
4507 
4508  // Break when found first key frame after edit entry completion
4509  if ((curr_cts + frame_duration >= (edit_list_duration + edit_list_media_time)) &&
4511  if (msc->ctts_count) {
4512  // If we have CTTS and this is the first keyframe after edit elist,
4513  // wait for one more, because there might be trailing B-frames after this I-frame
4514  // that do belong to the edit.
4515  if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO && found_keyframe_after_edit == 0) {
4516  found_keyframe_after_edit = 1;
4517  continue;
4518  }
4519  if (tts_sample_old != 0) {
4520  if (add_tts_entry(&msc->tts_data, &msc->tts_count,
4521  &msc->tts_allocated_size,
4522  tts_sample_old - edit_list_start_tts_sample,
4523  tts_data_old[tts_index_old].offset, tts_data_old[tts_index_old].duration) == -1) {
4524  av_log(mov->fc, AV_LOG_ERROR, "Cannot add Time To Sample entry %"PRId64" - {%"PRId64", %d}\n",
4525  tts_index_old, tts_sample_old - edit_list_start_tts_sample,
4526  tts_data_old[tts_index_old].offset);
4527  break;
4528  }
4529  }
4530  }
4531  break;
4532  }
4533  }
4534  }
4535  // If there are empty edits, then msc->min_corrected_pts might be positive
4536  // intentionally. So we subtract the sum duration of empty edits here.
4537  msc->min_corrected_pts -= empty_edits_sum_duration;
4538 
4539  // If the minimum pts turns out to be greater than zero after fixing the index, then we subtract the
4540  // dts by that amount to make the first pts zero.
4541  if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
4542  if (msc->min_corrected_pts > 0) {
4543  av_log(mov->fc, AV_LOG_DEBUG, "Offset DTS by %"PRId64" to make first pts zero.\n", msc->min_corrected_pts);
4544  for (int i = 0; i < sti->nb_index_entries; ++i)
4546  }
4547  }
4548  // Start time should be equal to zero or the duration of any empty edits.
4549  st->start_time = empty_edits_sum_duration;
4550 
4551  // Update av stream length, if it ends up shorter than the track's media duration
4552  st->duration = FFMIN(st->duration, edit_list_dts_entry_end - start_dts);
4553  msc->start_pad = sti->skip_samples;
4554 
4555  // Free the old index and the old CTTS structures
4556  av_free(e_old);
4557  av_free(tts_data_old);
4558  av_freep(&frame_duration_buffer);
4559 
4560  // Null terminate the index ranges array
4561  current_index_range = current_index_range ? current_index_range + 1
4562  : msc->index_ranges;
4563  current_index_range->start = 0;
4564  current_index_range->end = 0;
4565  msc->current_index = msc->index_ranges[0].start;
4566 }
4567 
4568 static uint32_t get_sgpd_sync_index(const MOVStreamContext *sc, int nal_unit_type)
4569 {
4570  for (uint32_t i = 0; i < sc->sgpd_sync_count; i++)
4571  if (sc->sgpd_sync[i] == nal_unit_type)
4572  return i + 1;
4573  return 0;
4574 }
4575 
4577 {
4578  int k;
4579  int sample_id = 0;
4580  uint32_t cra_index;
4581  MOVStreamContext *sc = st->priv_data;
4582 
4583  if (st->codecpar->codec_id != AV_CODEC_ID_HEVC || !sc->sync_group_count)
4584  return 0;
4585 
4586  /* Build an unrolled index of the samples */
4587  sc->sample_offsets_count = 0;
4588  for (uint32_t i = 0; i < sc->ctts_count; i++) {
4589  if (sc->ctts_data[i].count > INT_MAX - sc->sample_offsets_count)
4590  return AVERROR(ENOMEM);
4591  sc->sample_offsets_count += sc->ctts_data[i].count;
4592  }
4593  av_freep(&sc->sample_offsets);
4595  if (!sc->sample_offsets)
4596  return AVERROR(ENOMEM);
4597  k = 0;
4598  for (uint32_t i = 0; i < sc->ctts_count; i++)
4599  for (int j = 0; j < sc->ctts_data[i].count; j++)
4600  sc->sample_offsets[k++] = sc->ctts_data[i].offset;
4601 
4602  /* The following HEVC NAL type reveal the use of open GOP sync points
4603  * (TODO: BLA types may also be concerned) */
4604  cra_index = get_sgpd_sync_index(sc, HEVC_NAL_CRA_NUT); /* Clean Random Access */
4605  if (!cra_index)
4606  return 0;
4607 
4608  /* Build a list of open-GOP key samples */
4609  sc->open_key_samples_count = 0;
4610  for (uint32_t i = 0; i < sc->sync_group_count; i++)
4611  if (sc->sync_group[i].index == cra_index) {
4612  if (sc->sync_group[i].count > INT_MAX - sc->open_key_samples_count)
4613  return AVERROR(ENOMEM);
4615  }
4616  av_freep(&sc->open_key_samples);
4618  if (!sc->open_key_samples)
4619  return AVERROR(ENOMEM);
4620  k = 0;
4621  for (uint32_t i = 0; i < sc->sync_group_count; i++) {
4622  const MOVSbgp *sg = &sc->sync_group[i];
4623  if (sg->index == cra_index)
4624  for (uint32_t j = 0; j < sg->count; j++)
4625  sc->open_key_samples[k++] = sample_id;
4626  if (sg->count > INT_MAX - sample_id)
4627  return AVERROR_PATCHWELCOME;
4628  sample_id += sg->count;
4629  }
4630 
4631  /* Identify the minimal time step between samples */
4632  sc->min_sample_duration = UINT_MAX;
4633  for (uint32_t i = 0; i < sc->stts_count; i++)
4635 
4636  return 0;
4637 }
4638 
4639 #define MOV_MERGE_CTTS 1
4640 #define MOV_MERGE_STTS 2
4641 /*
4642  * Merge stts and ctts arrays into a new combined array.
4643  * stts_count and ctts_count may be left untouched as they will be
4644  * used to check for the presence of either of them.
4645  */
4646 static int mov_merge_tts_data(MOVContext *mov, AVStream *st, int flags)
4647 {
4648  MOVStreamContext *sc = st->priv_data;
4649  int ctts = sc->ctts_data && (flags & MOV_MERGE_CTTS);
4650  int stts = sc->stts_data && (flags & MOV_MERGE_STTS);
4651  int idx = 0;
4652 
4653  if (!sc->ctts_data && !sc->stts_data)
4654  return 0;
4655  // Expand time to sample entries such that we have a 1-1 mapping with samples
4656  if (!sc->sample_count || sc->sample_count >= UINT_MAX / sizeof(*sc->tts_data))
4657  return -1;
4658 
4659  if (ctts) {
4661  sc->sample_count * sizeof(*sc->tts_data));
4662  if (!sc->tts_data)
4663  return -1;
4664 
4665  memset(sc->tts_data, 0, sc->tts_allocated_size);
4666 
4667  for (int i = 0; i < sc->ctts_count &&
4668  idx < sc->sample_count; i++)
4669  for (int j = 0; j < sc->ctts_data[i].count &&
4670  idx < sc->sample_count; j++) {
4671  sc->tts_data[idx].offset = sc->ctts_data[i].offset;
4672  sc->tts_data[idx++].count = 1;
4673  }
4674 
4675  sc->tts_count = idx;
4676  } else
4677  sc->ctts_count = 0;
4678  av_freep(&sc->ctts_data);
4679  sc->ctts_allocated_size = 0;
4680 
4681  idx = 0;
4682  if (stts) {
4684  sc->sample_count * sizeof(*sc->tts_data));
4685  if (!tts_data)
4686  return -1;
4687 
4688  if (!sc->tts_data)
4689  memset(tts_data, 0, sc->tts_allocated_size);
4690  sc->tts_data = tts_data;
4691 
4692  for (int i = 0; i < sc->stts_count &&
4693  idx < sc->sample_count; i++)
4694  for (int j = 0; j < sc->stts_data[i].count &&
4695  idx < sc->sample_count; j++) {
4696  sc->tts_data[idx].duration = sc->stts_data[i].duration;
4697  sc->tts_data[idx++].count = 1;
4698  }
4699 
4700  sc->tts_count = FFMAX(sc->tts_count, idx);
4701  } else
4702  sc->stts_count = 0;
4703  av_freep(&sc->stts_data);
4704  sc->stts_allocated_size = 0;
4705 
4706  return 0;
4707 }
4708 
4709 static void mov_build_index(MOVContext *mov, AVStream *st)
4710 {
4711  MOVStreamContext *sc = st->priv_data;
4712  FFStream *const sti = ffstream(st);
4713  int64_t current_offset;
4714  int64_t current_dts = 0;
4715  unsigned int stts_index = 0;
4716  unsigned int stsc_index = 0;
4717  unsigned int stss_index = 0;
4718  unsigned int stps_index = 0;
4719  unsigned int i, j;
4720  uint64_t stream_size = 0;
4721 
4722  int ret = build_open_gop_key_points(st);
4723  if (ret < 0)
4724  return;
4725 
4726  if (sc->elst_count) {
4727  int i, edit_start_index = 0, multiple_edits = 0;
4728  int64_t empty_duration = 0; // empty duration of the first edit list entry
4729  int64_t start_time = 0; // start time of the media
4730 
4731  for (i = 0; i < sc->elst_count; i++) {
4732  const MOVElst *e = &sc->elst_data[i];
4733  if (i == 0 && e->time == -1) {
4734  /* if empty, the first entry is the start time of the stream
4735  * relative to the presentation itself */
4736  empty_duration = e->duration;
4737  edit_start_index = 1;
4738  } else if (i == edit_start_index && e->time >= 0) {
4739  start_time = e->time;
4740  } else {
4741  multiple_edits = 1;
4742  }
4743  }
4744 
4745  if (multiple_edits && !mov->advanced_editlist) {
4747  av_log(mov->fc, AV_LOG_WARNING, "multiple edit list entries, "
4748  "not supported in fragmented MP4 files\n");
4749  else
4750  av_log(mov->fc, AV_LOG_WARNING, "multiple edit list entries, "
4751  "Use -advanced_editlist to correctly decode otherwise "
4752  "a/v desync might occur\n");
4753  }
4754 
4755  /* adjust first dts according to edit list */
4756  if ((empty_duration || start_time) && mov->time_scale > 0) {
4757  if (empty_duration)
4758  empty_duration = av_rescale(empty_duration, sc->time_scale, mov->time_scale);
4759 
4760  if (av_sat_sub64(start_time, empty_duration) != start_time - (uint64_t)empty_duration)
4761  av_log(mov->fc, AV_LOG_WARNING, "start_time - empty_duration is not representable\n");
4762 
4763  sc->time_offset = start_time - (uint64_t)empty_duration;
4765  if (!mov->advanced_editlist)
4766  current_dts = -sc->time_offset;
4767  }
4768 
4769  if (!multiple_edits && !mov->advanced_editlist &&
4772  (AVRational){1, st->codecpar->sample_rate});
4773  }
4774 
4775  /* only use old uncompressed audio chunk demuxing when stts specifies it */
4776  if (!(st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
4777  sc->stts_count == 1 && sc->stts_data && sc->stts_data[0].duration == 1)) {
4778  unsigned int current_sample = 0;
4779  unsigned int stts_sample = 0;
4780  unsigned int sample_size;
4781  unsigned int distance = 0;
4782  unsigned int rap_group_index = 0;
4783  unsigned int rap_group_sample = 0;
4784  int rap_group_present = sc->rap_group_count && sc->rap_group;
4785  int key_off = (sc->keyframe_count && sc->keyframes[0] > 0) || (sc->stps_count && sc->stps_data[0] > 0);
4786 
4787  current_dts -= sc->dts_shift;
4788 
4789  if (!sc->sample_count || sti->nb_index_entries || sc->tts_count)
4790  return;
4791  if (sc->sample_count >= UINT_MAX / sizeof(*sti->index_entries) - sti->nb_index_entries)
4792  return;
4793  if (av_reallocp_array(&sti->index_entries,
4794  sti->nb_index_entries + sc->sample_count,
4795  sizeof(*sti->index_entries)) < 0) {
4796  sti->nb_index_entries = 0;
4797  return;
4798  }
4799  sti->index_entries_allocated_size = (sti->nb_index_entries + sc->sample_count) * sizeof(*sti->index_entries);
4800 
4802  if (ret < 0)
4803  return;
4804 
4805  for (i = 0; i < sc->chunk_count; i++) {
4806  int64_t next_offset = i+1 < sc->chunk_count ? sc->chunk_offsets[i+1] : INT64_MAX;
4807  current_offset = sc->chunk_offsets[i];
4808  while (mov_stsc_index_valid(stsc_index, sc->stsc_count) &&
4809  i + 1 == sc->stsc_data[stsc_index + 1].first)
4810  stsc_index++;
4811 
4812  if (next_offset > current_offset && sc->sample_size>0 && sc->sample_size < sc->stsz_sample_size &&
4813  sc->stsc_data[stsc_index].count * (int64_t)sc->stsz_sample_size > next_offset - current_offset) {
4814  av_log(mov->fc, AV_LOG_WARNING, "STSZ sample size %d invalid (too large), ignoring\n", sc->stsz_sample_size);
4815  sc->stsz_sample_size = sc->sample_size;
4816  }
4817  if (sc->stsz_sample_size>0 && sc->stsz_sample_size < sc->sample_size) {
4818  av_log(mov->fc, AV_LOG_WARNING, "STSZ sample size %d invalid (too small), ignoring\n", sc->stsz_sample_size);
4819  sc->stsz_sample_size = sc->sample_size;
4820  }
4821 
4822  for (j = 0; j < sc->stsc_data[stsc_index].count; j++) {
4823  int keyframe = 0;
4824  if (current_sample >= sc->sample_count) {
4825  av_log(mov->fc, AV_LOG_ERROR, "wrong sample count\n");
4826  return;
4827  }
4828 
4829  if (!sc->keyframe_absent && (!sc->keyframe_count || current_sample+key_off == sc->keyframes[stss_index])) {
4830  keyframe = 1;
4831  if (stss_index + 1 < sc->keyframe_count)
4832  stss_index++;
4833  } else if (sc->stps_count && current_sample+key_off == sc->stps_data[stps_index]) {
4834  keyframe = 1;
4835  if (stps_index + 1 < sc->stps_count)
4836  stps_index++;
4837  }
4838  if (rap_group_present && rap_group_index < sc->rap_group_count) {
4839  if (sc->rap_group[rap_group_index].index > 0)
4840  keyframe = 1;
4841  if (++rap_group_sample == sc->rap_group[rap_group_index].count) {
4842  rap_group_sample = 0;
4843  rap_group_index++;
4844  }
4845  }
4846  if (sc->keyframe_absent
4847  && !sc->stps_count
4848  && !rap_group_present
4849  && (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO || (i==0 && j==0)))
4850  keyframe = 1;
4851  if (keyframe)
4852  distance = 0;
4853  sample_size = sc->stsz_sample_size > 0 ? sc->stsz_sample_size : sc->sample_sizes[current_sample];
4854  if (current_offset > INT64_MAX - sample_size) {
4855  av_log(mov->fc, AV_LOG_ERROR, "Current offset %"PRId64" or sample size %u is too large\n",
4856  current_offset,
4857  sample_size);
4858  return;
4859  }
4860 
4861  if (sc->pseudo_stream_id == -1 ||
4862  sc->stsc_data[stsc_index].id - 1 == sc->pseudo_stream_id) {
4863  AVIndexEntry *e;
4864  if (sample_size > 0x3FFFFFFF) {
4865  av_log(mov->fc, AV_LOG_ERROR, "Sample size %u is too large\n", sample_size);
4866  return;
4867  }
4868  e = &sti->index_entries[sti->nb_index_entries++];
4869  e->pos = current_offset;
4870  e->timestamp = current_dts;
4871  e->size = sample_size;
4872  e->min_distance = distance;
4873  e->flags = keyframe ? AVINDEX_KEYFRAME : 0;
4874  av_log(mov->fc, AV_LOG_TRACE, "AVIndex stream %d, sample %u, offset %"PRIx64", dts %"PRId64", "
4875  "size %u, distance %u, keyframe %d\n", st->index, current_sample,
4876  current_offset, current_dts, sample_size, distance, keyframe);
4877  if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && sti->nb_index_entries < 100)
4878  ff_rfps_add_frame(mov->fc, st, current_dts);
4879  }
4880 
4881  current_offset += sample_size;
4882  stream_size += sample_size;
4883 
4884  current_dts += sc->tts_data[stts_index].duration;
4885 
4886  distance++;
4887  stts_sample++;
4888  current_sample++;
4889  if (stts_index + 1 < sc->tts_count && stts_sample == sc->tts_data[stts_index].count) {
4890  stts_sample = 0;
4891  stts_index++;
4892  }
4893  }
4894  }
4895  if (st->duration > 0)
4896  st->codecpar->bit_rate = stream_size*8*sc->time_scale/st->duration;
4897  } else {
4898  unsigned chunk_samples, total = 0;
4899 
4900  if (!sc->chunk_count || sc->tts_count)
4901  return;
4902 
4903  // compute total chunk count
4904  for (i = 0; i < sc->stsc_count; i++) {
4905  unsigned count, chunk_count;
4906 
4907  chunk_samples = sc->stsc_data[i].count;
4908  if (i != sc->stsc_count - 1 &&
4909  sc->samples_per_frame && chunk_samples % sc->samples_per_frame) {
4910  av_log(mov->fc, AV_LOG_ERROR, "error unaligned chunk\n");
4911  return;
4912  }
4913 
4914  if (sc->samples_per_frame >= 160) { // gsm
4915  count = chunk_samples / sc->samples_per_frame;
4916  } else if (sc->samples_per_frame > 1) {
4917  unsigned samples = (1024/sc->samples_per_frame)*sc->samples_per_frame;
4918  count = (chunk_samples+samples-1) / samples;
4919  } else {
4920  count = (chunk_samples+1023) / 1024;
4921  }
4922 
4923  if (mov_stsc_index_valid(i, sc->stsc_count))
4924  chunk_count = sc->stsc_data[i+1].first - sc->stsc_data[i].first;
4925  else
4926  chunk_count = sc->chunk_count - (sc->stsc_data[i].first - 1);
4927  total += chunk_count * count;
4928  }
4929 
4930  av_log(mov->fc, AV_LOG_TRACE, "chunk count %u\n", total);
4931  if (total >= UINT_MAX / sizeof(*sti->index_entries) - sti->nb_index_entries)
4932  return;
4933  if (av_reallocp_array(&sti->index_entries,
4934  sti->nb_index_entries + total,
4935  sizeof(*sti->index_entries)) < 0) {
4936  sti->nb_index_entries = 0;
4937  return;
4938  }
4939  sti->index_entries_allocated_size = (sti->nb_index_entries + total) * sizeof(*sti->index_entries);
4940 
4941  // populate index
4942  for (i = 0; i < sc->chunk_count; i++) {
4943  current_offset = sc->chunk_offsets[i];
4944  if (mov_stsc_index_valid(stsc_index, sc->stsc_count) &&
4945  i + 1 == sc->stsc_data[stsc_index + 1].first)
4946  stsc_index++;
4947  chunk_samples = sc->stsc_data[stsc_index].count;
4948 
4949  while (chunk_samples > 0) {
4950  AVIndexEntry *e;
4951  unsigned size, samples;
4952 
4953  if (sc->samples_per_frame > 1 && !sc->bytes_per_frame) {
4955  "Zero bytes per frame, but %d samples per frame",
4956  sc->samples_per_frame);
4957  return;
4958  }
4959 
4960  if (sc->samples_per_frame >= 160) { // gsm
4961  samples = sc->samples_per_frame;
4962  size = sc->bytes_per_frame;
4963  } else {
4964  if (sc->samples_per_frame > 1) {
4965  samples = FFMIN((1024 / sc->samples_per_frame)*
4966  sc->samples_per_frame, chunk_samples);
4968  } else {
4969  samples = FFMIN(1024, chunk_samples);
4970  size = samples * sc->sample_size;
4971  }
4972  }
4973 
4974  if (sti->nb_index_entries >= total) {
4975  av_log(mov->fc, AV_LOG_ERROR, "wrong chunk count %u\n", total);
4976  return;
4977  }
4978  if (size > 0x3FFFFFFF) {
4979  av_log(mov->fc, AV_LOG_ERROR, "Sample size %u is too large\n", size);
4980  return;
4981  }
4982  e = &sti->index_entries[sti->nb_index_entries++];
4983  e->pos = current_offset;
4984  e->timestamp = current_dts;
4985  e->size = size;
4986  e->min_distance = 0;
4987  e->flags = AVINDEX_KEYFRAME;
4988  av_log(mov->fc, AV_LOG_TRACE, "AVIndex stream %d, chunk %u, offset %"PRIx64", dts %"PRId64", "
4989  "size %u, duration %u\n", st->index, i, current_offset, current_dts,
4990  size, samples);
4991 
4992  current_offset += size;
4993  current_dts += samples;
4994  chunk_samples -= samples;
4995  }
4996  }
4997 
4999  if (ret < 0)
5000  return;
5001  }
5002 
5003  if (!mov->ignore_editlist && mov->advanced_editlist) {
5004  // Fix index according to edit lists.
5005  mov_fix_index(mov, st);
5006  }
5007 
5008  // Update start time of the stream.
5010  st->start_time = sti->index_entries[0].timestamp + sc->dts_shift;
5011  if (sc->tts_data) {
5012  st->start_time += sc->tts_data[0].offset;
5013  }
5014  }
5015 
5016  mov_estimate_video_delay(mov, st);
5017 }
5018 
5019 static int test_same_origin(const char *src, const char *ref) {
5020  char src_proto[64];
5021  char ref_proto[64];
5022  char src_auth[256];
5023  char ref_auth[256];
5024  char src_host[256];
5025  char ref_host[256];
5026  int src_port=-1;
5027  int ref_port=-1;
5028 
5029  av_url_split(src_proto, sizeof(src_proto), src_auth, sizeof(src_auth), src_host, sizeof(src_host), &src_port, NULL, 0, src);
5030  av_url_split(ref_proto, sizeof(ref_proto), ref_auth, sizeof(ref_auth), ref_host, sizeof(ref_host), &ref_port, NULL, 0, ref);
5031 
5032  if (strlen(src) == 0) {
5033  return -1;
5034  } else if (strlen(src_auth) + 1 >= sizeof(src_auth) ||
5035  strlen(ref_auth) + 1 >= sizeof(ref_auth) ||
5036  strlen(src_host) + 1 >= sizeof(src_host) ||
5037  strlen(ref_host) + 1 >= sizeof(ref_host)) {
5038  return 0;
5039  } else if (strcmp(src_proto, ref_proto) ||
5040  strcmp(src_auth, ref_auth) ||
5041  strcmp(src_host, ref_host) ||
5042  src_port != ref_port) {
5043  return 0;
5044  } else
5045  return 1;
5046 }
5047 
5048 static int mov_open_dref(MOVContext *c, AVIOContext **pb, const char *src, MOVDref *ref)
5049 {
5050  /* try relative path, we do not try the absolute because it can leak information about our
5051  system to an attacker */
5052  if (ref->nlvl_to > 0 && ref->nlvl_from > 0) {
5053  char filename[1025];
5054  const char *src_path;
5055  int i, l;
5056 
5057  /* find a source dir */
5058  src_path = strrchr(src, '/');
5059  if (src_path)
5060  src_path++;
5061  else
5062  src_path = src;
5063 
5064  /* find a next level down to target */
5065  for (i = 0, l = strlen(ref->path) - 1; l >= 0; l--)
5066  if (ref->path[l] == '/') {
5067  if (i == ref->nlvl_to - 1)
5068  break;
5069  else
5070  i++;
5071  }
5072 
5073  /* compose filename if next level down to target was found */
5074  if (i == ref->nlvl_to - 1 && src_path - src < sizeof(filename)) {
5075  memcpy(filename, src, src_path - src);
5076  filename[src_path - src] = 0;
5077 
5078  for (i = 1; i < ref->nlvl_from; i++)
5079  av_strlcat(filename, "../", sizeof(filename));
5080 
5081  av_strlcat(filename, ref->path + l + 1, sizeof(filename));
5082  if (!c->use_absolute_path) {
5083  int same_origin = test_same_origin(src, filename);
5084 
5085  if (!same_origin) {
5086  av_log(c->fc, AV_LOG_ERROR,
5087  "Reference with mismatching origin, %s not tried for security reasons, "
5088  "set demuxer option use_absolute_path to allow it anyway\n",
5089  ref->path);
5090  return AVERROR(ENOENT);
5091  }
5092 
5093  if (strstr(ref->path + l + 1, "..") ||
5094  strstr(ref->path + l + 1, ":") ||
5095  (ref->nlvl_from > 1 && same_origin < 0) ||
5096  (filename[0] == '/' && src_path == src))
5097  return AVERROR(ENOENT);
5098  }
5099 
5100  if (strlen(filename) + 1 == sizeof(filename))
5101  return AVERROR(ENOENT);
5102  if (!c->fc->io_open(c->fc, pb, filename, AVIO_FLAG_READ, NULL))
5103  return 0;
5104  }
5105  } else if (c->use_absolute_path) {
5106  av_log(c->fc, AV_LOG_WARNING, "Using absolute path on user request, "
5107  "this is a possible security issue\n");
5108  if (!c->fc->io_open(c->fc, pb, ref->path, AVIO_FLAG_READ, NULL))
5109  return 0;
5110  } else {
5111  av_log(c->fc, AV_LOG_ERROR,
5112  "Absolute path %s not tried for security reasons, "
5113  "set demuxer option use_absolute_path to allow absolute paths\n",
5114  ref->path);
5115  }
5116 
5117  return AVERROR(ENOENT);
5118 }
5119 
5121 {
5122  if (sc->time_scale <= 0) {
5123  av_log(c->fc, AV_LOG_WARNING, "stream %d, timescale not set\n", sc->ffindex);
5124  sc->time_scale = c->time_scale;
5125  if (sc->time_scale <= 0)
5126  sc->time_scale = 1;
5127  }
5128 }
5129 
5130 #if CONFIG_IAMFDEC
5131 static int mov_update_iamf_streams(MOVContext *c, const AVStream *st)
5132 {
5133  const MOVStreamContext *sc = st->priv_data;
5134  const IAMFContext *iamf = &sc->iamf->iamf;
5135 
5136  for (int i = 0; i < iamf->nb_audio_elements; i++) {
5137  const AVStreamGroup *stg = NULL;
5138 
5139  for (int j = 0; j < c->fc->nb_stream_groups; j++)
5140  if (c->fc->stream_groups[j]->id == iamf->audio_elements[i]->audio_element_id)
5141  stg = c->fc->stream_groups[j];
5142  av_assert0(stg);
5143 
5144  for (int j = 0; j < stg->nb_streams; j++) {
5145  const FFStream *sti = cffstream(st);
5146  AVStream *out = stg->streams[j];
5147  FFStream *out_sti = ffstream(stg->streams[j]);
5148 
5149  out->codecpar->bit_rate = 0;
5150 
5151  if (out == st)
5152  continue;
5153 
5154  out->time_base = st->time_base;
5155  out->start_time = st->start_time;
5156  out->duration = st->duration;
5157  out->nb_frames = st->nb_frames;
5158  out->discard = st->discard;
5159 
5160  av_assert0(!out_sti->index_entries);
5162  if (!out_sti->index_entries)
5163  return AVERROR(ENOMEM);
5164 
5166  out_sti->nb_index_entries = sti->nb_index_entries;
5167  out_sti->skip_samples = sti->skip_samples;
5168  memcpy(out_sti->index_entries, sti->index_entries, sti->index_entries_allocated_size);
5169  }
5170  }
5171 
5172  return 0;
5173 }
5174 #endif
5175 
5176 static int sanity_checks(void *log_obj, MOVStreamContext *sc, int index)
5177 {
5178  if ((sc->chunk_count && (!sc->stts_count || !sc->stsc_count ||
5179  (!sc->sample_size && !sc->sample_count))) ||
5180  (sc->sample_count && (!sc->chunk_count ||
5181  (!sc->sample_size && !sc->sample_sizes)))) {
5182  av_log(log_obj, AV_LOG_ERROR, "stream %d, missing mandatory atoms, broken header\n",
5183  index);
5184  return 1;
5185  }
5186 
5187  if (sc->stsc_count && sc->stsc_data[ sc->stsc_count - 1 ].first > sc->chunk_count) {
5188  av_log(log_obj, AV_LOG_ERROR, "stream %d, contradictionary STSC and STCO\n",
5189  index);
5190  return 2;
5191  }
5192  return 0;
5193 }
5194 
5196 {
5197  AVStream *st;
5198  MOVStreamContext *sc;
5199  int ret;
5200 
5201  st = avformat_new_stream(c->fc, NULL);
5202  if (!st) return AVERROR(ENOMEM);
5203  st->id = -1;
5204  sc = av_mallocz(sizeof(MOVStreamContext));
5205  if (!sc) return AVERROR(ENOMEM);
5206 
5207  st->priv_data = sc;
5209  sc->ffindex = st->index;
5210  c->trak_index = st->index;
5211  sc->tref_flags = 0;
5212  sc->tref_id = -1;
5213  sc->refcount = 1;
5214 
5215  if ((ret = mov_read_default(c, pb, atom)) < 0)
5216  return ret;
5217 
5218  c->trak_index = -1;
5219 
5220  // Here stsc refers to a chunk not described in stco. This is technically invalid,
5221  // but we can overlook it (clearing stsc) whenever stts_count == 0 (indicating no samples).
5222  if (!sc->chunk_count && !sc->stts_count && sc->stsc_count) {
5223  sc->stsc_count = 0;
5224  av_freep(&sc->stsc_data);
5225  }
5226 
5227  ret = sanity_checks(c->fc, sc, st->index);
5228  if (ret)
5229  return ret > 1 ? AVERROR_INVALIDDATA : 0;
5230 
5231  fix_timescale(c, sc);
5232 
5233  avpriv_set_pts_info(st, 64, 1, sc->time_scale);
5234 
5235  /*
5236  * Advanced edit list support does not work with fragemented MP4s, which
5237  * have stsc, stsz, stco, and stts with zero entries in the moov atom.
5238  * In these files, trun atoms may be streamed in.
5239  */
5240  if (!sc->stts_count && c->advanced_editlist) {
5241 
5242  av_log(c->fc, AV_LOG_VERBOSE, "advanced_editlist does not work with fragmented "
5243  "MP4. disabling.\n");
5244  c->advanced_editlist = 0;
5245  c->advanced_editlist_autodisabled = 1;
5246  }
5247 
5248  mov_build_index(c, st);
5249 
5250 #if CONFIG_IAMFDEC
5251  if (sc->iamf) {
5252  ret = mov_update_iamf_streams(c, st);
5253  if (ret < 0)
5254  return ret;
5255  }
5256 #endif
5257 
5258  if (sc->dref_id-1 < sc->drefs_count && sc->drefs[sc->dref_id-1].path) {
5259  MOVDref *dref = &sc->drefs[sc->dref_id - 1];
5260  if (c->enable_drefs) {
5261  if (mov_open_dref(c, &sc->pb, c->fc->url, dref) < 0)
5262  av_log(c->fc, AV_LOG_ERROR,
5263  "stream %d, error opening alias: path='%s', dir='%s', "
5264  "filename='%s', volume='%s', nlvl_from=%d, nlvl_to=%d\n",
5265  st->index, dref->path, dref->dir, dref->filename,
5266  dref->volume, dref->nlvl_from, dref->nlvl_to);
5267  } else {
5268  av_log(c->fc, AV_LOG_WARNING,
5269  "Skipped opening external track: "
5270  "stream %d, alias: path='%s', dir='%s', "
5271  "filename='%s', volume='%s', nlvl_from=%d, nlvl_to=%d."
5272  "Set enable_drefs to allow this.\n",
5273  st->index, dref->path, dref->dir, dref->filename,
5274  dref->volume, dref->nlvl_from, dref->nlvl_to);
5275  }
5276  } else {
5277  sc->pb = c->fc->pb;
5278  sc->pb_is_copied = 1;
5279  }
5280 
5281  if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
5282  int stts_constant = sc->stts_count && sc->tts_count;
5283  if (sc->h_spacing && sc->v_spacing)
5285  sc->h_spacing, sc->v_spacing, INT_MAX);
5286  if (!st->sample_aspect_ratio.num && st->codecpar->width && st->codecpar->height &&
5287  sc->height && sc->width &&
5288  (st->codecpar->width != sc->width || st->codecpar->height != sc->height)) {
5290  (int64_t)st->codecpar->height * sc->width,
5291  (int64_t)st->codecpar->width * sc->height, INT_MAX);
5292  }
5293 
5294 #if FF_API_R_FRAME_RATE
5295  for (unsigned int i = 1; sc->stts_count && i + 1 < sc->tts_count; i++) {
5296  if (sc->tts_data[i].duration == sc->tts_data[0].duration)
5297  continue;
5298  stts_constant = 0;
5299  }
5300  if (stts_constant)
5302  sc->time_scale, sc->tts_data[0].duration, INT_MAX);
5303 #endif
5304  }
5305 
5306 #if CONFIG_H261_DECODER || CONFIG_H263_DECODER || CONFIG_MPEG4_DECODER
5307  switch (st->codecpar->codec_id) {
5308 #if CONFIG_H261_DECODER
5309  case AV_CODEC_ID_H261:
5310 #endif
5311 #if CONFIG_H263_DECODER
5312  case AV_CODEC_ID_H263:
5313 #endif
5314 #if CONFIG_MPEG4_DECODER
5315  case AV_CODEC_ID_MPEG4:
5316 #endif
5317  st->codecpar->width = 0; /* let decoder init width/height */
5318  st->codecpar->height= 0;
5319  break;
5320  }
5321 #endif
5322 
5323  // If the duration of the mp3 packets is not constant, then they could need a parser
5324  if (st->codecpar->codec_id == AV_CODEC_ID_MP3
5325  && sc->time_scale == st->codecpar->sample_rate) {
5326  int stts_constant = 1;
5327  for (int i = 1; sc->stts_count && i < sc->tts_count; i++) {
5328  if (sc->tts_data[i].duration == sc->tts_data[0].duration)
5329  continue;
5330  stts_constant = 0;
5331  }
5332  if (!stts_constant)
5334  }
5335  /* Do not need those anymore. */
5336  av_freep(&sc->chunk_offsets);
5337  av_freep(&sc->sample_sizes);
5338  av_freep(&sc->keyframes);
5339  av_freep(&sc->stps_data);
5340  av_freep(&sc->elst_data);
5341  av_freep(&sc->rap_group);
5342  av_freep(&sc->sync_group);
5343  av_freep(&sc->sgpd_sync);
5344 
5345  return 0;
5346 }
5347 
5349 {
5350  int ret;
5351  c->itunes_metadata = 1;
5352  ret = mov_read_default(c, pb, atom);
5353  c->itunes_metadata = 0;
5354  return ret;
5355 }
5356 
5358 {
5359  uint32_t count;
5360  uint32_t i;
5361 
5362  if (atom.size < 8)
5363  return 0;
5364 
5365  avio_skip(pb, 4);
5366  count = avio_rb32(pb);
5367  atom.size -= 8;
5368  if (count >= UINT_MAX / sizeof(*c->meta_keys)) {
5369  av_log(c->fc, AV_LOG_ERROR,
5370  "The 'keys' atom with the invalid key count: %"PRIu32"\n", count);
5371  return AVERROR_INVALIDDATA;
5372  }
5373 
5374  c->meta_keys_count = count + 1;
5375  c->meta_keys = av_mallocz(c->meta_keys_count * sizeof(*c->meta_keys));
5376  if (!c->meta_keys)
5377  return AVERROR(ENOMEM);
5378 
5379  for (i = 1; i <= count; ++i) {
5380  uint32_t key_size = avio_rb32(pb);
5381  uint32_t type = avio_rl32(pb);
5382  if (key_size < 8 || key_size > atom.size) {
5383  av_log(c->fc, AV_LOG_ERROR,
5384  "The key# %"PRIu32" in meta has invalid size:"
5385  "%"PRIu32"\n", i, key_size);
5386  return AVERROR_INVALIDDATA;
5387  }
5388  atom.size -= key_size;
5389  key_size -= 8;
5390  if (type != MKTAG('m','d','t','a')) {
5391  avio_skip(pb, key_size);
5392  continue;
5393  }
5394  c->meta_keys[i] = av_mallocz(key_size + 1);
5395  if (!c->meta_keys[i])
5396  return AVERROR(ENOMEM);
5397  avio_read(pb, c->meta_keys[i], key_size);
5398  }
5399 
5400  return 0;
5401 }
5402 
5404 {
5405  int64_t end = av_sat_add64(avio_tell(pb), atom.size);
5406  uint8_t *key = NULL, *val = NULL, *mean = NULL;
5407  int i;
5408  int ret = 0;
5409  AVStream *st;
5410  MOVStreamContext *sc;
5411 
5412  if (c->fc->nb_streams < 1)
5413  return 0;
5414  st = c->fc->streams[c->fc->nb_streams-1];
5415  sc = st->priv_data;
5416 
5417  for (i = 0; i < 3; i++) {
5418  uint8_t **p;
5419  uint32_t len, tag;
5420 
5421  if (end - avio_tell(pb) <= 12)
5422  break;
5423 
5424  len = avio_rb32(pb);
5425  tag = avio_rl32(pb);
5426  avio_skip(pb, 4); // flags
5427 
5428  if (len < 12 || len - 12 > end - avio_tell(pb))
5429  break;
5430  len -= 12;
5431 
5432  if (tag == MKTAG('m', 'e', 'a', 'n'))
5433  p = &mean;
5434  else if (tag == MKTAG('n', 'a', 'm', 'e'))
5435  p = &key;
5436  else if (tag == MKTAG('d', 'a', 't', 'a') && len > 4) {
5437  avio_skip(pb, 4);
5438  len -= 4;
5439  p = &val;
5440  } else
5441  break;
5442 
5443  if (*p)
5444  break;
5445 
5446  *p = av_malloc(len + 1);
5447  if (!*p) {
5448  ret = AVERROR(ENOMEM);
5449  break;
5450  }
5451  ret = ffio_read_size(pb, *p, len);
5452  if (ret < 0) {
5453  av_freep(p);
5454  break;
5455  }
5456  (*p)[len] = 0;
5457  }
5458 
5459  if (mean && key && val) {
5460  if (strcmp(key, "iTunSMPB") == 0) {
5461  int priming, remainder, samples;
5462  if(sscanf(val, "%*X %X %X %X", &priming, &remainder, &samples) == 3){
5463  if(priming>0 && priming<16384)
5464  sc->start_pad = priming;
5465  }
5466  }
5467  if (strcmp(key, "cdec") != 0) {
5468  av_dict_set(&c->fc->metadata, key, val,
5470  key = val = NULL;
5471  }
5472  } else {
5473  av_log(c->fc, AV_LOG_VERBOSE,
5474  "Unhandled or malformed custom metadata of size %"PRId64"\n", atom.size);
5475  }
5476 
5477  avio_seek(pb, end, SEEK_SET);
5478  av_freep(&key);
5479  av_freep(&val);
5480  av_freep(&mean);
5481  return ret;
5482 }
5483 
5485 {
5486  MOVStreamContext *sc;
5487  AVStream *st;
5488 
5489  st = avformat_new_stream(c->fc, NULL);
5490  if (!st)
5491  return AVERROR(ENOMEM);
5492  sc = av_mallocz(sizeof(MOVStreamContext));
5493  if (!sc)
5494  goto fail;
5495 
5496  item->st = st;
5497  st->id = item->item_id;
5498  st->priv_data = sc;
5500  st->codecpar->codec_id = mov_codec_id(st, item->type);
5501  sc->id = st->id;
5502  sc->ffindex = st->index;
5503  st->avg_frame_rate.num = st->avg_frame_rate.den = 1;
5504  st->time_base.num = st->time_base.den = 1;
5505  st->nb_frames = 1;
5506  sc->time_scale = 1;
5507  sc->pb = c->fc->pb;
5508  sc->pb_is_copied = 1;
5509  sc->refcount = 1;
5510 
5511  if (item->name)
5512  av_dict_set(&st->metadata, "title", item->name, 0);
5513 
5514  // Populate the necessary fields used by mov_build_index.
5515  sc->stsc_data = av_malloc_array(1, sizeof(*sc->stsc_data));
5516  if (!sc->stsc_data)
5517  goto fail;
5518  sc->stsc_count = 1;
5519  sc->stsc_data[0].first = 1;
5520  sc->stsc_data[0].count = 1;
5521  sc->stsc_data[0].id = 1;
5522  sc->chunk_offsets = av_malloc_array(1, sizeof(*sc->chunk_offsets));
5523  if (!sc->chunk_offsets)
5524  goto fail;
5525  sc->chunk_count = 1;
5526  sc->stts_data = av_malloc_array(1, sizeof(*sc->stts_data));
5527  if (!sc->stts_data)
5528  goto fail;
5529  sc->stts_count = 1;
5530  sc->stts_data[0].count = 1;
5531  // Not used for still images. But needed by mov_build_index.
5532  sc->stts_data[0].duration = 0;
5533 
5534  return 0;
5535 fail:
5536  mov_free_stream_context(c->fc, st);
5537  ff_remove_stream(c->fc, st);
5538  item->st = NULL;
5539 
5540  return AVERROR(ENOMEM);
5541 }
5542 
5544 {
5545  while (atom.size > 8) {
5546  uint32_t tag;
5547  if (avio_feof(pb))
5548  return AVERROR_EOF;
5549  tag = avio_rl32(pb);
5550  atom.size -= 4;
5551  if (tag == MKTAG('h','d','l','r')) {
5552  avio_seek(pb, -8, SEEK_CUR);
5553  atom.size += 8;
5554  return mov_read_default(c, pb, atom);
5555  }
5556  }
5557  return 0;
5558 }
5559 
5560 // return 1 when matrix is identity, 0 otherwise
5561 #define IS_MATRIX_IDENT(matrix) \
5562  ( (matrix)[0][0] == (1 << 16) && \
5563  (matrix)[1][1] == (1 << 16) && \
5564  (matrix)[2][2] == (1 << 30) && \
5565  !(matrix)[0][1] && !(matrix)[0][2] && \
5566  !(matrix)[1][0] && !(matrix)[1][2] && \
5567  !(matrix)[2][0] && !(matrix)[2][1])
5568 
5570 {
5571  int i, j, e;
5572  int width;
5573  int height;
5574  int display_matrix[3][3];
5575  int res_display_matrix[3][3] = { { 0 } };
5576  AVStream *st;
5577  MOVStreamContext *sc;
5578  int version;
5579  int flags;
5580 
5581  if (c->fc->nb_streams < 1)
5582  return 0;
5583  st = c->fc->streams[c->fc->nb_streams-1];
5584  sc = st->priv_data;
5585 
5586  // Each stream (trak) should have exactly 1 tkhd. This catches bad files and
5587  // avoids corrupting AVStreams mapped to an earlier tkhd.
5588  if (st->id != -1)
5589  return AVERROR_INVALIDDATA;
5590 
5591  version = avio_r8(pb);
5592  flags = avio_rb24(pb);
5594 
5595  if (version == 1) {
5596  avio_rb64(pb);
5597  avio_rb64(pb);
5598  } else {
5599  avio_rb32(pb); /* creation time */
5600  avio_rb32(pb); /* modification time */
5601  }
5602  st->id = (int)avio_rb32(pb); /* track id (NOT 0 !)*/
5603  sc->id = st->id;
5604  avio_rb32(pb); /* reserved */
5605 
5606  /* highlevel (considering edits) duration in movie timebase */
5607  (version == 1) ? avio_rb64(pb) : avio_rb32(pb);
5608  avio_rb32(pb); /* reserved */
5609  avio_rb32(pb); /* reserved */
5610 
5611  avio_rb16(pb); /* layer */
5612  avio_rb16(pb); /* alternate group */
5613  avio_rb16(pb); /* volume */
5614  avio_rb16(pb); /* reserved */
5615 
5616  //read in the display matrix (outlined in ISO 14496-12, Section 6.2.2)
5617  // they're kept in fixed point format through all calculations
5618  // save u,v,z to store the whole matrix in the AV_PKT_DATA_DISPLAYMATRIX
5619  // side data, but the scale factor is not needed to calculate aspect ratio
5620  for (i = 0; i < 3; i++) {
5621  display_matrix[i][0] = avio_rb32(pb); // 16.16 fixed point
5622  display_matrix[i][1] = avio_rb32(pb); // 16.16 fixed point
5623  display_matrix[i][2] = avio_rb32(pb); // 2.30 fixed point
5624  }
5625 
5626  width = avio_rb32(pb); // 16.16 fixed point track width
5627  height = avio_rb32(pb); // 16.16 fixed point track height
5628  sc->width = width >> 16;
5629  sc->height = height >> 16;
5630 
5631  // apply the moov display matrix (after the tkhd one)
5632  for (i = 0; i < 3; i++) {
5633  const int sh[3] = { 16, 16, 30 };
5634  for (j = 0; j < 3; j++) {
5635  for (e = 0; e < 3; e++) {
5636  res_display_matrix[i][j] +=
5637  ((int64_t) display_matrix[i][e] *
5638  c->movie_display_matrix[e][j]) >> sh[e];
5639  }
5640  }
5641  }
5642 
5643  // save the matrix when it is not the default identity
5644  if (!IS_MATRIX_IDENT(res_display_matrix)) {
5645  av_freep(&sc->display_matrix);
5646  sc->display_matrix = av_malloc(sizeof(int32_t) * 9);
5647  if (!sc->display_matrix)
5648  return AVERROR(ENOMEM);
5649 
5650  for (i = 0; i < 3; i++)
5651  for (j = 0; j < 3; j++)
5652  sc->display_matrix[i * 3 + j] = res_display_matrix[i][j];
5653  }
5654 
5655  // transform the display width/height according to the matrix
5656  // to keep the same scale, use [width height 1<<16]
5657  if (width && height && sc->display_matrix) {
5658  double disp_transform[2];
5659 
5660  for (i = 0; i < 2; i++)
5661  disp_transform[i] = hypot(sc->display_matrix[0 + i],
5662  sc->display_matrix[3 + i]);
5663 
5664  if (disp_transform[0] > 1 && disp_transform[1] > 1 &&
5665  disp_transform[0] < (1<<24) && disp_transform[1] < (1<<24) &&
5666  fabs((disp_transform[0] / disp_transform[1]) - 1.0) > 0.01)
5668  disp_transform[0] / disp_transform[1],
5669  INT_MAX);
5670  }
5671  return 0;
5672 }
5673 
5675 {
5676  MOVFragment *frag = &c->fragment;
5677  MOVTrackExt *trex = NULL;
5678  int flags, track_id, i;
5679  MOVFragmentStreamInfo * frag_stream_info;
5680 
5681  avio_r8(pb); /* version */
5682  flags = avio_rb24(pb);
5683 
5684  track_id = avio_rb32(pb);
5685  if (!track_id)
5686  return AVERROR_INVALIDDATA;
5687  for (i = 0; i < c->trex_count; i++)
5688  if (c->trex_data[i].track_id == track_id) {
5689  trex = &c->trex_data[i];
5690  break;
5691  }
5692  if (!trex) {
5693  av_log(c->fc, AV_LOG_WARNING, "could not find corresponding trex (id %u)\n", track_id);
5694  return 0;
5695  }
5696  c->fragment.found_tfhd = 1;
5697  frag->track_id = track_id;
5698  set_frag_stream(&c->frag_index, track_id);
5699 
5702  frag->moof_offset : frag->implicit_offset;
5703  frag->stsd_id = flags & MOV_TFHD_STSD_ID ? avio_rb32(pb) : trex->stsd_id;
5704 
5706  avio_rb32(pb) : trex->duration;
5707  frag->size = flags & MOV_TFHD_DEFAULT_SIZE ?
5708  avio_rb32(pb) : trex->size;
5709  frag->flags = flags & MOV_TFHD_DEFAULT_FLAGS ?
5710  avio_rb32(pb) : trex->flags;
5711  av_log(c->fc, AV_LOG_TRACE, "frag flags 0x%x\n", frag->flags);
5712 
5713  frag_stream_info = get_current_frag_stream_info(&c->frag_index);
5714  if (frag_stream_info) {
5715  frag_stream_info->next_trun_dts = AV_NOPTS_VALUE;
5716  frag_stream_info->stsd_id = frag->stsd_id;
5717  }
5718  return 0;
5719 }
5720 
5722 {
5723  unsigned i, num;
5724  void *new_tracks;
5725 
5726  num = atom.size / 4;
5727  if (!(new_tracks = av_malloc_array(num, sizeof(int))))
5728  return AVERROR(ENOMEM);
5729 
5730  av_free(c->chapter_tracks);
5731  c->chapter_tracks = new_tracks;
5732  c->nb_chapter_tracks = num;
5733 
5734  for (i = 0; i < num && !pb->eof_reached; i++)
5735  c->chapter_tracks[i] = avio_rb32(pb);
5736 
5737  c->nb_chapter_tracks = i;
5738 
5739  return 0;
5740 }
5741 
5743 {
5744  MOVTrackExt *trex;
5745  int err;
5746 
5747  if ((uint64_t)c->trex_count+1 >= UINT_MAX / sizeof(*c->trex_data))
5748  return AVERROR_INVALIDDATA;
5749  if ((err = av_reallocp_array(&c->trex_data, c->trex_count + 1,
5750  sizeof(*c->trex_data))) < 0) {
5751  c->trex_count = 0;
5752  return err;
5753  }
5754 
5755  c->fc->duration = AV_NOPTS_VALUE; // the duration from mvhd is not representing the whole file when fragments are used.
5756 
5757  trex = &c->trex_data[c->trex_count++];
5758  avio_r8(pb); /* version */
5759  avio_rb24(pb); /* flags */
5760  trex->track_id = avio_rb32(pb);
5761  trex->stsd_id = avio_rb32(pb);
5762  trex->duration = avio_rb32(pb);
5763  trex->size = avio_rb32(pb);
5764  trex->flags = avio_rb32(pb);
5765  return 0;
5766 }
5767 
5769 {
5770  MOVFragment *frag = &c->fragment;
5771  AVStream *st = NULL;
5772  MOVStreamContext *sc;
5773  int version, i;
5774  MOVFragmentStreamInfo * frag_stream_info;
5775  int64_t base_media_decode_time;
5776 
5777  for (i = 0; i < c->fc->nb_streams; i++) {
5778  sc = c->fc->streams[i]->priv_data;
5779  if (sc->id == frag->track_id) {
5780  st = c->fc->streams[i];
5781  break;
5782  }
5783  }
5784  if (!st) {
5785  av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %u\n", frag->track_id);
5786  return 0;
5787  }
5788  sc = st->priv_data;
5789  if (sc->pseudo_stream_id + 1 != frag->stsd_id && sc->pseudo_stream_id != -1)
5790  return 0;
5791  version = avio_r8(pb);
5792  avio_rb24(pb); /* flags */
5793  if (version) {
5794  base_media_decode_time = avio_rb64(pb);
5795  } else {
5796  base_media_decode_time = avio_rb32(pb);
5797  }
5798 
5799  frag_stream_info = get_current_frag_stream_info(&c->frag_index);
5800  if (frag_stream_info)
5801  frag_stream_info->tfdt_dts = base_media_decode_time;
5802  sc->track_end = base_media_decode_time;
5803 
5804  return 0;
5805 }
5806 
5808 {
5809  MOVFragment *frag = &c->fragment;
5810  AVStream *st = NULL;
5811  FFStream *sti = NULL;
5812  MOVStreamContext *sc;
5813  MOVTimeToSample *tts_data;
5814  uint64_t offset;
5815  int64_t dts, pts = AV_NOPTS_VALUE;
5816  int data_offset = 0;
5817  unsigned entries, first_sample_flags = frag->flags;
5818  int flags, distance, i;
5819  int64_t prev_dts = AV_NOPTS_VALUE;
5820  int next_frag_index = -1, index_entry_pos;
5821  size_t requested_size;
5822  size_t old_allocated_size;
5823  AVIndexEntry *new_entries;
5824  MOVFragmentStreamInfo * frag_stream_info;
5825 
5826  if (!frag->found_tfhd) {
5827  av_log(c->fc, AV_LOG_ERROR, "trun track id unknown, no tfhd was found\n");
5828  return AVERROR_INVALIDDATA;
5829  }
5830 
5831  for (i = 0; i < c->fc->nb_streams; i++) {
5832  sc = c->fc->streams[i]->priv_data;
5833  if (sc->id == frag->track_id) {
5834  st = c->fc->streams[i];
5835  sti = ffstream(st);
5836  break;
5837  }
5838  }
5839  if (!st) {
5840  av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %u\n", frag->track_id);
5841  return 0;
5842  }
5843  sc = st->priv_data;
5844  if (sc->pseudo_stream_id+1 != frag->stsd_id && sc->pseudo_stream_id != -1)
5845  return 0;
5846 
5847  // Find the next frag_index index that has a valid index_entry for
5848  // the current track_id.
5849  //
5850  // A valid index_entry means the trun for the fragment was read
5851  // and it's samples are in index_entries at the given position.
5852  // New index entries will be inserted before the index_entry found.
5853  index_entry_pos = sti->nb_index_entries;
5854  for (i = c->frag_index.current + 1; i < c->frag_index.nb_items; i++) {
5855  frag_stream_info = get_frag_stream_info(&c->frag_index, i, frag->track_id);
5856  if (frag_stream_info && frag_stream_info->index_entry >= 0) {
5857  next_frag_index = i;
5858  index_entry_pos = frag_stream_info->index_entry;
5859  break;
5860  }
5861  }
5862  av_assert0(index_entry_pos <= sti->nb_index_entries);
5863 
5864  avio_r8(pb); /* version */
5865  flags = avio_rb24(pb);
5866  entries = avio_rb32(pb);
5867  av_log(c->fc, AV_LOG_TRACE, "flags 0x%x entries %u\n", flags, entries);
5868 
5869  if ((uint64_t)entries+sc->tts_count >= UINT_MAX/sizeof(*sc->tts_data))
5870  return AVERROR_INVALIDDATA;
5871  if (flags & MOV_TRUN_DATA_OFFSET) data_offset = avio_rb32(pb);
5872  if (flags & MOV_TRUN_FIRST_SAMPLE_FLAGS) first_sample_flags = avio_rb32(pb);
5873 
5874  frag_stream_info = get_current_frag_stream_info(&c->frag_index);
5875  if (frag_stream_info) {
5876  if (frag_stream_info->next_trun_dts != AV_NOPTS_VALUE) {
5877  dts = frag_stream_info->next_trun_dts - sc->time_offset;
5878  } else if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE &&
5879  c->use_mfra_for == FF_MOV_FLAG_MFRA_PTS) {
5880  pts = frag_stream_info->first_tfra_pts;
5881  av_log(c->fc, AV_LOG_DEBUG, "found mfra time %"PRId64
5882  ", using it for pts\n", pts);
5883  } else if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE &&
5884  c->use_mfra_for == FF_MOV_FLAG_MFRA_DTS) {
5885  dts = frag_stream_info->first_tfra_pts;
5886  av_log(c->fc, AV_LOG_DEBUG, "found mfra time %"PRId64
5887  ", using it for dts\n", pts);
5888  } else {
5889  int has_tfdt = frag_stream_info->tfdt_dts != AV_NOPTS_VALUE;
5890  int has_sidx = frag_stream_info->sidx_pts != AV_NOPTS_VALUE;
5891  int fallback_tfdt = !c->use_tfdt && !has_sidx && has_tfdt;
5892  int fallback_sidx = c->use_tfdt && !has_tfdt && has_sidx;
5893 
5894  if (fallback_sidx) {
5895  av_log(c->fc, AV_LOG_DEBUG, "use_tfdt set but no tfdt found, using sidx instead\n");
5896  }
5897  if (fallback_tfdt) {
5898  av_log(c->fc, AV_LOG_DEBUG, "use_tfdt not set but no sidx found, using tfdt instead\n");
5899  }
5900 
5901  if (has_tfdt && c->use_tfdt || fallback_tfdt) {
5902  dts = frag_stream_info->tfdt_dts - sc->time_offset;
5903  av_log(c->fc, AV_LOG_DEBUG, "found tfdt time %"PRId64
5904  ", using it for dts\n", dts);
5905  } else if (has_sidx && !c->use_tfdt || fallback_sidx) {
5906  // FIXME: sidx earliest_presentation_time is *PTS*, s.b.
5907  // pts = frag_stream_info->sidx_pts;
5908  dts = frag_stream_info->sidx_pts;
5909  av_log(c->fc, AV_LOG_DEBUG, "found sidx time %"PRId64
5910  ", using it for dts\n", frag_stream_info->sidx_pts);
5911  } else {
5912  dts = sc->track_end - sc->time_offset;
5913  av_log(c->fc, AV_LOG_DEBUG, "found track end time %"PRId64
5914  ", using it for dts\n", dts);
5915  }
5916  }
5917  } else {
5918  dts = sc->track_end - sc->time_offset;
5919  av_log(c->fc, AV_LOG_DEBUG, "found track end time %"PRId64
5920  ", using it for dts\n", dts);
5921  }
5922  offset = frag->base_data_offset + data_offset;
5923  distance = 0;
5924  av_log(c->fc, AV_LOG_TRACE, "first sample flags 0x%x\n", first_sample_flags);
5925 
5926  // realloc space for new index entries
5927  if ((uint64_t)sti->nb_index_entries + entries >= UINT_MAX / sizeof(AVIndexEntry)) {
5928  entries = UINT_MAX / sizeof(AVIndexEntry) - sti->nb_index_entries;
5929  av_log(c->fc, AV_LOG_ERROR, "Failed to add index entry\n");
5930  }
5931  if (entries == 0)
5932  return 0;
5933 
5934  requested_size = (sti->nb_index_entries + entries) * sizeof(AVIndexEntry);
5935  new_entries = av_fast_realloc(sti->index_entries,
5937  requested_size);
5938  if (!new_entries)
5939  return AVERROR(ENOMEM);
5940  sti->index_entries= new_entries;
5941 
5942  requested_size = (sti->nb_index_entries + entries) * sizeof(*sc->tts_data);
5943  old_allocated_size = sc->tts_allocated_size;
5944  tts_data = av_fast_realloc(sc->tts_data, &sc->tts_allocated_size,
5945  requested_size);
5946  if (!tts_data)
5947  return AVERROR(ENOMEM);
5948  sc->tts_data = tts_data;
5949 
5950  // In case there were samples without time to sample entries, ensure they get
5951  // zero valued entries. This ensures clips which mix boxes with and
5952  // without time to sample entries don't pickup uninitialized data.
5953  memset((uint8_t*)(sc->tts_data) + old_allocated_size, 0,
5954  sc->tts_allocated_size - old_allocated_size);
5955 
5956  if (index_entry_pos < sti->nb_index_entries) {
5957  // Make hole in index_entries and tts_data for new samples
5958  memmove(sti->index_entries + index_entry_pos + entries,
5959  sti->index_entries + index_entry_pos,
5960  sizeof(*sti->index_entries) *
5961  (sti->nb_index_entries - index_entry_pos));
5962  memmove(sc->tts_data + index_entry_pos + entries,
5963  sc->tts_data + index_entry_pos,
5964  sizeof(*sc->tts_data) * (sc->tts_count - index_entry_pos));
5965  if (index_entry_pos < sc->current_sample) {
5966  sc->current_sample += entries;
5967  }
5968  }
5969 
5970  sti->nb_index_entries += entries;
5971  sc->tts_count = sti->nb_index_entries;
5972  sc->stts_count = sti->nb_index_entries;
5973  if (flags & MOV_TRUN_SAMPLE_CTS)
5974  sc->ctts_count = sti->nb_index_entries;
5975 
5976  // Record the index_entry position in frag_index of this fragment
5977  if (frag_stream_info) {
5978  frag_stream_info->index_entry = index_entry_pos;
5979  if (frag_stream_info->index_base < 0)
5980  frag_stream_info->index_base = index_entry_pos;
5981  }
5982 
5983  if (index_entry_pos > 0)
5984  prev_dts = sti->index_entries[index_entry_pos-1].timestamp;
5985 
5986  for (i = 0; i < entries && !pb->eof_reached; i++) {
5987  unsigned sample_size = frag->size;
5988  int sample_flags = i ? frag->flags : first_sample_flags;
5989  unsigned sample_duration = frag->duration;
5990  unsigned ctts_duration = 0;
5991  int keyframe = 0;
5992  int index_entry_flags = 0;
5993 
5994  if (flags & MOV_TRUN_SAMPLE_DURATION) sample_duration = avio_rb32(pb);
5995  if (flags & MOV_TRUN_SAMPLE_SIZE) sample_size = avio_rb32(pb);
5996  if (flags & MOV_TRUN_SAMPLE_FLAGS) sample_flags = avio_rb32(pb);
5997  if (flags & MOV_TRUN_SAMPLE_CTS) ctts_duration = avio_rb32(pb);
5998 
5999  mov_update_dts_shift(sc, ctts_duration, c->fc);
6000  if (pts != AV_NOPTS_VALUE) {
6001  dts = pts - sc->dts_shift;
6002  if (flags & MOV_TRUN_SAMPLE_CTS) {
6003  dts -= ctts_duration;
6004  } else {
6005  dts -= sc->time_offset;
6006  }
6007  av_log(c->fc, AV_LOG_DEBUG,
6008  "pts %"PRId64" calculated dts %"PRId64
6009  " sc->dts_shift %d ctts.duration %d"
6010  " sc->time_offset %"PRId64
6011  " flags & MOV_TRUN_SAMPLE_CTS %d\n",
6012  pts, dts,
6013  sc->dts_shift, ctts_duration,
6015  pts = AV_NOPTS_VALUE;
6016  }
6017 
6018  keyframe =
6019  !(sample_flags & (MOV_FRAG_SAMPLE_FLAG_IS_NON_SYNC |
6021  if (keyframe) {
6022  distance = 0;
6023  index_entry_flags |= AVINDEX_KEYFRAME;
6024  }
6025  // Fragments can overlap in time. Discard overlapping frames after
6026  // decoding.
6027  if (prev_dts >= dts)
6028  index_entry_flags |= AVINDEX_DISCARD_FRAME;
6029 
6030  sti->index_entries[index_entry_pos].pos = offset;
6031  sti->index_entries[index_entry_pos].timestamp = dts;
6032  sti->index_entries[index_entry_pos].size = sample_size;
6033  sti->index_entries[index_entry_pos].min_distance = distance;
6034  sti->index_entries[index_entry_pos].flags = index_entry_flags;
6035 
6036  sc->tts_data[index_entry_pos].count = 1;
6037  sc->tts_data[index_entry_pos].offset = ctts_duration;
6038  sc->tts_data[index_entry_pos].duration = sample_duration;
6039  index_entry_pos++;
6040 
6041  av_log(c->fc, AV_LOG_TRACE, "AVIndex stream %d, sample %d, offset %"PRIx64", dts %"PRId64", "
6042  "size %u, distance %d, keyframe %d\n", st->index,
6043  index_entry_pos, offset, dts, sample_size, distance, keyframe);
6044  distance++;
6045  if (av_sat_add64(dts, sample_duration) != dts + (uint64_t)sample_duration)
6046  return AVERROR_INVALIDDATA;
6047  if (!sample_size)
6048  return AVERROR_INVALIDDATA;
6049  dts += sample_duration;
6050  offset += sample_size;
6051  sc->data_size += sample_size;
6052 
6053  if (sample_duration <= INT64_MAX - sc->duration_for_fps &&
6054  1 <= INT_MAX - sc->nb_frames_for_fps
6055  ) {
6056  sc->duration_for_fps += sample_duration;
6057  sc->nb_frames_for_fps ++;
6058  }
6059  }
6060  if (frag_stream_info)
6061  frag_stream_info->next_trun_dts = dts + sc->time_offset;
6062  if (i < entries) {
6063  // EOF found before reading all entries. Fix the hole this would
6064  // leave in index_entries and tts_data
6065  int gap = entries - i;
6066  memmove(sti->index_entries + index_entry_pos,
6067  sti->index_entries + index_entry_pos + gap,
6068  sizeof(*sti->index_entries) *
6069  (sti->nb_index_entries - (index_entry_pos + gap)));
6070  memmove(sc->tts_data + index_entry_pos,
6071  sc->tts_data + index_entry_pos + gap,
6072  sizeof(*sc->tts_data) *
6073  (sc->tts_count - (index_entry_pos + gap)));
6074 
6075  sti->nb_index_entries -= gap;
6076  sc->tts_count -= gap;
6077  if (index_entry_pos < sc->current_sample) {
6078  sc->current_sample -= gap;
6079  }
6080  entries = i;
6081  }
6082 
6083  // The end of this new fragment may overlap in time with the start
6084  // of the next fragment in index_entries. Mark the samples in the next
6085  // fragment that overlap with AVINDEX_DISCARD_FRAME
6086  prev_dts = AV_NOPTS_VALUE;
6087  if (index_entry_pos > 0)
6088  prev_dts = sti->index_entries[index_entry_pos-1].timestamp;
6089  for (int i = index_entry_pos; i < sti->nb_index_entries; i++) {
6090  if (prev_dts < sti->index_entries[i].timestamp)
6091  break;
6093  }
6094 
6095  // If a hole was created to insert the new index_entries into,
6096  // the index_entry recorded for all subsequent moof must
6097  // be incremented by the number of entries inserted.
6098  fix_frag_index_entries(&c->frag_index, next_frag_index,
6099  frag->track_id, entries);
6100 
6101  if (pb->eof_reached) {
6102  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted TRUN atom\n");
6103  return AVERROR_EOF;
6104  }
6105 
6106  frag->implicit_offset = offset;
6107 
6108  sc->track_end = dts + sc->time_offset;
6109  if (st->duration < sc->track_end)
6110  st->duration = sc->track_end;
6111 
6112  return 0;
6113 }
6114 
6116 {
6117  int64_t stream_size = avio_size(pb);
6118  int64_t offset = av_sat_add64(avio_tell(pb), atom.size), pts, timestamp;
6119  uint8_t version, is_complete;
6120  int64_t offadd;
6121  unsigned i, j, track_id, item_count;
6122  AVStream *st = NULL;
6123  AVStream *ref_st = NULL;
6124  MOVStreamContext *sc, *ref_sc = NULL;
6125  AVRational timescale;
6126 
6127  version = avio_r8(pb);
6128  if (version > 1) {
6129  avpriv_request_sample(c->fc, "sidx version %u", version);
6130  return 0;
6131  }
6132 
6133  avio_rb24(pb); // flags
6134 
6135  track_id = avio_rb32(pb); // Reference ID
6136  for (i = 0; i < c->fc->nb_streams; i++) {
6137  sc = c->fc->streams[i]->priv_data;
6138  if (sc->id == track_id) {
6139  st = c->fc->streams[i];
6140  break;
6141  }
6142  }
6143  if (!st) {
6144  av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %d\n", track_id);
6145  return 0;
6146  }
6147 
6148  sc = st->priv_data;
6149 
6150  timescale = av_make_q(1, avio_rb32(pb));
6151 
6152  if (timescale.den <= 0) {
6153  av_log(c->fc, AV_LOG_ERROR, "Invalid sidx timescale 1/%d\n", timescale.den);
6154  return AVERROR_INVALIDDATA;
6155  }
6156 
6157  if (version == 0) {
6158  pts = avio_rb32(pb);
6159  offadd= avio_rb32(pb);
6160  } else {
6161  pts = avio_rb64(pb);
6162  offadd= avio_rb64(pb);
6163  }
6164  if (av_sat_add64(offset, offadd) != offset + (uint64_t)offadd)
6165  return AVERROR_INVALIDDATA;
6166 
6167  offset += (uint64_t)offadd;
6168 
6169  avio_rb16(pb); // reserved
6170 
6171  item_count = avio_rb16(pb);
6172  if (item_count == 0)
6173  return AVERROR_INVALIDDATA;
6174 
6175  for (i = 0; i < item_count; i++) {
6176  int index;
6177  MOVFragmentStreamInfo * frag_stream_info;
6178  uint32_t size = avio_rb32(pb);
6179  uint32_t duration = avio_rb32(pb);
6180  if (size & 0x80000000) {
6181  avpriv_request_sample(c->fc, "sidx reference_type 1");
6182  return AVERROR_PATCHWELCOME;
6183  }
6184  avio_rb32(pb); // sap_flags
6185  timestamp = av_rescale_q(pts, timescale, st->time_base);
6186 
6188  frag_stream_info = get_frag_stream_info(&c->frag_index, index, track_id);
6189  if (frag_stream_info)
6190  frag_stream_info->sidx_pts = timestamp;
6191 
6192  if (av_sat_add64(offset, size) != offset + (uint64_t)size ||
6193  av_sat_add64(pts, duration) != pts + (uint64_t)duration
6194  )
6195  return AVERROR_INVALIDDATA;
6196  offset += size;
6197  pts += duration;
6198  }
6199 
6200  st->duration = sc->track_end = pts;
6201 
6202  sc->has_sidx = 1;
6203 
6204  // See if the remaining bytes are just an mfra which we can ignore.
6205  is_complete = offset == stream_size;
6206  if (!is_complete && (pb->seekable & AVIO_SEEKABLE_NORMAL) && stream_size > 0 ) {
6207  int64_t ret;
6208  int64_t original_pos = avio_tell(pb);
6209  if (!c->have_read_mfra_size) {
6210  if ((ret = avio_seek(pb, stream_size - 4, SEEK_SET)) < 0)
6211  return ret;
6212  c->mfra_size = avio_rb32(pb);
6213  c->have_read_mfra_size = 1;
6214  if ((ret = avio_seek(pb, original_pos, SEEK_SET)) < 0)
6215  return ret;
6216  }
6217  if (offset == stream_size - c->mfra_size)
6218  is_complete = 1;
6219  }
6220 
6221  if (is_complete) {
6222  // Find first entry in fragment index that came from an sidx.
6223  // This will pretty much always be the first entry.
6224  for (i = 0; i < c->frag_index.nb_items; i++) {
6225  MOVFragmentIndexItem * item = &c->frag_index.item[i];
6226  for (j = 0; ref_st == NULL && j < item->nb_stream_info; j++) {
6227  MOVFragmentStreamInfo * si;
6228  si = &item->stream_info[j];
6229  if (si->sidx_pts != AV_NOPTS_VALUE) {
6230  ref_st = c->fc->streams[j];
6231  ref_sc = ref_st->priv_data;
6232  break;
6233  }
6234  }
6235  }
6236  if (ref_st) for (i = 0; i < c->fc->nb_streams; i++) {
6237  st = c->fc->streams[i];
6238  sc = st->priv_data;
6239  if (!sc->has_sidx) {
6240  st->duration = sc->track_end = av_rescale(ref_st->duration, sc->time_scale, ref_sc->time_scale);
6241  }
6242  }
6243 
6244  if (offadd == 0)
6245  c->frag_index.complete = 1;
6246  }
6247 
6248  return 0;
6249 }
6250 
6251 /* this atom should be null (from specs), but some buggy files put the 'moov' atom inside it... */
6252 /* like the files created with Adobe Premiere 5.0, for samples see */
6253 /* http://graphics.tudelft.nl/~wouter/publications/soundtests/ */
6255 {
6256  int err;
6257 
6258  if (atom.size < 8)
6259  return 0; /* continue */
6260  if (avio_rb32(pb) != 0) { /* 0 sized mdat atom... use the 'wide' atom size */
6261  avio_skip(pb, atom.size - 4);
6262  return 0;
6263  }
6264  atom.type = avio_rl32(pb);
6265  atom.size -= 8;
6266  if (atom.type != MKTAG('m','d','a','t')) {
6267  avio_skip(pb, atom.size);
6268  return 0;
6269  }
6270  err = mov_read_mdat(c, pb, atom);
6271  return err;
6272 }
6273 
6275 {
6276 #if CONFIG_ZLIB
6277  FFIOContext ctx;
6278  uint8_t *cmov_data;
6279  uint8_t *moov_data; /* uncompressed data */
6280  long cmov_len, moov_len;
6281  int ret = -1;
6282 
6283  avio_rb32(pb); /* dcom atom */
6284  if (avio_rl32(pb) != MKTAG('d','c','o','m'))
6285  return AVERROR_INVALIDDATA;
6286  if (avio_rl32(pb) != MKTAG('z','l','i','b')) {
6287  av_log(c->fc, AV_LOG_ERROR, "unknown compression for cmov atom !\n");
6288  return AVERROR_INVALIDDATA;
6289  }
6290  avio_rb32(pb); /* cmvd atom */
6291  if (avio_rl32(pb) != MKTAG('c','m','v','d'))
6292  return AVERROR_INVALIDDATA;
6293  moov_len = avio_rb32(pb); /* uncompressed size */
6294  cmov_len = atom.size - 6 * 4;
6295 
6296  cmov_data = av_malloc(cmov_len);
6297  if (!cmov_data)
6298  return AVERROR(ENOMEM);
6299  moov_data = av_malloc(moov_len);
6300  if (!moov_data) {
6301  av_free(cmov_data);
6302  return AVERROR(ENOMEM);
6303  }
6304  ret = ffio_read_size(pb, cmov_data, cmov_len);
6305  if (ret < 0)
6306  goto free_and_return;
6307 
6309  if (uncompress (moov_data, (uLongf *) &moov_len, (const Bytef *)cmov_data, cmov_len) != Z_OK)
6310  goto free_and_return;
6311  ffio_init_read_context(&ctx, moov_data, moov_len);
6312  ctx.pub.seekable = AVIO_SEEKABLE_NORMAL;
6313  atom.type = MKTAG('m','o','o','v');
6314  atom.size = moov_len;
6315  ret = mov_read_default(c, &ctx.pub, atom);
6316 free_and_return:
6317  av_free(moov_data);
6318  av_free(cmov_data);
6319  return ret;
6320 #else
6321  av_log(c->fc, AV_LOG_ERROR, "this file requires zlib support compiled in\n");
6322  return AVERROR(ENOSYS);
6323 #endif
6324 }
6325 
6326 /* edit list atom */
6328 {
6329  MOVStreamContext *sc;
6330  int i, edit_count, version;
6331  int64_t elst_entry_size;
6332 
6333  if (c->fc->nb_streams < 1 || c->ignore_editlist)
6334  return 0;
6335  sc = c->fc->streams[c->fc->nb_streams-1]->priv_data;
6336 
6337  version = avio_r8(pb); /* version */
6338  avio_rb24(pb); /* flags */
6339  edit_count = avio_rb32(pb); /* entries */
6340  atom.size -= 8;
6341 
6342  elst_entry_size = version == 1 ? 20 : 12;
6343  if (atom.size != edit_count * elst_entry_size) {
6344  if (c->fc->strict_std_compliance >= FF_COMPLIANCE_STRICT) {
6345  av_log(c->fc, AV_LOG_ERROR, "Invalid edit list entry_count: %d for elst atom of size: %"PRId64" bytes.\n",
6346  edit_count, atom.size + 8);
6347  return AVERROR_INVALIDDATA;
6348  } else {
6349  edit_count = atom.size / elst_entry_size;
6350  if (edit_count * elst_entry_size != atom.size) {
6351  av_log(c->fc, AV_LOG_WARNING, "ELST atom of %"PRId64" bytes, bigger than %d entries.\n", atom.size, edit_count);
6352  }
6353  }
6354  }
6355 
6356  if (!edit_count)
6357  return 0;
6358  if (sc->elst_data)
6359  av_log(c->fc, AV_LOG_WARNING, "Duplicated ELST atom\n");
6360  av_free(sc->elst_data);
6361  sc->elst_count = 0;
6362  sc->elst_data = av_malloc_array(edit_count, sizeof(*sc->elst_data));
6363  if (!sc->elst_data)
6364  return AVERROR(ENOMEM);
6365 
6366  av_log(c->fc, AV_LOG_TRACE, "track[%u].edit_count = %i\n", c->fc->nb_streams - 1, edit_count);
6367  for (i = 0; i < edit_count && atom.size > 0 && !pb->eof_reached; i++) {
6368  MOVElst *e = &sc->elst_data[i];
6369 
6370  if (version == 1) {
6371  e->duration = avio_rb64(pb);
6372  e->time = avio_rb64(pb);
6373  atom.size -= 16;
6374  } else {
6375  e->duration = avio_rb32(pb); /* segment duration */
6376  e->time = (int32_t)avio_rb32(pb); /* media time */
6377  atom.size -= 8;
6378  }
6379  e->rate = avio_rb32(pb) / 65536.0;
6380  atom.size -= 4;
6381  av_log(c->fc, AV_LOG_TRACE, "duration=%"PRId64" time=%"PRId64" rate=%f\n",
6382  e->duration, e->time, e->rate);
6383 
6384  if (e->time < 0 && e->time != -1 &&
6385  c->fc->strict_std_compliance >= FF_COMPLIANCE_STRICT) {
6386  av_log(c->fc, AV_LOG_ERROR, "Track %d, edit %d: Invalid edit list media time=%"PRId64"\n",
6387  c->fc->nb_streams-1, i, e->time);
6388  return AVERROR_INVALIDDATA;
6389  }
6390  if (e->duration < 0) {
6391  av_log(c->fc, AV_LOG_ERROR, "Track %d, edit %d: Invalid edit list duration=%"PRId64"\n",
6392  c->fc->nb_streams-1, i, e->duration);
6393  return AVERROR_INVALIDDATA;
6394  }
6395  }
6396  sc->elst_count = i;
6397 
6398  return 0;
6399 }
6400 
6402 {
6403  MOVStreamContext *sc;
6404 
6405  if (c->fc->nb_streams < 1)
6406  return AVERROR_INVALIDDATA;
6407  sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
6408  sc->timecode_track = avio_rb32(pb);
6409  return 0;
6410 }
6411 
6413 {
6414  AVStream *st;
6415  int version, color_range, color_primaries, color_trc, color_space;
6416 
6417  if (c->fc->nb_streams < 1)
6418  return 0;
6419  st = c->fc->streams[c->fc->nb_streams - 1];
6420 
6421  if (atom.size < 5) {
6422  av_log(c->fc, AV_LOG_ERROR, "Empty VP Codec Configuration box\n");
6423  return AVERROR_INVALIDDATA;
6424  }
6425 
6426  version = avio_r8(pb);
6427  if (version != 1) {
6428  av_log(c->fc, AV_LOG_WARNING, "Unsupported VP Codec Configuration box version %d\n", version);
6429  return 0;
6430  }
6431  avio_skip(pb, 3); /* flags */
6432 
6433  avio_skip(pb, 2); /* profile + level */
6434  color_range = avio_r8(pb); /* bitDepth, chromaSubsampling, videoFullRangeFlag */
6435  color_primaries = avio_r8(pb);
6436  color_trc = avio_r8(pb);
6437  color_space = avio_r8(pb);
6438  if (avio_rb16(pb)) /* codecIntializationDataSize */
6439  return AVERROR_INVALIDDATA;
6440 
6443  if (!av_color_transfer_name(color_trc))
6444  color_trc = AVCOL_TRC_UNSPECIFIED;
6445  if (!av_color_space_name(color_space))
6446  color_space = AVCOL_SPC_UNSPECIFIED;
6447 
6450  st->codecpar->color_trc = color_trc;
6451  st->codecpar->color_space = color_space;
6452 
6453  return 0;
6454 }
6455 
6457 {
6458  MOVStreamContext *sc;
6459  int i, version;
6460 
6461  if (c->fc->nb_streams < 1)
6462  return AVERROR_INVALIDDATA;
6463 
6464  sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
6465 
6466  if (atom.size < 5) {
6467  av_log(c->fc, AV_LOG_ERROR, "Empty Mastering Display Metadata box\n");
6468  return AVERROR_INVALIDDATA;
6469  }
6470 
6471  version = avio_r8(pb);
6472  if (version) {
6473  av_log(c->fc, AV_LOG_WARNING, "Unsupported Mastering Display Metadata box version %d\n", version);
6474  return 0;
6475  }
6476  if (sc->mastering) {
6477  av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicate Mastering Display Metadata\n");
6478  return 0;
6479  }
6480 
6481  avio_skip(pb, 3); /* flags */
6482 
6484  if (!sc->mastering)
6485  return AVERROR(ENOMEM);
6486 
6487  for (i = 0; i < 3; i++) {
6488  sc->mastering->display_primaries[i][0] = av_make_q(avio_rb16(pb), 1 << 16);
6489  sc->mastering->display_primaries[i][1] = av_make_q(avio_rb16(pb), 1 << 16);
6490  }
6491  sc->mastering->white_point[0] = av_make_q(avio_rb16(pb), 1 << 16);
6492  sc->mastering->white_point[1] = av_make_q(avio_rb16(pb), 1 << 16);
6493 
6494  sc->mastering->max_luminance = av_make_q(avio_rb32(pb), 1 << 8);
6495  sc->mastering->min_luminance = av_make_q(avio_rb32(pb), 1 << 14);
6496 
6497  sc->mastering->has_primaries = 1;
6498  sc->mastering->has_luminance = 1;
6499 
6500  return 0;
6501 }
6502 
6504 {
6505  MOVStreamContext *sc;
6506  const int mapping[3] = {1, 2, 0};
6507  const int chroma_den = 50000;
6508  const int luma_den = 10000;
6509  int i;
6510 
6511  if (c->fc->nb_streams < 1)
6512  return AVERROR_INVALIDDATA;
6513 
6514  sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
6515 
6516  if (atom.size < 24) {
6517  av_log(c->fc, AV_LOG_ERROR, "Invalid Mastering Display Color Volume box\n");
6518  return AVERROR_INVALIDDATA;
6519  }
6520 
6521  if (sc->mastering) {
6522  av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicate Mastering Display Color Volume\n");
6523  return 0;
6524  }
6525 
6527  if (!sc->mastering)
6528  return AVERROR(ENOMEM);
6529 
6530  for (i = 0; i < 3; i++) {
6531  const int j = mapping[i];
6532  sc->mastering->display_primaries[j][0] = av_make_q(avio_rb16(pb), chroma_den);
6533  sc->mastering->display_primaries[j][1] = av_make_q(avio_rb16(pb), chroma_den);
6534  }
6535  sc->mastering->white_point[0] = av_make_q(avio_rb16(pb), chroma_den);
6536  sc->mastering->white_point[1] = av_make_q(avio_rb16(pb), chroma_den);
6537 
6538  sc->mastering->max_luminance = av_make_q(avio_rb32(pb), luma_den);
6539  sc->mastering->min_luminance = av_make_q(avio_rb32(pb), luma_den);
6540 
6541  sc->mastering->has_luminance = 1;
6542  sc->mastering->has_primaries = 1;
6543 
6544  return 0;
6545 }
6546 
6548 {
6549  MOVStreamContext *sc;
6550  int version;
6551 
6552  if (c->fc->nb_streams < 1)
6553  return AVERROR_INVALIDDATA;
6554 
6555  sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
6556 
6557  if (atom.size < 5) {
6558  av_log(c->fc, AV_LOG_ERROR, "Empty Content Light Level box\n");
6559  return AVERROR_INVALIDDATA;
6560  }
6561 
6562  version = avio_r8(pb);
6563  if (version) {
6564  av_log(c->fc, AV_LOG_WARNING, "Unsupported Content Light Level box version %d\n", version);
6565  return 0;
6566  }
6567  avio_skip(pb, 3); /* flags */
6568 
6569  if (sc->coll){
6570  av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicate COLL\n");
6571  return 0;
6572  }
6573 
6575  if (!sc->coll)
6576  return AVERROR(ENOMEM);
6577 
6578  sc->coll->MaxCLL = avio_rb16(pb);
6579  sc->coll->MaxFALL = avio_rb16(pb);
6580 
6581  return 0;
6582 }
6583 
6585 {
6586  MOVStreamContext *sc;
6587 
6588  if (c->fc->nb_streams < 1)
6589  return AVERROR_INVALIDDATA;
6590 
6591  sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
6592 
6593  if (atom.size < 4) {
6594  av_log(c->fc, AV_LOG_ERROR, "Empty Content Light Level Info box\n");
6595  return AVERROR_INVALIDDATA;
6596  }
6597 
6598  if (sc->coll){
6599  av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicate CLLI/COLL\n");
6600  return 0;
6601  }
6602 
6604  if (!sc->coll)
6605  return AVERROR(ENOMEM);
6606 
6607  sc->coll->MaxCLL = avio_rb16(pb);
6608  sc->coll->MaxFALL = avio_rb16(pb);
6609 
6610  return 0;
6611 }
6612 
6614 {
6615  MOVStreamContext *sc;
6616  const int illuminance_den = 10000;
6617  const int ambient_den = 50000;
6618  if (c->fc->nb_streams < 1)
6619  return AVERROR_INVALIDDATA;
6620  sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
6621  if (atom.size < 6) {
6622  av_log(c->fc, AV_LOG_ERROR, "Empty Ambient Viewing Environment Info box\n");
6623  return AVERROR_INVALIDDATA;
6624  }
6625  if (sc->ambient){
6626  av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicate AMVE\n");
6627  return 0;
6628  }
6630  if (!sc->ambient)
6631  return AVERROR(ENOMEM);
6632  sc->ambient->ambient_illuminance = av_make_q(avio_rb32(pb), illuminance_den);
6633  sc->ambient->ambient_light_x = av_make_q(avio_rb16(pb), ambient_den);
6634  sc->ambient->ambient_light_y = av_make_q(avio_rb16(pb), ambient_den);
6635  return 0;
6636 }
6637 
6639 {
6640  AVStream *st;
6641  MOVStreamContext *sc;
6642  enum AVStereo3DType type;
6643  int mode;
6644 
6645  if (c->fc->nb_streams < 1)
6646  return 0;
6647 
6648  st = c->fc->streams[c->fc->nb_streams - 1];
6649  sc = st->priv_data;
6650 
6651  if (atom.size < 5) {
6652  av_log(c->fc, AV_LOG_ERROR, "Empty stereoscopic video box\n");
6653  return AVERROR_INVALIDDATA;
6654  }
6655 
6656  if (sc->stereo3d)
6657  return AVERROR_INVALIDDATA;
6658 
6659  avio_skip(pb, 4); /* version + flags */
6660 
6661  mode = avio_r8(pb);
6662  switch (mode) {
6663  case 0:
6664  type = AV_STEREO3D_2D;
6665  break;
6666  case 1:
6668  break;
6669  case 2:
6671  break;
6672  default:
6673  av_log(c->fc, AV_LOG_WARNING, "Unknown st3d mode value %d\n", mode);
6674  return 0;
6675  }
6676 
6678  if (!sc->stereo3d)
6679  return AVERROR(ENOMEM);
6680 
6681  sc->stereo3d->type = type;
6682  return 0;
6683 }
6684 
6686 {
6687  AVStream *st;
6688  MOVStreamContext *sc;
6689  int size = 0;
6690  int64_t remaining;
6691  uint32_t tag = 0;
6693 
6694  if (c->fc->nb_streams < 1)
6695  return 0;
6696 
6697  st = c->fc->streams[c->fc->nb_streams - 1];
6698  sc = st->priv_data;
6699 
6700  remaining = atom.size;
6701  while (remaining > 0) {
6702  size = avio_rb32(pb);
6703  if (size < 8 || size > remaining ) {
6704  av_log(c->fc, AV_LOG_ERROR, "Invalid child size in pack box\n");
6705  return AVERROR_INVALIDDATA;
6706  }
6707 
6708  tag = avio_rl32(pb);
6709  switch (tag) {
6710  case MKTAG('p','k','i','n'): {
6711  if (size != 16) {
6712  av_log(c->fc, AV_LOG_ERROR, "Invalid size of pkin box: %d\n", size);
6713  return AVERROR_INVALIDDATA;
6714  }
6715  avio_skip(pb, 1); // version
6716  avio_skip(pb, 3); // flags
6717 
6718  tag = avio_rl32(pb);
6719  switch (tag) {
6720  case MKTAG('s','i','d','e'):
6722  break;
6723  case MKTAG('o','v','e','r'):
6725  break;
6726  case 0:
6727  // This means value will be set in another layer
6728  break;
6729  default:
6730  av_log(c->fc, AV_LOG_WARNING, "Unknown tag in pkin: %s\n",
6731  av_fourcc2str(tag));
6732  avio_skip(pb, size - 8);
6733  break;
6734  }
6735 
6736  break;
6737  }
6738  default:
6739  av_log(c->fc, AV_LOG_WARNING, "Unknown tag in pack: %s\n",
6740  av_fourcc2str(tag));
6741  avio_skip(pb, size - 8);
6742  break;
6743  }
6744  remaining -= size;
6745  }
6746 
6747  if (remaining != 0) {
6748  av_log(c->fc, AV_LOG_ERROR, "Broken pack box\n");
6749  return AVERROR_INVALIDDATA;
6750  }
6751 
6752  if (type == AV_STEREO3D_2D)
6753  return 0;
6754 
6755  if (!sc->stereo3d) {
6757  if (!sc->stereo3d)
6758  return AVERROR(ENOMEM);
6759  }
6760 
6761  sc->stereo3d->type = type;
6762 
6763  return 0;
6764 }
6765 
6767 {
6768  AVStream *st;
6769  MOVStreamContext *sc;
6770  int size, version, layout;
6771  int32_t yaw, pitch, roll;
6772  uint32_t l = 0, t = 0, r = 0, b = 0;
6773  uint32_t tag, padding = 0;
6774  enum AVSphericalProjection projection;
6775 
6776  if (c->fc->nb_streams < 1)
6777  return 0;
6778 
6779  st = c->fc->streams[c->fc->nb_streams - 1];
6780  sc = st->priv_data;
6781 
6782  if (atom.size < 8) {
6783  av_log(c->fc, AV_LOG_ERROR, "Empty spherical video box\n");
6784  return AVERROR_INVALIDDATA;
6785  }
6786 
6787  size = avio_rb32(pb);
6788  if (size <= 12 || size > atom.size)
6789  return AVERROR_INVALIDDATA;
6790 
6791  tag = avio_rl32(pb);
6792  if (tag != MKTAG('s','v','h','d')) {
6793  av_log(c->fc, AV_LOG_ERROR, "Missing spherical video header\n");
6794  return 0;
6795  }
6796  version = avio_r8(pb);
6797  if (version != 0) {
6798  av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
6799  version);
6800  return 0;
6801  }
6802  avio_skip(pb, 3); /* flags */
6803  avio_skip(pb, size - 12); /* metadata_source */
6804 
6805  size = avio_rb32(pb);
6806  if (size > atom.size)
6807  return AVERROR_INVALIDDATA;
6808 
6809  tag = avio_rl32(pb);
6810  if (tag != MKTAG('p','r','o','j')) {
6811  av_log(c->fc, AV_LOG_ERROR, "Missing projection box\n");
6812  return 0;
6813  }
6814 
6815  size = avio_rb32(pb);
6816  if (size > atom.size)
6817  return AVERROR_INVALIDDATA;
6818 
6819  tag = avio_rl32(pb);
6820  if (tag != MKTAG('p','r','h','d')) {
6821  av_log(c->fc, AV_LOG_ERROR, "Missing projection header box\n");
6822  return 0;
6823  }
6824  version = avio_r8(pb);
6825  if (version != 0) {
6826  av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
6827  version);
6828  return 0;
6829  }
6830  avio_skip(pb, 3); /* flags */
6831 
6832  /* 16.16 fixed point */
6833  yaw = avio_rb32(pb);
6834  pitch = avio_rb32(pb);
6835  roll = avio_rb32(pb);
6836 
6837  size = avio_rb32(pb);
6838  if (size > atom.size)
6839  return AVERROR_INVALIDDATA;
6840 
6841  tag = avio_rl32(pb);
6842  version = avio_r8(pb);
6843  if (version != 0) {
6844  av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
6845  version);
6846  return 0;
6847  }
6848  avio_skip(pb, 3); /* flags */
6849  switch (tag) {
6850  case MKTAG('c','b','m','p'):
6851  layout = avio_rb32(pb);
6852  if (layout) {
6853  av_log(c->fc, AV_LOG_WARNING,
6854  "Unsupported cubemap layout %d\n", layout);
6855  return 0;
6856  }
6857  projection = AV_SPHERICAL_CUBEMAP;
6858  padding = avio_rb32(pb);
6859  break;
6860  case MKTAG('e','q','u','i'):
6861  t = avio_rb32(pb);
6862  b = avio_rb32(pb);
6863  l = avio_rb32(pb);
6864  r = avio_rb32(pb);
6865 
6866  if (b >= UINT_MAX - t || r >= UINT_MAX - l) {
6867  av_log(c->fc, AV_LOG_ERROR,
6868  "Invalid bounding rectangle coordinates "
6869  "%"PRIu32",%"PRIu32",%"PRIu32",%"PRIu32"\n", l, t, r, b);
6870  return AVERROR_INVALIDDATA;
6871  }
6872 
6873  if (l || t || r || b)
6874  projection = AV_SPHERICAL_EQUIRECTANGULAR_TILE;
6875  else
6876  projection = AV_SPHERICAL_EQUIRECTANGULAR;
6877  break;
6878  default:
6879  av_log(c->fc, AV_LOG_ERROR, "Unknown projection type: %s\n", av_fourcc2str(tag));
6880  return 0;
6881  }
6882 
6884  if (!sc->spherical)
6885  return AVERROR(ENOMEM);
6886 
6887  sc->spherical->projection = projection;
6888 
6889  sc->spherical->yaw = yaw;
6890  sc->spherical->pitch = pitch;
6891  sc->spherical->roll = roll;
6892 
6893  sc->spherical->padding = padding;
6894 
6895  sc->spherical->bound_left = l;
6896  sc->spherical->bound_top = t;
6897  sc->spherical->bound_right = r;
6898  sc->spherical->bound_bottom = b;
6899 
6900  return 0;
6901 }
6902 
6904 {
6905  AVStream *st;
6906  MOVStreamContext *sc;
6907  int size;
6908  uint32_t tag;
6909  enum AVSphericalProjection projection;
6910 
6911  if (c->fc->nb_streams < 1)
6912  return 0;
6913 
6914  st = c->fc->streams[c->fc->nb_streams - 1];
6915  sc = st->priv_data;
6916 
6917  if (atom.size < 16) {
6918  av_log(c->fc, AV_LOG_ERROR, "Invalid size for proj box: %"PRIu64"\n", atom.size);
6919  return AVERROR_INVALIDDATA;
6920  }
6921 
6922  size = avio_rb32(pb);
6923  if (size < 16) {
6924  av_log(c->fc, AV_LOG_ERROR, "Invalid size for prji box: %d\n", size);
6925  return AVERROR_INVALIDDATA;
6926  } else if (size > 16) {
6927  av_log(c->fc, AV_LOG_WARNING, "Box has more bytes (%d) than prji box required (16) \n", size);
6928  }
6929 
6930  tag = avio_rl32(pb);
6931  if (tag != MKTAG('p','r','j','i')) {
6932  av_log(c->fc, AV_LOG_ERROR, "Invalid child box of proj box: %s\n",
6933  av_fourcc2str(tag));
6934  return AVERROR_INVALIDDATA;
6935  }
6936 
6937  // version and flags, only support (0, 0)
6938  unsigned n = avio_rl32(pb);
6939  if (n != 0) {
6940  av_log(c->fc, AV_LOG_ERROR, "prji version %u, flag %u are not supported\n",
6941  n & 0xFF, n >> 8);
6942  return AVERROR_PATCHWELCOME;
6943  }
6944 
6945  tag = avio_rl32(pb);
6946  switch (tag) {
6947  case MKTAG('r','e','c','t'):
6948  projection = AV_SPHERICAL_RECTILINEAR;
6949  break;
6950  case MKTAG('e','q','u','i'):
6951  projection = AV_SPHERICAL_EQUIRECTANGULAR;
6952  break;
6953  case MKTAG('h','e','q','u'):
6954  projection = AV_SPHERICAL_HALF_EQUIRECTANGULAR;
6955  break;
6956  case MKTAG('f','i','s','h'):
6957  projection = AV_SPHERICAL_FISHEYE;
6958  break;
6959  case MKTAG('p','r','i','m'):
6960  projection = AV_SPHERICAL_PARAMETRIC_IMMERSIVE;
6961  break;
6962  default:
6963  av_log(c->fc, AV_LOG_ERROR, "Invalid projection type in prji box: %s\n", av_fourcc2str(tag));
6964  return AVERROR_INVALIDDATA;
6965  }
6966 
6968  if (!sc->spherical)
6969  return AVERROR(ENOMEM);
6970 
6971  sc->spherical->projection = projection;
6972 
6973  return 0;
6974 }
6975 
6977 {
6978  AVStream *st;
6979  MOVStreamContext *sc;
6980  int size, flags = 0;
6981  int64_t remaining;
6982  uint32_t tag, baseline = 0;
6985  enum AVStereo3DPrimaryEye primary_eye = AV_PRIMARY_EYE_NONE;
6986  AVRational horizontal_disparity_adjustment = { 0, 1 };
6987 
6988  if (c->fc->nb_streams < 1)
6989  return 0;
6990 
6991  st = c->fc->streams[c->fc->nb_streams - 1];
6992  sc = st->priv_data;
6993 
6994  remaining = atom.size;
6995  while (remaining > 0) {
6996  size = avio_rb32(pb);
6997  if (size < 8 || size > remaining ) {
6998  av_log(c->fc, AV_LOG_ERROR, "Invalid child size in eyes box\n");
6999  return AVERROR_INVALIDDATA;
7000  }
7001 
7002  tag = avio_rl32(pb);
7003  switch (tag) {
7004  case MKTAG('s','t','r','i'): {
7005  int has_right, has_left;
7006  uint8_t tmp;
7007  if (size != 13) {
7008  av_log(c->fc, AV_LOG_ERROR, "Invalid size of stri box: %d\n", size);
7009  return AVERROR_INVALIDDATA;
7010  }
7011  avio_skip(pb, 1); // version
7012  avio_skip(pb, 3); // flags
7013 
7014  tmp = avio_r8(pb);
7015 
7016  // eye_views_reversed
7017  if (tmp & 8) {
7019  }
7020  // has_additional_views
7021  if (tmp & 4) {
7022  // skip...
7023  }
7024 
7025  has_right = tmp & 2; // has_right_eye_view
7026  has_left = tmp & 1; // has_left_eye_view
7027 
7028  if (has_left && has_right)
7029  view = AV_STEREO3D_VIEW_PACKED;
7030  else if (has_left)
7031  view = AV_STEREO3D_VIEW_LEFT;
7032  else if (has_right)
7033  view = AV_STEREO3D_VIEW_RIGHT;
7034  if (has_left || has_right)
7036 
7037  break;
7038  }
7039  case MKTAG('h','e','r','o'): {
7040  int tmp;
7041  if (size != 13) {
7042  av_log(c->fc, AV_LOG_ERROR, "Invalid size of hero box: %d\n", size);
7043  return AVERROR_INVALIDDATA;
7044  }
7045  avio_skip(pb, 1); // version
7046  avio_skip(pb, 3); // flags
7047 
7048  tmp = avio_r8(pb);
7049  if (tmp == 0)
7050  primary_eye = AV_PRIMARY_EYE_NONE;
7051  else if (tmp == 1)
7052  primary_eye = AV_PRIMARY_EYE_LEFT;
7053  else if (tmp == 2)
7054  primary_eye = AV_PRIMARY_EYE_RIGHT;
7055  else
7056  av_log(c->fc, AV_LOG_WARNING, "Unknown hero eye type: %d\n", tmp);
7057 
7058  break;
7059  }
7060  case MKTAG('c','a','m','s'): {
7061  uint32_t subtag;
7062  int subsize;
7063  if (size != 24) {
7064  av_log(c->fc, AV_LOG_ERROR, "Invalid size of cams box: %d\n", size);
7065  return AVERROR_INVALIDDATA;
7066  }
7067 
7068  subsize = avio_rb32(pb);
7069  if (subsize != 16) {
7070  av_log(c->fc, AV_LOG_ERROR, "Invalid size of blin box: %d\n", size);
7071  return AVERROR_INVALIDDATA;
7072  }
7073 
7074  subtag = avio_rl32(pb);
7075  if (subtag != MKTAG('b','l','i','n')) {
7076  av_log(c->fc, AV_LOG_ERROR, "Expected blin box, got %s\n",
7077  av_fourcc2str(subtag));
7078  return AVERROR_INVALIDDATA;
7079  }
7080 
7081  avio_skip(pb, 1); // version
7082  avio_skip(pb, 3); // flags
7083 
7084  baseline = avio_rb32(pb);
7085 
7086  break;
7087  }
7088  case MKTAG('c','m','f','y'): {
7089  uint32_t subtag;
7090  int subsize;
7091  int32_t adjustment;
7092  if (size != 24) {
7093  av_log(c->fc, AV_LOG_ERROR, "Invalid size of cmfy box: %d\n", size);
7094  return AVERROR_INVALIDDATA;
7095  }
7096 
7097  subsize = avio_rb32(pb);
7098  if (subsize != 16) {
7099  av_log(c->fc, AV_LOG_ERROR, "Invalid size of dadj box: %d\n", size);
7100  return AVERROR_INVALIDDATA;
7101  }
7102 
7103  subtag = avio_rl32(pb);
7104  if (subtag != MKTAG('d','a','d','j')) {
7105  av_log(c->fc, AV_LOG_ERROR, "Expected dadj box, got %s\n",
7106  av_fourcc2str(subtag));
7107  return AVERROR_INVALIDDATA;
7108  }
7109 
7110  avio_skip(pb, 1); // version
7111  avio_skip(pb, 3); // flags
7112 
7113  adjustment = (int32_t) avio_rb32(pb);
7114 
7115  horizontal_disparity_adjustment.num = (int) adjustment;
7116  horizontal_disparity_adjustment.den = 10000;
7117 
7118  break;
7119  }
7120  default:
7121  av_log(c->fc, AV_LOG_WARNING, "Unknown tag in eyes: %s\n",
7122  av_fourcc2str(tag));
7123  avio_skip(pb, size - 8);
7124  break;
7125  }
7126  remaining -= size;
7127  }
7128 
7129  if (remaining != 0) {
7130  av_log(c->fc, AV_LOG_ERROR, "Broken eyes box\n");
7131  return AVERROR_INVALIDDATA;
7132  }
7133 
7134  if (type == AV_STEREO3D_2D)
7135  return 0;
7136 
7137  if (!sc->stereo3d) {
7139  if (!sc->stereo3d)
7140  return AVERROR(ENOMEM);
7141  }
7142 
7143  sc->stereo3d->flags = flags;
7144  sc->stereo3d->type = type;
7145  sc->stereo3d->view = view;
7146  sc->stereo3d->primary_eye = primary_eye;
7147  sc->stereo3d->baseline = baseline;
7148  sc->stereo3d->horizontal_disparity_adjustment = horizontal_disparity_adjustment;
7149 
7150  return 0;
7151 }
7152 
7154 {
7155  int size;
7156  int64_t remaining;
7157  uint32_t tag;
7158 
7159  if (c->fc->nb_streams < 1)
7160  return 0;
7161 
7162  if (atom.size < 8) {
7163  av_log(c->fc, AV_LOG_ERROR, "Empty video extension usage box\n");
7164  return AVERROR_INVALIDDATA;
7165  }
7166 
7167  remaining = atom.size;
7168  while (remaining > 0) {
7169  size = avio_rb32(pb);
7170  if (size < 8 || size > remaining ) {
7171  av_log(c->fc, AV_LOG_ERROR, "Invalid child size in vexu box\n");
7172  return AVERROR_INVALIDDATA;
7173  }
7174 
7175  tag = avio_rl32(pb);
7176  switch (tag) {
7177  case MKTAG('p','r','o','j'): {
7178  MOVAtom proj = { tag, size - 8 };
7179  int ret = mov_read_vexu_proj(c, pb, proj);
7180  if (ret < 0)
7181  return ret;
7182  break;
7183  }
7184  case MKTAG('e','y','e','s'): {
7185  MOVAtom eyes = { tag, size - 8 };
7186  int ret = mov_read_eyes(c, pb, eyes);
7187  if (ret < 0)
7188  return ret;
7189  break;
7190  }
7191  case MKTAG('p','a','c','k'): {
7192  MOVAtom pack = { tag, size - 8 };
7193  int ret = mov_read_pack(c, pb, pack);
7194  if (ret < 0)
7195  return ret;
7196  break;
7197  }
7198  default:
7199  av_log(c->fc, AV_LOG_WARNING, "Unknown tag in vexu: %s\n",
7200  av_fourcc2str(tag));
7201  avio_skip(pb, size - 8);
7202  break;
7203  }
7204  remaining -= size;
7205  }
7206 
7207  if (remaining != 0) {
7208  av_log(c->fc, AV_LOG_ERROR, "Broken vexu box\n");
7209  return AVERROR_INVALIDDATA;
7210  }
7211 
7212  return 0;
7213 }
7214 
7216 {
7217  AVStream *st;
7218  MOVStreamContext *sc;
7219 
7220  if (c->fc->nb_streams < 1)
7221  return 0;
7222 
7223  st = c->fc->streams[c->fc->nb_streams - 1];
7224  sc = st->priv_data;
7225 
7226  if (atom.size != 4) {
7227  av_log(c->fc, AV_LOG_ERROR, "Invalid size of hfov box: %"PRIu64"\n", atom.size);
7228  return AVERROR_INVALIDDATA;
7229  }
7230 
7231 
7232  if (!sc->stereo3d) {
7234  if (!sc->stereo3d)
7235  return AVERROR(ENOMEM);
7236  }
7237 
7239  sc->stereo3d->horizontal_field_of_view.den = 1000; // thousands of a degree
7240 
7241  return 0;
7242 }
7243 
7245 {
7246  int ret = 0;
7247  uint8_t *buffer = av_malloc(len + 1);
7248  const char *val;
7249 
7250  if (!buffer)
7251  return AVERROR(ENOMEM);
7252  buffer[len] = '\0';
7253 
7254  ret = ffio_read_size(pb, buffer, len);
7255  if (ret < 0)
7256  goto out;
7257 
7258  /* Check for mandatory keys and values, try to support XML as best-effort */
7259  if (!sc->spherical &&
7260  av_stristr(buffer, "<GSpherical:StitchingSoftware>") &&
7261  (val = av_stristr(buffer, "<GSpherical:Spherical>")) &&
7262  av_stristr(val, "true") &&
7263  (val = av_stristr(buffer, "<GSpherical:Stitched>")) &&
7264  av_stristr(val, "true") &&
7265  (val = av_stristr(buffer, "<GSpherical:ProjectionType>")) &&
7266  av_stristr(val, "equirectangular")) {
7268  if (!sc->spherical)
7269  goto out;
7270 
7272 
7273  if (av_stristr(buffer, "<GSpherical:StereoMode>") && !sc->stereo3d) {
7274  enum AVStereo3DType mode;
7275 
7276  if (av_stristr(buffer, "left-right"))
7278  else if (av_stristr(buffer, "top-bottom"))
7280  else
7281  mode = AV_STEREO3D_2D;
7282 
7284  if (!sc->stereo3d)
7285  goto out;
7286 
7287  sc->stereo3d->type = mode;
7288  }
7289 
7290  /* orientation */
7291  val = av_stristr(buffer, "<GSpherical:InitialViewHeadingDegrees>");
7292  if (val)
7293  sc->spherical->yaw = strtol(val, NULL, 10) * (1 << 16);
7294  val = av_stristr(buffer, "<GSpherical:InitialViewPitchDegrees>");
7295  if (val)
7296  sc->spherical->pitch = strtol(val, NULL, 10) * (1 << 16);
7297  val = av_stristr(buffer, "<GSpherical:InitialViewRollDegrees>");
7298  if (val)
7299  sc->spherical->roll = strtol(val, NULL, 10) * (1 << 16);
7300  }
7301 
7302 out:
7303  av_free(buffer);
7304  return ret;
7305 }
7306 
7308 {
7309  AVStream *st;
7310  MOVStreamContext *sc;
7311  int64_t ret;
7312  AVUUID uuid;
7313  static const AVUUID uuid_isml_manifest = {
7314  0xa5, 0xd4, 0x0b, 0x30, 0xe8, 0x14, 0x11, 0xdd,
7315  0xba, 0x2f, 0x08, 0x00, 0x20, 0x0c, 0x9a, 0x66
7316  };
7317  static const AVUUID uuid_xmp = {
7318  0xbe, 0x7a, 0xcf, 0xcb, 0x97, 0xa9, 0x42, 0xe8,
7319  0x9c, 0x71, 0x99, 0x94, 0x91, 0xe3, 0xaf, 0xac
7320  };
7321  static const AVUUID uuid_spherical = {
7322  0xff, 0xcc, 0x82, 0x63, 0xf8, 0x55, 0x4a, 0x93,
7323  0x88, 0x14, 0x58, 0x7a, 0x02, 0x52, 0x1f, 0xdd,
7324  };
7325 
7326  if (atom.size < AV_UUID_LEN || atom.size >= FFMIN(INT_MAX, SIZE_MAX))
7327  return AVERROR_INVALIDDATA;
7328 
7329  if (c->fc->nb_streams < 1)
7330  return 0;
7331  st = c->fc->streams[c->fc->nb_streams - 1];
7332  sc = st->priv_data;
7333 
7334  ret = ffio_read_size(pb, uuid, AV_UUID_LEN);
7335  if (ret < 0)
7336  return ret;
7337  if (av_uuid_equal(uuid, uuid_isml_manifest)) {
7338  uint8_t *buffer, *ptr;
7339  char *endptr;
7340  size_t len = atom.size - AV_UUID_LEN;
7341 
7342  if (len < 4) {
7343  return AVERROR_INVALIDDATA;
7344  }
7345  ret = avio_skip(pb, 4); // zeroes
7346  len -= 4;
7347 
7348  buffer = av_mallocz(len + 1);
7349  if (!buffer) {
7350  return AVERROR(ENOMEM);
7351  }
7352  ret = ffio_read_size(pb, buffer, len);
7353  if (ret < 0) {
7354  av_free(buffer);
7355  return ret;
7356  }
7357 
7358  ptr = buffer;
7359  while ((ptr = av_stristr(ptr, "systemBitrate=\""))) {
7360  ptr += sizeof("systemBitrate=\"") - 1;
7361  c->bitrates_count++;
7362  c->bitrates = av_realloc_f(c->bitrates, c->bitrates_count, sizeof(*c->bitrates));
7363  if (!c->bitrates) {
7364  c->bitrates_count = 0;
7365  av_free(buffer);
7366  return AVERROR(ENOMEM);
7367  }
7368  errno = 0;
7369  ret = strtol(ptr, &endptr, 10);
7370  if (ret < 0 || errno || *endptr != '"') {
7371  c->bitrates[c->bitrates_count - 1] = 0;
7372  } else {
7373  c->bitrates[c->bitrates_count - 1] = ret;
7374  }
7375  }
7376 
7377  av_free(buffer);
7378  } else if (av_uuid_equal(uuid, uuid_xmp)) {
7379  uint8_t *buffer;
7380  size_t len = atom.size - AV_UUID_LEN;
7381  if (c->export_xmp) {
7382  buffer = av_mallocz(len + 1);
7383  if (!buffer) {
7384  return AVERROR(ENOMEM);
7385  }
7386  ret = ffio_read_size(pb, buffer, len);
7387  if (ret < 0) {
7388  av_free(buffer);
7389  return ret;
7390  }
7391  buffer[len] = '\0';
7392  av_dict_set(&c->fc->metadata, "xmp",
7394  } else {
7395  // skip all uuid atom, which makes it fast for long uuid-xmp file
7396  ret = avio_skip(pb, len);
7397  if (ret < 0)
7398  return ret;
7399  }
7400  } else if (av_uuid_equal(uuid, uuid_spherical)) {
7401  size_t len = atom.size - AV_UUID_LEN;
7402  ret = mov_parse_uuid_spherical(sc, pb, len);
7403  if (ret < 0)
7404  return ret;
7405  if (!sc->spherical)
7406  av_log(c->fc, AV_LOG_WARNING, "Invalid spherical metadata found\n");
7407  }
7408 
7409  return 0;
7410 }
7411 
7413 {
7414  int ret;
7415  uint8_t content[16];
7416 
7417  if (atom.size < 8)
7418  return 0;
7419 
7420  ret = ffio_read_size(pb, content, FFMIN(sizeof(content), atom.size));
7421  if (ret < 0)
7422  return ret;
7423 
7424  if ( !c->found_moov
7425  && !c->found_mdat
7426  && !memcmp(content, "Anevia\x1A\x1A", 8)
7427  && c->use_mfra_for == FF_MOV_FLAG_MFRA_AUTO) {
7428  c->use_mfra_for = FF_MOV_FLAG_MFRA_PTS;
7429  }
7430 
7431  return 0;
7432 }
7433 
7435 {
7436  uint32_t format = avio_rl32(pb);
7437  MOVStreamContext *sc;
7438  enum AVCodecID id;
7439  AVStream *st;
7440 
7441  if (c->fc->nb_streams < 1)
7442  return 0;
7443  st = c->fc->streams[c->fc->nb_streams - 1];
7444  sc = st->priv_data;
7445 
7446  switch (sc->format)
7447  {
7448  case MKTAG('e','n','c','v'): // encrypted video
7449  case MKTAG('e','n','c','a'): // encrypted audio
7450  id = mov_codec_id(st, format);
7451  if (st->codecpar->codec_id != AV_CODEC_ID_NONE &&
7452  st->codecpar->codec_id != id) {
7453  av_log(c->fc, AV_LOG_WARNING,
7454  "ignoring 'frma' atom of '%.4s', stream has codec id %d\n",
7455  (char*)&format, st->codecpar->codec_id);
7456  break;
7457  }
7458 
7459  st->codecpar->codec_id = id;
7460  sc->format = format;
7461  break;
7462 
7463  default:
7464  if (format != sc->format) {
7465  av_log(c->fc, AV_LOG_WARNING,
7466  "ignoring 'frma' atom of '%.4s', stream format is '%.4s'\n",
7467  (char*)&format, (char*)&sc->format);
7468  }
7469  break;
7470  }
7471 
7472  return 0;
7473 }
7474 
7475 /**
7476  * Gets the current encryption info and associated current stream context. If
7477  * we are parsing a track fragment, this will return the specific encryption
7478  * info for this fragment; otherwise this will return the global encryption
7479  * info for the current stream.
7480  */
7482 {
7483  MOVFragmentStreamInfo *frag_stream_info;
7484  AVStream *st;
7485  int i;
7486 
7487  frag_stream_info = get_current_frag_stream_info(&c->frag_index);
7488  if (frag_stream_info) {
7489  for (i = 0; i < c->fc->nb_streams; i++) {
7490  *sc = c->fc->streams[i]->priv_data;
7491  if ((*sc)->id == frag_stream_info->id) {
7492  st = c->fc->streams[i];
7493  break;
7494  }
7495  }
7496  if (i == c->fc->nb_streams)
7497  return 0;
7498  *sc = st->priv_data;
7499 
7500  if (!frag_stream_info->encryption_index) {
7501  // If this stream isn't encrypted, don't create the index.
7502  if (!(*sc)->cenc.default_encrypted_sample)
7503  return 0;
7504  frag_stream_info->encryption_index = av_mallocz(sizeof(*frag_stream_info->encryption_index));
7505  if (!frag_stream_info->encryption_index)
7506  return AVERROR(ENOMEM);
7507  }
7508  *encryption_index = frag_stream_info->encryption_index;
7509  return 1;
7510  } else {
7511  // No current track fragment, using stream level encryption info.
7512 
7513  if (c->fc->nb_streams < 1)
7514  return 0;
7515  st = c->fc->streams[c->fc->nb_streams - 1];
7516  *sc = st->priv_data;
7517 
7518  if (!(*sc)->cenc.encryption_index) {
7519  // If this stream isn't encrypted, don't create the index.
7520  if (!(*sc)->cenc.default_encrypted_sample)
7521  return 0;
7522  (*sc)->cenc.encryption_index = av_mallocz(sizeof(*frag_stream_info->encryption_index));
7523  if (!(*sc)->cenc.encryption_index)
7524  return AVERROR(ENOMEM);
7525  }
7526 
7527  *encryption_index = (*sc)->cenc.encryption_index;
7528  return 1;
7529  }
7530 }
7531 
7533 {
7534  int i, ret;
7535  unsigned int subsample_count;
7536  AVSubsampleEncryptionInfo *subsamples;
7537 
7538  if (!sc->cenc.default_encrypted_sample) {
7539  av_log(c->fc, AV_LOG_ERROR, "Missing schm or tenc\n");
7540  return AVERROR_INVALIDDATA;
7541  }
7542 
7543  if (sc->cenc.per_sample_iv_size || use_subsamples) {
7545  if (!*sample)
7546  return AVERROR(ENOMEM);
7547  } else
7548  *sample = NULL;
7549 
7550  if (sc->cenc.per_sample_iv_size != 0) {
7551  if ((ret = ffio_read_size(pb, (*sample)->iv, sc->cenc.per_sample_iv_size)) < 0) {
7552  av_log(c->fc, AV_LOG_ERROR, "failed to read the initialization vector\n");
7554  *sample = NULL;
7555  return ret;
7556  }
7557  }
7558 
7559  if (use_subsamples) {
7560  subsample_count = avio_rb16(pb);
7561  av_free((*sample)->subsamples);
7562  (*sample)->subsamples = av_calloc(subsample_count, sizeof(*subsamples));
7563  if (!(*sample)->subsamples) {
7565  *sample = NULL;
7566  return AVERROR(ENOMEM);
7567  }
7568 
7569  for (i = 0; i < subsample_count && !pb->eof_reached; i++) {
7570  (*sample)->subsamples[i].bytes_of_clear_data = avio_rb16(pb);
7571  (*sample)->subsamples[i].bytes_of_protected_data = avio_rb32(pb);
7572  }
7573 
7574  if (pb->eof_reached) {
7575  av_log(c->fc, AV_LOG_ERROR, "hit EOF while reading sub-sample encryption info\n");
7577  *sample = NULL;
7578  return AVERROR_INVALIDDATA;
7579  }
7580  (*sample)->subsample_count = subsample_count;
7581  }
7582 
7583  return 0;
7584 }
7585 
7587 {
7588  AVEncryptionInfo **encrypted_samples;
7589  MOVEncryptionIndex *encryption_index;
7590  MOVStreamContext *sc;
7591  int use_subsamples, ret;
7592  unsigned int sample_count, i, alloc_size = 0;
7593 
7594  ret = get_current_encryption_info(c, &encryption_index, &sc);
7595  if (ret != 1)
7596  return ret;
7597 
7598  if (encryption_index->nb_encrypted_samples) {
7599  // This can happen if we have both saio/saiz and senc atoms.
7600  av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in senc\n");
7601  return 0;
7602  }
7603 
7604  avio_r8(pb); /* version */
7605  use_subsamples = avio_rb24(pb) & 0x02; /* flags */
7606 
7607  sample_count = avio_rb32(pb);
7608  if (sample_count >= INT_MAX / sizeof(*encrypted_samples))
7609  return AVERROR(ENOMEM);
7610 
7611  for (i = 0; i < sample_count; i++) {
7612  unsigned int min_samples = FFMIN(FFMAX(i + 1, 1024 * 1024), sample_count);
7613  encrypted_samples = av_fast_realloc(encryption_index->encrypted_samples, &alloc_size,
7614  min_samples * sizeof(*encrypted_samples));
7615  if (encrypted_samples) {
7616  encryption_index->encrypted_samples = encrypted_samples;
7617 
7619  c, pb, sc, &encryption_index->encrypted_samples[i], use_subsamples);
7620  } else {
7621  ret = AVERROR(ENOMEM);
7622  }
7623  if (pb->eof_reached) {
7624  av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading senc\n");
7625  if (ret >= 0)
7626  av_encryption_info_free(encryption_index->encrypted_samples[i]);
7628  }
7629 
7630  if (ret < 0) {
7631  for (; i > 0; i--)
7632  av_encryption_info_free(encryption_index->encrypted_samples[i - 1]);
7633  av_freep(&encryption_index->encrypted_samples);
7634  return ret;
7635  }
7636  }
7637  encryption_index->nb_encrypted_samples = sample_count;
7638 
7639  return 0;
7640 }
7641 
7643 {
7644  AVEncryptionInfo **sample, **encrypted_samples;
7645  int64_t prev_pos;
7646  size_t sample_count, sample_info_size, i;
7647  int ret = 0;
7648  unsigned int alloc_size = 0;
7649 
7650  if (encryption_index->nb_encrypted_samples)
7651  return 0;
7652  sample_count = encryption_index->auxiliary_info_sample_count;
7653  if (encryption_index->auxiliary_offsets_count != 1) {
7654  av_log(c->fc, AV_LOG_ERROR, "Multiple auxiliary info chunks are not supported\n");
7655  return AVERROR_PATCHWELCOME;
7656  }
7657  if (sample_count >= INT_MAX / sizeof(*encrypted_samples))
7658  return AVERROR(ENOMEM);
7659 
7660  prev_pos = avio_tell(pb);
7661  if (!(pb->seekable & AVIO_SEEKABLE_NORMAL) ||
7662  avio_seek(pb, encryption_index->auxiliary_offsets[0], SEEK_SET) != encryption_index->auxiliary_offsets[0]) {
7663  av_log(c->fc, AV_LOG_INFO, "Failed to seek for auxiliary info, will only parse senc atoms for encryption info\n");
7664  goto finish;
7665  }
7666 
7667  for (i = 0; i < sample_count && !pb->eof_reached; i++) {
7668  unsigned int min_samples = FFMIN(FFMAX(i + 1, 1024 * 1024), sample_count);
7669  encrypted_samples = av_fast_realloc(encryption_index->encrypted_samples, &alloc_size,
7670  min_samples * sizeof(*encrypted_samples));
7671  if (!encrypted_samples) {
7672  ret = AVERROR(ENOMEM);
7673  goto finish;
7674  }
7675  encryption_index->encrypted_samples = encrypted_samples;
7676 
7677  sample = &encryption_index->encrypted_samples[i];
7678  sample_info_size = encryption_index->auxiliary_info_default_size
7679  ? encryption_index->auxiliary_info_default_size
7680  : encryption_index->auxiliary_info_sizes[i];
7681 
7682  ret = mov_read_sample_encryption_info(c, pb, sc, sample, sample_info_size > sc->cenc.per_sample_iv_size);
7683  if (ret < 0)
7684  goto finish;
7685  }
7686  if (pb->eof_reached) {
7687  av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading auxiliary info\n");
7689  } else {
7690  encryption_index->nb_encrypted_samples = sample_count;
7691  }
7692 
7693 finish:
7694  avio_seek(pb, prev_pos, SEEK_SET);
7695  if (ret < 0) {
7696  for (; i > 0; i--) {
7697  av_encryption_info_free(encryption_index->encrypted_samples[i - 1]);
7698  }
7699  av_freep(&encryption_index->encrypted_samples);
7700  }
7701  return ret;
7702 }
7703 
7705 {
7706  MOVEncryptionIndex *encryption_index;
7707  MOVStreamContext *sc;
7708  int ret;
7709  unsigned int sample_count, aux_info_type, aux_info_param;
7710 
7711  ret = get_current_encryption_info(c, &encryption_index, &sc);
7712  if (ret != 1)
7713  return ret;
7714 
7715  if (encryption_index->nb_encrypted_samples) {
7716  // This can happen if we have both saio/saiz and senc atoms.
7717  av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in saiz\n");
7718  return 0;
7719  }
7720 
7721  if (encryption_index->auxiliary_info_sample_count) {
7722  av_log(c->fc, AV_LOG_ERROR, "Duplicate saiz atom\n");
7723  return AVERROR_INVALIDDATA;
7724  }
7725 
7726  avio_r8(pb); /* version */
7727  if (avio_rb24(pb) & 0x01) { /* flags */
7728  aux_info_type = avio_rb32(pb);
7729  aux_info_param = avio_rb32(pb);
7730  if (sc->cenc.default_encrypted_sample) {
7731  if (aux_info_type != sc->cenc.default_encrypted_sample->scheme) {
7732  av_log(c->fc, AV_LOG_DEBUG, "Ignoring saiz box with non-zero aux_info_type\n");
7733  return 0;
7734  }
7735  if (aux_info_param != 0) {
7736  av_log(c->fc, AV_LOG_DEBUG, "Ignoring saiz box with non-zero aux_info_type_parameter\n");
7737  return 0;
7738  }
7739  } else {
7740  // Didn't see 'schm' or 'tenc', so this isn't encrypted.
7741  if ((aux_info_type == MKBETAG('c','e','n','c') ||
7742  aux_info_type == MKBETAG('c','e','n','s') ||
7743  aux_info_type == MKBETAG('c','b','c','1') ||
7744  aux_info_type == MKBETAG('c','b','c','s')) &&
7745  aux_info_param == 0) {
7746  av_log(c->fc, AV_LOG_ERROR, "Saw encrypted saiz without schm/tenc\n");
7747  return AVERROR_INVALIDDATA;
7748  } else {
7749  return 0;
7750  }
7751  }
7752  } else if (!sc->cenc.default_encrypted_sample) {
7753  // Didn't see 'schm' or 'tenc', so this isn't encrypted.
7754  return 0;
7755  }
7756 
7757  encryption_index->auxiliary_info_default_size = avio_r8(pb);
7758  sample_count = avio_rb32(pb);
7759 
7760  if (encryption_index->auxiliary_info_default_size == 0) {
7761  if (sample_count == 0)
7762  return AVERROR_INVALIDDATA;
7763 
7764  encryption_index->auxiliary_info_sizes = av_malloc(sample_count);
7765  if (!encryption_index->auxiliary_info_sizes)
7766  return AVERROR(ENOMEM);
7767 
7768  ret = avio_read(pb, encryption_index->auxiliary_info_sizes, sample_count);
7769  if (ret != sample_count) {
7770  av_freep(&encryption_index->auxiliary_info_sizes);
7771 
7772  if (ret >= 0)
7774  av_log(c->fc, AV_LOG_ERROR, "Failed to read the auxiliary info, %s\n",
7775  av_err2str(ret));
7776  return ret;
7777  }
7778  }
7779  encryption_index->auxiliary_info_sample_count = sample_count;
7780 
7781  if (encryption_index->auxiliary_offsets_count) {
7782  return mov_parse_auxiliary_info(c, sc, pb, encryption_index);
7783  }
7784 
7785  return 0;
7786 }
7787 
7789 {
7790  uint64_t *auxiliary_offsets;
7791  MOVEncryptionIndex *encryption_index;
7792  MOVStreamContext *sc;
7793  int i, ret;
7794  unsigned int version, entry_count, aux_info_type, aux_info_param;
7795  unsigned int alloc_size = 0;
7796 
7797  ret = get_current_encryption_info(c, &encryption_index, &sc);
7798  if (ret != 1)
7799  return ret;
7800 
7801  if (encryption_index->nb_encrypted_samples) {
7802  // This can happen if we have both saio/saiz and senc atoms.
7803  av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in saio\n");
7804  return 0;
7805  }
7806 
7807  if (encryption_index->auxiliary_offsets_count) {
7808  av_log(c->fc, AV_LOG_ERROR, "Duplicate saio atom\n");
7809  return AVERROR_INVALIDDATA;
7810  }
7811 
7812  version = avio_r8(pb); /* version */
7813  if (avio_rb24(pb) & 0x01) { /* flags */
7814  aux_info_type = avio_rb32(pb);
7815  aux_info_param = avio_rb32(pb);
7816  if (sc->cenc.default_encrypted_sample) {
7817  if (aux_info_type != sc->cenc.default_encrypted_sample->scheme) {
7818  av_log(c->fc, AV_LOG_DEBUG, "Ignoring saio box with non-zero aux_info_type\n");
7819  return 0;
7820  }
7821  if (aux_info_param != 0) {
7822  av_log(c->fc, AV_LOG_DEBUG, "Ignoring saio box with non-zero aux_info_type_parameter\n");
7823  return 0;
7824  }
7825  } else {
7826  // Didn't see 'schm' or 'tenc', so this isn't encrypted.
7827  if ((aux_info_type == MKBETAG('c','e','n','c') ||
7828  aux_info_type == MKBETAG('c','e','n','s') ||
7829  aux_info_type == MKBETAG('c','b','c','1') ||
7830  aux_info_type == MKBETAG('c','b','c','s')) &&
7831  aux_info_param == 0) {
7832  av_log(c->fc, AV_LOG_ERROR, "Saw encrypted saio without schm/tenc\n");
7833  return AVERROR_INVALIDDATA;
7834  } else {
7835  return 0;
7836  }
7837  }
7838  } else if (!sc->cenc.default_encrypted_sample) {
7839  // Didn't see 'schm' or 'tenc', so this isn't encrypted.
7840  return 0;
7841  }
7842 
7843  entry_count = avio_rb32(pb);
7844  if (entry_count >= INT_MAX / sizeof(*auxiliary_offsets))
7845  return AVERROR(ENOMEM);
7846 
7847  for (i = 0; i < entry_count && !pb->eof_reached; i++) {
7848  unsigned int min_offsets = FFMIN(FFMAX(i + 1, 1024), entry_count);
7849  auxiliary_offsets = av_fast_realloc(
7850  encryption_index->auxiliary_offsets, &alloc_size,
7851  min_offsets * sizeof(*auxiliary_offsets));
7852  if (!auxiliary_offsets) {
7853  av_freep(&encryption_index->auxiliary_offsets);
7854  return AVERROR(ENOMEM);
7855  }
7856  encryption_index->auxiliary_offsets = auxiliary_offsets;
7857 
7858  if (version == 0) {
7859  encryption_index->auxiliary_offsets[i] = avio_rb32(pb);
7860  } else {
7861  encryption_index->auxiliary_offsets[i] = avio_rb64(pb);
7862  }
7863  if (c->frag_index.current >= 0) {
7864  encryption_index->auxiliary_offsets[i] += c->fragment.base_data_offset;
7865  }
7866  }
7867 
7868  if (pb->eof_reached) {
7869  av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading saio\n");
7870  av_freep(&encryption_index->auxiliary_offsets);
7871  return AVERROR_INVALIDDATA;
7872  }
7873 
7874  encryption_index->auxiliary_offsets_count = entry_count;
7875 
7876  if (encryption_index->auxiliary_info_sample_count) {
7877  return mov_parse_auxiliary_info(c, sc, pb, encryption_index);
7878  }
7879 
7880  return 0;
7881 }
7882 
7884 {
7885  AVEncryptionInitInfo *info, *old_init_info;
7886  uint8_t **key_ids;
7887  AVStream *st;
7888  const AVPacketSideData *old_side_data;
7889  uint8_t *side_data, *extra_data;
7890  size_t side_data_size;
7891  int ret = 0;
7892  unsigned int version, kid_count, extra_data_size, alloc_size = 0;
7893 
7894  if (c->fc->nb_streams < 1)
7895  return 0;
7896  st = c->fc->streams[c->fc->nb_streams-1];
7897 
7898  version = avio_r8(pb); /* version */
7899  avio_rb24(pb); /* flags */
7900 
7901  info = av_encryption_init_info_alloc(/* system_id_size */ 16, /* num_key_ids */ 0,
7902  /* key_id_size */ 16, /* data_size */ 0);
7903  if (!info)
7904  return AVERROR(ENOMEM);
7905 
7906  if ((ret = ffio_read_size(pb, info->system_id, 16)) < 0) {
7907  av_log(c->fc, AV_LOG_ERROR, "Failed to read the system id\n");
7908  goto finish;
7909  }
7910 
7911  if (version > 0) {
7912  kid_count = avio_rb32(pb);
7913  if (kid_count >= INT_MAX / sizeof(*key_ids)) {
7914  ret = AVERROR(ENOMEM);
7915  goto finish;
7916  }
7917 
7918  for (unsigned int i = 0; i < kid_count && !pb->eof_reached; i++) {
7919  unsigned int min_kid_count = FFMIN(FFMAX(i + 1, 1024), kid_count);
7920  key_ids = av_fast_realloc(info->key_ids, &alloc_size,
7921  min_kid_count * sizeof(*key_ids));
7922  if (!key_ids) {
7923  ret = AVERROR(ENOMEM);
7924  goto finish;
7925  }
7926  info->key_ids = key_ids;
7927 
7928  info->key_ids[i] = av_mallocz(16);
7929  if (!info->key_ids[i]) {
7930  ret = AVERROR(ENOMEM);
7931  goto finish;
7932  }
7933  info->num_key_ids = i + 1;
7934 
7935  if ((ret = ffio_read_size(pb, info->key_ids[i], 16)) < 0) {
7936  av_log(c->fc, AV_LOG_ERROR, "Failed to read the key id\n");
7937  goto finish;
7938  }
7939  }
7940 
7941  if (pb->eof_reached) {
7942  av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading pssh\n");
7944  goto finish;
7945  }
7946  }
7947 
7948  extra_data_size = avio_rb32(pb);
7949  extra_data = av_malloc(extra_data_size);
7950  if (!extra_data) {
7951  ret = AVERROR(ENOMEM);
7952  goto finish;
7953  }
7954  ret = avio_read(pb, extra_data, extra_data_size);
7955  if (ret != extra_data_size) {
7956  av_free(extra_data);
7957 
7958  if (ret >= 0)
7960  goto finish;
7961  }
7962 
7963  av_freep(&info->data); // malloc(0) may still allocate something.
7964  info->data = extra_data;
7965  info->data_size = extra_data_size;
7966 
7967  // If there is existing initialization data, append to the list.
7970  if (old_side_data) {
7971  old_init_info = av_encryption_init_info_get_side_data(old_side_data->data, old_side_data->size);
7972  if (old_init_info) {
7973  // Append to the end of the list.
7974  for (AVEncryptionInitInfo *cur = old_init_info;; cur = cur->next) {
7975  if (!cur->next) {
7976  cur->next = info;
7977  break;
7978  }
7979  }
7980  info = old_init_info;
7981  } else {
7982  // Assume existing side-data will be valid, so the only error we could get is OOM.
7983  ret = AVERROR(ENOMEM);
7984  goto finish;
7985  }
7986  }
7987 
7988  side_data = av_encryption_init_info_add_side_data(info, &side_data_size);
7989  if (!side_data) {
7990  ret = AVERROR(ENOMEM);
7991  goto finish;
7992  }
7996  side_data, side_data_size, 0))
7997  av_free(side_data);
7998 
7999 finish:
8001  return ret;
8002 }
8003 
8005 {
8006  AVStream *st;
8007  MOVStreamContext *sc;
8008 
8009  if (c->fc->nb_streams < 1)
8010  return 0;
8011  st = c->fc->streams[c->fc->nb_streams-1];
8012  sc = st->priv_data;
8013 
8014  if (sc->pseudo_stream_id != 0) {
8015  av_log(c->fc, AV_LOG_ERROR, "schm boxes are only supported in first sample descriptor\n");
8016  return AVERROR_PATCHWELCOME;
8017  }
8018 
8019  if (atom.size < 8)
8020  return AVERROR_INVALIDDATA;
8021 
8022  avio_rb32(pb); /* version and flags */
8023 
8024  if (!sc->cenc.default_encrypted_sample) {
8026  if (!sc->cenc.default_encrypted_sample) {
8027  return AVERROR(ENOMEM);
8028  }
8029  }
8030 
8032  return 0;
8033 }
8034 
8036 {
8037  AVStream *st;
8038  MOVStreamContext *sc;
8039  unsigned int version, pattern, is_protected, iv_size;
8040 
8041  if (c->fc->nb_streams < 1)
8042  return 0;
8043  st = c->fc->streams[c->fc->nb_streams-1];
8044  sc = st->priv_data;
8045 
8046  if (sc->pseudo_stream_id != 0) {
8047  av_log(c->fc, AV_LOG_ERROR, "tenc atom are only supported in first sample descriptor\n");
8048  return AVERROR_PATCHWELCOME;
8049  }
8050 
8051  if (!sc->cenc.default_encrypted_sample) {
8053  if (!sc->cenc.default_encrypted_sample) {
8054  return AVERROR(ENOMEM);
8055  }
8056  }
8057 
8058  if (atom.size < 20)
8059  return AVERROR_INVALIDDATA;
8060 
8061  version = avio_r8(pb); /* version */
8062  avio_rb24(pb); /* flags */
8063 
8064  avio_r8(pb); /* reserved */
8065  pattern = avio_r8(pb);
8066 
8067  if (version > 0) {
8068  sc->cenc.default_encrypted_sample->crypt_byte_block = pattern >> 4;
8069  sc->cenc.default_encrypted_sample->skip_byte_block = pattern & 0xf;
8070  }
8071 
8072  is_protected = avio_r8(pb);
8073  if (is_protected && !sc->cenc.encryption_index) {
8074  // The whole stream should be by-default encrypted.
8076  if (!sc->cenc.encryption_index)
8077  return AVERROR(ENOMEM);
8078  }
8079  sc->cenc.per_sample_iv_size = avio_r8(pb);
8080  if (sc->cenc.per_sample_iv_size != 0 && sc->cenc.per_sample_iv_size != 8 &&
8081  sc->cenc.per_sample_iv_size != 16) {
8082  av_log(c->fc, AV_LOG_ERROR, "invalid per-sample IV size value\n");
8083  return AVERROR_INVALIDDATA;
8084  }
8085  if (avio_read(pb, sc->cenc.default_encrypted_sample->key_id, 16) != 16) {
8086  av_log(c->fc, AV_LOG_ERROR, "failed to read the default key ID\n");
8087  return AVERROR_INVALIDDATA;
8088  }
8089 
8090  if (is_protected && !sc->cenc.per_sample_iv_size) {
8091  iv_size = avio_r8(pb);
8092  if (iv_size != 8 && iv_size != 16) {
8093  av_log(c->fc, AV_LOG_ERROR, "invalid default_constant_IV_size in tenc atom\n");
8094  return AVERROR_INVALIDDATA;
8095  }
8096 
8097  if (avio_read(pb, sc->cenc.default_encrypted_sample->iv, iv_size) != iv_size) {
8098  av_log(c->fc, AV_LOG_ERROR, "failed to read the default IV\n");
8099  return AVERROR_INVALIDDATA;
8100  }
8101  }
8102 
8103  return 0;
8104 }
8105 
8107 {
8108  AVStream *st;
8109  int last, type, size, ret;
8110  uint8_t buf[4];
8111 
8112  if (c->fc->nb_streams < 1)
8113  return 0;
8114  st = c->fc->streams[c->fc->nb_streams-1];
8115 
8116  if ((uint64_t)atom.size > (1<<30) || atom.size < 42)
8117  return AVERROR_INVALIDDATA;
8118 
8119  /* Check FlacSpecificBox version. */
8120  if (avio_r8(pb) != 0)
8121  return AVERROR_INVALIDDATA;
8122 
8123  avio_rb24(pb); /* Flags */
8124 
8125  if (avio_read(pb, buf, sizeof(buf)) != sizeof(buf)) {
8126  av_log(c->fc, AV_LOG_ERROR, "failed to read FLAC metadata block header\n");
8127  return pb->error < 0 ? pb->error : AVERROR_INVALIDDATA;
8128  }
8129  flac_parse_block_header(buf, &last, &type, &size);
8130 
8132  av_log(c->fc, AV_LOG_ERROR, "STREAMINFO must be first FLACMetadataBlock\n");
8133  return AVERROR_INVALIDDATA;
8134  }
8135 
8136  ret = ff_get_extradata(c->fc, st->codecpar, pb, size);
8137  if (ret < 0)
8138  return ret;
8139 
8140  if (!last)
8141  av_log(c->fc, AV_LOG_WARNING, "non-STREAMINFO FLACMetadataBlock(s) ignored\n");
8142 
8143  return 0;
8144 }
8145 
8146 static int get_key_from_kid(uint8_t* out, int len, MOVContext *c, AVEncryptionInfo *sample) {
8147  AVDictionaryEntry *key_entry_hex;
8148  char kid_hex[16*2+1];
8149 
8150  if (c->decryption_default_key && c->decryption_default_key_len != len) {
8151  av_log(c->fc, AV_LOG_ERROR, "invalid default decryption key length: got %d, expected %d\n", c->decryption_default_key_len, len);
8152  return -1;
8153  }
8154 
8155  if (!c->decryption_keys) {
8156  av_assert0(c->decryption_default_key);
8157  memcpy(out, c->decryption_default_key, len);
8158  return 0;
8159  }
8160 
8161  if (sample->key_id_size != 16) {
8162  av_log(c->fc, AV_LOG_ERROR, "invalid key ID size: got %u, expected 16\n", sample->key_id_size);
8163  return -1;
8164  }
8165 
8166  ff_data_to_hex(kid_hex, sample->key_id, 16, 1);
8167  key_entry_hex = av_dict_get(c->decryption_keys, kid_hex, NULL, AV_DICT_DONT_STRDUP_KEY|AV_DICT_DONT_STRDUP_VAL);
8168  if (!key_entry_hex) {
8169  if (!c->decryption_default_key) {
8170  av_log(c->fc, AV_LOG_ERROR, "unable to find KID %s\n", kid_hex);
8171  return -1;
8172  }
8173  memcpy(out, c->decryption_default_key, len);
8174  return 0;
8175  }
8176  if (strlen(key_entry_hex->value) != len*2) {
8177  return -1;
8178  }
8179  ff_hex_to_data(out, key_entry_hex->value);
8180  return 0;
8181 }
8182 
8184 {
8185  int i, ret;
8186  int bytes_of_protected_data;
8187  uint8_t decryption_key[AES_CTR_KEY_SIZE];
8188 
8189  if (!sc->cenc.aes_ctr) {
8190  ret = get_key_from_kid(decryption_key, sizeof(decryption_key), c, sample);
8191  if (ret < 0) {
8192  return ret;
8193  }
8194 
8195  /* initialize the cipher */
8196  sc->cenc.aes_ctr = av_aes_ctr_alloc();
8197  if (!sc->cenc.aes_ctr) {
8198  return AVERROR(ENOMEM);
8199  }
8200 
8201  ret = av_aes_ctr_init(sc->cenc.aes_ctr, decryption_key);
8202  if (ret < 0) {
8203  return ret;
8204  }
8205  }
8206 
8208 
8209  if (!sample->subsample_count) {
8210  /* decrypt the whole packet */
8212  return 0;
8213  }
8214 
8215  for (i = 0; i < sample->subsample_count; i++) {
8216  if (sample->subsamples[i].bytes_of_clear_data + (int64_t)sample->subsamples[i].bytes_of_protected_data > size) {
8217  av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n");
8218  return AVERROR_INVALIDDATA;
8219  }
8220 
8221  /* skip the clear bytes */
8222  input += sample->subsamples[i].bytes_of_clear_data;
8223  size -= sample->subsamples[i].bytes_of_clear_data;
8224 
8225  /* decrypt the encrypted bytes */
8226 
8227  bytes_of_protected_data = sample->subsamples[i].bytes_of_protected_data;
8228  av_aes_ctr_crypt(sc->cenc.aes_ctr, input, input, bytes_of_protected_data);
8229 
8230  input += bytes_of_protected_data;
8231  size -= bytes_of_protected_data;
8232  }
8233 
8234  if (size > 0) {
8235  av_log(c->fc, AV_LOG_ERROR, "leftover packet bytes after subsample processing\n");
8236  return AVERROR_INVALIDDATA;
8237  }
8238 
8239  return 0;
8240 }
8241 
8243 {
8244  int i, ret;
8245  int num_of_encrypted_blocks;
8246  uint8_t iv[16];
8247  uint8_t decryption_key[16];
8248 
8249  if (!sc->cenc.aes_ctx) {
8250  ret = get_key_from_kid(decryption_key, sizeof(decryption_key), c, sample);
8251  if (ret < 0) {
8252  return ret;
8253  }
8254 
8255  /* initialize the cipher */
8256  sc->cenc.aes_ctx = av_aes_alloc();
8257  if (!sc->cenc.aes_ctx) {
8258  return AVERROR(ENOMEM);
8259  }
8260 
8261  ret = av_aes_init(sc->cenc.aes_ctx, decryption_key, 16 * 8, 1);
8262  if (ret < 0) {
8263  return ret;
8264  }
8265  }
8266 
8267  memcpy(iv, sample->iv, 16);
8268 
8269  /* whole-block full sample encryption */
8270  if (!sample->subsample_count) {
8271  /* decrypt the whole packet */
8272  av_aes_crypt(sc->cenc.aes_ctx, input, input, size/16, iv, 1);
8273  return 0;
8274  }
8275 
8276  for (i = 0; i < sample->subsample_count; i++) {
8277  if (sample->subsamples[i].bytes_of_clear_data + (int64_t)sample->subsamples[i].bytes_of_protected_data > size) {
8278  av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n");
8279  return AVERROR_INVALIDDATA;
8280  }
8281 
8282  if (sample->subsamples[i].bytes_of_protected_data % 16) {
8283  av_log(c->fc, AV_LOG_ERROR, "subsample BytesOfProtectedData is not a multiple of 16\n");
8284  return AVERROR_INVALIDDATA;
8285  }
8286 
8287  /* skip the clear bytes */
8288  input += sample->subsamples[i].bytes_of_clear_data;
8289  size -= sample->subsamples[i].bytes_of_clear_data;
8290 
8291  /* decrypt the encrypted bytes */
8292  num_of_encrypted_blocks = sample->subsamples[i].bytes_of_protected_data/16;
8293  if (num_of_encrypted_blocks > 0) {
8294  av_aes_crypt(sc->cenc.aes_ctx, input, input, num_of_encrypted_blocks, iv, 1);
8295  }
8296  input += sample->subsamples[i].bytes_of_protected_data;
8297  size -= sample->subsamples[i].bytes_of_protected_data;
8298  }
8299 
8300  if (size > 0) {
8301  av_log(c->fc, AV_LOG_ERROR, "leftover packet bytes after subsample processing\n");
8302  return AVERROR_INVALIDDATA;
8303  }
8304 
8305  return 0;
8306 }
8307 
8309 {
8310  int i, ret, rem_bytes;
8311  uint8_t *data;
8312  uint8_t decryption_key[AES_CTR_KEY_SIZE];
8313 
8314  if (!sc->cenc.aes_ctr) {
8315  ret = get_key_from_kid(decryption_key, sizeof(decryption_key), c, sample);
8316  if (ret < 0) {
8317  return ret;
8318  }
8319 
8320  /* initialize the cipher */
8321  sc->cenc.aes_ctr = av_aes_ctr_alloc();
8322  if (!sc->cenc.aes_ctr) {
8323  return AVERROR(ENOMEM);
8324  }
8325 
8326  ret = av_aes_ctr_init(sc->cenc.aes_ctr, decryption_key);
8327  if (ret < 0) {
8328  return ret;
8329  }
8330  }
8331 
8333 
8334  /* whole-block full sample encryption */
8335  if (!sample->subsample_count) {
8336  /* decrypt the whole packet */
8338  return 0;
8339  } else if (!sample->crypt_byte_block && !sample->skip_byte_block) {
8340  av_log(c->fc, AV_LOG_ERROR, "pattern encryption is not present in 'cens' scheme\n");
8341  return AVERROR_INVALIDDATA;
8342  }
8343 
8344  for (i = 0; i < sample->subsample_count; i++) {
8345  if (sample->subsamples[i].bytes_of_clear_data + (int64_t)sample->subsamples[i].bytes_of_protected_data > size) {
8346  av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n");
8347  return AVERROR_INVALIDDATA;
8348  }
8349 
8350  /* skip the clear bytes */
8351  input += sample->subsamples[i].bytes_of_clear_data;
8352  size -= sample->subsamples[i].bytes_of_clear_data;
8353 
8354  /* decrypt the encrypted bytes */
8355  data = input;
8356  rem_bytes = sample->subsamples[i].bytes_of_protected_data;
8357  while (rem_bytes > 0) {
8358  if (rem_bytes < 16*sample->crypt_byte_block) {
8359  break;
8360  }
8361  av_aes_ctr_crypt(sc->cenc.aes_ctr, data, data, 16*sample->crypt_byte_block);
8362  data += 16*sample->crypt_byte_block;
8363  rem_bytes -= 16*sample->crypt_byte_block;
8364  data += FFMIN(16*sample->skip_byte_block, rem_bytes);
8365  rem_bytes -= FFMIN(16*sample->skip_byte_block, rem_bytes);
8366  }
8367  input += sample->subsamples[i].bytes_of_protected_data;
8368  size -= sample->subsamples[i].bytes_of_protected_data;
8369  }
8370 
8371  if (size > 0) {
8372  av_log(c->fc, AV_LOG_ERROR, "leftover packet bytes after subsample processing\n");
8373  return AVERROR_INVALIDDATA;
8374  }
8375 
8376  return 0;
8377 }
8378 
8380 {
8381  int i, ret, rem_bytes;
8382  uint8_t iv[16];
8383  uint8_t *data;
8384  uint8_t decryption_key[16];
8385 
8386  if (!sc->cenc.aes_ctx) {
8387  ret = get_key_from_kid(decryption_key, sizeof(decryption_key), c, sample);
8388  if (ret < 0) {
8389  return ret;
8390  }
8391 
8392  /* initialize the cipher */
8393  sc->cenc.aes_ctx = av_aes_alloc();
8394  if (!sc->cenc.aes_ctx) {
8395  return AVERROR(ENOMEM);
8396  }
8397 
8398  ret = av_aes_init(sc->cenc.aes_ctx, decryption_key, 16 * 8, 1);
8399  if (ret < 0) {
8400  return ret;
8401  }
8402  }
8403 
8404  /* whole-block full sample encryption */
8405  if (!sample->subsample_count) {
8406  /* decrypt the whole packet */
8407  memcpy(iv, sample->iv, 16);
8408  av_aes_crypt(sc->cenc.aes_ctx, input, input, size/16, iv, 1);
8409  return 0;
8410  } else if (!sample->crypt_byte_block && !sample->skip_byte_block) {
8411  av_log(c->fc, AV_LOG_ERROR, "pattern encryption is not present in 'cbcs' scheme\n");
8412  return AVERROR_INVALIDDATA;
8413  }
8414 
8415  for (i = 0; i < sample->subsample_count; i++) {
8416  if (sample->subsamples[i].bytes_of_clear_data + (int64_t)sample->subsamples[i].bytes_of_protected_data > size) {
8417  av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n");
8418  return AVERROR_INVALIDDATA;
8419  }
8420 
8421  /* skip the clear bytes */
8422  input += sample->subsamples[i].bytes_of_clear_data;
8423  size -= sample->subsamples[i].bytes_of_clear_data;
8424 
8425  /* decrypt the encrypted bytes */
8426  memcpy(iv, sample->iv, 16);
8427  data = input;
8428  rem_bytes = sample->subsamples[i].bytes_of_protected_data;
8429  while (rem_bytes > 0) {
8430  if (rem_bytes < 16*sample->crypt_byte_block) {
8431  break;
8432  }
8433  av_aes_crypt(sc->cenc.aes_ctx, data, data, sample->crypt_byte_block, iv, 1);
8434  data += 16*sample->crypt_byte_block;
8435  rem_bytes -= 16*sample->crypt_byte_block;
8436  data += FFMIN(16*sample->skip_byte_block, rem_bytes);
8437  rem_bytes -= FFMIN(16*sample->skip_byte_block, rem_bytes);
8438  }
8439  input += sample->subsamples[i].bytes_of_protected_data;
8440  size -= sample->subsamples[i].bytes_of_protected_data;
8441  }
8442 
8443  if (size > 0) {
8444  av_log(c->fc, AV_LOG_ERROR, "leftover packet bytes after subsample processing\n");
8445  return AVERROR_INVALIDDATA;
8446  }
8447 
8448  return 0;
8449 }
8450 
8452 {
8453  if (sample->scheme == MKBETAG('c','e','n','c') && !sample->crypt_byte_block && !sample->skip_byte_block) {
8454  return cenc_scheme_decrypt(c, sc, sample, input, size);
8455  } else if (sample->scheme == MKBETAG('c','b','c','1') && !sample->crypt_byte_block && !sample->skip_byte_block) {
8456  return cbc1_scheme_decrypt(c, sc, sample, input, size);
8457  } else if (sample->scheme == MKBETAG('c','e','n','s')) {
8458  return cens_scheme_decrypt(c, sc, sample, input, size);
8459  } else if (sample->scheme == MKBETAG('c','b','c','s')) {
8460  return cbcs_scheme_decrypt(c, sc, sample, input, size);
8461  } else {
8462  av_log(c->fc, AV_LOG_ERROR, "invalid encryption scheme\n");
8463  return AVERROR_INVALIDDATA;
8464  }
8465 }
8466 
8468 {
8469  int current = frag_index->current;
8470 
8471  if (!frag_index->nb_items)
8472  return NULL;
8473 
8474  // Check frag_index->current is the right one for pkt. It can out of sync.
8475  if (current >= 0 && current < frag_index->nb_items) {
8476  if (frag_index->item[current].moof_offset < pkt->pos &&
8477  (current + 1 == frag_index->nb_items ||
8478  frag_index->item[current + 1].moof_offset > pkt->pos))
8479  return get_frag_stream_info(frag_index, current, id);
8480  }
8481 
8482 
8483  for (int i = 0; i < frag_index->nb_items; i++) {
8484  if (frag_index->item[i].moof_offset > pkt->pos)
8485  break;
8486  current = i;
8487  }
8488  frag_index->current = current;
8489  return get_frag_stream_info(frag_index, current, id);
8490 }
8491 
8492 static int cenc_filter(MOVContext *mov, AVStream* st, MOVStreamContext *sc, AVPacket *pkt, int current_index)
8493 {
8494  MOVFragmentStreamInfo *frag_stream_info;
8495  MOVEncryptionIndex *encryption_index;
8496  AVEncryptionInfo *encrypted_sample;
8497  int encrypted_index, ret;
8498 
8499  frag_stream_info = get_frag_stream_info_from_pkt(&mov->frag_index, pkt, sc->id);
8500  encrypted_index = current_index;
8501  encryption_index = NULL;
8502  if (frag_stream_info) {
8503  // Note this only supports encryption info in the first sample descriptor.
8504  if (frag_stream_info->stsd_id == 1) {
8505  if (frag_stream_info->encryption_index) {
8506  encrypted_index = current_index - frag_stream_info->index_base;
8507  encryption_index = frag_stream_info->encryption_index;
8508  } else {
8509  encryption_index = sc->cenc.encryption_index;
8510  }
8511  }
8512  } else {
8513  encryption_index = sc->cenc.encryption_index;
8514  }
8515 
8516  if (encryption_index) {
8517  if (encryption_index->auxiliary_info_sample_count &&
8518  !encryption_index->nb_encrypted_samples) {
8519  av_log(mov->fc, AV_LOG_ERROR, "saiz atom found without saio\n");
8520  return AVERROR_INVALIDDATA;
8521  }
8522  if (encryption_index->auxiliary_offsets_count &&
8523  !encryption_index->nb_encrypted_samples) {
8524  av_log(mov->fc, AV_LOG_ERROR, "saio atom found without saiz\n");
8525  return AVERROR_INVALIDDATA;
8526  }
8527 
8528  encrypted_sample = NULL;
8529  if (!encryption_index->nb_encrypted_samples) {
8530  // Full-sample encryption with default settings.
8531  encrypted_sample = sc->cenc.default_encrypted_sample;
8532  } else if (encrypted_index >= 0 && encrypted_index < encryption_index->nb_encrypted_samples) {
8533  // Per-sample setting override.
8534  encrypted_sample = encryption_index->encrypted_samples[encrypted_index];
8535  if (!encrypted_sample) {
8536  encrypted_sample = sc->cenc.default_encrypted_sample;
8537  }
8538  }
8539 
8540  if (!encrypted_sample) {
8541  av_log(mov->fc, AV_LOG_ERROR, "Incorrect number of samples in encryption info\n");
8542  return AVERROR_INVALIDDATA;
8543  }
8544 
8545  if (mov->decryption_keys || mov->decryption_default_key) {
8546  return cenc_decrypt(mov, sc, encrypted_sample, pkt->data, pkt->size);
8547  } else {
8548  size_t size;
8549  uint8_t *side_data = av_encryption_info_add_side_data(encrypted_sample, &size);
8550  if (!side_data)
8551  return AVERROR(ENOMEM);
8553  if (ret < 0)
8554  av_free(side_data);
8555  return ret;
8556  }
8557  }
8558 
8559  return 0;
8560 }
8561 
8563 {
8564  const int OPUS_SEEK_PREROLL_MS = 80;
8565  int ret;
8566  AVStream *st;
8567  size_t size;
8568  uint16_t pre_skip;
8569 
8570  if (c->fc->nb_streams < 1)
8571  return 0;
8572  st = c->fc->streams[c->fc->nb_streams-1];
8573 
8574  if ((uint64_t)atom.size > (1<<30) || atom.size < 11)
8575  return AVERROR_INVALIDDATA;
8576 
8577  /* Check OpusSpecificBox version. */
8578  if (avio_r8(pb) != 0) {
8579  av_log(c->fc, AV_LOG_ERROR, "unsupported OpusSpecificBox version\n");
8580  return AVERROR_INVALIDDATA;
8581  }
8582 
8583  /* OpusSpecificBox size plus magic for Ogg OpusHead header. */
8584  size = atom.size + 8;
8585 
8586  if ((ret = ff_alloc_extradata(st->codecpar, size)) < 0)
8587  return ret;
8588 
8589  AV_WL32A(st->codecpar->extradata, MKTAG('O','p','u','s'));
8590  AV_WL32A(st->codecpar->extradata + 4, MKTAG('H','e','a','d'));
8591  AV_WB8(st->codecpar->extradata + 8, 1); /* OpusHead version */
8592  avio_read(pb, st->codecpar->extradata + 9, size - 9);
8593 
8594  /* OpusSpecificBox is stored in big-endian, but OpusHead is
8595  little-endian; aside from the preceding magic and version they're
8596  otherwise currently identical. Data after output gain at offset 16
8597  doesn't need to be bytewapped. */
8598  pre_skip = AV_RB16A(st->codecpar->extradata + 10);
8599  AV_WL16A(st->codecpar->extradata + 10, pre_skip);
8600  AV_WL32A(st->codecpar->extradata + 12, AV_RB32A(st->codecpar->extradata + 12));
8601  AV_WL16A(st->codecpar->extradata + 16, AV_RB16A(st->codecpar->extradata + 16));
8602 
8603  st->codecpar->initial_padding = pre_skip;
8605  (AVRational){1, 1000},
8606  (AVRational){1, 48000});
8607 
8608  return 0;
8609 }
8610 
8612 {
8613  AVStream *st;
8614  unsigned format_info;
8615  int channel_assignment, channel_assignment1, channel_assignment2;
8616  int ratebits;
8617  uint64_t chmask;
8618 
8619  if (c->fc->nb_streams < 1)
8620  return 0;
8621  st = c->fc->streams[c->fc->nb_streams-1];
8622 
8623  if (atom.size < 10)
8624  return AVERROR_INVALIDDATA;
8625 
8626  format_info = avio_rb32(pb);
8627 
8628  ratebits = (format_info >> 28) & 0xF;
8629  channel_assignment1 = (format_info >> 15) & 0x1F;
8630  channel_assignment2 = format_info & 0x1FFF;
8631  if (channel_assignment2)
8632  channel_assignment = channel_assignment2;
8633  else
8634  channel_assignment = channel_assignment1;
8635 
8636  st->codecpar->frame_size = 40 << (ratebits & 0x7);
8637  st->codecpar->sample_rate = mlp_samplerate(ratebits);
8638 
8640  chmask = truehd_layout(channel_assignment);
8642 
8643  return 0;
8644 }
8645 
8647 {
8648  AVStream *st;
8649  uint8_t buf[ISOM_DVCC_DVVC_SIZE];
8650  int ret;
8651  int64_t read_size = atom.size;
8652 
8653  if (c->fc->nb_streams < 1)
8654  return 0;
8655  st = c->fc->streams[c->fc->nb_streams-1];
8656 
8657  // At most 24 bytes
8658  read_size = FFMIN(read_size, ISOM_DVCC_DVVC_SIZE);
8659 
8660  if ((ret = ffio_read_size(pb, buf, read_size)) < 0)
8661  return ret;
8662 
8663  return ff_isom_parse_dvcc_dvvc(c->fc, st, buf, read_size);
8664 }
8665 
8667 {
8668  AVStream *st;
8669  uint8_t *buf;
8670  int ret, old_size, num_arrays;
8671 
8672  if (c->fc->nb_streams < 1)
8673  return 0;
8674  st = c->fc->streams[c->fc->nb_streams-1];
8675 
8676  if (!st->codecpar->extradata_size)
8677  // TODO: handle lhvC when present before hvcC
8678  return 0;
8679 
8680  if (atom.size < 6 || st->codecpar->extradata_size < 23)
8681  return AVERROR_INVALIDDATA;
8682 
8684  if (!buf)
8685  return AVERROR(ENOMEM);
8686  memset(buf + atom.size, 0, AV_INPUT_BUFFER_PADDING_SIZE);
8687 
8688  ret = ffio_read_size(pb, buf, atom.size);
8689  if (ret < 0) {
8690  av_free(buf);
8691  av_log(c->fc, AV_LOG_WARNING, "lhvC atom truncated\n");
8692  return 0;
8693  }
8694 
8695  num_arrays = buf[5];
8696  old_size = st->codecpar->extradata_size;
8697  atom.size -= 8 /* account for mov_realloc_extradata offsetting */
8698  + 6 /* lhvC bytes before the arrays*/;
8699 
8700  ret = mov_realloc_extradata(st->codecpar, atom);
8701  if (ret < 0) {
8702  av_free(buf);
8703  return ret;
8704  }
8705 
8706  st->codecpar->extradata[22] += num_arrays;
8707  memcpy(st->codecpar->extradata + old_size, buf + 6, atom.size + 8);
8708 
8710 
8711  av_free(buf);
8712  return 0;
8713 }
8714 
8716 {
8717  AVFormatContext *ctx = c->fc;
8718  AVStream *st = NULL;
8719  AVBPrint scheme_buf, value_buf;
8720  int64_t scheme_str_len = 0, value_str_len = 0;
8721  int version, flags, ret = AVERROR_BUG;
8722  int64_t size = atom.size;
8723 
8724  if (atom.size < 6)
8725  // 4 bytes for version + flags, 2x 1 byte for null
8726  return AVERROR_INVALIDDATA;
8727 
8728  if (c->fc->nb_streams < 1)
8729  return 0;
8730  st = c->fc->streams[c->fc->nb_streams-1];
8731 
8732  version = avio_r8(pb);
8733  flags = avio_rb24(pb);
8734  size -= 4;
8735 
8736  if (version != 0 || flags != 0) {
8738  "Unsupported 'kind' box with version %d, flags: %x",
8739  version, flags);
8740  return AVERROR_INVALIDDATA;
8741  }
8742 
8743  av_bprint_init(&scheme_buf, 0, AV_BPRINT_SIZE_UNLIMITED);
8744  av_bprint_init(&value_buf, 0, AV_BPRINT_SIZE_UNLIMITED);
8745 
8746  if ((scheme_str_len = ff_read_string_to_bprint_overwrite(pb, &scheme_buf,
8747  size)) < 0) {
8748  ret = scheme_str_len;
8749  goto cleanup;
8750  }
8751 
8752  if (scheme_str_len + 1 >= size) {
8753  // we need to have another string, even if nullptr.
8754  // we check with + 1 since we expect that if size was not hit,
8755  // an additional null was read.
8757  goto cleanup;
8758  }
8759 
8760  size -= scheme_str_len + 1;
8761 
8762  if ((value_str_len = ff_read_string_to_bprint_overwrite(pb, &value_buf,
8763  size)) < 0) {
8764  ret = value_str_len;
8765  goto cleanup;
8766  }
8767 
8768  if (value_str_len == size) {
8769  // in case of no trailing null, box is not valid.
8771  goto cleanup;
8772  }
8773 
8775  "%s stream %d KindBox(scheme: %s, value: %s)\n",
8777  st->index,
8778  scheme_buf.str, value_buf.str);
8779 
8780  for (int i = 0; ff_mov_track_kind_table[i].scheme_uri; i++) {
8782  if (!av_strstart(scheme_buf.str, map.scheme_uri, NULL))
8783  continue;
8784 
8785  for (int j = 0; map.value_maps[j].disposition; j++) {
8786  const struct MP4TrackKindValueMapping value_map = map.value_maps[j];
8787  if (!av_strstart(value_buf.str, value_map.value, NULL))
8788  continue;
8789 
8790  st->disposition |= value_map.disposition;
8791  }
8792  }
8793 
8794  ret = 0;
8795 
8796 cleanup:
8797 
8798  av_bprint_finalize(&scheme_buf, NULL);
8799  av_bprint_finalize(&value_buf, NULL);
8800 
8801  return ret;
8802 }
8803 
8805 {
8806  AVStream *st;
8807  AVChannelLayout ch_layout = { 0 };
8808  int ret, i, version, type;
8809  int ambisonic_order, channel_order, normalization, channel_count;
8810  int ambi_channels, non_diegetic_channels;
8811 
8812  if (c->fc->nb_streams < 1)
8813  return 0;
8814 
8815  st = c->fc->streams[c->fc->nb_streams - 1];
8816 
8817  if (atom.size < 16) {
8818  av_log(c->fc, AV_LOG_ERROR, "SA3D audio box too small\n");
8819  return AVERROR_INVALIDDATA;
8820  }
8821 
8822  version = avio_r8(pb);
8823  if (version) {
8824  av_log(c->fc, AV_LOG_WARNING, "Unsupported SA3D box version %d\n", version);
8825  return 0;
8826  }
8827 
8828  type = avio_r8(pb);
8829  if (type & 0x7f) {
8830  av_log(c->fc, AV_LOG_WARNING,
8831  "Unsupported ambisonic type %d\n", type & 0x7f);
8832  return 0;
8833  }
8834  non_diegetic_channels = (type >> 7) * 2; // head_locked_stereo
8835 
8836  ambisonic_order = avio_rb32(pb);
8837 
8838  channel_order = avio_r8(pb);
8839  if (channel_order) {
8840  av_log(c->fc, AV_LOG_WARNING,
8841  "Unsupported channel_order %d\n", channel_order);
8842  return 0;
8843  }
8844 
8845  normalization = avio_r8(pb);
8846  if (normalization) {
8847  av_log(c->fc, AV_LOG_WARNING,
8848  "Unsupported normalization %d\n", normalization);
8849  return 0;
8850  }
8851 
8852  channel_count = avio_rb32(pb);
8853  if (ambisonic_order < 0 || ambisonic_order > 31 ||
8854  channel_count != ((ambisonic_order + 1LL) * (ambisonic_order + 1LL) +
8855  non_diegetic_channels)) {
8856  av_log(c->fc, AV_LOG_ERROR,
8857  "Invalid number of channels (%d / %d)\n",
8858  channel_count, ambisonic_order);
8859  return 0;
8860  }
8861  ambi_channels = channel_count - non_diegetic_channels;
8862 
8863  ret = av_channel_layout_custom_init(&ch_layout, channel_count);
8864  if (ret < 0)
8865  return 0;
8866 
8867  for (i = 0; i < channel_count; i++) {
8868  unsigned channel = avio_rb32(pb);
8869 
8870  if (channel >= channel_count) {
8871  av_log(c->fc, AV_LOG_ERROR, "Invalid channel index (%d / %d)\n",
8872  channel, ambisonic_order);
8873  av_channel_layout_uninit(&ch_layout);
8874  return 0;
8875  }
8876  if (channel >= ambi_channels)
8877  ch_layout.u.map[i].id = channel - ambi_channels;
8878  else
8879  ch_layout.u.map[i].id = AV_CHAN_AMBISONIC_BASE + channel;
8880  }
8881 
8883  if (ret < 0) {
8884  av_channel_layout_uninit(&ch_layout);
8885  return 0;
8886  }
8887 
8889  st->codecpar->ch_layout = ch_layout;
8890 
8891  return 0;
8892 }
8893 
8895 {
8896  AVStream *st;
8897  int version;
8898 
8899  if (c->fc->nb_streams < 1)
8900  return 0;
8901 
8902  st = c->fc->streams[c->fc->nb_streams - 1];
8903 
8904  if (atom.size < 5) {
8905  av_log(c->fc, AV_LOG_ERROR, "Empty SAND audio box\n");
8906  return AVERROR_INVALIDDATA;
8907  }
8908 
8909  version = avio_r8(pb);
8910  if (version) {
8911  av_log(c->fc, AV_LOG_WARNING, "Unsupported SAND box version %d\n", version);
8912  return 0;
8913  }
8914 
8916 
8917  return 0;
8918 }
8919 
8920 static int rb_size(AVIOContext *pb, int64_t *value, int size)
8921 {
8922  if (size == 0)
8923  *value = 0;
8924  else if (size == 1)
8925  *value = avio_r8(pb);
8926  else if (size == 2)
8927  *value = avio_rb16(pb);
8928  else if (size == 4)
8929  *value = avio_rb32(pb);
8930  else if (size == 8) {
8931  *value = avio_rb64(pb);
8932  if (*value < 0)
8933  return -1;
8934  } else
8935  return -1;
8936  return size;
8937 }
8938 
8940 {
8941  avio_rb32(pb); // version & flags.
8942  c->primary_item_id = avio_rb16(pb);
8943  av_log(c->fc, AV_LOG_TRACE, "pitm: primary_item_id %d\n", c->primary_item_id);
8944  return atom.size;
8945 }
8946 
8948 {
8949  c->idat_offset = avio_tell(pb);
8950  return 0;
8951 }
8952 
8954 {
8955  HEIFItem **heif_item;
8956  int version, offset_size, length_size, base_offset_size, index_size;
8957  int item_count, extent_count;
8958  int64_t base_offset, extent_offset, extent_length;
8959  uint8_t value;
8960 
8961  if (c->found_iloc) {
8962  av_log(c->fc, AV_LOG_INFO, "Duplicate iloc box found\n");
8963  return 0;
8964  }
8965 
8966  version = avio_r8(pb);
8967  avio_rb24(pb); // flags.
8968 
8969  value = avio_r8(pb);
8970  offset_size = (value >> 4) & 0xF;
8971  length_size = value & 0xF;
8972  value = avio_r8(pb);
8973  base_offset_size = (value >> 4) & 0xF;
8974  index_size = !version ? 0 : (value & 0xF);
8975  if (index_size) {
8976  avpriv_report_missing_feature(c->fc, "iloc: index_size != 0");
8977  return AVERROR_PATCHWELCOME;
8978  }
8979  item_count = (version < 2) ? avio_rb16(pb) : avio_rb32(pb);
8980 
8981  heif_item = av_realloc_array(c->heif_item, FFMAX(item_count, c->nb_heif_item), sizeof(*c->heif_item));
8982  if (!heif_item)
8983  return AVERROR(ENOMEM);
8984  c->heif_item = heif_item;
8985  if (item_count > c->nb_heif_item)
8986  memset(&c->heif_item[c->nb_heif_item], 0,
8987  sizeof(*c->heif_item) * (item_count - c->nb_heif_item));
8988  c->nb_heif_item = FFMAX(c->nb_heif_item, item_count);
8989 
8990  av_log(c->fc, AV_LOG_TRACE, "iloc: item_count %d\n", item_count);
8991  for (int i = 0; i < item_count; i++) {
8992  HEIFItem *item = NULL;
8993  int item_id = (version < 2) ? avio_rb16(pb) : avio_rb32(pb);
8994  int offset_type = (version > 0) ? avio_rb16(pb) & 0xf : 0;
8995  int j;
8996 
8997  if (avio_feof(pb))
8998  return AVERROR_INVALIDDATA;
8999  if (offset_type > 1) {
9000  avpriv_report_missing_feature(c->fc, "iloc offset type %d", offset_type);
9001  return AVERROR_PATCHWELCOME;
9002  }
9003 
9004  avio_rb16(pb); // data_reference_index.
9005  if (rb_size(pb, &base_offset, base_offset_size) < 0)
9006  return AVERROR_INVALIDDATA;
9007  extent_count = avio_rb16(pb);
9008  if (extent_count > 1) {
9009  // For still AVIF images, we only support one extent item.
9010  avpriv_report_missing_feature(c->fc, "iloc: extent_count > 1");
9011  return AVERROR_PATCHWELCOME;
9012  }
9013 
9014  if (rb_size(pb, &extent_offset, offset_size) < 0 ||
9015  rb_size(pb, &extent_length, length_size) < 0 ||
9016  base_offset > INT64_MAX - extent_offset)
9017  return AVERROR_INVALIDDATA;
9018 
9019  for (j = 0; j < c->nb_heif_item; j++) {
9020  item = c->heif_item[j];
9021  if (!item)
9022  item = c->heif_item[j] = av_mallocz(sizeof(*item));
9023  else if (item->item_id != item_id)
9024  continue;
9025  break;
9026  }
9027  if (!item)
9028  return AVERROR(ENOMEM);
9029  if (j == c->nb_heif_item)
9030  return AVERROR_INVALIDDATA;
9031 
9032  item->item_id = item_id;
9033 
9034  if (offset_type == 1)
9035  item->is_idat_relative = 1;
9036  item->extent_length = extent_length;
9037  item->extent_offset = base_offset + extent_offset;
9038  av_log(c->fc, AV_LOG_TRACE, "iloc: item_idx %d, item->item_id %d, offset_type %d, "
9039  "extent_offset %"PRId64", extent_length %"PRId64"\n",
9040  i, item->item_id, offset_type, item->extent_offset, item->extent_length);
9041  }
9042 
9043  c->found_iloc = 1;
9044  return atom.size;
9045 }
9046 
9048 {
9049  HEIFItem *item = NULL;
9050  AVBPrint item_name;
9051  int64_t size = atom.size;
9052  uint32_t item_type;
9053  int item_id;
9054  int i, version, ret;
9055 
9056  version = avio_r8(pb);
9057  avio_rb24(pb); // flags.
9058  size -= 4;
9059  if (size < 0)
9060  return AVERROR_INVALIDDATA;
9061 
9062  if (version < 2) {
9063  avpriv_report_missing_feature(c->fc, "infe version < 2");
9064  avio_skip(pb, size);
9065  return 1;
9066  }
9067 
9068  item_id = version > 2 ? avio_rb32(pb) : avio_rb16(pb);
9069  avio_rb16(pb); // item_protection_index
9070  item_type = avio_rl32(pb);
9071  size -= 8;
9072  if (size < 1)
9073  return AVERROR_INVALIDDATA;
9074 
9077  if (ret < 0) {
9079  return ret;
9080  }
9081 
9082  av_log(c->fc, AV_LOG_TRACE, "infe: item_id %d, item_type %s, item_name %s\n",
9083  item_id, av_fourcc2str(item_type), item_name.str);
9084 
9085  size -= ret + 1;
9086  if (size > 0)
9087  avio_skip(pb, size);
9088 
9089  for (i = 0; i < c->nb_heif_item; i++) {
9090  item = c->heif_item[i];
9091  if (!item)
9092  item = c->heif_item[i] = av_mallocz(sizeof(*item));
9093  else if (item->item_id != item_id)
9094  continue;
9095  break;
9096  }
9097  if (!item) {
9099  return AVERROR(ENOMEM);
9100  }
9101  if (i == c->nb_heif_item) {
9103  return AVERROR_INVALIDDATA;
9104  }
9105 
9106  av_freep(&item->name);
9107  av_bprint_finalize(&item_name, ret ? &item->name : NULL);
9108  item->item_id = item_id;
9109  item->type = item_type;
9110 
9111  switch (item_type) {
9112  case MKTAG('a','v','0','1'):
9113  case MKTAG('j','p','e','g'):
9114  case MKTAG('h','v','c','1'):
9115  ret = heif_add_stream(c, item);
9116  if (ret < 0)
9117  return ret;
9118  break;
9119  }
9120 
9121  return 0;
9122 }
9123 
9125 {
9126  HEIFItem **heif_item;
9127  int entry_count;
9128  int version, got_stream = 0, ret, i;
9129 
9130  if (c->found_iinf) {
9131  av_log(c->fc, AV_LOG_WARNING, "Duplicate iinf box found\n");
9132  return 0;
9133  }
9134 
9135  version = avio_r8(pb);
9136  avio_rb24(pb); // flags.
9137  entry_count = version ? avio_rb32(pb) : avio_rb16(pb);
9138 
9139  heif_item = av_realloc_array(c->heif_item, FFMAX(entry_count, c->nb_heif_item), sizeof(*c->heif_item));
9140  if (!heif_item)
9141  return AVERROR(ENOMEM);
9142  c->heif_item = heif_item;
9143  if (entry_count > c->nb_heif_item)
9144  memset(&c->heif_item[c->nb_heif_item], 0,
9145  sizeof(*c->heif_item) * (entry_count - c->nb_heif_item));
9146  c->nb_heif_item = FFMAX(c->nb_heif_item, entry_count);
9147 
9148  for (i = 0; i < entry_count; i++) {
9149  MOVAtom infe;
9150 
9151  infe.size = avio_rb32(pb) - 8;
9152  infe.type = avio_rl32(pb);
9153  if (avio_feof(pb)) {
9155  goto fail;
9156  }
9157  ret = mov_read_infe(c, pb, infe);
9158  if (ret < 0)
9159  goto fail;
9160  if (!ret)
9161  got_stream = 1;
9162  }
9163 
9164  c->found_iinf = got_stream;
9165  return 0;
9166 fail:
9167  for (; i >= 0; i--) {
9168  HEIFItem *item = c->heif_item[i];
9169 
9170  if (!item)
9171  continue;
9172 
9173  av_freep(&item->name);
9174  }
9175  return ret;
9176 }
9177 
9179 {
9180  HEIFItem *item = NULL;
9181  HEIFGrid *grid;
9182  int entries, i;
9183  int from_item_id = version ? avio_rb32(pb) : avio_rb16(pb);
9184  int ret = 0;
9185 
9186  for (int i = 0; i < c->nb_heif_grid; i++) {
9187  if (c->heif_grid[i].item->item_id == from_item_id) {
9188  av_log(c->fc, AV_LOG_ERROR, "More than one 'dimg' box "
9189  "referencing the same Derived Image item\n");
9190  return AVERROR_INVALIDDATA;
9191  }
9192  }
9193  for (int i = 0; i < c->nb_heif_item; i++) {
9194  if (!c->heif_item[i] || c->heif_item[i]->item_id != from_item_id)
9195  continue;
9196  item = c->heif_item[i];
9197 
9198  switch (item->type) {
9199  case MKTAG('g','r','i','d'):
9200  case MKTAG('i','o','v','l'):
9201  break;
9202  default:
9203  avpriv_report_missing_feature(c->fc, "Derived Image item of type %s",
9204  av_fourcc2str(item->type));
9205  return 0;
9206  }
9207  break;
9208  }
9209  if (!item) {
9210  av_log(c->fc, AV_LOG_ERROR, "Missing grid information\n");
9211  return AVERROR_INVALIDDATA;
9212  }
9213 
9214  grid = av_realloc_array(c->heif_grid, c->nb_heif_grid + 1U,
9215  sizeof(*c->heif_grid));
9216  if (!grid)
9217  return AVERROR(ENOMEM);
9218  c->heif_grid = grid;
9219  grid = &grid[c->nb_heif_grid];
9220 
9221  entries = avio_rb16(pb);
9222  grid->tile_id_list = av_malloc_array(entries, sizeof(*grid->tile_id_list));
9223  grid->tile_idx_list = av_calloc(entries, sizeof(*grid->tile_idx_list));
9224  grid->tile_item_list = av_calloc(entries, sizeof(*grid->tile_item_list));
9225  if (!grid->tile_id_list || !grid->tile_item_list || !grid->tile_idx_list) {
9226  ret = AVERROR(ENOMEM);
9227  goto fail;
9228  }
9229  /* 'to' item ids */
9230  for (i = 0; i < entries; i++) {
9231  grid->tile_id_list[i] = version ? avio_rb32(pb) : avio_rb16(pb);
9232 
9233  if (avio_feof(pb)) {
9235  goto fail;
9236  }
9237  }
9238 
9239  grid->nb_tiles = entries;
9240  grid->item = item;
9241  ++c->nb_heif_grid;
9242 
9243  av_log(c->fc, AV_LOG_TRACE, "dimg: from_item_id %d, entries %d\n",
9244  from_item_id, entries);
9245 
9246  return 0;
9247 fail:
9248  av_freep(&grid->tile_id_list);
9249  av_freep(&grid->tile_idx_list);
9250  av_freep(&grid->tile_item_list);
9251 
9252  return ret;
9253 }
9254 
9255 static int mov_read_iref_cdsc(MOVContext *c, AVIOContext *pb, uint32_t type, int version)
9256 {
9257  HEIFItem *from_item = NULL;
9258  int entries;
9259  int from_item_id = version ? avio_rb32(pb) : avio_rb16(pb);
9260  const HEIFItemRef ref = { type, from_item_id };
9261 
9262  from_item = get_heif_item(c, from_item_id);
9263  if (!from_item) {
9264  av_log(c->fc, AV_LOG_ERROR, "Missing stream referenced by thmb item\n");
9265  return AVERROR_INVALIDDATA;
9266  }
9267 
9268  entries = avio_rb16(pb);
9269  /* 'to' item ids */
9270  for (int i = 0; i < entries; i++) {
9271  HEIFItem *item = get_heif_item(c, version ? avio_rb32(pb) : avio_rb16(pb));
9272 
9273  if (avio_feof(pb))
9274  return AVERROR_INVALIDDATA;
9275 
9276  if (!item) {
9277  av_log(c->fc, AV_LOG_WARNING, "Missing stream referenced by %s item\n",
9278  av_fourcc2str(type));
9279  continue;
9280  }
9281 
9282  if (!av_dynarray2_add((void **)&item->iref_list, &item->nb_iref_list,
9283  sizeof(*item->iref_list), (const uint8_t *)&ref))
9284  return AVERROR(ENOMEM);
9285  }
9286 
9287  av_log(c->fc, AV_LOG_TRACE, "%s: from_item_id %d, entries %d\n",
9288  av_fourcc2str(type), from_item_id, entries);
9289 
9290  return 0;
9291 }
9292 
9294 {
9295  int version = avio_r8(pb);
9296  int ret;
9297 
9298  avio_rb24(pb); // flags
9299  atom.size -= 4;
9300 
9301  if (version > 1) {
9302  av_log(c->fc, AV_LOG_WARNING, "Unknown iref box version %d\n", version);
9303  return 0;
9304  }
9305 
9306  while (atom.size) {
9307  uint32_t type, size = avio_rb32(pb);
9308  int64_t next = avio_tell(pb);
9309 
9310  if (size < 14 || next < 0 || next > INT64_MAX - size)
9311  return AVERROR_INVALIDDATA;
9312 
9313  next += size - 4;
9314  type = avio_rl32(pb);
9315  switch (type) {
9316  case MKTAG('d','i','m','g'):
9317  ret = mov_read_iref_dimg(c, pb, version);
9318  if (ret < 0)
9319  return ret;
9320  break;
9321  case MKTAG('c','d','s','c'):
9322  case MKTAG('t','h','m','b'):
9323  ret = mov_read_iref_cdsc(c, pb, type, version);
9324  if (ret < 0)
9325  return ret;
9326  break;
9327  default:
9328  av_log(c->fc, AV_LOG_DEBUG, "Unknown iref type %s size %"PRIu32"\n",
9329  av_fourcc2str(type), size);
9330  }
9331 
9332  atom.size -= size;
9333  avio_seek(pb, next, SEEK_SET);
9334  }
9335  return 0;
9336 }
9337 
9339 {
9340  HEIFItem *item;
9341  uint32_t width, height;
9342 
9343  avio_r8(pb); /* version */
9344  avio_rb24(pb); /* flags */
9345  width = avio_rb32(pb);
9346  height = avio_rb32(pb);
9347 
9348  av_log(c->fc, AV_LOG_TRACE, "ispe: item_id %d, width %"PRIu32", height %"PRIu32"\n",
9349  c->cur_item_id, width, height);
9350 
9351  item = get_heif_item(c, c->cur_item_id);
9352  if (item) {
9353  item->width = width;
9354  item->height = height;
9355  }
9356 
9357  return 0;
9358 }
9359 
9361 {
9362  HEIFItem *item;
9363  int angle;
9364 
9365  angle = avio_r8(pb) & 0x3;
9366 
9367  av_log(c->fc, AV_LOG_TRACE, "irot: item_id %d, angle %u\n",
9368  c->cur_item_id, angle);
9369 
9370  item = get_heif_item(c, c->cur_item_id);
9371  if (item) {
9372  // angle * 90 specifies the angle (in anti-clockwise direction)
9373  // in units of degrees.
9374  item->rotation = angle * 90;
9375  }
9376 
9377  return 0;
9378 }
9379 
9381 {
9382  HEIFItem *item;
9383  int axis;
9384 
9385  axis = avio_r8(pb) & 0x1;
9386 
9387  av_log(c->fc, AV_LOG_TRACE, "imir: item_id %d, axis %u\n",
9388  c->cur_item_id, axis);
9389 
9390  item = get_heif_item(c, c->cur_item_id);
9391  if (item) {
9392  item->hflip = axis;
9393  item->vflip = !axis;
9394  }
9395 
9396  return 0;
9397 }
9398 
9400 {
9401  typedef struct MOVAtoms {
9402  FFIOContext b;
9403  uint32_t type;
9404  int64_t size;
9405  uint8_t *data;
9406  } MOVAtoms;
9407  MOVAtoms *atoms = NULL;
9408  MOVAtom a;
9409  unsigned count;
9410  int nb_atoms = 0;
9411  int version, flags;
9412  int ret;
9413 
9414  a.size = avio_rb32(pb);
9415  a.type = avio_rl32(pb);
9416 
9417  if (a.size < 8 || a.type != MKTAG('i','p','c','o'))
9418  return AVERROR_INVALIDDATA;
9419 
9420  a.size -= 8;
9421  while (a.size >= 8) {
9422  MOVAtoms *ref = av_dynarray2_add((void**)&atoms, &nb_atoms, sizeof(MOVAtoms), NULL);
9423  if (!ref) {
9424  ret = AVERROR(ENOMEM);
9425  goto fail;
9426  }
9427  ref->data = NULL;
9428  ref->size = avio_rb32(pb);
9429  ref->type = avio_rl32(pb);
9430  if (ref->size > a.size || ref->size < 8)
9431  break;
9432  ref->data = av_malloc(ref->size);
9433  if (!ref->data) {
9435  goto fail;
9436  }
9437  av_log(c->fc, AV_LOG_TRACE, "ipco: index %d, box type %s\n", nb_atoms, av_fourcc2str(ref->type));
9438  avio_seek(pb, -8, SEEK_CUR);
9439  if (avio_read(pb, ref->data, ref->size) != ref->size) {
9441  goto fail;
9442  }
9443  ffio_init_read_context(&ref->b, ref->data, ref->size);
9444  a.size -= ref->size;
9445  }
9446 
9447  if (a.size) {
9449  goto fail;
9450  }
9451 
9452  a.size = avio_rb32(pb);
9453  a.type = avio_rl32(pb);
9454 
9455  if (a.size < 8 || a.type != MKTAG('i','p','m','a')) {
9457  goto fail;
9458  }
9459 
9460  version = avio_r8(pb);
9461  flags = avio_rb24(pb);
9462  count = avio_rb32(pb);
9463 
9464  for (int i = 0; i < count; i++) {
9465  int item_id = version ? avio_rb32(pb) : avio_rb16(pb);
9466  int assoc_count = avio_r8(pb);
9467 
9468  if (avio_feof(pb)) {
9470  goto fail;
9471  }
9472 
9473  for (int j = 0; j < assoc_count; j++) {
9474  MOVAtoms *ref;
9475  int index = avio_r8(pb) & 0x7f;
9476  if (flags & 1) {
9477  index <<= 8;
9478  index |= avio_r8(pb);
9479  }
9480  if (index > nb_atoms || index <= 0) {
9482  goto fail;
9483  }
9484  ref = &atoms[--index];
9485 
9486  av_log(c->fc, AV_LOG_TRACE, "ipma: property_index %d, item_id %d, item_type %s\n",
9487  index + 1, item_id, av_fourcc2str(ref->type));
9488 
9489  c->cur_item_id = item_id;
9490 
9491  ret = mov_read_default(c, &ref->b.pub,
9492  (MOVAtom) { .size = ref->size,
9493  .type = MKTAG('i','p','c','o') });
9494  if (ret < 0)
9495  goto fail;
9496  ffio_init_read_context(&ref->b, ref->data, ref->size);
9497  }
9498  }
9499 
9500  ret = 0;
9501 fail:
9502  c->cur_item_id = -1;
9503  for (int i = 0; i < nb_atoms; i++)
9504  av_free(atoms[i].data);
9505  av_free(atoms);
9506 
9507  return ret;
9508 }
9509 
9511 { MKTAG('A','C','L','R'), mov_read_aclr },
9512 { MKTAG('A','P','R','G'), mov_read_avid },
9513 { MKTAG('A','A','L','P'), mov_read_avid },
9514 { MKTAG('A','R','E','S'), mov_read_ares },
9515 { MKTAG('a','v','s','s'), mov_read_avss },
9516 { MKTAG('a','v','1','C'), mov_read_glbl },
9517 { MKTAG('c','h','p','l'), mov_read_chpl },
9518 { MKTAG('c','o','6','4'), mov_read_stco },
9519 { MKTAG('c','o','l','r'), mov_read_colr },
9520 { MKTAG('c','t','t','s'), mov_read_ctts }, /* composition time to sample */
9521 { MKTAG('d','i','n','f'), mov_read_default },
9522 { MKTAG('D','p','x','E'), mov_read_dpxe },
9523 { MKTAG('d','r','e','f'), mov_read_dref },
9524 { MKTAG('e','d','t','s'), mov_read_default },
9525 { MKTAG('e','l','s','t'), mov_read_elst },
9526 { MKTAG('e','n','d','a'), mov_read_enda },
9527 { MKTAG('f','i','e','l'), mov_read_fiel },
9528 { MKTAG('a','d','r','m'), mov_read_adrm },
9529 { MKTAG('f','t','y','p'), mov_read_ftyp },
9530 { MKTAG('g','l','b','l'), mov_read_glbl },
9531 { MKTAG('h','d','l','r'), mov_read_hdlr },
9532 { MKTAG('i','l','s','t'), mov_read_ilst },
9533 { MKTAG('j','p','2','h'), mov_read_jp2h },
9534 { MKTAG('m','d','a','t'), mov_read_mdat },
9535 { MKTAG('m','d','h','d'), mov_read_mdhd },
9536 { MKTAG('m','d','i','a'), mov_read_default },
9537 { MKTAG('m','e','t','a'), mov_read_meta },
9538 { MKTAG('m','i','n','f'), mov_read_default },
9539 { MKTAG('m','o','o','f'), mov_read_moof },
9540 { MKTAG('m','o','o','v'), mov_read_moov },
9541 { MKTAG('m','v','e','x'), mov_read_default },
9542 { MKTAG('m','v','h','d'), mov_read_mvhd },
9543 { MKTAG('S','M','I',' '), mov_read_svq3 },
9544 { MKTAG('a','l','a','c'), mov_read_alac }, /* alac specific atom */
9545 { MKTAG('a','v','c','C'), mov_read_glbl },
9546 { MKTAG('p','a','s','p'), mov_read_pasp },
9547 { MKTAG('c','l','a','p'), mov_read_clap },
9548 { MKTAG('s','b','a','s'), mov_read_sbas },
9549 { MKTAG('s','i','d','x'), mov_read_sidx },
9550 { MKTAG('s','t','b','l'), mov_read_default },
9551 { MKTAG('s','t','c','o'), mov_read_stco },
9552 { MKTAG('s','t','p','s'), mov_read_stps },
9553 { MKTAG('s','t','r','f'), mov_read_strf },
9554 { MKTAG('s','t','s','c'), mov_read_stsc },
9555 { MKTAG('s','t','s','d'), mov_read_stsd }, /* sample description */
9556 { MKTAG('s','t','s','s'), mov_read_stss }, /* sync sample */
9557 { MKTAG('s','t','s','z'), mov_read_stsz }, /* sample size */
9558 { MKTAG('s','t','t','s'), mov_read_stts },
9559 { MKTAG('s','t','z','2'), mov_read_stsz }, /* compact sample size */
9560 { MKTAG('s','d','t','p'), mov_read_sdtp }, /* independent and disposable samples */
9561 { MKTAG('t','k','h','d'), mov_read_tkhd }, /* track header */
9562 { MKTAG('t','f','d','t'), mov_read_tfdt },
9563 { MKTAG('t','f','h','d'), mov_read_tfhd }, /* track fragment header */
9564 { MKTAG('t','r','a','k'), mov_read_trak },
9565 { MKTAG('t','r','a','f'), mov_read_default },
9566 { MKTAG('t','r','e','f'), mov_read_default },
9567 { MKTAG('t','m','c','d'), mov_read_tmcd },
9568 { MKTAG('c','h','a','p'), mov_read_chap },
9569 { MKTAG('t','r','e','x'), mov_read_trex },
9570 { MKTAG('t','r','u','n'), mov_read_trun },
9571 { MKTAG('u','d','t','a'), mov_read_default },
9572 { MKTAG('w','a','v','e'), mov_read_wave },
9573 { MKTAG('e','s','d','s'), mov_read_esds },
9574 { MKTAG('d','a','c','3'), mov_read_dac3 }, /* AC-3 info */
9575 { MKTAG('d','e','c','3'), mov_read_dec3 }, /* EAC-3 info */
9576 { MKTAG('d','d','t','s'), mov_read_ddts }, /* DTS audio descriptor */
9577 { MKTAG('w','i','d','e'), mov_read_wide }, /* place holder */
9578 { MKTAG('w','f','e','x'), mov_read_wfex },
9579 { MKTAG('c','m','o','v'), mov_read_cmov },
9580 { MKTAG('c','h','a','n'), mov_read_chan }, /* channel layout from quicktime */
9581 { MKTAG('c','h','n','l'), mov_read_chnl }, /* channel layout from ISO-14496-12 */
9582 { MKTAG('d','v','c','1'), mov_read_dvc1 },
9583 { MKTAG('s','g','p','d'), mov_read_sgpd },
9584 { MKTAG('s','b','g','p'), mov_read_sbgp },
9585 { MKTAG('h','v','c','C'), mov_read_glbl },
9586 { MKTAG('v','v','c','C'), mov_read_glbl },
9587 { MKTAG('u','u','i','d'), mov_read_uuid },
9588 { MKTAG('C','i','n', 0x8e), mov_read_targa_y216 },
9589 { MKTAG('f','r','e','e'), mov_read_free },
9590 { MKTAG('-','-','-','-'), mov_read_custom },
9591 { MKTAG('s','i','n','f'), mov_read_default },
9592 { MKTAG('f','r','m','a'), mov_read_frma },
9593 { MKTAG('s','e','n','c'), mov_read_senc },
9594 { MKTAG('s','a','i','z'), mov_read_saiz },
9595 { MKTAG('s','a','i','o'), mov_read_saio },
9596 { MKTAG('p','s','s','h'), mov_read_pssh },
9597 { MKTAG('s','c','h','m'), mov_read_schm },
9598 { MKTAG('s','c','h','i'), mov_read_default },
9599 { MKTAG('t','e','n','c'), mov_read_tenc },
9600 { MKTAG('d','f','L','a'), mov_read_dfla },
9601 { MKTAG('s','t','3','d'), mov_read_st3d }, /* stereoscopic 3D video box */
9602 { MKTAG('s','v','3','d'), mov_read_sv3d }, /* spherical video box */
9603 { MKTAG('v','e','x','u'), mov_read_vexu }, /* video extension usage */
9604 { MKTAG('h','f','o','v'), mov_read_hfov },
9605 { MKTAG('d','O','p','s'), mov_read_dops },
9606 { MKTAG('d','m','l','p'), mov_read_dmlp },
9607 { MKTAG('S','m','D','m'), mov_read_smdm },
9608 { MKTAG('C','o','L','L'), mov_read_coll },
9609 { MKTAG('v','p','c','C'), mov_read_vpcc },
9610 { MKTAG('m','d','c','v'), mov_read_mdcv },
9611 { MKTAG('c','l','l','i'), mov_read_clli },
9612 { MKTAG('d','v','c','C'), mov_read_dvcc_dvvc },
9613 { MKTAG('d','v','v','C'), mov_read_dvcc_dvvc },
9614 { MKTAG('d','v','w','C'), mov_read_dvcc_dvvc },
9615 { MKTAG('k','i','n','d'), mov_read_kind },
9616 { MKTAG('S','A','3','D'), mov_read_SA3D }, /* ambisonic audio box */
9617 { MKTAG('S','A','N','D'), mov_read_SAND }, /* non diegetic audio box */
9618 { MKTAG('i','l','o','c'), mov_read_iloc },
9619 { MKTAG('p','c','m','C'), mov_read_pcmc }, /* PCM configuration box */
9620 { MKTAG('p','i','t','m'), mov_read_pitm },
9621 { MKTAG('e','v','c','C'), mov_read_glbl },
9622 { MKTAG('i','d','a','t'), mov_read_idat },
9623 { MKTAG('i','m','i','r'), mov_read_imir },
9624 { MKTAG('i','r','e','f'), mov_read_iref },
9625 { MKTAG('i','s','p','e'), mov_read_ispe },
9626 { MKTAG('i','r','o','t'), mov_read_irot },
9627 { MKTAG('i','p','r','p'), mov_read_iprp },
9628 { MKTAG('i','i','n','f'), mov_read_iinf },
9629 { MKTAG('a','m','v','e'), mov_read_amve }, /* ambient viewing environment box */
9630 { MKTAG('l','h','v','C'), mov_read_lhvc },
9631 { MKTAG('l','v','c','C'), mov_read_glbl },
9632 { MKTAG('a','p','v','C'), mov_read_glbl },
9633 #if CONFIG_IAMFDEC
9634 { MKTAG('i','a','c','b'), mov_read_iacb },
9635 #endif
9636 { MKTAG('s','r','a','t'), mov_read_srat },
9637 { 0, NULL }
9638 };
9639 
9641 {
9642  int64_t total_size = 0;
9643  MOVAtom a;
9644  int i;
9645 
9646  if (c->atom_depth > 10) {
9647  av_log(c->fc, AV_LOG_ERROR, "Atoms too deeply nested\n");
9648  return AVERROR_INVALIDDATA;
9649  }
9650  c->atom_depth ++;
9651 
9652  if (atom.size < 0)
9653  atom.size = INT64_MAX;
9654  while (total_size <= atom.size - 8) {
9655  int (*parse)(MOVContext*, AVIOContext*, MOVAtom) = NULL;
9656  a.size = avio_rb32(pb);
9657  a.type = avio_rl32(pb);
9658  if (avio_feof(pb))
9659  break;
9660  if (((a.type == MKTAG('f','r','e','e') && c->moov_retry) ||
9661  a.type == MKTAG('h','o','o','v')) &&
9662  a.size >= 8 &&
9663  c->fc->strict_std_compliance < FF_COMPLIANCE_STRICT) {
9664  uint32_t type;
9665  avio_skip(pb, 4);
9666  type = avio_rl32(pb);
9667  if (avio_feof(pb))
9668  break;
9669  avio_seek(pb, -8, SEEK_CUR);
9670  if (type == MKTAG('m','v','h','d') ||
9671  type == MKTAG('c','m','o','v')) {
9672  av_log(c->fc, AV_LOG_ERROR, "Detected moov in a free or hoov atom.\n");
9673  a.type = MKTAG('m','o','o','v');
9674  }
9675  }
9676  if (atom.type != MKTAG('r','o','o','t') &&
9677  atom.type != MKTAG('m','o','o','v')) {
9678  if (a.type == MKTAG('t','r','a','k') ||
9679  a.type == MKTAG('m','d','a','t')) {
9680  av_log(c->fc, AV_LOG_ERROR, "Broken file, trak/mdat not at top-level\n");
9681  avio_skip(pb, -8);
9682  c->atom_depth --;
9683  return 0;
9684  }
9685  }
9686  total_size += 8;
9687  if (a.size == 1 && total_size + 8 <= atom.size) { /* 64 bit extended size */
9688  a.size = avio_rb64(pb) - 8;
9689  total_size += 8;
9690  }
9691  av_log(c->fc, AV_LOG_TRACE, "type:'%s' parent:'%s' sz: %"PRId64" %"PRId64" %"PRId64"\n",
9692  av_fourcc2str(a.type), av_fourcc2str(atom.type), a.size, total_size, atom.size);
9693  if (a.size == 0) {
9694  a.size = atom.size - total_size + 8;
9695  }
9696  if (a.size < 0)
9697  break;
9698  a.size -= 8;
9699  if (a.size < 0)
9700  break;
9701  a.size = FFMIN(a.size, atom.size - total_size);
9702 
9703  for (i = 0; mov_default_parse_table[i].type; i++)
9704  if (mov_default_parse_table[i].type == a.type) {
9706  break;
9707  }
9708 
9709  // container is user data
9710  if (!parse && (atom.type == MKTAG('u','d','t','a') ||
9711  atom.type == MKTAG('i','l','s','t')))
9713 
9714  // Supports parsing the QuickTime Metadata Keys.
9715  // https://developer.apple.com/library/mac/documentation/QuickTime/QTFF/Metadata/Metadata.html
9716  if (!parse && c->found_hdlr_mdta &&
9717  atom.type == MKTAG('m','e','t','a') &&
9718  a.type == MKTAG('k','e','y','s') &&
9719  c->meta_keys_count == 0) {
9720  parse = mov_read_keys;
9721  }
9722 
9723  if (!parse) { /* skip leaf atoms data */
9724  avio_skip(pb, a.size);
9725  } else {
9726  int64_t start_pos = avio_tell(pb);
9727  int64_t left;
9728  int err = parse(c, pb, a);
9729  if (err < 0) {
9730  c->atom_depth --;
9731  return err;
9732  }
9733  if (c->found_moov && c->found_mdat && a.size <= INT64_MAX - start_pos &&
9734  ((!(pb->seekable & AVIO_SEEKABLE_NORMAL) || c->fc->flags & AVFMT_FLAG_IGNIDX || c->frag_index.complete) ||
9735  start_pos + a.size == avio_size(pb))) {
9736  if (!(pb->seekable & AVIO_SEEKABLE_NORMAL) || c->fc->flags & AVFMT_FLAG_IGNIDX || c->frag_index.complete)
9737  c->next_root_atom = start_pos + a.size;
9738  c->atom_depth --;
9739  return 0;
9740  }
9741  left = a.size - avio_tell(pb) + start_pos;
9742  if (left > 0) /* skip garbage at atom end */
9743  avio_skip(pb, left);
9744  else if (left < 0) {
9745  av_log(c->fc, AV_LOG_WARNING,
9746  "overread end of atom '%s' by %"PRId64" bytes\n",
9747  av_fourcc2str(a.type), -left);
9748  avio_seek(pb, left, SEEK_CUR);
9749  }
9750  }
9751 
9752  total_size += a.size;
9753  }
9754 
9755  if (total_size < atom.size && atom.size < 0x7ffff)
9756  avio_skip(pb, atom.size - total_size);
9757 
9758  c->atom_depth --;
9759  return 0;
9760 }
9761 
9762 static int mov_probe(const AVProbeData *p)
9763 {
9764  int64_t offset;
9765  uint32_t tag;
9766  int score = 0;
9767  int moov_offset = -1;
9768 
9769  /* check file header */
9770  offset = 0;
9771  for (;;) {
9772  int64_t size;
9773  int minsize = 8;
9774  /* ignore invalid offset */
9775  if ((offset + 8ULL) > (unsigned int)p->buf_size)
9776  break;
9777  size = AV_RB32(p->buf + offset);
9778  if (size == 1 && offset + 16 <= (unsigned int)p->buf_size) {
9779  size = AV_RB64(p->buf+offset + 8);
9780  minsize = 16;
9781  } else if (size == 0) {
9782  size = p->buf_size - offset;
9783  }
9784  if (size < minsize) {
9785  offset += 4;
9786  continue;
9787  }
9788  tag = AV_RL32(p->buf + offset + 4);
9789  switch(tag) {
9790  /* check for obvious tags */
9791  case MKTAG('m','o','o','v'):
9792  moov_offset = offset + 4;
9793  case MKTAG('m','d','a','t'):
9794  case MKTAG('p','n','o','t'): /* detect movs with preview pics like ew.mov and april.mov */
9795  case MKTAG('u','d','t','a'): /* Packet Video PVAuthor adds this and a lot of more junk */
9796  case MKTAG('f','t','y','p'):
9797  if (tag == MKTAG('f','t','y','p') &&
9798  ( AV_RL32(p->buf + offset + 8) == MKTAG('j','p','2',' ')
9799  || AV_RL32(p->buf + offset + 8) == MKTAG('j','p','x',' ')
9800  || AV_RL32(p->buf + offset + 8) == MKTAG('j','x','l',' ')
9801  )) {
9802  score = FFMAX(score, 5);
9803  } else {
9804  score = AVPROBE_SCORE_MAX;
9805  }
9806  break;
9807  /* those are more common words, so rate then a bit less */
9808  case MKTAG('e','d','i','w'): /* xdcam files have reverted first tags */
9809  case MKTAG('w','i','d','e'):
9810  case MKTAG('f','r','e','e'):
9811  case MKTAG('j','u','n','k'):
9812  case MKTAG('p','i','c','t'):
9813  score = FFMAX(score, AVPROBE_SCORE_MAX - 5);
9814  break;
9815  case MKTAG(0x82,0x82,0x7f,0x7d):
9816  score = FFMAX(score, AVPROBE_SCORE_EXTENSION - 5);
9817  break;
9818  case MKTAG('s','k','i','p'):
9819  case MKTAG('u','u','i','d'):
9820  case MKTAG('p','r','f','l'):
9821  /* if we only find those cause probedata is too small at least rate them */
9822  score = FFMAX(score, AVPROBE_SCORE_EXTENSION);
9823  break;
9824  }
9825  if (size > INT64_MAX - offset)
9826  break;
9827  offset += size;
9828  }
9829  if (score > AVPROBE_SCORE_MAX - 50 && moov_offset != -1) {
9830  /* moov atom in the header - we should make sure that this is not a
9831  * MOV-packed MPEG-PS */
9832  offset = moov_offset;
9833 
9834  while (offset < (p->buf_size - 16)) { /* Sufficient space */
9835  /* We found an actual hdlr atom */
9836  if (AV_RL32(p->buf + offset ) == MKTAG('h','d','l','r') &&
9837  AV_RL32(p->buf + offset + 8) == MKTAG('m','h','l','r') &&
9838  AV_RL32(p->buf + offset + 12) == MKTAG('M','P','E','G')) {
9839  av_log(NULL, AV_LOG_WARNING, "Found media data tag MPEG indicating this is a MOV-packed MPEG-PS.\n");
9840  /* We found a media handler reference atom describing an
9841  * MPEG-PS-in-MOV, return a
9842  * low score to force expanding the probe window until
9843  * mpegps_probe finds what it needs */
9844  return 5;
9845  } else {
9846  /* Keep looking */
9847  offset += 2;
9848  }
9849  }
9850  }
9851 
9852  return score;
9853 }
9854 
9855 // must be done after parsing all trak because there's no order requirement
9857 {
9858  MOVContext *mov = s->priv_data;
9859  MOVStreamContext *sc;
9860  int64_t cur_pos;
9861  int i, j;
9862  int chapter_track;
9863 
9864  for (j = 0; j < mov->nb_chapter_tracks; j++) {
9865  AVStream *st = NULL;
9866  FFStream *sti = NULL;
9867  chapter_track = mov->chapter_tracks[j];
9868  for (i = 0; i < s->nb_streams; i++) {
9869  sc = mov->fc->streams[i]->priv_data;
9870  if (sc->id == chapter_track) {
9871  st = s->streams[i];
9872  break;
9873  }
9874  }
9875  if (!st) {
9876  av_log(s, AV_LOG_ERROR, "Referenced QT chapter track not found\n");
9877  continue;
9878  }
9879  sti = ffstream(st);
9880 
9881  sc = st->priv_data;
9882  cur_pos = avio_tell(sc->pb);
9883 
9884  if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
9886  if (!st->attached_pic.data && sti->nb_index_entries) {
9887  // Retrieve the first frame, if possible
9888  AVIndexEntry *sample = &sti->index_entries[0];
9889  if (avio_seek(sc->pb, sample->pos, SEEK_SET) != sample->pos) {
9890  av_log(s, AV_LOG_ERROR, "Failed to retrieve first frame\n");
9891  goto finish;
9892  }
9893 
9894  if (ff_add_attached_pic(s, st, sc->pb, NULL, sample->size) < 0)
9895  goto finish;
9896  }
9897  } else {
9900  st->discard = AVDISCARD_ALL;
9901  for (int i = 0; i < sti->nb_index_entries; i++) {
9902  AVIndexEntry *sample = &sti->index_entries[i];
9903  int64_t end = i+1 < sti->nb_index_entries ? sti->index_entries[i+1].timestamp : st->duration;
9904  uint8_t *title;
9905  uint16_t ch;
9906  int len, title_len;
9907 
9908  if (end < sample->timestamp) {
9909  av_log(s, AV_LOG_WARNING, "ignoring stream duration which is shorter than chapters\n");
9910  end = AV_NOPTS_VALUE;
9911  }
9912 
9913  if (avio_seek(sc->pb, sample->pos, SEEK_SET) != sample->pos) {
9914  av_log(s, AV_LOG_ERROR, "Chapter %d not found in file\n", i);
9915  goto finish;
9916  }
9917 
9918  // the first two bytes are the length of the title
9919  len = avio_rb16(sc->pb);
9920  if (len > sample->size-2)
9921  continue;
9922  title_len = 2*len + 1;
9923  if (!(title = av_mallocz(title_len)))
9924  goto finish;
9925 
9926  // The samples could theoretically be in any encoding if there's an encd
9927  // atom following, but in practice are only utf-8 or utf-16, distinguished
9928  // instead by the presence of a BOM
9929  if (!len) {
9930  title[0] = 0;
9931  } else {
9932  ch = avio_rb16(sc->pb);
9933  if (ch == 0xfeff)
9934  avio_get_str16be(sc->pb, len, title, title_len);
9935  else if (ch == 0xfffe)
9936  avio_get_str16le(sc->pb, len, title, title_len);
9937  else {
9938  AV_WB16(title, ch);
9939  if (len == 1 || len == 2)
9940  title[len] = 0;
9941  else
9942  avio_get_str(sc->pb, INT_MAX, title + 2, len - 1);
9943  }
9944  }
9945 
9946  avpriv_new_chapter(s, i, st->time_base, sample->timestamp, end, title);
9947  av_freep(&title);
9948  }
9949  }
9950 finish:
9951  avio_seek(sc->pb, cur_pos, SEEK_SET);
9952  }
9953 }
9954 
9956  int64_t value, int flags)
9957 {
9958  AVTimecode tc;
9959  char buf[AV_TIMECODE_STR_SIZE];
9960  AVRational rate = st->avg_frame_rate;
9961  int ret = av_timecode_init(&tc, rate, flags, 0, s);
9962  if (ret < 0)
9963  return ret;
9964  av_dict_set(&st->metadata, "timecode",
9965  av_timecode_make_string(&tc, buf, value), 0);
9966  return 0;
9967 }
9968 
9970 {
9971  MOVStreamContext *sc = st->priv_data;
9972  FFStream *const sti = ffstream(st);
9973  char buf[AV_TIMECODE_STR_SIZE];
9974  int64_t cur_pos = avio_tell(sc->pb);
9975  int hh, mm, ss, ff, drop;
9976 
9977  if (!sti->nb_index_entries)
9978  return -1;
9979 
9980  avio_seek(sc->pb, sti->index_entries->pos, SEEK_SET);
9981  avio_skip(s->pb, 13);
9982  hh = avio_r8(s->pb);
9983  mm = avio_r8(s->pb);
9984  ss = avio_r8(s->pb);
9985  drop = avio_r8(s->pb);
9986  ff = avio_r8(s->pb);
9987  snprintf(buf, AV_TIMECODE_STR_SIZE, "%02d:%02d:%02d%c%02d",
9988  hh, mm, ss, drop ? ';' : ':', ff);
9989  av_dict_set(&st->metadata, "timecode", buf, 0);
9990 
9991  avio_seek(sc->pb, cur_pos, SEEK_SET);
9992  return 0;
9993 }
9994 
9996 {
9997  MOVStreamContext *sc = st->priv_data;
9998  FFStream *const sti = ffstream(st);
9999  int flags = 0;
10000  int64_t cur_pos = avio_tell(sc->pb);
10001  int64_t value;
10002  AVRational tc_rate = st->avg_frame_rate;
10003  int tmcd_nb_frames = sc->tmcd_nb_frames;
10004  int rounded_tc_rate;
10005 
10006  if (!sti->nb_index_entries)
10007  return -1;
10008 
10009  if (!tc_rate.num || !tc_rate.den || !tmcd_nb_frames)
10010  return -1;
10011 
10012  avio_seek(sc->pb, sti->index_entries->pos, SEEK_SET);
10013  value = avio_rb32(s->pb);
10014 
10015  if (sc->tmcd_flags & 0x0001) flags |= AV_TIMECODE_FLAG_DROPFRAME;
10016  if (sc->tmcd_flags & 0x0002) flags |= AV_TIMECODE_FLAG_24HOURSMAX;
10017  if (sc->tmcd_flags & 0x0004) flags |= AV_TIMECODE_FLAG_ALLOWNEGATIVE;
10018 
10019  /* Assume Counter flag is set to 1 in tmcd track (even though it is likely
10020  * not the case) and thus assume "frame number format" instead of QT one.
10021  * No sample with tmcd track can be found with a QT timecode at the moment,
10022  * despite what the tmcd track "suggests" (Counter flag set to 0 means QT
10023  * format). */
10024 
10025  /* 60 fps content have tmcd_nb_frames set to 30 but tc_rate set to 60, so
10026  * we multiply the frame number with the quotient.
10027  * See tickets #9492, #9710. */
10028  rounded_tc_rate = (tc_rate.num + tc_rate.den / 2LL) / tc_rate.den;
10029  /* Work around files where tmcd_nb_frames is rounded down from frame rate
10030  * instead of up. See ticket #5978. */
10031  if (tmcd_nb_frames == tc_rate.num / tc_rate.den &&
10032  s->strict_std_compliance < FF_COMPLIANCE_STRICT)
10033  tmcd_nb_frames = rounded_tc_rate;
10034  value = av_rescale(value, rounded_tc_rate, tmcd_nb_frames);
10035 
10037 
10038  avio_seek(sc->pb, cur_pos, SEEK_SET);
10039  return 0;
10040 }
10041 
10043  int i;
10044  if (!index || !*index) return;
10045  for (i = 0; i < (*index)->nb_encrypted_samples; i++) {
10046  av_encryption_info_free((*index)->encrypted_samples[i]);
10047  }
10048  av_freep(&(*index)->encrypted_samples);
10049  av_freep(&(*index)->auxiliary_info_sizes);
10050  av_freep(&(*index)->auxiliary_offsets);
10051  av_freep(index);
10052 }
10053 
10055 {
10056  MOVStreamContext *sc = st->priv_data;
10057 
10058  if (!sc || --sc->refcount) {
10059  st->priv_data = NULL;
10060  return;
10061  }
10062 
10063  av_freep(&sc->tts_data);
10064  for (int i = 0; i < sc->drefs_count; i++) {
10065  av_freep(&sc->drefs[i].path);
10066  av_freep(&sc->drefs[i].dir);
10067  }
10068  av_freep(&sc->drefs);
10069 
10070  sc->drefs_count = 0;
10071 
10072  if (!sc->pb_is_copied)
10073  ff_format_io_close(s, &sc->pb);
10074 
10075  sc->pb = NULL;
10076  av_freep(&sc->chunk_offsets);
10077  av_freep(&sc->stsc_data);
10078  av_freep(&sc->sample_sizes);
10079  av_freep(&sc->keyframes);
10080  av_freep(&sc->ctts_data);
10081  av_freep(&sc->stts_data);
10082  av_freep(&sc->sdtp_data);
10083  av_freep(&sc->stps_data);
10084  av_freep(&sc->elst_data);
10085  av_freep(&sc->rap_group);
10086  av_freep(&sc->sync_group);
10087  av_freep(&sc->sgpd_sync);
10088  av_freep(&sc->sample_offsets);
10089  av_freep(&sc->open_key_samples);
10090  av_freep(&sc->display_matrix);
10091  av_freep(&sc->index_ranges);
10092 
10093  if (sc->extradata)
10094  for (int i = 0; i < sc->stsd_count; i++)
10095  av_free(sc->extradata[i]);
10096  av_freep(&sc->extradata);
10097  av_freep(&sc->extradata_size);
10098 
10102 
10103  av_freep(&sc->stereo3d);
10104  av_freep(&sc->spherical);
10105  av_freep(&sc->mastering);
10106  av_freep(&sc->coll);
10107  av_freep(&sc->ambient);
10108 
10109 #if CONFIG_IAMFDEC
10110  if (sc->iamf)
10112 #endif
10113  av_freep(&sc->iamf);
10114 }
10115 
10117 {
10118  MOVContext *mov = s->priv_data;
10119  int i, j;
10120 
10121  for (i = 0; i < s->nb_streams; i++) {
10122  AVStream *st = s->streams[i];
10123 
10125  }
10126 
10127  av_freep(&mov->dv_demux);
10129  mov->dv_fctx = NULL;
10130 
10131  if (mov->meta_keys) {
10132  for (i = 1; i < mov->meta_keys_count; i++) {
10133  av_freep(&mov->meta_keys[i]);
10134  }
10135  av_freep(&mov->meta_keys);
10136  }
10137 
10138  av_freep(&mov->trex_data);
10139  av_freep(&mov->bitrates);
10140 
10141  for (i = 0; i < mov->frag_index.nb_items; i++) {
10143  for (j = 0; j < mov->frag_index.item[i].nb_stream_info; j++) {
10144  mov_free_encryption_index(&frag[j].encryption_index);
10145  }
10147  }
10148  av_freep(&mov->frag_index.item);
10149 
10150  av_freep(&mov->aes_decrypt);
10151  av_freep(&mov->chapter_tracks);
10152  for (i = 0; i < mov->nb_heif_item; i++) {
10153  if (!mov->heif_item[i])
10154  continue;
10155  av_freep(&mov->heif_item[i]->name);
10156  av_freep(&mov->heif_item[i]->iref_list);
10157  av_freep(&mov->heif_item[i]->icc_profile);
10158  av_freep(&mov->heif_item[i]);
10159  }
10160  av_freep(&mov->heif_item);
10161  for (i = 0; i < mov->nb_heif_grid; i++) {
10162  av_freep(&mov->heif_grid[i].tile_id_list);
10165  }
10166  av_freep(&mov->heif_grid);
10167 
10168  return 0;
10169 }
10170 
10171 static int tmcd_is_referenced(AVFormatContext *s, int tmcd_id)
10172 {
10173  int i;
10174 
10175  for (i = 0; i < s->nb_streams; i++) {
10176  AVStream *st = s->streams[i];
10177  MOVStreamContext *sc = st->priv_data;
10178 
10179  if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO &&
10180  sc->timecode_track == tmcd_id)
10181  return 1;
10182  }
10183  return 0;
10184 }
10185 
10186 /* look for a tmcd track not referenced by any video track, and export it globally */
10188 {
10189  int i;
10190 
10191  for (i = 0; i < s->nb_streams; i++) {
10192  AVStream *st = s->streams[i];
10193 
10194  if (st->codecpar->codec_tag == MKTAG('t','m','c','d') &&
10195  !tmcd_is_referenced(s, i + 1)) {
10196  AVDictionaryEntry *tcr = av_dict_get(st->metadata, "timecode", NULL, 0);
10197  if (tcr) {
10198  av_dict_set(&s->metadata, "timecode", tcr->value, 0);
10199  break;
10200  }
10201  }
10202  }
10203 }
10204 
10205 static int read_tfra(MOVContext *mov, AVIOContext *f)
10206 {
10207  int version, fieldlength, i, j;
10208  int64_t pos = avio_tell(f);
10209  uint32_t size = avio_rb32(f);
10210  unsigned track_id, item_count;
10211 
10212  if (avio_rb32(f) != MKBETAG('t', 'f', 'r', 'a')) {
10213  return 1;
10214  }
10215  av_log(mov->fc, AV_LOG_VERBOSE, "found tfra\n");
10216 
10217  version = avio_r8(f);
10218  avio_rb24(f);
10219  track_id = avio_rb32(f);
10220  fieldlength = avio_rb32(f);
10221  item_count = avio_rb32(f);
10222  for (i = 0; i < item_count; i++) {
10223  int64_t time, offset;
10224  int index;
10225  MOVFragmentStreamInfo * frag_stream_info;
10226 
10227  if (avio_feof(f)) {
10228  return AVERROR_INVALIDDATA;
10229  }
10230 
10231  if (version == 1) {
10232  time = avio_rb64(f);
10233  offset = avio_rb64(f);
10234  } else {
10235  time = avio_rb32(f);
10236  offset = avio_rb32(f);
10237  }
10238 
10239  // The first sample of each stream in a fragment is always a random
10240  // access sample. So it's entry in the tfra can be used as the
10241  // initial PTS of the fragment.
10242  index = update_frag_index(mov, offset);
10243  frag_stream_info = get_frag_stream_info(&mov->frag_index, index, track_id);
10244  if (frag_stream_info &&
10245  frag_stream_info->first_tfra_pts == AV_NOPTS_VALUE)
10246  frag_stream_info->first_tfra_pts = time;
10247 
10248  for (j = 0; j < ((fieldlength >> 4) & 3) + 1; j++)
10249  avio_r8(f);
10250  for (j = 0; j < ((fieldlength >> 2) & 3) + 1; j++)
10251  avio_r8(f);
10252  for (j = 0; j < ((fieldlength >> 0) & 3) + 1; j++)
10253  avio_r8(f);
10254  }
10255 
10256  avio_seek(f, pos + size, SEEK_SET);
10257  return 0;
10258 }
10259 
10261 {
10262  int64_t stream_size = avio_size(f);
10263  int64_t original_pos = avio_tell(f);
10264  int64_t seek_ret;
10265  int ret = -1;
10266  if ((seek_ret = avio_seek(f, stream_size - 4, SEEK_SET)) < 0) {
10267  ret = seek_ret;
10268  goto fail;
10269  }
10270  c->mfra_size = avio_rb32(f);
10271  c->have_read_mfra_size = 1;
10272  if (!c->mfra_size || c->mfra_size > stream_size) {
10273  av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (unreasonable size)\n");
10274  goto fail;
10275  }
10276  if ((seek_ret = avio_seek(f, -((int64_t) c->mfra_size), SEEK_CUR)) < 0) {
10277  ret = seek_ret;
10278  goto fail;
10279  }
10280  if (avio_rb32(f) != c->mfra_size) {
10281  av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (size mismatch)\n");
10282  goto fail;
10283  }
10284  if (avio_rb32(f) != MKBETAG('m', 'f', 'r', 'a')) {
10285  av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (tag mismatch)\n");
10286  goto fail;
10287  }
10288  av_log(c->fc, AV_LOG_VERBOSE, "stream has mfra\n");
10289  do {
10290  ret = read_tfra(c, f);
10291  if (ret < 0)
10292  goto fail;
10293  } while (!ret);
10294  ret = 0;
10295  c->frag_index.complete = 1;
10296 fail:
10297  seek_ret = avio_seek(f, original_pos, SEEK_SET);
10298  if (seek_ret < 0) {
10299  av_log(c->fc, AV_LOG_ERROR,
10300  "failed to seek back after looking for mfra\n");
10301  ret = seek_ret;
10302  }
10303  return ret;
10304 }
10305 
10306 static int set_icc_profile_from_item(AVPacketSideData **coded_side_data, int *nb_coded_side_data,
10307  const HEIFItem *item)
10308 {
10309  AVPacketSideData *sd = av_packet_side_data_new(coded_side_data, nb_coded_side_data,
10311  item->icc_profile_size, 0);
10312  if (!sd)
10313  return AVERROR(ENOMEM);
10314 
10315  memcpy(sd->data, item->icc_profile, item->icc_profile_size);
10316 
10317  return 0;
10318 }
10319 
10320 static int set_display_matrix_from_item(AVPacketSideData **coded_side_data, int *nb_coded_side_data,
10321  const HEIFItem *item)
10322 {
10323  int32_t *matrix;
10324  AVPacketSideData *sd = av_packet_side_data_new(coded_side_data,
10325  nb_coded_side_data,
10327  9 * sizeof(*matrix), 0);
10328  if (!sd)
10329  return AVERROR(ENOMEM);
10330 
10331  matrix = (int32_t*)sd->data;
10332  /* rotation is in the counter-clockwise direction whereas
10333  * av_display_rotation_set() expects its argument to be
10334  * oriented clockwise, so we need to negate it. */
10336  av_display_matrix_flip(matrix, item->hflip, item->vflip);
10337 
10338  return 0;
10339 }
10340 
10341 static int read_image_grid(AVFormatContext *s, const HEIFGrid *grid,
10342  AVStreamGroupTileGrid *tile_grid)
10343 {
10344  MOVContext *c = s->priv_data;
10345  const HEIFItem *item = grid->item;
10346  int64_t offset = 0, pos = avio_tell(s->pb);
10347  int x = 0, y = 0, i = 0;
10348  int tile_rows, tile_cols;
10349  int flags, size;
10350 
10351  if (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL)) {
10352  av_log(c->fc, AV_LOG_INFO, "grid box with non seekable input\n");
10353  return AVERROR_PATCHWELCOME;
10354  }
10355  if (item->is_idat_relative) {
10356  if (!c->idat_offset) {
10357  av_log(c->fc, AV_LOG_ERROR, "missing idat box required by the image grid\n");
10358  return AVERROR_INVALIDDATA;
10359  }
10360  offset = c->idat_offset;
10361  }
10362 
10363  if (offset > INT64_MAX - item->extent_offset)
10364  return AVERROR_INVALIDDATA;
10365 
10366  avio_seek(s->pb, item->extent_offset + offset, SEEK_SET);
10367 
10368  avio_r8(s->pb); /* version */
10369  flags = avio_r8(s->pb);
10370 
10371  tile_rows = avio_r8(s->pb) + 1;
10372  tile_cols = avio_r8(s->pb) + 1;
10373  /* actual width and height of output image */
10374  tile_grid->width = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
10375  tile_grid->height = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
10376 
10377  av_log(c->fc, AV_LOG_TRACE, "grid: grid_rows %d grid_cols %d output_width %d output_height %d\n",
10378  tile_rows, tile_cols, tile_grid->width, tile_grid->height);
10379 
10380  avio_seek(s->pb, pos, SEEK_SET);
10381 
10382  size = tile_rows * tile_cols;
10383  tile_grid->nb_tiles = grid->nb_tiles;
10384 
10385  if (tile_grid->nb_tiles != size)
10386  return AVERROR_INVALIDDATA;
10387 
10388  for (int i = 0; i < tile_cols; i++)
10389  tile_grid->coded_width += grid->tile_item_list[i]->width;
10390  for (int i = 0; i < size; i += tile_cols)
10391  tile_grid->coded_height += grid->tile_item_list[i]->height;
10392 
10393  tile_grid->offsets = av_calloc(tile_grid->nb_tiles, sizeof(*tile_grid->offsets));
10394  if (!tile_grid->offsets)
10395  return AVERROR(ENOMEM);
10396 
10397  while (y < tile_grid->coded_height) {
10398  int left_col = i;
10399 
10400  while (x < tile_grid->coded_width) {
10401  if (i == tile_grid->nb_tiles)
10402  return AVERROR_INVALIDDATA;
10403 
10404  tile_grid->offsets[i].idx = grid->tile_idx_list[i];
10405  tile_grid->offsets[i].horizontal = x;
10406  tile_grid->offsets[i].vertical = y;
10407 
10408  x += grid->tile_item_list[i++]->width;
10409  }
10410 
10411  if (x > tile_grid->coded_width) {
10412  av_log(c->fc, AV_LOG_ERROR, "Non uniform HEIF tiles\n");
10413  return AVERROR_INVALIDDATA;
10414  }
10415 
10416  x = 0;
10417  y += grid->tile_item_list[left_col]->height;
10418  }
10419 
10420  if (y > tile_grid->coded_height || i != tile_grid->nb_tiles) {
10421  av_log(c->fc, AV_LOG_ERROR, "Non uniform HEIF tiles\n");
10422  return AVERROR_INVALIDDATA;
10423  }
10424 
10425  return 0;
10426 }
10427 
10428 static int read_image_iovl(AVFormatContext *s, const HEIFGrid *grid,
10429  AVStreamGroupTileGrid *tile_grid)
10430 {
10431  MOVContext *c = s->priv_data;
10432  const HEIFItem *item = grid->item;
10433  uint16_t canvas_fill_value[4];
10434  int64_t offset = 0, pos = avio_tell(s->pb);
10435  int ret = 0, flags;
10436 
10437  if (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL)) {
10438  av_log(c->fc, AV_LOG_INFO, "iovl box with non seekable input\n");
10439  return AVERROR_PATCHWELCOME;
10440  }
10441  if (item->is_idat_relative) {
10442  if (!c->idat_offset) {
10443  av_log(c->fc, AV_LOG_ERROR, "missing idat box required by the image overlay\n");
10444  return AVERROR_INVALIDDATA;
10445  }
10446  offset = c->idat_offset;
10447  }
10448 
10449  if (offset > INT64_MAX - item->extent_offset)
10450  return AVERROR_INVALIDDATA;
10451 
10452  avio_seek(s->pb, item->extent_offset + offset, SEEK_SET);
10453 
10454  avio_r8(s->pb); /* version */
10455  flags = avio_r8(s->pb);
10456 
10457  for (int i = 0; i < 4; i++)
10458  canvas_fill_value[i] = avio_rb16(s->pb);
10459  av_log(c->fc, AV_LOG_TRACE, "iovl: canvas_fill_value { %u, %u, %u, %u }\n",
10460  canvas_fill_value[0], canvas_fill_value[1],
10461  canvas_fill_value[2], canvas_fill_value[3]);
10462  for (int i = 0; i < 4; i++)
10463  tile_grid->background[i] = canvas_fill_value[i];
10464 
10465  /* actual width and height of output image */
10466  tile_grid->width =
10467  tile_grid->coded_width = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
10468  tile_grid->height =
10469  tile_grid->coded_height = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
10470 
10471  av_log(c->fc, AV_LOG_TRACE, "iovl: output_width %d, output_height %d\n",
10472  tile_grid->width, tile_grid->height);
10473 
10474  tile_grid->nb_tiles = grid->nb_tiles;
10475  tile_grid->offsets = av_malloc_array(tile_grid->nb_tiles, sizeof(*tile_grid->offsets));
10476  if (!tile_grid->offsets) {
10477  ret = AVERROR(ENOMEM);
10478  goto fail;
10479  }
10480 
10481  for (int i = 0; i < tile_grid->nb_tiles; i++) {
10482  tile_grid->offsets[i].idx = grid->tile_idx_list[i];
10483  tile_grid->offsets[i].horizontal = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
10484  tile_grid->offsets[i].vertical = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
10485  av_log(c->fc, AV_LOG_TRACE, "iovl: stream_idx[%d] %u, "
10486  "horizontal_offset[%d] %d, vertical_offset[%d] %d\n",
10487  i, tile_grid->offsets[i].idx,
10488  i, tile_grid->offsets[i].horizontal, i, tile_grid->offsets[i].vertical);
10489  }
10490 
10491 fail:
10492  avio_seek(s->pb, pos, SEEK_SET);
10493 
10494  return ret;
10495 }
10496 
10498  AVPacketSideData **coded_side_data, int *nb_coded_side_data,
10499  const HEIFItem *ref)
10500 {
10501  MOVContext *c = s->priv_data;
10502  AVPacketSideData *sd;
10503  AVExifMetadata ifd = { 0 };
10504  AVBufferRef *buf;
10505  int64_t offset = 0, pos = avio_tell(s->pb);
10506  unsigned orientation_id = av_exif_get_tag_id("Orientation");
10507  int err;
10508 
10509  if (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL)) {
10510  av_log(c->fc, AV_LOG_WARNING, "Exif metadata with non seekable input\n");
10511  return AVERROR_PATCHWELCOME;
10512  }
10513  if (ref->is_idat_relative) {
10514  if (!c->idat_offset) {
10515  av_log(c->fc, AV_LOG_ERROR, "missing idat box required by the Exif metadata\n");
10516  return AVERROR_INVALIDDATA;
10517  }
10518  offset = c->idat_offset;
10519  }
10520 
10521  buf = av_buffer_alloc(ref->extent_length);
10522  if (!buf)
10523  return AVERROR(ENOMEM);
10524 
10525  if (offset > INT64_MAX - ref->extent_offset) {
10526  err = AVERROR(ENOMEM);
10527  goto fail;
10528  }
10529 
10530  avio_seek(s->pb, ref->extent_offset + offset, SEEK_SET);
10531  err = avio_read(s->pb, buf->data, ref->extent_length);
10532  if (err != ref->extent_length) {
10533  if (err > 0)
10534  err = AVERROR_INVALIDDATA;
10535  goto fail;
10536  }
10537 
10538  // HEIF spec states that Exif metadata is informative. The irot item property is
10539  // the normative source of rotation information. So we remove any Orientation tag
10540  // present in the Exif buffer.
10541  err = av_exif_parse_buffer(s, buf->data, ref->extent_length, &ifd, AV_EXIF_T_OFF);
10542  if (err < 0) {
10543  av_log(s, AV_LOG_ERROR, "Unable to parse Exif metadata\n");
10544  goto fail;
10545  }
10546 
10547  err = av_exif_remove_entry(s, &ifd, orientation_id, 0);
10548  if (err < 0)
10549  goto fail;
10550  else if (!err)
10551  goto finish;
10552 
10553  av_buffer_unref(&buf);
10554  err = av_exif_write(s, &ifd, &buf, AV_EXIF_T_OFF);
10555  if (err < 0)
10556  goto fail;
10557 
10558 finish:
10559  offset = AV_RB32(buf->data) + 4;
10560  if (offset >= buf->size) {
10561  err = AVERROR_INVALIDDATA;
10562  goto fail;
10563  }
10564  sd = av_packet_side_data_new(coded_side_data, nb_coded_side_data,
10565  AV_PKT_DATA_EXIF, buf->size - offset, 0);
10566  if (!sd) {
10567  err = AVERROR(ENOMEM);
10568  goto fail;
10569  }
10570  memcpy(sd->data, buf->data + offset, buf->size - offset);
10571 
10572  err = 0;
10573 fail:
10574  av_buffer_unref(&buf);
10575  av_exif_free(&ifd);
10576  avio_seek(s->pb, pos, SEEK_SET);
10577 
10578  return err;
10579 }
10580 
10582 {
10583  MOVContext *mov = s->priv_data;
10584 
10585  for (int i = 0; i < mov->nb_heif_grid; i++) {
10587  AVStreamGroupTileGrid *tile_grid;
10588  const HEIFGrid *grid = &mov->heif_grid[i];
10589  int err, loop = 1;
10590 
10591  if (!stg)
10592  return AVERROR(ENOMEM);
10593 
10594  stg->id = grid->item->item_id;
10595  tile_grid = stg->params.tile_grid;
10596 
10597  for (int j = 0; j < grid->nb_tiles; j++) {
10598  int tile_id = grid->tile_id_list[j];
10599  int k;
10600 
10601  for (k = 0; k < mov->nb_heif_item; k++) {
10602  HEIFItem *item = mov->heif_item[k];
10603  AVStream *st;
10604 
10605  if (!item || item->item_id != tile_id)
10606  continue;
10607  st = item->st;
10608  if (!st) {
10609  av_log(s, AV_LOG_WARNING, "HEIF item id %d from grid id %d doesn't "
10610  "reference a stream\n",
10611  tile_id, grid->item->item_id);
10612  ff_remove_stream_group(s, stg);
10613  loop = 0;
10614  break;
10615  }
10616 
10617  grid->tile_item_list[j] = item;
10618  grid->tile_idx_list[j] = stg->nb_streams;
10619 
10620  err = avformat_stream_group_add_stream(stg, st);
10621  if (err < 0) {
10622  int l;
10623  if (err != AVERROR(EEXIST))
10624  return err;
10625 
10626  for (l = 0; l < stg->nb_streams; l++)
10627  if (stg->streams[l]->index == st->index)
10628  break;
10629  av_assert0(l < stg->nb_streams);
10630  grid->tile_idx_list[j] = l;
10631  }
10632 
10633  if (item->item_id != mov->primary_item_id)
10635  break;
10636  }
10637 
10638  if (k == mov->nb_heif_item) {
10639  av_assert0(loop);
10640  av_log(s, AV_LOG_WARNING, "HEIF item id %d referenced by grid id %d doesn't "
10641  "exist\n",
10642  tile_id, grid->item->item_id);
10643  ff_remove_stream_group(s, stg);
10644  loop = 0;
10645  }
10646  if (!loop)
10647  break;
10648  }
10649 
10650  if (!loop)
10651  continue;
10652 
10653  switch (grid->item->type) {
10654  case MKTAG('g','r','i','d'):
10655  err = read_image_grid(s, grid, tile_grid);
10656  break;
10657  case MKTAG('i','o','v','l'):
10658  err = read_image_iovl(s, grid, tile_grid);
10659  break;
10660  default:
10661  av_assert0(0);
10662  }
10663  if (err < 0)
10664  return err;
10665 
10666  for (int j = 0; j < grid->item->nb_iref_list; j++) {
10667  HEIFItem *ref = get_heif_item(mov, grid->item->iref_list[j].item_id);
10668 
10669  av_assert0(ref);
10670  switch(ref->type) {
10671  case MKTAG('E','x','i','f'):
10672  err = mov_parse_exif_item(s, &tile_grid->coded_side_data,
10673  &tile_grid->nb_coded_side_data, ref);
10674  if (err < 0 && (s->error_recognition & AV_EF_EXPLODE))
10675  return err;
10676  break;
10677  default:
10678  break;
10679  }
10680  }
10681 
10682  /* rotation */
10683  if (grid->item->rotation || grid->item->hflip || grid->item->vflip) {
10685  &tile_grid->nb_coded_side_data, grid->item);
10686  if (err < 0)
10687  return err;
10688  }
10689 
10690  /* ICC profile */
10691  if (grid->item->icc_profile_size) {
10692  err = set_icc_profile_from_item(&tile_grid->coded_side_data,
10693  &tile_grid->nb_coded_side_data, grid->item);
10694  if (err < 0)
10695  return err;
10696  }
10697 
10698  if (grid->item->name)
10699  av_dict_set(&stg->metadata, "title", grid->item->name, 0);
10700  if (grid->item->item_id == mov->primary_item_id)
10702  }
10703 
10704  return 0;
10705 }
10706 
10708 {
10709  MOVContext *mov = s->priv_data;
10710  int err;
10711 
10712  for (int i = 0; i < mov->nb_heif_item; i++) {
10713  HEIFItem *item = mov->heif_item[i];
10714  MOVStreamContext *sc;
10715  AVStream *st;
10716  int64_t offset = 0;
10717 
10718  if (!item)
10719  continue;
10720  if (!item->st) {
10721  continue;
10722  }
10723  if (item->is_idat_relative) {
10724  if (!mov->idat_offset) {
10725  av_log(s, AV_LOG_ERROR, "Missing idat box for item %d\n", item->item_id);
10726  return AVERROR_INVALIDDATA;
10727  }
10728  offset = mov->idat_offset;
10729  }
10730 
10731  st = item->st;
10732  sc = st->priv_data;
10733  st->codecpar->width = item->width;
10734  st->codecpar->height = item->height;
10735 
10736  sc->sample_size = sc->stsz_sample_size = item->extent_length;
10737  sc->sample_count = 1;
10738 
10739  err = sanity_checks(s, sc, st->index);
10740  if (err)
10741  return AVERROR_INVALIDDATA;
10742 
10743  if (offset > INT64_MAX - item->extent_offset)
10744  return AVERROR_INVALIDDATA;
10745 
10746  sc->chunk_offsets[0] = item->extent_offset + offset;
10747 
10748  if (item->item_id == mov->primary_item_id)
10750 
10751  for (int j = 0; j < item->nb_iref_list; j++) {
10752  HEIFItem *ref = get_heif_item(mov, item->iref_list[j].item_id);
10753 
10754  av_assert0(ref);
10755  switch(ref->type) {
10756  case MKTAG('E','x','i','f'):
10759  if (err < 0 && (s->error_recognition & AV_EF_EXPLODE))
10760  return err;
10761  break;
10762  default:
10763  break;
10764  }
10765  }
10766 
10767  if (item->rotation || item->hflip || item->vflip) {
10769  &st->codecpar->nb_coded_side_data, item);
10770  if (err < 0)
10771  return err;
10772  }
10773 
10774  mov_build_index(mov, st);
10775  }
10776 
10777  if (mov->nb_heif_grid) {
10778  err = mov_parse_tiles(s);
10779  if (err < 0)
10780  return err;
10781  }
10782 
10783  return 0;
10784 }
10785 
10787  int first_index)
10788 {
10789  MOVStreamContext *sc = st->priv_data;
10790 
10791  if (sc->tref_id < 0)
10792  return NULL;
10793 
10794  for (int i = first_index; i < s->nb_streams; i++)
10795  if (s->streams[i]->id == sc->tref_id)
10796  return s->streams[i];
10797 
10798  return NULL;
10799 }
10800 
10802 {
10803  int err;
10804 
10805  // Don't try to add a group if there's only one track
10806  if (s->nb_streams <= 1)
10807  return 0;
10808 
10809  for (int i = 0; i < s->nb_streams; i++) {
10810  AVStreamGroup *stg;
10811  AVStream *st = s->streams[i];
10812  AVStream *st_base;
10813  MOVStreamContext *sc = st->priv_data;
10814  int j = 0;
10815 
10816  /* Find an enhancement stream. */
10817  if (st->codecpar->codec_id != AV_CODEC_ID_LCEVC ||
10819  continue;
10820 
10822  if (!stg)
10823  return AVERROR(ENOMEM);
10824 
10825  stg->id = st->id;
10826  stg->params.lcevc->width = st->codecpar->width;
10827  stg->params.lcevc->height = st->codecpar->height;
10828 
10829  while (st_base = mov_find_reference_track(s, st, j)) {
10830  err = avformat_stream_group_add_stream(stg, st_base);
10831  if (err < 0)
10832  return err;
10833 
10834  j = st_base->index + 1;
10835  }
10836  if (!j) {
10837  av_log(s, AV_LOG_ERROR, "Failed to find base stream for enhancement stream\n");
10838  return AVERROR_INVALIDDATA;
10839  }
10840 
10841  err = avformat_stream_group_add_stream(stg, st);
10842  if (err < 0)
10843  return err;
10844 
10845  stg->params.lcevc->lcevc_index = stg->nb_streams - 1;
10846  }
10847 
10848  return 0;
10849 }
10850 
10852 {
10853  int highest_id = 0, lowest_iamf_id = INT_MAX;
10854 
10855  for (int i = 0; i < s->nb_streams; i++) {
10856  const AVStream *st = s->streams[i];
10857  const MOVStreamContext *sc = st->priv_data;
10858  if (!sc->iamf)
10859  highest_id = FFMAX(highest_id, st->id);
10860  }
10861 
10862  for (int i = 0; i < s->nb_stream_groups; i++) {
10863  AVStreamGroup *stg = s->stream_groups[i];
10865  continue;
10866  for (int j = 0; j < stg->nb_streams; j++) {
10867  AVStream *st = stg->streams[j];
10868  lowest_iamf_id = FFMIN(lowest_iamf_id, st->id);
10869  }
10870  }
10871 
10872  if (highest_id < lowest_iamf_id)
10873  return;
10874 
10875  highest_id += !lowest_iamf_id;
10876  for (int i = 0; highest_id > 1 && i < s->nb_stream_groups; i++) {
10877  AVStreamGroup *stg = s->stream_groups[i];
10879  continue;
10880  for (int j = 0; j < stg->nb_streams; j++) {
10881  AVStream *st = stg->streams[j];
10882  MOVStreamContext *sc = st->priv_data;
10883  st->id += highest_id;
10884  sc->iamf_stream_offset = highest_id;
10885  }
10886  }
10887 }
10888 
10890 {
10891  MOVContext *mov = s->priv_data;
10892  AVIOContext *pb = s->pb;
10893  int j, err;
10894  MOVAtom atom = { AV_RL32("root") };
10895  int i;
10896 
10897  mov->fc = s;
10898  mov->trak_index = -1;
10899  mov->primary_item_id = -1;
10900  mov->cur_item_id = -1;
10901  /* .mov and .mp4 aren't streamable anyway (only progressive download if moov is before mdat) */
10902  if (pb->seekable & AVIO_SEEKABLE_NORMAL)
10903  atom.size = avio_size(pb);
10904  else
10905  atom.size = INT64_MAX;
10906 
10907  /* check MOV header */
10908  do {
10909  if (mov->moov_retry)
10910  avio_seek(pb, 0, SEEK_SET);
10911  if ((err = mov_read_default(mov, pb, atom)) < 0) {
10912  av_log(s, AV_LOG_ERROR, "error reading header\n");
10913  return err;
10914  }
10915  } while ((pb->seekable & AVIO_SEEKABLE_NORMAL) &&
10916  !mov->found_moov && (!mov->found_iloc || !mov->found_iinf) && !mov->moov_retry++);
10917  if (!mov->found_moov && !mov->found_iloc && !mov->found_iinf) {
10918  av_log(s, AV_LOG_ERROR, "moov atom not found\n");
10919  return AVERROR_INVALIDDATA;
10920  }
10921  av_log(mov->fc, AV_LOG_TRACE, "on_parse_exit_offset=%"PRId64"\n", avio_tell(pb));
10922 
10923  if (mov->found_iloc && mov->found_iinf) {
10924  err = mov_parse_heif_items(s);
10925  if (err < 0)
10926  return err;
10927  }
10928  // prevent iloc and iinf boxes from being parsed while reading packets.
10929  // this is needed because an iinf box may have been parsed but ignored
10930  // for having old infe boxes which create no streams.
10931  mov->found_iloc = mov->found_iinf = 1;
10932 
10933  if (pb->seekable & AVIO_SEEKABLE_NORMAL) {
10934  if (mov->nb_chapter_tracks > 0 && !mov->ignore_chapters)
10936  for (i = 0; i < s->nb_streams; i++)
10937  if (s->streams[i]->codecpar->codec_tag == AV_RL32("tmcd")) {
10938  mov_read_timecode_track(s, s->streams[i]);
10939  } else if (s->streams[i]->codecpar->codec_tag == AV_RL32("rtmd")) {
10940  mov_read_rtmd_track(s, s->streams[i]);
10941  }
10942  }
10943 
10944  /* copy timecode metadata from tmcd tracks to the related video streams */
10945  for (i = 0; i < s->nb_streams; i++) {
10946  AVStream *st = s->streams[i];
10947  MOVStreamContext *sc = st->priv_data;
10948  if (sc->timecode_track > 0) {
10949  AVDictionaryEntry *tcr;
10950  int tmcd_st_id = -1;
10951 
10952  for (j = 0; j < s->nb_streams; j++) {
10953  MOVStreamContext *sc2 = s->streams[j]->priv_data;
10954  if (sc2->id == sc->timecode_track)
10955  tmcd_st_id = j;
10956  }
10957 
10958  if (tmcd_st_id < 0 || tmcd_st_id == i)
10959  continue;
10960  tcr = av_dict_get(s->streams[tmcd_st_id]->metadata, "timecode", NULL, 0);
10961  if (tcr)
10962  av_dict_set(&st->metadata, "timecode", tcr->value, 0);
10963  }
10964  }
10966 
10967  /* Create LCEVC stream groups. */
10968  err = mov_parse_lcevc_streams(s);
10969  if (err < 0)
10970  return err;
10971 
10972  for (i = 0; i < s->nb_streams; i++) {
10973  AVStream *st = s->streams[i];
10974  FFStream *const sti = ffstream(st);
10975  MOVStreamContext *sc = st->priv_data;
10976  uint32_t dvdsub_clut[FF_DVDCLUT_CLUT_LEN] = {0};
10977  fix_timescale(mov, sc);
10978 
10979  /* Set the primary extradata based on the first Sample if it doesn't reference the first stsd entry. */
10980  if (sc->stsc_count && sc->extradata_size && !sc->iamf &&
10981  sc->stsc_data[0].id > 1 && sc->stsc_data[0].id <= sc->stsd_count) {
10982  sc->last_stsd_index = sc->stsc_data[0].id - 1;
10983  av_freep(&st->codecpar->extradata);
10985  if (sc->extradata_size[sc->last_stsd_index]) {
10987  if (!st->codecpar->extradata)
10988  return AVERROR(ENOMEM);
10989  memcpy(st->codecpar->extradata, sc->extradata[sc->last_stsd_index], sc->extradata_size[sc->last_stsd_index]);
10990  }
10991  }
10992 
10993  if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
10994  st->codecpar->codec_id == AV_CODEC_ID_AAC) {
10995  sti->skip_samples = sc->start_pad;
10996  }
10997  if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && sc->nb_frames_for_fps > 0 && sc->duration_for_fps > 0)
10999  sc->time_scale*(int64_t)sc->nb_frames_for_fps, sc->duration_for_fps, INT_MAX);
11001  if (st->codecpar->width <= 0 || st->codecpar->height <= 0) {
11002  st->codecpar->width = sc->width;
11003  st->codecpar->height = sc->height;
11004  }
11007 
11008  for (j = 0; j < FF_DVDCLUT_CLUT_LEN; j++)
11009  dvdsub_clut[j] = AV_RB32(st->codecpar->extradata + j * 4);
11010 
11011  err = ff_dvdclut_yuv_to_rgb(dvdsub_clut, FF_DVDCLUT_CLUT_SIZE);
11012  if (err < 0)
11013  return err;
11014 
11015  av_freep(&st->codecpar->extradata);
11016  st->codecpar->extradata_size = 0;
11017 
11019  st->codecpar);
11020  if (err < 0)
11021  return err;
11022  }
11023  }
11024  if (mov->handbrake_version &&
11025  mov->handbrake_version <= 1000000*0 + 1000*10 + 2 && // 0.10.2
11026  st->codecpar->codec_id == AV_CODEC_ID_MP3) {
11027  av_log(s, AV_LOG_VERBOSE, "Forcing full parsing for mp3 stream\n");
11029  }
11030  }
11031 
11032  if (mov->trex_data || mov->use_mfra_for > 0) {
11033  for (i = 0; i < s->nb_streams; i++) {
11034  AVStream *st = s->streams[i];
11035  MOVStreamContext *sc = st->priv_data;
11036  if (sc->duration_for_fps > 0) {
11037  /* Akin to sc->data_size * 8 * sc->time_scale / sc->duration_for_fps but accounting for overflows. */
11039  if (st->codecpar->bit_rate == INT64_MIN) {
11040  av_log(s, AV_LOG_WARNING, "Overflow during bit rate calculation %"PRId64" * 8 * %d\n",
11041  sc->data_size, sc->time_scale);
11042  st->codecpar->bit_rate = 0;
11043  if (s->error_recognition & AV_EF_EXPLODE)
11044  return AVERROR_INVALIDDATA;
11045  }
11046  }
11047  }
11048  }
11049 
11050  for (i = 0; i < mov->bitrates_count && i < s->nb_streams; i++) {
11051  if (mov->bitrates[i]) {
11052  s->streams[i]->codecpar->bit_rate = mov->bitrates[i];
11053  }
11054  }
11055 
11057 
11058  for (i = 0; i < s->nb_streams; i++) {
11059  AVStream *st = s->streams[i];
11060  MOVStreamContext *sc = st->priv_data;
11061 
11062  switch (st->codecpar->codec_type) {
11063  case AVMEDIA_TYPE_AUDIO:
11064  err = ff_replaygain_export(st, s->metadata);
11065  if (err < 0)
11066  return err;
11067  break;
11068  case AVMEDIA_TYPE_VIDEO:
11069  if (sc->display_matrix) {
11072  (uint8_t*)sc->display_matrix, sizeof(int32_t) * 9, 0))
11073  return AVERROR(ENOMEM);
11074 
11075  sc->display_matrix = NULL;
11076  }
11077  if (sc->stereo3d) {
11080  (uint8_t *)sc->stereo3d, sc->stereo3d_size, 0))
11081  return AVERROR(ENOMEM);
11082 
11083  sc->stereo3d = NULL;
11084  }
11085  if (sc->spherical) {
11088  (uint8_t *)sc->spherical, sc->spherical_size, 0))
11089  return AVERROR(ENOMEM);
11090 
11091  sc->spherical = NULL;
11092  }
11093  if (sc->mastering) {
11096  (uint8_t *)sc->mastering, sc->mastering_size, 0))
11097  return AVERROR(ENOMEM);
11098 
11099  sc->mastering = NULL;
11100  }
11101  if (sc->coll) {
11104  (uint8_t *)sc->coll, sc->coll_size, 0))
11105  return AVERROR(ENOMEM);
11106 
11107  sc->coll = NULL;
11108  }
11109  if (sc->ambient) {
11112  (uint8_t *) sc->ambient, sc->ambient_size, 0))
11113  return AVERROR(ENOMEM);
11114 
11115  sc->ambient = NULL;
11116  }
11117  break;
11118  }
11119  }
11120 
11121  fix_stream_ids(s);
11122 
11124 
11125  for (i = 0; i < mov->frag_index.nb_items; i++)
11126  if (mov->frag_index.item[i].moof_offset <= mov->fragment.moof_offset)
11127  mov->frag_index.item[i].headers_read = 1;
11128 
11129  return 0;
11130 }
11131 
11133 {
11135  int64_t best_dts = INT64_MAX;
11136  int i;
11137  MOVContext *mov = s->priv_data;
11138  int no_interleave = !mov->interleaved_read || !(s->pb->seekable & AVIO_SEEKABLE_NORMAL);
11139  for (i = 0; i < s->nb_streams; i++) {
11140  AVStream *avst = s->streams[i];
11141  FFStream *const avsti = ffstream(avst);
11142  MOVStreamContext *msc = avst->priv_data;
11143  if (msc->pb && msc->current_sample < avsti->nb_index_entries) {
11144  AVIndexEntry *current_sample = &avsti->index_entries[msc->current_sample];
11145  int64_t dts = av_rescale(current_sample->timestamp, AV_TIME_BASE, msc->time_scale);
11146  uint64_t dtsdiff = best_dts > dts ? best_dts - (uint64_t)dts : ((uint64_t)dts - best_dts);
11147  av_log(s, AV_LOG_TRACE, "stream %d, sample %d, dts %"PRId64"\n", i, msc->current_sample, dts);
11148  if (!sample || (no_interleave && current_sample->pos < sample->pos) ||
11149  ((s->pb->seekable & AVIO_SEEKABLE_NORMAL) &&
11150  ((msc->pb != s->pb && dts < best_dts) || (msc->pb == s->pb && dts != AV_NOPTS_VALUE &&
11151  ((dtsdiff <= AV_TIME_BASE && current_sample->pos < sample->pos) ||
11152  (dtsdiff > AV_TIME_BASE && dts < best_dts && mov->interleaved_read)))))) {
11153  sample = current_sample;
11154  best_dts = dts;
11155  *st = avst;
11156  }
11157  }
11158  }
11159  return sample;
11160 }
11161 
11162 static int should_retry(AVIOContext *pb, int error_code) {
11163  if (error_code == AVERROR_EOF || avio_feof(pb))
11164  return 0;
11165 
11166  return 1;
11167 }
11168 
11169 static int mov_switch_root(AVFormatContext *s, int64_t target, int index)
11170 {
11171  int ret;
11172  MOVContext *mov = s->priv_data;
11173 
11174  if (index >= 0 && index < mov->frag_index.nb_items)
11175  target = mov->frag_index.item[index].moof_offset;
11176  if (target >= 0 && avio_seek(s->pb, target, SEEK_SET) != target) {
11177  av_log(mov->fc, AV_LOG_ERROR, "root atom offset 0x%"PRIx64": partial file\n", target);
11178  return AVERROR_INVALIDDATA;
11179  }
11180 
11181  mov->next_root_atom = 0;
11182  if ((index < 0 && target >= 0) || index >= mov->frag_index.nb_items)
11183  index = search_frag_moof_offset(&mov->frag_index, target);
11184  if (index >= 0 && index < mov->frag_index.nb_items &&
11185  mov->frag_index.item[index].moof_offset == target) {
11186  if (index + 1 < mov->frag_index.nb_items)
11187  mov->next_root_atom = mov->frag_index.item[index + 1].moof_offset;
11188  if (mov->frag_index.item[index].headers_read)
11189  return 0;
11190  mov->frag_index.item[index].headers_read = 1;
11191  }
11192 
11193  mov->found_mdat = 0;
11194 
11195  ret = mov_read_default(mov, s->pb, (MOVAtom){ AV_RL32("root"), INT64_MAX });
11196  if (ret < 0)
11197  return ret;
11198  if (avio_feof(s->pb))
11199  return AVERROR_EOF;
11200  av_log(s, AV_LOG_TRACE, "read fragments, offset 0x%"PRIx64"\n", avio_tell(s->pb));
11201 
11202  return 1;
11203 }
11204 
11206 {
11207  MOVStreamContext *sc = st->priv_data;
11208  uint8_t *side, *extradata;
11209  int extradata_size;
11210 
11211  /* Save the current index. */
11212  sc->last_stsd_index = sc->stsc_data[sc->stsc_index].id - 1;
11213 
11214  /* Notify the decoder that extradata changed. */
11215  extradata_size = sc->extradata_size[sc->last_stsd_index];
11216  extradata = sc->extradata[sc->last_stsd_index];
11217  if (st->discard != AVDISCARD_ALL && extradata_size > 0 && extradata) {
11220  extradata_size);
11221  if (!side)
11222  return AVERROR(ENOMEM);
11223  memcpy(side, extradata, extradata_size);
11224  }
11225 
11226  return 0;
11227 }
11228 
11229 static int get_eia608_packet(AVIOContext *pb, AVPacket *pkt, int src_size)
11230 {
11231  /* We can't make assumptions about the structure of the payload,
11232  because it may include multiple cdat and cdt2 samples. */
11233  const uint32_t cdat = AV_RB32("cdat");
11234  const uint32_t cdt2 = AV_RB32("cdt2");
11235  int ret, out_size = 0;
11236 
11237  /* a valid payload must have size, 4cc, and at least 1 byte pair: */
11238  if (src_size < 10)
11239  return AVERROR_INVALIDDATA;
11240 
11241  /* avoid an int overflow: */
11242  if ((src_size - 8) / 2 >= INT_MAX / 3)
11243  return AVERROR_INVALIDDATA;
11244 
11245  ret = av_new_packet(pkt, ((src_size - 8) / 2) * 3);
11246  if (ret < 0)
11247  return ret;
11248 
11249  /* parse and re-format the c608 payload in one pass. */
11250  while (src_size >= 10) {
11251  const uint32_t atom_size = avio_rb32(pb);
11252  const uint32_t atom_type = avio_rb32(pb);
11253  const uint32_t data_size = atom_size - 8;
11254  const uint8_t cc_field =
11255  atom_type == cdat ? 1 :
11256  atom_type == cdt2 ? 2 :
11257  0;
11258 
11259  /* account for bytes consumed for atom size and type. */
11260  src_size -= 8;
11261 
11262  /* make sure the data size stays within the buffer boundaries. */
11263  if (data_size < 2 || data_size > src_size) {
11265  break;
11266  }
11267 
11268  /* make sure the data size is consistent with N byte pairs. */
11269  if (data_size % 2 != 0) {
11271  break;
11272  }
11273 
11274  if (!cc_field) {
11275  /* neither cdat or cdt2 ... skip it */
11276  avio_skip(pb, data_size);
11277  src_size -= data_size;
11278  continue;
11279  }
11280 
11281  for (uint32_t i = 0; i < data_size; i += 2) {
11282  pkt->data[out_size] = (0x1F << 3) | (1 << 2) | (cc_field - 1);
11283  pkt->data[out_size + 1] = avio_r8(pb);
11284  pkt->data[out_size + 2] = avio_r8(pb);
11285  out_size += 3;
11286  src_size -= 2;
11287  }
11288  }
11289 
11290  if (src_size > 0)
11291  /* skip any remaining unread portion of the input payload */
11292  avio_skip(pb, src_size);
11293 
11295  return ret;
11296 }
11297 
11299  int64_t current_index, AVPacket *pkt)
11300 {
11301  MOVStreamContext *sc = st->priv_data;
11302 
11303  pkt->stream_index = sc->ffindex;
11304  pkt->dts = sample->timestamp;
11305  if (sample->flags & AVINDEX_DISCARD_FRAME) {
11307  }
11308  if (sc->stts_count && sc->tts_index < sc->tts_count)
11309  pkt->duration = sc->tts_data[sc->tts_index].duration;
11310  if (sc->ctts_count && sc->tts_index < sc->tts_count) {
11312  } else {
11313  if (pkt->duration == 0) {
11314  int64_t next_dts = (sc->current_sample < ffstream(st)->nb_index_entries) ?
11316  if (next_dts >= pkt->dts)
11317  pkt->duration = next_dts - pkt->dts;
11318  }
11319  pkt->pts = pkt->dts;
11320  }
11321 
11322  if (sc->tts_data && sc->tts_index < sc->tts_count) {
11323  /* update tts context */
11324  sc->tts_sample++;
11325  if (sc->tts_index < sc->tts_count &&
11326  sc->tts_data[sc->tts_index].count == sc->tts_sample) {
11327  sc->tts_index++;
11328  sc->tts_sample = 0;
11329  }
11330  }
11331 
11332  if (sc->sdtp_data && sc->current_sample <= sc->sdtp_count) {
11333  uint8_t sample_flags = sc->sdtp_data[sc->current_sample - 1];
11334  uint8_t sample_is_depended_on = (sample_flags >> 2) & 0x3;
11335  pkt->flags |= sample_is_depended_on == MOV_SAMPLE_DEPENDENCY_NO ? AV_PKT_FLAG_DISPOSABLE : 0;
11336  }
11337  pkt->flags |= sample->flags & AVINDEX_KEYFRAME ? AV_PKT_FLAG_KEY : 0;
11338  pkt->pos = sample->pos;
11339 
11340  /* Multiple stsd handling. */
11341  if (sc->stsc_data) {
11342  if (sc->stsc_data[sc->stsc_index].id > 0 &&
11343  sc->stsc_data[sc->stsc_index].id - 1 < sc->stsd_count &&
11344  sc->stsc_data[sc->stsc_index].id - 1 != sc->last_stsd_index) {
11345  int ret = mov_change_extradata(st, pkt);
11346  if (ret < 0)
11347  return ret;
11348  }
11349 
11350  /* Update the stsc index for the next sample */
11351  sc->stsc_sample++;
11352  if (mov_stsc_index_valid(sc->stsc_index, sc->stsc_count) &&
11353  mov_get_stsc_samples(sc, sc->stsc_index) == sc->stsc_sample) {
11354  sc->stsc_index++;
11355  sc->stsc_sample = 0;
11356  }
11357  }
11358 
11359  return 0;
11360 }
11361 
11363 {
11364  MOVContext *mov = s->priv_data;
11365  MOVStreamContext *sc;
11367  AVStream *st = NULL;
11368  FFStream *avsti = NULL;
11369  int64_t current_index;
11370  int ret;
11371  int i;
11372  mov->fc = s;
11373  retry:
11374  if (s->pb->pos == 0) {
11375 
11376  // Discard current fragment index
11377  if (mov->frag_index.allocated_size > 0) {
11378  for(int i = 0; i < mov->frag_index.nb_items; i++) {
11380  }
11381  av_freep(&mov->frag_index.item);
11382  mov->frag_index.nb_items = 0;
11383  mov->frag_index.allocated_size = 0;
11384  mov->frag_index.current = -1;
11385  mov->frag_index.complete = 0;
11386  }
11387 
11388  for (i = 0; i < s->nb_streams; i++) {
11389  AVStream *avst = s->streams[i];
11390  MOVStreamContext *msc = avst->priv_data;
11391 
11392  // Clear current sample
11393  mov_current_sample_set(msc, 0);
11394  msc->tts_index = 0;
11395 
11396  // Discard current index entries
11397  avsti = ffstream(avst);
11398  if (avsti->index_entries_allocated_size > 0) {
11399  av_freep(&avsti->index_entries);
11400  avsti->index_entries_allocated_size = 0;
11401  avsti->nb_index_entries = 0;
11402  }
11403  }
11404 
11405  if ((ret = mov_switch_root(s, -1, -1)) < 0)
11406  return ret;
11407  }
11408  sample = mov_find_next_sample(s, &st);
11409  if (!sample || (mov->next_root_atom && sample->pos > mov->next_root_atom)) {
11410  if (!mov->next_root_atom)
11411  return AVERROR_EOF;
11412  if ((ret = mov_switch_root(s, mov->next_root_atom, -1)) < 0)
11413  return ret;
11414  goto retry;
11415  }
11416  sc = st->priv_data;
11417  /* must be done just before reading, to avoid infinite loop on sample */
11418  current_index = sc->current_index;
11420 
11421  if (mov->next_root_atom) {
11422  sample->pos = FFMIN(sample->pos, mov->next_root_atom);
11423  sample->size = FFMIN(sample->size, (mov->next_root_atom - sample->pos));
11424  }
11425 
11426  if (st->discard != AVDISCARD_ALL || sc->iamf) {
11427  int64_t ret64 = avio_seek(sc->pb, sample->pos, SEEK_SET);
11428  if (ret64 != sample->pos) {
11429  av_log(mov->fc, AV_LOG_ERROR, "stream %d, offset 0x%"PRIx64": partial file\n",
11430  sc->ffindex, sample->pos);
11431  if (should_retry(sc->pb, ret64)) {
11433  } else if (ret64 < 0) {
11434  return (int)ret64;
11435  }
11436  return AVERROR_INVALIDDATA;
11437  }
11438 
11439  if (st->discard == AVDISCARD_NONKEY && !(sample->flags & AVINDEX_KEYFRAME)) {
11440  av_log(mov->fc, AV_LOG_DEBUG, "Nonkey frame from stream %d discarded due to AVDISCARD_NONKEY\n", sc->ffindex);
11441  goto retry;
11442  }
11443 
11444  if (st->codecpar->codec_id == AV_CODEC_ID_EIA_608 && sample->size > 8)
11445  ret = get_eia608_packet(sc->pb, pkt, sample->size);
11446 #if CONFIG_IAMFDEC
11447  else if (sc->iamf) {
11448  int64_t pts, dts, pos, duration;
11449  int flags, size = sample->size;
11450  ret = mov_finalize_packet(s, st, sample, current_index, pkt);
11451  pts = pkt->pts; dts = pkt->dts;
11452  pos = pkt->pos; flags = pkt->flags;
11453  duration = pkt->duration;
11454  while (!ret && size > 0) {
11455  ret = ff_iamf_read_packet(s, sc->iamf, sc->pb, size, sc->iamf_stream_offset, pkt);
11456  if (ret < 0) {
11457  if (should_retry(sc->pb, ret))
11459  return ret;
11460  }
11461  size -= ret;
11462 
11463  if (pkt->flags & AV_PKT_FLAG_DISCARD) {
11465  ret = 0;
11466  continue;
11467  }
11468  pkt->pts = pts; pkt->dts = dts;
11469  pkt->pos = pos; pkt->flags |= flags;
11470  pkt->duration = duration;
11471  ret = ff_buffer_packet(s, pkt);
11472  }
11473  if (!ret)
11474  return FFERROR_REDO;
11475  }
11476 #endif
11477  else if (st->codecpar->codec_id == AV_CODEC_ID_APV && sample->size > 4) {
11478  const uint32_t au_size = avio_rb32(sc->pb);
11479  ret = av_get_packet(sc->pb, pkt, au_size);
11480  } else
11481  ret = av_get_packet(sc->pb, pkt, sample->size);
11482  if (ret < 0) {
11483  if (should_retry(sc->pb, ret)) {
11485  }
11486  return ret;
11487  }
11488 #if CONFIG_DV_DEMUXER
11489  if (mov->dv_demux && sc->dv_audio_container) {
11492  if (ret < 0)
11493  return ret;
11495  if (ret < 0)
11496  return ret;
11497  }
11498 #endif
11499  if (sc->has_palette) {
11500  uint8_t *pal;
11501 
11503  if (!pal) {
11504  av_log(mov->fc, AV_LOG_ERROR, "Cannot append palette to packet\n");
11505  } else {
11506  memcpy(pal, sc->palette, AVPALETTE_SIZE);
11507  sc->has_palette = 0;
11508  }
11509  }
11510  if (st->codecpar->codec_id == AV_CODEC_ID_MP3 && !ffstream(st)->need_parsing && pkt->size > 4) {
11511  if (ff_mpa_check_header(AV_RB32(pkt->data)) < 0)
11513  }
11514  }
11515 
11516  ret = mov_finalize_packet(s, st, sample, current_index, pkt);
11517  if (ret < 0)
11518  return ret;
11519 
11520  if (st->discard == AVDISCARD_ALL)
11521  goto retry;
11522 
11523  if (mov->aax_mode)
11524  aax_filter(pkt->data, pkt->size, mov);
11525 
11526  ret = cenc_filter(mov, st, sc, pkt, current_index);
11527  if (ret < 0) {
11528  return ret;
11529  }
11530 
11531  return 0;
11532 }
11533 
11535 {
11536  MOVContext *mov = s->priv_data;
11537  int index;
11538 
11539  if (!mov->frag_index.complete)
11540  return 0;
11541 
11542  index = search_frag_timestamp(s, &mov->frag_index, st, timestamp);
11543  if (index < 0)
11544  index = 0;
11545  if (!mov->frag_index.item[index].headers_read)
11546  return mov_switch_root(s, -1, index);
11547  if (index + 1 < mov->frag_index.nb_items)
11548  mov->next_root_atom = mov->frag_index.item[index + 1].moof_offset;
11549 
11550  return 0;
11551 }
11552 
11553 static int is_open_key_sample(const MOVStreamContext *sc, int sample)
11554 {
11555  // TODO: a bisect search would scale much better
11556  for (int i = 0; i < sc->open_key_samples_count; i++) {
11557  const int oks = sc->open_key_samples[i];
11558  if (oks == sample)
11559  return 1;
11560  if (oks > sample) /* list is monotically increasing so we can stop early */
11561  break;
11562  }
11563  return 0;
11564 }
11565 
11566 /*
11567  * Some key sample may be key frames but not IDR frames, so a random access to
11568  * them may not be allowed.
11569  */
11570 static int can_seek_to_key_sample(AVStream *st, int sample, int64_t requested_pts)
11571 {
11572  MOVStreamContext *sc = st->priv_data;
11573  FFStream *const sti = ffstream(st);
11574  int64_t key_sample_dts, key_sample_pts;
11575 
11576  if (st->codecpar->codec_id != AV_CODEC_ID_HEVC)
11577  return 1;
11578 
11579  if (sample >= sc->sample_offsets_count)
11580  return 1;
11581 
11582  key_sample_dts = sti->index_entries[sample].timestamp;
11583  key_sample_pts = key_sample_dts + sc->sample_offsets[sample] + sc->dts_shift;
11584 
11585  /*
11586  * If the sample needs to be presented before an open key sample, they may
11587  * not be decodable properly, even though they come after in decoding
11588  * order.
11589  */
11590  if (is_open_key_sample(sc, sample) && key_sample_pts > requested_pts)
11591  return 0;
11592 
11593  return 1;
11594 }
11595 
11596 static int mov_seek_stream(AVFormatContext *s, AVStream *st, int64_t timestamp, int flags)
11597 {
11598  MOVStreamContext *sc = st->priv_data;
11599  FFStream *const sti = ffstream(st);
11600  int sample, time_sample, ret, requested_sample;
11601  int64_t next_ts;
11602  unsigned int i;
11603 
11604  // Here we consider timestamp to be PTS, hence try to offset it so that we
11605  // can search over the DTS timeline.
11606  timestamp -= (sc->min_corrected_pts + sc->dts_shift);
11607 
11608  ret = mov_seek_fragment(s, st, timestamp);
11609  if (ret < 0)
11610  return ret;
11611 
11612  for (;;) {
11613  sample = av_index_search_timestamp(st, timestamp, flags);
11614  av_log(s, AV_LOG_TRACE, "stream %d, timestamp %"PRId64", sample %d\n", st->index, timestamp, sample);
11615  if (sample < 0 && sti->nb_index_entries && timestamp < sti->index_entries[0].timestamp)
11616  sample = 0;
11617  if (sample < 0) /* not sure what to do */
11618  return AVERROR_INVALIDDATA;
11619 
11620  if (!sample || can_seek_to_key_sample(st, sample, timestamp))
11621  break;
11622 
11623  next_ts = timestamp - FFMAX(sc->min_sample_duration, 1);
11624  requested_sample = av_index_search_timestamp(st, next_ts, flags);
11625 
11626  // If we've reached a different sample trying to find a good pts to
11627  // seek to, give up searching because we'll end up seeking back to
11628  // sample 0 on every seek.
11629  if (sample != requested_sample && !can_seek_to_key_sample(st, requested_sample, next_ts))
11630  break;
11631 
11632  timestamp = next_ts;
11633  }
11634 
11636  av_log(s, AV_LOG_TRACE, "stream %d, found sample %d\n", st->index, sc->current_sample);
11637  /* adjust time to sample index */
11638  if (sc->tts_data) {
11639  time_sample = 0;
11640  for (i = 0; i < sc->tts_count; i++) {
11641  int next = time_sample + sc->tts_data[i].count;
11642  if (next > sc->current_sample) {
11643  sc->tts_index = i;
11644  sc->tts_sample = sc->current_sample - time_sample;
11645  break;
11646  }
11647  time_sample = next;
11648  }
11649  }
11650 
11651  /* adjust stsd index */
11652  if (sc->chunk_count) {
11653  time_sample = 0;
11654  for (i = 0; i < sc->stsc_count; i++) {
11655  int64_t next = time_sample + mov_get_stsc_samples(sc, i);
11656  if (next > sc->current_sample) {
11657  sc->stsc_index = i;
11658  sc->stsc_sample = sc->current_sample - time_sample;
11659  break;
11660  }
11661  av_assert0(next == (int)next);
11662  time_sample = next;
11663  }
11664  }
11665 
11666  return sample;
11667 }
11668 
11670 {
11671  MOVStreamContext *sc = st->priv_data;
11672  FFStream *const sti = ffstream(st);
11673  int64_t first_ts = sti->index_entries[0].timestamp;
11675  int64_t off;
11676 
11678  return 0;
11679 
11680  /* compute skip samples according to stream start_pad, seek ts and first ts */
11681  off = av_rescale_q(ts - first_ts, st->time_base,
11682  (AVRational){1, st->codecpar->sample_rate});
11683  return FFMAX(sc->start_pad - off, 0);
11684 }
11685 
11686 static int mov_read_seek(AVFormatContext *s, int stream_index, int64_t sample_time, int flags)
11687 {
11688  MOVContext *mc = s->priv_data;
11689  AVStream *st;
11690  FFStream *sti;
11691  int sample;
11692  int i;
11693 
11694  if (stream_index >= s->nb_streams)
11695  return AVERROR_INVALIDDATA;
11696 
11697  st = s->streams[stream_index];
11698  sti = ffstream(st);
11699  sample = mov_seek_stream(s, st, sample_time, flags);
11700  if (sample < 0)
11701  return sample;
11702 
11703  if (mc->seek_individually) {
11704  /* adjust seek timestamp to found sample timestamp */
11705  int64_t seek_timestamp = sti->index_entries[sample].timestamp;
11707 
11708  for (i = 0; i < s->nb_streams; i++) {
11709  AVStream *const st = s->streams[i];
11710  FFStream *const sti = ffstream(st);
11711  int64_t timestamp;
11712 
11713  if (stream_index == i)
11714  continue;
11715 
11716  timestamp = av_rescale_q(seek_timestamp, s->streams[stream_index]->time_base, st->time_base);
11717  sample = mov_seek_stream(s, st, timestamp, flags);
11718  if (sample >= 0)
11720  }
11721  } else {
11722  for (i = 0; i < s->nb_streams; i++) {
11723  MOVStreamContext *sc;
11724  st = s->streams[i];
11725  sc = st->priv_data;
11726  mov_current_sample_set(sc, 0);
11727  }
11728  while (1) {
11729  MOVStreamContext *sc;
11731  if (!entry)
11732  return AVERROR_INVALIDDATA;
11733  sc = st->priv_data;
11734  if (sc->ffindex == stream_index && sc->current_sample == sample)
11735  break;
11737  }
11738  }
11739  return 0;
11740 }
11741 
11742 #define OFFSET(x) offsetof(MOVContext, x)
11743 #define FLAGS AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM
11744 static const AVOption mov_options[] = {
11745  {"use_absolute_path",
11746  "allow using absolute path when opening alias, this is a possible security issue",
11747  OFFSET(use_absolute_path), AV_OPT_TYPE_BOOL, {.i64 = 0},
11748  0, 1, FLAGS},
11749  {"seek_streams_individually",
11750  "Seek each stream individually to the closest point",
11751  OFFSET(seek_individually), AV_OPT_TYPE_BOOL, { .i64 = 1 },
11752  0, 1, FLAGS},
11753  {"ignore_editlist", "Ignore the edit list atom.", OFFSET(ignore_editlist), AV_OPT_TYPE_BOOL, {.i64 = 0},
11754  0, 1, FLAGS},
11755  {"advanced_editlist",
11756  "Modify the AVIndex according to the editlists. Use this option to decode in the order specified by the edits.",
11757  OFFSET(advanced_editlist), AV_OPT_TYPE_BOOL, {.i64 = 1},
11758  0, 1, FLAGS},
11759  {"ignore_chapters", "", OFFSET(ignore_chapters), AV_OPT_TYPE_BOOL, {.i64 = 0},
11760  0, 1, FLAGS},
11761  {"use_mfra_for",
11762  "use mfra for fragment timestamps",
11763  OFFSET(use_mfra_for), AV_OPT_TYPE_INT, {.i64 = FF_MOV_FLAG_MFRA_AUTO},
11765  .unit = "use_mfra_for"},
11766  {"auto", "auto", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_AUTO}, 0, 0,
11767  FLAGS, .unit = "use_mfra_for" },
11768  {"dts", "dts", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_DTS}, 0, 0,
11769  FLAGS, .unit = "use_mfra_for" },
11770  {"pts", "pts", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_PTS}, 0, 0,
11771  FLAGS, .unit = "use_mfra_for" },
11772  {"use_tfdt", "use tfdt for fragment timestamps", OFFSET(use_tfdt), AV_OPT_TYPE_BOOL, {.i64 = 1},
11773  0, 1, FLAGS},
11774  { "export_all", "Export unrecognized metadata entries", OFFSET(export_all),
11775  AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = FLAGS },
11776  { "export_xmp", "Export full XMP metadata", OFFSET(export_xmp),
11777  AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = FLAGS },
11778  { "activation_bytes", "Secret bytes for Audible AAX files", OFFSET(activation_bytes),
11780  { "audible_key", "AES-128 Key for Audible AAXC files", OFFSET(audible_key),
11782  { "audible_iv", "AES-128 IV for Audible AAXC files", OFFSET(audible_iv),
11784  { "audible_fixed_key", // extracted from libAAX_SDK.so and AAXSDKWin.dll files!
11785  "Fixed key used for handling Audible AAX files", OFFSET(audible_fixed_key),
11786  AV_OPT_TYPE_BINARY, {.str="77214d4b196a87cd520045fd20a51d67"},
11787  .flags = AV_OPT_FLAG_DECODING_PARAM },
11788  { "decryption_key", "The default media decryption key (hex)", OFFSET(decryption_default_key), AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM },
11789  { "decryption_keys", "The media decryption keys by KID (hex)", OFFSET(decryption_keys), AV_OPT_TYPE_DICT, .flags = AV_OPT_FLAG_DECODING_PARAM },
11790  { "enable_drefs", "Enable external track support.", OFFSET(enable_drefs), AV_OPT_TYPE_BOOL,
11791  {.i64 = 0}, 0, 1, FLAGS },
11792  { "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 },
11793  { "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 },
11794 
11795  { NULL },
11796 };
11797 
11798 static const AVClass mov_class = {
11799  .class_name = "mov,mp4,m4a,3gp,3g2,mj2",
11800  .item_name = av_default_item_name,
11801  .option = mov_options,
11802  .version = LIBAVUTIL_VERSION_INT,
11803 };
11804 
11806  .p.name = "mov,mp4,m4a,3gp,3g2,mj2",
11807  .p.long_name = NULL_IF_CONFIG_SMALL("QuickTime / MOV"),
11808  .p.priv_class = &mov_class,
11809  .p.extensions = "mov,mp4,m4a,3gp,3g2,mj2,psp,m4v,m4b,ism,ismv,isma,f4v,avif,heic,heif",
11811  .priv_data_size = sizeof(MOVContext),
11812  .flags_internal = FF_INFMT_FLAG_INIT_CLEANUP,
11813  .read_probe = mov_probe,
11818 };
HEIFItemRef::item_id
int item_id
Definition: isom.h:291
avpriv_new_chapter
AVChapter * avpriv_new_chapter(AVFormatContext *s, int64_t id, AVRational time_base, int64_t start, int64_t end, const char *title)
Add a new chapter.
Definition: demux_utils.c:43
MOVStreamContext::ctts_allocated_size
unsigned int ctts_allocated_size
Definition: isom.h:191
item_name
item_name
Definition: libkvazaar.c:311
AV_CODEC_ID_PCM_S16LE
@ AV_CODEC_ID_PCM_S16LE
Definition: codec_id.h:338
flags
const SwsFlags flags[]
Definition: swscale.c:71
AV_EXIF_T_OFF
@ AV_EXIF_T_OFF
The first four bytes point to the actual start, then it's AV_EXIF_TIFF_HEADER.
Definition: exif.h:69
mov_finalize_stsd_entry
static int mov_finalize_stsd_entry(MOVContext *c, AVStream *st)
Definition: mov.c:3081
mov_read_chpl
static int mov_read_chpl(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:599
AVMasteringDisplayMetadata::has_primaries
int has_primaries
Flag indicating whether the display primaries (and white point) are set.
Definition: mastering_display_metadata.h:62
mov_read_frma
static int mov_read_frma(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:7434
mov_read_meta
static int mov_read_meta(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5543
AV_CODEC_ID_EIA_608
@ AV_CODEC_ID_EIA_608
Definition: codec_id.h:582
AV_PKT_DATA_DISPLAYMATRIX
@ AV_PKT_DATA_DISPLAYMATRIX
This side data contains a 3x3 transformation matrix describing an affine transformation that needs to...
Definition: packet.h:105
av_packet_unref
void av_packet_unref(AVPacket *pkt)
Wipe the packet.
Definition: packet.c:432
MOVContext::found_iloc
int found_iloc
'iloc' atom has been found
Definition: isom.h:327
AV_CODEC_ID_MACE6
@ AV_CODEC_ID_MACE6
Definition: codec_id.h:470
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:2336
read_image_iovl
static int read_image_iovl(AVFormatContext *s, const HEIFGrid *grid, AVStreamGroupTileGrid *tile_grid)
Definition: mov.c:10428
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:9360
AVMEDIA_TYPE_SUBTITLE
@ AVMEDIA_TYPE_SUBTITLE
Definition: avutil.h:203
AVIAMFSubmix::elements
AVIAMFSubmixElement ** elements
Array of submix elements.
Definition: iamf.h:568
skip_bits_long
static void skip_bits_long(GetBitContext *s, int n)
Skips the specified number of bits.
Definition: get_bits.h:280
AV_LOG_WARNING
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:216
AV_BPRINT_SIZE_UNLIMITED
#define AV_BPRINT_SIZE_UNLIMITED
MOV_TFHD_DEFAULT_FLAGS
#define MOV_TFHD_DEFAULT_FLAGS
Definition: isom.h:407
PUT_UTF8
#define PUT_UTF8(val, tmp, PUT_BYTE)
Definition: common.h:541
AV_TIMECODE_STR_SIZE
#define AV_TIMECODE_STR_SIZE
Definition: timecode.h:33
av_aes_init
int av_aes_init(AVAES *a, const uint8_t *key, int key_bits, int decrypt)
Initialize an AVAES context.
Definition: aes.c:231
AV_CODEC_ID_PCM_F32BE
@ AV_CODEC_ID_PCM_F32BE
Definition: codec_id.h:358
FFStream::skip_samples
int skip_samples
Number of samples to skip at the start of the frame decoded from the next packet.
Definition: internal.h:208
MOVStreamContext::audio_cid
int16_t audio_cid
stsd audio compression id
Definition: isom.h:221
AVMasteringDisplayMetadata::max_luminance
AVRational max_luminance
Max luminance of mastering display (cd/m^2).
Definition: mastering_display_metadata.h:57
AVSphericalProjection
AVSphericalProjection
Projection of the video surface(s) on a sphere.
Definition: spherical.h:47
AV_CODEC_ID_ADPCM_MS
@ AV_CODEC_ID_ADPCM_MS
Definition: codec_id.h:383
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:8562
can_seek_to_key_sample
static int can_seek_to_key_sample(AVStream *st, int sample, int64_t requested_pts)
Definition: mov.c:11570
AV_CODEC_ID_ADPCM_IMA_QT
@ AV_CODEC_ID_ADPCM_IMA_QT
Definition: codec_id.h:377
entry
#define entry
Definition: aom_film_grain_template.c:66
AVFMT_NO_BYTE_SEEK
#define AVFMT_NO_BYTE_SEEK
Format does not allow seeking by bytes.
Definition: avformat.h:486
AV_EF_EXPLODE
#define AV_EF_EXPLODE
abort decoding on minor error detection
Definition: defs.h:51
AVStreamGroup::id
int64_t id
Group type-specific group ID.
Definition: avformat.h:1116
AV_CODEC_ID_AC3
@ AV_CODEC_ID_AC3
Definition: codec_id.h:463
HEIFItem::name
char * name
Definition: isom.h:298
AV_STEREO3D_VIEW_LEFT
@ AV_STEREO3D_VIEW_LEFT
Frame contains only the left view.
Definition: stereo3d.h:158
MOVStreamContext::sync_group
MOVSbgp * sync_group
Definition: isom.h:243
MOVStreamContext::height
int height
tkhd height
Definition: isom.h:229
MOVContext::moov_retry
int moov_retry
Definition: isom.h:355
MOV_TRUN_SAMPLE_FLAGS
#define MOV_TRUN_SAMPLE_FLAGS
Definition: isom.h:415
AV_PKT_DATA_AMBIENT_VIEWING_ENVIRONMENT
@ AV_PKT_DATA_AMBIENT_VIEWING_ENVIRONMENT
Ambient viewing environment metadata, as defined by H.274.
Definition: packet.h:327
MOVContext::nb_chapter_tracks
unsigned int nb_chapter_tracks
Definition: isom.h:343
mix
static int mix(int c0, int c1)
Definition: 4xm.c:717
MOVStreamContext::last_stsd_index
int last_stsd_index
Definition: isom.h:258
ff_ac3_channel_layout_tab
const uint16_t ff_ac3_channel_layout_tab[8]
Map audio coding mode (acmod) to channel layout mask.
Definition: ac3_channel_layout_tab.h:31
r
const char * r
Definition: vf_curves.c:127
AVERROR
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later. That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another. Frame references ownership and permissions
opt.h
get_heif_item
static HEIFItem * get_heif_item(MOVContext *c, unsigned id)
Get the requested item.
Definition: mov.c:194
MOV_TKHD_FLAG_ENABLED
#define MOV_TKHD_FLAG_ENABLED
Definition: isom.h:428
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:1132
AVFMT_SHOW_IDS
#define AVFMT_SHOW_IDS
Show format stream IDs numbers.
Definition: avformat.h:476
AVSphericalMapping::projection
enum AVSphericalProjection projection
Projection type.
Definition: spherical.h:104
AV_WL32
#define AV_WL32(p, v)
Definition: intreadwrite.h:422
av_exif_parse_buffer
int av_exif_parse_buffer(void *logctx, const uint8_t *buf, size_t size, AVExifMetadata *ifd, enum AVExifHeaderMode header_mode)
Decodes the EXIF data provided in the buffer and writes it into the struct *ifd.
Definition: exif.c:881
AV_STREAM_GROUP_PARAMS_LCEVC
@ AV_STREAM_GROUP_PARAMS_LCEVC
Definition: avformat.h:1091
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:11798
AVSphericalMapping::bound_bottom
uint32_t bound_bottom
Distance from the bottom edge.
Definition: spherical.h:188
MOVStreamContext::open_key_samples
int * open_key_samples
Definition: isom.h:248
AVUUID
uint8_t AVUUID[AV_UUID_LEN]
Definition: uuid.h:60
out
static FILE * out
Definition: movenc.c:55
MOVFragmentStreamInfo
Definition: isom.h:139
AVFieldOrder
AVFieldOrder
Definition: defs.h:211
mov_read_targa_y216
static int mov_read_targa_y216(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2316
mov_read_chnl
static int mov_read_chnl(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1227
mov_read_moof
static int mov_read_moof(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1853
av_bprint_init
void av_bprint_init(AVBPrint *buf, unsigned size_init, unsigned size_max)
Definition: bprint.c:69
ctype
#define ctype
Definition: afir_template.c:46
AV_PKT_DATA_FRAME_CROPPING
@ AV_PKT_DATA_FRAME_CROPPING
The number of pixels to discard from the top/bottom/left/right border of the decoded frame to obtain ...
Definition: packet.h:340
av_exif_write
int av_exif_write(void *logctx, const AVExifMetadata *ifd, AVBufferRef **buffer, enum AVExifHeaderMode header_mode)
Allocates a buffer using av_malloc of an appropriate size and writes the EXIF data represented by ifd...
Definition: exif.c:752
AVCodecParameters
This struct describes the properties of an encoded stream.
Definition: codec_par.h:47
HEIFItem::icc_profile
uint8_t * icc_profile
Definition: isom.h:309
AVFMT_FLAG_IGNIDX
#define AVFMT_FLAG_IGNIDX
Ignore index.
Definition: avformat.h:1416
AVExifMetadata
Definition: exif.h:76
sanity_checks
static int sanity_checks(void *log_obj, MOVStreamContext *sc, int index)
Definition: mov.c:5176
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:10171
HEIFItem::hflip
int hflip
Definition: isom.h:305
AV_PKT_DATA_NEW_EXTRADATA
@ AV_PKT_DATA_NEW_EXTRADATA
The AV_PKT_DATA_NEW_EXTRADATA is used to notify the codec or the format that the extradata buffer was...
Definition: packet.h:56
IAMFAudioElement::nb_substreams
unsigned int nb_substreams
Definition: iamf.h:99
AVStream::priv_data
void * priv_data
Definition: avformat.h:769
AVERROR_EOF
#define AVERROR_EOF
End of file.
Definition: error.h:57
AVBufferRef::data
uint8_t * data
The data buffer.
Definition: buffer.h:90
AV_DISPOSITION_ATTACHED_PIC
#define AV_DISPOSITION_ATTACHED_PIC
The stream is stored in the file as an attached picture/"cover art" (e.g.
Definition: avformat.h:670
AVStream::discard
enum AVDiscard discard
Selects which packets can be discarded at will and do not need to be demuxed.
Definition: avformat.h:815
AV_FIELD_PROGRESSIVE
@ AV_FIELD_PROGRESSIVE
Definition: defs.h:213
mov_options
static const AVOption mov_options[]
Definition: mov.c:11744
mov_codec_id
static int mov_codec_id(AVStream *st, uint32_t format)
Definition: mov.c:2665
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:8953
matrix
Definition: vc1dsp.c:43
AVMasteringDisplayMetadata::display_primaries
AVRational display_primaries[3][2]
CIE 1931 xy chromaticity coords of color primaries (r, g, b order).
Definition: mastering_display_metadata.h:42
AV_PKT_FLAG_DISCARD
#define AV_PKT_FLAG_DISCARD
Flag is used to discard packets which are required to maintain valid decoder state but are not requir...
Definition: packet.h:650
AVMasteringDisplayMetadata::has_luminance
int has_luminance
Flag indicating whether the luminance (min_ and max_) have been set.
Definition: mastering_display_metadata.h:67
get_bits_long
static unsigned int get_bits_long(GetBitContext *s, int n)
Read 0-32 bits.
Definition: get_bits.h:424
int64_t
long long int64_t
Definition: coverity.c:34
output
filter_frame For filters that do not use the this method is called when a frame is pushed to the filter s input It can be called at any time except in a reentrant way If the input frame is enough to produce output
Definition: filter_design.txt:226
mov_read_alac
static int mov_read_alac(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2288
test_same_origin
static int test_same_origin(const char *src, const char *ref)
Definition: mov.c:5019
cbcs_scheme_decrypt
static int cbcs_scheme_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
Definition: mov.c:8379
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:622
IS_MATRIX_IDENT
#define IS_MATRIX_IDENT(matrix)
Definition: mov.c:5561
AVStreamGroup::disposition
int disposition
Stream group disposition - a combination of AV_DISPOSITION_* flags.
Definition: avformat.h:1174
av_unused
#define av_unused
Definition: attributes.h:156
AV_DISPOSITION_DEFAULT
#define AV_DISPOSITION_DEFAULT
The stream should be chosen by default among other streams of the same type, unless the user has expl...
Definition: avformat.h:617
mov_update_dts_shift
static void mov_update_dts_shift(MOVStreamContext *sc, int duration, void *logctx)
Definition: mov.c:3717
MOVStreamContext::spherical
AVSphericalMapping * spherical
Definition: isom.h:265
mask
int mask
Definition: mediacodecdec_common.c:154
out_size
static 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:2293
AV_RB32A
#define AV_RB32A(p)
Definition: intreadwrite.h:575
MOVContext::primary_item_id
int primary_item_id
Definition: isom.h:380
mode
Definition: swscale.c:59
MOVContext::found_moov
int found_moov
'moov' atom has been found
Definition: isom.h:326
ff_iamf_read_packet
int ff_iamf_read_packet(AVFormatContext *s, IAMFDemuxContext *c, AVIOContext *pb, int max_size, int stream_id_offset, AVPacket *pkt)
Definition: iamf_reader.c:308
mov_read_custom
static int mov_read_custom(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5403
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:1331
HEIFGrid::nb_tiles
int nb_tiles
Definition: isom.h:318
ID3v1_GENRE_MAX
#define ID3v1_GENRE_MAX
Definition: id3v1.h:29
MOVSbgp
Definition: isom.h:121
MOVCtts
Definition: isom.h:68
AVPacketSideData
This structure stores auxiliary information for decoding, presenting, or otherwise processing the cod...
Definition: packet.h:409
mov_read_extradata
static int mov_read_extradata(MOVContext *c, AVIOContext *pb, MOVAtom atom, enum AVCodecID codec_id)
Definition: mov.c:2262
AVCOL_RANGE_JPEG
@ AVCOL_RANGE_JPEG
Full range content.
Definition: pixfmt.h:777
mpegaudiodecheader.h
MOVStreamContext::rap_group_count
unsigned int rap_group_count
Definition: isom.h:240
av_display_matrix_flip
void av_display_matrix_flip(int32_t matrix[9], int hflip, int vflip)
Flip the input matrix horizontally and/or vertically.
Definition: display.c:66
av_sha_init
av_cold int av_sha_init(AVSHA *ctx, int bits)
Initialize SHA-1 or SHA-2 hashing.
Definition: sha.c:274
HEIFItem::type
int type
Definition: isom.h:307
mov_read_mvhd
static int mov_read_mvhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1955
mov_read_idat
static int mov_read_idat(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:8947
AVPacket::data
uint8_t * data
Definition: packet.h:588
MOVContext::found_mdat
int found_mdat
'mdat' atom has been found
Definition: isom.h:329
MOVStreamContext::drefs_count
unsigned drefs_count
Definition: isom.h:222
AVEncryptionInfo::crypt_byte_block
uint32_t crypt_byte_block
Only used for pattern encryption.
Definition: encryption_info.h:51
AV_PKT_DATA_ENCRYPTION_INIT_INFO
@ AV_PKT_DATA_ENCRYPTION_INIT_INFO
This side data is encryption initialization data.
Definition: packet.h:246
mov_read_avid
static int mov_read_avid(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2308
AVAmbientViewingEnvironment::ambient_light_x
AVRational ambient_light_x
Normalized x chromaticity coordinate of the environmental ambient light in the nominal viewing enviro...
Definition: ambient_viewing_environment.h:47
AVCodecParameters::seek_preroll
int seek_preroll
Audio only.
Definition: codec_par.h:214
av_dynarray2_add
void * av_dynarray2_add(void **tab_ptr, int *nb_ptr, size_t elem_size, const uint8_t *elem_data)
Add an element of size elem_size to a dynamic array.
Definition: mem.c:343
AVOption
AVOption.
Definition: opt.h:429
MOVContext::trex_data
MOVTrackExt * trex_data
Definition: isom.h:338
mov_read_stps
static int mov_read_stps(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:3370
MOVContext::bitrates
int * bitrates
bitrates read before streams creation
Definition: isom.h:353
b
#define b
Definition: input.c:42
AVCOL_TRC_UNSPECIFIED
@ AVCOL_TRC_UNSPECIFIED
Definition: pixfmt.h:669
MOVContext::interleaved_read
int interleaved_read
Definition: isom.h:387
mov_read_tkhd
static int mov_read_tkhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5569
MOVElst::rate
float rate
Definition: isom.h:82
AVStream::avg_frame_rate
AVRational avg_frame_rate
Average framerate.
Definition: avformat.h:833
table
static const uint16_t table[]
Definition: prosumer.c:203
spherical.h
mov_read_colr
static int mov_read_colr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2109
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:1994
mov_read_strf
static int mov_read_strf(MOVContext *c, AVIOContext *pb, MOVAtom atom)
An strf atom is a BITMAPINFOHEADER struct.
Definition: mov.c:2578
AV_CODEC_ID_ALAC
@ AV_CODEC_ID_ALAC
Definition: codec_id.h:476
HEIFItem::st
AVStream * st
Definition: isom.h:295
FF_COMPLIANCE_STRICT
#define FF_COMPLIANCE_STRICT
Strictly conform to all the things in the spec no matter what consequences.
Definition: defs.h:59
AVIOContext::error
int error
contains the error code or 0 if no error happened
Definition: avio.h:239
AV_CODEC_ID_AMR_NB
@ AV_CODEC_ID_AMR_NB
Definition: codec_id.h:441
av_iamf_mix_presentation_free
void av_iamf_mix_presentation_free(AVIAMFMixPresentation **pmix_presentation)
Free an AVIAMFMixPresentation and all its contents.
Definition: iamf.c:536
mov_parse_auxiliary_info
static int mov_parse_auxiliary_info(MOVContext *c, MOVStreamContext *sc, AVIOContext *pb, MOVEncryptionIndex *encryption_index)
Definition: mov.c:7642
mov_seek_stream
static int mov_seek_stream(AVFormatContext *s, AVStream *st, int64_t timestamp, int flags)
Definition: mov.c:11596
mov_read_saio
static int mov_read_saio(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:7788
mov_get_stsc_samples
static int64_t mov_get_stsc_samples(MOVStreamContext *sc, unsigned int index)
Definition: mov.c:3355
AV_LOG_VERBOSE
#define AV_LOG_VERBOSE
Detailed information.
Definition: log.h:226
ff_codec_wav_tags
const AVCodecTag ff_codec_wav_tags[]
Definition: riff.c:530
get_edit_list_entry
static int get_edit_list_entry(MOVContext *mov, const MOVStreamContext *msc, unsigned int edit_list_index, int64_t *edit_list_media_time, int64_t *edit_list_duration, int64_t global_timescale)
Get ith edit list entry (media time, duration).
Definition: mov.c:3926
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:11205
HEIFItemRef
Definition: isom.h:289
MOVStreamContext::tref_id
int tref_id
Definition: isom.h:226
MP4TrackKindMapping::scheme_uri
const char * scheme_uri
Definition: isom.h:490
AVINDEX_DISCARD_FRAME
#define AVINDEX_DISCARD_FRAME
Definition: avformat.h:607
av_display_rotation_set
void av_display_rotation_set(int32_t matrix[9], double angle)
Initialize a transformation matrix describing a pure clockwise rotation by the specified angle (in de...
Definition: display.c:51
AVPacket::duration
int64_t duration
Duration of this packet in AVStream->time_base units, 0 if unknown.
Definition: packet.h:606
AVCodecParameters::codec_tag
uint32_t codec_tag
Additional information about the codec (corresponds to the AVI FOURCC).
Definition: codec_par.h:59
fixed_key
static const uint8_t fixed_key[]
Definition: aes_ctr.c:45
AV_SPHERICAL_EQUIRECTANGULAR_TILE
@ AV_SPHERICAL_EQUIRECTANGULAR_TILE
Video represents a portion of a sphere mapped on a flat surface using equirectangular projection.
Definition: spherical.h:68
AVStereo3D::baseline
uint32_t baseline
The distance between the centres of the lenses of the camera system, in micrometers.
Definition: stereo3d.h:228
MOVDref::dir
char * dir
Definition: isom.h:88
mov_current_sample_set
static void mov_current_sample_set(MOVStreamContext *sc, int current_sample)
Definition: mov.c:4230
mathematics.h
AVDictionary
Definition: dict.c:32
ffio_init_read_context
void ffio_init_read_context(FFIOContext *s, const uint8_t *buffer, int buffer_size)
Wrap a buffer in an AVIOContext for reading.
Definition: aviobuf.c:99
AV_PKT_FLAG_DISPOSABLE
#define AV_PKT_FLAG_DISPOSABLE
Flag is used to indicate packets that contain frames that can be discarded by the decoder.
Definition: packet.h:662
AVChannelLayout::order
enum AVChannelOrder order
Channel order used in this layout.
Definition: channel_layout.h:324
FFMAX
#define FFMAX(a, b)
Definition: macros.h:47
MOVAtom
Definition: isom.h:94
AVStreamGroupTileGrid::vertical
int vertical
Offset in pixels from the top edge of the canvas where the tile should be placed.
Definition: avformat.h:1000
iamf_parse.h
mov_read_moov
static int mov_read_moov(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1603
av_sub_q
AVRational av_sub_q(AVRational b, AVRational c)
Subtract one rational from another.
Definition: rational.c:101
cffstream
static const av_always_inline FFStream * cffstream(const AVStream *st)
Definition: internal.h:367
mov_read_esds
static int mov_read_esds(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:848
MOVStreamContext::sample_count
unsigned int sample_count
Definition: isom.h:205
MOVFragmentIndex::allocated_size
int allocated_size
Definition: isom.h:161
MOVTrackExt::flags
unsigned flags
Definition: isom.h:118
AVChannelLayout::nb_channels
int nb_channels
Number of channels in this layout.
Definition: channel_layout.h:329
HEIFItem::height
int height
Definition: isom.h:303
AV_SPHERICAL_EQUIRECTANGULAR
@ AV_SPHERICAL_EQUIRECTANGULAR
Video represents a sphere mapped on a flat surface using equirectangular projection.
Definition: spherical.h:52
intfloat.h
id3v1.h
MOVStreamContext::ctts_data
MOVCtts * ctts_data
Definition: isom.h:192
ff_dvdclut_yuv_to_rgb
int ff_dvdclut_yuv_to_rgb(uint32_t *clut, const size_t clut_size)
Definition: dvdclut.c:50
AV_CODEC_ID_R10K
@ AV_CODEC_ID_R10K
Definition: codec_id.h:197
av_encryption_init_info_get_side_data
AVEncryptionInitInfo * av_encryption_init_info_get_side_data(const uint8_t *side_data, size_t side_data_size)
Creates a copy of the AVEncryptionInitInfo that is contained in the given side data.
Definition: encryption_info.c:231
AVStreamGroupTileGrid::offsets
struct AVStreamGroupTileGrid::@439 * offsets
An nb_tiles sized array of offsets in pixels from the topleft edge of the canvas, indicating where ea...
AV_STEREO3D_VIEW_RIGHT
@ AV_STEREO3D_VIEW_RIGHT
Frame contains only the right view.
Definition: stereo3d.h:163
MOVContext::advanced_editlist_autodisabled
int advanced_editlist_autodisabled
Definition: isom.h:347
avio_size
int64_t avio_size(AVIOContext *s)
Get the filesize.
Definition: aviobuf.c:326
av_strlcatf
size_t av_strlcatf(char *dst, size_t size, const char *fmt,...)
Definition: avstring.c:103
mov_read_stco
static int mov_read_stco(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2600
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:7153
FFIOContext
Definition: avio_internal.h:28
AV_PKT_FLAG_KEY
#define AV_PKT_FLAG_KEY
The packet contains a keyframe.
Definition: packet.h:643
init_get_bits
static int init_get_bits(GetBitContext *s, const uint8_t *buffer, int bit_size)
Initialize GetBitContext.
Definition: get_bits.h:517
MOVStreamContext::aes_ctr
struct AVAESCTR * aes_ctr
Definition: isom.h:278
cenc_filter
static int cenc_filter(MOVContext *mov, AVStream *st, MOVStreamContext *sc, AVPacket *pkt, int current_index)
Definition: mov.c:8492
mov_read_sdtp
static int mov_read_sdtp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:3679
mov_read_jp2h
static int mov_read_jp2h(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2298
AV_STEREO3D_UNSPEC
@ AV_STEREO3D_UNSPEC
Video is stereoscopic but the packing is unspecified.
Definition: stereo3d.h:143
AVIndexEntry
Definition: avformat.h:598
AV_WB64
#define AV_WB64(p, v)
Definition: intreadwrite.h:429
MOVStreamContext::dv_audio_container
int dv_audio_container
Definition: isom.h:219
AV_CODEC_ID_AMR_WB
@ AV_CODEC_ID_AMR_WB
Definition: codec_id.h:442
mov_read_tfhd
static int mov_read_tfhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5674
AV_CODEC_ID_BIN_DATA
@ AV_CODEC_ID_BIN_DATA
Definition: codec_id.h:613
OPUS_SEEK_PREROLL_MS
#define OPUS_SEEK_PREROLL_MS
Definition: oggparseopus.c:36
AV_CODEC_ID_H261
@ AV_CODEC_ID_H261
Definition: codec_id.h:55
IAMFMixPresentation::cmix
const AVIAMFMixPresentation * cmix
Definition: iamf.h:108
MOVContext::decryption_default_key
uint8_t * decryption_default_key
Definition: isom.h:373
mov_read_wide
static int mov_read_wide(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6254
AVINDEX_KEYFRAME
#define AVINDEX_KEYFRAME
Definition: avformat.h:606
AV_FIELD_BT
@ AV_FIELD_BT
Bottom coded first, top displayed first.
Definition: defs.h:217
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:205
ff_get_extradata
int ff_get_extradata(void *logctx, AVCodecParameters *par, AVIOContext *pb, int size)
Allocate extradata with additional AV_INPUT_BUFFER_PADDING_SIZE at end which is always set to 0 and f...
Definition: demux_utils.c:340
AVStereo3D::horizontal_field_of_view
AVRational horizontal_field_of_view
Horizontal field of view, in degrees.
Definition: stereo3d.h:239
skip_bits
static void skip_bits(GetBitContext *s, int n)
Definition: get_bits.h:383
AVCodecParameters::color_primaries
enum AVColorPrimaries color_primaries
Definition: codec_par.h:167
AVEncryptionInfo::scheme
uint32_t scheme
The fourcc encryption scheme, in big-endian byte order.
Definition: encryption_info.h:45
MOVStreamContext::stsc_count
unsigned int stsc_count
Definition: isom.h:193
MOVStreamContext::has_palette
int has_palette
Definition: isom.h:234
AVPROBE_SCORE_MAX
#define AVPROBE_SCORE_MAX
maximum score
Definition: avformat.h:463
AV_STEREO3D_SIDEBYSIDE
@ AV_STEREO3D_SIDEBYSIDE
Views are next to each other.
Definition: stereo3d.h:64
MOVIndexRange::start
int64_t start
Definition: isom.h:169
AVPacketSideData::size
size_t size
Definition: packet.h:411
get_bits
static unsigned int get_bits(GetBitContext *s, int n)
Read 1-25 bits.
Definition: get_bits.h:337
ff_remove_stream
void ff_remove_stream(AVFormatContext *s, AVStream *st)
Remove a stream from its AVFormatContext and free it.
Definition: avformat.c:116
OFFSET
#define OFFSET(x)
Definition: mov.c:11742
HEIFGrid::tile_item_list
HEIFItem ** tile_item_list
Definition: isom.h:315
set_icc_profile_from_item
static int set_icc_profile_from_item(AVPacketSideData **coded_side_data, int *nb_coded_side_data, const HEIFItem *item)
Definition: mov.c:10306
AV_FIELD_TT
@ AV_FIELD_TT
Top coded_first, top displayed first.
Definition: defs.h:214
AV_STEREO3D_VIEW_PACKED
@ AV_STEREO3D_VIEW_PACKED
Frame contains two packed views.
Definition: stereo3d.h:153
AV_SPHERICAL_PARAMETRIC_IMMERSIVE
@ AV_SPHERICAL_PARAMETRIC_IMMERSIVE
Parametric Immersive projection (Apple).
Definition: spherical.h:90
MOVStreamContext::nb_frames_for_fps
int nb_frames_for_fps
Definition: isom.h:252
avpriv_dv_produce_packet
int avpriv_dv_produce_packet(DVDemuxContext *c, AVPacket *pkt, uint8_t *buf, int buf_size, int64_t pos)
Definition: dv.c:738
avpriv_set_pts_info
void avpriv_set_pts_info(AVStream *st, int pts_wrap_bits, unsigned int pts_num, unsigned int pts_den)
Set the time base and wrapping info for a given stream.
Definition: avformat.c:781
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:1541
AV_OPT_TYPE_BINARY
@ AV_OPT_TYPE_BINARY
Underlying C type is a uint8_t* that is either NULL or points to an array allocated with the av_mallo...
Definition: opt.h:286
av_color_space_name
const char * av_color_space_name(enum AVColorSpace space)
Definition: pixdesc.c:3856
av_packet_add_side_data
int av_packet_add_side_data(AVPacket *pkt, enum AVPacketSideDataType type, uint8_t *data, size_t size)
Wrap an existing array as a packet side data.
Definition: packet.c:197
MOVStreamContext::mastering
AVMasteringDisplayMetadata * mastering
Definition: isom.h:267
AV_CODEC_ID_SPEEX
@ AV_CODEC_ID_SPEEX
Definition: codec_id.h:495
AV_FOURCC_MAX_STRING_SIZE
#define AV_FOURCC_MAX_STRING_SIZE
Definition: avutil.h:345
AV_PKT_DATA_PALETTE
@ AV_PKT_DATA_PALETTE
An AV_PKT_DATA_PALETTE side data packet contains exactly AVPALETTE_SIZE bytes worth of palette.
Definition: packet.h:47
ffstream
static av_always_inline FFStream * ffstream(AVStream *st)
Definition: internal.h:362
MOVFragmentIndexItem::current
int current
Definition: isom.h:155
AVFMT_SEEK_TO_PTS
#define AVFMT_SEEK_TO_PTS
Seeking is based on PTS.
Definition: avformat.h:499
AV_CODEC_ID_PCM_S16BE
@ AV_CODEC_ID_PCM_S16BE
Definition: codec_id.h:339
mov_read_mdhd
static int mov_read_mdhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1909
mov_read_ctts
static int mov_read_ctts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:3728
MOVTrackExt
Definition: isom.h:113
MOV_FRAG_SAMPLE_FLAG_IS_NON_SYNC
#define MOV_FRAG_SAMPLE_FLAG_IS_NON_SYNC
Definition: isom.h:419
fail
#define fail()
Definition: checkasm.h:221
mov_read_aclr
static int mov_read_aclr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2373
AVSEEK_FLAG_ANY
#define AVSEEK_FLAG_ANY
seek to any frame, even non-keyframes
Definition: avformat.h:2475
av_int2float
static av_always_inline float av_int2float(uint32_t i)
Reinterpret a 32-bit integer as a float.
Definition: intfloat.h:40
MOVFragment::found_tfhd
int found_tfhd
Definition: isom.h:102
AVStreamGroupTileGrid
AVStreamGroupTileGrid holds information on how to combine several independent images on a single canv...
Definition: avformat.h:951
FF_DVDCLUT_CLUT_SIZE
#define FF_DVDCLUT_CLUT_SIZE
Definition: dvdclut.h:29
AV_STEREO3D_2D
@ AV_STEREO3D_2D
Video is not stereoscopic (and metadata has to be there).
Definition: stereo3d.h:52
read_seek
static int read_seek(AVFormatContext *ctx, int stream_index, int64_t timestamp, int flags)
Definition: libcdio.c:151
HEIFItem::item_id
int item_id
Definition: isom.h:299
av_shrink_packet
void av_shrink_packet(AVPacket *pkt, int size)
Reduce packet size, correctly zeroing padding.
Definition: packet.c:113
timecode.h
get_current_frag_stream_info
static MOVFragmentStreamInfo * get_current_frag_stream_info(MOVFragmentIndex *frag_index)
Definition: mov.c:1660
GetBitContext
Definition: get_bits.h:109
MOVStreamContext::mastering_size
size_t mastering_size
Definition: isom.h:268
AVStreamGroupTileGrid::coded_width
int coded_width
Width of the canvas.
Definition: avformat.h:966
av_iamf_audio_element_free
void av_iamf_audio_element_free(AVIAMFAudioElement **paudio_element)
Free an AVIAMFAudioElement and all its contents.
Definition: iamf.c:338
FFStream::index_entries_allocated_size
unsigned int index_entries_allocated_size
Definition: internal.h:187
read_close
static av_cold int read_close(AVFormatContext *ctx)
Definition: libcdio.c:143
mov_read_amve
static int mov_read_amve(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6613
mov_read_enda
static int mov_read_enda(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2023
mov_read_chap
static int mov_read_chap(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5721
MOVParseTableEntry
Definition: mov.c:82
avio_tell
static av_always_inline int64_t avio_tell(AVIOContext *s)
ftell() equivalent for AVIOContext.
Definition: avio.h:494
av_exif_free
void av_exif_free(AVExifMetadata *ifd)
Frees all resources associated with the given EXIF metadata struct.
Definition: exif.c:658
MOV_TRUN_SAMPLE_DURATION
#define MOV_TRUN_SAMPLE_DURATION
Definition: isom.h:413
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:10320
type
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf type
Definition: writing_filters.txt:86
MOVContext
Definition: isom.h:321
AV_DISPOSITION_TIMED_THUMBNAILS
#define AV_DISPOSITION_TIMED_THUMBNAILS
The stream is sparse, and contains thumbnail images, often corresponding to chapter markers.
Definition: avformat.h:675
AVStreamGroupTileGrid::coded_height
int coded_height
Width of the canvas.
Definition: avformat.h:972
pts
static int64_t pts
Definition: transcode_aac.c:644
MOVStreamContext::v_spacing
int v_spacing
pasp vSpacing
Definition: isom.h:231
AVEncryptionInfo::iv
uint8_t * iv
The initialization vector.
Definition: encryption_info.h:71
AV_CODEC_ID_MP3
@ AV_CODEC_ID_MP3
preferred ID for decoding MPEG audio layer 1, 2 or 3
Definition: codec_id.h:461
AVStream::duration
int64_t duration
Decoding: duration of the stream, in stream time base.
Definition: avformat.h:803
AVAmbientViewingEnvironment::ambient_illuminance
AVRational ambient_illuminance
Environmental illuminance of the ambient viewing environment in lux.
Definition: ambient_viewing_environment.h:40
ss
#define ss(width, name, subs,...)
Definition: cbs_vp9.c:202
MOVStreamContext::width
int width
tkhd width
Definition: isom.h:228
MOVContext::meta_keys
char ** meta_keys
Definition: isom.h:332
get_key_from_kid
static int get_key_from_kid(uint8_t *out, int len, MOVContext *c, AVEncryptionInfo *sample)
Definition: mov.c:8146
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:391
loop
static int loop
Definition: ffplay.c:337
ff_data_to_hex
char * ff_data_to_hex(char *buf, const uint8_t *src, int size, int lowercase)
Write hexadecimal string corresponding to given binary data.
Definition: utils.c:458
update_frag_index
static int update_frag_index(MOVContext *c, int64_t offset)
Definition: mov.c:1777
AV_CODEC_ID_PRORES_RAW
@ AV_CODEC_ID_PRORES_RAW
Definition: codec_id.h:333
AVRational::num
int num
Numerator.
Definition: rational.h:59
MOVStreamContext::keyframes
int * keyframes
Definition: isom.h:209
MOVEncryptionIndex::auxiliary_info_sample_count
size_t auxiliary_info_sample_count
Definition: isom.h:133
AV_FIELD_TB
@ AV_FIELD_TB
Top coded first, bottom displayed first.
Definition: defs.h:216
mov_read_pack
static int mov_read_pack(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6685
AVStream::attached_pic
AVPacket attached_pic
For streams with AV_DISPOSITION_ATTACHED_PIC disposition, this packet will contain the attached pictu...
Definition: avformat.h:842
MOVStsc::id
int id
Definition: isom.h:76
mov_read_saiz
static int mov_read_saiz(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:7704
MOV_FRAG_SAMPLE_FLAG_DEPENDS_YES
#define MOV_FRAG_SAMPLE_FLAG_DEPENDS_YES
Definition: isom.h:426
mov_merge_tts_data
static int mov_merge_tts_data(MOVContext *mov, AVStream *st, int flags)
Definition: mov.c:4646
MOVContext::idat_offset
int64_t idat_offset
Definition: isom.h:386
MOV_TRUN_DATA_OFFSET
#define MOV_TRUN_DATA_OFFSET
Definition: isom.h:411
av_encryption_info_clone
AVEncryptionInfo * av_encryption_info_clone(const AVEncryptionInfo *info)
Allocates an AVEncryptionInfo structure with a copy of the given data.
Definition: encryption_info.c:65
av_ambient_viewing_environment_alloc
AVAmbientViewingEnvironment * av_ambient_viewing_environment_alloc(size_t *size)
Allocate an AVAmbientViewingEnvironment structure.
Definition: ambient_viewing_environment.c:31
AV_DICT_DONT_STRDUP_VAL
#define AV_DICT_DONT_STRDUP_VAL
Take ownership of a value that's been allocated with av_malloc() or another memory allocation functio...
Definition: dict.h:79
IAMFAudioElement::element
AVIAMFAudioElement * element
element backs celement iff the AVIAMFAudioElement is owned by this structure.
Definition: iamf.h:95
MOVStreamContext::elst_data
MOVElst * elst_data
Definition: isom.h:199
mov_read_ares
static int mov_read_ares(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2330
mov_read_adrm
static int mov_read_adrm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1415
av_get_bits_per_sample
int av_get_bits_per_sample(enum AVCodecID codec_id)
Return codec bits per sample.
Definition: utils.c:549
AVCodecParameters::color_trc
enum AVColorTransferCharacteristic color_trc
Definition: codec_par.h:168
IAMFContext::audio_elements
IAMFAudioElement ** audio_elements
Definition: iamf.h:131
MOVFragmentIndex::complete
int complete
Definition: isom.h:162
AV_CODEC_ID_PCM_S8
@ AV_CODEC_ID_PCM_S8
Definition: codec_id.h:342
avassert.h
avio_rb32
unsigned int avio_rb32(AVIOContext *s)
Definition: aviobuf.c:764
AV_LOG_TRACE
#define AV_LOG_TRACE
Extremely verbose debugging, useful for libav* development.
Definition: log.h:236
MOVStreamContext::stsc_sample
int stsc_sample
Definition: isom.h:196
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:210
AV_CODEC_ID_MACE3
@ AV_CODEC_ID_MACE3
Definition: codec_id.h:469
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:10042
AV_CH_LOW_FREQUENCY
#define AV_CH_LOW_FREQUENCY
Definition: channel_layout.h:178
MOVEncryptionIndex::auxiliary_offsets
uint64_t * auxiliary_offsets
Absolute seek position.
Definition: isom.h:135
read_packet
static int read_packet(void *opaque, uint8_t *buf, int buf_size)
Definition: avio_read_callback.c:42
AV_FIELD_UNKNOWN
@ AV_FIELD_UNKNOWN
Definition: defs.h:212
MOVStreamContext::dts_shift
int dts_shift
dts shift when ctts is negative
Definition: isom.h:232
av_timecode_init
int av_timecode_init(AVTimecode *tc, AVRational rate, int flags, int frame_start, void *log_ctx)
Init a timecode struct with the passed parameters.
Definition: timecode.c:201
AVCodecParameters::frame_size
int frame_size
Audio only.
Definition: codec_par.h:195
mov_read_srat
static int mov_read_srat(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1078
avio_get_str16le
int avio_get_str16le(AVIOContext *pb, int maxlen, char *buf, int buflen)
Read a UTF-16 string from pb and convert it to UTF-8.
mov_metadata_track_or_disc_number
static int mov_metadata_track_or_disc_number(MOVContext *c, AVIOContext *pb, unsigned len, const char *key)
Definition: mov.c:91
av_dict_get
AVDictionaryEntry * av_dict_get(const AVDictionary *m, const char *key, const AVDictionaryEntry *prev, int flags)
Get a dictionary entry with matching key.
Definition: dict.c:60
AES_CTR_KEY_SIZE
#define AES_CTR_KEY_SIZE
Definition: aes_ctr.h:35
MOVStreamContext::stsd_version
int stsd_version
Definition: isom.h:260
mov_parse_exif_item
static int mov_parse_exif_item(AVFormatContext *s, AVPacketSideData **coded_side_data, int *nb_coded_side_data, const HEIFItem *ref)
Definition: mov.c:10497
AV_STREAM_GROUP_PARAMS_IAMF_MIX_PRESENTATION
@ AV_STREAM_GROUP_PARAMS_IAMF_MIX_PRESENTATION
Definition: avformat.h:1089
ff_add_attached_pic
int ff_add_attached_pic(AVFormatContext *s, AVStream *st, AVIOContext *pb, AVBufferRef **buf, int size)
Add an attached pic to an AVStream.
Definition: demux_utils.c:107
add_tts_entry
static int add_tts_entry(MOVTimeToSample **tts_data, unsigned int *tts_count, unsigned int *allocated_size, int count, int offset, unsigned int duration)
Definition: mov.c:4121
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:463
MOV_MERGE_STTS
#define MOV_MERGE_STTS
Definition: mov.c:4640
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:6547
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:5195
IAMFSubStream::audio_substream_id
unsigned int audio_substream_id
Definition: iamf.h:83
MOVContext::fc
AVFormatContext * fc
Definition: isom.h:323
MOV_TFHD_DEFAULT_BASE_IS_MOOF
#define MOV_TFHD_DEFAULT_BASE_IS_MOOF
Definition: isom.h:409
av_new_packet
int av_new_packet(AVPacket *pkt, int size)
Allocate the payload of a packet and initialize its fields with default values.
Definition: packet.c:98
AV_CODEC_ID_BMP
@ AV_CODEC_ID_BMP
Definition: codec_id.h:130
MOVStreamContext::cenc
struct MOVStreamContext::@471 cenc
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:405
ALAC_EXTRADATA_SIZE
#define ALAC_EXTRADATA_SIZE
DRM_BLOB_SIZE
#define DRM_BLOB_SIZE
Definition: mov.c:1413
MOVStreamContext::sample_offsets_count
int sample_offsets_count
Definition: isom.h:247
MOVCtts::count
unsigned int count
Definition: isom.h:69
MOVStreamContext::drefs
MOVDref * drefs
Definition: isom.h:223
av_realloc_array
void * av_realloc_array(void *ptr, size_t nmemb, size_t size)
Definition: mem.c:217
AVInputFormat::name
const char * name
A comma separated list of short names for the format.
Definition: avformat.h:549
MOVContext::aes_decrypt
struct AVAES * aes_decrypt
Definition: isom.h:372
AVSphericalMapping::bound_top
uint32_t bound_top
Distance from the top edge.
Definition: spherical.h:186
AVMEDIA_TYPE_AUDIO
@ AVMEDIA_TYPE_AUDIO
Definition: avutil.h:201
AV_CODEC_ID_VP9
@ AV_CODEC_ID_VP9
Definition: codec_id.h:222
MOVFragmentIndex::nb_items
int nb_items
Definition: isom.h:164
AVCodecParameters::width
int width
Video only.
Definition: codec_par.h:134
MOVTimeToSample
Definition: isom.h:57
AV_CHANNEL_ORDER_UNSPEC
@ AV_CHANNEL_ORDER_UNSPEC
Only the channel count is specified, without any further information about the channel order.
Definition: channel_layout.h:119
AV_CODEC_ID_MP2
@ AV_CODEC_ID_MP2
Definition: codec_id.h:460
HEIFGrid::tile_idx_list
unsigned * tile_idx_list
Definition: isom.h:317
MOV_TRUN_FIRST_SAMPLE_FLAGS
#define MOV_TRUN_FIRST_SAMPLE_FLAGS
Definition: isom.h:412
av_q2d
static double av_q2d(AVRational a)
Convert an AVRational to a double.
Definition: rational.h:104
AVIndexEntry::size
int size
Definition: avformat.h:609
av_channel_layout_from_mask
int av_channel_layout_from_mask(AVChannelLayout *channel_layout, uint64_t mask)
Initialize a native channel layout from a bitmask indicating which channels are present.
Definition: channel_layout.c:252
MOVStreamContext::keyframe_absent
int keyframe_absent
Definition: isom.h:207
info
MIPS optimizations info
Definition: mips.txt:2
MOVStts::duration
unsigned int duration
Definition: isom.h:65
fc
#define fc(width, name, range_min, range_max)
Definition: cbs_av1.c:494
MOVStreamContext::coll_size
size_t coll_size
Definition: isom.h:270
tile_rows
int tile_rows
Definition: h265_levels.c:217
mov_estimate_video_delay
static void mov_estimate_video_delay(MOVContext *c, AVStream *st)
Definition: mov.c:4150
AVIndexEntry::timestamp
int64_t timestamp
Timestamp in AVStream.time_base units, preferably the time from which on correctly decoded frames are...
Definition: avformat.h:600
av_assert0
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:42
MOVStreamContext::min_corrected_pts
int64_t min_corrected_pts
minimum Composition time shown by the edits excluding empty edits.
Definition: isom.h:212
ffio_read_leb
unsigned int ffio_read_leb(AVIOContext *s)
Read a unsigned integer coded as a variable number of up to eight little-endian bytes,...
Definition: aviobuf.c:930
tile_cols
int tile_cols
Definition: av1_levels.c:73
MOVStreamContext::sdtp_count
unsigned int sdtp_count
Definition: isom.h:188
dvdclut.h
mov_read_lhvc
static int mov_read_lhvc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:8666
AV_LOG_DEBUG
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:231
AVPacketSideData::data
uint8_t * data
Definition: packet.h:410
ctx
static AVFormatContext * ctx
Definition: movenc.c:49
hevc.h
get_bits.h
limits.h
mov_read_sidx
static int mov_read_sidx(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6115
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:352
av_rescale_q
int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq)
Rescale a 64-bit integer by 2 rational numbers.
Definition: mathematics.c:142
ff_iamfdec_read_descriptors
int ff_iamfdec_read_descriptors(IAMFContext *c, AVIOContext *pb, int max_size, void *log_ctx)
Definition: iamf_parse.c:1225
FLAC_METADATA_TYPE_STREAMINFO
@ FLAC_METADATA_TYPE_STREAMINFO
Definition: flac.h:46
FFStream::display_aspect_ratio
AVRational display_aspect_ratio
display aspect ratio (0 if unknown)
Definition: internal.h:296
IAMFContext::nb_mix_presentations
int nb_mix_presentations
Definition: iamf.h:134
mov_find_next_sample
static AVIndexEntry * mov_find_next_sample(AVFormatContext *s, AVStream **st)
Definition: mov.c:11132
AV_CODEC_ID_TARGA_Y216
@ AV_CODEC_ID_TARGA_Y216
Definition: codec_id.h:258
AVIndexEntry::min_distance
int min_distance
Minimum distance between this and the previous keyframe, used to avoid unneeded searching.
Definition: avformat.h:610
mov_read_dvcc_dvvc
static int mov_read_dvcc_dvvc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:8646
MOVParseTableEntry::parse
int(* parse)(MOVContext *ctx, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:84
codec_id
enum AVCodecID codec_id
Definition: vaapi_decode.c:410
AV_CODEC_ID_SVQ3
@ AV_CODEC_ID_SVQ3
Definition: codec_id.h:75
key
const char * key
Definition: hwcontext_opencl.c:189
AVCodecParameters::nb_coded_side_data
int nb_coded_side_data
Amount of entries in coded_side_data.
Definition: codec_par.h:86
MOVStreamContext::sdtp_data
uint8_t * sdtp_data
Definition: isom.h:189
color_range
color_range
Definition: vf_selectivecolor.c:43
AVMEDIA_TYPE_DATA
@ AVMEDIA_TYPE_DATA
Opaque data information usually continuous.
Definition: avutil.h:202
mov_read_udta_string
static int mov_read_udta_string(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:345
av_mallocz
#define av_mallocz(s)
Definition: tableprint_vlc.h:31
mov_read_stss
static int mov_read_stss(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:3411
mov_read_ddts
static int mov_read_ddts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1155
mov_read_uuid
static int mov_read_uuid(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:7307
AVCOL_PRI_UNSPECIFIED
@ AVCOL_PRI_UNSPECIFIED
Definition: pixfmt.h:639
MOVTrackExt::duration
unsigned duration
Definition: isom.h:116
AV_CODEC_ID_H264
@ AV_CODEC_ID_H264
Definition: codec_id.h:79
av_content_light_metadata_alloc
AVContentLightMetadata * av_content_light_metadata_alloc(size_t *size)
Allocate an AVContentLightMetadata structure and set its fields to default values.
Definition: mastering_display_metadata.c:72
tmp
static uint8_t tmp[40]
Definition: aes_ctr.c:52
av_sha_final
void av_sha_final(AVSHA *ctx, uint8_t *digest)
Finish hashing and output digest value.
Definition: sha.c:347
MOVStreamContext::current_sample
int current_sample
Definition: isom.h:213
MOVFragmentStreamInfo::sidx_pts
int64_t sidx_pts
Definition: isom.h:141
MAX_REORDER_DELAY
#define MAX_REORDER_DELAY
Definition: mov.c:4149
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:10116
ff_hex_to_data
int ff_hex_to_data(uint8_t *data, const char *p)
Parse a string of hexadecimal strings.
Definition: utils.c:479
MOVAtom::size
int64_t size
Definition: isom.h: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:469
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:6274
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:7532
FFStream::need_parsing
enum AVStreamParseType need_parsing
Definition: internal.h:314
MOVStreamContext::keyframe_count
unsigned int keyframe_count
Definition: isom.h:208
mov_read_SAND
static int mov_read_SAND(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:8894
IAMFAudioElement::audio_element_id
unsigned int audio_element_id
Definition: iamf.h:96
AVDISCARD_ALL
@ AVDISCARD_ALL
discard all
Definition: defs.h:232
AVFormatContext
Format I/O context.
Definition: avformat.h:1263
av_realloc_f
#define av_realloc_f(p, o, n)
Definition: tableprint_vlc.h:33
mov_read_stts
static int mov_read_stts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:3559
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:1083
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:3972
set_frag_stream
static void set_frag_stream(MOVFragmentIndex *frag_index, int id)
Definition: mov.c:1640
mov_read_free
static int mov_read_free(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:7412
mov_realloc_extradata
static int mov_realloc_extradata(AVCodecParameters *par, MOVAtom atom)
Definition: mov.c:2225
AVStream::codecpar
AVCodecParameters * codecpar
Codec parameters associated with this stream.
Definition: avformat.h:767
LIBAVUTIL_VERSION_INT
#define LIBAVUTIL_VERSION_INT
Definition: version.h:85
av_exif_get_tag_id
int32_t av_exif_get_tag_id(const char *name)
Retrieves the tag ID associated with the provided tag string name.
Definition: exif.c:243
AV_PKT_DATA_EXIF
@ AV_PKT_DATA_EXIF
Extensible image file format metadata.
Definition: packet.h:369
AVSEEK_FLAG_BACKWARD
#define AVSEEK_FLAG_BACKWARD
Definition: avformat.h:2473
aes.h
AVClass
Describe the class of an AVClass context structure.
Definition: log.h:76
MOVStreamContext::tts_sample
int tts_sample
Definition: isom.h:202
avpriv_dv_get_packet
int avpriv_dv_get_packet(DVDemuxContext *c, AVPacket *pkt)
Definition: dv.c:733
MOVContext::ignore_editlist
int ignore_editlist
Definition: isom.h:345
result
and forward the result(frame or status change) to the corresponding input. If nothing is possible
fabs
static __device__ float fabs(float a)
Definition: cuda_runtime.h:182
metadata
Stream codec metadata
Definition: ogg-flac-chained-meta.txt:2
AVStream::time_base
AVRational time_base
This is the fundamental unit of time (in seconds) in terms of which frame timestamps are represented.
Definition: avformat.h:783
NULL
#define NULL
Definition: coverity.c:32
sha.h
truehd_layout
static uint64_t truehd_layout(int chanmap)
Definition: mlp_parse.h:105
MOVDref
Definition: isom.h:85
AVERROR_PATCHWELCOME
#define AVERROR_PATCHWELCOME
Not yet implemented in FFmpeg, patches welcome.
Definition: error.h:64
format
New swscale design to change SwsGraph is what coordinates multiple passes These can include cascaded scaling error diffusion and so on Or we could have separate passes for the vertical and horizontal scaling In between each SwsPass lies a fully allocated image buffer Graph passes may have different levels of e g we can have a single threaded error diffusion pass following a multi threaded scaling pass SwsGraph is internally recreated whenever the image format
Definition: swscale-v2.txt:14
av_buffer_unref
void av_buffer_unref(AVBufferRef **buf)
Free a given reference and automatically free the buffer if there are no more references to it.
Definition: buffer.c:139
AV_CODEC_ID_AV1
@ AV_CODEC_ID_AV1
Definition: codec_id.h:284
MOVStreamContext::ctts_count
unsigned int ctts_count
Definition: isom.h:190
AVEncryptionInitInfo
This describes info used to initialize an encryption key system.
Definition: encryption_info.h:88
isom.h
MP4TrackKindValueMapping::disposition
int disposition
Definition: isom.h:485
mov_read_ftyp
static int mov_read_ftyp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1555
AV_WB16
#define AV_WB16(p, v)
Definition: intreadwrite.h:401
MOVContext::nb_heif_grid
int nb_heif_grid
Definition: isom.h:385
read_image_grid
static int read_image_grid(AVFormatContext *s, const HEIFGrid *grid, AVStreamGroupTileGrid *tile_grid)
Definition: mov.c:10341
MOVElst
Definition: isom.h:79
av_aes_ctr_alloc
struct AVAESCTR * av_aes_ctr_alloc(void)
Allocate an AVAESCTR context.
Definition: aes_ctr.c:41
flac_parse_block_header
static av_always_inline void flac_parse_block_header(const uint8_t *block_header, int *last, int *type, int *size)
Parse the metadata block parameters from the header.
Definition: flac.h:63
AVStreamGroupTileGrid::coded_side_data
AVPacketSideData * coded_side_data
Additional data associated with the grid.
Definition: avformat.h:1054
AVRational
Rational number (pair of numerator and denominator).
Definition: rational.h:58
AV_PRIMARY_EYE_LEFT
@ AV_PRIMARY_EYE_LEFT
Left eye.
Definition: stereo3d.h:183
mov_read_sgpd
static int mov_read_sgpd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:3809
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:9762
AVPALETTE_SIZE
#define AVPALETTE_SIZE
Definition: pixfmt.h:32
AV_OPT_TYPE_DICT
@ AV_OPT_TYPE_DICT
Underlying C type is AVDictionary*.
Definition: opt.h:290
MOVDref::nlvl_to
int16_t nlvl_to
Definition: isom.h:91
get_eia608_packet
static int get_eia608_packet(AVIOContext *pb, AVPacket *pkt, int src_size)
Definition: mov.c:11229
AV_CODEC_ID_DVD_SUBTITLE
@ AV_CODEC_ID_DVD_SUBTITLE
Definition: codec_id.h:572
AVIndexEntry::flags
int flags
Definition: avformat.h:608
MOVStreamContext::time_offset
int64_t time_offset
time offset of the edit list entries
Definition: isom.h:211
mov_read_smdm
static int mov_read_smdm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6456
av_default_item_name
const char * av_default_item_name(void *ptr)
Return the context name.
Definition: log.c:242
AVStereo3D::horizontal_disparity_adjustment
AVRational horizontal_disparity_adjustment
Relative shift of the left and right images, which changes the zero parallax plane.
Definition: stereo3d.h:234
avio_rb64
uint64_t avio_rb64(AVIOContext *s)
Definition: aviobuf.c:911
av_aes_crypt
void av_aes_crypt(AVAES *a, uint8_t *dst, const uint8_t *src, int count, uint8_t *iv, int decrypt)
Encrypt or decrypt a buffer using a previously initialized context.
Definition: aes.c:171
MOVStreamContext::current_index_range
MOVIndexRange * current_index_range
Definition: isom.h:216
mov_open_dref
static int mov_open_dref(MOVContext *c, AVIOContext **pb, const char *src, MOVDref *ref)
Definition: mov.c:5048
FFStream::nb_index_entries
int nb_index_entries
Definition: internal.h:186
AVProbeData
This structure contains the data a format has to probe a file.
Definition: avformat.h:451
av_aes_alloc
struct AVAES * av_aes_alloc(void)
Allocate an AVAES context.
Definition: aes.c:37
TAG_IS_AVCI
#define TAG_IS_AVCI(tag)
Definition: isom.h:439
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:8004
AVStream::metadata
AVDictionary * metadata
Definition: avformat.h:824
FLAC_STREAMINFO_SIZE
#define FLAC_STREAMINFO_SIZE
Definition: flac.h:32
av_color_primaries_name
const char * av_color_primaries_name(enum AVColorPrimaries primaries)
Definition: pixdesc.c:3790
FF_MOV_FLAG_MFRA_DTS
#define FF_MOV_FLAG_MFRA_DTS
Definition: isom.h:462
MOV_SAMPLE_DEPENDENCY_NO
#define MOV_SAMPLE_DEPENDENCY_NO
Definition: isom.h:435
AV_DICT_DONT_OVERWRITE
#define AV_DICT_DONT_OVERWRITE
Don't overwrite existing entries.
Definition: dict.h:81
ff_codec_movvideo_tags
const AVCodecTag ff_codec_movvideo_tags[]
Definition: isom_tags.c:29
MOVStreamContext::tts_index
int tts_index
Definition: isom.h:201
AV_DISPOSITION_MULTILAYER
#define AV_DISPOSITION_MULTILAYER
The video stream contains multiple layers, e.g.
Definition: avformat.h:714
MOVFragmentStreamInfo::index_base
int index_base
Definition: isom.h:146
MOVStreamContext::rap_group
MOVSbgp * rap_group
Definition: isom.h:241
AV_CODEC_ID_QDM2
@ AV_CODEC_ID_QDM2
Definition: codec_id.h:479
mov_read_ilst
static int mov_read_ilst(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5348
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:8467
get_sgpd_sync_index
static uint32_t get_sgpd_sync_index(const MOVStreamContext *sc, int nal_unit_type)
Definition: mov.c:4568
mov_read_fiel
static int mov_read_fiel(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2191
parse
static int parse(AVCodecParserContext *s, AVCodecContext *avctx, const uint8_t **poutbuf, int *poutbuf_size, const uint8_t *buf, int buf_size)
Definition: apv_parser.c:92
MOV_MP4_TTML_TAG
#define MOV_MP4_TTML_TAG
Definition: isom.h:480
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:403
MOVFragmentStreamInfo::stsd_id
int stsd_id
Definition: isom.h:149
av_exif_remove_entry
int av_exif_remove_entry(void *logctx, AVExifMetadata *ifd, uint16_t id, int flags)
Remove an entry from the provided EXIF metadata struct.
Definition: exif.c:1278
MOVStreamContext::open_key_samples_count
int open_key_samples_count
Definition: isom.h:249
HEIFItem
Definition: isom.h:294
ff_codec_movaudio_tags
const AVCodecTag ff_codec_movaudio_tags[]
Definition: isom_tags.c:311
ff_codec_movdata_tags
const AVCodecTag ff_codec_movdata_tags[]
Definition: isom.c:82
mov_read_wfex
static int mov_read_wfex(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1259
av_stereo3d_alloc_size
AVStereo3D * av_stereo3d_alloc_size(size_t *size)
Allocate an AVStereo3D structure and set its fields to default values.
Definition: stereo3d.c:39
index
int index
Definition: gxfenc.c:90
c
Undefined Behavior In the C some operations are like signed integer dereferencing freed accessing outside allocated Undefined Behavior must not occur in a C it is not safe even if the output of undefined operations is unused The unsafety may seem nit picking but Optimizing compilers have in fact optimized code on the assumption that no undefined Behavior occurs Optimizing code based on wrong assumptions can and has in some cases lead to effects beyond the output of computations The signed integer overflow problem in speed critical code Code which is highly optimized and works with signed integers sometimes has the problem that often the output of the computation does not c
Definition: undefined.txt:32
AVPROBE_SCORE_EXTENSION
#define AVPROBE_SCORE_EXTENSION
score for file extension
Definition: avformat.h: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:2890
cid
uint16_t cid
Definition: mxfenc.c:2333
mov_skip_multiple_stsd
static int mov_skip_multiple_stsd(MOVContext *c, AVIOContext *pb, int codec_tag, int format, int64_t size)
Definition: mov.c:3055
MOVStts
Definition: isom.h:63
AVAudioServiceType
AVAudioServiceType
Definition: defs.h:235
AV_CODEC_ID_MPEG1VIDEO
@ AV_CODEC_ID_MPEG1VIDEO
Definition: codec_id.h:53
AV_CODEC_ID_GSM
@ AV_CODEC_ID_GSM
as in Berlin toast format
Definition: codec_id.h:478
AVStream::nb_frames
int64_t nb_frames
number of frames in this stream if known or 0
Definition: avformat.h:805
AVCodecID
AVCodecID
Identify the syntax and semantics of the bitstream.
Definition: codec_id.h:49
av_packet_side_data_get
const AVPacketSideData * av_packet_side_data_get(const AVPacketSideData *sd, int nb_sd, enum AVPacketSideDataType type)
Get side information from a side data array.
Definition: packet.c:644
AVIAMFSubmixElement::audio_element_id
unsigned int audio_element_id
The id of the Audio Element this submix element references.
Definition: iamf.h:455
AV_CODEC_ID_EAC3
@ AV_CODEC_ID_EAC3
Definition: codec_id.h:500
should_retry
static int should_retry(AVIOContext *pb, int error_code)
Definition: mov.c:11162
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:520
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:559
AV_WB32
#define AV_WB32(p, v)
Definition: intreadwrite.h:415
mov_read_pasp
static int mov_read_pasp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1383
MOVContext::dv_demux
DVDemuxContext * dv_demux
Definition: isom.h:334
AV_CODEC_ID_AAC
@ AV_CODEC_ID_AAC
Definition: codec_id.h:462
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:8804
mov_read_elst
static int mov_read_elst(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6327
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:1090
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:10889
AV_CODEC_ID_QCELP
@ AV_CODEC_ID_QCELP
Definition: codec_id.h:484
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:8242
avio_rl32
unsigned int avio_rl32(AVIOContext *s)
Definition: aviobuf.c:733
MOVStreamContext::tref_flags
unsigned tref_flags
Definition: isom.h:225
AVDISCARD_NONKEY
@ AVDISCARD_NONKEY
discard all frames except keyframes
Definition: defs.h:231
MOVFragment::flags
unsigned flags
Definition: isom.h:110
f
f
Definition: af_crystalizer.c:122
AVIOContext
Bytestream IO Context.
Definition: avio.h:160
AV_CODEC_ID_PCM_S24LE
@ AV_CODEC_ID_PCM_S24LE
Definition: codec_id.h:350
mov_read_wave
static int mov_read_wave(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2421
AV_SPHERICAL_CUBEMAP
@ AV_SPHERICAL_CUBEMAP
Video frame is split into 6 faces of a cube, and arranged on a 3x2 layout.
Definition: spherical.h:61
avio_rb24
unsigned int avio_rb24(AVIOContext *s)
Definition: aviobuf.c:757
ff_mpa_check_header
static int ff_mpa_check_header(uint32_t header)
Definition: mpegaudiodecheader.h:62
MOVStreamContext::aes_ctx
struct AVAES * aes_ctx
Definition: isom.h:279
MOV_TREF_FLAG_ENHANCEMENT
#define MOV_TREF_FLAG_ENHANCEMENT
Definition: isom.h:437
cens_scheme_decrypt
static int cens_scheme_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
Definition: mov.c:8308
MOVContext::handbrake_version
int handbrake_version
Definition: isom.h:341
mov_free_stream_context
static void mov_free_stream_context(AVFormatContext *s, AVStream *st)
Definition: mov.c:10054
AVPacket::size
int size
Definition: packet.h:589
NULL_IF_CONFIG_SMALL
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
Definition: internal.h:94
ff_codec_get_id
enum AVCodecID ff_codec_get_id(const AVCodecTag *tags, unsigned int tag)
Definition: utils.c:143
avformat_alloc_context
AVFormatContext * avformat_alloc_context(void)
Allocate an AVFormatContext.
Definition: options.c:163
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:7481
AVIOContext::seekable
int seekable
A combination of AVIO_SEEKABLE_ flags or 0 when the stream is not seekable.
Definition: avio.h:261
av_aes_ctr_init
int av_aes_ctr_init(struct AVAESCTR *a, const uint8_t *key)
Initialize an AVAESCTR context.
Definition: aes_ctr.c:74
height
#define height
Definition: dsp.h:89
qtpalette.h
av_bprint_finalize
int av_bprint_finalize(AVBPrint *buf, char **ret_str)
Finalize a print buffer.
Definition: bprint.c:235
AVChannelLayout
An AVChannelLayout holds information about the channel layout of audio data.
Definition: channel_layout.h:319
FFStream
Definition: internal.h:128
mov_read_dref
static int mov_read_dref(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:638
mov_current_sample_dec
static void mov_current_sample_dec(MOVStreamContext *sc)
Definition: mov.c:4218
AVSphericalMapping::bound_right
uint32_t bound_right
Distance from the right edge.
Definition: spherical.h:187
MOVStsc::first
int first
Definition: isom.h:74
dst
uint8_t ptrdiff_t const uint8_t ptrdiff_t int intptr_t intptr_t int int16_t * dst
Definition: dsp.h:87
av_bswap32
#define av_bswap32
Definition: bswap.h:47
i
#define i(width, name, range_min, range_max)
Definition: cbs_h264.c:63
MOVStreamContext::stsz_sample_size
unsigned int stsz_sample_size
always contains sample size from stsz atom
Definition: isom.h:204
FF_MOV_FLAG_MFRA_AUTO
#define FF_MOV_FLAG_MFRA_AUTO
Definition: isom.h:461
ff_dict_set_timestamp
int ff_dict_set_timestamp(AVDictionary **dict, const char *key, int64_t timestamp)
Set a dictionary value to an ISO-8601 compliant timestamp string.
Definition: utils.c:610
av_err2str
#define av_err2str(errnum)
Convenience macro, the return value should be used only directly in function arguments but never stan...
Definition: error.h:122
for
for(k=2;k<=8;++k)
Definition: h264pred_template.c:424
MOVStreamContext::sgpd_sync
uint8_t * sgpd_sync
Definition: isom.h:244
start_time
static int64_t start_time
Definition: ffplay.c:328
uuid.h
ff_dvdclut_palette_extradata_cat
int ff_dvdclut_palette_extradata_cat(const uint32_t *clut, const size_t clut_size, AVCodecParameters *par)
Definition: dvdclut.c:28
mov_read_trun
static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5807
MOVStreamContext::stereo3d_size
size_t stereo3d_size
Definition: isom.h:264
avio_get_str
int avio_get_str(AVIOContext *pb, int maxlen, char *buf, int buflen)
Read a string from pb into buf.
Definition: aviobuf.c:869
mov_read_iprp
static int mov_read_iprp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:9399
av_sha_update
void av_sha_update(struct AVSHA *ctx, const uint8_t *data, size_t len)
Update hash value.
Definition: sha.c:315
sample
#define sample
Definition: flacdsp_template.c:44
hypot
static av_const double hypot(double x, double y)
Definition: libm.h:368
AV_CODEC_ID_H263
@ AV_CODEC_ID_H263
Definition: codec_id.h:56
MOV_TFHD_STSD_ID
#define MOV_TFHD_STSD_ID
Definition: isom.h:404
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:1208
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:3269
AV_WL32A
#define AV_WL32A(p, v)
Definition: intreadwrite.h:571
av_reallocp
int av_reallocp(void *ptr, size_t size)
Allocate, reallocate, or free a block of memory through a pointer to a pointer.
Definition: mem.c:188
ff_get_qtpalette
int ff_get_qtpalette(int codec_id, AVIOContext *pb, uint32_t *palette)
Retrieve the palette (or "color table" in QuickTime terms), either from the video sample description,...
Definition: qtpalette.c:323
AV_NOPTS_VALUE
#define AV_NOPTS_VALUE
Undefined timestamp value.
Definition: avutil.h:247
MKBETAG
#define MKBETAG(a, b, c, d)
Definition: macros.h:56
AV_CODEC_ID_QDMC
@ AV_CODEC_ID_QDMC
Definition: codec_id.h:510
av_fourcc_make_string
char * av_fourcc_make_string(char *buf, uint32_t fourcc)
Fill the provided buffer with a string containing a FourCC (four-character code) representation.
Definition: utils.c:75
AV_RB32
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_WL16 uint64_t_TMPL AV_WB64 unsigned int_TMPL AV_RB32
Definition: bytestream.h:96
avpriv_report_missing_feature
void avpriv_report_missing_feature(void *avc, const char *msg,...) av_printf_format(2
Log a generic warning message about a missing feature.
av_aes_ctr_set_full_iv
void av_aes_ctr_set_full_iv(struct AVAESCTR *a, const uint8_t *iv)
Forcefully change the "full" 16-byte iv, including the counter.
Definition: aes_ctr.c:53
AVStreamGroup::iamf_audio_element
struct AVIAMFAudioElement * iamf_audio_element
Definition: avformat.h:1130
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:903
mov_parse_heif_items
static int mov_parse_heif_items(AVFormatContext *s)
Definition: mov.c:10707
HEIFItem::is_idat_relative
int is_idat_relative
Definition: isom.h:308
IAMFContext
Definition: iamf.h:128
add_index_entry
static int64_t add_index_entry(AVStream *st, int64_t pos, int64_t timestamp, int size, int distance, int flags)
Add index entry with the given values, to the end of ffstream(st)->index_entries.
Definition: mov.c:4068
MOVDref::path
char * path
Definition: isom.h:87
mov_current_sample_inc
static void mov_current_sample_inc(MOVStreamContext *sc)
Definition: mov.c:4206
AVStream::sample_aspect_ratio
AVRational sample_aspect_ratio
sample aspect ratio (0 if unknown)
Definition: avformat.h:822
FFInputFormat::p
AVInputFormat p
The public AVInputFormat.
Definition: demux.h:70
dovi_isom.h
AVPacket::dts
int64_t dts
Decompression timestamp in AVStream->time_base units; the time at which the packet is decompressed.
Definition: packet.h:587
mov_read_vexu_proj
static int mov_read_vexu_proj(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6903
fix_timescale
static void fix_timescale(MOVContext *c, MOVStreamContext *sc)
Definition: mov.c:5120
avio_r8
int avio_r8(AVIOContext *s)
Definition: aviobuf.c:606
IAMFAudioElement::substreams
IAMFSubStream * substreams
Definition: iamf.h:98
AVSphericalMapping::padding
uint32_t padding
Number of pixels to pad from the edge of each cube face.
Definition: spherical.h:200
a
The reader does not expect b to be semantically here and if the code is changed by maybe adding a a division or other the signedness will almost certainly be mistaken To avoid this confusion a new type was SUINT is the C unsigned type but it holds a signed int to use the same example SUINT a
Definition: undefined.txt:41
av_channel_layout_retype
int av_channel_layout_retype(AVChannelLayout *channel_layout, enum AVChannelOrder order, int flags)
Change the AVChannelOrder of a channel layout.
Definition: channel_layout.c:885
av_reallocp_array
int av_reallocp_array(void *ptr, size_t nmemb, size_t size)
Allocate, reallocate an array through a pointer to a pointer.
Definition: mem.c:225
AVIAMFAudioElement
Information on how to combine one or more audio streams, as defined in section 3.6 of IAMF.
Definition: iamf.h:359
AV_PRIMARY_EYE_NONE
@ AV_PRIMARY_EYE_NONE
Neither eye.
Definition: stereo3d.h:178
mov_read_default
static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:9640
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:481
ffio_ensure_seekback
int ffio_ensure_seekback(AVIOContext *s, int64_t buf_size)
Ensures that the requested seekback buffer size will be available.
Definition: aviobuf.c:1026
AVStreamGroupTileGrid::nb_tiles
unsigned int nb_tiles
Amount of tiles in the grid.
Definition: avformat.h:959
av_packet_side_data_add
AVPacketSideData * av_packet_side_data_add(AVPacketSideData **psd, int *pnb_sd, enum AVPacketSideDataType type, void *data, size_t size, int flags)
Wrap existing data as packet side data.
Definition: packet.c:687
mov_read_packet
static int mov_read_packet(AVFormatContext *s, AVPacket *pkt)
Definition: mov.c:11362
mov_read_infe
static int mov_read_infe(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:9047
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:1075
AVStreamGroup::lcevc
struct AVStreamGroupLCEVC * lcevc
Definition: avformat.h:1133
attributes.h
AV_CODEC_ID_LCEVC
@ AV_CODEC_ID_LCEVC
Definition: codec_id.h:615
MOVEncryptionIndex::auxiliary_offsets_count
size_t auxiliary_offsets_count
Definition: isom.h:136
HEIFItem::vflip
int vflip
Definition: isom.h:306
AVPacket::flags
int flags
A combination of AV_PKT_FLAG values.
Definition: packet.h:594
av_dict_free
void av_dict_free(AVDictionary **pm)
Free all the memory allocated for an AVDictionary struct and all keys and values.
Definition: dict.c:233
av_encryption_info_free
void av_encryption_info_free(AVEncryptionInfo *info)
Frees the given encryption info object.
Definition: encryption_info.c:82
read_header
static int read_header(FFV1Context *f, RangeCoder *c)
Definition: ffv1dec.c:501
av_strstart
int av_strstart(const char *str, const char *pfx, const char **ptr)
Return non-zero if pfx is a prefix of str.
Definition: avstring.c:36
mov_find_reference_track
static AVStream * mov_find_reference_track(AVFormatContext *s, AVStream *st, int first_index)
Definition: mov.c:10786
AVSubsampleEncryptionInfo
This file is part of FFmpeg.
Definition: encryption_info.h:25
av_buffer_alloc
AVBufferRef * av_buffer_alloc(size_t size)
Allocate an AVBuffer of the given size using av_malloc().
Definition: buffer.c:77
MOVFragmentIndexItem::stream_info
MOVFragmentStreamInfo * stream_info
Definition: isom.h:157
version
version
Definition: libkvazaar.c:313
AV_STREAM_GROUP_PARAMS_IAMF_AUDIO_ELEMENT
@ AV_STREAM_GROUP_PARAMS_IAMF_AUDIO_ELEMENT
Definition: avformat.h:1088
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:1164
ff_rfps_calculate
void ff_rfps_calculate(AVFormatContext *ic)
Definition: demux.c:2397
input
and forward the test the status of outputs and forward it to the corresponding return FFERROR_NOT_READY If the filters stores internally one or a few frame for some input
Definition: filter_design.txt:172
MOV_MP4_IPCM_TAG
#define MOV_MP4_IPCM_TAG
Definition: isom.h:482
mov_read_clli
static int mov_read_clli(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6584
MOVStreamContext::chunk_offsets
int64_t * chunk_offsets
Definition: isom.h:181
AVStreamGroup::params
union AVStreamGroup::@440 params
Group type-specific parameters.
AVStreamGroup::iamf_mix_presentation
struct AVIAMFMixPresentation * iamf_mix_presentation
Definition: avformat.h:1131
AVBufferRef::size
size_t size
Size of data in bytes.
Definition: buffer.h:94
MOVFragmentIndex::item
MOVFragmentIndexItem * item
Definition: isom.h:165
AV_LOG_INFO
#define AV_LOG_INFO
Standard information.
Definition: log.h:221
MOVStreamContext::iamf
struct IAMFDemuxContext * iamf
Definition: isom.h:285
FFERROR_REDO
#define FFERROR_REDO
Returned by demuxers to indicate that data was consumed but discarded (ignored streams or junk data).
Definition: demux.h:224
av_encryption_init_info_alloc
AVEncryptionInitInfo * av_encryption_init_info_alloc(uint32_t system_id_size, uint32_t num_key_ids, uint32_t key_id_size, uint32_t data_size)
Allocates an AVEncryptionInitInfo structure and sub-pointers to hold the given sizes.
Definition: encryption_info.c:178
av_channel_layout_custom_init
int av_channel_layout_custom_init(AVChannelLayout *channel_layout, int nb_channels)
Initialize a custom channel layout with the specified number of channels.
Definition: channel_layout.c:232
av_aes_ctr_free
void av_aes_ctr_free(struct AVAESCTR *a)
Release an AVAESCTR context.
Definition: aes_ctr.c:84
av_mastering_display_metadata_alloc_size
AVMasteringDisplayMetadata * av_mastering_display_metadata_alloc_size(size_t *size)
Allocate an AVMasteringDisplayMetadata structure and set its fields to default values.
Definition: mastering_display_metadata.c:44
mov_read_dfla
static int mov_read_dfla(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:8106
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:9510
layout
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel layout
Definition: filter_design.txt:18
MOVDref::nlvl_from
int16_t nlvl_from
Definition: isom.h:91
AVStreamGroupTileGrid::nb_coded_side_data
int nb_coded_side_data
Amount of entries in coded_side_data.
Definition: avformat.h:1059
mov_metadata_creation_time
static void mov_metadata_creation_time(MOVContext *c, AVIOContext *pb, AVDictionary **metadata, int version)
Definition: mov.c:1879
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
AVChannelLayout::u
union AVChannelLayout::@508 u
Details about which channels are present in this layout.
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:8035
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:3349
mov_finalize_packet
static int mov_finalize_packet(AVFormatContext *s, AVStream *st, AVIndexEntry *sample, int64_t current_index, AVPacket *pkt)
Definition: mov.c:11298
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:11686
bprint.h
MOVContext::advanced_editlist
int advanced_editlist
Definition: isom.h:346
MOVStreamContext::time_scale
int time_scale
Definition: isom.h:210
mlp_parse.h
mac_to_unicode
static const uint32_t mac_to_unicode[128]
Definition: mov.c:150
AVStreamGroupTileGrid::width
int width
Width of the final image for presentation.
Definition: avformat.h:1036
MOVStreamContext::bytes_per_frame
unsigned int bytes_per_frame
Definition: isom.h:217
AVSphericalMapping::roll
int32_t roll
Rotation around the forward vector [-180, 180].
Definition: spherical.h:146
IAMFContext::nb_audio_elements
int nb_audio_elements
Definition: iamf.h:132
MOVIndexRange::end
int64_t end
Definition: isom.h:170
AV_CODEC_ID_NONE
@ AV_CODEC_ID_NONE
Definition: codec_id.h:50
AVPacket::pts
int64_t pts
Presentation timestamp in AVStream->time_base units; the time at which the decompressed packet will b...
Definition: packet.h:581
avio_internal.h
MOVCtts::offset
int offset
Definition: isom.h:70
mov_read_trex
static int mov_read_trex(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5742
search_frag_timestamp
static int search_frag_timestamp(AVFormatContext *s, MOVFragmentIndex *frag_index, AVStream *st, int64_t timestamp)
Definition: mov.c:1752
HEIFItem::width
int width
Definition: isom.h:302
FLAGS
#define FLAGS
Definition: mov.c:11743
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:4258
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:7883
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:3203
internal.h
AV_SPHERICAL_FISHEYE
@ AV_SPHERICAL_FISHEYE
Fisheye projection (Apple).
Definition: spherical.h:84
AVCodecParameters::height
int height
Definition: codec_par.h:135
AV_TIME_BASE
#define AV_TIME_BASE
Internal time base represented as integer.
Definition: avutil.h:253
MOVStreamContext::stps_count
unsigned int stps_count
Definition: isom.h:197
AVCodecParameters::block_align
int block_align
Audio only.
Definition: codec_par.h:191
AV_CODEC_ID_TTML
@ AV_CODEC_ID_TTML
Definition: codec_id.h:596
rb_size
static int rb_size(AVIOContext *pb, int64_t *value, int size)
Definition: mov.c:8920
AVStereo3DPrimaryEye
AVStereo3DPrimaryEye
List of possible primary eyes.
Definition: stereo3d.h:174
av_malloc_array
#define av_malloc_array(a, b)
Definition: tableprint_vlc.h:32
AV_CODEC_ID_CAVS
@ AV_CODEC_ID_CAVS
Definition: codec_id.h:139
display.h
ff_mov_read_stsd_entries
int ff_mov_read_stsd_entries(MOVContext *c, AVIOContext *pb, int entries)
Definition: mov.c:3102
AV_FIELD_BB
@ AV_FIELD_BB
Bottom coded first, bottom displayed first.
Definition: defs.h:215
AV_PKT_DATA_ICC_PROFILE
@ AV_PKT_DATA_ICC_PROFILE
ICC profile data consisting of an opaque octet buffer following the format described by ISO 15076-1.
Definition: packet.h:271
AV_STEREO3D_TOPBOTTOM
@ AV_STEREO3D_TOPBOTTOM
Views are on top of each other.
Definition: stereo3d.h:76
MOVFragment::duration
unsigned duration
Definition: isom.h:108
AVIAMFMixPresentation
Information on how to render and mix one or more AVIAMFAudioElement to generate the final audio outpu...
Definition: iamf.h:616
ff_id3v1_genre_str
const char *const ff_id3v1_genre_str[ID3v1_GENRE_MAX+1]
ID3v1 genres.
Definition: id3v1.c:26
MOVStreamContext::sample_sizes
unsigned int * sample_sizes
Definition: isom.h:206
MOVContext::frag_index
MOVFragmentIndex frag_index
Definition: isom.h:359
mov_read_vpcc
static int mov_read_vpcc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6412
AV_CODEC_ID_PCM_F64BE
@ AV_CODEC_ID_PCM_F64BE
Definition: codec_id.h:360
AV_CODEC_ID_HEVC
@ AV_CODEC_ID_HEVC
Definition: codec_id.h:228
value
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf default value
Definition: writing_filters.txt:86
av_url_split
void av_url_split(char *proto, int proto_size, char *authorization, int authorization_size, char *hostname, int hostname_size, int *port_ptr, char *path, int path_size, const char *url)
Split a URL string into components.
Definition: utils.c:361
MOVStreamContext::dref_id
int dref_id
Definition: isom.h:224
FFMIN
#define FFMIN(a, b)
Definition: macros.h:49
av_d2q
AVRational av_d2q(double d, int max)
Convert a double precision floating point number to a rational.
Definition: rational.c:106
fix_frag_index_entries
static void fix_frag_index_entries(MOVFragmentIndex *frag_index, int index, int id, int entries)
Definition: mov.c:1838
mov_finalize_stsd_codec
static int mov_finalize_stsd_codec(MOVContext *c, AVIOContext *pb, AVStream *st, MOVStreamContext *sc)
Definition: mov.c:2952
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:347
mov_read_mdcv
static int mov_read_mdcv(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6503
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:1405
AV_CODEC_ID_VC1
@ AV_CODEC_ID_VC1
Definition: codec_id.h:122
demux.h
AV_DISPOSITION_DEPENDENT
#define AV_DISPOSITION_DEPENDENT
The stream is intended to be mixed with another stream before presentation.
Definition: avformat.h:705
MOVStreamContext::pb
AVIOContext * pb
Definition: isom.h:174
mov_read_keys
static int mov_read_keys(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5357
mov_read_iref_cdsc
static int mov_read_iref_cdsc(MOVContext *c, AVIOContext *pb, uint32_t type, int version)
Definition: mov.c:9255
AVCodecParameters::color_range
enum AVColorRange color_range
Video only.
Definition: codec_par.h:166
AV_CH_SIDE_RIGHT
#define AV_CH_SIDE_RIGHT
Definition: channel_layout.h:185
len
int len
Definition: vorbis_enc_data.h:426
AV_CODEC_ID_JPEG2000
@ AV_CODEC_ID_JPEG2000
Definition: codec_id.h:140
exif.h
MOVFragment::size
unsigned size
Definition: isom.h:109
MOV_TFHD_DEFAULT_SIZE
#define MOV_TFHD_DEFAULT_SIZE
Definition: isom.h:406
MOVTimeToSample::count
unsigned int count
Definition: isom.h:58
ff_get_wav_header
int ff_get_wav_header(AVFormatContext *s, AVIOContext *pb, AVCodecParameters *par, int size, int big_endian)
Definition: riffdec.c:95
AVCOL_SPC_UNSPECIFIED
@ AVCOL_SPC_UNSPECIFIED
Definition: pixfmt.h:703
fix_stream_ids
static void fix_stream_ids(AVFormatContext *s)
Definition: mov.c:10851
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:4709
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:2416
AVSHA
hash context
Definition: sha.c:35
AVCOL_RANGE_MPEG
@ AVCOL_RANGE_MPEG
Narrow or limited range content.
Definition: pixfmt.h:760
av_calloc
void * av_calloc(size_t nmemb, size_t size)
Definition: mem.c:264
MOVFragmentStreamInfo::tfdt_dts
int64_t tfdt_dts
Definition: isom.h:143
AV_IAMF_AUDIO_ELEMENT_TYPE_SCENE
@ AV_IAMF_AUDIO_ELEMENT_TYPE_SCENE
Definition: iamf.h:349
AVCodecParameters::field_order
enum AVFieldOrder field_order
Video only.
Definition: codec_par.h:161
av_get_packet
int av_get_packet(AVIOContext *s, AVPacket *pkt, int size)
Allocate and read the payload of a packet and initialize its fields with default values.
Definition: utils.c:98
mov_read_iinf
static int mov_read_iinf(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:9124
ff_read_string_to_bprint_overwrite
int64_t ff_read_string_to_bprint_overwrite(AVIOContext *s, struct AVBPrint *bp, int64_t max_len)
Read a whole null-terminated string of text from AVIOContext to an AVBPrint buffer overwriting its co...
Definition: aviobuf.c:863
AVStreamGroupTileGrid::horizontal
int horizontal
Offset in pixels from the left edge of the canvas where the tile should be placed.
Definition: avformat.h:995
get_stream_info_time
static int64_t get_stream_info_time(MOVFragmentStreamInfo *frag_stream_info)
Definition: mov.c:1700
MP4TrackKindValueMapping
Definition: isom.h:484
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:4109
AV_WB8
#define AV_WB8(p, d)
Definition: intreadwrite.h:392
MOVStreamContext::chunk_count
unsigned int chunk_count
Definition: isom.h:180
av_cmp_q
static int av_cmp_q(AVRational a, AVRational b)
Compare two rationals.
Definition: rational.h:89
MOVStreamContext::data_size
int64_t data_size
Definition: isom.h:235
AV_TIMECODE_FLAG_DROPFRAME
@ AV_TIMECODE_FLAG_DROPFRAME
timecode is drop frame
Definition: timecode.h:36
language
Undefined Behavior In the C language
Definition: undefined.txt:3
MOVStreamContext::ambient
AVAmbientViewingEnvironment * ambient
Definition: isom.h:271
mov_read_tmcd
static int mov_read_tmcd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6401
mov_chan.h
AVStream::disposition
int disposition
Stream disposition - a combination of AV_DISPOSITION_* flags.
Definition: avformat.h:813
MOVStreamContext::ambient_size
size_t ambient_size
Definition: isom.h:272
tag
uint32_t tag
Definition: movenc.c:2046
AVStream::id
int id
Format-specific stream ID.
Definition: avformat.h:756
ret
ret
Definition: filter_design.txt:187
AVStream
Stream structure.
Definition: avformat.h:744
AV_CODEC_ID_APV
@ AV_CODEC_ID_APV
Definition: codec_id.h:332
AV_LOG_FATAL
#define AV_LOG_FATAL
Something went wrong and recovery is not possible.
Definition: log.h:204
HEIFItem::extent_length
int64_t extent_length
Definition: isom.h:300
MOVEncryptionIndex::nb_encrypted_samples
unsigned int nb_encrypted_samples
Definition: isom.h:129
mov_read_senc
static int mov_read_senc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:7586
avio_seek
int64_t avio_seek(AVIOContext *s, int64_t offset, int whence)
fseek() equivalent for AVIOContext.
Definition: aviobuf.c:236
FFSWAP
#define FFSWAP(type, a, b)
Definition: macros.h:52
AVClass::class_name
const char * class_name
The name of the class; usually it is the same name as the context structure type to which the AVClass...
Definition: log.h:81
AVEncryptionInfo::key_id
uint8_t * key_id
The ID of the key used to encrypt the packet.
Definition: encryption_info.h:63
av_strlcat
size_t av_strlcat(char *dst, const char *src, size_t size)
Append the string src to the string dst, but to a total length of no more than size - 1 bytes,...
Definition: avstring.c:95
MOVStreamContext::stts_data
MOVStts * stts_data
Definition: isom.h:187
AVSphericalMapping::pitch
int32_t pitch
Rotation around the right vector [-90, 90].
Definition: spherical.h:145
AVStreamGroup::metadata
AVDictionary * metadata
Metadata that applies to the whole group.
Definition: avformat.h:1144
av_malloc
void * av_malloc(size_t size)
Allocate a memory block with alignment suitable for all memory accesses (including vectors if availab...
Definition: mem.c:98
avio_rb16
unsigned int avio_rb16(AVIOContext *s)
Definition: aviobuf.c:749
AVStereo3D::type
enum AVStereo3DType type
How views are packed within the video.
Definition: stereo3d.h:207
MOVSbgp::index
unsigned int index
Definition: isom.h:123
HEIFItem::icc_profile_size
size_t icc_profile_size
Definition: isom.h:310
MOVContext::chapter_tracks
int * chapter_tracks
Definition: isom.h:342
cdt2
static const int16_t cdt2[8]
Definition: truemotion1data.h:43
AVSTREAM_PARSE_HEADERS
@ AVSTREAM_PARSE_HEADERS
Only parse headers, do not repack.
Definition: avformat.h:590
pos
unsigned int pos
Definition: spdifenc.c:414
avformat.h
MOVFragment::implicit_offset
uint64_t implicit_offset
Definition: isom.h:106
dict.h
av_packet_side_data_new
AVPacketSideData * av_packet_side_data_new(AVPacketSideData **psd, int *pnb_sd, enum AVPacketSideDataType type, size_t size, int flags)
Allocate a new packet side data.
Definition: packet.c:694
AV_AUDIO_SERVICE_TYPE_KARAOKE
@ AV_AUDIO_SERVICE_TYPE_KARAOKE
Definition: defs.h:244
mov_read_dmlp
static int mov_read_dmlp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:8611
flag
#define flag(name)
Definition: cbs_av1.c:496
AV_INPUT_BUFFER_PADDING_SIZE
#define AV_INPUT_BUFFER_PADDING_SIZE
Definition: defs.h:40
MOVStreamContext::pseudo_stream_id
int pseudo_stream_id
-1 means demux all ids
Definition: isom.h:220
MOVContext::time_scale
int time_scale
Definition: isom.h:324
id
enum AVCodecID id
Definition: dts2pts.c:549
mov_read_tfdt
static int mov_read_tfdt(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5768
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:5484
search_frag_moof_offset
static int search_frag_moof_offset(MOVFragmentIndex *frag_index, int64_t offset)
Definition: mov.c:1676
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:11169
MOVContext::use_mfra_for
int use_mfra_for
Definition: isom.h:356
AVEncryptionInfo
This describes encryption info for a packet.
Definition: encryption_info.h:43
MOVStreamContext::encryption_index
MOVEncryptionIndex * encryption_index
Definition: isom.h:282
MIN_DATA_ENTRY_BOX_SIZE
#define MIN_DATA_ENTRY_BOX_SIZE
Definition: mov.c:637
AVStreamGroup
Definition: avformat.h:1097
av_get_media_type_string
const char * av_get_media_type_string(enum AVMediaType media_type)
Return a string describing the media_type enum, NULL if media_type is unknown.
Definition: utils.c:28
IAMFMixPresentation
Definition: iamf.h:107
AVStream::index
int index
stream index in AVFormatContext
Definition: avformat.h:750
avpriv_dv_init_demux
DVDemuxContext * avpriv_dv_init_demux(AVFormatContext *s)
Definition: dv.c:728
mov_seek_fragment
static int mov_seek_fragment(AVFormatContext *s, AVStream *st, int64_t timestamp)
Definition: mov.c:11534
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:2705
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:1112
get_frag_time
static int64_t get_frag_time(AVFormatContext *s, AVStream *dst_st, MOVFragmentIndex *frag_index, int index)
Definition: mov.c:1710
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:1151
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:3865
MOVFragment::moof_offset
uint64_t moof_offset
Definition: isom.h:105
AVIO_SEEKABLE_NORMAL
#define AVIO_SEEKABLE_NORMAL
Seeking works like for a local file.
Definition: avio.h:41
av_packet_new_side_data
uint8_t * av_packet_new_side_data(AVPacket *pkt, enum AVPacketSideDataType type, size_t size)
Allocate new information of a packet.
Definition: packet.c:231
buffer
the frame and frame reference mechanism is intended to as much as expensive copies of that data while still allowing the filters to produce correct results The data is stored in buffers represented by AVFrame structures Several references can point to the same frame buffer
Definition: filter_design.txt:49
mov_read_glbl
static int mov_read_glbl(MOVContext *c, AVIOContext *pb, MOVAtom atom)
This function reads atom content and puts data in extradata without tag nor size unlike mov_read_extr...
Definition: mov.c:2478
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:7244
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:124
AV_OPT_TYPE_INT
@ AV_OPT_TYPE_INT
Underlying C type is int.
Definition: opt.h:259
MOVContext::dv_fctx
AVFormatContext * dv_fctx
Definition: isom.h:335
av_channel_layout_uninit
void av_channel_layout_uninit(AVChannelLayout *channel_layout)
Free any allocated data in the channel layout and reset the channel count to 0.
Definition: channel_layout.c:442
AV_CODEC_ID_DVAUDIO
@ AV_CODEC_ID_DVAUDIO
Definition: codec_id.h:466
avformat_free_context
void avformat_free_context(AVFormatContext *s)
Free an AVFormatContext and all its streams.
Definition: avformat.c:144
MOVContext::aax_mode
unsigned int aax_mode
'aax' file has been detected
Definition: isom.h:361
mov_read_sv3d
static int mov_read_sv3d(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6766
avio_read
int avio_read(AVIOContext *s, unsigned char *buf, int size)
Read size bytes from AVIOContext into buf.
Definition: aviobuf.c:615
mov_aaxc_crypto
static int mov_aaxc_crypto(MOVContext *c)
Definition: mov.c:1516
mov_get_skip_samples
static int64_t mov_get_skip_samples(AVStream *st, int sample)
Definition: mov.c:11669
MOVFragmentIndex
Definition: isom.h:160
AV_RB8
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_WL16 uint64_t_TMPL AV_WB64 unsigned int_TMPL AV_WB32 unsigned int_TMPL AV_WB24 unsigned int_TMPL AV_WB16 unsigned int_TMPL AV_RB8
Definition: bytestream.h:99
ref
static int ref[MAX_W *MAX_W]
Definition: jpeg2000dwt.c:117
AVStream::r_frame_rate
AVRational r_frame_rate
Real base framerate of the stream.
Definition: avformat.h:878
MOVStreamContext::tts_count
unsigned int tts_count
Definition: isom.h:182
MOVStreamContext::track_end
int64_t track_end
used for dts generation in fragmented movie files
Definition: isom.h:238
MOVStreamContext::sgpd_sync_count
uint32_t sgpd_sync_count
Definition: isom.h:245
MOVContext::fragment
MOVFragment fragment
current fragment in moof atom
Definition: isom.h:337
AVIndexEntry::pos
int64_t pos
Definition: avformat.h:599
AVIOContext::eof_reached
int eof_reached
true if was unable to read due to error or eof
Definition: avio.h:238
mov_metadata_int8_bypass_padding
static int mov_metadata_int8_bypass_padding(MOVContext *c, AVIOContext *pb, unsigned len, const char *key)
Definition: mov.c:111
AVStreamGroupLCEVC::width
int width
Width of the final stream for presentation.
Definition: avformat.h:1079
MOVDref::type
uint32_t type
Definition: isom.h:86
samples
Filter the word “frame” indicates either a video frame or a group of audio samples
Definition: filter_design.txt:8
mean
static float mean(const float *input, int size)
Definition: vf_nnedi.c:861
mov_read_covr
static int mov_read_covr(MOVContext *c, AVIOContext *pb, int type, int len)
Definition: mov.c:231
MOVParseTableEntry::type
uint32_t type
Definition: mov.c:83
Windows::Graphics::DirectX::Direct3D11::p
IDirect3DDxgiInterfaceAccess _COM_Outptr_ void ** p
Definition: vsrc_gfxcapture_winrt.hpp:53
AVMasteringDisplayMetadata::min_luminance
AVRational min_luminance
Min luminance of mastering display (cd/m^2).
Definition: mastering_display_metadata.h:52
MOVStreamContext::per_sample_iv_size
unsigned int per_sample_iv_size
Definition: isom.h:280
ff_codec_movsubtitle_tags
const AVCodecTag ff_codec_movsubtitle_tags[]
Definition: isom.c:75
av_mul_q
AVRational av_mul_q(AVRational b, AVRational c)
Multiply two rationals.
Definition: rational.c:80
AVPacket::stream_index
int stream_index
Definition: packet.h:590
MOVFragmentIndexItem::nb_stream_info
int nb_stream_info
Definition: isom.h:156
avio_skip
int64_t avio_skip(AVIOContext *s, int64_t offset)
Skip given number of bytes forward.
Definition: aviobuf.c:321
export_orphan_timecode
static void export_orphan_timecode(AVFormatContext *s)
Definition: mov.c:10187
mov_read_sbas
static int mov_read_sbas(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2549
MOVStreamContext::has_sidx
int has_sidx
Definition: isom.h:276
AV_CH_FRONT_RIGHT
#define AV_CH_FRONT_RIGHT
Definition: channel_layout.h:176
av_aes_ctr_crypt
void av_aes_ctr_crypt(struct AVAESCTR *a, uint8_t *dst, const uint8_t *src, int count)
Process a buffer using a previously initialized context.
Definition: aes_ctr.c:102
mov_metadata_gnre
static int mov_metadata_gnre(MOVContext *c, AVIOContext *pb, unsigned len, const char *key)
Definition: mov.c:134
AV_PKT_DATA_ENCRYPTION_INFO
@ AV_PKT_DATA_ENCRYPTION_INFO
This side data contains encryption info for how to decrypt the packet.
Definition: packet.h:252
MOV_MERGE_CTTS
#define MOV_MERGE_CTTS
Definition: mov.c:4639
FFStream::index_entries
AVIndexEntry * index_entries
Only used if the format does not support seeking natively.
Definition: internal.h:184
av_dict_set_int
int av_dict_set_int(AVDictionary **pm, const char *key, int64_t value, int flags)
Convenience wrapper for av_dict_set() that converts the value to a string and stores it.
Definition: dict.c:177
mov_read_dpxe
static int mov_read_dpxe(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2303
AVIAMFSubmix::nb_elements
unsigned int nb_elements
Number of elements in the submix.
Definition: iamf.h:575
MOVFragmentStreamInfo::id
int id
Definition: isom.h:140
AVIO_FLAG_READ
#define AVIO_FLAG_READ
read-only
Definition: avio.h:617
AV_PKT_DATA_AUDIO_SERVICE_TYPE
@ AV_PKT_DATA_AUDIO_SERVICE_TYPE
This side data should be associated with an audio stream and corresponds to enum AVAudioServiceType.
Definition: packet.h:117
av_spherical_alloc
AVSphericalMapping * av_spherical_alloc(size_t *size)
Allocate a AVSphericalVideo structure and initialize its fields to default values.
Definition: spherical.c:26
AV_OPT_FLAG_DECODING_PARAM
#define AV_OPT_FLAG_DECODING_PARAM
A generic parameter which can be set by the user for demuxing or decoding.
Definition: opt.h:356
mov_read_rtmd_track
static int mov_read_rtmd_track(AVFormatContext *s, AVStream *st)
Definition: mov.c:9969
AVMEDIA_TYPE_VIDEO
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:200
read_probe
static int read_probe(const AVProbeData *p)
Definition: cdg.c:30
MOVStreamContext::pb_is_copied
int pb_is_copied
Definition: isom.h:176
AV_CODEC_ID_PCM_S32LE
@ AV_CODEC_ID_PCM_S32LE
Definition: codec_id.h:346
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:10581
mem.h
AVStreamGroup::type
enum AVStreamGroupParamsType type
Group type.
Definition: avformat.h:1124
MOVElst::time
int64_t time
Definition: isom.h:81
AVBufferRef
A reference to a data buffer.
Definition: buffer.h:82
HEIFGrid
Definition: isom.h:313
mov_read_iref_dimg
static int mov_read_iref_dimg(MOVContext *c, AVIOContext *pb, int version)
Definition: mov.c:9178
mov_read_pcmc
static int mov_read_pcmc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2032
build_open_gop_key_points
static int build_open_gop_key_points(AVStream *st)
Definition: mov.c:4576
mov_parse_stsd_audio
static void mov_parse_stsd_audio(MOVContext *c, AVIOContext *pb, AVStream *st, MOVStreamContext *sc)
Definition: mov.c:2769
IAMFContext::mix_presentations
IAMFMixPresentation ** mix_presentations
Definition: iamf.h:133
AV_CODEC_ID_PCM_U8
@ AV_CODEC_ID_PCM_U8
Definition: codec_id.h:343
MOVContext::trak_index
int trak_index
Index of the current 'trak'.
Definition: isom.h:331
mov_read_timecode_track
static int mov_read_timecode_track(AVFormatContext *s, AVStream *st)
Definition: mov.c:9995
HEIFGrid::item
HEIFItem * item
Definition: isom.h:314
AVSphericalMapping::bound_left
uint32_t bound_left
Distance from the left edge.
Definition: spherical.h:185
mov_read_mac_string
static int mov_read_mac_string(MOVContext *c, AVIOContext *pb, int len, char *dst, int dstlen)
Definition: mov.c:169
MOVEncryptionIndex::auxiliary_info_sizes
uint8_t * auxiliary_info_sizes
Definition: isom.h:132
MOVFragment::stsd_id
unsigned stsd_id
Definition: isom.h:107
AVCodecParameters::video_delay
int video_delay
Video only.
Definition: codec_par.h:175
HEIFGrid::tile_id_list
int16_t * tile_id_list
Definition: isom.h:316
avpriv_request_sample
#define avpriv_request_sample(...)
Definition: tableprint_vlc.h:37
MOVStreamContext::tts_data
MOVTimeToSample * tts_data
Definition: isom.h:184
map
const VDPAUPixFmtMap * map
Definition: hwcontext_vdpau.c:71
avformat_stream_group_create
AVStreamGroup * avformat_stream_group_create(AVFormatContext *s, enum AVStreamGroupParamsType type, AVDictionary **options)
Add a new empty stream group to a media file.
Definition: options.c:440
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:361
AVStreamGroupTileGrid::height
int height
Height of the final image for presentation.
Definition: avformat.h:1046
AVStereo3D::view
enum AVStereo3DView view
Determines which views are packed.
Definition: stereo3d.h:217
read_tfra
static int read_tfra(MOVContext *mov, AVIOContext *f)
Definition: mov.c:10205
av_free
#define av_free(p)
Definition: tableprint_vlc.h:34
AVDictionaryEntry
Definition: dict.h:90
av_add_q
AVRational av_add_q(AVRational b, AVRational c)
Add two rationals.
Definition: rational.c:93
AVCodecParameters::codec_id
enum AVCodecID codec_id
Specific type of the encoded data (the codec used).
Definition: codec_par.h:55
AVStereo3DView
AVStereo3DView
List of possible view types.
Definition: stereo3d.h:149
AVPacket
This structure stores compressed data.
Definition: packet.h:565
AVContentLightMetadata::MaxFALL
unsigned MaxFALL
Max average light level per frame (cd/m^2).
Definition: mastering_display_metadata.h:116
mov_parse_lcevc_streams
static int mov_parse_lcevc_streams(AVFormatContext *s)
Definition: mov.c:10801
mov_read_hfov
static int mov_read_hfov(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:7215
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:378
MOVContext::nb_heif_item
int nb_heif_item
Definition: isom.h:383
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:35
av_dict_set
int av_dict_set(AVDictionary **pm, const char *key, const char *value, int flags)
Set the given entry in *pm, overwriting an existing entry.
Definition: dict.c:86
riff.h
av_dict_copy
int av_dict_copy(AVDictionary **dst, const AVDictionary *src, int flags)
Copy entries from one AVDictionary struct into another.
Definition: dict.c:247
av_encryption_info_alloc
AVEncryptionInfo * av_encryption_info_alloc(uint32_t subsample_count, uint32_t key_id_size, uint32_t iv_size)
Allocates an AVEncryptionInfo structure and sub-pointers to hold the given number of subsamples.
Definition: encryption_info.c:41
AVPacket::pos
int64_t pos
byte position in stream, -1 if unknown
Definition: packet.h:608
FFInputFormat
Definition: demux.h:66
MOVContext::decryption_keys
AVDictionary * decryption_keys
Definition: isom.h:388
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:6976
AV_CODEC_ID_ILBC
@ AV_CODEC_ID_ILBC
Definition: codec_id.h:519
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:414
MOVStreamContext::tmcd_flags
uint32_t tmcd_flags
tmcd track flags
Definition: isom.h:236
int32_t
int32_t
Definition: audioconvert.c:56
HEIFItem::rotation
int rotation
Definition: isom.h:304
MOVAtom::type
uint32_t type
Definition: isom.h:95
distance
static float distance(float x, float y, int band)
Definition: nellymoserenc.c:231
AVSTREAM_PARSE_FULL
@ AVSTREAM_PARSE_FULL
full parsing and repack
Definition: avformat.h:589
parse_timecode_in_framenum_format
static int parse_timecode_in_framenum_format(AVFormatContext *s, AVStream *st, int64_t value, int flags)
Definition: mov.c:9955
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:449
replaygain.h
MOVFragmentIndexItem::headers_read
int headers_read
Definition: isom.h:154
AV_CODEC_ID_VP8
@ AV_CODEC_ID_VP8
Definition: codec_id.h:192
AVERROR_BUG
#define AVERROR_BUG
Internal bug, also see AVERROR_BUG2.
Definition: error.h:52
MOVStreamContext::start_pad
int start_pad
amount of samples to skip due to enc-dec delay
Definition: isom.h:239
MP4TrackKindValueMapping::value
const char * value
Definition: isom.h:486
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:359
ff_mov_demuxer
const FFInputFormat ff_mov_demuxer
Definition: mov.c:11805
AVCodecParameters::bit_rate
int64_t bit_rate
The average bitrate of the encoded data (in bits per second).
Definition: codec_par.h:97
MOVStts::count
unsigned int count
Definition: isom.h:64
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
MOVStreamContext::display_matrix
int32_t * display_matrix
Definition: isom.h:262
MOVContext::heif_grid
HEIFGrid * heif_grid
Definition: isom.h:384
MOVStreamContext::min_sample_duration
uint32_t min_sample_duration
Definition: isom.h:250
MOVStreamContext::current_index
int64_t current_index
Definition: isom.h:214
AVERROR_INVALIDDATA
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:61
ff_mov_track_kind_table
const struct MP4TrackKindMapping ff_mov_track_kind_table[]
Definition: isom.c:451
get_curr_st
static AVStream * get_curr_st(MOVContext *c)
Get the current stream in the parsing process.
Definition: mov.c:213
MOVStreamContext::stts_allocated_size
unsigned int stts_allocated_size
Definition: isom.h:186
MOVFragmentStreamInfo::index_entry
int index_entry
Definition: isom.h:147
cenc_decrypt
static int cenc_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
Definition: mov.c:8451
MOVStreamContext::format
uint32_t format
Definition: isom.h:274
MKTAG
#define MKTAG(a, b, c, d)
Definition: macros.h:55
ffio_read_size
int ffio_read_size(AVIOContext *s, unsigned char *buf, int size)
Read size bytes from AVIOContext into buf.
Definition: aviobuf.c:665
MOVStreamContext::sync_group_count
unsigned int sync_group_count
Definition: isom.h:242
MOVContext::bitrates_count
int bitrates_count
Definition: isom.h:354
AV_CODEC_ID_VORBIS
@ AV_CODEC_ID_VORBIS
Definition: codec_id.h:465
AVDictionaryEntry::value
char * value
Definition: dict.h:92
AVStream::start_time
int64_t start_time
Decoding: pts of the first frame of the stream in presentation order, in stream time base.
Definition: avformat.h:793
MOVStreamContext::id
int id
AVStream id.
Definition: isom.h:177
MOVStreamContext::samples_per_frame
unsigned int samples_per_frame
Definition: isom.h:218
MOVStreamContext::tts_allocated_size
unsigned int tts_allocated_size
Definition: isom.h:183
pkt
static AVPacket * pkt
Definition: demux_decode.c:55
MOVElst::duration
int64_t duration
Definition: isom.h:80
ac3tab.h
avstring.h
mov_read_ispe
static int mov_read_ispe(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:9338
width
#define width
Definition: dsp.h:89
AVAmbientViewingEnvironment::ambient_light_y
AVRational ambient_light_y
Normalized y chromaticity coordinate of the environmental ambient light in the nominal viewing enviro...
Definition: ambient_viewing_environment.h:54
mov_read_iref
static int mov_read_iref(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:9293
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:1274
mov_read_mfra
static int mov_read_mfra(MOVContext *c, AVIOContext *f)
Definition: mov.c:10260
AV_CODEC_ID_FLV1
@ AV_CODEC_ID_FLV1
Definition: codec_id.h:73
mov_metadata_int8_no_padding
static int mov_metadata_int8_no_padding(MOVContext *c, AVIOContext *pb, unsigned len, const char *key)
Definition: mov.c:125
flac.h
AVStreamGroupTileGrid::idx
unsigned int idx
Index of the stream in the group this tile references.
Definition: avformat.h:990
AVTimecode
Definition: timecode.h:41
get_frag_stream_info
static MOVFragmentStreamInfo * get_frag_stream_info(MOVFragmentIndex *frag_index, int index, int id)
Definition: mov.c:1621
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:8715
MOVContext::heif_item
HEIFItem ** heif_item
Definition: isom.h:382
MOVStreamContext::stts_count
unsigned int stts_count
Definition: isom.h:185
MOV_TRUN_SAMPLE_CTS
#define MOV_TRUN_SAMPLE_CTS
Definition: isom.h:416
HEIFItem::iref_list
HEIFItemRef * iref_list
Definition: isom.h:296
AV_OPT_TYPE_CONST
@ AV_OPT_TYPE_CONST
Special option type for declaring named constants.
Definition: opt.h:299
MOV_ISMV_TTML_TAG
#define MOV_ISMV_TTML_TAG
Definition: isom.h:479
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:351
mov_read_st3d
static int mov_read_st3d(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6638
mov_read_imir
static int mov_read_imir(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:9380
is_open_key_sample
static int is_open_key_sample(const MOVStreamContext *sc, int sample)
Definition: mov.c:11553
mov_read_dvc1
static int mov_read_dvc1(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2524
MOVStreamContext::elst_count
unsigned int elst_count
Definition: isom.h:200
av_color_transfer_name
const char * av_color_transfer_name(enum AVColorTransferCharacteristic transfer)
Definition: pixdesc.c:3823
AVChannelCustom::id
enum AVChannel id
Definition: channel_layout.h:284
mov_read_atom_into_extradata
static int64_t mov_read_atom_into_extradata(MOVContext *c, AVIOContext *pb, MOVAtom atom, AVCodecParameters *par, uint8_t *buf)
Definition: mov.c:2240
AV_WL16A
#define AV_WL16A(p, v)
Definition: intreadwrite.h:557
AV_RB64
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_WL16 uint64_t_TMPL AV_RB64
Definition: bytestream.h:95
AVSphericalMapping::yaw
int32_t yaw
Rotation around the up vector [-180, 180].
Definition: spherical.h:144
src
#define src
Definition: vp8dsp.c:248
mov_read_chapters
static void mov_read_chapters(AVFormatContext *s)
Definition: mov.c:9856
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
duration
static int64_t duration
Definition: ffplay.c:329
MOVContext::cur_item_id
int cur_item_id
Definition: isom.h:381
av_timecode_make_string
char * av_timecode_make_string(const AVTimecode *tc, char *buf, int framenum_arg)
Load timecode string in buf.
Definition: timecode.c:104
AVFMT_EVENT_FLAG_METADATA_UPDATED
#define AVFMT_EVENT_FLAG_METADATA_UPDATED
Definition: avformat.h:1637
AV_DICT_DONT_STRDUP_KEY
#define AV_DICT_DONT_STRDUP_KEY
Take ownership of a key that's been allocated with av_malloc() or another memory allocation function.
Definition: dict.h:77
MOVContext::next_root_atom
int64_t next_root_atom
offset of the next root atom
Definition: isom.h:350
MOVContext::found_iinf
int found_iinf
'iinf' atom has been found
Definition: isom.h:328
MOVContext::meta_keys_count
unsigned meta_keys_count
Definition: isom.h:333
avcodec_parameters_copy
int avcodec_parameters_copy(AVCodecParameters *dst, const AVCodecParameters *src)
Copy the contents of src to dst.
Definition: codec_par.c:107
iamf_reader.h
AVStreamGroupTileGrid::background
uint8_t background[4]
The pixel value per channel in RGBA format used if no pixel of any tile is located at a particular pi...
Definition: avformat.h:1010
MOVStreamContext::palette
uint32_t palette[256]
Definition: isom.h:233
cenc_scheme_decrypt
static int cenc_scheme_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
Definition: mov.c:8183
MOVFragment::track_id
unsigned track_id
Definition: isom.h:103
mov_read_hdlr
static int mov_read_hdlr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:782
mov_parse_stsd_data
static int mov_parse_stsd_data(MOVContext *c, AVIOContext *pb, AVStream *st, MOVStreamContext *sc, int64_t size)
Definition: mov.c:2906
AV_CH_SIDE_LEFT
#define AV_CH_SIDE_LEFT
Definition: channel_layout.h:184
ff_iamf_read_deinit
void ff_iamf_read_deinit(IAMFDemuxContext *c)
Definition: iamf_reader.c:371
AV_CODEC_ID_PRORES
@ AV_CODEC_ID_PRORES
Definition: codec_id.h:200
AV_RB16
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_WL16 uint64_t_TMPL AV_WB64 unsigned int_TMPL AV_WB32 unsigned int_TMPL AV_WB24 unsigned int_TMPL AV_RB16
Definition: bytestream.h:98
av_realloc
void * av_realloc(void *ptr, size_t size)
Allocate, reallocate, or free a block of memory.
Definition: mem.c:155
av_encryption_init_info_add_side_data
uint8_t * av_encryption_init_info_add_side_data(const AVEncryptionInitInfo *info, size_t *side_data_size)
Allocates and initializes side data that holds a copy of the given encryption init info.
Definition: encryption_info.c:292
av_fourcc2str
#define av_fourcc2str(fourcc)
Definition: avutil.h:347
ff_mov_read_chan
int ff_mov_read_chan(AVFormatContext *s, AVIOContext *pb, AVStream *st, int64_t size)
Read 'chan' tag from the input stream.
Definition: mov_chan.c:524
av_index_search_timestamp
int av_index_search_timestamp(AVStream *st, int64_t timestamp, int flags)
Get the index for a specific timestamp.
Definition: seek.c:245
mov_read_pitm
static int mov_read_pitm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:8939
MOVContext::ignore_chapters
int ignore_chapters
Definition: isom.h:348
MOVTimeToSample::offset
int offset
Definition: isom.h:60
mov_read_dac3
static int mov_read_dac3(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:853
MP4TrackKindMapping
Definition: isom.h:489
ff_alloc_extradata
int ff_alloc_extradata(AVCodecParameters *par, int size)
Allocate extradata with additional AV_INPUT_BUFFER_PADDING_SIZE at end which is always set to 0.
Definition: utils.c:237
HEIFItem::nb_iref_list
int nb_iref_list
Definition: isom.h:297
AV_DISPOSITION_NON_DIEGETIC
#define AV_DISPOSITION_NON_DIEGETIC
The stream is intended to be mixed with a spatial audio track.
Definition: avformat.h:682
avio_feof
int avio_feof(AVIOContext *s)
Similar to feof() but also returns nonzero on read errors.
Definition: aviobuf.c:349
mc
#define mc
Definition: vf_colormatrix.c:100
MOVStreamContext::ffindex
int ffindex
AVStream index.
Definition: isom.h:178
HEIFItem::extent_offset
int64_t extent_offset
Definition: isom.h:301
mov_read_stsz
static int mov_read_stsz(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:3466