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  ret = ff_alloc_extradata(st->codecpar, descriptors_size);
936  if (ret < 0)
937  return ret;
938 
939  ret = avio_read(pb, st->codecpar->extradata, descriptors_size);
940  if (ret != descriptors_size)
941  return ret < 0 ? ret : AVERROR_INVALIDDATA;
942 
943  ffio_init_read_context(&b, st->codecpar->extradata, descriptors_size);
944  descriptor_pb = &b.pub;
945 
946  ret = ff_iamfdec_read_descriptors(iamf, descriptor_pb, descriptors_size, c->fc);
947  if (ret < 0)
948  return ret;
949 
950  metadata = st->metadata;
951  st->metadata = NULL;
952  start_time = st->start_time;
953  nb_frames = st->nb_frames;
954  duration = st->duration;
955  disposition = st->disposition;
956 
957  for (int i = 0; i < iamf->nb_audio_elements; i++) {
958  IAMFAudioElement *audio_element = iamf->audio_elements[i];
959  const AVIAMFAudioElement *element;
960  AVStreamGroup *stg =
962 
963  if (!stg) {
964  ret = AVERROR(ENOMEM);
965  goto fail;
966  }
967 
969  stg->id = audio_element->audio_element_id;
970  /* Transfer ownership */
971  element = stg->params.iamf_audio_element = audio_element->element;
972  audio_element->element = NULL;
973 
974  for (int j = 0; j < audio_element->nb_substreams; j++) {
975  IAMFSubStream *substream = &audio_element->substreams[j];
976  AVStream *stream;
977 
978  if (!i && !j) {
979  if (audio_element->layers[0].substream_count != 1)
980  disposition &= ~AV_DISPOSITION_DEFAULT;
981  stream = st;
982  } else
983  stream = avformat_new_stream(c->fc, NULL);
984  if (!stream) {
985  ret = AVERROR(ENOMEM);
986  goto fail;
987  }
988 
989  stream->start_time = start_time;
990  stream->nb_frames = nb_frames;
991  stream->duration = duration;
992  stream->disposition = disposition;
993  if (stream != st) {
994  stream->priv_data = sc;
995  sc->refcount++;
996  }
997 
1000  if (i || j) {
1002  if (audio_element->layers[0].substream_count == 1)
1003  stream->disposition &= ~AV_DISPOSITION_DEFAULT;
1004  }
1005 
1006  ret = avcodec_parameters_copy(stream->codecpar, substream->codecpar);
1007  if (ret < 0)
1008  goto fail;
1009 
1010  stream->id = substream->audio_substream_id;
1011 
1012  avpriv_set_pts_info(st, 64, 1, sc->time_scale);
1013 
1014  ret = avformat_stream_group_add_stream(stg, stream);
1015  if (ret < 0)
1016  goto fail;
1017  }
1018 
1019  ret = av_dict_copy(&stg->metadata, metadata, 0);
1020  if (ret < 0)
1021  goto fail;
1022  }
1023 
1024  for (int i = 0; i < iamf->nb_mix_presentations; i++) {
1025  IAMFMixPresentation *mix_presentation = iamf->mix_presentations[i];
1026  const AVIAMFMixPresentation *mix = mix_presentation->cmix;
1027  AVStreamGroup *stg =
1029 
1030  if (!stg) {
1031  ret = AVERROR(ENOMEM);
1032  goto fail;
1033  }
1034 
1036  stg->id = mix_presentation->mix_presentation_id;
1037  /* Transfer ownership */
1038  stg->params.iamf_mix_presentation = mix_presentation->mix;
1039  mix_presentation->mix = NULL;
1040 
1041  for (int j = 0; j < mix->nb_submixes; j++) {
1042  const AVIAMFSubmix *submix = mix->submixes[j];
1043 
1044  for (int k = 0; k < submix->nb_elements; k++) {
1045  const AVIAMFSubmixElement *submix_element = submix->elements[k];
1046  const AVStreamGroup *audio_element = NULL;
1047 
1048  for (int l = 0; l < c->fc->nb_stream_groups; l++)
1049  if (c->fc->stream_groups[l]->type == AV_STREAM_GROUP_PARAMS_IAMF_AUDIO_ELEMENT &&
1050  c->fc->stream_groups[l]->id == submix_element->audio_element_id) {
1051  audio_element = c->fc->stream_groups[l];
1052  break;
1053  }
1054  av_assert0(audio_element);
1055 
1056  for (int l = 0; l < audio_element->nb_streams; l++) {
1057  ret = avformat_stream_group_add_stream(stg, audio_element->streams[l]);
1058  if (ret < 0 && ret != AVERROR(EEXIST))
1059  goto fail;
1060  }
1061  }
1062  }
1063 
1064  ret = av_dict_copy(&stg->metadata, metadata, 0);
1065  if (ret < 0)
1066  goto fail;
1067  }
1068 
1069  ret = 0;
1070 fail:
1072 
1073  return ret;
1074 }
1075 #endif
1076 
1078 {
1079  AVStream *st;
1080  int32_t sample_rate;
1081 
1082  if (atom.size < 8 || c->fc->nb_streams < 1)
1083  return 0;
1084 
1085  st = c->fc->streams[c->fc->nb_streams-1];
1086  if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO) {
1087  av_log(c->fc, AV_LOG_WARNING, "'srat' within non-audio sample entry, skip\n");
1088  return 0;
1089  }
1090 
1091  if (!c->isom) {
1092  av_log(c->fc, AV_LOG_WARNING, "'srat' within non-isom, skip\n");
1093  return 0;
1094  }
1095 
1096  avio_skip(pb, 4); // version+flags
1097  sample_rate = avio_rb32(pb);
1098  if (sample_rate > 0) {
1099  av_log(c->fc, AV_LOG_DEBUG,
1100  "overwrite sample rate from %d to %d by 'srat'\n",
1101  st->codecpar->sample_rate, sample_rate);
1102  st->codecpar->sample_rate = sample_rate;
1103  } else {
1104  av_log(c->fc, AV_LOG_WARNING,
1105  "ignore invalid sample rate %d in 'srat'\n", sample_rate);
1106  }
1107 
1108  return 0;
1109 }
1110 
1112 {
1113  AVStream *st;
1114  AVPacketSideData *sd;
1115  enum AVAudioServiceType *ast;
1116  int eac3info, acmod, lfeon, bsmod;
1117  uint64_t mask;
1118 
1119  if (c->fc->nb_streams < 1)
1120  return 0;
1121  st = c->fc->streams[c->fc->nb_streams-1];
1122 
1126  sizeof(*ast), 0);
1127  if (!sd)
1128  return AVERROR(ENOMEM);
1129 
1130  ast = (enum AVAudioServiceType*)sd->data;
1131 
1132  /* No need to parse fields for additional independent substreams and its
1133  * associated dependent substreams since libavcodec's E-AC-3 decoder
1134  * does not support them yet. */
1135  avio_rb16(pb); /* data_rate and num_ind_sub */
1136  eac3info = avio_rb24(pb);
1137  bsmod = (eac3info >> 12) & 0x1f;
1138  acmod = (eac3info >> 9) & 0x7;
1139  lfeon = (eac3info >> 8) & 0x1;
1140 
1142  if (lfeon)
1146 
1147  *ast = bsmod;
1148  if (st->codecpar->ch_layout.nb_channels > 1 && bsmod == 0x7)
1150 
1151  return 0;
1152 }
1153 
1155 {
1156 #define DDTS_SIZE 20
1157  uint8_t buf[DDTS_SIZE + AV_INPUT_BUFFER_PADDING_SIZE];
1158  AVStream *st = NULL;
1159  uint32_t frame_duration_code = 0;
1160  uint32_t channel_layout_code = 0;
1161  GetBitContext gb;
1162  int ret;
1163 
1164  if ((ret = ffio_read_size(pb, buf, DDTS_SIZE)) < 0)
1165  return ret;
1166 
1167  init_get_bits(&gb, buf, 8 * DDTS_SIZE);
1168 
1169  if (c->fc->nb_streams < 1) {
1170  return 0;
1171  }
1172  st = c->fc->streams[c->fc->nb_streams-1];
1173 
1174  st->codecpar->sample_rate = get_bits_long(&gb, 32);
1175  if (st->codecpar->sample_rate <= 0) {
1176  av_log(c->fc, AV_LOG_ERROR, "Invalid sample rate %d\n", st->codecpar->sample_rate);
1177  return AVERROR_INVALIDDATA;
1178  }
1179  skip_bits_long(&gb, 32); /* max bitrate */
1180  st->codecpar->bit_rate = get_bits_long(&gb, 32);
1181  st->codecpar->bits_per_coded_sample = get_bits(&gb, 8);
1182  frame_duration_code = get_bits(&gb, 2);
1183  skip_bits(&gb, 30); /* various fields */
1184  channel_layout_code = get_bits(&gb, 16);
1185 
1186  st->codecpar->frame_size =
1187  (frame_duration_code == 0) ? 512 :
1188  (frame_duration_code == 1) ? 1024 :
1189  (frame_duration_code == 2) ? 2048 :
1190  (frame_duration_code == 3) ? 4096 : 0;
1191 
1192  if (channel_layout_code > 0xff) {
1193  av_log(c->fc, AV_LOG_WARNING, "Unsupported DTS audio channel layout\n");
1194  }
1197  ((channel_layout_code & 0x1) ? AV_CH_FRONT_CENTER : 0) |
1198  ((channel_layout_code & 0x2) ? AV_CH_FRONT_LEFT : 0) |
1199  ((channel_layout_code & 0x2) ? AV_CH_FRONT_RIGHT : 0) |
1200  ((channel_layout_code & 0x4) ? AV_CH_SIDE_LEFT : 0) |
1201  ((channel_layout_code & 0x4) ? AV_CH_SIDE_RIGHT : 0) |
1202  ((channel_layout_code & 0x8) ? AV_CH_LOW_FREQUENCY : 0));
1203 
1204  return 0;
1205 }
1206 
1208 {
1209  AVStream *st;
1210 
1211  if (c->fc->nb_streams < 1)
1212  return 0;
1213  st = c->fc->streams[c->fc->nb_streams-1];
1214 
1215  if (atom.size < 16)
1216  return 0;
1217 
1218  /* skip version and flags */
1219  avio_skip(pb, 4);
1220 
1221  ff_mov_read_chan(c->fc, pb, st, atom.size - 4);
1222 
1223  return 0;
1224 }
1225 
1227 {
1228  int64_t end = av_sat_add64(avio_tell(pb), atom.size);
1229  int version, flags;
1230  int ret;
1231  AVStream *st;
1232 
1233  if (c->fc->nb_streams < 1)
1234  return 0;
1235  st = c->fc->streams[c->fc->nb_streams-1];
1236 
1237  version = avio_r8(pb);
1238  flags = avio_rb24(pb);
1239  if (version != 0 || flags != 0) {
1240  av_log(c->fc, AV_LOG_ERROR,
1241  "Unsupported 'chnl' box with version %d, flags: %#x",
1242  version, flags);
1243  return AVERROR_INVALIDDATA;
1244  }
1245 
1246  ret = ff_mov_read_chnl(c->fc, pb, st);
1247  if (ret < 0)
1248  return ret;
1249 
1250  if (avio_tell(pb) != end) {
1251  av_log(c->fc, AV_LOG_WARNING, "skip %" PRId64 " bytes of unknown data inside chnl\n",
1252  end - avio_tell(pb));
1253  avio_seek(pb, end, SEEK_SET);
1254  }
1255  return ret;
1256 }
1257 
1259 {
1260  AVStream *st;
1261  int ret;
1262 
1263  if (c->fc->nb_streams < 1)
1264  return 0;
1265  st = c->fc->streams[c->fc->nb_streams-1];
1266 
1267  if ((ret = ff_get_wav_header(c->fc, pb, st->codecpar, atom.size, 0)) < 0)
1268  av_log(c->fc, AV_LOG_WARNING, "get_wav_header failed\n");
1269 
1270  return ret;
1271 }
1272 
1274 {
1275  AVStream *st;
1276  HEIFItem *item;
1277  AVPacketSideData *sd;
1278  int width, height, err = 0;
1279  AVRational aperture_width, aperture_height, horiz_off, vert_off;
1280  AVRational pc_x, pc_y;
1281  uint64_t top, bottom, left, right;
1282 
1283  item = get_heif_item(c, c->cur_item_id);
1284  st = get_curr_st(c);
1285  if (!st)
1286  return 0;
1287 
1288  width = st->codecpar->width;
1289  height = st->codecpar->height;
1290  if ((!width || !height) && item) {
1291  width = item->width;
1292  height = item->height;
1293  }
1294  if (!width || !height) {
1295  err = AVERROR_INVALIDDATA;
1296  goto fail;
1297  }
1298 
1299  aperture_width.num = avio_rb32(pb);
1300  aperture_width.den = avio_rb32(pb);
1301  aperture_height.num = avio_rb32(pb);
1302  aperture_height.den = avio_rb32(pb);
1303 
1304  horiz_off.num = avio_rb32(pb);
1305  horiz_off.den = avio_rb32(pb);
1306  vert_off.num = avio_rb32(pb);
1307  vert_off.den = avio_rb32(pb);
1308 
1309  if (aperture_width.num < 0 || aperture_width.den < 0 ||
1310  aperture_height.num < 0 || aperture_height.den < 0 ||
1311  horiz_off.den < 0 || vert_off.den < 0) {
1312  err = AVERROR_INVALIDDATA;
1313  goto fail;
1314  }
1315  if ((av_cmp_q((AVRational) { width, 1 }, aperture_width) < 0) ||
1316  (av_cmp_q((AVRational) { height, 1 }, aperture_height) < 0)) {
1317  err = AVERROR_INVALIDDATA;
1318  goto fail;
1319  }
1320  av_log(c->fc, AV_LOG_TRACE, "clap: apertureWidth %d/%d, apertureHeight %d/%d "
1321  "horizOff %d/%d vertOff %d/%d\n",
1322  aperture_width.num, aperture_width.den, aperture_height.num, aperture_height.den,
1323  horiz_off.num, horiz_off.den, vert_off.num, vert_off.den);
1324 
1325  pc_x = av_mul_q((AVRational) { width - 1, 1 }, (AVRational) { 1, 2 });
1326  pc_x = av_add_q(pc_x, horiz_off);
1327  pc_y = av_mul_q((AVRational) { height - 1, 1 }, (AVRational) { 1, 2 });
1328  pc_y = av_add_q(pc_y, vert_off);
1329 
1330  aperture_width = av_sub_q(aperture_width, (AVRational) { 1, 1 });
1331  aperture_width = av_mul_q(aperture_width, (AVRational) { 1, 2 });
1332  aperture_height = av_sub_q(aperture_height, (AVRational) { 1, 1 });
1333  aperture_height = av_mul_q(aperture_height, (AVRational) { 1, 2 });
1334 
1335  left = av_q2d(av_sub_q(pc_x, aperture_width));
1336  right = av_q2d(av_add_q(pc_x, aperture_width));
1337  top = av_q2d(av_sub_q(pc_y, aperture_height));
1338  bottom = av_q2d(av_add_q(pc_y, aperture_height));
1339 
1340  if (bottom > (height - 1) ||
1341  right > (width - 1)) {
1342  err = AVERROR_INVALIDDATA;
1343  goto fail;
1344  }
1345 
1346  bottom = height - 1 - bottom;
1347  right = width - 1 - right;
1348 
1349  if (!(left | right | top | bottom))
1350  return 0;
1351 
1352  if ((left + right) >= width ||
1353  (top + bottom) >= height) {
1354  err = AVERROR_INVALIDDATA;
1355  goto fail;
1356  }
1357 
1361  sizeof(uint32_t) * 4, 0);
1362  if (!sd)
1363  return AVERROR(ENOMEM);
1364 
1365  AV_WL32A(sd->data, top);
1366  AV_WL32A(sd->data + 4, bottom);
1367  AV_WL32A(sd->data + 8, left);
1368  AV_WL32A(sd->data + 12, right);
1369 
1370 fail:
1371  if (err < 0) {
1372  int explode = !!(c->fc->error_recognition & AV_EF_EXPLODE);
1373  av_log(c->fc, explode ? AV_LOG_ERROR : AV_LOG_WARNING, "Invalid clap box\n");
1374  if (!explode)
1375  err = 0;
1376  }
1377 
1378  return err;
1379 }
1380 
1381 /* This atom overrides any previously set aspect ratio */
1383 {
1384  const int num = avio_rb32(pb);
1385  const int den = avio_rb32(pb);
1386  AVStream *st;
1387  MOVStreamContext *sc;
1388 
1389  if (c->fc->nb_streams < 1)
1390  return 0;
1391  st = c->fc->streams[c->fc->nb_streams-1];
1392  sc = st->priv_data;
1393 
1394  av_log(c->fc, AV_LOG_TRACE, "pasp: hSpacing %d, vSpacing %d\n", num, den);
1395 
1396  if (den != 0) {
1397  sc->h_spacing = num;
1398  sc->v_spacing = den;
1399  }
1400  return 0;
1401 }
1402 
1403 /* this atom contains actual media data */
1405 {
1406  if (atom.size == 0) /* wrong one (MP4) */
1407  return 0;
1408  c->found_mdat=1;
1409  return 0; /* now go for moov */
1410 }
1411 
1412 #define DRM_BLOB_SIZE 56
1413 
1415 {
1416  uint8_t intermediate_key[20];
1417  uint8_t intermediate_iv[20];
1418  uint8_t input[64];
1419  uint8_t output[64];
1420  uint8_t file_checksum[20];
1421  uint8_t calculated_checksum[20];
1422  char checksum_string[2 * sizeof(file_checksum) + 1];
1423  struct AVSHA *sha;
1424  int i;
1425  int ret = 0;
1426  uint8_t *activation_bytes = c->activation_bytes;
1427  uint8_t *fixed_key = c->audible_fixed_key;
1428 
1429  c->aax_mode = 1;
1430 
1431  sha = av_sha_alloc();
1432  if (!sha)
1433  return AVERROR(ENOMEM);
1434  av_free(c->aes_decrypt);
1435  c->aes_decrypt = av_aes_alloc();
1436  if (!c->aes_decrypt) {
1437  ret = AVERROR(ENOMEM);
1438  goto fail;
1439  }
1440 
1441  /* drm blob processing */
1442  avio_read(pb, output, 8); // go to offset 8, absolute position 0x251
1444  avio_read(pb, output, 4); // go to offset 4, absolute position 0x28d
1445  ret = ffio_read_size(pb, file_checksum, 20);
1446  if (ret < 0)
1447  goto fail;
1448 
1449  // required by external tools
1450  ff_data_to_hex(checksum_string, file_checksum, sizeof(file_checksum), 1);
1451  av_log(c->fc, AV_LOG_INFO, "[aax] file checksum == %s\n", checksum_string);
1452 
1453  /* verify activation data */
1454  if (!activation_bytes) {
1455  av_log(c->fc, AV_LOG_WARNING, "[aax] activation_bytes option is missing!\n");
1456  ret = 0; /* allow ffprobe to continue working on .aax files */
1457  goto fail;
1458  }
1459  if (c->activation_bytes_size != 4) {
1460  av_log(c->fc, AV_LOG_FATAL, "[aax] activation_bytes value needs to be 4 bytes!\n");
1461  ret = AVERROR(EINVAL);
1462  goto fail;
1463  }
1464 
1465  /* verify fixed key */
1466  if (c->audible_fixed_key_size != 16) {
1467  av_log(c->fc, AV_LOG_FATAL, "[aax] audible_fixed_key value needs to be 16 bytes!\n");
1468  ret = AVERROR(EINVAL);
1469  goto fail;
1470  }
1471 
1472  /* AAX (and AAX+) key derivation */
1473  av_sha_init(sha, 160);
1474  av_sha_update(sha, fixed_key, 16);
1475  av_sha_update(sha, activation_bytes, 4);
1476  av_sha_final(sha, intermediate_key);
1477  av_sha_init(sha, 160);
1478  av_sha_update(sha, fixed_key, 16);
1479  av_sha_update(sha, intermediate_key, 20);
1480  av_sha_update(sha, activation_bytes, 4);
1481  av_sha_final(sha, intermediate_iv);
1482  av_sha_init(sha, 160);
1483  av_sha_update(sha, intermediate_key, 16);
1484  av_sha_update(sha, intermediate_iv, 16);
1485  av_sha_final(sha, calculated_checksum);
1486  if (memcmp(calculated_checksum, file_checksum, 20)) { // critical error
1487  av_log(c->fc, AV_LOG_ERROR, "[aax] mismatch in checksums!\n");
1489  goto fail;
1490  }
1491  av_aes_init(c->aes_decrypt, intermediate_key, 128, 1);
1492  av_aes_crypt(c->aes_decrypt, output, input, DRM_BLOB_SIZE >> 4, intermediate_iv, 1);
1493  for (i = 0; i < 4; i++) {
1494  // file data (in output) is stored in big-endian mode
1495  if (activation_bytes[i] != output[3 - i]) { // critical error
1496  av_log(c->fc, AV_LOG_ERROR, "[aax] error in drm blob decryption!\n");
1498  goto fail;
1499  }
1500  }
1501  memcpy(c->file_key, output + 8, 16);
1502  memcpy(input, output + 26, 16);
1503  av_sha_init(sha, 160);
1504  av_sha_update(sha, input, 16);
1505  av_sha_update(sha, c->file_key, 16);
1506  av_sha_update(sha, fixed_key, 16);
1507  av_sha_final(sha, c->file_iv);
1508 
1509 fail:
1510  av_free(sha);
1511 
1512  return ret;
1513 }
1514 
1516 {
1517  if (c->audible_key_size != 16) {
1518  av_log(c->fc, AV_LOG_FATAL, "[aaxc] audible_key value needs to be 16 bytes!\n");
1519  return AVERROR(EINVAL);
1520  }
1521 
1522  if (c->audible_iv_size != 16) {
1523  av_log(c->fc, AV_LOG_FATAL, "[aaxc] audible_iv value needs to be 16 bytes!\n");
1524  return AVERROR(EINVAL);
1525  }
1526 
1527  c->aes_decrypt = av_aes_alloc();
1528  if (!c->aes_decrypt) {
1529  return AVERROR(ENOMEM);
1530  }
1531 
1532  memcpy(c->file_key, c->audible_key, 16);
1533  memcpy(c->file_iv, c->audible_iv, 16);
1534  c->aax_mode = 1;
1535 
1536  return 0;
1537 }
1538 
1539 // Audible AAX (and AAX+) bytestream decryption
1540 static int aax_filter(uint8_t *input, int size, MOVContext *c)
1541 {
1542  int blocks = 0;
1543  unsigned char iv[16];
1544 
1545  memcpy(iv, c->file_iv, 16); // iv is overwritten
1546  blocks = size >> 4; // trailing bytes are not encrypted!
1547  av_aes_init(c->aes_decrypt, c->file_key, 128, 1);
1548  av_aes_crypt(c->aes_decrypt, input, input, blocks, iv, 1);
1549 
1550  return 0;
1551 }
1552 
1553 /* read major brand, minor version and compatible brands and store them as metadata */
1555 {
1556  uint32_t minor_ver;
1557  int comp_brand_size;
1558  char* comp_brands_str;
1559  uint8_t type[5] = {0};
1560  int ret = ffio_read_size(pb, type, 4);
1561  if (ret < 0)
1562  return ret;
1563  if (c->fc->nb_streams) {
1564  if (c->fc->strict_std_compliance >= FF_COMPLIANCE_STRICT)
1565  return AVERROR_INVALIDDATA;
1566  av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate FTYP\n");
1567  return 0;
1568  }
1569 
1570  if (strcmp(type, "qt "))
1571  c->isom = 1;
1572  av_log(c->fc, AV_LOG_DEBUG, "ISO: File Type Major Brand: %.4s\n",(char *)&type);
1573  av_dict_set(&c->fc->metadata, "major_brand", type, 0);
1574  minor_ver = avio_rb32(pb); /* minor version */
1575  av_dict_set_int(&c->fc->metadata, "minor_version", minor_ver, 0);
1576 
1577  comp_brand_size = atom.size - 8;
1578  if (comp_brand_size < 0 || comp_brand_size == INT_MAX)
1579  return AVERROR_INVALIDDATA;
1580  comp_brands_str = av_malloc(comp_brand_size + 1); /* Add null terminator */
1581  if (!comp_brands_str)
1582  return AVERROR(ENOMEM);
1583 
1584  ret = ffio_read_size(pb, comp_brands_str, comp_brand_size);
1585  if (ret < 0) {
1586  av_freep(&comp_brands_str);
1587  return ret;
1588  }
1589  comp_brands_str[comp_brand_size] = 0;
1590  av_dict_set(&c->fc->metadata, "compatible_brands",
1591  comp_brands_str, AV_DICT_DONT_STRDUP_VAL);
1592 
1593  // Logic for handling Audible's .aaxc files
1594  if (!strcmp(type, "aaxc")) {
1595  mov_aaxc_crypto(c);
1596  }
1597 
1598  return 0;
1599 }
1600 
1601 /* this atom should contain all header atoms */
1603 {
1604  int ret;
1605 
1606  if (c->found_moov) {
1607  av_log(c->fc, AV_LOG_WARNING, "Found duplicated MOOV Atom. Skipped it\n");
1608  avio_skip(pb, atom.size);
1609  return 0;
1610  }
1611 
1612  if ((ret = mov_read_default(c, pb, atom)) < 0)
1613  return ret;
1614  /* we parsed the 'moov' atom, we can terminate the parsing as soon as we find the 'mdat' */
1615  /* so we don't parse the whole file if over a network */
1616  c->found_moov=1;
1617  return 0; /* now go for mdat */
1618 }
1619 
1621  MOVFragmentIndex *frag_index,
1622  int index,
1623  int id)
1624 {
1625  int i;
1626  MOVFragmentIndexItem * item;
1627 
1628  if (index < 0 || index >= frag_index->nb_items)
1629  return NULL;
1630  item = &frag_index->item[index];
1631  for (i = 0; i < item->nb_stream_info; i++)
1632  if (item->stream_info[i].id == id)
1633  return &item->stream_info[i];
1634 
1635  // This shouldn't happen
1636  return NULL;
1637 }
1638 
1639 static void set_frag_stream(MOVFragmentIndex *frag_index, int id)
1640 {
1641  int i;
1642  MOVFragmentIndexItem * item;
1643 
1644  if (frag_index->current < 0 ||
1645  frag_index->current >= frag_index->nb_items)
1646  return;
1647 
1648  item = &frag_index->item[frag_index->current];
1649  for (i = 0; i < item->nb_stream_info; i++)
1650  if (item->stream_info[i].id == id) {
1651  item->current = i;
1652  return;
1653  }
1654 
1655  // id not found. This shouldn't happen.
1656  item->current = -1;
1657 }
1658 
1660  MOVFragmentIndex *frag_index)
1661 {
1662  MOVFragmentIndexItem *item;
1663  if (frag_index->current < 0 ||
1664  frag_index->current >= frag_index->nb_items)
1665  return NULL;
1666 
1667  item = &frag_index->item[frag_index->current];
1668  if (item->current >= 0 && item->current < item->nb_stream_info)
1669  return &item->stream_info[item->current];
1670 
1671  // This shouldn't happen
1672  return NULL;
1673 }
1674 
1676 {
1677  int a, b, m;
1678  int64_t moof_offset;
1679 
1680  // Optimize for appending new entries
1681  if (!frag_index->nb_items ||
1682  frag_index->item[frag_index->nb_items - 1].moof_offset < offset)
1683  return frag_index->nb_items;
1684 
1685  a = -1;
1686  b = frag_index->nb_items;
1687 
1688  while (b - a > 1) {
1689  m = (a + b) >> 1;
1690  moof_offset = frag_index->item[m].moof_offset;
1691  if (moof_offset >= offset)
1692  b = m;
1693  if (moof_offset <= offset)
1694  a = m;
1695  }
1696  return b;
1697 }
1698 
1700 {
1701  av_assert0(frag_stream_info);
1702  if (frag_stream_info->sidx_pts != AV_NOPTS_VALUE)
1703  return frag_stream_info->sidx_pts;
1704  if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE)
1705  return frag_stream_info->first_tfra_pts;
1706  return frag_stream_info->tfdt_dts;
1707 }
1708 
1710  MOVFragmentIndex *frag_index, int index)
1711 {
1712  MOVFragmentStreamInfo * frag_stream_info;
1713  MOVStreamContext *sc = dst_st->priv_data;
1714  int64_t timestamp;
1715  int i, j;
1716 
1717  // If the stream is referenced by any sidx, limit the search
1718  // to fragments that referenced this stream in the sidx
1719  if (sc->has_sidx) {
1720  frag_stream_info = get_frag_stream_info(frag_index, index, sc->id);
1721  if (!frag_stream_info)
1722  return AV_NOPTS_VALUE;
1723  if (frag_stream_info->sidx_pts != AV_NOPTS_VALUE)
1724  return frag_stream_info->sidx_pts;
1725  if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE)
1726  return frag_stream_info->first_tfra_pts;
1727  return frag_stream_info->sidx_pts;
1728  }
1729 
1730  for (i = 0; i < frag_index->item[index].nb_stream_info; i++) {
1731  if (dst_st->id != frag_index->item[index].stream_info[i].id)
1732  continue;
1733  AVStream *frag_stream = NULL;
1734  frag_stream_info = &frag_index->item[index].stream_info[i];
1735  for (j = 0; j < s->nb_streams; j++) {
1736  MOVStreamContext *sc2 = s->streams[j]->priv_data;
1737  if (sc2->id == frag_stream_info->id)
1738  frag_stream = s->streams[j];
1739  }
1740  if (!frag_stream) {
1741  av_log(s, AV_LOG_WARNING, "No stream matching sidx ID found.\n");
1742  continue;
1743  }
1744  timestamp = get_stream_info_time(frag_stream_info);
1745  if (timestamp != AV_NOPTS_VALUE)
1746  return av_rescale_q(timestamp, frag_stream->time_base, dst_st->time_base);
1747  }
1748  return AV_NOPTS_VALUE;
1749 }
1750 
1752  AVStream *st, int64_t timestamp)
1753 {
1754  int a, b, m, m0;
1755  int64_t frag_time;
1756 
1757  a = -1;
1758  b = frag_index->nb_items;
1759 
1760  while (b - a > 1) {
1761  m0 = m = (a + b) >> 1;
1762 
1763  while (m < b &&
1764  (frag_time = get_frag_time(s, st, frag_index, m)) == AV_NOPTS_VALUE)
1765  m++;
1766 
1767  if (m < b && frag_time <= timestamp)
1768  a = m;
1769  else
1770  b = m0;
1771  }
1772 
1773  return a;
1774 }
1775 
1777 {
1778  int index, i;
1779  MOVFragmentIndexItem * item;
1780  MOVFragmentStreamInfo * frag_stream_info;
1781 
1782  // If moof_offset already exists in frag_index, return index to it
1783  index = search_frag_moof_offset(&c->frag_index, offset);
1784  if (index < c->frag_index.nb_items &&
1785  c->frag_index.item[index].moof_offset == offset)
1786  return index;
1787 
1788  // offset is not yet in frag index.
1789  // Insert new item at index (sorted by moof offset)
1790  item = av_fast_realloc(c->frag_index.item,
1791  &c->frag_index.allocated_size,
1792  (c->frag_index.nb_items + 1) *
1793  sizeof(*c->frag_index.item));
1794  if (!item)
1795  return -1;
1796  c->frag_index.item = item;
1797 
1798  frag_stream_info = av_realloc_array(NULL, c->fc->nb_streams,
1799  sizeof(*item->stream_info));
1800  if (!frag_stream_info)
1801  return -1;
1802 
1803  for (i = 0; i < c->fc->nb_streams; i++) {
1804  // Avoid building frag index if streams lack track id.
1805  MOVStreamContext *sc = c->fc->streams[i]->priv_data;
1806  if (sc->id < 0) {
1807  av_free(frag_stream_info);
1808  return AVERROR_INVALIDDATA;
1809  }
1810 
1811  frag_stream_info[i].id = sc->id;
1812  frag_stream_info[i].sidx_pts = AV_NOPTS_VALUE;
1813  frag_stream_info[i].tfdt_dts = AV_NOPTS_VALUE;
1814  frag_stream_info[i].next_trun_dts = AV_NOPTS_VALUE;
1815  frag_stream_info[i].first_tfra_pts = AV_NOPTS_VALUE;
1816  frag_stream_info[i].index_base = -1;
1817  frag_stream_info[i].index_entry = -1;
1818  frag_stream_info[i].encryption_index = NULL;
1819  frag_stream_info[i].stsd_id = -1;
1820  }
1821 
1822  if (index < c->frag_index.nb_items)
1823  memmove(c->frag_index.item + index + 1, c->frag_index.item + index,
1824  (c->frag_index.nb_items - index) * sizeof(*c->frag_index.item));
1825 
1826  item = &c->frag_index.item[index];
1827  item->headers_read = 0;
1828  item->current = 0;
1829  item->nb_stream_info = c->fc->nb_streams;
1830  item->moof_offset = offset;
1831  item->stream_info = frag_stream_info;
1832  c->frag_index.nb_items++;
1833 
1834  return index;
1835 }
1836 
1837 static void fix_frag_index_entries(MOVFragmentIndex *frag_index, int index,
1838  int id, int entries)
1839 {
1840  int i;
1841  MOVFragmentStreamInfo * frag_stream_info;
1842 
1843  if (index < 0)
1844  return;
1845  for (i = index; i < frag_index->nb_items; i++) {
1846  frag_stream_info = get_frag_stream_info(frag_index, i, id);
1847  if (frag_stream_info && frag_stream_info->index_entry >= 0)
1848  frag_stream_info->index_entry += entries;
1849  }
1850 }
1851 
1853 {
1854  // Set by mov_read_tfhd(). mov_read_trun() will reject files missing tfhd.
1855  c->fragment.found_tfhd = 0;
1856 
1857  if (!c->has_looked_for_mfra && c->use_mfra_for > 0) {
1858  c->has_looked_for_mfra = 1;
1859  if (pb->seekable & AVIO_SEEKABLE_NORMAL) {
1860  int ret;
1861  av_log(c->fc, AV_LOG_VERBOSE, "stream has moof boxes, will look "
1862  "for a mfra\n");
1863  if ((ret = mov_read_mfra(c, pb)) < 0) {
1864  av_log(c->fc, AV_LOG_VERBOSE, "found a moof box but failed to "
1865  "read the mfra (may be a live ismv)\n");
1866  }
1867  } else {
1868  av_log(c->fc, AV_LOG_VERBOSE, "found a moof box but stream is not "
1869  "seekable, can not look for mfra\n");
1870  }
1871  }
1872  c->fragment.moof_offset = c->fragment.implicit_offset = avio_tell(pb) - 8;
1873  av_log(c->fc, AV_LOG_TRACE, "moof offset %"PRIx64"\n", c->fragment.moof_offset);
1874  c->frag_index.current = update_frag_index(c, c->fragment.moof_offset);
1875  return mov_read_default(c, pb, atom);
1876 }
1877 
1879 {
1880  int64_t time;
1881  if (version == 1) {
1882  time = avio_rb64(pb);
1883  avio_rb64(pb);
1884  if (time < 0) {
1885  av_log(c->fc, AV_LOG_DEBUG, "creation_time is negative\n");
1886  return;
1887  }
1888  } else {
1889  time = avio_rb32(pb);
1890  avio_rb32(pb); /* modification time */
1891  if (time > 0 && time < 2082844800) {
1892  av_log(c->fc, AV_LOG_WARNING, "Detected creation time before 1970, parsing as unix timestamp.\n");
1893  time += 2082844800;
1894  }
1895  }
1896  if (time) {
1897  time -= 2082844800; /* seconds between 1904-01-01 and Epoch */
1898 
1899  if ((int64_t)(time * 1000000ULL) / 1000000 != time) {
1900  av_log(c->fc, AV_LOG_DEBUG, "creation_time is not representable\n");
1901  return;
1902  }
1903 
1904  ff_dict_set_timestamp(metadata, "creation_time", time * 1000000);
1905  }
1906 }
1907 
1909 {
1910  AVStream *st;
1911  MOVStreamContext *sc;
1912  int version;
1913  char language[4] = {0};
1914  unsigned lang;
1915 
1916  if (c->fc->nb_streams < 1)
1917  return 0;
1918  st = c->fc->streams[c->fc->nb_streams-1];
1919  sc = st->priv_data;
1920 
1921  if (sc->time_scale) {
1922  av_log(c->fc, AV_LOG_ERROR, "Multiple mdhd?\n");
1923  return AVERROR_INVALIDDATA;
1924  }
1925 
1926  version = avio_r8(pb);
1927  if (version > 1) {
1928  avpriv_request_sample(c->fc, "Version %d", version);
1929  return AVERROR_PATCHWELCOME;
1930  }
1931  avio_rb24(pb); /* flags */
1933 
1934  sc->time_scale = avio_rb32(pb);
1935  if (sc->time_scale <= 0) {
1936  av_log(c->fc, AV_LOG_ERROR, "Invalid mdhd time scale %d, defaulting to 1\n", sc->time_scale);
1937  sc->time_scale = 1;
1938  }
1939  st->duration = (version == 1) ? avio_rb64(pb) : avio_rb32(pb); /* duration */
1940 
1941  if ((version == 1 && st->duration == UINT64_MAX) ||
1942  (version != 1 && st->duration == UINT32_MAX)) {
1943  st->duration = 0;
1944  }
1945 
1946  lang = avio_rb16(pb); /* language */
1947  if (ff_mov_lang_to_iso639(lang, language))
1948  av_dict_set(&st->metadata, "language", language, 0);
1949  avio_rb16(pb); /* quality */
1950 
1951  return 0;
1952 }
1953 
1955 {
1956  int i;
1957  int version = avio_r8(pb); /* version */
1958  avio_rb24(pb); /* flags */
1959 
1960  mov_metadata_creation_time(c, pb, &c->fc->metadata, version);
1961  c->time_scale = avio_rb32(pb); /* time scale */
1962  if (c->time_scale <= 0) {
1963  av_log(c->fc, AV_LOG_ERROR, "Invalid mvhd time scale %d, defaulting to 1\n", c->time_scale);
1964  c->time_scale = 1;
1965  }
1966  av_log(c->fc, AV_LOG_TRACE, "time scale = %i\n", c->time_scale);
1967 
1968  c->duration = (version == 1) ? avio_rb64(pb) : avio_rb32(pb); /* duration */
1969  avio_rb32(pb); /* preferred scale */
1970 
1971  avio_rb16(pb); /* preferred volume */
1972 
1973  avio_skip(pb, 10); /* reserved */
1974 
1975  /* movie display matrix, store it in main context and use it later on */
1976  for (i = 0; i < 3; i++) {
1977  c->movie_display_matrix[i][0] = avio_rb32(pb); // 16.16 fixed point
1978  c->movie_display_matrix[i][1] = avio_rb32(pb); // 16.16 fixed point
1979  c->movie_display_matrix[i][2] = avio_rb32(pb); // 2.30 fixed point
1980  }
1981 
1982  avio_rb32(pb); /* preview time */
1983  avio_rb32(pb); /* preview duration */
1984  avio_rb32(pb); /* poster time */
1985  avio_rb32(pb); /* selection time */
1986  avio_rb32(pb); /* selection duration */
1987  avio_rb32(pb); /* current time */
1988  avio_rb32(pb); /* next track ID */
1989 
1990  return 0;
1991 }
1992 
1994 {
1995  AVStream *st;
1996 
1997  if (fc->nb_streams < 1)
1998  return;
1999  st = fc->streams[fc->nb_streams-1];
2000 
2001  switch (st->codecpar->codec_id) {
2002  case AV_CODEC_ID_PCM_S16BE:
2004  break;
2005  case AV_CODEC_ID_PCM_S24BE:
2007  break;
2008  case AV_CODEC_ID_PCM_S32BE:
2010  break;
2011  case AV_CODEC_ID_PCM_F32BE:
2013  break;
2014  case AV_CODEC_ID_PCM_F64BE:
2016  break;
2017  default:
2018  break;
2019  }
2020 }
2021 
2023 {
2024  int little_endian = avio_rb16(pb) & 0xFF;
2025  av_log(c->fc, AV_LOG_TRACE, "enda %d\n", little_endian);
2026  if (little_endian == 1)
2028  return 0;
2029 }
2030 
2032 {
2033  int format_flags;
2034  int version, flags;
2035  int pcm_sample_size;
2036  AVFormatContext *fc = c->fc;
2037  AVStream *st;
2038  MOVStreamContext *sc;
2039 
2040  if (atom.size < 6) {
2041  av_log(c->fc, AV_LOG_ERROR, "Empty pcmC box\n");
2042  return AVERROR_INVALIDDATA;
2043  }
2044 
2045  version = avio_r8(pb);
2046  flags = avio_rb24(pb);
2047 
2048  if (version != 0 || flags != 0) {
2049  av_log(c->fc, AV_LOG_ERROR,
2050  "Unsupported 'pcmC' box with version %d, flags: %x",
2051  version, flags);
2052  return AVERROR_INVALIDDATA;
2053  }
2054 
2055  format_flags = avio_r8(pb);
2056  pcm_sample_size = avio_r8(pb);
2057 
2058  if (fc->nb_streams < 1)
2059  return AVERROR_INVALIDDATA;
2060 
2061  st = fc->streams[fc->nb_streams - 1];
2062  sc = st->priv_data;
2063 
2064  if (sc->format == MOV_MP4_FPCM_TAG) {
2065  switch (pcm_sample_size) {
2066  case 32:
2068  break;
2069  case 64:
2071  break;
2072  default:
2073  av_log(fc, AV_LOG_ERROR, "invalid pcm_sample_size %d for %s\n",
2074  pcm_sample_size,
2075  av_fourcc2str(sc->format));
2076  return AVERROR_INVALIDDATA;
2077  }
2078  } else if (sc->format == MOV_MP4_IPCM_TAG) {
2079  switch (pcm_sample_size) {
2080  case 16:
2082  break;
2083  case 24:
2085  break;
2086  case 32:
2088  break;
2089  default:
2090  av_log(fc, AV_LOG_ERROR, "invalid pcm_sample_size %d for %s\n",
2091  pcm_sample_size,
2092  av_fourcc2str(sc->format));
2093  return AVERROR_INVALIDDATA;
2094  }
2095  } else {
2096  av_log(fc, AV_LOG_ERROR, "'pcmC' with invalid sample entry '%s'\n",
2097  av_fourcc2str(sc->format));
2098  return AVERROR_INVALIDDATA;
2099  }
2100 
2101  if (format_flags & 1) // indicates little-endian format. If not present, big-endian format is used
2104 
2105  return 0;
2106 }
2107 
2109 {
2110  AVStream *st;
2111  HEIFItem *item = NULL;
2112  char color_parameter_type[5] = { 0 };
2113  uint16_t color_primaries, color_trc, color_matrix;
2114  int ret;
2115 
2116  st = get_curr_st(c);
2117  if (!st) {
2118  item = get_heif_item(c, c->cur_item_id);
2119  if (!item)
2120  return 0;
2121  }
2122 
2123  ret = ffio_read_size(pb, color_parameter_type, 4);
2124  if (ret < 0)
2125  return ret;
2126  if (strncmp(color_parameter_type, "nclx", 4) &&
2127  strncmp(color_parameter_type, "nclc", 4) &&
2128  strncmp(color_parameter_type, "prof", 4)) {
2129  av_log(c->fc, AV_LOG_WARNING, "unsupported color_parameter_type %s\n",
2130  color_parameter_type);
2131  return 0;
2132  }
2133 
2134  if (!strncmp(color_parameter_type, "prof", 4)) {
2135  AVPacketSideData *sd;
2136  uint8_t *icc_profile;
2137  if (st) {
2141  atom.size - 4, 0);
2142  if (!sd)
2143  return AVERROR(ENOMEM);
2144  icc_profile = sd->data;
2145  } else {
2146  av_freep(&item->icc_profile);
2147  icc_profile = item->icc_profile = av_malloc(atom.size - 4);
2148  if (!icc_profile) {
2149  item->icc_profile_size = 0;
2150  return AVERROR(ENOMEM);
2151  }
2152  item->icc_profile_size = atom.size - 4;
2153  }
2154  ret = ffio_read_size(pb, icc_profile, atom.size - 4);
2155  if (ret < 0)
2156  return ret;
2157  } else if (st) {
2158  color_primaries = avio_rb16(pb);
2159  color_trc = avio_rb16(pb);
2160  color_matrix = avio_rb16(pb);
2161 
2162  av_log(c->fc, AV_LOG_TRACE,
2163  "%s: pri %d trc %d matrix %d",
2164  color_parameter_type, color_primaries, color_trc, color_matrix);
2165 
2166  if (!strncmp(color_parameter_type, "nclx", 4)) {
2167  uint8_t color_range = avio_r8(pb) >> 7;
2168  av_log(c->fc, AV_LOG_TRACE, " full %"PRIu8"", color_range);
2169  if (color_range)
2171  else
2173  }
2174 
2177  if (!av_color_transfer_name(color_trc))
2178  color_trc = AVCOL_TRC_UNSPECIFIED;
2179  if (!av_color_space_name(color_matrix))
2180  color_matrix = AVCOL_SPC_UNSPECIFIED;
2181 
2183  st->codecpar->color_trc = color_trc;
2184  st->codecpar->color_space = color_matrix;
2185  av_log(c->fc, AV_LOG_TRACE, "\n");
2186  }
2187  return 0;
2188 }
2189 
2191 {
2192  AVStream *st;
2193  unsigned mov_field_order;
2194  enum AVFieldOrder decoded_field_order = AV_FIELD_UNKNOWN;
2195 
2196  if (c->fc->nb_streams < 1) // will happen with jp2 files
2197  return 0;
2198  st = c->fc->streams[c->fc->nb_streams-1];
2199  if (atom.size < 2)
2200  return AVERROR_INVALIDDATA;
2201  mov_field_order = avio_rb16(pb);
2202  if ((mov_field_order & 0xFF00) == 0x0100)
2203  decoded_field_order = AV_FIELD_PROGRESSIVE;
2204  else if ((mov_field_order & 0xFF00) == 0x0200) {
2205  switch (mov_field_order & 0xFF) {
2206  case 0x01: decoded_field_order = AV_FIELD_TT;
2207  break;
2208  case 0x06: decoded_field_order = AV_FIELD_BB;
2209  break;
2210  case 0x09: decoded_field_order = AV_FIELD_TB;
2211  break;
2212  case 0x0E: decoded_field_order = AV_FIELD_BT;
2213  break;
2214  }
2215  }
2216  if (decoded_field_order == AV_FIELD_UNKNOWN && mov_field_order) {
2217  av_log(c->fc, AV_LOG_ERROR, "Unknown MOV field order 0x%04x\n", mov_field_order);
2218  }
2219  st->codecpar->field_order = decoded_field_order;
2220 
2221  return 0;
2222 }
2223 
2225 {
2226  int err = 0;
2227  uint64_t size = (uint64_t)par->extradata_size + atom.size + 8 + AV_INPUT_BUFFER_PADDING_SIZE;
2228  if (size > INT_MAX || (uint64_t)atom.size > INT_MAX)
2229  return AVERROR_INVALIDDATA;
2230  if ((err = av_reallocp(&par->extradata, size)) < 0) {
2231  par->extradata_size = 0;
2232  return err;
2233  }
2235  return 0;
2236 }
2237 
2238 /* Read a whole atom into the extradata return the size of the atom read, possibly truncated if != atom.size */
2240  AVCodecParameters *par, uint8_t *buf)
2241 {
2242  int64_t result = atom.size;
2243  int err;
2244 
2245  AV_WB32(buf , atom.size + 8);
2246  AV_WL32(buf + 4, atom.type);
2247  err = ffio_read_size(pb, buf + 8, atom.size);
2248  if (err < 0) {
2249  par->extradata_size -= atom.size;
2250  return err;
2251  } else if (err < atom.size) {
2252  av_log(c->fc, AV_LOG_WARNING, "truncated extradata\n");
2253  par->extradata_size -= atom.size - err;
2254  result = err;
2255  }
2256  memset(buf + 8 + err, 0, AV_INPUT_BUFFER_PADDING_SIZE);
2257  return result;
2258 }
2259 
2260 /* FIXME modify QDM2/SVQ3/H.264 decoders to take full atom as extradata */
2262  enum AVCodecID codec_id)
2263 {
2264  AVStream *st;
2265  uint64_t original_size;
2266  int err;
2267 
2268  if (c->fc->nb_streams < 1) // will happen with jp2 files
2269  return 0;
2270  st = c->fc->streams[c->fc->nb_streams-1];
2271 
2272  if (st->codecpar->codec_id != codec_id)
2273  return 0; /* unexpected codec_id - don't mess with extradata */
2274 
2275  original_size = st->codecpar->extradata_size;
2276  err = mov_realloc_extradata(st->codecpar, atom);
2277  if (err)
2278  return err;
2279 
2280  err = mov_read_atom_into_extradata(c, pb, atom, st->codecpar, st->codecpar->extradata + original_size);
2281  if (err < 0)
2282  return err;
2283  return 0; // Note: this is the original behavior to ignore truncation.
2284 }
2285 
2286 /* wrapper functions for reading ALAC/AVS/MJPEG/MJPEG2000 extradata atoms only for those codecs */
2288 {
2289  return mov_read_extradata(c, pb, atom, AV_CODEC_ID_ALAC);
2290 }
2291 
2293 {
2294  return mov_read_extradata(c, pb, atom, AV_CODEC_ID_CAVS);
2295 }
2296 
2298 {
2299  return mov_read_extradata(c, pb, atom, AV_CODEC_ID_JPEG2000);
2300 }
2301 
2303 {
2304  return mov_read_extradata(c, pb, atom, AV_CODEC_ID_R10K);
2305 }
2306 
2308 {
2309  int ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_AVUI);
2310  if (!ret)
2311  ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_DNXHD);
2312  return ret;
2313 }
2314 
2316 {
2317  int ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_TARGA_Y216);
2318 
2319  if (!ret && c->fc->nb_streams >= 1) {
2320  AVCodecParameters *par = c->fc->streams[c->fc->nb_streams-1]->codecpar;
2321  if (par->extradata_size >= 40) {
2322  par->height = AV_RB16(&par->extradata[36]);
2323  par->width = AV_RB16(&par->extradata[38]);
2324  }
2325  }
2326  return ret;
2327 }
2328 
2330 {
2331  if (c->fc->nb_streams >= 1) {
2332  AVStream *const st = c->fc->streams[c->fc->nb_streams - 1];
2333  FFStream *const sti = ffstream(st);
2334  AVCodecParameters *par = st->codecpar;
2335 
2336  if (par->codec_tag == MKTAG('A', 'V', 'i', 'n') &&
2337  par->codec_id == AV_CODEC_ID_H264 &&
2338  atom.size > 11) {
2339  int cid;
2340  avio_skip(pb, 10);
2341  cid = avio_rb16(pb);
2342  /* For AVID AVCI50, force width of 1440 to be able to select the correct SPS and PPS */
2343  if (cid == 0xd4d || cid == 0xd4e)
2344  par->width = 1440;
2345  return 0;
2346  } else if ((par->codec_tag == MKTAG('A', 'V', 'd', '1') ||
2347  par->codec_tag == MKTAG('A', 'V', 'j', '2') ||
2348  par->codec_tag == MKTAG('A', 'V', 'd', 'n')) &&
2349  atom.size >= 24) {
2350  int num, den;
2351  avio_skip(pb, 12);
2352  num = avio_rb32(pb);
2353  den = avio_rb32(pb);
2354  if (num <= 0 || den <= 0)
2355  return 0;
2356  switch (avio_rb32(pb)) {
2357  case 2:
2358  if (den >= INT_MAX / 2)
2359  return 0;
2360  den *= 2;
2362  case 1:
2363  sti->display_aspect_ratio = (AVRational){ num, den };
2365  default:
2366  return 0;
2367  }
2368  }
2369  }
2370 
2371  return mov_read_avid(c, pb, atom);
2372 }
2373 
2375 {
2376  int ret = 0;
2377  int length = 0;
2378  uint64_t original_size;
2379  if (c->fc->nb_streams >= 1) {
2380  AVCodecParameters *par = c->fc->streams[c->fc->nb_streams-1]->codecpar;
2381  if (par->codec_id == AV_CODEC_ID_H264)
2382  return 0;
2383  if (atom.size == 16) {
2384  original_size = par->extradata_size;
2385  ret = mov_realloc_extradata(par, atom);
2386  if (!ret) {
2387  length = mov_read_atom_into_extradata(c, pb, atom, par, par->extradata + original_size);
2388  if (length == atom.size) {
2389  const uint8_t range_value = par->extradata[original_size + 19];
2390  switch (range_value) {
2391  case 1:
2393  break;
2394  case 2:
2396  break;
2397  default:
2398  av_log(c->fc, AV_LOG_WARNING, "ignored unknown aclr value (%d)\n", range_value);
2399  break;
2400  }
2401  ff_dlog(c->fc, "color_range: %d\n", par->color_range);
2402  } else {
2403  /* For some reason the whole atom was not added to the extradata */
2404  av_log(c->fc, AV_LOG_ERROR, "aclr not decoded - incomplete atom\n");
2405  }
2406  } else {
2407  av_log(c->fc, AV_LOG_ERROR, "aclr not decoded - unable to add atom to extradata\n");
2408  }
2409  } else {
2410  av_log(c->fc, AV_LOG_WARNING, "aclr not decoded - unexpected size %"PRId64"\n", atom.size);
2411  }
2412  }
2413 
2414  return ret;
2415 }
2416 
2418 {
2419  return mov_read_extradata(c, pb, atom, AV_CODEC_ID_SVQ3);
2420 }
2421 
2423 {
2424  AVStream *st;
2425  int ret;
2426 
2427  if (c->fc->nb_streams < 1)
2428  return 0;
2429  st = c->fc->streams[c->fc->nb_streams-1];
2430 
2431  if ((uint64_t)atom.size > (1<<30))
2432  return AVERROR_INVALIDDATA;
2433 
2434  if (st->codecpar->codec_id == AV_CODEC_ID_QDM2 ||
2437  // pass all frma atom to codec, needed at least for QDMC and QDM2
2438  ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size);
2439  if (ret < 0)
2440  return ret;
2441  } else if (atom.size > 8) { /* to read frma, esds atoms */
2442  if (st->codecpar->codec_id == AV_CODEC_ID_ALAC && atom.size >= 24) {
2443  uint64_t buffer;
2444  ret = ffio_ensure_seekback(pb, 8);
2445  if (ret < 0)
2446  return ret;
2447  buffer = avio_rb64(pb);
2448  atom.size -= 8;
2449  if ( (buffer & 0xFFFFFFFF) == MKBETAG('f','r','m','a')
2450  && buffer >> 32 <= atom.size
2451  && buffer >> 32 >= 8) {
2452  avio_skip(pb, -8);
2453  atom.size += 8;
2454  } else if (!st->codecpar->extradata_size) {
2455 #define ALAC_EXTRADATA_SIZE 36
2457  if (!st->codecpar->extradata)
2458  return AVERROR(ENOMEM);
2461  AV_WB32(st->codecpar->extradata + 4, MKTAG('a','l','a','c'));
2462  AV_WB64(st->codecpar->extradata + 12, buffer);
2463  avio_read(pb, st->codecpar->extradata + 20, 16);
2464  avio_skip(pb, atom.size - 24);
2465  return 0;
2466  }
2467  }
2468  if ((ret = mov_read_default(c, pb, atom)) < 0)
2469  return ret;
2470  } else
2471  avio_skip(pb, atom.size);
2472  return 0;
2473 }
2474 
2475 /**
2476  * This function reads atom content and puts data in extradata without tag
2477  * nor size unlike mov_read_extradata.
2478  */
2480 {
2481  AVStream *st;
2482  int ret;
2483 
2484  st = get_curr_st(c);
2485  if (!st)
2486  return 0;
2487 
2488  if ((uint64_t)atom.size > (1<<30))
2489  return AVERROR_INVALIDDATA;
2490 
2491  if (atom.type == MKTAG('v','v','c','C')) {
2492  avio_skip(pb, 4);
2493  atom.size -= 4;
2494  }
2495 
2496  if (atom.size >= 10) {
2497  // Broken files created by legacy versions of libavformat will
2498  // wrap a whole fiel atom inside of a glbl atom.
2499  unsigned size = avio_rb32(pb);
2500  unsigned type = avio_rl32(pb);
2501  if (avio_feof(pb))
2502  return AVERROR_INVALIDDATA;
2503  avio_seek(pb, -8, SEEK_CUR);
2504  if (type == MKTAG('f','i','e','l') && size == atom.size)
2505  return mov_read_default(c, pb, atom);
2506  }
2507  if (st->codecpar->extradata_size > 1 && st->codecpar->extradata) {
2508  av_log(c->fc, AV_LOG_WARNING, "ignoring multiple glbl\n");
2509  return 0;
2510  }
2511  ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size);
2512  if (ret < 0)
2513  return ret;
2514  if (atom.type == MKTAG('h','v','c','C') && st->codecpar->codec_tag == MKTAG('d','v','h','1'))
2515  /* HEVC-based Dolby Vision derived from hvc1.
2516  Happens to match with an identifier
2517  previously utilized for DV. Thus, if we have
2518  the hvcC extradata box available as specified,
2519  set codec to HEVC */
2521 
2522  return 0;
2523 }
2524 
2526 {
2527  AVStream *st;
2528  uint8_t profile_level;
2529  int ret;
2530 
2531  if (c->fc->nb_streams < 1)
2532  return 0;
2533  st = c->fc->streams[c->fc->nb_streams-1];
2534 
2535  if (atom.size >= (1<<28) || atom.size < 7)
2536  return AVERROR_INVALIDDATA;
2537 
2538  profile_level = avio_r8(pb);
2539  if ((profile_level & 0xf0) != 0xc0)
2540  return 0;
2541 
2542  avio_seek(pb, 6, SEEK_CUR);
2543  ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size - 7);
2544  if (ret < 0)
2545  return ret;
2546 
2547  return 0;
2548 }
2549 
2551 {
2552  AVStream* st;
2553  MOVStreamContext* sc;
2554 
2555  if (c->fc->nb_streams < 1)
2556  return 0;
2557 
2558  /* For SBAS this should be fine - though beware if someone implements a
2559  * tref atom processor that doesn't drop down to default then this may
2560  * be lost. */
2561  if (atom.size > 4) {
2562  av_log(c->fc, AV_LOG_ERROR, "Only a single tref of type sbas is supported\n");
2563  return AVERROR_PATCHWELCOME;
2564  }
2565 
2566  st = c->fc->streams[c->fc->nb_streams - 1];
2567  sc = st->priv_data;
2568  sc->tref_id = avio_rb32(pb);
2570 
2571  return 0;
2572 }
2573 
2574 /**
2575  * An strf atom is a BITMAPINFOHEADER struct. This struct is 40 bytes itself,
2576  * but can have extradata appended at the end after the 40 bytes belonging
2577  * to the struct.
2578  */
2580 {
2581  AVStream *st;
2582  int ret;
2583 
2584  if (c->fc->nb_streams < 1)
2585  return 0;
2586  if (atom.size <= 40)
2587  return 0;
2588  st = c->fc->streams[c->fc->nb_streams-1];
2589 
2590  if ((uint64_t)atom.size > (1<<30))
2591  return AVERROR_INVALIDDATA;
2592 
2593  avio_skip(pb, 40);
2594  ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size - 40);
2595  if (ret < 0)
2596  return ret;
2597 
2598  return 0;
2599 }
2600 
2602 {
2603  AVStream *st;
2604  MOVStreamContext *sc;
2605  unsigned int i, entries;
2606 
2607  if (c->trak_index < 0) {
2608  av_log(c->fc, AV_LOG_WARNING, "STCO outside TRAK\n");
2609  return 0;
2610  }
2611  if (c->fc->nb_streams < 1)
2612  return 0;
2613  st = c->fc->streams[c->fc->nb_streams-1];
2614  sc = st->priv_data;
2615 
2616  avio_r8(pb); /* version */
2617  avio_rb24(pb); /* flags */
2618 
2619  // Clamp allocation size for `chunk_offsets` -- don't throw an error for an
2620  // invalid count since the EOF path doesn't throw either.
2621  entries = avio_rb32(pb);
2622  entries =
2623  FFMIN(entries,
2624  FFMAX(0, (atom.size - 8) /
2625  (atom.type == MKTAG('s', 't', 'c', 'o') ? 4 : 8)));
2626 
2627  if (!entries)
2628  return 0;
2629 
2630  if (sc->chunk_offsets) {
2631  av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicated STCO atom\n");
2632  return 0;
2633  }
2634 
2635  av_free(sc->chunk_offsets);
2636  sc->chunk_count = 0;
2637  sc->chunk_offsets = av_malloc_array(entries, sizeof(*sc->chunk_offsets));
2638  if (!sc->chunk_offsets)
2639  return AVERROR(ENOMEM);
2640  sc->chunk_count = entries;
2641 
2642  if (atom.type == MKTAG('s','t','c','o'))
2643  for (i = 0; i < entries && !pb->eof_reached; i++)
2644  sc->chunk_offsets[i] = avio_rb32(pb);
2645  else if (atom.type == MKTAG('c','o','6','4'))
2646  for (i = 0; i < entries && !pb->eof_reached; i++) {
2647  sc->chunk_offsets[i] = avio_rb64(pb);
2648  if (sc->chunk_offsets[i] < 0) {
2649  av_log(c->fc, AV_LOG_WARNING, "Impossible chunk_offset\n");
2650  sc->chunk_offsets[i] = 0;
2651  }
2652  }
2653  else
2654  return AVERROR_INVALIDDATA;
2655 
2656  sc->chunk_count = i;
2657 
2658  if (pb->eof_reached) {
2659  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STCO atom\n");
2660  return AVERROR_EOF;
2661  }
2662 
2663  return 0;
2664 }
2665 
2666 static int mov_codec_id(AVStream *st, uint32_t format)
2667 {
2669 
2670  if (id <= 0 &&
2671  ((format & 0xFFFF) == 'm' + ('s' << 8) ||
2672  (format & 0xFFFF) == 'T' + ('S' << 8)))
2674 
2675  if (st->codecpar->codec_type != AVMEDIA_TYPE_VIDEO && id > 0) {
2677  } else if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO &&
2678  /* skip old ASF MPEG-4 tag */
2679  format && format != MKTAG('m','p','4','s')) {
2681  if (id <= 0)
2683  if (id > 0)
2685  else if (st->codecpar->codec_type == AVMEDIA_TYPE_DATA ||
2687  st->codecpar->codec_id == AV_CODEC_ID_NONE)) {
2689  if (id <= 0) {
2691  AV_CODEC_ID_TTML : id;
2692  }
2693 
2694  if (id > 0)
2696  else
2698  }
2699  }
2700 
2701  st->codecpar->codec_tag = format;
2702 
2703  return id;
2704 }
2705 
2707  AVStream *st, MOVStreamContext *sc)
2708 {
2709  uint8_t codec_name[32] = { 0 };
2710  int64_t stsd_start;
2711  unsigned int len;
2712  uint32_t id = 0;
2713 
2714  /* The first 16 bytes of the video sample description are already
2715  * read in ff_mov_read_stsd_entries() */
2716  stsd_start = avio_tell(pb) - 16;
2717 
2718  if (c->isom) {
2719  avio_skip(pb, 2); /* pre_defined */
2720  avio_skip(pb, 2); /* reserved */
2721  avio_skip(pb, 12); /* pre_defined */
2722  } else {
2723  avio_rb16(pb); /* version */
2724  avio_rb16(pb); /* revision level */
2725  id = avio_rl32(pb); /* vendor */
2726  av_dict_set(&st->metadata, "vendor_id", av_fourcc2str(id), 0);
2727  avio_rb32(pb); /* temporal quality */
2728  avio_rb32(pb); /* spatial quality */
2729  }
2730 
2731  st->codecpar->width = avio_rb16(pb); /* width */
2732  st->codecpar->height = avio_rb16(pb); /* height */
2733 
2734  avio_rb32(pb); /* horiz resolution */
2735  avio_rb32(pb); /* vert resolution */
2736  avio_rb32(pb); /* data size, always 0 */
2737  avio_rb16(pb); /* frames per samples */
2738 
2739  len = avio_r8(pb); /* codec name, pascal string */
2740  if (len > 31)
2741  len = 31;
2742  mov_read_mac_string(c, pb, len, codec_name, sizeof(codec_name));
2743  if (len < 31)
2744  avio_skip(pb, 31 - len);
2745 
2746  if (codec_name[0])
2747  av_dict_set(&st->metadata, "encoder", codec_name, 0);
2748 
2749  /* codec_tag YV12 triggers an UV swap in rawdec.c */
2750  if (!strncmp(codec_name, "Planar Y'CbCr 8-bit 4:2:0", 25)) {
2751  st->codecpar->codec_tag = MKTAG('I', '4', '2', '0');
2752  st->codecpar->width &= ~1;
2753  st->codecpar->height &= ~1;
2754  }
2755  /* Flash Media Server uses tag H.263 with Sorenson Spark */
2756  if (st->codecpar->codec_tag == MKTAG('H','2','6','3') &&
2757  !strncmp(codec_name, "Sorenson H263", 13))
2759 
2760  st->codecpar->bits_per_coded_sample = avio_rb16(pb); /* depth */
2761 
2762  avio_seek(pb, stsd_start, SEEK_SET);
2763 
2764  if (ff_get_qtpalette(st->codecpar->codec_id, pb, sc->palette)) {
2765  st->codecpar->bits_per_coded_sample &= 0x1F;
2766  sc->has_palette = 1;
2767  }
2768 }
2769 
2771  AVStream *st, MOVStreamContext *sc)
2772 {
2773  int bits_per_sample, flags;
2774  uint16_t version = avio_rb16(pb);
2775  uint32_t id = 0;
2776  AVDictionaryEntry *compatible_brands = av_dict_get(c->fc->metadata, "compatible_brands", NULL, AV_DICT_MATCH_CASE);
2777  int channel_count;
2778 
2779  if (c->isom)
2780  avio_skip(pb, 6); /* reserved */
2781  else {
2782  avio_rb16(pb); /* revision level */
2783  id = avio_rl32(pb); /* vendor */
2784  av_dict_set(&st->metadata, "vendor_id", av_fourcc2str(id), 0);
2785  }
2786 
2787  channel_count = avio_rb16(pb);
2788 
2790  st->codecpar->ch_layout.nb_channels = channel_count;
2791  st->codecpar->bits_per_coded_sample = avio_rb16(pb); /* sample size */
2792  av_log(c->fc, AV_LOG_TRACE, "audio channels %d\n", channel_count);
2793 
2794  sc->audio_cid = avio_rb16(pb);
2795  avio_rb16(pb); /* packet size = 0 */
2796 
2797  st->codecpar->sample_rate = ((avio_rb32(pb) >> 16));
2798 
2799  // Read QT version 1 fields. In version 0 these do not exist.
2800  av_log(c->fc, AV_LOG_TRACE, "version =%d, isom =%d\n", version, c->isom);
2801  if (!c->isom ||
2802  (compatible_brands && strstr(compatible_brands->value, "qt ")) ||
2803  (sc->stsd_version == 0 && version > 0)) {
2804  if (version == 1) {
2805  sc->samples_per_frame = avio_rb32(pb);
2806  avio_rb32(pb); /* bytes per packet */
2807  sc->bytes_per_frame = avio_rb32(pb);
2808  avio_rb32(pb); /* bytes per sample */
2809  } else if (version == 2) {
2810  avio_rb32(pb); /* sizeof struct only */
2812  channel_count = avio_rb32(pb);
2814  st->codecpar->ch_layout.nb_channels = channel_count;
2815  avio_rb32(pb); /* always 0x7F000000 */
2817 
2818  flags = avio_rb32(pb); /* lpcm format specific flag */
2819  sc->bytes_per_frame = avio_rb32(pb);
2820  sc->samples_per_frame = avio_rb32(pb);
2821  if (st->codecpar->codec_tag == MKTAG('l','p','c','m'))
2822  st->codecpar->codec_id =
2824  flags);
2825  }
2826  if (version == 0 || (version == 1 && sc->audio_cid != -2)) {
2827  /* can't correctly handle variable sized packet as audio unit */
2828  switch (st->codecpar->codec_id) {
2829  case AV_CODEC_ID_MP2:
2830  case AV_CODEC_ID_MP3:
2832  break;
2833  }
2834  }
2835  }
2836 
2837  if (sc->format == 0) {
2838  if (st->codecpar->bits_per_coded_sample == 8)
2839  st->codecpar->codec_id = mov_codec_id(st, MKTAG('r','a','w',' '));
2840  else if (st->codecpar->bits_per_coded_sample == 16)
2841  st->codecpar->codec_id = mov_codec_id(st, MKTAG('t','w','o','s'));
2842  }
2843 
2844  switch (st->codecpar->codec_id) {
2845  case AV_CODEC_ID_PCM_S8:
2846  case AV_CODEC_ID_PCM_U8:
2847  if (st->codecpar->bits_per_coded_sample == 16)
2849  break;
2850  case AV_CODEC_ID_PCM_S16LE:
2851  case AV_CODEC_ID_PCM_S16BE:
2852  if (st->codecpar->bits_per_coded_sample == 8)
2854  else if (st->codecpar->bits_per_coded_sample == 24)
2855  st->codecpar->codec_id =
2858  else if (st->codecpar->bits_per_coded_sample == 32)
2859  st->codecpar->codec_id =
2862  break;
2863  /* set values for old format before stsd version 1 appeared */
2864  case AV_CODEC_ID_MACE3:
2865  sc->samples_per_frame = 6;
2867  break;
2868  case AV_CODEC_ID_MACE6:
2869  sc->samples_per_frame = 6;
2871  break;
2873  sc->samples_per_frame = 64;
2875  break;
2876  case AV_CODEC_ID_GSM:
2877  sc->samples_per_frame = 160;
2878  sc->bytes_per_frame = 33;
2879  break;
2880  default:
2881  break;
2882  }
2883 
2884  bits_per_sample = av_get_bits_per_sample(st->codecpar->codec_id);
2885  if (bits_per_sample && (bits_per_sample >> 3) * (uint64_t)st->codecpar->ch_layout.nb_channels <= INT_MAX) {
2886  st->codecpar->bits_per_coded_sample = bits_per_sample;
2887  sc->sample_size = (bits_per_sample >> 3) * st->codecpar->ch_layout.nb_channels;
2888  }
2889 }
2890 
2892  AVStream *st, MOVStreamContext *sc,
2893  int64_t size)
2894 {
2895  // ttxt stsd contains display flags, justification, background
2896  // color, fonts, and default styles, so fake an atom to read it
2897  MOVAtom fake_atom = { .size = size };
2898  // mp4s contains a regular esds atom, dfxp ISMV TTML has no content
2899  // in extradata unlike stpp MP4 TTML.
2900  if (st->codecpar->codec_tag != AV_RL32("mp4s") &&
2902  mov_read_glbl(c, pb, fake_atom);
2903  st->codecpar->width = sc->width;
2904  st->codecpar->height = sc->height;
2905 }
2906 
2908  AVStream *st, MOVStreamContext *sc,
2909  int64_t size)
2910 {
2911  int ret;
2912 
2913  if (st->codecpar->codec_tag == MKTAG('t','m','c','d')) {
2914  if ((int)size != size)
2915  return AVERROR(ENOMEM);
2916 
2917  ret = ff_get_extradata(c->fc, st->codecpar, pb, size);
2918  if (ret < 0)
2919  return ret;
2920  if (size > 16) {
2921  MOVStreamContext *tmcd_ctx = st->priv_data;
2922  int val;
2923  val = AV_RB32(st->codecpar->extradata + 4);
2924  tmcd_ctx->tmcd_flags = val;
2925  st->avg_frame_rate.num = AV_RB32(st->codecpar->extradata + 8); /* timescale */
2926  st->avg_frame_rate.den = AV_RB32(st->codecpar->extradata + 12); /* frameDuration */
2927  tmcd_ctx->tmcd_nb_frames = st->codecpar->extradata[16]; /* number of frames */
2928  if (size > 30) {
2929  uint32_t len = AV_RB32(st->codecpar->extradata + 18); /* name atom length */
2930  uint32_t format = AV_RB32(st->codecpar->extradata + 22);
2931  if (format == AV_RB32("name") && (int64_t)size >= (int64_t)len + 18) {
2932  uint16_t str_size = AV_RB16(st->codecpar->extradata + 26); /* string length */
2933  if (str_size > 0 && size >= (int)str_size + 30 &&
2934  st->codecpar->extradata[30] /* Don't add empty string */) {
2935  char *reel_name = av_malloc(str_size + 1);
2936  if (!reel_name)
2937  return AVERROR(ENOMEM);
2938  memcpy(reel_name, st->codecpar->extradata + 30, str_size);
2939  reel_name[str_size] = 0; /* Add null terminator */
2940  av_dict_set(&st->metadata, "reel_name", reel_name,
2942  }
2943  }
2944  }
2945  }
2946  } else {
2947  /* other codec type, just skip (rtp, mp4s ...) */
2948  avio_skip(pb, size);
2949  }
2950  return 0;
2951 }
2952 
2954  AVStream *st, MOVStreamContext *sc)
2955 {
2956  FFStream *const sti = ffstream(st);
2957 
2958  if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
2959  !st->codecpar->sample_rate && sc->time_scale > 1)
2960  st->codecpar->sample_rate = sc->time_scale;
2961 
2962  /* special codec parameters handling */
2963  switch (st->codecpar->codec_id) {
2964 #if CONFIG_DV_DEMUXER
2965  case AV_CODEC_ID_DVAUDIO:
2966  if (c->dv_fctx) {
2967  avpriv_request_sample(c->fc, "multiple DV audio streams");
2968  return AVERROR(ENOSYS);
2969  }
2970 
2971  c->dv_fctx = avformat_alloc_context();
2972  if (!c->dv_fctx) {
2973  av_log(c->fc, AV_LOG_ERROR, "dv demux context alloc error\n");
2974  return AVERROR(ENOMEM);
2975  }
2976  c->dv_demux = avpriv_dv_init_demux(c->dv_fctx);
2977  if (!c->dv_demux) {
2978  av_log(c->fc, AV_LOG_ERROR, "dv demux context init error\n");
2979  return AVERROR(ENOMEM);
2980  }
2981  sc->dv_audio_container = 1;
2983  break;
2984 #endif
2985  /* no ifdef since parameters are always those */
2986  case AV_CODEC_ID_QCELP:
2989  // force sample rate for qcelp when not stored in mov
2990  if (st->codecpar->codec_tag != MKTAG('Q','c','l','p'))
2991  st->codecpar->sample_rate = 8000;
2992  // FIXME: Why is the following needed for some files?
2993  sc->samples_per_frame = 160;
2994  if (!sc->bytes_per_frame)
2995  sc->bytes_per_frame = 35;
2996  break;
2997  case AV_CODEC_ID_AMR_NB:
3000  /* force sample rate for amr, stsd in 3gp does not store sample rate */
3001  st->codecpar->sample_rate = 8000;
3002  break;
3003  case AV_CODEC_ID_AMR_WB:
3006  st->codecpar->sample_rate = 16000;
3007  break;
3008  case AV_CODEC_ID_MP2:
3009  case AV_CODEC_ID_MP3:
3010  /* force type after stsd for m1a hdlr */
3012  break;
3013  case AV_CODEC_ID_GSM:
3014  case AV_CODEC_ID_ADPCM_MS:
3016  case AV_CODEC_ID_ILBC:
3017  case AV_CODEC_ID_MACE3:
3018  case AV_CODEC_ID_MACE6:
3019  case AV_CODEC_ID_QDM2:
3021  break;
3022  case AV_CODEC_ID_ALAC:
3023  if (st->codecpar->extradata_size == 36) {
3024  int channel_count = AV_RB8(st->codecpar->extradata + 21);
3025  if (st->codecpar->ch_layout.nb_channels != channel_count) {
3028  st->codecpar->ch_layout.nb_channels = channel_count;
3029  }
3030  st->codecpar->sample_rate = AV_RB32(st->codecpar->extradata + 32);
3031  }
3032  break;
3033  case AV_CODEC_ID_AC3:
3034  case AV_CODEC_ID_EAC3:
3036  case AV_CODEC_ID_VC1:
3037  case AV_CODEC_ID_VP8:
3038  case AV_CODEC_ID_VP9:
3040  break;
3042  case AV_CODEC_ID_PRORES:
3043  case AV_CODEC_ID_APV:
3044  case AV_CODEC_ID_EVC:
3045  case AV_CODEC_ID_AV1:
3046  /* field_order detection of H264 requires parsing */
3047  case AV_CODEC_ID_H264:
3049  break;
3050  default:
3051  break;
3052  }
3053  return 0;
3054 }
3055 
3057  int codec_tag, int format,
3058  int64_t size)
3059 {
3060  if (codec_tag &&
3061  (codec_tag != format &&
3062  // AVID 1:1 samples with differing data format and codec tag exist
3063  (codec_tag != AV_RL32("AV1x") || format != AV_RL32("AVup")) &&
3064  // prores is allowed to have differing data format and codec tag
3065  codec_tag != AV_RL32("apcn") && codec_tag != AV_RL32("apch") &&
3066  // so is dv (sigh)
3067  codec_tag != AV_RL32("dvpp") && codec_tag != AV_RL32("dvcp") &&
3068  (c->fc->video_codec_id ? ff_codec_get_id(ff_codec_movvideo_tags, format) != c->fc->video_codec_id
3069  : codec_tag != MKTAG('j','p','e','g')))) {
3070  /* Multiple fourcc, we skip JPEG. This is not correct, we should
3071  * export it as a separate AVStream but this needs a few changes
3072  * in the MOV demuxer, patch welcome. */
3073 
3074  av_log(c->fc, AV_LOG_WARNING, "multiple fourcc not supported\n");
3075  avio_skip(pb, size);
3076  return 1;
3077  }
3078 
3079  return 0;
3080 }
3081 
3083 {
3084  int ret;
3085 
3086  /* special codec parameters handling */
3087  switch (st->codecpar->codec_id) {
3088  case AV_CODEC_ID_H264:
3089  // done for ai5q, ai52, ai55, ai1q, ai12 and ai15.
3090  if (!st->codecpar->extradata_size && TAG_IS_AVCI(st->codecpar->codec_tag)) {
3092  if (ret < 0)
3093  return ret;
3094  }
3095  break;
3096  default:
3097  break;
3098  }
3099 
3100  return 0;
3101 }
3102 
3104 {
3105  AVStream *st;
3106  MOVStreamContext *sc;
3107  int pseudo_stream_id;
3108 
3109  av_assert0 (c->fc->nb_streams >= 1);
3110  st = c->fc->streams[c->fc->nb_streams-1];
3111  sc = st->priv_data;
3112 
3113  for (pseudo_stream_id = 0;
3114  pseudo_stream_id < entries && !pb->eof_reached;
3115  pseudo_stream_id++) {
3116  //Parsing Sample description table
3117  enum AVCodecID id;
3118  int ret, dref_id = 1;
3119  MOVAtom a = { AV_RL32("stsd") };
3120  int64_t start_pos = avio_tell(pb);
3121  int64_t size = avio_rb32(pb); /* size */
3122  uint32_t format = avio_rl32(pb); /* data format */
3123 
3124  if (size >= 16) {
3125  avio_rb32(pb); /* reserved */
3126  avio_rb16(pb); /* reserved */
3127  dref_id = avio_rb16(pb);
3128  } else if (size <= 7) {
3129  av_log(c->fc, AV_LOG_ERROR,
3130  "invalid size %"PRId64" in stsd\n", size);
3131  return AVERROR_INVALIDDATA;
3132  }
3133 
3135  size - (avio_tell(pb) - start_pos))) {
3136  sc->stsd_count++;
3137  continue;
3138  }
3139 
3140  sc->pseudo_stream_id = st->codecpar->codec_tag ? -1 : pseudo_stream_id;
3141  sc->dref_id= dref_id;
3142  sc->format = format;
3143 
3144  id = mov_codec_id(st, format);
3145 
3146  av_log(c->fc, AV_LOG_TRACE,
3147  "size=%"PRId64" 4CC=%s codec_type=%d\n", size,
3149 
3150  st->codecpar->codec_id = id;
3152  mov_parse_stsd_video(c, pb, st, sc);
3153  } else if (st->codecpar->codec_type==AVMEDIA_TYPE_AUDIO) {
3154  mov_parse_stsd_audio(c, pb, st, sc);
3155  if (st->codecpar->sample_rate < 0) {
3156  av_log(c->fc, AV_LOG_ERROR, "Invalid sample rate %d\n", st->codecpar->sample_rate);
3157  return AVERROR_INVALIDDATA;
3158  }
3159  if (st->codecpar->ch_layout.nb_channels < 0) {
3160  av_log(c->fc, AV_LOG_ERROR, "Invalid channels %d\n", st->codecpar->ch_layout.nb_channels);
3161  return AVERROR_INVALIDDATA;
3162  }
3163  } else if (st->codecpar->codec_type==AVMEDIA_TYPE_SUBTITLE){
3164  mov_parse_stsd_subtitle(c, pb, st, sc,
3165  size - (avio_tell(pb) - start_pos));
3166  } else {
3167  ret = mov_parse_stsd_data(c, pb, st, sc,
3168  size - (avio_tell(pb) - start_pos));
3169  if (ret < 0)
3170  return ret;
3171  }
3172  /* this will read extra atoms at the end (wave, alac, damr, avcC, hvcC, SMI ...) */
3173  a.size = size - (avio_tell(pb) - start_pos);
3174  if (a.size > 8) {
3175  if ((ret = mov_read_default(c, pb, a)) < 0)
3176  return ret;
3177  } else if (a.size > 0)
3178  avio_skip(pb, a.size);
3179 
3180  ret = mov_finalize_stsd_entry(c, st);
3181  if (ret < 0)
3182  return ret;
3183 
3184  if (sc->extradata && st->codecpar->extradata) {
3185  int extra_size = st->codecpar->extradata_size;
3186 
3187  /* Move the current stream extradata to the stream context one. */
3188  sc->extradata_size[pseudo_stream_id] = extra_size;
3189  sc->extradata[pseudo_stream_id] = st->codecpar->extradata;
3190  st->codecpar->extradata = NULL;
3191  st->codecpar->extradata_size = 0;
3192  }
3193  sc->stsd_count++;
3194  }
3195 
3196  if (pb->eof_reached) {
3197  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSD atom\n");
3198  return AVERROR_EOF;
3199  }
3200 
3201  return 0;
3202 }
3203 
3205 {
3206  AVStream *st;
3207  MOVStreamContext *sc;
3208  int ret, entries;
3209 
3210  if (c->fc->nb_streams < 1)
3211  return 0;
3212  st = c->fc->streams[c->fc->nb_streams - 1];
3213  sc = st->priv_data;
3214 
3215  if (sc->extradata) {
3216  av_log(c->fc, AV_LOG_ERROR,
3217  "Duplicate stsd found in this track.\n");
3218  return AVERROR_INVALIDDATA;
3219  }
3220 
3221  sc->stsd_version = avio_r8(pb);
3222  avio_rb24(pb); /* flags */
3223  entries = avio_rb32(pb);
3224 
3225  /* Each entry contains a size (4 bytes) and format (4 bytes). */
3226  if (entries <= 0 || entries > atom.size / 8 || entries > 1024) {
3227  av_log(c->fc, AV_LOG_ERROR, "invalid STSD entries %d\n", entries);
3228  return AVERROR_INVALIDDATA;
3229  }
3230 
3231  /* Prepare space for hosting multiple extradata. */
3232  sc->extradata = av_calloc(entries, sizeof(*sc->extradata));
3233  if (!sc->extradata)
3234  return AVERROR(ENOMEM);
3235 
3236  sc->extradata_size = av_calloc(entries, sizeof(*sc->extradata_size));
3237  if (!sc->extradata_size) {
3238  ret = AVERROR(ENOMEM);
3239  goto fail;
3240  }
3241 
3242  ret = ff_mov_read_stsd_entries(c, pb, entries);
3243  if (ret < 0)
3244  goto fail;
3245 
3246  /* Restore back the primary extradata. */
3247  av_freep(&st->codecpar->extradata);
3248  st->codecpar->extradata_size = sc->extradata_size[0];
3249  if (sc->extradata_size[0]) {
3251  if (!st->codecpar->extradata)
3252  return AVERROR(ENOMEM);
3253  memcpy(st->codecpar->extradata, sc->extradata[0], sc->extradata_size[0]);
3254  }
3255 
3256  return mov_finalize_stsd_codec(c, pb, st, sc);
3257 fail:
3258  if (sc->extradata) {
3259  int j;
3260  for (j = 0; j < sc->stsd_count; j++)
3261  av_freep(&sc->extradata[j]);
3262  }
3263 
3264  sc->stsd_count = 0;
3265  av_freep(&sc->extradata);
3266  av_freep(&sc->extradata_size);
3267  return ret;
3268 }
3269 
3271 {
3272  AVStream *st;
3273  MOVStreamContext *sc;
3274  unsigned int i, entries;
3275 
3276  if (c->trak_index < 0) {
3277  av_log(c->fc, AV_LOG_WARNING, "STSC outside TRAK\n");
3278  return 0;
3279  }
3280 
3281  if (c->fc->nb_streams < 1)
3282  return 0;
3283  st = c->fc->streams[c->fc->nb_streams-1];
3284  sc = st->priv_data;
3285 
3286  avio_r8(pb); /* version */
3287  avio_rb24(pb); /* flags */
3288 
3289  entries = avio_rb32(pb);
3290  if ((uint64_t)entries * 12 + 4 > atom.size)
3291  return AVERROR_INVALIDDATA;
3292 
3293  av_log(c->fc, AV_LOG_TRACE, "track[%u].stsc.entries = %u\n", c->fc->nb_streams - 1, entries);
3294 
3295  if (!entries)
3296  return 0;
3297  if (sc->stsc_data) {
3298  av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicated STSC atom\n");
3299  return 0;
3300  }
3301  av_free(sc->stsc_data);
3302  sc->stsc_count = 0;
3303  sc->stsc_data = av_malloc_array(entries, sizeof(*sc->stsc_data));
3304  if (!sc->stsc_data)
3305  return AVERROR(ENOMEM);
3306 
3307  for (i = 0; i < entries && !pb->eof_reached; i++) {
3308  sc->stsc_data[i].first = avio_rb32(pb);
3309  sc->stsc_data[i].count = avio_rb32(pb);
3310  sc->stsc_data[i].id = avio_rb32(pb);
3311  }
3312 
3313  sc->stsc_count = i;
3314  for (i = sc->stsc_count - 1; i < UINT_MAX; i--) {
3315  int64_t first_min = i + 1;
3316  if ((i+1 < sc->stsc_count && sc->stsc_data[i].first >= sc->stsc_data[i+1].first) ||
3317  (i > 0 && sc->stsc_data[i].first <= sc->stsc_data[i-1].first) ||
3318  sc->stsc_data[i].first < first_min ||
3319  sc->stsc_data[i].count < 1 ||
3320  sc->stsc_data[i].id < 1) {
3321  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);
3322  if (i+1 >= sc->stsc_count) {
3323  if (sc->stsc_data[i].count == 0 && i > 0) {
3324  sc->stsc_count --;
3325  continue;
3326  }
3327  sc->stsc_data[i].first = FFMAX(sc->stsc_data[i].first, first_min);
3328  if (i > 0 && sc->stsc_data[i].first <= sc->stsc_data[i-1].first)
3329  sc->stsc_data[i].first = FFMIN(sc->stsc_data[i-1].first + 1LL, INT_MAX);
3330  sc->stsc_data[i].count = FFMAX(sc->stsc_data[i].count, 1);
3331  sc->stsc_data[i].id = FFMAX(sc->stsc_data[i].id, 1);
3332  continue;
3333  }
3334  av_assert0(sc->stsc_data[i+1].first >= 2);
3335  // We replace this entry by the next valid
3336  sc->stsc_data[i].first = sc->stsc_data[i+1].first - 1;
3337  sc->stsc_data[i].count = sc->stsc_data[i+1].count;
3338  sc->stsc_data[i].id = sc->stsc_data[i+1].id;
3339  }
3340  }
3341 
3342  if (pb->eof_reached) {
3343  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSC atom\n");
3344  return AVERROR_EOF;
3345  }
3346 
3347  return 0;
3348 }
3349 
3350 static inline int mov_stsc_index_valid(unsigned int index, unsigned int count)
3351 {
3352  return index < count - 1;
3353 }
3354 
3355 /* Compute the samples value for the stsc entry at the given index. */
3356 static inline int64_t mov_get_stsc_samples(MOVStreamContext *sc, unsigned int index)
3357 {
3358  int chunk_count;
3359 
3361  chunk_count = sc->stsc_data[index + 1].first - sc->stsc_data[index].first;
3362  else {
3363  // Validation for stsc / stco happens earlier in mov_read_stsc + mov_read_trak.
3365  chunk_count = sc->chunk_count - (sc->stsc_data[index].first - 1);
3366  }
3367 
3368  return sc->stsc_data[index].count * (int64_t)chunk_count;
3369 }
3370 
3372 {
3373  AVStream *st;
3374  MOVStreamContext *sc;
3375  unsigned i, entries;
3376 
3377  if (c->trak_index < 0) {
3378  av_log(c->fc, AV_LOG_WARNING, "STPS outside TRAK\n");
3379  return 0;
3380  }
3381 
3382  if (c->fc->nb_streams < 1)
3383  return 0;
3384  st = c->fc->streams[c->fc->nb_streams-1];
3385  sc = st->priv_data;
3386 
3387  avio_rb32(pb); // version + flags
3388 
3389  entries = avio_rb32(pb);
3390  if (sc->stps_data)
3391  av_log(c->fc, AV_LOG_WARNING, "Duplicated STPS atom\n");
3392  av_free(sc->stps_data);
3393  sc->stps_count = 0;
3394  sc->stps_data = av_malloc_array(entries, sizeof(*sc->stps_data));
3395  if (!sc->stps_data)
3396  return AVERROR(ENOMEM);
3397 
3398  for (i = 0; i < entries && !pb->eof_reached; i++) {
3399  sc->stps_data[i] = avio_rb32(pb);
3400  }
3401 
3402  sc->stps_count = i;
3403 
3404  if (pb->eof_reached) {
3405  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STPS atom\n");
3406  return AVERROR_EOF;
3407  }
3408 
3409  return 0;
3410 }
3411 
3413 {
3414  AVStream *st;
3415  FFStream *sti;
3416  MOVStreamContext *sc;
3417  unsigned int i, entries;
3418 
3419  if (c->trak_index < 0) {
3420  av_log(c->fc, AV_LOG_WARNING, "STSS outside TRAK\n");
3421  return 0;
3422  }
3423 
3424  if (c->fc->nb_streams < 1)
3425  return 0;
3426  st = c->fc->streams[c->fc->nb_streams-1];
3427  sti = ffstream(st);
3428  sc = st->priv_data;
3429 
3430  avio_r8(pb); /* version */
3431  avio_rb24(pb); /* flags */
3432 
3433  entries = avio_rb32(pb);
3434 
3435  av_log(c->fc, AV_LOG_TRACE, "keyframe_count = %u\n", entries);
3436 
3437  if (!entries) {
3438  sc->keyframe_absent = 1;
3439  if (!sti->need_parsing && st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
3441  return 0;
3442  }
3443  if (sc->keyframes)
3444  av_log(c->fc, AV_LOG_WARNING, "Duplicated STSS atom\n");
3445  if (entries >= UINT_MAX / sizeof(int))
3446  return AVERROR_INVALIDDATA;
3447  av_freep(&sc->keyframes);
3448  sc->keyframe_count = 0;
3449  sc->keyframes = av_malloc_array(entries, sizeof(*sc->keyframes));
3450  if (!sc->keyframes)
3451  return AVERROR(ENOMEM);
3452 
3453  for (i = 0; i < entries && !pb->eof_reached; i++) {
3454  sc->keyframes[i] = avio_rb32(pb);
3455  }
3456 
3457  sc->keyframe_count = i;
3458 
3459  if (pb->eof_reached) {
3460  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSS atom\n");
3461  return AVERROR_EOF;
3462  }
3463 
3464  return 0;
3465 }
3466 
3468 {
3469  AVStream *st;
3470  MOVStreamContext *sc;
3471  unsigned int i, entries, sample_size, field_size, num_bytes;
3472  GetBitContext gb;
3473  unsigned char* buf;
3474  int ret;
3475 
3476  if (c->trak_index < 0) {
3477  av_log(c->fc, AV_LOG_WARNING, "STSZ outside TRAK\n");
3478  return 0;
3479  }
3480 
3481  if (c->fc->nb_streams < 1)
3482  return 0;
3483  st = c->fc->streams[c->fc->nb_streams-1];
3484  sc = st->priv_data;
3485 
3486  avio_r8(pb); /* version */
3487  avio_rb24(pb); /* flags */
3488 
3489  if (atom.type == MKTAG('s','t','s','z')) {
3490  sample_size = avio_rb32(pb);
3491  if (!sc->sample_size) /* do not overwrite value computed in stsd */
3492  sc->sample_size = sample_size;
3493  sc->stsz_sample_size = sample_size;
3494  field_size = 32;
3495  } else {
3496  sample_size = 0;
3497  avio_rb24(pb); /* reserved */
3498  field_size = avio_r8(pb);
3499  }
3500  entries = avio_rb32(pb);
3501 
3502  av_log(c->fc, AV_LOG_TRACE, "sample_size = %u sample_count = %u\n", sc->sample_size, entries);
3503 
3504  sc->sample_count = entries;
3505  if (sample_size)
3506  return 0;
3507 
3508  if (field_size != 4 && field_size != 8 && field_size != 16 && field_size != 32) {
3509  av_log(c->fc, AV_LOG_ERROR, "Invalid sample field size %u\n", field_size);
3510  return AVERROR_INVALIDDATA;
3511  }
3512 
3513  if (!entries)
3514  return 0;
3515  if (entries >= (INT_MAX - 4 - 8 * AV_INPUT_BUFFER_PADDING_SIZE) / field_size)
3516  return AVERROR_INVALIDDATA;
3517  if (sc->sample_sizes)
3518  av_log(c->fc, AV_LOG_WARNING, "Duplicated STSZ atom\n");
3519  av_free(sc->sample_sizes);
3520  sc->sample_count = 0;
3521  sc->sample_sizes = av_malloc_array(entries, sizeof(*sc->sample_sizes));
3522  if (!sc->sample_sizes)
3523  return AVERROR(ENOMEM);
3524 
3525  num_bytes = (entries*field_size+4)>>3;
3526 
3527  buf = av_malloc(num_bytes+AV_INPUT_BUFFER_PADDING_SIZE);
3528  if (!buf) {
3529  av_freep(&sc->sample_sizes);
3530  return AVERROR(ENOMEM);
3531  }
3532 
3533  ret = ffio_read_size(pb, buf, num_bytes);
3534  if (ret < 0) {
3535  av_freep(&sc->sample_sizes);
3536  av_free(buf);
3537  av_log(c->fc, AV_LOG_WARNING, "STSZ atom truncated\n");
3538  return 0;
3539  }
3540 
3541  init_get_bits(&gb, buf, 8*num_bytes);
3542 
3543  for (i = 0; i < entries; i++) {
3544  sc->sample_sizes[i] = get_bits_long(&gb, field_size);
3545  if (sc->sample_sizes[i] > INT64_MAX - sc->data_size) {
3546  av_free(buf);
3547  av_log(c->fc, AV_LOG_ERROR, "Sample size overflow in STSZ\n");
3548  return AVERROR_INVALIDDATA;
3549  }
3550  sc->data_size += sc->sample_sizes[i];
3551  }
3552 
3553  sc->sample_count = i;
3554 
3555  av_free(buf);
3556 
3557  return 0;
3558 }
3559 
3561 {
3562  AVStream *st;
3563  MOVStreamContext *sc;
3564  unsigned int i, entries;
3565  int64_t duration = 0;
3566  int64_t total_sample_count = 0;
3567  int64_t current_dts = 0;
3568  int64_t corrected_dts = 0;
3569 
3570  if (c->trak_index < 0) {
3571  av_log(c->fc, AV_LOG_WARNING, "STTS outside TRAK\n");
3572  return 0;
3573  }
3574 
3575  if (c->fc->nb_streams < 1)
3576  return 0;
3577  st = c->fc->streams[c->fc->nb_streams-1];
3578  sc = st->priv_data;
3579 
3580  avio_r8(pb); /* version */
3581  avio_rb24(pb); /* flags */
3582  entries = avio_rb32(pb);
3583 
3584  av_log(c->fc, AV_LOG_TRACE, "track[%u].stts.entries = %u\n",
3585  c->fc->nb_streams-1, entries);
3586 
3587  if (sc->stts_data)
3588  av_log(c->fc, AV_LOG_WARNING, "Duplicated STTS atom\n");
3589  av_freep(&sc->stts_data);
3590  sc->stts_count = 0;
3591  if (entries >= INT_MAX / sizeof(*sc->stts_data))
3592  return AVERROR(ENOMEM);
3593 
3594  for (i = 0; i < entries && !pb->eof_reached; i++) {
3595  unsigned int sample_duration;
3596  unsigned int sample_count;
3597  unsigned int min_entries = FFMIN(FFMAX(i + 1, 1024 * 1024), entries);
3598  MOVStts *stts_data = av_fast_realloc(sc->stts_data, &sc->stts_allocated_size,
3599  min_entries * sizeof(*sc->stts_data));
3600  if (!stts_data) {
3601  av_freep(&sc->stts_data);
3602  sc->stts_count = 0;
3603  return AVERROR(ENOMEM);
3604  }
3605  sc->stts_count = min_entries;
3606  sc->stts_data = stts_data;
3607 
3608  sample_count = avio_rb32(pb);
3609  sample_duration = avio_rb32(pb);
3610 
3611  sc->stts_data[i].count= sample_count;
3612  sc->stts_data[i].duration= sample_duration;
3613 
3614  av_log(c->fc, AV_LOG_TRACE, "sample_count=%u, sample_duration=%u\n",
3615  sample_count, sample_duration);
3616 
3617  /* STTS sample offsets are uint32 but some files store it as int32
3618  * with negative values used to correct DTS delays.
3619  There may be abnormally large values as well. */
3620  if (sample_duration > c->max_stts_delta) {
3621  // assume high delta is a correction if negative when cast as int32
3622  int32_t delta_magnitude = (int32_t)sample_duration;
3623  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",
3624  sample_duration, i, sample_count, st->index);
3625  sc->stts_data[i].duration = 1;
3626  corrected_dts = av_sat_add64(corrected_dts, (delta_magnitude < 0 ? (int64_t)delta_magnitude : 1) * sample_count);
3627  } else {
3628  corrected_dts += sample_duration * (uint64_t)sample_count;
3629  }
3630 
3631  current_dts += sc->stts_data[i].duration * (uint64_t)sample_count;
3632 
3633  if (current_dts > corrected_dts) {
3634  int64_t drift = av_sat_sub64(current_dts, corrected_dts) / FFMAX(sample_count, 1);
3635  uint32_t correction = (sc->stts_data[i].duration > drift) ? drift : sc->stts_data[i].duration - 1;
3636  current_dts -= correction * (uint64_t)sample_count;
3637  sc->stts_data[i].duration -= correction;
3638  }
3639 
3640  duration+=(int64_t)sc->stts_data[i].duration*(uint64_t)sc->stts_data[i].count;
3641  total_sample_count+=sc->stts_data[i].count;
3642  }
3643 
3644  sc->stts_count = i;
3645 
3646  if (duration > 0 &&
3647  duration <= INT64_MAX - sc->duration_for_fps &&
3648  total_sample_count <= INT_MAX - sc->nb_frames_for_fps) {
3649  sc->duration_for_fps += duration;
3650  sc->nb_frames_for_fps += total_sample_count;
3651  }
3652 
3653  if (pb->eof_reached) {
3654  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STTS atom\n");
3655  return AVERROR_EOF;
3656  }
3657 
3658  st->nb_frames= total_sample_count;
3659  if (duration)
3660  st->duration= FFMIN(st->duration, duration);
3661 
3662  // All samples have zero duration. They have higher chance be chose by
3663  // mov_find_next_sample, which leads to seek again and again.
3664  //
3665  // It's AVERROR_INVALIDDATA actually, but such files exist in the wild.
3666  // So only mark data stream as discarded for safety.
3667  if (!duration && sc->stts_count &&
3669  av_log(c->fc, AV_LOG_WARNING,
3670  "All samples in data stream index:id [%d:%d] have zero "
3671  "duration, stream set to be discarded by default. Override "
3672  "using AVStream->discard or -discard for ffmpeg command.\n",
3673  st->index, sc->id);
3674  st->discard = AVDISCARD_ALL;
3675  }
3676  sc->track_end = duration;
3677  return 0;
3678 }
3679 
3681 {
3682  AVStream *st;
3683  MOVStreamContext *sc;
3684  unsigned int i;
3685  int64_t entries;
3686 
3687  if (c->fc->nb_streams < 1)
3688  return 0;
3689  st = c->fc->streams[c->fc->nb_streams - 1];
3690  sc = st->priv_data;
3691 
3692  avio_r8(pb); /* version */
3693  avio_rb24(pb); /* flags */
3694  entries = atom.size - 4;
3695 
3696  av_log(c->fc, AV_LOG_TRACE, "track[%u].sdtp.entries = %" PRId64 "\n",
3697  c->fc->nb_streams - 1, entries);
3698 
3699  if (sc->sdtp_data)
3700  av_log(c->fc, AV_LOG_WARNING, "Duplicated SDTP atom\n");
3701  av_freep(&sc->sdtp_data);
3702  sc->sdtp_count = 0;
3703 
3704  if (entries < 0 || entries > UINT_MAX)
3705  return AVERROR(ERANGE);
3706 
3707  sc->sdtp_data = av_malloc(entries);
3708  if (!sc->sdtp_data)
3709  return AVERROR(ENOMEM);
3710 
3711  for (i = 0; i < entries && !pb->eof_reached; i++)
3712  sc->sdtp_data[i] = avio_r8(pb);
3713  sc->sdtp_count = i;
3714 
3715  return 0;
3716 }
3717 
3718 static void mov_update_dts_shift(MOVStreamContext *sc, int duration, void *logctx)
3719 {
3720  if (duration < 0) {
3721  if (duration == INT_MIN) {
3722  av_log(logctx, AV_LOG_WARNING, "mov_update_dts_shift(): dts_shift set to %d\n", INT_MAX);
3723  duration++;
3724  }
3725  sc->dts_shift = FFMAX(sc->dts_shift, -duration);
3726  }
3727 }
3728 
3730 {
3731  AVStream *st;
3732  MOVStreamContext *sc;
3733  unsigned int i, entries, ctts_count = 0;
3734 
3735  if (c->trak_index < 0) {
3736  av_log(c->fc, AV_LOG_WARNING, "CTTS outside TRAK\n");
3737  return 0;
3738  }
3739 
3740  if (c->fc->nb_streams < 1)
3741  return 0;
3742  st = c->fc->streams[c->fc->nb_streams-1];
3743  sc = st->priv_data;
3744 
3745  avio_r8(pb); /* version */
3746  avio_rb24(pb); /* flags */
3747  entries = avio_rb32(pb);
3748 
3749  av_log(c->fc, AV_LOG_TRACE, "track[%u].ctts.entries = %u\n", c->fc->nb_streams - 1, entries);
3750 
3751  if (!entries)
3752  return 0;
3753  if (entries >= UINT_MAX / sizeof(*sc->ctts_data))
3754  return AVERROR_INVALIDDATA;
3755  av_freep(&sc->ctts_data);
3756  sc->ctts_data = av_fast_realloc(NULL, &sc->ctts_allocated_size, entries * sizeof(*sc->ctts_data));
3757  if (!sc->ctts_data)
3758  return AVERROR(ENOMEM);
3759 
3760  for (i = 0; i < entries && !pb->eof_reached; i++) {
3761  MOVCtts *ctts_data;
3762  const size_t min_size_needed = (ctts_count + 1) * sizeof(MOVCtts);
3763  const size_t requested_size =
3764  min_size_needed > sc->ctts_allocated_size ?
3765  FFMAX(min_size_needed, 2 * sc->ctts_allocated_size) :
3766  min_size_needed;
3767  int count = avio_rb32(pb);
3768  int duration = avio_rb32(pb);
3769 
3770  if (count <= 0) {
3771  av_log(c->fc, AV_LOG_TRACE,
3772  "ignoring CTTS entry with count=%d duration=%d\n",
3773  count, duration);
3774  continue;
3775  }
3776 
3777  if (ctts_count >= UINT_MAX / sizeof(MOVCtts) - 1)
3778  return AVERROR(ENOMEM);
3779 
3780  ctts_data = av_fast_realloc(sc->ctts_data, &sc->ctts_allocated_size, requested_size);
3781 
3782  if (!ctts_data)
3783  return AVERROR(ENOMEM);
3784 
3785  sc->ctts_data = ctts_data;
3786 
3787  ctts_data[ctts_count].count = count;
3788  ctts_data[ctts_count].offset = duration;
3789  ctts_count++;
3790 
3791  av_log(c->fc, AV_LOG_TRACE, "count=%d, duration=%d\n",
3792  count, duration);
3793 
3794  if (i+2<entries)
3795  mov_update_dts_shift(sc, duration, c->fc);
3796  }
3797 
3798  sc->ctts_count = ctts_count;
3799 
3800  if (pb->eof_reached) {
3801  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted CTTS atom\n");
3802  return AVERROR_EOF;
3803  }
3804 
3805  av_log(c->fc, AV_LOG_TRACE, "dts shift %d\n", sc->dts_shift);
3806 
3807  return 0;
3808 }
3809 
3811 {
3812  AVStream *st;
3813  MOVStreamContext *sc;
3814  uint8_t version;
3815  uint32_t grouping_type;
3816  uint32_t default_length;
3817  av_unused uint32_t default_group_description_index;
3818  uint32_t entry_count;
3819 
3820  if (c->fc->nb_streams < 1)
3821  return 0;
3822  st = c->fc->streams[c->fc->nb_streams - 1];
3823  sc = st->priv_data;
3824 
3825  version = avio_r8(pb); /* version */
3826  avio_rb24(pb); /* flags */
3827  grouping_type = avio_rl32(pb);
3828 
3829  /*
3830  * This function only supports "sync" boxes, but the code is able to parse
3831  * other boxes (such as "tscl", "tsas" and "stsa")
3832  */
3833  if (grouping_type != MKTAG('s','y','n','c'))
3834  return 0;
3835 
3836  default_length = version >= 1 ? avio_rb32(pb) : 0;
3837  default_group_description_index = version >= 2 ? avio_rb32(pb) : 0;
3838  entry_count = avio_rb32(pb);
3839 
3840  av_freep(&sc->sgpd_sync);
3841  sc->sgpd_sync_count = entry_count;
3842  sc->sgpd_sync = av_calloc(entry_count, sizeof(*sc->sgpd_sync));
3843  if (!sc->sgpd_sync)
3844  return AVERROR(ENOMEM);
3845 
3846  for (uint32_t i = 0; i < entry_count && !pb->eof_reached; i++) {
3847  uint32_t description_length = default_length;
3848  if (version >= 1 && default_length == 0)
3849  description_length = avio_rb32(pb);
3850  if (grouping_type == MKTAG('s','y','n','c')) {
3851  const uint8_t nal_unit_type = avio_r8(pb) & 0x3f;
3852  sc->sgpd_sync[i] = nal_unit_type;
3853  description_length -= 1;
3854  }
3855  avio_skip(pb, description_length);
3856  }
3857 
3858  if (pb->eof_reached) {
3859  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted SGPD atom\n");
3860  return AVERROR_EOF;
3861  }
3862 
3863  return 0;
3864 }
3865 
3867 {
3868  AVStream *st;
3869  MOVStreamContext *sc;
3870  unsigned int i, entries;
3871  uint8_t version;
3872  uint32_t grouping_type;
3873  MOVSbgp *table, **tablep;
3874  int *table_count;
3875 
3876  if (c->fc->nb_streams < 1)
3877  return 0;
3878  st = c->fc->streams[c->fc->nb_streams-1];
3879  sc = st->priv_data;
3880 
3881  version = avio_r8(pb); /* version */
3882  avio_rb24(pb); /* flags */
3883  grouping_type = avio_rl32(pb);
3884 
3885  if (grouping_type == MKTAG('r','a','p',' ')) {
3886  tablep = &sc->rap_group;
3887  table_count = &sc->rap_group_count;
3888  } else if (grouping_type == MKTAG('s','y','n','c')) {
3889  tablep = &sc->sync_group;
3890  table_count = &sc->sync_group_count;
3891  } else {
3892  return 0;
3893  }
3894 
3895  if (version == 1)
3896  avio_rb32(pb); /* grouping_type_parameter */
3897 
3898  entries = avio_rb32(pb);
3899  if (!entries)
3900  return 0;
3901  if (*tablep)
3902  av_log(c->fc, AV_LOG_WARNING, "Duplicated SBGP %s atom\n", av_fourcc2str(grouping_type));
3903  av_freep(tablep);
3904  table = av_malloc_array(entries, sizeof(*table));
3905  if (!table)
3906  return AVERROR(ENOMEM);
3907  *tablep = table;
3908 
3909  for (i = 0; i < entries && !pb->eof_reached; i++) {
3910  table[i].count = avio_rb32(pb); /* sample_count */
3911  table[i].index = avio_rb32(pb); /* group_description_index */
3912  }
3913 
3914  *table_count = i;
3915 
3916  if (pb->eof_reached) {
3917  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted SBGP atom\n");
3918  return AVERROR_EOF;
3919  }
3920 
3921  return 0;
3922 }
3923 
3924 /**
3925  * Get ith edit list entry (media time, duration).
3926  */
3928  const MOVStreamContext *msc,
3929  unsigned int edit_list_index,
3930  int64_t *edit_list_media_time,
3931  int64_t *edit_list_duration,
3932  int64_t global_timescale)
3933 {
3934  if (edit_list_index == msc->elst_count) {
3935  return 0;
3936  }
3937  *edit_list_media_time = msc->elst_data[edit_list_index].time;
3938  *edit_list_duration = msc->elst_data[edit_list_index].duration;
3939 
3940  /* duration is in global timescale units;convert to msc timescale */
3941  if (global_timescale == 0) {
3942  avpriv_request_sample(mov->fc, "Support for mvhd.timescale = 0 with editlists");
3943  return 0;
3944  }
3945  *edit_list_duration = av_rescale(*edit_list_duration, msc->time_scale,
3946  global_timescale);
3947 
3948  if (*edit_list_duration + (uint64_t)*edit_list_media_time > INT64_MAX)
3949  *edit_list_duration = 0;
3950 
3951  return 1;
3952 }
3953 
3954 /**
3955  * Find the closest previous frame to the timestamp_pts, in e_old index
3956  * entries. Searching for just any frame / just key frames can be controlled by
3957  * last argument 'flag'.
3958  * Note that if ctts_data is not NULL, we will always search for a key frame
3959  * irrespective of the value of 'flag'. If we don't find any keyframe, we will
3960  * return the first frame of the video.
3961  *
3962  * Here the timestamp_pts is considered to be a presentation timestamp and
3963  * the timestamp of index entries are considered to be decoding timestamps.
3964  *
3965  * Returns 0 if successful in finding a frame, else returns -1.
3966  * Places the found index corresponding output arg.
3967  *
3968  * If ctts_old is not NULL, then refines the searched entry by searching
3969  * backwards from the found timestamp, to find the frame with correct PTS.
3970  *
3971  * Places the found ctts_index and ctts_sample in corresponding output args.
3972  */
3974  AVIndexEntry *e_old,
3975  int nb_old,
3976  MOVTimeToSample *tts_data,
3977  int64_t tts_count,
3978  int64_t timestamp_pts,
3979  int flag,
3980  int64_t* index,
3981  int64_t* tts_index,
3982  int64_t* tts_sample)
3983 {
3984  MOVStreamContext *msc = st->priv_data;
3985  FFStream *const sti = ffstream(st);
3986  AVIndexEntry *e_keep = sti->index_entries;
3987  int nb_keep = sti->nb_index_entries;
3988  int64_t i = 0;
3989 
3990  av_assert0(index);
3991 
3992  // If dts_shift > 0, then all the index timestamps will have to be offset by
3993  // at least dts_shift amount to obtain PTS.
3994  // Hence we decrement the searched timestamp_pts by dts_shift to find the closest index element.
3995  if (msc->dts_shift > 0) {
3996  timestamp_pts -= msc->dts_shift;
3997  }
3998 
3999  sti->index_entries = e_old;
4000  sti->nb_index_entries = nb_old;
4001  *index = av_index_search_timestamp(st, timestamp_pts, flag | AVSEEK_FLAG_BACKWARD);
4002 
4003  // Keep going backwards in the index entries until the timestamp is the same.
4004  if (*index >= 0) {
4005  for (i = *index; i > 0 && e_old[i].timestamp == e_old[i - 1].timestamp;
4006  i--) {
4007  if ((flag & AVSEEK_FLAG_ANY) ||
4008  (e_old[i - 1].flags & AVINDEX_KEYFRAME)) {
4009  *index = i - 1;
4010  }
4011  }
4012  }
4013 
4014  // If we have CTTS then refine the search, by searching backwards over PTS
4015  // computed by adding corresponding CTTS durations to index timestamps.
4016  if (msc->ctts_count && *index >= 0) {
4017  av_assert0(tts_index);
4018  av_assert0(tts_sample);
4019  // Find out the ctts_index for the found frame.
4020  *tts_index = 0;
4021  *tts_sample = 0;
4022  for (int64_t index_tts_count = 0; index_tts_count < *index; index_tts_count++) {
4023  if (*tts_index < tts_count) {
4024  (*tts_sample)++;
4025  if (tts_data[*tts_index].count == *tts_sample) {
4026  (*tts_index)++;
4027  *tts_sample = 0;
4028  }
4029  }
4030  }
4031 
4032  while (*index >= 0 && (*tts_index) >= 0 && (*tts_index) < tts_count) {
4033  // Find a "key frame" with PTS <= timestamp_pts (So that we can decode B-frames correctly).
4034  // No need to add dts_shift to the timestamp here because timestamp_pts has already been
4035  // compensated by dts_shift above.
4036  if ((e_old[*index].timestamp + tts_data[*tts_index].offset) <= timestamp_pts &&
4037  (e_old[*index].flags & AVINDEX_KEYFRAME)) {
4038  break;
4039  }
4040 
4041  (*index)--;
4042  if (*tts_sample == 0) {
4043  (*tts_index)--;
4044  if (*tts_index >= 0)
4045  *tts_sample = tts_data[*tts_index].count - 1;
4046  } else {
4047  (*tts_sample)--;
4048  }
4049  }
4050  }
4051 
4052  /* restore AVStream state*/
4053  sti->index_entries = e_keep;
4054  sti->nb_index_entries = nb_keep;
4055  return *index >= 0 ? 0 : -1;
4056 }
4057 
4058 /**
4059  * Add index entry with the given values, to the end of ffstream(st)->index_entries.
4060  * Returns the new size ffstream(st)->index_entries if successful, else returns -1.
4061  *
4062  * This function is similar to ff_add_index_entry in libavformat/utils.c
4063  * except that here we are always unconditionally adding an index entry to
4064  * the end, instead of searching the entries list and skipping the add if
4065  * there is an existing entry with the same timestamp.
4066  * This is needed because the mov_fix_index calls this func with the same
4067  * unincremented timestamp for successive discarded frames.
4068  */
4070  int size, int distance, int flags)
4071 {
4072  FFStream *const sti = ffstream(st);
4073  AVIndexEntry *entries, *ie;
4074  int64_t index = -1;
4075  const size_t min_size_needed = (sti->nb_index_entries + 1) * sizeof(AVIndexEntry);
4076 
4077  // Double the allocation each time, to lower memory fragmentation.
4078  // Another difference from ff_add_index_entry function.
4079  const size_t requested_size =
4080  min_size_needed > sti->index_entries_allocated_size ?
4081  FFMAX(min_size_needed, 2 * sti->index_entries_allocated_size) :
4082  min_size_needed;
4083 
4084  if (sti->nb_index_entries + 1U >= UINT_MAX / sizeof(AVIndexEntry))
4085  return -1;
4086 
4087  entries = av_fast_realloc(sti->index_entries,
4089  requested_size);
4090  if (!entries)
4091  return -1;
4092 
4093  sti->index_entries = entries;
4094 
4095  index = sti->nb_index_entries++;
4096  ie= &entries[index];
4097 
4098  ie->pos = pos;
4099  ie->timestamp = timestamp;
4100  ie->min_distance= distance;
4101  ie->size= size;
4102  ie->flags = flags;
4103  return index;
4104 }
4105 
4106 /**
4107  * Rewrite timestamps of index entries in the range [end_index - frame_duration_buffer_size, end_index)
4108  * by subtracting end_ts successively by the amounts given in frame_duration_buffer.
4109  */
4110 static void fix_index_entry_timestamps(AVStream* st, int end_index, int64_t end_ts,
4111  int64_t* frame_duration_buffer,
4112  int frame_duration_buffer_size) {
4113  FFStream *const sti = ffstream(st);
4114  int i = 0;
4115  av_assert0(end_index >= 0 && end_index <= sti->nb_index_entries);
4116  for (i = 0; i < frame_duration_buffer_size; i++) {
4117  end_ts -= frame_duration_buffer[frame_duration_buffer_size - 1 - i];
4118  sti->index_entries[end_index - 1 - i].timestamp = end_ts;
4119  }
4120 }
4121 
4122 static int add_tts_entry(MOVTimeToSample **tts_data, unsigned int *tts_count, unsigned int *allocated_size,
4123  int count, int offset, unsigned int duration)
4124 {
4125  MOVTimeToSample *tts_buf_new;
4126  const size_t min_size_needed = (*tts_count + 1) * sizeof(MOVTimeToSample);
4127  const size_t requested_size =
4128  min_size_needed > *allocated_size ?
4129  FFMAX(min_size_needed, 2 * (*allocated_size)) :
4130  min_size_needed;
4131 
4132  if ((unsigned)(*tts_count) >= UINT_MAX / sizeof(MOVTimeToSample) - 1)
4133  return -1;
4134 
4135  tts_buf_new = av_fast_realloc(*tts_data, allocated_size, requested_size);
4136 
4137  if (!tts_buf_new)
4138  return -1;
4139 
4140  *tts_data = tts_buf_new;
4141 
4142  tts_buf_new[*tts_count].count = count;
4143  tts_buf_new[*tts_count].offset = offset;
4144  tts_buf_new[*tts_count].duration = duration;
4145 
4146  *tts_count = (*tts_count) + 1;
4147  return 0;
4148 }
4149 
4150 #define MAX_REORDER_DELAY 16
4152 {
4153  MOVStreamContext *msc = st->priv_data;
4154  FFStream *const sti = ffstream(st);
4155  int ctts_ind = 0;
4156  int ctts_sample = 0;
4157  int64_t pts_buf[MAX_REORDER_DELAY + 1]; // Circular buffer to sort pts.
4158  int buf_start = 0;
4159  int j, r, num_swaps;
4160 
4161  for (j = 0; j < MAX_REORDER_DELAY + 1; j++)
4162  pts_buf[j] = INT64_MIN;
4163 
4164  if (st->codecpar->video_delay <= 0 && msc->ctts_count &&
4166  st->codecpar->video_delay = 0;
4167  for (int ind = 0; ind < sti->nb_index_entries && ctts_ind < msc->tts_count; ++ind) {
4168  // Point j to the last elem of the buffer and insert the current pts there.
4169  j = buf_start;
4170  buf_start = (buf_start + 1);
4171  if (buf_start == MAX_REORDER_DELAY + 1)
4172  buf_start = 0;
4173 
4174  pts_buf[j] = sti->index_entries[ind].timestamp + msc->tts_data[ctts_ind].offset;
4175 
4176  // The timestamps that are already in the sorted buffer, and are greater than the
4177  // current pts, are exactly the timestamps that need to be buffered to output PTS
4178  // in correct sorted order.
4179  // Hence the video delay (which is the buffer size used to sort DTS and output PTS),
4180  // can be computed as the maximum no. of swaps any particular timestamp needs to
4181  // go through, to keep this buffer in sorted order.
4182  num_swaps = 0;
4183  while (j != buf_start) {
4184  r = j - 1;
4185  if (r < 0) r = MAX_REORDER_DELAY;
4186  if (pts_buf[j] < pts_buf[r]) {
4187  FFSWAP(int64_t, pts_buf[j], pts_buf[r]);
4188  ++num_swaps;
4189  } else {
4190  break;
4191  }
4192  j = r;
4193  }
4194  st->codecpar->video_delay = FFMAX(st->codecpar->video_delay, num_swaps);
4195 
4196  ctts_sample++;
4197  if (ctts_sample == msc->tts_data[ctts_ind].count) {
4198  ctts_ind++;
4199  ctts_sample = 0;
4200  }
4201  }
4202  av_log(c->fc, AV_LOG_DEBUG, "Setting codecpar->delay to %d for stream st: %d\n",
4203  st->codecpar->video_delay, st->index);
4204  }
4205 }
4206 
4208 {
4209  sc->current_sample++;
4210  sc->current_index++;
4211  if (sc->index_ranges &&
4212  sc->current_index >= sc->current_index_range->end &&
4213  sc->current_index_range->end) {
4214  sc->current_index_range++;
4216  }
4217 }
4218 
4220 {
4221  sc->current_sample--;
4222  sc->current_index--;
4223  if (sc->index_ranges &&
4225  sc->current_index_range > sc->index_ranges) {
4226  sc->current_index_range--;
4227  sc->current_index = sc->current_index_range->end - 1;
4228  }
4229 }
4230 
4231 static void mov_current_sample_set(MOVStreamContext *sc, int current_sample)
4232 {
4233  int64_t range_size;
4234 
4235  sc->current_sample = current_sample;
4236  sc->current_index = current_sample;
4237  if (!sc->index_ranges) {
4238  return;
4239  }
4240 
4241  for (sc->current_index_range = sc->index_ranges;
4242  sc->current_index_range->end;
4243  sc->current_index_range++) {
4244  range_size = sc->current_index_range->end - sc->current_index_range->start;
4245  if (range_size > current_sample) {
4246  sc->current_index = sc->current_index_range->start + current_sample;
4247  break;
4248  }
4249  current_sample -= range_size;
4250  }
4251 }
4252 
4253 /**
4254  * Fix ffstream(st)->index_entries, so that it contains only the entries (and the entries
4255  * which are needed to decode them) that fall in the edit list time ranges.
4256  * Also fixes the timestamps of the index entries to match the timeline
4257  * specified the edit lists.
4258  */
4259 static void mov_fix_index(MOVContext *mov, AVStream *st)
4260 {
4261  MOVStreamContext *msc = st->priv_data;
4262  FFStream *const sti = ffstream(st);
4263  AVIndexEntry *e_old = sti->index_entries;
4264  int nb_old = sti->nb_index_entries;
4265  const AVIndexEntry *e_old_end = e_old + nb_old;
4266  const AVIndexEntry *current = NULL;
4267  MOVTimeToSample *tts_data_old = msc->tts_data;
4268  int64_t tts_index_old = 0;
4269  int64_t tts_sample_old = 0;
4270  int64_t tts_count_old = msc->tts_count;
4271  int64_t edit_list_media_time = 0;
4272  int64_t edit_list_duration = 0;
4273  int64_t frame_duration = 0;
4274  int64_t edit_list_dts_counter = 0;
4275  int64_t edit_list_dts_entry_end = 0;
4276  int64_t edit_list_start_tts_sample = 0;
4277  int64_t curr_cts;
4278  int64_t curr_ctts = 0;
4279  int64_t empty_edits_sum_duration = 0;
4280  int64_t edit_list_index = 0;
4281  int64_t index;
4282  int flags;
4283  int64_t start_dts = 0;
4284  int64_t edit_list_start_encountered = 0;
4285  int64_t search_timestamp = 0;
4286  int64_t* frame_duration_buffer = NULL;
4287  int num_discarded_begin = 0;
4288  int first_non_zero_audio_edit = -1;
4289  int packet_skip_samples = 0;
4290  MOVIndexRange *current_index_range = NULL;
4291  int found_keyframe_after_edit = 0;
4292  int found_non_empty_edit = 0;
4293 
4294  if (!msc->elst_data || msc->elst_count <= 0 || nb_old <= 0) {
4295  return;
4296  }
4297 
4298  // allocate the index ranges array
4299  msc->index_ranges = av_malloc_array(msc->elst_count + 1,
4300  sizeof(msc->index_ranges[0]));
4301  if (!msc->index_ranges) {
4302  av_log(mov->fc, AV_LOG_ERROR, "Cannot allocate index ranges buffer\n");
4303  return;
4304  }
4305  msc->current_index_range = msc->index_ranges;
4306 
4307  // Clean AVStream from traces of old index
4308  sti->index_entries = NULL;
4310  sti->nb_index_entries = 0;
4311 
4312  // Clean time to sample fields of MOVStreamContext
4313  msc->tts_data = NULL;
4314  msc->tts_count = 0;
4315  msc->tts_index = 0;
4316  msc->tts_sample = 0;
4317  msc->tts_allocated_size = 0;
4318 
4319  // Reinitialize min_corrected_pts so that it can be computed again.
4320  msc->min_corrected_pts = -1;
4321 
4322  // If the dts_shift is positive (in case of negative ctts values in mov),
4323  // then negate the DTS by dts_shift
4324  if (msc->dts_shift > 0) {
4325  edit_list_dts_entry_end -= msc->dts_shift;
4326  av_log(mov->fc, AV_LOG_DEBUG, "Shifting DTS by %d because of negative CTTS.\n", msc->dts_shift);
4327  }
4328 
4329  start_dts = edit_list_dts_entry_end;
4330 
4331  while (get_edit_list_entry(mov, msc, edit_list_index, &edit_list_media_time,
4332  &edit_list_duration, mov->time_scale)) {
4333  av_log(mov->fc, AV_LOG_DEBUG, "Processing st: %d, edit list %"PRId64" - media time: %"PRId64", duration: %"PRId64"\n",
4334  st->index, edit_list_index, edit_list_media_time, edit_list_duration);
4335  edit_list_index++;
4336  edit_list_dts_counter = edit_list_dts_entry_end;
4337  edit_list_dts_entry_end = av_sat_add64(edit_list_dts_entry_end, edit_list_duration);
4338  if (edit_list_dts_entry_end == INT64_MAX) {
4339  av_log(mov->fc, AV_LOG_ERROR, "Cannot calculate dts entry length with duration %"PRId64"\n",
4340  edit_list_duration);
4341  break;
4342  }
4343  num_discarded_begin = 0;
4344  if (!found_non_empty_edit && edit_list_media_time == -1) {
4345  empty_edits_sum_duration += edit_list_duration;
4346  continue;
4347  }
4348  found_non_empty_edit = 1;
4349 
4350  // If we encounter a non-negative edit list reset the skip_samples/start_pad fields and set them
4351  // according to the edit list below.
4352  if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
4353  if (first_non_zero_audio_edit < 0) {
4354  first_non_zero_audio_edit = 1;
4355  } else {
4356  first_non_zero_audio_edit = 0;
4357  }
4358 
4359  if (first_non_zero_audio_edit > 0)
4360  sti->skip_samples = msc->start_pad = 0;
4361  }
4362 
4363  // While reordering frame index according to edit list we must handle properly
4364  // the scenario when edit list entry starts from none key frame.
4365  // We find closest previous key frame and preserve it and consequent frames in index.
4366  // All frames which are outside edit list entry time boundaries will be dropped after decoding.
4367  search_timestamp = edit_list_media_time;
4368  if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
4369  // Audio decoders like AAC need need a decoder delay samples previous to the current sample,
4370  // to correctly decode this frame. Hence for audio we seek to a frame 1 sec. before the
4371  // edit_list_media_time to cover the decoder delay.
4372  search_timestamp = FFMAX(search_timestamp - msc->time_scale, e_old[0].timestamp);
4373  }
4374 
4375  if (find_prev_closest_index(st, e_old, nb_old, tts_data_old, tts_count_old, search_timestamp, 0,
4376  &index, &tts_index_old, &tts_sample_old) < 0) {
4377  av_log(mov->fc, AV_LOG_WARNING,
4378  "st: %d edit list: %"PRId64" Missing key frame while searching for timestamp: %"PRId64"\n",
4379  st->index, edit_list_index, search_timestamp);
4380  if (find_prev_closest_index(st, e_old, nb_old, tts_data_old, tts_count_old, search_timestamp, AVSEEK_FLAG_ANY,
4381  &index, &tts_index_old, &tts_sample_old) < 0) {
4382  av_log(mov->fc, AV_LOG_WARNING,
4383  "st: %d edit list %"PRId64" Cannot find an index entry before timestamp: %"PRId64".\n",
4384  st->index, edit_list_index, search_timestamp);
4385  index = 0;
4386  tts_index_old = 0;
4387  tts_sample_old = 0;
4388  }
4389  }
4390  current = e_old + index;
4391  edit_list_start_tts_sample = tts_sample_old;
4392 
4393  // Iterate over index and arrange it according to edit list
4394  edit_list_start_encountered = 0;
4395  found_keyframe_after_edit = 0;
4396  for (; current < e_old_end; current++, index++) {
4397  // check if frame outside edit list mark it for discard
4398  frame_duration = (current + 1 < e_old_end) ?
4399  ((current + 1)->timestamp - current->timestamp) : edit_list_duration;
4400 
4401  flags = current->flags;
4402 
4403  // frames (pts) before or after edit list
4404  curr_cts = current->timestamp + msc->dts_shift;
4405  curr_ctts = 0;
4406 
4407  if (tts_data_old && tts_index_old < tts_count_old) {
4408  curr_ctts = tts_data_old[tts_index_old].offset;
4409  av_log(mov->fc, AV_LOG_TRACE, "stts: %"PRId64" ctts: %"PRId64", tts_index: %"PRId64", tts_count: %"PRId64"\n",
4410  curr_cts, curr_ctts, tts_index_old, tts_count_old);
4411  curr_cts += curr_ctts;
4412  tts_sample_old++;
4413  if (tts_sample_old == tts_data_old[tts_index_old].count) {
4414  if (add_tts_entry(&msc->tts_data, &msc->tts_count,
4415  &msc->tts_allocated_size,
4416  tts_data_old[tts_index_old].count - edit_list_start_tts_sample,
4417  tts_data_old[tts_index_old].offset, tts_data_old[tts_index_old].duration) == -1) {
4418  av_log(mov->fc, AV_LOG_ERROR, "Cannot add Time To Sample entry %"PRId64" - {%"PRId64", %d}\n",
4419  tts_index_old,
4420  tts_data_old[tts_index_old].count - edit_list_start_tts_sample,
4421  tts_data_old[tts_index_old].offset);
4422  break;
4423  }
4424  tts_index_old++;
4425  tts_sample_old = 0;
4426  edit_list_start_tts_sample = 0;
4427  }
4428  }
4429 
4430  if (curr_cts < edit_list_media_time || curr_cts >= (edit_list_duration + edit_list_media_time)) {
4432  curr_cts < edit_list_media_time && curr_cts + frame_duration > edit_list_media_time &&
4433  first_non_zero_audio_edit > 0) {
4434  packet_skip_samples = edit_list_media_time - curr_cts;
4435  sti->skip_samples += packet_skip_samples;
4436 
4437  // Shift the index entry timestamp by packet_skip_samples to be correct.
4438  edit_list_dts_counter -= packet_skip_samples;
4439  if (edit_list_start_encountered == 0) {
4440  edit_list_start_encountered = 1;
4441  // Make timestamps strictly monotonically increasing for audio, by rewriting timestamps for
4442  // discarded packets.
4443  if (frame_duration_buffer) {
4444  fix_index_entry_timestamps(st, sti->nb_index_entries, edit_list_dts_counter,
4445  frame_duration_buffer, num_discarded_begin);
4446  av_freep(&frame_duration_buffer);
4447  }
4448  }
4449 
4450  av_log(mov->fc, AV_LOG_DEBUG, "skip %d audio samples from curr_cts: %"PRId64"\n", packet_skip_samples, curr_cts);
4451  } else {
4453  av_log(mov->fc, AV_LOG_DEBUG, "drop a frame at curr_cts: %"PRId64" @ %"PRId64"\n", curr_cts, index);
4454 
4455  if (edit_list_start_encountered == 0) {
4456  num_discarded_begin++;
4457  frame_duration_buffer = av_realloc(frame_duration_buffer,
4458  num_discarded_begin * sizeof(int64_t));
4459  if (!frame_duration_buffer) {
4460  av_log(mov->fc, AV_LOG_ERROR, "Cannot reallocate frame duration buffer\n");
4461  break;
4462  }
4463  frame_duration_buffer[num_discarded_begin - 1] = frame_duration;
4464 
4465  // Increment skip_samples for the first non-zero audio edit list
4466  if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
4467  first_non_zero_audio_edit > 0 && st->codecpar->codec_id != AV_CODEC_ID_VORBIS) {
4468  sti->skip_samples += frame_duration;
4469  }
4470  }
4471  }
4472  } else {
4473  if (msc->min_corrected_pts < 0) {
4474  msc->min_corrected_pts = edit_list_dts_counter + curr_ctts + msc->dts_shift;
4475  } else {
4476  msc->min_corrected_pts = FFMIN(msc->min_corrected_pts, edit_list_dts_counter + curr_ctts + msc->dts_shift);
4477  }
4478  if (edit_list_start_encountered == 0) {
4479  edit_list_start_encountered = 1;
4480  // Make timestamps strictly monotonically increasing by rewriting timestamps for
4481  // discarded packets.
4482  if (frame_duration_buffer) {
4483  fix_index_entry_timestamps(st, sti->nb_index_entries, edit_list_dts_counter,
4484  frame_duration_buffer, num_discarded_begin);
4485  av_freep(&frame_duration_buffer);
4486  }
4487  }
4488  }
4489 
4490  if (add_index_entry(st, current->pos, edit_list_dts_counter, current->size,
4491  current->min_distance, flags) == -1) {
4492  av_log(mov->fc, AV_LOG_ERROR, "Cannot add index entry\n");
4493  break;
4494  }
4495 
4496  // Update the index ranges array
4497  if (!current_index_range || index != current_index_range->end) {
4498  current_index_range = current_index_range ? current_index_range + 1
4499  : msc->index_ranges;
4500  current_index_range->start = index;
4501  }
4502  current_index_range->end = index + 1;
4503 
4504  // Only start incrementing DTS in frame_duration amounts, when we encounter a frame in edit list.
4505  if (edit_list_start_encountered > 0) {
4506  edit_list_dts_counter = edit_list_dts_counter + frame_duration;
4507  }
4508 
4509  // Break when found first key frame after edit entry completion
4510  if ((curr_cts + frame_duration >= (edit_list_duration + edit_list_media_time)) &&
4512  if (msc->ctts_count) {
4513  // If we have CTTS and this is the first keyframe after edit elist,
4514  // wait for one more, because there might be trailing B-frames after this I-frame
4515  // that do belong to the edit.
4516  if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO && found_keyframe_after_edit == 0) {
4517  found_keyframe_after_edit = 1;
4518  continue;
4519  }
4520  if (tts_sample_old != 0) {
4521  if (add_tts_entry(&msc->tts_data, &msc->tts_count,
4522  &msc->tts_allocated_size,
4523  tts_sample_old - edit_list_start_tts_sample,
4524  tts_data_old[tts_index_old].offset, tts_data_old[tts_index_old].duration) == -1) {
4525  av_log(mov->fc, AV_LOG_ERROR, "Cannot add Time To Sample entry %"PRId64" - {%"PRId64", %d}\n",
4526  tts_index_old, tts_sample_old - edit_list_start_tts_sample,
4527  tts_data_old[tts_index_old].offset);
4528  break;
4529  }
4530  }
4531  }
4532  break;
4533  }
4534  }
4535  }
4536  // If there are empty edits, then msc->min_corrected_pts might be positive
4537  // intentionally. So we subtract the sum duration of empty edits here.
4538  msc->min_corrected_pts -= empty_edits_sum_duration;
4539 
4540  // If the minimum pts turns out to be greater than zero after fixing the index, then we subtract the
4541  // dts by that amount to make the first pts zero.
4542  if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
4543  if (msc->min_corrected_pts > 0) {
4544  av_log(mov->fc, AV_LOG_DEBUG, "Offset DTS by %"PRId64" to make first pts zero.\n", msc->min_corrected_pts);
4545  for (int i = 0; i < sti->nb_index_entries; ++i)
4547  }
4548  }
4549  // Start time should be equal to zero or the duration of any empty edits.
4550  st->start_time = empty_edits_sum_duration;
4551 
4552  // Update av stream length, if it ends up shorter than the track's media duration
4553  st->duration = FFMIN(st->duration, edit_list_dts_entry_end - start_dts);
4554  msc->start_pad = sti->skip_samples;
4555 
4556  // Free the old index and the old CTTS structures
4557  av_free(e_old);
4558  av_free(tts_data_old);
4559  av_freep(&frame_duration_buffer);
4560 
4561  // Null terminate the index ranges array
4562  current_index_range = current_index_range ? current_index_range + 1
4563  : msc->index_ranges;
4564  current_index_range->start = 0;
4565  current_index_range->end = 0;
4566  msc->current_index = msc->index_ranges[0].start;
4567 }
4568 
4569 static uint32_t get_sgpd_sync_index(const MOVStreamContext *sc, int nal_unit_type)
4570 {
4571  for (uint32_t i = 0; i < sc->sgpd_sync_count; i++)
4572  if (sc->sgpd_sync[i] == nal_unit_type)
4573  return i + 1;
4574  return 0;
4575 }
4576 
4578 {
4579  int k;
4580  int sample_id = 0;
4581  uint32_t cra_index;
4582  MOVStreamContext *sc = st->priv_data;
4583 
4584  if (st->codecpar->codec_id != AV_CODEC_ID_HEVC || !sc->sync_group_count)
4585  return 0;
4586 
4587  /* Build an unrolled index of the samples */
4588  sc->sample_offsets_count = 0;
4589  for (uint32_t i = 0; i < sc->ctts_count; i++) {
4590  if (sc->ctts_data[i].count > INT_MAX - sc->sample_offsets_count)
4591  return AVERROR(ENOMEM);
4592  sc->sample_offsets_count += sc->ctts_data[i].count;
4593  }
4594  av_freep(&sc->sample_offsets);
4596  if (!sc->sample_offsets)
4597  return AVERROR(ENOMEM);
4598  k = 0;
4599  for (uint32_t i = 0; i < sc->ctts_count; i++)
4600  for (int j = 0; j < sc->ctts_data[i].count; j++)
4601  sc->sample_offsets[k++] = sc->ctts_data[i].offset;
4602 
4603  /* The following HEVC NAL type reveal the use of open GOP sync points
4604  * (TODO: BLA types may also be concerned) */
4605  cra_index = get_sgpd_sync_index(sc, HEVC_NAL_CRA_NUT); /* Clean Random Access */
4606  if (!cra_index)
4607  return 0;
4608 
4609  /* Build a list of open-GOP key samples */
4610  sc->open_key_samples_count = 0;
4611  for (uint32_t i = 0; i < sc->sync_group_count; i++)
4612  if (sc->sync_group[i].index == cra_index) {
4613  if (sc->sync_group[i].count > INT_MAX - sc->open_key_samples_count)
4614  return AVERROR(ENOMEM);
4616  }
4617  av_freep(&sc->open_key_samples);
4619  if (!sc->open_key_samples)
4620  return AVERROR(ENOMEM);
4621  k = 0;
4622  for (uint32_t i = 0; i < sc->sync_group_count; i++) {
4623  const MOVSbgp *sg = &sc->sync_group[i];
4624  if (sg->index == cra_index)
4625  for (uint32_t j = 0; j < sg->count; j++)
4626  sc->open_key_samples[k++] = sample_id;
4627  if (sg->count > INT_MAX - sample_id)
4628  return AVERROR_PATCHWELCOME;
4629  sample_id += sg->count;
4630  }
4631 
4632  /* Identify the minimal time step between samples */
4633  sc->min_sample_duration = UINT_MAX;
4634  for (uint32_t i = 0; i < sc->stts_count; i++)
4636 
4637  return 0;
4638 }
4639 
4640 #define MOV_MERGE_CTTS 1
4641 #define MOV_MERGE_STTS 2
4642 /*
4643  * Merge stts and ctts arrays into a new combined array.
4644  * stts_count and ctts_count may be left untouched as they will be
4645  * used to check for the presence of either of them.
4646  */
4647 static int mov_merge_tts_data(MOVContext *mov, AVStream *st, int flags)
4648 {
4649  MOVStreamContext *sc = st->priv_data;
4650  int ctts = sc->ctts_data && (flags & MOV_MERGE_CTTS);
4651  int stts = sc->stts_data && (flags & MOV_MERGE_STTS);
4652  int idx = 0;
4653 
4654  if (!sc->ctts_data && !sc->stts_data)
4655  return 0;
4656  // Expand time to sample entries such that we have a 1-1 mapping with samples
4657  if (!sc->sample_count || sc->sample_count >= UINT_MAX / sizeof(*sc->tts_data))
4658  return -1;
4659 
4660  if (ctts) {
4662  sc->sample_count * sizeof(*sc->tts_data));
4663  if (!sc->tts_data)
4664  return -1;
4665 
4666  memset(sc->tts_data, 0, sc->tts_allocated_size);
4667 
4668  for (int i = 0; i < sc->ctts_count &&
4669  idx < sc->sample_count; i++)
4670  for (int j = 0; j < sc->ctts_data[i].count &&
4671  idx < sc->sample_count; j++) {
4672  sc->tts_data[idx].offset = sc->ctts_data[i].offset;
4673  sc->tts_data[idx++].count = 1;
4674  }
4675 
4676  sc->tts_count = idx;
4677  } else
4678  sc->ctts_count = 0;
4679  av_freep(&sc->ctts_data);
4680  sc->ctts_allocated_size = 0;
4681 
4682  idx = 0;
4683  if (stts) {
4685  sc->sample_count * sizeof(*sc->tts_data));
4686  if (!tts_data)
4687  return -1;
4688 
4689  if (!sc->tts_data)
4690  memset(tts_data, 0, sc->tts_allocated_size);
4691  sc->tts_data = tts_data;
4692 
4693  for (int i = 0; i < sc->stts_count &&
4694  idx < sc->sample_count; i++)
4695  for (int j = 0; j < sc->stts_data[i].count &&
4696  idx < sc->sample_count; j++) {
4697  sc->tts_data[idx].duration = sc->stts_data[i].duration;
4698  sc->tts_data[idx++].count = 1;
4699  }
4700 
4701  sc->tts_count = FFMAX(sc->tts_count, idx);
4702  } else
4703  sc->stts_count = 0;
4704  av_freep(&sc->stts_data);
4705  sc->stts_allocated_size = 0;
4706 
4707  return 0;
4708 }
4709 
4710 static void mov_build_index(MOVContext *mov, AVStream *st)
4711 {
4712  MOVStreamContext *sc = st->priv_data;
4713  FFStream *const sti = ffstream(st);
4714  int64_t current_offset;
4715  int64_t current_dts = 0;
4716  unsigned int stts_index = 0;
4717  unsigned int stsc_index = 0;
4718  unsigned int stss_index = 0;
4719  unsigned int stps_index = 0;
4720  unsigned int i, j;
4721  uint64_t stream_size = 0;
4722 
4723  int ret = build_open_gop_key_points(st);
4724  if (ret < 0)
4725  return;
4726 
4727  if (sc->elst_count) {
4728  int i, edit_start_index = 0, multiple_edits = 0;
4729  int64_t empty_duration = 0; // empty duration of the first edit list entry
4730  int64_t start_time = 0; // start time of the media
4731 
4732  for (i = 0; i < sc->elst_count; i++) {
4733  const MOVElst *e = &sc->elst_data[i];
4734  if (i == 0 && e->time == -1) {
4735  /* if empty, the first entry is the start time of the stream
4736  * relative to the presentation itself */
4737  empty_duration = e->duration;
4738  edit_start_index = 1;
4739  } else if (i == edit_start_index && e->time >= 0) {
4740  start_time = e->time;
4741  } else {
4742  multiple_edits = 1;
4743  }
4744  }
4745 
4746  if (multiple_edits && !mov->advanced_editlist) {
4748  av_log(mov->fc, AV_LOG_WARNING, "multiple edit list entries, "
4749  "not supported in fragmented MP4 files\n");
4750  else
4751  av_log(mov->fc, AV_LOG_WARNING, "multiple edit list entries, "
4752  "Use -advanced_editlist to correctly decode otherwise "
4753  "a/v desync might occur\n");
4754  }
4755 
4756  /* adjust first dts according to edit list */
4757  if ((empty_duration || start_time) && mov->time_scale > 0) {
4758  if (empty_duration)
4759  empty_duration = av_rescale(empty_duration, sc->time_scale, mov->time_scale);
4760 
4761  if (av_sat_sub64(start_time, empty_duration) != start_time - (uint64_t)empty_duration)
4762  av_log(mov->fc, AV_LOG_WARNING, "start_time - empty_duration is not representable\n");
4763 
4764  sc->time_offset = start_time - (uint64_t)empty_duration;
4766  if (!mov->advanced_editlist)
4767  current_dts = -sc->time_offset;
4768  }
4769 
4770  if (!multiple_edits && !mov->advanced_editlist &&
4773  (AVRational){1, st->codecpar->sample_rate});
4774  }
4775 
4776  /* only use old uncompressed audio chunk demuxing when stts specifies it */
4777  if (!(st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
4778  sc->stts_count == 1 && sc->stts_data && sc->stts_data[0].duration == 1)) {
4779  unsigned int current_sample = 0;
4780  unsigned int stts_sample = 0;
4781  unsigned int sample_size;
4782  unsigned int distance = 0;
4783  unsigned int rap_group_index = 0;
4784  unsigned int rap_group_sample = 0;
4785  int rap_group_present = sc->rap_group_count && sc->rap_group;
4786  int key_off = (sc->keyframe_count && sc->keyframes[0] > 0) || (sc->stps_count && sc->stps_data[0] > 0);
4787 
4788  current_dts -= sc->dts_shift;
4789 
4790  if (!sc->sample_count || sti->nb_index_entries || sc->tts_count)
4791  return;
4792  if (sc->sample_count >= UINT_MAX / sizeof(*sti->index_entries) - sti->nb_index_entries)
4793  return;
4794  if (av_reallocp_array(&sti->index_entries,
4795  sti->nb_index_entries + sc->sample_count,
4796  sizeof(*sti->index_entries)) < 0) {
4797  sti->nb_index_entries = 0;
4798  return;
4799  }
4800  sti->index_entries_allocated_size = (sti->nb_index_entries + sc->sample_count) * sizeof(*sti->index_entries);
4801 
4803  if (ret < 0)
4804  return;
4805 
4806  for (i = 0; i < sc->chunk_count; i++) {
4807  int64_t next_offset = i+1 < sc->chunk_count ? sc->chunk_offsets[i+1] : INT64_MAX;
4808  current_offset = sc->chunk_offsets[i];
4809  while (mov_stsc_index_valid(stsc_index, sc->stsc_count) &&
4810  i + 1 == sc->stsc_data[stsc_index + 1].first)
4811  stsc_index++;
4812 
4813  if (next_offset > current_offset && sc->sample_size>0 && sc->sample_size < sc->stsz_sample_size &&
4814  sc->stsc_data[stsc_index].count * (int64_t)sc->stsz_sample_size > next_offset - current_offset) {
4815  av_log(mov->fc, AV_LOG_WARNING, "STSZ sample size %d invalid (too large), ignoring\n", sc->stsz_sample_size);
4816  sc->stsz_sample_size = sc->sample_size;
4817  }
4818  if (sc->stsz_sample_size>0 && sc->stsz_sample_size < sc->sample_size) {
4819  av_log(mov->fc, AV_LOG_WARNING, "STSZ sample size %d invalid (too small), ignoring\n", sc->stsz_sample_size);
4820  sc->stsz_sample_size = sc->sample_size;
4821  }
4822 
4823  for (j = 0; j < sc->stsc_data[stsc_index].count; j++) {
4824  int keyframe = 0;
4825  if (current_sample >= sc->sample_count) {
4826  av_log(mov->fc, AV_LOG_ERROR, "wrong sample count\n");
4827  return;
4828  }
4829 
4830  if (!sc->keyframe_absent && (!sc->keyframe_count || current_sample+key_off == sc->keyframes[stss_index])) {
4831  keyframe = 1;
4832  if (stss_index + 1 < sc->keyframe_count)
4833  stss_index++;
4834  } else if (sc->stps_count && current_sample+key_off == sc->stps_data[stps_index]) {
4835  keyframe = 1;
4836  if (stps_index + 1 < sc->stps_count)
4837  stps_index++;
4838  }
4839  if (rap_group_present && rap_group_index < sc->rap_group_count) {
4840  if (sc->rap_group[rap_group_index].index > 0)
4841  keyframe = 1;
4842  if (++rap_group_sample == sc->rap_group[rap_group_index].count) {
4843  rap_group_sample = 0;
4844  rap_group_index++;
4845  }
4846  }
4847  if (sc->keyframe_absent
4848  && !sc->stps_count
4849  && !rap_group_present
4850  && (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO || (i==0 && j==0)))
4851  keyframe = 1;
4852  if (keyframe)
4853  distance = 0;
4854  sample_size = sc->stsz_sample_size > 0 ? sc->stsz_sample_size : sc->sample_sizes[current_sample];
4855  if (current_offset > INT64_MAX - sample_size) {
4856  av_log(mov->fc, AV_LOG_ERROR, "Current offset %"PRId64" or sample size %u is too large\n",
4857  current_offset,
4858  sample_size);
4859  return;
4860  }
4861 
4862  if (sc->pseudo_stream_id == -1 ||
4863  sc->stsc_data[stsc_index].id - 1 == sc->pseudo_stream_id) {
4864  AVIndexEntry *e;
4865  if (sample_size > 0x3FFFFFFF) {
4866  av_log(mov->fc, AV_LOG_ERROR, "Sample size %u is too large\n", sample_size);
4867  return;
4868  }
4869  e = &sti->index_entries[sti->nb_index_entries++];
4870  e->pos = current_offset;
4871  e->timestamp = current_dts;
4872  e->size = sample_size;
4873  e->min_distance = distance;
4874  e->flags = keyframe ? AVINDEX_KEYFRAME : 0;
4875  av_log(mov->fc, AV_LOG_TRACE, "AVIndex stream %d, sample %u, offset %"PRIx64", dts %"PRId64", "
4876  "size %u, distance %u, keyframe %d\n", st->index, current_sample,
4877  current_offset, current_dts, sample_size, distance, keyframe);
4878  if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && sti->nb_index_entries < 100)
4879  ff_rfps_add_frame(mov->fc, st, current_dts);
4880  }
4881 
4882  current_offset += sample_size;
4883  stream_size += sample_size;
4884 
4885  current_dts += sc->tts_data[stts_index].duration;
4886 
4887  distance++;
4888  stts_sample++;
4889  current_sample++;
4890  if (stts_index + 1 < sc->tts_count && stts_sample == sc->tts_data[stts_index].count) {
4891  stts_sample = 0;
4892  stts_index++;
4893  }
4894  }
4895  }
4896  if (st->duration > 0)
4897  st->codecpar->bit_rate = stream_size*8*sc->time_scale/st->duration;
4898  } else {
4899  unsigned chunk_samples, total = 0;
4900 
4901  if (!sc->chunk_count || sc->tts_count)
4902  return;
4903 
4904  // compute total chunk count
4905  for (i = 0; i < sc->stsc_count; i++) {
4906  unsigned count, chunk_count;
4907 
4908  chunk_samples = sc->stsc_data[i].count;
4909  if (i != sc->stsc_count - 1 &&
4910  sc->samples_per_frame && chunk_samples % sc->samples_per_frame) {
4911  av_log(mov->fc, AV_LOG_ERROR, "error unaligned chunk\n");
4912  return;
4913  }
4914 
4915  if (sc->samples_per_frame >= 160) { // gsm
4916  count = chunk_samples / sc->samples_per_frame;
4917  } else if (sc->samples_per_frame > 1) {
4918  unsigned samples = (1024/sc->samples_per_frame)*sc->samples_per_frame;
4919  count = (chunk_samples+samples-1) / samples;
4920  } else {
4921  count = (chunk_samples+1023) / 1024;
4922  }
4923 
4924  if (mov_stsc_index_valid(i, sc->stsc_count))
4925  chunk_count = sc->stsc_data[i+1].first - sc->stsc_data[i].first;
4926  else
4927  chunk_count = sc->chunk_count - (sc->stsc_data[i].first - 1);
4928  total += chunk_count * count;
4929  }
4930 
4931  av_log(mov->fc, AV_LOG_TRACE, "chunk count %u\n", total);
4932  if (total >= UINT_MAX / sizeof(*sti->index_entries) - sti->nb_index_entries)
4933  return;
4934  if (av_reallocp_array(&sti->index_entries,
4935  sti->nb_index_entries + total,
4936  sizeof(*sti->index_entries)) < 0) {
4937  sti->nb_index_entries = 0;
4938  return;
4939  }
4940  sti->index_entries_allocated_size = (sti->nb_index_entries + total) * sizeof(*sti->index_entries);
4941 
4942  // populate index
4943  for (i = 0; i < sc->chunk_count; i++) {
4944  current_offset = sc->chunk_offsets[i];
4945  if (mov_stsc_index_valid(stsc_index, sc->stsc_count) &&
4946  i + 1 == sc->stsc_data[stsc_index + 1].first)
4947  stsc_index++;
4948  chunk_samples = sc->stsc_data[stsc_index].count;
4949 
4950  while (chunk_samples > 0) {
4951  AVIndexEntry *e;
4952  unsigned size, samples;
4953 
4954  if (sc->samples_per_frame > 1 && !sc->bytes_per_frame) {
4956  "Zero bytes per frame, but %d samples per frame",
4957  sc->samples_per_frame);
4958  return;
4959  }
4960 
4961  if (sc->samples_per_frame >= 160) { // gsm
4962  samples = sc->samples_per_frame;
4963  size = sc->bytes_per_frame;
4964  } else {
4965  if (sc->samples_per_frame > 1) {
4966  samples = FFMIN((1024 / sc->samples_per_frame)*
4967  sc->samples_per_frame, chunk_samples);
4969  } else {
4970  samples = FFMIN(1024, chunk_samples);
4971  size = samples * sc->sample_size;
4972  }
4973  }
4974 
4975  if (sti->nb_index_entries >= total) {
4976  av_log(mov->fc, AV_LOG_ERROR, "wrong chunk count %u\n", total);
4977  return;
4978  }
4979  if (size > 0x3FFFFFFF) {
4980  av_log(mov->fc, AV_LOG_ERROR, "Sample size %u is too large\n", size);
4981  return;
4982  }
4983  e = &sti->index_entries[sti->nb_index_entries++];
4984  e->pos = current_offset;
4985  e->timestamp = current_dts;
4986  e->size = size;
4987  e->min_distance = 0;
4988  e->flags = AVINDEX_KEYFRAME;
4989  av_log(mov->fc, AV_LOG_TRACE, "AVIndex stream %d, chunk %u, offset %"PRIx64", dts %"PRId64", "
4990  "size %u, duration %u\n", st->index, i, current_offset, current_dts,
4991  size, samples);
4992 
4993  current_offset += size;
4994  current_dts += samples;
4995  chunk_samples -= samples;
4996  }
4997  }
4998 
5000  if (ret < 0)
5001  return;
5002  }
5003 
5004  if (!mov->ignore_editlist && mov->advanced_editlist) {
5005  // Fix index according to edit lists.
5006  mov_fix_index(mov, st);
5007  }
5008 
5009  // Update start time of the stream.
5011  st->start_time = sti->index_entries[0].timestamp + sc->dts_shift;
5012  if (sc->tts_data) {
5013  st->start_time += sc->tts_data[0].offset;
5014  }
5015  }
5016 
5017  mov_estimate_video_delay(mov, st);
5018 }
5019 
5020 static int test_same_origin(const char *src, const char *ref) {
5021  char src_proto[64];
5022  char ref_proto[64];
5023  char src_auth[256];
5024  char ref_auth[256];
5025  char src_host[256];
5026  char ref_host[256];
5027  int src_port=-1;
5028  int ref_port=-1;
5029 
5030  av_url_split(src_proto, sizeof(src_proto), src_auth, sizeof(src_auth), src_host, sizeof(src_host), &src_port, NULL, 0, src);
5031  av_url_split(ref_proto, sizeof(ref_proto), ref_auth, sizeof(ref_auth), ref_host, sizeof(ref_host), &ref_port, NULL, 0, ref);
5032 
5033  if (strlen(src) == 0) {
5034  return -1;
5035  } else if (strlen(src_auth) + 1 >= sizeof(src_auth) ||
5036  strlen(ref_auth) + 1 >= sizeof(ref_auth) ||
5037  strlen(src_host) + 1 >= sizeof(src_host) ||
5038  strlen(ref_host) + 1 >= sizeof(ref_host)) {
5039  return 0;
5040  } else if (strcmp(src_proto, ref_proto) ||
5041  strcmp(src_auth, ref_auth) ||
5042  strcmp(src_host, ref_host) ||
5043  src_port != ref_port) {
5044  return 0;
5045  } else
5046  return 1;
5047 }
5048 
5049 static int mov_open_dref(MOVContext *c, AVIOContext **pb, const char *src, MOVDref *ref)
5050 {
5051  /* try relative path, we do not try the absolute because it can leak information about our
5052  system to an attacker */
5053  if (ref->nlvl_to > 0 && ref->nlvl_from > 0) {
5054  char filename[1025];
5055  const char *src_path;
5056  int i, l;
5057 
5058  /* find a source dir */
5059  src_path = strrchr(src, '/');
5060  if (src_path)
5061  src_path++;
5062  else
5063  src_path = src;
5064 
5065  /* find a next level down to target */
5066  for (i = 0, l = strlen(ref->path) - 1; l >= 0; l--)
5067  if (ref->path[l] == '/') {
5068  if (i == ref->nlvl_to - 1)
5069  break;
5070  else
5071  i++;
5072  }
5073 
5074  /* compose filename if next level down to target was found */
5075  if (i == ref->nlvl_to - 1 && src_path - src < sizeof(filename)) {
5076  memcpy(filename, src, src_path - src);
5077  filename[src_path - src] = 0;
5078 
5079  for (i = 1; i < ref->nlvl_from; i++)
5080  av_strlcat(filename, "../", sizeof(filename));
5081 
5082  av_strlcat(filename, ref->path + l + 1, sizeof(filename));
5083  if (!c->use_absolute_path) {
5084  int same_origin = test_same_origin(src, filename);
5085 
5086  if (!same_origin) {
5087  av_log(c->fc, AV_LOG_ERROR,
5088  "Reference with mismatching origin, %s not tried for security reasons, "
5089  "set demuxer option use_absolute_path to allow it anyway\n",
5090  ref->path);
5091  return AVERROR(ENOENT);
5092  }
5093 
5094  if (strstr(ref->path + l + 1, "..") ||
5095  strstr(ref->path + l + 1, ":") ||
5096  (ref->nlvl_from > 1 && same_origin < 0) ||
5097  (filename[0] == '/' && src_path == src))
5098  return AVERROR(ENOENT);
5099  }
5100 
5101  if (strlen(filename) + 1 == sizeof(filename))
5102  return AVERROR(ENOENT);
5103  if (!c->fc->io_open(c->fc, pb, filename, AVIO_FLAG_READ, NULL))
5104  return 0;
5105  }
5106  } else if (c->use_absolute_path) {
5107  av_log(c->fc, AV_LOG_WARNING, "Using absolute path on user request, "
5108  "this is a possible security issue\n");
5109  if (!c->fc->io_open(c->fc, pb, ref->path, AVIO_FLAG_READ, NULL))
5110  return 0;
5111  } else {
5112  av_log(c->fc, AV_LOG_ERROR,
5113  "Absolute path %s not tried for security reasons, "
5114  "set demuxer option use_absolute_path to allow absolute paths\n",
5115  ref->path);
5116  }
5117 
5118  return AVERROR(ENOENT);
5119 }
5120 
5122 {
5123  if (sc->time_scale <= 0) {
5124  av_log(c->fc, AV_LOG_WARNING, "stream %d, timescale not set\n", sc->ffindex);
5125  sc->time_scale = c->time_scale;
5126  if (sc->time_scale <= 0)
5127  sc->time_scale = 1;
5128  }
5129 }
5130 
5131 #if CONFIG_IAMFDEC
5132 static int mov_update_iamf_streams(MOVContext *c, const AVStream *st)
5133 {
5134  const MOVStreamContext *sc = st->priv_data;
5135  const IAMFContext *iamf = &sc->iamf->iamf;
5136 
5137  for (int i = 0; i < iamf->nb_audio_elements; i++) {
5138  const AVStreamGroup *stg = NULL;
5139 
5140  for (int j = 0; j < c->fc->nb_stream_groups; j++)
5141  if (c->fc->stream_groups[j]->id == iamf->audio_elements[i]->audio_element_id)
5142  stg = c->fc->stream_groups[j];
5143  av_assert0(stg);
5144 
5145  for (int j = 0; j < stg->nb_streams; j++) {
5146  const FFStream *sti = cffstream(st);
5147  AVStream *out = stg->streams[j];
5148  FFStream *out_sti = ffstream(stg->streams[j]);
5149 
5150  out->codecpar->bit_rate = 0;
5151 
5152  if (out == st)
5153  continue;
5154 
5155  out->time_base = st->time_base;
5156  out->start_time = st->start_time;
5157  out->duration = st->duration;
5158  out->nb_frames = st->nb_frames;
5159  out->discard = st->discard;
5160 
5161  av_assert0(!out_sti->index_entries);
5163  if (!out_sti->index_entries)
5164  return AVERROR(ENOMEM);
5165 
5167  out_sti->nb_index_entries = sti->nb_index_entries;
5168  out_sti->skip_samples = sti->skip_samples;
5169  memcpy(out_sti->index_entries, sti->index_entries, sti->index_entries_allocated_size);
5170  }
5171  }
5172 
5173  return 0;
5174 }
5175 #endif
5176 
5177 static int sanity_checks(void *log_obj, MOVStreamContext *sc, int index)
5178 {
5179  if ((sc->chunk_count && (!sc->stts_count || !sc->stsc_count ||
5180  (!sc->sample_size && !sc->sample_count))) ||
5181  (sc->sample_count && (!sc->chunk_count ||
5182  (!sc->sample_size && !sc->sample_sizes)))) {
5183  av_log(log_obj, AV_LOG_ERROR, "stream %d, missing mandatory atoms, broken header\n",
5184  index);
5185  return 1;
5186  }
5187 
5188  if (sc->stsc_count && sc->stsc_data[ sc->stsc_count - 1 ].first > sc->chunk_count) {
5189  av_log(log_obj, AV_LOG_ERROR, "stream %d, contradictionary STSC and STCO\n",
5190  index);
5191  return 2;
5192  }
5193  return 0;
5194 }
5195 
5197 {
5198  AVStream *st;
5199  MOVStreamContext *sc;
5200  int ret;
5201 
5202  st = avformat_new_stream(c->fc, NULL);
5203  if (!st) return AVERROR(ENOMEM);
5204  st->id = -1;
5205  sc = av_mallocz(sizeof(MOVStreamContext));
5206  if (!sc) return AVERROR(ENOMEM);
5207 
5208  st->priv_data = sc;
5210  sc->ffindex = st->index;
5211  c->trak_index = st->index;
5212  sc->tref_flags = 0;
5213  sc->tref_id = -1;
5214  sc->refcount = 1;
5215 
5216  if ((ret = mov_read_default(c, pb, atom)) < 0)
5217  return ret;
5218 
5219  c->trak_index = -1;
5220 
5221  // Here stsc refers to a chunk not described in stco. This is technically invalid,
5222  // but we can overlook it (clearing stsc) whenever stts_count == 0 (indicating no samples).
5223  if (!sc->chunk_count && !sc->stts_count && sc->stsc_count) {
5224  sc->stsc_count = 0;
5225  av_freep(&sc->stsc_data);
5226  }
5227 
5228  ret = sanity_checks(c->fc, sc, st->index);
5229  if (ret)
5230  return ret > 1 ? AVERROR_INVALIDDATA : 0;
5231 
5232  fix_timescale(c, sc);
5233 
5234  avpriv_set_pts_info(st, 64, 1, sc->time_scale);
5235 
5236  /*
5237  * Advanced edit list support does not work with fragemented MP4s, which
5238  * have stsc, stsz, stco, and stts with zero entries in the moov atom.
5239  * In these files, trun atoms may be streamed in.
5240  */
5241  if (!sc->stts_count && c->advanced_editlist) {
5242 
5243  av_log(c->fc, AV_LOG_VERBOSE, "advanced_editlist does not work with fragmented "
5244  "MP4. disabling.\n");
5245  c->advanced_editlist = 0;
5246  c->advanced_editlist_autodisabled = 1;
5247  }
5248 
5249  mov_build_index(c, st);
5250 
5251 #if CONFIG_IAMFDEC
5252  if (sc->iamf) {
5253  ret = mov_update_iamf_streams(c, st);
5254  if (ret < 0)
5255  return ret;
5256  }
5257 #endif
5258 
5259  if (sc->dref_id-1 < sc->drefs_count && sc->drefs[sc->dref_id-1].path) {
5260  MOVDref *dref = &sc->drefs[sc->dref_id - 1];
5261  if (c->enable_drefs) {
5262  if (mov_open_dref(c, &sc->pb, c->fc->url, dref) < 0)
5263  av_log(c->fc, AV_LOG_ERROR,
5264  "stream %d, error opening alias: path='%s', dir='%s', "
5265  "filename='%s', volume='%s', nlvl_from=%d, nlvl_to=%d\n",
5266  st->index, dref->path, dref->dir, dref->filename,
5267  dref->volume, dref->nlvl_from, dref->nlvl_to);
5268  } else {
5269  av_log(c->fc, AV_LOG_WARNING,
5270  "Skipped opening external track: "
5271  "stream %d, alias: path='%s', dir='%s', "
5272  "filename='%s', volume='%s', nlvl_from=%d, nlvl_to=%d."
5273  "Set enable_drefs to allow this.\n",
5274  st->index, dref->path, dref->dir, dref->filename,
5275  dref->volume, dref->nlvl_from, dref->nlvl_to);
5276  }
5277  } else {
5278  sc->pb = c->fc->pb;
5279  sc->pb_is_copied = 1;
5280  }
5281 
5282  if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
5283  int stts_constant = sc->stts_count && sc->tts_count;
5284  if (sc->h_spacing && sc->v_spacing)
5286  sc->h_spacing, sc->v_spacing, INT_MAX);
5287  if (!st->sample_aspect_ratio.num && st->codecpar->width && st->codecpar->height &&
5288  sc->height && sc->width &&
5289  (st->codecpar->width != sc->width || st->codecpar->height != sc->height)) {
5291  (int64_t)st->codecpar->height * sc->width,
5292  (int64_t)st->codecpar->width * sc->height, INT_MAX);
5293  }
5294 
5295 #if FF_API_R_FRAME_RATE
5296  for (unsigned int i = 1; sc->stts_count && i + 1 < sc->tts_count; i++) {
5297  if (sc->tts_data[i].duration == sc->tts_data[0].duration)
5298  continue;
5299  stts_constant = 0;
5300  }
5301  if (stts_constant)
5303  sc->time_scale, sc->tts_data[0].duration, INT_MAX);
5304 #endif
5305  }
5306 
5307 #if CONFIG_H261_DECODER || CONFIG_H263_DECODER || CONFIG_MPEG4_DECODER
5308  switch (st->codecpar->codec_id) {
5309 #if CONFIG_H261_DECODER
5310  case AV_CODEC_ID_H261:
5311 #endif
5312 #if CONFIG_H263_DECODER
5313  case AV_CODEC_ID_H263:
5314 #endif
5315 #if CONFIG_MPEG4_DECODER
5316  case AV_CODEC_ID_MPEG4:
5317 #endif
5318  st->codecpar->width = 0; /* let decoder init width/height */
5319  st->codecpar->height= 0;
5320  break;
5321  }
5322 #endif
5323 
5324  // If the duration of the mp3 packets is not constant, then they could need a parser
5325  if (st->codecpar->codec_id == AV_CODEC_ID_MP3
5326  && sc->time_scale == st->codecpar->sample_rate) {
5327  int stts_constant = 1;
5328  for (int i = 1; sc->stts_count && i < sc->tts_count; i++) {
5329  if (sc->tts_data[i].duration == sc->tts_data[0].duration)
5330  continue;
5331  stts_constant = 0;
5332  }
5333  if (!stts_constant)
5335  }
5336  /* Do not need those anymore. */
5337  av_freep(&sc->chunk_offsets);
5338  av_freep(&sc->sample_sizes);
5339  av_freep(&sc->keyframes);
5340  av_freep(&sc->stps_data);
5341  av_freep(&sc->elst_data);
5342  av_freep(&sc->rap_group);
5343  av_freep(&sc->sync_group);
5344  av_freep(&sc->sgpd_sync);
5345 
5346  return 0;
5347 }
5348 
5350 {
5351  int ret;
5352  c->itunes_metadata = 1;
5353  ret = mov_read_default(c, pb, atom);
5354  c->itunes_metadata = 0;
5355  return ret;
5356 }
5357 
5359 {
5360  uint32_t count;
5361  uint32_t i;
5362 
5363  if (atom.size < 8)
5364  return 0;
5365 
5366  avio_skip(pb, 4);
5367  count = avio_rb32(pb);
5368  atom.size -= 8;
5369  if (count >= UINT_MAX / sizeof(*c->meta_keys)) {
5370  av_log(c->fc, AV_LOG_ERROR,
5371  "The 'keys' atom with the invalid key count: %"PRIu32"\n", count);
5372  return AVERROR_INVALIDDATA;
5373  }
5374 
5375  c->meta_keys_count = count + 1;
5376  c->meta_keys = av_mallocz(c->meta_keys_count * sizeof(*c->meta_keys));
5377  if (!c->meta_keys)
5378  return AVERROR(ENOMEM);
5379 
5380  for (i = 1; i <= count; ++i) {
5381  uint32_t key_size = avio_rb32(pb);
5382  uint32_t type = avio_rl32(pb);
5383  if (key_size < 8 || key_size > atom.size) {
5384  av_log(c->fc, AV_LOG_ERROR,
5385  "The key# %"PRIu32" in meta has invalid size:"
5386  "%"PRIu32"\n", i, key_size);
5387  return AVERROR_INVALIDDATA;
5388  }
5389  atom.size -= key_size;
5390  key_size -= 8;
5391  if (type != MKTAG('m','d','t','a')) {
5392  avio_skip(pb, key_size);
5393  continue;
5394  }
5395  c->meta_keys[i] = av_mallocz(key_size + 1);
5396  if (!c->meta_keys[i])
5397  return AVERROR(ENOMEM);
5398  avio_read(pb, c->meta_keys[i], key_size);
5399  }
5400 
5401  return 0;
5402 }
5403 
5405 {
5406  int64_t end = av_sat_add64(avio_tell(pb), atom.size);
5407  uint8_t *key = NULL, *val = NULL, *mean = NULL;
5408  int i;
5409  int ret = 0;
5410  AVStream *st;
5411  MOVStreamContext *sc;
5412 
5413  if (c->fc->nb_streams < 1)
5414  return 0;
5415  st = c->fc->streams[c->fc->nb_streams-1];
5416  sc = st->priv_data;
5417 
5418  for (i = 0; i < 3; i++) {
5419  uint8_t **p;
5420  uint32_t len, tag;
5421 
5422  if (end - avio_tell(pb) <= 12)
5423  break;
5424 
5425  len = avio_rb32(pb);
5426  tag = avio_rl32(pb);
5427  avio_skip(pb, 4); // flags
5428 
5429  if (len < 12 || len - 12 > end - avio_tell(pb))
5430  break;
5431  len -= 12;
5432 
5433  if (tag == MKTAG('m', 'e', 'a', 'n'))
5434  p = &mean;
5435  else if (tag == MKTAG('n', 'a', 'm', 'e'))
5436  p = &key;
5437  else if (tag == MKTAG('d', 'a', 't', 'a') && len > 4) {
5438  avio_skip(pb, 4);
5439  len -= 4;
5440  p = &val;
5441  } else
5442  break;
5443 
5444  if (*p)
5445  break;
5446 
5447  *p = av_malloc(len + 1);
5448  if (!*p) {
5449  ret = AVERROR(ENOMEM);
5450  break;
5451  }
5452  ret = ffio_read_size(pb, *p, len);
5453  if (ret < 0) {
5454  av_freep(p);
5455  break;
5456  }
5457  (*p)[len] = 0;
5458  }
5459 
5460  if (mean && key && val) {
5461  if (strcmp(key, "iTunSMPB") == 0) {
5462  int priming, remainder, samples;
5463  if(sscanf(val, "%*X %X %X %X", &priming, &remainder, &samples) == 3){
5464  if(priming>0 && priming<16384)
5465  sc->start_pad = priming;
5466  }
5467  }
5468  if (strcmp(key, "cdec") != 0) {
5469  av_dict_set(&c->fc->metadata, key, val,
5471  key = val = NULL;
5472  }
5473  } else {
5474  av_log(c->fc, AV_LOG_VERBOSE,
5475  "Unhandled or malformed custom metadata of size %"PRId64"\n", atom.size);
5476  }
5477 
5478  avio_seek(pb, end, SEEK_SET);
5479  av_freep(&key);
5480  av_freep(&val);
5481  av_freep(&mean);
5482  return ret;
5483 }
5484 
5486 {
5487  MOVStreamContext *sc;
5488  AVStream *st;
5489 
5490  st = avformat_new_stream(c->fc, NULL);
5491  if (!st)
5492  return AVERROR(ENOMEM);
5493  sc = av_mallocz(sizeof(MOVStreamContext));
5494  if (!sc)
5495  goto fail;
5496 
5497  item->st = st;
5498  st->id = item->item_id;
5499  st->priv_data = sc;
5501  st->codecpar->codec_id = mov_codec_id(st, item->type);
5502  sc->id = st->id;
5503  sc->ffindex = st->index;
5504  st->avg_frame_rate.num = st->avg_frame_rate.den = 1;
5505  st->time_base.num = st->time_base.den = 1;
5506  st->nb_frames = 1;
5507  sc->time_scale = 1;
5508  sc->pb = c->fc->pb;
5509  sc->pb_is_copied = 1;
5510  sc->refcount = 1;
5511 
5512  if (item->name)
5513  av_dict_set(&st->metadata, "title", item->name, 0);
5514 
5515  // Populate the necessary fields used by mov_build_index.
5516  sc->stsc_data = av_malloc_array(1, sizeof(*sc->stsc_data));
5517  if (!sc->stsc_data)
5518  goto fail;
5519  sc->stsc_count = 1;
5520  sc->stsc_data[0].first = 1;
5521  sc->stsc_data[0].count = 1;
5522  sc->stsc_data[0].id = 1;
5523  sc->chunk_offsets = av_malloc_array(1, sizeof(*sc->chunk_offsets));
5524  if (!sc->chunk_offsets)
5525  goto fail;
5526  sc->chunk_count = 1;
5527  sc->stts_data = av_malloc_array(1, sizeof(*sc->stts_data));
5528  if (!sc->stts_data)
5529  goto fail;
5530  sc->stts_count = 1;
5531  sc->stts_data[0].count = 1;
5532  // Not used for still images. But needed by mov_build_index.
5533  sc->stts_data[0].duration = 0;
5534 
5535  return 0;
5536 fail:
5537  mov_free_stream_context(c->fc, st);
5538  ff_remove_stream(c->fc, st);
5539  item->st = NULL;
5540 
5541  return AVERROR(ENOMEM);
5542 }
5543 
5545 {
5546  while (atom.size > 8) {
5547  uint32_t tag;
5548  if (avio_feof(pb))
5549  return AVERROR_EOF;
5550  tag = avio_rl32(pb);
5551  atom.size -= 4;
5552  if (tag == MKTAG('h','d','l','r')) {
5553  avio_seek(pb, -8, SEEK_CUR);
5554  atom.size += 8;
5555  return mov_read_default(c, pb, atom);
5556  }
5557  }
5558  return 0;
5559 }
5560 
5561 // return 1 when matrix is identity, 0 otherwise
5562 #define IS_MATRIX_IDENT(matrix) \
5563  ( (matrix)[0][0] == (1 << 16) && \
5564  (matrix)[1][1] == (1 << 16) && \
5565  (matrix)[2][2] == (1 << 30) && \
5566  !(matrix)[0][1] && !(matrix)[0][2] && \
5567  !(matrix)[1][0] && !(matrix)[1][2] && \
5568  !(matrix)[2][0] && !(matrix)[2][1])
5569 
5571 {
5572  int i, j, e;
5573  int width;
5574  int height;
5575  int display_matrix[3][3];
5576  int res_display_matrix[3][3] = { { 0 } };
5577  AVStream *st;
5578  MOVStreamContext *sc;
5579  int version;
5580  int flags;
5581 
5582  if (c->fc->nb_streams < 1)
5583  return 0;
5584  st = c->fc->streams[c->fc->nb_streams-1];
5585  sc = st->priv_data;
5586 
5587  // Each stream (trak) should have exactly 1 tkhd. This catches bad files and
5588  // avoids corrupting AVStreams mapped to an earlier tkhd.
5589  if (st->id != -1)
5590  return AVERROR_INVALIDDATA;
5591 
5592  version = avio_r8(pb);
5593  flags = avio_rb24(pb);
5595 
5596  if (version == 1) {
5597  avio_rb64(pb);
5598  avio_rb64(pb);
5599  } else {
5600  avio_rb32(pb); /* creation time */
5601  avio_rb32(pb); /* modification time */
5602  }
5603  st->id = (int)avio_rb32(pb); /* track id (NOT 0 !)*/
5604  sc->id = st->id;
5605  avio_rb32(pb); /* reserved */
5606 
5607  /* highlevel (considering edits) duration in movie timebase */
5608  (version == 1) ? avio_rb64(pb) : avio_rb32(pb);
5609  avio_rb32(pb); /* reserved */
5610  avio_rb32(pb); /* reserved */
5611 
5612  avio_rb16(pb); /* layer */
5613  avio_rb16(pb); /* alternate group */
5614  avio_rb16(pb); /* volume */
5615  avio_rb16(pb); /* reserved */
5616 
5617  //read in the display matrix (outlined in ISO 14496-12, Section 6.2.2)
5618  // they're kept in fixed point format through all calculations
5619  // save u,v,z to store the whole matrix in the AV_PKT_DATA_DISPLAYMATRIX
5620  // side data, but the scale factor is not needed to calculate aspect ratio
5621  for (i = 0; i < 3; i++) {
5622  display_matrix[i][0] = avio_rb32(pb); // 16.16 fixed point
5623  display_matrix[i][1] = avio_rb32(pb); // 16.16 fixed point
5624  display_matrix[i][2] = avio_rb32(pb); // 2.30 fixed point
5625  }
5626 
5627  width = avio_rb32(pb); // 16.16 fixed point track width
5628  height = avio_rb32(pb); // 16.16 fixed point track height
5629  sc->width = width >> 16;
5630  sc->height = height >> 16;
5631 
5632  // apply the moov display matrix (after the tkhd one)
5633  for (i = 0; i < 3; i++) {
5634  const int sh[3] = { 16, 16, 30 };
5635  for (j = 0; j < 3; j++) {
5636  for (e = 0; e < 3; e++) {
5637  res_display_matrix[i][j] +=
5638  ((int64_t) display_matrix[i][e] *
5639  c->movie_display_matrix[e][j]) >> sh[e];
5640  }
5641  }
5642  }
5643 
5644  // save the matrix when it is not the default identity
5645  if (!IS_MATRIX_IDENT(res_display_matrix)) {
5646  av_freep(&sc->display_matrix);
5647  sc->display_matrix = av_malloc(sizeof(int32_t) * 9);
5648  if (!sc->display_matrix)
5649  return AVERROR(ENOMEM);
5650 
5651  for (i = 0; i < 3; i++)
5652  for (j = 0; j < 3; j++)
5653  sc->display_matrix[i * 3 + j] = res_display_matrix[i][j];
5654  }
5655 
5656  // transform the display width/height according to the matrix
5657  // to keep the same scale, use [width height 1<<16]
5658  if (width && height && sc->display_matrix) {
5659  double disp_transform[2];
5660 
5661  for (i = 0; i < 2; i++)
5662  disp_transform[i] = hypot(sc->display_matrix[0 + i],
5663  sc->display_matrix[3 + i]);
5664 
5665  if (disp_transform[0] > 1 && disp_transform[1] > 1 &&
5666  disp_transform[0] < (1<<24) && disp_transform[1] < (1<<24) &&
5667  fabs((disp_transform[0] / disp_transform[1]) - 1.0) > 0.01)
5669  disp_transform[0] / disp_transform[1],
5670  INT_MAX);
5671  }
5672  return 0;
5673 }
5674 
5676 {
5677  MOVFragment *frag = &c->fragment;
5678  MOVTrackExt *trex = NULL;
5679  int flags, track_id, i;
5680  MOVFragmentStreamInfo * frag_stream_info;
5681 
5682  avio_r8(pb); /* version */
5683  flags = avio_rb24(pb);
5684 
5685  track_id = avio_rb32(pb);
5686  if (!track_id)
5687  return AVERROR_INVALIDDATA;
5688  for (i = 0; i < c->trex_count; i++)
5689  if (c->trex_data[i].track_id == track_id) {
5690  trex = &c->trex_data[i];
5691  break;
5692  }
5693  if (!trex) {
5694  av_log(c->fc, AV_LOG_WARNING, "could not find corresponding trex (id %u)\n", track_id);
5695  return 0;
5696  }
5697  c->fragment.found_tfhd = 1;
5698  frag->track_id = track_id;
5699  set_frag_stream(&c->frag_index, track_id);
5700 
5703  frag->moof_offset : frag->implicit_offset;
5704  frag->stsd_id = flags & MOV_TFHD_STSD_ID ? avio_rb32(pb) : trex->stsd_id;
5705 
5707  avio_rb32(pb) : trex->duration;
5708  frag->size = flags & MOV_TFHD_DEFAULT_SIZE ?
5709  avio_rb32(pb) : trex->size;
5710  frag->flags = flags & MOV_TFHD_DEFAULT_FLAGS ?
5711  avio_rb32(pb) : trex->flags;
5712  av_log(c->fc, AV_LOG_TRACE, "frag flags 0x%x\n", frag->flags);
5713 
5714  frag_stream_info = get_current_frag_stream_info(&c->frag_index);
5715  if (frag_stream_info) {
5716  frag_stream_info->next_trun_dts = AV_NOPTS_VALUE;
5717  frag_stream_info->stsd_id = frag->stsd_id;
5718  }
5719  return 0;
5720 }
5721 
5723 {
5724  unsigned i, num;
5725  void *new_tracks;
5726 
5727  num = atom.size / 4;
5728  if (!(new_tracks = av_malloc_array(num, sizeof(int))))
5729  return AVERROR(ENOMEM);
5730 
5731  av_free(c->chapter_tracks);
5732  c->chapter_tracks = new_tracks;
5733  c->nb_chapter_tracks = num;
5734 
5735  for (i = 0; i < num && !pb->eof_reached; i++)
5736  c->chapter_tracks[i] = avio_rb32(pb);
5737 
5738  c->nb_chapter_tracks = i;
5739 
5740  return 0;
5741 }
5742 
5744 {
5745  MOVTrackExt *trex;
5746  int err;
5747 
5748  if ((uint64_t)c->trex_count+1 >= UINT_MAX / sizeof(*c->trex_data))
5749  return AVERROR_INVALIDDATA;
5750  if ((err = av_reallocp_array(&c->trex_data, c->trex_count + 1,
5751  sizeof(*c->trex_data))) < 0) {
5752  c->trex_count = 0;
5753  return err;
5754  }
5755 
5756  c->fc->duration = AV_NOPTS_VALUE; // the duration from mvhd is not representing the whole file when fragments are used.
5757 
5758  trex = &c->trex_data[c->trex_count++];
5759  avio_r8(pb); /* version */
5760  avio_rb24(pb); /* flags */
5761  trex->track_id = avio_rb32(pb);
5762  trex->stsd_id = avio_rb32(pb);
5763  trex->duration = avio_rb32(pb);
5764  trex->size = avio_rb32(pb);
5765  trex->flags = avio_rb32(pb);
5766  return 0;
5767 }
5768 
5770 {
5771  MOVFragment *frag = &c->fragment;
5772  AVStream *st = NULL;
5773  MOVStreamContext *sc;
5774  int version, i;
5775  MOVFragmentStreamInfo * frag_stream_info;
5776  int64_t base_media_decode_time;
5777 
5778  for (i = 0; i < c->fc->nb_streams; i++) {
5779  sc = c->fc->streams[i]->priv_data;
5780  if (sc->id == frag->track_id) {
5781  st = c->fc->streams[i];
5782  break;
5783  }
5784  }
5785  if (!st) {
5786  av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %u\n", frag->track_id);
5787  return 0;
5788  }
5789  sc = st->priv_data;
5790  if (sc->pseudo_stream_id + 1 != frag->stsd_id && sc->pseudo_stream_id != -1)
5791  return 0;
5792  version = avio_r8(pb);
5793  avio_rb24(pb); /* flags */
5794  if (version) {
5795  base_media_decode_time = avio_rb64(pb);
5796  } else {
5797  base_media_decode_time = avio_rb32(pb);
5798  }
5799 
5800  frag_stream_info = get_current_frag_stream_info(&c->frag_index);
5801  if (frag_stream_info)
5802  frag_stream_info->tfdt_dts = base_media_decode_time;
5803  sc->track_end = base_media_decode_time;
5804 
5805  return 0;
5806 }
5807 
5809 {
5810  MOVFragment *frag = &c->fragment;
5811  AVStream *st = NULL;
5812  FFStream *sti = NULL;
5813  MOVStreamContext *sc;
5814  MOVTimeToSample *tts_data;
5815  uint64_t offset;
5816  int64_t dts, pts = AV_NOPTS_VALUE;
5817  int data_offset = 0;
5818  unsigned entries, first_sample_flags = frag->flags;
5819  int flags, distance, i;
5820  int64_t prev_dts = AV_NOPTS_VALUE;
5821  int next_frag_index = -1, index_entry_pos;
5822  size_t requested_size;
5823  size_t old_allocated_size;
5824  AVIndexEntry *new_entries;
5825  MOVFragmentStreamInfo * frag_stream_info;
5826 
5827  if (!frag->found_tfhd) {
5828  av_log(c->fc, AV_LOG_ERROR, "trun track id unknown, no tfhd was found\n");
5829  return AVERROR_INVALIDDATA;
5830  }
5831 
5832  for (i = 0; i < c->fc->nb_streams; i++) {
5833  sc = c->fc->streams[i]->priv_data;
5834  if (sc->id == frag->track_id) {
5835  st = c->fc->streams[i];
5836  sti = ffstream(st);
5837  break;
5838  }
5839  }
5840  if (!st) {
5841  av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %u\n", frag->track_id);
5842  return 0;
5843  }
5844  sc = st->priv_data;
5845  if (sc->pseudo_stream_id+1 != frag->stsd_id && sc->pseudo_stream_id != -1)
5846  return 0;
5847 
5848  // Find the next frag_index index that has a valid index_entry for
5849  // the current track_id.
5850  //
5851  // A valid index_entry means the trun for the fragment was read
5852  // and it's samples are in index_entries at the given position.
5853  // New index entries will be inserted before the index_entry found.
5854  index_entry_pos = sti->nb_index_entries;
5855  for (i = c->frag_index.current + 1; i < c->frag_index.nb_items; i++) {
5856  frag_stream_info = get_frag_stream_info(&c->frag_index, i, frag->track_id);
5857  if (frag_stream_info && frag_stream_info->index_entry >= 0) {
5858  next_frag_index = i;
5859  index_entry_pos = frag_stream_info->index_entry;
5860  break;
5861  }
5862  }
5863  av_assert0(index_entry_pos <= sti->nb_index_entries);
5864 
5865  avio_r8(pb); /* version */
5866  flags = avio_rb24(pb);
5867  entries = avio_rb32(pb);
5868  av_log(c->fc, AV_LOG_TRACE, "flags 0x%x entries %u\n", flags, entries);
5869 
5870  if ((uint64_t)entries+sc->tts_count >= UINT_MAX/sizeof(*sc->tts_data))
5871  return AVERROR_INVALIDDATA;
5872  if (flags & MOV_TRUN_DATA_OFFSET) data_offset = avio_rb32(pb);
5873  if (flags & MOV_TRUN_FIRST_SAMPLE_FLAGS) first_sample_flags = avio_rb32(pb);
5874 
5875  frag_stream_info = get_current_frag_stream_info(&c->frag_index);
5876  if (frag_stream_info) {
5877  if (frag_stream_info->next_trun_dts != AV_NOPTS_VALUE) {
5878  dts = frag_stream_info->next_trun_dts - sc->time_offset;
5879  } else if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE &&
5880  c->use_mfra_for == FF_MOV_FLAG_MFRA_PTS) {
5881  pts = frag_stream_info->first_tfra_pts;
5882  av_log(c->fc, AV_LOG_DEBUG, "found mfra time %"PRId64
5883  ", using it for pts\n", pts);
5884  } else if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE &&
5885  c->use_mfra_for == FF_MOV_FLAG_MFRA_DTS) {
5886  dts = frag_stream_info->first_tfra_pts;
5887  av_log(c->fc, AV_LOG_DEBUG, "found mfra time %"PRId64
5888  ", using it for dts\n", pts);
5889  } else {
5890  int has_tfdt = frag_stream_info->tfdt_dts != AV_NOPTS_VALUE;
5891  int has_sidx = frag_stream_info->sidx_pts != AV_NOPTS_VALUE;
5892  int fallback_tfdt = !c->use_tfdt && !has_sidx && has_tfdt;
5893  int fallback_sidx = c->use_tfdt && !has_tfdt && has_sidx;
5894 
5895  if (fallback_sidx) {
5896  av_log(c->fc, AV_LOG_DEBUG, "use_tfdt set but no tfdt found, using sidx instead\n");
5897  }
5898  if (fallback_tfdt) {
5899  av_log(c->fc, AV_LOG_DEBUG, "use_tfdt not set but no sidx found, using tfdt instead\n");
5900  }
5901 
5902  if (has_tfdt && c->use_tfdt || fallback_tfdt) {
5903  dts = frag_stream_info->tfdt_dts - sc->time_offset;
5904  av_log(c->fc, AV_LOG_DEBUG, "found tfdt time %"PRId64
5905  ", using it for dts\n", dts);
5906  } else if (has_sidx && !c->use_tfdt || fallback_sidx) {
5907  // FIXME: sidx earliest_presentation_time is *PTS*, s.b.
5908  // pts = frag_stream_info->sidx_pts;
5909  dts = frag_stream_info->sidx_pts;
5910  av_log(c->fc, AV_LOG_DEBUG, "found sidx time %"PRId64
5911  ", using it for dts\n", frag_stream_info->sidx_pts);
5912  } else {
5913  dts = sc->track_end - sc->time_offset;
5914  av_log(c->fc, AV_LOG_DEBUG, "found track end time %"PRId64
5915  ", using it for dts\n", dts);
5916  }
5917  }
5918  } else {
5919  dts = sc->track_end - sc->time_offset;
5920  av_log(c->fc, AV_LOG_DEBUG, "found track end time %"PRId64
5921  ", using it for dts\n", dts);
5922  }
5923  offset = frag->base_data_offset + data_offset;
5924  distance = 0;
5925  av_log(c->fc, AV_LOG_TRACE, "first sample flags 0x%x\n", first_sample_flags);
5926 
5927  // realloc space for new index entries
5928  if ((uint64_t)sti->nb_index_entries + entries >= UINT_MAX / sizeof(AVIndexEntry)) {
5929  entries = UINT_MAX / sizeof(AVIndexEntry) - sti->nb_index_entries;
5930  av_log(c->fc, AV_LOG_ERROR, "Failed to add index entry\n");
5931  }
5932  if (entries == 0)
5933  return 0;
5934 
5935  requested_size = (sti->nb_index_entries + entries) * sizeof(AVIndexEntry);
5936  new_entries = av_fast_realloc(sti->index_entries,
5938  requested_size);
5939  if (!new_entries)
5940  return AVERROR(ENOMEM);
5941  sti->index_entries= new_entries;
5942 
5943  requested_size = (sti->nb_index_entries + entries) * sizeof(*sc->tts_data);
5944  old_allocated_size = sc->tts_allocated_size;
5945  tts_data = av_fast_realloc(sc->tts_data, &sc->tts_allocated_size,
5946  requested_size);
5947  if (!tts_data)
5948  return AVERROR(ENOMEM);
5949  sc->tts_data = tts_data;
5950 
5951  // In case there were samples without time to sample entries, ensure they get
5952  // zero valued entries. This ensures clips which mix boxes with and
5953  // without time to sample entries don't pickup uninitialized data.
5954  memset((uint8_t*)(sc->tts_data) + old_allocated_size, 0,
5955  sc->tts_allocated_size - old_allocated_size);
5956 
5957  if (index_entry_pos < sti->nb_index_entries) {
5958  // Make hole in index_entries and tts_data for new samples
5959  memmove(sti->index_entries + index_entry_pos + entries,
5960  sti->index_entries + index_entry_pos,
5961  sizeof(*sti->index_entries) *
5962  (sti->nb_index_entries - index_entry_pos));
5963  memmove(sc->tts_data + index_entry_pos + entries,
5964  sc->tts_data + index_entry_pos,
5965  sizeof(*sc->tts_data) * (sc->tts_count - index_entry_pos));
5966  if (index_entry_pos < sc->current_sample) {
5967  sc->current_sample += entries;
5968  }
5969  }
5970 
5971  sti->nb_index_entries += entries;
5972  sc->tts_count = sti->nb_index_entries;
5973  sc->stts_count = sti->nb_index_entries;
5974  if (flags & MOV_TRUN_SAMPLE_CTS)
5975  sc->ctts_count = sti->nb_index_entries;
5976 
5977  // Record the index_entry position in frag_index of this fragment
5978  if (frag_stream_info) {
5979  frag_stream_info->index_entry = index_entry_pos;
5980  if (frag_stream_info->index_base < 0)
5981  frag_stream_info->index_base = index_entry_pos;
5982  }
5983 
5984  if (index_entry_pos > 0)
5985  prev_dts = sti->index_entries[index_entry_pos-1].timestamp;
5986 
5987  for (i = 0; i < entries && !pb->eof_reached; i++) {
5988  unsigned sample_size = frag->size;
5989  int sample_flags = i ? frag->flags : first_sample_flags;
5990  unsigned sample_duration = frag->duration;
5991  unsigned ctts_duration = 0;
5992  int keyframe = 0;
5993  int index_entry_flags = 0;
5994 
5995  if (flags & MOV_TRUN_SAMPLE_DURATION) sample_duration = avio_rb32(pb);
5996  if (flags & MOV_TRUN_SAMPLE_SIZE) sample_size = avio_rb32(pb);
5997  if (flags & MOV_TRUN_SAMPLE_FLAGS) sample_flags = avio_rb32(pb);
5998  if (flags & MOV_TRUN_SAMPLE_CTS) ctts_duration = avio_rb32(pb);
5999 
6000  mov_update_dts_shift(sc, ctts_duration, c->fc);
6001  if (pts != AV_NOPTS_VALUE) {
6002  dts = pts - sc->dts_shift;
6003  if (flags & MOV_TRUN_SAMPLE_CTS) {
6004  dts -= ctts_duration;
6005  } else {
6006  dts -= sc->time_offset;
6007  }
6008  av_log(c->fc, AV_LOG_DEBUG,
6009  "pts %"PRId64" calculated dts %"PRId64
6010  " sc->dts_shift %d ctts.duration %d"
6011  " sc->time_offset %"PRId64
6012  " flags & MOV_TRUN_SAMPLE_CTS %d\n",
6013  pts, dts,
6014  sc->dts_shift, ctts_duration,
6016  pts = AV_NOPTS_VALUE;
6017  }
6018 
6019  keyframe =
6020  !(sample_flags & (MOV_FRAG_SAMPLE_FLAG_IS_NON_SYNC |
6022  if (keyframe) {
6023  distance = 0;
6024  index_entry_flags |= AVINDEX_KEYFRAME;
6025  }
6026  // Fragments can overlap in time. Discard overlapping frames after
6027  // decoding.
6028  if (prev_dts >= dts)
6029  index_entry_flags |= AVINDEX_DISCARD_FRAME;
6030 
6031  sti->index_entries[index_entry_pos].pos = offset;
6032  sti->index_entries[index_entry_pos].timestamp = dts;
6033  sti->index_entries[index_entry_pos].size = sample_size;
6034  sti->index_entries[index_entry_pos].min_distance = distance;
6035  sti->index_entries[index_entry_pos].flags = index_entry_flags;
6036 
6037  sc->tts_data[index_entry_pos].count = 1;
6038  sc->tts_data[index_entry_pos].offset = ctts_duration;
6039  sc->tts_data[index_entry_pos].duration = sample_duration;
6040  index_entry_pos++;
6041 
6042  av_log(c->fc, AV_LOG_TRACE, "AVIndex stream %d, sample %d, offset %"PRIx64", dts %"PRId64", "
6043  "size %u, distance %d, keyframe %d\n", st->index,
6044  index_entry_pos, offset, dts, sample_size, distance, keyframe);
6045  distance++;
6046  if (av_sat_add64(dts, sample_duration) != dts + (uint64_t)sample_duration)
6047  return AVERROR_INVALIDDATA;
6048  if (!sample_size)
6049  return AVERROR_INVALIDDATA;
6050  dts += sample_duration;
6051  offset += sample_size;
6052  sc->data_size += sample_size;
6053 
6054  if (sample_duration <= INT64_MAX - sc->duration_for_fps &&
6055  1 <= INT_MAX - sc->nb_frames_for_fps
6056  ) {
6057  sc->duration_for_fps += sample_duration;
6058  sc->nb_frames_for_fps ++;
6059  }
6060  }
6061  if (frag_stream_info)
6062  frag_stream_info->next_trun_dts = dts + sc->time_offset;
6063  if (i < entries) {
6064  // EOF found before reading all entries. Fix the hole this would
6065  // leave in index_entries and tts_data
6066  int gap = entries - i;
6067  memmove(sti->index_entries + index_entry_pos,
6068  sti->index_entries + index_entry_pos + gap,
6069  sizeof(*sti->index_entries) *
6070  (sti->nb_index_entries - (index_entry_pos + gap)));
6071  memmove(sc->tts_data + index_entry_pos,
6072  sc->tts_data + index_entry_pos + gap,
6073  sizeof(*sc->tts_data) *
6074  (sc->tts_count - (index_entry_pos + gap)));
6075 
6076  sti->nb_index_entries -= gap;
6077  sc->tts_count -= gap;
6078  if (index_entry_pos < sc->current_sample) {
6079  sc->current_sample -= gap;
6080  }
6081  entries = i;
6082  }
6083 
6084  // The end of this new fragment may overlap in time with the start
6085  // of the next fragment in index_entries. Mark the samples in the next
6086  // fragment that overlap with AVINDEX_DISCARD_FRAME
6087  prev_dts = AV_NOPTS_VALUE;
6088  if (index_entry_pos > 0)
6089  prev_dts = sti->index_entries[index_entry_pos-1].timestamp;
6090  for (int i = index_entry_pos; i < sti->nb_index_entries; i++) {
6091  if (prev_dts < sti->index_entries[i].timestamp)
6092  break;
6094  }
6095 
6096  // If a hole was created to insert the new index_entries into,
6097  // the index_entry recorded for all subsequent moof must
6098  // be incremented by the number of entries inserted.
6099  fix_frag_index_entries(&c->frag_index, next_frag_index,
6100  frag->track_id, entries);
6101 
6102  if (pb->eof_reached) {
6103  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted TRUN atom\n");
6104  return AVERROR_EOF;
6105  }
6106 
6107  frag->implicit_offset = offset;
6108 
6109  sc->track_end = dts + sc->time_offset;
6110  if (st->duration < sc->track_end)
6111  st->duration = sc->track_end;
6112 
6113  return 0;
6114 }
6115 
6117 {
6118  int64_t stream_size = avio_size(pb);
6119  int64_t offset = av_sat_add64(avio_tell(pb), atom.size), pts, timestamp;
6120  uint8_t version, is_complete;
6121  int64_t offadd;
6122  unsigned i, j, track_id, item_count;
6123  AVStream *st = NULL;
6124  AVStream *ref_st = NULL;
6125  MOVStreamContext *sc, *ref_sc = NULL;
6126  AVRational timescale;
6127 
6128  version = avio_r8(pb);
6129  if (version > 1) {
6130  avpriv_request_sample(c->fc, "sidx version %u", version);
6131  return 0;
6132  }
6133 
6134  avio_rb24(pb); // flags
6135 
6136  track_id = avio_rb32(pb); // Reference ID
6137  for (i = 0; i < c->fc->nb_streams; i++) {
6138  sc = c->fc->streams[i]->priv_data;
6139  if (sc->id == track_id) {
6140  st = c->fc->streams[i];
6141  break;
6142  }
6143  }
6144  if (!st) {
6145  av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %d\n", track_id);
6146  return 0;
6147  }
6148 
6149  sc = st->priv_data;
6150 
6151  timescale = av_make_q(1, avio_rb32(pb));
6152 
6153  if (timescale.den <= 0) {
6154  av_log(c->fc, AV_LOG_ERROR, "Invalid sidx timescale 1/%d\n", timescale.den);
6155  return AVERROR_INVALIDDATA;
6156  }
6157 
6158  if (version == 0) {
6159  pts = avio_rb32(pb);
6160  offadd= avio_rb32(pb);
6161  } else {
6162  pts = avio_rb64(pb);
6163  offadd= avio_rb64(pb);
6164  }
6165  if (av_sat_add64(offset, offadd) != offset + (uint64_t)offadd)
6166  return AVERROR_INVALIDDATA;
6167 
6168  offset += (uint64_t)offadd;
6169 
6170  avio_rb16(pb); // reserved
6171 
6172  item_count = avio_rb16(pb);
6173  if (item_count == 0)
6174  return AVERROR_INVALIDDATA;
6175 
6176  for (i = 0; i < item_count; i++) {
6177  int index;
6178  MOVFragmentStreamInfo * frag_stream_info;
6179  uint32_t size = avio_rb32(pb);
6180  uint32_t duration = avio_rb32(pb);
6181  if (size & 0x80000000) {
6182  avpriv_request_sample(c->fc, "sidx reference_type 1");
6183  return AVERROR_PATCHWELCOME;
6184  }
6185  avio_rb32(pb); // sap_flags
6186  timestamp = av_rescale_q(pts, timescale, st->time_base);
6187 
6189  frag_stream_info = get_frag_stream_info(&c->frag_index, index, track_id);
6190  if (frag_stream_info)
6191  frag_stream_info->sidx_pts = timestamp;
6192 
6193  if (av_sat_add64(offset, size) != offset + (uint64_t)size ||
6194  av_sat_add64(pts, duration) != pts + (uint64_t)duration
6195  )
6196  return AVERROR_INVALIDDATA;
6197  offset += size;
6198  pts += duration;
6199  }
6200 
6201  st->duration = sc->track_end = pts;
6202 
6203  sc->has_sidx = 1;
6204 
6205  // See if the remaining bytes are just an mfra which we can ignore.
6206  is_complete = offset == stream_size;
6207  if (!is_complete && (pb->seekable & AVIO_SEEKABLE_NORMAL) && stream_size > 0 ) {
6208  int64_t ret;
6209  int64_t original_pos = avio_tell(pb);
6210  if (!c->have_read_mfra_size) {
6211  if ((ret = avio_seek(pb, stream_size - 4, SEEK_SET)) < 0)
6212  return ret;
6213  c->mfra_size = avio_rb32(pb);
6214  c->have_read_mfra_size = 1;
6215  if ((ret = avio_seek(pb, original_pos, SEEK_SET)) < 0)
6216  return ret;
6217  }
6218  if (offset == stream_size - c->mfra_size)
6219  is_complete = 1;
6220  }
6221 
6222  if (is_complete) {
6223  // Find first entry in fragment index that came from an sidx.
6224  // This will pretty much always be the first entry.
6225  for (i = 0; i < c->frag_index.nb_items; i++) {
6226  MOVFragmentIndexItem * item = &c->frag_index.item[i];
6227  for (j = 0; ref_st == NULL && j < item->nb_stream_info; j++) {
6228  MOVFragmentStreamInfo * si;
6229  si = &item->stream_info[j];
6230  if (si->sidx_pts != AV_NOPTS_VALUE) {
6231  ref_st = c->fc->streams[j];
6232  ref_sc = ref_st->priv_data;
6233  break;
6234  }
6235  }
6236  }
6237  if (ref_st) for (i = 0; i < c->fc->nb_streams; i++) {
6238  st = c->fc->streams[i];
6239  sc = st->priv_data;
6240  if (!sc->has_sidx) {
6241  st->duration = sc->track_end = av_rescale(ref_st->duration, sc->time_scale, ref_sc->time_scale);
6242  }
6243  }
6244 
6245  if (offadd == 0)
6246  c->frag_index.complete = 1;
6247  }
6248 
6249  return 0;
6250 }
6251 
6252 /* this atom should be null (from specs), but some buggy files put the 'moov' atom inside it... */
6253 /* like the files created with Adobe Premiere 5.0, for samples see */
6254 /* http://graphics.tudelft.nl/~wouter/publications/soundtests/ */
6256 {
6257  int err;
6258 
6259  if (atom.size < 8)
6260  return 0; /* continue */
6261  if (avio_rb32(pb) != 0) { /* 0 sized mdat atom... use the 'wide' atom size */
6262  avio_skip(pb, atom.size - 4);
6263  return 0;
6264  }
6265  atom.type = avio_rl32(pb);
6266  atom.size -= 8;
6267  if (atom.type != MKTAG('m','d','a','t')) {
6268  avio_skip(pb, atom.size);
6269  return 0;
6270  }
6271  err = mov_read_mdat(c, pb, atom);
6272  return err;
6273 }
6274 
6276 {
6277 #if CONFIG_ZLIB
6278  FFIOContext ctx;
6279  uint8_t *cmov_data;
6280  uint8_t *moov_data; /* uncompressed data */
6281  long cmov_len, moov_len;
6282  int ret = -1;
6283 
6284  avio_rb32(pb); /* dcom atom */
6285  if (avio_rl32(pb) != MKTAG('d','c','o','m'))
6286  return AVERROR_INVALIDDATA;
6287  if (avio_rl32(pb) != MKTAG('z','l','i','b')) {
6288  av_log(c->fc, AV_LOG_ERROR, "unknown compression for cmov atom !\n");
6289  return AVERROR_INVALIDDATA;
6290  }
6291  avio_rb32(pb); /* cmvd atom */
6292  if (avio_rl32(pb) != MKTAG('c','m','v','d'))
6293  return AVERROR_INVALIDDATA;
6294  moov_len = avio_rb32(pb); /* uncompressed size */
6295  cmov_len = atom.size - 6 * 4;
6296 
6297  cmov_data = av_malloc(cmov_len);
6298  if (!cmov_data)
6299  return AVERROR(ENOMEM);
6300  moov_data = av_malloc(moov_len);
6301  if (!moov_data) {
6302  av_free(cmov_data);
6303  return AVERROR(ENOMEM);
6304  }
6305  ret = ffio_read_size(pb, cmov_data, cmov_len);
6306  if (ret < 0)
6307  goto free_and_return;
6308 
6310  if (uncompress (moov_data, (uLongf *) &moov_len, (const Bytef *)cmov_data, cmov_len) != Z_OK)
6311  goto free_and_return;
6312  ffio_init_read_context(&ctx, moov_data, moov_len);
6313  ctx.pub.seekable = AVIO_SEEKABLE_NORMAL;
6314  atom.type = MKTAG('m','o','o','v');
6315  atom.size = moov_len;
6316  ret = mov_read_default(c, &ctx.pub, atom);
6317 free_and_return:
6318  av_free(moov_data);
6319  av_free(cmov_data);
6320  return ret;
6321 #else
6322  av_log(c->fc, AV_LOG_ERROR, "this file requires zlib support compiled in\n");
6323  return AVERROR(ENOSYS);
6324 #endif
6325 }
6326 
6327 /* edit list atom */
6329 {
6330  MOVStreamContext *sc;
6331  int i, edit_count, version;
6332  int64_t elst_entry_size;
6333 
6334  if (c->fc->nb_streams < 1 || c->ignore_editlist)
6335  return 0;
6336  sc = c->fc->streams[c->fc->nb_streams-1]->priv_data;
6337 
6338  version = avio_r8(pb); /* version */
6339  avio_rb24(pb); /* flags */
6340  edit_count = avio_rb32(pb); /* entries */
6341  atom.size -= 8;
6342 
6343  elst_entry_size = version == 1 ? 20 : 12;
6344  if (atom.size != edit_count * elst_entry_size) {
6345  if (c->fc->strict_std_compliance >= FF_COMPLIANCE_STRICT) {
6346  av_log(c->fc, AV_LOG_ERROR, "Invalid edit list entry_count: %d for elst atom of size: %"PRId64" bytes.\n",
6347  edit_count, atom.size + 8);
6348  return AVERROR_INVALIDDATA;
6349  } else {
6350  edit_count = atom.size / elst_entry_size;
6351  if (edit_count * elst_entry_size != atom.size) {
6352  av_log(c->fc, AV_LOG_WARNING, "ELST atom of %"PRId64" bytes, bigger than %d entries.\n", atom.size, edit_count);
6353  }
6354  }
6355  }
6356 
6357  if (!edit_count)
6358  return 0;
6359  if (sc->elst_data)
6360  av_log(c->fc, AV_LOG_WARNING, "Duplicated ELST atom\n");
6361  av_free(sc->elst_data);
6362  sc->elst_count = 0;
6363  sc->elst_data = av_malloc_array(edit_count, sizeof(*sc->elst_data));
6364  if (!sc->elst_data)
6365  return AVERROR(ENOMEM);
6366 
6367  av_log(c->fc, AV_LOG_TRACE, "track[%u].edit_count = %i\n", c->fc->nb_streams - 1, edit_count);
6368  for (i = 0; i < edit_count && atom.size > 0 && !pb->eof_reached; i++) {
6369  MOVElst *e = &sc->elst_data[i];
6370 
6371  if (version == 1) {
6372  e->duration = avio_rb64(pb);
6373  e->time = avio_rb64(pb);
6374  atom.size -= 16;
6375  } else {
6376  e->duration = avio_rb32(pb); /* segment duration */
6377  e->time = (int32_t)avio_rb32(pb); /* media time */
6378  atom.size -= 8;
6379  }
6380  e->rate = avio_rb32(pb) / 65536.0;
6381  atom.size -= 4;
6382  av_log(c->fc, AV_LOG_TRACE, "duration=%"PRId64" time=%"PRId64" rate=%f\n",
6383  e->duration, e->time, e->rate);
6384 
6385  if (e->time < 0 && e->time != -1 &&
6386  c->fc->strict_std_compliance >= FF_COMPLIANCE_STRICT) {
6387  av_log(c->fc, AV_LOG_ERROR, "Track %d, edit %d: Invalid edit list media time=%"PRId64"\n",
6388  c->fc->nb_streams-1, i, e->time);
6389  return AVERROR_INVALIDDATA;
6390  }
6391  if (e->duration < 0) {
6392  av_log(c->fc, AV_LOG_ERROR, "Track %d, edit %d: Invalid edit list duration=%"PRId64"\n",
6393  c->fc->nb_streams-1, i, e->duration);
6394  return AVERROR_INVALIDDATA;
6395  }
6396  }
6397  sc->elst_count = i;
6398 
6399  return 0;
6400 }
6401 
6403 {
6404  MOVStreamContext *sc;
6405 
6406  if (c->fc->nb_streams < 1)
6407  return AVERROR_INVALIDDATA;
6408  sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
6409  sc->timecode_track = avio_rb32(pb);
6410  return 0;
6411 }
6412 
6414 {
6415  AVStream *st;
6416  int version, color_range, color_primaries, color_trc, color_space;
6417 
6418  if (c->fc->nb_streams < 1)
6419  return 0;
6420  st = c->fc->streams[c->fc->nb_streams - 1];
6421 
6422  if (atom.size < 5) {
6423  av_log(c->fc, AV_LOG_ERROR, "Empty VP Codec Configuration box\n");
6424  return AVERROR_INVALIDDATA;
6425  }
6426 
6427  version = avio_r8(pb);
6428  if (version != 1) {
6429  av_log(c->fc, AV_LOG_WARNING, "Unsupported VP Codec Configuration box version %d\n", version);
6430  return 0;
6431  }
6432  avio_skip(pb, 3); /* flags */
6433 
6434  avio_skip(pb, 2); /* profile + level */
6435  color_range = avio_r8(pb); /* bitDepth, chromaSubsampling, videoFullRangeFlag */
6436  color_primaries = avio_r8(pb);
6437  color_trc = avio_r8(pb);
6438  color_space = avio_r8(pb);
6439  if (avio_rb16(pb)) /* codecIntializationDataSize */
6440  return AVERROR_INVALIDDATA;
6441 
6444  if (!av_color_transfer_name(color_trc))
6445  color_trc = AVCOL_TRC_UNSPECIFIED;
6446  if (!av_color_space_name(color_space))
6447  color_space = AVCOL_SPC_UNSPECIFIED;
6448 
6451  st->codecpar->color_trc = color_trc;
6452  st->codecpar->color_space = color_space;
6453 
6454  return 0;
6455 }
6456 
6458 {
6459  MOVStreamContext *sc;
6460  int i, version;
6461 
6462  if (c->fc->nb_streams < 1)
6463  return AVERROR_INVALIDDATA;
6464 
6465  sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
6466 
6467  if (atom.size < 5) {
6468  av_log(c->fc, AV_LOG_ERROR, "Empty Mastering Display Metadata box\n");
6469  return AVERROR_INVALIDDATA;
6470  }
6471 
6472  version = avio_r8(pb);
6473  if (version) {
6474  av_log(c->fc, AV_LOG_WARNING, "Unsupported Mastering Display Metadata box version %d\n", version);
6475  return 0;
6476  }
6477  if (sc->mastering) {
6478  av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicate Mastering Display Metadata\n");
6479  return 0;
6480  }
6481 
6482  avio_skip(pb, 3); /* flags */
6483 
6485  if (!sc->mastering)
6486  return AVERROR(ENOMEM);
6487 
6488  for (i = 0; i < 3; i++) {
6489  sc->mastering->display_primaries[i][0] = av_make_q(avio_rb16(pb), 1 << 16);
6490  sc->mastering->display_primaries[i][1] = av_make_q(avio_rb16(pb), 1 << 16);
6491  }
6492  sc->mastering->white_point[0] = av_make_q(avio_rb16(pb), 1 << 16);
6493  sc->mastering->white_point[1] = av_make_q(avio_rb16(pb), 1 << 16);
6494 
6495  sc->mastering->max_luminance = av_make_q(avio_rb32(pb), 1 << 8);
6496  sc->mastering->min_luminance = av_make_q(avio_rb32(pb), 1 << 14);
6497 
6498  sc->mastering->has_primaries = 1;
6499  sc->mastering->has_luminance = 1;
6500 
6501  return 0;
6502 }
6503 
6505 {
6506  MOVStreamContext *sc;
6507  const int mapping[3] = {1, 2, 0};
6508  const int chroma_den = 50000;
6509  const int luma_den = 10000;
6510  int i;
6511 
6512  if (c->fc->nb_streams < 1)
6513  return AVERROR_INVALIDDATA;
6514 
6515  sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
6516 
6517  if (atom.size < 24) {
6518  av_log(c->fc, AV_LOG_ERROR, "Invalid Mastering Display Color Volume box\n");
6519  return AVERROR_INVALIDDATA;
6520  }
6521 
6522  if (sc->mastering) {
6523  av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicate Mastering Display Color Volume\n");
6524  return 0;
6525  }
6526 
6528  if (!sc->mastering)
6529  return AVERROR(ENOMEM);
6530 
6531  for (i = 0; i < 3; i++) {
6532  const int j = mapping[i];
6533  sc->mastering->display_primaries[j][0] = av_make_q(avio_rb16(pb), chroma_den);
6534  sc->mastering->display_primaries[j][1] = av_make_q(avio_rb16(pb), chroma_den);
6535  }
6536  sc->mastering->white_point[0] = av_make_q(avio_rb16(pb), chroma_den);
6537  sc->mastering->white_point[1] = av_make_q(avio_rb16(pb), chroma_den);
6538 
6539  sc->mastering->max_luminance = av_make_q(avio_rb32(pb), luma_den);
6540  sc->mastering->min_luminance = av_make_q(avio_rb32(pb), luma_den);
6541 
6542  sc->mastering->has_luminance = 1;
6543  sc->mastering->has_primaries = 1;
6544 
6545  return 0;
6546 }
6547 
6549 {
6550  MOVStreamContext *sc;
6551  int version;
6552 
6553  if (c->fc->nb_streams < 1)
6554  return AVERROR_INVALIDDATA;
6555 
6556  sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
6557 
6558  if (atom.size < 5) {
6559  av_log(c->fc, AV_LOG_ERROR, "Empty Content Light Level box\n");
6560  return AVERROR_INVALIDDATA;
6561  }
6562 
6563  version = avio_r8(pb);
6564  if (version) {
6565  av_log(c->fc, AV_LOG_WARNING, "Unsupported Content Light Level box version %d\n", version);
6566  return 0;
6567  }
6568  avio_skip(pb, 3); /* flags */
6569 
6570  if (sc->coll){
6571  av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicate COLL\n");
6572  return 0;
6573  }
6574 
6576  if (!sc->coll)
6577  return AVERROR(ENOMEM);
6578 
6579  sc->coll->MaxCLL = avio_rb16(pb);
6580  sc->coll->MaxFALL = avio_rb16(pb);
6581 
6582  return 0;
6583 }
6584 
6586 {
6587  MOVStreamContext *sc;
6588 
6589  if (c->fc->nb_streams < 1)
6590  return AVERROR_INVALIDDATA;
6591 
6592  sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
6593 
6594  if (atom.size < 4) {
6595  av_log(c->fc, AV_LOG_ERROR, "Empty Content Light Level Info box\n");
6596  return AVERROR_INVALIDDATA;
6597  }
6598 
6599  if (sc->coll){
6600  av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicate CLLI/COLL\n");
6601  return 0;
6602  }
6603 
6605  if (!sc->coll)
6606  return AVERROR(ENOMEM);
6607 
6608  sc->coll->MaxCLL = avio_rb16(pb);
6609  sc->coll->MaxFALL = avio_rb16(pb);
6610 
6611  return 0;
6612 }
6613 
6615 {
6616  MOVStreamContext *sc;
6617  const int illuminance_den = 10000;
6618  const int ambient_den = 50000;
6619  if (c->fc->nb_streams < 1)
6620  return AVERROR_INVALIDDATA;
6621  sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
6622  if (atom.size < 6) {
6623  av_log(c->fc, AV_LOG_ERROR, "Empty Ambient Viewing Environment Info box\n");
6624  return AVERROR_INVALIDDATA;
6625  }
6626  if (sc->ambient){
6627  av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicate AMVE\n");
6628  return 0;
6629  }
6631  if (!sc->ambient)
6632  return AVERROR(ENOMEM);
6633  sc->ambient->ambient_illuminance = av_make_q(avio_rb32(pb), illuminance_den);
6634  sc->ambient->ambient_light_x = av_make_q(avio_rb16(pb), ambient_den);
6635  sc->ambient->ambient_light_y = av_make_q(avio_rb16(pb), ambient_den);
6636  return 0;
6637 }
6638 
6640 {
6641  AVStream *st;
6642  MOVStreamContext *sc;
6643  enum AVStereo3DType type;
6644  int mode;
6645 
6646  if (c->fc->nb_streams < 1)
6647  return 0;
6648 
6649  st = c->fc->streams[c->fc->nb_streams - 1];
6650  sc = st->priv_data;
6651 
6652  if (atom.size < 5) {
6653  av_log(c->fc, AV_LOG_ERROR, "Empty stereoscopic video box\n");
6654  return AVERROR_INVALIDDATA;
6655  }
6656 
6657  if (sc->stereo3d)
6658  return AVERROR_INVALIDDATA;
6659 
6660  avio_skip(pb, 4); /* version + flags */
6661 
6662  mode = avio_r8(pb);
6663  switch (mode) {
6664  case 0:
6665  type = AV_STEREO3D_2D;
6666  break;
6667  case 1:
6669  break;
6670  case 2:
6672  break;
6673  default:
6674  av_log(c->fc, AV_LOG_WARNING, "Unknown st3d mode value %d\n", mode);
6675  return 0;
6676  }
6677 
6679  if (!sc->stereo3d)
6680  return AVERROR(ENOMEM);
6681 
6682  sc->stereo3d->type = type;
6683  return 0;
6684 }
6685 
6687 {
6688  AVStream *st;
6689  MOVStreamContext *sc;
6690  int size = 0;
6691  int64_t remaining;
6692  uint32_t tag = 0;
6694 
6695  if (c->fc->nb_streams < 1)
6696  return 0;
6697 
6698  st = c->fc->streams[c->fc->nb_streams - 1];
6699  sc = st->priv_data;
6700 
6701  remaining = atom.size;
6702  while (remaining > 0) {
6703  size = avio_rb32(pb);
6704  if (size < 8 || size > remaining ) {
6705  av_log(c->fc, AV_LOG_ERROR, "Invalid child size in pack box\n");
6706  return AVERROR_INVALIDDATA;
6707  }
6708 
6709  tag = avio_rl32(pb);
6710  switch (tag) {
6711  case MKTAG('p','k','i','n'): {
6712  if (size != 16) {
6713  av_log(c->fc, AV_LOG_ERROR, "Invalid size of pkin box: %d\n", size);
6714  return AVERROR_INVALIDDATA;
6715  }
6716  avio_skip(pb, 1); // version
6717  avio_skip(pb, 3); // flags
6718 
6719  tag = avio_rl32(pb);
6720  switch (tag) {
6721  case MKTAG('s','i','d','e'):
6723  break;
6724  case MKTAG('o','v','e','r'):
6726  break;
6727  case 0:
6728  // This means value will be set in another layer
6729  break;
6730  default:
6731  av_log(c->fc, AV_LOG_WARNING, "Unknown tag in pkin: %s\n",
6732  av_fourcc2str(tag));
6733  avio_skip(pb, size - 8);
6734  break;
6735  }
6736 
6737  break;
6738  }
6739  default:
6740  av_log(c->fc, AV_LOG_WARNING, "Unknown tag in pack: %s\n",
6741  av_fourcc2str(tag));
6742  avio_skip(pb, size - 8);
6743  break;
6744  }
6745  remaining -= size;
6746  }
6747 
6748  if (remaining != 0) {
6749  av_log(c->fc, AV_LOG_ERROR, "Broken pack box\n");
6750  return AVERROR_INVALIDDATA;
6751  }
6752 
6753  if (type == AV_STEREO3D_2D)
6754  return 0;
6755 
6756  if (!sc->stereo3d) {
6758  if (!sc->stereo3d)
6759  return AVERROR(ENOMEM);
6760  }
6761 
6762  sc->stereo3d->type = type;
6763 
6764  return 0;
6765 }
6766 
6768 {
6769  AVStream *st;
6770  MOVStreamContext *sc;
6771  int size, version, layout;
6772  int32_t yaw, pitch, roll;
6773  uint32_t l = 0, t = 0, r = 0, b = 0;
6774  uint32_t tag, padding = 0;
6775  enum AVSphericalProjection projection;
6776 
6777  if (c->fc->nb_streams < 1)
6778  return 0;
6779 
6780  st = c->fc->streams[c->fc->nb_streams - 1];
6781  sc = st->priv_data;
6782 
6783  if (atom.size < 8) {
6784  av_log(c->fc, AV_LOG_ERROR, "Empty spherical video box\n");
6785  return AVERROR_INVALIDDATA;
6786  }
6787 
6788  size = avio_rb32(pb);
6789  if (size <= 12 || size > atom.size)
6790  return AVERROR_INVALIDDATA;
6791 
6792  tag = avio_rl32(pb);
6793  if (tag != MKTAG('s','v','h','d')) {
6794  av_log(c->fc, AV_LOG_ERROR, "Missing spherical video header\n");
6795  return 0;
6796  }
6797  version = avio_r8(pb);
6798  if (version != 0) {
6799  av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
6800  version);
6801  return 0;
6802  }
6803  avio_skip(pb, 3); /* flags */
6804  avio_skip(pb, size - 12); /* metadata_source */
6805 
6806  size = avio_rb32(pb);
6807  if (size > atom.size)
6808  return AVERROR_INVALIDDATA;
6809 
6810  tag = avio_rl32(pb);
6811  if (tag != MKTAG('p','r','o','j')) {
6812  av_log(c->fc, AV_LOG_ERROR, "Missing projection box\n");
6813  return 0;
6814  }
6815 
6816  size = avio_rb32(pb);
6817  if (size > atom.size)
6818  return AVERROR_INVALIDDATA;
6819 
6820  tag = avio_rl32(pb);
6821  if (tag != MKTAG('p','r','h','d')) {
6822  av_log(c->fc, AV_LOG_ERROR, "Missing projection header box\n");
6823  return 0;
6824  }
6825  version = avio_r8(pb);
6826  if (version != 0) {
6827  av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
6828  version);
6829  return 0;
6830  }
6831  avio_skip(pb, 3); /* flags */
6832 
6833  /* 16.16 fixed point */
6834  yaw = avio_rb32(pb);
6835  pitch = avio_rb32(pb);
6836  roll = avio_rb32(pb);
6837 
6838  size = avio_rb32(pb);
6839  if (size > atom.size)
6840  return AVERROR_INVALIDDATA;
6841 
6842  tag = avio_rl32(pb);
6843  version = avio_r8(pb);
6844  if (version != 0) {
6845  av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
6846  version);
6847  return 0;
6848  }
6849  avio_skip(pb, 3); /* flags */
6850  switch (tag) {
6851  case MKTAG('c','b','m','p'):
6852  layout = avio_rb32(pb);
6853  if (layout) {
6854  av_log(c->fc, AV_LOG_WARNING,
6855  "Unsupported cubemap layout %d\n", layout);
6856  return 0;
6857  }
6858  projection = AV_SPHERICAL_CUBEMAP;
6859  padding = avio_rb32(pb);
6860  break;
6861  case MKTAG('e','q','u','i'):
6862  t = avio_rb32(pb);
6863  b = avio_rb32(pb);
6864  l = avio_rb32(pb);
6865  r = avio_rb32(pb);
6866 
6867  if (b >= UINT_MAX - t || r >= UINT_MAX - l) {
6868  av_log(c->fc, AV_LOG_ERROR,
6869  "Invalid bounding rectangle coordinates "
6870  "%"PRIu32",%"PRIu32",%"PRIu32",%"PRIu32"\n", l, t, r, b);
6871  return AVERROR_INVALIDDATA;
6872  }
6873 
6874  if (l || t || r || b)
6875  projection = AV_SPHERICAL_EQUIRECTANGULAR_TILE;
6876  else
6877  projection = AV_SPHERICAL_EQUIRECTANGULAR;
6878  break;
6879  default:
6880  av_log(c->fc, AV_LOG_ERROR, "Unknown projection type: %s\n", av_fourcc2str(tag));
6881  return 0;
6882  }
6883 
6885  if (!sc->spherical)
6886  return AVERROR(ENOMEM);
6887 
6888  sc->spherical->projection = projection;
6889 
6890  sc->spherical->yaw = yaw;
6891  sc->spherical->pitch = pitch;
6892  sc->spherical->roll = roll;
6893 
6894  sc->spherical->padding = padding;
6895 
6896  sc->spherical->bound_left = l;
6897  sc->spherical->bound_top = t;
6898  sc->spherical->bound_right = r;
6899  sc->spherical->bound_bottom = b;
6900 
6901  return 0;
6902 }
6903 
6905 {
6906  AVStream *st;
6907  MOVStreamContext *sc;
6908  int size;
6909  uint32_t tag;
6910  enum AVSphericalProjection projection;
6911 
6912  if (c->fc->nb_streams < 1)
6913  return 0;
6914 
6915  st = c->fc->streams[c->fc->nb_streams - 1];
6916  sc = st->priv_data;
6917 
6918  if (atom.size < 16) {
6919  av_log(c->fc, AV_LOG_ERROR, "Invalid size for proj box: %"PRIu64"\n", atom.size);
6920  return AVERROR_INVALIDDATA;
6921  }
6922 
6923  size = avio_rb32(pb);
6924  if (size < 16) {
6925  av_log(c->fc, AV_LOG_ERROR, "Invalid size for prji box: %d\n", size);
6926  return AVERROR_INVALIDDATA;
6927  } else if (size > 16) {
6928  av_log(c->fc, AV_LOG_WARNING, "Box has more bytes (%d) than prji box required (16) \n", size);
6929  }
6930 
6931  tag = avio_rl32(pb);
6932  if (tag != MKTAG('p','r','j','i')) {
6933  av_log(c->fc, AV_LOG_ERROR, "Invalid child box of proj box: %s\n",
6934  av_fourcc2str(tag));
6935  return AVERROR_INVALIDDATA;
6936  }
6937 
6938  // version and flags, only support (0, 0)
6939  unsigned n = avio_rl32(pb);
6940  if (n != 0) {
6941  av_log(c->fc, AV_LOG_ERROR, "prji version %u, flag %u are not supported\n",
6942  n & 0xFF, n >> 8);
6943  return AVERROR_PATCHWELCOME;
6944  }
6945 
6946  tag = avio_rl32(pb);
6947  switch (tag) {
6948  case MKTAG('r','e','c','t'):
6949  projection = AV_SPHERICAL_RECTILINEAR;
6950  break;
6951  case MKTAG('e','q','u','i'):
6952  projection = AV_SPHERICAL_EQUIRECTANGULAR;
6953  break;
6954  case MKTAG('h','e','q','u'):
6955  projection = AV_SPHERICAL_HALF_EQUIRECTANGULAR;
6956  break;
6957  case MKTAG('f','i','s','h'):
6958  projection = AV_SPHERICAL_FISHEYE;
6959  break;
6960  case MKTAG('p','r','i','m'):
6961  projection = AV_SPHERICAL_PARAMETRIC_IMMERSIVE;
6962  break;
6963  default:
6964  av_log(c->fc, AV_LOG_ERROR, "Invalid projection type in prji box: %s\n", av_fourcc2str(tag));
6965  return AVERROR_INVALIDDATA;
6966  }
6967 
6969  if (!sc->spherical)
6970  return AVERROR(ENOMEM);
6971 
6972  sc->spherical->projection = projection;
6973 
6974  return 0;
6975 }
6976 
6978 {
6979  AVStream *st;
6980  MOVStreamContext *sc;
6981  int size, flags = 0;
6982  int64_t remaining;
6983  uint32_t tag, baseline = 0;
6986  enum AVStereo3DPrimaryEye primary_eye = AV_PRIMARY_EYE_NONE;
6987  AVRational horizontal_disparity_adjustment = { 0, 1 };
6988 
6989  if (c->fc->nb_streams < 1)
6990  return 0;
6991 
6992  st = c->fc->streams[c->fc->nb_streams - 1];
6993  sc = st->priv_data;
6994 
6995  remaining = atom.size;
6996  while (remaining > 0) {
6997  size = avio_rb32(pb);
6998  if (size < 8 || size > remaining ) {
6999  av_log(c->fc, AV_LOG_ERROR, "Invalid child size in eyes box\n");
7000  return AVERROR_INVALIDDATA;
7001  }
7002 
7003  tag = avio_rl32(pb);
7004  switch (tag) {
7005  case MKTAG('s','t','r','i'): {
7006  int has_right, has_left;
7007  uint8_t tmp;
7008  if (size != 13) {
7009  av_log(c->fc, AV_LOG_ERROR, "Invalid size of stri box: %d\n", size);
7010  return AVERROR_INVALIDDATA;
7011  }
7012  avio_skip(pb, 1); // version
7013  avio_skip(pb, 3); // flags
7014 
7015  tmp = avio_r8(pb);
7016 
7017  // eye_views_reversed
7018  if (tmp & 8) {
7020  }
7021  // has_additional_views
7022  if (tmp & 4) {
7023  // skip...
7024  }
7025 
7026  has_right = tmp & 2; // has_right_eye_view
7027  has_left = tmp & 1; // has_left_eye_view
7028 
7029  if (has_left && has_right)
7030  view = AV_STEREO3D_VIEW_PACKED;
7031  else if (has_left)
7032  view = AV_STEREO3D_VIEW_LEFT;
7033  else if (has_right)
7034  view = AV_STEREO3D_VIEW_RIGHT;
7035  if (has_left || has_right)
7037 
7038  break;
7039  }
7040  case MKTAG('h','e','r','o'): {
7041  int tmp;
7042  if (size != 13) {
7043  av_log(c->fc, AV_LOG_ERROR, "Invalid size of hero box: %d\n", size);
7044  return AVERROR_INVALIDDATA;
7045  }
7046  avio_skip(pb, 1); // version
7047  avio_skip(pb, 3); // flags
7048 
7049  tmp = avio_r8(pb);
7050  if (tmp == 0)
7051  primary_eye = AV_PRIMARY_EYE_NONE;
7052  else if (tmp == 1)
7053  primary_eye = AV_PRIMARY_EYE_LEFT;
7054  else if (tmp == 2)
7055  primary_eye = AV_PRIMARY_EYE_RIGHT;
7056  else
7057  av_log(c->fc, AV_LOG_WARNING, "Unknown hero eye type: %d\n", tmp);
7058 
7059  break;
7060  }
7061  case MKTAG('c','a','m','s'): {
7062  uint32_t subtag;
7063  int subsize;
7064  if (size != 24) {
7065  av_log(c->fc, AV_LOG_ERROR, "Invalid size of cams box: %d\n", size);
7066  return AVERROR_INVALIDDATA;
7067  }
7068 
7069  subsize = avio_rb32(pb);
7070  if (subsize != 16) {
7071  av_log(c->fc, AV_LOG_ERROR, "Invalid size of blin box: %d\n", size);
7072  return AVERROR_INVALIDDATA;
7073  }
7074 
7075  subtag = avio_rl32(pb);
7076  if (subtag != MKTAG('b','l','i','n')) {
7077  av_log(c->fc, AV_LOG_ERROR, "Expected blin box, got %s\n",
7078  av_fourcc2str(subtag));
7079  return AVERROR_INVALIDDATA;
7080  }
7081 
7082  avio_skip(pb, 1); // version
7083  avio_skip(pb, 3); // flags
7084 
7085  baseline = avio_rb32(pb);
7086 
7087  break;
7088  }
7089  case MKTAG('c','m','f','y'): {
7090  uint32_t subtag;
7091  int subsize;
7092  int32_t adjustment;
7093  if (size != 24) {
7094  av_log(c->fc, AV_LOG_ERROR, "Invalid size of cmfy box: %d\n", size);
7095  return AVERROR_INVALIDDATA;
7096  }
7097 
7098  subsize = avio_rb32(pb);
7099  if (subsize != 16) {
7100  av_log(c->fc, AV_LOG_ERROR, "Invalid size of dadj box: %d\n", size);
7101  return AVERROR_INVALIDDATA;
7102  }
7103 
7104  subtag = avio_rl32(pb);
7105  if (subtag != MKTAG('d','a','d','j')) {
7106  av_log(c->fc, AV_LOG_ERROR, "Expected dadj box, got %s\n",
7107  av_fourcc2str(subtag));
7108  return AVERROR_INVALIDDATA;
7109  }
7110 
7111  avio_skip(pb, 1); // version
7112  avio_skip(pb, 3); // flags
7113 
7114  adjustment = (int32_t) avio_rb32(pb);
7115 
7116  horizontal_disparity_adjustment.num = (int) adjustment;
7117  horizontal_disparity_adjustment.den = 10000;
7118 
7119  break;
7120  }
7121  default:
7122  av_log(c->fc, AV_LOG_WARNING, "Unknown tag in eyes: %s\n",
7123  av_fourcc2str(tag));
7124  avio_skip(pb, size - 8);
7125  break;
7126  }
7127  remaining -= size;
7128  }
7129 
7130  if (remaining != 0) {
7131  av_log(c->fc, AV_LOG_ERROR, "Broken eyes box\n");
7132  return AVERROR_INVALIDDATA;
7133  }
7134 
7135  if (type == AV_STEREO3D_2D)
7136  return 0;
7137 
7138  if (!sc->stereo3d) {
7140  if (!sc->stereo3d)
7141  return AVERROR(ENOMEM);
7142  }
7143 
7144  sc->stereo3d->flags = flags;
7145  sc->stereo3d->type = type;
7146  sc->stereo3d->view = view;
7147  sc->stereo3d->primary_eye = primary_eye;
7148  sc->stereo3d->baseline = baseline;
7149  sc->stereo3d->horizontal_disparity_adjustment = horizontal_disparity_adjustment;
7150 
7151  return 0;
7152 }
7153 
7155 {
7156  int size;
7157  int64_t remaining;
7158  uint32_t tag;
7159 
7160  if (c->fc->nb_streams < 1)
7161  return 0;
7162 
7163  if (atom.size < 8) {
7164  av_log(c->fc, AV_LOG_ERROR, "Empty video extension usage box\n");
7165  return AVERROR_INVALIDDATA;
7166  }
7167 
7168  remaining = atom.size;
7169  while (remaining > 0) {
7170  size = avio_rb32(pb);
7171  if (size < 8 || size > remaining ) {
7172  av_log(c->fc, AV_LOG_ERROR, "Invalid child size in vexu box\n");
7173  return AVERROR_INVALIDDATA;
7174  }
7175 
7176  tag = avio_rl32(pb);
7177  switch (tag) {
7178  case MKTAG('p','r','o','j'): {
7179  MOVAtom proj = { tag, size - 8 };
7180  int ret = mov_read_vexu_proj(c, pb, proj);
7181  if (ret < 0)
7182  return ret;
7183  break;
7184  }
7185  case MKTAG('e','y','e','s'): {
7186  MOVAtom eyes = { tag, size - 8 };
7187  int ret = mov_read_eyes(c, pb, eyes);
7188  if (ret < 0)
7189  return ret;
7190  break;
7191  }
7192  case MKTAG('p','a','c','k'): {
7193  MOVAtom pack = { tag, size - 8 };
7194  int ret = mov_read_pack(c, pb, pack);
7195  if (ret < 0)
7196  return ret;
7197  break;
7198  }
7199  default:
7200  av_log(c->fc, AV_LOG_WARNING, "Unknown tag in vexu: %s\n",
7201  av_fourcc2str(tag));
7202  avio_skip(pb, size - 8);
7203  break;
7204  }
7205  remaining -= size;
7206  }
7207 
7208  if (remaining != 0) {
7209  av_log(c->fc, AV_LOG_ERROR, "Broken vexu box\n");
7210  return AVERROR_INVALIDDATA;
7211  }
7212 
7213  return 0;
7214 }
7215 
7217 {
7218  AVStream *st;
7219  MOVStreamContext *sc;
7220 
7221  if (c->fc->nb_streams < 1)
7222  return 0;
7223 
7224  st = c->fc->streams[c->fc->nb_streams - 1];
7225  sc = st->priv_data;
7226 
7227  if (atom.size != 4) {
7228  av_log(c->fc, AV_LOG_ERROR, "Invalid size of hfov box: %"PRIu64"\n", atom.size);
7229  return AVERROR_INVALIDDATA;
7230  }
7231 
7232 
7233  if (!sc->stereo3d) {
7235  if (!sc->stereo3d)
7236  return AVERROR(ENOMEM);
7237  }
7238 
7240  sc->stereo3d->horizontal_field_of_view.den = 1000; // thousands of a degree
7241 
7242  return 0;
7243 }
7244 
7246 {
7247  int ret = 0;
7248  uint8_t *buffer = av_malloc(len + 1);
7249  const char *val;
7250 
7251  if (!buffer)
7252  return AVERROR(ENOMEM);
7253  buffer[len] = '\0';
7254 
7255  ret = ffio_read_size(pb, buffer, len);
7256  if (ret < 0)
7257  goto out;
7258 
7259  /* Check for mandatory keys and values, try to support XML as best-effort */
7260  if (!sc->spherical &&
7261  av_stristr(buffer, "<GSpherical:StitchingSoftware>") &&
7262  (val = av_stristr(buffer, "<GSpherical:Spherical>")) &&
7263  av_stristr(val, "true") &&
7264  (val = av_stristr(buffer, "<GSpherical:Stitched>")) &&
7265  av_stristr(val, "true") &&
7266  (val = av_stristr(buffer, "<GSpherical:ProjectionType>")) &&
7267  av_stristr(val, "equirectangular")) {
7269  if (!sc->spherical)
7270  goto out;
7271 
7273 
7274  if (av_stristr(buffer, "<GSpherical:StereoMode>") && !sc->stereo3d) {
7275  enum AVStereo3DType mode;
7276 
7277  if (av_stristr(buffer, "left-right"))
7279  else if (av_stristr(buffer, "top-bottom"))
7281  else
7282  mode = AV_STEREO3D_2D;
7283 
7285  if (!sc->stereo3d)
7286  goto out;
7287 
7288  sc->stereo3d->type = mode;
7289  }
7290 
7291  /* orientation */
7292  val = av_stristr(buffer, "<GSpherical:InitialViewHeadingDegrees>");
7293  if (val)
7294  sc->spherical->yaw = strtol(val, NULL, 10) * (1 << 16);
7295  val = av_stristr(buffer, "<GSpherical:InitialViewPitchDegrees>");
7296  if (val)
7297  sc->spherical->pitch = strtol(val, NULL, 10) * (1 << 16);
7298  val = av_stristr(buffer, "<GSpherical:InitialViewRollDegrees>");
7299  if (val)
7300  sc->spherical->roll = strtol(val, NULL, 10) * (1 << 16);
7301  }
7302 
7303 out:
7304  av_free(buffer);
7305  return ret;
7306 }
7307 
7309 {
7310  AVStream *st;
7311  MOVStreamContext *sc;
7312  int64_t ret;
7313  AVUUID uuid;
7314  static const AVUUID uuid_isml_manifest = {
7315  0xa5, 0xd4, 0x0b, 0x30, 0xe8, 0x14, 0x11, 0xdd,
7316  0xba, 0x2f, 0x08, 0x00, 0x20, 0x0c, 0x9a, 0x66
7317  };
7318  static const AVUUID uuid_xmp = {
7319  0xbe, 0x7a, 0xcf, 0xcb, 0x97, 0xa9, 0x42, 0xe8,
7320  0x9c, 0x71, 0x99, 0x94, 0x91, 0xe3, 0xaf, 0xac
7321  };
7322  static const AVUUID uuid_spherical = {
7323  0xff, 0xcc, 0x82, 0x63, 0xf8, 0x55, 0x4a, 0x93,
7324  0x88, 0x14, 0x58, 0x7a, 0x02, 0x52, 0x1f, 0xdd,
7325  };
7326 
7327  if (atom.size < AV_UUID_LEN || atom.size >= FFMIN(INT_MAX, SIZE_MAX))
7328  return AVERROR_INVALIDDATA;
7329 
7330  if (c->fc->nb_streams < 1)
7331  return 0;
7332  st = c->fc->streams[c->fc->nb_streams - 1];
7333  sc = st->priv_data;
7334 
7335  ret = ffio_read_size(pb, uuid, AV_UUID_LEN);
7336  if (ret < 0)
7337  return ret;
7338  if (av_uuid_equal(uuid, uuid_isml_manifest)) {
7339  uint8_t *buffer, *ptr;
7340  char *endptr;
7341  size_t len = atom.size - AV_UUID_LEN;
7342 
7343  if (len < 4) {
7344  return AVERROR_INVALIDDATA;
7345  }
7346  ret = avio_skip(pb, 4); // zeroes
7347  len -= 4;
7348 
7349  buffer = av_mallocz(len + 1);
7350  if (!buffer) {
7351  return AVERROR(ENOMEM);
7352  }
7353  ret = ffio_read_size(pb, buffer, len);
7354  if (ret < 0) {
7355  av_free(buffer);
7356  return ret;
7357  }
7358 
7359  ptr = buffer;
7360  while ((ptr = av_stristr(ptr, "systemBitrate=\""))) {
7361  ptr += sizeof("systemBitrate=\"") - 1;
7362  c->bitrates_count++;
7363  c->bitrates = av_realloc_f(c->bitrates, c->bitrates_count, sizeof(*c->bitrates));
7364  if (!c->bitrates) {
7365  c->bitrates_count = 0;
7366  av_free(buffer);
7367  return AVERROR(ENOMEM);
7368  }
7369  errno = 0;
7370  ret = strtol(ptr, &endptr, 10);
7371  if (ret < 0 || errno || *endptr != '"') {
7372  c->bitrates[c->bitrates_count - 1] = 0;
7373  } else {
7374  c->bitrates[c->bitrates_count - 1] = ret;
7375  }
7376  }
7377 
7378  av_free(buffer);
7379  } else if (av_uuid_equal(uuid, uuid_xmp)) {
7380  uint8_t *buffer;
7381  size_t len = atom.size - AV_UUID_LEN;
7382  if (c->export_xmp) {
7383  buffer = av_mallocz(len + 1);
7384  if (!buffer) {
7385  return AVERROR(ENOMEM);
7386  }
7387  ret = ffio_read_size(pb, buffer, len);
7388  if (ret < 0) {
7389  av_free(buffer);
7390  return ret;
7391  }
7392  buffer[len] = '\0';
7393  av_dict_set(&c->fc->metadata, "xmp",
7395  } else {
7396  // skip all uuid atom, which makes it fast for long uuid-xmp file
7397  ret = avio_skip(pb, len);
7398  if (ret < 0)
7399  return ret;
7400  }
7401  } else if (av_uuid_equal(uuid, uuid_spherical)) {
7402  size_t len = atom.size - AV_UUID_LEN;
7403  ret = mov_parse_uuid_spherical(sc, pb, len);
7404  if (ret < 0)
7405  return ret;
7406  if (!sc->spherical)
7407  av_log(c->fc, AV_LOG_WARNING, "Invalid spherical metadata found\n");
7408  }
7409 
7410  return 0;
7411 }
7412 
7414 {
7415  int ret;
7416  uint8_t content[16];
7417 
7418  if (atom.size < 8)
7419  return 0;
7420 
7421  ret = ffio_read_size(pb, content, FFMIN(sizeof(content), atom.size));
7422  if (ret < 0)
7423  return ret;
7424 
7425  if ( !c->found_moov
7426  && !c->found_mdat
7427  && !memcmp(content, "Anevia\x1A\x1A", 8)
7428  && c->use_mfra_for == FF_MOV_FLAG_MFRA_AUTO) {
7429  c->use_mfra_for = FF_MOV_FLAG_MFRA_PTS;
7430  }
7431 
7432  return 0;
7433 }
7434 
7436 {
7437  uint32_t format = avio_rl32(pb);
7438  MOVStreamContext *sc;
7439  enum AVCodecID id;
7440  AVStream *st;
7441 
7442  if (c->fc->nb_streams < 1)
7443  return 0;
7444  st = c->fc->streams[c->fc->nb_streams - 1];
7445  sc = st->priv_data;
7446 
7447  switch (sc->format)
7448  {
7449  case MKTAG('e','n','c','v'): // encrypted video
7450  case MKTAG('e','n','c','a'): // encrypted audio
7451  id = mov_codec_id(st, format);
7452  if (st->codecpar->codec_id != AV_CODEC_ID_NONE &&
7453  st->codecpar->codec_id != id) {
7454  av_log(c->fc, AV_LOG_WARNING,
7455  "ignoring 'frma' atom of '%.4s', stream has codec id %d\n",
7456  (char*)&format, st->codecpar->codec_id);
7457  break;
7458  }
7459 
7460  st->codecpar->codec_id = id;
7461  sc->format = format;
7462  break;
7463 
7464  default:
7465  if (format != sc->format) {
7466  av_log(c->fc, AV_LOG_WARNING,
7467  "ignoring 'frma' atom of '%.4s', stream format is '%.4s'\n",
7468  (char*)&format, (char*)&sc->format);
7469  }
7470  break;
7471  }
7472 
7473  return 0;
7474 }
7475 
7476 /**
7477  * Gets the current encryption info and associated current stream context. If
7478  * we are parsing a track fragment, this will return the specific encryption
7479  * info for this fragment; otherwise this will return the global encryption
7480  * info for the current stream.
7481  */
7483 {
7484  MOVFragmentStreamInfo *frag_stream_info;
7485  AVStream *st;
7486  int i;
7487 
7488  frag_stream_info = get_current_frag_stream_info(&c->frag_index);
7489  if (frag_stream_info) {
7490  for (i = 0; i < c->fc->nb_streams; i++) {
7491  *sc = c->fc->streams[i]->priv_data;
7492  if ((*sc)->id == frag_stream_info->id) {
7493  st = c->fc->streams[i];
7494  break;
7495  }
7496  }
7497  if (i == c->fc->nb_streams)
7498  return 0;
7499  *sc = st->priv_data;
7500 
7501  if (!frag_stream_info->encryption_index) {
7502  // If this stream isn't encrypted, don't create the index.
7503  if (!(*sc)->cenc.default_encrypted_sample)
7504  return 0;
7505  frag_stream_info->encryption_index = av_mallocz(sizeof(*frag_stream_info->encryption_index));
7506  if (!frag_stream_info->encryption_index)
7507  return AVERROR(ENOMEM);
7508  }
7509  *encryption_index = frag_stream_info->encryption_index;
7510  return 1;
7511  } else {
7512  // No current track fragment, using stream level encryption info.
7513 
7514  if (c->fc->nb_streams < 1)
7515  return 0;
7516  st = c->fc->streams[c->fc->nb_streams - 1];
7517  *sc = st->priv_data;
7518 
7519  if (!(*sc)->cenc.encryption_index) {
7520  // If this stream isn't encrypted, don't create the index.
7521  if (!(*sc)->cenc.default_encrypted_sample)
7522  return 0;
7523  (*sc)->cenc.encryption_index = av_mallocz(sizeof(*frag_stream_info->encryption_index));
7524  if (!(*sc)->cenc.encryption_index)
7525  return AVERROR(ENOMEM);
7526  }
7527 
7528  *encryption_index = (*sc)->cenc.encryption_index;
7529  return 1;
7530  }
7531 }
7532 
7534 {
7535  int i, ret;
7536  unsigned int subsample_count;
7537  AVSubsampleEncryptionInfo *subsamples;
7538 
7539  if (!sc->cenc.default_encrypted_sample) {
7540  av_log(c->fc, AV_LOG_ERROR, "Missing schm or tenc\n");
7541  return AVERROR_INVALIDDATA;
7542  }
7543 
7544  if (sc->cenc.per_sample_iv_size || use_subsamples) {
7546  if (!*sample)
7547  return AVERROR(ENOMEM);
7548  } else
7549  *sample = NULL;
7550 
7551  if (sc->cenc.per_sample_iv_size != 0) {
7552  if ((ret = ffio_read_size(pb, (*sample)->iv, sc->cenc.per_sample_iv_size)) < 0) {
7553  av_log(c->fc, AV_LOG_ERROR, "failed to read the initialization vector\n");
7555  *sample = NULL;
7556  return ret;
7557  }
7558  }
7559 
7560  if (use_subsamples) {
7561  subsample_count = avio_rb16(pb);
7562  av_free((*sample)->subsamples);
7563  (*sample)->subsamples = av_calloc(subsample_count, sizeof(*subsamples));
7564  if (!(*sample)->subsamples) {
7566  *sample = NULL;
7567  return AVERROR(ENOMEM);
7568  }
7569 
7570  for (i = 0; i < subsample_count && !pb->eof_reached; i++) {
7571  (*sample)->subsamples[i].bytes_of_clear_data = avio_rb16(pb);
7572  (*sample)->subsamples[i].bytes_of_protected_data = avio_rb32(pb);
7573  }
7574 
7575  if (pb->eof_reached) {
7576  av_log(c->fc, AV_LOG_ERROR, "hit EOF while reading sub-sample encryption info\n");
7578  *sample = NULL;
7579  return AVERROR_INVALIDDATA;
7580  }
7581  (*sample)->subsample_count = subsample_count;
7582  }
7583 
7584  return 0;
7585 }
7586 
7588 {
7589  AVEncryptionInfo **encrypted_samples;
7590  MOVEncryptionIndex *encryption_index;
7591  MOVStreamContext *sc;
7592  int use_subsamples, ret;
7593  unsigned int sample_count, i, alloc_size = 0;
7594 
7595  ret = get_current_encryption_info(c, &encryption_index, &sc);
7596  if (ret != 1)
7597  return ret;
7598 
7599  if (encryption_index->nb_encrypted_samples) {
7600  // This can happen if we have both saio/saiz and senc atoms.
7601  av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in senc\n");
7602  return 0;
7603  }
7604 
7605  avio_r8(pb); /* version */
7606  use_subsamples = avio_rb24(pb) & 0x02; /* flags */
7607 
7608  sample_count = avio_rb32(pb);
7609  if (sample_count >= INT_MAX / sizeof(*encrypted_samples))
7610  return AVERROR(ENOMEM);
7611 
7612  for (i = 0; i < sample_count; i++) {
7613  unsigned int min_samples = FFMIN(FFMAX(i + 1, 1024 * 1024), sample_count);
7614  encrypted_samples = av_fast_realloc(encryption_index->encrypted_samples, &alloc_size,
7615  min_samples * sizeof(*encrypted_samples));
7616  if (encrypted_samples) {
7617  encryption_index->encrypted_samples = encrypted_samples;
7618 
7620  c, pb, sc, &encryption_index->encrypted_samples[i], use_subsamples);
7621  } else {
7622  ret = AVERROR(ENOMEM);
7623  }
7624  if (pb->eof_reached) {
7625  av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading senc\n");
7626  if (ret >= 0)
7627  av_encryption_info_free(encryption_index->encrypted_samples[i]);
7629  }
7630 
7631  if (ret < 0) {
7632  for (; i > 0; i--)
7633  av_encryption_info_free(encryption_index->encrypted_samples[i - 1]);
7634  av_freep(&encryption_index->encrypted_samples);
7635  return ret;
7636  }
7637  }
7638  encryption_index->nb_encrypted_samples = sample_count;
7639 
7640  return 0;
7641 }
7642 
7644 {
7645  AVEncryptionInfo **sample, **encrypted_samples;
7646  int64_t prev_pos;
7647  size_t sample_count, sample_info_size, i;
7648  int ret = 0;
7649  unsigned int alloc_size = 0;
7650 
7651  if (encryption_index->nb_encrypted_samples)
7652  return 0;
7653  sample_count = encryption_index->auxiliary_info_sample_count;
7654  if (encryption_index->auxiliary_offsets_count != 1) {
7655  av_log(c->fc, AV_LOG_ERROR, "Multiple auxiliary info chunks are not supported\n");
7656  return AVERROR_PATCHWELCOME;
7657  }
7658  if (sample_count >= INT_MAX / sizeof(*encrypted_samples))
7659  return AVERROR(ENOMEM);
7660 
7661  prev_pos = avio_tell(pb);
7662  if (!(pb->seekable & AVIO_SEEKABLE_NORMAL) ||
7663  avio_seek(pb, encryption_index->auxiliary_offsets[0], SEEK_SET) != encryption_index->auxiliary_offsets[0]) {
7664  av_log(c->fc, AV_LOG_INFO, "Failed to seek for auxiliary info, will only parse senc atoms for encryption info\n");
7665  goto finish;
7666  }
7667 
7668  for (i = 0; i < sample_count && !pb->eof_reached; i++) {
7669  unsigned int min_samples = FFMIN(FFMAX(i + 1, 1024 * 1024), sample_count);
7670  encrypted_samples = av_fast_realloc(encryption_index->encrypted_samples, &alloc_size,
7671  min_samples * sizeof(*encrypted_samples));
7672  if (!encrypted_samples) {
7673  ret = AVERROR(ENOMEM);
7674  goto finish;
7675  }
7676  encryption_index->encrypted_samples = encrypted_samples;
7677 
7678  sample = &encryption_index->encrypted_samples[i];
7679  sample_info_size = encryption_index->auxiliary_info_default_size
7680  ? encryption_index->auxiliary_info_default_size
7681  : encryption_index->auxiliary_info_sizes[i];
7682 
7683  ret = mov_read_sample_encryption_info(c, pb, sc, sample, sample_info_size > sc->cenc.per_sample_iv_size);
7684  if (ret < 0)
7685  goto finish;
7686  }
7687  if (pb->eof_reached) {
7688  av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading auxiliary info\n");
7690  } else {
7691  encryption_index->nb_encrypted_samples = sample_count;
7692  }
7693 
7694 finish:
7695  avio_seek(pb, prev_pos, SEEK_SET);
7696  if (ret < 0) {
7697  for (; i > 0; i--) {
7698  av_encryption_info_free(encryption_index->encrypted_samples[i - 1]);
7699  }
7700  av_freep(&encryption_index->encrypted_samples);
7701  }
7702  return ret;
7703 }
7704 
7706 {
7707  MOVEncryptionIndex *encryption_index;
7708  MOVStreamContext *sc;
7709  int ret;
7710  unsigned int sample_count, aux_info_type, aux_info_param;
7711 
7712  ret = get_current_encryption_info(c, &encryption_index, &sc);
7713  if (ret != 1)
7714  return ret;
7715 
7716  if (encryption_index->nb_encrypted_samples) {
7717  // This can happen if we have both saio/saiz and senc atoms.
7718  av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in saiz\n");
7719  return 0;
7720  }
7721 
7722  if (encryption_index->auxiliary_info_sample_count) {
7723  av_log(c->fc, AV_LOG_ERROR, "Duplicate saiz atom\n");
7724  return AVERROR_INVALIDDATA;
7725  }
7726 
7727  avio_r8(pb); /* version */
7728  if (avio_rb24(pb) & 0x01) { /* flags */
7729  aux_info_type = avio_rb32(pb);
7730  aux_info_param = avio_rb32(pb);
7731  if (sc->cenc.default_encrypted_sample) {
7732  if (aux_info_type != sc->cenc.default_encrypted_sample->scheme) {
7733  av_log(c->fc, AV_LOG_DEBUG, "Ignoring saiz box with non-zero aux_info_type\n");
7734  return 0;
7735  }
7736  if (aux_info_param != 0) {
7737  av_log(c->fc, AV_LOG_DEBUG, "Ignoring saiz box with non-zero aux_info_type_parameter\n");
7738  return 0;
7739  }
7740  } else {
7741  // Didn't see 'schm' or 'tenc', so this isn't encrypted.
7742  if ((aux_info_type == MKBETAG('c','e','n','c') ||
7743  aux_info_type == MKBETAG('c','e','n','s') ||
7744  aux_info_type == MKBETAG('c','b','c','1') ||
7745  aux_info_type == MKBETAG('c','b','c','s')) &&
7746  aux_info_param == 0) {
7747  av_log(c->fc, AV_LOG_ERROR, "Saw encrypted saiz without schm/tenc\n");
7748  return AVERROR_INVALIDDATA;
7749  } else {
7750  return 0;
7751  }
7752  }
7753  } else if (!sc->cenc.default_encrypted_sample) {
7754  // Didn't see 'schm' or 'tenc', so this isn't encrypted.
7755  return 0;
7756  }
7757 
7758  encryption_index->auxiliary_info_default_size = avio_r8(pb);
7759  sample_count = avio_rb32(pb);
7760 
7761  if (encryption_index->auxiliary_info_default_size == 0) {
7762  if (sample_count == 0)
7763  return AVERROR_INVALIDDATA;
7764 
7765  encryption_index->auxiliary_info_sizes = av_malloc(sample_count);
7766  if (!encryption_index->auxiliary_info_sizes)
7767  return AVERROR(ENOMEM);
7768 
7769  ret = avio_read(pb, encryption_index->auxiliary_info_sizes, sample_count);
7770  if (ret != sample_count) {
7771  av_freep(&encryption_index->auxiliary_info_sizes);
7772 
7773  if (ret >= 0)
7775  av_log(c->fc, AV_LOG_ERROR, "Failed to read the auxiliary info, %s\n",
7776  av_err2str(ret));
7777  return ret;
7778  }
7779  }
7780  encryption_index->auxiliary_info_sample_count = sample_count;
7781 
7782  if (encryption_index->auxiliary_offsets_count) {
7783  return mov_parse_auxiliary_info(c, sc, pb, encryption_index);
7784  }
7785 
7786  return 0;
7787 }
7788 
7790 {
7791  uint64_t *auxiliary_offsets;
7792  MOVEncryptionIndex *encryption_index;
7793  MOVStreamContext *sc;
7794  int i, ret;
7795  unsigned int version, entry_count, aux_info_type, aux_info_param;
7796  unsigned int alloc_size = 0;
7797 
7798  ret = get_current_encryption_info(c, &encryption_index, &sc);
7799  if (ret != 1)
7800  return ret;
7801 
7802  if (encryption_index->nb_encrypted_samples) {
7803  // This can happen if we have both saio/saiz and senc atoms.
7804  av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in saio\n");
7805  return 0;
7806  }
7807 
7808  if (encryption_index->auxiliary_offsets_count) {
7809  av_log(c->fc, AV_LOG_ERROR, "Duplicate saio atom\n");
7810  return AVERROR_INVALIDDATA;
7811  }
7812 
7813  version = avio_r8(pb); /* version */
7814  if (avio_rb24(pb) & 0x01) { /* flags */
7815  aux_info_type = avio_rb32(pb);
7816  aux_info_param = avio_rb32(pb);
7817  if (sc->cenc.default_encrypted_sample) {
7818  if (aux_info_type != sc->cenc.default_encrypted_sample->scheme) {
7819  av_log(c->fc, AV_LOG_DEBUG, "Ignoring saio box with non-zero aux_info_type\n");
7820  return 0;
7821  }
7822  if (aux_info_param != 0) {
7823  av_log(c->fc, AV_LOG_DEBUG, "Ignoring saio box with non-zero aux_info_type_parameter\n");
7824  return 0;
7825  }
7826  } else {
7827  // Didn't see 'schm' or 'tenc', so this isn't encrypted.
7828  if ((aux_info_type == MKBETAG('c','e','n','c') ||
7829  aux_info_type == MKBETAG('c','e','n','s') ||
7830  aux_info_type == MKBETAG('c','b','c','1') ||
7831  aux_info_type == MKBETAG('c','b','c','s')) &&
7832  aux_info_param == 0) {
7833  av_log(c->fc, AV_LOG_ERROR, "Saw encrypted saio without schm/tenc\n");
7834  return AVERROR_INVALIDDATA;
7835  } else {
7836  return 0;
7837  }
7838  }
7839  } else if (!sc->cenc.default_encrypted_sample) {
7840  // Didn't see 'schm' or 'tenc', so this isn't encrypted.
7841  return 0;
7842  }
7843 
7844  entry_count = avio_rb32(pb);
7845  if (entry_count >= INT_MAX / sizeof(*auxiliary_offsets))
7846  return AVERROR(ENOMEM);
7847 
7848  for (i = 0; i < entry_count && !pb->eof_reached; i++) {
7849  unsigned int min_offsets = FFMIN(FFMAX(i + 1, 1024), entry_count);
7850  auxiliary_offsets = av_fast_realloc(
7851  encryption_index->auxiliary_offsets, &alloc_size,
7852  min_offsets * sizeof(*auxiliary_offsets));
7853  if (!auxiliary_offsets) {
7854  av_freep(&encryption_index->auxiliary_offsets);
7855  return AVERROR(ENOMEM);
7856  }
7857  encryption_index->auxiliary_offsets = auxiliary_offsets;
7858 
7859  if (version == 0) {
7860  encryption_index->auxiliary_offsets[i] = avio_rb32(pb);
7861  } else {
7862  encryption_index->auxiliary_offsets[i] = avio_rb64(pb);
7863  }
7864  if (c->frag_index.current >= 0) {
7865  encryption_index->auxiliary_offsets[i] += c->fragment.base_data_offset;
7866  }
7867  }
7868 
7869  if (pb->eof_reached) {
7870  av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading saio\n");
7871  av_freep(&encryption_index->auxiliary_offsets);
7872  return AVERROR_INVALIDDATA;
7873  }
7874 
7875  encryption_index->auxiliary_offsets_count = entry_count;
7876 
7877  if (encryption_index->auxiliary_info_sample_count) {
7878  return mov_parse_auxiliary_info(c, sc, pb, encryption_index);
7879  }
7880 
7881  return 0;
7882 }
7883 
7885 {
7886  AVEncryptionInitInfo *info, *old_init_info;
7887  uint8_t **key_ids;
7888  AVStream *st;
7889  const AVPacketSideData *old_side_data;
7890  uint8_t *side_data, *extra_data;
7891  size_t side_data_size;
7892  int ret = 0;
7893  unsigned int version, kid_count, extra_data_size, alloc_size = 0;
7894 
7895  if (c->fc->nb_streams < 1)
7896  return 0;
7897  st = c->fc->streams[c->fc->nb_streams-1];
7898 
7899  version = avio_r8(pb); /* version */
7900  avio_rb24(pb); /* flags */
7901 
7902  info = av_encryption_init_info_alloc(/* system_id_size */ 16, /* num_key_ids */ 0,
7903  /* key_id_size */ 16, /* data_size */ 0);
7904  if (!info)
7905  return AVERROR(ENOMEM);
7906 
7907  if ((ret = ffio_read_size(pb, info->system_id, 16)) < 0) {
7908  av_log(c->fc, AV_LOG_ERROR, "Failed to read the system id\n");
7909  goto finish;
7910  }
7911 
7912  if (version > 0) {
7913  kid_count = avio_rb32(pb);
7914  if (kid_count >= INT_MAX / sizeof(*key_ids)) {
7915  ret = AVERROR(ENOMEM);
7916  goto finish;
7917  }
7918 
7919  for (unsigned int i = 0; i < kid_count && !pb->eof_reached; i++) {
7920  unsigned int min_kid_count = FFMIN(FFMAX(i + 1, 1024), kid_count);
7921  key_ids = av_fast_realloc(info->key_ids, &alloc_size,
7922  min_kid_count * sizeof(*key_ids));
7923  if (!key_ids) {
7924  ret = AVERROR(ENOMEM);
7925  goto finish;
7926  }
7927  info->key_ids = key_ids;
7928 
7929  info->key_ids[i] = av_mallocz(16);
7930  if (!info->key_ids[i]) {
7931  ret = AVERROR(ENOMEM);
7932  goto finish;
7933  }
7934  info->num_key_ids = i + 1;
7935 
7936  if ((ret = ffio_read_size(pb, info->key_ids[i], 16)) < 0) {
7937  av_log(c->fc, AV_LOG_ERROR, "Failed to read the key id\n");
7938  goto finish;
7939  }
7940  }
7941 
7942  if (pb->eof_reached) {
7943  av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading pssh\n");
7945  goto finish;
7946  }
7947  }
7948 
7949  extra_data_size = avio_rb32(pb);
7950  extra_data = av_malloc(extra_data_size);
7951  if (!extra_data) {
7952  ret = AVERROR(ENOMEM);
7953  goto finish;
7954  }
7955  ret = avio_read(pb, extra_data, extra_data_size);
7956  if (ret != extra_data_size) {
7957  av_free(extra_data);
7958 
7959  if (ret >= 0)
7961  goto finish;
7962  }
7963 
7964  av_freep(&info->data); // malloc(0) may still allocate something.
7965  info->data = extra_data;
7966  info->data_size = extra_data_size;
7967 
7968  // If there is existing initialization data, append to the list.
7971  if (old_side_data) {
7972  old_init_info = av_encryption_init_info_get_side_data(old_side_data->data, old_side_data->size);
7973  if (old_init_info) {
7974  // Append to the end of the list.
7975  for (AVEncryptionInitInfo *cur = old_init_info;; cur = cur->next) {
7976  if (!cur->next) {
7977  cur->next = info;
7978  break;
7979  }
7980  }
7981  info = old_init_info;
7982  } else {
7983  // Assume existing side-data will be valid, so the only error we could get is OOM.
7984  ret = AVERROR(ENOMEM);
7985  goto finish;
7986  }
7987  }
7988 
7989  side_data = av_encryption_init_info_add_side_data(info, &side_data_size);
7990  if (!side_data) {
7991  ret = AVERROR(ENOMEM);
7992  goto finish;
7993  }
7997  side_data, side_data_size, 0))
7998  av_free(side_data);
7999 
8000 finish:
8002  return ret;
8003 }
8004 
8006 {
8007  AVStream *st;
8008  MOVStreamContext *sc;
8009 
8010  if (c->fc->nb_streams < 1)
8011  return 0;
8012  st = c->fc->streams[c->fc->nb_streams-1];
8013  sc = st->priv_data;
8014 
8015  if (sc->pseudo_stream_id != 0) {
8016  av_log(c->fc, AV_LOG_ERROR, "schm boxes are only supported in first sample descriptor\n");
8017  return AVERROR_PATCHWELCOME;
8018  }
8019 
8020  if (atom.size < 8)
8021  return AVERROR_INVALIDDATA;
8022 
8023  avio_rb32(pb); /* version and flags */
8024 
8025  if (!sc->cenc.default_encrypted_sample) {
8027  if (!sc->cenc.default_encrypted_sample) {
8028  return AVERROR(ENOMEM);
8029  }
8030  }
8031 
8033  return 0;
8034 }
8035 
8037 {
8038  AVStream *st;
8039  MOVStreamContext *sc;
8040  unsigned int version, pattern, is_protected, iv_size;
8041 
8042  if (c->fc->nb_streams < 1)
8043  return 0;
8044  st = c->fc->streams[c->fc->nb_streams-1];
8045  sc = st->priv_data;
8046 
8047  if (sc->pseudo_stream_id != 0) {
8048  av_log(c->fc, AV_LOG_ERROR, "tenc atom are only supported in first sample descriptor\n");
8049  return AVERROR_PATCHWELCOME;
8050  }
8051 
8052  if (!sc->cenc.default_encrypted_sample) {
8054  if (!sc->cenc.default_encrypted_sample) {
8055  return AVERROR(ENOMEM);
8056  }
8057  }
8058 
8059  if (atom.size < 20)
8060  return AVERROR_INVALIDDATA;
8061 
8062  version = avio_r8(pb); /* version */
8063  avio_rb24(pb); /* flags */
8064 
8065  avio_r8(pb); /* reserved */
8066  pattern = avio_r8(pb);
8067 
8068  if (version > 0) {
8069  sc->cenc.default_encrypted_sample->crypt_byte_block = pattern >> 4;
8070  sc->cenc.default_encrypted_sample->skip_byte_block = pattern & 0xf;
8071  }
8072 
8073  is_protected = avio_r8(pb);
8074  if (is_protected && !sc->cenc.encryption_index) {
8075  // The whole stream should be by-default encrypted.
8077  if (!sc->cenc.encryption_index)
8078  return AVERROR(ENOMEM);
8079  }
8080  sc->cenc.per_sample_iv_size = avio_r8(pb);
8081  if (sc->cenc.per_sample_iv_size != 0 && sc->cenc.per_sample_iv_size != 8 &&
8082  sc->cenc.per_sample_iv_size != 16) {
8083  av_log(c->fc, AV_LOG_ERROR, "invalid per-sample IV size value\n");
8084  return AVERROR_INVALIDDATA;
8085  }
8086  if (avio_read(pb, sc->cenc.default_encrypted_sample->key_id, 16) != 16) {
8087  av_log(c->fc, AV_LOG_ERROR, "failed to read the default key ID\n");
8088  return AVERROR_INVALIDDATA;
8089  }
8090 
8091  if (is_protected && !sc->cenc.per_sample_iv_size) {
8092  iv_size = avio_r8(pb);
8093  if (iv_size != 8 && iv_size != 16) {
8094  av_log(c->fc, AV_LOG_ERROR, "invalid default_constant_IV_size in tenc atom\n");
8095  return AVERROR_INVALIDDATA;
8096  }
8097 
8098  if (avio_read(pb, sc->cenc.default_encrypted_sample->iv, iv_size) != iv_size) {
8099  av_log(c->fc, AV_LOG_ERROR, "failed to read the default IV\n");
8100  return AVERROR_INVALIDDATA;
8101  }
8102  }
8103 
8104  return 0;
8105 }
8106 
8108 {
8109  AVStream *st;
8110  int last, type, size, ret;
8111  uint8_t buf[4];
8112 
8113  if (c->fc->nb_streams < 1)
8114  return 0;
8115  st = c->fc->streams[c->fc->nb_streams-1];
8116 
8117  if ((uint64_t)atom.size > (1<<30) || atom.size < 42)
8118  return AVERROR_INVALIDDATA;
8119 
8120  /* Check FlacSpecificBox version. */
8121  if (avio_r8(pb) != 0)
8122  return AVERROR_INVALIDDATA;
8123 
8124  avio_rb24(pb); /* Flags */
8125 
8126  if (avio_read(pb, buf, sizeof(buf)) != sizeof(buf)) {
8127  av_log(c->fc, AV_LOG_ERROR, "failed to read FLAC metadata block header\n");
8128  return pb->error < 0 ? pb->error : AVERROR_INVALIDDATA;
8129  }
8130  flac_parse_block_header(buf, &last, &type, &size);
8131 
8133  av_log(c->fc, AV_LOG_ERROR, "STREAMINFO must be first FLACMetadataBlock\n");
8134  return AVERROR_INVALIDDATA;
8135  }
8136 
8137  ret = ff_get_extradata(c->fc, st->codecpar, pb, size);
8138  if (ret < 0)
8139  return ret;
8140 
8141  if (!last)
8142  av_log(c->fc, AV_LOG_WARNING, "non-STREAMINFO FLACMetadataBlock(s) ignored\n");
8143 
8144  return 0;
8145 }
8146 
8147 static int get_key_from_kid(uint8_t* out, int len, MOVContext *c, AVEncryptionInfo *sample) {
8148  AVDictionaryEntry *key_entry_hex;
8149  char kid_hex[16*2+1];
8150 
8151  if (c->decryption_default_key && c->decryption_default_key_len != len) {
8152  av_log(c->fc, AV_LOG_ERROR, "invalid default decryption key length: got %d, expected %d\n", c->decryption_default_key_len, len);
8153  return -1;
8154  }
8155 
8156  if (!c->decryption_keys) {
8157  av_assert0(c->decryption_default_key);
8158  memcpy(out, c->decryption_default_key, len);
8159  return 0;
8160  }
8161 
8162  if (sample->key_id_size != 16) {
8163  av_log(c->fc, AV_LOG_ERROR, "invalid key ID size: got %u, expected 16\n", sample->key_id_size);
8164  return -1;
8165  }
8166 
8167  ff_data_to_hex(kid_hex, sample->key_id, 16, 1);
8168  key_entry_hex = av_dict_get(c->decryption_keys, kid_hex, NULL, AV_DICT_DONT_STRDUP_KEY|AV_DICT_DONT_STRDUP_VAL);
8169  if (!key_entry_hex) {
8170  if (!c->decryption_default_key) {
8171  av_log(c->fc, AV_LOG_ERROR, "unable to find KID %s\n", kid_hex);
8172  return -1;
8173  }
8174  memcpy(out, c->decryption_default_key, len);
8175  return 0;
8176  }
8177  if (strlen(key_entry_hex->value) != len*2) {
8178  return -1;
8179  }
8180  ff_hex_to_data(out, key_entry_hex->value);
8181  return 0;
8182 }
8183 
8185 {
8186  int i, ret;
8187  int bytes_of_protected_data;
8188  uint8_t decryption_key[AES_CTR_KEY_SIZE];
8189 
8190  if (!sc->cenc.aes_ctr) {
8191  ret = get_key_from_kid(decryption_key, sizeof(decryption_key), c, sample);
8192  if (ret < 0) {
8193  return ret;
8194  }
8195 
8196  /* initialize the cipher */
8197  sc->cenc.aes_ctr = av_aes_ctr_alloc();
8198  if (!sc->cenc.aes_ctr) {
8199  return AVERROR(ENOMEM);
8200  }
8201 
8202  ret = av_aes_ctr_init(sc->cenc.aes_ctr, decryption_key);
8203  if (ret < 0) {
8204  return ret;
8205  }
8206  }
8207 
8209 
8210  if (!sample->subsample_count) {
8211  /* decrypt the whole packet */
8213  return 0;
8214  }
8215 
8216  for (i = 0; i < sample->subsample_count; i++) {
8217  if (sample->subsamples[i].bytes_of_clear_data + (int64_t)sample->subsamples[i].bytes_of_protected_data > size) {
8218  av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n");
8219  return AVERROR_INVALIDDATA;
8220  }
8221 
8222  /* skip the clear bytes */
8223  input += sample->subsamples[i].bytes_of_clear_data;
8224  size -= sample->subsamples[i].bytes_of_clear_data;
8225 
8226  /* decrypt the encrypted bytes */
8227 
8228  bytes_of_protected_data = sample->subsamples[i].bytes_of_protected_data;
8229  av_aes_ctr_crypt(sc->cenc.aes_ctr, input, input, bytes_of_protected_data);
8230 
8231  input += bytes_of_protected_data;
8232  size -= bytes_of_protected_data;
8233  }
8234 
8235  if (size > 0) {
8236  av_log(c->fc, AV_LOG_ERROR, "leftover packet bytes after subsample processing\n");
8237  return AVERROR_INVALIDDATA;
8238  }
8239 
8240  return 0;
8241 }
8242 
8244 {
8245  int i, ret;
8246  int num_of_encrypted_blocks;
8247  uint8_t iv[16];
8248  uint8_t decryption_key[16];
8249 
8250  if (!sc->cenc.aes_ctx) {
8251  ret = get_key_from_kid(decryption_key, sizeof(decryption_key), c, sample);
8252  if (ret < 0) {
8253  return ret;
8254  }
8255 
8256  /* initialize the cipher */
8257  sc->cenc.aes_ctx = av_aes_alloc();
8258  if (!sc->cenc.aes_ctx) {
8259  return AVERROR(ENOMEM);
8260  }
8261 
8262  ret = av_aes_init(sc->cenc.aes_ctx, decryption_key, 16 * 8, 1);
8263  if (ret < 0) {
8264  return ret;
8265  }
8266  }
8267 
8268  memcpy(iv, sample->iv, 16);
8269 
8270  /* whole-block full sample encryption */
8271  if (!sample->subsample_count) {
8272  /* decrypt the whole packet */
8273  av_aes_crypt(sc->cenc.aes_ctx, input, input, size/16, iv, 1);
8274  return 0;
8275  }
8276 
8277  for (i = 0; i < sample->subsample_count; i++) {
8278  if (sample->subsamples[i].bytes_of_clear_data + (int64_t)sample->subsamples[i].bytes_of_protected_data > size) {
8279  av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n");
8280  return AVERROR_INVALIDDATA;
8281  }
8282 
8283  if (sample->subsamples[i].bytes_of_protected_data % 16) {
8284  av_log(c->fc, AV_LOG_ERROR, "subsample BytesOfProtectedData is not a multiple of 16\n");
8285  return AVERROR_INVALIDDATA;
8286  }
8287 
8288  /* skip the clear bytes */
8289  input += sample->subsamples[i].bytes_of_clear_data;
8290  size -= sample->subsamples[i].bytes_of_clear_data;
8291 
8292  /* decrypt the encrypted bytes */
8293  num_of_encrypted_blocks = sample->subsamples[i].bytes_of_protected_data/16;
8294  if (num_of_encrypted_blocks > 0) {
8295  av_aes_crypt(sc->cenc.aes_ctx, input, input, num_of_encrypted_blocks, iv, 1);
8296  }
8297  input += sample->subsamples[i].bytes_of_protected_data;
8298  size -= sample->subsamples[i].bytes_of_protected_data;
8299  }
8300 
8301  if (size > 0) {
8302  av_log(c->fc, AV_LOG_ERROR, "leftover packet bytes after subsample processing\n");
8303  return AVERROR_INVALIDDATA;
8304  }
8305 
8306  return 0;
8307 }
8308 
8310 {
8311  int i, ret, rem_bytes;
8312  uint8_t *data;
8313  uint8_t decryption_key[AES_CTR_KEY_SIZE];
8314 
8315  if (!sc->cenc.aes_ctr) {
8316  ret = get_key_from_kid(decryption_key, sizeof(decryption_key), c, sample);
8317  if (ret < 0) {
8318  return ret;
8319  }
8320 
8321  /* initialize the cipher */
8322  sc->cenc.aes_ctr = av_aes_ctr_alloc();
8323  if (!sc->cenc.aes_ctr) {
8324  return AVERROR(ENOMEM);
8325  }
8326 
8327  ret = av_aes_ctr_init(sc->cenc.aes_ctr, decryption_key);
8328  if (ret < 0) {
8329  return ret;
8330  }
8331  }
8332 
8334 
8335  /* whole-block full sample encryption */
8336  if (!sample->subsample_count) {
8337  /* decrypt the whole packet */
8339  return 0;
8340  } else if (!sample->crypt_byte_block && !sample->skip_byte_block) {
8341  av_log(c->fc, AV_LOG_ERROR, "pattern encryption is not present in 'cens' scheme\n");
8342  return AVERROR_INVALIDDATA;
8343  }
8344 
8345  for (i = 0; i < sample->subsample_count; i++) {
8346  if (sample->subsamples[i].bytes_of_clear_data + (int64_t)sample->subsamples[i].bytes_of_protected_data > size) {
8347  av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n");
8348  return AVERROR_INVALIDDATA;
8349  }
8350 
8351  /* skip the clear bytes */
8352  input += sample->subsamples[i].bytes_of_clear_data;
8353  size -= sample->subsamples[i].bytes_of_clear_data;
8354 
8355  /* decrypt the encrypted bytes */
8356  data = input;
8357  rem_bytes = sample->subsamples[i].bytes_of_protected_data;
8358  while (rem_bytes > 0) {
8359  if (rem_bytes < 16*sample->crypt_byte_block) {
8360  break;
8361  }
8362  av_aes_ctr_crypt(sc->cenc.aes_ctr, data, data, 16*sample->crypt_byte_block);
8363  data += 16*sample->crypt_byte_block;
8364  rem_bytes -= 16*sample->crypt_byte_block;
8365  data += FFMIN(16*sample->skip_byte_block, rem_bytes);
8366  rem_bytes -= FFMIN(16*sample->skip_byte_block, rem_bytes);
8367  }
8368  input += sample->subsamples[i].bytes_of_protected_data;
8369  size -= sample->subsamples[i].bytes_of_protected_data;
8370  }
8371 
8372  if (size > 0) {
8373  av_log(c->fc, AV_LOG_ERROR, "leftover packet bytes after subsample processing\n");
8374  return AVERROR_INVALIDDATA;
8375  }
8376 
8377  return 0;
8378 }
8379 
8381 {
8382  int i, ret, rem_bytes;
8383  uint8_t iv[16];
8384  uint8_t *data;
8385  uint8_t decryption_key[16];
8386 
8387  if (!sc->cenc.aes_ctx) {
8388  ret = get_key_from_kid(decryption_key, sizeof(decryption_key), c, sample);
8389  if (ret < 0) {
8390  return ret;
8391  }
8392 
8393  /* initialize the cipher */
8394  sc->cenc.aes_ctx = av_aes_alloc();
8395  if (!sc->cenc.aes_ctx) {
8396  return AVERROR(ENOMEM);
8397  }
8398 
8399  ret = av_aes_init(sc->cenc.aes_ctx, decryption_key, 16 * 8, 1);
8400  if (ret < 0) {
8401  return ret;
8402  }
8403  }
8404 
8405  /* whole-block full sample encryption */
8406  if (!sample->subsample_count) {
8407  /* decrypt the whole packet */
8408  memcpy(iv, sample->iv, 16);
8409  av_aes_crypt(sc->cenc.aes_ctx, input, input, size/16, iv, 1);
8410  return 0;
8411  } else if (!sample->crypt_byte_block && !sample->skip_byte_block) {
8412  av_log(c->fc, AV_LOG_ERROR, "pattern encryption is not present in 'cbcs' scheme\n");
8413  return AVERROR_INVALIDDATA;
8414  }
8415 
8416  for (i = 0; i < sample->subsample_count; i++) {
8417  if (sample->subsamples[i].bytes_of_clear_data + (int64_t)sample->subsamples[i].bytes_of_protected_data > size) {
8418  av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n");
8419  return AVERROR_INVALIDDATA;
8420  }
8421 
8422  /* skip the clear bytes */
8423  input += sample->subsamples[i].bytes_of_clear_data;
8424  size -= sample->subsamples[i].bytes_of_clear_data;
8425 
8426  /* decrypt the encrypted bytes */
8427  memcpy(iv, sample->iv, 16);
8428  data = input;
8429  rem_bytes = sample->subsamples[i].bytes_of_protected_data;
8430  while (rem_bytes > 0) {
8431  if (rem_bytes < 16*sample->crypt_byte_block) {
8432  break;
8433  }
8434  av_aes_crypt(sc->cenc.aes_ctx, data, data, sample->crypt_byte_block, iv, 1);
8435  data += 16*sample->crypt_byte_block;
8436  rem_bytes -= 16*sample->crypt_byte_block;
8437  data += FFMIN(16*sample->skip_byte_block, rem_bytes);
8438  rem_bytes -= FFMIN(16*sample->skip_byte_block, rem_bytes);
8439  }
8440  input += sample->subsamples[i].bytes_of_protected_data;
8441  size -= sample->subsamples[i].bytes_of_protected_data;
8442  }
8443 
8444  if (size > 0) {
8445  av_log(c->fc, AV_LOG_ERROR, "leftover packet bytes after subsample processing\n");
8446  return AVERROR_INVALIDDATA;
8447  }
8448 
8449  return 0;
8450 }
8451 
8453 {
8454  if (sample->scheme == MKBETAG('c','e','n','c') && !sample->crypt_byte_block && !sample->skip_byte_block) {
8455  return cenc_scheme_decrypt(c, sc, sample, input, size);
8456  } else if (sample->scheme == MKBETAG('c','b','c','1') && !sample->crypt_byte_block && !sample->skip_byte_block) {
8457  return cbc1_scheme_decrypt(c, sc, sample, input, size);
8458  } else if (sample->scheme == MKBETAG('c','e','n','s')) {
8459  return cens_scheme_decrypt(c, sc, sample, input, size);
8460  } else if (sample->scheme == MKBETAG('c','b','c','s')) {
8461  return cbcs_scheme_decrypt(c, sc, sample, input, size);
8462  } else {
8463  av_log(c->fc, AV_LOG_ERROR, "invalid encryption scheme\n");
8464  return AVERROR_INVALIDDATA;
8465  }
8466 }
8467 
8469 {
8470  int current = frag_index->current;
8471 
8472  if (!frag_index->nb_items)
8473  return NULL;
8474 
8475  // Check frag_index->current is the right one for pkt. It can out of sync.
8476  if (current >= 0 && current < frag_index->nb_items) {
8477  if (frag_index->item[current].moof_offset < pkt->pos &&
8478  (current + 1 == frag_index->nb_items ||
8479  frag_index->item[current + 1].moof_offset > pkt->pos))
8480  return get_frag_stream_info(frag_index, current, id);
8481  }
8482 
8483 
8484  for (int i = 0; i < frag_index->nb_items; i++) {
8485  if (frag_index->item[i].moof_offset > pkt->pos)
8486  break;
8487  current = i;
8488  }
8489  frag_index->current = current;
8490  return get_frag_stream_info(frag_index, current, id);
8491 }
8492 
8493 static int cenc_filter(MOVContext *mov, AVStream* st, MOVStreamContext *sc, AVPacket *pkt, int current_index)
8494 {
8495  MOVFragmentStreamInfo *frag_stream_info;
8496  MOVEncryptionIndex *encryption_index;
8497  AVEncryptionInfo *encrypted_sample;
8498  int encrypted_index, ret;
8499 
8500  frag_stream_info = get_frag_stream_info_from_pkt(&mov->frag_index, pkt, sc->id);
8501  encrypted_index = current_index;
8502  encryption_index = NULL;
8503  if (frag_stream_info) {
8504  // Note this only supports encryption info in the first sample descriptor.
8505  if (frag_stream_info->stsd_id == 1) {
8506  if (frag_stream_info->encryption_index) {
8507  encrypted_index = current_index - frag_stream_info->index_base;
8508  encryption_index = frag_stream_info->encryption_index;
8509  } else {
8510  encryption_index = sc->cenc.encryption_index;
8511  }
8512  }
8513  } else {
8514  encryption_index = sc->cenc.encryption_index;
8515  }
8516 
8517  if (encryption_index) {
8518  if (encryption_index->auxiliary_info_sample_count &&
8519  !encryption_index->nb_encrypted_samples) {
8520  av_log(mov->fc, AV_LOG_ERROR, "saiz atom found without saio\n");
8521  return AVERROR_INVALIDDATA;
8522  }
8523  if (encryption_index->auxiliary_offsets_count &&
8524  !encryption_index->nb_encrypted_samples) {
8525  av_log(mov->fc, AV_LOG_ERROR, "saio atom found without saiz\n");
8526  return AVERROR_INVALIDDATA;
8527  }
8528 
8529  encrypted_sample = NULL;
8530  if (!encryption_index->nb_encrypted_samples) {
8531  // Full-sample encryption with default settings.
8532  encrypted_sample = sc->cenc.default_encrypted_sample;
8533  } else if (encrypted_index >= 0 && encrypted_index < encryption_index->nb_encrypted_samples) {
8534  // Per-sample setting override.
8535  encrypted_sample = encryption_index->encrypted_samples[encrypted_index];
8536  if (!encrypted_sample) {
8537  encrypted_sample = sc->cenc.default_encrypted_sample;
8538  }
8539  }
8540 
8541  if (!encrypted_sample) {
8542  av_log(mov->fc, AV_LOG_ERROR, "Incorrect number of samples in encryption info\n");
8543  return AVERROR_INVALIDDATA;
8544  }
8545 
8546  if (mov->decryption_keys || mov->decryption_default_key) {
8547  return cenc_decrypt(mov, sc, encrypted_sample, pkt->data, pkt->size);
8548  } else {
8549  size_t size;
8550  uint8_t *side_data = av_encryption_info_add_side_data(encrypted_sample, &size);
8551  if (!side_data)
8552  return AVERROR(ENOMEM);
8554  if (ret < 0)
8555  av_free(side_data);
8556  return ret;
8557  }
8558  }
8559 
8560  return 0;
8561 }
8562 
8564 {
8565  const int OPUS_SEEK_PREROLL_MS = 80;
8566  int ret;
8567  AVStream *st;
8568  size_t size;
8569  uint16_t pre_skip;
8570 
8571  if (c->fc->nb_streams < 1)
8572  return 0;
8573  st = c->fc->streams[c->fc->nb_streams-1];
8574 
8575  if ((uint64_t)atom.size > (1<<30) || atom.size < 11 || st->codecpar->extradata)
8576  return AVERROR_INVALIDDATA;
8577 
8578  /* Check OpusSpecificBox version. */
8579  if (avio_r8(pb) != 0) {
8580  av_log(c->fc, AV_LOG_ERROR, "unsupported OpusSpecificBox version\n");
8581  return AVERROR_INVALIDDATA;
8582  }
8583 
8584  /* OpusSpecificBox size plus magic for Ogg OpusHead header. */
8585  size = atom.size + 8;
8586 
8587  if ((ret = ff_alloc_extradata(st->codecpar, size)) < 0)
8588  return ret;
8589 
8590  AV_WL32A(st->codecpar->extradata, MKTAG('O','p','u','s'));
8591  AV_WL32A(st->codecpar->extradata + 4, MKTAG('H','e','a','d'));
8592  AV_WB8(st->codecpar->extradata + 8, 1); /* OpusHead version */
8593  if ((ret = ffio_read_size(pb, st->codecpar->extradata + 9, size - 9)) < 0) {
8594  av_freep(&st->codecpar->extradata);
8595  st->codecpar->extradata_size = 0;
8596  return ret;
8597  }
8598 
8599  /* OpusSpecificBox is stored in big-endian, but OpusHead is
8600  little-endian; aside from the preceding magic and version they're
8601  otherwise currently identical. Data after output gain at offset 16
8602  doesn't need to be bytewapped. */
8603  pre_skip = AV_RB16A(st->codecpar->extradata + 10);
8604  AV_WL16A(st->codecpar->extradata + 10, pre_skip);
8605  AV_WL32A(st->codecpar->extradata + 12, AV_RB32A(st->codecpar->extradata + 12));
8606  AV_WL16A(st->codecpar->extradata + 16, AV_RB16A(st->codecpar->extradata + 16));
8607 
8608  st->codecpar->initial_padding = pre_skip;
8610  (AVRational){1, 1000},
8611  (AVRational){1, 48000});
8612 
8613  return 0;
8614 }
8615 
8617 {
8618  AVStream *st;
8619  unsigned format_info;
8620  int channel_assignment, channel_assignment1, channel_assignment2;
8621  int ratebits;
8622  uint64_t chmask;
8623 
8624  if (c->fc->nb_streams < 1)
8625  return 0;
8626  st = c->fc->streams[c->fc->nb_streams-1];
8627 
8628  if (atom.size < 10)
8629  return AVERROR_INVALIDDATA;
8630 
8631  format_info = avio_rb32(pb);
8632 
8633  ratebits = (format_info >> 28) & 0xF;
8634  channel_assignment1 = (format_info >> 15) & 0x1F;
8635  channel_assignment2 = format_info & 0x1FFF;
8636  if (channel_assignment2)
8637  channel_assignment = channel_assignment2;
8638  else
8639  channel_assignment = channel_assignment1;
8640 
8641  st->codecpar->frame_size = 40 << (ratebits & 0x7);
8642  st->codecpar->sample_rate = mlp_samplerate(ratebits);
8643 
8645  chmask = truehd_layout(channel_assignment);
8647 
8648  return 0;
8649 }
8650 
8652 {
8653  AVStream *st;
8654  uint8_t buf[ISOM_DVCC_DVVC_SIZE];
8655  int ret;
8656  int64_t read_size = atom.size;
8657 
8658  if (c->fc->nb_streams < 1)
8659  return 0;
8660  st = c->fc->streams[c->fc->nb_streams-1];
8661 
8662  // At most 24 bytes
8663  read_size = FFMIN(read_size, ISOM_DVCC_DVVC_SIZE);
8664 
8665  if ((ret = ffio_read_size(pb, buf, read_size)) < 0)
8666  return ret;
8667 
8668  return ff_isom_parse_dvcc_dvvc(c->fc, st, buf, read_size);
8669 }
8670 
8672 {
8673  AVStream *st;
8674  uint8_t *buf;
8675  int ret, old_size, num_arrays;
8676 
8677  if (c->fc->nb_streams < 1)
8678  return 0;
8679  st = c->fc->streams[c->fc->nb_streams-1];
8680 
8681  if (!st->codecpar->extradata_size)
8682  // TODO: handle lhvC when present before hvcC
8683  return 0;
8684 
8685  if (atom.size < 6 || st->codecpar->extradata_size < 23 ||
8686  atom.size > INT_MAX - AV_INPUT_BUFFER_PADDING_SIZE) {
8687  return AVERROR_INVALIDDATA;
8688  }
8689 
8691  if (!buf)
8692  return AVERROR(ENOMEM);
8693  memset(buf + atom.size, 0, AV_INPUT_BUFFER_PADDING_SIZE);
8694 
8695  ret = ffio_read_size(pb, buf, atom.size);
8696  if (ret < 0) {
8697  av_free(buf);
8698  av_log(c->fc, AV_LOG_WARNING, "lhvC atom truncated\n");
8699  return 0;
8700  }
8701 
8702  num_arrays = buf[5];
8703  old_size = st->codecpar->extradata_size;
8704  atom.size -= 8 /* account for mov_realloc_extradata offsetting */
8705  + 6 /* lhvC bytes before the arrays*/;
8706 
8707  ret = mov_realloc_extradata(st->codecpar, atom);
8708  if (ret < 0) {
8709  av_free(buf);
8710  return ret;
8711  }
8712 
8713  st->codecpar->extradata[22] += num_arrays;
8714  memcpy(st->codecpar->extradata + old_size, buf + 6, atom.size + 8);
8715 
8717 
8718  av_free(buf);
8719  return 0;
8720 }
8721 
8723 {
8724  AVFormatContext *ctx = c->fc;
8725  AVStream *st = NULL;
8726  AVBPrint scheme_buf, value_buf;
8727  int64_t scheme_str_len = 0, value_str_len = 0;
8728  int version, flags, ret = AVERROR_BUG;
8729  int64_t size = atom.size;
8730 
8731  if (atom.size < 6)
8732  // 4 bytes for version + flags, 2x 1 byte for null
8733  return AVERROR_INVALIDDATA;
8734 
8735  if (c->fc->nb_streams < 1)
8736  return 0;
8737  st = c->fc->streams[c->fc->nb_streams-1];
8738 
8739  version = avio_r8(pb);
8740  flags = avio_rb24(pb);
8741  size -= 4;
8742 
8743  if (version != 0 || flags != 0) {
8745  "Unsupported 'kind' box with version %d, flags: %x",
8746  version, flags);
8747  return AVERROR_INVALIDDATA;
8748  }
8749 
8750  av_bprint_init(&scheme_buf, 0, AV_BPRINT_SIZE_UNLIMITED);
8751  av_bprint_init(&value_buf, 0, AV_BPRINT_SIZE_UNLIMITED);
8752 
8753  if ((scheme_str_len = ff_read_string_to_bprint_overwrite(pb, &scheme_buf,
8754  size)) < 0) {
8755  ret = scheme_str_len;
8756  goto cleanup;
8757  }
8758 
8759  if (scheme_str_len + 1 >= size) {
8760  // we need to have another string, even if nullptr.
8761  // we check with + 1 since we expect that if size was not hit,
8762  // an additional null was read.
8764  goto cleanup;
8765  }
8766 
8767  size -= scheme_str_len + 1;
8768 
8769  if ((value_str_len = ff_read_string_to_bprint_overwrite(pb, &value_buf,
8770  size)) < 0) {
8771  ret = value_str_len;
8772  goto cleanup;
8773  }
8774 
8775  if (value_str_len == size) {
8776  // in case of no trailing null, box is not valid.
8778  goto cleanup;
8779  }
8780 
8782  "%s stream %d KindBox(scheme: %s, value: %s)\n",
8784  st->index,
8785  scheme_buf.str, value_buf.str);
8786 
8787  for (int i = 0; ff_mov_track_kind_table[i].scheme_uri; i++) {
8789  if (!av_strstart(scheme_buf.str, map.scheme_uri, NULL))
8790  continue;
8791 
8792  for (int j = 0; map.value_maps[j].disposition; j++) {
8793  const struct MP4TrackKindValueMapping value_map = map.value_maps[j];
8794  if (!av_strstart(value_buf.str, value_map.value, NULL))
8795  continue;
8796 
8797  st->disposition |= value_map.disposition;
8798  }
8799  }
8800 
8801  ret = 0;
8802 
8803 cleanup:
8804 
8805  av_bprint_finalize(&scheme_buf, NULL);
8806  av_bprint_finalize(&value_buf, NULL);
8807 
8808  return ret;
8809 }
8810 
8812 {
8813  AVStream *st;
8814  AVChannelLayout ch_layout = { 0 };
8815  int ret, i, version, type;
8816  int ambisonic_order, channel_order, normalization, channel_count;
8817  int ambi_channels, non_diegetic_channels;
8818 
8819  if (c->fc->nb_streams < 1)
8820  return 0;
8821 
8822  st = c->fc->streams[c->fc->nb_streams - 1];
8823 
8824  if (atom.size < 16) {
8825  av_log(c->fc, AV_LOG_ERROR, "SA3D audio box too small\n");
8826  return AVERROR_INVALIDDATA;
8827  }
8828 
8829  version = avio_r8(pb);
8830  if (version) {
8831  av_log(c->fc, AV_LOG_WARNING, "Unsupported SA3D box version %d\n", version);
8832  return 0;
8833  }
8834 
8835  type = avio_r8(pb);
8836  if (type & 0x7f) {
8837  av_log(c->fc, AV_LOG_WARNING,
8838  "Unsupported ambisonic type %d\n", type & 0x7f);
8839  return 0;
8840  }
8841  non_diegetic_channels = (type >> 7) * 2; // head_locked_stereo
8842 
8843  ambisonic_order = avio_rb32(pb);
8844 
8845  channel_order = avio_r8(pb);
8846  if (channel_order) {
8847  av_log(c->fc, AV_LOG_WARNING,
8848  "Unsupported channel_order %d\n", channel_order);
8849  return 0;
8850  }
8851 
8852  normalization = avio_r8(pb);
8853  if (normalization) {
8854  av_log(c->fc, AV_LOG_WARNING,
8855  "Unsupported normalization %d\n", normalization);
8856  return 0;
8857  }
8858 
8859  channel_count = avio_rb32(pb);
8860  if (ambisonic_order < 0 || ambisonic_order > 31 ||
8861  channel_count != ((ambisonic_order + 1LL) * (ambisonic_order + 1LL) +
8862  non_diegetic_channels)) {
8863  av_log(c->fc, AV_LOG_ERROR,
8864  "Invalid number of channels (%d / %d)\n",
8865  channel_count, ambisonic_order);
8866  return 0;
8867  }
8868  ambi_channels = channel_count - non_diegetic_channels;
8869 
8870  ret = av_channel_layout_custom_init(&ch_layout, channel_count);
8871  if (ret < 0)
8872  return 0;
8873 
8874  for (i = 0; i < channel_count; i++) {
8875  unsigned channel = avio_rb32(pb);
8876 
8877  if (channel >= channel_count) {
8878  av_log(c->fc, AV_LOG_ERROR, "Invalid channel index (%d / %d)\n",
8879  channel, ambisonic_order);
8880  av_channel_layout_uninit(&ch_layout);
8881  return 0;
8882  }
8883  if (channel >= ambi_channels)
8884  ch_layout.u.map[i].id = channel - ambi_channels;
8885  else
8886  ch_layout.u.map[i].id = AV_CHAN_AMBISONIC_BASE + channel;
8887  }
8888 
8890  if (ret < 0) {
8891  av_channel_layout_uninit(&ch_layout);
8892  return 0;
8893  }
8894 
8896  st->codecpar->ch_layout = ch_layout;
8897 
8898  return 0;
8899 }
8900 
8902 {
8903  AVStream *st;
8904  int version;
8905 
8906  if (c->fc->nb_streams < 1)
8907  return 0;
8908 
8909  st = c->fc->streams[c->fc->nb_streams - 1];
8910 
8911  if (atom.size < 5) {
8912  av_log(c->fc, AV_LOG_ERROR, "Empty SAND audio box\n");
8913  return AVERROR_INVALIDDATA;
8914  }
8915 
8916  version = avio_r8(pb);
8917  if (version) {
8918  av_log(c->fc, AV_LOG_WARNING, "Unsupported SAND box version %d\n", version);
8919  return 0;
8920  }
8921 
8923 
8924  return 0;
8925 }
8926 
8927 static int rb_size(AVIOContext *pb, int64_t *value, int size)
8928 {
8929  if (size == 0)
8930  *value = 0;
8931  else if (size == 1)
8932  *value = avio_r8(pb);
8933  else if (size == 2)
8934  *value = avio_rb16(pb);
8935  else if (size == 4)
8936  *value = avio_rb32(pb);
8937  else if (size == 8) {
8938  *value = avio_rb64(pb);
8939  if (*value < 0)
8940  return -1;
8941  } else
8942  return -1;
8943  return size;
8944 }
8945 
8947 {
8948  avio_rb32(pb); // version & flags.
8949  c->primary_item_id = avio_rb16(pb);
8950  av_log(c->fc, AV_LOG_TRACE, "pitm: primary_item_id %d\n", c->primary_item_id);
8951  return atom.size;
8952 }
8953 
8955 {
8956  c->idat_offset = avio_tell(pb);
8957  return 0;
8958 }
8959 
8961 {
8962  HEIFItem **heif_item;
8963  int version, offset_size, length_size, base_offset_size, index_size;
8964  int item_count, extent_count;
8965  int64_t base_offset, extent_offset, extent_length;
8966  uint8_t value;
8967 
8968  if (c->found_iloc) {
8969  av_log(c->fc, AV_LOG_INFO, "Duplicate iloc box found\n");
8970  return 0;
8971  }
8972 
8973  version = avio_r8(pb);
8974  avio_rb24(pb); // flags.
8975 
8976  value = avio_r8(pb);
8977  offset_size = (value >> 4) & 0xF;
8978  length_size = value & 0xF;
8979  value = avio_r8(pb);
8980  base_offset_size = (value >> 4) & 0xF;
8981  index_size = !version ? 0 : (value & 0xF);
8982  if (index_size) {
8983  avpriv_report_missing_feature(c->fc, "iloc: index_size != 0");
8984  return AVERROR_PATCHWELCOME;
8985  }
8986  item_count = (version < 2) ? avio_rb16(pb) : avio_rb32(pb);
8987 
8988  heif_item = av_realloc_array(c->heif_item, FFMAX(item_count, c->nb_heif_item), sizeof(*c->heif_item));
8989  if (!heif_item)
8990  return AVERROR(ENOMEM);
8991  c->heif_item = heif_item;
8992  if (item_count > c->nb_heif_item)
8993  memset(&c->heif_item[c->nb_heif_item], 0,
8994  sizeof(*c->heif_item) * (item_count - c->nb_heif_item));
8995  c->nb_heif_item = FFMAX(c->nb_heif_item, item_count);
8996 
8997  av_log(c->fc, AV_LOG_TRACE, "iloc: item_count %d\n", item_count);
8998  for (int i = 0; i < item_count; i++) {
8999  HEIFItem *item = NULL;
9000  int item_id = (version < 2) ? avio_rb16(pb) : avio_rb32(pb);
9001  int offset_type = (version > 0) ? avio_rb16(pb) & 0xf : 0;
9002  int j;
9003 
9004  if (avio_feof(pb))
9005  return AVERROR_INVALIDDATA;
9006  if (offset_type > 1) {
9007  avpriv_report_missing_feature(c->fc, "iloc offset type %d", offset_type);
9008  return AVERROR_PATCHWELCOME;
9009  }
9010 
9011  avio_rb16(pb); // data_reference_index.
9012  if (rb_size(pb, &base_offset, base_offset_size) < 0)
9013  return AVERROR_INVALIDDATA;
9014  extent_count = avio_rb16(pb);
9015  if (extent_count > 1) {
9016  // For still AVIF images, we only support one extent item.
9017  avpriv_report_missing_feature(c->fc, "iloc: extent_count > 1");
9018  return AVERROR_PATCHWELCOME;
9019  }
9020 
9021  if (rb_size(pb, &extent_offset, offset_size) < 0 ||
9022  rb_size(pb, &extent_length, length_size) < 0 ||
9023  base_offset > INT64_MAX - extent_offset)
9024  return AVERROR_INVALIDDATA;
9025 
9026  for (j = 0; j < c->nb_heif_item; j++) {
9027  item = c->heif_item[j];
9028  if (!item)
9029  item = c->heif_item[j] = av_mallocz(sizeof(*item));
9030  else if (item->item_id != item_id)
9031  continue;
9032  break;
9033  }
9034  if (!item)
9035  return AVERROR(ENOMEM);
9036  if (j == c->nb_heif_item)
9037  return AVERROR_INVALIDDATA;
9038 
9039  item->item_id = item_id;
9040 
9041  if (offset_type == 1)
9042  item->is_idat_relative = 1;
9043  item->extent_length = extent_length;
9044  item->extent_offset = base_offset + extent_offset;
9045  av_log(c->fc, AV_LOG_TRACE, "iloc: item_idx %d, item->item_id %d, offset_type %d, "
9046  "extent_offset %"PRId64", extent_length %"PRId64"\n",
9047  i, item->item_id, offset_type, item->extent_offset, item->extent_length);
9048  }
9049 
9050  c->found_iloc = 1;
9051  return atom.size;
9052 }
9053 
9055 {
9056  HEIFItem *item = NULL;
9057  AVBPrint item_name;
9058  int64_t size = atom.size;
9059  uint32_t item_type;
9060  int item_id;
9061  int i, version, ret;
9062 
9063  version = avio_r8(pb);
9064  avio_rb24(pb); // flags.
9065  size -= 4;
9066  if (size < 0)
9067  return AVERROR_INVALIDDATA;
9068 
9069  if (version < 2) {
9070  avpriv_report_missing_feature(c->fc, "infe version < 2");
9071  avio_skip(pb, size);
9072  return 1;
9073  }
9074 
9075  item_id = version > 2 ? avio_rb32(pb) : avio_rb16(pb);
9076  avio_rb16(pb); // item_protection_index
9077  item_type = avio_rl32(pb);
9078  size -= 8;
9079  if (size < 1)
9080  return AVERROR_INVALIDDATA;
9081 
9084  if (ret < 0) {
9086  return ret;
9087  }
9088 
9089  av_log(c->fc, AV_LOG_TRACE, "infe: item_id %d, item_type %s, item_name %s\n",
9090  item_id, av_fourcc2str(item_type), item_name.str);
9091 
9092  size -= ret + 1;
9093  if (size > 0)
9094  avio_skip(pb, size);
9095 
9096  for (i = 0; i < c->nb_heif_item; i++) {
9097  item = c->heif_item[i];
9098  if (!item)
9099  item = c->heif_item[i] = av_mallocz(sizeof(*item));
9100  else if (item->item_id != item_id)
9101  continue;
9102  break;
9103  }
9104  if (!item) {
9106  return AVERROR(ENOMEM);
9107  }
9108  if (i == c->nb_heif_item) {
9110  return AVERROR_INVALIDDATA;
9111  }
9112 
9113  av_freep(&item->name);
9114  av_bprint_finalize(&item_name, ret ? &item->name : NULL);
9115  item->item_id = item_id;
9116  item->type = item_type;
9117 
9118  switch (item_type) {
9119  case MKTAG('a','v','0','1'):
9120  case MKTAG('j','p','e','g'):
9121  case MKTAG('h','v','c','1'):
9122  ret = heif_add_stream(c, item);
9123  if (ret < 0)
9124  return ret;
9125  break;
9126  }
9127 
9128  return 0;
9129 }
9130 
9132 {
9133  HEIFItem **heif_item;
9134  int entry_count;
9135  int version, got_stream = 0, ret, i;
9136 
9137  if (c->found_iinf) {
9138  av_log(c->fc, AV_LOG_WARNING, "Duplicate iinf box found\n");
9139  return 0;
9140  }
9141 
9142  version = avio_r8(pb);
9143  avio_rb24(pb); // flags.
9144  entry_count = version ? avio_rb32(pb) : avio_rb16(pb);
9145 
9146  heif_item = av_realloc_array(c->heif_item, FFMAX(entry_count, c->nb_heif_item), sizeof(*c->heif_item));
9147  if (!heif_item)
9148  return AVERROR(ENOMEM);
9149  c->heif_item = heif_item;
9150  if (entry_count > c->nb_heif_item)
9151  memset(&c->heif_item[c->nb_heif_item], 0,
9152  sizeof(*c->heif_item) * (entry_count - c->nb_heif_item));
9153  c->nb_heif_item = FFMAX(c->nb_heif_item, entry_count);
9154 
9155  for (i = 0; i < entry_count; i++) {
9156  MOVAtom infe;
9157 
9158  infe.size = avio_rb32(pb) - 8;
9159  infe.type = avio_rl32(pb);
9160  if (avio_feof(pb)) {
9162  goto fail;
9163  }
9164  ret = mov_read_infe(c, pb, infe);
9165  if (ret < 0)
9166  goto fail;
9167  if (!ret)
9168  got_stream = 1;
9169  }
9170 
9171  c->found_iinf = got_stream;
9172  return 0;
9173 fail:
9174  for (; i >= 0; i--) {
9175  HEIFItem *item = c->heif_item[i];
9176 
9177  if (!item)
9178  continue;
9179 
9180  av_freep(&item->name);
9181  }
9182  return ret;
9183 }
9184 
9186 {
9187  HEIFItem *item = NULL;
9188  HEIFGrid *grid;
9189  int entries, i;
9190  int from_item_id = version ? avio_rb32(pb) : avio_rb16(pb);
9191  int ret = 0;
9192 
9193  for (int i = 0; i < c->nb_heif_grid; i++) {
9194  if (c->heif_grid[i].item->item_id == from_item_id) {
9195  av_log(c->fc, AV_LOG_ERROR, "More than one 'dimg' box "
9196  "referencing the same Derived Image item\n");
9197  return AVERROR_INVALIDDATA;
9198  }
9199  }
9200  for (int i = 0; i < c->nb_heif_item; i++) {
9201  if (!c->heif_item[i] || c->heif_item[i]->item_id != from_item_id)
9202  continue;
9203  item = c->heif_item[i];
9204 
9205  switch (item->type) {
9206  case MKTAG('g','r','i','d'):
9207  case MKTAG('i','o','v','l'):
9208  break;
9209  default:
9210  avpriv_report_missing_feature(c->fc, "Derived Image item of type %s",
9211  av_fourcc2str(item->type));
9212  return 0;
9213  }
9214  break;
9215  }
9216  if (!item) {
9217  av_log(c->fc, AV_LOG_ERROR, "Missing grid information\n");
9218  return AVERROR_INVALIDDATA;
9219  }
9220 
9221  entries = avio_rb16(pb);
9222  if (!entries) {
9223  av_log(c->fc, AV_LOG_ERROR,
9224  "Derived image item references no input images\n");
9225  return AVERROR_INVALIDDATA;
9226  }
9227 
9228  grid = av_realloc_array(c->heif_grid, c->nb_heif_grid + 1U,
9229  sizeof(*c->heif_grid));
9230  if (!grid)
9231  return AVERROR(ENOMEM);
9232  c->heif_grid = grid;
9233  grid = &grid[c->nb_heif_grid];
9234 
9235  grid->tile_id_list = av_malloc_array(entries, sizeof(*grid->tile_id_list));
9236  grid->tile_idx_list = av_calloc(entries, sizeof(*grid->tile_idx_list));
9237  grid->tile_item_list = av_calloc(entries, sizeof(*grid->tile_item_list));
9238  if (!grid->tile_id_list || !grid->tile_item_list || !grid->tile_idx_list) {
9239  ret = AVERROR(ENOMEM);
9240  goto fail;
9241  }
9242  /* 'to' item ids */
9243  for (i = 0; i < entries; i++) {
9244  grid->tile_id_list[i] = version ? avio_rb32(pb) : avio_rb16(pb);
9245 
9246  if (avio_feof(pb)) {
9248  goto fail;
9249  }
9250  }
9251 
9252  grid->nb_tiles = entries;
9253  grid->item = item;
9254  ++c->nb_heif_grid;
9255 
9256  av_log(c->fc, AV_LOG_TRACE, "dimg: from_item_id %d, entries %d\n",
9257  from_item_id, entries);
9258 
9259  return 0;
9260 fail:
9261  av_freep(&grid->tile_id_list);
9262  av_freep(&grid->tile_idx_list);
9263  av_freep(&grid->tile_item_list);
9264 
9265  return ret;
9266 }
9267 
9268 static int mov_read_iref_cdsc(MOVContext *c, AVIOContext *pb, uint32_t type, int version)
9269 {
9270  HEIFItem *from_item = NULL;
9271  int entries;
9272  int from_item_id = version ? avio_rb32(pb) : avio_rb16(pb);
9273  const HEIFItemRef ref = { type, from_item_id };
9274 
9275  from_item = get_heif_item(c, from_item_id);
9276  if (!from_item) {
9277  av_log(c->fc, AV_LOG_ERROR, "Missing stream referenced by thmb item\n");
9278  return AVERROR_INVALIDDATA;
9279  }
9280 
9281  entries = avio_rb16(pb);
9282  /* 'to' item ids */
9283  for (int i = 0; i < entries; i++) {
9284  HEIFItem *item = get_heif_item(c, version ? avio_rb32(pb) : avio_rb16(pb));
9285 
9286  if (avio_feof(pb))
9287  return AVERROR_INVALIDDATA;
9288 
9289  if (!item) {
9290  av_log(c->fc, AV_LOG_WARNING, "Missing stream referenced by %s item\n",
9291  av_fourcc2str(type));
9292  continue;
9293  }
9294 
9295  if (!av_dynarray2_add((void **)&item->iref_list, &item->nb_iref_list,
9296  sizeof(*item->iref_list), (const uint8_t *)&ref))
9297  return AVERROR(ENOMEM);
9298  }
9299 
9300  av_log(c->fc, AV_LOG_TRACE, "%s: from_item_id %d, entries %d\n",
9301  av_fourcc2str(type), from_item_id, entries);
9302 
9303  return 0;
9304 }
9305 
9307 {
9308  int version = avio_r8(pb);
9309  int ret;
9310 
9311  avio_rb24(pb); // flags
9312  atom.size -= 4;
9313 
9314  if (version > 1) {
9315  av_log(c->fc, AV_LOG_WARNING, "Unknown iref box version %d\n", version);
9316  return 0;
9317  }
9318 
9319  while (atom.size) {
9320  uint32_t type, size = avio_rb32(pb);
9321  int64_t next = avio_tell(pb);
9322 
9323  if (size < 14 || next < 0 || next > INT64_MAX - size)
9324  return AVERROR_INVALIDDATA;
9325 
9326  next += size - 4;
9327  type = avio_rl32(pb);
9328  switch (type) {
9329  case MKTAG('d','i','m','g'):
9330  ret = mov_read_iref_dimg(c, pb, version);
9331  if (ret < 0)
9332  return ret;
9333  break;
9334  case MKTAG('c','d','s','c'):
9335  case MKTAG('t','h','m','b'):
9336  ret = mov_read_iref_cdsc(c, pb, type, version);
9337  if (ret < 0)
9338  return ret;
9339  break;
9340  default:
9341  av_log(c->fc, AV_LOG_DEBUG, "Unknown iref type %s size %"PRIu32"\n",
9342  av_fourcc2str(type), size);
9343  }
9344 
9345  atom.size -= size;
9346  avio_seek(pb, next, SEEK_SET);
9347  }
9348  return 0;
9349 }
9350 
9352 {
9353  HEIFItem *item;
9354  uint32_t width, height;
9355 
9356  avio_r8(pb); /* version */
9357  avio_rb24(pb); /* flags */
9358  width = avio_rb32(pb);
9359  height = avio_rb32(pb);
9360 
9361  av_log(c->fc, AV_LOG_TRACE, "ispe: item_id %d, width %"PRIu32", height %"PRIu32"\n",
9362  c->cur_item_id, width, height);
9363 
9364  item = get_heif_item(c, c->cur_item_id);
9365  if (item) {
9366  item->width = width;
9367  item->height = height;
9368  }
9369 
9370  return 0;
9371 }
9372 
9374 {
9375  HEIFItem *item;
9376  int angle;
9377 
9378  angle = avio_r8(pb) & 0x3;
9379 
9380  av_log(c->fc, AV_LOG_TRACE, "irot: item_id %d, angle %u\n",
9381  c->cur_item_id, angle);
9382 
9383  item = get_heif_item(c, c->cur_item_id);
9384  if (item) {
9385  // angle * 90 specifies the angle (in anti-clockwise direction)
9386  // in units of degrees.
9387  item->rotation = angle * 90;
9388  }
9389 
9390  return 0;
9391 }
9392 
9394 {
9395  HEIFItem *item;
9396  int axis;
9397 
9398  axis = avio_r8(pb) & 0x1;
9399 
9400  av_log(c->fc, AV_LOG_TRACE, "imir: item_id %d, axis %u\n",
9401  c->cur_item_id, axis);
9402 
9403  item = get_heif_item(c, c->cur_item_id);
9404  if (item) {
9405  item->hflip = axis;
9406  item->vflip = !axis;
9407  }
9408 
9409  return 0;
9410 }
9411 
9413 {
9414  typedef struct MOVAtoms {
9415  FFIOContext b;
9416  uint32_t type;
9417  int64_t size;
9418  uint8_t *data;
9419  } MOVAtoms;
9420  MOVAtoms *atoms = NULL;
9421  MOVAtom a;
9422  unsigned count;
9423  int nb_atoms = 0;
9424  int version, flags;
9425  int ret;
9426 
9427  a.size = avio_rb32(pb);
9428  a.type = avio_rl32(pb);
9429 
9430  if (a.size < 8 || a.type != MKTAG('i','p','c','o'))
9431  return AVERROR_INVALIDDATA;
9432 
9433  a.size -= 8;
9434  while (a.size >= 8) {
9435  MOVAtoms *ref = av_dynarray2_add((void**)&atoms, &nb_atoms, sizeof(MOVAtoms), NULL);
9436  if (!ref) {
9437  ret = AVERROR(ENOMEM);
9438  goto fail;
9439  }
9440  ref->data = NULL;
9441  ref->size = avio_rb32(pb);
9442  ref->type = avio_rl32(pb);
9443  if (ref->size > a.size || ref->size < 8)
9444  break;
9445  ref->data = av_malloc(ref->size);
9446  if (!ref->data) {
9448  goto fail;
9449  }
9450  av_log(c->fc, AV_LOG_TRACE, "ipco: index %d, box type %s\n", nb_atoms, av_fourcc2str(ref->type));
9451  avio_seek(pb, -8, SEEK_CUR);
9452  if (avio_read(pb, ref->data, ref->size) != ref->size) {
9454  goto fail;
9455  }
9456  ffio_init_read_context(&ref->b, ref->data, ref->size);
9457  a.size -= ref->size;
9458  }
9459 
9460  if (a.size) {
9462  goto fail;
9463  }
9464 
9465  a.size = avio_rb32(pb);
9466  a.type = avio_rl32(pb);
9467 
9468  if (a.size < 8 || a.type != MKTAG('i','p','m','a')) {
9470  goto fail;
9471  }
9472 
9473  version = avio_r8(pb);
9474  flags = avio_rb24(pb);
9475  count = avio_rb32(pb);
9476 
9477  for (int i = 0; i < count; i++) {
9478  int item_id = version ? avio_rb32(pb) : avio_rb16(pb);
9479  int assoc_count = avio_r8(pb);
9480 
9481  if (avio_feof(pb)) {
9483  goto fail;
9484  }
9485 
9486  for (int j = 0; j < assoc_count; j++) {
9487  MOVAtoms *ref;
9488  int index = avio_r8(pb) & 0x7f;
9489  if (flags & 1) {
9490  index <<= 8;
9491  index |= avio_r8(pb);
9492  }
9493  if (index > nb_atoms || index <= 0) {
9495  goto fail;
9496  }
9497  ref = &atoms[--index];
9498 
9499  av_log(c->fc, AV_LOG_TRACE, "ipma: property_index %d, item_id %d, item_type %s\n",
9500  index + 1, item_id, av_fourcc2str(ref->type));
9501 
9502  c->cur_item_id = item_id;
9503 
9504  ret = mov_read_default(c, &ref->b.pub,
9505  (MOVAtom) { .size = ref->size,
9506  .type = MKTAG('i','p','c','o') });
9507  if (ret < 0)
9508  goto fail;
9509  ffio_init_read_context(&ref->b, ref->data, ref->size);
9510  }
9511  }
9512 
9513  ret = 0;
9514 fail:
9515  c->cur_item_id = -1;
9516  for (int i = 0; i < nb_atoms; i++)
9517  av_free(atoms[i].data);
9518  av_free(atoms);
9519 
9520  return ret;
9521 }
9522 
9524 { MKTAG('A','C','L','R'), mov_read_aclr },
9525 { MKTAG('A','P','R','G'), mov_read_avid },
9526 { MKTAG('A','A','L','P'), mov_read_avid },
9527 { MKTAG('A','R','E','S'), mov_read_ares },
9528 { MKTAG('a','v','s','s'), mov_read_avss },
9529 { MKTAG('a','v','1','C'), mov_read_glbl },
9530 { MKTAG('c','h','p','l'), mov_read_chpl },
9531 { MKTAG('c','o','6','4'), mov_read_stco },
9532 { MKTAG('c','o','l','r'), mov_read_colr },
9533 { MKTAG('c','t','t','s'), mov_read_ctts }, /* composition time to sample */
9534 { MKTAG('d','i','n','f'), mov_read_default },
9535 { MKTAG('D','p','x','E'), mov_read_dpxe },
9536 { MKTAG('d','r','e','f'), mov_read_dref },
9537 { MKTAG('e','d','t','s'), mov_read_default },
9538 { MKTAG('e','l','s','t'), mov_read_elst },
9539 { MKTAG('e','n','d','a'), mov_read_enda },
9540 { MKTAG('f','i','e','l'), mov_read_fiel },
9541 { MKTAG('a','d','r','m'), mov_read_adrm },
9542 { MKTAG('f','t','y','p'), mov_read_ftyp },
9543 { MKTAG('g','l','b','l'), mov_read_glbl },
9544 { MKTAG('h','d','l','r'), mov_read_hdlr },
9545 { MKTAG('i','l','s','t'), mov_read_ilst },
9546 { MKTAG('j','p','2','h'), mov_read_jp2h },
9547 { MKTAG('m','d','a','t'), mov_read_mdat },
9548 { MKTAG('m','d','h','d'), mov_read_mdhd },
9549 { MKTAG('m','d','i','a'), mov_read_default },
9550 { MKTAG('m','e','t','a'), mov_read_meta },
9551 { MKTAG('m','i','n','f'), mov_read_default },
9552 { MKTAG('m','o','o','f'), mov_read_moof },
9553 { MKTAG('m','o','o','v'), mov_read_moov },
9554 { MKTAG('m','v','e','x'), mov_read_default },
9555 { MKTAG('m','v','h','d'), mov_read_mvhd },
9556 { MKTAG('S','M','I',' '), mov_read_svq3 },
9557 { MKTAG('a','l','a','c'), mov_read_alac }, /* alac specific atom */
9558 { MKTAG('a','v','c','C'), mov_read_glbl },
9559 { MKTAG('p','a','s','p'), mov_read_pasp },
9560 { MKTAG('c','l','a','p'), mov_read_clap },
9561 { MKTAG('s','b','a','s'), mov_read_sbas },
9562 { MKTAG('s','i','d','x'), mov_read_sidx },
9563 { MKTAG('s','t','b','l'), mov_read_default },
9564 { MKTAG('s','t','c','o'), mov_read_stco },
9565 { MKTAG('s','t','p','s'), mov_read_stps },
9566 { MKTAG('s','t','r','f'), mov_read_strf },
9567 { MKTAG('s','t','s','c'), mov_read_stsc },
9568 { MKTAG('s','t','s','d'), mov_read_stsd }, /* sample description */
9569 { MKTAG('s','t','s','s'), mov_read_stss }, /* sync sample */
9570 { MKTAG('s','t','s','z'), mov_read_stsz }, /* sample size */
9571 { MKTAG('s','t','t','s'), mov_read_stts },
9572 { MKTAG('s','t','z','2'), mov_read_stsz }, /* compact sample size */
9573 { MKTAG('s','d','t','p'), mov_read_sdtp }, /* independent and disposable samples */
9574 { MKTAG('t','k','h','d'), mov_read_tkhd }, /* track header */
9575 { MKTAG('t','f','d','t'), mov_read_tfdt },
9576 { MKTAG('t','f','h','d'), mov_read_tfhd }, /* track fragment header */
9577 { MKTAG('t','r','a','k'), mov_read_trak },
9578 { MKTAG('t','r','a','f'), mov_read_default },
9579 { MKTAG('t','r','e','f'), mov_read_default },
9580 { MKTAG('t','m','c','d'), mov_read_tmcd },
9581 { MKTAG('c','h','a','p'), mov_read_chap },
9582 { MKTAG('t','r','e','x'), mov_read_trex },
9583 { MKTAG('t','r','u','n'), mov_read_trun },
9584 { MKTAG('u','d','t','a'), mov_read_default },
9585 { MKTAG('w','a','v','e'), mov_read_wave },
9586 { MKTAG('e','s','d','s'), mov_read_esds },
9587 { MKTAG('d','a','c','3'), mov_read_dac3 }, /* AC-3 info */
9588 { MKTAG('d','e','c','3'), mov_read_dec3 }, /* EAC-3 info */
9589 { MKTAG('d','d','t','s'), mov_read_ddts }, /* DTS audio descriptor */
9590 { MKTAG('w','i','d','e'), mov_read_wide }, /* place holder */
9591 { MKTAG('w','f','e','x'), mov_read_wfex },
9592 { MKTAG('c','m','o','v'), mov_read_cmov },
9593 { MKTAG('c','h','a','n'), mov_read_chan }, /* channel layout from quicktime */
9594 { MKTAG('c','h','n','l'), mov_read_chnl }, /* channel layout from ISO-14496-12 */
9595 { MKTAG('d','v','c','1'), mov_read_dvc1 },
9596 { MKTAG('s','g','p','d'), mov_read_sgpd },
9597 { MKTAG('s','b','g','p'), mov_read_sbgp },
9598 { MKTAG('h','v','c','C'), mov_read_glbl },
9599 { MKTAG('v','v','c','C'), mov_read_glbl },
9600 { MKTAG('u','u','i','d'), mov_read_uuid },
9601 { MKTAG('C','i','n', 0x8e), mov_read_targa_y216 },
9602 { MKTAG('f','r','e','e'), mov_read_free },
9603 { MKTAG('-','-','-','-'), mov_read_custom },
9604 { MKTAG('s','i','n','f'), mov_read_default },
9605 { MKTAG('f','r','m','a'), mov_read_frma },
9606 { MKTAG('s','e','n','c'), mov_read_senc },
9607 { MKTAG('s','a','i','z'), mov_read_saiz },
9608 { MKTAG('s','a','i','o'), mov_read_saio },
9609 { MKTAG('p','s','s','h'), mov_read_pssh },
9610 { MKTAG('s','c','h','m'), mov_read_schm },
9611 { MKTAG('s','c','h','i'), mov_read_default },
9612 { MKTAG('t','e','n','c'), mov_read_tenc },
9613 { MKTAG('d','f','L','a'), mov_read_dfla },
9614 { MKTAG('s','t','3','d'), mov_read_st3d }, /* stereoscopic 3D video box */
9615 { MKTAG('s','v','3','d'), mov_read_sv3d }, /* spherical video box */
9616 { MKTAG('v','e','x','u'), mov_read_vexu }, /* video extension usage */
9617 { MKTAG('h','f','o','v'), mov_read_hfov },
9618 { MKTAG('d','O','p','s'), mov_read_dops },
9619 { MKTAG('d','m','l','p'), mov_read_dmlp },
9620 { MKTAG('S','m','D','m'), mov_read_smdm },
9621 { MKTAG('C','o','L','L'), mov_read_coll },
9622 { MKTAG('v','p','c','C'), mov_read_vpcc },
9623 { MKTAG('m','d','c','v'), mov_read_mdcv },
9624 { MKTAG('c','l','l','i'), mov_read_clli },
9625 { MKTAG('d','v','c','C'), mov_read_dvcc_dvvc },
9626 { MKTAG('d','v','v','C'), mov_read_dvcc_dvvc },
9627 { MKTAG('d','v','w','C'), mov_read_dvcc_dvvc },
9628 { MKTAG('k','i','n','d'), mov_read_kind },
9629 { MKTAG('S','A','3','D'), mov_read_SA3D }, /* ambisonic audio box */
9630 { MKTAG('S','A','N','D'), mov_read_SAND }, /* non diegetic audio box */
9631 { MKTAG('i','l','o','c'), mov_read_iloc },
9632 { MKTAG('p','c','m','C'), mov_read_pcmc }, /* PCM configuration box */
9633 { MKTAG('p','i','t','m'), mov_read_pitm },
9634 { MKTAG('e','v','c','C'), mov_read_glbl },
9635 { MKTAG('i','d','a','t'), mov_read_idat },
9636 { MKTAG('i','m','i','r'), mov_read_imir },
9637 { MKTAG('i','r','e','f'), mov_read_iref },
9638 { MKTAG('i','s','p','e'), mov_read_ispe },
9639 { MKTAG('i','r','o','t'), mov_read_irot },
9640 { MKTAG('i','p','r','p'), mov_read_iprp },
9641 { MKTAG('i','i','n','f'), mov_read_iinf },
9642 { MKTAG('a','m','v','e'), mov_read_amve }, /* ambient viewing environment box */
9643 { MKTAG('l','h','v','C'), mov_read_lhvc },
9644 { MKTAG('l','v','c','C'), mov_read_glbl },
9645 { MKTAG('a','p','v','C'), mov_read_glbl },
9646 #if CONFIG_IAMFDEC
9647 { MKTAG('i','a','c','b'), mov_read_iacb },
9648 #endif
9649 { MKTAG('s','r','a','t'), mov_read_srat },
9650 { 0, NULL }
9651 };
9652 
9654 {
9655  int64_t total_size = 0;
9656  MOVAtom a;
9657  int i;
9658 
9659  if (c->atom_depth > 10) {
9660  av_log(c->fc, AV_LOG_ERROR, "Atoms too deeply nested\n");
9661  return AVERROR_INVALIDDATA;
9662  }
9663  c->atom_depth ++;
9664 
9665  if (atom.size < 0)
9666  atom.size = INT64_MAX;
9667  while (total_size <= atom.size - 8) {
9668  int (*parse)(MOVContext*, AVIOContext*, MOVAtom) = NULL;
9669  a.size = avio_rb32(pb);
9670  a.type = avio_rl32(pb);
9671  if (avio_feof(pb))
9672  break;
9673  if (((a.type == MKTAG('f','r','e','e') && c->moov_retry) ||
9674  a.type == MKTAG('h','o','o','v')) &&
9675  a.size >= 8 &&
9676  c->fc->strict_std_compliance < FF_COMPLIANCE_STRICT) {
9677  uint32_t type;
9678  avio_skip(pb, 4);
9679  type = avio_rl32(pb);
9680  if (avio_feof(pb))
9681  break;
9682  avio_seek(pb, -8, SEEK_CUR);
9683  if (type == MKTAG('m','v','h','d') ||
9684  type == MKTAG('c','m','o','v')) {
9685  av_log(c->fc, AV_LOG_ERROR, "Detected moov in a free or hoov atom.\n");
9686  a.type = MKTAG('m','o','o','v');
9687  }
9688  }
9689  if (atom.type != MKTAG('r','o','o','t') &&
9690  atom.type != MKTAG('m','o','o','v')) {
9691  if (a.type == MKTAG('t','r','a','k') ||
9692  a.type == MKTAG('m','d','a','t')) {
9693  av_log(c->fc, AV_LOG_ERROR, "Broken file, trak/mdat not at top-level\n");
9694  avio_skip(pb, -8);
9695  c->atom_depth --;
9696  return 0;
9697  }
9698  }
9699  total_size += 8;
9700  if (a.size == 1 && total_size + 8 <= atom.size) { /* 64 bit extended size */
9701  a.size = avio_rb64(pb) - 8;
9702  total_size += 8;
9703  }
9704  av_log(c->fc, AV_LOG_TRACE, "type:'%s' parent:'%s' sz: %"PRId64" %"PRId64" %"PRId64"\n",
9705  av_fourcc2str(a.type), av_fourcc2str(atom.type), a.size, total_size, atom.size);
9706  if (a.size == 0) {
9707  a.size = atom.size - total_size + 8;
9708  }
9709  if (a.size < 0)
9710  break;
9711  a.size -= 8;
9712  if (a.size < 0)
9713  break;
9714  a.size = FFMIN(a.size, atom.size - total_size);
9715 
9716  for (i = 0; mov_default_parse_table[i].type; i++)
9717  if (mov_default_parse_table[i].type == a.type) {
9719  break;
9720  }
9721 
9722  // container is user data
9723  if (!parse && (atom.type == MKTAG('u','d','t','a') ||
9724  atom.type == MKTAG('i','l','s','t')))
9726 
9727  // Supports parsing the QuickTime Metadata Keys.
9728  // https://developer.apple.com/library/mac/documentation/QuickTime/QTFF/Metadata/Metadata.html
9729  if (!parse && c->found_hdlr_mdta &&
9730  atom.type == MKTAG('m','e','t','a') &&
9731  a.type == MKTAG('k','e','y','s') &&
9732  c->meta_keys_count == 0) {
9733  parse = mov_read_keys;
9734  }
9735 
9736  if (!parse) { /* skip leaf atoms data */
9737  avio_skip(pb, a.size);
9738  } else {
9739  int64_t start_pos = avio_tell(pb);
9740  int64_t left;
9741  int err = parse(c, pb, a);
9742  if (err < 0) {
9743  c->atom_depth --;
9744  return err;
9745  }
9746  if (c->found_moov && c->found_mdat && a.size <= INT64_MAX - start_pos &&
9747  ((!(pb->seekable & AVIO_SEEKABLE_NORMAL) || c->fc->flags & AVFMT_FLAG_IGNIDX || c->frag_index.complete) ||
9748  start_pos + a.size == avio_size(pb))) {
9749  if (!(pb->seekable & AVIO_SEEKABLE_NORMAL) || c->fc->flags & AVFMT_FLAG_IGNIDX || c->frag_index.complete)
9750  c->next_root_atom = start_pos + a.size;
9751  c->atom_depth --;
9752  return 0;
9753  }
9754  left = a.size - avio_tell(pb) + start_pos;
9755  if (left > 0) /* skip garbage at atom end */
9756  avio_skip(pb, left);
9757  else if (left < 0) {
9758  av_log(c->fc, AV_LOG_WARNING,
9759  "overread end of atom '%s' by %"PRId64" bytes\n",
9760  av_fourcc2str(a.type), -left);
9761  avio_seek(pb, left, SEEK_CUR);
9762  }
9763  }
9764 
9765  total_size += a.size;
9766  }
9767 
9768  if (total_size < atom.size && atom.size < 0x7ffff)
9769  avio_skip(pb, atom.size - total_size);
9770 
9771  c->atom_depth --;
9772  return 0;
9773 }
9774 
9775 static int mov_probe(const AVProbeData *p)
9776 {
9777  int64_t offset;
9778  uint32_t tag;
9779  int score = 0;
9780  int moov_offset = -1;
9781 
9782  /* check file header */
9783  offset = 0;
9784  for (;;) {
9785  int64_t size;
9786  int minsize = 8;
9787  /* ignore invalid offset */
9788  if ((offset + 8ULL) > (unsigned int)p->buf_size)
9789  break;
9790  size = AV_RB32(p->buf + offset);
9791  if (size == 1 && offset + 16 <= (unsigned int)p->buf_size) {
9792  size = AV_RB64(p->buf+offset + 8);
9793  minsize = 16;
9794  } else if (size == 0) {
9795  size = p->buf_size - offset;
9796  }
9797  if (size < minsize) {
9798  offset += 4;
9799  continue;
9800  }
9801  tag = AV_RL32(p->buf + offset + 4);
9802  switch(tag) {
9803  /* check for obvious tags */
9804  case MKTAG('m','o','o','v'):
9805  moov_offset = offset + 4;
9807  case MKTAG('m','d','a','t'):
9808  case MKTAG('p','n','o','t'): /* detect movs with preview pics like ew.mov and april.mov */
9809  case MKTAG('u','d','t','a'): /* Packet Video PVAuthor adds this and a lot of more junk */
9810  case MKTAG('f','t','y','p'):
9811  if (tag == MKTAG('f','t','y','p') &&
9812  ( AV_RL32(p->buf + offset + 8) == MKTAG('j','p','2',' ')
9813  || AV_RL32(p->buf + offset + 8) == MKTAG('j','p','x',' ')
9814  || AV_RL32(p->buf + offset + 8) == MKTAG('j','x','l',' ')
9815  )) {
9816  score = FFMAX(score, 5);
9817  } else {
9818  score = AVPROBE_SCORE_MAX;
9819  }
9820  break;
9821  /* those are more common words, so rate then a bit less */
9822  case MKTAG('e','d','i','w'): /* xdcam files have reverted first tags */
9823  case MKTAG('w','i','d','e'):
9824  case MKTAG('f','r','e','e'):
9825  case MKTAG('j','u','n','k'):
9826  case MKTAG('p','i','c','t'):
9827  score = FFMAX(score, AVPROBE_SCORE_MAX - 5);
9828  break;
9829  case MKTAG(0x82,0x82,0x7f,0x7d):
9830  score = FFMAX(score, AVPROBE_SCORE_EXTENSION - 5);
9831  break;
9832  case MKTAG('s','k','i','p'):
9833  case MKTAG('u','u','i','d'):
9834  case MKTAG('p','r','f','l'):
9835  /* if we only find those cause probedata is too small at least rate them */
9836  score = FFMAX(score, AVPROBE_SCORE_EXTENSION);
9837  break;
9838  }
9839  if (size > INT64_MAX - offset)
9840  break;
9841  offset += size;
9842  }
9843  if (score > AVPROBE_SCORE_MAX - 50 && moov_offset != -1) {
9844  /* moov atom in the header - we should make sure that this is not a
9845  * MOV-packed MPEG-PS */
9846  offset = moov_offset;
9847 
9848  while (offset < (p->buf_size - 16)) { /* Sufficient space */
9849  /* We found an actual hdlr atom */
9850  if (AV_RL32(p->buf + offset ) == MKTAG('h','d','l','r') &&
9851  AV_RL32(p->buf + offset + 8) == MKTAG('m','h','l','r') &&
9852  AV_RL32(p->buf + offset + 12) == MKTAG('M','P','E','G')) {
9853  av_log(NULL, AV_LOG_WARNING, "Found media data tag MPEG indicating this is a MOV-packed MPEG-PS.\n");
9854  /* We found a media handler reference atom describing an
9855  * MPEG-PS-in-MOV, return a
9856  * low score to force expanding the probe window until
9857  * mpegps_probe finds what it needs */
9858  return 5;
9859  } else {
9860  /* Keep looking */
9861  offset += 2;
9862  }
9863  }
9864  }
9865 
9866  return score;
9867 }
9868 
9869 // must be done after parsing all trak because there's no order requirement
9871 {
9872  MOVContext *mov = s->priv_data;
9873  MOVStreamContext *sc;
9874  int64_t cur_pos;
9875  int i, j;
9876  int chapter_track;
9877 
9878  for (j = 0; j < mov->nb_chapter_tracks; j++) {
9879  AVStream *st = NULL;
9880  FFStream *sti = NULL;
9881  chapter_track = mov->chapter_tracks[j];
9882  for (i = 0; i < s->nb_streams; i++) {
9883  sc = mov->fc->streams[i]->priv_data;
9884  if (sc->id == chapter_track) {
9885  st = s->streams[i];
9886  break;
9887  }
9888  }
9889  if (!st) {
9890  av_log(s, AV_LOG_ERROR, "Referenced QT chapter track not found\n");
9891  continue;
9892  }
9893  sti = ffstream(st);
9894 
9895  sc = st->priv_data;
9896  cur_pos = avio_tell(sc->pb);
9897 
9898  if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
9900  if (!st->attached_pic.data && sti->nb_index_entries) {
9901  // Retrieve the first frame, if possible
9902  AVIndexEntry *sample = &sti->index_entries[0];
9903  if (avio_seek(sc->pb, sample->pos, SEEK_SET) != sample->pos) {
9904  av_log(s, AV_LOG_ERROR, "Failed to retrieve first frame\n");
9905  goto finish;
9906  }
9907 
9908  if (ff_add_attached_pic(s, st, sc->pb, NULL, sample->size) < 0)
9909  goto finish;
9910  }
9911  } else {
9914  st->discard = AVDISCARD_ALL;
9915  for (int i = 0; i < sti->nb_index_entries; i++) {
9916  AVIndexEntry *sample = &sti->index_entries[i];
9917  int64_t end = i+1 < sti->nb_index_entries ? sti->index_entries[i+1].timestamp : st->duration;
9918  uint8_t *title;
9919  uint16_t ch;
9920  int len, title_len;
9921 
9922  if (end < sample->timestamp) {
9923  av_log(s, AV_LOG_WARNING, "ignoring stream duration which is shorter than chapters\n");
9924  end = AV_NOPTS_VALUE;
9925  }
9926 
9927  if (avio_seek(sc->pb, sample->pos, SEEK_SET) != sample->pos) {
9928  av_log(s, AV_LOG_ERROR, "Chapter %d not found in file\n", i);
9929  goto finish;
9930  }
9931 
9932  // the first two bytes are the length of the title
9933  len = avio_rb16(sc->pb);
9934  if (len > sample->size-2)
9935  continue;
9936  title_len = 2*len + 1;
9937  if (!(title = av_mallocz(title_len)))
9938  goto finish;
9939 
9940  // The samples could theoretically be in any encoding if there's an encd
9941  // atom following, but in practice are only utf-8 or utf-16, distinguished
9942  // instead by the presence of a BOM
9943  if (!len) {
9944  title[0] = 0;
9945  } else {
9946  ch = avio_rb16(sc->pb);
9947  if (ch == 0xfeff)
9948  avio_get_str16be(sc->pb, len, title, title_len);
9949  else if (ch == 0xfffe)
9950  avio_get_str16le(sc->pb, len, title, title_len);
9951  else {
9952  AV_WB16(title, ch);
9953  if (len == 1 || len == 2)
9954  title[len] = 0;
9955  else
9956  avio_get_str(sc->pb, INT_MAX, title + 2, len - 1);
9957  }
9958  }
9959 
9960  avpriv_new_chapter(s, i, st->time_base, sample->timestamp, end, title);
9961  av_freep(&title);
9962  }
9963  }
9964 finish:
9965  avio_seek(sc->pb, cur_pos, SEEK_SET);
9966  }
9967 }
9968 
9970  int64_t value, int flags)
9971 {
9972  AVTimecode tc;
9973  char buf[AV_TIMECODE_STR_SIZE];
9974  AVRational rate = st->avg_frame_rate;
9975  int ret = av_timecode_init(&tc, rate, flags, 0, s);
9976  if (ret < 0)
9977  return ret;
9978  av_dict_set(&st->metadata, "timecode",
9979  av_timecode_make_string(&tc, buf, value), 0);
9980  return 0;
9981 }
9982 
9984 {
9985  MOVStreamContext *sc = st->priv_data;
9986  FFStream *const sti = ffstream(st);
9987  char buf[AV_TIMECODE_STR_SIZE];
9988  int64_t cur_pos = avio_tell(sc->pb);
9989  int hh, mm, ss, ff, drop;
9990 
9991  if (!sti->nb_index_entries)
9992  return -1;
9993 
9994  avio_seek(sc->pb, sti->index_entries->pos, SEEK_SET);
9995  avio_skip(s->pb, 13);
9996  hh = avio_r8(s->pb);
9997  mm = avio_r8(s->pb);
9998  ss = avio_r8(s->pb);
9999  drop = avio_r8(s->pb);
10000  ff = avio_r8(s->pb);
10001  snprintf(buf, AV_TIMECODE_STR_SIZE, "%02d:%02d:%02d%c%02d",
10002  hh, mm, ss, drop ? ';' : ':', ff);
10003  av_dict_set(&st->metadata, "timecode", buf, 0);
10004 
10005  avio_seek(sc->pb, cur_pos, SEEK_SET);
10006  return 0;
10007 }
10008 
10010 {
10011  MOVStreamContext *sc = st->priv_data;
10012  FFStream *const sti = ffstream(st);
10013  int flags = 0;
10014  int64_t cur_pos = avio_tell(sc->pb);
10015  int64_t value;
10016  AVRational tc_rate = st->avg_frame_rate;
10017  int tmcd_nb_frames = sc->tmcd_nb_frames;
10018  int rounded_tc_rate;
10019 
10020  if (!sti->nb_index_entries)
10021  return -1;
10022 
10023  if (!tc_rate.num || !tc_rate.den || !tmcd_nb_frames)
10024  return -1;
10025 
10026  avio_seek(sc->pb, sti->index_entries->pos, SEEK_SET);
10027  value = avio_rb32(s->pb);
10028 
10029  if (sc->tmcd_flags & 0x0001) flags |= AV_TIMECODE_FLAG_DROPFRAME;
10030  if (sc->tmcd_flags & 0x0002) flags |= AV_TIMECODE_FLAG_24HOURSMAX;
10031  if (sc->tmcd_flags & 0x0004) flags |= AV_TIMECODE_FLAG_ALLOWNEGATIVE;
10032 
10033  /* Assume Counter flag is set to 1 in tmcd track (even though it is likely
10034  * not the case) and thus assume "frame number format" instead of QT one.
10035  * No sample with tmcd track can be found with a QT timecode at the moment,
10036  * despite what the tmcd track "suggests" (Counter flag set to 0 means QT
10037  * format). */
10038 
10039  /* 60 fps content have tmcd_nb_frames set to 30 but tc_rate set to 60, so
10040  * we multiply the frame number with the quotient.
10041  * See tickets #9492, #9710. */
10042  rounded_tc_rate = (tc_rate.num + tc_rate.den / 2LL) / tc_rate.den;
10043  /* Work around files where tmcd_nb_frames is rounded down from frame rate
10044  * instead of up. See ticket #5978. */
10045  if (tmcd_nb_frames == tc_rate.num / tc_rate.den &&
10046  s->strict_std_compliance < FF_COMPLIANCE_STRICT)
10047  tmcd_nb_frames = rounded_tc_rate;
10048  value = av_rescale(value, rounded_tc_rate, tmcd_nb_frames);
10049 
10051 
10052  avio_seek(sc->pb, cur_pos, SEEK_SET);
10053  return 0;
10054 }
10055 
10057  int i;
10058  if (!index || !*index) return;
10059  for (i = 0; i < (*index)->nb_encrypted_samples; i++) {
10060  av_encryption_info_free((*index)->encrypted_samples[i]);
10061  }
10062  av_freep(&(*index)->encrypted_samples);
10063  av_freep(&(*index)->auxiliary_info_sizes);
10064  av_freep(&(*index)->auxiliary_offsets);
10065  av_freep(index);
10066 }
10067 
10069 {
10070  MOVStreamContext *sc = st->priv_data;
10071 
10072  if (!sc || --sc->refcount) {
10073  st->priv_data = NULL;
10074  return;
10075  }
10076 
10077  av_freep(&sc->tts_data);
10078  for (int i = 0; i < sc->drefs_count; i++) {
10079  av_freep(&sc->drefs[i].path);
10080  av_freep(&sc->drefs[i].dir);
10081  }
10082  av_freep(&sc->drefs);
10083 
10084  sc->drefs_count = 0;
10085 
10086  if (!sc->pb_is_copied)
10087  ff_format_io_close(s, &sc->pb);
10088 
10089  sc->pb = NULL;
10090  av_freep(&sc->chunk_offsets);
10091  av_freep(&sc->stsc_data);
10092  av_freep(&sc->sample_sizes);
10093  av_freep(&sc->keyframes);
10094  av_freep(&sc->ctts_data);
10095  av_freep(&sc->stts_data);
10096  av_freep(&sc->sdtp_data);
10097  av_freep(&sc->stps_data);
10098  av_freep(&sc->elst_data);
10099  av_freep(&sc->rap_group);
10100  av_freep(&sc->sync_group);
10101  av_freep(&sc->sgpd_sync);
10102  av_freep(&sc->sample_offsets);
10103  av_freep(&sc->open_key_samples);
10104  av_freep(&sc->display_matrix);
10105  av_freep(&sc->index_ranges);
10106 
10107  if (sc->extradata)
10108  for (int i = 0; i < sc->stsd_count; i++)
10109  av_free(sc->extradata[i]);
10110  av_freep(&sc->extradata);
10111  av_freep(&sc->extradata_size);
10112 
10116 
10117  av_freep(&sc->stereo3d);
10118  av_freep(&sc->spherical);
10119  av_freep(&sc->mastering);
10120  av_freep(&sc->coll);
10121  av_freep(&sc->ambient);
10122 
10123 #if CONFIG_IAMFDEC
10124  if (sc->iamf)
10126 #endif
10127  av_freep(&sc->iamf);
10128 }
10129 
10131 {
10132  MOVContext *mov = s->priv_data;
10133  int i, j;
10134 
10135  for (i = 0; i < s->nb_streams; i++) {
10136  AVStream *st = s->streams[i];
10137 
10139  }
10140 
10141  av_freep(&mov->dv_demux);
10143  mov->dv_fctx = NULL;
10144 
10145  if (mov->meta_keys) {
10146  for (i = 1; i < mov->meta_keys_count; i++) {
10147  av_freep(&mov->meta_keys[i]);
10148  }
10149  av_freep(&mov->meta_keys);
10150  }
10151 
10152  av_freep(&mov->trex_data);
10153  av_freep(&mov->bitrates);
10154 
10155  for (i = 0; i < mov->frag_index.nb_items; i++) {
10157  for (j = 0; j < mov->frag_index.item[i].nb_stream_info; j++) {
10158  mov_free_encryption_index(&frag[j].encryption_index);
10159  }
10161  }
10162  av_freep(&mov->frag_index.item);
10163 
10164  av_freep(&mov->aes_decrypt);
10165  av_freep(&mov->chapter_tracks);
10166  for (i = 0; i < mov->nb_heif_item; i++) {
10167  if (!mov->heif_item[i])
10168  continue;
10169  av_freep(&mov->heif_item[i]->name);
10170  av_freep(&mov->heif_item[i]->iref_list);
10171  av_freep(&mov->heif_item[i]->icc_profile);
10172  av_freep(&mov->heif_item[i]);
10173  }
10174  av_freep(&mov->heif_item);
10175  for (i = 0; i < mov->nb_heif_grid; i++) {
10176  av_freep(&mov->heif_grid[i].tile_id_list);
10179  }
10180  av_freep(&mov->heif_grid);
10181 
10182  return 0;
10183 }
10184 
10185 static int tmcd_is_referenced(AVFormatContext *s, int tmcd_id)
10186 {
10187  int i;
10188 
10189  for (i = 0; i < s->nb_streams; i++) {
10190  AVStream *st = s->streams[i];
10191  MOVStreamContext *sc = st->priv_data;
10192 
10193  if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO &&
10194  sc->timecode_track == tmcd_id)
10195  return 1;
10196  }
10197  return 0;
10198 }
10199 
10200 /* look for a tmcd track not referenced by any video track, and export it globally */
10202 {
10203  int i;
10204 
10205  for (i = 0; i < s->nb_streams; i++) {
10206  AVStream *st = s->streams[i];
10207 
10208  if (st->codecpar->codec_tag == MKTAG('t','m','c','d') &&
10209  !tmcd_is_referenced(s, i + 1)) {
10210  AVDictionaryEntry *tcr = av_dict_get(st->metadata, "timecode", NULL, 0);
10211  if (tcr) {
10212  av_dict_set(&s->metadata, "timecode", tcr->value, 0);
10213  break;
10214  }
10215  }
10216  }
10217 }
10218 
10219 static int read_tfra(MOVContext *mov, AVIOContext *f)
10220 {
10221  int version, fieldlength, i, j;
10222  int64_t pos = avio_tell(f);
10223  uint32_t size = avio_rb32(f);
10224  unsigned track_id, item_count;
10225 
10226  if (avio_rb32(f) != MKBETAG('t', 'f', 'r', 'a')) {
10227  return 1;
10228  }
10229  av_log(mov->fc, AV_LOG_VERBOSE, "found tfra\n");
10230 
10231  version = avio_r8(f);
10232  avio_rb24(f);
10233  track_id = avio_rb32(f);
10234  fieldlength = avio_rb32(f);
10235  item_count = avio_rb32(f);
10236  for (i = 0; i < item_count; i++) {
10237  int64_t time, offset;
10238  int index;
10239  MOVFragmentStreamInfo * frag_stream_info;
10240 
10241  if (avio_feof(f)) {
10242  return AVERROR_INVALIDDATA;
10243  }
10244 
10245  if (version == 1) {
10246  time = avio_rb64(f);
10247  offset = avio_rb64(f);
10248  } else {
10249  time = avio_rb32(f);
10250  offset = avio_rb32(f);
10251  }
10252 
10253  // The first sample of each stream in a fragment is always a random
10254  // access sample. So it's entry in the tfra can be used as the
10255  // initial PTS of the fragment.
10256  index = update_frag_index(mov, offset);
10257  frag_stream_info = get_frag_stream_info(&mov->frag_index, index, track_id);
10258  if (frag_stream_info &&
10259  frag_stream_info->first_tfra_pts == AV_NOPTS_VALUE)
10260  frag_stream_info->first_tfra_pts = time;
10261 
10262  for (j = 0; j < ((fieldlength >> 4) & 3) + 1; j++)
10263  avio_r8(f);
10264  for (j = 0; j < ((fieldlength >> 2) & 3) + 1; j++)
10265  avio_r8(f);
10266  for (j = 0; j < ((fieldlength >> 0) & 3) + 1; j++)
10267  avio_r8(f);
10268  }
10269 
10270  avio_seek(f, pos + size, SEEK_SET);
10271  return 0;
10272 }
10273 
10275 {
10276  int64_t stream_size = avio_size(f);
10277  int64_t original_pos = avio_tell(f);
10278  int64_t seek_ret;
10279  int ret = -1;
10280  if ((seek_ret = avio_seek(f, stream_size - 4, SEEK_SET)) < 0) {
10281  ret = seek_ret;
10282  goto fail;
10283  }
10284  c->mfra_size = avio_rb32(f);
10285  c->have_read_mfra_size = 1;
10286  if (!c->mfra_size || c->mfra_size > stream_size) {
10287  av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (unreasonable size)\n");
10288  goto fail;
10289  }
10290  if ((seek_ret = avio_seek(f, -((int64_t) c->mfra_size), SEEK_CUR)) < 0) {
10291  ret = seek_ret;
10292  goto fail;
10293  }
10294  if (avio_rb32(f) != c->mfra_size) {
10295  av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (size mismatch)\n");
10296  goto fail;
10297  }
10298  if (avio_rb32(f) != MKBETAG('m', 'f', 'r', 'a')) {
10299  av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (tag mismatch)\n");
10300  goto fail;
10301  }
10302  av_log(c->fc, AV_LOG_VERBOSE, "stream has mfra\n");
10303  do {
10304  ret = read_tfra(c, f);
10305  if (ret < 0)
10306  goto fail;
10307  } while (!ret);
10308  ret = 0;
10309  c->frag_index.complete = 1;
10310 fail:
10311  seek_ret = avio_seek(f, original_pos, SEEK_SET);
10312  if (seek_ret < 0) {
10313  av_log(c->fc, AV_LOG_ERROR,
10314  "failed to seek back after looking for mfra\n");
10315  ret = seek_ret;
10316  }
10317  return ret;
10318 }
10319 
10320 static int set_icc_profile_from_item(AVPacketSideData **coded_side_data, int *nb_coded_side_data,
10321  const HEIFItem *item)
10322 {
10323  AVPacketSideData *sd = av_packet_side_data_new(coded_side_data, nb_coded_side_data,
10325  item->icc_profile_size, 0);
10326  if (!sd)
10327  return AVERROR(ENOMEM);
10328 
10329  memcpy(sd->data, item->icc_profile, item->icc_profile_size);
10330 
10331  return 0;
10332 }
10333 
10334 static int set_display_matrix_from_item(AVPacketSideData **coded_side_data, int *nb_coded_side_data,
10335  const HEIFItem *item)
10336 {
10337  int32_t *matrix;
10338  AVPacketSideData *sd = av_packet_side_data_new(coded_side_data,
10339  nb_coded_side_data,
10341  9 * sizeof(*matrix), 0);
10342  if (!sd)
10343  return AVERROR(ENOMEM);
10344 
10345  matrix = (int32_t*)sd->data;
10346  /* rotation is in the counter-clockwise direction whereas
10347  * av_display_rotation_set() expects its argument to be
10348  * oriented clockwise, so we need to negate it. */
10350  av_display_matrix_flip(matrix, item->hflip, item->vflip);
10351 
10352  return 0;
10353 }
10354 
10355 static int read_image_grid(AVFormatContext *s, const HEIFGrid *grid,
10356  AVStreamGroupTileGrid *tile_grid)
10357 {
10358  MOVContext *c = s->priv_data;
10359  const HEIFItem *item = grid->item;
10360  int64_t offset = 0, pos = avio_tell(s->pb);
10361  int x = 0, y = 0, i = 0;
10362  int tile_rows, tile_cols;
10363  int flags, size;
10364 
10365  if (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL)) {
10366  av_log(c->fc, AV_LOG_INFO, "grid box with non seekable input\n");
10367  return AVERROR_PATCHWELCOME;
10368  }
10369  if (item->is_idat_relative) {
10370  if (!c->idat_offset) {
10371  av_log(c->fc, AV_LOG_ERROR, "missing idat box required by the image grid\n");
10372  return AVERROR_INVALIDDATA;
10373  }
10374  offset = c->idat_offset;
10375  }
10376 
10377  if (offset > INT64_MAX - item->extent_offset)
10378  return AVERROR_INVALIDDATA;
10379 
10380  avio_seek(s->pb, item->extent_offset + offset, SEEK_SET);
10381 
10382  avio_r8(s->pb); /* version */
10383  flags = avio_r8(s->pb);
10384 
10385  tile_rows = avio_r8(s->pb) + 1;
10386  tile_cols = avio_r8(s->pb) + 1;
10387  /* actual width and height of output image */
10388  tile_grid->width = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
10389  tile_grid->height = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
10390 
10391  av_log(c->fc, AV_LOG_TRACE, "grid: grid_rows %d grid_cols %d output_width %d output_height %d\n",
10392  tile_rows, tile_cols, tile_grid->width, tile_grid->height);
10393 
10394  avio_seek(s->pb, pos, SEEK_SET);
10395 
10396  size = tile_rows * tile_cols;
10397  tile_grid->nb_tiles = grid->nb_tiles;
10398 
10399  if (tile_grid->nb_tiles != size)
10400  return AVERROR_INVALIDDATA;
10401 
10402  for (int i = 0; i < tile_cols; i++)
10403  tile_grid->coded_width += grid->tile_item_list[i]->width;
10404  for (int i = 0; i < size; i += tile_cols)
10405  tile_grid->coded_height += grid->tile_item_list[i]->height;
10406 
10407  tile_grid->offsets = av_calloc(tile_grid->nb_tiles, sizeof(*tile_grid->offsets));
10408  if (!tile_grid->offsets)
10409  return AVERROR(ENOMEM);
10410 
10411  while (y < tile_grid->coded_height) {
10412  int left_col = i;
10413 
10414  while (x < tile_grid->coded_width) {
10415  if (i == tile_grid->nb_tiles)
10416  return AVERROR_INVALIDDATA;
10417 
10418  tile_grid->offsets[i].idx = grid->tile_idx_list[i];
10419  tile_grid->offsets[i].horizontal = x;
10420  tile_grid->offsets[i].vertical = y;
10421 
10422  x += grid->tile_item_list[i++]->width;
10423  }
10424 
10425  if (x > tile_grid->coded_width) {
10426  av_log(c->fc, AV_LOG_ERROR, "Non uniform HEIF tiles\n");
10427  return AVERROR_INVALIDDATA;
10428  }
10429 
10430  x = 0;
10431  y += grid->tile_item_list[left_col]->height;
10432  }
10433 
10434  if (y > tile_grid->coded_height || i != tile_grid->nb_tiles) {
10435  av_log(c->fc, AV_LOG_ERROR, "Non uniform HEIF tiles\n");
10436  return AVERROR_INVALIDDATA;
10437  }
10438 
10439  return 0;
10440 }
10441 
10442 static int read_image_iovl(AVFormatContext *s, const HEIFGrid *grid,
10443  AVStreamGroupTileGrid *tile_grid)
10444 {
10445  MOVContext *c = s->priv_data;
10446  const HEIFItem *item = grid->item;
10447  uint16_t canvas_fill_value[4];
10448  int64_t offset = 0, pos = avio_tell(s->pb);
10449  int ret = 0, flags;
10450 
10451  if (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL)) {
10452  av_log(c->fc, AV_LOG_INFO, "iovl box with non seekable input\n");
10453  return AVERROR_PATCHWELCOME;
10454  }
10455  if (item->is_idat_relative) {
10456  if (!c->idat_offset) {
10457  av_log(c->fc, AV_LOG_ERROR, "missing idat box required by the image overlay\n");
10458  return AVERROR_INVALIDDATA;
10459  }
10460  offset = c->idat_offset;
10461  }
10462 
10463  if (offset > INT64_MAX - item->extent_offset)
10464  return AVERROR_INVALIDDATA;
10465 
10466  avio_seek(s->pb, item->extent_offset + offset, SEEK_SET);
10467 
10468  avio_r8(s->pb); /* version */
10469  flags = avio_r8(s->pb);
10470 
10471  for (int i = 0; i < 4; i++)
10472  canvas_fill_value[i] = avio_rb16(s->pb);
10473  av_log(c->fc, AV_LOG_TRACE, "iovl: canvas_fill_value { %u, %u, %u, %u }\n",
10474  canvas_fill_value[0], canvas_fill_value[1],
10475  canvas_fill_value[2], canvas_fill_value[3]);
10476  for (int i = 0; i < 4; i++)
10477  tile_grid->background[i] = canvas_fill_value[i];
10478 
10479  /* actual width and height of output image */
10480  tile_grid->width =
10481  tile_grid->coded_width = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
10482  tile_grid->height =
10483  tile_grid->coded_height = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
10484 
10485  av_log(c->fc, AV_LOG_TRACE, "iovl: output_width %d, output_height %d\n",
10486  tile_grid->width, tile_grid->height);
10487 
10488  tile_grid->nb_tiles = grid->nb_tiles;
10489  tile_grid->offsets = av_malloc_array(tile_grid->nb_tiles, sizeof(*tile_grid->offsets));
10490  if (!tile_grid->offsets) {
10491  ret = AVERROR(ENOMEM);
10492  goto fail;
10493  }
10494 
10495  for (int i = 0; i < tile_grid->nb_tiles; i++) {
10496  tile_grid->offsets[i].idx = grid->tile_idx_list[i];
10497  tile_grid->offsets[i].horizontal = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
10498  tile_grid->offsets[i].vertical = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
10499  av_log(c->fc, AV_LOG_TRACE, "iovl: stream_idx[%d] %u, "
10500  "horizontal_offset[%d] %d, vertical_offset[%d] %d\n",
10501  i, tile_grid->offsets[i].idx,
10502  i, tile_grid->offsets[i].horizontal, i, tile_grid->offsets[i].vertical);
10503  }
10504 
10505 fail:
10506  avio_seek(s->pb, pos, SEEK_SET);
10507 
10508  return ret;
10509 }
10510 
10512  AVPacketSideData **coded_side_data, int *nb_coded_side_data,
10513  const HEIFItem *ref)
10514 {
10515  MOVContext *c = s->priv_data;
10516  AVPacketSideData *sd;
10517  AVExifMetadata ifd = { 0 };
10518  AVBufferRef *buf;
10519  int64_t offset = 0, pos = avio_tell(s->pb);
10520  unsigned orientation_id = av_exif_get_tag_id("Orientation");
10521  int err;
10522 
10523  if (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL)) {
10524  av_log(c->fc, AV_LOG_WARNING, "Exif metadata with non seekable input\n");
10525  return AVERROR_PATCHWELCOME;
10526  }
10527  if (ref->is_idat_relative) {
10528  if (!c->idat_offset) {
10529  av_log(c->fc, AV_LOG_ERROR, "missing idat box required by the Exif metadata\n");
10530  return AVERROR_INVALIDDATA;
10531  }
10532  offset = c->idat_offset;
10533  }
10534 
10535  buf = av_buffer_alloc(ref->extent_length);
10536  if (!buf)
10537  return AVERROR(ENOMEM);
10538 
10539  if (offset > INT64_MAX - ref->extent_offset) {
10540  err = AVERROR(ENOMEM);
10541  goto fail;
10542  }
10543 
10544  avio_seek(s->pb, ref->extent_offset + offset, SEEK_SET);
10545  err = avio_read(s->pb, buf->data, ref->extent_length);
10546  if (err != ref->extent_length) {
10547  if (err > 0)
10548  err = AVERROR_INVALIDDATA;
10549  goto fail;
10550  }
10551 
10552  // HEIF spec states that Exif metadata is informative. The irot item property is
10553  // the normative source of rotation information. So we remove any Orientation tag
10554  // present in the Exif buffer.
10555  err = av_exif_parse_buffer(s, buf->data, ref->extent_length, &ifd, AV_EXIF_T_OFF);
10556  if (err < 0) {
10557  av_log(s, AV_LOG_ERROR, "Unable to parse Exif metadata\n");
10558  goto fail;
10559  }
10560 
10561  err = av_exif_remove_entry(s, &ifd, orientation_id, 0);
10562  if (err < 0)
10563  goto fail;
10564  else if (!err)
10565  goto finish;
10566 
10567  av_buffer_unref(&buf);
10568  err = av_exif_write(s, &ifd, &buf, AV_EXIF_T_OFF);
10569  if (err < 0)
10570  goto fail;
10571 
10572 finish:
10573  offset = AV_RB32(buf->data) + 4;
10574  if (offset >= buf->size) {
10575  err = AVERROR_INVALIDDATA;
10576  goto fail;
10577  }
10578  sd = av_packet_side_data_new(coded_side_data, nb_coded_side_data,
10579  AV_PKT_DATA_EXIF, buf->size - offset, 0);
10580  if (!sd) {
10581  err = AVERROR(ENOMEM);
10582  goto fail;
10583  }
10584  memcpy(sd->data, buf->data + offset, buf->size - offset);
10585 
10586  err = 0;
10587 fail:
10588  av_buffer_unref(&buf);
10589  av_exif_free(&ifd);
10590  avio_seek(s->pb, pos, SEEK_SET);
10591 
10592  return err;
10593 }
10594 
10596 {
10597  MOVContext *mov = s->priv_data;
10598 
10599  for (int i = 0; i < mov->nb_heif_grid; i++) {
10601  AVStreamGroupTileGrid *tile_grid;
10602  const HEIFGrid *grid = &mov->heif_grid[i];
10603  int err, loop = 1;
10604 
10605  if (!stg)
10606  return AVERROR(ENOMEM);
10607 
10608  stg->id = grid->item->item_id;
10609  tile_grid = stg->params.tile_grid;
10610 
10611  for (int j = 0; j < grid->nb_tiles; j++) {
10612  int tile_id = grid->tile_id_list[j];
10613  int k;
10614 
10615  for (k = 0; k < mov->nb_heif_item; k++) {
10616  HEIFItem *item = mov->heif_item[k];
10617  AVStream *st;
10618 
10619  if (!item || item->item_id != tile_id)
10620  continue;
10621  st = item->st;
10622  if (!st) {
10623  av_log(s, AV_LOG_WARNING, "HEIF item id %d from grid id %d doesn't "
10624  "reference a stream\n",
10625  tile_id, grid->item->item_id);
10626  ff_remove_stream_group(s, stg);
10627  loop = 0;
10628  break;
10629  }
10630 
10631  grid->tile_item_list[j] = item;
10632  grid->tile_idx_list[j] = stg->nb_streams;
10633 
10634  err = avformat_stream_group_add_stream(stg, st);
10635  if (err < 0) {
10636  int l;
10637  if (err != AVERROR(EEXIST))
10638  return err;
10639 
10640  for (l = 0; l < stg->nb_streams; l++)
10641  if (stg->streams[l]->index == st->index)
10642  break;
10643  av_assert0(l < stg->nb_streams);
10644  grid->tile_idx_list[j] = l;
10645  }
10646 
10647  if (item->item_id != mov->primary_item_id)
10649  break;
10650  }
10651 
10652  if (k == mov->nb_heif_item) {
10653  av_assert0(loop);
10654  av_log(s, AV_LOG_WARNING, "HEIF item id %d referenced by grid id %d doesn't "
10655  "exist\n",
10656  tile_id, grid->item->item_id);
10657  ff_remove_stream_group(s, stg);
10658  loop = 0;
10659  }
10660  if (!loop)
10661  break;
10662  }
10663 
10664  if (!loop)
10665  continue;
10666 
10667  switch (grid->item->type) {
10668  case MKTAG('g','r','i','d'):
10669  err = read_image_grid(s, grid, tile_grid);
10670  break;
10671  case MKTAG('i','o','v','l'):
10672  err = read_image_iovl(s, grid, tile_grid);
10673  break;
10674  default:
10675  av_assert0(0);
10676  }
10677  if (err < 0)
10678  return err;
10679 
10680  for (int j = 0; j < grid->item->nb_iref_list; j++) {
10681  HEIFItem *ref = get_heif_item(mov, grid->item->iref_list[j].item_id);
10682 
10683  av_assert0(ref);
10684  switch(ref->type) {
10685  case MKTAG('E','x','i','f'):
10686  err = mov_parse_exif_item(s, &tile_grid->coded_side_data,
10687  &tile_grid->nb_coded_side_data, ref);
10688  if (err < 0 && (s->error_recognition & AV_EF_EXPLODE))
10689  return err;
10690  break;
10691  default:
10692  break;
10693  }
10694  }
10695 
10696  /* rotation */
10697  if (grid->item->rotation || grid->item->hflip || grid->item->vflip) {
10699  &tile_grid->nb_coded_side_data, grid->item);
10700  if (err < 0)
10701  return err;
10702  }
10703 
10704  /* ICC profile */
10705  if (grid->item->icc_profile_size) {
10706  err = set_icc_profile_from_item(&tile_grid->coded_side_data,
10707  &tile_grid->nb_coded_side_data, grid->item);
10708  if (err < 0)
10709  return err;
10710  }
10711 
10712  if (grid->item->name)
10713  av_dict_set(&stg->metadata, "title", grid->item->name, 0);
10714  if (grid->item->item_id == mov->primary_item_id)
10716  }
10717 
10718  return 0;
10719 }
10720 
10722 {
10723  MOVContext *mov = s->priv_data;
10724  int err;
10725 
10726  for (int i = 0; i < mov->nb_heif_item; i++) {
10727  HEIFItem *item = mov->heif_item[i];
10728  MOVStreamContext *sc;
10729  AVStream *st;
10730  int64_t offset = 0;
10731 
10732  if (!item)
10733  continue;
10734  if (!item->st) {
10735  continue;
10736  }
10737  if (item->is_idat_relative) {
10738  if (!mov->idat_offset) {
10739  av_log(s, AV_LOG_ERROR, "Missing idat box for item %d\n", item->item_id);
10740  return AVERROR_INVALIDDATA;
10741  }
10742  offset = mov->idat_offset;
10743  }
10744 
10745  st = item->st;
10746  sc = st->priv_data;
10747  st->codecpar->width = item->width;
10748  st->codecpar->height = item->height;
10749 
10750  sc->sample_size = sc->stsz_sample_size = item->extent_length;
10751  sc->sample_count = 1;
10752 
10753  err = sanity_checks(s, sc, st->index);
10754  if (err)
10755  return AVERROR_INVALIDDATA;
10756 
10757  if (offset > INT64_MAX - item->extent_offset)
10758  return AVERROR_INVALIDDATA;
10759 
10760  sc->chunk_offsets[0] = item->extent_offset + offset;
10761 
10762  if (item->item_id == mov->primary_item_id)
10764 
10765  for (int j = 0; j < item->nb_iref_list; j++) {
10766  HEIFItem *ref = get_heif_item(mov, item->iref_list[j].item_id);
10767 
10768  av_assert0(ref);
10769  switch(ref->type) {
10770  case MKTAG('E','x','i','f'):
10773  if (err < 0 && (s->error_recognition & AV_EF_EXPLODE))
10774  return err;
10775  break;
10776  default:
10777  break;
10778  }
10779  }
10780 
10781  if (item->rotation || item->hflip || item->vflip) {
10783  &st->codecpar->nb_coded_side_data, item);
10784  if (err < 0)
10785  return err;
10786  }
10787 
10788  mov_build_index(mov, st);
10789  }
10790 
10791  if (mov->nb_heif_grid) {
10792  err = mov_parse_tiles(s);
10793  if (err < 0)
10794  return err;
10795  }
10796 
10797  return 0;
10798 }
10799 
10801  int first_index)
10802 {
10803  MOVStreamContext *sc = st->priv_data;
10804 
10805  if (sc->tref_id < 0)
10806  return NULL;
10807 
10808  for (int i = first_index; i < s->nb_streams; i++)
10809  if (s->streams[i]->index != st->index &&
10810  s->streams[i]->id == sc->tref_id)
10811  return s->streams[i];
10812 
10813  return NULL;
10814 }
10815 
10817 {
10818  int err;
10819 
10820  // Don't try to add a group if there's only one track
10821  if (s->nb_streams <= 1)
10822  return 0;
10823 
10824  for (int i = 0; i < s->nb_streams; i++) {
10825  AVStreamGroup *stg;
10826  AVStream *st = s->streams[i];
10827  AVStream *st_base;
10828  MOVStreamContext *sc = st->priv_data;
10829  int j = 0;
10830 
10831  /* Find an enhancement stream. */
10832  if (st->codecpar->codec_id != AV_CODEC_ID_LCEVC ||
10834  continue;
10835 
10837  if (!stg)
10838  return AVERROR(ENOMEM);
10839 
10840  stg->id = st->id;
10841  stg->params.lcevc->width = st->codecpar->width;
10842  stg->params.lcevc->height = st->codecpar->height;
10843 
10844  while (st_base = mov_find_reference_track(s, st, j)) {
10845  err = avformat_stream_group_add_stream(stg, st_base);
10846  if (err < 0)
10847  return err;
10848 
10849  j = st_base->index + 1;
10850  }
10851  if (!j) {
10852  int loglevel = (s->error_recognition & AV_EF_EXPLODE) ? AV_LOG_ERROR : AV_LOG_WARNING;
10853  av_log(s, loglevel, "Failed to find base stream for LCEVC stream\n");
10854  ff_remove_stream_group(s, stg);
10855  if (s->error_recognition & AV_EF_EXPLODE)
10856  return AVERROR_INVALIDDATA;
10857  continue;
10858  }
10859 
10860  err = avformat_stream_group_add_stream(stg, st);
10861  if (err < 0)
10862  return err;
10863 
10864  stg->params.lcevc->lcevc_index = stg->nb_streams - 1;
10865  }
10866 
10867  return 0;
10868 }
10869 
10871 {
10872  int highest_id = 0, lowest_iamf_id = INT_MAX;
10873 
10874  for (int i = 0; i < s->nb_streams; i++) {
10875  const AVStream *st = s->streams[i];
10876  const MOVStreamContext *sc = st->priv_data;
10877  if (!sc->iamf)
10878  highest_id = FFMAX(highest_id, st->id);
10879  }
10880 
10881  for (int i = 0; i < s->nb_stream_groups; i++) {
10882  AVStreamGroup *stg = s->stream_groups[i];
10884  continue;
10885  for (int j = 0; j < stg->nb_streams; j++) {
10886  AVStream *st = stg->streams[j];
10887  lowest_iamf_id = FFMIN(lowest_iamf_id, st->id);
10888  }
10889  }
10890 
10891  if (highest_id < lowest_iamf_id)
10892  return;
10893 
10894  highest_id += !lowest_iamf_id;
10895  for (int i = 0; highest_id > 1 && i < s->nb_stream_groups; i++) {
10896  AVStreamGroup *stg = s->stream_groups[i];
10898  continue;
10899  for (int j = 0; j < stg->nb_streams; j++) {
10900  AVStream *st = stg->streams[j];
10901  MOVStreamContext *sc = st->priv_data;
10902  st->id += highest_id;
10903  sc->iamf_stream_offset = highest_id;
10904  }
10905  }
10906 }
10907 
10909 {
10910  MOVContext *mov = s->priv_data;
10911  AVIOContext *pb = s->pb;
10912  int j, err;
10913  MOVAtom atom = { AV_RL32("root") };
10914  int i;
10915 
10916  mov->fc = s;
10917  mov->trak_index = -1;
10918  mov->primary_item_id = -1;
10919  mov->cur_item_id = -1;
10920  /* .mov and .mp4 aren't streamable anyway (only progressive download if moov is before mdat) */
10921  if (pb->seekable & AVIO_SEEKABLE_NORMAL)
10922  atom.size = avio_size(pb);
10923  else
10924  atom.size = INT64_MAX;
10925 
10926  /* check MOV header */
10927  do {
10928  if (mov->moov_retry)
10929  avio_seek(pb, 0, SEEK_SET);
10930  if ((err = mov_read_default(mov, pb, atom)) < 0) {
10931  av_log(s, AV_LOG_ERROR, "error reading header\n");
10932  return err;
10933  }
10934  } while ((pb->seekable & AVIO_SEEKABLE_NORMAL) &&
10935  !mov->found_moov && (!mov->found_iloc || !mov->found_iinf) && !mov->moov_retry++);
10936  if (!mov->found_moov && !mov->found_iloc && !mov->found_iinf) {
10937  av_log(s, AV_LOG_ERROR, "moov atom not found\n");
10938  return AVERROR_INVALIDDATA;
10939  }
10940  av_log(mov->fc, AV_LOG_TRACE, "on_parse_exit_offset=%"PRId64"\n", avio_tell(pb));
10941 
10942  if (mov->found_iloc && mov->found_iinf) {
10943  err = mov_parse_heif_items(s);
10944  if (err < 0)
10945  return err;
10946  }
10947  // prevent iloc and iinf boxes from being parsed while reading packets.
10948  // this is needed because an iinf box may have been parsed but ignored
10949  // for having old infe boxes which create no streams.
10950  mov->found_iloc = mov->found_iinf = 1;
10951 
10952  if (pb->seekable & AVIO_SEEKABLE_NORMAL) {
10953  if (mov->nb_chapter_tracks > 0 && !mov->ignore_chapters)
10955  for (i = 0; i < s->nb_streams; i++)
10956  if (s->streams[i]->codecpar->codec_tag == AV_RL32("tmcd")) {
10957  mov_read_timecode_track(s, s->streams[i]);
10958  } else if (s->streams[i]->codecpar->codec_tag == AV_RL32("rtmd")) {
10959  mov_read_rtmd_track(s, s->streams[i]);
10960  }
10961  }
10962 
10963  /* copy timecode metadata from tmcd tracks to the related video streams */
10964  for (i = 0; i < s->nb_streams; i++) {
10965  AVStream *st = s->streams[i];
10966  MOVStreamContext *sc = st->priv_data;
10967  if (sc->timecode_track > 0) {
10968  AVDictionaryEntry *tcr;
10969  int tmcd_st_id = -1;
10970 
10971  for (j = 0; j < s->nb_streams; j++) {
10972  MOVStreamContext *sc2 = s->streams[j]->priv_data;
10973  if (sc2->id == sc->timecode_track)
10974  tmcd_st_id = j;
10975  }
10976 
10977  if (tmcd_st_id < 0 || tmcd_st_id == i)
10978  continue;
10979  tcr = av_dict_get(s->streams[tmcd_st_id]->metadata, "timecode", NULL, 0);
10980  if (tcr)
10981  av_dict_set(&st->metadata, "timecode", tcr->value, 0);
10982  }
10983  }
10985 
10986  /* Create LCEVC stream groups. */
10987  err = mov_parse_lcevc_streams(s);
10988  if (err < 0)
10989  return err;
10990 
10991  for (i = 0; i < s->nb_streams; i++) {
10992  AVStream *st = s->streams[i];
10993  FFStream *const sti = ffstream(st);
10994  MOVStreamContext *sc = st->priv_data;
10995  uint32_t dvdsub_clut[FF_DVDCLUT_CLUT_LEN] = {0};
10996  fix_timescale(mov, sc);
10997 
10998  /* Set the primary extradata based on the first Sample if it doesn't reference the first stsd entry. */
10999  if (sc->stsc_count && sc->extradata_size && !sc->iamf &&
11000  sc->stsc_data[0].id > 1 && sc->stsc_data[0].id <= sc->stsd_count) {
11001  sc->last_stsd_index = sc->stsc_data[0].id - 1;
11002  av_freep(&st->codecpar->extradata);
11004  if (sc->extradata_size[sc->last_stsd_index]) {
11006  if (!st->codecpar->extradata)
11007  return AVERROR(ENOMEM);
11008  memcpy(st->codecpar->extradata, sc->extradata[sc->last_stsd_index], sc->extradata_size[sc->last_stsd_index]);
11009  }
11010  }
11011 
11012  if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
11013  st->codecpar->codec_id == AV_CODEC_ID_AAC) {
11014  sti->skip_samples = sc->start_pad;
11015  }
11016  if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && sc->nb_frames_for_fps > 0 && sc->duration_for_fps > 0)
11018  sc->time_scale*(int64_t)sc->nb_frames_for_fps, sc->duration_for_fps, INT_MAX);
11020  if (st->codecpar->width <= 0 || st->codecpar->height <= 0) {
11021  st->codecpar->width = sc->width;
11022  st->codecpar->height = sc->height;
11023  }
11026 
11027  for (j = 0; j < FF_DVDCLUT_CLUT_LEN; j++)
11028  dvdsub_clut[j] = AV_RB32(st->codecpar->extradata + j * 4);
11029 
11030  err = ff_dvdclut_yuv_to_rgb(dvdsub_clut, FF_DVDCLUT_CLUT_SIZE);
11031  if (err < 0)
11032  return err;
11033 
11034  av_freep(&st->codecpar->extradata);
11035  st->codecpar->extradata_size = 0;
11036 
11038  st->codecpar);
11039  if (err < 0)
11040  return err;
11041  }
11042  }
11043  if (mov->handbrake_version &&
11044  mov->handbrake_version <= 1000000*0 + 1000*10 + 2 && // 0.10.2
11045  st->codecpar->codec_id == AV_CODEC_ID_MP3) {
11046  av_log(s, AV_LOG_VERBOSE, "Forcing full parsing for mp3 stream\n");
11048  }
11049  }
11050 
11051  if (mov->trex_data || mov->use_mfra_for > 0) {
11052  for (i = 0; i < s->nb_streams; i++) {
11053  AVStream *st = s->streams[i];
11054  MOVStreamContext *sc = st->priv_data;
11055  if (sc->duration_for_fps > 0) {
11056  /* Akin to sc->data_size * 8 * sc->time_scale / sc->duration_for_fps but accounting for overflows. */
11058  if (st->codecpar->bit_rate == INT64_MIN) {
11059  av_log(s, AV_LOG_WARNING, "Overflow during bit rate calculation %"PRId64" * 8 * %d\n",
11060  sc->data_size, sc->time_scale);
11061  st->codecpar->bit_rate = 0;
11062  if (s->error_recognition & AV_EF_EXPLODE)
11063  return AVERROR_INVALIDDATA;
11064  }
11065  }
11066  }
11067  }
11068 
11069  for (i = 0; i < mov->bitrates_count && i < s->nb_streams; i++) {
11070  if (mov->bitrates[i]) {
11071  s->streams[i]->codecpar->bit_rate = mov->bitrates[i];
11072  }
11073  }
11074 
11076 
11077  for (i = 0; i < s->nb_streams; i++) {
11078  AVStream *st = s->streams[i];
11079  MOVStreamContext *sc = st->priv_data;
11080 
11081  switch (st->codecpar->codec_type) {
11082  case AVMEDIA_TYPE_AUDIO:
11083  err = ff_replaygain_export(st, s->metadata);
11084  if (err < 0)
11085  return err;
11086  break;
11087  case AVMEDIA_TYPE_VIDEO:
11088  if (sc->display_matrix) {
11091  (uint8_t*)sc->display_matrix, sizeof(int32_t) * 9, 0))
11092  return AVERROR(ENOMEM);
11093 
11094  sc->display_matrix = NULL;
11095  }
11096  if (sc->stereo3d) {
11099  (uint8_t *)sc->stereo3d, sc->stereo3d_size, 0))
11100  return AVERROR(ENOMEM);
11101 
11102  sc->stereo3d = NULL;
11103  }
11104  if (sc->spherical) {
11107  (uint8_t *)sc->spherical, sc->spherical_size, 0))
11108  return AVERROR(ENOMEM);
11109 
11110  sc->spherical = NULL;
11111  }
11112  if (sc->mastering) {
11115  (uint8_t *)sc->mastering, sc->mastering_size, 0))
11116  return AVERROR(ENOMEM);
11117 
11118  sc->mastering = NULL;
11119  }
11120  if (sc->coll) {
11123  (uint8_t *)sc->coll, sc->coll_size, 0))
11124  return AVERROR(ENOMEM);
11125 
11126  sc->coll = NULL;
11127  }
11128  if (sc->ambient) {
11131  (uint8_t *) sc->ambient, sc->ambient_size, 0))
11132  return AVERROR(ENOMEM);
11133 
11134  sc->ambient = NULL;
11135  }
11136  break;
11137  }
11138  }
11139 
11140  fix_stream_ids(s);
11141 
11143 
11144  for (i = 0; i < mov->frag_index.nb_items; i++)
11145  if (mov->frag_index.item[i].moof_offset <= mov->fragment.moof_offset)
11146  mov->frag_index.item[i].headers_read = 1;
11147 
11148  return 0;
11149 }
11150 
11152 {
11154  int64_t best_dts = INT64_MAX;
11155  int i;
11156  MOVContext *mov = s->priv_data;
11157  int no_interleave = !mov->interleaved_read || !(s->pb->seekable & AVIO_SEEKABLE_NORMAL);
11158  for (i = 0; i < s->nb_streams; i++) {
11159  AVStream *avst = s->streams[i];
11160  FFStream *const avsti = ffstream(avst);
11161  MOVStreamContext *msc = avst->priv_data;
11162  if (msc->pb && msc->current_sample < avsti->nb_index_entries) {
11163  AVIndexEntry *current_sample = &avsti->index_entries[msc->current_sample];
11164  int64_t dts = av_rescale(current_sample->timestamp, AV_TIME_BASE, msc->time_scale);
11165  uint64_t dtsdiff = best_dts > dts ? best_dts - (uint64_t)dts : ((uint64_t)dts - best_dts);
11166  av_log(s, AV_LOG_TRACE, "stream %d, sample %d, dts %"PRId64"\n", i, msc->current_sample, dts);
11167  if (!sample || (no_interleave && current_sample->pos < sample->pos) ||
11168  ((s->pb->seekable & AVIO_SEEKABLE_NORMAL) &&
11169  ((msc->pb != s->pb && dts < best_dts) || (msc->pb == s->pb && dts != AV_NOPTS_VALUE &&
11170  ((dtsdiff <= AV_TIME_BASE && current_sample->pos < sample->pos) ||
11171  (dtsdiff > AV_TIME_BASE && dts < best_dts && mov->interleaved_read)))))) {
11172  sample = current_sample;
11173  best_dts = dts;
11174  *st = avst;
11175  }
11176  }
11177  }
11178  return sample;
11179 }
11180 
11181 static int should_retry(AVIOContext *pb, int error_code) {
11182  if (error_code == AVERROR_EOF || avio_feof(pb))
11183  return 0;
11184 
11185  return 1;
11186 }
11187 
11188 static int mov_switch_root(AVFormatContext *s, int64_t target, int index)
11189 {
11190  int ret;
11191  MOVContext *mov = s->priv_data;
11192 
11193  if (index >= 0 && index < mov->frag_index.nb_items)
11194  target = mov->frag_index.item[index].moof_offset;
11195  if (target >= 0 && avio_seek(s->pb, target, SEEK_SET) != target) {
11196  av_log(mov->fc, AV_LOG_ERROR, "root atom offset 0x%"PRIx64": partial file\n", target);
11197  return AVERROR_INVALIDDATA;
11198  }
11199 
11200  mov->next_root_atom = 0;
11201  if ((index < 0 && target >= 0) || index >= mov->frag_index.nb_items)
11202  index = search_frag_moof_offset(&mov->frag_index, target);
11203  if (index >= 0 && index < mov->frag_index.nb_items &&
11204  mov->frag_index.item[index].moof_offset == target) {
11205  if (index + 1 < mov->frag_index.nb_items)
11206  mov->next_root_atom = mov->frag_index.item[index + 1].moof_offset;
11207  if (mov->frag_index.item[index].headers_read)
11208  return 0;
11209  mov->frag_index.item[index].headers_read = 1;
11210  }
11211 
11212  mov->found_mdat = 0;
11213 
11214  ret = mov_read_default(mov, s->pb, (MOVAtom){ AV_RL32("root"), INT64_MAX });
11215  if (ret < 0)
11216  return ret;
11217  if (avio_feof(s->pb))
11218  return AVERROR_EOF;
11219  av_log(s, AV_LOG_TRACE, "read fragments, offset 0x%"PRIx64"\n", avio_tell(s->pb));
11220 
11221  return 1;
11222 }
11223 
11225 {
11226  MOVStreamContext *sc = st->priv_data;
11227  uint8_t *side, *extradata;
11228  int extradata_size;
11229 
11230  /* Save the current index. */
11231  sc->last_stsd_index = sc->stsc_data[sc->stsc_index].id - 1;
11232 
11233  /* Notify the decoder that extradata changed. */
11234  extradata_size = sc->extradata_size[sc->last_stsd_index];
11235  extradata = sc->extradata[sc->last_stsd_index];
11236  if (st->discard != AVDISCARD_ALL && extradata_size > 0 && extradata) {
11239  extradata_size);
11240  if (!side)
11241  return AVERROR(ENOMEM);
11242  memcpy(side, extradata, extradata_size);
11243  }
11244 
11245  return 0;
11246 }
11247 
11248 static int get_eia608_packet(AVIOContext *pb, AVPacket *pkt, int src_size)
11249 {
11250  /* We can't make assumptions about the structure of the payload,
11251  because it may include multiple cdat and cdt2 samples. */
11252  const uint32_t cdat = AV_RB32("cdat");
11253  const uint32_t cdt2 = AV_RB32("cdt2");
11254  int ret, out_size = 0;
11255 
11256  /* a valid payload must have size, 4cc, and at least 1 byte pair: */
11257  if (src_size < 10)
11258  return AVERROR_INVALIDDATA;
11259 
11260  /* avoid an int overflow: */
11261  if ((src_size - 8) / 2 >= INT_MAX / 3)
11262  return AVERROR_INVALIDDATA;
11263 
11264  ret = av_new_packet(pkt, ((src_size - 8) / 2) * 3);
11265  if (ret < 0)
11266  return ret;
11267 
11268  /* parse and re-format the c608 payload in one pass. */
11269  while (src_size >= 10) {
11270  const uint32_t atom_size = avio_rb32(pb);
11271  const uint32_t atom_type = avio_rb32(pb);
11272  const uint32_t data_size = atom_size - 8;
11273  const uint8_t cc_field =
11274  atom_type == cdat ? 1 :
11275  atom_type == cdt2 ? 2 :
11276  0;
11277 
11278  /* account for bytes consumed for atom size and type. */
11279  src_size -= 8;
11280 
11281  /* make sure the data size stays within the buffer boundaries. */
11282  if (data_size < 2 || data_size > src_size) {
11284  break;
11285  }
11286 
11287  /* make sure the data size is consistent with N byte pairs. */
11288  if (data_size % 2 != 0) {
11290  break;
11291  }
11292 
11293  if (!cc_field) {
11294  /* neither cdat or cdt2 ... skip it */
11295  avio_skip(pb, data_size);
11296  src_size -= data_size;
11297  continue;
11298  }
11299 
11300  for (uint32_t i = 0; i < data_size; i += 2) {
11301  pkt->data[out_size] = (0x1F << 3) | (1 << 2) | (cc_field - 1);
11302  pkt->data[out_size + 1] = avio_r8(pb);
11303  pkt->data[out_size + 2] = avio_r8(pb);
11304  out_size += 3;
11305  src_size -= 2;
11306  }
11307  }
11308 
11309  if (src_size > 0)
11310  /* skip any remaining unread portion of the input payload */
11311  avio_skip(pb, src_size);
11312 
11314  return ret;
11315 }
11316 
11318  int64_t current_index, AVPacket *pkt)
11319 {
11320  MOVStreamContext *sc = st->priv_data;
11321 
11322  pkt->stream_index = sc->ffindex;
11323  pkt->dts = sample->timestamp;
11324  if (sample->flags & AVINDEX_DISCARD_FRAME) {
11326  }
11327  if (sc->stts_count && sc->tts_index < sc->tts_count)
11328  pkt->duration = sc->tts_data[sc->tts_index].duration;
11329  if (sc->ctts_count && sc->tts_index < sc->tts_count) {
11331  } else {
11332  if (pkt->duration == 0) {
11333  int64_t next_dts = (sc->current_sample < ffstream(st)->nb_index_entries) ?
11335  if (next_dts >= pkt->dts)
11336  pkt->duration = next_dts - pkt->dts;
11337  }
11338  pkt->pts = pkt->dts;
11339  }
11340 
11341  if (sc->tts_data && sc->tts_index < sc->tts_count) {
11342  /* update tts context */
11343  sc->tts_sample++;
11344  if (sc->tts_index < sc->tts_count &&
11345  sc->tts_data[sc->tts_index].count == sc->tts_sample) {
11346  sc->tts_index++;
11347  sc->tts_sample = 0;
11348  }
11349  }
11350 
11351  if (sc->sdtp_data && sc->current_sample <= sc->sdtp_count) {
11352  uint8_t sample_flags = sc->sdtp_data[sc->current_sample - 1];
11353  uint8_t sample_is_depended_on = (sample_flags >> 2) & 0x3;
11354  pkt->flags |= sample_is_depended_on == MOV_SAMPLE_DEPENDENCY_NO ? AV_PKT_FLAG_DISPOSABLE : 0;
11355  }
11356  pkt->flags |= sample->flags & AVINDEX_KEYFRAME ? AV_PKT_FLAG_KEY : 0;
11357  pkt->pos = sample->pos;
11358 
11359  /* Multiple stsd handling. */
11360  if (sc->stsc_data) {
11361  if (sc->stsc_data[sc->stsc_index].id > 0 &&
11362  sc->stsc_data[sc->stsc_index].id - 1 < sc->stsd_count &&
11363  sc->stsc_data[sc->stsc_index].id - 1 != sc->last_stsd_index) {
11364  int ret = mov_change_extradata(st, pkt);
11365  if (ret < 0)
11366  return ret;
11367  }
11368 
11369  /* Update the stsc index for the next sample */
11370  sc->stsc_sample++;
11371  if (mov_stsc_index_valid(sc->stsc_index, sc->stsc_count) &&
11372  mov_get_stsc_samples(sc, sc->stsc_index) == sc->stsc_sample) {
11373  sc->stsc_index++;
11374  sc->stsc_sample = 0;
11375  }
11376  }
11377 
11378  return 0;
11379 }
11380 
11382 {
11383  MOVContext *mov = s->priv_data;
11384  MOVStreamContext *sc;
11386  AVStream *st = NULL;
11387  FFStream *avsti = NULL;
11388  int64_t current_index;
11389  int ret;
11390  int i;
11391  mov->fc = s;
11392  retry:
11393  if (s->pb->pos == 0) {
11394 
11395  // Discard current fragment index
11396  if (mov->frag_index.allocated_size > 0) {
11397  for(int i = 0; i < mov->frag_index.nb_items; i++) {
11399  }
11400  av_freep(&mov->frag_index.item);
11401  mov->frag_index.nb_items = 0;
11402  mov->frag_index.allocated_size = 0;
11403  mov->frag_index.current = -1;
11404  mov->frag_index.complete = 0;
11405  }
11406 
11407  for (i = 0; i < s->nb_streams; i++) {
11408  AVStream *avst = s->streams[i];
11409  MOVStreamContext *msc = avst->priv_data;
11410 
11411  // Clear current sample
11412  mov_current_sample_set(msc, 0);
11413  msc->tts_index = 0;
11414 
11415  // Discard current index entries
11416  avsti = ffstream(avst);
11417  if (avsti->index_entries_allocated_size > 0) {
11418  av_freep(&avsti->index_entries);
11419  avsti->index_entries_allocated_size = 0;
11420  avsti->nb_index_entries = 0;
11421  }
11422  }
11423 
11424  if ((ret = mov_switch_root(s, -1, -1)) < 0)
11425  return ret;
11426  }
11427  sample = mov_find_next_sample(s, &st);
11428  if (!sample || (mov->next_root_atom && sample->pos > mov->next_root_atom)) {
11429  if (!mov->next_root_atom)
11430  return AVERROR_EOF;
11431  if ((ret = mov_switch_root(s, mov->next_root_atom, -1)) < 0)
11432  return ret;
11433  goto retry;
11434  }
11435  sc = st->priv_data;
11436  /* must be done just before reading, to avoid infinite loop on sample */
11437  current_index = sc->current_index;
11439 
11440  if (mov->next_root_atom) {
11441  sample->pos = FFMIN(sample->pos, mov->next_root_atom);
11442  sample->size = FFMIN(sample->size, (mov->next_root_atom - sample->pos));
11443  }
11444 
11445  if (st->discard != AVDISCARD_ALL || sc->iamf) {
11446  int64_t ret64 = avio_seek(sc->pb, sample->pos, SEEK_SET);
11447  if (ret64 != sample->pos) {
11448  av_log(mov->fc, AV_LOG_ERROR, "stream %d, offset 0x%"PRIx64": partial file\n",
11449  sc->ffindex, sample->pos);
11450  if (should_retry(sc->pb, ret64)) {
11452  } else if (ret64 < 0) {
11453  return (int)ret64;
11454  }
11455  return AVERROR_INVALIDDATA;
11456  }
11457 
11458  if (st->discard == AVDISCARD_NONKEY && !(sample->flags & AVINDEX_KEYFRAME)) {
11459  av_log(mov->fc, AV_LOG_DEBUG, "Nonkey frame from stream %d discarded due to AVDISCARD_NONKEY\n", sc->ffindex);
11460  goto retry;
11461  }
11462 
11463  if (st->codecpar->codec_id == AV_CODEC_ID_EIA_608 && sample->size > 8)
11464  ret = get_eia608_packet(sc->pb, pkt, sample->size);
11465 #if CONFIG_IAMFDEC
11466  else if (sc->iamf) {
11467  int64_t pts, dts, pos, duration;
11468  int flags, size = sample->size;
11469  ret = mov_finalize_packet(s, st, sample, current_index, pkt);
11470  pts = pkt->pts; dts = pkt->dts;
11471  pos = pkt->pos; flags = pkt->flags;
11472  duration = pkt->duration;
11473  while (!ret && size > 0) {
11474  ret = ff_iamf_read_packet(s, sc->iamf, sc->pb, size, sc->iamf_stream_offset, pkt);
11475  if (ret < 0) {
11476  if (should_retry(sc->pb, ret))
11478  return ret;
11479  }
11480  size -= ret;
11481 
11482  if (pkt->flags & AV_PKT_FLAG_DISCARD) {
11484  ret = 0;
11485  continue;
11486  }
11487  pkt->pts = pts; pkt->dts = dts;
11488  pkt->pos = pos; pkt->flags |= flags;
11489  pkt->duration = duration;
11490  ret = ff_buffer_packet(s, pkt);
11491  }
11492  if (!ret)
11493  return FFERROR_REDO;
11494  }
11495 #endif
11496  else if (st->codecpar->codec_id == AV_CODEC_ID_APV && sample->size > 4) {
11497  const uint32_t au_size = avio_rb32(sc->pb);
11498  ret = av_get_packet(sc->pb, pkt, au_size);
11499  } else
11500  ret = av_get_packet(sc->pb, pkt, sample->size);
11501  if (ret < 0) {
11502  if (should_retry(sc->pb, ret)) {
11504  }
11505  return ret;
11506  }
11507 #if CONFIG_DV_DEMUXER
11508  if (mov->dv_demux && sc->dv_audio_container) {
11511  if (ret < 0)
11512  return ret;
11514  if (ret < 0)
11515  return ret;
11516  }
11517 #endif
11518  if (sc->has_palette) {
11519  uint8_t *pal;
11520 
11522  if (!pal) {
11523  av_log(mov->fc, AV_LOG_ERROR, "Cannot append palette to packet\n");
11524  } else {
11525  memcpy(pal, sc->palette, AVPALETTE_SIZE);
11526  sc->has_palette = 0;
11527  }
11528  }
11529  if (st->codecpar->codec_id == AV_CODEC_ID_MP3 && !ffstream(st)->need_parsing && pkt->size > 4) {
11530  if (ff_mpa_check_header(AV_RB32(pkt->data)) < 0)
11532  }
11533  }
11534 
11535  ret = mov_finalize_packet(s, st, sample, current_index, pkt);
11536  if (ret < 0)
11537  return ret;
11538 
11539  if (st->discard == AVDISCARD_ALL)
11540  goto retry;
11541 
11542  if (mov->aax_mode)
11543  aax_filter(pkt->data, pkt->size, mov);
11544 
11545  ret = cenc_filter(mov, st, sc, pkt, current_index);
11546  if (ret < 0) {
11547  return ret;
11548  }
11549 
11550  return 0;
11551 }
11552 
11554 {
11555  MOVContext *mov = s->priv_data;
11556  int index;
11557 
11558  if (!mov->frag_index.complete)
11559  return 0;
11560 
11561  index = search_frag_timestamp(s, &mov->frag_index, st, timestamp);
11562  if (index < 0)
11563  index = 0;
11564  if (!mov->frag_index.item[index].headers_read)
11565  return mov_switch_root(s, -1, index);
11566  if (index + 1 < mov->frag_index.nb_items)
11567  mov->next_root_atom = mov->frag_index.item[index + 1].moof_offset;
11568 
11569  return 0;
11570 }
11571 
11572 static int is_open_key_sample(const MOVStreamContext *sc, int sample)
11573 {
11574  // TODO: a bisect search would scale much better
11575  for (int i = 0; i < sc->open_key_samples_count; i++) {
11576  const int oks = sc->open_key_samples[i];
11577  if (oks == sample)
11578  return 1;
11579  if (oks > sample) /* list is monotically increasing so we can stop early */
11580  break;
11581  }
11582  return 0;
11583 }
11584 
11585 /*
11586  * Some key sample may be key frames but not IDR frames, so a random access to
11587  * them may not be allowed.
11588  */
11589 static int can_seek_to_key_sample(AVStream *st, int sample, int64_t requested_pts)
11590 {
11591  MOVStreamContext *sc = st->priv_data;
11592  FFStream *const sti = ffstream(st);
11593  int64_t key_sample_dts, key_sample_pts;
11594 
11595  if (st->codecpar->codec_id != AV_CODEC_ID_HEVC)
11596  return 1;
11597 
11598  if (sample >= sc->sample_offsets_count)
11599  return 1;
11600 
11601  key_sample_dts = sti->index_entries[sample].timestamp;
11602  key_sample_pts = key_sample_dts + sc->sample_offsets[sample] + sc->dts_shift;
11603 
11604  /*
11605  * If the sample needs to be presented before an open key sample, they may
11606  * not be decodable properly, even though they come after in decoding
11607  * order.
11608  */
11609  if (is_open_key_sample(sc, sample) && key_sample_pts > requested_pts)
11610  return 0;
11611 
11612  return 1;
11613 }
11614 
11615 static int mov_seek_stream(AVFormatContext *s, AVStream *st, int64_t timestamp, int flags)
11616 {
11617  MOVStreamContext *sc = st->priv_data;
11618  FFStream *const sti = ffstream(st);
11619  int sample, time_sample, ret, requested_sample;
11620  int64_t next_ts;
11621  unsigned int i;
11622 
11623  // Here we consider timestamp to be PTS, hence try to offset it so that we
11624  // can search over the DTS timeline.
11625  timestamp -= (sc->min_corrected_pts + sc->dts_shift);
11626 
11627  ret = mov_seek_fragment(s, st, timestamp);
11628  if (ret < 0)
11629  return ret;
11630 
11631  for (;;) {
11632  sample = av_index_search_timestamp(st, timestamp, flags);
11633  av_log(s, AV_LOG_TRACE, "stream %d, timestamp %"PRId64", sample %d\n", st->index, timestamp, sample);
11634  if (sample < 0 && sti->nb_index_entries && timestamp < sti->index_entries[0].timestamp)
11635  sample = 0;
11636  if (sample < 0) /* not sure what to do */
11637  return AVERROR_INVALIDDATA;
11638 
11639  if (!sample || can_seek_to_key_sample(st, sample, timestamp))
11640  break;
11641 
11642  next_ts = timestamp - FFMAX(sc->min_sample_duration, 1);
11643  requested_sample = av_index_search_timestamp(st, next_ts, flags);
11644 
11645  // If we've reached a different sample trying to find a good pts to
11646  // seek to, give up searching because we'll end up seeking back to
11647  // sample 0 on every seek.
11648  if (sample != requested_sample && !can_seek_to_key_sample(st, requested_sample, next_ts))
11649  break;
11650 
11651  timestamp = next_ts;
11652  }
11653 
11655  av_log(s, AV_LOG_TRACE, "stream %d, found sample %d\n", st->index, sc->current_sample);
11656  /* adjust time to sample index */
11657  if (sc->tts_data) {
11658  time_sample = 0;
11659  for (i = 0; i < sc->tts_count; i++) {
11660  int next = time_sample + sc->tts_data[i].count;
11661  if (next > sc->current_sample) {
11662  sc->tts_index = i;
11663  sc->tts_sample = sc->current_sample - time_sample;
11664  break;
11665  }
11666  time_sample = next;
11667  }
11668  }
11669 
11670  /* adjust stsd index */
11671  if (sc->chunk_count) {
11672  time_sample = 0;
11673  for (i = 0; i < sc->stsc_count; i++) {
11674  int64_t next = time_sample + mov_get_stsc_samples(sc, i);
11675  if (next > sc->current_sample) {
11676  sc->stsc_index = i;
11677  sc->stsc_sample = sc->current_sample - time_sample;
11678  break;
11679  }
11680  av_assert0(next == (int)next);
11681  time_sample = next;
11682  }
11683  }
11684 
11685  return sample;
11686 }
11687 
11689 {
11690  MOVStreamContext *sc = st->priv_data;
11691  FFStream *const sti = ffstream(st);
11692  int64_t first_ts = sti->index_entries[0].timestamp;
11694  int64_t off;
11695 
11697  return 0;
11698 
11699  /* compute skip samples according to stream start_pad, seek ts and first ts */
11700  off = av_rescale_q(ts - first_ts, st->time_base,
11701  (AVRational){1, st->codecpar->sample_rate});
11702  return FFMAX(sc->start_pad - off, 0);
11703 }
11704 
11705 static int mov_read_seek(AVFormatContext *s, int stream_index, int64_t sample_time, int flags)
11706 {
11707  MOVContext *mc = s->priv_data;
11708  AVStream *st;
11709  FFStream *sti;
11710  int sample;
11711  int i;
11712 
11713  if (stream_index >= s->nb_streams)
11714  return AVERROR_INVALIDDATA;
11715 
11716  st = s->streams[stream_index];
11717  sti = ffstream(st);
11718  sample = mov_seek_stream(s, st, sample_time, flags);
11719  if (sample < 0)
11720  return sample;
11721 
11722  if (mc->seek_individually) {
11723  /* adjust seek timestamp to found sample timestamp */
11724  int64_t seek_timestamp = sti->index_entries[sample].timestamp;
11726 
11727  for (i = 0; i < s->nb_streams; i++) {
11728  AVStream *const st = s->streams[i];
11729  FFStream *const sti = ffstream(st);
11730  int64_t timestamp;
11731 
11732  if (stream_index == i)
11733  continue;
11734 
11735  timestamp = av_rescale_q(seek_timestamp, s->streams[stream_index]->time_base, st->time_base);
11736  sample = mov_seek_stream(s, st, timestamp, flags);
11737  if (sample >= 0)
11739  }
11740  } else {
11741  for (i = 0; i < s->nb_streams; i++) {
11742  MOVStreamContext *sc;
11743  st = s->streams[i];
11744  sc = st->priv_data;
11745  mov_current_sample_set(sc, 0);
11746  }
11747  while (1) {
11748  MOVStreamContext *sc;
11750  if (!entry)
11751  return AVERROR_INVALIDDATA;
11752  sc = st->priv_data;
11753  if (sc->ffindex == stream_index && sc->current_sample == sample)
11754  break;
11756  }
11757  }
11758  return 0;
11759 }
11760 
11761 #define OFFSET(x) offsetof(MOVContext, x)
11762 #define FLAGS AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM
11763 static const AVOption mov_options[] = {
11764  {"use_absolute_path",
11765  "allow using absolute path when opening alias, this is a possible security issue",
11766  OFFSET(use_absolute_path), AV_OPT_TYPE_BOOL, {.i64 = 0},
11767  0, 1, FLAGS},
11768  {"seek_streams_individually",
11769  "Seek each stream individually to the closest point",
11770  OFFSET(seek_individually), AV_OPT_TYPE_BOOL, { .i64 = 1 },
11771  0, 1, FLAGS},
11772  {"ignore_editlist", "Ignore the edit list atom.", OFFSET(ignore_editlist), AV_OPT_TYPE_BOOL, {.i64 = 0},
11773  0, 1, FLAGS},
11774  {"advanced_editlist",
11775  "Modify the AVIndex according to the editlists. Use this option to decode in the order specified by the edits.",
11776  OFFSET(advanced_editlist), AV_OPT_TYPE_BOOL, {.i64 = 1},
11777  0, 1, FLAGS},
11778  {"ignore_chapters", "", OFFSET(ignore_chapters), AV_OPT_TYPE_BOOL, {.i64 = 0},
11779  0, 1, FLAGS},
11780  {"use_mfra_for",
11781  "use mfra for fragment timestamps",
11782  OFFSET(use_mfra_for), AV_OPT_TYPE_INT, {.i64 = FF_MOV_FLAG_MFRA_AUTO},
11784  .unit = "use_mfra_for"},
11785  {"auto", "auto", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_AUTO}, 0, 0,
11786  FLAGS, .unit = "use_mfra_for" },
11787  {"dts", "dts", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_DTS}, 0, 0,
11788  FLAGS, .unit = "use_mfra_for" },
11789  {"pts", "pts", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_PTS}, 0, 0,
11790  FLAGS, .unit = "use_mfra_for" },
11791  {"use_tfdt", "use tfdt for fragment timestamps", OFFSET(use_tfdt), AV_OPT_TYPE_BOOL, {.i64 = 1},
11792  0, 1, FLAGS},
11793  { "export_all", "Export unrecognized metadata entries", OFFSET(export_all),
11794  AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = FLAGS },
11795  { "export_xmp", "Export full XMP metadata", OFFSET(export_xmp),
11796  AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = FLAGS },
11797  { "activation_bytes", "Secret bytes for Audible AAX files", OFFSET(activation_bytes),
11799  { "audible_key", "AES-128 Key for Audible AAXC files", OFFSET(audible_key),
11801  { "audible_iv", "AES-128 IV for Audible AAXC files", OFFSET(audible_iv),
11803  { "audible_fixed_key", // extracted from libAAX_SDK.so and AAXSDKWin.dll files!
11804  "Fixed key used for handling Audible AAX files", OFFSET(audible_fixed_key),
11805  AV_OPT_TYPE_BINARY, {.str="77214d4b196a87cd520045fd20a51d67"},
11806  .flags = AV_OPT_FLAG_DECODING_PARAM },
11807  { "decryption_key", "The default media decryption key (hex)", OFFSET(decryption_default_key), AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM },
11808  { "decryption_keys", "The media decryption keys by KID (hex)", OFFSET(decryption_keys), AV_OPT_TYPE_DICT, .flags = AV_OPT_FLAG_DECODING_PARAM },
11809  { "enable_drefs", "Enable external track support.", OFFSET(enable_drefs), AV_OPT_TYPE_BOOL,
11810  {.i64 = 0}, 0, 1, FLAGS },
11811  { "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 },
11812  { "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 },
11813 
11814  { NULL },
11815 };
11816 
11817 static const AVClass mov_class = {
11818  .class_name = "mov,mp4,m4a,3gp,3g2,mj2",
11819  .item_name = av_default_item_name,
11820  .option = mov_options,
11821  .version = LIBAVUTIL_VERSION_INT,
11822 };
11823 
11825  .p.name = "mov,mp4,m4a,3gp,3g2,mj2",
11826  .p.long_name = NULL_IF_CONFIG_SMALL("QuickTime / MOV"),
11827  .p.priv_class = &mov_class,
11828  .p.extensions = "mov,mp4,m4a,3gp,3g2,mj2,psp,m4v,m4b,ism,ismv,isma,f4v,avif,heic,heif",
11830  .priv_data_size = sizeof(MOVContext),
11831  .flags_internal = FF_INFMT_FLAG_INIT_CLEANUP,
11832  .read_probe = mov_probe,
11837 };
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:72
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:3082
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:7435
mov_read_meta
static int mov_read_meta(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5544
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:433
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:10442
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:9373
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:71
mov_read_dops
static int mov_read_dops(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:8563
can_seek_to_key_sample
static int can_seek_to_key_sample(AVStream *st, int sample, int64_t requested_pts)
Definition: mov.c:11589
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:53
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:882
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:11817
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
AVStreamGroupTileGrid::offsets
struct AVStreamGroupTileGrid::@446 * offsets
An nb_tiles sized array of offsets in pixels from the topleft edge of the canvas, indicating where ea...
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:2315
mov_read_chnl
static int mov_read_chnl(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1226
mov_read_moof
static int mov_read_moof(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1852
av_bprint_init
void av_bprint_init(AVBPrint *buf, unsigned size_init, unsigned size_max)
Definition: bprint.c:69
ctype
#define ctype
Definition: afir_template.c:46
AV_PKT_DATA_FRAME_CROPPING
@ AV_PKT_DATA_FRAME_CROPPING
The number of pixels to discard from the top/bottom/left/right border of the decoded frame to obtain ...
Definition: packet.h:340
av_exif_write
int av_exif_write(void *logctx, const AVExifMetadata *ifd, AVBufferRef **buffer, enum AVExifHeaderMode header_mode)
Allocates a buffer using av_malloc of an appropriate size and writes the EXIF data represented by ifd...
Definition: exif.c:753
AVCodecParameters
This struct describes the properties of an encoded stream.
Definition: codec_par.h:49
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:5177
av_stristr
char * av_stristr(const char *s1, const char *s2)
Locate the first case-independent occurrence in the string haystack of the string needle.
Definition: avstring.c:58
AVCodecParameters::color_space
enum AVColorSpace color_space
Definition: codec_par.h:192
avformat_new_stream
AVStream * avformat_new_stream(AVFormatContext *s, const struct AVCodec *c)
Add a new stream to a media file.
ff_replaygain_export
int ff_replaygain_export(AVStream *st, AVDictionary *metadata)
Parse replaygain tags and export them as per-stream side data.
Definition: replaygain.c:94
tmcd_is_referenced
static int tmcd_is_referenced(AVFormatContext *s, int tmcd_id)
Definition: mov.c:10185
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:11763
mov_codec_id
static int mov_codec_id(AVStream *st, uint32_t format)
Definition: mov.c:2666
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:8960
matrix
Definition: vc1dsp.c:43
AVMasteringDisplayMetadata::display_primaries
AVRational display_primaries[3][2]
CIE 1931 xy chromaticity coords of color primaries (r, g, b order).
Definition: mastering_display_metadata.h:42
AV_PKT_FLAG_DISCARD
#define AV_PKT_FLAG_DISCARD
Flag is used to discard packets which are required to maintain valid decoder state but are not requir...
Definition: packet.h:657
AVMasteringDisplayMetadata::has_luminance
int has_luminance
Flag indicating whether the luminance (min_ and max_) have been set.
Definition: mastering_display_metadata.h:67
get_bits_long
static unsigned int get_bits_long(GetBitContext *s, int n)
Read 0-32 bits.
Definition: get_bits.h:424
int64_t
long long int64_t
Definition: coverity.c:34
output
filter_frame For filters that do not use the this method is called when a frame is pushed to the filter s input It can be called at any time except in a reentrant way If the input frame is enough to produce output
Definition: filter_design.txt:226
mov_read_alac
static int mov_read_alac(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2287
test_same_origin
static int test_same_origin(const char *src, const char *ref)
Definition: mov.c:5020
cbcs_scheme_decrypt
static int cbcs_scheme_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
Definition: mov.c:8380
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:5562
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:164
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:3718
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:2292
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:60
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:5404
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:416
mov_read_extradata
static int mov_read_extradata(MOVContext *c, AVIOContext *pb, MOVAtom atom, enum AVCodecID codec_id)
Definition: mov.c:2261
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:1954
mov_read_idat
static int mov_read_idat(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:8954
AVPacket::data
uint8_t * data
Definition: packet.h:595
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:2307
AVAmbientViewingEnvironment::ambient_light_x
AVRational ambient_light_x
Normalized x chromaticity coordinate of the environmental ambient light in the nominal viewing enviro...
Definition: ambient_viewing_environment.h:47
AVCodecParameters::seek_preroll
int seek_preroll
Number of audio samples to skip after a discontinuity.
Definition: codec_par.h:256
av_dynarray2_add
void * av_dynarray2_add(void **tab_ptr, int *nb_ptr, size_t elem_size, const uint8_t *elem_data)
Add an element of size elem_size to a dynamic array.
Definition: mem.c: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:3371
MOVContext::bitrates
int * bitrates
bitrates read before streams creation
Definition: isom.h:353
b
#define b
Definition: input.c:43
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:5570
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:2108
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:1993
mov_read_strf
static int mov_read_strf(MOVContext *c, AVIOContext *pb, MOVAtom atom)
An strf atom is a BITMAPINFOHEADER struct.
Definition: mov.c:2579
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:7643
mov_seek_stream
static int mov_seek_stream(AVFormatContext *s, AVStream *st, int64_t timestamp, int flags)
Definition: mov.c:11615
mov_read_saio
static int mov_read_saio(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:7789
mov_get_stsc_samples
static int64_t mov_get_stsc_samples(MOVStreamContext *sc, unsigned int index)
Definition: mov.c:3356
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:3927
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:11224
nb_streams
static unsigned int nb_streams
Definition: ffprobe.c:352
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:613
AVCodecParameters::codec_tag
uint32_t codec_tag
Additional information about the codec (corresponds to the AVI FOURCC).
Definition: codec_par.h:61
fixed_key
static const uint8_t fixed_key[]
Definition: aes_ctr.c:45
AV_SPHERICAL_EQUIRECTANGULAR_TILE
@ AV_SPHERICAL_EQUIRECTANGULAR_TILE
Video represents a portion of a sphere mapped on a flat surface using equirectangular projection.
Definition: spherical.h:68
AVStereo3D::baseline
uint32_t baseline
The distance between the centres of the lenses of the camera system, in micrometers.
Definition: stereo3d.h:228
MOVDref::dir
char * dir
Definition: isom.h:88
mov_current_sample_set
static void mov_current_sample_set(MOVStreamContext *sc, int current_sample)
Definition: mov.c:4231
mathematics.h
AVDictionary
Definition: dict.c:32
ffio_init_read_context
void ffio_init_read_context(FFIOContext *s, const uint8_t *buffer, int buffer_size)
Wrap a buffer in an AVIOContext for reading.
Definition: aviobuf.c:99
AV_PKT_FLAG_DISPOSABLE
#define AV_PKT_FLAG_DISPOSABLE
Flag is used to indicate packets that contain frames that can be discarded by the decoder.
Definition: packet.h:669
AVChannelLayout::order
enum AVChannelOrder order
Channel order used in this layout.
Definition: channel_layout.h:324
FFMAX
#define FFMAX(a, b)
Definition: macros.h:47
MOVAtom
Definition: isom.h: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:1602
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
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:2601
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:7154
FFIOContext
Definition: avio_internal.h:28
AV_PKT_FLAG_KEY
#define AV_PKT_FLAG_KEY
The packet contains a keyframe.
Definition: packet.h:650
init_get_bits
static int init_get_bits(GetBitContext *s, const uint8_t *buffer, int bit_size)
Initialize GetBitContext.
Definition: get_bits.h:517
MOVStreamContext::aes_ctr
struct AVAESCTR * aes_ctr
Definition: isom.h:278
cenc_filter
static int cenc_filter(MOVContext *mov, AVStream *st, MOVStreamContext *sc, AVPacket *pkt, int current_index)
Definition: mov.c:8493
mov_read_sdtp
static int mov_read_sdtp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:3680
mov_read_jp2h
static int mov_read_jp2h(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2297
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:5675
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:6255
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:190
AVEncryptionInfo::scheme
uint32_t scheme
The fourcc encryption scheme, in big-endian byte order.
Definition: encryption_info.h:45
MOVStreamContext::stsc_count
unsigned int stsc_count
Definition: isom.h: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:418
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:11761
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:10320
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:1540
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:1908
mov_read_ctts
static int mov_read_ctts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:3729
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:224
mov_read_aclr
static int mov_read_aclr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2374
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:1659
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:6614
mov_read_enda
static int mov_read_enda(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2022
mov_read_chap
static int mov_read_chap(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5722
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:659
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:10334
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:8147
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:1776
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:6686
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:7705
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:4647
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:2329
mov_read_adrm
static int mov_read_adrm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1414
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:191
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:10056
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 frame size, if known.
Definition: codec_par.h:227
mov_read_srat
static int mov_read_srat(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1077
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:10511
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:4122
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:4641
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:6548
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:5196
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
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:1412
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
MOVStreamContext::cenc
struct MOVStreamContext::@478 cenc
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
The width of the video frame in pixels.
Definition: codec_par.h:143
MOVTimeToSample
Definition: isom.h:57
AV_CHANNEL_ORDER_UNSPEC
@ AV_CHANNEL_ORDER_UNSPEC
Only the channel count is specified, without any further information about the channel order.
Definition: channel_layout.h:119
AV_CODEC_ID_MP2
@ AV_CODEC_ID_MP2
Definition: codec_id.h: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:253
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:4151
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:8671
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:417
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:6116
AV_PKT_DATA_STEREO3D
@ AV_PKT_DATA_STEREO3D
This side data should be associated with a video stream and contains Stereoscopic 3D information in f...
Definition: packet.h:111
av_rescale_q
int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq)
Rescale a 64-bit integer by 2 rational numbers.
Definition: mathematics.c:142
ff_iamfdec_read_descriptors
int ff_iamfdec_read_descriptors(IAMFContext *c, AVIOContext *pb, int max_size, void *log_ctx)
Definition: iamf_parse.c: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:11151
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:8651
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:88
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:3412
mov_read_ddts
static int mov_read_ddts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1154
mov_read_uuid
static int mov_read_uuid(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:7308
AVCOL_PRI_UNSPECIFIED
@ AVCOL_PRI_UNSPECIFIED
Definition: pixfmt.h:639
MOVTrackExt::duration
unsigned duration
Definition: isom.h:116
av_fallthrough
#define av_fallthrough
Definition: attributes.h:67
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:4150
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:10130
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:6275
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:7533
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:8901
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:3560
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:3973
set_frag_stream
static void set_frag_stream(MOVFragmentIndex *frag_index, int id)
Definition: mov.c:1639
mov_read_free
static int mov_read_free(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:7413
mov_realloc_extradata
static int mov_realloc_extradata(AVCodecParameters *par, MOVAtom atom)
Definition: mov.c:2224
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:244
AV_PKT_DATA_EXIF
@ AV_PKT_DATA_EXIF
Extensible image file format metadata.
Definition: packet.h:369
AVSEEK_FLAG_BACKWARD
#define AVSEEK_FLAG_BACKWARD
Definition: avformat.h: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:1554
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:10355
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:3810
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:9775
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:11248
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:6457
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:5049
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:8005
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:5349
MOVTimeToSample::duration
unsigned int duration
Definition: isom.h:59
AV_CH_FRONT_CENTER
#define AV_CH_FRONT_CENTER
Definition: channel_layout.h:177
AVCodecParameters::ch_layout
AVChannelLayout ch_layout
The channel layout and number of channels.
Definition: codec_par.h:207
get_frag_stream_info_from_pkt
static MOVFragmentStreamInfo * get_frag_stream_info_from_pkt(MOVFragmentIndex *frag_index, AVPacket *pkt, int id)
Definition: mov.c:8468
get_sgpd_sync_index
static uint32_t get_sgpd_sync_index(const MOVStreamContext *sc, int nal_unit_type)
Definition: mov.c:4569
mov_read_fiel
static int mov_read_fiel(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2190
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:1289
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:1258
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
The number of audio samples per second.
Definition: codec_par.h:213
mov_parse_stsd_subtitle
static void mov_parse_stsd_subtitle(MOVContext *c, AVIOContext *pb, AVStream *st, MOVStreamContext *sc, int64_t size)
Definition: mov.c:2891
cid
uint16_t cid
Definition: mxfenc.c:2335
mov_skip_multiple_stsd
static int mov_skip_multiple_stsd(MOVContext *c, AVIOContext *pb, int codec_tag, int format, int64_t size)
Definition: mov.c:3056
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:645
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:11181
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:521
AV_PKT_DATA_SPHERICAL
@ AV_PKT_DATA_SPHERICAL
This side data should be associated with a video stream and corresponds to the AVSphericalMapping str...
Definition: packet.h:225
AVCodecParameters::extradata_size
int extradata_size
Size of the extradata content in bytes.
Definition: codec_par.h:75
AVIAMFSubmix
Submix layout as defined in section 3.7 of IAMF.
Definition: iamf.h:559
AV_WB32
#define AV_WB32(p, v)
Definition: intreadwrite.h:415
mov_read_pasp
static int mov_read_pasp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1382
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:8811
mov_read_elst
static int mov_read_elst(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6328
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:10908
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:8243
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:2422
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:8309
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:10068
AVPacket::size
int size
Definition: packet.h:596
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:164
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:7482
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:4219
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:5808
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:9412
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:1207
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:3270
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:10721
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:4069
MOVDref::path
char * path
Definition: isom.h:87
mov_current_sample_inc
static void mov_current_sample_inc(MOVStreamContext *sc)
Definition: mov.c:4207
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:594
mov_read_vexu_proj
static int mov_read_vexu_proj(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6904
fix_timescale
static void fix_timescale(MOVContext *c, MOVStreamContext *sc)
Definition: mov.c:5121
avio_r8
int avio_r8(AVIOContext *s)
Definition: aviobuf.c:606
IAMFAudioElement::substreams
IAMFSubStream * substreams
Definition: iamf.h:98
AVSphericalMapping::padding
uint32_t padding
Number of pixels to pad from the edge of each cube face.
Definition: spherical.h:200
a
The reader does not expect b to be semantically here and if the code is changed by maybe adding a a division or other the signedness will almost certainly be mistaken To avoid this confusion a new type was SUINT is the C unsigned type but it holds a signed int to use the same example SUINT a
Definition: undefined.txt:41
av_channel_layout_retype
int av_channel_layout_retype(AVChannelLayout *channel_layout, enum AVChannelOrder order, int flags)
Change the AVChannelOrder of a channel layout.
Definition: channel_layout.c:887
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:9653
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:688
mov_read_packet
static int mov_read_packet(AVFormatContext *s, AVPacket *pkt)
Definition: mov.c:11381
mov_read_infe
static int mov_read_infe(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:9054
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:601
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:10800
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:6585
MOVStreamContext::chunk_offsets
int64_t * chunk_offsets
Definition: isom.h:181
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:233
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:8107
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:9523
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
AVChannelLayout::u
union AVChannelLayout::@515 u
Details about which channels are present in this layout.
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:1878
mov_metadata_hmmt
static int mov_metadata_hmmt(MOVContext *c, AVIOContext *pb, unsigned len)
Definition: mov.c:324
AV_CODEC_ID_MJPEG
@ AV_CODEC_ID_MJPEG
Definition: codec_id.h:59
MOVFragmentStreamInfo::next_trun_dts
int64_t next_trun_dts
Definition: isom.h:144
MOVStreamContext::stsc_index
unsigned int stsc_index
Definition: isom.h:195
av_sha_alloc
struct AVSHA * av_sha_alloc(void)
Allocate an AVSHA context.
Definition: sha.c:46
mov_read_tenc
static int mov_read_tenc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:8036
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:3350
mov_finalize_packet
static int mov_finalize_packet(AVFormatContext *s, AVStream *st, AVIndexEntry *sample, int64_t current_index, AVPacket *pkt)
Definition: mov.c:11317
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:11705
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_malloc
#define av_malloc(s)
Definition: ops_asmgen.c:44
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:588
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:5743
search_frag_timestamp
static int search_frag_timestamp(AVFormatContext *s, MOVFragmentIndex *frag_index, AVStream *st, int64_t timestamp)
Definition: mov.c:1751
HEIFItem::width
int width
Definition: isom.h:302
FLAGS
#define FLAGS
Definition: mov.c:11762
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:4259
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:7884
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:3204
internal.h
AV_SPHERICAL_FISHEYE
@ AV_SPHERICAL_FISHEYE
Fisheye projection (Apple).
Definition: spherical.h:84
AVCodecParameters::height
int height
The height of the video frame in pixels.
Definition: codec_par.h:150
AV_TIME_BASE
#define AV_TIME_BASE
Internal time base represented as integer.
Definition: avutil.h:253
MOVStreamContext::stps_count
unsigned int stps_count
Definition: isom.h:197
AVCodecParameters::block_align
int block_align
The number of bytes per coded audio frame, required by some formats.
Definition: codec_par.h:221
AV_CODEC_ID_TTML
@ AV_CODEC_ID_TTML
Definition: codec_id.h:596
rb_size
static int rb_size(AVIOContext *pb, int64_t *value, int size)
Definition: mov.c:8927
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:3103
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:6413
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:1837
mov_finalize_stsd_codec
static int mov_finalize_stsd_codec(MOVContext *c, AVIOContext *pb, AVStream *st, MOVStreamContext *sc)
Definition: mov.c:2953
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:6504
AV_TIMECODE_FLAG_ALLOWNEGATIVE
@ AV_TIMECODE_FLAG_ALLOWNEGATIVE
negative time values are allowed
Definition: timecode.h:38
AVStreamGroup::params
union AVStreamGroup::@447 params
Group type-specific parameters.
mov_read_mdat
static int mov_read_mdat(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1404
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:5358
mov_read_iref_cdsc
static int mov_read_iref_cdsc(MOVContext *c, AVIOContext *pb, uint32_t type, int version)
Definition: mov.c:9268
AVCodecParameters::color_range
enum AVColorRange color_range
Additional colorspace characteristics.
Definition: codec_par.h:189
AV_CH_SIDE_RIGHT
#define AV_CH_SIDE_RIGHT
Definition: channel_layout.h:185
len
int len
Definition: vorbis_enc_data.h:426
AV_CODEC_ID_JPEG2000
@ AV_CODEC_ID_JPEG2000
Definition: codec_id.h: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:10870
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:4710
AVCodecParameters::coded_side_data
AVPacketSideData * coded_side_data
Additional data associated with the entire stream.
Definition: codec_par.h:83
mov_read_svq3
static int mov_read_svq3(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2417
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
The order of the fields in interlaced video.
Definition: codec_par.h:182
av_get_packet
int av_get_packet(AVIOContext *s, AVPacket *pkt, int size)
Allocate and read the payload of a packet and initialize its fields with default values.
Definition: utils.c:98
mov_read_iinf
static int mov_read_iinf(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:9131
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:1699
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:4110
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
AVCodecParameters::avcodec_parameters_copy
int avcodec_parameters_copy(AVCodecParameters *dst, const AVCodecParameters *src)
Copy the contents of src to dst.
Definition: codec_par.c:107
mov_read_tmcd
static int mov_read_tmcd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6402
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:7587
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
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:695
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:8616
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:550
mov_read_tfdt
static int mov_read_tfdt(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5769
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:5485
search_frag_moof_offset
static int search_frag_moof_offset(MOVFragmentIndex *frag_index, int64_t offset)
Definition: mov.c:1675
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:11188
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:11553
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:2706
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:1111
get_frag_time
static int64_t get_frag_time(AVFormatContext *s, AVStream *dst_st, MOVFragmentIndex *frag_index, int index)
Definition: mov.c:1709
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:3866
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:2479
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:7245
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:443
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:6767
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:1515
mov_get_skip_samples
static int64_t mov_get_skip_samples(AVStream *st, int sample)
Definition: mov.c:11688
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:597
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:10201
mov_read_sbas
static int mov_read_sbas(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2550
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
av_realloc
#define av_realloc(p, s)
Definition: ops_asmgen.c:46
MOV_MERGE_CTTS
#define MOV_MERGE_CTTS
Definition: mov.c:4640
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:2302
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:9983
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:113
mov_parse_tiles
static int mov_parse_tiles(AVFormatContext *s)
Definition: mov.c:10595
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:9185
mov_read_pcmc
static int mov_read_pcmc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2031
build_open_gop_key_points
static int build_open_gop_key_points(AVStream *st)
Definition: mov.c:4577
mov_parse_stsd_audio
static void mov_parse_stsd_audio(MOVContext *c, AVIOContext *pb, AVStream *st, MOVStreamContext *sc)
Definition: mov.c:2770
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:10009
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
Number of delayed frames.
Definition: codec_par.h:200
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:441
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:10219
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:57
AVStereo3DView
AVStereo3DView
List of possible view types.
Definition: stereo3d.h:149
AVPacket
This structure stores compressed data.
Definition: packet.h:572
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:10816
mov_read_hfov
static int mov_read_hfov(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:7216
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:615
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:6977
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:9969
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:11824
AVCodecParameters::bit_rate
int64_t bit_rate
The average bitrate of the encoded data (in bits per second).
Definition: codec_par.h:99
MOVStts::count
unsigned int count
Definition: isom.h:64
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
MOVStreamContext::display_matrix
int32_t * display_matrix
Definition: isom.h: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:8452
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:9351
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:9306
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:1273
mov_read_mfra
static int mov_read_mfra(MOVContext *c, AVIOContext *f)
Definition: mov.c:10274
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:1620
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:8722
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
Number of padding audio samples at the start.
Definition: codec_par.h:239
AV_CODEC_ID_PCM_S24BE
@ AV_CODEC_ID_PCM_S24BE
Definition: codec_id.h:351
mov_read_st3d
static int mov_read_st3d(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6639
mov_read_imir
static int mov_read_imir(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:9393
is_open_key_sample
static int is_open_key_sample(const MOVStreamContext *sc, int sample)
Definition: mov.c:11572
mov_read_dvc1
static int mov_read_dvc1(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2525
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:2239
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:9870
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
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:8184
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:2907
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_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:8946
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:3467