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( 'p','c','s','t'): key = "podcast";
397  case MKTAG( 'p','g','a','p'): key = "gapless_playback";
399  case MKTAG( 'p','u','r','d'): key = "purchase_date"; break;
400  case MKTAG( 'r','t','n','g'): key = "rating";
402  case MKTAG( 's','o','a','a'): key = "sort_album_artist"; break;
403  case MKTAG( 's','o','a','l'): key = "sort_album"; break;
404  case MKTAG( 's','o','a','r'): key = "sort_artist"; break;
405  case MKTAG( 's','o','c','o'): key = "sort_composer"; break;
406  case MKTAG( 's','o','n','m'): key = "sort_name"; break;
407  case MKTAG( 's','o','s','n'): key = "sort_show"; break;
408  case MKTAG( 's','t','i','k'): key = "media_type";
410  case MKTAG( 't','r','k','n'): key = "track";
412  case MKTAG( 't','v','e','n'): key = "episode_id"; break;
413  case MKTAG( 't','v','e','s'): key = "episode_sort";
415  case MKTAG( 't','v','n','n'): key = "network"; break;
416  case MKTAG( 't','v','s','h'): key = "show"; break;
417  case MKTAG( 't','v','s','n'): key = "season_number";
419  case MKTAG(0xa9,'A','R','T'): key = "artist"; break;
420  case MKTAG(0xa9,'P','R','D'): key = "producer"; break;
421  case MKTAG(0xa9,'a','l','b'): key = "album"; break;
422  case MKTAG(0xa9,'a','u','t'): key = "artist"; break;
423  case MKTAG(0xa9,'c','h','p'): key = "chapter"; break;
424  case MKTAG(0xa9,'c','m','t'): key = "comment"; break;
425  case MKTAG(0xa9,'c','o','m'): key = "composer"; break;
426  case MKTAG(0xa9,'c','p','y'): key = "copyright"; break;
427  case MKTAG(0xa9,'d','a','y'): key = "date"; break;
428  case MKTAG(0xa9,'d','i','r'): key = "director"; break;
429  case MKTAG(0xa9,'d','i','s'): key = "disclaimer"; break;
430  case MKTAG(0xa9,'e','d','1'): key = "edit_date"; break;
431  case MKTAG(0xa9,'e','n','c'): key = "encoder"; break;
432  case MKTAG(0xa9,'f','m','t'): key = "original_format"; break;
433  case MKTAG(0xa9,'g','e','n'): key = "genre"; break;
434  case MKTAG(0xa9,'g','r','p'): key = "grouping"; break;
435  case MKTAG(0xa9,'h','s','t'): key = "host_computer"; break;
436  case MKTAG(0xa9,'i','n','f'): key = "comment"; break;
437  case MKTAG(0xa9,'l','y','r'): key = "lyrics"; break;
438  case MKTAG(0xa9,'m','a','k'): key = "make"; break;
439  case MKTAG(0xa9,'m','o','d'): key = "model"; break;
440  case MKTAG(0xa9,'n','a','m'): key = "title"; break;
441  case MKTAG(0xa9,'o','p','e'): key = "original_artist"; break;
442  case MKTAG(0xa9,'p','r','d'): key = "producer"; break;
443  case MKTAG(0xa9,'p','r','f'): key = "performers"; break;
444  case MKTAG(0xa9,'r','e','q'): key = "playback_requirements"; break;
445  case MKTAG(0xa9,'s','r','c'): key = "original_source"; break;
446  case MKTAG(0xa9,'s','t','3'): key = "subtitle"; break;
447  case MKTAG(0xa9,'s','w','r'): key = "encoder"; break;
448  case MKTAG(0xa9,'t','o','o'): key = "encoder"; break;
449  case MKTAG(0xa9,'t','r','k'): key = "track"; break;
450  case MKTAG(0xa9,'u','r','l'): key = "URL"; break;
451  case MKTAG(0xa9,'w','r','n'): key = "warning"; break;
452  case MKTAG(0xa9,'w','r','t'): key = "composer"; break;
453  case MKTAG(0xa9,'x','y','z'): key = "location"; break;
454  }
455 retry:
456  if (c->itunes_metadata && atom.size > 8) {
457  int data_size = avio_rb32(pb);
458  int tag = avio_rl32(pb);
459  if (tag == MKTAG('d','a','t','a') && data_size <= atom.size && data_size >= 16) {
460  data_type = avio_rb32(pb); // type
461  avio_rb32(pb); // unknown
462  str_size = data_size - 16;
463  atom.size -= 16;
464 
465  if (!key && c->found_hdlr_mdta && c->meta_keys) {
466  uint32_t index = av_bswap32(atom.type); // BE number has been read as LE
467  if (index < c->meta_keys_count && index > 0) {
468  key = c->meta_keys[index];
469  } else if (atom.type != MKTAG('c', 'o', 'v', 'r')) {
470  av_log(c->fc, AV_LOG_WARNING,
471  "The index of 'data' is out of range: %"PRId32" < 1 or >= %d.\n",
472  index, c->meta_keys_count);
473  }
474  }
475  if (atom.type == MKTAG('c', 'o', 'v', 'r') ||
476  (key && !strcmp(key, "com.apple.quicktime.artwork"))) {
477  int ret = mov_read_covr(c, pb, data_type, str_size);
478  if (ret < 0) {
479  av_log(c->fc, AV_LOG_ERROR, "Error parsing cover art.\n");
480  return ret;
481  }
482  atom.size -= str_size;
483  if (atom.size > 8)
484  goto retry;
485  return ret;
486  }
487  } else return 0;
488  } else if (atom.size > 4 && (key || c->export_all) && !c->itunes_metadata && !raw) {
489  str_size = avio_rb16(pb); // string length
490  if (str_size > atom.size) {
491  raw = 1;
492  avio_seek(pb, -2, SEEK_CUR);
493  av_log(c->fc, AV_LOG_WARNING, "UDTA parsing failed retrying raw\n");
494  goto retry;
495  }
496  langcode = avio_rb16(pb);
497  ff_mov_lang_to_iso639(langcode, language);
498  atom.size -= 4;
499  } else
500  str_size = atom.size;
501 
502  if (c->export_all && !key) {
503  key = av_fourcc_make_string(tmp_key, atom.type);
504  }
505 
506  if (!key)
507  return 0;
508  if (atom.size < 0 || str_size >= INT_MAX/2)
509  return AVERROR_INVALIDDATA;
510 
511  // Allocates enough space if data_type is a int32 or float32 number, otherwise
512  // worst-case requirement for output string in case of utf8 coded input
513  num = (data_type >= 21 && data_type <= 23);
514  str_size_alloc = (num ? 512 : (raw ? str_size : str_size * 2)) + 1;
515  str = av_mallocz(str_size_alloc);
516  if (!str)
517  return AVERROR(ENOMEM);
518 
519  if (parse)
520  parse(c, pb, str_size, key);
521  else {
522  if (!raw && (data_type == 3 || (data_type == 0 && (langcode < 0x400 || langcode == 0x7fff)))) { // MAC Encoded
523  mov_read_mac_string(c, pb, str_size, str, str_size_alloc);
524  } else if (data_type == 21) { // BE signed integer, variable size
525  int val = 0;
526  if (str_size == 1)
527  val = (int8_t)avio_r8(pb);
528  else if (str_size == 2)
529  val = (int16_t)avio_rb16(pb);
530  else if (str_size == 3)
531  val = ((int32_t)(avio_rb24(pb)<<8))>>8;
532  else if (str_size == 4)
533  val = (int32_t)avio_rb32(pb);
534  if (snprintf(str, str_size_alloc, "%d", val) >= str_size_alloc) {
535  av_log(c->fc, AV_LOG_ERROR,
536  "Failed to store the number (%d) in string.\n", val);
537  av_free(str);
538  return AVERROR_INVALIDDATA;
539  }
540  } else if (data_type == 22) { // BE unsigned integer, variable size
541  unsigned int val = 0;
542  if (str_size == 1)
543  val = avio_r8(pb);
544  else if (str_size == 2)
545  val = avio_rb16(pb);
546  else if (str_size == 3)
547  val = avio_rb24(pb);
548  else if (str_size == 4)
549  val = avio_rb32(pb);
550  if (snprintf(str, str_size_alloc, "%u", val) >= str_size_alloc) {
551  av_log(c->fc, AV_LOG_ERROR,
552  "Failed to store the number (%u) in string.\n", val);
553  av_free(str);
554  return AVERROR_INVALIDDATA;
555  }
556  } else if (data_type == 23 && str_size >= 4) { // BE float32
557  float val = av_int2float(avio_rb32(pb));
558  if (snprintf(str, str_size_alloc, "%f", val) >= str_size_alloc) {
559  av_log(c->fc, AV_LOG_ERROR,
560  "Failed to store the float32 number (%f) in string.\n", val);
561  av_free(str);
562  return AVERROR_INVALIDDATA;
563  }
564  } else if (data_type > 1 && data_type != 4) {
565  // data_type can be 0 if not set at all above. data_type 1 means
566  // UTF8 and 4 means "UTF8 sort". For any other type (UTF16 or e.g.
567  // a picture), don't return it blindly in a string that is supposed
568  // to be UTF8 text.
569  av_log(c->fc, AV_LOG_WARNING, "Skipping unhandled metadata %s of type %d\n", key, data_type);
570  av_free(str);
571  return 0;
572  } else {
573  int ret = ffio_read_size(pb, str, str_size);
574  if (ret < 0) {
575  av_free(str);
576  return ret;
577  }
578  str[str_size] = 0;
579  }
580  c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
581  av_dict_set(metadata, key, str, 0);
582  if (*language && strcmp(language, "und")) {
583  snprintf(key2, sizeof(key2), "%s-%s", key, language);
584  av_dict_set(metadata, key2, str, 0);
585  }
586  if (!strcmp(key, "encoder")) {
587  int major, minor, micro;
588  if (sscanf(str, "HandBrake %d.%d.%d", &major, &minor, &micro) == 3) {
589  c->handbrake_version = 1000000*major + 1000*minor + micro;
590  }
591  }
592  }
593 
594  av_freep(&str);
595  return 0;
596 }
597 
599 {
600  int64_t start;
601  int i, nb_chapters, str_len, version;
602  char str[256+1];
603  int ret;
604 
605  if (c->ignore_chapters)
606  return 0;
607 
608  if ((atom.size -= 5) < 0)
609  return 0;
610 
611  version = avio_r8(pb);
612  avio_rb24(pb);
613  if (version)
614  avio_rb32(pb); // ???
615  nb_chapters = avio_r8(pb);
616 
617  for (i = 0; i < nb_chapters; i++) {
618  if (atom.size < 9)
619  return 0;
620 
621  start = avio_rb64(pb);
622  str_len = avio_r8(pb);
623 
624  if ((atom.size -= 9+str_len) < 0)
625  return 0;
626 
627  ret = ffio_read_size(pb, str, str_len);
628  if (ret < 0)
629  return ret;
630  str[str_len] = 0;
631  avpriv_new_chapter(c->fc, i, (AVRational){1,10000000}, start, AV_NOPTS_VALUE, str);
632  }
633  return 0;
634 }
635 
636 #define MIN_DATA_ENTRY_BOX_SIZE 12
638 {
639  AVStream *st;
640  MOVStreamContext *sc;
641  int entries, i, j;
642 
643  if (c->fc->nb_streams < 1)
644  return 0;
645  st = c->fc->streams[c->fc->nb_streams-1];
646  sc = st->priv_data;
647 
648  avio_rb32(pb); // version + flags
649  entries = avio_rb32(pb);
650  if (!entries ||
651  entries > (atom.size - 1) / MIN_DATA_ENTRY_BOX_SIZE + 1 ||
652  entries >= UINT_MAX / sizeof(*sc->drefs))
653  return AVERROR_INVALIDDATA;
654 
655  for (i = 0; i < sc->drefs_count; i++) {
656  MOVDref *dref = &sc->drefs[i];
657  av_freep(&dref->path);
658  av_freep(&dref->dir);
659  }
660  av_free(sc->drefs);
661  sc->drefs_count = 0;
662  sc->drefs = av_mallocz(entries * sizeof(*sc->drefs));
663  if (!sc->drefs)
664  return AVERROR(ENOMEM);
665  sc->drefs_count = entries;
666 
667  for (i = 0; i < entries; i++) {
668  MOVDref *dref = &sc->drefs[i];
669  uint32_t size = avio_rb32(pb);
670  int64_t next = avio_tell(pb);
671 
672  if (size < 12 || next < 0 || next > INT64_MAX - size)
673  return AVERROR_INVALIDDATA;
674 
675  next += size - 4;
676 
677  dref->type = avio_rl32(pb);
678  avio_rb32(pb); // version + flags
679 
680  if (dref->type == MKTAG('a','l','i','s') && size > 150) {
681  /* macintosh alias record */
682  uint16_t volume_len, len;
683  int16_t type;
684  int ret;
685 
686  avio_skip(pb, 10);
687 
688  volume_len = avio_r8(pb);
689  volume_len = FFMIN(volume_len, 27);
690  ret = ffio_read_size(pb, dref->volume, 27);
691  if (ret < 0)
692  return ret;
693  dref->volume[volume_len] = 0;
694  av_log(c->fc, AV_LOG_DEBUG, "volume %s, len %d\n", dref->volume, volume_len);
695 
696  avio_skip(pb, 12);
697 
698  len = avio_r8(pb);
699  len = FFMIN(len, 63);
700  ret = ffio_read_size(pb, dref->filename, 63);
701  if (ret < 0)
702  return ret;
703  dref->filename[len] = 0;
704  av_log(c->fc, AV_LOG_DEBUG, "filename %s, len %d\n", dref->filename, len);
705 
706  avio_skip(pb, 16);
707 
708  /* read next level up_from_alias/down_to_target */
709  dref->nlvl_from = avio_rb16(pb);
710  dref->nlvl_to = avio_rb16(pb);
711  av_log(c->fc, AV_LOG_DEBUG, "nlvl from %d, nlvl to %d\n",
712  dref->nlvl_from, dref->nlvl_to);
713 
714  avio_skip(pb, 16);
715 
716  for (type = 0; type != -1 && avio_tell(pb) < next; ) {
717  if (avio_feof(pb))
718  return AVERROR_EOF;
719  type = avio_rb16(pb);
720  len = avio_rb16(pb);
721  av_log(c->fc, AV_LOG_DEBUG, "type %d, len %d\n", type, len);
722  if (len&1)
723  len += 1;
724  if (type == 2) { // absolute path
725  av_free(dref->path);
726  dref->path = av_mallocz(len+1);
727  if (!dref->path)
728  return AVERROR(ENOMEM);
729 
730  ret = ffio_read_size(pb, dref->path, len);
731  if (ret < 0) {
732  av_freep(&dref->path);
733  return ret;
734  }
735  if (len > volume_len && !strncmp(dref->path, dref->volume, volume_len)) {
736  len -= volume_len;
737  memmove(dref->path, dref->path+volume_len, len);
738  dref->path[len] = 0;
739  }
740  // trim string of any ending zeros
741  for (j = len - 1; j >= 0; j--) {
742  if (dref->path[j] == 0)
743  len--;
744  else
745  break;
746  }
747  for (j = 0; j < len; j++)
748  if (dref->path[j] == ':' || dref->path[j] == 0)
749  dref->path[j] = '/';
750  av_log(c->fc, AV_LOG_DEBUG, "path %s\n", dref->path);
751  } else if (type == 0) { // directory name
752  av_free(dref->dir);
753  dref->dir = av_malloc(len+1);
754  if (!dref->dir)
755  return AVERROR(ENOMEM);
756 
757  ret = ffio_read_size(pb, dref->dir, len);
758  if (ret < 0) {
759  av_freep(&dref->dir);
760  return ret;
761  }
762  dref->dir[len] = 0;
763  for (j = 0; j < len; j++)
764  if (dref->dir[j] == ':')
765  dref->dir[j] = '/';
766  av_log(c->fc, AV_LOG_DEBUG, "dir %s\n", dref->dir);
767  } else
768  avio_skip(pb, len);
769  }
770  } else {
771  av_log(c->fc, AV_LOG_DEBUG, "Unknown dref type 0x%08"PRIx32" size %"PRIu32"\n",
772  dref->type, size);
773  entries--;
774  i--;
775  }
776  avio_seek(pb, next, SEEK_SET);
777  }
778  return 0;
779 }
780 
782 {
783  AVStream *st;
784  uint32_t type;
785  uint32_t ctype;
786  int64_t title_size;
787  char *title_str;
788  int ret;
789 
790  avio_r8(pb); /* version */
791  avio_rb24(pb); /* flags */
792 
793  /* component type */
794  ctype = avio_rl32(pb);
795  type = avio_rl32(pb); /* component subtype */
796 
797  av_log(c->fc, AV_LOG_TRACE, "ctype=%s\n", av_fourcc2str(ctype));
798  av_log(c->fc, AV_LOG_TRACE, "stype=%s\n", av_fourcc2str(type));
799 
800  if (c->trak_index < 0) { // meta not inside a trak
801  if (type == MKTAG('m','d','t','a')) {
802  c->found_hdlr_mdta = 1;
803  }
804  return 0;
805  }
806 
807  st = c->fc->streams[c->fc->nb_streams-1];
808 
809  if (type == MKTAG('v','i','d','e'))
811  else if (type == MKTAG('s','o','u','n'))
813  else if (type == MKTAG('m','1','a',' '))
815  else if ((type == MKTAG('s','u','b','p')) || (type == MKTAG('c','l','c','p')))
817 
818  avio_rb32(pb); /* component manufacture */
819  avio_rb32(pb); /* component flags */
820  avio_rb32(pb); /* component flags mask */
821 
822  title_size = atom.size - 24;
823  if (title_size > 0) {
824  if (title_size > FFMIN(INT_MAX, SIZE_MAX-1))
825  return AVERROR_INVALIDDATA;
826  title_str = av_malloc(title_size + 1); /* Add null terminator */
827  if (!title_str)
828  return AVERROR(ENOMEM);
829 
830  ret = ffio_read_size(pb, title_str, title_size);
831  if (ret < 0) {
832  av_freep(&title_str);
833  return ret;
834  }
835  title_str[title_size] = 0;
836  if (title_str[0]) {
837  int off = (!c->isom && title_str[0] == title_size - 1);
838  // flag added so as to not set stream handler name if already set from mdia->hdlr
839  av_dict_set(&st->metadata, "handler_name", title_str + off, AV_DICT_DONT_OVERWRITE);
840  }
841  av_freep(&title_str);
842  }
843 
844  return 0;
845 }
846 
848 {
849  return ff_mov_read_esds(c->fc, pb);
850 }
851 
853 {
854  AVStream *st;
855  AVPacketSideData *sd;
856  enum AVAudioServiceType *ast;
857  int ac3info, acmod, lfeon, bsmod;
858  uint64_t mask;
859 
860  if (c->fc->nb_streams < 1)
861  return 0;
862  st = c->fc->streams[c->fc->nb_streams-1];
863 
867  sizeof(*ast), 0);
868  if (!sd)
869  return AVERROR(ENOMEM);
870 
871  ast = (enum AVAudioServiceType*)sd->data;
872  ac3info = avio_rb24(pb);
873  bsmod = (ac3info >> 14) & 0x7;
874  acmod = (ac3info >> 11) & 0x7;
875  lfeon = (ac3info >> 10) & 0x1;
876 
878  if (lfeon)
882 
883  *ast = bsmod;
884  if (st->codecpar->ch_layout.nb_channels > 1 && bsmod == 0x7)
886 
887  return 0;
888 }
889 
890 #if CONFIG_IAMFDEC
891 static int mov_read_iacb(MOVContext *c, AVIOContext *pb, MOVAtom atom)
892 {
893  AVStream *st;
894  MOVStreamContext *sc;
895  FFIOContext b;
896  AVIOContext *descriptor_pb;
898  IAMFContext *iamf;
900  unsigned descriptors_size;
901  int nb_frames, disposition;
902  int version, ret;
903 
904  if (atom.size < 5)
905  return AVERROR_INVALIDDATA;
906 
907  if (c->fc->nb_streams < 1)
908  return 0;
909 
910  version = avio_r8(pb);
911  if (version != 1) {
912  av_log(c->fc, AV_LOG_ERROR, "%s configurationVersion %d",
913  version < 1 ? "invalid" : "unsupported", version);
914  return AVERROR_INVALIDDATA;
915  }
916 
917  descriptors_size = ffio_read_leb(pb);
918  if (!descriptors_size || descriptors_size > INT_MAX)
919  return AVERROR_INVALIDDATA;
920 
921  st = c->fc->streams[c->fc->nb_streams - 1];
922  sc = st->priv_data;
923 
924  if (st->codecpar->extradata) {
925  av_log(c->fc, AV_LOG_WARNING, "ignoring iacb\n");
926  return 0;
927  }
928 
929  sc->iamf = av_mallocz(sizeof(*sc->iamf));
930  if (!sc->iamf)
931  return AVERROR(ENOMEM);
932  iamf = &sc->iamf->iamf;
933 
934  st->codecpar->extradata = av_malloc(descriptors_size);
935  if (!st->codecpar->extradata)
936  return AVERROR(ENOMEM);
937  st->codecpar->extradata_size = descriptors_size;
938 
939  ret = avio_read(pb, st->codecpar->extradata, descriptors_size);
940  if (ret != descriptors_size)
941  return ret < 0 ? ret : AVERROR_INVALIDDATA;
942 
943  ffio_init_read_context(&b, st->codecpar->extradata, descriptors_size);
944  descriptor_pb = &b.pub;
945 
946  ret = ff_iamfdec_read_descriptors(iamf, descriptor_pb, descriptors_size, c->fc);
947  if (ret < 0)
948  return ret;
949 
950  metadata = st->metadata;
951  st->metadata = NULL;
952  start_time = st->start_time;
953  nb_frames = st->nb_frames;
954  duration = st->duration;
955  disposition = st->disposition;
956 
957  for (int i = 0; i < iamf->nb_audio_elements; i++) {
958  IAMFAudioElement *audio_element = iamf->audio_elements[i];
959  const AVIAMFAudioElement *element;
960  AVStreamGroup *stg =
962 
963  if (!stg) {
964  ret = AVERROR(ENOMEM);
965  goto fail;
966  }
967 
969  stg->id = audio_element->audio_element_id;
970  /* Transfer ownership */
971  element = stg->params.iamf_audio_element = audio_element->element;
972  audio_element->element = NULL;
973 
974  for (int j = 0; j < audio_element->nb_substreams; j++) {
975  IAMFSubStream *substream = &audio_element->substreams[j];
976  AVStream *stream;
977 
978  if (!i && !j) {
979  if (audio_element->layers[0].substream_count != 1)
980  disposition &= ~AV_DISPOSITION_DEFAULT;
981  stream = st;
982  } else
983  stream = avformat_new_stream(c->fc, NULL);
984  if (!stream) {
985  ret = AVERROR(ENOMEM);
986  goto fail;
987  }
988 
989  stream->start_time = start_time;
990  stream->nb_frames = nb_frames;
991  stream->duration = duration;
992  stream->disposition = disposition;
993  if (stream != st) {
994  stream->priv_data = sc;
995  sc->refcount++;
996  }
997 
1000  if (i || j) {
1002  if (audio_element->layers[0].substream_count == 1)
1003  stream->disposition &= ~AV_DISPOSITION_DEFAULT;
1004  }
1005 
1006  ret = avcodec_parameters_copy(stream->codecpar, substream->codecpar);
1007  if (ret < 0)
1008  goto fail;
1009 
1010  stream->id = substream->audio_substream_id;
1011 
1012  avpriv_set_pts_info(st, 64, 1, sc->time_scale);
1013 
1014  ret = avformat_stream_group_add_stream(stg, stream);
1015  if (ret < 0)
1016  goto fail;
1017  }
1018 
1019  ret = av_dict_copy(&stg->metadata, metadata, 0);
1020  if (ret < 0)
1021  goto fail;
1022  }
1023 
1024  for (int i = 0; i < iamf->nb_mix_presentations; i++) {
1025  IAMFMixPresentation *mix_presentation = iamf->mix_presentations[i];
1026  const AVIAMFMixPresentation *mix = mix_presentation->cmix;
1027  AVStreamGroup *stg =
1029 
1030  if (!stg) {
1031  ret = AVERROR(ENOMEM);
1032  goto fail;
1033  }
1034 
1036  stg->id = mix_presentation->mix_presentation_id;
1037  /* Transfer ownership */
1038  stg->params.iamf_mix_presentation = mix_presentation->mix;
1039  mix_presentation->mix = NULL;
1040 
1041  for (int j = 0; j < mix->nb_submixes; j++) {
1042  const AVIAMFSubmix *submix = mix->submixes[j];
1043 
1044  for (int k = 0; k < submix->nb_elements; k++) {
1045  const AVIAMFSubmixElement *submix_element = submix->elements[k];
1046  const AVStreamGroup *audio_element = NULL;
1047 
1048  for (int l = 0; l < c->fc->nb_stream_groups; l++)
1049  if (c->fc->stream_groups[l]->type == AV_STREAM_GROUP_PARAMS_IAMF_AUDIO_ELEMENT &&
1050  c->fc->stream_groups[l]->id == submix_element->audio_element_id) {
1051  audio_element = c->fc->stream_groups[l];
1052  break;
1053  }
1054  av_assert0(audio_element);
1055 
1056  for (int l = 0; l < audio_element->nb_streams; l++) {
1057  ret = avformat_stream_group_add_stream(stg, audio_element->streams[l]);
1058  if (ret < 0 && ret != AVERROR(EEXIST))
1059  goto fail;
1060  }
1061  }
1062  }
1063 
1064  ret = av_dict_copy(&stg->metadata, metadata, 0);
1065  if (ret < 0)
1066  goto fail;
1067  }
1068 
1069  ret = 0;
1070 fail:
1072 
1073  return ret;
1074 }
1075 #endif
1076 
1078 {
1079  AVStream *st;
1080  AVPacketSideData *sd;
1081  enum AVAudioServiceType *ast;
1082  int eac3info, acmod, lfeon, bsmod;
1083  uint64_t mask;
1084 
1085  if (c->fc->nb_streams < 1)
1086  return 0;
1087  st = c->fc->streams[c->fc->nb_streams-1];
1088 
1092  sizeof(*ast), 0);
1093  if (!sd)
1094  return AVERROR(ENOMEM);
1095 
1096  ast = (enum AVAudioServiceType*)sd->data;
1097 
1098  /* No need to parse fields for additional independent substreams and its
1099  * associated dependent substreams since libavcodec's E-AC-3 decoder
1100  * does not support them yet. */
1101  avio_rb16(pb); /* data_rate and num_ind_sub */
1102  eac3info = avio_rb24(pb);
1103  bsmod = (eac3info >> 12) & 0x1f;
1104  acmod = (eac3info >> 9) & 0x7;
1105  lfeon = (eac3info >> 8) & 0x1;
1106 
1108  if (lfeon)
1112 
1113  *ast = bsmod;
1114  if (st->codecpar->ch_layout.nb_channels > 1 && bsmod == 0x7)
1116 
1117  return 0;
1118 }
1119 
1121 {
1122 #define DDTS_SIZE 20
1123  uint8_t buf[DDTS_SIZE + AV_INPUT_BUFFER_PADDING_SIZE];
1124  AVStream *st = NULL;
1125  uint32_t frame_duration_code = 0;
1126  uint32_t channel_layout_code = 0;
1127  GetBitContext gb;
1128  int ret;
1129 
1130  if ((ret = ffio_read_size(pb, buf, DDTS_SIZE)) < 0)
1131  return ret;
1132 
1133  init_get_bits(&gb, buf, 8 * DDTS_SIZE);
1134 
1135  if (c->fc->nb_streams < 1) {
1136  return 0;
1137  }
1138  st = c->fc->streams[c->fc->nb_streams-1];
1139 
1140  st->codecpar->sample_rate = get_bits_long(&gb, 32);
1141  if (st->codecpar->sample_rate <= 0) {
1142  av_log(c->fc, AV_LOG_ERROR, "Invalid sample rate %d\n", st->codecpar->sample_rate);
1143  return AVERROR_INVALIDDATA;
1144  }
1145  skip_bits_long(&gb, 32); /* max bitrate */
1146  st->codecpar->bit_rate = get_bits_long(&gb, 32);
1147  st->codecpar->bits_per_coded_sample = get_bits(&gb, 8);
1148  frame_duration_code = get_bits(&gb, 2);
1149  skip_bits(&gb, 30); /* various fields */
1150  channel_layout_code = get_bits(&gb, 16);
1151 
1152  st->codecpar->frame_size =
1153  (frame_duration_code == 0) ? 512 :
1154  (frame_duration_code == 1) ? 1024 :
1155  (frame_duration_code == 2) ? 2048 :
1156  (frame_duration_code == 3) ? 4096 : 0;
1157 
1158  if (channel_layout_code > 0xff) {
1159  av_log(c->fc, AV_LOG_WARNING, "Unsupported DTS audio channel layout\n");
1160  }
1163  ((channel_layout_code & 0x1) ? AV_CH_FRONT_CENTER : 0) |
1164  ((channel_layout_code & 0x2) ? AV_CH_FRONT_LEFT : 0) |
1165  ((channel_layout_code & 0x2) ? AV_CH_FRONT_RIGHT : 0) |
1166  ((channel_layout_code & 0x4) ? AV_CH_SIDE_LEFT : 0) |
1167  ((channel_layout_code & 0x4) ? AV_CH_SIDE_RIGHT : 0) |
1168  ((channel_layout_code & 0x8) ? AV_CH_LOW_FREQUENCY : 0));
1169 
1170  return 0;
1171 }
1172 
1174 {
1175  AVStream *st;
1176 
1177  if (c->fc->nb_streams < 1)
1178  return 0;
1179  st = c->fc->streams[c->fc->nb_streams-1];
1180 
1181  if (atom.size < 16)
1182  return 0;
1183 
1184  /* skip version and flags */
1185  avio_skip(pb, 4);
1186 
1187  ff_mov_read_chan(c->fc, pb, st, atom.size - 4);
1188 
1189  return 0;
1190 }
1191 
1193 {
1194  int64_t end = av_sat_add64(avio_tell(pb), atom.size);
1195  int version, flags;
1196  int ret;
1197  AVStream *st;
1198 
1199  if (c->fc->nb_streams < 1)
1200  return 0;
1201  st = c->fc->streams[c->fc->nb_streams-1];
1202 
1203  version = avio_r8(pb);
1204  flags = avio_rb24(pb);
1205  if (version != 0 || flags != 0) {
1206  av_log(c->fc, AV_LOG_ERROR,
1207  "Unsupported 'chnl' box with version %d, flags: %#x",
1208  version, flags);
1209  return AVERROR_INVALIDDATA;
1210  }
1211 
1212  ret = ff_mov_read_chnl(c->fc, pb, st);
1213  if (ret < 0)
1214  return ret;
1215 
1216  if (avio_tell(pb) != end) {
1217  av_log(c->fc, AV_LOG_WARNING, "skip %" PRId64 " bytes of unknown data inside chnl\n",
1218  end - avio_tell(pb));
1219  avio_seek(pb, end, SEEK_SET);
1220  }
1221  return ret;
1222 }
1223 
1225 {
1226  AVStream *st;
1227  int ret;
1228 
1229  if (c->fc->nb_streams < 1)
1230  return 0;
1231  st = c->fc->streams[c->fc->nb_streams-1];
1232 
1233  if ((ret = ff_get_wav_header(c->fc, pb, st->codecpar, atom.size, 0)) < 0)
1234  av_log(c->fc, AV_LOG_WARNING, "get_wav_header failed\n");
1235 
1236  return ret;
1237 }
1238 
1240 {
1241  AVStream *st;
1242  HEIFItem *item;
1243  AVPacketSideData *sd;
1244  int width, height, err = 0;
1245  AVRational aperture_width, aperture_height, horiz_off, vert_off;
1246  AVRational pc_x, pc_y;
1247  uint64_t top, bottom, left, right;
1248 
1249  item = get_heif_item(c, c->cur_item_id);
1250  st = get_curr_st(c);
1251  if (!st)
1252  return 0;
1253 
1254  width = st->codecpar->width;
1255  height = st->codecpar->height;
1256  if ((!width || !height) && item) {
1257  width = item->width;
1258  height = item->height;
1259  }
1260  if (!width || !height) {
1261  err = AVERROR_INVALIDDATA;
1262  goto fail;
1263  }
1264 
1265  aperture_width.num = avio_rb32(pb);
1266  aperture_width.den = avio_rb32(pb);
1267  aperture_height.num = avio_rb32(pb);
1268  aperture_height.den = avio_rb32(pb);
1269 
1270  horiz_off.num = avio_rb32(pb);
1271  horiz_off.den = avio_rb32(pb);
1272  vert_off.num = avio_rb32(pb);
1273  vert_off.den = avio_rb32(pb);
1274 
1275  if (aperture_width.num < 0 || aperture_width.den < 0 ||
1276  aperture_height.num < 0 || aperture_height.den < 0 ||
1277  horiz_off.den < 0 || vert_off.den < 0) {
1278  err = AVERROR_INVALIDDATA;
1279  goto fail;
1280  }
1281  if ((av_cmp_q((AVRational) { width, 1 }, aperture_width) < 0) ||
1282  (av_cmp_q((AVRational) { height, 1 }, aperture_height) < 0)) {
1283  err = AVERROR_INVALIDDATA;
1284  goto fail;
1285  }
1286  av_log(c->fc, AV_LOG_TRACE, "clap: apertureWidth %d/%d, apertureHeight %d/%d "
1287  "horizOff %d/%d vertOff %d/%d\n",
1288  aperture_width.num, aperture_width.den, aperture_height.num, aperture_height.den,
1289  horiz_off.num, horiz_off.den, vert_off.num, vert_off.den);
1290 
1291  pc_x = av_mul_q((AVRational) { width - 1, 1 }, (AVRational) { 1, 2 });
1292  pc_x = av_add_q(pc_x, horiz_off);
1293  pc_y = av_mul_q((AVRational) { height - 1, 1 }, (AVRational) { 1, 2 });
1294  pc_y = av_add_q(pc_y, vert_off);
1295 
1296  aperture_width = av_sub_q(aperture_width, (AVRational) { 1, 1 });
1297  aperture_width = av_mul_q(aperture_width, (AVRational) { 1, 2 });
1298  aperture_height = av_sub_q(aperture_height, (AVRational) { 1, 1 });
1299  aperture_height = av_mul_q(aperture_height, (AVRational) { 1, 2 });
1300 
1301  left = av_q2d(av_sub_q(pc_x, aperture_width));
1302  right = av_q2d(av_add_q(pc_x, aperture_width));
1303  top = av_q2d(av_sub_q(pc_y, aperture_height));
1304  bottom = av_q2d(av_add_q(pc_y, aperture_height));
1305 
1306  if (bottom > (height - 1) ||
1307  right > (width - 1)) {
1308  err = AVERROR_INVALIDDATA;
1309  goto fail;
1310  }
1311 
1312  bottom = height - 1 - bottom;
1313  right = width - 1 - right;
1314 
1315  if (!(left | right | top | bottom))
1316  return 0;
1317 
1318  if ((left + right) >= width ||
1319  (top + bottom) >= height) {
1320  err = AVERROR_INVALIDDATA;
1321  goto fail;
1322  }
1323 
1327  sizeof(uint32_t) * 4, 0);
1328  if (!sd)
1329  return AVERROR(ENOMEM);
1330 
1331  AV_WL32A(sd->data, top);
1332  AV_WL32A(sd->data + 4, bottom);
1333  AV_WL32A(sd->data + 8, left);
1334  AV_WL32A(sd->data + 12, right);
1335 
1336 fail:
1337  if (err < 0) {
1338  int explode = !!(c->fc->error_recognition & AV_EF_EXPLODE);
1339  av_log(c->fc, explode ? AV_LOG_ERROR : AV_LOG_WARNING, "Invalid clap box\n");
1340  if (!explode)
1341  err = 0;
1342  }
1343 
1344  return err;
1345 }
1346 
1347 /* This atom overrides any previously set aspect ratio */
1349 {
1350  const int num = avio_rb32(pb);
1351  const int den = avio_rb32(pb);
1352  AVStream *st;
1353  MOVStreamContext *sc;
1354 
1355  if (c->fc->nb_streams < 1)
1356  return 0;
1357  st = c->fc->streams[c->fc->nb_streams-1];
1358  sc = st->priv_data;
1359 
1360  av_log(c->fc, AV_LOG_TRACE, "pasp: hSpacing %d, vSpacing %d\n", num, den);
1361 
1362  if (den != 0) {
1363  sc->h_spacing = num;
1364  sc->v_spacing = den;
1365  }
1366  return 0;
1367 }
1368 
1369 /* this atom contains actual media data */
1371 {
1372  if (atom.size == 0) /* wrong one (MP4) */
1373  return 0;
1374  c->found_mdat=1;
1375  return 0; /* now go for moov */
1376 }
1377 
1378 #define DRM_BLOB_SIZE 56
1379 
1381 {
1382  uint8_t intermediate_key[20];
1383  uint8_t intermediate_iv[20];
1384  uint8_t input[64];
1385  uint8_t output[64];
1386  uint8_t file_checksum[20];
1387  uint8_t calculated_checksum[20];
1388  char checksum_string[2 * sizeof(file_checksum) + 1];
1389  struct AVSHA *sha;
1390  int i;
1391  int ret = 0;
1392  uint8_t *activation_bytes = c->activation_bytes;
1393  uint8_t *fixed_key = c->audible_fixed_key;
1394 
1395  c->aax_mode = 1;
1396 
1397  sha = av_sha_alloc();
1398  if (!sha)
1399  return AVERROR(ENOMEM);
1400  av_free(c->aes_decrypt);
1401  c->aes_decrypt = av_aes_alloc();
1402  if (!c->aes_decrypt) {
1403  ret = AVERROR(ENOMEM);
1404  goto fail;
1405  }
1406 
1407  /* drm blob processing */
1408  avio_read(pb, output, 8); // go to offset 8, absolute position 0x251
1410  avio_read(pb, output, 4); // go to offset 4, absolute position 0x28d
1411  ret = ffio_read_size(pb, file_checksum, 20);
1412  if (ret < 0)
1413  goto fail;
1414 
1415  // required by external tools
1416  ff_data_to_hex(checksum_string, file_checksum, sizeof(file_checksum), 1);
1417  av_log(c->fc, AV_LOG_INFO, "[aax] file checksum == %s\n", checksum_string);
1418 
1419  /* verify activation data */
1420  if (!activation_bytes) {
1421  av_log(c->fc, AV_LOG_WARNING, "[aax] activation_bytes option is missing!\n");
1422  ret = 0; /* allow ffprobe to continue working on .aax files */
1423  goto fail;
1424  }
1425  if (c->activation_bytes_size != 4) {
1426  av_log(c->fc, AV_LOG_FATAL, "[aax] activation_bytes value needs to be 4 bytes!\n");
1427  ret = AVERROR(EINVAL);
1428  goto fail;
1429  }
1430 
1431  /* verify fixed key */
1432  if (c->audible_fixed_key_size != 16) {
1433  av_log(c->fc, AV_LOG_FATAL, "[aax] audible_fixed_key value needs to be 16 bytes!\n");
1434  ret = AVERROR(EINVAL);
1435  goto fail;
1436  }
1437 
1438  /* AAX (and AAX+) key derivation */
1439  av_sha_init(sha, 160);
1440  av_sha_update(sha, fixed_key, 16);
1441  av_sha_update(sha, activation_bytes, 4);
1442  av_sha_final(sha, intermediate_key);
1443  av_sha_init(sha, 160);
1444  av_sha_update(sha, fixed_key, 16);
1445  av_sha_update(sha, intermediate_key, 20);
1446  av_sha_update(sha, activation_bytes, 4);
1447  av_sha_final(sha, intermediate_iv);
1448  av_sha_init(sha, 160);
1449  av_sha_update(sha, intermediate_key, 16);
1450  av_sha_update(sha, intermediate_iv, 16);
1451  av_sha_final(sha, calculated_checksum);
1452  if (memcmp(calculated_checksum, file_checksum, 20)) { // critical error
1453  av_log(c->fc, AV_LOG_ERROR, "[aax] mismatch in checksums!\n");
1455  goto fail;
1456  }
1457  av_aes_init(c->aes_decrypt, intermediate_key, 128, 1);
1458  av_aes_crypt(c->aes_decrypt, output, input, DRM_BLOB_SIZE >> 4, intermediate_iv, 1);
1459  for (i = 0; i < 4; i++) {
1460  // file data (in output) is stored in big-endian mode
1461  if (activation_bytes[i] != output[3 - i]) { // critical error
1462  av_log(c->fc, AV_LOG_ERROR, "[aax] error in drm blob decryption!\n");
1464  goto fail;
1465  }
1466  }
1467  memcpy(c->file_key, output + 8, 16);
1468  memcpy(input, output + 26, 16);
1469  av_sha_init(sha, 160);
1470  av_sha_update(sha, input, 16);
1471  av_sha_update(sha, c->file_key, 16);
1472  av_sha_update(sha, fixed_key, 16);
1473  av_sha_final(sha, c->file_iv);
1474 
1475 fail:
1476  av_free(sha);
1477 
1478  return ret;
1479 }
1480 
1482 {
1483  if (c->audible_key_size != 16) {
1484  av_log(c->fc, AV_LOG_FATAL, "[aaxc] audible_key value needs to be 16 bytes!\n");
1485  return AVERROR(EINVAL);
1486  }
1487 
1488  if (c->audible_iv_size != 16) {
1489  av_log(c->fc, AV_LOG_FATAL, "[aaxc] audible_iv value needs to be 16 bytes!\n");
1490  return AVERROR(EINVAL);
1491  }
1492 
1493  c->aes_decrypt = av_aes_alloc();
1494  if (!c->aes_decrypt) {
1495  return AVERROR(ENOMEM);
1496  }
1497 
1498  memcpy(c->file_key, c->audible_key, 16);
1499  memcpy(c->file_iv, c->audible_iv, 16);
1500  c->aax_mode = 1;
1501 
1502  return 0;
1503 }
1504 
1505 // Audible AAX (and AAX+) bytestream decryption
1506 static int aax_filter(uint8_t *input, int size, MOVContext *c)
1507 {
1508  int blocks = 0;
1509  unsigned char iv[16];
1510 
1511  memcpy(iv, c->file_iv, 16); // iv is overwritten
1512  blocks = size >> 4; // trailing bytes are not encrypted!
1513  av_aes_init(c->aes_decrypt, c->file_key, 128, 1);
1514  av_aes_crypt(c->aes_decrypt, input, input, blocks, iv, 1);
1515 
1516  return 0;
1517 }
1518 
1519 /* read major brand, minor version and compatible brands and store them as metadata */
1521 {
1522  uint32_t minor_ver;
1523  int comp_brand_size;
1524  char* comp_brands_str;
1525  uint8_t type[5] = {0};
1526  int ret = ffio_read_size(pb, type, 4);
1527  if (ret < 0)
1528  return ret;
1529  if (c->fc->nb_streams) {
1530  if (c->fc->strict_std_compliance >= FF_COMPLIANCE_STRICT)
1531  return AVERROR_INVALIDDATA;
1532  av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate FTYP\n");
1533  return 0;
1534  }
1535 
1536  if (strcmp(type, "qt "))
1537  c->isom = 1;
1538  av_log(c->fc, AV_LOG_DEBUG, "ISO: File Type Major Brand: %.4s\n",(char *)&type);
1539  av_dict_set(&c->fc->metadata, "major_brand", type, 0);
1540  minor_ver = avio_rb32(pb); /* minor version */
1541  av_dict_set_int(&c->fc->metadata, "minor_version", minor_ver, 0);
1542 
1543  comp_brand_size = atom.size - 8;
1544  if (comp_brand_size < 0 || comp_brand_size == INT_MAX)
1545  return AVERROR_INVALIDDATA;
1546  comp_brands_str = av_malloc(comp_brand_size + 1); /* Add null terminator */
1547  if (!comp_brands_str)
1548  return AVERROR(ENOMEM);
1549 
1550  ret = ffio_read_size(pb, comp_brands_str, comp_brand_size);
1551  if (ret < 0) {
1552  av_freep(&comp_brands_str);
1553  return ret;
1554  }
1555  comp_brands_str[comp_brand_size] = 0;
1556  av_dict_set(&c->fc->metadata, "compatible_brands",
1557  comp_brands_str, AV_DICT_DONT_STRDUP_VAL);
1558 
1559  // Logic for handling Audible's .aaxc files
1560  if (!strcmp(type, "aaxc")) {
1561  mov_aaxc_crypto(c);
1562  }
1563 
1564  return 0;
1565 }
1566 
1567 /* this atom should contain all header atoms */
1569 {
1570  int ret;
1571 
1572  if (c->found_moov) {
1573  av_log(c->fc, AV_LOG_WARNING, "Found duplicated MOOV Atom. Skipped it\n");
1574  avio_skip(pb, atom.size);
1575  return 0;
1576  }
1577 
1578  if ((ret = mov_read_default(c, pb, atom)) < 0)
1579  return ret;
1580  /* we parsed the 'moov' atom, we can terminate the parsing as soon as we find the 'mdat' */
1581  /* so we don't parse the whole file if over a network */
1582  c->found_moov=1;
1583  return 0; /* now go for mdat */
1584 }
1585 
1587  MOVFragmentIndex *frag_index,
1588  int index,
1589  int id)
1590 {
1591  int i;
1592  MOVFragmentIndexItem * item;
1593 
1594  if (index < 0 || index >= frag_index->nb_items)
1595  return NULL;
1596  item = &frag_index->item[index];
1597  for (i = 0; i < item->nb_stream_info; i++)
1598  if (item->stream_info[i].id == id)
1599  return &item->stream_info[i];
1600 
1601  // This shouldn't happen
1602  return NULL;
1603 }
1604 
1605 static void set_frag_stream(MOVFragmentIndex *frag_index, int id)
1606 {
1607  int i;
1608  MOVFragmentIndexItem * item;
1609 
1610  if (frag_index->current < 0 ||
1611  frag_index->current >= frag_index->nb_items)
1612  return;
1613 
1614  item = &frag_index->item[frag_index->current];
1615  for (i = 0; i < item->nb_stream_info; i++)
1616  if (item->stream_info[i].id == id) {
1617  item->current = i;
1618  return;
1619  }
1620 
1621  // id not found. This shouldn't happen.
1622  item->current = -1;
1623 }
1624 
1626  MOVFragmentIndex *frag_index)
1627 {
1628  MOVFragmentIndexItem *item;
1629  if (frag_index->current < 0 ||
1630  frag_index->current >= frag_index->nb_items)
1631  return NULL;
1632 
1633  item = &frag_index->item[frag_index->current];
1634  if (item->current >= 0 && item->current < item->nb_stream_info)
1635  return &item->stream_info[item->current];
1636 
1637  // This shouldn't happen
1638  return NULL;
1639 }
1640 
1642 {
1643  int a, b, m;
1644  int64_t moof_offset;
1645 
1646  // Optimize for appending new entries
1647  if (!frag_index->nb_items ||
1648  frag_index->item[frag_index->nb_items - 1].moof_offset < offset)
1649  return frag_index->nb_items;
1650 
1651  a = -1;
1652  b = frag_index->nb_items;
1653 
1654  while (b - a > 1) {
1655  m = (a + b) >> 1;
1656  moof_offset = frag_index->item[m].moof_offset;
1657  if (moof_offset >= offset)
1658  b = m;
1659  if (moof_offset <= offset)
1660  a = m;
1661  }
1662  return b;
1663 }
1664 
1666 {
1667  av_assert0(frag_stream_info);
1668  if (frag_stream_info->sidx_pts != AV_NOPTS_VALUE)
1669  return frag_stream_info->sidx_pts;
1670  if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE)
1671  return frag_stream_info->first_tfra_pts;
1672  return frag_stream_info->tfdt_dts;
1673 }
1674 
1676  MOVFragmentIndex *frag_index, int index)
1677 {
1678  MOVFragmentStreamInfo * frag_stream_info;
1679  MOVStreamContext *sc = dst_st->priv_data;
1680  int64_t timestamp;
1681  int i, j;
1682 
1683  // If the stream is referenced by any sidx, limit the search
1684  // to fragments that referenced this stream in the sidx
1685  if (sc->has_sidx) {
1686  frag_stream_info = get_frag_stream_info(frag_index, index, sc->id);
1687  if (!frag_stream_info)
1688  return AV_NOPTS_VALUE;
1689  if (frag_stream_info->sidx_pts != AV_NOPTS_VALUE)
1690  return frag_stream_info->sidx_pts;
1691  if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE)
1692  return frag_stream_info->first_tfra_pts;
1693  return frag_stream_info->sidx_pts;
1694  }
1695 
1696  for (i = 0; i < frag_index->item[index].nb_stream_info; i++) {
1697  AVStream *frag_stream = NULL;
1698  frag_stream_info = &frag_index->item[index].stream_info[i];
1699  for (j = 0; j < s->nb_streams; j++) {
1700  MOVStreamContext *sc2 = s->streams[j]->priv_data;
1701  if (sc2->id == frag_stream_info->id)
1702  frag_stream = s->streams[j];
1703  }
1704  if (!frag_stream) {
1705  av_log(s, AV_LOG_WARNING, "No stream matching sidx ID found.\n");
1706  continue;
1707  }
1708  timestamp = get_stream_info_time(frag_stream_info);
1709  if (timestamp != AV_NOPTS_VALUE)
1710  return av_rescale_q(timestamp, frag_stream->time_base, dst_st->time_base);
1711  }
1712  return AV_NOPTS_VALUE;
1713 }
1714 
1716  AVStream *st, int64_t timestamp)
1717 {
1718  int a, b, m, m0;
1719  int64_t frag_time;
1720 
1721  a = -1;
1722  b = frag_index->nb_items;
1723 
1724  while (b - a > 1) {
1725  m0 = m = (a + b) >> 1;
1726 
1727  while (m < b &&
1728  (frag_time = get_frag_time(s, st, frag_index, m)) == AV_NOPTS_VALUE)
1729  m++;
1730 
1731  if (m < b && frag_time <= timestamp)
1732  a = m;
1733  else
1734  b = m0;
1735  }
1736 
1737  return a;
1738 }
1739 
1741 {
1742  int index, i;
1743  MOVFragmentIndexItem * item;
1744  MOVFragmentStreamInfo * frag_stream_info;
1745 
1746  // If moof_offset already exists in frag_index, return index to it
1747  index = search_frag_moof_offset(&c->frag_index, offset);
1748  if (index < c->frag_index.nb_items &&
1749  c->frag_index.item[index].moof_offset == offset)
1750  return index;
1751 
1752  // offset is not yet in frag index.
1753  // Insert new item at index (sorted by moof offset)
1754  item = av_fast_realloc(c->frag_index.item,
1755  &c->frag_index.allocated_size,
1756  (c->frag_index.nb_items + 1) *
1757  sizeof(*c->frag_index.item));
1758  if (!item)
1759  return -1;
1760  c->frag_index.item = item;
1761 
1762  frag_stream_info = av_realloc_array(NULL, c->fc->nb_streams,
1763  sizeof(*item->stream_info));
1764  if (!frag_stream_info)
1765  return -1;
1766 
1767  for (i = 0; i < c->fc->nb_streams; i++) {
1768  // Avoid building frag index if streams lack track id.
1769  MOVStreamContext *sc = c->fc->streams[i]->priv_data;
1770  if (sc->id < 0) {
1771  av_free(frag_stream_info);
1772  return AVERROR_INVALIDDATA;
1773  }
1774 
1775  frag_stream_info[i].id = sc->id;
1776  frag_stream_info[i].sidx_pts = AV_NOPTS_VALUE;
1777  frag_stream_info[i].tfdt_dts = AV_NOPTS_VALUE;
1778  frag_stream_info[i].next_trun_dts = AV_NOPTS_VALUE;
1779  frag_stream_info[i].first_tfra_pts = AV_NOPTS_VALUE;
1780  frag_stream_info[i].index_base = -1;
1781  frag_stream_info[i].index_entry = -1;
1782  frag_stream_info[i].encryption_index = NULL;
1783  frag_stream_info[i].stsd_id = -1;
1784  }
1785 
1786  if (index < c->frag_index.nb_items)
1787  memmove(c->frag_index.item + index + 1, c->frag_index.item + index,
1788  (c->frag_index.nb_items - index) * sizeof(*c->frag_index.item));
1789 
1790  item = &c->frag_index.item[index];
1791  item->headers_read = 0;
1792  item->current = 0;
1793  item->nb_stream_info = c->fc->nb_streams;
1794  item->moof_offset = offset;
1795  item->stream_info = frag_stream_info;
1796  c->frag_index.nb_items++;
1797 
1798  return index;
1799 }
1800 
1801 static void fix_frag_index_entries(MOVFragmentIndex *frag_index, int index,
1802  int id, int entries)
1803 {
1804  int i;
1805  MOVFragmentStreamInfo * frag_stream_info;
1806 
1807  if (index < 0)
1808  return;
1809  for (i = index; i < frag_index->nb_items; i++) {
1810  frag_stream_info = get_frag_stream_info(frag_index, i, id);
1811  if (frag_stream_info && frag_stream_info->index_entry >= 0)
1812  frag_stream_info->index_entry += entries;
1813  }
1814 }
1815 
1817 {
1818  // Set by mov_read_tfhd(). mov_read_trun() will reject files missing tfhd.
1819  c->fragment.found_tfhd = 0;
1820 
1821  if (!c->has_looked_for_mfra && c->use_mfra_for > 0) {
1822  c->has_looked_for_mfra = 1;
1823  if (pb->seekable & AVIO_SEEKABLE_NORMAL) {
1824  int ret;
1825  av_log(c->fc, AV_LOG_VERBOSE, "stream has moof boxes, will look "
1826  "for a mfra\n");
1827  if ((ret = mov_read_mfra(c, pb)) < 0) {
1828  av_log(c->fc, AV_LOG_VERBOSE, "found a moof box but failed to "
1829  "read the mfra (may be a live ismv)\n");
1830  }
1831  } else {
1832  av_log(c->fc, AV_LOG_VERBOSE, "found a moof box but stream is not "
1833  "seekable, can not look for mfra\n");
1834  }
1835  }
1836  c->fragment.moof_offset = c->fragment.implicit_offset = avio_tell(pb) - 8;
1837  av_log(c->fc, AV_LOG_TRACE, "moof offset %"PRIx64"\n", c->fragment.moof_offset);
1838  c->frag_index.current = update_frag_index(c, c->fragment.moof_offset);
1839  return mov_read_default(c, pb, atom);
1840 }
1841 
1843 {
1844  int64_t time;
1845  if (version == 1) {
1846  time = avio_rb64(pb);
1847  avio_rb64(pb);
1848  if (time < 0) {
1849  av_log(c->fc, AV_LOG_DEBUG, "creation_time is negative\n");
1850  return;
1851  }
1852  } else {
1853  time = avio_rb32(pb);
1854  avio_rb32(pb); /* modification time */
1855  if (time > 0 && time < 2082844800) {
1856  av_log(c->fc, AV_LOG_WARNING, "Detected creation time before 1970, parsing as unix timestamp.\n");
1857  time += 2082844800;
1858  }
1859  }
1860  if (time) {
1861  time -= 2082844800; /* seconds between 1904-01-01 and Epoch */
1862 
1863  if ((int64_t)(time * 1000000ULL) / 1000000 != time) {
1864  av_log(c->fc, AV_LOG_DEBUG, "creation_time is not representable\n");
1865  return;
1866  }
1867 
1868  ff_dict_set_timestamp(metadata, "creation_time", time * 1000000);
1869  }
1870 }
1871 
1873 {
1874  AVStream *st;
1875  MOVStreamContext *sc;
1876  int version;
1877  char language[4] = {0};
1878  unsigned lang;
1879 
1880  if (c->fc->nb_streams < 1)
1881  return 0;
1882  st = c->fc->streams[c->fc->nb_streams-1];
1883  sc = st->priv_data;
1884 
1885  if (sc->time_scale) {
1886  av_log(c->fc, AV_LOG_ERROR, "Multiple mdhd?\n");
1887  return AVERROR_INVALIDDATA;
1888  }
1889 
1890  version = avio_r8(pb);
1891  if (version > 1) {
1892  avpriv_request_sample(c->fc, "Version %d", version);
1893  return AVERROR_PATCHWELCOME;
1894  }
1895  avio_rb24(pb); /* flags */
1897 
1898  sc->time_scale = avio_rb32(pb);
1899  if (sc->time_scale <= 0) {
1900  av_log(c->fc, AV_LOG_ERROR, "Invalid mdhd time scale %d, defaulting to 1\n", sc->time_scale);
1901  sc->time_scale = 1;
1902  }
1903  st->duration = (version == 1) ? avio_rb64(pb) : avio_rb32(pb); /* duration */
1904 
1905  if ((version == 1 && st->duration == UINT64_MAX) ||
1906  (version != 1 && st->duration == UINT32_MAX)) {
1907  st->duration = 0;
1908  }
1909 
1910  lang = avio_rb16(pb); /* language */
1911  if (ff_mov_lang_to_iso639(lang, language))
1912  av_dict_set(&st->metadata, "language", language, 0);
1913  avio_rb16(pb); /* quality */
1914 
1915  return 0;
1916 }
1917 
1919 {
1920  int i;
1921  int version = avio_r8(pb); /* version */
1922  avio_rb24(pb); /* flags */
1923 
1924  mov_metadata_creation_time(c, pb, &c->fc->metadata, version);
1925  c->time_scale = avio_rb32(pb); /* time scale */
1926  if (c->time_scale <= 0) {
1927  av_log(c->fc, AV_LOG_ERROR, "Invalid mvhd time scale %d, defaulting to 1\n", c->time_scale);
1928  c->time_scale = 1;
1929  }
1930  av_log(c->fc, AV_LOG_TRACE, "time scale = %i\n", c->time_scale);
1931 
1932  c->duration = (version == 1) ? avio_rb64(pb) : avio_rb32(pb); /* duration */
1933  avio_rb32(pb); /* preferred scale */
1934 
1935  avio_rb16(pb); /* preferred volume */
1936 
1937  avio_skip(pb, 10); /* reserved */
1938 
1939  /* movie display matrix, store it in main context and use it later on */
1940  for (i = 0; i < 3; i++) {
1941  c->movie_display_matrix[i][0] = avio_rb32(pb); // 16.16 fixed point
1942  c->movie_display_matrix[i][1] = avio_rb32(pb); // 16.16 fixed point
1943  c->movie_display_matrix[i][2] = avio_rb32(pb); // 2.30 fixed point
1944  }
1945 
1946  avio_rb32(pb); /* preview time */
1947  avio_rb32(pb); /* preview duration */
1948  avio_rb32(pb); /* poster time */
1949  avio_rb32(pb); /* selection time */
1950  avio_rb32(pb); /* selection duration */
1951  avio_rb32(pb); /* current time */
1952  avio_rb32(pb); /* next track ID */
1953 
1954  return 0;
1955 }
1956 
1958 {
1959  AVStream *st;
1960 
1961  if (fc->nb_streams < 1)
1962  return;
1963  st = fc->streams[fc->nb_streams-1];
1964 
1965  switch (st->codecpar->codec_id) {
1966  case AV_CODEC_ID_PCM_S16BE:
1968  break;
1969  case AV_CODEC_ID_PCM_S24BE:
1971  break;
1972  case AV_CODEC_ID_PCM_S32BE:
1974  break;
1975  case AV_CODEC_ID_PCM_F32BE:
1977  break;
1978  case AV_CODEC_ID_PCM_F64BE:
1980  break;
1981  default:
1982  break;
1983  }
1984 }
1985 
1987 {
1988  int little_endian = avio_rb16(pb) & 0xFF;
1989  av_log(c->fc, AV_LOG_TRACE, "enda %d\n", little_endian);
1990  if (little_endian == 1)
1992  return 0;
1993 }
1994 
1996 {
1997  int format_flags;
1998  int version, flags;
1999  int pcm_sample_size;
2000  AVFormatContext *fc = c->fc;
2001  AVStream *st;
2002  MOVStreamContext *sc;
2003 
2004  if (atom.size < 6) {
2005  av_log(c->fc, AV_LOG_ERROR, "Empty pcmC box\n");
2006  return AVERROR_INVALIDDATA;
2007  }
2008 
2009  version = avio_r8(pb);
2010  flags = avio_rb24(pb);
2011 
2012  if (version != 0 || flags != 0) {
2013  av_log(c->fc, AV_LOG_ERROR,
2014  "Unsupported 'pcmC' box with version %d, flags: %x",
2015  version, flags);
2016  return AVERROR_INVALIDDATA;
2017  }
2018 
2019  format_flags = avio_r8(pb);
2020  pcm_sample_size = avio_r8(pb);
2021 
2022  if (fc->nb_streams < 1)
2023  return AVERROR_INVALIDDATA;
2024 
2025  st = fc->streams[fc->nb_streams - 1];
2026  sc = st->priv_data;
2027 
2028  if (sc->format == MOV_MP4_FPCM_TAG) {
2029  switch (pcm_sample_size) {
2030  case 32:
2032  break;
2033  case 64:
2035  break;
2036  default:
2037  av_log(fc, AV_LOG_ERROR, "invalid pcm_sample_size %d for %s\n",
2038  pcm_sample_size,
2039  av_fourcc2str(sc->format));
2040  return AVERROR_INVALIDDATA;
2041  }
2042  } else if (sc->format == MOV_MP4_IPCM_TAG) {
2043  switch (pcm_sample_size) {
2044  case 16:
2046  break;
2047  case 24:
2049  break;
2050  case 32:
2052  break;
2053  default:
2054  av_log(fc, AV_LOG_ERROR, "invalid pcm_sample_size %d for %s\n",
2055  pcm_sample_size,
2056  av_fourcc2str(sc->format));
2057  return AVERROR_INVALIDDATA;
2058  }
2059  } else {
2060  av_log(fc, AV_LOG_ERROR, "'pcmC' with invalid sample entry '%s'\n",
2061  av_fourcc2str(sc->format));
2062  return AVERROR_INVALIDDATA;
2063  }
2064 
2065  if (format_flags & 1) // indicates little-endian format. If not present, big-endian format is used
2068 
2069  return 0;
2070 }
2071 
2073 {
2074  AVStream *st;
2075  HEIFItem *item = NULL;
2076  char color_parameter_type[5] = { 0 };
2077  uint16_t color_primaries, color_trc, color_matrix;
2078  int ret;
2079 
2080  st = get_curr_st(c);
2081  if (!st) {
2082  item = get_heif_item(c, c->cur_item_id);
2083  if (!item)
2084  return 0;
2085  }
2086 
2087  ret = ffio_read_size(pb, color_parameter_type, 4);
2088  if (ret < 0)
2089  return ret;
2090  if (strncmp(color_parameter_type, "nclx", 4) &&
2091  strncmp(color_parameter_type, "nclc", 4) &&
2092  strncmp(color_parameter_type, "prof", 4)) {
2093  av_log(c->fc, AV_LOG_WARNING, "unsupported color_parameter_type %s\n",
2094  color_parameter_type);
2095  return 0;
2096  }
2097 
2098  if (!strncmp(color_parameter_type, "prof", 4)) {
2099  AVPacketSideData *sd;
2100  uint8_t *icc_profile;
2101  if (st) {
2105  atom.size - 4, 0);
2106  if (!sd)
2107  return AVERROR(ENOMEM);
2108  icc_profile = sd->data;
2109  } else {
2110  av_freep(&item->icc_profile);
2111  icc_profile = item->icc_profile = av_malloc(atom.size - 4);
2112  if (!icc_profile) {
2113  item->icc_profile_size = 0;
2114  return AVERROR(ENOMEM);
2115  }
2116  item->icc_profile_size = atom.size - 4;
2117  }
2118  ret = ffio_read_size(pb, icc_profile, atom.size - 4);
2119  if (ret < 0)
2120  return ret;
2121  } else if (st) {
2122  color_primaries = avio_rb16(pb);
2123  color_trc = avio_rb16(pb);
2124  color_matrix = avio_rb16(pb);
2125 
2126  av_log(c->fc, AV_LOG_TRACE,
2127  "%s: pri %d trc %d matrix %d",
2128  color_parameter_type, color_primaries, color_trc, color_matrix);
2129 
2130  if (!strncmp(color_parameter_type, "nclx", 4)) {
2131  uint8_t color_range = avio_r8(pb) >> 7;
2132  av_log(c->fc, AV_LOG_TRACE, " full %"PRIu8"", color_range);
2133  if (color_range)
2135  else
2137  }
2138 
2141  if (!av_color_transfer_name(color_trc))
2142  color_trc = AVCOL_TRC_UNSPECIFIED;
2143  if (!av_color_space_name(color_matrix))
2144  color_matrix = AVCOL_SPC_UNSPECIFIED;
2145 
2147  st->codecpar->color_trc = color_trc;
2148  st->codecpar->color_space = color_matrix;
2149  av_log(c->fc, AV_LOG_TRACE, "\n");
2150  }
2151  return 0;
2152 }
2153 
2155 {
2156  AVStream *st;
2157  unsigned mov_field_order;
2158  enum AVFieldOrder decoded_field_order = AV_FIELD_UNKNOWN;
2159 
2160  if (c->fc->nb_streams < 1) // will happen with jp2 files
2161  return 0;
2162  st = c->fc->streams[c->fc->nb_streams-1];
2163  if (atom.size < 2)
2164  return AVERROR_INVALIDDATA;
2165  mov_field_order = avio_rb16(pb);
2166  if ((mov_field_order & 0xFF00) == 0x0100)
2167  decoded_field_order = AV_FIELD_PROGRESSIVE;
2168  else if ((mov_field_order & 0xFF00) == 0x0200) {
2169  switch (mov_field_order & 0xFF) {
2170  case 0x01: decoded_field_order = AV_FIELD_TT;
2171  break;
2172  case 0x06: decoded_field_order = AV_FIELD_BB;
2173  break;
2174  case 0x09: decoded_field_order = AV_FIELD_TB;
2175  break;
2176  case 0x0E: decoded_field_order = AV_FIELD_BT;
2177  break;
2178  }
2179  }
2180  if (decoded_field_order == AV_FIELD_UNKNOWN && mov_field_order) {
2181  av_log(c->fc, AV_LOG_ERROR, "Unknown MOV field order 0x%04x\n", mov_field_order);
2182  }
2183  st->codecpar->field_order = decoded_field_order;
2184 
2185  return 0;
2186 }
2187 
2189 {
2190  int err = 0;
2191  uint64_t size = (uint64_t)par->extradata_size + atom.size + 8 + AV_INPUT_BUFFER_PADDING_SIZE;
2192  if (size > INT_MAX || (uint64_t)atom.size > INT_MAX)
2193  return AVERROR_INVALIDDATA;
2194  if ((err = av_reallocp(&par->extradata, size)) < 0) {
2195  par->extradata_size = 0;
2196  return err;
2197  }
2199  return 0;
2200 }
2201 
2202 /* Read a whole atom into the extradata return the size of the atom read, possibly truncated if != atom.size */
2204  AVCodecParameters *par, uint8_t *buf)
2205 {
2206  int64_t result = atom.size;
2207  int err;
2208 
2209  AV_WB32(buf , atom.size + 8);
2210  AV_WL32(buf + 4, atom.type);
2211  err = ffio_read_size(pb, buf + 8, atom.size);
2212  if (err < 0) {
2213  par->extradata_size -= atom.size;
2214  return err;
2215  } else if (err < atom.size) {
2216  av_log(c->fc, AV_LOG_WARNING, "truncated extradata\n");
2217  par->extradata_size -= atom.size - err;
2218  result = err;
2219  }
2220  memset(buf + 8 + err, 0, AV_INPUT_BUFFER_PADDING_SIZE);
2221  return result;
2222 }
2223 
2224 /* FIXME modify QDM2/SVQ3/H.264 decoders to take full atom as extradata */
2226  enum AVCodecID codec_id)
2227 {
2228  AVStream *st;
2229  uint64_t original_size;
2230  int err;
2231 
2232  if (c->fc->nb_streams < 1) // will happen with jp2 files
2233  return 0;
2234  st = c->fc->streams[c->fc->nb_streams-1];
2235 
2236  if (st->codecpar->codec_id != codec_id)
2237  return 0; /* unexpected codec_id - don't mess with extradata */
2238 
2239  original_size = st->codecpar->extradata_size;
2240  err = mov_realloc_extradata(st->codecpar, atom);
2241  if (err)
2242  return err;
2243 
2244  err = mov_read_atom_into_extradata(c, pb, atom, st->codecpar, st->codecpar->extradata + original_size);
2245  if (err < 0)
2246  return err;
2247  return 0; // Note: this is the original behavior to ignore truncation.
2248 }
2249 
2250 /* wrapper functions for reading ALAC/AVS/MJPEG/MJPEG2000 extradata atoms only for those codecs */
2252 {
2253  return mov_read_extradata(c, pb, atom, AV_CODEC_ID_ALAC);
2254 }
2255 
2257 {
2258  return mov_read_extradata(c, pb, atom, AV_CODEC_ID_CAVS);
2259 }
2260 
2262 {
2263  return mov_read_extradata(c, pb, atom, AV_CODEC_ID_JPEG2000);
2264 }
2265 
2267 {
2268  return mov_read_extradata(c, pb, atom, AV_CODEC_ID_R10K);
2269 }
2270 
2272 {
2273  int ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_AVUI);
2274  if (!ret)
2275  ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_DNXHD);
2276  return ret;
2277 }
2278 
2280 {
2281  int ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_TARGA_Y216);
2282 
2283  if (!ret && c->fc->nb_streams >= 1) {
2284  AVCodecParameters *par = c->fc->streams[c->fc->nb_streams-1]->codecpar;
2285  if (par->extradata_size >= 40) {
2286  par->height = AV_RB16(&par->extradata[36]);
2287  par->width = AV_RB16(&par->extradata[38]);
2288  }
2289  }
2290  return ret;
2291 }
2292 
2294 {
2295  if (c->fc->nb_streams >= 1) {
2296  AVStream *const st = c->fc->streams[c->fc->nb_streams - 1];
2297  FFStream *const sti = ffstream(st);
2298  AVCodecParameters *par = st->codecpar;
2299 
2300  if (par->codec_tag == MKTAG('A', 'V', 'i', 'n') &&
2301  par->codec_id == AV_CODEC_ID_H264 &&
2302  atom.size > 11) {
2303  int cid;
2304  avio_skip(pb, 10);
2305  cid = avio_rb16(pb);
2306  /* For AVID AVCI50, force width of 1440 to be able to select the correct SPS and PPS */
2307  if (cid == 0xd4d || cid == 0xd4e)
2308  par->width = 1440;
2309  return 0;
2310  } else if ((par->codec_tag == MKTAG('A', 'V', 'd', '1') ||
2311  par->codec_tag == MKTAG('A', 'V', 'j', '2') ||
2312  par->codec_tag == MKTAG('A', 'V', 'd', 'n')) &&
2313  atom.size >= 24) {
2314  int num, den;
2315  avio_skip(pb, 12);
2316  num = avio_rb32(pb);
2317  den = avio_rb32(pb);
2318  if (num <= 0 || den <= 0)
2319  return 0;
2320  switch (avio_rb32(pb)) {
2321  case 2:
2322  if (den >= INT_MAX / 2)
2323  return 0;
2324  den *= 2;
2325  case 1:
2326  sti->display_aspect_ratio = (AVRational){ num, den };
2327  default:
2328  return 0;
2329  }
2330  }
2331  }
2332 
2333  return mov_read_avid(c, pb, atom);
2334 }
2335 
2337 {
2338  int ret = 0;
2339  int length = 0;
2340  uint64_t original_size;
2341  if (c->fc->nb_streams >= 1) {
2342  AVCodecParameters *par = c->fc->streams[c->fc->nb_streams-1]->codecpar;
2343  if (par->codec_id == AV_CODEC_ID_H264)
2344  return 0;
2345  if (atom.size == 16) {
2346  original_size = par->extradata_size;
2347  ret = mov_realloc_extradata(par, atom);
2348  if (!ret) {
2349  length = mov_read_atom_into_extradata(c, pb, atom, par, par->extradata + original_size);
2350  if (length == atom.size) {
2351  const uint8_t range_value = par->extradata[original_size + 19];
2352  switch (range_value) {
2353  case 1:
2355  break;
2356  case 2:
2358  break;
2359  default:
2360  av_log(c->fc, AV_LOG_WARNING, "ignored unknown aclr value (%d)\n", range_value);
2361  break;
2362  }
2363  ff_dlog(c->fc, "color_range: %d\n", par->color_range);
2364  } else {
2365  /* For some reason the whole atom was not added to the extradata */
2366  av_log(c->fc, AV_LOG_ERROR, "aclr not decoded - incomplete atom\n");
2367  }
2368  } else {
2369  av_log(c->fc, AV_LOG_ERROR, "aclr not decoded - unable to add atom to extradata\n");
2370  }
2371  } else {
2372  av_log(c->fc, AV_LOG_WARNING, "aclr not decoded - unexpected size %"PRId64"\n", atom.size);
2373  }
2374  }
2375 
2376  return ret;
2377 }
2378 
2380 {
2381  return mov_read_extradata(c, pb, atom, AV_CODEC_ID_SVQ3);
2382 }
2383 
2385 {
2386  AVStream *st;
2387  int ret;
2388 
2389  if (c->fc->nb_streams < 1)
2390  return 0;
2391  st = c->fc->streams[c->fc->nb_streams-1];
2392 
2393  if ((uint64_t)atom.size > (1<<30))
2394  return AVERROR_INVALIDDATA;
2395 
2396  if (st->codecpar->codec_id == AV_CODEC_ID_QDM2 ||
2399  // pass all frma atom to codec, needed at least for QDMC and QDM2
2400  ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size);
2401  if (ret < 0)
2402  return ret;
2403  } else if (atom.size > 8) { /* to read frma, esds atoms */
2404  if (st->codecpar->codec_id == AV_CODEC_ID_ALAC && atom.size >= 24) {
2405  uint64_t buffer;
2406  ret = ffio_ensure_seekback(pb, 8);
2407  if (ret < 0)
2408  return ret;
2409  buffer = avio_rb64(pb);
2410  atom.size -= 8;
2411  if ( (buffer & 0xFFFFFFFF) == MKBETAG('f','r','m','a')
2412  && buffer >> 32 <= atom.size
2413  && buffer >> 32 >= 8) {
2414  avio_skip(pb, -8);
2415  atom.size += 8;
2416  } else if (!st->codecpar->extradata_size) {
2417 #define ALAC_EXTRADATA_SIZE 36
2419  if (!st->codecpar->extradata)
2420  return AVERROR(ENOMEM);
2423  AV_WB32(st->codecpar->extradata + 4, MKTAG('a','l','a','c'));
2424  AV_WB64(st->codecpar->extradata + 12, buffer);
2425  avio_read(pb, st->codecpar->extradata + 20, 16);
2426  avio_skip(pb, atom.size - 24);
2427  return 0;
2428  }
2429  }
2430  if ((ret = mov_read_default(c, pb, atom)) < 0)
2431  return ret;
2432  } else
2433  avio_skip(pb, atom.size);
2434  return 0;
2435 }
2436 
2437 /**
2438  * This function reads atom content and puts data in extradata without tag
2439  * nor size unlike mov_read_extradata.
2440  */
2442 {
2443  AVStream *st;
2444  int ret;
2445 
2446  st = get_curr_st(c);
2447  if (!st)
2448  return 0;
2449 
2450  if ((uint64_t)atom.size > (1<<30))
2451  return AVERROR_INVALIDDATA;
2452 
2453  if (atom.type == MKTAG('v','v','c','C')) {
2454  avio_skip(pb, 4);
2455  atom.size -= 4;
2456  }
2457 
2458  if (atom.size >= 10) {
2459  // Broken files created by legacy versions of libavformat will
2460  // wrap a whole fiel atom inside of a glbl atom.
2461  unsigned size = avio_rb32(pb);
2462  unsigned type = avio_rl32(pb);
2463  if (avio_feof(pb))
2464  return AVERROR_INVALIDDATA;
2465  avio_seek(pb, -8, SEEK_CUR);
2466  if (type == MKTAG('f','i','e','l') && size == atom.size)
2467  return mov_read_default(c, pb, atom);
2468  }
2469  if (st->codecpar->extradata_size > 1 && st->codecpar->extradata) {
2470  av_log(c->fc, AV_LOG_WARNING, "ignoring multiple glbl\n");
2471  return 0;
2472  }
2473  ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size);
2474  if (ret < 0)
2475  return ret;
2476  if (atom.type == MKTAG('h','v','c','C') && st->codecpar->codec_tag == MKTAG('d','v','h','1'))
2477  /* HEVC-based Dolby Vision derived from hvc1.
2478  Happens to match with an identifier
2479  previously utilized for DV. Thus, if we have
2480  the hvcC extradata box available as specified,
2481  set codec to HEVC */
2483 
2484  return 0;
2485 }
2486 
2488 {
2489  AVStream *st;
2490  uint8_t profile_level;
2491  int ret;
2492 
2493  if (c->fc->nb_streams < 1)
2494  return 0;
2495  st = c->fc->streams[c->fc->nb_streams-1];
2496 
2497  if (atom.size >= (1<<28) || atom.size < 7)
2498  return AVERROR_INVALIDDATA;
2499 
2500  profile_level = avio_r8(pb);
2501  if ((profile_level & 0xf0) != 0xc0)
2502  return 0;
2503 
2504  avio_seek(pb, 6, SEEK_CUR);
2505  ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size - 7);
2506  if (ret < 0)
2507  return ret;
2508 
2509  return 0;
2510 }
2511 
2513 {
2514  AVStream* st;
2515  MOVStreamContext* sc;
2516 
2517  if (c->fc->nb_streams < 1)
2518  return 0;
2519 
2520  /* For SBAS this should be fine - though beware if someone implements a
2521  * tref atom processor that doesn't drop down to default then this may
2522  * be lost. */
2523  if (atom.size > 4) {
2524  av_log(c->fc, AV_LOG_ERROR, "Only a single tref of type sbas is supported\n");
2525  return AVERROR_PATCHWELCOME;
2526  }
2527 
2528  st = c->fc->streams[c->fc->nb_streams - 1];
2529  sc = st->priv_data;
2530  sc->tref_id = avio_rb32(pb);
2532 
2533  return 0;
2534 }
2535 
2536 /**
2537  * An strf atom is a BITMAPINFOHEADER struct. This struct is 40 bytes itself,
2538  * but can have extradata appended at the end after the 40 bytes belonging
2539  * to the struct.
2540  */
2542 {
2543  AVStream *st;
2544  int ret;
2545 
2546  if (c->fc->nb_streams < 1)
2547  return 0;
2548  if (atom.size <= 40)
2549  return 0;
2550  st = c->fc->streams[c->fc->nb_streams-1];
2551 
2552  if ((uint64_t)atom.size > (1<<30))
2553  return AVERROR_INVALIDDATA;
2554 
2555  avio_skip(pb, 40);
2556  ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size - 40);
2557  if (ret < 0)
2558  return ret;
2559 
2560  return 0;
2561 }
2562 
2564 {
2565  AVStream *st;
2566  MOVStreamContext *sc;
2567  unsigned int i, entries;
2568 
2569  if (c->trak_index < 0) {
2570  av_log(c->fc, AV_LOG_WARNING, "STCO outside TRAK\n");
2571  return 0;
2572  }
2573  if (c->fc->nb_streams < 1)
2574  return 0;
2575  st = c->fc->streams[c->fc->nb_streams-1];
2576  sc = st->priv_data;
2577 
2578  avio_r8(pb); /* version */
2579  avio_rb24(pb); /* flags */
2580 
2581  // Clamp allocation size for `chunk_offsets` -- don't throw an error for an
2582  // invalid count since the EOF path doesn't throw either.
2583  entries = avio_rb32(pb);
2584  entries =
2585  FFMIN(entries,
2586  FFMAX(0, (atom.size - 8) /
2587  (atom.type == MKTAG('s', 't', 'c', 'o') ? 4 : 8)));
2588 
2589  if (!entries)
2590  return 0;
2591 
2592  if (sc->chunk_offsets) {
2593  av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicated STCO atom\n");
2594  return 0;
2595  }
2596 
2597  av_free(sc->chunk_offsets);
2598  sc->chunk_count = 0;
2599  sc->chunk_offsets = av_malloc_array(entries, sizeof(*sc->chunk_offsets));
2600  if (!sc->chunk_offsets)
2601  return AVERROR(ENOMEM);
2602  sc->chunk_count = entries;
2603 
2604  if (atom.type == MKTAG('s','t','c','o'))
2605  for (i = 0; i < entries && !pb->eof_reached; i++)
2606  sc->chunk_offsets[i] = avio_rb32(pb);
2607  else if (atom.type == MKTAG('c','o','6','4'))
2608  for (i = 0; i < entries && !pb->eof_reached; i++) {
2609  sc->chunk_offsets[i] = avio_rb64(pb);
2610  if (sc->chunk_offsets[i] < 0) {
2611  av_log(c->fc, AV_LOG_WARNING, "Impossible chunk_offset\n");
2612  sc->chunk_offsets[i] = 0;
2613  }
2614  }
2615  else
2616  return AVERROR_INVALIDDATA;
2617 
2618  sc->chunk_count = i;
2619 
2620  if (pb->eof_reached) {
2621  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STCO atom\n");
2622  return AVERROR_EOF;
2623  }
2624 
2625  return 0;
2626 }
2627 
2628 static int mov_codec_id(AVStream *st, uint32_t format)
2629 {
2631 
2632  if (id <= 0 &&
2633  ((format & 0xFFFF) == 'm' + ('s' << 8) ||
2634  (format & 0xFFFF) == 'T' + ('S' << 8)))
2636 
2637  if (st->codecpar->codec_type != AVMEDIA_TYPE_VIDEO && id > 0) {
2639  } else if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO &&
2640  /* skip old ASF MPEG-4 tag */
2641  format && format != MKTAG('m','p','4','s')) {
2643  if (id <= 0)
2645  if (id > 0)
2647  else if (st->codecpar->codec_type == AVMEDIA_TYPE_DATA ||
2649  st->codecpar->codec_id == AV_CODEC_ID_NONE)) {
2651  if (id <= 0) {
2653  AV_CODEC_ID_TTML : id;
2654  }
2655 
2656  if (id > 0)
2658  else
2660  }
2661  }
2662 
2663  st->codecpar->codec_tag = format;
2664 
2665  return id;
2666 }
2667 
2669  AVStream *st, MOVStreamContext *sc)
2670 {
2671  uint8_t codec_name[32] = { 0 };
2672  int64_t stsd_start;
2673  unsigned int len;
2674  uint32_t id = 0;
2675 
2676  /* The first 16 bytes of the video sample description are already
2677  * read in ff_mov_read_stsd_entries() */
2678  stsd_start = avio_tell(pb) - 16;
2679 
2680  avio_rb16(pb); /* version */
2681  avio_rb16(pb); /* revision level */
2682  id = avio_rl32(pb); /* vendor */
2683  av_dict_set(&st->metadata, "vendor_id", av_fourcc2str(id), 0);
2684  avio_rb32(pb); /* temporal quality */
2685  avio_rb32(pb); /* spatial quality */
2686 
2687  st->codecpar->width = avio_rb16(pb); /* width */
2688  st->codecpar->height = avio_rb16(pb); /* height */
2689 
2690  avio_rb32(pb); /* horiz resolution */
2691  avio_rb32(pb); /* vert resolution */
2692  avio_rb32(pb); /* data size, always 0 */
2693  avio_rb16(pb); /* frames per samples */
2694 
2695  len = avio_r8(pb); /* codec name, pascal string */
2696  if (len > 31)
2697  len = 31;
2698  mov_read_mac_string(c, pb, len, codec_name, sizeof(codec_name));
2699  if (len < 31)
2700  avio_skip(pb, 31 - len);
2701 
2702  if (codec_name[0])
2703  av_dict_set(&st->metadata, "encoder", codec_name, 0);
2704 
2705  /* codec_tag YV12 triggers an UV swap in rawdec.c */
2706  if (!strncmp(codec_name, "Planar Y'CbCr 8-bit 4:2:0", 25)) {
2707  st->codecpar->codec_tag = MKTAG('I', '4', '2', '0');
2708  st->codecpar->width &= ~1;
2709  st->codecpar->height &= ~1;
2710  }
2711  /* Flash Media Server uses tag H.263 with Sorenson Spark */
2712  if (st->codecpar->codec_tag == MKTAG('H','2','6','3') &&
2713  !strncmp(codec_name, "Sorenson H263", 13))
2715 
2716  st->codecpar->bits_per_coded_sample = avio_rb16(pb); /* depth */
2717 
2718  avio_seek(pb, stsd_start, SEEK_SET);
2719 
2720  if (ff_get_qtpalette(st->codecpar->codec_id, pb, sc->palette)) {
2721  st->codecpar->bits_per_coded_sample &= 0x1F;
2722  sc->has_palette = 1;
2723  }
2724 }
2725 
2727  AVStream *st, MOVStreamContext *sc)
2728 {
2729  int bits_per_sample, flags;
2730  uint16_t version = avio_rb16(pb);
2731  uint32_t id = 0;
2732  AVDictionaryEntry *compatible_brands = av_dict_get(c->fc->metadata, "compatible_brands", NULL, AV_DICT_MATCH_CASE);
2733  int channel_count;
2734 
2735  avio_rb16(pb); /* revision level */
2736  id = avio_rl32(pb); /* vendor */
2737  av_dict_set(&st->metadata, "vendor_id", av_fourcc2str(id), 0);
2738 
2739  channel_count = avio_rb16(pb);
2740 
2742  st->codecpar->ch_layout.nb_channels = channel_count;
2743  st->codecpar->bits_per_coded_sample = avio_rb16(pb); /* sample size */
2744  av_log(c->fc, AV_LOG_TRACE, "audio channels %d\n", channel_count);
2745 
2746  sc->audio_cid = avio_rb16(pb);
2747  avio_rb16(pb); /* packet size = 0 */
2748 
2749  st->codecpar->sample_rate = ((avio_rb32(pb) >> 16));
2750 
2751  // Read QT version 1 fields. In version 0 these do not exist.
2752  av_log(c->fc, AV_LOG_TRACE, "version =%d, isom =%d\n", version, c->isom);
2753  if (!c->isom ||
2754  (compatible_brands && strstr(compatible_brands->value, "qt ")) ||
2755  (sc->stsd_version == 0 && version > 0)) {
2756  if (version == 1) {
2757  sc->samples_per_frame = avio_rb32(pb);
2758  avio_rb32(pb); /* bytes per packet */
2759  sc->bytes_per_frame = avio_rb32(pb);
2760  avio_rb32(pb); /* bytes per sample */
2761  } else if (version == 2) {
2762  avio_rb32(pb); /* sizeof struct only */
2764  channel_count = avio_rb32(pb);
2766  st->codecpar->ch_layout.nb_channels = channel_count;
2767  avio_rb32(pb); /* always 0x7F000000 */
2769 
2770  flags = avio_rb32(pb); /* lpcm format specific flag */
2771  sc->bytes_per_frame = avio_rb32(pb);
2772  sc->samples_per_frame = avio_rb32(pb);
2773  if (st->codecpar->codec_tag == MKTAG('l','p','c','m'))
2774  st->codecpar->codec_id =
2776  flags);
2777  }
2778  if (version == 0 || (version == 1 && sc->audio_cid != -2)) {
2779  /* can't correctly handle variable sized packet as audio unit */
2780  switch (st->codecpar->codec_id) {
2781  case AV_CODEC_ID_MP2:
2782  case AV_CODEC_ID_MP3:
2784  break;
2785  }
2786  }
2787  }
2788 
2789  if (sc->format == 0) {
2790  if (st->codecpar->bits_per_coded_sample == 8)
2791  st->codecpar->codec_id = mov_codec_id(st, MKTAG('r','a','w',' '));
2792  else if (st->codecpar->bits_per_coded_sample == 16)
2793  st->codecpar->codec_id = mov_codec_id(st, MKTAG('t','w','o','s'));
2794  }
2795 
2796  switch (st->codecpar->codec_id) {
2797  case AV_CODEC_ID_PCM_S8:
2798  case AV_CODEC_ID_PCM_U8:
2799  if (st->codecpar->bits_per_coded_sample == 16)
2801  break;
2802  case AV_CODEC_ID_PCM_S16LE:
2803  case AV_CODEC_ID_PCM_S16BE:
2804  if (st->codecpar->bits_per_coded_sample == 8)
2806  else if (st->codecpar->bits_per_coded_sample == 24)
2807  st->codecpar->codec_id =
2810  else if (st->codecpar->bits_per_coded_sample == 32)
2811  st->codecpar->codec_id =
2814  break;
2815  /* set values for old format before stsd version 1 appeared */
2816  case AV_CODEC_ID_MACE3:
2817  sc->samples_per_frame = 6;
2819  break;
2820  case AV_CODEC_ID_MACE6:
2821  sc->samples_per_frame = 6;
2823  break;
2825  sc->samples_per_frame = 64;
2827  break;
2828  case AV_CODEC_ID_GSM:
2829  sc->samples_per_frame = 160;
2830  sc->bytes_per_frame = 33;
2831  break;
2832  default:
2833  break;
2834  }
2835 
2836  bits_per_sample = av_get_bits_per_sample(st->codecpar->codec_id);
2837  if (bits_per_sample && (bits_per_sample >> 3) * (uint64_t)st->codecpar->ch_layout.nb_channels <= INT_MAX) {
2838  st->codecpar->bits_per_coded_sample = bits_per_sample;
2839  sc->sample_size = (bits_per_sample >> 3) * st->codecpar->ch_layout.nb_channels;
2840  }
2841 }
2842 
2844  AVStream *st, MOVStreamContext *sc,
2845  int64_t size)
2846 {
2847  // ttxt stsd contains display flags, justification, background
2848  // color, fonts, and default styles, so fake an atom to read it
2849  MOVAtom fake_atom = { .size = size };
2850  // mp4s contains a regular esds atom, dfxp ISMV TTML has no content
2851  // in extradata unlike stpp MP4 TTML.
2852  if (st->codecpar->codec_tag != AV_RL32("mp4s") &&
2854  mov_read_glbl(c, pb, fake_atom);
2855  st->codecpar->width = sc->width;
2856  st->codecpar->height = sc->height;
2857 }
2858 
2860  AVStream *st, MOVStreamContext *sc,
2861  int64_t size)
2862 {
2863  int ret;
2864 
2865  if (st->codecpar->codec_tag == MKTAG('t','m','c','d')) {
2866  if ((int)size != size)
2867  return AVERROR(ENOMEM);
2868 
2869  ret = ff_get_extradata(c->fc, st->codecpar, pb, size);
2870  if (ret < 0)
2871  return ret;
2872  if (size > 16) {
2873  MOVStreamContext *tmcd_ctx = st->priv_data;
2874  int val;
2875  val = AV_RB32(st->codecpar->extradata + 4);
2876  tmcd_ctx->tmcd_flags = val;
2877  st->avg_frame_rate.num = AV_RB32(st->codecpar->extradata + 8); /* timescale */
2878  st->avg_frame_rate.den = AV_RB32(st->codecpar->extradata + 12); /* frameDuration */
2879  tmcd_ctx->tmcd_nb_frames = st->codecpar->extradata[16]; /* number of frames */
2880  if (size > 30) {
2881  uint32_t len = AV_RB32(st->codecpar->extradata + 18); /* name atom length */
2882  uint32_t format = AV_RB32(st->codecpar->extradata + 22);
2883  if (format == AV_RB32("name") && (int64_t)size >= (int64_t)len + 18) {
2884  uint16_t str_size = AV_RB16(st->codecpar->extradata + 26); /* string length */
2885  if (str_size > 0 && size >= (int)str_size + 30 &&
2886  st->codecpar->extradata[30] /* Don't add empty string */) {
2887  char *reel_name = av_malloc(str_size + 1);
2888  if (!reel_name)
2889  return AVERROR(ENOMEM);
2890  memcpy(reel_name, st->codecpar->extradata + 30, str_size);
2891  reel_name[str_size] = 0; /* Add null terminator */
2892  av_dict_set(&st->metadata, "reel_name", reel_name,
2894  }
2895  }
2896  }
2897  }
2898  } else {
2899  /* other codec type, just skip (rtp, mp4s ...) */
2900  avio_skip(pb, size);
2901  }
2902  return 0;
2903 }
2904 
2906  AVStream *st, MOVStreamContext *sc)
2907 {
2908  FFStream *const sti = ffstream(st);
2909 
2910  if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
2911  !st->codecpar->sample_rate && sc->time_scale > 1)
2912  st->codecpar->sample_rate = sc->time_scale;
2913 
2914  /* special codec parameters handling */
2915  switch (st->codecpar->codec_id) {
2916 #if CONFIG_DV_DEMUXER
2917  case AV_CODEC_ID_DVAUDIO:
2918  if (c->dv_fctx) {
2919  avpriv_request_sample(c->fc, "multiple DV audio streams");
2920  return AVERROR(ENOSYS);
2921  }
2922 
2923  c->dv_fctx = avformat_alloc_context();
2924  if (!c->dv_fctx) {
2925  av_log(c->fc, AV_LOG_ERROR, "dv demux context alloc error\n");
2926  return AVERROR(ENOMEM);
2927  }
2928  c->dv_demux = avpriv_dv_init_demux(c->dv_fctx);
2929  if (!c->dv_demux) {
2930  av_log(c->fc, AV_LOG_ERROR, "dv demux context init error\n");
2931  return AVERROR(ENOMEM);
2932  }
2933  sc->dv_audio_container = 1;
2935  break;
2936 #endif
2937  /* no ifdef since parameters are always those */
2938  case AV_CODEC_ID_QCELP:
2941  // force sample rate for qcelp when not stored in mov
2942  if (st->codecpar->codec_tag != MKTAG('Q','c','l','p'))
2943  st->codecpar->sample_rate = 8000;
2944  // FIXME: Why is the following needed for some files?
2945  sc->samples_per_frame = 160;
2946  if (!sc->bytes_per_frame)
2947  sc->bytes_per_frame = 35;
2948  break;
2949  case AV_CODEC_ID_AMR_NB:
2952  /* force sample rate for amr, stsd in 3gp does not store sample rate */
2953  st->codecpar->sample_rate = 8000;
2954  break;
2955  case AV_CODEC_ID_AMR_WB:
2958  st->codecpar->sample_rate = 16000;
2959  break;
2960  case AV_CODEC_ID_MP2:
2961  case AV_CODEC_ID_MP3:
2962  /* force type after stsd for m1a hdlr */
2964  break;
2965  case AV_CODEC_ID_GSM:
2966  case AV_CODEC_ID_ADPCM_MS:
2968  case AV_CODEC_ID_ILBC:
2969  case AV_CODEC_ID_MACE3:
2970  case AV_CODEC_ID_MACE6:
2971  case AV_CODEC_ID_QDM2:
2973  break;
2974  case AV_CODEC_ID_ALAC:
2975  if (st->codecpar->extradata_size == 36) {
2976  int channel_count = AV_RB8(st->codecpar->extradata + 21);
2977  if (st->codecpar->ch_layout.nb_channels != channel_count) {
2980  st->codecpar->ch_layout.nb_channels = channel_count;
2981  }
2982  st->codecpar->sample_rate = AV_RB32(st->codecpar->extradata + 32);
2983  }
2984  break;
2985  case AV_CODEC_ID_AC3:
2986  case AV_CODEC_ID_EAC3:
2988  case AV_CODEC_ID_VC1:
2989  case AV_CODEC_ID_VP8:
2990  case AV_CODEC_ID_VP9:
2992  break;
2994  case AV_CODEC_ID_APV:
2995  case AV_CODEC_ID_EVC:
2996  case AV_CODEC_ID_AV1:
2997  /* field_order detection of H264 requires parsing */
2998  case AV_CODEC_ID_H264:
3000  break;
3001  default:
3002  break;
3003  }
3004  return 0;
3005 }
3006 
3008  int codec_tag, int format,
3009  int64_t size)
3010 {
3011  if (codec_tag &&
3012  (codec_tag != format &&
3013  // AVID 1:1 samples with differing data format and codec tag exist
3014  (codec_tag != AV_RL32("AV1x") || format != AV_RL32("AVup")) &&
3015  // prores is allowed to have differing data format and codec tag
3016  codec_tag != AV_RL32("apcn") && codec_tag != AV_RL32("apch") &&
3017  // so is dv (sigh)
3018  codec_tag != AV_RL32("dvpp") && codec_tag != AV_RL32("dvcp") &&
3019  (c->fc->video_codec_id ? ff_codec_get_id(ff_codec_movvideo_tags, format) != c->fc->video_codec_id
3020  : codec_tag != MKTAG('j','p','e','g')))) {
3021  /* Multiple fourcc, we skip JPEG. This is not correct, we should
3022  * export it as a separate AVStream but this needs a few changes
3023  * in the MOV demuxer, patch welcome. */
3024 
3025  av_log(c->fc, AV_LOG_WARNING, "multiple fourcc not supported\n");
3026  avio_skip(pb, size);
3027  return 1;
3028  }
3029 
3030  return 0;
3031 }
3032 
3034 {
3035  int ret;
3036 
3037  /* special codec parameters handling */
3038  switch (st->codecpar->codec_id) {
3039  case AV_CODEC_ID_H264:
3040  // done for ai5q, ai52, ai55, ai1q, ai12 and ai15.
3041  if (!st->codecpar->extradata_size && TAG_IS_AVCI(st->codecpar->codec_tag)) {
3043  if (ret < 0)
3044  return ret;
3045  }
3046  break;
3047  default:
3048  break;
3049  }
3050 
3051  return 0;
3052 }
3053 
3055 {
3056  AVStream *st;
3057  MOVStreamContext *sc;
3058  int pseudo_stream_id;
3059 
3060  av_assert0 (c->fc->nb_streams >= 1);
3061  st = c->fc->streams[c->fc->nb_streams-1];
3062  sc = st->priv_data;
3063 
3064  for (pseudo_stream_id = 0;
3065  pseudo_stream_id < entries && !pb->eof_reached;
3066  pseudo_stream_id++) {
3067  //Parsing Sample description table
3068  enum AVCodecID id;
3069  int ret, dref_id = 1;
3070  MOVAtom a = { AV_RL32("stsd") };
3071  int64_t start_pos = avio_tell(pb);
3072  int64_t size = avio_rb32(pb); /* size */
3073  uint32_t format = avio_rl32(pb); /* data format */
3074 
3075  if (size >= 16) {
3076  avio_rb32(pb); /* reserved */
3077  avio_rb16(pb); /* reserved */
3078  dref_id = avio_rb16(pb);
3079  } else if (size <= 7) {
3080  av_log(c->fc, AV_LOG_ERROR,
3081  "invalid size %"PRId64" in stsd\n", size);
3082  return AVERROR_INVALIDDATA;
3083  }
3084 
3086  size - (avio_tell(pb) - start_pos))) {
3087  sc->stsd_count++;
3088  continue;
3089  }
3090 
3091  sc->pseudo_stream_id = st->codecpar->codec_tag ? -1 : pseudo_stream_id;
3092  sc->dref_id= dref_id;
3093  sc->format = format;
3094 
3095  id = mov_codec_id(st, format);
3096 
3097  av_log(c->fc, AV_LOG_TRACE,
3098  "size=%"PRId64" 4CC=%s codec_type=%d\n", size,
3100 
3101  st->codecpar->codec_id = id;
3103  mov_parse_stsd_video(c, pb, st, sc);
3104  } else if (st->codecpar->codec_type==AVMEDIA_TYPE_AUDIO) {
3105  mov_parse_stsd_audio(c, pb, st, sc);
3106  if (st->codecpar->sample_rate < 0) {
3107  av_log(c->fc, AV_LOG_ERROR, "Invalid sample rate %d\n", st->codecpar->sample_rate);
3108  return AVERROR_INVALIDDATA;
3109  }
3110  if (st->codecpar->ch_layout.nb_channels < 0) {
3111  av_log(c->fc, AV_LOG_ERROR, "Invalid channels %d\n", st->codecpar->ch_layout.nb_channels);
3112  return AVERROR_INVALIDDATA;
3113  }
3114  } else if (st->codecpar->codec_type==AVMEDIA_TYPE_SUBTITLE){
3115  mov_parse_stsd_subtitle(c, pb, st, sc,
3116  size - (avio_tell(pb) - start_pos));
3117  } else {
3118  ret = mov_parse_stsd_data(c, pb, st, sc,
3119  size - (avio_tell(pb) - start_pos));
3120  if (ret < 0)
3121  return ret;
3122  }
3123  /* this will read extra atoms at the end (wave, alac, damr, avcC, hvcC, SMI ...) */
3124  a.size = size - (avio_tell(pb) - start_pos);
3125  if (a.size > 8) {
3126  if ((ret = mov_read_default(c, pb, a)) < 0)
3127  return ret;
3128  } else if (a.size > 0)
3129  avio_skip(pb, a.size);
3130 
3131  ret = mov_finalize_stsd_entry(c, st);
3132  if (ret < 0)
3133  return ret;
3134 
3135  if (sc->extradata && st->codecpar->extradata) {
3136  int extra_size = st->codecpar->extradata_size;
3137 
3138  /* Move the current stream extradata to the stream context one. */
3139  sc->extradata_size[pseudo_stream_id] = extra_size;
3140  sc->extradata[pseudo_stream_id] = st->codecpar->extradata;
3141  st->codecpar->extradata = NULL;
3142  st->codecpar->extradata_size = 0;
3143  }
3144  sc->stsd_count++;
3145  }
3146 
3147  if (pb->eof_reached) {
3148  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSD atom\n");
3149  return AVERROR_EOF;
3150  }
3151 
3152  return 0;
3153 }
3154 
3156 {
3157  AVStream *st;
3158  MOVStreamContext *sc;
3159  int ret, entries;
3160 
3161  if (c->fc->nb_streams < 1)
3162  return 0;
3163  st = c->fc->streams[c->fc->nb_streams - 1];
3164  sc = st->priv_data;
3165 
3166  sc->stsd_version = avio_r8(pb);
3167  avio_rb24(pb); /* flags */
3168  entries = avio_rb32(pb);
3169 
3170  /* Each entry contains a size (4 bytes) and format (4 bytes). */
3171  if (entries <= 0 || entries > atom.size / 8 || entries > 1024) {
3172  av_log(c->fc, AV_LOG_ERROR, "invalid STSD entries %d\n", entries);
3173  return AVERROR_INVALIDDATA;
3174  }
3175 
3176  if (sc->extradata) {
3177  av_log(c->fc, AV_LOG_ERROR,
3178  "Duplicate stsd found in this track.\n");
3179  return AVERROR_INVALIDDATA;
3180  }
3181 
3182  /* Prepare space for hosting multiple extradata. */
3183  sc->extradata = av_calloc(entries, sizeof(*sc->extradata));
3184  if (!sc->extradata)
3185  return AVERROR(ENOMEM);
3186 
3187  sc->extradata_size = av_calloc(entries, sizeof(*sc->extradata_size));
3188  if (!sc->extradata_size) {
3189  ret = AVERROR(ENOMEM);
3190  goto fail;
3191  }
3192 
3193  ret = ff_mov_read_stsd_entries(c, pb, entries);
3194  if (ret < 0)
3195  goto fail;
3196 
3197  /* Restore back the primary extradata. */
3198  av_freep(&st->codecpar->extradata);
3199  st->codecpar->extradata_size = sc->extradata_size[0];
3200  if (sc->extradata_size[0]) {
3202  if (!st->codecpar->extradata)
3203  return AVERROR(ENOMEM);
3204  memcpy(st->codecpar->extradata, sc->extradata[0], sc->extradata_size[0]);
3205  }
3206 
3207  return mov_finalize_stsd_codec(c, pb, st, sc);
3208 fail:
3209  if (sc->extradata) {
3210  int j;
3211  for (j = 0; j < sc->stsd_count; j++)
3212  av_freep(&sc->extradata[j]);
3213  }
3214 
3215  av_freep(&sc->extradata);
3216  av_freep(&sc->extradata_size);
3217  return ret;
3218 }
3219 
3221 {
3222  AVStream *st;
3223  MOVStreamContext *sc;
3224  unsigned int i, entries;
3225 
3226  if (c->trak_index < 0) {
3227  av_log(c->fc, AV_LOG_WARNING, "STSC outside TRAK\n");
3228  return 0;
3229  }
3230 
3231  if (c->fc->nb_streams < 1)
3232  return 0;
3233  st = c->fc->streams[c->fc->nb_streams-1];
3234  sc = st->priv_data;
3235 
3236  avio_r8(pb); /* version */
3237  avio_rb24(pb); /* flags */
3238 
3239  entries = avio_rb32(pb);
3240  if ((uint64_t)entries * 12 + 4 > atom.size)
3241  return AVERROR_INVALIDDATA;
3242 
3243  av_log(c->fc, AV_LOG_TRACE, "track[%u].stsc.entries = %u\n", c->fc->nb_streams - 1, entries);
3244 
3245  if (!entries)
3246  return 0;
3247  if (sc->stsc_data) {
3248  av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicated STSC atom\n");
3249  return 0;
3250  }
3251  av_free(sc->stsc_data);
3252  sc->stsc_count = 0;
3253  sc->stsc_data = av_malloc_array(entries, sizeof(*sc->stsc_data));
3254  if (!sc->stsc_data)
3255  return AVERROR(ENOMEM);
3256 
3257  for (i = 0; i < entries && !pb->eof_reached; i++) {
3258  sc->stsc_data[i].first = avio_rb32(pb);
3259  sc->stsc_data[i].count = avio_rb32(pb);
3260  sc->stsc_data[i].id = avio_rb32(pb);
3261  }
3262 
3263  sc->stsc_count = i;
3264  for (i = sc->stsc_count - 1; i < UINT_MAX; i--) {
3265  int64_t first_min = i + 1;
3266  if ((i+1 < sc->stsc_count && sc->stsc_data[i].first >= sc->stsc_data[i+1].first) ||
3267  (i > 0 && sc->stsc_data[i].first <= sc->stsc_data[i-1].first) ||
3268  sc->stsc_data[i].first < first_min ||
3269  sc->stsc_data[i].count < 1 ||
3270  sc->stsc_data[i].id < 1) {
3271  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);
3272  if (i+1 >= sc->stsc_count) {
3273  if (sc->stsc_data[i].count == 0 && i > 0) {
3274  sc->stsc_count --;
3275  continue;
3276  }
3277  sc->stsc_data[i].first = FFMAX(sc->stsc_data[i].first, first_min);
3278  if (i > 0 && sc->stsc_data[i].first <= sc->stsc_data[i-1].first)
3279  sc->stsc_data[i].first = FFMIN(sc->stsc_data[i-1].first + 1LL, INT_MAX);
3280  sc->stsc_data[i].count = FFMAX(sc->stsc_data[i].count, 1);
3281  sc->stsc_data[i].id = FFMAX(sc->stsc_data[i].id, 1);
3282  continue;
3283  }
3284  av_assert0(sc->stsc_data[i+1].first >= 2);
3285  // We replace this entry by the next valid
3286  sc->stsc_data[i].first = sc->stsc_data[i+1].first - 1;
3287  sc->stsc_data[i].count = sc->stsc_data[i+1].count;
3288  sc->stsc_data[i].id = sc->stsc_data[i+1].id;
3289  }
3290  }
3291 
3292  if (pb->eof_reached) {
3293  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSC atom\n");
3294  return AVERROR_EOF;
3295  }
3296 
3297  return 0;
3298 }
3299 
3300 static inline int mov_stsc_index_valid(unsigned int index, unsigned int count)
3301 {
3302  return index < count - 1;
3303 }
3304 
3305 /* Compute the samples value for the stsc entry at the given index. */
3306 static inline int64_t mov_get_stsc_samples(MOVStreamContext *sc, unsigned int index)
3307 {
3308  int chunk_count;
3309 
3311  chunk_count = sc->stsc_data[index + 1].first - sc->stsc_data[index].first;
3312  else {
3313  // Validation for stsc / stco happens earlier in mov_read_stsc + mov_read_trak.
3315  chunk_count = sc->chunk_count - (sc->stsc_data[index].first - 1);
3316  }
3317 
3318  return sc->stsc_data[index].count * (int64_t)chunk_count;
3319 }
3320 
3322 {
3323  AVStream *st;
3324  MOVStreamContext *sc;
3325  unsigned i, entries;
3326 
3327  if (c->trak_index < 0) {
3328  av_log(c->fc, AV_LOG_WARNING, "STPS outside TRAK\n");
3329  return 0;
3330  }
3331 
3332  if (c->fc->nb_streams < 1)
3333  return 0;
3334  st = c->fc->streams[c->fc->nb_streams-1];
3335  sc = st->priv_data;
3336 
3337  avio_rb32(pb); // version + flags
3338 
3339  entries = avio_rb32(pb);
3340  if (sc->stps_data)
3341  av_log(c->fc, AV_LOG_WARNING, "Duplicated STPS atom\n");
3342  av_free(sc->stps_data);
3343  sc->stps_count = 0;
3344  sc->stps_data = av_malloc_array(entries, sizeof(*sc->stps_data));
3345  if (!sc->stps_data)
3346  return AVERROR(ENOMEM);
3347 
3348  for (i = 0; i < entries && !pb->eof_reached; i++) {
3349  sc->stps_data[i] = avio_rb32(pb);
3350  }
3351 
3352  sc->stps_count = i;
3353 
3354  if (pb->eof_reached) {
3355  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STPS atom\n");
3356  return AVERROR_EOF;
3357  }
3358 
3359  return 0;
3360 }
3361 
3363 {
3364  AVStream *st;
3365  FFStream *sti;
3366  MOVStreamContext *sc;
3367  unsigned int i, entries;
3368 
3369  if (c->trak_index < 0) {
3370  av_log(c->fc, AV_LOG_WARNING, "STSS outside TRAK\n");
3371  return 0;
3372  }
3373 
3374  if (c->fc->nb_streams < 1)
3375  return 0;
3376  st = c->fc->streams[c->fc->nb_streams-1];
3377  sti = ffstream(st);
3378  sc = st->priv_data;
3379 
3380  avio_r8(pb); /* version */
3381  avio_rb24(pb); /* flags */
3382 
3383  entries = avio_rb32(pb);
3384 
3385  av_log(c->fc, AV_LOG_TRACE, "keyframe_count = %u\n", entries);
3386 
3387  if (!entries) {
3388  sc->keyframe_absent = 1;
3389  if (!sti->need_parsing && st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
3391  return 0;
3392  }
3393  if (sc->keyframes)
3394  av_log(c->fc, AV_LOG_WARNING, "Duplicated STSS atom\n");
3395  if (entries >= UINT_MAX / sizeof(int))
3396  return AVERROR_INVALIDDATA;
3397  av_freep(&sc->keyframes);
3398  sc->keyframe_count = 0;
3399  sc->keyframes = av_malloc_array(entries, sizeof(*sc->keyframes));
3400  if (!sc->keyframes)
3401  return AVERROR(ENOMEM);
3402 
3403  for (i = 0; i < entries && !pb->eof_reached; i++) {
3404  sc->keyframes[i] = avio_rb32(pb);
3405  }
3406 
3407  sc->keyframe_count = i;
3408 
3409  if (pb->eof_reached) {
3410  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSS atom\n");
3411  return AVERROR_EOF;
3412  }
3413 
3414  return 0;
3415 }
3416 
3418 {
3419  AVStream *st;
3420  MOVStreamContext *sc;
3421  unsigned int i, entries, sample_size, field_size, num_bytes;
3422  GetBitContext gb;
3423  unsigned char* buf;
3424  int ret;
3425 
3426  if (c->trak_index < 0) {
3427  av_log(c->fc, AV_LOG_WARNING, "STSZ outside TRAK\n");
3428  return 0;
3429  }
3430 
3431  if (c->fc->nb_streams < 1)
3432  return 0;
3433  st = c->fc->streams[c->fc->nb_streams-1];
3434  sc = st->priv_data;
3435 
3436  avio_r8(pb); /* version */
3437  avio_rb24(pb); /* flags */
3438 
3439  if (atom.type == MKTAG('s','t','s','z')) {
3440  sample_size = avio_rb32(pb);
3441  if (!sc->sample_size) /* do not overwrite value computed in stsd */
3442  sc->sample_size = sample_size;
3443  sc->stsz_sample_size = sample_size;
3444  field_size = 32;
3445  } else {
3446  sample_size = 0;
3447  avio_rb24(pb); /* reserved */
3448  field_size = avio_r8(pb);
3449  }
3450  entries = avio_rb32(pb);
3451 
3452  av_log(c->fc, AV_LOG_TRACE, "sample_size = %u sample_count = %u\n", sc->sample_size, entries);
3453 
3454  sc->sample_count = entries;
3455  if (sample_size)
3456  return 0;
3457 
3458  if (field_size != 4 && field_size != 8 && field_size != 16 && field_size != 32) {
3459  av_log(c->fc, AV_LOG_ERROR, "Invalid sample field size %u\n", field_size);
3460  return AVERROR_INVALIDDATA;
3461  }
3462 
3463  if (!entries)
3464  return 0;
3465  if (entries >= (INT_MAX - 4 - 8 * AV_INPUT_BUFFER_PADDING_SIZE) / field_size)
3466  return AVERROR_INVALIDDATA;
3467  if (sc->sample_sizes)
3468  av_log(c->fc, AV_LOG_WARNING, "Duplicated STSZ atom\n");
3469  av_free(sc->sample_sizes);
3470  sc->sample_count = 0;
3471  sc->sample_sizes = av_malloc_array(entries, sizeof(*sc->sample_sizes));
3472  if (!sc->sample_sizes)
3473  return AVERROR(ENOMEM);
3474 
3475  num_bytes = (entries*field_size+4)>>3;
3476 
3477  buf = av_malloc(num_bytes+AV_INPUT_BUFFER_PADDING_SIZE);
3478  if (!buf) {
3479  av_freep(&sc->sample_sizes);
3480  return AVERROR(ENOMEM);
3481  }
3482 
3483  ret = ffio_read_size(pb, buf, num_bytes);
3484  if (ret < 0) {
3485  av_freep(&sc->sample_sizes);
3486  av_free(buf);
3487  av_log(c->fc, AV_LOG_WARNING, "STSZ atom truncated\n");
3488  return 0;
3489  }
3490 
3491  init_get_bits(&gb, buf, 8*num_bytes);
3492 
3493  for (i = 0; i < entries; i++) {
3494  sc->sample_sizes[i] = get_bits_long(&gb, field_size);
3495  if (sc->sample_sizes[i] > INT64_MAX - sc->data_size) {
3496  av_free(buf);
3497  av_log(c->fc, AV_LOG_ERROR, "Sample size overflow in STSZ\n");
3498  return AVERROR_INVALIDDATA;
3499  }
3500  sc->data_size += sc->sample_sizes[i];
3501  }
3502 
3503  sc->sample_count = i;
3504 
3505  av_free(buf);
3506 
3507  return 0;
3508 }
3509 
3511 {
3512  AVStream *st;
3513  MOVStreamContext *sc;
3514  unsigned int i, entries;
3515  int64_t duration = 0;
3516  int64_t total_sample_count = 0;
3517  int64_t current_dts = 0;
3518  int64_t corrected_dts = 0;
3519 
3520  if (c->trak_index < 0) {
3521  av_log(c->fc, AV_LOG_WARNING, "STTS outside TRAK\n");
3522  return 0;
3523  }
3524 
3525  if (c->fc->nb_streams < 1)
3526  return 0;
3527  st = c->fc->streams[c->fc->nb_streams-1];
3528  sc = st->priv_data;
3529 
3530  avio_r8(pb); /* version */
3531  avio_rb24(pb); /* flags */
3532  entries = avio_rb32(pb);
3533 
3534  av_log(c->fc, AV_LOG_TRACE, "track[%u].stts.entries = %u\n",
3535  c->fc->nb_streams-1, entries);
3536 
3537  if (sc->stts_data)
3538  av_log(c->fc, AV_LOG_WARNING, "Duplicated STTS atom\n");
3539  av_freep(&sc->stts_data);
3540  sc->stts_count = 0;
3541  if (entries >= INT_MAX / sizeof(*sc->stts_data))
3542  return AVERROR(ENOMEM);
3543 
3544  for (i = 0; i < entries && !pb->eof_reached; i++) {
3545  unsigned int sample_duration;
3546  unsigned int sample_count;
3547  unsigned int min_entries = FFMIN(FFMAX(i + 1, 1024 * 1024), entries);
3548  MOVStts *stts_data = av_fast_realloc(sc->stts_data, &sc->stts_allocated_size,
3549  min_entries * sizeof(*sc->stts_data));
3550  if (!stts_data) {
3551  av_freep(&sc->stts_data);
3552  sc->stts_count = 0;
3553  return AVERROR(ENOMEM);
3554  }
3555  sc->stts_count = min_entries;
3556  sc->stts_data = stts_data;
3557 
3558  sample_count = avio_rb32(pb);
3559  sample_duration = avio_rb32(pb);
3560 
3561  sc->stts_data[i].count= sample_count;
3562  sc->stts_data[i].duration= sample_duration;
3563 
3564  av_log(c->fc, AV_LOG_TRACE, "sample_count=%u, sample_duration=%u\n",
3565  sample_count, sample_duration);
3566 
3567  /* STTS sample offsets are uint32 but some files store it as int32
3568  * with negative values used to correct DTS delays.
3569  There may be abnormally large values as well. */
3570  if (sample_duration > c->max_stts_delta) {
3571  // assume high delta is a correction if negative when cast as int32
3572  int32_t delta_magnitude = (int32_t)sample_duration;
3573  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",
3574  sample_duration, i, sample_count, st->index);
3575  sc->stts_data[i].duration = 1;
3576  corrected_dts = av_sat_add64(corrected_dts, (delta_magnitude < 0 ? (int64_t)delta_magnitude : 1) * sample_count);
3577  } else {
3578  corrected_dts += sample_duration * (uint64_t)sample_count;
3579  }
3580 
3581  current_dts += sc->stts_data[i].duration * (uint64_t)sample_count;
3582 
3583  if (current_dts > corrected_dts) {
3584  int64_t drift = av_sat_sub64(current_dts, corrected_dts) / FFMAX(sample_count, 1);
3585  uint32_t correction = (sc->stts_data[i].duration > drift) ? drift : sc->stts_data[i].duration - 1;
3586  current_dts -= correction * (uint64_t)sample_count;
3587  sc->stts_data[i].duration -= correction;
3588  }
3589 
3590  duration+=(int64_t)sc->stts_data[i].duration*(uint64_t)sc->stts_data[i].count;
3591  total_sample_count+=sc->stts_data[i].count;
3592  }
3593 
3594  sc->stts_count = i;
3595 
3596  if (duration > 0 &&
3597  duration <= INT64_MAX - sc->duration_for_fps &&
3598  total_sample_count <= INT_MAX - sc->nb_frames_for_fps) {
3599  sc->duration_for_fps += duration;
3600  sc->nb_frames_for_fps += total_sample_count;
3601  }
3602 
3603  if (pb->eof_reached) {
3604  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STTS atom\n");
3605  return AVERROR_EOF;
3606  }
3607 
3608  st->nb_frames= total_sample_count;
3609  if (duration)
3610  st->duration= FFMIN(st->duration, duration);
3611 
3612  // All samples have zero duration. They have higher chance be chose by
3613  // mov_find_next_sample, which leads to seek again and again.
3614  //
3615  // It's AVERROR_INVALIDDATA actually, but such files exist in the wild.
3616  // So only mark data stream as discarded for safety.
3617  if (!duration && sc->stts_count &&
3619  av_log(c->fc, AV_LOG_WARNING,
3620  "All samples in data stream index:id [%d:%d] have zero "
3621  "duration, stream set to be discarded by default. Override "
3622  "using AVStream->discard or -discard for ffmpeg command.\n",
3623  st->index, sc->id);
3624  st->discard = AVDISCARD_ALL;
3625  }
3626  sc->track_end = duration;
3627  return 0;
3628 }
3629 
3631 {
3632  AVStream *st;
3633  MOVStreamContext *sc;
3634  int64_t i, entries;
3635 
3636  if (c->fc->nb_streams < 1)
3637  return 0;
3638  st = c->fc->streams[c->fc->nb_streams - 1];
3639  sc = st->priv_data;
3640 
3641  avio_r8(pb); /* version */
3642  avio_rb24(pb); /* flags */
3643  entries = atom.size - 4;
3644 
3645  av_log(c->fc, AV_LOG_TRACE, "track[%u].sdtp.entries = %" PRId64 "\n",
3646  c->fc->nb_streams - 1, entries);
3647 
3648  if (sc->sdtp_data)
3649  av_log(c->fc, AV_LOG_WARNING, "Duplicated SDTP atom\n");
3650  av_freep(&sc->sdtp_data);
3651  sc->sdtp_count = 0;
3652 
3653  sc->sdtp_data = av_malloc(entries);
3654  if (!sc->sdtp_data)
3655  return AVERROR(ENOMEM);
3656 
3657  for (i = 0; i < entries && !pb->eof_reached; i++)
3658  sc->sdtp_data[i] = avio_r8(pb);
3659  sc->sdtp_count = i;
3660 
3661  return 0;
3662 }
3663 
3664 static void mov_update_dts_shift(MOVStreamContext *sc, int duration, void *logctx)
3665 {
3666  if (duration < 0) {
3667  if (duration == INT_MIN) {
3668  av_log(logctx, AV_LOG_WARNING, "mov_update_dts_shift(): dts_shift set to %d\n", INT_MAX);
3669  duration++;
3670  }
3671  sc->dts_shift = FFMAX(sc->dts_shift, -duration);
3672  }
3673 }
3674 
3676 {
3677  AVStream *st;
3678  MOVStreamContext *sc;
3679  unsigned int i, entries, ctts_count = 0;
3680 
3681  if (c->trak_index < 0) {
3682  av_log(c->fc, AV_LOG_WARNING, "CTTS outside TRAK\n");
3683  return 0;
3684  }
3685 
3686  if (c->fc->nb_streams < 1)
3687  return 0;
3688  st = c->fc->streams[c->fc->nb_streams-1];
3689  sc = st->priv_data;
3690 
3691  avio_r8(pb); /* version */
3692  avio_rb24(pb); /* flags */
3693  entries = avio_rb32(pb);
3694 
3695  av_log(c->fc, AV_LOG_TRACE, "track[%u].ctts.entries = %u\n", c->fc->nb_streams - 1, entries);
3696 
3697  if (!entries)
3698  return 0;
3699  if (entries >= UINT_MAX / sizeof(*sc->ctts_data))
3700  return AVERROR_INVALIDDATA;
3701  av_freep(&sc->ctts_data);
3702  sc->ctts_data = av_fast_realloc(NULL, &sc->ctts_allocated_size, entries * sizeof(*sc->ctts_data));
3703  if (!sc->ctts_data)
3704  return AVERROR(ENOMEM);
3705 
3706  for (i = 0; i < entries && !pb->eof_reached; i++) {
3707  MOVCtts *ctts_data;
3708  const size_t min_size_needed = (ctts_count + 1) * sizeof(MOVCtts);
3709  const size_t requested_size =
3710  min_size_needed > sc->ctts_allocated_size ?
3711  FFMAX(min_size_needed, 2 * sc->ctts_allocated_size) :
3712  min_size_needed;
3713  int count = avio_rb32(pb);
3714  int duration = avio_rb32(pb);
3715 
3716  if (count <= 0) {
3717  av_log(c->fc, AV_LOG_TRACE,
3718  "ignoring CTTS entry with count=%d duration=%d\n",
3719  count, duration);
3720  continue;
3721  }
3722 
3723  if (ctts_count >= UINT_MAX / sizeof(MOVCtts) - 1)
3724  return AVERROR(ENOMEM);
3725 
3726  ctts_data = av_fast_realloc(sc->ctts_data, &sc->ctts_allocated_size, requested_size);
3727 
3728  if (!ctts_data)
3729  return AVERROR(ENOMEM);
3730 
3731  sc->ctts_data = ctts_data;
3732 
3733  ctts_data[ctts_count].count = count;
3734  ctts_data[ctts_count].offset = duration;
3735  ctts_count++;
3736 
3737  av_log(c->fc, AV_LOG_TRACE, "count=%d, duration=%d\n",
3738  count, duration);
3739 
3740  if (i+2<entries)
3741  mov_update_dts_shift(sc, duration, c->fc);
3742  }
3743 
3744  sc->ctts_count = ctts_count;
3745 
3746  if (pb->eof_reached) {
3747  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted CTTS atom\n");
3748  return AVERROR_EOF;
3749  }
3750 
3751  av_log(c->fc, AV_LOG_TRACE, "dts shift %d\n", sc->dts_shift);
3752 
3753  return 0;
3754 }
3755 
3757 {
3758  AVStream *st;
3759  MOVStreamContext *sc;
3760  uint8_t version;
3761  uint32_t grouping_type;
3762  uint32_t default_length;
3763  av_unused uint32_t default_group_description_index;
3764  uint32_t entry_count;
3765 
3766  if (c->fc->nb_streams < 1)
3767  return 0;
3768  st = c->fc->streams[c->fc->nb_streams - 1];
3769  sc = st->priv_data;
3770 
3771  version = avio_r8(pb); /* version */
3772  avio_rb24(pb); /* flags */
3773  grouping_type = avio_rl32(pb);
3774 
3775  /*
3776  * This function only supports "sync" boxes, but the code is able to parse
3777  * other boxes (such as "tscl", "tsas" and "stsa")
3778  */
3779  if (grouping_type != MKTAG('s','y','n','c'))
3780  return 0;
3781 
3782  default_length = version >= 1 ? avio_rb32(pb) : 0;
3783  default_group_description_index = version >= 2 ? avio_rb32(pb) : 0;
3784  entry_count = avio_rb32(pb);
3785 
3786  av_freep(&sc->sgpd_sync);
3787  sc->sgpd_sync_count = entry_count;
3788  sc->sgpd_sync = av_calloc(entry_count, sizeof(*sc->sgpd_sync));
3789  if (!sc->sgpd_sync)
3790  return AVERROR(ENOMEM);
3791 
3792  for (uint32_t i = 0; i < entry_count && !pb->eof_reached; i++) {
3793  uint32_t description_length = default_length;
3794  if (version >= 1 && default_length == 0)
3795  description_length = avio_rb32(pb);
3796  if (grouping_type == MKTAG('s','y','n','c')) {
3797  const uint8_t nal_unit_type = avio_r8(pb) & 0x3f;
3798  sc->sgpd_sync[i] = nal_unit_type;
3799  description_length -= 1;
3800  }
3801  avio_skip(pb, description_length);
3802  }
3803 
3804  if (pb->eof_reached) {
3805  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted SGPD atom\n");
3806  return AVERROR_EOF;
3807  }
3808 
3809  return 0;
3810 }
3811 
3813 {
3814  AVStream *st;
3815  MOVStreamContext *sc;
3816  unsigned int i, entries;
3817  uint8_t version;
3818  uint32_t grouping_type;
3819  MOVSbgp *table, **tablep;
3820  int *table_count;
3821 
3822  if (c->fc->nb_streams < 1)
3823  return 0;
3824  st = c->fc->streams[c->fc->nb_streams-1];
3825  sc = st->priv_data;
3826 
3827  version = avio_r8(pb); /* version */
3828  avio_rb24(pb); /* flags */
3829  grouping_type = avio_rl32(pb);
3830 
3831  if (grouping_type == MKTAG('r','a','p',' ')) {
3832  tablep = &sc->rap_group;
3833  table_count = &sc->rap_group_count;
3834  } else if (grouping_type == MKTAG('s','y','n','c')) {
3835  tablep = &sc->sync_group;
3836  table_count = &sc->sync_group_count;
3837  } else {
3838  return 0;
3839  }
3840 
3841  if (version == 1)
3842  avio_rb32(pb); /* grouping_type_parameter */
3843 
3844  entries = avio_rb32(pb);
3845  if (!entries)
3846  return 0;
3847  if (*tablep)
3848  av_log(c->fc, AV_LOG_WARNING, "Duplicated SBGP %s atom\n", av_fourcc2str(grouping_type));
3849  av_freep(tablep);
3850  table = av_malloc_array(entries, sizeof(*table));
3851  if (!table)
3852  return AVERROR(ENOMEM);
3853  *tablep = table;
3854 
3855  for (i = 0; i < entries && !pb->eof_reached; i++) {
3856  table[i].count = avio_rb32(pb); /* sample_count */
3857  table[i].index = avio_rb32(pb); /* group_description_index */
3858  }
3859 
3860  *table_count = i;
3861 
3862  if (pb->eof_reached) {
3863  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted SBGP atom\n");
3864  return AVERROR_EOF;
3865  }
3866 
3867  return 0;
3868 }
3869 
3870 /**
3871  * Get ith edit list entry (media time, duration).
3872  */
3874  const MOVStreamContext *msc,
3875  unsigned int edit_list_index,
3876  int64_t *edit_list_media_time,
3877  int64_t *edit_list_duration,
3878  int64_t global_timescale)
3879 {
3880  if (edit_list_index == msc->elst_count) {
3881  return 0;
3882  }
3883  *edit_list_media_time = msc->elst_data[edit_list_index].time;
3884  *edit_list_duration = msc->elst_data[edit_list_index].duration;
3885 
3886  /* duration is in global timescale units;convert to msc timescale */
3887  if (global_timescale == 0) {
3888  avpriv_request_sample(mov->fc, "Support for mvhd.timescale = 0 with editlists");
3889  return 0;
3890  }
3891  *edit_list_duration = av_rescale(*edit_list_duration, msc->time_scale,
3892  global_timescale);
3893 
3894  if (*edit_list_duration + (uint64_t)*edit_list_media_time > INT64_MAX)
3895  *edit_list_duration = 0;
3896 
3897  return 1;
3898 }
3899 
3900 /**
3901  * Find the closest previous frame to the timestamp_pts, in e_old index
3902  * entries. Searching for just any frame / just key frames can be controlled by
3903  * last argument 'flag'.
3904  * Note that if ctts_data is not NULL, we will always search for a key frame
3905  * irrespective of the value of 'flag'. If we don't find any keyframe, we will
3906  * return the first frame of the video.
3907  *
3908  * Here the timestamp_pts is considered to be a presentation timestamp and
3909  * the timestamp of index entries are considered to be decoding timestamps.
3910  *
3911  * Returns 0 if successful in finding a frame, else returns -1.
3912  * Places the found index corresponding output arg.
3913  *
3914  * If ctts_old is not NULL, then refines the searched entry by searching
3915  * backwards from the found timestamp, to find the frame with correct PTS.
3916  *
3917  * Places the found ctts_index and ctts_sample in corresponding output args.
3918  */
3920  AVIndexEntry *e_old,
3921  int nb_old,
3922  MOVTimeToSample *tts_data,
3923  int64_t tts_count,
3924  int64_t timestamp_pts,
3925  int flag,
3926  int64_t* index,
3927  int64_t* tts_index,
3928  int64_t* tts_sample)
3929 {
3930  MOVStreamContext *msc = st->priv_data;
3931  FFStream *const sti = ffstream(st);
3932  AVIndexEntry *e_keep = sti->index_entries;
3933  int nb_keep = sti->nb_index_entries;
3934  int64_t i = 0;
3935 
3936  av_assert0(index);
3937 
3938  // If dts_shift > 0, then all the index timestamps will have to be offset by
3939  // at least dts_shift amount to obtain PTS.
3940  // Hence we decrement the searched timestamp_pts by dts_shift to find the closest index element.
3941  if (msc->dts_shift > 0) {
3942  timestamp_pts -= msc->dts_shift;
3943  }
3944 
3945  sti->index_entries = e_old;
3946  sti->nb_index_entries = nb_old;
3947  *index = av_index_search_timestamp(st, timestamp_pts, flag | AVSEEK_FLAG_BACKWARD);
3948 
3949  // Keep going backwards in the index entries until the timestamp is the same.
3950  if (*index >= 0) {
3951  for (i = *index; i > 0 && e_old[i].timestamp == e_old[i - 1].timestamp;
3952  i--) {
3953  if ((flag & AVSEEK_FLAG_ANY) ||
3954  (e_old[i - 1].flags & AVINDEX_KEYFRAME)) {
3955  *index = i - 1;
3956  }
3957  }
3958  }
3959 
3960  // If we have CTTS then refine the search, by searching backwards over PTS
3961  // computed by adding corresponding CTTS durations to index timestamps.
3962  if (msc->ctts_count && *index >= 0) {
3963  av_assert0(tts_index);
3964  av_assert0(tts_sample);
3965  // Find out the ctts_index for the found frame.
3966  *tts_index = 0;
3967  *tts_sample = 0;
3968  for (int64_t index_tts_count = 0; index_tts_count < *index; index_tts_count++) {
3969  if (*tts_index < tts_count) {
3970  (*tts_sample)++;
3971  if (tts_data[*tts_index].count == *tts_sample) {
3972  (*tts_index)++;
3973  *tts_sample = 0;
3974  }
3975  }
3976  }
3977 
3978  while (*index >= 0 && (*tts_index) >= 0 && (*tts_index) < tts_count) {
3979  // Find a "key frame" with PTS <= timestamp_pts (So that we can decode B-frames correctly).
3980  // No need to add dts_shift to the timestamp here because timestamp_pts has already been
3981  // compensated by dts_shift above.
3982  if ((e_old[*index].timestamp + tts_data[*tts_index].offset) <= timestamp_pts &&
3983  (e_old[*index].flags & AVINDEX_KEYFRAME)) {
3984  break;
3985  }
3986 
3987  (*index)--;
3988  if (*tts_sample == 0) {
3989  (*tts_index)--;
3990  if (*tts_index >= 0)
3991  *tts_sample = tts_data[*tts_index].count - 1;
3992  } else {
3993  (*tts_sample)--;
3994  }
3995  }
3996  }
3997 
3998  /* restore AVStream state*/
3999  sti->index_entries = e_keep;
4000  sti->nb_index_entries = nb_keep;
4001  return *index >= 0 ? 0 : -1;
4002 }
4003 
4004 /**
4005  * Add index entry with the given values, to the end of ffstream(st)->index_entries.
4006  * Returns the new size ffstream(st)->index_entries if successful, else returns -1.
4007  *
4008  * This function is similar to ff_add_index_entry in libavformat/utils.c
4009  * except that here we are always unconditionally adding an index entry to
4010  * the end, instead of searching the entries list and skipping the add if
4011  * there is an existing entry with the same timestamp.
4012  * This is needed because the mov_fix_index calls this func with the same
4013  * unincremented timestamp for successive discarded frames.
4014  */
4016  int size, int distance, int flags)
4017 {
4018  FFStream *const sti = ffstream(st);
4019  AVIndexEntry *entries, *ie;
4020  int64_t index = -1;
4021  const size_t min_size_needed = (sti->nb_index_entries + 1) * sizeof(AVIndexEntry);
4022 
4023  // Double the allocation each time, to lower memory fragmentation.
4024  // Another difference from ff_add_index_entry function.
4025  const size_t requested_size =
4026  min_size_needed > sti->index_entries_allocated_size ?
4027  FFMAX(min_size_needed, 2 * sti->index_entries_allocated_size) :
4028  min_size_needed;
4029 
4030  if (sti->nb_index_entries + 1U >= UINT_MAX / sizeof(AVIndexEntry))
4031  return -1;
4032 
4033  entries = av_fast_realloc(sti->index_entries,
4035  requested_size);
4036  if (!entries)
4037  return -1;
4038 
4039  sti->index_entries = entries;
4040 
4041  index = sti->nb_index_entries++;
4042  ie= &entries[index];
4043 
4044  ie->pos = pos;
4045  ie->timestamp = timestamp;
4046  ie->min_distance= distance;
4047  ie->size= size;
4048  ie->flags = flags;
4049  return index;
4050 }
4051 
4052 /**
4053  * Rewrite timestamps of index entries in the range [end_index - frame_duration_buffer_size, end_index)
4054  * by subtracting end_ts successively by the amounts given in frame_duration_buffer.
4055  */
4056 static void fix_index_entry_timestamps(AVStream* st, int end_index, int64_t end_ts,
4057  int64_t* frame_duration_buffer,
4058  int frame_duration_buffer_size) {
4059  FFStream *const sti = ffstream(st);
4060  int i = 0;
4061  av_assert0(end_index >= 0 && end_index <= sti->nb_index_entries);
4062  for (i = 0; i < frame_duration_buffer_size; i++) {
4063  end_ts -= frame_duration_buffer[frame_duration_buffer_size - 1 - i];
4064  sti->index_entries[end_index - 1 - i].timestamp = end_ts;
4065  }
4066 }
4067 
4068 static int add_tts_entry(MOVTimeToSample **tts_data, unsigned int *tts_count, unsigned int *allocated_size,
4069  int count, int offset, unsigned int duration)
4070 {
4071  MOVTimeToSample *tts_buf_new;
4072  const size_t min_size_needed = (*tts_count + 1) * sizeof(MOVTimeToSample);
4073  const size_t requested_size =
4074  min_size_needed > *allocated_size ?
4075  FFMAX(min_size_needed, 2 * (*allocated_size)) :
4076  min_size_needed;
4077 
4078  if ((unsigned)(*tts_count) >= UINT_MAX / sizeof(MOVTimeToSample) - 1)
4079  return -1;
4080 
4081  tts_buf_new = av_fast_realloc(*tts_data, allocated_size, requested_size);
4082 
4083  if (!tts_buf_new)
4084  return -1;
4085 
4086  *tts_data = tts_buf_new;
4087 
4088  tts_buf_new[*tts_count].count = count;
4089  tts_buf_new[*tts_count].offset = offset;
4090  tts_buf_new[*tts_count].duration = duration;
4091 
4092  *tts_count = (*tts_count) + 1;
4093  return 0;
4094 }
4095 
4096 #define MAX_REORDER_DELAY 16
4098 {
4099  MOVStreamContext *msc = st->priv_data;
4100  FFStream *const sti = ffstream(st);
4101  int ctts_ind = 0;
4102  int ctts_sample = 0;
4103  int64_t pts_buf[MAX_REORDER_DELAY + 1]; // Circular buffer to sort pts.
4104  int buf_start = 0;
4105  int j, r, num_swaps;
4106 
4107  for (j = 0; j < MAX_REORDER_DELAY + 1; j++)
4108  pts_buf[j] = INT64_MIN;
4109 
4110  if (st->codecpar->video_delay <= 0 && msc->ctts_count &&
4112  st->codecpar->video_delay = 0;
4113  for (int ind = 0; ind < sti->nb_index_entries && ctts_ind < msc->tts_count; ++ind) {
4114  // Point j to the last elem of the buffer and insert the current pts there.
4115  j = buf_start;
4116  buf_start = (buf_start + 1);
4117  if (buf_start == MAX_REORDER_DELAY + 1)
4118  buf_start = 0;
4119 
4120  pts_buf[j] = sti->index_entries[ind].timestamp + msc->tts_data[ctts_ind].offset;
4121 
4122  // The timestamps that are already in the sorted buffer, and are greater than the
4123  // current pts, are exactly the timestamps that need to be buffered to output PTS
4124  // in correct sorted order.
4125  // Hence the video delay (which is the buffer size used to sort DTS and output PTS),
4126  // can be computed as the maximum no. of swaps any particular timestamp needs to
4127  // go through, to keep this buffer in sorted order.
4128  num_swaps = 0;
4129  while (j != buf_start) {
4130  r = j - 1;
4131  if (r < 0) r = MAX_REORDER_DELAY;
4132  if (pts_buf[j] < pts_buf[r]) {
4133  FFSWAP(int64_t, pts_buf[j], pts_buf[r]);
4134  ++num_swaps;
4135  } else {
4136  break;
4137  }
4138  j = r;
4139  }
4140  st->codecpar->video_delay = FFMAX(st->codecpar->video_delay, num_swaps);
4141 
4142  ctts_sample++;
4143  if (ctts_sample == msc->tts_data[ctts_ind].count) {
4144  ctts_ind++;
4145  ctts_sample = 0;
4146  }
4147  }
4148  av_log(c->fc, AV_LOG_DEBUG, "Setting codecpar->delay to %d for stream st: %d\n",
4149  st->codecpar->video_delay, st->index);
4150  }
4151 }
4152 
4154 {
4155  sc->current_sample++;
4156  sc->current_index++;
4157  if (sc->index_ranges &&
4158  sc->current_index >= sc->current_index_range->end &&
4159  sc->current_index_range->end) {
4160  sc->current_index_range++;
4162  }
4163 }
4164 
4166 {
4167  sc->current_sample--;
4168  sc->current_index--;
4169  if (sc->index_ranges &&
4171  sc->current_index_range > sc->index_ranges) {
4172  sc->current_index_range--;
4173  sc->current_index = sc->current_index_range->end - 1;
4174  }
4175 }
4176 
4177 static void mov_current_sample_set(MOVStreamContext *sc, int current_sample)
4178 {
4179  int64_t range_size;
4180 
4181  sc->current_sample = current_sample;
4182  sc->current_index = current_sample;
4183  if (!sc->index_ranges) {
4184  return;
4185  }
4186 
4187  for (sc->current_index_range = sc->index_ranges;
4188  sc->current_index_range->end;
4189  sc->current_index_range++) {
4190  range_size = sc->current_index_range->end - sc->current_index_range->start;
4191  if (range_size > current_sample) {
4192  sc->current_index = sc->current_index_range->start + current_sample;
4193  break;
4194  }
4195  current_sample -= range_size;
4196  }
4197 }
4198 
4199 /**
4200  * Fix ffstream(st)->index_entries, so that it contains only the entries (and the entries
4201  * which are needed to decode them) that fall in the edit list time ranges.
4202  * Also fixes the timestamps of the index entries to match the timeline
4203  * specified the edit lists.
4204  */
4205 static void mov_fix_index(MOVContext *mov, AVStream *st)
4206 {
4207  MOVStreamContext *msc = st->priv_data;
4208  FFStream *const sti = ffstream(st);
4209  AVIndexEntry *e_old = sti->index_entries;
4210  int nb_old = sti->nb_index_entries;
4211  const AVIndexEntry *e_old_end = e_old + nb_old;
4212  const AVIndexEntry *current = NULL;
4213  MOVTimeToSample *tts_data_old = msc->tts_data;
4214  int64_t tts_index_old = 0;
4215  int64_t tts_sample_old = 0;
4216  int64_t tts_count_old = msc->tts_count;
4217  int64_t edit_list_media_time = 0;
4218  int64_t edit_list_duration = 0;
4219  int64_t frame_duration = 0;
4220  int64_t edit_list_dts_counter = 0;
4221  int64_t edit_list_dts_entry_end = 0;
4222  int64_t edit_list_start_tts_sample = 0;
4223  int64_t curr_cts;
4224  int64_t curr_ctts = 0;
4225  int64_t empty_edits_sum_duration = 0;
4226  int64_t edit_list_index = 0;
4227  int64_t index;
4228  int flags;
4229  int64_t start_dts = 0;
4230  int64_t edit_list_start_encountered = 0;
4231  int64_t search_timestamp = 0;
4232  int64_t* frame_duration_buffer = NULL;
4233  int num_discarded_begin = 0;
4234  int first_non_zero_audio_edit = -1;
4235  int packet_skip_samples = 0;
4236  MOVIndexRange *current_index_range = NULL;
4237  int found_keyframe_after_edit = 0;
4238  int found_non_empty_edit = 0;
4239 
4240  if (!msc->elst_data || msc->elst_count <= 0 || nb_old <= 0) {
4241  return;
4242  }
4243 
4244  // allocate the index ranges array
4245  msc->index_ranges = av_malloc_array(msc->elst_count + 1,
4246  sizeof(msc->index_ranges[0]));
4247  if (!msc->index_ranges) {
4248  av_log(mov->fc, AV_LOG_ERROR, "Cannot allocate index ranges buffer\n");
4249  return;
4250  }
4251  msc->current_index_range = msc->index_ranges;
4252 
4253  // Clean AVStream from traces of old index
4254  sti->index_entries = NULL;
4256  sti->nb_index_entries = 0;
4257 
4258  // Clean time to sample fields of MOVStreamContext
4259  msc->tts_data = NULL;
4260  msc->tts_count = 0;
4261  msc->tts_index = 0;
4262  msc->tts_sample = 0;
4263  msc->tts_allocated_size = 0;
4264 
4265  // Reinitialize min_corrected_pts so that it can be computed again.
4266  msc->min_corrected_pts = -1;
4267 
4268  // If the dts_shift is positive (in case of negative ctts values in mov),
4269  // then negate the DTS by dts_shift
4270  if (msc->dts_shift > 0) {
4271  edit_list_dts_entry_end -= msc->dts_shift;
4272  av_log(mov->fc, AV_LOG_DEBUG, "Shifting DTS by %d because of negative CTTS.\n", msc->dts_shift);
4273  }
4274 
4275  start_dts = edit_list_dts_entry_end;
4276 
4277  while (get_edit_list_entry(mov, msc, edit_list_index, &edit_list_media_time,
4278  &edit_list_duration, mov->time_scale)) {
4279  av_log(mov->fc, AV_LOG_DEBUG, "Processing st: %d, edit list %"PRId64" - media time: %"PRId64", duration: %"PRId64"\n",
4280  st->index, edit_list_index, edit_list_media_time, edit_list_duration);
4281  edit_list_index++;
4282  edit_list_dts_counter = edit_list_dts_entry_end;
4283  edit_list_dts_entry_end += edit_list_duration;
4284  num_discarded_begin = 0;
4285  if (!found_non_empty_edit && edit_list_media_time == -1) {
4286  empty_edits_sum_duration += edit_list_duration;
4287  continue;
4288  }
4289  found_non_empty_edit = 1;
4290 
4291  // If we encounter a non-negative edit list reset the skip_samples/start_pad fields and set them
4292  // according to the edit list below.
4293  if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
4294  if (first_non_zero_audio_edit < 0) {
4295  first_non_zero_audio_edit = 1;
4296  } else {
4297  first_non_zero_audio_edit = 0;
4298  }
4299 
4300  if (first_non_zero_audio_edit > 0)
4301  sti->skip_samples = msc->start_pad = 0;
4302  }
4303 
4304  // While reordering frame index according to edit list we must handle properly
4305  // the scenario when edit list entry starts from none key frame.
4306  // We find closest previous key frame and preserve it and consequent frames in index.
4307  // All frames which are outside edit list entry time boundaries will be dropped after decoding.
4308  search_timestamp = edit_list_media_time;
4309  if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
4310  // Audio decoders like AAC need need a decoder delay samples previous to the current sample,
4311  // to correctly decode this frame. Hence for audio we seek to a frame 1 sec. before the
4312  // edit_list_media_time to cover the decoder delay.
4313  search_timestamp = FFMAX(search_timestamp - msc->time_scale, e_old[0].timestamp);
4314  }
4315 
4316  if (find_prev_closest_index(st, e_old, nb_old, tts_data_old, tts_count_old, search_timestamp, 0,
4317  &index, &tts_index_old, &tts_sample_old) < 0) {
4318  av_log(mov->fc, AV_LOG_WARNING,
4319  "st: %d edit list: %"PRId64" Missing key frame while searching for timestamp: %"PRId64"\n",
4320  st->index, edit_list_index, search_timestamp);
4321  if (find_prev_closest_index(st, e_old, nb_old, tts_data_old, tts_count_old, search_timestamp, AVSEEK_FLAG_ANY,
4322  &index, &tts_index_old, &tts_sample_old) < 0) {
4323  av_log(mov->fc, AV_LOG_WARNING,
4324  "st: %d edit list %"PRId64" Cannot find an index entry before timestamp: %"PRId64".\n",
4325  st->index, edit_list_index, search_timestamp);
4326  index = 0;
4327  tts_index_old = 0;
4328  tts_sample_old = 0;
4329  }
4330  }
4331  current = e_old + index;
4332  edit_list_start_tts_sample = tts_sample_old;
4333 
4334  // Iterate over index and arrange it according to edit list
4335  edit_list_start_encountered = 0;
4336  found_keyframe_after_edit = 0;
4337  for (; current < e_old_end; current++, index++) {
4338  // check if frame outside edit list mark it for discard
4339  frame_duration = (current + 1 < e_old_end) ?
4340  ((current + 1)->timestamp - current->timestamp) : edit_list_duration;
4341 
4342  flags = current->flags;
4343 
4344  // frames (pts) before or after edit list
4345  curr_cts = current->timestamp + msc->dts_shift;
4346  curr_ctts = 0;
4347 
4348  if (tts_data_old && tts_index_old < tts_count_old) {
4349  curr_ctts = tts_data_old[tts_index_old].offset;
4350  av_log(mov->fc, AV_LOG_TRACE, "stts: %"PRId64" ctts: %"PRId64", tts_index: %"PRId64", tts_count: %"PRId64"\n",
4351  curr_cts, curr_ctts, tts_index_old, tts_count_old);
4352  curr_cts += curr_ctts;
4353  tts_sample_old++;
4354  if (tts_sample_old == tts_data_old[tts_index_old].count) {
4355  if (add_tts_entry(&msc->tts_data, &msc->tts_count,
4356  &msc->tts_allocated_size,
4357  tts_data_old[tts_index_old].count - edit_list_start_tts_sample,
4358  tts_data_old[tts_index_old].offset, tts_data_old[tts_index_old].duration) == -1) {
4359  av_log(mov->fc, AV_LOG_ERROR, "Cannot add Time To Sample entry %"PRId64" - {%"PRId64", %d}\n",
4360  tts_index_old,
4361  tts_data_old[tts_index_old].count - edit_list_start_tts_sample,
4362  tts_data_old[tts_index_old].offset);
4363  break;
4364  }
4365  tts_index_old++;
4366  tts_sample_old = 0;
4367  edit_list_start_tts_sample = 0;
4368  }
4369  }
4370 
4371  if (curr_cts < edit_list_media_time || curr_cts >= (edit_list_duration + edit_list_media_time)) {
4373  curr_cts < edit_list_media_time && curr_cts + frame_duration > edit_list_media_time &&
4374  first_non_zero_audio_edit > 0) {
4375  packet_skip_samples = edit_list_media_time - curr_cts;
4376  sti->skip_samples += packet_skip_samples;
4377 
4378  // Shift the index entry timestamp by packet_skip_samples to be correct.
4379  edit_list_dts_counter -= packet_skip_samples;
4380  if (edit_list_start_encountered == 0) {
4381  edit_list_start_encountered = 1;
4382  // Make timestamps strictly monotonically increasing for audio, by rewriting timestamps for
4383  // discarded packets.
4384  if (frame_duration_buffer) {
4385  fix_index_entry_timestamps(st, sti->nb_index_entries, edit_list_dts_counter,
4386  frame_duration_buffer, num_discarded_begin);
4387  av_freep(&frame_duration_buffer);
4388  }
4389  }
4390 
4391  av_log(mov->fc, AV_LOG_DEBUG, "skip %d audio samples from curr_cts: %"PRId64"\n", packet_skip_samples, curr_cts);
4392  } else {
4394  av_log(mov->fc, AV_LOG_DEBUG, "drop a frame at curr_cts: %"PRId64" @ %"PRId64"\n", curr_cts, index);
4395 
4396  if (edit_list_start_encountered == 0) {
4397  num_discarded_begin++;
4398  frame_duration_buffer = av_realloc(frame_duration_buffer,
4399  num_discarded_begin * sizeof(int64_t));
4400  if (!frame_duration_buffer) {
4401  av_log(mov->fc, AV_LOG_ERROR, "Cannot reallocate frame duration buffer\n");
4402  break;
4403  }
4404  frame_duration_buffer[num_discarded_begin - 1] = frame_duration;
4405 
4406  // Increment skip_samples for the first non-zero audio edit list
4407  if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
4408  first_non_zero_audio_edit > 0 && st->codecpar->codec_id != AV_CODEC_ID_VORBIS) {
4409  sti->skip_samples += frame_duration;
4410  }
4411  }
4412  }
4413  } else {
4414  if (msc->min_corrected_pts < 0) {
4415  msc->min_corrected_pts = edit_list_dts_counter + curr_ctts + msc->dts_shift;
4416  } else {
4417  msc->min_corrected_pts = FFMIN(msc->min_corrected_pts, edit_list_dts_counter + curr_ctts + msc->dts_shift);
4418  }
4419  if (edit_list_start_encountered == 0) {
4420  edit_list_start_encountered = 1;
4421  // Make timestamps strictly monotonically increasing by rewriting timestamps for
4422  // discarded packets.
4423  if (frame_duration_buffer) {
4424  fix_index_entry_timestamps(st, sti->nb_index_entries, edit_list_dts_counter,
4425  frame_duration_buffer, num_discarded_begin);
4426  av_freep(&frame_duration_buffer);
4427  }
4428  }
4429  }
4430 
4431  if (add_index_entry(st, current->pos, edit_list_dts_counter, current->size,
4432  current->min_distance, flags) == -1) {
4433  av_log(mov->fc, AV_LOG_ERROR, "Cannot add index entry\n");
4434  break;
4435  }
4436 
4437  // Update the index ranges array
4438  if (!current_index_range || index != current_index_range->end) {
4439  current_index_range = current_index_range ? current_index_range + 1
4440  : msc->index_ranges;
4441  current_index_range->start = index;
4442  }
4443  current_index_range->end = index + 1;
4444 
4445  // Only start incrementing DTS in frame_duration amounts, when we encounter a frame in edit list.
4446  if (edit_list_start_encountered > 0) {
4447  edit_list_dts_counter = edit_list_dts_counter + frame_duration;
4448  }
4449 
4450  // Break when found first key frame after edit entry completion
4451  if ((curr_cts + frame_duration >= (edit_list_duration + edit_list_media_time)) &&
4453  if (msc->ctts_count) {
4454  // If we have CTTS and this is the first keyframe after edit elist,
4455  // wait for one more, because there might be trailing B-frames after this I-frame
4456  // that do belong to the edit.
4457  if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO && found_keyframe_after_edit == 0) {
4458  found_keyframe_after_edit = 1;
4459  continue;
4460  }
4461  if (tts_sample_old != 0) {
4462  if (add_tts_entry(&msc->tts_data, &msc->tts_count,
4463  &msc->tts_allocated_size,
4464  tts_sample_old - edit_list_start_tts_sample,
4465  tts_data_old[tts_index_old].offset, tts_data_old[tts_index_old].duration) == -1) {
4466  av_log(mov->fc, AV_LOG_ERROR, "Cannot add Time To Sample entry %"PRId64" - {%"PRId64", %d}\n",
4467  tts_index_old, tts_sample_old - edit_list_start_tts_sample,
4468  tts_data_old[tts_index_old].offset);
4469  break;
4470  }
4471  }
4472  }
4473  break;
4474  }
4475  }
4476  }
4477  // If there are empty edits, then msc->min_corrected_pts might be positive
4478  // intentionally. So we subtract the sum duration of empty edits here.
4479  msc->min_corrected_pts -= empty_edits_sum_duration;
4480 
4481  // If the minimum pts turns out to be greater than zero after fixing the index, then we subtract the
4482  // dts by that amount to make the first pts zero.
4483  if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
4484  if (msc->min_corrected_pts > 0) {
4485  av_log(mov->fc, AV_LOG_DEBUG, "Offset DTS by %"PRId64" to make first pts zero.\n", msc->min_corrected_pts);
4486  for (int i = 0; i < sti->nb_index_entries; ++i)
4488  }
4489  }
4490  // Start time should be equal to zero or the duration of any empty edits.
4491  st->start_time = empty_edits_sum_duration;
4492 
4493  // Update av stream length, if it ends up shorter than the track's media duration
4494  st->duration = FFMIN(st->duration, edit_list_dts_entry_end - start_dts);
4495  msc->start_pad = sti->skip_samples;
4496 
4497  // Free the old index and the old CTTS structures
4498  av_free(e_old);
4499  av_free(tts_data_old);
4500  av_freep(&frame_duration_buffer);
4501 
4502  // Null terminate the index ranges array
4503  current_index_range = current_index_range ? current_index_range + 1
4504  : msc->index_ranges;
4505  current_index_range->start = 0;
4506  current_index_range->end = 0;
4507  msc->current_index = msc->index_ranges[0].start;
4508 }
4509 
4510 static uint32_t get_sgpd_sync_index(const MOVStreamContext *sc, int nal_unit_type)
4511 {
4512  for (uint32_t i = 0; i < sc->sgpd_sync_count; i++)
4513  if (sc->sgpd_sync[i] == nal_unit_type)
4514  return i + 1;
4515  return 0;
4516 }
4517 
4519 {
4520  int k;
4521  int sample_id = 0;
4522  uint32_t cra_index;
4523  MOVStreamContext *sc = st->priv_data;
4524 
4525  if (st->codecpar->codec_id != AV_CODEC_ID_HEVC || !sc->sync_group_count)
4526  return 0;
4527 
4528  /* Build an unrolled index of the samples */
4529  sc->sample_offsets_count = 0;
4530  for (uint32_t i = 0; i < sc->ctts_count; i++) {
4531  if (sc->ctts_data[i].count > INT_MAX - sc->sample_offsets_count)
4532  return AVERROR(ENOMEM);
4533  sc->sample_offsets_count += sc->ctts_data[i].count;
4534  }
4535  av_freep(&sc->sample_offsets);
4537  if (!sc->sample_offsets)
4538  return AVERROR(ENOMEM);
4539  k = 0;
4540  for (uint32_t i = 0; i < sc->ctts_count; i++)
4541  for (int j = 0; j < sc->ctts_data[i].count; j++)
4542  sc->sample_offsets[k++] = sc->ctts_data[i].offset;
4543 
4544  /* The following HEVC NAL type reveal the use of open GOP sync points
4545  * (TODO: BLA types may also be concerned) */
4546  cra_index = get_sgpd_sync_index(sc, HEVC_NAL_CRA_NUT); /* Clean Random Access */
4547  if (!cra_index)
4548  return 0;
4549 
4550  /* Build a list of open-GOP key samples */
4551  sc->open_key_samples_count = 0;
4552  for (uint32_t i = 0; i < sc->sync_group_count; i++)
4553  if (sc->sync_group[i].index == cra_index) {
4554  if (sc->sync_group[i].count > INT_MAX - sc->open_key_samples_count)
4555  return AVERROR(ENOMEM);
4557  }
4558  av_freep(&sc->open_key_samples);
4560  if (!sc->open_key_samples)
4561  return AVERROR(ENOMEM);
4562  k = 0;
4563  for (uint32_t i = 0; i < sc->sync_group_count; i++) {
4564  const MOVSbgp *sg = &sc->sync_group[i];
4565  if (sg->index == cra_index)
4566  for (uint32_t j = 0; j < sg->count; j++)
4567  sc->open_key_samples[k++] = sample_id;
4568  if (sg->count > INT_MAX - sample_id)
4569  return AVERROR_PATCHWELCOME;
4570  sample_id += sg->count;
4571  }
4572 
4573  /* Identify the minimal time step between samples */
4574  sc->min_sample_duration = UINT_MAX;
4575  for (uint32_t i = 0; i < sc->stts_count; i++)
4577 
4578  return 0;
4579 }
4580 
4581 #define MOV_MERGE_CTTS 1
4582 #define MOV_MERGE_STTS 2
4583 /*
4584  * Merge stts and ctts arrays into a new combined array.
4585  * stts_count and ctts_count may be left untouched as they will be
4586  * used to check for the presence of either of them.
4587  */
4588 static int mov_merge_tts_data(MOVContext *mov, AVStream *st, int flags)
4589 {
4590  MOVStreamContext *sc = st->priv_data;
4591  int ctts = sc->ctts_data && (flags & MOV_MERGE_CTTS);
4592  int stts = sc->stts_data && (flags & MOV_MERGE_STTS);
4593  int idx = 0;
4594 
4595  if (!sc->ctts_data && !sc->stts_data)
4596  return 0;
4597  // Expand time to sample entries such that we have a 1-1 mapping with samples
4598  if (!sc->sample_count || sc->sample_count >= UINT_MAX / sizeof(*sc->tts_data))
4599  return -1;
4600 
4601  if (ctts) {
4603  sc->sample_count * sizeof(*sc->tts_data));
4604  if (!sc->tts_data)
4605  return -1;
4606 
4607  memset(sc->tts_data, 0, sc->tts_allocated_size);
4608 
4609  for (int i = 0; i < sc->ctts_count &&
4610  idx < sc->sample_count; i++)
4611  for (int j = 0; j < sc->ctts_data[i].count &&
4612  idx < sc->sample_count; j++) {
4613  sc->tts_data[idx].offset = sc->ctts_data[i].offset;
4614  sc->tts_data[idx++].count = 1;
4615  }
4616 
4617  sc->tts_count = idx;
4618  } else
4619  sc->ctts_count = 0;
4620  av_freep(&sc->ctts_data);
4621  sc->ctts_allocated_size = 0;
4622 
4623  idx = 0;
4624  if (stts) {
4626  sc->sample_count * sizeof(*sc->tts_data));
4627  if (!tts_data)
4628  return -1;
4629 
4630  if (!sc->tts_data)
4631  memset(tts_data, 0, sc->tts_allocated_size);
4632  sc->tts_data = tts_data;
4633 
4634  for (int i = 0; i < sc->stts_count &&
4635  idx < sc->sample_count; i++)
4636  for (int j = 0; j < sc->stts_data[i].count &&
4637  idx < sc->sample_count; j++) {
4638  sc->tts_data[idx].duration = sc->stts_data[i].duration;
4639  sc->tts_data[idx++].count = 1;
4640  }
4641 
4642  sc->tts_count = FFMAX(sc->tts_count, idx);
4643  } else
4644  sc->stts_count = 0;
4645  av_freep(&sc->stts_data);
4646  sc->stts_allocated_size = 0;
4647 
4648  return 0;
4649 }
4650 
4651 static void mov_build_index(MOVContext *mov, AVStream *st)
4652 {
4653  MOVStreamContext *sc = st->priv_data;
4654  FFStream *const sti = ffstream(st);
4655  int64_t current_offset;
4656  int64_t current_dts = 0;
4657  unsigned int stts_index = 0;
4658  unsigned int stsc_index = 0;
4659  unsigned int stss_index = 0;
4660  unsigned int stps_index = 0;
4661  unsigned int i, j;
4662  uint64_t stream_size = 0;
4663 
4664  int ret = build_open_gop_key_points(st);
4665  if (ret < 0)
4666  return;
4667 
4668  if (sc->elst_count) {
4669  int i, edit_start_index = 0, multiple_edits = 0;
4670  int64_t empty_duration = 0; // empty duration of the first edit list entry
4671  int64_t start_time = 0; // start time of the media
4672 
4673  for (i = 0; i < sc->elst_count; i++) {
4674  const MOVElst *e = &sc->elst_data[i];
4675  if (i == 0 && e->time == -1) {
4676  /* if empty, the first entry is the start time of the stream
4677  * relative to the presentation itself */
4678  empty_duration = e->duration;
4679  edit_start_index = 1;
4680  } else if (i == edit_start_index && e->time >= 0) {
4681  start_time = e->time;
4682  } else {
4683  multiple_edits = 1;
4684  }
4685  }
4686 
4687  if (multiple_edits && !mov->advanced_editlist) {
4689  av_log(mov->fc, AV_LOG_WARNING, "multiple edit list entries, "
4690  "not supported in fragmented MP4 files\n");
4691  else
4692  av_log(mov->fc, AV_LOG_WARNING, "multiple edit list entries, "
4693  "Use -advanced_editlist to correctly decode otherwise "
4694  "a/v desync might occur\n");
4695  }
4696 
4697  /* adjust first dts according to edit list */
4698  if ((empty_duration || start_time) && mov->time_scale > 0) {
4699  if (empty_duration)
4700  empty_duration = av_rescale(empty_duration, sc->time_scale, mov->time_scale);
4701 
4702  if (av_sat_sub64(start_time, empty_duration) != start_time - (uint64_t)empty_duration)
4703  av_log(mov->fc, AV_LOG_WARNING, "start_time - empty_duration is not representable\n");
4704 
4705  sc->time_offset = start_time - (uint64_t)empty_duration;
4707  if (!mov->advanced_editlist)
4708  current_dts = -sc->time_offset;
4709  }
4710 
4711  if (!multiple_edits && !mov->advanced_editlist &&
4713  sc->start_pad = start_time;
4714  }
4715 
4716  /* only use old uncompressed audio chunk demuxing when stts specifies it */
4717  if (!(st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
4718  sc->stts_count == 1 && sc->stts_data && sc->stts_data[0].duration == 1)) {
4719  unsigned int current_sample = 0;
4720  unsigned int stts_sample = 0;
4721  unsigned int sample_size;
4722  unsigned int distance = 0;
4723  unsigned int rap_group_index = 0;
4724  unsigned int rap_group_sample = 0;
4725  int rap_group_present = sc->rap_group_count && sc->rap_group;
4726  int key_off = (sc->keyframe_count && sc->keyframes[0] > 0) || (sc->stps_count && sc->stps_data[0] > 0);
4727 
4728  current_dts -= sc->dts_shift;
4729 
4730  if (!sc->sample_count || sti->nb_index_entries || sc->tts_count)
4731  return;
4732  if (sc->sample_count >= UINT_MAX / sizeof(*sti->index_entries) - sti->nb_index_entries)
4733  return;
4734  if (av_reallocp_array(&sti->index_entries,
4735  sti->nb_index_entries + sc->sample_count,
4736  sizeof(*sti->index_entries)) < 0) {
4737  sti->nb_index_entries = 0;
4738  return;
4739  }
4740  sti->index_entries_allocated_size = (sti->nb_index_entries + sc->sample_count) * sizeof(*sti->index_entries);
4741 
4743  if (ret < 0)
4744  return;
4745 
4746  for (i = 0; i < sc->chunk_count; i++) {
4747  int64_t next_offset = i+1 < sc->chunk_count ? sc->chunk_offsets[i+1] : INT64_MAX;
4748  current_offset = sc->chunk_offsets[i];
4749  while (mov_stsc_index_valid(stsc_index, sc->stsc_count) &&
4750  i + 1 == sc->stsc_data[stsc_index + 1].first)
4751  stsc_index++;
4752 
4753  if (next_offset > current_offset && sc->sample_size>0 && sc->sample_size < sc->stsz_sample_size &&
4754  sc->stsc_data[stsc_index].count * (int64_t)sc->stsz_sample_size > next_offset - current_offset) {
4755  av_log(mov->fc, AV_LOG_WARNING, "STSZ sample size %d invalid (too large), ignoring\n", sc->stsz_sample_size);
4756  sc->stsz_sample_size = sc->sample_size;
4757  }
4758  if (sc->stsz_sample_size>0 && sc->stsz_sample_size < sc->sample_size) {
4759  av_log(mov->fc, AV_LOG_WARNING, "STSZ sample size %d invalid (too small), ignoring\n", sc->stsz_sample_size);
4760  sc->stsz_sample_size = sc->sample_size;
4761  }
4762 
4763  for (j = 0; j < sc->stsc_data[stsc_index].count; j++) {
4764  int keyframe = 0;
4765  if (current_sample >= sc->sample_count) {
4766  av_log(mov->fc, AV_LOG_ERROR, "wrong sample count\n");
4767  return;
4768  }
4769 
4770  if (!sc->keyframe_absent && (!sc->keyframe_count || current_sample+key_off == sc->keyframes[stss_index])) {
4771  keyframe = 1;
4772  if (stss_index + 1 < sc->keyframe_count)
4773  stss_index++;
4774  } else if (sc->stps_count && current_sample+key_off == sc->stps_data[stps_index]) {
4775  keyframe = 1;
4776  if (stps_index + 1 < sc->stps_count)
4777  stps_index++;
4778  }
4779  if (rap_group_present && rap_group_index < sc->rap_group_count) {
4780  if (sc->rap_group[rap_group_index].index > 0)
4781  keyframe = 1;
4782  if (++rap_group_sample == sc->rap_group[rap_group_index].count) {
4783  rap_group_sample = 0;
4784  rap_group_index++;
4785  }
4786  }
4787  if (sc->keyframe_absent
4788  && !sc->stps_count
4789  && !rap_group_present
4790  && (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO || (i==0 && j==0)))
4791  keyframe = 1;
4792  if (keyframe)
4793  distance = 0;
4794  sample_size = sc->stsz_sample_size > 0 ? sc->stsz_sample_size : sc->sample_sizes[current_sample];
4795  if (current_offset > INT64_MAX - sample_size) {
4796  av_log(mov->fc, AV_LOG_ERROR, "Current offset %"PRId64" or sample size %u is too large\n",
4797  current_offset,
4798  sample_size);
4799  return;
4800  }
4801 
4802  if (sc->pseudo_stream_id == -1 ||
4803  sc->stsc_data[stsc_index].id - 1 == sc->pseudo_stream_id) {
4804  AVIndexEntry *e;
4805  if (sample_size > 0x3FFFFFFF) {
4806  av_log(mov->fc, AV_LOG_ERROR, "Sample size %u is too large\n", sample_size);
4807  return;
4808  }
4809  e = &sti->index_entries[sti->nb_index_entries++];
4810  e->pos = current_offset;
4811  e->timestamp = current_dts;
4812  e->size = sample_size;
4813  e->min_distance = distance;
4814  e->flags = keyframe ? AVINDEX_KEYFRAME : 0;
4815  av_log(mov->fc, AV_LOG_TRACE, "AVIndex stream %d, sample %u, offset %"PRIx64", dts %"PRId64", "
4816  "size %u, distance %u, keyframe %d\n", st->index, current_sample,
4817  current_offset, current_dts, sample_size, distance, keyframe);
4818  if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && sti->nb_index_entries < 100)
4819  ff_rfps_add_frame(mov->fc, st, current_dts);
4820  }
4821 
4822  current_offset += sample_size;
4823  stream_size += sample_size;
4824 
4825  current_dts += sc->tts_data[stts_index].duration;
4826 
4827  distance++;
4828  stts_sample++;
4829  current_sample++;
4830  if (stts_index + 1 < sc->tts_count && stts_sample == sc->tts_data[stts_index].count) {
4831  stts_sample = 0;
4832  stts_index++;
4833  }
4834  }
4835  }
4836  if (st->duration > 0)
4837  st->codecpar->bit_rate = stream_size*8*sc->time_scale/st->duration;
4838  } else {
4839  unsigned chunk_samples, total = 0;
4840 
4841  if (!sc->chunk_count || sc->tts_count)
4842  return;
4843 
4844  // compute total chunk count
4845  for (i = 0; i < sc->stsc_count; i++) {
4846  unsigned count, chunk_count;
4847 
4848  chunk_samples = sc->stsc_data[i].count;
4849  if (i != sc->stsc_count - 1 &&
4850  sc->samples_per_frame && chunk_samples % sc->samples_per_frame) {
4851  av_log(mov->fc, AV_LOG_ERROR, "error unaligned chunk\n");
4852  return;
4853  }
4854 
4855  if (sc->samples_per_frame >= 160) { // gsm
4856  count = chunk_samples / sc->samples_per_frame;
4857  } else if (sc->samples_per_frame > 1) {
4858  unsigned samples = (1024/sc->samples_per_frame)*sc->samples_per_frame;
4859  count = (chunk_samples+samples-1) / samples;
4860  } else {
4861  count = (chunk_samples+1023) / 1024;
4862  }
4863 
4864  if (mov_stsc_index_valid(i, sc->stsc_count))
4865  chunk_count = sc->stsc_data[i+1].first - sc->stsc_data[i].first;
4866  else
4867  chunk_count = sc->chunk_count - (sc->stsc_data[i].first - 1);
4868  total += chunk_count * count;
4869  }
4870 
4871  av_log(mov->fc, AV_LOG_TRACE, "chunk count %u\n", total);
4872  if (total >= UINT_MAX / sizeof(*sti->index_entries) - sti->nb_index_entries)
4873  return;
4874  if (av_reallocp_array(&sti->index_entries,
4875  sti->nb_index_entries + total,
4876  sizeof(*sti->index_entries)) < 0) {
4877  sti->nb_index_entries = 0;
4878  return;
4879  }
4880  sti->index_entries_allocated_size = (sti->nb_index_entries + total) * sizeof(*sti->index_entries);
4881 
4882  // populate index
4883  for (i = 0; i < sc->chunk_count; i++) {
4884  current_offset = sc->chunk_offsets[i];
4885  if (mov_stsc_index_valid(stsc_index, sc->stsc_count) &&
4886  i + 1 == sc->stsc_data[stsc_index + 1].first)
4887  stsc_index++;
4888  chunk_samples = sc->stsc_data[stsc_index].count;
4889 
4890  while (chunk_samples > 0) {
4891  AVIndexEntry *e;
4892  unsigned size, samples;
4893 
4894  if (sc->samples_per_frame > 1 && !sc->bytes_per_frame) {
4896  "Zero bytes per frame, but %d samples per frame",
4897  sc->samples_per_frame);
4898  return;
4899  }
4900 
4901  if (sc->samples_per_frame >= 160) { // gsm
4902  samples = sc->samples_per_frame;
4903  size = sc->bytes_per_frame;
4904  } else {
4905  if (sc->samples_per_frame > 1) {
4906  samples = FFMIN((1024 / sc->samples_per_frame)*
4907  sc->samples_per_frame, chunk_samples);
4909  } else {
4910  samples = FFMIN(1024, chunk_samples);
4911  size = samples * sc->sample_size;
4912  }
4913  }
4914 
4915  if (sti->nb_index_entries >= total) {
4916  av_log(mov->fc, AV_LOG_ERROR, "wrong chunk count %u\n", total);
4917  return;
4918  }
4919  if (size > 0x3FFFFFFF) {
4920  av_log(mov->fc, AV_LOG_ERROR, "Sample size %u is too large\n", size);
4921  return;
4922  }
4923  e = &sti->index_entries[sti->nb_index_entries++];
4924  e->pos = current_offset;
4925  e->timestamp = current_dts;
4926  e->size = size;
4927  e->min_distance = 0;
4928  e->flags = AVINDEX_KEYFRAME;
4929  av_log(mov->fc, AV_LOG_TRACE, "AVIndex stream %d, chunk %u, offset %"PRIx64", dts %"PRId64", "
4930  "size %u, duration %u\n", st->index, i, current_offset, current_dts,
4931  size, samples);
4932 
4933  current_offset += size;
4934  current_dts += samples;
4935  chunk_samples -= samples;
4936  }
4937  }
4938 
4940  if (ret < 0)
4941  return;
4942  }
4943 
4944  if (!mov->ignore_editlist && mov->advanced_editlist) {
4945  // Fix index according to edit lists.
4946  mov_fix_index(mov, st);
4947  }
4948 
4949  // Update start time of the stream.
4951  st->start_time = sti->index_entries[0].timestamp + sc->dts_shift;
4952  if (sc->tts_data) {
4953  st->start_time += sc->tts_data[0].offset;
4954  }
4955  }
4956 
4957  mov_estimate_video_delay(mov, st);
4958 }
4959 
4960 static int test_same_origin(const char *src, const char *ref) {
4961  char src_proto[64];
4962  char ref_proto[64];
4963  char src_auth[256];
4964  char ref_auth[256];
4965  char src_host[256];
4966  char ref_host[256];
4967  int src_port=-1;
4968  int ref_port=-1;
4969 
4970  av_url_split(src_proto, sizeof(src_proto), src_auth, sizeof(src_auth), src_host, sizeof(src_host), &src_port, NULL, 0, src);
4971  av_url_split(ref_proto, sizeof(ref_proto), ref_auth, sizeof(ref_auth), ref_host, sizeof(ref_host), &ref_port, NULL, 0, ref);
4972 
4973  if (strlen(src) == 0) {
4974  return -1;
4975  } else if (strlen(src_auth) + 1 >= sizeof(src_auth) ||
4976  strlen(ref_auth) + 1 >= sizeof(ref_auth) ||
4977  strlen(src_host) + 1 >= sizeof(src_host) ||
4978  strlen(ref_host) + 1 >= sizeof(ref_host)) {
4979  return 0;
4980  } else if (strcmp(src_proto, ref_proto) ||
4981  strcmp(src_auth, ref_auth) ||
4982  strcmp(src_host, ref_host) ||
4983  src_port != ref_port) {
4984  return 0;
4985  } else
4986  return 1;
4987 }
4988 
4989 static int mov_open_dref(MOVContext *c, AVIOContext **pb, const char *src, MOVDref *ref)
4990 {
4991  /* try relative path, we do not try the absolute because it can leak information about our
4992  system to an attacker */
4993  if (ref->nlvl_to > 0 && ref->nlvl_from > 0) {
4994  char filename[1025];
4995  const char *src_path;
4996  int i, l;
4997 
4998  /* find a source dir */
4999  src_path = strrchr(src, '/');
5000  if (src_path)
5001  src_path++;
5002  else
5003  src_path = src;
5004 
5005  /* find a next level down to target */
5006  for (i = 0, l = strlen(ref->path) - 1; l >= 0; l--)
5007  if (ref->path[l] == '/') {
5008  if (i == ref->nlvl_to - 1)
5009  break;
5010  else
5011  i++;
5012  }
5013 
5014  /* compose filename if next level down to target was found */
5015  if (i == ref->nlvl_to - 1 && src_path - src < sizeof(filename)) {
5016  memcpy(filename, src, src_path - src);
5017  filename[src_path - src] = 0;
5018 
5019  for (i = 1; i < ref->nlvl_from; i++)
5020  av_strlcat(filename, "../", sizeof(filename));
5021 
5022  av_strlcat(filename, ref->path + l + 1, sizeof(filename));
5023  if (!c->use_absolute_path) {
5024  int same_origin = test_same_origin(src, filename);
5025 
5026  if (!same_origin) {
5027  av_log(c->fc, AV_LOG_ERROR,
5028  "Reference with mismatching origin, %s not tried for security reasons, "
5029  "set demuxer option use_absolute_path to allow it anyway\n",
5030  ref->path);
5031  return AVERROR(ENOENT);
5032  }
5033 
5034  if (strstr(ref->path + l + 1, "..") ||
5035  strstr(ref->path + l + 1, ":") ||
5036  (ref->nlvl_from > 1 && same_origin < 0) ||
5037  (filename[0] == '/' && src_path == src))
5038  return AVERROR(ENOENT);
5039  }
5040 
5041  if (strlen(filename) + 1 == sizeof(filename))
5042  return AVERROR(ENOENT);
5043  if (!c->fc->io_open(c->fc, pb, filename, AVIO_FLAG_READ, NULL))
5044  return 0;
5045  }
5046  } else if (c->use_absolute_path) {
5047  av_log(c->fc, AV_LOG_WARNING, "Using absolute path on user request, "
5048  "this is a possible security issue\n");
5049  if (!c->fc->io_open(c->fc, pb, ref->path, AVIO_FLAG_READ, NULL))
5050  return 0;
5051  } else {
5052  av_log(c->fc, AV_LOG_ERROR,
5053  "Absolute path %s not tried for security reasons, "
5054  "set demuxer option use_absolute_path to allow absolute paths\n",
5055  ref->path);
5056  }
5057 
5058  return AVERROR(ENOENT);
5059 }
5060 
5062 {
5063  if (sc->time_scale <= 0) {
5064  av_log(c->fc, AV_LOG_WARNING, "stream %d, timescale not set\n", sc->ffindex);
5065  sc->time_scale = c->time_scale;
5066  if (sc->time_scale <= 0)
5067  sc->time_scale = 1;
5068  }
5069 }
5070 
5071 #if CONFIG_IAMFDEC
5072 static int mov_update_iamf_streams(MOVContext *c, const AVStream *st)
5073 {
5074  const MOVStreamContext *sc = st->priv_data;
5075  const IAMFContext *iamf = &sc->iamf->iamf;
5076 
5077  for (int i = 0; i < iamf->nb_audio_elements; i++) {
5078  const AVStreamGroup *stg = NULL;
5079 
5080  for (int j = 0; j < c->fc->nb_stream_groups; j++)
5081  if (c->fc->stream_groups[j]->id == iamf->audio_elements[i]->audio_element_id)
5082  stg = c->fc->stream_groups[j];
5083  av_assert0(stg);
5084 
5085  for (int j = 0; j < stg->nb_streams; j++) {
5086  const FFStream *sti = cffstream(st);
5087  AVStream *out = stg->streams[j];
5088  FFStream *out_sti = ffstream(stg->streams[j]);
5089 
5090  out->codecpar->bit_rate = 0;
5091 
5092  if (out == st)
5093  continue;
5094 
5095  out->time_base = st->time_base;
5096  out->start_time = st->start_time;
5097  out->duration = st->duration;
5098  out->nb_frames = st->nb_frames;
5099  out->discard = st->discard;
5100 
5101  av_assert0(!out_sti->index_entries);
5103  if (!out_sti->index_entries)
5104  return AVERROR(ENOMEM);
5105 
5107  out_sti->nb_index_entries = sti->nb_index_entries;
5108  out_sti->skip_samples = sti->skip_samples;
5109  memcpy(out_sti->index_entries, sti->index_entries, sti->index_entries_allocated_size);
5110  }
5111  }
5112 
5113  return 0;
5114 }
5115 #endif
5116 
5117 static int sanity_checks(void *log_obj, MOVStreamContext *sc, int index)
5118 {
5119  if ((sc->chunk_count && (!sc->stts_count || !sc->stsc_count ||
5120  (!sc->sample_size && !sc->sample_count))) ||
5121  (!sc->chunk_count && sc->sample_count)) {
5122  av_log(log_obj, AV_LOG_ERROR, "stream %d, missing mandatory atoms, broken header\n",
5123  index);
5124  return 1;
5125  }
5126 
5127  if (sc->stsc_count && sc->stsc_data[ sc->stsc_count - 1 ].first > sc->chunk_count) {
5128  av_log(log_obj, AV_LOG_ERROR, "stream %d, contradictionary STSC and STCO\n",
5129  index);
5130  return 2;
5131  }
5132  return 0;
5133 }
5134 
5136 {
5137  AVStream *st;
5138  MOVStreamContext *sc;
5139  int ret;
5140 
5141  st = avformat_new_stream(c->fc, NULL);
5142  if (!st) return AVERROR(ENOMEM);
5143  st->id = -1;
5144  sc = av_mallocz(sizeof(MOVStreamContext));
5145  if (!sc) return AVERROR(ENOMEM);
5146 
5147  st->priv_data = sc;
5149  sc->ffindex = st->index;
5150  c->trak_index = st->index;
5151  sc->tref_flags = 0;
5152  sc->tref_id = -1;
5153  sc->refcount = 1;
5154 
5155  if ((ret = mov_read_default(c, pb, atom)) < 0)
5156  return ret;
5157 
5158  c->trak_index = -1;
5159 
5160  // Here stsc refers to a chunk not described in stco. This is technically invalid,
5161  // but we can overlook it (clearing stsc) whenever stts_count == 0 (indicating no samples).
5162  if (!sc->chunk_count && !sc->stts_count && sc->stsc_count) {
5163  sc->stsc_count = 0;
5164  av_freep(&sc->stsc_data);
5165  }
5166 
5167  ret = sanity_checks(c->fc, sc, st->index);
5168  if (ret)
5169  return ret > 1 ? AVERROR_INVALIDDATA : 0;
5170 
5171  fix_timescale(c, sc);
5172 
5173  avpriv_set_pts_info(st, 64, 1, sc->time_scale);
5174 
5175  /*
5176  * Advanced edit list support does not work with fragemented MP4s, which
5177  * have stsc, stsz, stco, and stts with zero entries in the moov atom.
5178  * In these files, trun atoms may be streamed in.
5179  */
5180  if (!sc->stts_count && c->advanced_editlist) {
5181 
5182  av_log(c->fc, AV_LOG_VERBOSE, "advanced_editlist does not work with fragmented "
5183  "MP4. disabling.\n");
5184  c->advanced_editlist = 0;
5185  c->advanced_editlist_autodisabled = 1;
5186  }
5187 
5188  mov_build_index(c, st);
5189 
5190 #if CONFIG_IAMFDEC
5191  if (sc->iamf) {
5192  ret = mov_update_iamf_streams(c, st);
5193  if (ret < 0)
5194  return ret;
5195  }
5196 #endif
5197 
5198  if (sc->dref_id-1 < sc->drefs_count && sc->drefs[sc->dref_id-1].path) {
5199  MOVDref *dref = &sc->drefs[sc->dref_id - 1];
5200  if (c->enable_drefs) {
5201  if (mov_open_dref(c, &sc->pb, c->fc->url, dref) < 0)
5202  av_log(c->fc, AV_LOG_ERROR,
5203  "stream %d, error opening alias: path='%s', dir='%s', "
5204  "filename='%s', volume='%s', nlvl_from=%d, nlvl_to=%d\n",
5205  st->index, dref->path, dref->dir, dref->filename,
5206  dref->volume, dref->nlvl_from, dref->nlvl_to);
5207  } else {
5208  av_log(c->fc, AV_LOG_WARNING,
5209  "Skipped opening external track: "
5210  "stream %d, alias: path='%s', dir='%s', "
5211  "filename='%s', volume='%s', nlvl_from=%d, nlvl_to=%d."
5212  "Set enable_drefs to allow this.\n",
5213  st->index, dref->path, dref->dir, dref->filename,
5214  dref->volume, dref->nlvl_from, dref->nlvl_to);
5215  }
5216  } else {
5217  sc->pb = c->fc->pb;
5218  sc->pb_is_copied = 1;
5219  }
5220 
5221  if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
5222  int stts_constant = sc->stts_count && sc->tts_count;
5223  if (sc->h_spacing && sc->v_spacing)
5225  sc->h_spacing, sc->v_spacing, INT_MAX);
5226  if (!st->sample_aspect_ratio.num && st->codecpar->width && st->codecpar->height &&
5227  sc->height && sc->width &&
5228  (st->codecpar->width != sc->width || st->codecpar->height != sc->height)) {
5230  (int64_t)st->codecpar->height * sc->width,
5231  (int64_t)st->codecpar->width * sc->height, INT_MAX);
5232  }
5233 
5234 #if FF_API_R_FRAME_RATE
5235  for (unsigned int i = 1; sc->stts_count && i + 1 < sc->tts_count; i++) {
5236  if (sc->tts_data[i].duration == sc->tts_data[0].duration)
5237  continue;
5238  stts_constant = 0;
5239  }
5240  if (stts_constant)
5242  sc->time_scale, sc->tts_data[0].duration, INT_MAX);
5243 #endif
5244  }
5245 
5246 #if CONFIG_H261_DECODER || CONFIG_H263_DECODER || CONFIG_MPEG4_DECODER
5247  switch (st->codecpar->codec_id) {
5248 #if CONFIG_H261_DECODER
5249  case AV_CODEC_ID_H261:
5250 #endif
5251 #if CONFIG_H263_DECODER
5252  case AV_CODEC_ID_H263:
5253 #endif
5254 #if CONFIG_MPEG4_DECODER
5255  case AV_CODEC_ID_MPEG4:
5256 #endif
5257  st->codecpar->width = 0; /* let decoder init width/height */
5258  st->codecpar->height= 0;
5259  break;
5260  }
5261 #endif
5262 
5263  // If the duration of the mp3 packets is not constant, then they could need a parser
5264  if (st->codecpar->codec_id == AV_CODEC_ID_MP3
5265  && sc->time_scale == st->codecpar->sample_rate) {
5266  int stts_constant = 1;
5267  for (int i = 1; sc->stts_count && i < sc->tts_count; i++) {
5268  if (sc->tts_data[i].duration == sc->tts_data[0].duration)
5269  continue;
5270  stts_constant = 0;
5271  }
5272  if (!stts_constant)
5274  }
5275  /* Do not need those anymore. */
5276  av_freep(&sc->chunk_offsets);
5277  av_freep(&sc->sample_sizes);
5278  av_freep(&sc->keyframes);
5279  av_freep(&sc->stps_data);
5280  av_freep(&sc->elst_data);
5281  av_freep(&sc->rap_group);
5282  av_freep(&sc->sync_group);
5283  av_freep(&sc->sgpd_sync);
5284 
5285  return 0;
5286 }
5287 
5289 {
5290  int ret;
5291  c->itunes_metadata = 1;
5292  ret = mov_read_default(c, pb, atom);
5293  c->itunes_metadata = 0;
5294  return ret;
5295 }
5296 
5298 {
5299  uint32_t count;
5300  uint32_t i;
5301 
5302  if (atom.size < 8)
5303  return 0;
5304 
5305  avio_skip(pb, 4);
5306  count = avio_rb32(pb);
5307  atom.size -= 8;
5308  if (count >= UINT_MAX / sizeof(*c->meta_keys)) {
5309  av_log(c->fc, AV_LOG_ERROR,
5310  "The 'keys' atom with the invalid key count: %"PRIu32"\n", count);
5311  return AVERROR_INVALIDDATA;
5312  }
5313 
5314  c->meta_keys_count = count + 1;
5315  c->meta_keys = av_mallocz(c->meta_keys_count * sizeof(*c->meta_keys));
5316  if (!c->meta_keys)
5317  return AVERROR(ENOMEM);
5318 
5319  for (i = 1; i <= count; ++i) {
5320  uint32_t key_size = avio_rb32(pb);
5321  uint32_t type = avio_rl32(pb);
5322  if (key_size < 8 || key_size > atom.size) {
5323  av_log(c->fc, AV_LOG_ERROR,
5324  "The key# %"PRIu32" in meta has invalid size:"
5325  "%"PRIu32"\n", i, key_size);
5326  return AVERROR_INVALIDDATA;
5327  }
5328  atom.size -= key_size;
5329  key_size -= 8;
5330  if (type != MKTAG('m','d','t','a')) {
5331  avio_skip(pb, key_size);
5332  continue;
5333  }
5334  c->meta_keys[i] = av_mallocz(key_size + 1);
5335  if (!c->meta_keys[i])
5336  return AVERROR(ENOMEM);
5337  avio_read(pb, c->meta_keys[i], key_size);
5338  }
5339 
5340  return 0;
5341 }
5342 
5344 {
5345  int64_t end = av_sat_add64(avio_tell(pb), atom.size);
5346  uint8_t *key = NULL, *val = NULL, *mean = NULL;
5347  int i;
5348  int ret = 0;
5349  AVStream *st;
5350  MOVStreamContext *sc;
5351 
5352  if (c->fc->nb_streams < 1)
5353  return 0;
5354  st = c->fc->streams[c->fc->nb_streams-1];
5355  sc = st->priv_data;
5356 
5357  for (i = 0; i < 3; i++) {
5358  uint8_t **p;
5359  uint32_t len, tag;
5360 
5361  if (end - avio_tell(pb) <= 12)
5362  break;
5363 
5364  len = avio_rb32(pb);
5365  tag = avio_rl32(pb);
5366  avio_skip(pb, 4); // flags
5367 
5368  if (len < 12 || len - 12 > end - avio_tell(pb))
5369  break;
5370  len -= 12;
5371 
5372  if (tag == MKTAG('m', 'e', 'a', 'n'))
5373  p = &mean;
5374  else if (tag == MKTAG('n', 'a', 'm', 'e'))
5375  p = &key;
5376  else if (tag == MKTAG('d', 'a', 't', 'a') && len > 4) {
5377  avio_skip(pb, 4);
5378  len -= 4;
5379  p = &val;
5380  } else
5381  break;
5382 
5383  if (*p)
5384  break;
5385 
5386  *p = av_malloc(len + 1);
5387  if (!*p) {
5388  ret = AVERROR(ENOMEM);
5389  break;
5390  }
5391  ret = ffio_read_size(pb, *p, len);
5392  if (ret < 0) {
5393  av_freep(p);
5394  break;
5395  }
5396  (*p)[len] = 0;
5397  }
5398 
5399  if (mean && key && val) {
5400  if (strcmp(key, "iTunSMPB") == 0) {
5401  int priming, remainder, samples;
5402  if(sscanf(val, "%*X %X %X %X", &priming, &remainder, &samples) == 3){
5403  if(priming>0 && priming<16384)
5404  sc->start_pad = priming;
5405  }
5406  }
5407  if (strcmp(key, "cdec") != 0) {
5408  av_dict_set(&c->fc->metadata, key, val,
5410  key = val = NULL;
5411  }
5412  } else {
5413  av_log(c->fc, AV_LOG_VERBOSE,
5414  "Unhandled or malformed custom metadata of size %"PRId64"\n", atom.size);
5415  }
5416 
5417  avio_seek(pb, end, SEEK_SET);
5418  av_freep(&key);
5419  av_freep(&val);
5420  av_freep(&mean);
5421  return ret;
5422 }
5423 
5425 {
5426  MOVStreamContext *sc;
5427  AVStream *st;
5428 
5429  st = avformat_new_stream(c->fc, NULL);
5430  if (!st)
5431  return AVERROR(ENOMEM);
5432  sc = av_mallocz(sizeof(MOVStreamContext));
5433  if (!sc)
5434  goto fail;
5435 
5436  item->st = st;
5437  st->id = item->item_id;
5438  st->priv_data = sc;
5440  st->codecpar->codec_id = mov_codec_id(st, item->type);
5441  sc->id = st->id;
5442  sc->ffindex = st->index;
5443  st->avg_frame_rate.num = st->avg_frame_rate.den = 1;
5444  st->time_base.num = st->time_base.den = 1;
5445  st->nb_frames = 1;
5446  sc->time_scale = 1;
5447  sc->pb = c->fc->pb;
5448  sc->pb_is_copied = 1;
5449  sc->refcount = 1;
5450 
5451  if (item->name)
5452  av_dict_set(&st->metadata, "title", item->name, 0);
5453 
5454  // Populate the necessary fields used by mov_build_index.
5455  sc->stsc_data = av_malloc_array(1, sizeof(*sc->stsc_data));
5456  if (!sc->stsc_data)
5457  goto fail;
5458  sc->stsc_count = 1;
5459  sc->stsc_data[0].first = 1;
5460  sc->stsc_data[0].count = 1;
5461  sc->stsc_data[0].id = 1;
5462  sc->chunk_offsets = av_malloc_array(1, sizeof(*sc->chunk_offsets));
5463  if (!sc->chunk_offsets)
5464  goto fail;
5465  sc->chunk_count = 1;
5466  sc->stts_data = av_malloc_array(1, sizeof(*sc->stts_data));
5467  if (!sc->stts_data)
5468  goto fail;
5469  sc->stts_count = 1;
5470  sc->stts_data[0].count = 1;
5471  // Not used for still images. But needed by mov_build_index.
5472  sc->stts_data[0].duration = 0;
5473 
5474  return 0;
5475 fail:
5476  mov_free_stream_context(c->fc, st);
5477  ff_remove_stream(c->fc, st);
5478  item->st = NULL;
5479 
5480  return AVERROR(ENOMEM);
5481 }
5482 
5484 {
5485  while (atom.size > 8) {
5486  uint32_t tag;
5487  if (avio_feof(pb))
5488  return AVERROR_EOF;
5489  tag = avio_rl32(pb);
5490  atom.size -= 4;
5491  if (tag == MKTAG('h','d','l','r')) {
5492  avio_seek(pb, -8, SEEK_CUR);
5493  atom.size += 8;
5494  return mov_read_default(c, pb, atom);
5495  }
5496  }
5497  return 0;
5498 }
5499 
5500 // return 1 when matrix is identity, 0 otherwise
5501 #define IS_MATRIX_IDENT(matrix) \
5502  ( (matrix)[0][0] == (1 << 16) && \
5503  (matrix)[1][1] == (1 << 16) && \
5504  (matrix)[2][2] == (1 << 30) && \
5505  !(matrix)[0][1] && !(matrix)[0][2] && \
5506  !(matrix)[1][0] && !(matrix)[1][2] && \
5507  !(matrix)[2][0] && !(matrix)[2][1])
5508 
5510 {
5511  int i, j, e;
5512  int width;
5513  int height;
5514  int display_matrix[3][3];
5515  int res_display_matrix[3][3] = { { 0 } };
5516  AVStream *st;
5517  MOVStreamContext *sc;
5518  int version;
5519  int flags;
5520 
5521  if (c->fc->nb_streams < 1)
5522  return 0;
5523  st = c->fc->streams[c->fc->nb_streams-1];
5524  sc = st->priv_data;
5525 
5526  // Each stream (trak) should have exactly 1 tkhd. This catches bad files and
5527  // avoids corrupting AVStreams mapped to an earlier tkhd.
5528  if (st->id != -1)
5529  return AVERROR_INVALIDDATA;
5530 
5531  version = avio_r8(pb);
5532  flags = avio_rb24(pb);
5534 
5535  if (version == 1) {
5536  avio_rb64(pb);
5537  avio_rb64(pb);
5538  } else {
5539  avio_rb32(pb); /* creation time */
5540  avio_rb32(pb); /* modification time */
5541  }
5542  st->id = (int)avio_rb32(pb); /* track id (NOT 0 !)*/
5543  sc->id = st->id;
5544  avio_rb32(pb); /* reserved */
5545 
5546  /* highlevel (considering edits) duration in movie timebase */
5547  (version == 1) ? avio_rb64(pb) : avio_rb32(pb);
5548  avio_rb32(pb); /* reserved */
5549  avio_rb32(pb); /* reserved */
5550 
5551  avio_rb16(pb); /* layer */
5552  avio_rb16(pb); /* alternate group */
5553  avio_rb16(pb); /* volume */
5554  avio_rb16(pb); /* reserved */
5555 
5556  //read in the display matrix (outlined in ISO 14496-12, Section 6.2.2)
5557  // they're kept in fixed point format through all calculations
5558  // save u,v,z to store the whole matrix in the AV_PKT_DATA_DISPLAYMATRIX
5559  // side data, but the scale factor is not needed to calculate aspect ratio
5560  for (i = 0; i < 3; i++) {
5561  display_matrix[i][0] = avio_rb32(pb); // 16.16 fixed point
5562  display_matrix[i][1] = avio_rb32(pb); // 16.16 fixed point
5563  display_matrix[i][2] = avio_rb32(pb); // 2.30 fixed point
5564  }
5565 
5566  width = avio_rb32(pb); // 16.16 fixed point track width
5567  height = avio_rb32(pb); // 16.16 fixed point track height
5568  sc->width = width >> 16;
5569  sc->height = height >> 16;
5570 
5571  // apply the moov display matrix (after the tkhd one)
5572  for (i = 0; i < 3; i++) {
5573  const int sh[3] = { 16, 16, 30 };
5574  for (j = 0; j < 3; j++) {
5575  for (e = 0; e < 3; e++) {
5576  res_display_matrix[i][j] +=
5577  ((int64_t) display_matrix[i][e] *
5578  c->movie_display_matrix[e][j]) >> sh[e];
5579  }
5580  }
5581  }
5582 
5583  // save the matrix when it is not the default identity
5584  if (!IS_MATRIX_IDENT(res_display_matrix)) {
5585  av_freep(&sc->display_matrix);
5586  sc->display_matrix = av_malloc(sizeof(int32_t) * 9);
5587  if (!sc->display_matrix)
5588  return AVERROR(ENOMEM);
5589 
5590  for (i = 0; i < 3; i++)
5591  for (j = 0; j < 3; j++)
5592  sc->display_matrix[i * 3 + j] = res_display_matrix[i][j];
5593  }
5594 
5595  // transform the display width/height according to the matrix
5596  // to keep the same scale, use [width height 1<<16]
5597  if (width && height && sc->display_matrix) {
5598  double disp_transform[2];
5599 
5600  for (i = 0; i < 2; i++)
5601  disp_transform[i] = hypot(sc->display_matrix[0 + i],
5602  sc->display_matrix[3 + i]);
5603 
5604  if (disp_transform[0] > 1 && disp_transform[1] > 1 &&
5605  disp_transform[0] < (1<<24) && disp_transform[1] < (1<<24) &&
5606  fabs((disp_transform[0] / disp_transform[1]) - 1.0) > 0.01)
5608  disp_transform[0] / disp_transform[1],
5609  INT_MAX);
5610  }
5611  return 0;
5612 }
5613 
5615 {
5616  MOVFragment *frag = &c->fragment;
5617  MOVTrackExt *trex = NULL;
5618  int flags, track_id, i;
5619  MOVFragmentStreamInfo * frag_stream_info;
5620 
5621  avio_r8(pb); /* version */
5622  flags = avio_rb24(pb);
5623 
5624  track_id = avio_rb32(pb);
5625  if (!track_id)
5626  return AVERROR_INVALIDDATA;
5627  for (i = 0; i < c->trex_count; i++)
5628  if (c->trex_data[i].track_id == track_id) {
5629  trex = &c->trex_data[i];
5630  break;
5631  }
5632  if (!trex) {
5633  av_log(c->fc, AV_LOG_WARNING, "could not find corresponding trex (id %u)\n", track_id);
5634  return 0;
5635  }
5636  c->fragment.found_tfhd = 1;
5637  frag->track_id = track_id;
5638  set_frag_stream(&c->frag_index, track_id);
5639 
5642  frag->moof_offset : frag->implicit_offset;
5643  frag->stsd_id = flags & MOV_TFHD_STSD_ID ? avio_rb32(pb) : trex->stsd_id;
5644 
5646  avio_rb32(pb) : trex->duration;
5647  frag->size = flags & MOV_TFHD_DEFAULT_SIZE ?
5648  avio_rb32(pb) : trex->size;
5649  frag->flags = flags & MOV_TFHD_DEFAULT_FLAGS ?
5650  avio_rb32(pb) : trex->flags;
5651  av_log(c->fc, AV_LOG_TRACE, "frag flags 0x%x\n", frag->flags);
5652 
5653  frag_stream_info = get_current_frag_stream_info(&c->frag_index);
5654  if (frag_stream_info) {
5655  frag_stream_info->next_trun_dts = AV_NOPTS_VALUE;
5656  frag_stream_info->stsd_id = frag->stsd_id;
5657  }
5658  return 0;
5659 }
5660 
5662 {
5663  unsigned i, num;
5664  void *new_tracks;
5665 
5666  num = atom.size / 4;
5667  if (!(new_tracks = av_malloc_array(num, sizeof(int))))
5668  return AVERROR(ENOMEM);
5669 
5670  av_free(c->chapter_tracks);
5671  c->chapter_tracks = new_tracks;
5672  c->nb_chapter_tracks = num;
5673 
5674  for (i = 0; i < num && !pb->eof_reached; i++)
5675  c->chapter_tracks[i] = avio_rb32(pb);
5676 
5677  c->nb_chapter_tracks = i;
5678 
5679  return 0;
5680 }
5681 
5683 {
5684  MOVTrackExt *trex;
5685  int err;
5686 
5687  if ((uint64_t)c->trex_count+1 >= UINT_MAX / sizeof(*c->trex_data))
5688  return AVERROR_INVALIDDATA;
5689  if ((err = av_reallocp_array(&c->trex_data, c->trex_count + 1,
5690  sizeof(*c->trex_data))) < 0) {
5691  c->trex_count = 0;
5692  return err;
5693  }
5694 
5695  c->fc->duration = AV_NOPTS_VALUE; // the duration from mvhd is not representing the whole file when fragments are used.
5696 
5697  trex = &c->trex_data[c->trex_count++];
5698  avio_r8(pb); /* version */
5699  avio_rb24(pb); /* flags */
5700  trex->track_id = avio_rb32(pb);
5701  trex->stsd_id = avio_rb32(pb);
5702  trex->duration = avio_rb32(pb);
5703  trex->size = avio_rb32(pb);
5704  trex->flags = avio_rb32(pb);
5705  return 0;
5706 }
5707 
5709 {
5710  MOVFragment *frag = &c->fragment;
5711  AVStream *st = NULL;
5712  MOVStreamContext *sc;
5713  int version, i;
5714  MOVFragmentStreamInfo * frag_stream_info;
5715  int64_t base_media_decode_time;
5716 
5717  for (i = 0; i < c->fc->nb_streams; i++) {
5718  sc = c->fc->streams[i]->priv_data;
5719  if (sc->id == frag->track_id) {
5720  st = c->fc->streams[i];
5721  break;
5722  }
5723  }
5724  if (!st) {
5725  av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %u\n", frag->track_id);
5726  return 0;
5727  }
5728  sc = st->priv_data;
5729  if (sc->pseudo_stream_id + 1 != frag->stsd_id && sc->pseudo_stream_id != -1)
5730  return 0;
5731  version = avio_r8(pb);
5732  avio_rb24(pb); /* flags */
5733  if (version) {
5734  base_media_decode_time = avio_rb64(pb);
5735  } else {
5736  base_media_decode_time = avio_rb32(pb);
5737  }
5738 
5739  frag_stream_info = get_current_frag_stream_info(&c->frag_index);
5740  if (frag_stream_info)
5741  frag_stream_info->tfdt_dts = base_media_decode_time;
5742  sc->track_end = base_media_decode_time;
5743 
5744  return 0;
5745 }
5746 
5748 {
5749  MOVFragment *frag = &c->fragment;
5750  AVStream *st = NULL;
5751  FFStream *sti = NULL;
5752  MOVStreamContext *sc;
5753  MOVTimeToSample *tts_data;
5754  uint64_t offset;
5755  int64_t dts, pts = AV_NOPTS_VALUE;
5756  int data_offset = 0;
5757  unsigned entries, first_sample_flags = frag->flags;
5758  int flags, distance, i;
5759  int64_t prev_dts = AV_NOPTS_VALUE;
5760  int next_frag_index = -1, index_entry_pos;
5761  size_t requested_size;
5762  size_t old_allocated_size;
5763  AVIndexEntry *new_entries;
5764  MOVFragmentStreamInfo * frag_stream_info;
5765 
5766  if (!frag->found_tfhd) {
5767  av_log(c->fc, AV_LOG_ERROR, "trun track id unknown, no tfhd was found\n");
5768  return AVERROR_INVALIDDATA;
5769  }
5770 
5771  for (i = 0; i < c->fc->nb_streams; i++) {
5772  sc = c->fc->streams[i]->priv_data;
5773  if (sc->id == frag->track_id) {
5774  st = c->fc->streams[i];
5775  sti = ffstream(st);
5776  break;
5777  }
5778  }
5779  if (!st) {
5780  av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %u\n", frag->track_id);
5781  return 0;
5782  }
5783  sc = st->priv_data;
5784  if (sc->pseudo_stream_id+1 != frag->stsd_id && sc->pseudo_stream_id != -1)
5785  return 0;
5786 
5787  // Find the next frag_index index that has a valid index_entry for
5788  // the current track_id.
5789  //
5790  // A valid index_entry means the trun for the fragment was read
5791  // and it's samples are in index_entries at the given position.
5792  // New index entries will be inserted before the index_entry found.
5793  index_entry_pos = sti->nb_index_entries;
5794  for (i = c->frag_index.current + 1; i < c->frag_index.nb_items; i++) {
5795  frag_stream_info = get_frag_stream_info(&c->frag_index, i, frag->track_id);
5796  if (frag_stream_info && frag_stream_info->index_entry >= 0) {
5797  next_frag_index = i;
5798  index_entry_pos = frag_stream_info->index_entry;
5799  break;
5800  }
5801  }
5802  av_assert0(index_entry_pos <= sti->nb_index_entries);
5803 
5804  avio_r8(pb); /* version */
5805  flags = avio_rb24(pb);
5806  entries = avio_rb32(pb);
5807  av_log(c->fc, AV_LOG_TRACE, "flags 0x%x entries %u\n", flags, entries);
5808 
5809  if ((uint64_t)entries+sc->tts_count >= UINT_MAX/sizeof(*sc->tts_data))
5810  return AVERROR_INVALIDDATA;
5811  if (flags & MOV_TRUN_DATA_OFFSET) data_offset = avio_rb32(pb);
5812  if (flags & MOV_TRUN_FIRST_SAMPLE_FLAGS) first_sample_flags = avio_rb32(pb);
5813 
5814  frag_stream_info = get_current_frag_stream_info(&c->frag_index);
5815  if (frag_stream_info) {
5816  if (frag_stream_info->next_trun_dts != AV_NOPTS_VALUE) {
5817  dts = frag_stream_info->next_trun_dts - sc->time_offset;
5818  } else if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE &&
5819  c->use_mfra_for == FF_MOV_FLAG_MFRA_PTS) {
5820  pts = frag_stream_info->first_tfra_pts;
5821  av_log(c->fc, AV_LOG_DEBUG, "found mfra time %"PRId64
5822  ", using it for pts\n", pts);
5823  } else if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE &&
5824  c->use_mfra_for == FF_MOV_FLAG_MFRA_DTS) {
5825  dts = frag_stream_info->first_tfra_pts;
5826  av_log(c->fc, AV_LOG_DEBUG, "found mfra time %"PRId64
5827  ", using it for dts\n", pts);
5828  } else {
5829  int has_tfdt = frag_stream_info->tfdt_dts != AV_NOPTS_VALUE;
5830  int has_sidx = frag_stream_info->sidx_pts != AV_NOPTS_VALUE;
5831  int fallback_tfdt = !c->use_tfdt && !has_sidx && has_tfdt;
5832  int fallback_sidx = c->use_tfdt && !has_tfdt && has_sidx;
5833 
5834  if (fallback_sidx) {
5835  av_log(c->fc, AV_LOG_DEBUG, "use_tfdt set but no tfdt found, using sidx instead\n");
5836  }
5837  if (fallback_tfdt) {
5838  av_log(c->fc, AV_LOG_DEBUG, "use_tfdt not set but no sidx found, using tfdt instead\n");
5839  }
5840 
5841  if (has_tfdt && c->use_tfdt || fallback_tfdt) {
5842  dts = frag_stream_info->tfdt_dts - sc->time_offset;
5843  av_log(c->fc, AV_LOG_DEBUG, "found tfdt time %"PRId64
5844  ", using it for dts\n", dts);
5845  } else if (has_sidx && !c->use_tfdt || fallback_sidx) {
5846  // FIXME: sidx earliest_presentation_time is *PTS*, s.b.
5847  // pts = frag_stream_info->sidx_pts;
5848  dts = frag_stream_info->sidx_pts - sc->time_offset;
5849  av_log(c->fc, AV_LOG_DEBUG, "found sidx time %"PRId64
5850  ", using it for dts\n", frag_stream_info->sidx_pts);
5851  } else {
5852  dts = sc->track_end - sc->time_offset;
5853  av_log(c->fc, AV_LOG_DEBUG, "found track end time %"PRId64
5854  ", using it for dts\n", dts);
5855  }
5856  }
5857  } else {
5858  dts = sc->track_end - sc->time_offset;
5859  av_log(c->fc, AV_LOG_DEBUG, "found track end time %"PRId64
5860  ", using it for dts\n", dts);
5861  }
5862  offset = frag->base_data_offset + data_offset;
5863  distance = 0;
5864  av_log(c->fc, AV_LOG_TRACE, "first sample flags 0x%x\n", first_sample_flags);
5865 
5866  // realloc space for new index entries
5867  if ((uint64_t)sti->nb_index_entries + entries >= UINT_MAX / sizeof(AVIndexEntry)) {
5868  entries = UINT_MAX / sizeof(AVIndexEntry) - sti->nb_index_entries;
5869  av_log(c->fc, AV_LOG_ERROR, "Failed to add index entry\n");
5870  }
5871  if (entries == 0)
5872  return 0;
5873 
5874  requested_size = (sti->nb_index_entries + entries) * sizeof(AVIndexEntry);
5875  new_entries = av_fast_realloc(sti->index_entries,
5877  requested_size);
5878  if (!new_entries)
5879  return AVERROR(ENOMEM);
5880  sti->index_entries= new_entries;
5881 
5882  requested_size = (sti->nb_index_entries + entries) * sizeof(*sc->tts_data);
5883  old_allocated_size = sc->tts_allocated_size;
5884  tts_data = av_fast_realloc(sc->tts_data, &sc->tts_allocated_size,
5885  requested_size);
5886  if (!tts_data)
5887  return AVERROR(ENOMEM);
5888  sc->tts_data = tts_data;
5889 
5890  // In case there were samples without time to sample entries, ensure they get
5891  // zero valued entries. This ensures clips which mix boxes with and
5892  // without time to sample entries don't pickup uninitialized data.
5893  memset((uint8_t*)(sc->tts_data) + old_allocated_size, 0,
5894  sc->tts_allocated_size - old_allocated_size);
5895 
5896  if (index_entry_pos < sti->nb_index_entries) {
5897  // Make hole in index_entries and tts_data for new samples
5898  memmove(sti->index_entries + index_entry_pos + entries,
5899  sti->index_entries + index_entry_pos,
5900  sizeof(*sti->index_entries) *
5901  (sti->nb_index_entries - index_entry_pos));
5902  memmove(sc->tts_data + index_entry_pos + entries,
5903  sc->tts_data + index_entry_pos,
5904  sizeof(*sc->tts_data) * (sc->tts_count - index_entry_pos));
5905  if (index_entry_pos < sc->current_sample) {
5906  sc->current_sample += entries;
5907  }
5908  }
5909 
5910  sti->nb_index_entries += entries;
5911  sc->tts_count = sti->nb_index_entries;
5912  sc->stts_count = sti->nb_index_entries;
5913  if (flags & MOV_TRUN_SAMPLE_CTS)
5914  sc->ctts_count = sti->nb_index_entries;
5915 
5916  // Record the index_entry position in frag_index of this fragment
5917  if (frag_stream_info) {
5918  frag_stream_info->index_entry = index_entry_pos;
5919  if (frag_stream_info->index_base < 0)
5920  frag_stream_info->index_base = index_entry_pos;
5921  }
5922 
5923  if (index_entry_pos > 0)
5924  prev_dts = sti->index_entries[index_entry_pos-1].timestamp;
5925 
5926  for (i = 0; i < entries && !pb->eof_reached; i++) {
5927  unsigned sample_size = frag->size;
5928  int sample_flags = i ? frag->flags : first_sample_flags;
5929  unsigned sample_duration = frag->duration;
5930  unsigned ctts_duration = 0;
5931  int keyframe = 0;
5932  int index_entry_flags = 0;
5933 
5934  if (flags & MOV_TRUN_SAMPLE_DURATION) sample_duration = avio_rb32(pb);
5935  if (flags & MOV_TRUN_SAMPLE_SIZE) sample_size = avio_rb32(pb);
5936  if (flags & MOV_TRUN_SAMPLE_FLAGS) sample_flags = avio_rb32(pb);
5937  if (flags & MOV_TRUN_SAMPLE_CTS) ctts_duration = avio_rb32(pb);
5938 
5939  mov_update_dts_shift(sc, ctts_duration, c->fc);
5940  if (pts != AV_NOPTS_VALUE) {
5941  dts = pts - sc->dts_shift;
5942  if (flags & MOV_TRUN_SAMPLE_CTS) {
5943  dts -= ctts_duration;
5944  } else {
5945  dts -= sc->time_offset;
5946  }
5947  av_log(c->fc, AV_LOG_DEBUG,
5948  "pts %"PRId64" calculated dts %"PRId64
5949  " sc->dts_shift %d ctts.duration %d"
5950  " sc->time_offset %"PRId64
5951  " flags & MOV_TRUN_SAMPLE_CTS %d\n",
5952  pts, dts,
5953  sc->dts_shift, ctts_duration,
5955  pts = AV_NOPTS_VALUE;
5956  }
5957 
5958  keyframe =
5959  !(sample_flags & (MOV_FRAG_SAMPLE_FLAG_IS_NON_SYNC |
5961  if (keyframe) {
5962  distance = 0;
5963  index_entry_flags |= AVINDEX_KEYFRAME;
5964  }
5965  // Fragments can overlap in time. Discard overlapping frames after
5966  // decoding.
5967  if (prev_dts >= dts)
5968  index_entry_flags |= AVINDEX_DISCARD_FRAME;
5969 
5970  sti->index_entries[index_entry_pos].pos = offset;
5971  sti->index_entries[index_entry_pos].timestamp = dts;
5972  sti->index_entries[index_entry_pos].size = sample_size;
5973  sti->index_entries[index_entry_pos].min_distance = distance;
5974  sti->index_entries[index_entry_pos].flags = index_entry_flags;
5975 
5976  sc->tts_data[index_entry_pos].count = 1;
5977  sc->tts_data[index_entry_pos].offset = ctts_duration;
5978  sc->tts_data[index_entry_pos].duration = sample_duration;
5979  index_entry_pos++;
5980 
5981  av_log(c->fc, AV_LOG_TRACE, "AVIndex stream %d, sample %d, offset %"PRIx64", dts %"PRId64", "
5982  "size %u, distance %d, keyframe %d\n", st->index,
5983  index_entry_pos, offset, dts, sample_size, distance, keyframe);
5984  distance++;
5985  if (av_sat_add64(dts, sample_duration) != dts + (uint64_t)sample_duration)
5986  return AVERROR_INVALIDDATA;
5987  if (!sample_size)
5988  return AVERROR_INVALIDDATA;
5989  dts += sample_duration;
5990  offset += sample_size;
5991  sc->data_size += sample_size;
5992 
5993  if (sample_duration <= INT64_MAX - sc->duration_for_fps &&
5994  1 <= INT_MAX - sc->nb_frames_for_fps
5995  ) {
5996  sc->duration_for_fps += sample_duration;
5997  sc->nb_frames_for_fps ++;
5998  }
5999  }
6000  if (frag_stream_info)
6001  frag_stream_info->next_trun_dts = dts + sc->time_offset;
6002  if (i < entries) {
6003  // EOF found before reading all entries. Fix the hole this would
6004  // leave in index_entries and tts_data
6005  int gap = entries - i;
6006  memmove(sti->index_entries + index_entry_pos,
6007  sti->index_entries + index_entry_pos + gap,
6008  sizeof(*sti->index_entries) *
6009  (sti->nb_index_entries - (index_entry_pos + gap)));
6010  memmove(sc->tts_data + index_entry_pos,
6011  sc->tts_data + index_entry_pos + gap,
6012  sizeof(*sc->tts_data) *
6013  (sc->tts_count - (index_entry_pos + gap)));
6014 
6015  sti->nb_index_entries -= gap;
6016  sc->tts_count -= gap;
6017  if (index_entry_pos < sc->current_sample) {
6018  sc->current_sample -= gap;
6019  }
6020  entries = i;
6021  }
6022 
6023  // The end of this new fragment may overlap in time with the start
6024  // of the next fragment in index_entries. Mark the samples in the next
6025  // fragment that overlap with AVINDEX_DISCARD_FRAME
6026  prev_dts = AV_NOPTS_VALUE;
6027  if (index_entry_pos > 0)
6028  prev_dts = sti->index_entries[index_entry_pos-1].timestamp;
6029  for (int i = index_entry_pos; i < sti->nb_index_entries; i++) {
6030  if (prev_dts < sti->index_entries[i].timestamp)
6031  break;
6033  }
6034 
6035  // If a hole was created to insert the new index_entries into,
6036  // the index_entry recorded for all subsequent moof must
6037  // be incremented by the number of entries inserted.
6038  fix_frag_index_entries(&c->frag_index, next_frag_index,
6039  frag->track_id, entries);
6040 
6041  if (pb->eof_reached) {
6042  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted TRUN atom\n");
6043  return AVERROR_EOF;
6044  }
6045 
6046  frag->implicit_offset = offset;
6047 
6048  sc->track_end = dts + sc->time_offset;
6049  if (st->duration < sc->track_end)
6050  st->duration = sc->track_end;
6051 
6052  return 0;
6053 }
6054 
6056 {
6057  int64_t stream_size = avio_size(pb);
6058  int64_t offset = av_sat_add64(avio_tell(pb), atom.size), pts, timestamp;
6059  uint8_t version, is_complete;
6060  int64_t offadd;
6061  unsigned i, j, track_id, item_count;
6062  AVStream *st = NULL;
6063  AVStream *ref_st = NULL;
6064  MOVStreamContext *sc, *ref_sc = NULL;
6065  AVRational timescale;
6066 
6067  version = avio_r8(pb);
6068  if (version > 1) {
6069  avpriv_request_sample(c->fc, "sidx version %u", version);
6070  return 0;
6071  }
6072 
6073  avio_rb24(pb); // flags
6074 
6075  track_id = avio_rb32(pb); // Reference ID
6076  for (i = 0; i < c->fc->nb_streams; i++) {
6077  sc = c->fc->streams[i]->priv_data;
6078  if (sc->id == track_id) {
6079  st = c->fc->streams[i];
6080  break;
6081  }
6082  }
6083  if (!st) {
6084  av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %d\n", track_id);
6085  return 0;
6086  }
6087 
6088  sc = st->priv_data;
6089 
6090  timescale = av_make_q(1, avio_rb32(pb));
6091 
6092  if (timescale.den <= 0) {
6093  av_log(c->fc, AV_LOG_ERROR, "Invalid sidx timescale 1/%d\n", timescale.den);
6094  return AVERROR_INVALIDDATA;
6095  }
6096 
6097  if (version == 0) {
6098  pts = avio_rb32(pb);
6099  offadd= avio_rb32(pb);
6100  } else {
6101  pts = avio_rb64(pb);
6102  offadd= avio_rb64(pb);
6103  }
6104  if (av_sat_add64(offset, offadd) != offset + (uint64_t)offadd)
6105  return AVERROR_INVALIDDATA;
6106 
6107  offset += (uint64_t)offadd;
6108 
6109  avio_rb16(pb); // reserved
6110 
6111  item_count = avio_rb16(pb);
6112  if (item_count == 0)
6113  return AVERROR_INVALIDDATA;
6114 
6115  for (i = 0; i < item_count; i++) {
6116  int index;
6117  MOVFragmentStreamInfo * frag_stream_info;
6118  uint32_t size = avio_rb32(pb);
6119  uint32_t duration = avio_rb32(pb);
6120  if (size & 0x80000000) {
6121  avpriv_request_sample(c->fc, "sidx reference_type 1");
6122  return AVERROR_PATCHWELCOME;
6123  }
6124  avio_rb32(pb); // sap_flags
6125  timestamp = av_rescale_q(pts, timescale, st->time_base);
6126 
6128  frag_stream_info = get_frag_stream_info(&c->frag_index, index, track_id);
6129  if (frag_stream_info)
6130  frag_stream_info->sidx_pts = timestamp;
6131 
6132  if (av_sat_add64(offset, size) != offset + (uint64_t)size ||
6133  av_sat_add64(pts, duration) != pts + (uint64_t)duration
6134  )
6135  return AVERROR_INVALIDDATA;
6136  offset += size;
6137  pts += duration;
6138  }
6139 
6140  st->duration = sc->track_end = pts;
6141 
6142  sc->has_sidx = 1;
6143 
6144  // See if the remaining bytes are just an mfra which we can ignore.
6145  is_complete = offset == stream_size;
6146  if (!is_complete && (pb->seekable & AVIO_SEEKABLE_NORMAL) && stream_size > 0 ) {
6147  int64_t ret;
6148  int64_t original_pos = avio_tell(pb);
6149  if (!c->have_read_mfra_size) {
6150  if ((ret = avio_seek(pb, stream_size - 4, SEEK_SET)) < 0)
6151  return ret;
6152  c->mfra_size = avio_rb32(pb);
6153  c->have_read_mfra_size = 1;
6154  if ((ret = avio_seek(pb, original_pos, SEEK_SET)) < 0)
6155  return ret;
6156  }
6157  if (offset == stream_size - c->mfra_size)
6158  is_complete = 1;
6159  }
6160 
6161  if (is_complete) {
6162  // Find first entry in fragment index that came from an sidx.
6163  // This will pretty much always be the first entry.
6164  for (i = 0; i < c->frag_index.nb_items; i++) {
6165  MOVFragmentIndexItem * item = &c->frag_index.item[i];
6166  for (j = 0; ref_st == NULL && j < item->nb_stream_info; j++) {
6167  MOVFragmentStreamInfo * si;
6168  si = &item->stream_info[j];
6169  if (si->sidx_pts != AV_NOPTS_VALUE) {
6170  ref_st = c->fc->streams[j];
6171  ref_sc = ref_st->priv_data;
6172  break;
6173  }
6174  }
6175  }
6176  if (ref_st) for (i = 0; i < c->fc->nb_streams; i++) {
6177  st = c->fc->streams[i];
6178  sc = st->priv_data;
6179  if (!sc->has_sidx) {
6180  st->duration = sc->track_end = av_rescale(ref_st->duration, sc->time_scale, ref_sc->time_scale);
6181  }
6182  }
6183 
6184  c->frag_index.complete = 1;
6185  }
6186 
6187  return 0;
6188 }
6189 
6190 /* this atom should be null (from specs), but some buggy files put the 'moov' atom inside it... */
6191 /* like the files created with Adobe Premiere 5.0, for samples see */
6192 /* http://graphics.tudelft.nl/~wouter/publications/soundtests/ */
6194 {
6195  int err;
6196 
6197  if (atom.size < 8)
6198  return 0; /* continue */
6199  if (avio_rb32(pb) != 0) { /* 0 sized mdat atom... use the 'wide' atom size */
6200  avio_skip(pb, atom.size - 4);
6201  return 0;
6202  }
6203  atom.type = avio_rl32(pb);
6204  atom.size -= 8;
6205  if (atom.type != MKTAG('m','d','a','t')) {
6206  avio_skip(pb, atom.size);
6207  return 0;
6208  }
6209  err = mov_read_mdat(c, pb, atom);
6210  return err;
6211 }
6212 
6214 {
6215 #if CONFIG_ZLIB
6216  FFIOContext ctx;
6217  uint8_t *cmov_data;
6218  uint8_t *moov_data; /* uncompressed data */
6219  long cmov_len, moov_len;
6220  int ret = -1;
6221 
6222  avio_rb32(pb); /* dcom atom */
6223  if (avio_rl32(pb) != MKTAG('d','c','o','m'))
6224  return AVERROR_INVALIDDATA;
6225  if (avio_rl32(pb) != MKTAG('z','l','i','b')) {
6226  av_log(c->fc, AV_LOG_ERROR, "unknown compression for cmov atom !\n");
6227  return AVERROR_INVALIDDATA;
6228  }
6229  avio_rb32(pb); /* cmvd atom */
6230  if (avio_rl32(pb) != MKTAG('c','m','v','d'))
6231  return AVERROR_INVALIDDATA;
6232  moov_len = avio_rb32(pb); /* uncompressed size */
6233  cmov_len = atom.size - 6 * 4;
6234 
6235  cmov_data = av_malloc(cmov_len);
6236  if (!cmov_data)
6237  return AVERROR(ENOMEM);
6238  moov_data = av_malloc(moov_len);
6239  if (!moov_data) {
6240  av_free(cmov_data);
6241  return AVERROR(ENOMEM);
6242  }
6243  ret = ffio_read_size(pb, cmov_data, cmov_len);
6244  if (ret < 0)
6245  goto free_and_return;
6246 
6248  if (uncompress (moov_data, (uLongf *) &moov_len, (const Bytef *)cmov_data, cmov_len) != Z_OK)
6249  goto free_and_return;
6250  ffio_init_read_context(&ctx, moov_data, moov_len);
6251  ctx.pub.seekable = AVIO_SEEKABLE_NORMAL;
6252  atom.type = MKTAG('m','o','o','v');
6253  atom.size = moov_len;
6254  ret = mov_read_default(c, &ctx.pub, atom);
6255 free_and_return:
6256  av_free(moov_data);
6257  av_free(cmov_data);
6258  return ret;
6259 #else
6260  av_log(c->fc, AV_LOG_ERROR, "this file requires zlib support compiled in\n");
6261  return AVERROR(ENOSYS);
6262 #endif
6263 }
6264 
6265 /* edit list atom */
6267 {
6268  MOVStreamContext *sc;
6269  int i, edit_count, version;
6270  int64_t elst_entry_size;
6271 
6272  if (c->fc->nb_streams < 1 || c->ignore_editlist)
6273  return 0;
6274  sc = c->fc->streams[c->fc->nb_streams-1]->priv_data;
6275 
6276  version = avio_r8(pb); /* version */
6277  avio_rb24(pb); /* flags */
6278  edit_count = avio_rb32(pb); /* entries */
6279  atom.size -= 8;
6280 
6281  elst_entry_size = version == 1 ? 20 : 12;
6282  if (atom.size != edit_count * elst_entry_size) {
6283  if (c->fc->strict_std_compliance >= FF_COMPLIANCE_STRICT) {
6284  av_log(c->fc, AV_LOG_ERROR, "Invalid edit list entry_count: %d for elst atom of size: %"PRId64" bytes.\n",
6285  edit_count, atom.size + 8);
6286  return AVERROR_INVALIDDATA;
6287  } else {
6288  edit_count = atom.size / elst_entry_size;
6289  if (edit_count * elst_entry_size != atom.size) {
6290  av_log(c->fc, AV_LOG_WARNING, "ELST atom of %"PRId64" bytes, bigger than %d entries.\n", atom.size, edit_count);
6291  }
6292  }
6293  }
6294 
6295  if (!edit_count)
6296  return 0;
6297  if (sc->elst_data)
6298  av_log(c->fc, AV_LOG_WARNING, "Duplicated ELST atom\n");
6299  av_free(sc->elst_data);
6300  sc->elst_count = 0;
6301  sc->elst_data = av_malloc_array(edit_count, sizeof(*sc->elst_data));
6302  if (!sc->elst_data)
6303  return AVERROR(ENOMEM);
6304 
6305  av_log(c->fc, AV_LOG_TRACE, "track[%u].edit_count = %i\n", c->fc->nb_streams - 1, edit_count);
6306  for (i = 0; i < edit_count && atom.size > 0 && !pb->eof_reached; i++) {
6307  MOVElst *e = &sc->elst_data[i];
6308 
6309  if (version == 1) {
6310  e->duration = avio_rb64(pb);
6311  e->time = avio_rb64(pb);
6312  atom.size -= 16;
6313  } else {
6314  e->duration = avio_rb32(pb); /* segment duration */
6315  e->time = (int32_t)avio_rb32(pb); /* media time */
6316  atom.size -= 8;
6317  }
6318  e->rate = avio_rb32(pb) / 65536.0;
6319  atom.size -= 4;
6320  av_log(c->fc, AV_LOG_TRACE, "duration=%"PRId64" time=%"PRId64" rate=%f\n",
6321  e->duration, e->time, e->rate);
6322 
6323  if (e->time < 0 && e->time != -1 &&
6324  c->fc->strict_std_compliance >= FF_COMPLIANCE_STRICT) {
6325  av_log(c->fc, AV_LOG_ERROR, "Track %d, edit %d: Invalid edit list media time=%"PRId64"\n",
6326  c->fc->nb_streams-1, i, e->time);
6327  return AVERROR_INVALIDDATA;
6328  }
6329  if (e->duration < 0) {
6330  av_log(c->fc, AV_LOG_ERROR, "Track %d, edit %d: Invalid edit list duration=%"PRId64"\n",
6331  c->fc->nb_streams-1, i, e->duration);
6332  return AVERROR_INVALIDDATA;
6333  }
6334  }
6335  sc->elst_count = i;
6336 
6337  return 0;
6338 }
6339 
6341 {
6342  MOVStreamContext *sc;
6343 
6344  if (c->fc->nb_streams < 1)
6345  return AVERROR_INVALIDDATA;
6346  sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
6347  sc->timecode_track = avio_rb32(pb);
6348  return 0;
6349 }
6350 
6352 {
6353  AVStream *st;
6354  int version, color_range, color_primaries, color_trc, color_space;
6355 
6356  if (c->fc->nb_streams < 1)
6357  return 0;
6358  st = c->fc->streams[c->fc->nb_streams - 1];
6359 
6360  if (atom.size < 5) {
6361  av_log(c->fc, AV_LOG_ERROR, "Empty VP Codec Configuration box\n");
6362  return AVERROR_INVALIDDATA;
6363  }
6364 
6365  version = avio_r8(pb);
6366  if (version != 1) {
6367  av_log(c->fc, AV_LOG_WARNING, "Unsupported VP Codec Configuration box version %d\n", version);
6368  return 0;
6369  }
6370  avio_skip(pb, 3); /* flags */
6371 
6372  avio_skip(pb, 2); /* profile + level */
6373  color_range = avio_r8(pb); /* bitDepth, chromaSubsampling, videoFullRangeFlag */
6374  color_primaries = avio_r8(pb);
6375  color_trc = avio_r8(pb);
6376  color_space = avio_r8(pb);
6377  if (avio_rb16(pb)) /* codecIntializationDataSize */
6378  return AVERROR_INVALIDDATA;
6379 
6382  if (!av_color_transfer_name(color_trc))
6383  color_trc = AVCOL_TRC_UNSPECIFIED;
6384  if (!av_color_space_name(color_space))
6385  color_space = AVCOL_SPC_UNSPECIFIED;
6386 
6389  st->codecpar->color_trc = color_trc;
6390  st->codecpar->color_space = color_space;
6391 
6392  return 0;
6393 }
6394 
6396 {
6397  MOVStreamContext *sc;
6398  int i, version;
6399 
6400  if (c->fc->nb_streams < 1)
6401  return AVERROR_INVALIDDATA;
6402 
6403  sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
6404 
6405  if (atom.size < 5) {
6406  av_log(c->fc, AV_LOG_ERROR, "Empty Mastering Display Metadata box\n");
6407  return AVERROR_INVALIDDATA;
6408  }
6409 
6410  version = avio_r8(pb);
6411  if (version) {
6412  av_log(c->fc, AV_LOG_WARNING, "Unsupported Mastering Display Metadata box version %d\n", version);
6413  return 0;
6414  }
6415  if (sc->mastering) {
6416  av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicate Mastering Display Metadata\n");
6417  return 0;
6418  }
6419 
6420  avio_skip(pb, 3); /* flags */
6421 
6423  if (!sc->mastering)
6424  return AVERROR(ENOMEM);
6425 
6426  for (i = 0; i < 3; i++) {
6427  sc->mastering->display_primaries[i][0] = av_make_q(avio_rb16(pb), 1 << 16);
6428  sc->mastering->display_primaries[i][1] = av_make_q(avio_rb16(pb), 1 << 16);
6429  }
6430  sc->mastering->white_point[0] = av_make_q(avio_rb16(pb), 1 << 16);
6431  sc->mastering->white_point[1] = av_make_q(avio_rb16(pb), 1 << 16);
6432 
6433  sc->mastering->max_luminance = av_make_q(avio_rb32(pb), 1 << 8);
6434  sc->mastering->min_luminance = av_make_q(avio_rb32(pb), 1 << 14);
6435 
6436  sc->mastering->has_primaries = 1;
6437  sc->mastering->has_luminance = 1;
6438 
6439  return 0;
6440 }
6441 
6443 {
6444  MOVStreamContext *sc;
6445  const int mapping[3] = {1, 2, 0};
6446  const int chroma_den = 50000;
6447  const int luma_den = 10000;
6448  int i;
6449 
6450  if (c->fc->nb_streams < 1)
6451  return AVERROR_INVALIDDATA;
6452 
6453  sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
6454 
6455  if (atom.size < 24) {
6456  av_log(c->fc, AV_LOG_ERROR, "Invalid Mastering Display Color Volume box\n");
6457  return AVERROR_INVALIDDATA;
6458  }
6459 
6460  if (sc->mastering) {
6461  av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicate Mastering Display Color Volume\n");
6462  return 0;
6463  }
6464 
6466  if (!sc->mastering)
6467  return AVERROR(ENOMEM);
6468 
6469  for (i = 0; i < 3; i++) {
6470  const int j = mapping[i];
6471  sc->mastering->display_primaries[j][0] = av_make_q(avio_rb16(pb), chroma_den);
6472  sc->mastering->display_primaries[j][1] = av_make_q(avio_rb16(pb), chroma_den);
6473  }
6474  sc->mastering->white_point[0] = av_make_q(avio_rb16(pb), chroma_den);
6475  sc->mastering->white_point[1] = av_make_q(avio_rb16(pb), chroma_den);
6476 
6477  sc->mastering->max_luminance = av_make_q(avio_rb32(pb), luma_den);
6478  sc->mastering->min_luminance = av_make_q(avio_rb32(pb), luma_den);
6479 
6480  sc->mastering->has_luminance = 1;
6481  sc->mastering->has_primaries = 1;
6482 
6483  return 0;
6484 }
6485 
6487 {
6488  MOVStreamContext *sc;
6489  int version;
6490 
6491  if (c->fc->nb_streams < 1)
6492  return AVERROR_INVALIDDATA;
6493 
6494  sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
6495 
6496  if (atom.size < 5) {
6497  av_log(c->fc, AV_LOG_ERROR, "Empty Content Light Level box\n");
6498  return AVERROR_INVALIDDATA;
6499  }
6500 
6501  version = avio_r8(pb);
6502  if (version) {
6503  av_log(c->fc, AV_LOG_WARNING, "Unsupported Content Light Level box version %d\n", version);
6504  return 0;
6505  }
6506  avio_skip(pb, 3); /* flags */
6507 
6508  if (sc->coll){
6509  av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicate COLL\n");
6510  return 0;
6511  }
6512 
6514  if (!sc->coll)
6515  return AVERROR(ENOMEM);
6516 
6517  sc->coll->MaxCLL = avio_rb16(pb);
6518  sc->coll->MaxFALL = avio_rb16(pb);
6519 
6520  return 0;
6521 }
6522 
6524 {
6525  MOVStreamContext *sc;
6526 
6527  if (c->fc->nb_streams < 1)
6528  return AVERROR_INVALIDDATA;
6529 
6530  sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
6531 
6532  if (atom.size < 4) {
6533  av_log(c->fc, AV_LOG_ERROR, "Empty Content Light Level Info box\n");
6534  return AVERROR_INVALIDDATA;
6535  }
6536 
6537  if (sc->coll){
6538  av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicate CLLI/COLL\n");
6539  return 0;
6540  }
6541 
6543  if (!sc->coll)
6544  return AVERROR(ENOMEM);
6545 
6546  sc->coll->MaxCLL = avio_rb16(pb);
6547  sc->coll->MaxFALL = avio_rb16(pb);
6548 
6549  return 0;
6550 }
6551 
6553 {
6554  MOVStreamContext *sc;
6555  const int illuminance_den = 10000;
6556  const int ambient_den = 50000;
6557  if (c->fc->nb_streams < 1)
6558  return AVERROR_INVALIDDATA;
6559  sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
6560  if (atom.size < 6) {
6561  av_log(c->fc, AV_LOG_ERROR, "Empty Ambient Viewing Environment Info box\n");
6562  return AVERROR_INVALIDDATA;
6563  }
6564  if (sc->ambient){
6565  av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicate AMVE\n");
6566  return 0;
6567  }
6569  if (!sc->ambient)
6570  return AVERROR(ENOMEM);
6571  sc->ambient->ambient_illuminance = av_make_q(avio_rb32(pb), illuminance_den);
6572  sc->ambient->ambient_light_x = av_make_q(avio_rb16(pb), ambient_den);
6573  sc->ambient->ambient_light_y = av_make_q(avio_rb16(pb), ambient_den);
6574  return 0;
6575 }
6576 
6578 {
6579  AVStream *st;
6580  MOVStreamContext *sc;
6581  enum AVStereo3DType type;
6582  int mode;
6583 
6584  if (c->fc->nb_streams < 1)
6585  return 0;
6586 
6587  st = c->fc->streams[c->fc->nb_streams - 1];
6588  sc = st->priv_data;
6589 
6590  if (atom.size < 5) {
6591  av_log(c->fc, AV_LOG_ERROR, "Empty stereoscopic video box\n");
6592  return AVERROR_INVALIDDATA;
6593  }
6594 
6595  if (sc->stereo3d)
6596  return AVERROR_INVALIDDATA;
6597 
6598  avio_skip(pb, 4); /* version + flags */
6599 
6600  mode = avio_r8(pb);
6601  switch (mode) {
6602  case 0:
6603  type = AV_STEREO3D_2D;
6604  break;
6605  case 1:
6607  break;
6608  case 2:
6610  break;
6611  default:
6612  av_log(c->fc, AV_LOG_WARNING, "Unknown st3d mode value %d\n", mode);
6613  return 0;
6614  }
6615 
6617  if (!sc->stereo3d)
6618  return AVERROR(ENOMEM);
6619 
6620  sc->stereo3d->type = type;
6621  return 0;
6622 }
6623 
6625 {
6626  AVStream *st;
6627  MOVStreamContext *sc;
6628  int size = 0;
6629  int64_t remaining;
6630  uint32_t tag = 0;
6632 
6633  if (c->fc->nb_streams < 1)
6634  return 0;
6635 
6636  st = c->fc->streams[c->fc->nb_streams - 1];
6637  sc = st->priv_data;
6638 
6639  remaining = atom.size;
6640  while (remaining > 0) {
6641  size = avio_rb32(pb);
6642  if (size < 8 || size > remaining ) {
6643  av_log(c->fc, AV_LOG_ERROR, "Invalid child size in pack box\n");
6644  return AVERROR_INVALIDDATA;
6645  }
6646 
6647  tag = avio_rl32(pb);
6648  switch (tag) {
6649  case MKTAG('p','k','i','n'): {
6650  if (size != 16) {
6651  av_log(c->fc, AV_LOG_ERROR, "Invalid size of pkin box: %d\n", size);
6652  return AVERROR_INVALIDDATA;
6653  }
6654  avio_skip(pb, 1); // version
6655  avio_skip(pb, 3); // flags
6656 
6657  tag = avio_rl32(pb);
6658  switch (tag) {
6659  case MKTAG('s','i','d','e'):
6661  break;
6662  case MKTAG('o','v','e','r'):
6664  break;
6665  case 0:
6666  // This means value will be set in another layer
6667  break;
6668  default:
6669  av_log(c->fc, AV_LOG_WARNING, "Unknown tag in pkin: 0x%08X\n", tag);
6670  avio_skip(pb, size - 8);
6671  break;
6672  }
6673 
6674  break;
6675  }
6676  default:
6677  av_log(c->fc, AV_LOG_WARNING, "Unknown tag in pack: 0x%08X\n", tag);
6678  avio_skip(pb, size - 8);
6679  break;
6680  }
6681  remaining -= size;
6682  }
6683 
6684  if (remaining != 0) {
6685  av_log(c->fc, AV_LOG_ERROR, "Broken pack box\n");
6686  return AVERROR_INVALIDDATA;
6687  }
6688 
6689  if (type == AV_STEREO3D_2D)
6690  return 0;
6691 
6692  if (!sc->stereo3d) {
6694  if (!sc->stereo3d)
6695  return AVERROR(ENOMEM);
6696  }
6697 
6698  sc->stereo3d->type = type;
6699 
6700  return 0;
6701 }
6702 
6704 {
6705  AVStream *st;
6706  MOVStreamContext *sc;
6707  int size, version, layout;
6708  int32_t yaw, pitch, roll;
6709  uint32_t l = 0, t = 0, r = 0, b = 0;
6710  uint32_t tag, padding = 0;
6711  enum AVSphericalProjection projection;
6712 
6713  if (c->fc->nb_streams < 1)
6714  return 0;
6715 
6716  st = c->fc->streams[c->fc->nb_streams - 1];
6717  sc = st->priv_data;
6718 
6719  if (atom.size < 8) {
6720  av_log(c->fc, AV_LOG_ERROR, "Empty spherical video box\n");
6721  return AVERROR_INVALIDDATA;
6722  }
6723 
6724  size = avio_rb32(pb);
6725  if (size <= 12 || size > atom.size)
6726  return AVERROR_INVALIDDATA;
6727 
6728  tag = avio_rl32(pb);
6729  if (tag != MKTAG('s','v','h','d')) {
6730  av_log(c->fc, AV_LOG_ERROR, "Missing spherical video header\n");
6731  return 0;
6732  }
6733  version = avio_r8(pb);
6734  if (version != 0) {
6735  av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
6736  version);
6737  return 0;
6738  }
6739  avio_skip(pb, 3); /* flags */
6740  avio_skip(pb, size - 12); /* metadata_source */
6741 
6742  size = avio_rb32(pb);
6743  if (size > atom.size)
6744  return AVERROR_INVALIDDATA;
6745 
6746  tag = avio_rl32(pb);
6747  if (tag != MKTAG('p','r','o','j')) {
6748  av_log(c->fc, AV_LOG_ERROR, "Missing projection box\n");
6749  return 0;
6750  }
6751 
6752  size = avio_rb32(pb);
6753  if (size > atom.size)
6754  return AVERROR_INVALIDDATA;
6755 
6756  tag = avio_rl32(pb);
6757  if (tag != MKTAG('p','r','h','d')) {
6758  av_log(c->fc, AV_LOG_ERROR, "Missing projection header box\n");
6759  return 0;
6760  }
6761  version = avio_r8(pb);
6762  if (version != 0) {
6763  av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
6764  version);
6765  return 0;
6766  }
6767  avio_skip(pb, 3); /* flags */
6768 
6769  /* 16.16 fixed point */
6770  yaw = avio_rb32(pb);
6771  pitch = avio_rb32(pb);
6772  roll = avio_rb32(pb);
6773 
6774  size = avio_rb32(pb);
6775  if (size > atom.size)
6776  return AVERROR_INVALIDDATA;
6777 
6778  tag = avio_rl32(pb);
6779  version = avio_r8(pb);
6780  if (version != 0) {
6781  av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
6782  version);
6783  return 0;
6784  }
6785  avio_skip(pb, 3); /* flags */
6786  switch (tag) {
6787  case MKTAG('c','b','m','p'):
6788  layout = avio_rb32(pb);
6789  if (layout) {
6790  av_log(c->fc, AV_LOG_WARNING,
6791  "Unsupported cubemap layout %d\n", layout);
6792  return 0;
6793  }
6794  projection = AV_SPHERICAL_CUBEMAP;
6795  padding = avio_rb32(pb);
6796  break;
6797  case MKTAG('e','q','u','i'):
6798  t = avio_rb32(pb);
6799  b = avio_rb32(pb);
6800  l = avio_rb32(pb);
6801  r = avio_rb32(pb);
6802 
6803  if (b >= UINT_MAX - t || r >= UINT_MAX - l) {
6804  av_log(c->fc, AV_LOG_ERROR,
6805  "Invalid bounding rectangle coordinates "
6806  "%"PRIu32",%"PRIu32",%"PRIu32",%"PRIu32"\n", l, t, r, b);
6807  return AVERROR_INVALIDDATA;
6808  }
6809 
6810  if (l || t || r || b)
6811  projection = AV_SPHERICAL_EQUIRECTANGULAR_TILE;
6812  else
6813  projection = AV_SPHERICAL_EQUIRECTANGULAR;
6814  break;
6815  default:
6816  av_log(c->fc, AV_LOG_ERROR, "Unknown projection type: %s\n", av_fourcc2str(tag));
6817  return 0;
6818  }
6819 
6821  if (!sc->spherical)
6822  return AVERROR(ENOMEM);
6823 
6824  sc->spherical->projection = projection;
6825 
6826  sc->spherical->yaw = yaw;
6827  sc->spherical->pitch = pitch;
6828  sc->spherical->roll = roll;
6829 
6830  sc->spherical->padding = padding;
6831 
6832  sc->spherical->bound_left = l;
6833  sc->spherical->bound_top = t;
6834  sc->spherical->bound_right = r;
6835  sc->spherical->bound_bottom = b;
6836 
6837  return 0;
6838 }
6839 
6841 {
6842  AVStream *st;
6843  MOVStreamContext *sc;
6844  int size;
6845  uint32_t tag;
6846  enum AVSphericalProjection projection;
6847 
6848  if (c->fc->nb_streams < 1)
6849  return 0;
6850 
6851  st = c->fc->streams[c->fc->nb_streams - 1];
6852  sc = st->priv_data;
6853 
6854  if (atom.size != 16) {
6855  av_log(c->fc, AV_LOG_ERROR, "Invalid size for proj box: %"PRIu64"\n", atom.size);
6856  return AVERROR_INVALIDDATA;
6857  }
6858 
6859  size = avio_rb32(pb);
6860  if (size != 16) {
6861  av_log(c->fc, AV_LOG_ERROR, "Invalid size for prji box: %d\n", size);
6862  return AVERROR_INVALIDDATA;
6863  }
6864 
6865  tag = avio_rl32(pb);
6866  if (tag != MKTAG('p','r','j','i')) {
6867  av_log(c->fc, AV_LOG_ERROR, "Invalid child box of proj box: 0x%08X\n", tag);
6868  return AVERROR_INVALIDDATA;
6869  }
6870 
6871  avio_skip(pb, 1); // version
6872  avio_skip(pb, 3); // flags
6873 
6874  tag = avio_rl32(pb);
6875  switch (tag) {
6876  case MKTAG('r','e','c','t'):
6877  projection = AV_SPHERICAL_RECTILINEAR;
6878  break;
6879  case MKTAG('e','q','u','i'):
6880  projection = AV_SPHERICAL_EQUIRECTANGULAR;
6881  break;
6882  case MKTAG('h','e','q','u'):
6883  projection = AV_SPHERICAL_HALF_EQUIRECTANGULAR;
6884  break;
6885  case MKTAG('f','i','s','h'):
6886  projection = AV_SPHERICAL_FISHEYE;
6887  break;
6888  case MKTAG('p','r','i','m'):
6889  projection = AV_SPHERICAL_PARAMETRIC_IMMERSIVE;
6890  break;
6891  default:
6892  av_log(c->fc, AV_LOG_ERROR, "Invalid projection type in prji box: 0x%08X\n", tag);
6893  return AVERROR_INVALIDDATA;
6894  }
6895 
6897  if (!sc->spherical)
6898  return AVERROR(ENOMEM);
6899 
6900  sc->spherical->projection = projection;
6901 
6902  return 0;
6903 }
6904 
6906 {
6907  AVStream *st;
6908  MOVStreamContext *sc;
6909  int size, flags = 0;
6910  int64_t remaining;
6911  uint32_t tag, baseline = 0;
6914  enum AVStereo3DPrimaryEye primary_eye = AV_PRIMARY_EYE_NONE;
6915  AVRational horizontal_disparity_adjustment = { 0, 1 };
6916 
6917  if (c->fc->nb_streams < 1)
6918  return 0;
6919 
6920  st = c->fc->streams[c->fc->nb_streams - 1];
6921  sc = st->priv_data;
6922 
6923  remaining = atom.size;
6924  while (remaining > 0) {
6925  size = avio_rb32(pb);
6926  if (size < 8 || size > remaining ) {
6927  av_log(c->fc, AV_LOG_ERROR, "Invalid child size in eyes box\n");
6928  return AVERROR_INVALIDDATA;
6929  }
6930 
6931  tag = avio_rl32(pb);
6932  switch (tag) {
6933  case MKTAG('s','t','r','i'): {
6934  int has_right, has_left;
6935  uint8_t tmp;
6936  if (size != 13) {
6937  av_log(c->fc, AV_LOG_ERROR, "Invalid size of stri box: %d\n", size);
6938  return AVERROR_INVALIDDATA;
6939  }
6940  avio_skip(pb, 1); // version
6941  avio_skip(pb, 3); // flags
6942 
6943  tmp = avio_r8(pb);
6944 
6945  // eye_views_reversed
6946  if (tmp & 8) {
6948  }
6949  // has_additional_views
6950  if (tmp & 4) {
6951  // skip...
6952  }
6953 
6954  has_right = tmp & 2; // has_right_eye_view
6955  has_left = tmp & 1; // has_left_eye_view
6956 
6957  if (has_left && has_right)
6958  view = AV_STEREO3D_VIEW_PACKED;
6959  else if (has_left)
6960  view = AV_STEREO3D_VIEW_LEFT;
6961  else if (has_right)
6962  view = AV_STEREO3D_VIEW_RIGHT;
6963  if (has_left || has_right)
6965 
6966  break;
6967  }
6968  case MKTAG('h','e','r','o'): {
6969  int tmp;
6970  if (size != 13) {
6971  av_log(c->fc, AV_LOG_ERROR, "Invalid size of hero box: %d\n", size);
6972  return AVERROR_INVALIDDATA;
6973  }
6974  avio_skip(pb, 1); // version
6975  avio_skip(pb, 3); // flags
6976 
6977  tmp = avio_r8(pb);
6978  if (tmp == 0)
6979  primary_eye = AV_PRIMARY_EYE_NONE;
6980  else if (tmp == 1)
6981  primary_eye = AV_PRIMARY_EYE_LEFT;
6982  else if (tmp == 2)
6983  primary_eye = AV_PRIMARY_EYE_RIGHT;
6984  else
6985  av_log(c->fc, AV_LOG_WARNING, "Unknown hero eye type: %d\n", tmp);
6986 
6987  break;
6988  }
6989  case MKTAG('c','a','m','s'): {
6990  uint32_t subtag;
6991  int subsize;
6992  if (size != 24) {
6993  av_log(c->fc, AV_LOG_ERROR, "Invalid size of cams box: %d\n", size);
6994  return AVERROR_INVALIDDATA;
6995  }
6996 
6997  subsize = avio_rb32(pb);
6998  if (subsize != 16) {
6999  av_log(c->fc, AV_LOG_ERROR, "Invalid size of blin box: %d\n", size);
7000  return AVERROR_INVALIDDATA;
7001  }
7002 
7003  subtag = avio_rl32(pb);
7004  if (subtag != MKTAG('b','l','i','n')) {
7005  av_log(c->fc, AV_LOG_ERROR, "Expected blin box, got 0x%08X\n", subtag);
7006  return AVERROR_INVALIDDATA;
7007  }
7008 
7009  avio_skip(pb, 1); // version
7010  avio_skip(pb, 3); // flags
7011 
7012  baseline = avio_rb32(pb);
7013 
7014  break;
7015  }
7016  case MKTAG('c','m','f','y'): {
7017  uint32_t subtag;
7018  int subsize;
7019  int32_t adjustment;
7020  if (size != 24) {
7021  av_log(c->fc, AV_LOG_ERROR, "Invalid size of cmfy box: %d\n", size);
7022  return AVERROR_INVALIDDATA;
7023  }
7024 
7025  subsize = avio_rb32(pb);
7026  if (subsize != 16) {
7027  av_log(c->fc, AV_LOG_ERROR, "Invalid size of dadj box: %d\n", size);
7028  return AVERROR_INVALIDDATA;
7029  }
7030 
7031  subtag = avio_rl32(pb);
7032  if (subtag != MKTAG('d','a','d','j')) {
7033  av_log(c->fc, AV_LOG_ERROR, "Expected dadj box, got 0x%08X\n", subtag);
7034  return AVERROR_INVALIDDATA;
7035  }
7036 
7037  avio_skip(pb, 1); // version
7038  avio_skip(pb, 3); // flags
7039 
7040  adjustment = (int32_t) avio_rb32(pb);
7041 
7042  horizontal_disparity_adjustment.num = (int) adjustment;
7043  horizontal_disparity_adjustment.den = 10000;
7044 
7045  break;
7046  }
7047  default:
7048  av_log(c->fc, AV_LOG_WARNING, "Unknown tag in eyes: 0x%08X\n", tag);
7049  avio_skip(pb, size - 8);
7050  break;
7051  }
7052  remaining -= size;
7053  }
7054 
7055  if (remaining != 0) {
7056  av_log(c->fc, AV_LOG_ERROR, "Broken eyes box\n");
7057  return AVERROR_INVALIDDATA;
7058  }
7059 
7060  if (type == AV_STEREO3D_2D)
7061  return 0;
7062 
7063  if (!sc->stereo3d) {
7065  if (!sc->stereo3d)
7066  return AVERROR(ENOMEM);
7067  }
7068 
7069  sc->stereo3d->flags = flags;
7070  sc->stereo3d->type = type;
7071  sc->stereo3d->view = view;
7072  sc->stereo3d->primary_eye = primary_eye;
7073  sc->stereo3d->baseline = baseline;
7074  sc->stereo3d->horizontal_disparity_adjustment = horizontal_disparity_adjustment;
7075 
7076  return 0;
7077 }
7078 
7080 {
7081  int size;
7082  int64_t remaining;
7083  uint32_t tag;
7084 
7085  if (c->fc->nb_streams < 1)
7086  return 0;
7087 
7088  if (atom.size < 8) {
7089  av_log(c->fc, AV_LOG_ERROR, "Empty video extension usage box\n");
7090  return AVERROR_INVALIDDATA;
7091  }
7092 
7093  remaining = atom.size;
7094  while (remaining > 0) {
7095  size = avio_rb32(pb);
7096  if (size < 8 || size > remaining ) {
7097  av_log(c->fc, AV_LOG_ERROR, "Invalid child size in vexu box\n");
7098  return AVERROR_INVALIDDATA;
7099  }
7100 
7101  tag = avio_rl32(pb);
7102  switch (tag) {
7103  case MKTAG('p','r','o','j'): {
7104  MOVAtom proj = { tag, size - 8 };
7105  int ret = mov_read_vexu_proj(c, pb, proj);
7106  if (ret < 0)
7107  return ret;
7108  break;
7109  }
7110  case MKTAG('e','y','e','s'): {
7111  MOVAtom eyes = { tag, size - 8 };
7112  int ret = mov_read_eyes(c, pb, eyes);
7113  if (ret < 0)
7114  return ret;
7115  break;
7116  }
7117  case MKTAG('p','a','c','k'): {
7118  MOVAtom pack = { tag, size - 8 };
7119  int ret = mov_read_pack(c, pb, pack);
7120  if (ret < 0)
7121  return ret;
7122  break;
7123  }
7124  default:
7125  av_log(c->fc, AV_LOG_WARNING, "Unknown tag in vexu: 0x%08X\n", tag);
7126  avio_skip(pb, size - 8);
7127  break;
7128  }
7129  remaining -= size;
7130  }
7131 
7132  if (remaining != 0) {
7133  av_log(c->fc, AV_LOG_ERROR, "Broken vexu box\n");
7134  return AVERROR_INVALIDDATA;
7135  }
7136 
7137  return 0;
7138 }
7139 
7141 {
7142  AVStream *st;
7143  MOVStreamContext *sc;
7144 
7145  if (c->fc->nb_streams < 1)
7146  return 0;
7147 
7148  st = c->fc->streams[c->fc->nb_streams - 1];
7149  sc = st->priv_data;
7150 
7151  if (atom.size != 4) {
7152  av_log(c->fc, AV_LOG_ERROR, "Invalid size of hfov box: %"PRIu64"\n", atom.size);
7153  return AVERROR_INVALIDDATA;
7154  }
7155 
7156 
7157  if (!sc->stereo3d) {
7159  if (!sc->stereo3d)
7160  return AVERROR(ENOMEM);
7161  }
7162 
7164  sc->stereo3d->horizontal_field_of_view.den = 1000; // thousands of a degree
7165 
7166  return 0;
7167 }
7168 
7170 {
7171  int ret = 0;
7172  uint8_t *buffer = av_malloc(len + 1);
7173  const char *val;
7174 
7175  if (!buffer)
7176  return AVERROR(ENOMEM);
7177  buffer[len] = '\0';
7178 
7179  ret = ffio_read_size(pb, buffer, len);
7180  if (ret < 0)
7181  goto out;
7182 
7183  /* Check for mandatory keys and values, try to support XML as best-effort */
7184  if (!sc->spherical &&
7185  av_stristr(buffer, "<GSpherical:StitchingSoftware>") &&
7186  (val = av_stristr(buffer, "<GSpherical:Spherical>")) &&
7187  av_stristr(val, "true") &&
7188  (val = av_stristr(buffer, "<GSpherical:Stitched>")) &&
7189  av_stristr(val, "true") &&
7190  (val = av_stristr(buffer, "<GSpherical:ProjectionType>")) &&
7191  av_stristr(val, "equirectangular")) {
7193  if (!sc->spherical)
7194  goto out;
7195 
7197 
7198  if (av_stristr(buffer, "<GSpherical:StereoMode>") && !sc->stereo3d) {
7199  enum AVStereo3DType mode;
7200 
7201  if (av_stristr(buffer, "left-right"))
7203  else if (av_stristr(buffer, "top-bottom"))
7205  else
7206  mode = AV_STEREO3D_2D;
7207 
7209  if (!sc->stereo3d)
7210  goto out;
7211 
7212  sc->stereo3d->type = mode;
7213  }
7214 
7215  /* orientation */
7216  val = av_stristr(buffer, "<GSpherical:InitialViewHeadingDegrees>");
7217  if (val)
7218  sc->spherical->yaw = strtol(val, NULL, 10) * (1 << 16);
7219  val = av_stristr(buffer, "<GSpherical:InitialViewPitchDegrees>");
7220  if (val)
7221  sc->spherical->pitch = strtol(val, NULL, 10) * (1 << 16);
7222  val = av_stristr(buffer, "<GSpherical:InitialViewRollDegrees>");
7223  if (val)
7224  sc->spherical->roll = strtol(val, NULL, 10) * (1 << 16);
7225  }
7226 
7227 out:
7228  av_free(buffer);
7229  return ret;
7230 }
7231 
7233 {
7234  AVStream *st;
7235  MOVStreamContext *sc;
7236  int64_t ret;
7237  AVUUID uuid;
7238  static const AVUUID uuid_isml_manifest = {
7239  0xa5, 0xd4, 0x0b, 0x30, 0xe8, 0x14, 0x11, 0xdd,
7240  0xba, 0x2f, 0x08, 0x00, 0x20, 0x0c, 0x9a, 0x66
7241  };
7242  static const AVUUID uuid_xmp = {
7243  0xbe, 0x7a, 0xcf, 0xcb, 0x97, 0xa9, 0x42, 0xe8,
7244  0x9c, 0x71, 0x99, 0x94, 0x91, 0xe3, 0xaf, 0xac
7245  };
7246  static const AVUUID uuid_spherical = {
7247  0xff, 0xcc, 0x82, 0x63, 0xf8, 0x55, 0x4a, 0x93,
7248  0x88, 0x14, 0x58, 0x7a, 0x02, 0x52, 0x1f, 0xdd,
7249  };
7250 
7251  if (atom.size < AV_UUID_LEN || atom.size >= FFMIN(INT_MAX, SIZE_MAX))
7252  return AVERROR_INVALIDDATA;
7253 
7254  if (c->fc->nb_streams < 1)
7255  return 0;
7256  st = c->fc->streams[c->fc->nb_streams - 1];
7257  sc = st->priv_data;
7258 
7259  ret = ffio_read_size(pb, uuid, AV_UUID_LEN);
7260  if (ret < 0)
7261  return ret;
7262  if (av_uuid_equal(uuid, uuid_isml_manifest)) {
7263  uint8_t *buffer, *ptr;
7264  char *endptr;
7265  size_t len = atom.size - AV_UUID_LEN;
7266 
7267  if (len < 4) {
7268  return AVERROR_INVALIDDATA;
7269  }
7270  ret = avio_skip(pb, 4); // zeroes
7271  len -= 4;
7272 
7273  buffer = av_mallocz(len + 1);
7274  if (!buffer) {
7275  return AVERROR(ENOMEM);
7276  }
7277  ret = ffio_read_size(pb, buffer, len);
7278  if (ret < 0) {
7279  av_free(buffer);
7280  return ret;
7281  }
7282 
7283  ptr = buffer;
7284  while ((ptr = av_stristr(ptr, "systemBitrate=\""))) {
7285  ptr += sizeof("systemBitrate=\"") - 1;
7286  c->bitrates_count++;
7287  c->bitrates = av_realloc_f(c->bitrates, c->bitrates_count, sizeof(*c->bitrates));
7288  if (!c->bitrates) {
7289  c->bitrates_count = 0;
7290  av_free(buffer);
7291  return AVERROR(ENOMEM);
7292  }
7293  errno = 0;
7294  ret = strtol(ptr, &endptr, 10);
7295  if (ret < 0 || errno || *endptr != '"') {
7296  c->bitrates[c->bitrates_count - 1] = 0;
7297  } else {
7298  c->bitrates[c->bitrates_count - 1] = ret;
7299  }
7300  }
7301 
7302  av_free(buffer);
7303  } else if (av_uuid_equal(uuid, uuid_xmp)) {
7304  uint8_t *buffer;
7305  size_t len = atom.size - AV_UUID_LEN;
7306  if (c->export_xmp) {
7307  buffer = av_mallocz(len + 1);
7308  if (!buffer) {
7309  return AVERROR(ENOMEM);
7310  }
7311  ret = ffio_read_size(pb, buffer, len);
7312  if (ret < 0) {
7313  av_free(buffer);
7314  return ret;
7315  }
7316  buffer[len] = '\0';
7317  av_dict_set(&c->fc->metadata, "xmp",
7319  } else {
7320  // skip all uuid atom, which makes it fast for long uuid-xmp file
7321  ret = avio_skip(pb, len);
7322  if (ret < 0)
7323  return ret;
7324  }
7325  } else if (av_uuid_equal(uuid, uuid_spherical)) {
7326  size_t len = atom.size - AV_UUID_LEN;
7327  ret = mov_parse_uuid_spherical(sc, pb, len);
7328  if (ret < 0)
7329  return ret;
7330  if (!sc->spherical)
7331  av_log(c->fc, AV_LOG_WARNING, "Invalid spherical metadata found\n");
7332  }
7333 
7334  return 0;
7335 }
7336 
7338 {
7339  int ret;
7340  uint8_t content[16];
7341 
7342  if (atom.size < 8)
7343  return 0;
7344 
7345  ret = ffio_read_size(pb, content, FFMIN(sizeof(content), atom.size));
7346  if (ret < 0)
7347  return ret;
7348 
7349  if ( !c->found_moov
7350  && !c->found_mdat
7351  && !memcmp(content, "Anevia\x1A\x1A", 8)
7352  && c->use_mfra_for == FF_MOV_FLAG_MFRA_AUTO) {
7353  c->use_mfra_for = FF_MOV_FLAG_MFRA_PTS;
7354  }
7355 
7356  return 0;
7357 }
7358 
7360 {
7361  uint32_t format = avio_rl32(pb);
7362  MOVStreamContext *sc;
7363  enum AVCodecID id;
7364  AVStream *st;
7365 
7366  if (c->fc->nb_streams < 1)
7367  return 0;
7368  st = c->fc->streams[c->fc->nb_streams - 1];
7369  sc = st->priv_data;
7370 
7371  switch (sc->format)
7372  {
7373  case MKTAG('e','n','c','v'): // encrypted video
7374  case MKTAG('e','n','c','a'): // encrypted audio
7375  id = mov_codec_id(st, format);
7376  if (st->codecpar->codec_id != AV_CODEC_ID_NONE &&
7377  st->codecpar->codec_id != id) {
7378  av_log(c->fc, AV_LOG_WARNING,
7379  "ignoring 'frma' atom of '%.4s', stream has codec id %d\n",
7380  (char*)&format, st->codecpar->codec_id);
7381  break;
7382  }
7383 
7384  st->codecpar->codec_id = id;
7385  sc->format = format;
7386  break;
7387 
7388  default:
7389  if (format != sc->format) {
7390  av_log(c->fc, AV_LOG_WARNING,
7391  "ignoring 'frma' atom of '%.4s', stream format is '%.4s'\n",
7392  (char*)&format, (char*)&sc->format);
7393  }
7394  break;
7395  }
7396 
7397  return 0;
7398 }
7399 
7400 /**
7401  * Gets the current encryption info and associated current stream context. If
7402  * we are parsing a track fragment, this will return the specific encryption
7403  * info for this fragment; otherwise this will return the global encryption
7404  * info for the current stream.
7405  */
7407 {
7408  MOVFragmentStreamInfo *frag_stream_info;
7409  AVStream *st;
7410  int i;
7411 
7412  frag_stream_info = get_current_frag_stream_info(&c->frag_index);
7413  if (frag_stream_info) {
7414  for (i = 0; i < c->fc->nb_streams; i++) {
7415  *sc = c->fc->streams[i]->priv_data;
7416  if ((*sc)->id == frag_stream_info->id) {
7417  st = c->fc->streams[i];
7418  break;
7419  }
7420  }
7421  if (i == c->fc->nb_streams)
7422  return 0;
7423  *sc = st->priv_data;
7424 
7425  if (!frag_stream_info->encryption_index) {
7426  // If this stream isn't encrypted, don't create the index.
7427  if (!(*sc)->cenc.default_encrypted_sample)
7428  return 0;
7429  frag_stream_info->encryption_index = av_mallocz(sizeof(*frag_stream_info->encryption_index));
7430  if (!frag_stream_info->encryption_index)
7431  return AVERROR(ENOMEM);
7432  }
7433  *encryption_index = frag_stream_info->encryption_index;
7434  return 1;
7435  } else {
7436  // No current track fragment, using stream level encryption info.
7437 
7438  if (c->fc->nb_streams < 1)
7439  return 0;
7440  st = c->fc->streams[c->fc->nb_streams - 1];
7441  *sc = st->priv_data;
7442 
7443  if (!(*sc)->cenc.encryption_index) {
7444  // If this stream isn't encrypted, don't create the index.
7445  if (!(*sc)->cenc.default_encrypted_sample)
7446  return 0;
7447  (*sc)->cenc.encryption_index = av_mallocz(sizeof(*frag_stream_info->encryption_index));
7448  if (!(*sc)->cenc.encryption_index)
7449  return AVERROR(ENOMEM);
7450  }
7451 
7452  *encryption_index = (*sc)->cenc.encryption_index;
7453  return 1;
7454  }
7455 }
7456 
7458 {
7459  int i, ret;
7460  unsigned int subsample_count;
7461  AVSubsampleEncryptionInfo *subsamples;
7462 
7463  if (!sc->cenc.default_encrypted_sample) {
7464  av_log(c->fc, AV_LOG_ERROR, "Missing schm or tenc\n");
7465  return AVERROR_INVALIDDATA;
7466  }
7467 
7468  if (sc->cenc.per_sample_iv_size || use_subsamples) {
7470  if (!*sample)
7471  return AVERROR(ENOMEM);
7472  } else
7473  *sample = NULL;
7474 
7475  if (sc->cenc.per_sample_iv_size != 0) {
7476  if ((ret = ffio_read_size(pb, (*sample)->iv, sc->cenc.per_sample_iv_size)) < 0) {
7477  av_log(c->fc, AV_LOG_ERROR, "failed to read the initialization vector\n");
7479  *sample = NULL;
7480  return ret;
7481  }
7482  }
7483 
7484  if (use_subsamples) {
7485  subsample_count = avio_rb16(pb);
7486  av_free((*sample)->subsamples);
7487  (*sample)->subsamples = av_calloc(subsample_count, sizeof(*subsamples));
7488  if (!(*sample)->subsamples) {
7490  *sample = NULL;
7491  return AVERROR(ENOMEM);
7492  }
7493 
7494  for (i = 0; i < subsample_count && !pb->eof_reached; i++) {
7495  (*sample)->subsamples[i].bytes_of_clear_data = avio_rb16(pb);
7496  (*sample)->subsamples[i].bytes_of_protected_data = avio_rb32(pb);
7497  }
7498 
7499  if (pb->eof_reached) {
7500  av_log(c->fc, AV_LOG_ERROR, "hit EOF while reading sub-sample encryption info\n");
7502  *sample = NULL;
7503  return AVERROR_INVALIDDATA;
7504  }
7505  (*sample)->subsample_count = subsample_count;
7506  }
7507 
7508  return 0;
7509 }
7510 
7512 {
7513  AVEncryptionInfo **encrypted_samples;
7514  MOVEncryptionIndex *encryption_index;
7515  MOVStreamContext *sc;
7516  int use_subsamples, ret;
7517  unsigned int sample_count, i, alloc_size = 0;
7518 
7519  ret = get_current_encryption_info(c, &encryption_index, &sc);
7520  if (ret != 1)
7521  return ret;
7522 
7523  if (encryption_index->nb_encrypted_samples) {
7524  // This can happen if we have both saio/saiz and senc atoms.
7525  av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in senc\n");
7526  return 0;
7527  }
7528 
7529  avio_r8(pb); /* version */
7530  use_subsamples = avio_rb24(pb) & 0x02; /* flags */
7531 
7532  sample_count = avio_rb32(pb);
7533  if (sample_count >= INT_MAX / sizeof(*encrypted_samples))
7534  return AVERROR(ENOMEM);
7535 
7536  for (i = 0; i < sample_count; i++) {
7537  unsigned int min_samples = FFMIN(FFMAX(i + 1, 1024 * 1024), sample_count);
7538  encrypted_samples = av_fast_realloc(encryption_index->encrypted_samples, &alloc_size,
7539  min_samples * sizeof(*encrypted_samples));
7540  if (encrypted_samples) {
7541  encryption_index->encrypted_samples = encrypted_samples;
7542 
7544  c, pb, sc, &encryption_index->encrypted_samples[i], use_subsamples);
7545  } else {
7546  ret = AVERROR(ENOMEM);
7547  }
7548  if (pb->eof_reached) {
7549  av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading senc\n");
7550  if (ret >= 0)
7551  av_encryption_info_free(encryption_index->encrypted_samples[i]);
7553  }
7554 
7555  if (ret < 0) {
7556  for (; i > 0; i--)
7557  av_encryption_info_free(encryption_index->encrypted_samples[i - 1]);
7558  av_freep(&encryption_index->encrypted_samples);
7559  return ret;
7560  }
7561  }
7562  encryption_index->nb_encrypted_samples = sample_count;
7563 
7564  return 0;
7565 }
7566 
7568 {
7569  AVEncryptionInfo **sample, **encrypted_samples;
7570  int64_t prev_pos;
7571  size_t sample_count, sample_info_size, i;
7572  int ret = 0;
7573  unsigned int alloc_size = 0;
7574 
7575  if (encryption_index->nb_encrypted_samples)
7576  return 0;
7577  sample_count = encryption_index->auxiliary_info_sample_count;
7578  if (encryption_index->auxiliary_offsets_count != 1) {
7579  av_log(c->fc, AV_LOG_ERROR, "Multiple auxiliary info chunks are not supported\n");
7580  return AVERROR_PATCHWELCOME;
7581  }
7582  if (sample_count >= INT_MAX / sizeof(*encrypted_samples))
7583  return AVERROR(ENOMEM);
7584 
7585  prev_pos = avio_tell(pb);
7586  if (!(pb->seekable & AVIO_SEEKABLE_NORMAL) ||
7587  avio_seek(pb, encryption_index->auxiliary_offsets[0], SEEK_SET) != encryption_index->auxiliary_offsets[0]) {
7588  av_log(c->fc, AV_LOG_INFO, "Failed to seek for auxiliary info, will only parse senc atoms for encryption info\n");
7589  goto finish;
7590  }
7591 
7592  for (i = 0; i < sample_count && !pb->eof_reached; i++) {
7593  unsigned int min_samples = FFMIN(FFMAX(i + 1, 1024 * 1024), sample_count);
7594  encrypted_samples = av_fast_realloc(encryption_index->encrypted_samples, &alloc_size,
7595  min_samples * sizeof(*encrypted_samples));
7596  if (!encrypted_samples) {
7597  ret = AVERROR(ENOMEM);
7598  goto finish;
7599  }
7600  encryption_index->encrypted_samples = encrypted_samples;
7601 
7602  sample = &encryption_index->encrypted_samples[i];
7603  sample_info_size = encryption_index->auxiliary_info_default_size
7604  ? encryption_index->auxiliary_info_default_size
7605  : encryption_index->auxiliary_info_sizes[i];
7606 
7607  ret = mov_read_sample_encryption_info(c, pb, sc, sample, sample_info_size > sc->cenc.per_sample_iv_size);
7608  if (ret < 0)
7609  goto finish;
7610  }
7611  if (pb->eof_reached) {
7612  av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading auxiliary info\n");
7614  } else {
7615  encryption_index->nb_encrypted_samples = sample_count;
7616  }
7617 
7618 finish:
7619  avio_seek(pb, prev_pos, SEEK_SET);
7620  if (ret < 0) {
7621  for (; i > 0; i--) {
7622  av_encryption_info_free(encryption_index->encrypted_samples[i - 1]);
7623  }
7624  av_freep(&encryption_index->encrypted_samples);
7625  }
7626  return ret;
7627 }
7628 
7630 {
7631  MOVEncryptionIndex *encryption_index;
7632  MOVStreamContext *sc;
7633  int ret;
7634  unsigned int sample_count, aux_info_type, aux_info_param;
7635 
7636  ret = get_current_encryption_info(c, &encryption_index, &sc);
7637  if (ret != 1)
7638  return ret;
7639 
7640  if (encryption_index->nb_encrypted_samples) {
7641  // This can happen if we have both saio/saiz and senc atoms.
7642  av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in saiz\n");
7643  return 0;
7644  }
7645 
7646  if (encryption_index->auxiliary_info_sample_count) {
7647  av_log(c->fc, AV_LOG_ERROR, "Duplicate saiz atom\n");
7648  return AVERROR_INVALIDDATA;
7649  }
7650 
7651  avio_r8(pb); /* version */
7652  if (avio_rb24(pb) & 0x01) { /* flags */
7653  aux_info_type = avio_rb32(pb);
7654  aux_info_param = avio_rb32(pb);
7655  if (sc->cenc.default_encrypted_sample) {
7656  if (aux_info_type != sc->cenc.default_encrypted_sample->scheme) {
7657  av_log(c->fc, AV_LOG_DEBUG, "Ignoring saiz box with non-zero aux_info_type\n");
7658  return 0;
7659  }
7660  if (aux_info_param != 0) {
7661  av_log(c->fc, AV_LOG_DEBUG, "Ignoring saiz box with non-zero aux_info_type_parameter\n");
7662  return 0;
7663  }
7664  } else {
7665  // Didn't see 'schm' or 'tenc', so this isn't encrypted.
7666  if ((aux_info_type == MKBETAG('c','e','n','c') ||
7667  aux_info_type == MKBETAG('c','e','n','s') ||
7668  aux_info_type == MKBETAG('c','b','c','1') ||
7669  aux_info_type == MKBETAG('c','b','c','s')) &&
7670  aux_info_param == 0) {
7671  av_log(c->fc, AV_LOG_ERROR, "Saw encrypted saiz without schm/tenc\n");
7672  return AVERROR_INVALIDDATA;
7673  } else {
7674  return 0;
7675  }
7676  }
7677  } else if (!sc->cenc.default_encrypted_sample) {
7678  // Didn't see 'schm' or 'tenc', so this isn't encrypted.
7679  return 0;
7680  }
7681 
7682  encryption_index->auxiliary_info_default_size = avio_r8(pb);
7683  sample_count = avio_rb32(pb);
7684 
7685  if (encryption_index->auxiliary_info_default_size == 0) {
7686  if (sample_count == 0)
7687  return AVERROR_INVALIDDATA;
7688 
7689  encryption_index->auxiliary_info_sizes = av_malloc(sample_count);
7690  if (!encryption_index->auxiliary_info_sizes)
7691  return AVERROR(ENOMEM);
7692 
7693  ret = avio_read(pb, encryption_index->auxiliary_info_sizes, sample_count);
7694  if (ret != sample_count) {
7695  av_freep(&encryption_index->auxiliary_info_sizes);
7696 
7697  if (ret >= 0)
7699  av_log(c->fc, AV_LOG_ERROR, "Failed to read the auxiliary info, %s\n",
7700  av_err2str(ret));
7701  return ret;
7702  }
7703  }
7704  encryption_index->auxiliary_info_sample_count = sample_count;
7705 
7706  if (encryption_index->auxiliary_offsets_count) {
7707  return mov_parse_auxiliary_info(c, sc, pb, encryption_index);
7708  }
7709 
7710  return 0;
7711 }
7712 
7714 {
7715  uint64_t *auxiliary_offsets;
7716  MOVEncryptionIndex *encryption_index;
7717  MOVStreamContext *sc;
7718  int i, ret;
7719  unsigned int version, entry_count, aux_info_type, aux_info_param;
7720  unsigned int alloc_size = 0;
7721 
7722  ret = get_current_encryption_info(c, &encryption_index, &sc);
7723  if (ret != 1)
7724  return ret;
7725 
7726  if (encryption_index->nb_encrypted_samples) {
7727  // This can happen if we have both saio/saiz and senc atoms.
7728  av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in saio\n");
7729  return 0;
7730  }
7731 
7732  if (encryption_index->auxiliary_offsets_count) {
7733  av_log(c->fc, AV_LOG_ERROR, "Duplicate saio atom\n");
7734  return AVERROR_INVALIDDATA;
7735  }
7736 
7737  version = avio_r8(pb); /* version */
7738  if (avio_rb24(pb) & 0x01) { /* flags */
7739  aux_info_type = avio_rb32(pb);
7740  aux_info_param = avio_rb32(pb);
7741  if (sc->cenc.default_encrypted_sample) {
7742  if (aux_info_type != sc->cenc.default_encrypted_sample->scheme) {
7743  av_log(c->fc, AV_LOG_DEBUG, "Ignoring saio box with non-zero aux_info_type\n");
7744  return 0;
7745  }
7746  if (aux_info_param != 0) {
7747  av_log(c->fc, AV_LOG_DEBUG, "Ignoring saio box with non-zero aux_info_type_parameter\n");
7748  return 0;
7749  }
7750  } else {
7751  // Didn't see 'schm' or 'tenc', so this isn't encrypted.
7752  if ((aux_info_type == MKBETAG('c','e','n','c') ||
7753  aux_info_type == MKBETAG('c','e','n','s') ||
7754  aux_info_type == MKBETAG('c','b','c','1') ||
7755  aux_info_type == MKBETAG('c','b','c','s')) &&
7756  aux_info_param == 0) {
7757  av_log(c->fc, AV_LOG_ERROR, "Saw encrypted saio without schm/tenc\n");
7758  return AVERROR_INVALIDDATA;
7759  } else {
7760  return 0;
7761  }
7762  }
7763  } else if (!sc->cenc.default_encrypted_sample) {
7764  // Didn't see 'schm' or 'tenc', so this isn't encrypted.
7765  return 0;
7766  }
7767 
7768  entry_count = avio_rb32(pb);
7769  if (entry_count >= INT_MAX / sizeof(*auxiliary_offsets))
7770  return AVERROR(ENOMEM);
7771 
7772  for (i = 0; i < entry_count && !pb->eof_reached; i++) {
7773  unsigned int min_offsets = FFMIN(FFMAX(i + 1, 1024), entry_count);
7774  auxiliary_offsets = av_fast_realloc(
7775  encryption_index->auxiliary_offsets, &alloc_size,
7776  min_offsets * sizeof(*auxiliary_offsets));
7777  if (!auxiliary_offsets) {
7778  av_freep(&encryption_index->auxiliary_offsets);
7779  return AVERROR(ENOMEM);
7780  }
7781  encryption_index->auxiliary_offsets = auxiliary_offsets;
7782 
7783  if (version == 0) {
7784  encryption_index->auxiliary_offsets[i] = avio_rb32(pb);
7785  } else {
7786  encryption_index->auxiliary_offsets[i] = avio_rb64(pb);
7787  }
7788  if (c->frag_index.current >= 0) {
7789  encryption_index->auxiliary_offsets[i] += c->fragment.base_data_offset;
7790  }
7791  }
7792 
7793  if (pb->eof_reached) {
7794  av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading saio\n");
7795  av_freep(&encryption_index->auxiliary_offsets);
7796  return AVERROR_INVALIDDATA;
7797  }
7798 
7799  encryption_index->auxiliary_offsets_count = entry_count;
7800 
7801  if (encryption_index->auxiliary_info_sample_count) {
7802  return mov_parse_auxiliary_info(c, sc, pb, encryption_index);
7803  }
7804 
7805  return 0;
7806 }
7807 
7809 {
7810  AVEncryptionInitInfo *info, *old_init_info;
7811  uint8_t **key_ids;
7812  AVStream *st;
7813  const AVPacketSideData *old_side_data;
7814  uint8_t *side_data, *extra_data;
7815  size_t side_data_size;
7816  int ret = 0;
7817  unsigned int version, kid_count, extra_data_size, alloc_size = 0;
7818 
7819  if (c->fc->nb_streams < 1)
7820  return 0;
7821  st = c->fc->streams[c->fc->nb_streams-1];
7822 
7823  version = avio_r8(pb); /* version */
7824  avio_rb24(pb); /* flags */
7825 
7826  info = av_encryption_init_info_alloc(/* system_id_size */ 16, /* num_key_ids */ 0,
7827  /* key_id_size */ 16, /* data_size */ 0);
7828  if (!info)
7829  return AVERROR(ENOMEM);
7830 
7831  if ((ret = ffio_read_size(pb, info->system_id, 16)) < 0) {
7832  av_log(c->fc, AV_LOG_ERROR, "Failed to read the system id\n");
7833  goto finish;
7834  }
7835 
7836  if (version > 0) {
7837  kid_count = avio_rb32(pb);
7838  if (kid_count >= INT_MAX / sizeof(*key_ids)) {
7839  ret = AVERROR(ENOMEM);
7840  goto finish;
7841  }
7842 
7843  for (unsigned int i = 0; i < kid_count && !pb->eof_reached; i++) {
7844  unsigned int min_kid_count = FFMIN(FFMAX(i + 1, 1024), kid_count);
7845  key_ids = av_fast_realloc(info->key_ids, &alloc_size,
7846  min_kid_count * sizeof(*key_ids));
7847  if (!key_ids) {
7848  ret = AVERROR(ENOMEM);
7849  goto finish;
7850  }
7851  info->key_ids = key_ids;
7852 
7853  info->key_ids[i] = av_mallocz(16);
7854  if (!info->key_ids[i]) {
7855  ret = AVERROR(ENOMEM);
7856  goto finish;
7857  }
7858  info->num_key_ids = i + 1;
7859 
7860  if ((ret = ffio_read_size(pb, info->key_ids[i], 16)) < 0) {
7861  av_log(c->fc, AV_LOG_ERROR, "Failed to read the key id\n");
7862  goto finish;
7863  }
7864  }
7865 
7866  if (pb->eof_reached) {
7867  av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading pssh\n");
7869  goto finish;
7870  }
7871  }
7872 
7873  extra_data_size = avio_rb32(pb);
7874  extra_data = av_malloc(extra_data_size);
7875  if (!extra_data) {
7876  ret = AVERROR(ENOMEM);
7877  goto finish;
7878  }
7879  ret = avio_read(pb, extra_data, extra_data_size);
7880  if (ret != extra_data_size) {
7881  av_free(extra_data);
7882 
7883  if (ret >= 0)
7885  goto finish;
7886  }
7887 
7888  av_freep(&info->data); // malloc(0) may still allocate something.
7889  info->data = extra_data;
7890  info->data_size = extra_data_size;
7891 
7892  // If there is existing initialization data, append to the list.
7895  if (old_side_data) {
7896  old_init_info = av_encryption_init_info_get_side_data(old_side_data->data, old_side_data->size);
7897  if (old_init_info) {
7898  // Append to the end of the list.
7899  for (AVEncryptionInitInfo *cur = old_init_info;; cur = cur->next) {
7900  if (!cur->next) {
7901  cur->next = info;
7902  break;
7903  }
7904  }
7905  info = old_init_info;
7906  } else {
7907  // Assume existing side-data will be valid, so the only error we could get is OOM.
7908  ret = AVERROR(ENOMEM);
7909  goto finish;
7910  }
7911  }
7912 
7913  side_data = av_encryption_init_info_add_side_data(info, &side_data_size);
7914  if (!side_data) {
7915  ret = AVERROR(ENOMEM);
7916  goto finish;
7917  }
7921  side_data, side_data_size, 0))
7922  av_free(side_data);
7923 
7924 finish:
7926  return ret;
7927 }
7928 
7930 {
7931  AVStream *st;
7932  MOVStreamContext *sc;
7933 
7934  if (c->fc->nb_streams < 1)
7935  return 0;
7936  st = c->fc->streams[c->fc->nb_streams-1];
7937  sc = st->priv_data;
7938 
7939  if (sc->pseudo_stream_id != 0) {
7940  av_log(c->fc, AV_LOG_ERROR, "schm boxes are only supported in first sample descriptor\n");
7941  return AVERROR_PATCHWELCOME;
7942  }
7943 
7944  if (atom.size < 8)
7945  return AVERROR_INVALIDDATA;
7946 
7947  avio_rb32(pb); /* version and flags */
7948 
7949  if (!sc->cenc.default_encrypted_sample) {
7951  if (!sc->cenc.default_encrypted_sample) {
7952  return AVERROR(ENOMEM);
7953  }
7954  }
7955 
7957  return 0;
7958 }
7959 
7961 {
7962  AVStream *st;
7963  MOVStreamContext *sc;
7964  unsigned int version, pattern, is_protected, iv_size;
7965 
7966  if (c->fc->nb_streams < 1)
7967  return 0;
7968  st = c->fc->streams[c->fc->nb_streams-1];
7969  sc = st->priv_data;
7970 
7971  if (sc->pseudo_stream_id != 0) {
7972  av_log(c->fc, AV_LOG_ERROR, "tenc atom are only supported in first sample descriptor\n");
7973  return AVERROR_PATCHWELCOME;
7974  }
7975 
7976  if (!sc->cenc.default_encrypted_sample) {
7978  if (!sc->cenc.default_encrypted_sample) {
7979  return AVERROR(ENOMEM);
7980  }
7981  }
7982 
7983  if (atom.size < 20)
7984  return AVERROR_INVALIDDATA;
7985 
7986  version = avio_r8(pb); /* version */
7987  avio_rb24(pb); /* flags */
7988 
7989  avio_r8(pb); /* reserved */
7990  pattern = avio_r8(pb);
7991 
7992  if (version > 0) {
7993  sc->cenc.default_encrypted_sample->crypt_byte_block = pattern >> 4;
7994  sc->cenc.default_encrypted_sample->skip_byte_block = pattern & 0xf;
7995  }
7996 
7997  is_protected = avio_r8(pb);
7998  if (is_protected && !sc->cenc.encryption_index) {
7999  // The whole stream should be by-default encrypted.
8001  if (!sc->cenc.encryption_index)
8002  return AVERROR(ENOMEM);
8003  }
8004  sc->cenc.per_sample_iv_size = avio_r8(pb);
8005  if (sc->cenc.per_sample_iv_size != 0 && sc->cenc.per_sample_iv_size != 8 &&
8006  sc->cenc.per_sample_iv_size != 16) {
8007  av_log(c->fc, AV_LOG_ERROR, "invalid per-sample IV size value\n");
8008  return AVERROR_INVALIDDATA;
8009  }
8010  if (avio_read(pb, sc->cenc.default_encrypted_sample->key_id, 16) != 16) {
8011  av_log(c->fc, AV_LOG_ERROR, "failed to read the default key ID\n");
8012  return AVERROR_INVALIDDATA;
8013  }
8014 
8015  if (is_protected && !sc->cenc.per_sample_iv_size) {
8016  iv_size = avio_r8(pb);
8017  if (iv_size != 8 && iv_size != 16) {
8018  av_log(c->fc, AV_LOG_ERROR, "invalid default_constant_IV_size in tenc atom\n");
8019  return AVERROR_INVALIDDATA;
8020  }
8021 
8022  if (avio_read(pb, sc->cenc.default_encrypted_sample->iv, iv_size) != iv_size) {
8023  av_log(c->fc, AV_LOG_ERROR, "failed to read the default IV\n");
8024  return AVERROR_INVALIDDATA;
8025  }
8026  }
8027 
8028  return 0;
8029 }
8030 
8032 {
8033  AVStream *st;
8034  int last, type, size, ret;
8035  uint8_t buf[4];
8036 
8037  if (c->fc->nb_streams < 1)
8038  return 0;
8039  st = c->fc->streams[c->fc->nb_streams-1];
8040 
8041  if ((uint64_t)atom.size > (1<<30) || atom.size < 42)
8042  return AVERROR_INVALIDDATA;
8043 
8044  /* Check FlacSpecificBox version. */
8045  if (avio_r8(pb) != 0)
8046  return AVERROR_INVALIDDATA;
8047 
8048  avio_rb24(pb); /* Flags */
8049 
8050  if (avio_read(pb, buf, sizeof(buf)) != sizeof(buf)) {
8051  av_log(c->fc, AV_LOG_ERROR, "failed to read FLAC metadata block header\n");
8052  return pb->error < 0 ? pb->error : AVERROR_INVALIDDATA;
8053  }
8054  flac_parse_block_header(buf, &last, &type, &size);
8055 
8057  av_log(c->fc, AV_LOG_ERROR, "STREAMINFO must be first FLACMetadataBlock\n");
8058  return AVERROR_INVALIDDATA;
8059  }
8060 
8061  ret = ff_get_extradata(c->fc, st->codecpar, pb, size);
8062  if (ret < 0)
8063  return ret;
8064 
8065  if (!last)
8066  av_log(c->fc, AV_LOG_WARNING, "non-STREAMINFO FLACMetadataBlock(s) ignored\n");
8067 
8068  return 0;
8069 }
8070 
8072 {
8073  int i, ret;
8074  int bytes_of_protected_data;
8075 
8076  if (!sc->cenc.aes_ctr) {
8077  /* initialize the cipher */
8078  sc->cenc.aes_ctr = av_aes_ctr_alloc();
8079  if (!sc->cenc.aes_ctr) {
8080  return AVERROR(ENOMEM);
8081  }
8082 
8083  ret = av_aes_ctr_init(sc->cenc.aes_ctr, c->decryption_key);
8084  if (ret < 0) {
8085  return ret;
8086  }
8087  }
8088 
8090 
8091  if (!sample->subsample_count) {
8092  /* decrypt the whole packet */
8094  return 0;
8095  }
8096 
8097  for (i = 0; i < sample->subsample_count; i++) {
8098  if (sample->subsamples[i].bytes_of_clear_data + sample->subsamples[i].bytes_of_protected_data > size) {
8099  av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n");
8100  return AVERROR_INVALIDDATA;
8101  }
8102 
8103  /* skip the clear bytes */
8104  input += sample->subsamples[i].bytes_of_clear_data;
8105  size -= sample->subsamples[i].bytes_of_clear_data;
8106 
8107  /* decrypt the encrypted bytes */
8108 
8109  bytes_of_protected_data = sample->subsamples[i].bytes_of_protected_data;
8110  av_aes_ctr_crypt(sc->cenc.aes_ctr, input, input, bytes_of_protected_data);
8111 
8112  input += bytes_of_protected_data;
8113  size -= bytes_of_protected_data;
8114  }
8115 
8116  if (size > 0) {
8117  av_log(c->fc, AV_LOG_ERROR, "leftover packet bytes after subsample processing\n");
8118  return AVERROR_INVALIDDATA;
8119  }
8120 
8121  return 0;
8122 }
8123 
8125 {
8126  int i, ret;
8127  int num_of_encrypted_blocks;
8128  uint8_t iv[16];
8129 
8130  if (!sc->cenc.aes_ctx) {
8131  /* initialize the cipher */
8132  sc->cenc.aes_ctx = av_aes_alloc();
8133  if (!sc->cenc.aes_ctx) {
8134  return AVERROR(ENOMEM);
8135  }
8136 
8137  ret = av_aes_init(sc->cenc.aes_ctx, c->decryption_key, 16 * 8, 1);
8138  if (ret < 0) {
8139  return ret;
8140  }
8141  }
8142 
8143  memcpy(iv, sample->iv, 16);
8144 
8145  /* whole-block full sample encryption */
8146  if (!sample->subsample_count) {
8147  /* decrypt the whole packet */
8148  av_aes_crypt(sc->cenc.aes_ctx, input, input, size/16, iv, 1);
8149  return 0;
8150  }
8151 
8152  for (i = 0; i < sample->subsample_count; i++) {
8153  if (sample->subsamples[i].bytes_of_clear_data + sample->subsamples[i].bytes_of_protected_data > size) {
8154  av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n");
8155  return AVERROR_INVALIDDATA;
8156  }
8157 
8158  if (sample->subsamples[i].bytes_of_protected_data % 16) {
8159  av_log(c->fc, AV_LOG_ERROR, "subsample BytesOfProtectedData is not a multiple of 16\n");
8160  return AVERROR_INVALIDDATA;
8161  }
8162 
8163  /* skip the clear bytes */
8164  input += sample->subsamples[i].bytes_of_clear_data;
8165  size -= sample->subsamples[i].bytes_of_clear_data;
8166 
8167  /* decrypt the encrypted bytes */
8168  num_of_encrypted_blocks = sample->subsamples[i].bytes_of_protected_data/16;
8169  if (num_of_encrypted_blocks > 0) {
8170  av_aes_crypt(sc->cenc.aes_ctx, input, input, num_of_encrypted_blocks, iv, 1);
8171  }
8172  input += sample->subsamples[i].bytes_of_protected_data;
8173  size -= sample->subsamples[i].bytes_of_protected_data;
8174  }
8175 
8176  if (size > 0) {
8177  av_log(c->fc, AV_LOG_ERROR, "leftover packet bytes after subsample processing\n");
8178  return AVERROR_INVALIDDATA;
8179  }
8180 
8181  return 0;
8182 }
8183 
8185 {
8186  int i, ret, rem_bytes;
8187  uint8_t *data;
8188 
8189  if (!sc->cenc.aes_ctr) {
8190  /* initialize the cipher */
8191  sc->cenc.aes_ctr = av_aes_ctr_alloc();
8192  if (!sc->cenc.aes_ctr) {
8193  return AVERROR(ENOMEM);
8194  }
8195 
8196  ret = av_aes_ctr_init(sc->cenc.aes_ctr, c->decryption_key);
8197  if (ret < 0) {
8198  return ret;
8199  }
8200  }
8201 
8203 
8204  /* whole-block full sample encryption */
8205  if (!sample->subsample_count) {
8206  /* decrypt the whole packet */
8208  return 0;
8209  } else if (!sample->crypt_byte_block && !sample->skip_byte_block) {
8210  av_log(c->fc, AV_LOG_ERROR, "pattern encryption is not present in 'cens' scheme\n");
8211  return AVERROR_INVALIDDATA;
8212  }
8213 
8214  for (i = 0; i < sample->subsample_count; i++) {
8215  if (sample->subsamples[i].bytes_of_clear_data + sample->subsamples[i].bytes_of_protected_data > size) {
8216  av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n");
8217  return AVERROR_INVALIDDATA;
8218  }
8219 
8220  /* skip the clear bytes */
8221  input += sample->subsamples[i].bytes_of_clear_data;
8222  size -= sample->subsamples[i].bytes_of_clear_data;
8223 
8224  /* decrypt the encrypted bytes */
8225  data = input;
8226  rem_bytes = sample->subsamples[i].bytes_of_protected_data;
8227  while (rem_bytes > 0) {
8228  if (rem_bytes < 16*sample->crypt_byte_block) {
8229  break;
8230  }
8231  av_aes_ctr_crypt(sc->cenc.aes_ctr, data, data, 16*sample->crypt_byte_block);
8232  data += 16*sample->crypt_byte_block;
8233  rem_bytes -= 16*sample->crypt_byte_block;
8234  data += FFMIN(16*sample->skip_byte_block, rem_bytes);
8235  rem_bytes -= FFMIN(16*sample->skip_byte_block, rem_bytes);
8236  }
8237  input += sample->subsamples[i].bytes_of_protected_data;
8238  size -= sample->subsamples[i].bytes_of_protected_data;
8239  }
8240 
8241  if (size > 0) {
8242  av_log(c->fc, AV_LOG_ERROR, "leftover packet bytes after subsample processing\n");
8243  return AVERROR_INVALIDDATA;
8244  }
8245 
8246  return 0;
8247 }
8248 
8250 {
8251  int i, ret, rem_bytes;
8252  uint8_t iv[16];
8253  uint8_t *data;
8254 
8255  if (!sc->cenc.aes_ctx) {
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, c->decryption_key, 16 * 8, 1);
8263  if (ret < 0) {
8264  return ret;
8265  }
8266  }
8267 
8268  /* whole-block full sample encryption */
8269  if (!sample->subsample_count) {
8270  /* decrypt the whole packet */
8271  memcpy(iv, sample->iv, 16);
8272  av_aes_crypt(sc->cenc.aes_ctx, input, input, size/16, iv, 1);
8273  return 0;
8274  } else if (!sample->crypt_byte_block && !sample->skip_byte_block) {
8275  av_log(c->fc, AV_LOG_ERROR, "pattern encryption is not present in 'cbcs' scheme\n");
8276  return AVERROR_INVALIDDATA;
8277  }
8278 
8279  for (i = 0; i < sample->subsample_count; i++) {
8280  if (sample->subsamples[i].bytes_of_clear_data + sample->subsamples[i].bytes_of_protected_data > size) {
8281  av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n");
8282  return AVERROR_INVALIDDATA;
8283  }
8284 
8285  /* skip the clear bytes */
8286  input += sample->subsamples[i].bytes_of_clear_data;
8287  size -= sample->subsamples[i].bytes_of_clear_data;
8288 
8289  /* decrypt the encrypted bytes */
8290  memcpy(iv, sample->iv, 16);
8291  data = input;
8292  rem_bytes = sample->subsamples[i].bytes_of_protected_data;
8293  while (rem_bytes > 0) {
8294  if (rem_bytes < 16*sample->crypt_byte_block) {
8295  break;
8296  }
8297  av_aes_crypt(sc->cenc.aes_ctx, data, data, sample->crypt_byte_block, iv, 1);
8298  data += 16*sample->crypt_byte_block;
8299  rem_bytes -= 16*sample->crypt_byte_block;
8300  data += FFMIN(16*sample->skip_byte_block, rem_bytes);
8301  rem_bytes -= FFMIN(16*sample->skip_byte_block, rem_bytes);
8302  }
8303  input += sample->subsamples[i].bytes_of_protected_data;
8304  size -= sample->subsamples[i].bytes_of_protected_data;
8305  }
8306 
8307  if (size > 0) {
8308  av_log(c->fc, AV_LOG_ERROR, "leftover packet bytes after subsample processing\n");
8309  return AVERROR_INVALIDDATA;
8310  }
8311 
8312  return 0;
8313 }
8314 
8316 {
8317  if (sample->scheme == MKBETAG('c','e','n','c') && !sample->crypt_byte_block && !sample->skip_byte_block) {
8318  return cenc_scheme_decrypt(c, sc, sample, input, size);
8319  } else if (sample->scheme == MKBETAG('c','b','c','1') && !sample->crypt_byte_block && !sample->skip_byte_block) {
8320  return cbc1_scheme_decrypt(c, sc, sample, input, size);
8321  } else if (sample->scheme == MKBETAG('c','e','n','s')) {
8322  return cens_scheme_decrypt(c, sc, sample, input, size);
8323  } else if (sample->scheme == MKBETAG('c','b','c','s')) {
8324  return cbcs_scheme_decrypt(c, sc, sample, input, size);
8325  } else {
8326  av_log(c->fc, AV_LOG_ERROR, "invalid encryption scheme\n");
8327  return AVERROR_INVALIDDATA;
8328  }
8329 }
8330 
8332 {
8333  int current = frag_index->current;
8334 
8335  if (!frag_index->nb_items)
8336  return NULL;
8337 
8338  // Check frag_index->current is the right one for pkt. It can out of sync.
8339  if (current >= 0 && current < frag_index->nb_items) {
8340  if (frag_index->item[current].moof_offset < pkt->pos &&
8341  (current + 1 == frag_index->nb_items ||
8342  frag_index->item[current + 1].moof_offset > pkt->pos))
8343  return get_frag_stream_info(frag_index, current, id);
8344  }
8345 
8346 
8347  for (int i = 0; i < frag_index->nb_items; i++) {
8348  if (frag_index->item[i].moof_offset > pkt->pos)
8349  break;
8350  current = i;
8351  }
8352  frag_index->current = current;
8353  return get_frag_stream_info(frag_index, current, id);
8354 }
8355 
8356 static int cenc_filter(MOVContext *mov, AVStream* st, MOVStreamContext *sc, AVPacket *pkt, int current_index)
8357 {
8358  MOVFragmentStreamInfo *frag_stream_info;
8359  MOVEncryptionIndex *encryption_index;
8360  AVEncryptionInfo *encrypted_sample;
8361  int encrypted_index, ret;
8362 
8363  frag_stream_info = get_frag_stream_info_from_pkt(&mov->frag_index, pkt, sc->id);
8364  encrypted_index = current_index;
8365  encryption_index = NULL;
8366  if (frag_stream_info) {
8367  // Note this only supports encryption info in the first sample descriptor.
8368  if (frag_stream_info->stsd_id == 1) {
8369  if (frag_stream_info->encryption_index) {
8370  encrypted_index = current_index - frag_stream_info->index_base;
8371  encryption_index = frag_stream_info->encryption_index;
8372  } else {
8373  encryption_index = sc->cenc.encryption_index;
8374  }
8375  }
8376  } else {
8377  encryption_index = sc->cenc.encryption_index;
8378  }
8379 
8380  if (encryption_index) {
8381  if (encryption_index->auxiliary_info_sample_count &&
8382  !encryption_index->nb_encrypted_samples) {
8383  av_log(mov->fc, AV_LOG_ERROR, "saiz atom found without saio\n");
8384  return AVERROR_INVALIDDATA;
8385  }
8386  if (encryption_index->auxiliary_offsets_count &&
8387  !encryption_index->nb_encrypted_samples) {
8388  av_log(mov->fc, AV_LOG_ERROR, "saio atom found without saiz\n");
8389  return AVERROR_INVALIDDATA;
8390  }
8391 
8392  encrypted_sample = NULL;
8393  if (!encryption_index->nb_encrypted_samples) {
8394  // Full-sample encryption with default settings.
8395  encrypted_sample = sc->cenc.default_encrypted_sample;
8396  } else if (encrypted_index >= 0 && encrypted_index < encryption_index->nb_encrypted_samples) {
8397  // Per-sample setting override.
8398  encrypted_sample = encryption_index->encrypted_samples[encrypted_index];
8399  if (!encrypted_sample) {
8400  encrypted_sample = sc->cenc.default_encrypted_sample;
8401  }
8402  }
8403 
8404  if (!encrypted_sample) {
8405  av_log(mov->fc, AV_LOG_ERROR, "Incorrect number of samples in encryption info\n");
8406  return AVERROR_INVALIDDATA;
8407  }
8408 
8409  if (mov->decryption_key) {
8410  return cenc_decrypt(mov, sc, encrypted_sample, pkt->data, pkt->size);
8411  } else {
8412  size_t size;
8413  uint8_t *side_data = av_encryption_info_add_side_data(encrypted_sample, &size);
8414  if (!side_data)
8415  return AVERROR(ENOMEM);
8417  if (ret < 0)
8418  av_free(side_data);
8419  return ret;
8420  }
8421  }
8422 
8423  return 0;
8424 }
8425 
8427 {
8428  const int OPUS_SEEK_PREROLL_MS = 80;
8429  int ret;
8430  AVStream *st;
8431  size_t size;
8432  uint16_t pre_skip;
8433 
8434  if (c->fc->nb_streams < 1)
8435  return 0;
8436  st = c->fc->streams[c->fc->nb_streams-1];
8437 
8438  if ((uint64_t)atom.size > (1<<30) || atom.size < 11)
8439  return AVERROR_INVALIDDATA;
8440 
8441  /* Check OpusSpecificBox version. */
8442  if (avio_r8(pb) != 0) {
8443  av_log(c->fc, AV_LOG_ERROR, "unsupported OpusSpecificBox version\n");
8444  return AVERROR_INVALIDDATA;
8445  }
8446 
8447  /* OpusSpecificBox size plus magic for Ogg OpusHead header. */
8448  size = atom.size + 8;
8449 
8450  if ((ret = ff_alloc_extradata(st->codecpar, size)) < 0)
8451  return ret;
8452 
8453  AV_WL32A(st->codecpar->extradata, MKTAG('O','p','u','s'));
8454  AV_WL32A(st->codecpar->extradata + 4, MKTAG('H','e','a','d'));
8455  AV_WB8(st->codecpar->extradata + 8, 1); /* OpusHead version */
8456  avio_read(pb, st->codecpar->extradata + 9, size - 9);
8457 
8458  /* OpusSpecificBox is stored in big-endian, but OpusHead is
8459  little-endian; aside from the preceding magic and version they're
8460  otherwise currently identical. Data after output gain at offset 16
8461  doesn't need to be bytewapped. */
8462  pre_skip = AV_RB16A(st->codecpar->extradata + 10);
8463  AV_WL16A(st->codecpar->extradata + 10, pre_skip);
8464  AV_WL32A(st->codecpar->extradata + 12, AV_RB32A(st->codecpar->extradata + 12));
8465  AV_WL16A(st->codecpar->extradata + 16, AV_RB16A(st->codecpar->extradata + 16));
8466 
8467  st->codecpar->initial_padding = pre_skip;
8469  (AVRational){1, 1000},
8470  (AVRational){1, 48000});
8471 
8472  return 0;
8473 }
8474 
8476 {
8477  AVStream *st;
8478  unsigned format_info;
8479  int channel_assignment, channel_assignment1, channel_assignment2;
8480  int ratebits;
8481  uint64_t chmask;
8482 
8483  if (c->fc->nb_streams < 1)
8484  return 0;
8485  st = c->fc->streams[c->fc->nb_streams-1];
8486 
8487  if (atom.size < 10)
8488  return AVERROR_INVALIDDATA;
8489 
8490  format_info = avio_rb32(pb);
8491 
8492  ratebits = (format_info >> 28) & 0xF;
8493  channel_assignment1 = (format_info >> 15) & 0x1F;
8494  channel_assignment2 = format_info & 0x1FFF;
8495  if (channel_assignment2)
8496  channel_assignment = channel_assignment2;
8497  else
8498  channel_assignment = channel_assignment1;
8499 
8500  st->codecpar->frame_size = 40 << (ratebits & 0x7);
8501  st->codecpar->sample_rate = mlp_samplerate(ratebits);
8502 
8504  chmask = truehd_layout(channel_assignment);
8506 
8507  return 0;
8508 }
8509 
8511 {
8512  AVStream *st;
8513  uint8_t buf[ISOM_DVCC_DVVC_SIZE];
8514  int ret;
8515  int64_t read_size = atom.size;
8516 
8517  if (c->fc->nb_streams < 1)
8518  return 0;
8519  st = c->fc->streams[c->fc->nb_streams-1];
8520 
8521  // At most 24 bytes
8522  read_size = FFMIN(read_size, ISOM_DVCC_DVVC_SIZE);
8523 
8524  if ((ret = ffio_read_size(pb, buf, read_size)) < 0)
8525  return ret;
8526 
8527  return ff_isom_parse_dvcc_dvvc(c->fc, st, buf, read_size);
8528 }
8529 
8531 {
8532  AVStream *st;
8533  uint8_t *buf;
8534  int ret, old_size, num_arrays;
8535 
8536  if (c->fc->nb_streams < 1)
8537  return 0;
8538  st = c->fc->streams[c->fc->nb_streams-1];
8539 
8540  if (!st->codecpar->extradata_size)
8541  // TODO: handle lhvC when present before hvcC
8542  return 0;
8543 
8544  if (atom.size < 6 || st->codecpar->extradata_size < 23)
8545  return AVERROR_INVALIDDATA;
8546 
8548  if (!buf)
8549  return AVERROR(ENOMEM);
8550  memset(buf + atom.size, 0, AV_INPUT_BUFFER_PADDING_SIZE);
8551 
8552  ret = ffio_read_size(pb, buf, atom.size);
8553  if (ret < 0) {
8554  av_free(buf);
8555  av_log(c->fc, AV_LOG_WARNING, "lhvC atom truncated\n");
8556  return 0;
8557  }
8558 
8559  num_arrays = buf[5];
8560  old_size = st->codecpar->extradata_size;
8561  atom.size -= 8 /* account for mov_realloc_extradata offsetting */
8562  + 6 /* lhvC bytes before the arrays*/;
8563 
8564  ret = mov_realloc_extradata(st->codecpar, atom);
8565  if (ret < 0) {
8566  av_free(buf);
8567  return ret;
8568  }
8569 
8570  st->codecpar->extradata[22] += num_arrays;
8571  memcpy(st->codecpar->extradata + old_size, buf + 6, atom.size + 8);
8572 
8574 
8575  av_free(buf);
8576  return 0;
8577 }
8578 
8580 {
8581  AVFormatContext *ctx = c->fc;
8582  AVStream *st = NULL;
8583  AVBPrint scheme_buf, value_buf;
8584  int64_t scheme_str_len = 0, value_str_len = 0;
8585  int version, flags, ret = AVERROR_BUG;
8586  int64_t size = atom.size;
8587 
8588  if (atom.size < 6)
8589  // 4 bytes for version + flags, 2x 1 byte for null
8590  return AVERROR_INVALIDDATA;
8591 
8592  if (c->fc->nb_streams < 1)
8593  return 0;
8594  st = c->fc->streams[c->fc->nb_streams-1];
8595 
8596  version = avio_r8(pb);
8597  flags = avio_rb24(pb);
8598  size -= 4;
8599 
8600  if (version != 0 || flags != 0) {
8602  "Unsupported 'kind' box with version %d, flags: %x",
8603  version, flags);
8604  return AVERROR_INVALIDDATA;
8605  }
8606 
8607  av_bprint_init(&scheme_buf, 0, AV_BPRINT_SIZE_UNLIMITED);
8608  av_bprint_init(&value_buf, 0, AV_BPRINT_SIZE_UNLIMITED);
8609 
8610  if ((scheme_str_len = ff_read_string_to_bprint_overwrite(pb, &scheme_buf,
8611  size)) < 0) {
8612  ret = scheme_str_len;
8613  goto cleanup;
8614  }
8615 
8616  if (scheme_str_len + 1 >= size) {
8617  // we need to have another string, even if nullptr.
8618  // we check with + 1 since we expect that if size was not hit,
8619  // an additional null was read.
8621  goto cleanup;
8622  }
8623 
8624  size -= scheme_str_len + 1;
8625 
8626  if ((value_str_len = ff_read_string_to_bprint_overwrite(pb, &value_buf,
8627  size)) < 0) {
8628  ret = value_str_len;
8629  goto cleanup;
8630  }
8631 
8632  if (value_str_len == size) {
8633  // in case of no trailing null, box is not valid.
8635  goto cleanup;
8636  }
8637 
8639  "%s stream %d KindBox(scheme: %s, value: %s)\n",
8641  st->index,
8642  scheme_buf.str, value_buf.str);
8643 
8644  for (int i = 0; ff_mov_track_kind_table[i].scheme_uri; i++) {
8646  if (!av_strstart(scheme_buf.str, map.scheme_uri, NULL))
8647  continue;
8648 
8649  for (int j = 0; map.value_maps[j].disposition; j++) {
8650  const struct MP4TrackKindValueMapping value_map = map.value_maps[j];
8651  if (!av_strstart(value_buf.str, value_map.value, NULL))
8652  continue;
8653 
8654  st->disposition |= value_map.disposition;
8655  }
8656  }
8657 
8658  ret = 0;
8659 
8660 cleanup:
8661 
8662  av_bprint_finalize(&scheme_buf, NULL);
8663  av_bprint_finalize(&value_buf, NULL);
8664 
8665  return ret;
8666 }
8667 
8669 {
8670  AVStream *st;
8671  AVChannelLayout ch_layout = { 0 };
8672  int ret, i, version, type;
8673  int ambisonic_order, channel_order, normalization, channel_count;
8674  int ambi_channels, non_diegetic_channels;
8675 
8676  if (c->fc->nb_streams < 1)
8677  return 0;
8678 
8679  st = c->fc->streams[c->fc->nb_streams - 1];
8680 
8681  if (atom.size < 16) {
8682  av_log(c->fc, AV_LOG_ERROR, "SA3D audio box too small\n");
8683  return AVERROR_INVALIDDATA;
8684  }
8685 
8686  version = avio_r8(pb);
8687  if (version) {
8688  av_log(c->fc, AV_LOG_WARNING, "Unsupported SA3D box version %d\n", version);
8689  return 0;
8690  }
8691 
8692  type = avio_r8(pb);
8693  if (type & 0x7f) {
8694  av_log(c->fc, AV_LOG_WARNING,
8695  "Unsupported ambisonic type %d\n", type & 0x7f);
8696  return 0;
8697  }
8698  non_diegetic_channels = (type >> 7) * 2; // head_locked_stereo
8699 
8700  ambisonic_order = avio_rb32(pb);
8701 
8702  channel_order = avio_r8(pb);
8703  if (channel_order) {
8704  av_log(c->fc, AV_LOG_WARNING,
8705  "Unsupported channel_order %d\n", channel_order);
8706  return 0;
8707  }
8708 
8709  normalization = avio_r8(pb);
8710  if (normalization) {
8711  av_log(c->fc, AV_LOG_WARNING,
8712  "Unsupported normalization %d\n", normalization);
8713  return 0;
8714  }
8715 
8716  channel_count = avio_rb32(pb);
8717  if (ambisonic_order < 0 || ambisonic_order > 31 ||
8718  channel_count != ((ambisonic_order + 1LL) * (ambisonic_order + 1LL) +
8719  non_diegetic_channels)) {
8720  av_log(c->fc, AV_LOG_ERROR,
8721  "Invalid number of channels (%d / %d)\n",
8722  channel_count, ambisonic_order);
8723  return 0;
8724  }
8725  ambi_channels = channel_count - non_diegetic_channels;
8726 
8727  ret = av_channel_layout_custom_init(&ch_layout, channel_count);
8728  if (ret < 0)
8729  return 0;
8730 
8731  for (i = 0; i < channel_count; i++) {
8732  unsigned channel = avio_rb32(pb);
8733 
8734  if (channel >= channel_count) {
8735  av_log(c->fc, AV_LOG_ERROR, "Invalid channel index (%d / %d)\n",
8736  channel, ambisonic_order);
8737  av_channel_layout_uninit(&ch_layout);
8738  return 0;
8739  }
8740  if (channel >= ambi_channels)
8741  ch_layout.u.map[i].id = channel - ambi_channels;
8742  else
8743  ch_layout.u.map[i].id = AV_CHAN_AMBISONIC_BASE + channel;
8744  }
8745 
8747  if (ret < 0) {
8748  av_channel_layout_uninit(&ch_layout);
8749  return 0;
8750  }
8751 
8753  st->codecpar->ch_layout = ch_layout;
8754 
8755  return 0;
8756 }
8757 
8759 {
8760  AVStream *st;
8761  int version;
8762 
8763  if (c->fc->nb_streams < 1)
8764  return 0;
8765 
8766  st = c->fc->streams[c->fc->nb_streams - 1];
8767 
8768  if (atom.size < 5) {
8769  av_log(c->fc, AV_LOG_ERROR, "Empty SAND audio box\n");
8770  return AVERROR_INVALIDDATA;
8771  }
8772 
8773  version = avio_r8(pb);
8774  if (version) {
8775  av_log(c->fc, AV_LOG_WARNING, "Unsupported SAND box version %d\n", version);
8776  return 0;
8777  }
8778 
8780 
8781  return 0;
8782 }
8783 
8784 static int rb_size(AVIOContext *pb, int64_t *value, int size)
8785 {
8786  if (size == 0)
8787  *value = 0;
8788  else if (size == 1)
8789  *value = avio_r8(pb);
8790  else if (size == 2)
8791  *value = avio_rb16(pb);
8792  else if (size == 4)
8793  *value = avio_rb32(pb);
8794  else if (size == 8) {
8795  *value = avio_rb64(pb);
8796  if (*value < 0)
8797  return -1;
8798  } else
8799  return -1;
8800  return size;
8801 }
8802 
8804 {
8805  avio_rb32(pb); // version & flags.
8806  c->primary_item_id = avio_rb16(pb);
8807  av_log(c->fc, AV_LOG_TRACE, "pitm: primary_item_id %d\n", c->primary_item_id);
8808  return atom.size;
8809 }
8810 
8812 {
8813  c->idat_offset = avio_tell(pb);
8814  return 0;
8815 }
8816 
8818 {
8819  HEIFItem **heif_item;
8820  int version, offset_size, length_size, base_offset_size, index_size;
8821  int item_count, extent_count;
8822  int64_t base_offset, extent_offset, extent_length;
8823  uint8_t value;
8824 
8825  if (c->found_iloc) {
8826  av_log(c->fc, AV_LOG_INFO, "Duplicate iloc box found\n");
8827  return 0;
8828  }
8829 
8830  version = avio_r8(pb);
8831  avio_rb24(pb); // flags.
8832 
8833  value = avio_r8(pb);
8834  offset_size = (value >> 4) & 0xF;
8835  length_size = value & 0xF;
8836  value = avio_r8(pb);
8837  base_offset_size = (value >> 4) & 0xF;
8838  index_size = !version ? 0 : (value & 0xF);
8839  if (index_size) {
8840  avpriv_report_missing_feature(c->fc, "iloc: index_size != 0");
8841  return AVERROR_PATCHWELCOME;
8842  }
8843  item_count = (version < 2) ? avio_rb16(pb) : avio_rb32(pb);
8844 
8845  heif_item = av_realloc_array(c->heif_item, FFMAX(item_count, c->nb_heif_item), sizeof(*c->heif_item));
8846  if (!heif_item)
8847  return AVERROR(ENOMEM);
8848  c->heif_item = heif_item;
8849  if (item_count > c->nb_heif_item)
8850  memset(&c->heif_item[c->nb_heif_item], 0,
8851  sizeof(*c->heif_item) * (item_count - c->nb_heif_item));
8852  c->nb_heif_item = FFMAX(c->nb_heif_item, item_count);
8853 
8854  av_log(c->fc, AV_LOG_TRACE, "iloc: item_count %d\n", item_count);
8855  for (int i = 0; i < item_count; i++) {
8856  HEIFItem *item = NULL;
8857  int item_id = (version < 2) ? avio_rb16(pb) : avio_rb32(pb);
8858  int offset_type = (version > 0) ? avio_rb16(pb) & 0xf : 0;
8859 
8860  if (avio_feof(pb))
8861  return AVERROR_INVALIDDATA;
8862  if (offset_type > 1) {
8863  avpriv_report_missing_feature(c->fc, "iloc offset type %d", offset_type);
8864  return AVERROR_PATCHWELCOME;
8865  }
8866 
8867  avio_rb16(pb); // data_reference_index.
8868  if (rb_size(pb, &base_offset, base_offset_size) < 0)
8869  return AVERROR_INVALIDDATA;
8870  extent_count = avio_rb16(pb);
8871  if (extent_count > 1) {
8872  // For still AVIF images, we only support one extent item.
8873  avpriv_report_missing_feature(c->fc, "iloc: extent_count > 1");
8874  return AVERROR_PATCHWELCOME;
8875  }
8876 
8877  if (rb_size(pb, &extent_offset, offset_size) < 0 ||
8878  rb_size(pb, &extent_length, length_size) < 0 ||
8879  base_offset > INT64_MAX - extent_offset)
8880  return AVERROR_INVALIDDATA;
8881 
8882  for (int j = 0; j < c->nb_heif_item; j++) {
8883  item = c->heif_item[j];
8884  if (!item)
8885  item = c->heif_item[j] = av_mallocz(sizeof(*item));
8886  else if (item->item_id != item_id)
8887  continue;
8888  break;
8889  }
8890  if (!item)
8891  return AVERROR(ENOMEM);
8892 
8893  item->item_id = item_id;
8894 
8895  if (offset_type == 1)
8896  item->is_idat_relative = 1;
8897  item->extent_length = extent_length;
8898  item->extent_offset = base_offset + extent_offset;
8899  av_log(c->fc, AV_LOG_TRACE, "iloc: item_idx %d, item->item_id %d, offset_type %d, "
8900  "extent_offset %"PRId64", extent_length %"PRId64"\n",
8901  i, item->item_id, offset_type, item->extent_offset, item->extent_length);
8902  }
8903 
8904  c->found_iloc = 1;
8905  return atom.size;
8906 }
8907 
8909 {
8910  HEIFItem *item = NULL;
8911  AVBPrint item_name;
8912  int64_t size = atom.size;
8913  uint32_t item_type;
8914  int item_id;
8915  int version, ret;
8916 
8917  version = avio_r8(pb);
8918  avio_rb24(pb); // flags.
8919  size -= 4;
8920  if (size < 0)
8921  return AVERROR_INVALIDDATA;
8922 
8923  if (version < 2) {
8924  avpriv_report_missing_feature(c->fc, "infe version < 2");
8925  avio_skip(pb, size);
8926  return 1;
8927  }
8928 
8929  item_id = version > 2 ? avio_rb32(pb) : avio_rb16(pb);
8930  avio_rb16(pb); // item_protection_index
8931  item_type = avio_rl32(pb);
8932  size -= 8;
8933  if (size < 1)
8934  return AVERROR_INVALIDDATA;
8935 
8938  if (ret < 0) {
8940  return ret;
8941  }
8942 
8943  av_log(c->fc, AV_LOG_TRACE, "infe: item_id %d, item_type %s, item_name %s\n",
8944  item_id, av_fourcc2str(item_type), item_name.str);
8945 
8946  size -= ret + 1;
8947  if (size > 0)
8948  avio_skip(pb, size);
8949 
8950  for (int i = 0; i < c->nb_heif_item; i++) {
8951  item = c->heif_item[i];
8952  if (!item)
8953  item = c->heif_item[i] = av_mallocz(sizeof(*item));
8954  else if (item->item_id != item_id)
8955  continue;
8956  break;
8957  }
8958  if (!item) {
8960  return AVERROR(ENOMEM);
8961  }
8962 
8963  av_freep(&item->name);
8964  av_bprint_finalize(&item_name, ret ? &item->name : NULL);
8965  item->item_id = item_id;
8966  item->type = item_type;
8967 
8968  switch (item_type) {
8969  case MKTAG('a','v','0','1'):
8970  case MKTAG('j','p','e','g'):
8971  case MKTAG('h','v','c','1'):
8972  ret = heif_add_stream(c, item);
8973  if (ret < 0)
8974  return ret;
8975  break;
8976  }
8977 
8978  return 0;
8979 }
8980 
8982 {
8983  HEIFItem **heif_item;
8984  int entry_count;
8985  int version, got_stream = 0, ret, i;
8986 
8987  if (c->found_iinf) {
8988  av_log(c->fc, AV_LOG_WARNING, "Duplicate iinf box found\n");
8989  return 0;
8990  }
8991 
8992  version = avio_r8(pb);
8993  avio_rb24(pb); // flags.
8994  entry_count = version ? avio_rb32(pb) : avio_rb16(pb);
8995 
8996  heif_item = av_realloc_array(c->heif_item, FFMAX(entry_count, c->nb_heif_item), sizeof(*c->heif_item));
8997  if (!heif_item)
8998  return AVERROR(ENOMEM);
8999  c->heif_item = heif_item;
9000  if (entry_count > c->nb_heif_item)
9001  memset(&c->heif_item[c->nb_heif_item], 0,
9002  sizeof(*c->heif_item) * (entry_count - c->nb_heif_item));
9003  c->nb_heif_item = FFMAX(c->nb_heif_item, entry_count);
9004 
9005  for (i = 0; i < entry_count; i++) {
9006  MOVAtom infe;
9007 
9008  infe.size = avio_rb32(pb) - 8;
9009  infe.type = avio_rl32(pb);
9010  if (avio_feof(pb)) {
9012  goto fail;
9013  }
9014  ret = mov_read_infe(c, pb, infe);
9015  if (ret < 0)
9016  goto fail;
9017  if (!ret)
9018  got_stream = 1;
9019  }
9020 
9021  c->found_iinf = got_stream;
9022  return 0;
9023 fail:
9024  for (; i >= 0; i--) {
9025  HEIFItem *item = c->heif_item[i];
9026 
9027  if (!item)
9028  continue;
9029 
9030  av_freep(&item->name);
9031  }
9032  return ret;
9033 }
9034 
9036 {
9037  HEIFItem *item = NULL;
9038  HEIFGrid *grid;
9039  int entries, i;
9040  int from_item_id = version ? avio_rb32(pb) : avio_rb16(pb);
9041 
9042  for (int i = 0; i < c->nb_heif_grid; i++) {
9043  if (c->heif_grid[i].item->item_id == from_item_id) {
9044  av_log(c->fc, AV_LOG_ERROR, "More than one 'dimg' box "
9045  "referencing the same Derived Image item\n");
9046  return AVERROR_INVALIDDATA;
9047  }
9048  }
9049  for (int i = 0; i < c->nb_heif_item; i++) {
9050  if (!c->heif_item[i] || c->heif_item[i]->item_id != from_item_id)
9051  continue;
9052  item = c->heif_item[i];
9053 
9054  switch (item->type) {
9055  case MKTAG('g','r','i','d'):
9056  case MKTAG('i','o','v','l'):
9057  break;
9058  default:
9059  avpriv_report_missing_feature(c->fc, "Derived Image item of type %s",
9060  av_fourcc2str(item->type));
9061  return 0;
9062  }
9063  break;
9064  }
9065  if (!item) {
9066  av_log(c->fc, AV_LOG_ERROR, "Missing grid information\n");
9067  return AVERROR_INVALIDDATA;
9068  }
9069 
9070  grid = av_realloc_array(c->heif_grid, c->nb_heif_grid + 1U,
9071  sizeof(*c->heif_grid));
9072  if (!grid)
9073  return AVERROR(ENOMEM);
9074  c->heif_grid = grid;
9075  grid = &grid[c->nb_heif_grid++];
9076 
9077  entries = avio_rb16(pb);
9078  grid->tile_id_list = av_malloc_array(entries, sizeof(*grid->tile_id_list));
9079  grid->tile_idx_list = av_calloc(entries, sizeof(*grid->tile_idx_list));
9080  grid->tile_item_list = av_calloc(entries, sizeof(*grid->tile_item_list));
9081  if (!grid->tile_id_list || !grid->tile_item_list || !grid->tile_idx_list)
9082  return AVERROR(ENOMEM);
9083  /* 'to' item ids */
9084  for (i = 0; i < entries; i++)
9085  grid->tile_id_list[i] = version ? avio_rb32(pb) : avio_rb16(pb);
9086  grid->nb_tiles = entries;
9087  grid->item = item;
9088 
9089  av_log(c->fc, AV_LOG_TRACE, "dimg: from_item_id %d, entries %d\n",
9090  from_item_id, entries);
9091 
9092  return 0;
9093 }
9094 
9095 static int mov_read_iref_cdsc(MOVContext *c, AVIOContext *pb, uint32_t type, int version)
9096 {
9097  HEIFItem *from_item = NULL;
9098  int entries;
9099  int from_item_id = version ? avio_rb32(pb) : avio_rb16(pb);
9100  const HEIFItemRef ref = { type, from_item_id };
9101 
9102  from_item = get_heif_item(c, from_item_id);
9103  if (!from_item) {
9104  av_log(c->fc, AV_LOG_ERROR, "Missing stream referenced by thmb item\n");
9105  return AVERROR_INVALIDDATA;
9106  }
9107 
9108  entries = avio_rb16(pb);
9109  /* 'to' item ids */
9110  for (int i = 0; i < entries; i++) {
9111  HEIFItem *item = get_heif_item(c, version ? avio_rb32(pb) : avio_rb16(pb));
9112  if (!item) {
9113  av_log(c->fc, AV_LOG_WARNING, "Missing stream referenced by %s item\n",
9114  av_fourcc2str(type));
9115  continue;
9116  }
9117 
9118  if (!av_dynarray2_add((void **)&item->iref_list, &item->nb_iref_list,
9119  sizeof(*item->iref_list), (const uint8_t *)&ref))
9120  return AVERROR(ENOMEM);
9121  }
9122 
9123  av_log(c->fc, AV_LOG_TRACE, "%s: from_item_id %d, entries %d\n",
9124  av_fourcc2str(type), from_item_id, entries);
9125 
9126  return 0;
9127 }
9128 
9130 {
9131  int version = avio_r8(pb);
9132  avio_rb24(pb); // flags
9133  atom.size -= 4;
9134 
9135  if (version > 1) {
9136  av_log(c->fc, AV_LOG_WARNING, "Unknown iref box version %d\n", version);
9137  return 0;
9138  }
9139 
9140  while (atom.size) {
9141  uint32_t type, size = avio_rb32(pb);
9142  int64_t next = avio_tell(pb);
9143 
9144  if (size < 14 || next < 0 || next > INT64_MAX - size)
9145  return AVERROR_INVALIDDATA;
9146 
9147  next += size - 4;
9148  type = avio_rl32(pb);
9149  switch (type) {
9150  case MKTAG('d','i','m','g'):
9152  break;
9153  case MKTAG('c','d','s','c'):
9154  case MKTAG('t','h','m','b'):
9156  break;
9157  default:
9158  av_log(c->fc, AV_LOG_DEBUG, "Unknown iref type %s size %"PRIu32"\n",
9159  av_fourcc2str(type), size);
9160  }
9161 
9162  atom.size -= size;
9163  avio_seek(pb, next, SEEK_SET);
9164  }
9165  return 0;
9166 }
9167 
9169 {
9170  HEIFItem *item;
9171  uint32_t width, height;
9172 
9173  avio_r8(pb); /* version */
9174  avio_rb24(pb); /* flags */
9175  width = avio_rb32(pb);
9176  height = avio_rb32(pb);
9177 
9178  av_log(c->fc, AV_LOG_TRACE, "ispe: item_id %d, width %u, height %u\n",
9179  c->cur_item_id, width, height);
9180 
9181  item = get_heif_item(c, c->cur_item_id);
9182  if (item) {
9183  item->width = width;
9184  item->height = height;
9185  }
9186 
9187  return 0;
9188 }
9189 
9191 {
9192  HEIFItem *item;
9193  int angle;
9194 
9195  angle = avio_r8(pb) & 0x3;
9196 
9197  av_log(c->fc, AV_LOG_TRACE, "irot: item_id %d, angle %u\n",
9198  c->cur_item_id, angle);
9199 
9200  item = get_heif_item(c, c->cur_item_id);
9201  if (item) {
9202  // angle * 90 specifies the angle (in anti-clockwise direction)
9203  // in units of degrees.
9204  item->rotation = angle * 90;
9205  }
9206 
9207  return 0;
9208 }
9209 
9211 {
9212  HEIFItem *item;
9213  int axis;
9214 
9215  axis = avio_r8(pb) & 0x1;
9216 
9217  av_log(c->fc, AV_LOG_TRACE, "imir: item_id %d, axis %u\n",
9218  c->cur_item_id, axis);
9219 
9220  item = get_heif_item(c, c->cur_item_id);
9221  if (item) {
9222  item->hflip = axis;
9223  item->vflip = !axis;
9224  }
9225 
9226  return 0;
9227 }
9228 
9230 {
9231  typedef struct MOVAtoms {
9232  FFIOContext b;
9233  uint32_t type;
9234  int64_t size;
9235  uint8_t *data;
9236  } MOVAtoms;
9237  MOVAtoms *atoms = NULL;
9238  MOVAtom a;
9239  unsigned count;
9240  int nb_atoms = 0;
9241  int version, flags;
9242  int ret;
9243 
9244  a.size = avio_rb32(pb);
9245  a.type = avio_rl32(pb);
9246 
9247  if (a.size < 8 || a.type != MKTAG('i','p','c','o'))
9248  return AVERROR_INVALIDDATA;
9249 
9250  a.size -= 8;
9251  while (a.size >= 8) {
9252  MOVAtoms *ref = av_dynarray2_add((void**)&atoms, &nb_atoms, sizeof(MOVAtoms), NULL);
9253  if (!ref) {
9254  ret = AVERROR(ENOMEM);
9255  goto fail;
9256  }
9257  ref->data = NULL;
9258  ref->size = avio_rb32(pb);
9259  ref->type = avio_rl32(pb);
9260  if (ref->size > a.size || ref->size < 8)
9261  break;
9262  ref->data = av_malloc(ref->size);
9263  if (!ref->data) {
9265  goto fail;
9266  }
9267  av_log(c->fc, AV_LOG_TRACE, "ipco: index %d, box type %s\n", nb_atoms, av_fourcc2str(ref->type));
9268  avio_seek(pb, -8, SEEK_CUR);
9269  if (avio_read(pb, ref->data, ref->size) != ref->size) {
9271  goto fail;
9272  }
9273  ffio_init_read_context(&ref->b, ref->data, ref->size);
9274  a.size -= ref->size;
9275  }
9276 
9277  if (a.size) {
9279  goto fail;
9280  }
9281 
9282  a.size = avio_rb32(pb);
9283  a.type = avio_rl32(pb);
9284 
9285  if (a.size < 8 || a.type != MKTAG('i','p','m','a')) {
9287  goto fail;
9288  }
9289 
9290  version = avio_r8(pb);
9291  flags = avio_rb24(pb);
9292  count = avio_rb32(pb);
9293 
9294  for (int i = 0; i < count; i++) {
9295  int item_id = version ? avio_rb32(pb) : avio_rb16(pb);
9296  int assoc_count = avio_r8(pb);
9297 
9298  if (avio_feof(pb)) {
9300  goto fail;
9301  }
9302 
9303  for (int j = 0; j < assoc_count; j++) {
9304  MOVAtoms *ref;
9305  int index = avio_r8(pb) & 0x7f;
9306  if (flags & 1) {
9307  index <<= 8;
9308  index |= avio_r8(pb);
9309  }
9310  if (index > nb_atoms || index <= 0) {
9312  goto fail;
9313  }
9314  ref = &atoms[--index];
9315 
9316  av_log(c->fc, AV_LOG_TRACE, "ipma: property_index %d, item_id %d, item_type %s\n",
9317  index + 1, item_id, av_fourcc2str(ref->type));
9318 
9319  c->cur_item_id = item_id;
9320 
9321  ret = mov_read_default(c, &ref->b.pub,
9322  (MOVAtom) { .size = ref->size,
9323  .type = MKTAG('i','p','c','o') });
9324  if (ret < 0)
9325  goto fail;
9326  ffio_init_read_context(&ref->b, ref->data, ref->size);
9327  }
9328  }
9329 
9330  ret = 0;
9331 fail:
9332  c->cur_item_id = -1;
9333  for (int i = 0; i < nb_atoms; i++)
9334  av_free(atoms[i].data);
9335  av_free(atoms);
9336 
9337  return ret;
9338 }
9339 
9341 { MKTAG('A','C','L','R'), mov_read_aclr },
9342 { MKTAG('A','P','R','G'), mov_read_avid },
9343 { MKTAG('A','A','L','P'), mov_read_avid },
9344 { MKTAG('A','R','E','S'), mov_read_ares },
9345 { MKTAG('a','v','s','s'), mov_read_avss },
9346 { MKTAG('a','v','1','C'), mov_read_glbl },
9347 { MKTAG('c','h','p','l'), mov_read_chpl },
9348 { MKTAG('c','o','6','4'), mov_read_stco },
9349 { MKTAG('c','o','l','r'), mov_read_colr },
9350 { MKTAG('c','t','t','s'), mov_read_ctts }, /* composition time to sample */
9351 { MKTAG('d','i','n','f'), mov_read_default },
9352 { MKTAG('D','p','x','E'), mov_read_dpxe },
9353 { MKTAG('d','r','e','f'), mov_read_dref },
9354 { MKTAG('e','d','t','s'), mov_read_default },
9355 { MKTAG('e','l','s','t'), mov_read_elst },
9356 { MKTAG('e','n','d','a'), mov_read_enda },
9357 { MKTAG('f','i','e','l'), mov_read_fiel },
9358 { MKTAG('a','d','r','m'), mov_read_adrm },
9359 { MKTAG('f','t','y','p'), mov_read_ftyp },
9360 { MKTAG('g','l','b','l'), mov_read_glbl },
9361 { MKTAG('h','d','l','r'), mov_read_hdlr },
9362 { MKTAG('i','l','s','t'), mov_read_ilst },
9363 { MKTAG('j','p','2','h'), mov_read_jp2h },
9364 { MKTAG('m','d','a','t'), mov_read_mdat },
9365 { MKTAG('m','d','h','d'), mov_read_mdhd },
9366 { MKTAG('m','d','i','a'), mov_read_default },
9367 { MKTAG('m','e','t','a'), mov_read_meta },
9368 { MKTAG('m','i','n','f'), mov_read_default },
9369 { MKTAG('m','o','o','f'), mov_read_moof },
9370 { MKTAG('m','o','o','v'), mov_read_moov },
9371 { MKTAG('m','v','e','x'), mov_read_default },
9372 { MKTAG('m','v','h','d'), mov_read_mvhd },
9373 { MKTAG('S','M','I',' '), mov_read_svq3 },
9374 { MKTAG('a','l','a','c'), mov_read_alac }, /* alac specific atom */
9375 { MKTAG('a','v','c','C'), mov_read_glbl },
9376 { MKTAG('p','a','s','p'), mov_read_pasp },
9377 { MKTAG('c','l','a','p'), mov_read_clap },
9378 { MKTAG('s','b','a','s'), mov_read_sbas },
9379 { MKTAG('s','i','d','x'), mov_read_sidx },
9380 { MKTAG('s','t','b','l'), mov_read_default },
9381 { MKTAG('s','t','c','o'), mov_read_stco },
9382 { MKTAG('s','t','p','s'), mov_read_stps },
9383 { MKTAG('s','t','r','f'), mov_read_strf },
9384 { MKTAG('s','t','s','c'), mov_read_stsc },
9385 { MKTAG('s','t','s','d'), mov_read_stsd }, /* sample description */
9386 { MKTAG('s','t','s','s'), mov_read_stss }, /* sync sample */
9387 { MKTAG('s','t','s','z'), mov_read_stsz }, /* sample size */
9388 { MKTAG('s','t','t','s'), mov_read_stts },
9389 { MKTAG('s','t','z','2'), mov_read_stsz }, /* compact sample size */
9390 { MKTAG('s','d','t','p'), mov_read_sdtp }, /* independent and disposable samples */
9391 { MKTAG('t','k','h','d'), mov_read_tkhd }, /* track header */
9392 { MKTAG('t','f','d','t'), mov_read_tfdt },
9393 { MKTAG('t','f','h','d'), mov_read_tfhd }, /* track fragment header */
9394 { MKTAG('t','r','a','k'), mov_read_trak },
9395 { MKTAG('t','r','a','f'), mov_read_default },
9396 { MKTAG('t','r','e','f'), mov_read_default },
9397 { MKTAG('t','m','c','d'), mov_read_tmcd },
9398 { MKTAG('c','h','a','p'), mov_read_chap },
9399 { MKTAG('t','r','e','x'), mov_read_trex },
9400 { MKTAG('t','r','u','n'), mov_read_trun },
9401 { MKTAG('u','d','t','a'), mov_read_default },
9402 { MKTAG('w','a','v','e'), mov_read_wave },
9403 { MKTAG('e','s','d','s'), mov_read_esds },
9404 { MKTAG('d','a','c','3'), mov_read_dac3 }, /* AC-3 info */
9405 { MKTAG('d','e','c','3'), mov_read_dec3 }, /* EAC-3 info */
9406 { MKTAG('d','d','t','s'), mov_read_ddts }, /* DTS audio descriptor */
9407 { MKTAG('w','i','d','e'), mov_read_wide }, /* place holder */
9408 { MKTAG('w','f','e','x'), mov_read_wfex },
9409 { MKTAG('c','m','o','v'), mov_read_cmov },
9410 { MKTAG('c','h','a','n'), mov_read_chan }, /* channel layout from quicktime */
9411 { MKTAG('c','h','n','l'), mov_read_chnl }, /* channel layout from ISO-14496-12 */
9412 { MKTAG('d','v','c','1'), mov_read_dvc1 },
9413 { MKTAG('s','g','p','d'), mov_read_sgpd },
9414 { MKTAG('s','b','g','p'), mov_read_sbgp },
9415 { MKTAG('h','v','c','C'), mov_read_glbl },
9416 { MKTAG('v','v','c','C'), mov_read_glbl },
9417 { MKTAG('u','u','i','d'), mov_read_uuid },
9418 { MKTAG('C','i','n', 0x8e), mov_read_targa_y216 },
9419 { MKTAG('f','r','e','e'), mov_read_free },
9420 { MKTAG('-','-','-','-'), mov_read_custom },
9421 { MKTAG('s','i','n','f'), mov_read_default },
9422 { MKTAG('f','r','m','a'), mov_read_frma },
9423 { MKTAG('s','e','n','c'), mov_read_senc },
9424 { MKTAG('s','a','i','z'), mov_read_saiz },
9425 { MKTAG('s','a','i','o'), mov_read_saio },
9426 { MKTAG('p','s','s','h'), mov_read_pssh },
9427 { MKTAG('s','c','h','m'), mov_read_schm },
9428 { MKTAG('s','c','h','i'), mov_read_default },
9429 { MKTAG('t','e','n','c'), mov_read_tenc },
9430 { MKTAG('d','f','L','a'), mov_read_dfla },
9431 { MKTAG('s','t','3','d'), mov_read_st3d }, /* stereoscopic 3D video box */
9432 { MKTAG('s','v','3','d'), mov_read_sv3d }, /* spherical video box */
9433 { MKTAG('v','e','x','u'), mov_read_vexu }, /* video extension usage */
9434 { MKTAG('h','f','o','v'), mov_read_hfov },
9435 { MKTAG('d','O','p','s'), mov_read_dops },
9436 { MKTAG('d','m','l','p'), mov_read_dmlp },
9437 { MKTAG('S','m','D','m'), mov_read_smdm },
9438 { MKTAG('C','o','L','L'), mov_read_coll },
9439 { MKTAG('v','p','c','C'), mov_read_vpcc },
9440 { MKTAG('m','d','c','v'), mov_read_mdcv },
9441 { MKTAG('c','l','l','i'), mov_read_clli },
9442 { MKTAG('d','v','c','C'), mov_read_dvcc_dvvc },
9443 { MKTAG('d','v','v','C'), mov_read_dvcc_dvvc },
9444 { MKTAG('d','v','w','C'), mov_read_dvcc_dvvc },
9445 { MKTAG('k','i','n','d'), mov_read_kind },
9446 { MKTAG('S','A','3','D'), mov_read_SA3D }, /* ambisonic audio box */
9447 { MKTAG('S','A','N','D'), mov_read_SAND }, /* non diegetic audio box */
9448 { MKTAG('i','l','o','c'), mov_read_iloc },
9449 { MKTAG('p','c','m','C'), mov_read_pcmc }, /* PCM configuration box */
9450 { MKTAG('p','i','t','m'), mov_read_pitm },
9451 { MKTAG('e','v','c','C'), mov_read_glbl },
9452 { MKTAG('i','d','a','t'), mov_read_idat },
9453 { MKTAG('i','m','i','r'), mov_read_imir },
9454 { MKTAG('i','r','e','f'), mov_read_iref },
9455 { MKTAG('i','s','p','e'), mov_read_ispe },
9456 { MKTAG('i','r','o','t'), mov_read_irot },
9457 { MKTAG('i','p','r','p'), mov_read_iprp },
9458 { MKTAG('i','i','n','f'), mov_read_iinf },
9459 { MKTAG('a','m','v','e'), mov_read_amve }, /* ambient viewing environment box */
9460 { MKTAG('l','h','v','C'), mov_read_lhvc },
9461 { MKTAG('l','v','c','C'), mov_read_glbl },
9462 { MKTAG('a','p','v','C'), mov_read_glbl },
9463 #if CONFIG_IAMFDEC
9464 { MKTAG('i','a','c','b'), mov_read_iacb },
9465 #endif
9466 { 0, NULL }
9467 };
9468 
9470 {
9471  int64_t total_size = 0;
9472  MOVAtom a;
9473  int i;
9474 
9475  if (c->atom_depth > 10) {
9476  av_log(c->fc, AV_LOG_ERROR, "Atoms too deeply nested\n");
9477  return AVERROR_INVALIDDATA;
9478  }
9479  c->atom_depth ++;
9480 
9481  if (atom.size < 0)
9482  atom.size = INT64_MAX;
9483  while (total_size <= atom.size - 8) {
9484  int (*parse)(MOVContext*, AVIOContext*, MOVAtom) = NULL;
9485  a.size = avio_rb32(pb);
9486  a.type = avio_rl32(pb);
9487  if (avio_feof(pb))
9488  break;
9489  if (((a.type == MKTAG('f','r','e','e') && c->moov_retry) ||
9490  a.type == MKTAG('h','o','o','v')) &&
9491  a.size >= 8 &&
9492  c->fc->strict_std_compliance < FF_COMPLIANCE_STRICT) {
9493  uint32_t type;
9494  avio_skip(pb, 4);
9495  type = avio_rl32(pb);
9496  if (avio_feof(pb))
9497  break;
9498  avio_seek(pb, -8, SEEK_CUR);
9499  if (type == MKTAG('m','v','h','d') ||
9500  type == MKTAG('c','m','o','v')) {
9501  av_log(c->fc, AV_LOG_ERROR, "Detected moov in a free or hoov atom.\n");
9502  a.type = MKTAG('m','o','o','v');
9503  }
9504  }
9505  if (atom.type != MKTAG('r','o','o','t') &&
9506  atom.type != MKTAG('m','o','o','v')) {
9507  if (a.type == MKTAG('t','r','a','k') ||
9508  a.type == MKTAG('m','d','a','t')) {
9509  av_log(c->fc, AV_LOG_ERROR, "Broken file, trak/mdat not at top-level\n");
9510  avio_skip(pb, -8);
9511  c->atom_depth --;
9512  return 0;
9513  }
9514  }
9515  total_size += 8;
9516  if (a.size == 1 && total_size + 8 <= atom.size) { /* 64 bit extended size */
9517  a.size = avio_rb64(pb) - 8;
9518  total_size += 8;
9519  }
9520  av_log(c->fc, AV_LOG_TRACE, "type:'%s' parent:'%s' sz: %"PRId64" %"PRId64" %"PRId64"\n",
9521  av_fourcc2str(a.type), av_fourcc2str(atom.type), a.size, total_size, atom.size);
9522  if (a.size == 0) {
9523  a.size = atom.size - total_size + 8;
9524  }
9525  if (a.size < 0)
9526  break;
9527  a.size -= 8;
9528  if (a.size < 0)
9529  break;
9530  a.size = FFMIN(a.size, atom.size - total_size);
9531 
9532  for (i = 0; mov_default_parse_table[i].type; i++)
9533  if (mov_default_parse_table[i].type == a.type) {
9535  break;
9536  }
9537 
9538  // container is user data
9539  if (!parse && (atom.type == MKTAG('u','d','t','a') ||
9540  atom.type == MKTAG('i','l','s','t')))
9542 
9543  // Supports parsing the QuickTime Metadata Keys.
9544  // https://developer.apple.com/library/mac/documentation/QuickTime/QTFF/Metadata/Metadata.html
9545  if (!parse && c->found_hdlr_mdta &&
9546  atom.type == MKTAG('m','e','t','a') &&
9547  a.type == MKTAG('k','e','y','s') &&
9548  c->meta_keys_count == 0) {
9549  parse = mov_read_keys;
9550  }
9551 
9552  if (!parse) { /* skip leaf atoms data */
9553  avio_skip(pb, a.size);
9554  } else {
9555  int64_t start_pos = avio_tell(pb);
9556  int64_t left;
9557  int err = parse(c, pb, a);
9558  if (err < 0) {
9559  c->atom_depth --;
9560  return err;
9561  }
9562  if (c->found_moov && c->found_mdat && a.size <= INT64_MAX - start_pos &&
9563  ((!(pb->seekable & AVIO_SEEKABLE_NORMAL) || c->fc->flags & AVFMT_FLAG_IGNIDX || c->frag_index.complete) ||
9564  start_pos + a.size == avio_size(pb))) {
9565  if (!(pb->seekable & AVIO_SEEKABLE_NORMAL) || c->fc->flags & AVFMT_FLAG_IGNIDX || c->frag_index.complete)
9566  c->next_root_atom = start_pos + a.size;
9567  c->atom_depth --;
9568  return 0;
9569  }
9570  left = a.size - avio_tell(pb) + start_pos;
9571  if (left > 0) /* skip garbage at atom end */
9572  avio_skip(pb, left);
9573  else if (left < 0) {
9574  av_log(c->fc, AV_LOG_WARNING,
9575  "overread end of atom '%s' by %"PRId64" bytes\n",
9576  av_fourcc2str(a.type), -left);
9577  avio_seek(pb, left, SEEK_CUR);
9578  }
9579  }
9580 
9581  total_size += a.size;
9582  }
9583 
9584  if (total_size < atom.size && atom.size < 0x7ffff)
9585  avio_skip(pb, atom.size - total_size);
9586 
9587  c->atom_depth --;
9588  return 0;
9589 }
9590 
9591 static int mov_probe(const AVProbeData *p)
9592 {
9593  int64_t offset;
9594  uint32_t tag;
9595  int score = 0;
9596  int moov_offset = -1;
9597 
9598  /* check file header */
9599  offset = 0;
9600  for (;;) {
9601  int64_t size;
9602  int minsize = 8;
9603  /* ignore invalid offset */
9604  if ((offset + 8ULL) > (unsigned int)p->buf_size)
9605  break;
9606  size = AV_RB32(p->buf + offset);
9607  if (size == 1 && offset + 16 <= (unsigned int)p->buf_size) {
9608  size = AV_RB64(p->buf+offset + 8);
9609  minsize = 16;
9610  } else if (size == 0) {
9611  size = p->buf_size - offset;
9612  }
9613  if (size < minsize) {
9614  offset += 4;
9615  continue;
9616  }
9617  tag = AV_RL32(p->buf + offset + 4);
9618  switch(tag) {
9619  /* check for obvious tags */
9620  case MKTAG('m','o','o','v'):
9621  moov_offset = offset + 4;
9622  case MKTAG('m','d','a','t'):
9623  case MKTAG('p','n','o','t'): /* detect movs with preview pics like ew.mov and april.mov */
9624  case MKTAG('u','d','t','a'): /* Packet Video PVAuthor adds this and a lot of more junk */
9625  case MKTAG('f','t','y','p'):
9626  if (tag == MKTAG('f','t','y','p') &&
9627  ( AV_RL32(p->buf + offset + 8) == MKTAG('j','p','2',' ')
9628  || AV_RL32(p->buf + offset + 8) == MKTAG('j','p','x',' ')
9629  || AV_RL32(p->buf + offset + 8) == MKTAG('j','x','l',' ')
9630  )) {
9631  score = FFMAX(score, 5);
9632  } else {
9633  score = AVPROBE_SCORE_MAX;
9634  }
9635  break;
9636  /* those are more common words, so rate then a bit less */
9637  case MKTAG('e','d','i','w'): /* xdcam files have reverted first tags */
9638  case MKTAG('w','i','d','e'):
9639  case MKTAG('f','r','e','e'):
9640  case MKTAG('j','u','n','k'):
9641  case MKTAG('p','i','c','t'):
9642  score = FFMAX(score, AVPROBE_SCORE_MAX - 5);
9643  break;
9644  case MKTAG(0x82,0x82,0x7f,0x7d):
9645  score = FFMAX(score, AVPROBE_SCORE_EXTENSION - 5);
9646  break;
9647  case MKTAG('s','k','i','p'):
9648  case MKTAG('u','u','i','d'):
9649  case MKTAG('p','r','f','l'):
9650  /* if we only find those cause probedata is too small at least rate them */
9651  score = FFMAX(score, AVPROBE_SCORE_EXTENSION);
9652  break;
9653  }
9654  if (size > INT64_MAX - offset)
9655  break;
9656  offset += size;
9657  }
9658  if (score > AVPROBE_SCORE_MAX - 50 && moov_offset != -1) {
9659  /* moov atom in the header - we should make sure that this is not a
9660  * MOV-packed MPEG-PS */
9661  offset = moov_offset;
9662 
9663  while (offset < (p->buf_size - 16)) { /* Sufficient space */
9664  /* We found an actual hdlr atom */
9665  if (AV_RL32(p->buf + offset ) == MKTAG('h','d','l','r') &&
9666  AV_RL32(p->buf + offset + 8) == MKTAG('m','h','l','r') &&
9667  AV_RL32(p->buf + offset + 12) == MKTAG('M','P','E','G')) {
9668  av_log(NULL, AV_LOG_WARNING, "Found media data tag MPEG indicating this is a MOV-packed MPEG-PS.\n");
9669  /* We found a media handler reference atom describing an
9670  * MPEG-PS-in-MOV, return a
9671  * low score to force expanding the probe window until
9672  * mpegps_probe finds what it needs */
9673  return 5;
9674  } else {
9675  /* Keep looking */
9676  offset += 2;
9677  }
9678  }
9679  }
9680 
9681  return score;
9682 }
9683 
9684 // must be done after parsing all trak because there's no order requirement
9686 {
9687  MOVContext *mov = s->priv_data;
9688  MOVStreamContext *sc;
9689  int64_t cur_pos;
9690  int i, j;
9691  int chapter_track;
9692 
9693  for (j = 0; j < mov->nb_chapter_tracks; j++) {
9694  AVStream *st = NULL;
9695  FFStream *sti = NULL;
9696  chapter_track = mov->chapter_tracks[j];
9697  for (i = 0; i < s->nb_streams; i++) {
9698  sc = mov->fc->streams[i]->priv_data;
9699  if (sc->id == chapter_track) {
9700  st = s->streams[i];
9701  break;
9702  }
9703  }
9704  if (!st) {
9705  av_log(s, AV_LOG_ERROR, "Referenced QT chapter track not found\n");
9706  continue;
9707  }
9708  sti = ffstream(st);
9709 
9710  sc = st->priv_data;
9711  cur_pos = avio_tell(sc->pb);
9712 
9713  if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
9715  if (!st->attached_pic.data && sti->nb_index_entries) {
9716  // Retrieve the first frame, if possible
9717  AVIndexEntry *sample = &sti->index_entries[0];
9718  if (avio_seek(sc->pb, sample->pos, SEEK_SET) != sample->pos) {
9719  av_log(s, AV_LOG_ERROR, "Failed to retrieve first frame\n");
9720  goto finish;
9721  }
9722 
9723  if (ff_add_attached_pic(s, st, sc->pb, NULL, sample->size) < 0)
9724  goto finish;
9725  }
9726  } else {
9729  st->discard = AVDISCARD_ALL;
9730  for (int i = 0; i < sti->nb_index_entries; i++) {
9731  AVIndexEntry *sample = &sti->index_entries[i];
9732  int64_t end = i+1 < sti->nb_index_entries ? sti->index_entries[i+1].timestamp : st->duration;
9733  uint8_t *title;
9734  uint16_t ch;
9735  int len, title_len;
9736 
9737  if (end < sample->timestamp) {
9738  av_log(s, AV_LOG_WARNING, "ignoring stream duration which is shorter than chapters\n");
9739  end = AV_NOPTS_VALUE;
9740  }
9741 
9742  if (avio_seek(sc->pb, sample->pos, SEEK_SET) != sample->pos) {
9743  av_log(s, AV_LOG_ERROR, "Chapter %d not found in file\n", i);
9744  goto finish;
9745  }
9746 
9747  // the first two bytes are the length of the title
9748  len = avio_rb16(sc->pb);
9749  if (len > sample->size-2)
9750  continue;
9751  title_len = 2*len + 1;
9752  if (!(title = av_mallocz(title_len)))
9753  goto finish;
9754 
9755  // The samples could theoretically be in any encoding if there's an encd
9756  // atom following, but in practice are only utf-8 or utf-16, distinguished
9757  // instead by the presence of a BOM
9758  if (!len) {
9759  title[0] = 0;
9760  } else {
9761  ch = avio_rb16(sc->pb);
9762  if (ch == 0xfeff)
9763  avio_get_str16be(sc->pb, len, title, title_len);
9764  else if (ch == 0xfffe)
9765  avio_get_str16le(sc->pb, len, title, title_len);
9766  else {
9767  AV_WB16(title, ch);
9768  if (len == 1 || len == 2)
9769  title[len] = 0;
9770  else
9771  avio_get_str(sc->pb, INT_MAX, title + 2, len - 1);
9772  }
9773  }
9774 
9775  avpriv_new_chapter(s, i, st->time_base, sample->timestamp, end, title);
9776  av_freep(&title);
9777  }
9778  }
9779 finish:
9780  avio_seek(sc->pb, cur_pos, SEEK_SET);
9781  }
9782 }
9783 
9785  int64_t value, int flags)
9786 {
9787  AVTimecode tc;
9788  char buf[AV_TIMECODE_STR_SIZE];
9789  AVRational rate = st->avg_frame_rate;
9790  int ret = av_timecode_init(&tc, rate, flags, 0, s);
9791  if (ret < 0)
9792  return ret;
9793  av_dict_set(&st->metadata, "timecode",
9794  av_timecode_make_string(&tc, buf, value), 0);
9795  return 0;
9796 }
9797 
9799 {
9800  MOVStreamContext *sc = st->priv_data;
9801  FFStream *const sti = ffstream(st);
9802  char buf[AV_TIMECODE_STR_SIZE];
9803  int64_t cur_pos = avio_tell(sc->pb);
9804  int hh, mm, ss, ff, drop;
9805 
9806  if (!sti->nb_index_entries)
9807  return -1;
9808 
9809  avio_seek(sc->pb, sti->index_entries->pos, SEEK_SET);
9810  avio_skip(s->pb, 13);
9811  hh = avio_r8(s->pb);
9812  mm = avio_r8(s->pb);
9813  ss = avio_r8(s->pb);
9814  drop = avio_r8(s->pb);
9815  ff = avio_r8(s->pb);
9816  snprintf(buf, AV_TIMECODE_STR_SIZE, "%02d:%02d:%02d%c%02d",
9817  hh, mm, ss, drop ? ';' : ':', ff);
9818  av_dict_set(&st->metadata, "timecode", buf, 0);
9819 
9820  avio_seek(sc->pb, cur_pos, SEEK_SET);
9821  return 0;
9822 }
9823 
9825 {
9826  MOVStreamContext *sc = st->priv_data;
9827  FFStream *const sti = ffstream(st);
9828  int flags = 0;
9829  int64_t cur_pos = avio_tell(sc->pb);
9830  int64_t value;
9831  AVRational tc_rate = st->avg_frame_rate;
9832  int tmcd_nb_frames = sc->tmcd_nb_frames;
9833  int rounded_tc_rate;
9834 
9835  if (!sti->nb_index_entries)
9836  return -1;
9837 
9838  if (!tc_rate.num || !tc_rate.den || !tmcd_nb_frames)
9839  return -1;
9840 
9841  avio_seek(sc->pb, sti->index_entries->pos, SEEK_SET);
9842  value = avio_rb32(s->pb);
9843 
9844  if (sc->tmcd_flags & 0x0001) flags |= AV_TIMECODE_FLAG_DROPFRAME;
9845  if (sc->tmcd_flags & 0x0002) flags |= AV_TIMECODE_FLAG_24HOURSMAX;
9846  if (sc->tmcd_flags & 0x0004) flags |= AV_TIMECODE_FLAG_ALLOWNEGATIVE;
9847 
9848  /* Assume Counter flag is set to 1 in tmcd track (even though it is likely
9849  * not the case) and thus assume "frame number format" instead of QT one.
9850  * No sample with tmcd track can be found with a QT timecode at the moment,
9851  * despite what the tmcd track "suggests" (Counter flag set to 0 means QT
9852  * format). */
9853 
9854  /* 60 fps content have tmcd_nb_frames set to 30 but tc_rate set to 60, so
9855  * we multiply the frame number with the quotient.
9856  * See tickets #9492, #9710. */
9857  rounded_tc_rate = (tc_rate.num + tc_rate.den / 2LL) / tc_rate.den;
9858  /* Work around files where tmcd_nb_frames is rounded down from frame rate
9859  * instead of up. See ticket #5978. */
9860  if (tmcd_nb_frames == tc_rate.num / tc_rate.den &&
9861  s->strict_std_compliance < FF_COMPLIANCE_STRICT)
9862  tmcd_nb_frames = rounded_tc_rate;
9863  value = av_rescale(value, rounded_tc_rate, tmcd_nb_frames);
9864 
9866 
9867  avio_seek(sc->pb, cur_pos, SEEK_SET);
9868  return 0;
9869 }
9870 
9872  int i;
9873  if (!index || !*index) return;
9874  for (i = 0; i < (*index)->nb_encrypted_samples; i++) {
9875  av_encryption_info_free((*index)->encrypted_samples[i]);
9876  }
9877  av_freep(&(*index)->encrypted_samples);
9878  av_freep(&(*index)->auxiliary_info_sizes);
9879  av_freep(&(*index)->auxiliary_offsets);
9880  av_freep(index);
9881 }
9882 
9884 {
9885  MOVStreamContext *sc = st->priv_data;
9886 
9887  if (!sc || --sc->refcount) {
9888  st->priv_data = NULL;
9889  return;
9890  }
9891 
9892  av_freep(&sc->tts_data);
9893  for (int i = 0; i < sc->drefs_count; i++) {
9894  av_freep(&sc->drefs[i].path);
9895  av_freep(&sc->drefs[i].dir);
9896  }
9897  av_freep(&sc->drefs);
9898 
9899  sc->drefs_count = 0;
9900 
9901  if (!sc->pb_is_copied)
9902  ff_format_io_close(s, &sc->pb);
9903 
9904  sc->pb = NULL;
9905  av_freep(&sc->chunk_offsets);
9906  av_freep(&sc->stsc_data);
9907  av_freep(&sc->sample_sizes);
9908  av_freep(&sc->keyframes);
9909  av_freep(&sc->ctts_data);
9910  av_freep(&sc->stts_data);
9911  av_freep(&sc->sdtp_data);
9912  av_freep(&sc->stps_data);
9913  av_freep(&sc->elst_data);
9914  av_freep(&sc->rap_group);
9915  av_freep(&sc->sync_group);
9916  av_freep(&sc->sgpd_sync);
9917  av_freep(&sc->sample_offsets);
9918  av_freep(&sc->open_key_samples);
9919  av_freep(&sc->display_matrix);
9920  av_freep(&sc->index_ranges);
9921 
9922  if (sc->extradata)
9923  for (int i = 0; i < sc->stsd_count; i++)
9924  av_free(sc->extradata[i]);
9925  av_freep(&sc->extradata);
9926  av_freep(&sc->extradata_size);
9927 
9931 
9932  av_freep(&sc->stereo3d);
9933  av_freep(&sc->spherical);
9934  av_freep(&sc->mastering);
9935  av_freep(&sc->coll);
9936  av_freep(&sc->ambient);
9937 
9938 #if CONFIG_IAMFDEC
9939  if (sc->iamf)
9941 #endif
9942  av_freep(&sc->iamf);
9943 }
9944 
9946 {
9947  MOVContext *mov = s->priv_data;
9948  int i, j;
9949 
9950  for (i = 0; i < s->nb_streams; i++) {
9951  AVStream *st = s->streams[i];
9952 
9954  }
9955 
9956  av_freep(&mov->dv_demux);
9958  mov->dv_fctx = NULL;
9959 
9960  if (mov->meta_keys) {
9961  for (i = 1; i < mov->meta_keys_count; i++) {
9962  av_freep(&mov->meta_keys[i]);
9963  }
9964  av_freep(&mov->meta_keys);
9965  }
9966 
9967  av_freep(&mov->trex_data);
9968  av_freep(&mov->bitrates);
9969 
9970  for (i = 0; i < mov->frag_index.nb_items; i++) {
9972  for (j = 0; j < mov->frag_index.item[i].nb_stream_info; j++) {
9973  mov_free_encryption_index(&frag[j].encryption_index);
9974  }
9976  }
9977  av_freep(&mov->frag_index.item);
9978 
9979  av_freep(&mov->aes_decrypt);
9980  av_freep(&mov->chapter_tracks);
9981  for (i = 0; i < mov->nb_heif_item; i++) {
9982  if (!mov->heif_item[i])
9983  continue;
9984  av_freep(&mov->heif_item[i]->name);
9985  av_freep(&mov->heif_item[i]->iref_list);
9986  av_freep(&mov->heif_item[i]->icc_profile);
9987  av_freep(&mov->heif_item[i]);
9988  }
9989  av_freep(&mov->heif_item);
9990  for (i = 0; i < mov->nb_heif_grid; i++) {
9991  av_freep(&mov->heif_grid[i].tile_id_list);
9994  }
9995  av_freep(&mov->heif_grid);
9996 
9997  return 0;
9998 }
9999 
10000 static int tmcd_is_referenced(AVFormatContext *s, int tmcd_id)
10001 {
10002  int i;
10003 
10004  for (i = 0; i < s->nb_streams; i++) {
10005  AVStream *st = s->streams[i];
10006  MOVStreamContext *sc = st->priv_data;
10007 
10008  if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO &&
10009  sc->timecode_track == tmcd_id)
10010  return 1;
10011  }
10012  return 0;
10013 }
10014 
10015 /* look for a tmcd track not referenced by any video track, and export it globally */
10017 {
10018  int i;
10019 
10020  for (i = 0; i < s->nb_streams; i++) {
10021  AVStream *st = s->streams[i];
10022 
10023  if (st->codecpar->codec_tag == MKTAG('t','m','c','d') &&
10024  !tmcd_is_referenced(s, i + 1)) {
10025  AVDictionaryEntry *tcr = av_dict_get(st->metadata, "timecode", NULL, 0);
10026  if (tcr) {
10027  av_dict_set(&s->metadata, "timecode", tcr->value, 0);
10028  break;
10029  }
10030  }
10031  }
10032 }
10033 
10034 static int read_tfra(MOVContext *mov, AVIOContext *f)
10035 {
10036  int version, fieldlength, i, j;
10037  int64_t pos = avio_tell(f);
10038  uint32_t size = avio_rb32(f);
10039  unsigned track_id, item_count;
10040 
10041  if (avio_rb32(f) != MKBETAG('t', 'f', 'r', 'a')) {
10042  return 1;
10043  }
10044  av_log(mov->fc, AV_LOG_VERBOSE, "found tfra\n");
10045 
10046  version = avio_r8(f);
10047  avio_rb24(f);
10048  track_id = avio_rb32(f);
10049  fieldlength = avio_rb32(f);
10050  item_count = avio_rb32(f);
10051  for (i = 0; i < item_count; i++) {
10052  int64_t time, offset;
10053  int index;
10054  MOVFragmentStreamInfo * frag_stream_info;
10055 
10056  if (avio_feof(f)) {
10057  return AVERROR_INVALIDDATA;
10058  }
10059 
10060  if (version == 1) {
10061  time = avio_rb64(f);
10062  offset = avio_rb64(f);
10063  } else {
10064  time = avio_rb32(f);
10065  offset = avio_rb32(f);
10066  }
10067 
10068  // The first sample of each stream in a fragment is always a random
10069  // access sample. So it's entry in the tfra can be used as the
10070  // initial PTS of the fragment.
10071  index = update_frag_index(mov, offset);
10072  frag_stream_info = get_frag_stream_info(&mov->frag_index, index, track_id);
10073  if (frag_stream_info &&
10074  frag_stream_info->first_tfra_pts == AV_NOPTS_VALUE)
10075  frag_stream_info->first_tfra_pts = time;
10076 
10077  for (j = 0; j < ((fieldlength >> 4) & 3) + 1; j++)
10078  avio_r8(f);
10079  for (j = 0; j < ((fieldlength >> 2) & 3) + 1; j++)
10080  avio_r8(f);
10081  for (j = 0; j < ((fieldlength >> 0) & 3) + 1; j++)
10082  avio_r8(f);
10083  }
10084 
10085  avio_seek(f, pos + size, SEEK_SET);
10086  return 0;
10087 }
10088 
10090 {
10091  int64_t stream_size = avio_size(f);
10092  int64_t original_pos = avio_tell(f);
10093  int64_t seek_ret;
10094  int ret = -1;
10095  if ((seek_ret = avio_seek(f, stream_size - 4, SEEK_SET)) < 0) {
10096  ret = seek_ret;
10097  goto fail;
10098  }
10099  c->mfra_size = avio_rb32(f);
10100  c->have_read_mfra_size = 1;
10101  if (!c->mfra_size || c->mfra_size > stream_size) {
10102  av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (unreasonable size)\n");
10103  goto fail;
10104  }
10105  if ((seek_ret = avio_seek(f, -((int64_t) c->mfra_size), SEEK_CUR)) < 0) {
10106  ret = seek_ret;
10107  goto fail;
10108  }
10109  if (avio_rb32(f) != c->mfra_size) {
10110  av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (size mismatch)\n");
10111  goto fail;
10112  }
10113  if (avio_rb32(f) != MKBETAG('m', 'f', 'r', 'a')) {
10114  av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (tag mismatch)\n");
10115  goto fail;
10116  }
10117  av_log(c->fc, AV_LOG_VERBOSE, "stream has mfra\n");
10118  do {
10119  ret = read_tfra(c, f);
10120  if (ret < 0)
10121  goto fail;
10122  } while (!ret);
10123  ret = 0;
10124  c->frag_index.complete = 1;
10125 fail:
10126  seek_ret = avio_seek(f, original_pos, SEEK_SET);
10127  if (seek_ret < 0) {
10128  av_log(c->fc, AV_LOG_ERROR,
10129  "failed to seek back after looking for mfra\n");
10130  ret = seek_ret;
10131  }
10132  return ret;
10133 }
10134 
10135 static int set_icc_profile_from_item(AVPacketSideData **coded_side_data, int *nb_coded_side_data,
10136  const HEIFItem *item)
10137 {
10138  AVPacketSideData *sd = av_packet_side_data_new(coded_side_data, nb_coded_side_data,
10140  item->icc_profile_size, 0);
10141  if (!sd)
10142  return AVERROR(ENOMEM);
10143 
10144  memcpy(sd->data, item->icc_profile, item->icc_profile_size);
10145 
10146  return 0;
10147 }
10148 
10149 static int set_display_matrix_from_item(AVPacketSideData **coded_side_data, int *nb_coded_side_data,
10150  const HEIFItem *item)
10151 {
10152  int32_t *matrix;
10153  AVPacketSideData *sd = av_packet_side_data_new(coded_side_data,
10154  nb_coded_side_data,
10156  9 * sizeof(*matrix), 0);
10157  if (!sd)
10158  return AVERROR(ENOMEM);
10159 
10160  matrix = (int32_t*)sd->data;
10161  /* rotation is in the counter-clockwise direction whereas
10162  * av_display_rotation_set() expects its argument to be
10163  * oriented clockwise, so we need to negate it. */
10165  av_display_matrix_flip(matrix, item->hflip, item->vflip);
10166 
10167  return 0;
10168 }
10169 
10170 static int read_image_grid(AVFormatContext *s, const HEIFGrid *grid,
10171  AVStreamGroupTileGrid *tile_grid)
10172 {
10173  MOVContext *c = s->priv_data;
10174  const HEIFItem *item = grid->item;
10175  int64_t offset = 0, pos = avio_tell(s->pb);
10176  int x = 0, y = 0, i = 0;
10177  int tile_rows, tile_cols;
10178  int flags, size;
10179 
10180  if (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL)) {
10181  av_log(c->fc, AV_LOG_INFO, "grid box with non seekable input\n");
10182  return AVERROR_PATCHWELCOME;
10183  }
10184  if (item->is_idat_relative) {
10185  if (!c->idat_offset) {
10186  av_log(c->fc, AV_LOG_ERROR, "missing idat box required by the image grid\n");
10187  return AVERROR_INVALIDDATA;
10188  }
10189  offset = c->idat_offset;
10190  }
10191 
10192  avio_seek(s->pb, item->extent_offset + offset, SEEK_SET);
10193 
10194  avio_r8(s->pb); /* version */
10195  flags = avio_r8(s->pb);
10196 
10197  tile_rows = avio_r8(s->pb) + 1;
10198  tile_cols = avio_r8(s->pb) + 1;
10199  /* actual width and height of output image */
10200  tile_grid->width = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
10201  tile_grid->height = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
10202 
10203  av_log(c->fc, AV_LOG_TRACE, "grid: grid_rows %d grid_cols %d output_width %d output_height %d\n",
10204  tile_rows, tile_cols, tile_grid->width, tile_grid->height);
10205 
10206  avio_seek(s->pb, pos, SEEK_SET);
10207 
10208  size = tile_rows * tile_cols;
10209  tile_grid->nb_tiles = grid->nb_tiles;
10210 
10211  if (tile_grid->nb_tiles != size)
10212  return AVERROR_INVALIDDATA;
10213 
10214  for (int i = 0; i < tile_cols; i++)
10215  tile_grid->coded_width += grid->tile_item_list[i]->width;
10216  for (int i = 0; i < size; i += tile_cols)
10217  tile_grid->coded_height += grid->tile_item_list[i]->height;
10218 
10219  tile_grid->offsets = av_calloc(tile_grid->nb_tiles, sizeof(*tile_grid->offsets));
10220  if (!tile_grid->offsets)
10221  return AVERROR(ENOMEM);
10222 
10223  while (y < tile_grid->coded_height) {
10224  int left_col = i;
10225 
10226  while (x < tile_grid->coded_width) {
10227  if (i == tile_grid->nb_tiles)
10228  return AVERROR_INVALIDDATA;
10229 
10230  tile_grid->offsets[i].idx = grid->tile_idx_list[i];
10231  tile_grid->offsets[i].horizontal = x;
10232  tile_grid->offsets[i].vertical = y;
10233 
10234  x += grid->tile_item_list[i++]->width;
10235  }
10236 
10237  if (x > tile_grid->coded_width) {
10238  av_log(c->fc, AV_LOG_ERROR, "Non uniform HEIF tiles\n");
10239  return AVERROR_INVALIDDATA;
10240  }
10241 
10242  x = 0;
10243  y += grid->tile_item_list[left_col]->height;
10244  }
10245 
10246  if (y > tile_grid->coded_height || i != tile_grid->nb_tiles) {
10247  av_log(c->fc, AV_LOG_ERROR, "Non uniform HEIF tiles\n");
10248  return AVERROR_INVALIDDATA;
10249  }
10250 
10251  return 0;
10252 }
10253 
10254 static int read_image_iovl(AVFormatContext *s, const HEIFGrid *grid,
10255  AVStreamGroupTileGrid *tile_grid)
10256 {
10257  MOVContext *c = s->priv_data;
10258  const HEIFItem *item = grid->item;
10259  uint16_t canvas_fill_value[4];
10260  int64_t offset = 0, pos = avio_tell(s->pb);
10261  int ret = 0, flags;
10262 
10263  if (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL)) {
10264  av_log(c->fc, AV_LOG_INFO, "iovl box with non seekable input\n");
10265  return AVERROR_PATCHWELCOME;
10266  }
10267  if (item->is_idat_relative) {
10268  if (!c->idat_offset) {
10269  av_log(c->fc, AV_LOG_ERROR, "missing idat box required by the image overlay\n");
10270  return AVERROR_INVALIDDATA;
10271  }
10272  offset = c->idat_offset;
10273  }
10274 
10275  avio_seek(s->pb, item->extent_offset + offset, SEEK_SET);
10276 
10277  avio_r8(s->pb); /* version */
10278  flags = avio_r8(s->pb);
10279 
10280  for (int i = 0; i < 4; i++)
10281  canvas_fill_value[i] = avio_rb16(s->pb);
10282  av_log(c->fc, AV_LOG_TRACE, "iovl: canvas_fill_value { %u, %u, %u, %u }\n",
10283  canvas_fill_value[0], canvas_fill_value[1],
10284  canvas_fill_value[2], canvas_fill_value[3]);
10285  for (int i = 0; i < 4; i++)
10286  tile_grid->background[i] = canvas_fill_value[i];
10287 
10288  /* actual width and height of output image */
10289  tile_grid->width =
10290  tile_grid->coded_width = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
10291  tile_grid->height =
10292  tile_grid->coded_height = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
10293 
10294  av_log(c->fc, AV_LOG_TRACE, "iovl: output_width %d, output_height %d\n",
10295  tile_grid->width, tile_grid->height);
10296 
10297  tile_grid->nb_tiles = grid->nb_tiles;
10298  tile_grid->offsets = av_malloc_array(tile_grid->nb_tiles, sizeof(*tile_grid->offsets));
10299  if (!tile_grid->offsets) {
10300  ret = AVERROR(ENOMEM);
10301  goto fail;
10302  }
10303 
10304  for (int i = 0; i < tile_grid->nb_tiles; i++) {
10305  tile_grid->offsets[i].idx = grid->tile_idx_list[i];
10306  tile_grid->offsets[i].horizontal = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
10307  tile_grid->offsets[i].vertical = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
10308  av_log(c->fc, AV_LOG_TRACE, "iovl: stream_idx[%d] %u, "
10309  "horizontal_offset[%d] %d, vertical_offset[%d] %d\n",
10310  i, tile_grid->offsets[i].idx,
10311  i, tile_grid->offsets[i].horizontal, i, tile_grid->offsets[i].vertical);
10312  }
10313 
10314 fail:
10315  avio_seek(s->pb, pos, SEEK_SET);
10316 
10317  return ret;
10318 }
10319 
10321  AVPacketSideData **coded_side_data, int *nb_coded_side_data,
10322  const HEIFItem *ref)
10323 {
10324  MOVContext *c = s->priv_data;
10325  AVPacketSideData *sd;
10326  AVExifMetadata ifd = { 0 };
10327  AVBufferRef *buf;
10328  int64_t offset = 0, pos = avio_tell(s->pb);
10329  unsigned orientation_id = av_exif_get_tag_id("Orientation");
10330  int err;
10331 
10332  if (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL)) {
10333  av_log(c->fc, AV_LOG_WARNING, "Exif metadata with non seekable input\n");
10334  return AVERROR_PATCHWELCOME;
10335  }
10336  if (ref->is_idat_relative) {
10337  if (!c->idat_offset) {
10338  av_log(c->fc, AV_LOG_ERROR, "missing idat box required by the Exif metadata\n");
10339  return AVERROR_INVALIDDATA;
10340  }
10341  offset = c->idat_offset;
10342  }
10343 
10344  buf = av_buffer_alloc(ref->extent_length);
10345  if (!buf)
10346  return AVERROR(ENOMEM);
10347 
10348  avio_seek(s->pb, ref->extent_offset + offset, SEEK_SET);
10349  err = avio_read(s->pb, buf->data, ref->extent_length);
10350  if (err != ref->extent_length) {
10351  if (err > 0)
10352  err = AVERROR_INVALIDDATA;
10353  goto fail;
10354  }
10355 
10356  // HEIF spec states that Exif metadata is informative. The irot item property is
10357  // the normative source of rotation information. So we remove any Orientation tag
10358  // present in the Exif buffer.
10359  err = av_exif_parse_buffer(s, buf->data, ref->extent_length, &ifd, AV_EXIF_T_OFF);
10360  if (err < 0) {
10361  av_log(s, AV_LOG_ERROR, "Unable to parse Exif metadata\n");
10362  goto fail;
10363  }
10364 
10365  err = av_exif_remove_entry(s, &ifd, orientation_id, 0);
10366  if (err < 0)
10367  goto fail;
10368  else if (!err)
10369  goto finish;
10370 
10371  av_buffer_unref(&buf);
10372  err = av_exif_write(s, &ifd, &buf, AV_EXIF_T_OFF);
10373  if (err < 0)
10374  goto fail;
10375 
10376 finish:
10377  offset = AV_RB32(buf->data) + 4;
10378  if (offset >= buf->size) {
10379  err = AVERROR_INVALIDDATA;
10380  goto fail;
10381  }
10382  sd = av_packet_side_data_new(coded_side_data, nb_coded_side_data,
10383  AV_PKT_DATA_EXIF, buf->size - offset, 0);
10384  if (!sd) {
10385  err = AVERROR(ENOMEM);
10386  goto fail;
10387  }
10388  memcpy(sd->data, buf->data + offset, buf->size - offset);
10389 
10390  err = 0;
10391 fail:
10392  av_buffer_unref(&buf);
10393  av_exif_free(&ifd);
10394  avio_seek(s->pb, pos, SEEK_SET);
10395 
10396  return err;
10397 }
10398 
10400 {
10401  MOVContext *mov = s->priv_data;
10402 
10403  for (int i = 0; i < mov->nb_heif_grid; i++) {
10405  AVStreamGroupTileGrid *tile_grid;
10406  const HEIFGrid *grid = &mov->heif_grid[i];
10407  int err, loop = 1;
10408 
10409  if (!stg)
10410  return AVERROR(ENOMEM);
10411 
10412  stg->id = grid->item->item_id;
10413  tile_grid = stg->params.tile_grid;
10414 
10415  for (int j = 0; j < grid->nb_tiles; j++) {
10416  int tile_id = grid->tile_id_list[j];
10417  int k;
10418 
10419  for (k = 0; k < mov->nb_heif_item; k++) {
10420  HEIFItem *item = mov->heif_item[k];
10421  AVStream *st;
10422 
10423  if (!item || item->item_id != tile_id)
10424  continue;
10425  st = item->st;
10426  if (!st) {
10427  av_log(s, AV_LOG_WARNING, "HEIF item id %d from grid id %d doesn't "
10428  "reference a stream\n",
10429  tile_id, grid->item->item_id);
10430  ff_remove_stream_group(s, stg);
10431  loop = 0;
10432  break;
10433  }
10434 
10435  grid->tile_item_list[j] = item;
10436  grid->tile_idx_list[j] = stg->nb_streams;
10437 
10438  err = avformat_stream_group_add_stream(stg, st);
10439  if (err < 0) {
10440  int l;
10441  if (err != AVERROR(EEXIST))
10442  return err;
10443 
10444  for (l = 0; l < stg->nb_streams; l++)
10445  if (stg->streams[l]->index == st->index)
10446  break;
10447  av_assert0(l < stg->nb_streams);
10448  grid->tile_idx_list[j] = l;
10449  }
10450 
10451  if (item->item_id != mov->primary_item_id)
10453  break;
10454  }
10455 
10456  if (k == mov->nb_heif_item) {
10457  av_assert0(loop);
10458  av_log(s, AV_LOG_WARNING, "HEIF item id %d referenced by grid id %d doesn't "
10459  "exist\n",
10460  tile_id, grid->item->item_id);
10461  ff_remove_stream_group(s, stg);
10462  loop = 0;
10463  }
10464  if (!loop)
10465  break;
10466  }
10467 
10468  if (!loop)
10469  continue;
10470 
10471  switch (grid->item->type) {
10472  case MKTAG('g','r','i','d'):
10473  err = read_image_grid(s, grid, tile_grid);
10474  break;
10475  case MKTAG('i','o','v','l'):
10476  err = read_image_iovl(s, grid, tile_grid);
10477  break;
10478  default:
10479  av_assert0(0);
10480  }
10481  if (err < 0)
10482  return err;
10483 
10484  for (int j = 0; j < grid->item->nb_iref_list; j++) {
10485  HEIFItem *ref = get_heif_item(mov, grid->item->iref_list[j].item_id);
10486 
10487  av_assert0(ref);
10488  switch(ref->type) {
10489  case MKTAG('E','x','i','f'):
10490  err = mov_parse_exif_item(s, &tile_grid->coded_side_data,
10491  &tile_grid->nb_coded_side_data, ref);
10492  if (err < 0 && (s->error_recognition & AV_EF_EXPLODE))
10493  return err;
10494  break;
10495  default:
10496  break;
10497  }
10498  }
10499 
10500  /* rotation */
10501  if (grid->item->rotation || grid->item->hflip || grid->item->vflip) {
10503  &tile_grid->nb_coded_side_data, grid->item);
10504  if (err < 0)
10505  return err;
10506  }
10507 
10508  /* ICC profile */
10509  if (grid->item->icc_profile_size) {
10510  err = set_icc_profile_from_item(&tile_grid->coded_side_data,
10511  &tile_grid->nb_coded_side_data, grid->item);
10512  if (err < 0)
10513  return err;
10514  }
10515 
10516  if (grid->item->name)
10517  av_dict_set(&stg->metadata, "title", grid->item->name, 0);
10518  if (grid->item->item_id == mov->primary_item_id)
10520  }
10521 
10522  return 0;
10523 }
10524 
10526 {
10527  MOVContext *mov = s->priv_data;
10528  int err;
10529 
10530  for (int i = 0; i < mov->nb_heif_item; i++) {
10531  HEIFItem *item = mov->heif_item[i];
10532  MOVStreamContext *sc;
10533  AVStream *st;
10534  int64_t offset = 0;
10535 
10536  if (!item)
10537  continue;
10538  if (!item->st) {
10539  continue;
10540  }
10541  if (item->is_idat_relative) {
10542  if (!mov->idat_offset) {
10543  av_log(s, AV_LOG_ERROR, "Missing idat box for item %d\n", item->item_id);
10544  return AVERROR_INVALIDDATA;
10545  }
10546  offset = mov->idat_offset;
10547  }
10548 
10549  st = item->st;
10550  sc = st->priv_data;
10551  st->codecpar->width = item->width;
10552  st->codecpar->height = item->height;
10553 
10554  sc->sample_size = sc->stsz_sample_size = item->extent_length;
10555  sc->sample_count = 1;
10556 
10557  err = sanity_checks(s, sc, st->index);
10558  if (err)
10559  return AVERROR_INVALIDDATA;
10560 
10561  sc->chunk_offsets[0] = item->extent_offset + offset;
10562 
10563  if (item->item_id == mov->primary_item_id)
10565 
10566  for (int j = 0; j < item->nb_iref_list; j++) {
10567  HEIFItem *ref = get_heif_item(mov, item->iref_list[j].item_id);
10568 
10569  av_assert0(ref);
10570  switch(ref->type) {
10571  case MKTAG('E','x','i','f'):
10574  if (err < 0 && (s->error_recognition & AV_EF_EXPLODE))
10575  return err;
10576  break;
10577  default:
10578  break;
10579  }
10580  }
10581 
10582  if (item->rotation || item->hflip || item->vflip) {
10584  &st->codecpar->nb_coded_side_data, item);
10585  if (err < 0)
10586  return err;
10587  }
10588 
10589  mov_build_index(mov, st);
10590  }
10591 
10592  if (mov->nb_heif_grid) {
10593  err = mov_parse_tiles(s);
10594  if (err < 0)
10595  return err;
10596  }
10597 
10598  return 0;
10599 }
10600 
10602  int first_index)
10603 {
10604  MOVStreamContext *sc = st->priv_data;
10605 
10606  if (sc->tref_id < 0)
10607  return NULL;
10608 
10609  for (int i = first_index; i < s->nb_streams; i++)
10610  if (s->streams[i]->id == sc->tref_id)
10611  return s->streams[i];
10612 
10613  return NULL;
10614 }
10615 
10617 {
10618  int err;
10619 
10620  for (int i = 0; i < s->nb_streams; i++) {
10621  AVStreamGroup *stg;
10622  AVStream *st = s->streams[i];
10623  AVStream *st_base;
10624  MOVStreamContext *sc = st->priv_data;
10625  int j = 0;
10626 
10627  /* Find an enhancement stream. */
10628  if (st->codecpar->codec_id != AV_CODEC_ID_LCEVC ||
10630  continue;
10631 
10633 
10635  if (!stg)
10636  return AVERROR(ENOMEM);
10637 
10638  stg->id = st->id;
10639  stg->params.lcevc->width = st->codecpar->width;
10640  stg->params.lcevc->height = st->codecpar->height;
10641  st->codecpar->width = 0;
10642  st->codecpar->height = 0;
10643 
10644  while (st_base = mov_find_reference_track(s, st, j)) {
10645  err = avformat_stream_group_add_stream(stg, st_base);
10646  if (err < 0)
10647  return err;
10648 
10649  j = st_base->index + 1;
10650  }
10651  if (!j) {
10652  av_log(s, AV_LOG_ERROR, "Failed to find base stream for enhancement stream\n");
10653  return AVERROR_INVALIDDATA;
10654  }
10655 
10656  err = avformat_stream_group_add_stream(stg, st);
10657  if (err < 0)
10658  return err;
10659 
10660  stg->params.lcevc->lcevc_index = stg->nb_streams - 1;
10661  }
10662 
10663  return 0;
10664 }
10665 
10667 {
10668  int highest_id = 0;
10669 
10670  for (int i = 0; i < s->nb_streams; i++) {
10671  const AVStream *st = s->streams[i];
10672  const MOVStreamContext *sc = st->priv_data;
10673  if (!sc->iamf)
10674  highest_id = FFMAX(highest_id, st->id);
10675  }
10676  highest_id += !highest_id;
10677  for (int i = 0; highest_id > 1 && i < s->nb_stream_groups; i++) {
10678  AVStreamGroup *stg = s->stream_groups[i];
10680  continue;
10681  for (int j = 0; j < stg->nb_streams; j++) {
10682  AVStream *st = stg->streams[j];
10683  MOVStreamContext *sc = st->priv_data;
10684  st->id += highest_id;
10685  sc->iamf_stream_offset = highest_id;
10686  }
10687  }
10688 }
10689 
10691 {
10692  MOVContext *mov = s->priv_data;
10693  AVIOContext *pb = s->pb;
10694  int j, err;
10695  MOVAtom atom = { AV_RL32("root") };
10696  int i;
10697 
10698  if (mov->decryption_key_len != 0 && mov->decryption_key_len != AES_CTR_KEY_SIZE) {
10699  av_log(s, AV_LOG_ERROR, "Invalid decryption key len %d expected %d\n",
10701  return AVERROR(EINVAL);
10702  }
10703 
10704  mov->fc = s;
10705  mov->trak_index = -1;
10706  mov->primary_item_id = -1;
10707  mov->cur_item_id = -1;
10708  /* .mov and .mp4 aren't streamable anyway (only progressive download if moov is before mdat) */
10709  if (pb->seekable & AVIO_SEEKABLE_NORMAL)
10710  atom.size = avio_size(pb);
10711  else
10712  atom.size = INT64_MAX;
10713 
10714  /* check MOV header */
10715  do {
10716  if (mov->moov_retry)
10717  avio_seek(pb, 0, SEEK_SET);
10718  if ((err = mov_read_default(mov, pb, atom)) < 0) {
10719  av_log(s, AV_LOG_ERROR, "error reading header\n");
10720  return err;
10721  }
10722  } while ((pb->seekable & AVIO_SEEKABLE_NORMAL) &&
10723  !mov->found_moov && (!mov->found_iloc || !mov->found_iinf) && !mov->moov_retry++);
10724  if (!mov->found_moov && !mov->found_iloc && !mov->found_iinf) {
10725  av_log(s, AV_LOG_ERROR, "moov atom not found\n");
10726  return AVERROR_INVALIDDATA;
10727  }
10728  av_log(mov->fc, AV_LOG_TRACE, "on_parse_exit_offset=%"PRId64"\n", avio_tell(pb));
10729 
10730  if (mov->found_iloc && mov->found_iinf) {
10731  err = mov_parse_heif_items(s);
10732  if (err < 0)
10733  return err;
10734  }
10735  // prevent iloc and iinf boxes from being parsed while reading packets.
10736  // this is needed because an iinf box may have been parsed but ignored
10737  // for having old infe boxes which create no streams.
10738  mov->found_iloc = mov->found_iinf = 1;
10739 
10740  if (pb->seekable & AVIO_SEEKABLE_NORMAL) {
10741  if (mov->nb_chapter_tracks > 0 && !mov->ignore_chapters)
10743  for (i = 0; i < s->nb_streams; i++)
10744  if (s->streams[i]->codecpar->codec_tag == AV_RL32("tmcd")) {
10745  mov_read_timecode_track(s, s->streams[i]);
10746  } else if (s->streams[i]->codecpar->codec_tag == AV_RL32("rtmd")) {
10747  mov_read_rtmd_track(s, s->streams[i]);
10748  }
10749  }
10750 
10751  /* copy timecode metadata from tmcd tracks to the related video streams */
10752  for (i = 0; i < s->nb_streams; i++) {
10753  AVStream *st = s->streams[i];
10754  MOVStreamContext *sc = st->priv_data;
10755  if (sc->timecode_track > 0) {
10756  AVDictionaryEntry *tcr;
10757  int tmcd_st_id = -1;
10758 
10759  for (j = 0; j < s->nb_streams; j++) {
10760  MOVStreamContext *sc2 = s->streams[j]->priv_data;
10761  if (sc2->id == sc->timecode_track)
10762  tmcd_st_id = j;
10763  }
10764 
10765  if (tmcd_st_id < 0 || tmcd_st_id == i)
10766  continue;
10767  tcr = av_dict_get(s->streams[tmcd_st_id]->metadata, "timecode", NULL, 0);
10768  if (tcr)
10769  av_dict_set(&st->metadata, "timecode", tcr->value, 0);
10770  }
10771  }
10773 
10774  /* Create LCEVC stream groups. */
10775  err = mov_parse_lcevc_streams(s);
10776  if (err < 0)
10777  return err;
10778 
10779  for (i = 0; i < s->nb_streams; i++) {
10780  AVStream *st = s->streams[i];
10781  FFStream *const sti = ffstream(st);
10782  MOVStreamContext *sc = st->priv_data;
10783  uint32_t dvdsub_clut[FF_DVDCLUT_CLUT_LEN] = {0};
10784  fix_timescale(mov, sc);
10785 
10786  /* Set the primary extradata based on the first Sample if it doesn't reference the first stsd entry. */
10787  if (sc->stsc_count && sc->extradata_size && !sc->iamf &&
10788  sc->stsc_data[0].id > 1 && sc->stsc_data[0].id <= sc->stsd_count) {
10789  sc->last_stsd_index = sc->stsc_data[0].id - 1;
10790  av_freep(&st->codecpar->extradata);
10792  if (sc->extradata_size[sc->last_stsd_index]) {
10794  if (!st->codecpar->extradata)
10795  return AVERROR(ENOMEM);
10796  memcpy(st->codecpar->extradata, sc->extradata[sc->last_stsd_index], sc->extradata_size[sc->last_stsd_index]);
10797  }
10798  }
10799 
10800  if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
10801  st->codecpar->codec_id == AV_CODEC_ID_AAC) {
10802  sti->skip_samples = sc->start_pad;
10803  }
10804  if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && sc->nb_frames_for_fps > 0 && sc->duration_for_fps > 0)
10806  sc->time_scale*(int64_t)sc->nb_frames_for_fps, sc->duration_for_fps, INT_MAX);
10808  if (st->codecpar->width <= 0 || st->codecpar->height <= 0) {
10809  st->codecpar->width = sc->width;
10810  st->codecpar->height = sc->height;
10811  }
10814 
10815  for (j = 0; j < FF_DVDCLUT_CLUT_LEN; j++)
10816  dvdsub_clut[j] = AV_RB32(st->codecpar->extradata + j * 4);
10817 
10818  err = ff_dvdclut_yuv_to_rgb(dvdsub_clut, FF_DVDCLUT_CLUT_SIZE);
10819  if (err < 0)
10820  return err;
10821 
10822  av_freep(&st->codecpar->extradata);
10823  st->codecpar->extradata_size = 0;
10824 
10826  st->codecpar);
10827  if (err < 0)
10828  return err;
10829  }
10830  }
10831  if (mov->handbrake_version &&
10832  mov->handbrake_version <= 1000000*0 + 1000*10 + 2 && // 0.10.2
10833  st->codecpar->codec_id == AV_CODEC_ID_MP3) {
10834  av_log(s, AV_LOG_VERBOSE, "Forcing full parsing for mp3 stream\n");
10836  }
10837  }
10838 
10839  if (mov->trex_data || mov->use_mfra_for > 0) {
10840  for (i = 0; i < s->nb_streams; i++) {
10841  AVStream *st = s->streams[i];
10842  MOVStreamContext *sc = st->priv_data;
10843  if (sc->duration_for_fps > 0) {
10844  /* Akin to sc->data_size * 8 * sc->time_scale / sc->duration_for_fps but accounting for overflows. */
10846  if (st->codecpar->bit_rate == INT64_MIN) {
10847  av_log(s, AV_LOG_WARNING, "Overflow during bit rate calculation %"PRId64" * 8 * %d\n",
10848  sc->data_size, sc->time_scale);
10849  st->codecpar->bit_rate = 0;
10850  if (s->error_recognition & AV_EF_EXPLODE)
10851  return AVERROR_INVALIDDATA;
10852  }
10853  }
10854  }
10855  }
10856 
10857  for (i = 0; i < mov->bitrates_count && i < s->nb_streams; i++) {
10858  if (mov->bitrates[i]) {
10859  s->streams[i]->codecpar->bit_rate = mov->bitrates[i];
10860  }
10861  }
10862 
10864 
10865  for (i = 0; i < s->nb_streams; i++) {
10866  AVStream *st = s->streams[i];
10867  MOVStreamContext *sc = st->priv_data;
10868 
10869  switch (st->codecpar->codec_type) {
10870  case AVMEDIA_TYPE_AUDIO:
10871  err = ff_replaygain_export(st, s->metadata);
10872  if (err < 0)
10873  return err;
10874  break;
10875  case AVMEDIA_TYPE_VIDEO:
10876  if (sc->display_matrix) {
10879  (uint8_t*)sc->display_matrix, sizeof(int32_t) * 9, 0))
10880  return AVERROR(ENOMEM);
10881 
10882  sc->display_matrix = NULL;
10883  }
10884  if (sc->stereo3d) {
10887  (uint8_t *)sc->stereo3d, sc->stereo3d_size, 0))
10888  return AVERROR(ENOMEM);
10889 
10890  sc->stereo3d = NULL;
10891  }
10892  if (sc->spherical) {
10895  (uint8_t *)sc->spherical, sc->spherical_size, 0))
10896  return AVERROR(ENOMEM);
10897 
10898  sc->spherical = NULL;
10899  }
10900  if (sc->mastering) {
10903  (uint8_t *)sc->mastering, sc->mastering_size, 0))
10904  return AVERROR(ENOMEM);
10905 
10906  sc->mastering = NULL;
10907  }
10908  if (sc->coll) {
10911  (uint8_t *)sc->coll, sc->coll_size, 0))
10912  return AVERROR(ENOMEM);
10913 
10914  sc->coll = NULL;
10915  }
10916  if (sc->ambient) {
10919  (uint8_t *) sc->ambient, sc->ambient_size, 0))
10920  return AVERROR(ENOMEM);
10921 
10922  sc->ambient = NULL;
10923  }
10924  break;
10925  }
10926  }
10927 
10928  fix_stream_ids(s);
10929 
10931 
10932  for (i = 0; i < mov->frag_index.nb_items; i++)
10933  if (mov->frag_index.item[i].moof_offset <= mov->fragment.moof_offset)
10934  mov->frag_index.item[i].headers_read = 1;
10935 
10936  return 0;
10937 }
10938 
10940 {
10942  int64_t best_dts = INT64_MAX;
10943  int i;
10944  MOVContext *mov = s->priv_data;
10945  int no_interleave = !mov->interleaved_read || !(s->pb->seekable & AVIO_SEEKABLE_NORMAL);
10946  for (i = 0; i < s->nb_streams; i++) {
10947  AVStream *avst = s->streams[i];
10948  FFStream *const avsti = ffstream(avst);
10949  MOVStreamContext *msc = avst->priv_data;
10950  if (msc->pb && msc->current_sample < avsti->nb_index_entries) {
10951  AVIndexEntry *current_sample = &avsti->index_entries[msc->current_sample];
10952  int64_t dts = av_rescale(current_sample->timestamp, AV_TIME_BASE, msc->time_scale);
10953  uint64_t dtsdiff = best_dts > dts ? best_dts - (uint64_t)dts : ((uint64_t)dts - best_dts);
10954  av_log(s, AV_LOG_TRACE, "stream %d, sample %d, dts %"PRId64"\n", i, msc->current_sample, dts);
10955  if (!sample || (no_interleave && current_sample->pos < sample->pos) ||
10956  ((s->pb->seekable & AVIO_SEEKABLE_NORMAL) &&
10957  ((msc->pb != s->pb && dts < best_dts) || (msc->pb == s->pb && dts != AV_NOPTS_VALUE &&
10958  ((dtsdiff <= AV_TIME_BASE && current_sample->pos < sample->pos) ||
10959  (dtsdiff > AV_TIME_BASE && dts < best_dts && mov->interleaved_read)))))) {
10960  sample = current_sample;
10961  best_dts = dts;
10962  *st = avst;
10963  }
10964  }
10965  }
10966  return sample;
10967 }
10968 
10969 static int should_retry(AVIOContext *pb, int error_code) {
10970  if (error_code == AVERROR_EOF || avio_feof(pb))
10971  return 0;
10972 
10973  return 1;
10974 }
10975 
10976 static int mov_switch_root(AVFormatContext *s, int64_t target, int index)
10977 {
10978  int ret;
10979  MOVContext *mov = s->priv_data;
10980 
10981  if (index >= 0 && index < mov->frag_index.nb_items)
10982  target = mov->frag_index.item[index].moof_offset;
10983  if (target >= 0 && avio_seek(s->pb, target, SEEK_SET) != target) {
10984  av_log(mov->fc, AV_LOG_ERROR, "root atom offset 0x%"PRIx64": partial file\n", target);
10985  return AVERROR_INVALIDDATA;
10986  }
10987 
10988  mov->next_root_atom = 0;
10989  if ((index < 0 && target >= 0) || index >= mov->frag_index.nb_items)
10990  index = search_frag_moof_offset(&mov->frag_index, target);
10991  if (index >= 0 && index < mov->frag_index.nb_items &&
10992  mov->frag_index.item[index].moof_offset == target) {
10993  if (index + 1 < mov->frag_index.nb_items)
10994  mov->next_root_atom = mov->frag_index.item[index + 1].moof_offset;
10995  if (mov->frag_index.item[index].headers_read)
10996  return 0;
10997  mov->frag_index.item[index].headers_read = 1;
10998  }
10999 
11000  mov->found_mdat = 0;
11001 
11002  ret = mov_read_default(mov, s->pb, (MOVAtom){ AV_RL32("root"), INT64_MAX });
11003  if (ret < 0)
11004  return ret;
11005  if (avio_feof(s->pb))
11006  return AVERROR_EOF;
11007  av_log(s, AV_LOG_TRACE, "read fragments, offset 0x%"PRIx64"\n", avio_tell(s->pb));
11008 
11009  return 1;
11010 }
11011 
11013 {
11014  MOVStreamContext *sc = st->priv_data;
11015  uint8_t *side, *extradata;
11016  int extradata_size;
11017 
11018  /* Save the current index. */
11019  sc->last_stsd_index = sc->stsc_data[sc->stsc_index].id - 1;
11020 
11021  /* Notify the decoder that extradata changed. */
11022  extradata_size = sc->extradata_size[sc->last_stsd_index];
11023  extradata = sc->extradata[sc->last_stsd_index];
11024  if (st->discard != AVDISCARD_ALL && extradata_size > 0 && extradata) {
11027  extradata_size);
11028  if (!side)
11029  return AVERROR(ENOMEM);
11030  memcpy(side, extradata, extradata_size);
11031  }
11032 
11033  return 0;
11034 }
11035 
11036 static int get_eia608_packet(AVIOContext *pb, AVPacket *pkt, int src_size)
11037 {
11038  /* We can't make assumptions about the structure of the payload,
11039  because it may include multiple cdat and cdt2 samples. */
11040  const uint32_t cdat = AV_RB32("cdat");
11041  const uint32_t cdt2 = AV_RB32("cdt2");
11042  int ret, out_size = 0;
11043 
11044  /* a valid payload must have size, 4cc, and at least 1 byte pair: */
11045  if (src_size < 10)
11046  return AVERROR_INVALIDDATA;
11047 
11048  /* avoid an int overflow: */
11049  if ((src_size - 8) / 2 >= INT_MAX / 3)
11050  return AVERROR_INVALIDDATA;
11051 
11052  ret = av_new_packet(pkt, ((src_size - 8) / 2) * 3);
11053  if (ret < 0)
11054  return ret;
11055 
11056  /* parse and re-format the c608 payload in one pass. */
11057  while (src_size >= 10) {
11058  const uint32_t atom_size = avio_rb32(pb);
11059  const uint32_t atom_type = avio_rb32(pb);
11060  const uint32_t data_size = atom_size - 8;
11061  const uint8_t cc_field =
11062  atom_type == cdat ? 1 :
11063  atom_type == cdt2 ? 2 :
11064  0;
11065 
11066  /* account for bytes consumed for atom size and type. */
11067  src_size -= 8;
11068 
11069  /* make sure the data size stays within the buffer boundaries. */
11070  if (data_size < 2 || data_size > src_size) {
11072  break;
11073  }
11074 
11075  /* make sure the data size is consistent with N byte pairs. */
11076  if (data_size % 2 != 0) {
11078  break;
11079  }
11080 
11081  if (!cc_field) {
11082  /* neither cdat or cdt2 ... skip it */
11083  avio_skip(pb, data_size);
11084  src_size -= data_size;
11085  continue;
11086  }
11087 
11088  for (uint32_t i = 0; i < data_size; i += 2) {
11089  pkt->data[out_size] = (0x1F << 3) | (1 << 2) | (cc_field - 1);
11090  pkt->data[out_size + 1] = avio_r8(pb);
11091  pkt->data[out_size + 2] = avio_r8(pb);
11092  out_size += 3;
11093  src_size -= 2;
11094  }
11095  }
11096 
11097  if (src_size > 0)
11098  /* skip any remaining unread portion of the input payload */
11099  avio_skip(pb, src_size);
11100 
11102  return ret;
11103 }
11104 
11106  int64_t current_index, AVPacket *pkt)
11107 {
11108  MOVStreamContext *sc = st->priv_data;
11109 
11110  pkt->stream_index = sc->ffindex;
11111  pkt->dts = sample->timestamp;
11112  if (sample->flags & AVINDEX_DISCARD_FRAME) {
11114  }
11115  if (sc->stts_count && sc->tts_index < sc->tts_count)
11116  pkt->duration = sc->tts_data[sc->tts_index].duration;
11117  if (sc->ctts_count && sc->tts_index < sc->tts_count) {
11119  } else {
11120  if (pkt->duration == 0) {
11121  int64_t next_dts = (sc->current_sample < ffstream(st)->nb_index_entries) ?
11123  if (next_dts >= pkt->dts)
11124  pkt->duration = next_dts - pkt->dts;
11125  }
11126  pkt->pts = pkt->dts;
11127  }
11128 
11129  if (sc->tts_data && sc->tts_index < sc->tts_count) {
11130  /* update tts context */
11131  sc->tts_sample++;
11132  if (sc->tts_index < sc->tts_count &&
11133  sc->tts_data[sc->tts_index].count == sc->tts_sample) {
11134  sc->tts_index++;
11135  sc->tts_sample = 0;
11136  }
11137  }
11138 
11139  if (sc->sdtp_data && sc->current_sample <= sc->sdtp_count) {
11140  uint8_t sample_flags = sc->sdtp_data[sc->current_sample - 1];
11141  uint8_t sample_is_depended_on = (sample_flags >> 2) & 0x3;
11142  pkt->flags |= sample_is_depended_on == MOV_SAMPLE_DEPENDENCY_NO ? AV_PKT_FLAG_DISPOSABLE : 0;
11143  }
11144  pkt->flags |= sample->flags & AVINDEX_KEYFRAME ? AV_PKT_FLAG_KEY : 0;
11145  pkt->pos = sample->pos;
11146 
11147  /* Multiple stsd handling. */
11148  if (sc->stsc_data) {
11149  if (sc->stsc_data[sc->stsc_index].id > 0 &&
11150  sc->stsc_data[sc->stsc_index].id - 1 < sc->stsd_count &&
11151  sc->stsc_data[sc->stsc_index].id - 1 != sc->last_stsd_index) {
11152  int ret = mov_change_extradata(st, pkt);
11153  if (ret < 0)
11154  return ret;
11155  }
11156 
11157  /* Update the stsc index for the next sample */
11158  sc->stsc_sample++;
11159  if (mov_stsc_index_valid(sc->stsc_index, sc->stsc_count) &&
11160  mov_get_stsc_samples(sc, sc->stsc_index) == sc->stsc_sample) {
11161  sc->stsc_index++;
11162  sc->stsc_sample = 0;
11163  }
11164  }
11165 
11166  return 0;
11167 }
11168 
11170 {
11171  MOVContext *mov = s->priv_data;
11172  MOVStreamContext *sc;
11174  AVStream *st = NULL;
11175  FFStream *avsti = NULL;
11176  int64_t current_index;
11177  int ret;
11178  int i;
11179  mov->fc = s;
11180  retry:
11181  if (s->pb->pos == 0) {
11182 
11183  // Discard current fragment index
11184  if (mov->frag_index.allocated_size > 0) {
11185  for(int i = 0; i < mov->frag_index.nb_items; i++) {
11187  }
11188  av_freep(&mov->frag_index.item);
11189  mov->frag_index.nb_items = 0;
11190  mov->frag_index.allocated_size = 0;
11191  mov->frag_index.current = -1;
11192  mov->frag_index.complete = 0;
11193  }
11194 
11195  for (i = 0; i < s->nb_streams; i++) {
11196  AVStream *avst = s->streams[i];
11197  MOVStreamContext *msc = avst->priv_data;
11198 
11199  // Clear current sample
11200  mov_current_sample_set(msc, 0);
11201  msc->tts_index = 0;
11202 
11203  // Discard current index entries
11204  avsti = ffstream(avst);
11205  if (avsti->index_entries_allocated_size > 0) {
11206  av_freep(&avsti->index_entries);
11207  avsti->index_entries_allocated_size = 0;
11208  avsti->nb_index_entries = 0;
11209  }
11210  }
11211 
11212  if ((ret = mov_switch_root(s, -1, -1)) < 0)
11213  return ret;
11214  }
11215  sample = mov_find_next_sample(s, &st);
11216  if (!sample || (mov->next_root_atom && sample->pos > mov->next_root_atom)) {
11217  if (!mov->next_root_atom)
11218  return AVERROR_EOF;
11219  if ((ret = mov_switch_root(s, mov->next_root_atom, -1)) < 0)
11220  return ret;
11221  goto retry;
11222  }
11223  sc = st->priv_data;
11224  /* must be done just before reading, to avoid infinite loop on sample */
11225  current_index = sc->current_index;
11227 
11228  if (mov->next_root_atom) {
11229  sample->pos = FFMIN(sample->pos, mov->next_root_atom);
11230  sample->size = FFMIN(sample->size, (mov->next_root_atom - sample->pos));
11231  }
11232 
11233  if (st->discard != AVDISCARD_ALL) {
11234  int64_t ret64 = avio_seek(sc->pb, sample->pos, SEEK_SET);
11235  if (ret64 != sample->pos) {
11236  av_log(mov->fc, AV_LOG_ERROR, "stream %d, offset 0x%"PRIx64": partial file\n",
11237  sc->ffindex, sample->pos);
11238  if (should_retry(sc->pb, ret64)) {
11240  } else if (ret64 < 0) {
11241  return (int)ret64;
11242  }
11243  return AVERROR_INVALIDDATA;
11244  }
11245 
11246  if (st->discard == AVDISCARD_NONKEY && !(sample->flags & AVINDEX_KEYFRAME)) {
11247  av_log(mov->fc, AV_LOG_DEBUG, "Nonkey frame from stream %d discarded due to AVDISCARD_NONKEY\n", sc->ffindex);
11248  goto retry;
11249  }
11250 
11251  if (st->codecpar->codec_id == AV_CODEC_ID_EIA_608 && sample->size > 8)
11252  ret = get_eia608_packet(sc->pb, pkt, sample->size);
11253 #if CONFIG_IAMFDEC
11254  else if (sc->iamf) {
11255  int64_t pts, dts, pos, duration;
11256  int flags, size = sample->size;
11257  ret = mov_finalize_packet(s, st, sample, current_index, pkt);
11258  pts = pkt->pts; dts = pkt->dts;
11259  pos = pkt->pos; flags = pkt->flags;
11260  duration = pkt->duration;
11261  while (!ret && size > 0) {
11262  ret = ff_iamf_read_packet(s, sc->iamf, sc->pb, size, sc->iamf_stream_offset, pkt);
11263  if (ret < 0) {
11264  if (should_retry(sc->pb, ret))
11266  return ret;
11267  }
11268  size -= ret;
11269  pkt->pts = pts; pkt->dts = dts;
11270  pkt->pos = pos; pkt->flags |= flags;
11271  pkt->duration = duration;
11272  ret = ff_buffer_packet(s, pkt);
11273  }
11274  if (!ret)
11275  return FFERROR_REDO;
11276  }
11277 #endif
11278  else if (st->codecpar->codec_id == AV_CODEC_ID_APV && sample->size > 4) {
11279  const uint32_t au_size = avio_rb32(sc->pb);
11280  ret = av_get_packet(sc->pb, pkt, au_size);
11281  } else
11282  ret = av_get_packet(sc->pb, pkt, sample->size);
11283  if (ret < 0) {
11284  if (should_retry(sc->pb, ret)) {
11286  }
11287  return ret;
11288  }
11289 #if CONFIG_DV_DEMUXER
11290  if (mov->dv_demux && sc->dv_audio_container) {
11293  if (ret < 0)
11294  return ret;
11296  if (ret < 0)
11297  return ret;
11298  }
11299 #endif
11300  if (sc->has_palette) {
11301  uint8_t *pal;
11302 
11304  if (!pal) {
11305  av_log(mov->fc, AV_LOG_ERROR, "Cannot append palette to packet\n");
11306  } else {
11307  memcpy(pal, sc->palette, AVPALETTE_SIZE);
11308  sc->has_palette = 0;
11309  }
11310  }
11311  if (st->codecpar->codec_id == AV_CODEC_ID_MP3 && !ffstream(st)->need_parsing && pkt->size > 4) {
11312  if (ff_mpa_check_header(AV_RB32(pkt->data)) < 0)
11314  }
11315  }
11316 
11317  ret = mov_finalize_packet(s, st, sample, current_index, pkt);
11318  if (ret < 0)
11319  return ret;
11320 
11321  if (st->discard == AVDISCARD_ALL)
11322  goto retry;
11323 
11324  if (mov->aax_mode)
11325  aax_filter(pkt->data, pkt->size, mov);
11326 
11327  ret = cenc_filter(mov, st, sc, pkt, current_index);
11328  if (ret < 0) {
11329  return ret;
11330  }
11331 
11332  return 0;
11333 }
11334 
11336 {
11337  MOVContext *mov = s->priv_data;
11338  int index;
11339 
11340  if (!mov->frag_index.complete)
11341  return 0;
11342 
11343  index = search_frag_timestamp(s, &mov->frag_index, st, timestamp);
11344  if (index < 0)
11345  index = 0;
11346  if (!mov->frag_index.item[index].headers_read)
11347  return mov_switch_root(s, -1, index);
11348  if (index + 1 < mov->frag_index.nb_items)
11349  mov->next_root_atom = mov->frag_index.item[index + 1].moof_offset;
11350 
11351  return 0;
11352 }
11353 
11354 static int is_open_key_sample(const MOVStreamContext *sc, int sample)
11355 {
11356  // TODO: a bisect search would scale much better
11357  for (int i = 0; i < sc->open_key_samples_count; i++) {
11358  const int oks = sc->open_key_samples[i];
11359  if (oks == sample)
11360  return 1;
11361  if (oks > sample) /* list is monotically increasing so we can stop early */
11362  break;
11363  }
11364  return 0;
11365 }
11366 
11367 /*
11368  * Some key sample may be key frames but not IDR frames, so a random access to
11369  * them may not be allowed.
11370  */
11371 static int can_seek_to_key_sample(AVStream *st, int sample, int64_t requested_pts)
11372 {
11373  MOVStreamContext *sc = st->priv_data;
11374  FFStream *const sti = ffstream(st);
11375  int64_t key_sample_dts, key_sample_pts;
11376 
11377  if (st->codecpar->codec_id != AV_CODEC_ID_HEVC)
11378  return 1;
11379 
11380  if (sample >= sc->sample_offsets_count)
11381  return 1;
11382 
11383  key_sample_dts = sti->index_entries[sample].timestamp;
11384  key_sample_pts = key_sample_dts + sc->sample_offsets[sample] + sc->dts_shift;
11385 
11386  /*
11387  * If the sample needs to be presented before an open key sample, they may
11388  * not be decodable properly, even though they come after in decoding
11389  * order.
11390  */
11391  if (is_open_key_sample(sc, sample) && key_sample_pts > requested_pts)
11392  return 0;
11393 
11394  return 1;
11395 }
11396 
11397 static int mov_seek_stream(AVFormatContext *s, AVStream *st, int64_t timestamp, int flags)
11398 {
11399  MOVStreamContext *sc = st->priv_data;
11400  FFStream *const sti = ffstream(st);
11401  int sample, time_sample, ret, requested_sample;
11402  int64_t next_ts;
11403  unsigned int i;
11404 
11405  // Here we consider timestamp to be PTS, hence try to offset it so that we
11406  // can search over the DTS timeline.
11407  timestamp -= (sc->min_corrected_pts + sc->dts_shift);
11408 
11409  ret = mov_seek_fragment(s, st, timestamp);
11410  if (ret < 0)
11411  return ret;
11412 
11413  for (;;) {
11414  sample = av_index_search_timestamp(st, timestamp, flags);
11415  av_log(s, AV_LOG_TRACE, "stream %d, timestamp %"PRId64", sample %d\n", st->index, timestamp, sample);
11416  if (sample < 0 && sti->nb_index_entries && timestamp < sti->index_entries[0].timestamp)
11417  sample = 0;
11418  if (sample < 0) /* not sure what to do */
11419  return AVERROR_INVALIDDATA;
11420 
11421  if (!sample || can_seek_to_key_sample(st, sample, timestamp))
11422  break;
11423 
11424  next_ts = timestamp - FFMAX(sc->min_sample_duration, 1);
11425  requested_sample = av_index_search_timestamp(st, next_ts, flags);
11426 
11427  // If we've reached a different sample trying to find a good pts to
11428  // seek to, give up searching because we'll end up seeking back to
11429  // sample 0 on every seek.
11430  if (sample != requested_sample && !can_seek_to_key_sample(st, requested_sample, next_ts))
11431  break;
11432 
11433  timestamp = next_ts;
11434  }
11435 
11437  av_log(s, AV_LOG_TRACE, "stream %d, found sample %d\n", st->index, sc->current_sample);
11438  /* adjust time to sample index */
11439  if (sc->tts_data) {
11440  time_sample = 0;
11441  for (i = 0; i < sc->tts_count; i++) {
11442  int next = time_sample + sc->tts_data[i].count;
11443  if (next > sc->current_sample) {
11444  sc->tts_index = i;
11445  sc->tts_sample = sc->current_sample - time_sample;
11446  break;
11447  }
11448  time_sample = next;
11449  }
11450  }
11451 
11452  /* adjust stsd index */
11453  if (sc->chunk_count) {
11454  time_sample = 0;
11455  for (i = 0; i < sc->stsc_count; i++) {
11456  int64_t next = time_sample + mov_get_stsc_samples(sc, i);
11457  if (next > sc->current_sample) {
11458  sc->stsc_index = i;
11459  sc->stsc_sample = sc->current_sample - time_sample;
11460  break;
11461  }
11462  av_assert0(next == (int)next);
11463  time_sample = next;
11464  }
11465  }
11466 
11467  return sample;
11468 }
11469 
11471 {
11472  MOVStreamContext *sc = st->priv_data;
11473  FFStream *const sti = ffstream(st);
11474  int64_t first_ts = sti->index_entries[0].timestamp;
11476  int64_t off;
11477 
11479  return 0;
11480 
11481  /* compute skip samples according to stream start_pad, seek ts and first ts */
11482  off = av_rescale_q(ts - first_ts, st->time_base,
11483  (AVRational){1, st->codecpar->sample_rate});
11484  return FFMAX(sc->start_pad - off, 0);
11485 }
11486 
11487 static int mov_read_seek(AVFormatContext *s, int stream_index, int64_t sample_time, int flags)
11488 {
11489  MOVContext *mc = s->priv_data;
11490  AVStream *st;
11491  FFStream *sti;
11492  int sample;
11493  int i;
11494 
11495  if (stream_index >= s->nb_streams)
11496  return AVERROR_INVALIDDATA;
11497 
11498  st = s->streams[stream_index];
11499  sti = ffstream(st);
11500  sample = mov_seek_stream(s, st, sample_time, flags);
11501  if (sample < 0)
11502  return sample;
11503 
11504  if (mc->seek_individually) {
11505  /* adjust seek timestamp to found sample timestamp */
11506  int64_t seek_timestamp = sti->index_entries[sample].timestamp;
11508 
11509  for (i = 0; i < s->nb_streams; i++) {
11510  AVStream *const st = s->streams[i];
11511  FFStream *const sti = ffstream(st);
11512  int64_t timestamp;
11513 
11514  if (stream_index == i)
11515  continue;
11516 
11517  timestamp = av_rescale_q(seek_timestamp, s->streams[stream_index]->time_base, st->time_base);
11518  sample = mov_seek_stream(s, st, timestamp, flags);
11519  if (sample >= 0)
11521  }
11522  } else {
11523  for (i = 0; i < s->nb_streams; i++) {
11524  MOVStreamContext *sc;
11525  st = s->streams[i];
11526  sc = st->priv_data;
11527  mov_current_sample_set(sc, 0);
11528  }
11529  while (1) {
11530  MOVStreamContext *sc;
11532  if (!entry)
11533  return AVERROR_INVALIDDATA;
11534  sc = st->priv_data;
11535  if (sc->ffindex == stream_index && sc->current_sample == sample)
11536  break;
11538  }
11539  }
11540  return 0;
11541 }
11542 
11543 #define OFFSET(x) offsetof(MOVContext, x)
11544 #define FLAGS AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM
11545 static const AVOption mov_options[] = {
11546  {"use_absolute_path",
11547  "allow using absolute path when opening alias, this is a possible security issue",
11548  OFFSET(use_absolute_path), AV_OPT_TYPE_BOOL, {.i64 = 0},
11549  0, 1, FLAGS},
11550  {"seek_streams_individually",
11551  "Seek each stream individually to the closest point",
11552  OFFSET(seek_individually), AV_OPT_TYPE_BOOL, { .i64 = 1 },
11553  0, 1, FLAGS},
11554  {"ignore_editlist", "Ignore the edit list atom.", OFFSET(ignore_editlist), AV_OPT_TYPE_BOOL, {.i64 = 0},
11555  0, 1, FLAGS},
11556  {"advanced_editlist",
11557  "Modify the AVIndex according to the editlists. Use this option to decode in the order specified by the edits.",
11558  OFFSET(advanced_editlist), AV_OPT_TYPE_BOOL, {.i64 = 1},
11559  0, 1, FLAGS},
11560  {"ignore_chapters", "", OFFSET(ignore_chapters), AV_OPT_TYPE_BOOL, {.i64 = 0},
11561  0, 1, FLAGS},
11562  {"use_mfra_for",
11563  "use mfra for fragment timestamps",
11564  OFFSET(use_mfra_for), AV_OPT_TYPE_INT, {.i64 = FF_MOV_FLAG_MFRA_AUTO},
11566  .unit = "use_mfra_for"},
11567  {"auto", "auto", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_AUTO}, 0, 0,
11568  FLAGS, .unit = "use_mfra_for" },
11569  {"dts", "dts", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_DTS}, 0, 0,
11570  FLAGS, .unit = "use_mfra_for" },
11571  {"pts", "pts", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_PTS}, 0, 0,
11572  FLAGS, .unit = "use_mfra_for" },
11573  {"use_tfdt", "use tfdt for fragment timestamps", OFFSET(use_tfdt), AV_OPT_TYPE_BOOL, {.i64 = 1},
11574  0, 1, FLAGS},
11575  { "export_all", "Export unrecognized metadata entries", OFFSET(export_all),
11576  AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = FLAGS },
11577  { "export_xmp", "Export full XMP metadata", OFFSET(export_xmp),
11578  AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = FLAGS },
11579  { "activation_bytes", "Secret bytes for Audible AAX files", OFFSET(activation_bytes),
11581  { "audible_key", "AES-128 Key for Audible AAXC files", OFFSET(audible_key),
11583  { "audible_iv", "AES-128 IV for Audible AAXC files", OFFSET(audible_iv),
11585  { "audible_fixed_key", // extracted from libAAX_SDK.so and AAXSDKWin.dll files!
11586  "Fixed key used for handling Audible AAX files", OFFSET(audible_fixed_key),
11587  AV_OPT_TYPE_BINARY, {.str="77214d4b196a87cd520045fd20a51d67"},
11588  .flags = AV_OPT_FLAG_DECODING_PARAM },
11589  { "decryption_key", "The media decryption key (hex)", OFFSET(decryption_key), AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM },
11590  { "enable_drefs", "Enable external track support.", OFFSET(enable_drefs), AV_OPT_TYPE_BOOL,
11591  {.i64 = 0}, 0, 1, FLAGS },
11592  { "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 },
11593  { "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 },
11594 
11595  { NULL },
11596 };
11597 
11598 static const AVClass mov_class = {
11599  .class_name = "mov,mp4,m4a,3gp,3g2,mj2",
11600  .item_name = av_default_item_name,
11601  .option = mov_options,
11602  .version = LIBAVUTIL_VERSION_INT,
11603 };
11604 
11606  .p.name = "mov,mp4,m4a,3gp,3g2,mj2",
11607  .p.long_name = NULL_IF_CONFIG_SMALL("QuickTime / MOV"),
11608  .p.priv_class = &mov_class,
11609  .p.extensions = "mov,mp4,m4a,3gp,3g2,mj2,psp,m4b,ism,ismv,isma,f4v,avif,heic,heif",
11611  .priv_data_size = sizeof(MOVContext),
11612  .flags_internal = FF_INFMT_FLAG_INIT_CLEANUP,
11613  .read_probe = mov_probe,
11618 };
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:313
AV_CODEC_ID_PCM_S16LE
@ AV_CODEC_ID_PCM_S16LE
Definition: codec_id.h:337
flags
const SwsFlags flags[]
Definition: swscale.c:61
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:3033
mov_read_chpl
static int mov_read_chpl(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:598
AVMasteringDisplayMetadata::has_primaries
int has_primaries
Flag indicating whether the display primaries (and white point) are set.
Definition: mastering_display_metadata.h:62
mov_read_frma
static int mov_read_frma(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:7359
mov_read_meta
static int mov_read_meta(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5483
AV_CODEC_ID_EIA_608
@ AV_CODEC_ID_EIA_608
Definition: codec_id.h:581
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:469
MOVFragmentStreamInfo::first_tfra_pts
int64_t first_tfra_pts
Definition: isom.h:142
ff_rfps_add_frame
int ff_rfps_add_frame(AVFormatContext *ic, AVStream *st, int64_t ts)
add frame for rfps calculation.
Definition: demux.c:2282
read_image_iovl
static int read_image_iovl(AVFormatContext *s, const HEIFGrid *grid, AVStreamGroupTileGrid *tile_grid)
Definition: mov.c:10254
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:9190
AVMEDIA_TYPE_SUBTITLE
@ AVMEDIA_TYPE_SUBTITLE
Definition: avutil.h:203
AVIAMFSubmix::elements
AVIAMFSubmixElement ** elements
Array of submix elements.
Definition: iamf.h:565
skip_bits_long
static void skip_bits_long(GetBitContext *s, int n)
Skips the specified number of bits.
Definition: get_bits.h:276
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:406
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:357
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:382
AVCodecParameters::extradata
uint8_t * extradata
Extra binary data needed for initializing the decoder, codec-dependent.
Definition: codec_par.h:69
mov_read_dops
static int mov_read_dops(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:8426
can_seek_to_key_sample
static int can_seek_to_key_sample(AVStream *st, int sample, int64_t requested_pts)
Definition: mov.c:11371
AV_CODEC_ID_ADPCM_IMA_QT
@ AV_CODEC_ID_ADPCM_IMA_QT
Definition: codec_id.h:376
entry
#define entry
Definition: aom_film_grain_template.c:66
AVFMT_NO_BYTE_SEEK
#define AVFMT_NO_BYTE_SEEK
Format does not allow seeking by bytes.
Definition: avformat.h:486
AV_EF_EXPLODE
#define AV_EF_EXPLODE
abort decoding on minor error detection
Definition: defs.h:51
AVStreamGroup::id
int64_t id
Group type-specific group ID.
Definition: avformat.h:1117
AV_CODEC_ID_AC3
@ AV_CODEC_ID_AC3
Definition: codec_id.h:462
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:414
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:427
AVCodecParameters::codec_type
enum AVMediaType codec_type
General type of the encoded data.
Definition: codec_par.h:51
AVStreamGroup::tile_grid
struct AVStreamGroupTileGrid * tile_grid
Definition: avformat.h:1133
AVFMT_SHOW_IDS
#define AVFMT_SHOW_IDS
Show format stream IDs numbers.
Definition: avformat.h:476
AVSphericalMapping::projection
enum AVSphericalProjection projection
Projection type.
Definition: spherical.h: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:767
AV_STREAM_GROUP_PARAMS_LCEVC
@ AV_STREAM_GROUP_PARAMS_LCEVC
Definition: avformat.h:1092
MOVStreamContext::extradata
uint8_t ** extradata
extradata array (and size) for multiple stsd
Definition: isom.h:256
mov_class
static const AVClass mov_class
Definition: mov.c:11598
AVSphericalMapping::bound_bottom
uint32_t bound_bottom
Distance from the bottom edge.
Definition: spherical.h:188
MOVStreamContext::open_key_samples
int * open_key_samples
Definition: isom.h:248
AVUUID
uint8_t AVUUID[AV_UUID_LEN]
Definition: uuid.h:60
out
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:2279
mov_read_chnl
static int mov_read_chnl(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1192
mov_read_moof
static int mov_read_moof(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1816
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:706
AVCodecParameters
This struct describes the properties of an encoded stream.
Definition: codec_par.h:47
HEIFItem::icc_profile
uint8_t * icc_profile
Definition: isom.h:309
AVFMT_FLAG_IGNIDX
#define AVFMT_FLAG_IGNIDX
Ignore index.
Definition: avformat.h:1417
AVExifMetadata
Definition: exif.h:76
sanity_checks
static int sanity_checks(void *log_obj, MOVStreamContext *sc, int index)
Definition: mov.c:5117
av_stristr
char * av_stristr(const char *s1, const char *s2)
Locate the first case-independent occurrence in the string haystack of the string needle.
Definition: avstring.c:58
AVCodecParameters::color_space
enum AVColorSpace color_space
Definition: codec_par.h:169
avformat_new_stream
AVStream * avformat_new_stream(AVFormatContext *s, const struct AVCodec *c)
Add a new stream to a media file.
ff_replaygain_export
int ff_replaygain_export(AVStream *st, AVDictionary *metadata)
Parse replaygain tags and export them as per-stream side data.
Definition: replaygain.c:94
tmcd_is_referenced
static int tmcd_is_referenced(AVFormatContext *s, int tmcd_id)
Definition: mov.c:10000
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:11545
mov_codec_id
static int mov_codec_id(AVStream *st, uint32_t format)
Definition: mov.c:2628
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:8817
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:620
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:419
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:2251
test_same_origin
static int test_same_origin(const char *src, const char *ref)
Definition: mov.c:4960
cbcs_scheme_decrypt
static int cbcs_scheme_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
Definition: mov.c:8249
MOVFragment::base_data_offset
uint64_t base_data_offset
Definition: isom.h:104
MOVStreamContext
Definition: isom.h:173
AVChannelLayout::map
AVChannelCustom * map
This member must be used when the channel order is AV_CHANNEL_ORDER_CUSTOM.
Definition: channel_layout.h:370
MOVStreamContext::stsc_data
MOVStsc * stsc_data
Definition: isom.h:194
ff_buffer_packet
int ff_buffer_packet(AVFormatContext *s, AVPacket *pkt)
Definition: demux.c:612
IS_MATRIX_IDENT
#define IS_MATRIX_IDENT(matrix)
Definition: mov.c:5501
AVStreamGroup::disposition
int disposition
Stream group disposition - a combination of AV_DISPOSITION_* flags.
Definition: avformat.h:1175
av_unused
#define av_unused
Definition: attributes.h:151
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:3664
MOVStreamContext::spherical
AVSphericalMapping * spherical
Definition: isom.h:265
mask
int mask
Definition: mediacodecdec_common.c:154
out_size
int out_size
Definition: movenc.c:56
AV_CODEC_ID_MPEG4
@ AV_CODEC_ID_MPEG4
Definition: codec_id.h:64
AVContentLightMetadata::MaxCLL
unsigned MaxCLL
Max content light level (cd/m^2).
Definition: mastering_display_metadata.h:111
avio_get_str16be
int avio_get_str16be(AVIOContext *pb, int maxlen, char *buf, int buflen)
MOVEncryptionIndex
Definition: isom.h:126
av_encryption_init_info_free
void av_encryption_init_info_free(AVEncryptionInitInfo *info)
Frees the given encryption init info object.
Definition: encryption_info.c:216
mov_read_avss
static int mov_read_avss(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2256
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:56
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:279
mov_read_custom
static int mov_read_custom(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5343
pixdesc.h
cleanup
static av_cold void cleanup(FlashSV2Context *s)
Definition: flashsv2enc.c:130
AVFormatContext::streams
AVStream ** streams
A list of all streams in the file.
Definition: avformat.h:1332
HEIFGrid::nb_tiles
int nb_tiles
Definition: isom.h:318
ID3v1_GENRE_MAX
#define ID3v1_GENRE_MAX
Definition: id3v1.h:29
MOVSbgp
Definition: isom.h:121
MOVCtts
Definition: isom.h:68
AVPacketSideData
This structure stores auxiliary information for decoding, presenting, or otherwise processing the cod...
Definition: packet.h:409
mov_read_extradata
static int mov_read_extradata(MOVContext *c, AVIOContext *pb, MOVAtom atom, enum AVCodecID codec_id)
Definition: mov.c:2225
AVCOL_RANGE_JPEG
@ AVCOL_RANGE_JPEG
Full range content.
Definition: pixfmt.h:767
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:1918
mov_read_idat
static int mov_read_idat(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:8811
AVPacket::data
uint8_t * data
Definition: packet.h:558
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:2271
AVAmbientViewingEnvironment::ambient_light_x
AVRational ambient_light_x
Normalized x chromaticity coordinate of the environmental ambient light in the nominal viewing enviro...
Definition: ambient_viewing_environment.h:47
AVCodecParameters::seek_preroll
int seek_preroll
Audio only.
Definition: codec_par.h:214
av_dynarray2_add
void * av_dynarray2_add(void **tab_ptr, int *nb_ptr, size_t elem_size, const uint8_t *elem_data)
Add an element of size elem_size to a dynamic array.
Definition: mem.c:343
AVOption
AVOption.
Definition: opt.h:429
MOVContext::trex_data
MOVTrackExt * trex_data
Definition: isom.h:338
mov_read_stps
static int mov_read_stps(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:3321
MOVContext::bitrates
int * bitrates
bitrates read before streams creation
Definition: isom.h:353
b
#define b
Definition: input.c:42
AVCOL_TRC_UNSPECIFIED
@ AVCOL_TRC_UNSPECIFIED
Definition: pixfmt.h:664
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:5509
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:2072
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:1957
mov_read_strf
static int mov_read_strf(MOVContext *c, AVIOContext *pb, MOVAtom atom)
An strf atom is a BITMAPINFOHEADER struct.
Definition: mov.c:2541
AV_CODEC_ID_ALAC
@ AV_CODEC_ID_ALAC
Definition: codec_id.h:475
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:440
av_iamf_mix_presentation_free
void av_iamf_mix_presentation_free(AVIAMFMixPresentation **pmix_presentation)
Free an AVIAMFMixPresentation and all its contents.
Definition: iamf.c:534
mov_parse_auxiliary_info
static int mov_parse_auxiliary_info(MOVContext *c, MOVStreamContext *sc, AVIOContext *pb, MOVEncryptionIndex *encryption_index)
Definition: mov.c:7567
mov_seek_stream
static int mov_seek_stream(AVFormatContext *s, AVStream *st, int64_t timestamp, int flags)
Definition: mov.c:11397
mov_read_saio
static int mov_read_saio(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:7713
mov_get_stsc_samples
static int64_t mov_get_stsc_samples(MOVStreamContext *sc, unsigned int index)
Definition: mov.c:3306
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:3873
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:11012
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:489
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:576
AVCodecParameters::codec_tag
uint32_t codec_tag
Additional information about the codec (corresponds to the AVI FOURCC).
Definition: codec_par.h:59
fixed_key
static const uint8_t fixed_key[]
Definition: aes_ctr.c:45
AV_SPHERICAL_EQUIRECTANGULAR_TILE
@ AV_SPHERICAL_EQUIRECTANGULAR_TILE
Video represents a portion of a sphere mapped on a flat surface using equirectangular projection.
Definition: spherical.h:68
AVStereo3D::baseline
uint32_t baseline
The distance between the centres of the lenses of the camera system, in micrometers.
Definition: stereo3d.h:228
MOVDref::dir
char * dir
Definition: isom.h:88
mov_current_sample_set
static void mov_current_sample_set(MOVStreamContext *sc, int current_sample)
Definition: mov.c:4177
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:632
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:1568
av_sub_q
AVRational av_sub_q(AVRational b, AVRational c)
Subtract one rational from another.
Definition: rational.c:101
cffstream
static const av_always_inline FFStream * cffstream(const AVStream *st)
Definition: internal.h:352
mov_read_esds
static int mov_read_esds(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:847
MOVStreamContext::sample_count
unsigned int sample_count
Definition: isom.h:205
MOVFragmentIndex::allocated_size
int allocated_size
Definition: isom.h:161
MOVTrackExt::flags
unsigned flags
Definition: isom.h:118
AVChannelLayout::nb_channels
int nb_channels
Number of channels in this layout.
Definition: channel_layout.h:329
HEIFItem::height
int height
Definition: isom.h: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:2563
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:7079
FFIOContext
Definition: avio_internal.h:28
AV_PKT_FLAG_KEY
#define AV_PKT_FLAG_KEY
The packet contains a keyframe.
Definition: packet.h:613
init_get_bits
static int init_get_bits(GetBitContext *s, const uint8_t *buffer, int bit_size)
Initialize GetBitContext.
Definition: get_bits.h:512
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:8356
mov_read_sdtp
static int mov_read_sdtp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:3630
mov_read_jp2h
static int mov_read_jp2h(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2261
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:441
mov_read_tfhd
static int mov_read_tfhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5614
AV_CODEC_ID_BIN_DATA
@ AV_CODEC_ID_BIN_DATA
Definition: codec_id.h:612
av_malloc
#define av_malloc(s)
Definition: tableprint_vlc.h:31
OPUS_SEEK_PREROLL_MS
#define OPUS_SEEK_PREROLL_MS
Definition: oggparseopus.c:36
AV_CODEC_ID_H261
@ AV_CODEC_ID_H261
Definition: codec_id.h:55
IAMFMixPresentation::cmix
const AVIAMFMixPresentation * cmix
Definition: iamf.h:108
mov_read_wide
static int mov_read_wide(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6193
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:191
ff_get_extradata
int ff_get_extradata(void *logctx, AVCodecParameters *par, AVIOContext *pb, int size)
Allocate extradata with additional AV_INPUT_BUFFER_PADDING_SIZE at end which is always set to 0 and f...
Definition: demux_utils.c:326
AVStereo3D::horizontal_field_of_view
AVRational horizontal_field_of_view
Horizontal field of view, in degrees.
Definition: stereo3d.h:239
skip_bits
static void skip_bits(GetBitContext *s, int n)
Definition: get_bits.h:379
AVCodecParameters::color_primaries
enum AVColorPrimaries color_primaries
Definition: codec_par.h:167
AVEncryptionInfo::scheme
uint32_t scheme
The fourcc encryption scheme, in big-endian byte order.
Definition: encryption_info.h:45
MOVStreamContext::stsc_count
unsigned int stsc_count
Definition: isom.h:193
MOVStreamContext::has_palette
int has_palette
Definition: isom.h:234
AVPROBE_SCORE_MAX
#define AVPROBE_SCORE_MAX
maximum score
Definition: avformat.h:463
AV_STEREO3D_SIDEBYSIDE
@ AV_STEREO3D_SIDEBYSIDE
Views are next to each other.
Definition: stereo3d.h:64
MOVIndexRange::start
int64_t start
Definition: isom.h:169
AVPacketSideData::size
size_t size
Definition: packet.h:411
get_bits
static unsigned int get_bits(GetBitContext *s, int n)
Read 1-25 bits.
Definition: get_bits.h:333
ff_remove_stream
void ff_remove_stream(AVFormatContext *s, AVStream *st)
Remove a stream from its AVFormatContext and free it.
Definition: avformat.c:113
OFFSET
#define OFFSET(x)
Definition: mov.c:11543
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:10135
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:736
avpriv_set_pts_info
void avpriv_set_pts_info(AVStream *st, int pts_wrap_bits, unsigned int pts_num, unsigned int pts_den)
Set the time base and wrapping info for a given stream.
Definition: avformat.c:777
FF_DVDCLUT_CLUT_LEN
#define FF_DVDCLUT_CLUT_LEN
Definition: dvdclut.h:28
AVEncryptionInfo::skip_byte_block
uint32_t skip_byte_block
Only used for pattern encryption.
Definition: encryption_info.h:57
finish
static void finish(void)
Definition: movenc.c:374
aax_filter
static int aax_filter(uint8_t *input, int size, MOVContext *c)
Definition: mov.c:1506
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:3823
av_packet_add_side_data
int av_packet_add_side_data(AVPacket *pkt, enum AVPacketSideDataType type, uint8_t *data, size_t size)
Wrap an existing array as a packet side data.
Definition: packet.c:198
MOVStreamContext::mastering
AVMasteringDisplayMetadata * mastering
Definition: isom.h:267
AV_CODEC_ID_SPEEX
@ AV_CODEC_ID_SPEEX
Definition: codec_id.h:494
AV_FOURCC_MAX_STRING_SIZE
#define AV_FOURCC_MAX_STRING_SIZE
Definition: avutil.h:345
AV_PKT_DATA_PALETTE
@ AV_PKT_DATA_PALETTE
An AV_PKT_DATA_PALETTE side data packet contains exactly AVPALETTE_SIZE bytes worth of palette.
Definition: packet.h:47
ffstream
static av_always_inline FFStream * ffstream(AVStream *st)
Definition: internal.h:347
MOVFragmentIndexItem::current
int current
Definition: isom.h:155
AVFMT_SEEK_TO_PTS
#define AVFMT_SEEK_TO_PTS
Seeking is based on PTS.
Definition: avformat.h:499
AV_CODEC_ID_PCM_S16BE
@ AV_CODEC_ID_PCM_S16BE
Definition: codec_id.h:338
mov_read_mdhd
static int mov_read_mdhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1872
mov_read_ctts
static int mov_read_ctts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:3675
MOVTrackExt
Definition: isom.h:113
MOV_FRAG_SAMPLE_FLAG_IS_NON_SYNC
#define MOV_FRAG_SAMPLE_FLAG_IS_NON_SYNC
Definition: isom.h:418
fail
#define fail()
Definition: checkasm.h:206
mov_read_aclr
static int mov_read_aclr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2336
AVSEEK_FLAG_ANY
#define AVSEEK_FLAG_ANY
seek to any frame, even non-keyframes
Definition: avformat.h:2376
av_int2float
static av_always_inline float av_int2float(uint32_t i)
Reinterpret a 32-bit integer as a float.
Definition: intfloat.h:40
MOVFragment::found_tfhd
int found_tfhd
Definition: isom.h:102
AVStreamGroupTileGrid
AVStreamGroupTileGrid holds information on how to combine several independent images on a single canv...
Definition: avformat.h:951
MOVContext::decryption_key
uint8_t * decryption_key
Definition: isom.h:373
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:114
timecode.h
get_current_frag_stream_info
static MOVFragmentStreamInfo * get_current_frag_stream_info(MOVFragmentIndex *frag_index)
Definition: mov.c:1625
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:336
FFStream::index_entries_allocated_size
unsigned int index_entries_allocated_size
Definition: internal.h:187
read_close
static av_cold int read_close(AVFormatContext *ctx)
Definition: libcdio.c:143
mov_read_amve
static int mov_read_amve(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6552
mov_read_enda
static int mov_read_enda(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1986
mov_read_chap
static int mov_read_chap(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5661
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:612
MOV_TRUN_SAMPLE_DURATION
#define MOV_TRUN_SAMPLE_DURATION
Definition: isom.h:412
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:10149
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:460
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
av_reduce
int av_reduce(int *dst_num, int *dst_den, int64_t num, int64_t den, int64_t max)
Reduce a fraction.
Definition: rational.c:35
MOVStreamContext::extradata_size
int * extradata_size
Definition: isom.h:257
AVIAMFAudioElement::audio_element_type
enum AVIAMFAudioElementType audio_element_type
Audio element type as defined in section 3.6 of IAMF.
Definition: iamf.h:388
loop
static int loop
Definition: ffplay.c:335
ff_data_to_hex
char * ff_data_to_hex(char *buf, const uint8_t *src, int size, int lowercase)
Write hexadecimal string corresponding to given binary data.
Definition: utils.c:458
update_frag_index
static int update_frag_index(MOVContext *c, int64_t offset)
Definition: mov.c:1740
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:6624
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:7629
MOV_FRAG_SAMPLE_FLAG_DEPENDS_YES
#define MOV_FRAG_SAMPLE_FLAG_DEPENDS_YES
Definition: isom.h:425
mov_merge_tts_data
static int mov_merge_tts_data(MOVContext *mov, AVStream *st, int flags)
Definition: mov.c:4588
MOVContext::idat_offset
int64_t idat_offset
Definition: isom.h:386
MOV_TRUN_DATA_OFFSET
#define MOV_TRUN_DATA_OFFSET
Definition: isom.h:410
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:2293
mov_read_adrm
static int mov_read_adrm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1380
av_get_bits_per_sample
int av_get_bits_per_sample(enum AVCodecID codec_id)
Return codec bits per sample.
Definition: utils.c:549
AVCodecParameters::color_trc
enum AVColorTransferCharacteristic color_trc
Definition: codec_par.h:168
IAMFContext::audio_elements
IAMFAudioElement ** audio_elements
Definition: iamf.h:131
MOVFragmentIndex::complete
int complete
Definition: isom.h:162
AV_CODEC_ID_PCM_S8
@ AV_CODEC_ID_PCM_S8
Definition: codec_id.h:341
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
pkt
AVPacket * pkt
Definition: movenc.c:60
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:210
AV_CODEC_ID_MACE3
@ AV_CODEC_ID_MACE3
Definition: codec_id.h:468
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:9871
AV_CH_LOW_FREQUENCY
#define AV_CH_LOW_FREQUENCY
Definition: channel_layout.h:178
duration
int64_t duration
Definition: movenc.c:65
MOVEncryptionIndex::auxiliary_offsets
uint64_t * auxiliary_offsets
Absolute seek position.
Definition: isom.h:135
read_packet
static int read_packet(void *opaque, uint8_t *buf, int buf_size)
Definition: avio_read_callback.c:42
AV_FIELD_UNKNOWN
@ AV_FIELD_UNKNOWN
Definition: defs.h:212
MOVStreamContext::dts_shift
int dts_shift
dts shift when ctts is negative
Definition: isom.h:232
av_timecode_init
int av_timecode_init(AVTimecode *tc, AVRational rate, int flags, int frame_start, void *log_ctx)
Init a timecode struct with the passed parameters.
Definition: timecode.c:201
AVCodecParameters::frame_size
int frame_size
Audio only.
Definition: codec_par.h:195
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:10320
AV_STREAM_GROUP_PARAMS_IAMF_MIX_PRESENTATION
@ AV_STREAM_GROUP_PARAMS_IAMF_MIX_PRESENTATION
Definition: avformat.h:1090
ff_add_attached_pic
int ff_add_attached_pic(AVFormatContext *s, AVStream *st, AVIOContext *pb, AVBufferRef **buf, int size)
Add an attached pic to an AVStream.
Definition: demux_utils.c:107
add_tts_entry
static int add_tts_entry(MOVTimeToSample **tts_data, unsigned int *tts_count, unsigned int *allocated_size, int count, int offset, unsigned int duration)
Definition: mov.c:4068
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:462
MOV_MERGE_STTS
#define MOV_MERGE_STTS
Definition: mov.c:4582
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:6486
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:5135
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:408
av_new_packet
int av_new_packet(AVPacket *pkt, int size)
Allocate the payload of a packet and initialize its fields with default values.
Definition: packet.c:99
AV_CODEC_ID_BMP
@ AV_CODEC_ID_BMP
Definition: codec_id.h:130
AV_CODEC_ID_EVC
@ AV_CODEC_ID_EVC
Definition: codec_id.h:325
IAMFLayer::substream_count
unsigned int substream_count
Definition: iamf.h:78
MOV_TFHD_DEFAULT_DURATION
#define MOV_TFHD_DEFAULT_DURATION
Definition: isom.h:404
ALAC_EXTRADATA_SIZE
#define ALAC_EXTRADATA_SIZE
DRM_BLOB_SIZE
#define DRM_BLOB_SIZE
Definition: mov.c:1378
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
AVChannelLayout::u
union AVChannelLayout::@476 u
Details about which channels are present in this layout.
AVInputFormat::name
const char * name
A comma separated list of short names for the format.
Definition: avformat.h:549
MOVContext::aes_decrypt
struct AVAES * aes_decrypt
Definition: isom.h:372
AVSphericalMapping::bound_top
uint32_t bound_top
Distance from the top edge.
Definition: spherical.h:186
AVMEDIA_TYPE_AUDIO
@ AVMEDIA_TYPE_AUDIO
Definition: avutil.h:201
AV_CODEC_ID_VP9
@ AV_CODEC_ID_VP9
Definition: codec_id.h:222
MOVFragmentIndex::nb_items
int nb_items
Definition: isom.h:164
AVCodecParameters::width
int width
Video only.
Definition: codec_par.h:134
MOVTimeToSample
Definition: isom.h:57
AV_CHANNEL_ORDER_UNSPEC
@ AV_CHANNEL_ORDER_UNSPEC
Only the channel count is specified, without any further information about the channel order.
Definition: channel_layout.h:119
AV_CODEC_ID_MP2
@ AV_CODEC_ID_MP2
Definition: codec_id.h:459
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:411
av_q2d
static double av_q2d(AVRational a)
Convert an AVRational to a double.
Definition: rational.h:104
AVIndexEntry::size
int size
Definition: avformat.h:609
av_channel_layout_from_mask
int av_channel_layout_from_mask(AVChannelLayout *channel_layout, uint64_t mask)
Initialize a native channel layout from a bitmask indicating which channels are present.
Definition: channel_layout.c:252
MOVStreamContext::keyframe_absent
int keyframe_absent
Definition: isom.h:207
info
MIPS optimizations info
Definition: mips.txt:2
MOVStts::duration
unsigned int duration
Definition: isom.h:65
fc
#define fc(width, name, range_min, range_max)
Definition: cbs_av1.c:494
MOVStreamContext::coll_size
size_t coll_size
Definition: isom.h:270
tile_rows
int tile_rows
Definition: h265_levels.c:217
mov_estimate_video_delay
static void mov_estimate_video_delay(MOVContext *c, AVStream *st)
Definition: mov.c:4097
AVIndexEntry::timestamp
int64_t timestamp
Timestamp in AVStream.time_base units, preferably the time from which on correctly decoded frames are...
Definition: avformat.h:600
av_assert0
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:41
MOVStreamContext::min_corrected_pts
int64_t min_corrected_pts
minimum Composition time shown by the edits excluding empty edits.
Definition: isom.h:212
ffio_read_leb
unsigned int ffio_read_leb(AVIOContext *s)
Read a unsigned integer coded as a variable number of up to eight little-endian bytes,...
Definition: aviobuf.c: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:8530
AV_LOG_DEBUG
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:231
AVPacketSideData::data
uint8_t * data
Definition: packet.h:410
ctx
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:6055
AV_PKT_DATA_STEREO3D
@ AV_PKT_DATA_STEREO3D
This side data should be associated with a video stream and contains Stereoscopic 3D information in f...
Definition: packet.h:111
nb_streams
static int nb_streams
Definition: ffprobe.c:340
av_rescale_q
int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq)
Rescale a 64-bit integer by 2 rational numbers.
Definition: mathematics.c:142
ff_iamfdec_read_descriptors
int ff_iamfdec_read_descriptors(IAMFContext *c, AVIOContext *pb, int max_size, void *log_ctx)
Definition: iamf_parse.c:1165
FFStream::display_aspect_ratio
AVRational display_aspect_ratio
display aspect ratio (0 if unknown)
Definition: internal.h:296
IAMFContext::nb_mix_presentations
int nb_mix_presentations
Definition: iamf.h:134
mov_find_next_sample
static AVIndexEntry * mov_find_next_sample(AVFormatContext *s, AVStream **st)
Definition: mov.c:10939
AV_CODEC_ID_TARGA_Y216
@ AV_CODEC_ID_TARGA_Y216
Definition: codec_id.h:258
MOVStreamContext::cenc
struct MOVStreamContext::@440 cenc
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:8510
MOVParseTableEntry::parse
int(* parse)(MOVContext *ctx, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:84
codec_id
enum AVCodecID codec_id
Definition: vaapi_decode.c:410
AV_CODEC_ID_SVQ3
@ AV_CODEC_ID_SVQ3
Definition: codec_id.h:75
key
const char * key
Definition: hwcontext_opencl.c:189
AVCodecParameters::nb_coded_side_data
int nb_coded_side_data
Amount of entries in coded_side_data.
Definition: codec_par.h:86
MOVStreamContext::sdtp_data
uint8_t * sdtp_data
Definition: isom.h:189
color_range
color_range
Definition: vf_selectivecolor.c:43
AVMEDIA_TYPE_DATA
@ AVMEDIA_TYPE_DATA
Opaque data information usually continuous.
Definition: avutil.h:202
mov_read_udta_string
static int mov_read_udta_string(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:345
mov_read_stss
static int mov_read_stss(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:3362
mov_read_ddts
static int mov_read_ddts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1120
mov_read_uuid
static int mov_read_uuid(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:7232
AVCOL_PRI_UNSPECIFIED
@ AVCOL_PRI_UNSPECIFIED
Definition: pixfmt.h:639
MOVTrackExt::duration
unsigned duration
Definition: isom.h:116
AV_CODEC_ID_H264
@ AV_CODEC_ID_H264
Definition: codec_id.h:79
av_content_light_metadata_alloc
AVContentLightMetadata * av_content_light_metadata_alloc(size_t *size)
Allocate an AVContentLightMetadata structure and set its fields to default values.
Definition: mastering_display_metadata.c:72
tmp
static uint8_t tmp[40]
Definition: aes_ctr.c:52
av_sha_final
void av_sha_final(AVSHA *ctx, uint8_t *digest)
Finish hashing and output digest value.
Definition: sha.c:347
MOVStreamContext::current_sample
int current_sample
Definition: isom.h:213
MOVFragmentStreamInfo::sidx_pts
int64_t sidx_pts
Definition: isom.h:141
MAX_REORDER_DELAY
#define MAX_REORDER_DELAY
Definition: mov.c:4096
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:9945
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:468
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:6213
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:7457
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:8758
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:1264
av_realloc_f
#define av_realloc_f(p, o, n)
Definition: tableprint_vlc.h:33
mov_read_stts
static int mov_read_stts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:3510
MOVStreamContext::index_ranges
MOVIndexRange * index_ranges
Definition: isom.h:215
DDTS_SIZE
#define DDTS_SIZE
internal.h
MOVTrackExt::stsd_id
unsigned stsd_id
Definition: isom.h:115
AVStreamGroupLCEVC::height
int height
Height of the final image for presentation.
Definition: avformat.h:1084
find_prev_closest_index
static int find_prev_closest_index(AVStream *st, AVIndexEntry *e_old, int nb_old, MOVTimeToSample *tts_data, int64_t tts_count, int64_t timestamp_pts, int flag, int64_t *index, int64_t *tts_index, int64_t *tts_sample)
Find the closest previous frame to the timestamp_pts, in e_old index entries.
Definition: mov.c:3919
set_frag_stream
static void set_frag_stream(MOVFragmentIndex *frag_index, int id)
Definition: mov.c:1605
mov_read_free
static int mov_read_free(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:7337
mov_realloc_extradata
static int mov_realloc_extradata(AVCodecParameters *par, MOVAtom atom)
Definition: mov.c:2188
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:225
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:2374
aes.h
AVClass
Describe the class of an AVClass context structure.
Definition: log.h:76
MOVStreamContext::tts_sample
int tts_sample
Definition: isom.h:202
avpriv_dv_get_packet
int avpriv_dv_get_packet(DVDemuxContext *c, AVPacket *pkt)
Definition: dv.c:731
MOVContext::ignore_editlist
int ignore_editlist
Definition: isom.h: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:484
mov_read_ftyp
static int mov_read_ftyp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1520
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:10170
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:3756
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:9591
AVPALETTE_SIZE
#define AVPALETTE_SIZE
Definition: pixfmt.h:32
MOVDref::nlvl_to
int16_t nlvl_to
Definition: isom.h:91
get_eia608_packet
static int get_eia608_packet(AVIOContext *pb, AVPacket *pkt, int src_size)
Definition: mov.c:11036
AV_CODEC_ID_DVD_SUBTITLE
@ AV_CODEC_ID_DVD_SUBTITLE
Definition: codec_id.h:571
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:6395
av_default_item_name
const char * av_default_item_name(void *ptr)
Return the context name.
Definition: log.c:241
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:4989
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:438
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:7929
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:3781
FF_MOV_FLAG_MFRA_DTS
#define FF_MOV_FLAG_MFRA_DTS
Definition: isom.h:461
MOV_SAMPLE_DEPENDENCY_NO
#define MOV_SAMPLE_DEPENDENCY_NO
Definition: isom.h:434
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:478
mov_read_ilst
static int mov_read_ilst(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5288
MOVTimeToSample::duration
unsigned int duration
Definition: isom.h:59
AV_CH_FRONT_CENTER
#define AV_CH_FRONT_CENTER
Definition: channel_layout.h:177
AVCodecParameters::ch_layout
AVChannelLayout ch_layout
Audio only.
Definition: codec_par.h:180
get_frag_stream_info_from_pkt
static MOVFragmentStreamInfo * get_frag_stream_info_from_pkt(MOVFragmentIndex *frag_index, AVPacket *pkt, int id)
Definition: mov.c:8331
get_sgpd_sync_index
static uint32_t get_sgpd_sync_index(const MOVStreamContext *sc, int nal_unit_type)
Definition: mov.c:4510
mov_read_fiel
static int mov_read_fiel(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2154
parse
static int parse(AVCodecParserContext *s, AVCodecContext *avctx, const uint8_t **poutbuf, int *poutbuf_size, const uint8_t *buf, int buf_size)
Definition: apv_parser.c:45
MOV_MP4_TTML_TAG
#define MOV_MP4_TTML_TAG
Definition: isom.h:479
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:402
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:1143
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:1224
av_stereo3d_alloc_size
AVStereo3D * av_stereo3d_alloc_size(size_t *size)
Allocate an AVStereo3D structure and set its fields to default values.
Definition: stereo3d.c:40
index
int index
Definition: gxfenc.c:90
c
Undefined Behavior In the C some operations are like signed integer dereferencing freed accessing outside allocated Undefined Behavior must not occur in a C it is not safe even if the output of undefined operations is unused The unsafety may seem nit picking but Optimizing compilers have in fact optimized code on the assumption that no undefined Behavior occurs Optimizing code based on wrong assumptions can and has in some cases lead to effects beyond the output of computations The signed integer overflow problem in speed critical code Code which is highly optimized and works with signed integers sometimes has the problem that often the output of the computation does not c
Definition: undefined.txt:32
AVPROBE_SCORE_EXTENSION
#define AVPROBE_SCORE_EXTENSION
score for file extension
Definition: avformat.h:461
MOVSbgp::count
unsigned int count
Definition: isom.h:122
AVCodecParameters::sample_rate
int sample_rate
Audio only.
Definition: codec_par.h:184
mov_parse_stsd_subtitle
static void mov_parse_stsd_subtitle(MOVContext *c, AVIOContext *pb, AVStream *st, MOVStreamContext *sc, int64_t size)
Definition: mov.c:2843
cid
uint16_t cid
Definition: mxfenc.c:2314
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:3007
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:477
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:670
AVIAMFSubmixElement::audio_element_id
unsigned int audio_element_id
The id of the Audio Element this submix element references.
Definition: iamf.h:452
AV_CODEC_ID_EAC3
@ AV_CODEC_ID_EAC3
Definition: codec_id.h:499
should_retry
static int should_retry(AVIOContext *pb, int error_code)
Definition: mov.c:10969
avformat_stream_group_add_stream
int avformat_stream_group_add_stream(AVStreamGroup *stg, AVStream *st)
Add an already allocated stream to a stream group.
Definition: options.c:513
AV_PKT_DATA_SPHERICAL
@ AV_PKT_DATA_SPHERICAL
This side data should be associated with a video stream and corresponds to the AVSphericalMapping str...
Definition: packet.h:225
AVCodecParameters::extradata_size
int extradata_size
Size of the extradata content in bytes.
Definition: codec_par.h:73
AVIAMFSubmix
Submix layout as defined in section 3.7 of IAMF.
Definition: iamf.h:556
AV_WB32
#define AV_WB32(p, v)
Definition: intreadwrite.h:415
mov_read_pasp
static int mov_read_pasp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1348
MOVContext::dv_demux
DVDemuxContext * dv_demux
Definition: isom.h:334
AV_CODEC_ID_AAC
@ AV_CODEC_ID_AAC
Definition: codec_id.h:461
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:8668
mov_read_elst
static int mov_read_elst(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6266
MOVEncryptionIndex::auxiliary_info_default_size
uint8_t auxiliary_info_default_size
Definition: isom.h:134
AV_STREAM_GROUP_PARAMS_TILE_GRID
@ AV_STREAM_GROUP_PARAMS_TILE_GRID
Definition: avformat.h:1091
IAMFAudioElement
Definition: iamf.h:89
AV_UUID_LEN
#define AV_UUID_LEN
Definition: uuid.h:57
av_sat_sub64
#define av_sat_sub64
Definition: common.h:142
mov_read_header
static int mov_read_header(AVFormatContext *s)
Definition: mov.c:10690
AV_CODEC_ID_QCELP
@ AV_CODEC_ID_QCELP
Definition: codec_id.h:483
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:8124
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:349
mov_read_wave
static int mov_read_wave(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2384
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:436
cens_scheme_decrypt
static int cens_scheme_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
Definition: mov.c:8184
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:9883
AVPacket::size
int size
Definition: packet.h:559
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
FLAC_METADATA_TYPE_STREAMINFO
@ FLAC_METADATA_TYPE_STREAMINFO
Definition: flac.h:46
avformat_alloc_context
AVFormatContext * avformat_alloc_context(void)
Allocate an AVFormatContext.
Definition: options.c:162
MOVFragmentIndexItem
Definition: isom.h:152
get_current_encryption_info
static int get_current_encryption_info(MOVContext *c, MOVEncryptionIndex **encryption_index, MOVStreamContext **sc)
Gets the current encryption info and associated current stream context.
Definition: mov.c:7406
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:637
mov_current_sample_dec
static void mov_current_sample_dec(MOVStreamContext *sc)
Definition: mov.c:4165
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
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:460
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:326
uuid.h
ff_dvdclut_palette_extradata_cat
int ff_dvdclut_palette_extradata_cat(const uint32_t *clut, const size_t clut_size, AVCodecParameters *par)
Definition: dvdclut.c:28
mov_read_trun
static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5747
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:9229
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:403
size
int size
Definition: twinvq_data.h:10344
mov_read_chan
static int mov_read_chan(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1173
av_make_q
static AVRational av_make_q(int num, int den)
Create an AVRational.
Definition: rational.h:71
mov_read_stsc
static int mov_read_stsc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:3220
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:509
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:1131
MOVStreamContext::coll
AVContentLightMetadata * coll
Definition: isom.h:269
aes_ctr.h
ff_format_io_close
int ff_format_io_close(AVFormatContext *s, AVIOContext **pb)
Definition: avformat.c:868
mov_parse_heif_items
static int mov_parse_heif_items(AVFormatContext *s)
Definition: mov.c:10525
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:4015
MOVDref::path
char * path
Definition: isom.h:87
mov_current_sample_inc
static void mov_current_sample_inc(MOVStreamContext *sc)
Definition: mov.c:4153
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:51
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:557
mov_read_vexu_proj
static int mov_read_vexu_proj(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6840
fix_timescale
static void fix_timescale(MOVContext *c, MOVStreamContext *sc)
Definition: mov.c:5061
avio_r8
int avio_r8(AVIOContext *s)
Definition: aviobuf.c:606
IAMFAudioElement::substreams
IAMFSubStream * substreams
Definition: iamf.h:98
AVSphericalMapping::padding
uint32_t padding
Number of pixels to pad from the edge of each cube face.
Definition: spherical.h:200
a
The reader does not expect b to be semantically here and if the code is changed by maybe adding a a division or other the signedness will almost certainly be mistaken To avoid this confusion a new type was SUINT is the C unsigned type but it holds a signed int to use the same example SUINT a
Definition: undefined.txt:41
av_channel_layout_retype
int av_channel_layout_retype(AVChannelLayout *channel_layout, enum AVChannelOrder order, int flags)
Change the AVChannelOrder of a channel layout.
Definition: channel_layout.c:885
av_reallocp_array
int av_reallocp_array(void *ptr, size_t nmemb, size_t size)
Allocate, reallocate an array through a pointer to a pointer.
Definition: mem.c:225
AVIAMFAudioElement
Information on how to combine one or more audio streams, as defined in section 3.6 of IAMF.
Definition: iamf.h:356
AV_PRIMARY_EYE_NONE
@ AV_PRIMARY_EYE_NONE
Neither eye.
Definition: stereo3d.h:178
mov_read_default
static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:9469
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:480
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:713
mov_read_packet
static int mov_read_packet(AVFormatContext *s, AVPacket *pkt)
Definition: mov.c:11169
mov_read_infe
static int mov_read_infe(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:8908
offset
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf offset
Definition: writing_filters.txt:86
AVStreamGroupLCEVC::lcevc_index
unsigned int lcevc_index
Index of the LCEVC data stream in AVStreamGroup.
Definition: avformat.h:1076
AVStreamGroup::lcevc
struct AVStreamGroupLCEVC * lcevc
Definition: avformat.h:1134
attributes.h
AV_CODEC_ID_LCEVC
@ AV_CODEC_ID_LCEVC
Definition: codec_id.h:614
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:564
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:498
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:10601
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:315
AV_STREAM_GROUP_PARAMS_IAMF_AUDIO_ELEMENT
@ AV_STREAM_GROUP_PARAMS_IAMF_AUDIO_ELEMENT
Definition: avformat.h:1089
AVEncryptionInitInfo::next
struct AVEncryptionInitInfo * next
An optional pointer to the next initialization info in the list.
Definition: encryption_info.h:122
AV_STEREO3D_FLAG_INVERT
#define AV_STEREO3D_FLAG_INVERT
Inverted views, Right/Bottom represents the left view.
Definition: stereo3d.h:194
AVStreamGroup::streams
AVStream ** streams
A list of streams in the group.
Definition: avformat.h:1165
ff_rfps_calculate
void ff_rfps_calculate(AVFormatContext *ic)
Definition: demux.c:2343
input
and forward the test the status of outputs and forward it to the corresponding return FFERROR_NOT_READY If the filters stores internally one or a few frame for some input
Definition: filter_design.txt:172
MOV_MP4_IPCM_TAG
#define MOV_MP4_IPCM_TAG
Definition: isom.h:481
mov_read_clli
static int mov_read_clli(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6523
MOVStreamContext::chunk_offsets
int64_t * chunk_offsets
Definition: isom.h:181
AVStreamGroup::iamf_mix_presentation
struct AVIAMFMixPresentation * iamf_mix_presentation
Definition: avformat.h:1132
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:181
av_encryption_init_info_alloc
AVEncryptionInitInfo * av_encryption_init_info_alloc(uint32_t system_id_size, uint32_t num_key_ids, uint32_t key_id_size, uint32_t data_size)
Allocates an AVEncryptionInitInfo structure and sub-pointers to hold the given sizes.
Definition: encryption_info.c:178
av_channel_layout_custom_init
int av_channel_layout_custom_init(AVChannelLayout *channel_layout, int nb_channels)
Initialize a custom channel layout with the specified number of channels.
Definition: channel_layout.c:232
MOVContext::decryption_key_len
int decryption_key_len
Definition: isom.h:374
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:8031
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:9340
layout
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel layout
Definition: filter_design.txt:18
MOVDref::nlvl_from
int16_t nlvl_from
Definition: isom.h:91
AVStreamGroupTileGrid::offsets
struct AVStreamGroupTileGrid::@408 * offsets
An nb_tiles sized array of offsets in pixels from the topleft edge of the canvas, indicating where ea...
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:1842
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:7960
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:3300
mov_finalize_packet
static int mov_finalize_packet(AVFormatContext *s, AVStream *st, AVIndexEntry *sample, int64_t current_index, AVPacket *pkt)
Definition: mov.c:11105
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:11487
bprint.h
MOVContext::advanced_editlist
int advanced_editlist
Definition: isom.h:346
MOVStreamContext::time_scale
int time_scale
Definition: isom.h:210
mlp_parse.h
mac_to_unicode
static const uint32_t mac_to_unicode[128]
Definition: mov.c:150
AVStreamGroupTileGrid::width
int width
Width of the final image for presentation.
Definition: avformat.h:1036
MOVStreamContext::bytes_per_frame
unsigned int bytes_per_frame
Definition: isom.h:217
AVSphericalMapping::roll
int32_t roll
Rotation around the forward vector [-180, 180].
Definition: spherical.h:146
IAMFContext::nb_audio_elements
int nb_audio_elements
Definition: iamf.h:132
MOVIndexRange::end
int64_t end
Definition: isom.h:170
AV_CODEC_ID_NONE
@ AV_CODEC_ID_NONE
Definition: codec_id.h:50
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:256
AVPacket::pts
int64_t pts
Presentation timestamp in AVStream->time_base units; the time at which the decompressed packet will b...
Definition: packet.h:551
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:5682
search_frag_timestamp
static int search_frag_timestamp(AVFormatContext *s, MOVFragmentIndex *frag_index, AVStream *st, int64_t timestamp)
Definition: mov.c:1715
HEIFItem::width
int width
Definition: isom.h:302
FLAGS
#define FLAGS
Definition: mov.c:11544
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:4205
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:7808
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:3155
internal.h
AV_SPHERICAL_FISHEYE
@ AV_SPHERICAL_FISHEYE
Fisheye projection (Apple).
Definition: spherical.h:84
AVCodecParameters::height
int height
Definition: codec_par.h:135
AV_TIME_BASE
#define AV_TIME_BASE
Internal time base represented as integer.
Definition: avutil.h:253
MOVStreamContext::stps_count
unsigned int stps_count
Definition: isom.h:197
AVCodecParameters::block_align
int block_align
Audio only.
Definition: codec_par.h:191
AV_CODEC_ID_TTML
@ AV_CODEC_ID_TTML
Definition: codec_id.h:595
rb_size
static int rb_size(AVIOContext *pb, int64_t *value, int size)
Definition: mov.c:8784
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:3054
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:613
ff_id3v1_genre_str
const char *const ff_id3v1_genre_str[ID3v1_GENRE_MAX+1]
ID3v1 genres.
Definition: id3v1.c:26
MOVStreamContext::sample_sizes
unsigned int * sample_sizes
Definition: isom.h:206
MOVContext::frag_index
MOVFragmentIndex frag_index
Definition: isom.h:359
mov_read_vpcc
static int mov_read_vpcc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6351
AV_CODEC_ID_PCM_F64BE
@ AV_CODEC_ID_PCM_F64BE
Definition: codec_id.h:359
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:1801
mov_finalize_stsd_codec
static int mov_finalize_stsd_codec(MOVContext *c, AVIOContext *pb, AVStream *st, MOVStreamContext *sc)
Definition: mov.c:2905
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:346
mov_read_mdcv
static int mov_read_mdcv(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6442
av_mallocz
void * av_mallocz(size_t size)
Allocate a memory block with alignment suitable for all memory accesses (including vectors if availab...
Definition: mem.c:256
AV_TIMECODE_FLAG_ALLOWNEGATIVE
@ AV_TIMECODE_FLAG_ALLOWNEGATIVE
negative time values are allowed
Definition: timecode.h:38
mov_read_mdat
static int mov_read_mdat(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1370
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:5297
mov_read_iref_cdsc
static int mov_read_iref_cdsc(MOVContext *c, AVIOContext *pb, uint32_t type, int version)
Definition: mov.c:9095
AVCodecParameters::color_range
enum AVColorRange color_range
Video only.
Definition: codec_par.h:166
AV_CH_SIDE_RIGHT
#define AV_CH_SIDE_RIGHT
Definition: channel_layout.h:185
len
int len
Definition: vorbis_enc_data.h:426
AV_CODEC_ID_JPEG2000
@ AV_CODEC_ID_JPEG2000
Definition: codec_id.h:140
exif.h
MOVFragment::size
unsigned size
Definition: isom.h:109
MOV_TFHD_DEFAULT_SIZE
#define MOV_TFHD_DEFAULT_SIZE
Definition: isom.h:405
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:693
fix_stream_ids
static void fix_stream_ids(AVFormatContext *s)
Definition: mov.c:10666
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:4651
AVCodecParameters::coded_side_data
AVPacketSideData * coded_side_data
Additional data associated with the entire stream.
Definition: codec_par.h:81
mov_read_svq3
static int mov_read_svq3(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2379
AVSHA
hash context
Definition: sha.c:35
AVCOL_RANGE_MPEG
@ AVCOL_RANGE_MPEG
Narrow or limited range content.
Definition: pixfmt.h:750
av_calloc
void * av_calloc(size_t nmemb, size_t size)
Definition: mem.c:264
MOVFragmentStreamInfo::tfdt_dts
int64_t tfdt_dts
Definition: isom.h:143
AV_IAMF_AUDIO_ELEMENT_TYPE_SCENE
@ AV_IAMF_AUDIO_ELEMENT_TYPE_SCENE
Definition: iamf.h:346
AVCodecParameters::field_order
enum AVFieldOrder field_order
Video only.
Definition: codec_par.h:161
av_get_packet
int av_get_packet(AVIOContext *s, AVPacket *pkt, int size)
Allocate and read the payload of a packet and initialize its fields with default values.
Definition: utils.c:98
mov_read_iinf
static int mov_read_iinf(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:8981
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:1665
MP4TrackKindValueMapping
Definition: isom.h:483
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:4056
AV_WB8
#define AV_WB8(p, d)
Definition: intreadwrite.h:392
MOVStreamContext::chunk_count
unsigned int chunk_count
Definition: isom.h:180
av_cmp_q
static int av_cmp_q(AVRational a, AVRational b)
Compare two rationals.
Definition: rational.h:89
MOVStreamContext::data_size
int64_t data_size
Definition: isom.h:235
AV_TIMECODE_FLAG_DROPFRAME
@ AV_TIMECODE_FLAG_DROPFRAME
timecode is drop frame
Definition: timecode.h:36
language
Undefined Behavior In the C language
Definition: undefined.txt:3
MOVStreamContext::ambient
AVAmbientViewingEnvironment * ambient
Definition: isom.h:271
mov_read_tmcd
static int mov_read_tmcd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6340
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:1957
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:7511
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:1145
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:720
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:8475
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:367
mov_read_tfdt
static int mov_read_tfdt(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5708
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:5424
search_frag_moof_offset
static int search_frag_moof_offset(MOVFragmentIndex *frag_index, int64_t offset)
Definition: mov.c:1641
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:10976
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:636
AVStreamGroup
Definition: avformat.h:1098
av_get_media_type_string
const char * av_get_media_type_string(enum AVMediaType media_type)
Return a string describing the media_type enum, NULL if media_type is unknown.
Definition: utils.c:28
IAMFMixPresentation
Definition: iamf.h:107
AVStream::index
int index
stream index in AVFormatContext
Definition: avformat.h:750
avpriv_dv_init_demux
DVDemuxContext * avpriv_dv_init_demux(AVFormatContext *s)
Definition: dv.c:726
mov_seek_fragment
static int mov_seek_fragment(AVFormatContext *s, AVStream *st, int64_t timestamp)
Definition: mov.c:11335
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:2668
ff_codec_bmp_tags
const AVCodecTag ff_codec_bmp_tags[]
Definition: riff.c:36
MOVStreamContext::h_spacing
int h_spacing
pasp hSpacing
Definition: isom.h:230
mov_read_dec3
static int mov_read_dec3(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1077
get_frag_time
static int64_t get_frag_time(AVFormatContext *s, AVStream *dst_st, MOVFragmentIndex *frag_index, int index)
Definition: mov.c:1675
MOVStreamContext::sample_size
unsigned int sample_size
may contain value calculated from stsd or value from stsz atom
Definition: isom.h:203
HEVC_NAL_CRA_NUT
@ HEVC_NAL_CRA_NUT
Definition: hevc.h:50
AVStreamGroup::nb_streams
unsigned int nb_streams
Number of elements in AVStreamGroup.streams.
Definition: avformat.h:1152
mlp_samplerate
static int mlp_samplerate(int in)
Definition: mlp_parse.h:87
channel_layout.h
MOVStreamContext::duration_for_fps
int64_t duration_for_fps
Definition: isom.h:253
ISOM_DVCC_DVVC_SIZE
#define ISOM_DVCC_DVVC_SIZE
Definition: dovi_isom.h:29
mov_read_sbgp
static int mov_read_sbgp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:3812
MOVFragment::moof_offset
uint64_t moof_offset
Definition: isom.h:105
AVIO_SEEKABLE_NORMAL
#define AVIO_SEEKABLE_NORMAL
Seeking works like for a local file.
Definition: avio.h:41
av_packet_new_side_data
uint8_t * av_packet_new_side_data(AVPacket *pkt, enum AVPacketSideDataType type, size_t size)
Allocate new information of a packet.
Definition: packet.c:232
buffer
the frame and frame reference mechanism is intended to as much as expensive copies of that data while still allowing the filters to produce correct results The data is stored in buffers represented by AVFrame structures Several references can point to the same frame buffer
Definition: filter_design.txt:49
mov_read_glbl
static int mov_read_glbl(MOVContext *c, AVIOContext *pb, MOVAtom atom)
This function reads atom content and puts data in extradata without tag nor size unlike mov_read_extr...
Definition: mov.c:2441
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:7169
MOVTrackExt::size
unsigned size
Definition: isom.h:117
ff_remove_stream_group
void ff_remove_stream_group(AVFormatContext *s, AVStreamGroup *stg)
Remove a stream group from its AVFormatContext and free it.
Definition: avformat.c:121
AV_OPT_TYPE_INT
@ AV_OPT_TYPE_INT
Underlying C type is int.
Definition: opt.h:259
MOVContext::dv_fctx
AVFormatContext * dv_fctx
Definition: isom.h:335
av_channel_layout_uninit
void av_channel_layout_uninit(AVChannelLayout *channel_layout)
Free any allocated data in the channel layout and reset the channel count to 0.
Definition: channel_layout.c:442
AV_CODEC_ID_DVAUDIO
@ AV_CODEC_ID_DVAUDIO
Definition: codec_id.h:465
avformat_free_context
void avformat_free_context(AVFormatContext *s)
Free an AVFormatContext and all its streams.
Definition: avformat.c:141
MOVContext::aax_mode
unsigned int aax_mode
'aax' file has been detected
Definition: isom.h:361
mov_read_sv3d
static int mov_read_sv3d(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6703
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:1481
mov_get_skip_samples
static int64_t mov_get_skip_samples(AVStream *st, int sample)
Definition: mov.c:11470
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:1080
MOVDref::type
uint32_t type
Definition: isom.h:86
samples
Filter the word “frame” indicates either a video frame or a group of audio samples
Definition: filter_design.txt:8
mean
static float mean(const float *input, int size)
Definition: vf_nnedi.c:861
mov_read_covr
static int mov_read_covr(MOVContext *c, AVIOContext *pb, int type, int len)
Definition: mov.c: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:560
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:10016
mov_read_sbas
static int mov_read_sbas(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2512
MOVStreamContext::has_sidx
int has_sidx
Definition: isom.h:276
AV_CH_FRONT_RIGHT
#define AV_CH_FRONT_RIGHT
Definition: channel_layout.h:176
av_aes_ctr_crypt
void av_aes_ctr_crypt(struct AVAESCTR *a, uint8_t *dst, const uint8_t *src, int count)
Process a buffer using a previously initialized context.
Definition: aes_ctr.c:102
mov_metadata_gnre
static int mov_metadata_gnre(MOVContext *c, AVIOContext *pb, unsigned len, const char *key)
Definition: mov.c:134
AV_PKT_DATA_ENCRYPTION_INFO
@ AV_PKT_DATA_ENCRYPTION_INFO
This side data contains encryption info for how to decrypt the packet.
Definition: packet.h:252
MOV_MERGE_CTTS
#define MOV_MERGE_CTTS
Definition: mov.c:4581
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:2266
AVIAMFSubmix::nb_elements
unsigned int nb_elements
Number of elements in the submix.
Definition: iamf.h:572
MOVFragmentStreamInfo::id
int id
Definition: isom.h:140
AVIO_FLAG_READ
#define AVIO_FLAG_READ
read-only
Definition: avio.h:617
AV_PKT_DATA_AUDIO_SERVICE_TYPE
@ AV_PKT_DATA_AUDIO_SERVICE_TYPE
This side data should be associated with an audio stream and corresponds to enum AVAudioServiceType.
Definition: packet.h:117
av_spherical_alloc
AVSphericalMapping * av_spherical_alloc(size_t *size)
Allocate a AVSphericalVideo structure and initialize its fields to default values.
Definition: spherical.c:26
AV_OPT_FLAG_DECODING_PARAM
#define AV_OPT_FLAG_DECODING_PARAM
A generic parameter which can be set by the user for demuxing or decoding.
Definition: opt.h:356
mov_read_rtmd_track
static int mov_read_rtmd_track(AVFormatContext *s, AVStream *st)
Definition: mov.c:9798
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:345
AVCodecParameters::bits_per_coded_sample
int bits_per_coded_sample
The number of bits per sample in the codedwords.
Definition: codec_par.h:110
mov_parse_tiles
static int mov_parse_tiles(AVFormatContext *s)
Definition: mov.c:10399
mem.h
AVStreamGroup::type
enum AVStreamGroupParamsType type
Group type.
Definition: avformat.h:1125
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:9035
mov_read_pcmc
static int mov_read_pcmc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1995
build_open_gop_key_points
static int build_open_gop_key_points(AVStream *st)
Definition: mov.c:4518
mov_parse_stsd_audio
static void mov_parse_stsd_audio(MOVContext *c, AVIOContext *pb, AVStream *st, MOVStreamContext *sc)
Definition: mov.c:2726
IAMFContext::mix_presentations
IAMFMixPresentation ** mix_presentations
Definition: iamf.h:133
AV_CODEC_ID_PCM_U8
@ AV_CODEC_ID_PCM_U8
Definition: codec_id.h:342
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:9824
HEIFGrid::item
HEIFItem * item
Definition: isom.h:314
AVSphericalMapping::bound_left
uint32_t bound_left
Distance from the left edge.
Definition: spherical.h:185
mov_read_mac_string
static int mov_read_mac_string(MOVContext *c, AVIOContext *pb, int len, char *dst, int dstlen)
Definition: mov.c:169
MOVEncryptionIndex::auxiliary_info_sizes
uint8_t * auxiliary_info_sizes
Definition: isom.h:132
MOVFragment::stsd_id
unsigned stsd_id
Definition: isom.h:107
AVCodecParameters::video_delay
int video_delay
Video only.
Definition: codec_par.h:175
HEIFGrid::tile_id_list
int16_t * tile_id_list
Definition: isom.h:316
avpriv_request_sample
#define avpriv_request_sample(...)
Definition: tableprint_vlc.h:37
MOVStreamContext::tts_data
MOVTimeToSample * tts_data
Definition: isom.h:184
map
const VDPAUPixFmtMap * map
Definition: hwcontext_vdpau.c:71
avformat_stream_group_create
AVStreamGroup * avformat_stream_group_create(AVFormatContext *s, enum AVStreamGroupParamsType type, AVDictionary **options)
Add a new empty stream group to a media file.
Definition: options.c:433
AV_CHANNEL_LAYOUT_MONO
#define AV_CHANNEL_LAYOUT_MONO
Definition: channel_layout.h:394
AV_CODEC_ID_PCM_F64LE
@ AV_CODEC_ID_PCM_F64LE
Definition: codec_id.h:360
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:10034
av_free
#define av_free(p)
Definition: tableprint_vlc.h:34
AVDictionaryEntry
Definition: dict.h:90
av_add_q
AVRational av_add_q(AVRational b, AVRational c)
Add two rationals.
Definition: rational.c:93
AVCodecParameters::codec_id
enum AVCodecID codec_id
Specific type of the encoded data (the codec used).
Definition: codec_par.h:55
AVStereo3DView
AVStereo3DView
List of possible view types.
Definition: stereo3d.h:149
AVPacket
This structure stores compressed data.
Definition: packet.h:535
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:10616
mov_read_hfov
static int mov_read_hfov(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:7140
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:377
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:578
FFInputFormat
Definition: demux.h:47
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:6905
AV_CODEC_ID_ILBC
@ AV_CODEC_ID_ILBC
Definition: codec_id.h:518
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:413
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:9784
MOVStreamContext::tmcd_nb_frames
uint8_t tmcd_nb_frames
tmcd number of frames per tick / second
Definition: isom.h:237
AVIAMFSubmixElement
Submix element as defined in section 3.7 of IAMF.
Definition: iamf.h:446
replaygain.h
AVStreamGroup::params
union AVStreamGroup::@409 params
Group type-specific parameters.
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:485
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:358
ff_mov_demuxer
const FFInputFormat ff_mov_demuxer
Definition: mov.c:11605
AVCodecParameters::bit_rate
int64_t bit_rate
The average bitrate of the encoded data (in bits per second).
Definition: codec_par.h:97
MOVStts::count
unsigned int count
Definition: isom.h:64
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
MOVStreamContext::display_matrix
int32_t * display_matrix
Definition: isom.h:262
MOVContext::heif_grid
HEIFGrid * heif_grid
Definition: isom.h:384
MOVStreamContext::min_sample_duration
uint32_t min_sample_duration
Definition: isom.h:250
MOVStreamContext::current_index
int64_t current_index
Definition: isom.h:214
AVERROR_INVALIDDATA
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:61
ff_mov_track_kind_table
const struct MP4TrackKindMapping ff_mov_track_kind_table[]
Definition: isom.c:451
get_curr_st
static AVStream * get_curr_st(MOVContext *c)
Get the current stream in the parsing process.
Definition: mov.c:213
MOVStreamContext::stts_allocated_size
unsigned int stts_allocated_size
Definition: isom.h:186
MOVFragmentStreamInfo::index_entry
int index_entry
Definition: isom.h:147
cenc_decrypt
static int cenc_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
Definition: mov.c:8315
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:464
AVDictionaryEntry::value
char * value
Definition: dict.h:92
AVStream::start_time
int64_t start_time
Decoding: pts of the first frame of the stream in presentation order, in stream time base.
Definition: avformat.h:793
MOVStreamContext::id
int id
AVStream id.
Definition: isom.h:177
MOVStreamContext::samples_per_frame
unsigned int samples_per_frame
Definition: isom.h:218
MOVStreamContext::tts_allocated_size
unsigned int tts_allocated_size
Definition: isom.h:183
MOVElst::duration
int64_t duration
Definition: isom.h:80
ac3tab.h
avstring.h
mov_read_ispe
static int mov_read_ispe(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:9168
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:9129
IAMFMixPresentation::mix
AVIAMFMixPresentation * mix
mix backs cmix iff the AVIAMFMixPresentation is owned by this structure.
Definition: iamf.h:113
mov_read_clap
static int mov_read_clap(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1239
mov_read_mfra
static int mov_read_mfra(MOVContext *c, AVIOContext *f)
Definition: mov.c:10089
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:1586
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:8579
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:415
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:478
snprintf
#define snprintf
Definition: snprintf.h:34
IAMFMixPresentation::mix_presentation_id
unsigned int mix_presentation_id
Definition: iamf.h:114
AVCodecParameters::initial_padding
int initial_padding
Audio only.
Definition: codec_par.h:203
AV_CODEC_ID_PCM_S24BE
@ AV_CODEC_ID_PCM_S24BE
Definition: codec_id.h:350
mov_read_st3d
static int mov_read_st3d(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6577
mov_read_imir
static int mov_read_imir(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:9210
is_open_key_sample
static int is_open_key_sample(const MOVStreamContext *sc, int sample)
Definition: mov.c:11354
mov_read_dvc1
static int mov_read_dvc1(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2487
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:3802
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:2203
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:9685
AV_CODEC_ID_DNXHD
@ AV_CODEC_ID_DNXHD
Definition: codec_id.h:151
channel
channel
Definition: ebur128.h:39
MOVStreamContext::default_encrypted_sample
AVEncryptionInfo * default_encrypted_sample
Definition: isom.h:281
MOVContext::cur_item_id
int cur_item_id
Definition: isom.h: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:1638
AV_DICT_DONT_STRDUP_KEY
#define AV_DICT_DONT_STRDUP_KEY
Take ownership of a key that's been allocated with av_malloc() or another memory allocation function.
Definition: dict.h:77
MOVContext::next_root_atom
int64_t next_root_atom
offset of the next root atom
Definition: isom.h:350
MOVContext::found_iinf
int found_iinf
'iinf' atom has been found
Definition: isom.h:328
MOVContext::meta_keys_count
unsigned meta_keys_count
Definition: isom.h:333
avcodec_parameters_copy
int avcodec_parameters_copy(AVCodecParameters *dst, const AVCodecParameters *src)
Copy the contents of src to dst.
Definition: codec_par.c:107
iamf_reader.h
AVStreamGroupTileGrid::background
uint8_t background[4]
The pixel value per channel in RGBA format used if no pixel of any tile is located at a particular pi...
Definition: avformat.h:1010
MOVStreamContext::palette
uint32_t palette[256]
Definition: isom.h:233
cenc_scheme_decrypt
static int cenc_scheme_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
Definition: mov.c:8071
MOVFragment::track_id
unsigned track_id
Definition: isom.h:103
mov_read_hdlr
static int mov_read_hdlr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:781
mov_parse_stsd_data
static int mov_parse_stsd_data(MOVContext *c, AVIOContext *pb, AVStream *st, MOVStreamContext *sc, int64_t size)
Definition: mov.c:2859
AV_CH_SIDE_LEFT
#define AV_CH_SIDE_LEFT
Definition: channel_layout.h:184
ff_iamf_read_deinit
void ff_iamf_read_deinit(IAMFDemuxContext *c)
Definition: iamf_reader.c:342
AV_RB16
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_WL16 uint64_t_TMPL AV_WB64 unsigned int_TMPL AV_WB32 unsigned int_TMPL AV_WB24 unsigned int_TMPL AV_RB16
Definition: bytestream.h:98
av_realloc
void * av_realloc(void *ptr, size_t size)
Allocate, reallocate, or free a block of memory.
Definition: mem.c:155
av_encryption_init_info_add_side_data
uint8_t * av_encryption_init_info_add_side_data(const AVEncryptionInitInfo *info, size_t *side_data_size)
Allocates and initializes side data that holds a copy of the given encryption init info.
Definition: encryption_info.c:292
av_fourcc2str
#define av_fourcc2str(fourcc)
Definition: avutil.h:347
ff_mov_read_chan
int ff_mov_read_chan(AVFormatContext *s, AVIOContext *pb, AVStream *st, int64_t size)
Read 'chan' tag from the input stream.
Definition: mov_chan.c:524
av_index_search_timestamp
int av_index_search_timestamp(AVStream *st, int64_t timestamp, int flags)
Get the index for a specific timestamp.
Definition: seek.c:245
mov_read_pitm
static int mov_read_pitm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:8803
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:852
MP4TrackKindMapping
Definition: isom.h:488
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:3417