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"
36 #include "libavutil/internal.h"
37 #include "libavutil/intreadwrite.h"
38 #include "libavutil/intfloat.h"
39 #include "libavutil/mathematics.h"
40 #include "libavutil/avassert.h"
41 #include "libavutil/avstring.h"
42 #include "libavutil/dict.h"
43 #include "libavutil/mem.h"
44 #include "libavutil/opt.h"
45 #include "libavutil/aes.h"
46 #include "libavutil/aes_ctr.h"
47 #include "libavutil/pixdesc.h"
48 #include "libavutil/sha.h"
49 #include "libavutil/spherical.h"
50 #include "libavutil/stereo3d.h"
51 #include "libavutil/timecode.h"
52 #include "libavutil/uuid.h"
53 #include "libavcodec/ac3tab.h"
54 #include "libavcodec/flac.h"
55 #include "libavcodec/hevc/hevc.h"
57 #include "libavcodec/mlp_parse.h"
58 #include "avformat.h"
59 #include "internal.h"
60 #include "avio_internal.h"
61 #include "demux.h"
62 #include "iamf_parse.h"
63 #include "iamf_reader.h"
64 #include "dovi_isom.h"
65 #include "riff.h"
66 #include "isom.h"
67 #include "libavcodec/get_bits.h"
68 #include "id3v1.h"
69 #include "mov_chan.h"
70 #include "replaygain.h"
71 
72 #if CONFIG_ZLIB
73 #include <zlib.h>
74 #endif
75 
76 #include "qtpalette.h"
77 
78 /* those functions parse an atom */
79 /* links atom IDs to parse functions */
80 typedef struct MOVParseTableEntry {
81  uint32_t type;
82  int (*parse)(MOVContext *ctx, AVIOContext *pb, MOVAtom atom);
84 
85 static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom);
86 static int mov_read_mfra(MOVContext *c, AVIOContext *f);
88 static int64_t add_ctts_entry(MOVCtts** ctts_data, unsigned int* ctts_count, unsigned int* allocated_size,
89  int count, int duration);
90 
92  unsigned len, const char *key)
93 {
94  char buf[16];
95 
96  short current, total = 0;
97  avio_rb16(pb); // unknown
98  current = avio_rb16(pb);
99  if (len >= 6)
100  total = avio_rb16(pb);
101  if (!total)
102  snprintf(buf, sizeof(buf), "%d", current);
103  else
104  snprintf(buf, sizeof(buf), "%d/%d", current, total);
105  c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
106  av_dict_set(&c->fc->metadata, key, buf, 0);
107 
108  return 0;
109 }
110 
112  unsigned len, const char *key)
113 {
114  /* bypass padding bytes */
115  avio_r8(pb);
116  avio_r8(pb);
117  avio_r8(pb);
118 
119  c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
120  av_dict_set_int(&c->fc->metadata, key, avio_r8(pb), 0);
121 
122  return 0;
123 }
124 
126  unsigned len, const char *key)
127 {
128  c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
129  av_dict_set_int(&c->fc->metadata, key, avio_r8(pb), 0);
130 
131  return 0;
132 }
133 
135  unsigned len, const char *key)
136 {
137  short genre;
138 
139  avio_r8(pb); // unknown
140 
141  genre = avio_r8(pb);
142  if (genre < 1 || genre > ID3v1_GENRE_MAX)
143  return 0;
144  c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
145  av_dict_set(&c->fc->metadata, key, ff_id3v1_genre_str[genre-1], 0);
146 
147  return 0;
148 }
149 
150 static const uint32_t mac_to_unicode[128] = {
151  0x00C4,0x00C5,0x00C7,0x00C9,0x00D1,0x00D6,0x00DC,0x00E1,
152  0x00E0,0x00E2,0x00E4,0x00E3,0x00E5,0x00E7,0x00E9,0x00E8,
153  0x00EA,0x00EB,0x00ED,0x00EC,0x00EE,0x00EF,0x00F1,0x00F3,
154  0x00F2,0x00F4,0x00F6,0x00F5,0x00FA,0x00F9,0x00FB,0x00FC,
155  0x2020,0x00B0,0x00A2,0x00A3,0x00A7,0x2022,0x00B6,0x00DF,
156  0x00AE,0x00A9,0x2122,0x00B4,0x00A8,0x2260,0x00C6,0x00D8,
157  0x221E,0x00B1,0x2264,0x2265,0x00A5,0x00B5,0x2202,0x2211,
158  0x220F,0x03C0,0x222B,0x00AA,0x00BA,0x03A9,0x00E6,0x00F8,
159  0x00BF,0x00A1,0x00AC,0x221A,0x0192,0x2248,0x2206,0x00AB,
160  0x00BB,0x2026,0x00A0,0x00C0,0x00C3,0x00D5,0x0152,0x0153,
161  0x2013,0x2014,0x201C,0x201D,0x2018,0x2019,0x00F7,0x25CA,
162  0x00FF,0x0178,0x2044,0x20AC,0x2039,0x203A,0xFB01,0xFB02,
163  0x2021,0x00B7,0x201A,0x201E,0x2030,0x00C2,0x00CA,0x00C1,
164  0x00CB,0x00C8,0x00CD,0x00CE,0x00CF,0x00CC,0x00D3,0x00D4,
165  0xF8FF,0x00D2,0x00DA,0x00DB,0x00D9,0x0131,0x02C6,0x02DC,
166  0x00AF,0x02D8,0x02D9,0x02DA,0x00B8,0x02DD,0x02DB,0x02C7,
167 };
168 
170  char *dst, int dstlen)
171 {
172  char *p = dst;
173  char *end = dst+dstlen-1;
174  int i;
175 
176  for (i = 0; i < len; i++) {
177  uint8_t t, c = avio_r8(pb);
178 
179  if (p >= end)
180  continue;
181 
182  if (c < 0x80)
183  *p++ = c;
184  else if (p < end)
185  PUT_UTF8(mac_to_unicode[c-0x80], t, if (p < end) *p++ = t;);
186  }
187  *p = 0;
188  return p - dst;
189 }
190 
191 /**
192  * Get the current item in the parsing process.
193  */
195 {
196  HEIFItem *item = NULL;
197 
198  for (int i = 0; i < c->nb_heif_item; i++) {
199  if (!c->heif_item[i] || c->heif_item[i]->item_id != c->cur_item_id)
200  continue;
201 
202  item = c->heif_item[i];
203  break;
204  }
205 
206  return item;
207 }
208 
209 /**
210  * Get the current stream in the parsing process. This can either be the
211  * latest stream added to the context, or the stream referenced by an item.
212  */
214 {
215  AVStream *st = NULL;
216  HEIFItem *item;
217 
218  if (c->fc->nb_streams < 1)
219  return NULL;
220 
221  if (c->cur_item_id == -1)
222  return c->fc->streams[c->fc->nb_streams-1];
223 
224  item = heif_cur_item(c);
225  if (item)
226  st = item->st;
227 
228  return st;
229 }
230 
231 static int mov_read_covr(MOVContext *c, AVIOContext *pb, int type, int len)
232 {
233  AVStream *st;
234  MOVStreamContext *sc;
235  enum AVCodecID id;
236  int ret;
237 
238  switch (type) {
239  case 0xd: id = AV_CODEC_ID_MJPEG; break;
240  case 0xe: id = AV_CODEC_ID_PNG; break;
241  case 0x1b: id = AV_CODEC_ID_BMP; break;
242  default:
243  av_log(c->fc, AV_LOG_WARNING, "Unknown cover type: 0x%x.\n", type);
244  avio_skip(pb, len);
245  return 0;
246  }
247 
248  sc = av_mallocz(sizeof(*sc));
249  if (!sc)
250  return AVERROR(ENOMEM);
251  ret = ff_add_attached_pic(c->fc, NULL, pb, NULL, len);
252  if (ret < 0) {
253  av_free(sc);
254  return ret;
255  }
256  st = c->fc->streams[c->fc->nb_streams - 1];
257  st->priv_data = sc;
258  sc->id = st->id;
259  sc->refcount = 1;
260 
261  if (st->attached_pic.size >= 8 && id != AV_CODEC_ID_BMP) {
262  if (AV_RB64(st->attached_pic.data) == 0x89504e470d0a1a0a) {
263  id = AV_CODEC_ID_PNG;
264  } else {
265  id = AV_CODEC_ID_MJPEG;
266  }
267  }
268  st->codecpar->codec_id = id;
269 
270  return 0;
271 }
272 
273 // 3GPP TS 26.244
274 static int mov_metadata_loci(MOVContext *c, AVIOContext *pb, unsigned len)
275 {
276  char language[4] = { 0 };
277  char buf[200], place[100];
278  uint16_t langcode = 0;
279  double longitude, latitude, altitude;
280  const char *key = "location";
281 
282  if (len < 4 + 2 + 1 + 1 + 4 + 4 + 4) {
283  av_log(c->fc, AV_LOG_ERROR, "loci too short\n");
284  return AVERROR_INVALIDDATA;
285  }
286 
287  avio_skip(pb, 4); // version+flags
288  langcode = avio_rb16(pb);
289  ff_mov_lang_to_iso639(langcode, language);
290  len -= 6;
291 
292  len -= avio_get_str(pb, len, place, sizeof(place));
293  if (len < 1) {
294  av_log(c->fc, AV_LOG_ERROR, "place name too long\n");
295  return AVERROR_INVALIDDATA;
296  }
297  avio_skip(pb, 1); // role
298  len -= 1;
299 
300  if (len < 12) {
301  av_log(c->fc, AV_LOG_ERROR,
302  "loci too short (%u bytes left, need at least %d)\n", len, 12);
303  return AVERROR_INVALIDDATA;
304  }
305  longitude = ((int32_t) avio_rb32(pb)) / (float) (1 << 16);
306  latitude = ((int32_t) avio_rb32(pb)) / (float) (1 << 16);
307  altitude = ((int32_t) avio_rb32(pb)) / (float) (1 << 16);
308 
309  // Try to output in the same format as the ?xyz field
310  snprintf(buf, sizeof(buf), "%+08.4f%+09.4f", latitude, longitude);
311  if (altitude)
312  av_strlcatf(buf, sizeof(buf), "%+f", altitude);
313  av_strlcatf(buf, sizeof(buf), "/%s", place);
314 
315  if (*language && strcmp(language, "und")) {
316  char key2[16];
317  snprintf(key2, sizeof(key2), "%s-%s", key, language);
318  av_dict_set(&c->fc->metadata, key2, buf, 0);
319  }
320  c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
321  return av_dict_set(&c->fc->metadata, key, buf, 0);
322 }
323 
324 static int mov_metadata_hmmt(MOVContext *c, AVIOContext *pb, unsigned len)
325 {
326  int i, n_hmmt;
327 
328  if (len < 2)
329  return 0;
330  if (c->ignore_chapters)
331  return 0;
332 
333  n_hmmt = avio_rb32(pb);
334  if (n_hmmt > len / 4)
335  return AVERROR_INVALIDDATA;
336  for (i = 0; i < n_hmmt && !pb->eof_reached; i++) {
337  int moment_time = avio_rb32(pb);
338  avpriv_new_chapter(c->fc, i, av_make_q(1, 1000), moment_time, AV_NOPTS_VALUE, NULL);
339  }
340  if (avio_feof(pb))
341  return AVERROR_INVALIDDATA;
342  return 0;
343 }
344 
346 {
347  char tmp_key[AV_FOURCC_MAX_STRING_SIZE] = {0};
348  char key2[32], language[4] = {0};
349  char *str = NULL;
350  const char *key = NULL;
351  uint16_t langcode = 0;
352  uint32_t data_type = 0, str_size_alloc;
353  uint64_t str_size;
354  int (*parse)(MOVContext*, AVIOContext*, unsigned, const char*) = NULL;
355  int raw = 0;
356  int num = 0;
357 
358  switch (atom.type) {
359  case MKTAG( '@','P','R','M'): key = "premiere_version"; raw = 1; break;
360  case MKTAG( '@','P','R','Q'): key = "quicktime_version"; raw = 1; break;
361  case MKTAG( 'X','M','P','_'):
362  if (c->export_xmp) { key = "xmp"; raw = 1; } break;
363  case MKTAG( 'a','A','R','T'): key = "album_artist"; break;
364  case MKTAG( 'a','k','I','D'): key = "account_type";
366  case MKTAG( 'a','p','I','D'): key = "account_id"; break;
367  case MKTAG( 'c','a','t','g'): key = "category"; break;
368  case MKTAG( 'c','p','i','l'): key = "compilation";
370  case MKTAG( 'c','p','r','t'): key = "copyright"; break;
371  case MKTAG( 'd','e','s','c'): key = "description"; break;
372  case MKTAG( 'd','i','s','k'): key = "disc";
374  case MKTAG( 'e','g','i','d'): key = "episode_uid";
376  case MKTAG( 'F','I','R','M'): key = "firmware"; raw = 1; break;
377  case MKTAG( 'g','n','r','e'): key = "genre";
378  parse = mov_metadata_gnre; break;
379  case MKTAG( 'h','d','v','d'): key = "hd_video";
381  case MKTAG( 'H','M','M','T'):
382  return mov_metadata_hmmt(c, pb, atom.size);
383  case MKTAG( 'k','e','y','w'): key = "keywords"; break;
384  case MKTAG( 'l','d','e','s'): key = "synopsis"; break;
385  case MKTAG( 'l','o','c','i'):
386  return mov_metadata_loci(c, pb, atom.size);
387  case MKTAG( 'm','a','n','u'): key = "make"; break;
388  case MKTAG( 'm','o','d','l'): key = "model"; break;
389  case MKTAG( 'p','c','s','t'): key = "podcast";
391  case MKTAG( 'p','g','a','p'): key = "gapless_playback";
393  case MKTAG( 'p','u','r','d'): key = "purchase_date"; break;
394  case MKTAG( 'r','t','n','g'): key = "rating";
396  case MKTAG( 's','o','a','a'): key = "sort_album_artist"; break;
397  case MKTAG( 's','o','a','l'): key = "sort_album"; break;
398  case MKTAG( 's','o','a','r'): key = "sort_artist"; break;
399  case MKTAG( 's','o','c','o'): key = "sort_composer"; break;
400  case MKTAG( 's','o','n','m'): key = "sort_name"; break;
401  case MKTAG( 's','o','s','n'): key = "sort_show"; break;
402  case MKTAG( 's','t','i','k'): key = "media_type";
404  case MKTAG( 't','r','k','n'): key = "track";
406  case MKTAG( 't','v','e','n'): key = "episode_id"; break;
407  case MKTAG( 't','v','e','s'): key = "episode_sort";
409  case MKTAG( 't','v','n','n'): key = "network"; break;
410  case MKTAG( 't','v','s','h'): key = "show"; break;
411  case MKTAG( 't','v','s','n'): key = "season_number";
413  case MKTAG(0xa9,'A','R','T'): key = "artist"; break;
414  case MKTAG(0xa9,'P','R','D'): key = "producer"; break;
415  case MKTAG(0xa9,'a','l','b'): key = "album"; break;
416  case MKTAG(0xa9,'a','u','t'): key = "artist"; break;
417  case MKTAG(0xa9,'c','h','p'): key = "chapter"; break;
418  case MKTAG(0xa9,'c','m','t'): key = "comment"; break;
419  case MKTAG(0xa9,'c','o','m'): key = "composer"; break;
420  case MKTAG(0xa9,'c','p','y'): key = "copyright"; break;
421  case MKTAG(0xa9,'d','a','y'): key = "date"; break;
422  case MKTAG(0xa9,'d','i','r'): key = "director"; break;
423  case MKTAG(0xa9,'d','i','s'): key = "disclaimer"; break;
424  case MKTAG(0xa9,'e','d','1'): key = "edit_date"; break;
425  case MKTAG(0xa9,'e','n','c'): key = "encoder"; break;
426  case MKTAG(0xa9,'f','m','t'): key = "original_format"; break;
427  case MKTAG(0xa9,'g','e','n'): key = "genre"; break;
428  case MKTAG(0xa9,'g','r','p'): key = "grouping"; break;
429  case MKTAG(0xa9,'h','s','t'): key = "host_computer"; break;
430  case MKTAG(0xa9,'i','n','f'): key = "comment"; break;
431  case MKTAG(0xa9,'l','y','r'): key = "lyrics"; break;
432  case MKTAG(0xa9,'m','a','k'): key = "make"; break;
433  case MKTAG(0xa9,'m','o','d'): key = "model"; break;
434  case MKTAG(0xa9,'n','a','m'): key = "title"; break;
435  case MKTAG(0xa9,'o','p','e'): key = "original_artist"; break;
436  case MKTAG(0xa9,'p','r','d'): key = "producer"; break;
437  case MKTAG(0xa9,'p','r','f'): key = "performers"; break;
438  case MKTAG(0xa9,'r','e','q'): key = "playback_requirements"; break;
439  case MKTAG(0xa9,'s','r','c'): key = "original_source"; break;
440  case MKTAG(0xa9,'s','t','3'): key = "subtitle"; break;
441  case MKTAG(0xa9,'s','w','r'): key = "encoder"; break;
442  case MKTAG(0xa9,'t','o','o'): key = "encoder"; break;
443  case MKTAG(0xa9,'t','r','k'): key = "track"; break;
444  case MKTAG(0xa9,'u','r','l'): key = "URL"; break;
445  case MKTAG(0xa9,'w','r','n'): key = "warning"; break;
446  case MKTAG(0xa9,'w','r','t'): key = "composer"; break;
447  case MKTAG(0xa9,'x','y','z'): key = "location"; break;
448  }
449 retry:
450  if (c->itunes_metadata && atom.size > 8) {
451  int data_size = avio_rb32(pb);
452  int tag = avio_rl32(pb);
453  if (tag == MKTAG('d','a','t','a') && data_size <= atom.size && data_size >= 16) {
454  data_type = avio_rb32(pb); // type
455  avio_rb32(pb); // unknown
456  str_size = data_size - 16;
457  atom.size -= 16;
458 
459  if (!key && c->found_hdlr_mdta && c->meta_keys) {
460  uint32_t index = av_bswap32(atom.type); // BE number has been read as LE
461  if (index < c->meta_keys_count && index > 0) {
462  key = c->meta_keys[index];
463  } else if (atom.type != MKTAG('c', 'o', 'v', 'r')) {
464  av_log(c->fc, AV_LOG_WARNING,
465  "The index of 'data' is out of range: %"PRId32" < 1 or >= %d.\n",
466  index, c->meta_keys_count);
467  }
468  }
469  if (atom.type == MKTAG('c', 'o', 'v', 'r') ||
470  (key && !strcmp(key, "com.apple.quicktime.artwork"))) {
471  int ret = mov_read_covr(c, pb, data_type, str_size);
472  if (ret < 0) {
473  av_log(c->fc, AV_LOG_ERROR, "Error parsing cover art.\n");
474  return ret;
475  }
476  atom.size -= str_size;
477  if (atom.size > 8)
478  goto retry;
479  return ret;
480  }
481  } else return 0;
482  } else if (atom.size > 4 && key && !c->itunes_metadata && !raw) {
483  str_size = avio_rb16(pb); // string length
484  if (str_size > atom.size) {
485  raw = 1;
486  avio_seek(pb, -2, SEEK_CUR);
487  av_log(c->fc, AV_LOG_WARNING, "UDTA parsing failed retrying raw\n");
488  goto retry;
489  }
490  langcode = avio_rb16(pb);
491  ff_mov_lang_to_iso639(langcode, language);
492  atom.size -= 4;
493  } else
494  str_size = atom.size;
495 
496  if (c->export_all && !key) {
497  key = av_fourcc_make_string(tmp_key, atom.type);
498  }
499 
500  if (!key)
501  return 0;
502  if (atom.size < 0 || str_size >= INT_MAX/2)
503  return AVERROR_INVALIDDATA;
504 
505  // Allocates enough space if data_type is a int32 or float32 number, otherwise
506  // worst-case requirement for output string in case of utf8 coded input
507  num = (data_type >= 21 && data_type <= 23);
508  str_size_alloc = (num ? 512 : (raw ? str_size : str_size * 2)) + 1;
509  str = av_mallocz(str_size_alloc);
510  if (!str)
511  return AVERROR(ENOMEM);
512 
513  if (parse)
514  parse(c, pb, str_size, key);
515  else {
516  if (!raw && (data_type == 3 || (data_type == 0 && (langcode < 0x400 || langcode == 0x7fff)))) { // MAC Encoded
517  mov_read_mac_string(c, pb, str_size, str, str_size_alloc);
518  } else if (data_type == 21) { // BE signed integer, variable size
519  int val = 0;
520  if (str_size == 1)
521  val = (int8_t)avio_r8(pb);
522  else if (str_size == 2)
523  val = (int16_t)avio_rb16(pb);
524  else if (str_size == 3)
525  val = ((int32_t)(avio_rb24(pb)<<8))>>8;
526  else if (str_size == 4)
527  val = (int32_t)avio_rb32(pb);
528  if (snprintf(str, str_size_alloc, "%d", val) >= str_size_alloc) {
529  av_log(c->fc, AV_LOG_ERROR,
530  "Failed to store the number (%d) in string.\n", val);
531  av_free(str);
532  return AVERROR_INVALIDDATA;
533  }
534  } else if (data_type == 22) { // BE unsigned integer, variable size
535  unsigned int val = 0;
536  if (str_size == 1)
537  val = avio_r8(pb);
538  else if (str_size == 2)
539  val = avio_rb16(pb);
540  else if (str_size == 3)
541  val = avio_rb24(pb);
542  else if (str_size == 4)
543  val = avio_rb32(pb);
544  if (snprintf(str, str_size_alloc, "%u", val) >= str_size_alloc) {
545  av_log(c->fc, AV_LOG_ERROR,
546  "Failed to store the number (%u) in string.\n", val);
547  av_free(str);
548  return AVERROR_INVALIDDATA;
549  }
550  } else if (data_type == 23 && str_size >= 4) { // BE float32
551  float val = av_int2float(avio_rb32(pb));
552  if (snprintf(str, str_size_alloc, "%f", val) >= str_size_alloc) {
553  av_log(c->fc, AV_LOG_ERROR,
554  "Failed to store the float32 number (%f) in string.\n", val);
555  av_free(str);
556  return AVERROR_INVALIDDATA;
557  }
558  } else if (data_type > 1 && data_type != 4) {
559  // data_type can be 0 if not set at all above. data_type 1 means
560  // UTF8 and 4 means "UTF8 sort". For any other type (UTF16 or e.g.
561  // a picture), don't return it blindly in a string that is supposed
562  // to be UTF8 text.
563  av_log(c->fc, AV_LOG_WARNING, "Skipping unhandled metadata %s of type %d\n", key, data_type);
564  av_free(str);
565  return 0;
566  } else {
567  int ret = ffio_read_size(pb, str, str_size);
568  if (ret < 0) {
569  av_free(str);
570  return ret;
571  }
572  str[str_size] = 0;
573  }
574  c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
575  av_dict_set(&c->fc->metadata, key, str, 0);
576  if (*language && strcmp(language, "und")) {
577  snprintf(key2, sizeof(key2), "%s-%s", key, language);
578  av_dict_set(&c->fc->metadata, key2, str, 0);
579  }
580  if (!strcmp(key, "encoder")) {
581  int major, minor, micro;
582  if (sscanf(str, "HandBrake %d.%d.%d", &major, &minor, &micro) == 3) {
583  c->handbrake_version = 1000000*major + 1000*minor + micro;
584  }
585  }
586  }
587 
588  av_freep(&str);
589  return 0;
590 }
591 
593 {
594  int64_t start;
595  int i, nb_chapters, str_len, version;
596  char str[256+1];
597  int ret;
598 
599  if (c->ignore_chapters)
600  return 0;
601 
602  if ((atom.size -= 5) < 0)
603  return 0;
604 
605  version = avio_r8(pb);
606  avio_rb24(pb);
607  if (version)
608  avio_rb32(pb); // ???
609  nb_chapters = avio_r8(pb);
610 
611  for (i = 0; i < nb_chapters; i++) {
612  if (atom.size < 9)
613  return 0;
614 
615  start = avio_rb64(pb);
616  str_len = avio_r8(pb);
617 
618  if ((atom.size -= 9+str_len) < 0)
619  return 0;
620 
621  ret = ffio_read_size(pb, str, str_len);
622  if (ret < 0)
623  return ret;
624  str[str_len] = 0;
625  avpriv_new_chapter(c->fc, i, (AVRational){1,10000000}, start, AV_NOPTS_VALUE, str);
626  }
627  return 0;
628 }
629 
630 #define MIN_DATA_ENTRY_BOX_SIZE 12
632 {
633  AVStream *st;
634  MOVStreamContext *sc;
635  int entries, i, j;
636 
637  if (c->fc->nb_streams < 1)
638  return 0;
639  st = c->fc->streams[c->fc->nb_streams-1];
640  sc = st->priv_data;
641 
642  avio_rb32(pb); // version + flags
643  entries = avio_rb32(pb);
644  if (!entries ||
645  entries > (atom.size - 1) / MIN_DATA_ENTRY_BOX_SIZE + 1 ||
646  entries >= UINT_MAX / sizeof(*sc->drefs))
647  return AVERROR_INVALIDDATA;
648 
649  for (i = 0; i < sc->drefs_count; i++) {
650  MOVDref *dref = &sc->drefs[i];
651  av_freep(&dref->path);
652  av_freep(&dref->dir);
653  }
654  av_free(sc->drefs);
655  sc->drefs_count = 0;
656  sc->drefs = av_mallocz(entries * sizeof(*sc->drefs));
657  if (!sc->drefs)
658  return AVERROR(ENOMEM);
659  sc->drefs_count = entries;
660 
661  for (i = 0; i < entries; i++) {
662  MOVDref *dref = &sc->drefs[i];
663  uint32_t size = avio_rb32(pb);
664  int64_t next = avio_tell(pb);
665 
666  if (size < 12 || next < 0 || next > INT64_MAX - size)
667  return AVERROR_INVALIDDATA;
668 
669  next += size - 4;
670 
671  dref->type = avio_rl32(pb);
672  avio_rb32(pb); // version + flags
673 
674  if (dref->type == MKTAG('a','l','i','s') && size > 150) {
675  /* macintosh alias record */
676  uint16_t volume_len, len;
677  int16_t type;
678  int ret;
679 
680  avio_skip(pb, 10);
681 
682  volume_len = avio_r8(pb);
683  volume_len = FFMIN(volume_len, 27);
684  ret = ffio_read_size(pb, dref->volume, 27);
685  if (ret < 0)
686  return ret;
687  dref->volume[volume_len] = 0;
688  av_log(c->fc, AV_LOG_DEBUG, "volume %s, len %d\n", dref->volume, volume_len);
689 
690  avio_skip(pb, 12);
691 
692  len = avio_r8(pb);
693  len = FFMIN(len, 63);
694  ret = ffio_read_size(pb, dref->filename, 63);
695  if (ret < 0)
696  return ret;
697  dref->filename[len] = 0;
698  av_log(c->fc, AV_LOG_DEBUG, "filename %s, len %d\n", dref->filename, len);
699 
700  avio_skip(pb, 16);
701 
702  /* read next level up_from_alias/down_to_target */
703  dref->nlvl_from = avio_rb16(pb);
704  dref->nlvl_to = avio_rb16(pb);
705  av_log(c->fc, AV_LOG_DEBUG, "nlvl from %d, nlvl to %d\n",
706  dref->nlvl_from, dref->nlvl_to);
707 
708  avio_skip(pb, 16);
709 
710  for (type = 0; type != -1 && avio_tell(pb) < next; ) {
711  if (avio_feof(pb))
712  return AVERROR_EOF;
713  type = avio_rb16(pb);
714  len = avio_rb16(pb);
715  av_log(c->fc, AV_LOG_DEBUG, "type %d, len %d\n", type, len);
716  if (len&1)
717  len += 1;
718  if (type == 2) { // absolute path
719  av_free(dref->path);
720  dref->path = av_mallocz(len+1);
721  if (!dref->path)
722  return AVERROR(ENOMEM);
723 
724  ret = ffio_read_size(pb, dref->path, len);
725  if (ret < 0) {
726  av_freep(&dref->path);
727  return ret;
728  }
729  if (len > volume_len && !strncmp(dref->path, dref->volume, volume_len)) {
730  len -= volume_len;
731  memmove(dref->path, dref->path+volume_len, len);
732  dref->path[len] = 0;
733  }
734  // trim string of any ending zeros
735  for (j = len - 1; j >= 0; j--) {
736  if (dref->path[j] == 0)
737  len--;
738  else
739  break;
740  }
741  for (j = 0; j < len; j++)
742  if (dref->path[j] == ':' || dref->path[j] == 0)
743  dref->path[j] = '/';
744  av_log(c->fc, AV_LOG_DEBUG, "path %s\n", dref->path);
745  } else if (type == 0) { // directory name
746  av_free(dref->dir);
747  dref->dir = av_malloc(len+1);
748  if (!dref->dir)
749  return AVERROR(ENOMEM);
750 
751  ret = ffio_read_size(pb, dref->dir, len);
752  if (ret < 0) {
753  av_freep(&dref->dir);
754  return ret;
755  }
756  dref->dir[len] = 0;
757  for (j = 0; j < len; j++)
758  if (dref->dir[j] == ':')
759  dref->dir[j] = '/';
760  av_log(c->fc, AV_LOG_DEBUG, "dir %s\n", dref->dir);
761  } else
762  avio_skip(pb, len);
763  }
764  } else {
765  av_log(c->fc, AV_LOG_DEBUG, "Unknown dref type 0x%08"PRIx32" size %"PRIu32"\n",
766  dref->type, size);
767  entries--;
768  i--;
769  }
770  avio_seek(pb, next, SEEK_SET);
771  }
772  return 0;
773 }
774 
776 {
777  AVStream *st;
778  uint32_t type;
779  uint32_t ctype;
780  int64_t title_size;
781  char *title_str;
782  int ret;
783 
784  avio_r8(pb); /* version */
785  avio_rb24(pb); /* flags */
786 
787  /* component type */
788  ctype = avio_rl32(pb);
789  type = avio_rl32(pb); /* component subtype */
790 
791  av_log(c->fc, AV_LOG_TRACE, "ctype=%s\n", av_fourcc2str(ctype));
792  av_log(c->fc, AV_LOG_TRACE, "stype=%s\n", av_fourcc2str(type));
793 
794  if (c->trak_index < 0) { // meta not inside a trak
795  if (type == MKTAG('m','d','t','a')) {
796  c->found_hdlr_mdta = 1;
797  }
798  return 0;
799  }
800 
801  st = c->fc->streams[c->fc->nb_streams-1];
802 
803  if (type == MKTAG('v','i','d','e'))
805  else if (type == MKTAG('s','o','u','n'))
807  else if (type == MKTAG('m','1','a',' '))
809  else if ((type == MKTAG('s','u','b','p')) || (type == MKTAG('c','l','c','p')))
811 
812  avio_rb32(pb); /* component manufacture */
813  avio_rb32(pb); /* component flags */
814  avio_rb32(pb); /* component flags mask */
815 
816  title_size = atom.size - 24;
817  if (title_size > 0) {
818  if (title_size > FFMIN(INT_MAX, SIZE_MAX-1))
819  return AVERROR_INVALIDDATA;
820  title_str = av_malloc(title_size + 1); /* Add null terminator */
821  if (!title_str)
822  return AVERROR(ENOMEM);
823 
824  ret = ffio_read_size(pb, title_str, title_size);
825  if (ret < 0) {
826  av_freep(&title_str);
827  return ret;
828  }
829  title_str[title_size] = 0;
830  if (title_str[0]) {
831  int off = (!c->isom && title_str[0] == title_size - 1);
832  // flag added so as to not set stream handler name if already set from mdia->hdlr
833  av_dict_set(&st->metadata, "handler_name", title_str + off, AV_DICT_DONT_OVERWRITE);
834  }
835  av_freep(&title_str);
836  }
837 
838  return 0;
839 }
840 
842 {
843  return ff_mov_read_esds(c->fc, pb);
844 }
845 
847 {
848  AVStream *st;
849  AVPacketSideData *sd;
850  enum AVAudioServiceType *ast;
851  int ac3info, acmod, lfeon, bsmod;
852  uint64_t mask;
853 
854  if (c->fc->nb_streams < 1)
855  return 0;
856  st = c->fc->streams[c->fc->nb_streams-1];
857 
861  sizeof(*ast), 0);
862  if (!sd)
863  return AVERROR(ENOMEM);
864 
865  ast = (enum AVAudioServiceType*)sd->data;
866  ac3info = avio_rb24(pb);
867  bsmod = (ac3info >> 14) & 0x7;
868  acmod = (ac3info >> 11) & 0x7;
869  lfeon = (ac3info >> 10) & 0x1;
870 
872  if (lfeon)
876 
877  *ast = bsmod;
878  if (st->codecpar->ch_layout.nb_channels > 1 && bsmod == 0x7)
880 
881  return 0;
882 }
883 
884 #if CONFIG_IAMFDEC
885 static int mov_read_iacb(MOVContext *c, AVIOContext *pb, MOVAtom atom)
886 {
887  AVStream *st;
888  MOVStreamContext *sc;
889  FFIOContext b;
890  AVIOContext *descriptor_pb;
891  AVDictionary *metadata;
892  IAMFContext *iamf;
894  unsigned descriptors_size;
895  int nb_frames, disposition;
896  int version, ret;
897 
898  if (atom.size < 5)
899  return AVERROR_INVALIDDATA;
900 
901  if (c->fc->nb_streams < 1)
902  return 0;
903 
904  version = avio_r8(pb);
905  if (version != 1) {
906  av_log(c->fc, AV_LOG_ERROR, "%s configurationVersion %d",
907  version < 1 ? "invalid" : "unsupported", version);
908  return AVERROR_INVALIDDATA;
909  }
910 
911  descriptors_size = ffio_read_leb(pb);
912  if (!descriptors_size || descriptors_size > INT_MAX)
913  return AVERROR_INVALIDDATA;
914 
915  st = c->fc->streams[c->fc->nb_streams - 1];
916  sc = st->priv_data;
917 
918  if (st->codecpar->extradata) {
919  av_log(c->fc, AV_LOG_WARNING, "ignoring iacb\n");
920  return 0;
921  }
922 
923  sc->iamf = av_mallocz(sizeof(*sc->iamf));
924  if (!sc->iamf)
925  return AVERROR(ENOMEM);
926  iamf = &sc->iamf->iamf;
927 
928  st->codecpar->extradata = av_malloc(descriptors_size);
929  if (!st->codecpar->extradata)
930  return AVERROR(ENOMEM);
931  st->codecpar->extradata_size = descriptors_size;
932 
933  ret = avio_read(pb, st->codecpar->extradata, descriptors_size);
934  if (ret != descriptors_size)
935  return ret < 0 ? ret : AVERROR_INVALIDDATA;
936 
937  ffio_init_read_context(&b, st->codecpar->extradata, descriptors_size);
938  descriptor_pb = &b.pub;
939 
940  ret = ff_iamfdec_read_descriptors(iamf, descriptor_pb, descriptors_size, c->fc);
941  if (ret < 0)
942  return ret;
943 
944  metadata = st->metadata;
945  st->metadata = NULL;
946  start_time = st->start_time;
947  nb_frames = st->nb_frames;
948  duration = st->duration;
949  disposition = st->disposition;
950 
951  for (int i = 0; i < iamf->nb_audio_elements; i++) {
952  IAMFAudioElement *audio_element = iamf->audio_elements[i];
953  const AVIAMFAudioElement *element;
954  AVStreamGroup *stg =
956 
957  if (!stg) {
958  ret = AVERROR(ENOMEM);
959  goto fail;
960  }
961 
963  stg->id = audio_element->audio_element_id;
964  /* Transfer ownership */
965  element = stg->params.iamf_audio_element = audio_element->element;
966  audio_element->element = NULL;
967 
968  for (int j = 0; j < audio_element->nb_substreams; j++) {
969  IAMFSubStream *substream = &audio_element->substreams[j];
970  AVStream *stream;
971 
972  if (!i && !j) {
973  if (audio_element->layers[0].substream_count != 1)
974  disposition &= ~AV_DISPOSITION_DEFAULT;
975  stream = st;
976  } else
977  stream = avformat_new_stream(c->fc, NULL);
978  if (!stream) {
979  ret = AVERROR(ENOMEM);
980  goto fail;
981  }
982 
983  stream->start_time = start_time;
984  stream->nb_frames = nb_frames;
985  stream->duration = duration;
986  stream->disposition = disposition;
987  if (stream != st) {
988  stream->priv_data = sc;
989  sc->refcount++;
990  }
991 
994  if (i || j) {
996  if (audio_element->layers[0].substream_count == 1)
998  }
999 
1000  ret = avcodec_parameters_copy(stream->codecpar, substream->codecpar);
1001  if (ret < 0)
1002  goto fail;
1003 
1004  stream->id = substream->audio_substream_id;
1005 
1006  avpriv_set_pts_info(st, 64, 1, sc->time_scale);
1007 
1008  ret = avformat_stream_group_add_stream(stg, stream);
1009  if (ret < 0)
1010  goto fail;
1011  }
1012 
1013  ret = av_dict_copy(&stg->metadata, metadata, 0);
1014  if (ret < 0)
1015  goto fail;
1016  }
1017 
1018  for (int i = 0; i < iamf->nb_mix_presentations; i++) {
1019  IAMFMixPresentation *mix_presentation = iamf->mix_presentations[i];
1020  const AVIAMFMixPresentation *mix = mix_presentation->cmix;
1021  AVStreamGroup *stg =
1023 
1024  if (!stg) {
1025  ret = AVERROR(ENOMEM);
1026  goto fail;
1027  }
1028 
1030  stg->id = mix_presentation->mix_presentation_id;
1031  /* Transfer ownership */
1032  stg->params.iamf_mix_presentation = mix_presentation->mix;
1033  mix_presentation->mix = NULL;
1034 
1035  for (int j = 0; j < mix->nb_submixes; j++) {
1036  const AVIAMFSubmix *submix = mix->submixes[j];
1037 
1038  for (int k = 0; k < submix->nb_elements; k++) {
1039  const AVIAMFSubmixElement *submix_element = submix->elements[k];
1040  const AVStreamGroup *audio_element = NULL;
1041 
1042  for (int l = 0; l < c->fc->nb_stream_groups; l++)
1043  if (c->fc->stream_groups[l]->type == AV_STREAM_GROUP_PARAMS_IAMF_AUDIO_ELEMENT &&
1044  c->fc->stream_groups[l]->id == submix_element->audio_element_id) {
1045  audio_element = c->fc->stream_groups[l];
1046  break;
1047  }
1048  av_assert0(audio_element);
1049 
1050  for (int l = 0; l < audio_element->nb_streams; l++) {
1051  ret = avformat_stream_group_add_stream(stg, audio_element->streams[l]);
1052  if (ret < 0 && ret != AVERROR(EEXIST))
1053  goto fail;
1054  }
1055  }
1056  }
1057 
1058  ret = av_dict_copy(&stg->metadata, metadata, 0);
1059  if (ret < 0)
1060  goto fail;
1061  }
1062 
1063  ret = 0;
1064 fail:
1065  av_dict_free(&metadata);
1066 
1067  return ret;
1068 }
1069 #endif
1070 
1072 {
1073  AVStream *st;
1074  AVPacketSideData *sd;
1075  enum AVAudioServiceType *ast;
1076  int eac3info, acmod, lfeon, bsmod;
1077  uint64_t mask;
1078 
1079  if (c->fc->nb_streams < 1)
1080  return 0;
1081  st = c->fc->streams[c->fc->nb_streams-1];
1082 
1086  sizeof(*ast), 0);
1087  if (!sd)
1088  return AVERROR(ENOMEM);
1089 
1090  ast = (enum AVAudioServiceType*)sd->data;
1091 
1092  /* No need to parse fields for additional independent substreams and its
1093  * associated dependent substreams since libavcodec's E-AC-3 decoder
1094  * does not support them yet. */
1095  avio_rb16(pb); /* data_rate and num_ind_sub */
1096  eac3info = avio_rb24(pb);
1097  bsmod = (eac3info >> 12) & 0x1f;
1098  acmod = (eac3info >> 9) & 0x7;
1099  lfeon = (eac3info >> 8) & 0x1;
1100 
1102  if (lfeon)
1106 
1107  *ast = bsmod;
1108  if (st->codecpar->ch_layout.nb_channels > 1 && bsmod == 0x7)
1110 
1111  return 0;
1112 }
1113 
1115 {
1116 #define DDTS_SIZE 20
1117  uint8_t buf[DDTS_SIZE + AV_INPUT_BUFFER_PADDING_SIZE];
1118  AVStream *st = NULL;
1119  uint32_t frame_duration_code = 0;
1120  uint32_t channel_layout_code = 0;
1121  GetBitContext gb;
1122  int ret;
1123 
1124  if ((ret = ffio_read_size(pb, buf, DDTS_SIZE)) < 0)
1125  return ret;
1126 
1127  init_get_bits(&gb, buf, 8 * DDTS_SIZE);
1128 
1129  if (c->fc->nb_streams < 1) {
1130  return 0;
1131  }
1132  st = c->fc->streams[c->fc->nb_streams-1];
1133 
1134  st->codecpar->sample_rate = get_bits_long(&gb, 32);
1135  if (st->codecpar->sample_rate <= 0) {
1136  av_log(c->fc, AV_LOG_ERROR, "Invalid sample rate %d\n", st->codecpar->sample_rate);
1137  return AVERROR_INVALIDDATA;
1138  }
1139  skip_bits_long(&gb, 32); /* max bitrate */
1140  st->codecpar->bit_rate = get_bits_long(&gb, 32);
1141  st->codecpar->bits_per_coded_sample = get_bits(&gb, 8);
1142  frame_duration_code = get_bits(&gb, 2);
1143  skip_bits(&gb, 30); /* various fields */
1144  channel_layout_code = get_bits(&gb, 16);
1145 
1146  st->codecpar->frame_size =
1147  (frame_duration_code == 0) ? 512 :
1148  (frame_duration_code == 1) ? 1024 :
1149  (frame_duration_code == 2) ? 2048 :
1150  (frame_duration_code == 3) ? 4096 : 0;
1151 
1152  if (channel_layout_code > 0xff) {
1153  av_log(c->fc, AV_LOG_WARNING, "Unsupported DTS audio channel layout\n");
1154  }
1157  ((channel_layout_code & 0x1) ? AV_CH_FRONT_CENTER : 0) |
1158  ((channel_layout_code & 0x2) ? AV_CH_FRONT_LEFT : 0) |
1159  ((channel_layout_code & 0x2) ? AV_CH_FRONT_RIGHT : 0) |
1160  ((channel_layout_code & 0x4) ? AV_CH_SIDE_LEFT : 0) |
1161  ((channel_layout_code & 0x4) ? AV_CH_SIDE_RIGHT : 0) |
1162  ((channel_layout_code & 0x8) ? AV_CH_LOW_FREQUENCY : 0));
1163 
1164  return 0;
1165 }
1166 
1168 {
1169  AVStream *st;
1170 
1171  if (c->fc->nb_streams < 1)
1172  return 0;
1173  st = c->fc->streams[c->fc->nb_streams-1];
1174 
1175  if (atom.size < 16)
1176  return 0;
1177 
1178  /* skip version and flags */
1179  avio_skip(pb, 4);
1180 
1181  ff_mov_read_chan(c->fc, pb, st, atom.size - 4);
1182 
1183  return 0;
1184 }
1185 
1187 {
1188  int64_t end = av_sat_add64(avio_tell(pb), atom.size);
1189  int version, flags;
1190  int ret;
1191  AVStream *st;
1192 
1193  if (c->fc->nb_streams < 1)
1194  return 0;
1195  st = c->fc->streams[c->fc->nb_streams-1];
1196 
1197  version = avio_r8(pb);
1198  flags = avio_rb24(pb);
1199  if (version != 0 || flags != 0) {
1200  av_log(c->fc, AV_LOG_ERROR,
1201  "Unsupported 'chnl' box with version %d, flags: %#x",
1202  version, flags);
1203  return AVERROR_INVALIDDATA;
1204  }
1205 
1206  ret = ff_mov_read_chnl(c->fc, pb, st);
1207  if (ret < 0)
1208  return ret;
1209 
1210  if (avio_tell(pb) != end) {
1211  av_log(c->fc, AV_LOG_WARNING, "skip %" PRId64 " bytes of unknown data inside chnl\n",
1212  end - avio_tell(pb));
1213  avio_seek(pb, end, SEEK_SET);
1214  }
1215  return ret;
1216 }
1217 
1219 {
1220  AVStream *st;
1221  int ret;
1222 
1223  if (c->fc->nb_streams < 1)
1224  return 0;
1225  st = c->fc->streams[c->fc->nb_streams-1];
1226 
1227  if ((ret = ff_get_wav_header(c->fc, pb, st->codecpar, atom.size, 0)) < 0)
1228  av_log(c->fc, AV_LOG_WARNING, "get_wav_header failed\n");
1229 
1230  return ret;
1231 }
1232 
1234 {
1235  AVStream *st;
1236  AVPacketSideData *sd;
1237  AVRational aperture_width, aperture_height, horiz_off, vert_off;
1238  AVRational pc_x, pc_y;
1239  uint64_t top, bottom, left, right;
1240 
1241  if (c->fc->nb_streams < 1)
1242  return 0;
1243  st = c->fc->streams[c->fc->nb_streams-1];
1244 
1245  aperture_width.num = avio_rb32(pb);
1246  aperture_width.den = avio_rb32(pb);
1247  aperture_height.num = avio_rb32(pb);
1248  aperture_height.den = avio_rb32(pb);
1249 
1250  horiz_off.num = avio_rb32(pb);
1251  horiz_off.den = avio_rb32(pb);
1252  vert_off.num = avio_rb32(pb);
1253  vert_off.den = avio_rb32(pb);
1254 
1255  if (aperture_width.num < 0 || aperture_width.den < 0 ||
1256  aperture_height.num < 0 || aperture_height.den < 0 ||
1257  horiz_off.den < 0 || vert_off.den < 0)
1258  return AVERROR_INVALIDDATA;
1259 
1260  av_log(c->fc, AV_LOG_TRACE, "clap: apertureWidth %d/%d, apertureHeight %d/%d "
1261  "horizOff %d/%d vertOff %d/%d\n",
1262  aperture_width.num, aperture_width.den, aperture_height.num, aperture_height.den,
1263  horiz_off.num, horiz_off.den, vert_off.num, vert_off.den);
1264 
1265  pc_x = av_mul_q((AVRational) { st->codecpar->width - 1, 1 }, (AVRational) { 1, 2 });
1266  pc_x = av_add_q(pc_x, horiz_off);
1267  pc_y = av_mul_q((AVRational) { st->codecpar->height - 1, 1 }, (AVRational) { 1, 2 });
1268  pc_y = av_add_q(pc_y, vert_off);
1269 
1270  aperture_width = av_sub_q(aperture_width, (AVRational) { 1, 1 });
1271  aperture_width = av_mul_q(aperture_width, (AVRational) { 1, 2 });
1272  aperture_height = av_sub_q(aperture_height, (AVRational) { 1, 1 });
1273  aperture_height = av_mul_q(aperture_height, (AVRational) { 1, 2 });
1274 
1275  left = av_q2d(av_sub_q(pc_x, aperture_width));
1276  right = av_q2d(av_add_q(pc_x, aperture_width));
1277  top = av_q2d(av_sub_q(pc_y, aperture_height));
1278  bottom = av_q2d(av_add_q(pc_y, aperture_height));
1279 
1280  if (bottom > (st->codecpar->height - 1) ||
1281  right > (st->codecpar->width - 1))
1282  return AVERROR_INVALIDDATA;
1283 
1284  bottom = st->codecpar->height - 1 - bottom;
1285  right = st->codecpar->width - 1 - right;
1286 
1287  if (!(left | right | top | bottom))
1288  return 0;
1289 
1290  if ((left + right) >= st->codecpar->width ||
1291  (top + bottom) >= st->codecpar->height)
1292  return AVERROR_INVALIDDATA;
1293 
1297  sizeof(uint32_t) * 4, 0);
1298  if (!sd)
1299  return AVERROR(ENOMEM);
1300 
1301  AV_WL32A(sd->data, top);
1302  AV_WL32A(sd->data + 4, bottom);
1303  AV_WL32A(sd->data + 8, left);
1304  AV_WL32A(sd->data + 12, right);
1305 
1306  return 0;
1307 }
1308 
1309 /* This atom overrides any previously set aspect ratio */
1311 {
1312  const int num = avio_rb32(pb);
1313  const int den = avio_rb32(pb);
1314  AVStream *st;
1315  MOVStreamContext *sc;
1316 
1317  if (c->fc->nb_streams < 1)
1318  return 0;
1319  st = c->fc->streams[c->fc->nb_streams-1];
1320  sc = st->priv_data;
1321 
1322  av_log(c->fc, AV_LOG_TRACE, "pasp: hSpacing %d, vSpacing %d\n", num, den);
1323 
1324  if (den != 0) {
1325  sc->h_spacing = num;
1326  sc->v_spacing = den;
1327  }
1328  return 0;
1329 }
1330 
1331 /* this atom contains actual media data */
1333 {
1334  if (atom.size == 0) /* wrong one (MP4) */
1335  return 0;
1336  c->found_mdat=1;
1337  return 0; /* now go for moov */
1338 }
1339 
1340 #define DRM_BLOB_SIZE 56
1341 
1343 {
1344  uint8_t intermediate_key[20];
1345  uint8_t intermediate_iv[20];
1346  uint8_t input[64];
1347  uint8_t output[64];
1348  uint8_t file_checksum[20];
1349  uint8_t calculated_checksum[20];
1350  char checksum_string[2 * sizeof(file_checksum) + 1];
1351  struct AVSHA *sha;
1352  int i;
1353  int ret = 0;
1354  uint8_t *activation_bytes = c->activation_bytes;
1355  uint8_t *fixed_key = c->audible_fixed_key;
1356 
1357  c->aax_mode = 1;
1358 
1359  sha = av_sha_alloc();
1360  if (!sha)
1361  return AVERROR(ENOMEM);
1362  av_free(c->aes_decrypt);
1363  c->aes_decrypt = av_aes_alloc();
1364  if (!c->aes_decrypt) {
1365  ret = AVERROR(ENOMEM);
1366  goto fail;
1367  }
1368 
1369  /* drm blob processing */
1370  avio_read(pb, output, 8); // go to offset 8, absolute position 0x251
1372  avio_read(pb, output, 4); // go to offset 4, absolute position 0x28d
1373  avio_read(pb, file_checksum, 20);
1374 
1375  // required by external tools
1376  ff_data_to_hex(checksum_string, file_checksum, sizeof(file_checksum), 1);
1377  av_log(c->fc, AV_LOG_INFO, "[aax] file checksum == %s\n", checksum_string);
1378 
1379  /* verify activation data */
1380  if (!activation_bytes) {
1381  av_log(c->fc, AV_LOG_WARNING, "[aax] activation_bytes option is missing!\n");
1382  ret = 0; /* allow ffprobe to continue working on .aax files */
1383  goto fail;
1384  }
1385  if (c->activation_bytes_size != 4) {
1386  av_log(c->fc, AV_LOG_FATAL, "[aax] activation_bytes value needs to be 4 bytes!\n");
1387  ret = AVERROR(EINVAL);
1388  goto fail;
1389  }
1390 
1391  /* verify fixed key */
1392  if (c->audible_fixed_key_size != 16) {
1393  av_log(c->fc, AV_LOG_FATAL, "[aax] audible_fixed_key value needs to be 16 bytes!\n");
1394  ret = AVERROR(EINVAL);
1395  goto fail;
1396  }
1397 
1398  /* AAX (and AAX+) key derivation */
1399  av_sha_init(sha, 160);
1400  av_sha_update(sha, fixed_key, 16);
1401  av_sha_update(sha, activation_bytes, 4);
1402  av_sha_final(sha, intermediate_key);
1403  av_sha_init(sha, 160);
1404  av_sha_update(sha, fixed_key, 16);
1405  av_sha_update(sha, intermediate_key, 20);
1406  av_sha_update(sha, activation_bytes, 4);
1407  av_sha_final(sha, intermediate_iv);
1408  av_sha_init(sha, 160);
1409  av_sha_update(sha, intermediate_key, 16);
1410  av_sha_update(sha, intermediate_iv, 16);
1411  av_sha_final(sha, calculated_checksum);
1412  if (memcmp(calculated_checksum, file_checksum, 20)) { // critical error
1413  av_log(c->fc, AV_LOG_ERROR, "[aax] mismatch in checksums!\n");
1415  goto fail;
1416  }
1417  av_aes_init(c->aes_decrypt, intermediate_key, 128, 1);
1418  av_aes_crypt(c->aes_decrypt, output, input, DRM_BLOB_SIZE >> 4, intermediate_iv, 1);
1419  for (i = 0; i < 4; i++) {
1420  // file data (in output) is stored in big-endian mode
1421  if (activation_bytes[i] != output[3 - i]) { // critical error
1422  av_log(c->fc, AV_LOG_ERROR, "[aax] error in drm blob decryption!\n");
1424  goto fail;
1425  }
1426  }
1427  memcpy(c->file_key, output + 8, 16);
1428  memcpy(input, output + 26, 16);
1429  av_sha_init(sha, 160);
1430  av_sha_update(sha, input, 16);
1431  av_sha_update(sha, c->file_key, 16);
1432  av_sha_update(sha, fixed_key, 16);
1433  av_sha_final(sha, c->file_iv);
1434 
1435 fail:
1436  av_free(sha);
1437 
1438  return ret;
1439 }
1440 
1442 {
1443  if (c->audible_key_size != 16) {
1444  av_log(c->fc, AV_LOG_FATAL, "[aaxc] audible_key value needs to be 16 bytes!\n");
1445  return AVERROR(EINVAL);
1446  }
1447 
1448  if (c->audible_iv_size != 16) {
1449  av_log(c->fc, AV_LOG_FATAL, "[aaxc] audible_iv value needs to be 16 bytes!\n");
1450  return AVERROR(EINVAL);
1451  }
1452 
1453  c->aes_decrypt = av_aes_alloc();
1454  if (!c->aes_decrypt) {
1455  return AVERROR(ENOMEM);
1456  }
1457 
1458  memcpy(c->file_key, c->audible_key, 16);
1459  memcpy(c->file_iv, c->audible_iv, 16);
1460  c->aax_mode = 1;
1461 
1462  return 0;
1463 }
1464 
1465 // Audible AAX (and AAX+) bytestream decryption
1466 static int aax_filter(uint8_t *input, int size, MOVContext *c)
1467 {
1468  int blocks = 0;
1469  unsigned char iv[16];
1470 
1471  memcpy(iv, c->file_iv, 16); // iv is overwritten
1472  blocks = size >> 4; // trailing bytes are not encrypted!
1473  av_aes_init(c->aes_decrypt, c->file_key, 128, 1);
1474  av_aes_crypt(c->aes_decrypt, input, input, blocks, iv, 1);
1475 
1476  return 0;
1477 }
1478 
1479 /* read major brand, minor version and compatible brands and store them as metadata */
1481 {
1482  uint32_t minor_ver;
1483  int comp_brand_size;
1484  char* comp_brands_str;
1485  uint8_t type[5] = {0};
1486  int ret = ffio_read_size(pb, type, 4);
1487  if (ret < 0)
1488  return ret;
1489  if (c->fc->nb_streams) {
1490  if (c->fc->strict_std_compliance >= FF_COMPLIANCE_STRICT)
1491  return AVERROR_INVALIDDATA;
1492  av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate FTYP\n");
1493  return 0;
1494  }
1495 
1496  if (strcmp(type, "qt "))
1497  c->isom = 1;
1498  av_log(c->fc, AV_LOG_DEBUG, "ISO: File Type Major Brand: %.4s\n",(char *)&type);
1499  av_dict_set(&c->fc->metadata, "major_brand", type, 0);
1500  minor_ver = avio_rb32(pb); /* minor version */
1501  av_dict_set_int(&c->fc->metadata, "minor_version", minor_ver, 0);
1502 
1503  comp_brand_size = atom.size - 8;
1504  if (comp_brand_size < 0 || comp_brand_size == INT_MAX)
1505  return AVERROR_INVALIDDATA;
1506  comp_brands_str = av_malloc(comp_brand_size + 1); /* Add null terminator */
1507  if (!comp_brands_str)
1508  return AVERROR(ENOMEM);
1509 
1510  ret = ffio_read_size(pb, comp_brands_str, comp_brand_size);
1511  if (ret < 0) {
1512  av_freep(&comp_brands_str);
1513  return ret;
1514  }
1515  comp_brands_str[comp_brand_size] = 0;
1516  av_dict_set(&c->fc->metadata, "compatible_brands",
1517  comp_brands_str, AV_DICT_DONT_STRDUP_VAL);
1518 
1519  // Logic for handling Audible's .aaxc files
1520  if (!strcmp(type, "aaxc")) {
1521  mov_aaxc_crypto(c);
1522  }
1523 
1524  return 0;
1525 }
1526 
1527 /* this atom should contain all header atoms */
1529 {
1530  int ret;
1531 
1532  if (c->found_moov) {
1533  av_log(c->fc, AV_LOG_WARNING, "Found duplicated MOOV Atom. Skipped it\n");
1534  avio_skip(pb, atom.size);
1535  return 0;
1536  }
1537 
1538  if ((ret = mov_read_default(c, pb, atom)) < 0)
1539  return ret;
1540  /* we parsed the 'moov' atom, we can terminate the parsing as soon as we find the 'mdat' */
1541  /* so we don't parse the whole file if over a network */
1542  c->found_moov=1;
1543  return 0; /* now go for mdat */
1544 }
1545 
1547  MOVFragmentIndex *frag_index,
1548  int index,
1549  int id)
1550 {
1551  int i;
1552  MOVFragmentIndexItem * item;
1553 
1554  if (index < 0 || index >= frag_index->nb_items)
1555  return NULL;
1556  item = &frag_index->item[index];
1557  for (i = 0; i < item->nb_stream_info; i++)
1558  if (item->stream_info[i].id == id)
1559  return &item->stream_info[i];
1560 
1561  // This shouldn't happen
1562  return NULL;
1563 }
1564 
1565 static void set_frag_stream(MOVFragmentIndex *frag_index, int id)
1566 {
1567  int i;
1568  MOVFragmentIndexItem * item;
1569 
1570  if (frag_index->current < 0 ||
1571  frag_index->current >= frag_index->nb_items)
1572  return;
1573 
1574  item = &frag_index->item[frag_index->current];
1575  for (i = 0; i < item->nb_stream_info; i++)
1576  if (item->stream_info[i].id == id) {
1577  item->current = i;
1578  return;
1579  }
1580 
1581  // id not found. This shouldn't happen.
1582  item->current = -1;
1583 }
1584 
1586  MOVFragmentIndex *frag_index)
1587 {
1588  MOVFragmentIndexItem *item;
1589  if (frag_index->current < 0 ||
1590  frag_index->current >= frag_index->nb_items)
1591  return NULL;
1592 
1593  item = &frag_index->item[frag_index->current];
1594  if (item->current >= 0 && item->current < item->nb_stream_info)
1595  return &item->stream_info[item->current];
1596 
1597  // This shouldn't happen
1598  return NULL;
1599 }
1600 
1602 {
1603  int a, b, m;
1604  int64_t moof_offset;
1605 
1606  // Optimize for appending new entries
1607  if (!frag_index->nb_items ||
1608  frag_index->item[frag_index->nb_items - 1].moof_offset < offset)
1609  return frag_index->nb_items;
1610 
1611  a = -1;
1612  b = frag_index->nb_items;
1613 
1614  while (b - a > 1) {
1615  m = (a + b) >> 1;
1616  moof_offset = frag_index->item[m].moof_offset;
1617  if (moof_offset >= offset)
1618  b = m;
1619  if (moof_offset <= offset)
1620  a = m;
1621  }
1622  return b;
1623 }
1624 
1626 {
1627  av_assert0(frag_stream_info);
1628  if (frag_stream_info->sidx_pts != AV_NOPTS_VALUE)
1629  return frag_stream_info->sidx_pts;
1630  if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE)
1631  return frag_stream_info->first_tfra_pts;
1632  return frag_stream_info->tfdt_dts;
1633 }
1634 
1636  MOVFragmentIndex *frag_index, int index)
1637 {
1638  MOVFragmentStreamInfo * frag_stream_info;
1639  MOVStreamContext *sc = dst_st->priv_data;
1640  int64_t timestamp;
1641  int i, j;
1642 
1643  // If the stream is referenced by any sidx, limit the search
1644  // to fragments that referenced this stream in the sidx
1645  if (sc->has_sidx) {
1646  frag_stream_info = get_frag_stream_info(frag_index, index, sc->id);
1647  if (!frag_stream_info)
1648  return AV_NOPTS_VALUE;
1649  if (frag_stream_info->sidx_pts != AV_NOPTS_VALUE)
1650  return frag_stream_info->sidx_pts;
1651  if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE)
1652  return frag_stream_info->first_tfra_pts;
1653  return frag_stream_info->sidx_pts;
1654  }
1655 
1656  for (i = 0; i < frag_index->item[index].nb_stream_info; i++) {
1657  AVStream *frag_stream = NULL;
1658  frag_stream_info = &frag_index->item[index].stream_info[i];
1659  for (j = 0; j < s->nb_streams; j++) {
1660  MOVStreamContext *sc2 = s->streams[j]->priv_data;
1661  if (sc2->id == frag_stream_info->id)
1662  frag_stream = s->streams[j];
1663  }
1664  if (!frag_stream) {
1665  av_log(s, AV_LOG_WARNING, "No stream matching sidx ID found.\n");
1666  continue;
1667  }
1668  timestamp = get_stream_info_time(frag_stream_info);
1669  if (timestamp != AV_NOPTS_VALUE)
1670  return av_rescale_q(timestamp, frag_stream->time_base, dst_st->time_base);
1671  }
1672  return AV_NOPTS_VALUE;
1673 }
1674 
1676  AVStream *st, int64_t timestamp)
1677 {
1678  int a, b, m, m0;
1679  int64_t frag_time;
1680 
1681  a = -1;
1682  b = frag_index->nb_items;
1683 
1684  while (b - a > 1) {
1685  m0 = m = (a + b) >> 1;
1686 
1687  while (m < b &&
1688  (frag_time = get_frag_time(s, st, frag_index, m)) == AV_NOPTS_VALUE)
1689  m++;
1690 
1691  if (m < b && frag_time <= timestamp)
1692  a = m;
1693  else
1694  b = m0;
1695  }
1696 
1697  return a;
1698 }
1699 
1701 {
1702  int index, i;
1703  MOVFragmentIndexItem * item;
1704  MOVFragmentStreamInfo * frag_stream_info;
1705 
1706  // If moof_offset already exists in frag_index, return index to it
1707  index = search_frag_moof_offset(&c->frag_index, offset);
1708  if (index < c->frag_index.nb_items &&
1709  c->frag_index.item[index].moof_offset == offset)
1710  return index;
1711 
1712  // offset is not yet in frag index.
1713  // Insert new item at index (sorted by moof offset)
1714  item = av_fast_realloc(c->frag_index.item,
1715  &c->frag_index.allocated_size,
1716  (c->frag_index.nb_items + 1) *
1717  sizeof(*c->frag_index.item));
1718  if (!item)
1719  return -1;
1720  c->frag_index.item = item;
1721 
1722  frag_stream_info = av_realloc_array(NULL, c->fc->nb_streams,
1723  sizeof(*item->stream_info));
1724  if (!frag_stream_info)
1725  return -1;
1726 
1727  for (i = 0; i < c->fc->nb_streams; i++) {
1728  // Avoid building frag index if streams lack track id.
1729  MOVStreamContext *sc = c->fc->streams[i]->priv_data;
1730  if (sc->id < 0) {
1731  av_free(frag_stream_info);
1732  return AVERROR_INVALIDDATA;
1733  }
1734 
1735  frag_stream_info[i].id = sc->id;
1736  frag_stream_info[i].sidx_pts = AV_NOPTS_VALUE;
1737  frag_stream_info[i].tfdt_dts = AV_NOPTS_VALUE;
1738  frag_stream_info[i].next_trun_dts = AV_NOPTS_VALUE;
1739  frag_stream_info[i].first_tfra_pts = AV_NOPTS_VALUE;
1740  frag_stream_info[i].index_base = -1;
1741  frag_stream_info[i].index_entry = -1;
1742  frag_stream_info[i].encryption_index = NULL;
1743  frag_stream_info[i].stsd_id = -1;
1744  }
1745 
1746  if (index < c->frag_index.nb_items)
1747  memmove(c->frag_index.item + index + 1, c->frag_index.item + index,
1748  (c->frag_index.nb_items - index) * sizeof(*c->frag_index.item));
1749 
1750  item = &c->frag_index.item[index];
1751  item->headers_read = 0;
1752  item->current = 0;
1753  item->nb_stream_info = c->fc->nb_streams;
1754  item->moof_offset = offset;
1755  item->stream_info = frag_stream_info;
1756  c->frag_index.nb_items++;
1757 
1758  return index;
1759 }
1760 
1761 static void fix_frag_index_entries(MOVFragmentIndex *frag_index, int index,
1762  int id, int entries)
1763 {
1764  int i;
1765  MOVFragmentStreamInfo * frag_stream_info;
1766 
1767  if (index < 0)
1768  return;
1769  for (i = index; i < frag_index->nb_items; i++) {
1770  frag_stream_info = get_frag_stream_info(frag_index, i, id);
1771  if (frag_stream_info && frag_stream_info->index_entry >= 0)
1772  frag_stream_info->index_entry += entries;
1773  }
1774 }
1775 
1777 {
1778  // Set by mov_read_tfhd(). mov_read_trun() will reject files missing tfhd.
1779  c->fragment.found_tfhd = 0;
1780 
1781  if (!c->has_looked_for_mfra && c->use_mfra_for > 0) {
1782  c->has_looked_for_mfra = 1;
1783  if (pb->seekable & AVIO_SEEKABLE_NORMAL) {
1784  int ret;
1785  av_log(c->fc, AV_LOG_VERBOSE, "stream has moof boxes, will look "
1786  "for a mfra\n");
1787  if ((ret = mov_read_mfra(c, pb)) < 0) {
1788  av_log(c->fc, AV_LOG_VERBOSE, "found a moof box but failed to "
1789  "read the mfra (may be a live ismv)\n");
1790  }
1791  } else {
1792  av_log(c->fc, AV_LOG_VERBOSE, "found a moof box but stream is not "
1793  "seekable, can not look for mfra\n");
1794  }
1795  }
1796  c->fragment.moof_offset = c->fragment.implicit_offset = avio_tell(pb) - 8;
1797  av_log(c->fc, AV_LOG_TRACE, "moof offset %"PRIx64"\n", c->fragment.moof_offset);
1798  c->frag_index.current = update_frag_index(c, c->fragment.moof_offset);
1799  return mov_read_default(c, pb, atom);
1800 }
1801 
1803 {
1804  int64_t time;
1805  if (version == 1) {
1806  time = avio_rb64(pb);
1807  avio_rb64(pb);
1808  if (time < 0) {
1809  av_log(c->fc, AV_LOG_DEBUG, "creation_time is negative\n");
1810  return;
1811  }
1812  } else {
1813  time = avio_rb32(pb);
1814  avio_rb32(pb); /* modification time */
1815  if (time > 0 && time < 2082844800) {
1816  av_log(c->fc, AV_LOG_WARNING, "Detected creation time before 1970, parsing as unix timestamp.\n");
1817  time += 2082844800;
1818  }
1819  }
1820  if (time) {
1821  time -= 2082844800; /* seconds between 1904-01-01 and Epoch */
1822 
1823  if ((int64_t)(time * 1000000ULL) / 1000000 != time) {
1824  av_log(c->fc, AV_LOG_DEBUG, "creation_time is not representable\n");
1825  return;
1826  }
1827 
1828  avpriv_dict_set_timestamp(metadata, "creation_time", time * 1000000);
1829  }
1830 }
1831 
1833 {
1834  AVStream *st;
1835  MOVStreamContext *sc;
1836  int version;
1837  char language[4] = {0};
1838  unsigned lang;
1839 
1840  if (c->fc->nb_streams < 1)
1841  return 0;
1842  st = c->fc->streams[c->fc->nb_streams-1];
1843  sc = st->priv_data;
1844 
1845  if (sc->time_scale) {
1846  av_log(c->fc, AV_LOG_ERROR, "Multiple mdhd?\n");
1847  return AVERROR_INVALIDDATA;
1848  }
1849 
1850  version = avio_r8(pb);
1851  if (version > 1) {
1852  avpriv_request_sample(c->fc, "Version %d", version);
1853  return AVERROR_PATCHWELCOME;
1854  }
1855  avio_rb24(pb); /* flags */
1857 
1858  sc->time_scale = avio_rb32(pb);
1859  if (sc->time_scale <= 0) {
1860  av_log(c->fc, AV_LOG_ERROR, "Invalid mdhd time scale %d, defaulting to 1\n", sc->time_scale);
1861  sc->time_scale = 1;
1862  }
1863  st->duration = (version == 1) ? avio_rb64(pb) : avio_rb32(pb); /* duration */
1864 
1865  if ((version == 1 && st->duration == UINT64_MAX) ||
1866  (version != 1 && st->duration == UINT32_MAX)) {
1867  st->duration = 0;
1868  }
1869 
1870  lang = avio_rb16(pb); /* language */
1871  if (ff_mov_lang_to_iso639(lang, language))
1872  av_dict_set(&st->metadata, "language", language, 0);
1873  avio_rb16(pb); /* quality */
1874 
1875  return 0;
1876 }
1877 
1879 {
1880  int i;
1881  int version = avio_r8(pb); /* version */
1882  avio_rb24(pb); /* flags */
1883 
1884  mov_metadata_creation_time(c, pb, &c->fc->metadata, version);
1885  c->time_scale = avio_rb32(pb); /* time scale */
1886  if (c->time_scale <= 0) {
1887  av_log(c->fc, AV_LOG_ERROR, "Invalid mvhd time scale %d, defaulting to 1\n", c->time_scale);
1888  c->time_scale = 1;
1889  }
1890  av_log(c->fc, AV_LOG_TRACE, "time scale = %i\n", c->time_scale);
1891 
1892  c->duration = (version == 1) ? avio_rb64(pb) : avio_rb32(pb); /* duration */
1893  avio_rb32(pb); /* preferred scale */
1894 
1895  avio_rb16(pb); /* preferred volume */
1896 
1897  avio_skip(pb, 10); /* reserved */
1898 
1899  /* movie display matrix, store it in main context and use it later on */
1900  for (i = 0; i < 3; i++) {
1901  c->movie_display_matrix[i][0] = avio_rb32(pb); // 16.16 fixed point
1902  c->movie_display_matrix[i][1] = avio_rb32(pb); // 16.16 fixed point
1903  c->movie_display_matrix[i][2] = avio_rb32(pb); // 2.30 fixed point
1904  }
1905 
1906  avio_rb32(pb); /* preview time */
1907  avio_rb32(pb); /* preview duration */
1908  avio_rb32(pb); /* poster time */
1909  avio_rb32(pb); /* selection time */
1910  avio_rb32(pb); /* selection duration */
1911  avio_rb32(pb); /* current time */
1912  avio_rb32(pb); /* next track ID */
1913 
1914  return 0;
1915 }
1916 
1918 {
1919  AVStream *st;
1920 
1921  if (fc->nb_streams < 1)
1922  return;
1923  st = fc->streams[fc->nb_streams-1];
1924 
1925  switch (st->codecpar->codec_id) {
1926  case AV_CODEC_ID_PCM_S16BE:
1928  break;
1929  case AV_CODEC_ID_PCM_S24BE:
1931  break;
1932  case AV_CODEC_ID_PCM_S32BE:
1934  break;
1935  case AV_CODEC_ID_PCM_F32BE:
1937  break;
1938  case AV_CODEC_ID_PCM_F64BE:
1940  break;
1941  default:
1942  break;
1943  }
1944 }
1945 
1947 {
1948  int little_endian = avio_rb16(pb) & 0xFF;
1949  av_log(c->fc, AV_LOG_TRACE, "enda %d\n", little_endian);
1950  if (little_endian == 1)
1952  return 0;
1953 }
1954 
1956 {
1957  int format_flags;
1958  int version, flags;
1959  int pcm_sample_size;
1960  AVFormatContext *fc = c->fc;
1961  AVStream *st;
1962  MOVStreamContext *sc;
1963 
1964  if (atom.size < 6) {
1965  av_log(c->fc, AV_LOG_ERROR, "Empty pcmC box\n");
1966  return AVERROR_INVALIDDATA;
1967  }
1968 
1969  version = avio_r8(pb);
1970  flags = avio_rb24(pb);
1971 
1972  if (version != 0 || flags != 0) {
1973  av_log(c->fc, AV_LOG_ERROR,
1974  "Unsupported 'pcmC' box with version %d, flags: %x",
1975  version, flags);
1976  return AVERROR_INVALIDDATA;
1977  }
1978 
1979  format_flags = avio_r8(pb);
1980  pcm_sample_size = avio_r8(pb);
1981 
1982  if (fc->nb_streams < 1)
1983  return AVERROR_INVALIDDATA;
1984 
1985  st = fc->streams[fc->nb_streams - 1];
1986  sc = st->priv_data;
1987 
1988  if (sc->format == MOV_MP4_FPCM_TAG) {
1989  switch (pcm_sample_size) {
1990  case 32:
1992  break;
1993  case 64:
1995  break;
1996  default:
1997  av_log(fc, AV_LOG_ERROR, "invalid pcm_sample_size %d for %s\n",
1998  pcm_sample_size,
1999  av_fourcc2str(sc->format));
2000  return AVERROR_INVALIDDATA;
2001  }
2002  } else if (sc->format == MOV_MP4_IPCM_TAG) {
2003  switch (pcm_sample_size) {
2004  case 16:
2006  break;
2007  case 24:
2009  break;
2010  case 32:
2012  break;
2013  default:
2014  av_log(fc, AV_LOG_ERROR, "invalid pcm_sample_size %d for %s\n",
2015  pcm_sample_size,
2016  av_fourcc2str(sc->format));
2017  return AVERROR_INVALIDDATA;
2018  }
2019  } else {
2020  av_log(fc, AV_LOG_ERROR, "'pcmC' with invalid sample entry '%s'\n",
2021  av_fourcc2str(sc->format));
2022  return AVERROR_INVALIDDATA;
2023  }
2024 
2025  if (format_flags & 1) // indicates little-endian format. If not present, big-endian format is used
2028 
2029  return 0;
2030 }
2031 
2033 {
2034  AVStream *st;
2035  char color_parameter_type[5] = { 0 };
2036  uint16_t color_primaries, color_trc, color_matrix;
2037  int ret;
2038 
2039  st = get_curr_st(c);
2040  if (!st)
2041  return 0;
2042 
2043  ret = ffio_read_size(pb, color_parameter_type, 4);
2044  if (ret < 0)
2045  return ret;
2046  if (strncmp(color_parameter_type, "nclx", 4) &&
2047  strncmp(color_parameter_type, "nclc", 4) &&
2048  strncmp(color_parameter_type, "prof", 4)) {
2049  av_log(c->fc, AV_LOG_WARNING, "unsupported color_parameter_type %s\n",
2050  color_parameter_type);
2051  return 0;
2052  }
2053 
2054  if (!strncmp(color_parameter_type, "prof", 4)) {
2058  atom.size - 4, 0);
2059  if (!sd)
2060  return AVERROR(ENOMEM);
2061  ret = ffio_read_size(pb, sd->data, atom.size - 4);
2062  if (ret < 0)
2063  return ret;
2064  } else {
2065  color_primaries = avio_rb16(pb);
2066  color_trc = avio_rb16(pb);
2067  color_matrix = avio_rb16(pb);
2068 
2069  av_log(c->fc, AV_LOG_TRACE,
2070  "%s: pri %d trc %d matrix %d",
2071  color_parameter_type, color_primaries, color_trc, color_matrix);
2072 
2073  if (!strncmp(color_parameter_type, "nclx", 4)) {
2074  uint8_t color_range = avio_r8(pb) >> 7;
2075  av_log(c->fc, AV_LOG_TRACE, " full %"PRIu8"", color_range);
2076  if (color_range)
2078  else
2080  }
2081 
2084  if (!av_color_transfer_name(color_trc))
2085  color_trc = AVCOL_TRC_UNSPECIFIED;
2086  if (!av_color_space_name(color_matrix))
2087  color_matrix = AVCOL_SPC_UNSPECIFIED;
2088 
2090  st->codecpar->color_trc = color_trc;
2091  st->codecpar->color_space = color_matrix;
2092  av_log(c->fc, AV_LOG_TRACE, "\n");
2093  }
2094  return 0;
2095 }
2096 
2098 {
2099  AVStream *st;
2100  unsigned mov_field_order;
2101  enum AVFieldOrder decoded_field_order = AV_FIELD_UNKNOWN;
2102 
2103  if (c->fc->nb_streams < 1) // will happen with jp2 files
2104  return 0;
2105  st = c->fc->streams[c->fc->nb_streams-1];
2106  if (atom.size < 2)
2107  return AVERROR_INVALIDDATA;
2108  mov_field_order = avio_rb16(pb);
2109  if ((mov_field_order & 0xFF00) == 0x0100)
2110  decoded_field_order = AV_FIELD_PROGRESSIVE;
2111  else if ((mov_field_order & 0xFF00) == 0x0200) {
2112  switch (mov_field_order & 0xFF) {
2113  case 0x01: decoded_field_order = AV_FIELD_TT;
2114  break;
2115  case 0x06: decoded_field_order = AV_FIELD_BB;
2116  break;
2117  case 0x09: decoded_field_order = AV_FIELD_TB;
2118  break;
2119  case 0x0E: decoded_field_order = AV_FIELD_BT;
2120  break;
2121  }
2122  }
2123  if (decoded_field_order == AV_FIELD_UNKNOWN && mov_field_order) {
2124  av_log(c->fc, AV_LOG_ERROR, "Unknown MOV field order 0x%04x\n", mov_field_order);
2125  }
2126  st->codecpar->field_order = decoded_field_order;
2127 
2128  return 0;
2129 }
2130 
2132 {
2133  int err = 0;
2134  uint64_t size = (uint64_t)par->extradata_size + atom.size + 8 + AV_INPUT_BUFFER_PADDING_SIZE;
2135  if (size > INT_MAX || (uint64_t)atom.size > INT_MAX)
2136  return AVERROR_INVALIDDATA;
2137  if ((err = av_reallocp(&par->extradata, size)) < 0) {
2138  par->extradata_size = 0;
2139  return err;
2140  }
2142  return 0;
2143 }
2144 
2145 /* Read a whole atom into the extradata return the size of the atom read, possibly truncated if != atom.size */
2147  AVCodecParameters *par, uint8_t *buf)
2148 {
2149  int64_t result = atom.size;
2150  int err;
2151 
2152  AV_WB32(buf , atom.size + 8);
2153  AV_WL32(buf + 4, atom.type);
2154  err = ffio_read_size(pb, buf + 8, atom.size);
2155  if (err < 0) {
2156  par->extradata_size -= atom.size;
2157  return err;
2158  } else if (err < atom.size) {
2159  av_log(c->fc, AV_LOG_WARNING, "truncated extradata\n");
2160  par->extradata_size -= atom.size - err;
2161  result = err;
2162  }
2163  memset(buf + 8 + err, 0, AV_INPUT_BUFFER_PADDING_SIZE);
2164  return result;
2165 }
2166 
2167 /* FIXME modify QDM2/SVQ3/H.264 decoders to take full atom as extradata */
2169  enum AVCodecID codec_id)
2170 {
2171  AVStream *st;
2172  uint64_t original_size;
2173  int err;
2174 
2175  if (c->fc->nb_streams < 1) // will happen with jp2 files
2176  return 0;
2177  st = c->fc->streams[c->fc->nb_streams-1];
2178 
2179  if (st->codecpar->codec_id != codec_id)
2180  return 0; /* unexpected codec_id - don't mess with extradata */
2181 
2182  original_size = st->codecpar->extradata_size;
2183  err = mov_realloc_extradata(st->codecpar, atom);
2184  if (err)
2185  return err;
2186 
2187  err = mov_read_atom_into_extradata(c, pb, atom, st->codecpar, st->codecpar->extradata + original_size);
2188  if (err < 0)
2189  return err;
2190  return 0; // Note: this is the original behavior to ignore truncation.
2191 }
2192 
2193 /* wrapper functions for reading ALAC/AVS/MJPEG/MJPEG2000 extradata atoms only for those codecs */
2195 {
2196  return mov_read_extradata(c, pb, atom, AV_CODEC_ID_ALAC);
2197 }
2198 
2200 {
2201  return mov_read_extradata(c, pb, atom, AV_CODEC_ID_CAVS);
2202 }
2203 
2205 {
2206  return mov_read_extradata(c, pb, atom, AV_CODEC_ID_JPEG2000);
2207 }
2208 
2210 {
2211  return mov_read_extradata(c, pb, atom, AV_CODEC_ID_R10K);
2212 }
2213 
2215 {
2216  int ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_AVUI);
2217  if (!ret)
2218  ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_DNXHD);
2219  return ret;
2220 }
2221 
2223 {
2224  int ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_TARGA_Y216);
2225 
2226  if (!ret && c->fc->nb_streams >= 1) {
2227  AVCodecParameters *par = c->fc->streams[c->fc->nb_streams-1]->codecpar;
2228  if (par->extradata_size >= 40) {
2229  par->height = AV_RB16(&par->extradata[36]);
2230  par->width = AV_RB16(&par->extradata[38]);
2231  }
2232  }
2233  return ret;
2234 }
2235 
2237 {
2238  if (c->fc->nb_streams >= 1) {
2239  AVStream *const st = c->fc->streams[c->fc->nb_streams - 1];
2240  FFStream *const sti = ffstream(st);
2241  AVCodecParameters *par = st->codecpar;
2242 
2243  if (par->codec_tag == MKTAG('A', 'V', 'i', 'n') &&
2244  par->codec_id == AV_CODEC_ID_H264 &&
2245  atom.size > 11) {
2246  int cid;
2247  avio_skip(pb, 10);
2248  cid = avio_rb16(pb);
2249  /* For AVID AVCI50, force width of 1440 to be able to select the correct SPS and PPS */
2250  if (cid == 0xd4d || cid == 0xd4e)
2251  par->width = 1440;
2252  return 0;
2253  } else if ((par->codec_tag == MKTAG('A', 'V', 'd', '1') ||
2254  par->codec_tag == MKTAG('A', 'V', 'j', '2') ||
2255  par->codec_tag == MKTAG('A', 'V', 'd', 'n')) &&
2256  atom.size >= 24) {
2257  int num, den;
2258  avio_skip(pb, 12);
2259  num = avio_rb32(pb);
2260  den = avio_rb32(pb);
2261  if (num <= 0 || den <= 0)
2262  return 0;
2263  switch (avio_rb32(pb)) {
2264  case 2:
2265  if (den >= INT_MAX / 2)
2266  return 0;
2267  den *= 2;
2268  case 1:
2269  sti->display_aspect_ratio = (AVRational){ num, den };
2270  default:
2271  return 0;
2272  }
2273  }
2274  }
2275 
2276  return mov_read_avid(c, pb, atom);
2277 }
2278 
2280 {
2281  int ret = 0;
2282  int length = 0;
2283  uint64_t original_size;
2284  if (c->fc->nb_streams >= 1) {
2285  AVCodecParameters *par = c->fc->streams[c->fc->nb_streams-1]->codecpar;
2286  if (par->codec_id == AV_CODEC_ID_H264)
2287  return 0;
2288  if (atom.size == 16) {
2289  original_size = par->extradata_size;
2290  ret = mov_realloc_extradata(par, atom);
2291  if (!ret) {
2292  length = mov_read_atom_into_extradata(c, pb, atom, par, par->extradata + original_size);
2293  if (length == atom.size) {
2294  const uint8_t range_value = par->extradata[original_size + 19];
2295  switch (range_value) {
2296  case 1:
2298  break;
2299  case 2:
2301  break;
2302  default:
2303  av_log(c->fc, AV_LOG_WARNING, "ignored unknown aclr value (%d)\n", range_value);
2304  break;
2305  }
2306  ff_dlog(c->fc, "color_range: %d\n", par->color_range);
2307  } else {
2308  /* For some reason the whole atom was not added to the extradata */
2309  av_log(c->fc, AV_LOG_ERROR, "aclr not decoded - incomplete atom\n");
2310  }
2311  } else {
2312  av_log(c->fc, AV_LOG_ERROR, "aclr not decoded - unable to add atom to extradata\n");
2313  }
2314  } else {
2315  av_log(c->fc, AV_LOG_WARNING, "aclr not decoded - unexpected size %"PRId64"\n", atom.size);
2316  }
2317  }
2318 
2319  return ret;
2320 }
2321 
2323 {
2324  return mov_read_extradata(c, pb, atom, AV_CODEC_ID_SVQ3);
2325 }
2326 
2328 {
2329  AVStream *st;
2330  int ret;
2331 
2332  if (c->fc->nb_streams < 1)
2333  return 0;
2334  st = c->fc->streams[c->fc->nb_streams-1];
2335 
2336  if ((uint64_t)atom.size > (1<<30))
2337  return AVERROR_INVALIDDATA;
2338 
2339  if (st->codecpar->codec_id == AV_CODEC_ID_QDM2 ||
2342  // pass all frma atom to codec, needed at least for QDMC and QDM2
2343  ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size);
2344  if (ret < 0)
2345  return ret;
2346  } else if (atom.size > 8) { /* to read frma, esds atoms */
2347  if (st->codecpar->codec_id == AV_CODEC_ID_ALAC && atom.size >= 24) {
2348  uint64_t buffer;
2349  ret = ffio_ensure_seekback(pb, 8);
2350  if (ret < 0)
2351  return ret;
2352  buffer = avio_rb64(pb);
2353  atom.size -= 8;
2354  if ( (buffer & 0xFFFFFFFF) == MKBETAG('f','r','m','a')
2355  && buffer >> 32 <= atom.size
2356  && buffer >> 32 >= 8) {
2357  avio_skip(pb, -8);
2358  atom.size += 8;
2359  } else if (!st->codecpar->extradata_size) {
2360 #define ALAC_EXTRADATA_SIZE 36
2362  if (!st->codecpar->extradata)
2363  return AVERROR(ENOMEM);
2366  AV_WB32(st->codecpar->extradata + 4, MKTAG('a','l','a','c'));
2367  AV_WB64(st->codecpar->extradata + 12, buffer);
2368  avio_read(pb, st->codecpar->extradata + 20, 16);
2369  avio_skip(pb, atom.size - 24);
2370  return 0;
2371  }
2372  }
2373  if ((ret = mov_read_default(c, pb, atom)) < 0)
2374  return ret;
2375  } else
2376  avio_skip(pb, atom.size);
2377  return 0;
2378 }
2379 
2380 /**
2381  * This function reads atom content and puts data in extradata without tag
2382  * nor size unlike mov_read_extradata.
2383  */
2385 {
2386  AVStream *st;
2387  int ret;
2388 
2389  st = get_curr_st(c);
2390  if (!st)
2391  return 0;
2392 
2393  if ((uint64_t)atom.size > (1<<30))
2394  return AVERROR_INVALIDDATA;
2395 
2396  if (atom.type == MKTAG('v','v','c','C')) {
2397  avio_skip(pb, 4);
2398  atom.size -= 4;
2399  }
2400 
2401  if (atom.size >= 10) {
2402  // Broken files created by legacy versions of libavformat will
2403  // wrap a whole fiel atom inside of a glbl atom.
2404  unsigned size = avio_rb32(pb);
2405  unsigned type = avio_rl32(pb);
2406  if (avio_feof(pb))
2407  return AVERROR_INVALIDDATA;
2408  avio_seek(pb, -8, SEEK_CUR);
2409  if (type == MKTAG('f','i','e','l') && size == atom.size)
2410  return mov_read_default(c, pb, atom);
2411  }
2412  if (st->codecpar->extradata_size > 1 && st->codecpar->extradata) {
2413  av_log(c->fc, AV_LOG_WARNING, "ignoring multiple glbl\n");
2414  return 0;
2415  }
2416  ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size);
2417  if (ret < 0)
2418  return ret;
2419  if (atom.type == MKTAG('h','v','c','C') && st->codecpar->codec_tag == MKTAG('d','v','h','1'))
2420  /* HEVC-based Dolby Vision derived from hvc1.
2421  Happens to match with an identifier
2422  previously utilized for DV. Thus, if we have
2423  the hvcC extradata box available as specified,
2424  set codec to HEVC */
2426 
2427  return 0;
2428 }
2429 
2431 {
2432  AVStream *st;
2433  uint8_t profile_level;
2434  int ret;
2435 
2436  if (c->fc->nb_streams < 1)
2437  return 0;
2438  st = c->fc->streams[c->fc->nb_streams-1];
2439 
2440  if (atom.size >= (1<<28) || atom.size < 7)
2441  return AVERROR_INVALIDDATA;
2442 
2443  profile_level = avio_r8(pb);
2444  if ((profile_level & 0xf0) != 0xc0)
2445  return 0;
2446 
2447  avio_seek(pb, 6, SEEK_CUR);
2448  ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size - 7);
2449  if (ret < 0)
2450  return ret;
2451 
2452  return 0;
2453 }
2454 
2456 {
2457  AVStream* st;
2458  MOVStreamContext* sc;
2459 
2460  if (c->fc->nb_streams < 1)
2461  return 0;
2462 
2463  /* For SBAS this should be fine - though beware if someone implements a
2464  * tref atom processor that doesn't drop down to default then this may
2465  * be lost. */
2466  if (atom.size > 4) {
2467  av_log(c->fc, AV_LOG_ERROR, "Only a single tref of type sbas is supported\n");
2468  return AVERROR_PATCHWELCOME;
2469  }
2470 
2471  st = c->fc->streams[c->fc->nb_streams - 1];
2472  sc = st->priv_data;
2473  sc->tref_id = avio_rb32(pb);
2475 
2476  return 0;
2477 }
2478 
2479 /**
2480  * An strf atom is a BITMAPINFOHEADER struct. This struct is 40 bytes itself,
2481  * but can have extradata appended at the end after the 40 bytes belonging
2482  * to the struct.
2483  */
2485 {
2486  AVStream *st;
2487  int ret;
2488 
2489  if (c->fc->nb_streams < 1)
2490  return 0;
2491  if (atom.size <= 40)
2492  return 0;
2493  st = c->fc->streams[c->fc->nb_streams-1];
2494 
2495  if ((uint64_t)atom.size > (1<<30))
2496  return AVERROR_INVALIDDATA;
2497 
2498  avio_skip(pb, 40);
2499  ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size - 40);
2500  if (ret < 0)
2501  return ret;
2502 
2503  return 0;
2504 }
2505 
2507 {
2508  AVStream *st;
2509  MOVStreamContext *sc;
2510  unsigned int i, entries;
2511 
2512  if (c->trak_index < 0) {
2513  av_log(c->fc, AV_LOG_WARNING, "STCO outside TRAK\n");
2514  return 0;
2515  }
2516  if (c->fc->nb_streams < 1)
2517  return 0;
2518  st = c->fc->streams[c->fc->nb_streams-1];
2519  sc = st->priv_data;
2520 
2521  avio_r8(pb); /* version */
2522  avio_rb24(pb); /* flags */
2523 
2524  // Clamp allocation size for `chunk_offsets` -- don't throw an error for an
2525  // invalid count since the EOF path doesn't throw either.
2526  entries = avio_rb32(pb);
2527  entries =
2528  FFMIN(entries,
2529  FFMAX(0, (atom.size - 8) /
2530  (atom.type == MKTAG('s', 't', 'c', 'o') ? 4 : 8)));
2531 
2532  if (!entries)
2533  return 0;
2534 
2535  if (sc->chunk_offsets) {
2536  av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicated STCO atom\n");
2537  return 0;
2538  }
2539 
2540  av_free(sc->chunk_offsets);
2541  sc->chunk_count = 0;
2542  sc->chunk_offsets = av_malloc_array(entries, sizeof(*sc->chunk_offsets));
2543  if (!sc->chunk_offsets)
2544  return AVERROR(ENOMEM);
2545  sc->chunk_count = entries;
2546 
2547  if (atom.type == MKTAG('s','t','c','o'))
2548  for (i = 0; i < entries && !pb->eof_reached; i++)
2549  sc->chunk_offsets[i] = avio_rb32(pb);
2550  else if (atom.type == MKTAG('c','o','6','4'))
2551  for (i = 0; i < entries && !pb->eof_reached; i++) {
2552  sc->chunk_offsets[i] = avio_rb64(pb);
2553  if (sc->chunk_offsets[i] < 0) {
2554  av_log(c->fc, AV_LOG_WARNING, "Impossible chunk_offset\n");
2555  sc->chunk_offsets[i] = 0;
2556  }
2557  }
2558  else
2559  return AVERROR_INVALIDDATA;
2560 
2561  sc->chunk_count = i;
2562 
2563  if (pb->eof_reached) {
2564  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STCO atom\n");
2565  return AVERROR_EOF;
2566  }
2567 
2568  return 0;
2569 }
2570 
2571 static int mov_codec_id(AVStream *st, uint32_t format)
2572 {
2574 
2575  if (id <= 0 &&
2576  ((format & 0xFFFF) == 'm' + ('s' << 8) ||
2577  (format & 0xFFFF) == 'T' + ('S' << 8)))
2579 
2580  if (st->codecpar->codec_type != AVMEDIA_TYPE_VIDEO && id > 0) {
2582  } else if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO &&
2583  /* skip old ASF MPEG-4 tag */
2584  format && format != MKTAG('m','p','4','s')) {
2586  if (id <= 0)
2588  if (id > 0)
2590  else if (st->codecpar->codec_type == AVMEDIA_TYPE_DATA ||
2592  st->codecpar->codec_id == AV_CODEC_ID_NONE)) {
2594  if (id <= 0) {
2596  AV_CODEC_ID_TTML : id;
2597  }
2598 
2599  if (id > 0)
2601  else
2603  }
2604  }
2605 
2606  st->codecpar->codec_tag = format;
2607 
2608  return id;
2609 }
2610 
2612  AVStream *st, MOVStreamContext *sc)
2613 {
2614  uint8_t codec_name[32] = { 0 };
2615  int64_t stsd_start;
2616  unsigned int len;
2617  uint32_t id = 0;
2618 
2619  /* The first 16 bytes of the video sample description are already
2620  * read in ff_mov_read_stsd_entries() */
2621  stsd_start = avio_tell(pb) - 16;
2622 
2623  avio_rb16(pb); /* version */
2624  avio_rb16(pb); /* revision level */
2625  id = avio_rl32(pb); /* vendor */
2626  av_dict_set(&st->metadata, "vendor_id", av_fourcc2str(id), 0);
2627  avio_rb32(pb); /* temporal quality */
2628  avio_rb32(pb); /* spatial quality */
2629 
2630  st->codecpar->width = avio_rb16(pb); /* width */
2631  st->codecpar->height = avio_rb16(pb); /* height */
2632 
2633  avio_rb32(pb); /* horiz resolution */
2634  avio_rb32(pb); /* vert resolution */
2635  avio_rb32(pb); /* data size, always 0 */
2636  avio_rb16(pb); /* frames per samples */
2637 
2638  len = avio_r8(pb); /* codec name, pascal string */
2639  if (len > 31)
2640  len = 31;
2641  mov_read_mac_string(c, pb, len, codec_name, sizeof(codec_name));
2642  if (len < 31)
2643  avio_skip(pb, 31 - len);
2644 
2645  if (codec_name[0])
2646  av_dict_set(&st->metadata, "encoder", codec_name, 0);
2647 
2648  /* codec_tag YV12 triggers an UV swap in rawdec.c */
2649  if (!strncmp(codec_name, "Planar Y'CbCr 8-bit 4:2:0", 25)) {
2650  st->codecpar->codec_tag = MKTAG('I', '4', '2', '0');
2651  st->codecpar->width &= ~1;
2652  st->codecpar->height &= ~1;
2653  }
2654  /* Flash Media Server uses tag H.263 with Sorenson Spark */
2655  if (st->codecpar->codec_tag == MKTAG('H','2','6','3') &&
2656  !strncmp(codec_name, "Sorenson H263", 13))
2658 
2659  st->codecpar->bits_per_coded_sample = avio_rb16(pb); /* depth */
2660 
2661  avio_seek(pb, stsd_start, SEEK_SET);
2662 
2663  if (ff_get_qtpalette(st->codecpar->codec_id, pb, sc->palette)) {
2664  st->codecpar->bits_per_coded_sample &= 0x1F;
2665  sc->has_palette = 1;
2666  }
2667 }
2668 
2670  AVStream *st, MOVStreamContext *sc)
2671 {
2672  int bits_per_sample, flags;
2673  uint16_t version = avio_rb16(pb);
2674  uint32_t id = 0;
2675  AVDictionaryEntry *compatible_brands = av_dict_get(c->fc->metadata, "compatible_brands", NULL, AV_DICT_MATCH_CASE);
2676  int channel_count;
2677 
2678  avio_rb16(pb); /* revision level */
2679  id = avio_rl32(pb); /* vendor */
2680  av_dict_set(&st->metadata, "vendor_id", av_fourcc2str(id), 0);
2681 
2682  channel_count = avio_rb16(pb);
2683 
2685  st->codecpar->ch_layout.nb_channels = channel_count;
2686  st->codecpar->bits_per_coded_sample = avio_rb16(pb); /* sample size */
2687  av_log(c->fc, AV_LOG_TRACE, "audio channels %d\n", channel_count);
2688 
2689  sc->audio_cid = avio_rb16(pb);
2690  avio_rb16(pb); /* packet size = 0 */
2691 
2692  st->codecpar->sample_rate = ((avio_rb32(pb) >> 16));
2693 
2694  // Read QT version 1 fields. In version 0 these do not exist.
2695  av_log(c->fc, AV_LOG_TRACE, "version =%d, isom =%d\n", version, c->isom);
2696  if (!c->isom ||
2697  (compatible_brands && strstr(compatible_brands->value, "qt ")) ||
2698  (sc->stsd_version == 0 && version > 0)) {
2699  if (version == 1) {
2700  sc->samples_per_frame = avio_rb32(pb);
2701  avio_rb32(pb); /* bytes per packet */
2702  sc->bytes_per_frame = avio_rb32(pb);
2703  avio_rb32(pb); /* bytes per sample */
2704  } else if (version == 2) {
2705  avio_rb32(pb); /* sizeof struct only */
2707  channel_count = avio_rb32(pb);
2709  st->codecpar->ch_layout.nb_channels = channel_count;
2710  avio_rb32(pb); /* always 0x7F000000 */
2712 
2713  flags = avio_rb32(pb); /* lpcm format specific flag */
2714  sc->bytes_per_frame = avio_rb32(pb);
2715  sc->samples_per_frame = avio_rb32(pb);
2716  if (st->codecpar->codec_tag == MKTAG('l','p','c','m'))
2717  st->codecpar->codec_id =
2719  flags);
2720  }
2721  if (version == 0 || (version == 1 && sc->audio_cid != -2)) {
2722  /* can't correctly handle variable sized packet as audio unit */
2723  switch (st->codecpar->codec_id) {
2724  case AV_CODEC_ID_MP2:
2725  case AV_CODEC_ID_MP3:
2727  break;
2728  }
2729  }
2730  }
2731 
2732  if (sc->format == 0) {
2733  if (st->codecpar->bits_per_coded_sample == 8)
2734  st->codecpar->codec_id = mov_codec_id(st, MKTAG('r','a','w',' '));
2735  else if (st->codecpar->bits_per_coded_sample == 16)
2736  st->codecpar->codec_id = mov_codec_id(st, MKTAG('t','w','o','s'));
2737  }
2738 
2739  switch (st->codecpar->codec_id) {
2740  case AV_CODEC_ID_PCM_S8:
2741  case AV_CODEC_ID_PCM_U8:
2742  if (st->codecpar->bits_per_coded_sample == 16)
2744  break;
2745  case AV_CODEC_ID_PCM_S16LE:
2746  case AV_CODEC_ID_PCM_S16BE:
2747  if (st->codecpar->bits_per_coded_sample == 8)
2749  else if (st->codecpar->bits_per_coded_sample == 24)
2750  st->codecpar->codec_id =
2753  else if (st->codecpar->bits_per_coded_sample == 32)
2754  st->codecpar->codec_id =
2757  break;
2758  /* set values for old format before stsd version 1 appeared */
2759  case AV_CODEC_ID_MACE3:
2760  sc->samples_per_frame = 6;
2762  break;
2763  case AV_CODEC_ID_MACE6:
2764  sc->samples_per_frame = 6;
2766  break;
2768  sc->samples_per_frame = 64;
2770  break;
2771  case AV_CODEC_ID_GSM:
2772  sc->samples_per_frame = 160;
2773  sc->bytes_per_frame = 33;
2774  break;
2775  default:
2776  break;
2777  }
2778 
2779  bits_per_sample = av_get_bits_per_sample(st->codecpar->codec_id);
2780  if (bits_per_sample && (bits_per_sample >> 3) * (uint64_t)st->codecpar->ch_layout.nb_channels <= INT_MAX) {
2781  st->codecpar->bits_per_coded_sample = bits_per_sample;
2782  sc->sample_size = (bits_per_sample >> 3) * st->codecpar->ch_layout.nb_channels;
2783  }
2784 }
2785 
2787  AVStream *st, MOVStreamContext *sc,
2788  int64_t size)
2789 {
2790  // ttxt stsd contains display flags, justification, background
2791  // color, fonts, and default styles, so fake an atom to read it
2792  MOVAtom fake_atom = { .size = size };
2793  // mp4s contains a regular esds atom, dfxp ISMV TTML has no content
2794  // in extradata unlike stpp MP4 TTML.
2795  if (st->codecpar->codec_tag != AV_RL32("mp4s") &&
2797  mov_read_glbl(c, pb, fake_atom);
2798  st->codecpar->width = sc->width;
2799  st->codecpar->height = sc->height;
2800 }
2801 
2802 static uint32_t yuv_to_rgba(uint32_t ycbcr)
2803 {
2804  uint8_t r, g, b;
2805  int y, cb, cr;
2806 
2807  y = (ycbcr >> 16) & 0xFF;
2808  cr = (ycbcr >> 8) & 0xFF;
2809  cb = ycbcr & 0xFF;
2810 
2811  b = av_clip_uint8((1164 * (y - 16) + 2018 * (cb - 128)) / 1000);
2812  g = av_clip_uint8((1164 * (y - 16) - 813 * (cr - 128) - 391 * (cb - 128)) / 1000);
2813  r = av_clip_uint8((1164 * (y - 16) + 1596 * (cr - 128) ) / 1000);
2814 
2815  return (r << 16) | (g << 8) | b;
2816 }
2817 
2819 {
2820  char buf[256] = {0};
2821  uint8_t *src = st->codecpar->extradata;
2822  int i, ret;
2823 
2824  if (st->codecpar->extradata_size != 64)
2825  return 0;
2826 
2827  if (st->codecpar->width > 0 && st->codecpar->height > 0)
2828  snprintf(buf, sizeof(buf), "size: %dx%d\n",
2829  st->codecpar->width, st->codecpar->height);
2830  av_strlcat(buf, "palette: ", sizeof(buf));
2831 
2832  for (i = 0; i < 16; i++) {
2833  uint32_t yuv = AV_RB32(src + i * 4);
2834  uint32_t rgba = yuv_to_rgba(yuv);
2835 
2836  av_strlcatf(buf, sizeof(buf), "%06"PRIx32"%s", rgba, i != 15 ? ", " : "");
2837  }
2838 
2839  if (av_strlcat(buf, "\n", sizeof(buf)) >= sizeof(buf))
2840  return 0;
2841 
2842  ret = ff_alloc_extradata(st->codecpar, strlen(buf));
2843  if (ret < 0)
2844  return ret;
2845  memcpy(st->codecpar->extradata, buf, st->codecpar->extradata_size);
2846 
2847  return 0;
2848 }
2849 
2851  AVStream *st, MOVStreamContext *sc,
2852  int64_t size)
2853 {
2854  int ret;
2855 
2856  if (st->codecpar->codec_tag == MKTAG('t','m','c','d')) {
2857  if ((int)size != size)
2858  return AVERROR(ENOMEM);
2859 
2860  ret = ff_get_extradata(c->fc, st->codecpar, pb, size);
2861  if (ret < 0)
2862  return ret;
2863  if (size > 16) {
2864  MOVStreamContext *tmcd_ctx = st->priv_data;
2865  int val;
2866  val = AV_RB32(st->codecpar->extradata + 4);
2867  tmcd_ctx->tmcd_flags = val;
2868  st->avg_frame_rate.num = AV_RB32(st->codecpar->extradata + 8); /* timescale */
2869  st->avg_frame_rate.den = AV_RB32(st->codecpar->extradata + 12); /* frameDuration */
2870  tmcd_ctx->tmcd_nb_frames = st->codecpar->extradata[16]; /* number of frames */
2871  if (size > 30) {
2872  uint32_t len = AV_RB32(st->codecpar->extradata + 18); /* name atom length */
2873  uint32_t format = AV_RB32(st->codecpar->extradata + 22);
2874  if (format == AV_RB32("name") && (int64_t)size >= (int64_t)len + 18) {
2875  uint16_t str_size = AV_RB16(st->codecpar->extradata + 26); /* string length */
2876  if (str_size > 0 && size >= (int)str_size + 30 &&
2877  st->codecpar->extradata[30] /* Don't add empty string */) {
2878  char *reel_name = av_malloc(str_size + 1);
2879  if (!reel_name)
2880  return AVERROR(ENOMEM);
2881  memcpy(reel_name, st->codecpar->extradata + 30, str_size);
2882  reel_name[str_size] = 0; /* Add null terminator */
2883  av_dict_set(&st->metadata, "reel_name", reel_name,
2885  }
2886  }
2887  }
2888  }
2889  } else {
2890  /* other codec type, just skip (rtp, mp4s ...) */
2891  avio_skip(pb, size);
2892  }
2893  return 0;
2894 }
2895 
2897  AVStream *st, MOVStreamContext *sc)
2898 {
2899  FFStream *const sti = ffstream(st);
2900 
2901  if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
2902  !st->codecpar->sample_rate && sc->time_scale > 1)
2903  st->codecpar->sample_rate = sc->time_scale;
2904 
2905  /* special codec parameters handling */
2906  switch (st->codecpar->codec_id) {
2907 #if CONFIG_DV_DEMUXER
2908  case AV_CODEC_ID_DVAUDIO:
2909  if (c->dv_fctx) {
2910  avpriv_request_sample(c->fc, "multiple DV audio streams");
2911  return AVERROR(ENOSYS);
2912  }
2913 
2914  c->dv_fctx = avformat_alloc_context();
2915  if (!c->dv_fctx) {
2916  av_log(c->fc, AV_LOG_ERROR, "dv demux context alloc error\n");
2917  return AVERROR(ENOMEM);
2918  }
2919  c->dv_demux = avpriv_dv_init_demux(c->dv_fctx);
2920  if (!c->dv_demux) {
2921  av_log(c->fc, AV_LOG_ERROR, "dv demux context init error\n");
2922  return AVERROR(ENOMEM);
2923  }
2924  sc->dv_audio_container = 1;
2926  break;
2927 #endif
2928  /* no ifdef since parameters are always those */
2929  case AV_CODEC_ID_QCELP:
2932  // force sample rate for qcelp when not stored in mov
2933  if (st->codecpar->codec_tag != MKTAG('Q','c','l','p'))
2934  st->codecpar->sample_rate = 8000;
2935  // FIXME: Why is the following needed for some files?
2936  sc->samples_per_frame = 160;
2937  if (!sc->bytes_per_frame)
2938  sc->bytes_per_frame = 35;
2939  break;
2940  case AV_CODEC_ID_AMR_NB:
2943  /* force sample rate for amr, stsd in 3gp does not store sample rate */
2944  st->codecpar->sample_rate = 8000;
2945  break;
2946  case AV_CODEC_ID_AMR_WB:
2949  st->codecpar->sample_rate = 16000;
2950  break;
2951  case AV_CODEC_ID_MP2:
2952  case AV_CODEC_ID_MP3:
2953  /* force type after stsd for m1a hdlr */
2955  break;
2956  case AV_CODEC_ID_GSM:
2957  case AV_CODEC_ID_ADPCM_MS:
2959  case AV_CODEC_ID_ILBC:
2960  case AV_CODEC_ID_MACE3:
2961  case AV_CODEC_ID_MACE6:
2962  case AV_CODEC_ID_QDM2:
2964  break;
2965  case AV_CODEC_ID_ALAC:
2966  if (st->codecpar->extradata_size == 36) {
2967  int channel_count = AV_RB8(st->codecpar->extradata + 21);
2968  if (st->codecpar->ch_layout.nb_channels != channel_count) {
2971  st->codecpar->ch_layout.nb_channels = channel_count;
2972  }
2973  st->codecpar->sample_rate = AV_RB32(st->codecpar->extradata + 32);
2974  }
2975  break;
2976  case AV_CODEC_ID_AC3:
2977  case AV_CODEC_ID_EAC3:
2979  case AV_CODEC_ID_VC1:
2980  case AV_CODEC_ID_VP8:
2981  case AV_CODEC_ID_VP9:
2983  break;
2984  case AV_CODEC_ID_EVC:
2985  case AV_CODEC_ID_AV1:
2986  /* field_order detection of H264 requires parsing */
2987  case AV_CODEC_ID_H264:
2989  break;
2990  default:
2991  break;
2992  }
2993  return 0;
2994 }
2995 
2997  int codec_tag, int format,
2998  int64_t size)
2999 {
3000  if (codec_tag &&
3001  (codec_tag != format &&
3002  // AVID 1:1 samples with differing data format and codec tag exist
3003  (codec_tag != AV_RL32("AV1x") || format != AV_RL32("AVup")) &&
3004  // prores is allowed to have differing data format and codec tag
3005  codec_tag != AV_RL32("apcn") && codec_tag != AV_RL32("apch") &&
3006  // so is dv (sigh)
3007  codec_tag != AV_RL32("dvpp") && codec_tag != AV_RL32("dvcp") &&
3008  (c->fc->video_codec_id ? ff_codec_get_id(ff_codec_movvideo_tags, format) != c->fc->video_codec_id
3009  : codec_tag != MKTAG('j','p','e','g')))) {
3010  /* Multiple fourcc, we skip JPEG. This is not correct, we should
3011  * export it as a separate AVStream but this needs a few changes
3012  * in the MOV demuxer, patch welcome. */
3013 
3014  av_log(c->fc, AV_LOG_WARNING, "multiple fourcc not supported\n");
3015  avio_skip(pb, size);
3016  return 1;
3017  }
3018 
3019  return 0;
3020 }
3021 
3023 {
3024  AVStream *st;
3025  MOVStreamContext *sc;
3026  int pseudo_stream_id;
3027 
3028  av_assert0 (c->fc->nb_streams >= 1);
3029  st = c->fc->streams[c->fc->nb_streams-1];
3030  sc = st->priv_data;
3031 
3032  for (pseudo_stream_id = 0;
3033  pseudo_stream_id < entries && !pb->eof_reached;
3034  pseudo_stream_id++) {
3035  //Parsing Sample description table
3036  enum AVCodecID id;
3037  int ret, dref_id = 1;
3038  MOVAtom a = { AV_RL32("stsd") };
3039  int64_t start_pos = avio_tell(pb);
3040  int64_t size = avio_rb32(pb); /* size */
3041  uint32_t format = avio_rl32(pb); /* data format */
3042 
3043  if (size >= 16) {
3044  avio_rb32(pb); /* reserved */
3045  avio_rb16(pb); /* reserved */
3046  dref_id = avio_rb16(pb);
3047  } else if (size <= 7) {
3048  av_log(c->fc, AV_LOG_ERROR,
3049  "invalid size %"PRId64" in stsd\n", size);
3050  return AVERROR_INVALIDDATA;
3051  }
3052 
3054  size - (avio_tell(pb) - start_pos))) {
3055  sc->stsd_count++;
3056  continue;
3057  }
3058 
3059  sc->pseudo_stream_id = st->codecpar->codec_tag ? -1 : pseudo_stream_id;
3060  sc->dref_id= dref_id;
3061  sc->format = format;
3062 
3063  id = mov_codec_id(st, format);
3064 
3065  av_log(c->fc, AV_LOG_TRACE,
3066  "size=%"PRId64" 4CC=%s codec_type=%d\n", size,
3068 
3069  st->codecpar->codec_id = id;
3071  mov_parse_stsd_video(c, pb, st, sc);
3072  } else if (st->codecpar->codec_type==AVMEDIA_TYPE_AUDIO) {
3073  mov_parse_stsd_audio(c, pb, st, sc);
3074  if (st->codecpar->sample_rate < 0) {
3075  av_log(c->fc, AV_LOG_ERROR, "Invalid sample rate %d\n", st->codecpar->sample_rate);
3076  return AVERROR_INVALIDDATA;
3077  }
3078  if (st->codecpar->ch_layout.nb_channels < 0) {
3079  av_log(c->fc, AV_LOG_ERROR, "Invalid channels %d\n", st->codecpar->ch_layout.nb_channels);
3080  return AVERROR_INVALIDDATA;
3081  }
3082  } else if (st->codecpar->codec_type==AVMEDIA_TYPE_SUBTITLE){
3083  mov_parse_stsd_subtitle(c, pb, st, sc,
3084  size - (avio_tell(pb) - start_pos));
3085  } else {
3086  ret = mov_parse_stsd_data(c, pb, st, sc,
3087  size - (avio_tell(pb) - start_pos));
3088  if (ret < 0)
3089  return ret;
3090  }
3091  /* this will read extra atoms at the end (wave, alac, damr, avcC, hvcC, SMI ...) */
3092  a.size = size - (avio_tell(pb) - start_pos);
3093  if (a.size > 8) {
3094  if ((ret = mov_read_default(c, pb, a)) < 0)
3095  return ret;
3096  } else if (a.size > 0)
3097  avio_skip(pb, a.size);
3098 
3099  if (sc->extradata && st->codecpar->extradata) {
3100  int extra_size = st->codecpar->extradata_size;
3101 
3102  /* Move the current stream extradata to the stream context one. */
3103  sc->extradata_size[pseudo_stream_id] = extra_size;
3104  sc->extradata[pseudo_stream_id] = st->codecpar->extradata;
3105  st->codecpar->extradata = NULL;
3106  st->codecpar->extradata_size = 0;
3107  }
3108  sc->stsd_count++;
3109  }
3110 
3111  if (pb->eof_reached) {
3112  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSD atom\n");
3113  return AVERROR_EOF;
3114  }
3115 
3116  return 0;
3117 }
3118 
3120 {
3121  AVStream *st;
3122  MOVStreamContext *sc;
3123  int ret, entries;
3124 
3125  if (c->fc->nb_streams < 1)
3126  return 0;
3127  st = c->fc->streams[c->fc->nb_streams - 1];
3128  sc = st->priv_data;
3129 
3130  sc->stsd_version = avio_r8(pb);
3131  avio_rb24(pb); /* flags */
3132  entries = avio_rb32(pb);
3133 
3134  /* Each entry contains a size (4 bytes) and format (4 bytes). */
3135  if (entries <= 0 || entries > atom.size / 8 || entries > 1024) {
3136  av_log(c->fc, AV_LOG_ERROR, "invalid STSD entries %d\n", entries);
3137  return AVERROR_INVALIDDATA;
3138  }
3139 
3140  if (sc->extradata) {
3141  av_log(c->fc, AV_LOG_ERROR,
3142  "Duplicate stsd found in this track.\n");
3143  return AVERROR_INVALIDDATA;
3144  }
3145 
3146  /* Prepare space for hosting multiple extradata. */
3147  sc->extradata = av_calloc(entries, sizeof(*sc->extradata));
3148  if (!sc->extradata)
3149  return AVERROR(ENOMEM);
3150 
3151  sc->extradata_size = av_calloc(entries, sizeof(*sc->extradata_size));
3152  if (!sc->extradata_size) {
3153  ret = AVERROR(ENOMEM);
3154  goto fail;
3155  }
3156 
3157  ret = ff_mov_read_stsd_entries(c, pb, entries);
3158  if (ret < 0)
3159  goto fail;
3160 
3161  /* Restore back the primary extradata. */
3162  av_freep(&st->codecpar->extradata);
3163  st->codecpar->extradata_size = sc->extradata_size[0];
3164  if (sc->extradata_size[0]) {
3166  if (!st->codecpar->extradata)
3167  return AVERROR(ENOMEM);
3168  memcpy(st->codecpar->extradata, sc->extradata[0], sc->extradata_size[0]);
3169  }
3170 
3171  return mov_finalize_stsd_codec(c, pb, st, sc);
3172 fail:
3173  if (sc->extradata) {
3174  int j;
3175  for (j = 0; j < sc->stsd_count; j++)
3176  av_freep(&sc->extradata[j]);
3177  }
3178 
3179  av_freep(&sc->extradata);
3180  av_freep(&sc->extradata_size);
3181  return ret;
3182 }
3183 
3185 {
3186  AVStream *st;
3187  MOVStreamContext *sc;
3188  unsigned int i, entries;
3189 
3190  if (c->trak_index < 0) {
3191  av_log(c->fc, AV_LOG_WARNING, "STSC outside TRAK\n");
3192  return 0;
3193  }
3194 
3195  if (c->fc->nb_streams < 1)
3196  return 0;
3197  st = c->fc->streams[c->fc->nb_streams-1];
3198  sc = st->priv_data;
3199 
3200  avio_r8(pb); /* version */
3201  avio_rb24(pb); /* flags */
3202 
3203  entries = avio_rb32(pb);
3204  if ((uint64_t)entries * 12 + 4 > atom.size)
3205  return AVERROR_INVALIDDATA;
3206 
3207  av_log(c->fc, AV_LOG_TRACE, "track[%u].stsc.entries = %u\n", c->fc->nb_streams - 1, entries);
3208 
3209  if (!entries)
3210  return 0;
3211  if (sc->stsc_data) {
3212  av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicated STSC atom\n");
3213  return 0;
3214  }
3215  av_free(sc->stsc_data);
3216  sc->stsc_count = 0;
3217  sc->stsc_data = av_malloc_array(entries, sizeof(*sc->stsc_data));
3218  if (!sc->stsc_data)
3219  return AVERROR(ENOMEM);
3220 
3221  for (i = 0; i < entries && !pb->eof_reached; i++) {
3222  sc->stsc_data[i].first = avio_rb32(pb);
3223  sc->stsc_data[i].count = avio_rb32(pb);
3224  sc->stsc_data[i].id = avio_rb32(pb);
3225  }
3226 
3227  sc->stsc_count = i;
3228  for (i = sc->stsc_count - 1; i < UINT_MAX; i--) {
3229  int64_t first_min = i + 1;
3230  if ((i+1 < sc->stsc_count && sc->stsc_data[i].first >= sc->stsc_data[i+1].first) ||
3231  (i > 0 && sc->stsc_data[i].first <= sc->stsc_data[i-1].first) ||
3232  sc->stsc_data[i].first < first_min ||
3233  sc->stsc_data[i].count < 1 ||
3234  sc->stsc_data[i].id < 1) {
3235  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);
3236  if (i+1 >= sc->stsc_count) {
3237  if (sc->stsc_data[i].count == 0 && i > 0) {
3238  sc->stsc_count --;
3239  continue;
3240  }
3241  sc->stsc_data[i].first = FFMAX(sc->stsc_data[i].first, first_min);
3242  if (i > 0 && sc->stsc_data[i].first <= sc->stsc_data[i-1].first)
3243  sc->stsc_data[i].first = FFMIN(sc->stsc_data[i-1].first + 1LL, INT_MAX);
3244  sc->stsc_data[i].count = FFMAX(sc->stsc_data[i].count, 1);
3245  sc->stsc_data[i].id = FFMAX(sc->stsc_data[i].id, 1);
3246  continue;
3247  }
3248  av_assert0(sc->stsc_data[i+1].first >= 2);
3249  // We replace this entry by the next valid
3250  sc->stsc_data[i].first = sc->stsc_data[i+1].first - 1;
3251  sc->stsc_data[i].count = sc->stsc_data[i+1].count;
3252  sc->stsc_data[i].id = sc->stsc_data[i+1].id;
3253  }
3254  }
3255 
3256  if (pb->eof_reached) {
3257  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSC atom\n");
3258  return AVERROR_EOF;
3259  }
3260 
3261  return 0;
3262 }
3263 
3264 static inline int mov_stsc_index_valid(unsigned int index, unsigned int count)
3265 {
3266  return index < count - 1;
3267 }
3268 
3269 /* Compute the samples value for the stsc entry at the given index. */
3270 static inline int64_t mov_get_stsc_samples(MOVStreamContext *sc, unsigned int index)
3271 {
3272  int chunk_count;
3273 
3275  chunk_count = sc->stsc_data[index + 1].first - sc->stsc_data[index].first;
3276  else {
3277  // Validation for stsc / stco happens earlier in mov_read_stsc + mov_read_trak.
3279  chunk_count = sc->chunk_count - (sc->stsc_data[index].first - 1);
3280  }
3281 
3282  return sc->stsc_data[index].count * (int64_t)chunk_count;
3283 }
3284 
3286 {
3287  AVStream *st;
3288  MOVStreamContext *sc;
3289  unsigned i, entries;
3290 
3291  if (c->trak_index < 0) {
3292  av_log(c->fc, AV_LOG_WARNING, "STPS outside TRAK\n");
3293  return 0;
3294  }
3295 
3296  if (c->fc->nb_streams < 1)
3297  return 0;
3298  st = c->fc->streams[c->fc->nb_streams-1];
3299  sc = st->priv_data;
3300 
3301  avio_rb32(pb); // version + flags
3302 
3303  entries = avio_rb32(pb);
3304  if (sc->stps_data)
3305  av_log(c->fc, AV_LOG_WARNING, "Duplicated STPS atom\n");
3306  av_free(sc->stps_data);
3307  sc->stps_count = 0;
3308  sc->stps_data = av_malloc_array(entries, sizeof(*sc->stps_data));
3309  if (!sc->stps_data)
3310  return AVERROR(ENOMEM);
3311 
3312  for (i = 0; i < entries && !pb->eof_reached; i++) {
3313  sc->stps_data[i] = avio_rb32(pb);
3314  }
3315 
3316  sc->stps_count = i;
3317 
3318  if (pb->eof_reached) {
3319  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STPS atom\n");
3320  return AVERROR_EOF;
3321  }
3322 
3323  return 0;
3324 }
3325 
3327 {
3328  AVStream *st;
3329  FFStream *sti;
3330  MOVStreamContext *sc;
3331  unsigned int i, entries;
3332 
3333  if (c->trak_index < 0) {
3334  av_log(c->fc, AV_LOG_WARNING, "STSS outside TRAK\n");
3335  return 0;
3336  }
3337 
3338  if (c->fc->nb_streams < 1)
3339  return 0;
3340  st = c->fc->streams[c->fc->nb_streams-1];
3341  sti = ffstream(st);
3342  sc = st->priv_data;
3343 
3344  avio_r8(pb); /* version */
3345  avio_rb24(pb); /* flags */
3346 
3347  entries = avio_rb32(pb);
3348 
3349  av_log(c->fc, AV_LOG_TRACE, "keyframe_count = %u\n", entries);
3350 
3351  if (!entries) {
3352  sc->keyframe_absent = 1;
3353  if (!sti->need_parsing && st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
3355  return 0;
3356  }
3357  if (sc->keyframes)
3358  av_log(c->fc, AV_LOG_WARNING, "Duplicated STSS atom\n");
3359  if (entries >= UINT_MAX / sizeof(int))
3360  return AVERROR_INVALIDDATA;
3361  av_freep(&sc->keyframes);
3362  sc->keyframe_count = 0;
3363  sc->keyframes = av_malloc_array(entries, sizeof(*sc->keyframes));
3364  if (!sc->keyframes)
3365  return AVERROR(ENOMEM);
3366 
3367  for (i = 0; i < entries && !pb->eof_reached; i++) {
3368  sc->keyframes[i] = avio_rb32(pb);
3369  }
3370 
3371  sc->keyframe_count = i;
3372 
3373  if (pb->eof_reached) {
3374  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSS atom\n");
3375  return AVERROR_EOF;
3376  }
3377 
3378  return 0;
3379 }
3380 
3382 {
3383  AVStream *st;
3384  MOVStreamContext *sc;
3385  unsigned int i, entries, sample_size, field_size, num_bytes;
3386  GetBitContext gb;
3387  unsigned char* buf;
3388  int ret;
3389 
3390  if (c->trak_index < 0) {
3391  av_log(c->fc, AV_LOG_WARNING, "STSZ outside TRAK\n");
3392  return 0;
3393  }
3394 
3395  if (c->fc->nb_streams < 1)
3396  return 0;
3397  st = c->fc->streams[c->fc->nb_streams-1];
3398  sc = st->priv_data;
3399 
3400  avio_r8(pb); /* version */
3401  avio_rb24(pb); /* flags */
3402 
3403  if (atom.type == MKTAG('s','t','s','z')) {
3404  sample_size = avio_rb32(pb);
3405  if (!sc->sample_size) /* do not overwrite value computed in stsd */
3406  sc->sample_size = sample_size;
3407  sc->stsz_sample_size = sample_size;
3408  field_size = 32;
3409  } else {
3410  sample_size = 0;
3411  avio_rb24(pb); /* reserved */
3412  field_size = avio_r8(pb);
3413  }
3414  entries = avio_rb32(pb);
3415 
3416  av_log(c->fc, AV_LOG_TRACE, "sample_size = %u sample_count = %u\n", sc->sample_size, entries);
3417 
3418  sc->sample_count = entries;
3419  if (sample_size)
3420  return 0;
3421 
3422  if (field_size != 4 && field_size != 8 && field_size != 16 && field_size != 32) {
3423  av_log(c->fc, AV_LOG_ERROR, "Invalid sample field size %u\n", field_size);
3424  return AVERROR_INVALIDDATA;
3425  }
3426 
3427  if (!entries)
3428  return 0;
3429  if (entries >= (INT_MAX - 4 - 8 * AV_INPUT_BUFFER_PADDING_SIZE) / field_size)
3430  return AVERROR_INVALIDDATA;
3431  if (sc->sample_sizes)
3432  av_log(c->fc, AV_LOG_WARNING, "Duplicated STSZ atom\n");
3433  av_free(sc->sample_sizes);
3434  sc->sample_count = 0;
3435  sc->sample_sizes = av_malloc_array(entries, sizeof(*sc->sample_sizes));
3436  if (!sc->sample_sizes)
3437  return AVERROR(ENOMEM);
3438 
3439  num_bytes = (entries*field_size+4)>>3;
3440 
3441  buf = av_malloc(num_bytes+AV_INPUT_BUFFER_PADDING_SIZE);
3442  if (!buf) {
3443  av_freep(&sc->sample_sizes);
3444  return AVERROR(ENOMEM);
3445  }
3446 
3447  ret = ffio_read_size(pb, buf, num_bytes);
3448  if (ret < 0) {
3449  av_freep(&sc->sample_sizes);
3450  av_free(buf);
3451  av_log(c->fc, AV_LOG_WARNING, "STSZ atom truncated\n");
3452  return 0;
3453  }
3454 
3455  init_get_bits(&gb, buf, 8*num_bytes);
3456 
3457  for (i = 0; i < entries; i++) {
3458  sc->sample_sizes[i] = get_bits_long(&gb, field_size);
3459  if (sc->sample_sizes[i] > INT64_MAX - sc->data_size) {
3460  av_free(buf);
3461  av_log(c->fc, AV_LOG_ERROR, "Sample size overflow in STSZ\n");
3462  return AVERROR_INVALIDDATA;
3463  }
3464  sc->data_size += sc->sample_sizes[i];
3465  }
3466 
3467  sc->sample_count = i;
3468 
3469  av_free(buf);
3470 
3471  return 0;
3472 }
3473 
3475 {
3476  AVStream *st;
3477  MOVStreamContext *sc;
3478  unsigned int i, entries, alloc_size = 0;
3479  int64_t duration = 0;
3480  int64_t total_sample_count = 0;
3481  int64_t current_dts = 0;
3482  int64_t corrected_dts = 0;
3483 
3484  if (c->trak_index < 0) {
3485  av_log(c->fc, AV_LOG_WARNING, "STTS outside TRAK\n");
3486  return 0;
3487  }
3488 
3489  if (c->fc->nb_streams < 1)
3490  return 0;
3491  st = c->fc->streams[c->fc->nb_streams-1];
3492  sc = st->priv_data;
3493 
3494  avio_r8(pb); /* version */
3495  avio_rb24(pb); /* flags */
3496  entries = avio_rb32(pb);
3497 
3498  av_log(c->fc, AV_LOG_TRACE, "track[%u].stts.entries = %u\n",
3499  c->fc->nb_streams-1, entries);
3500 
3501  if (sc->stts_data)
3502  av_log(c->fc, AV_LOG_WARNING, "Duplicated STTS atom\n");
3503  av_freep(&sc->stts_data);
3504  sc->stts_count = 0;
3505  if (entries >= INT_MAX / sizeof(*sc->stts_data))
3506  return AVERROR(ENOMEM);
3507 
3508  for (i = 0; i < entries && !pb->eof_reached; i++) {
3509  unsigned int sample_duration;
3510  unsigned int sample_count;
3511  unsigned int min_entries = FFMIN(FFMAX(i + 1, 1024 * 1024), entries);
3512  MOVStts *stts_data = av_fast_realloc(sc->stts_data, &alloc_size,
3513  min_entries * sizeof(*sc->stts_data));
3514  if (!stts_data) {
3515  av_freep(&sc->stts_data);
3516  sc->stts_count = 0;
3517  return AVERROR(ENOMEM);
3518  }
3519  sc->stts_count = min_entries;
3520  sc->stts_data = stts_data;
3521 
3522  sample_count = avio_rb32(pb);
3523  sample_duration = avio_rb32(pb);
3524 
3525  sc->stts_data[i].count= sample_count;
3526  sc->stts_data[i].duration= sample_duration;
3527 
3528  av_log(c->fc, AV_LOG_TRACE, "sample_count=%u, sample_duration=%u\n",
3529  sample_count, sample_duration);
3530 
3531  /* STTS sample offsets are uint32 but some files store it as int32
3532  * with negative values used to correct DTS delays.
3533  There may be abnormally large values as well. */
3534  if (sample_duration > c->max_stts_delta) {
3535  // assume high delta is a correction if negative when cast as int32
3536  int32_t delta_magnitude = (int32_t)sample_duration;
3537  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",
3538  sample_duration, i, sample_count, st->index);
3539  sc->stts_data[i].duration = 1;
3540  corrected_dts += (delta_magnitude < 0 ? (int64_t)delta_magnitude : 1) * sample_count;
3541  } else {
3542  corrected_dts += sample_duration * (uint64_t)sample_count;
3543  }
3544 
3545  current_dts += sc->stts_data[i].duration * (uint64_t)sample_count;
3546 
3547  if (current_dts > corrected_dts) {
3548  int64_t drift = av_sat_sub64(current_dts, corrected_dts) / FFMAX(sample_count, 1);
3549  uint32_t correction = (sc->stts_data[i].duration > drift) ? drift : sc->stts_data[i].duration - 1;
3550  current_dts -= correction * (uint64_t)sample_count;
3551  sc->stts_data[i].duration -= correction;
3552  }
3553 
3554  duration+=(int64_t)sc->stts_data[i].duration*(uint64_t)sc->stts_data[i].count;
3555  total_sample_count+=sc->stts_data[i].count;
3556  }
3557 
3558  sc->stts_count = i;
3559 
3560  if (duration > 0 &&
3561  duration <= INT64_MAX - sc->duration_for_fps &&
3562  total_sample_count <= INT_MAX - sc->nb_frames_for_fps) {
3563  sc->duration_for_fps += duration;
3564  sc->nb_frames_for_fps += total_sample_count;
3565  }
3566 
3567  if (pb->eof_reached) {
3568  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STTS atom\n");
3569  return AVERROR_EOF;
3570  }
3571 
3572  st->nb_frames= total_sample_count;
3573  if (duration)
3574  st->duration= FFMIN(st->duration, duration);
3575 
3576  // All samples have zero duration. They have higher chance be chose by
3577  // mov_find_next_sample, which leads to seek again and again.
3578  //
3579  // It's AVERROR_INVALIDDATA actually, but such files exist in the wild.
3580  // So only mark data stream as discarded for safety.
3581  if (!duration && sc->stts_count &&
3583  av_log(c->fc, AV_LOG_WARNING,
3584  "All samples in data stream index:id [%d:%d] have zero "
3585  "duration, stream set to be discarded by default. Override "
3586  "using AVStream->discard or -discard for ffmpeg command.\n",
3587  st->index, sc->id);
3588  st->discard = AVDISCARD_ALL;
3589  }
3590  sc->track_end = duration;
3591  return 0;
3592 }
3593 
3595 {
3596  AVStream *st;
3597  MOVStreamContext *sc;
3598  int64_t i, entries;
3599 
3600  if (c->fc->nb_streams < 1)
3601  return 0;
3602  st = c->fc->streams[c->fc->nb_streams - 1];
3603  sc = st->priv_data;
3604 
3605  avio_r8(pb); /* version */
3606  avio_rb24(pb); /* flags */
3607  entries = atom.size - 4;
3608 
3609  av_log(c->fc, AV_LOG_TRACE, "track[%u].sdtp.entries = %" PRId64 "\n",
3610  c->fc->nb_streams - 1, entries);
3611 
3612  if (sc->sdtp_data)
3613  av_log(c->fc, AV_LOG_WARNING, "Duplicated SDTP atom\n");
3614  av_freep(&sc->sdtp_data);
3615  sc->sdtp_count = 0;
3616 
3617  sc->sdtp_data = av_malloc(entries);
3618  if (!sc->sdtp_data)
3619  return AVERROR(ENOMEM);
3620 
3621  for (i = 0; i < entries && !pb->eof_reached; i++)
3622  sc->sdtp_data[i] = avio_r8(pb);
3623  sc->sdtp_count = i;
3624 
3625  return 0;
3626 }
3627 
3628 static void mov_update_dts_shift(MOVStreamContext *sc, int duration, void *logctx)
3629 {
3630  if (duration < 0) {
3631  if (duration == INT_MIN) {
3632  av_log(logctx, AV_LOG_WARNING, "mov_update_dts_shift(): dts_shift set to %d\n", INT_MAX);
3633  duration++;
3634  }
3635  sc->dts_shift = FFMAX(sc->dts_shift, -duration);
3636  }
3637 }
3638 
3640 {
3641  AVStream *st;
3642  MOVStreamContext *sc;
3643  unsigned int i, entries, ctts_count = 0;
3644 
3645  if (c->trak_index < 0) {
3646  av_log(c->fc, AV_LOG_WARNING, "CTTS outside TRAK\n");
3647  return 0;
3648  }
3649 
3650  if (c->fc->nb_streams < 1)
3651  return 0;
3652  st = c->fc->streams[c->fc->nb_streams-1];
3653  sc = st->priv_data;
3654 
3655  avio_r8(pb); /* version */
3656  avio_rb24(pb); /* flags */
3657  entries = avio_rb32(pb);
3658 
3659  av_log(c->fc, AV_LOG_TRACE, "track[%u].ctts.entries = %u\n", c->fc->nb_streams - 1, entries);
3660 
3661  if (!entries)
3662  return 0;
3663  if (entries >= UINT_MAX / sizeof(*sc->ctts_data))
3664  return AVERROR_INVALIDDATA;
3665  av_freep(&sc->ctts_data);
3666  sc->ctts_data = av_fast_realloc(NULL, &sc->ctts_allocated_size, entries * sizeof(*sc->ctts_data));
3667  if (!sc->ctts_data)
3668  return AVERROR(ENOMEM);
3669 
3670  for (i = 0; i < entries && !pb->eof_reached; i++) {
3671  int count = avio_rb32(pb);
3672  int duration = avio_rb32(pb);
3673 
3674  if (count <= 0) {
3675  av_log(c->fc, AV_LOG_TRACE,
3676  "ignoring CTTS entry with count=%d duration=%d\n",
3677  count, duration);
3678  continue;
3679  }
3680 
3681  add_ctts_entry(&sc->ctts_data, &ctts_count, &sc->ctts_allocated_size,
3682  count, duration);
3683 
3684  av_log(c->fc, AV_LOG_TRACE, "count=%d, duration=%d\n",
3685  count, duration);
3686 
3687  if (FFNABS(duration) < -(1<<28) && i+2<entries) {
3688  av_log(c->fc, AV_LOG_WARNING, "CTTS invalid\n");
3689  av_freep(&sc->ctts_data);
3690  sc->ctts_count = 0;
3691  return 0;
3692  }
3693 
3694  if (i+2<entries)
3695  mov_update_dts_shift(sc, duration, c->fc);
3696  }
3697 
3698  sc->ctts_count = ctts_count;
3699 
3700  if (pb->eof_reached) {
3701  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted CTTS atom\n");
3702  return AVERROR_EOF;
3703  }
3704 
3705  av_log(c->fc, AV_LOG_TRACE, "dts shift %d\n", sc->dts_shift);
3706 
3707  return 0;
3708 }
3709 
3711 {
3712  AVStream *st;
3713  MOVStreamContext *sc;
3714  uint8_t version;
3715  uint32_t grouping_type;
3716  uint32_t default_length;
3717  av_unused uint32_t default_group_description_index;
3718  uint32_t entry_count;
3719 
3720  if (c->fc->nb_streams < 1)
3721  return 0;
3722  st = c->fc->streams[c->fc->nb_streams - 1];
3723  sc = st->priv_data;
3724 
3725  version = avio_r8(pb); /* version */
3726  avio_rb24(pb); /* flags */
3727  grouping_type = avio_rl32(pb);
3728 
3729  /*
3730  * This function only supports "sync" boxes, but the code is able to parse
3731  * other boxes (such as "tscl", "tsas" and "stsa")
3732  */
3733  if (grouping_type != MKTAG('s','y','n','c'))
3734  return 0;
3735 
3736  default_length = version >= 1 ? avio_rb32(pb) : 0;
3737  default_group_description_index = version >= 2 ? avio_rb32(pb) : 0;
3738  entry_count = avio_rb32(pb);
3739 
3740  av_freep(&sc->sgpd_sync);
3741  sc->sgpd_sync_count = entry_count;
3742  sc->sgpd_sync = av_calloc(entry_count, sizeof(*sc->sgpd_sync));
3743  if (!sc->sgpd_sync)
3744  return AVERROR(ENOMEM);
3745 
3746  for (uint32_t i = 0; i < entry_count && !pb->eof_reached; i++) {
3747  uint32_t description_length = default_length;
3748  if (version >= 1 && default_length == 0)
3749  description_length = avio_rb32(pb);
3750  if (grouping_type == MKTAG('s','y','n','c')) {
3751  const uint8_t nal_unit_type = avio_r8(pb) & 0x3f;
3752  sc->sgpd_sync[i] = nal_unit_type;
3753  description_length -= 1;
3754  }
3755  avio_skip(pb, description_length);
3756  }
3757 
3758  if (pb->eof_reached) {
3759  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted SGPD atom\n");
3760  return AVERROR_EOF;
3761  }
3762 
3763  return 0;
3764 }
3765 
3767 {
3768  AVStream *st;
3769  MOVStreamContext *sc;
3770  unsigned int i, entries;
3771  uint8_t version;
3772  uint32_t grouping_type;
3773  MOVSbgp *table, **tablep;
3774  int *table_count;
3775 
3776  if (c->fc->nb_streams < 1)
3777  return 0;
3778  st = c->fc->streams[c->fc->nb_streams-1];
3779  sc = st->priv_data;
3780 
3781  version = avio_r8(pb); /* version */
3782  avio_rb24(pb); /* flags */
3783  grouping_type = avio_rl32(pb);
3784 
3785  if (grouping_type == MKTAG('r','a','p',' ')) {
3786  tablep = &sc->rap_group;
3787  table_count = &sc->rap_group_count;
3788  } else if (grouping_type == MKTAG('s','y','n','c')) {
3789  tablep = &sc->sync_group;
3790  table_count = &sc->sync_group_count;
3791  } else {
3792  return 0;
3793  }
3794 
3795  if (version == 1)
3796  avio_rb32(pb); /* grouping_type_parameter */
3797 
3798  entries = avio_rb32(pb);
3799  if (!entries)
3800  return 0;
3801  if (*tablep)
3802  av_log(c->fc, AV_LOG_WARNING, "Duplicated SBGP %s atom\n", av_fourcc2str(grouping_type));
3803  av_freep(tablep);
3804  table = av_malloc_array(entries, sizeof(*table));
3805  if (!table)
3806  return AVERROR(ENOMEM);
3807  *tablep = table;
3808 
3809  for (i = 0; i < entries && !pb->eof_reached; i++) {
3810  table[i].count = avio_rb32(pb); /* sample_count */
3811  table[i].index = avio_rb32(pb); /* group_description_index */
3812  }
3813 
3814  *table_count = i;
3815 
3816  if (pb->eof_reached) {
3817  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted SBGP atom\n");
3818  return AVERROR_EOF;
3819  }
3820 
3821  return 0;
3822 }
3823 
3824 /**
3825  * Get ith edit list entry (media time, duration).
3826  */
3828  const MOVStreamContext *msc,
3829  unsigned int edit_list_index,
3830  int64_t *edit_list_media_time,
3831  int64_t *edit_list_duration,
3832  int64_t global_timescale)
3833 {
3834  if (edit_list_index == msc->elst_count) {
3835  return 0;
3836  }
3837  *edit_list_media_time = msc->elst_data[edit_list_index].time;
3838  *edit_list_duration = msc->elst_data[edit_list_index].duration;
3839 
3840  /* duration is in global timescale units;convert to msc timescale */
3841  if (global_timescale == 0) {
3842  avpriv_request_sample(mov->fc, "Support for mvhd.timescale = 0 with editlists");
3843  return 0;
3844  }
3845  *edit_list_duration = av_rescale(*edit_list_duration, msc->time_scale,
3846  global_timescale);
3847 
3848  if (*edit_list_duration + (uint64_t)*edit_list_media_time > INT64_MAX)
3849  *edit_list_duration = 0;
3850 
3851  return 1;
3852 }
3853 
3854 /**
3855  * Find the closest previous frame to the timestamp_pts, in e_old index
3856  * entries. Searching for just any frame / just key frames can be controlled by
3857  * last argument 'flag'.
3858  * Note that if ctts_data is not NULL, we will always search for a key frame
3859  * irrespective of the value of 'flag'. If we don't find any keyframe, we will
3860  * return the first frame of the video.
3861  *
3862  * Here the timestamp_pts is considered to be a presentation timestamp and
3863  * the timestamp of index entries are considered to be decoding timestamps.
3864  *
3865  * Returns 0 if successful in finding a frame, else returns -1.
3866  * Places the found index corresponding output arg.
3867  *
3868  * If ctts_old is not NULL, then refines the searched entry by searching
3869  * backwards from the found timestamp, to find the frame with correct PTS.
3870  *
3871  * Places the found ctts_index and ctts_sample in corresponding output args.
3872  */
3874  AVIndexEntry *e_old,
3875  int nb_old,
3876  MOVCtts* ctts_data,
3877  int64_t ctts_count,
3878  int64_t timestamp_pts,
3879  int flag,
3880  int64_t* index,
3881  int64_t* ctts_index,
3882  int64_t* ctts_sample)
3883 {
3884  MOVStreamContext *msc = st->priv_data;
3885  FFStream *const sti = ffstream(st);
3886  AVIndexEntry *e_keep = sti->index_entries;
3887  int nb_keep = sti->nb_index_entries;
3888  int64_t i = 0;
3889  int64_t index_ctts_count;
3890 
3891  av_assert0(index);
3892 
3893  // If dts_shift > 0, then all the index timestamps will have to be offset by
3894  // at least dts_shift amount to obtain PTS.
3895  // Hence we decrement the searched timestamp_pts by dts_shift to find the closest index element.
3896  if (msc->dts_shift > 0) {
3897  timestamp_pts -= msc->dts_shift;
3898  }
3899 
3900  sti->index_entries = e_old;
3901  sti->nb_index_entries = nb_old;
3902  *index = av_index_search_timestamp(st, timestamp_pts, flag | AVSEEK_FLAG_BACKWARD);
3903 
3904  // Keep going backwards in the index entries until the timestamp is the same.
3905  if (*index >= 0) {
3906  for (i = *index; i > 0 && e_old[i].timestamp == e_old[i - 1].timestamp;
3907  i--) {
3908  if ((flag & AVSEEK_FLAG_ANY) ||
3909  (e_old[i - 1].flags & AVINDEX_KEYFRAME)) {
3910  *index = i - 1;
3911  }
3912  }
3913  }
3914 
3915  // If we have CTTS then refine the search, by searching backwards over PTS
3916  // computed by adding corresponding CTTS durations to index timestamps.
3917  if (ctts_data && *index >= 0) {
3918  av_assert0(ctts_index);
3919  av_assert0(ctts_sample);
3920  // Find out the ctts_index for the found frame.
3921  *ctts_index = 0;
3922  *ctts_sample = 0;
3923  for (index_ctts_count = 0; index_ctts_count < *index; index_ctts_count++) {
3924  if (*ctts_index < ctts_count) {
3925  (*ctts_sample)++;
3926  if (ctts_data[*ctts_index].count == *ctts_sample) {
3927  (*ctts_index)++;
3928  *ctts_sample = 0;
3929  }
3930  }
3931  }
3932 
3933  while (*index >= 0 && (*ctts_index) >= 0 && (*ctts_index) < ctts_count) {
3934  // Find a "key frame" with PTS <= timestamp_pts (So that we can decode B-frames correctly).
3935  // No need to add dts_shift to the timestamp here becase timestamp_pts has already been
3936  // compensated by dts_shift above.
3937  if ((e_old[*index].timestamp + ctts_data[*ctts_index].duration) <= timestamp_pts &&
3938  (e_old[*index].flags & AVINDEX_KEYFRAME)) {
3939  break;
3940  }
3941 
3942  (*index)--;
3943  if (*ctts_sample == 0) {
3944  (*ctts_index)--;
3945  if (*ctts_index >= 0)
3946  *ctts_sample = ctts_data[*ctts_index].count - 1;
3947  } else {
3948  (*ctts_sample)--;
3949  }
3950  }
3951  }
3952 
3953  /* restore AVStream state*/
3954  sti->index_entries = e_keep;
3955  sti->nb_index_entries = nb_keep;
3956  return *index >= 0 ? 0 : -1;
3957 }
3958 
3959 /**
3960  * Add index entry with the given values, to the end of ffstream(st)->index_entries.
3961  * Returns the new size ffstream(st)->index_entries if successful, else returns -1.
3962  *
3963  * This function is similar to ff_add_index_entry in libavformat/utils.c
3964  * except that here we are always unconditionally adding an index entry to
3965  * the end, instead of searching the entries list and skipping the add if
3966  * there is an existing entry with the same timestamp.
3967  * This is needed because the mov_fix_index calls this func with the same
3968  * unincremented timestamp for successive discarded frames.
3969  */
3971  int size, int distance, int flags)
3972 {
3973  FFStream *const sti = ffstream(st);
3974  AVIndexEntry *entries, *ie;
3975  int64_t index = -1;
3976  const size_t min_size_needed = (sti->nb_index_entries + 1) * sizeof(AVIndexEntry);
3977 
3978  // Double the allocation each time, to lower memory fragmentation.
3979  // Another difference from ff_add_index_entry function.
3980  const size_t requested_size =
3981  min_size_needed > sti->index_entries_allocated_size ?
3982  FFMAX(min_size_needed, 2 * sti->index_entries_allocated_size) :
3983  min_size_needed;
3984 
3985  if (sti->nb_index_entries + 1U >= UINT_MAX / sizeof(AVIndexEntry))
3986  return -1;
3987 
3988  entries = av_fast_realloc(sti->index_entries,
3990  requested_size);
3991  if (!entries)
3992  return -1;
3993 
3994  sti->index_entries = entries;
3995 
3996  index = sti->nb_index_entries++;
3997  ie= &entries[index];
3998 
3999  ie->pos = pos;
4000  ie->timestamp = timestamp;
4001  ie->min_distance= distance;
4002  ie->size= size;
4003  ie->flags = flags;
4004  return index;
4005 }
4006 
4007 /**
4008  * Rewrite timestamps of index entries in the range [end_index - frame_duration_buffer_size, end_index)
4009  * by subtracting end_ts successively by the amounts given in frame_duration_buffer.
4010  */
4011 static void fix_index_entry_timestamps(AVStream* st, int end_index, int64_t end_ts,
4012  int64_t* frame_duration_buffer,
4013  int frame_duration_buffer_size) {
4014  FFStream *const sti = ffstream(st);
4015  int i = 0;
4016  av_assert0(end_index >= 0 && end_index <= sti->nb_index_entries);
4017  for (i = 0; i < frame_duration_buffer_size; i++) {
4018  end_ts -= frame_duration_buffer[frame_duration_buffer_size - 1 - i];
4019  sti->index_entries[end_index - 1 - i].timestamp = end_ts;
4020  }
4021 }
4022 
4023 /**
4024  * Append a new ctts entry to ctts_data.
4025  * Returns the new ctts_count if successful, else returns -1.
4026  */
4027 static int64_t add_ctts_entry(MOVCtts** ctts_data, unsigned int* ctts_count, unsigned int* allocated_size,
4028  int count, int duration)
4029 {
4030  MOVCtts *ctts_buf_new;
4031  const size_t min_size_needed = (*ctts_count + 1) * sizeof(MOVCtts);
4032  const size_t requested_size =
4033  min_size_needed > *allocated_size ?
4034  FFMAX(min_size_needed, 2 * (*allocated_size)) :
4035  min_size_needed;
4036 
4037  if ((unsigned)(*ctts_count) >= UINT_MAX / sizeof(MOVCtts) - 1)
4038  return -1;
4039 
4040  ctts_buf_new = av_fast_realloc(*ctts_data, allocated_size, requested_size);
4041 
4042  if (!ctts_buf_new)
4043  return -1;
4044 
4045  *ctts_data = ctts_buf_new;
4046 
4047  ctts_buf_new[*ctts_count].count = count;
4048  ctts_buf_new[*ctts_count].duration = duration;
4049 
4050  *ctts_count = (*ctts_count) + 1;
4051  return *ctts_count;
4052 }
4053 
4054 #define MAX_REORDER_DELAY 16
4056 {
4057  MOVStreamContext *msc = st->priv_data;
4058  FFStream *const sti = ffstream(st);
4059  int ctts_ind = 0;
4060  int ctts_sample = 0;
4061  int64_t pts_buf[MAX_REORDER_DELAY + 1]; // Circular buffer to sort pts.
4062  int buf_start = 0;
4063  int j, r, num_swaps;
4064 
4065  for (j = 0; j < MAX_REORDER_DELAY + 1; j++)
4066  pts_buf[j] = INT64_MIN;
4067 
4068  if (st->codecpar->video_delay <= 0 && msc->ctts_data &&
4070  st->codecpar->video_delay = 0;
4071  for (int ind = 0; ind < sti->nb_index_entries && ctts_ind < msc->ctts_count; ++ind) {
4072  // Point j to the last elem of the buffer and insert the current pts there.
4073  j = buf_start;
4074  buf_start = (buf_start + 1);
4075  if (buf_start == MAX_REORDER_DELAY + 1)
4076  buf_start = 0;
4077 
4078  pts_buf[j] = sti->index_entries[ind].timestamp + msc->ctts_data[ctts_ind].duration;
4079 
4080  // The timestamps that are already in the sorted buffer, and are greater than the
4081  // current pts, are exactly the timestamps that need to be buffered to output PTS
4082  // in correct sorted order.
4083  // Hence the video delay (which is the buffer size used to sort DTS and output PTS),
4084  // can be computed as the maximum no. of swaps any particular timestamp needs to
4085  // go through, to keep this buffer in sorted order.
4086  num_swaps = 0;
4087  while (j != buf_start) {
4088  r = j - 1;
4089  if (r < 0) r = MAX_REORDER_DELAY;
4090  if (pts_buf[j] < pts_buf[r]) {
4091  FFSWAP(int64_t, pts_buf[j], pts_buf[r]);
4092  ++num_swaps;
4093  } else {
4094  break;
4095  }
4096  j = r;
4097  }
4098  st->codecpar->video_delay = FFMAX(st->codecpar->video_delay, num_swaps);
4099 
4100  ctts_sample++;
4101  if (ctts_sample == msc->ctts_data[ctts_ind].count) {
4102  ctts_ind++;
4103  ctts_sample = 0;
4104  }
4105  }
4106  av_log(c->fc, AV_LOG_DEBUG, "Setting codecpar->delay to %d for stream st: %d\n",
4107  st->codecpar->video_delay, st->index);
4108  }
4109 }
4110 
4112 {
4113  sc->current_sample++;
4114  sc->current_index++;
4115  if (sc->index_ranges &&
4116  sc->current_index >= sc->current_index_range->end &&
4117  sc->current_index_range->end) {
4118  sc->current_index_range++;
4120  }
4121 }
4122 
4124 {
4125  sc->current_sample--;
4126  sc->current_index--;
4127  if (sc->index_ranges &&
4129  sc->current_index_range > sc->index_ranges) {
4130  sc->current_index_range--;
4131  sc->current_index = sc->current_index_range->end - 1;
4132  }
4133 }
4134 
4135 static void mov_current_sample_set(MOVStreamContext *sc, int current_sample)
4136 {
4137  int64_t range_size;
4138 
4139  sc->current_sample = current_sample;
4140  sc->current_index = current_sample;
4141  if (!sc->index_ranges) {
4142  return;
4143  }
4144 
4145  for (sc->current_index_range = sc->index_ranges;
4146  sc->current_index_range->end;
4147  sc->current_index_range++) {
4148  range_size = sc->current_index_range->end - sc->current_index_range->start;
4149  if (range_size > current_sample) {
4150  sc->current_index = sc->current_index_range->start + current_sample;
4151  break;
4152  }
4153  current_sample -= range_size;
4154  }
4155 }
4156 
4157 /**
4158  * Fix ffstream(st)->index_entries, so that it contains only the entries (and the entries
4159  * which are needed to decode them) that fall in the edit list time ranges.
4160  * Also fixes the timestamps of the index entries to match the timeline
4161  * specified the edit lists.
4162  */
4163 static void mov_fix_index(MOVContext *mov, AVStream *st)
4164 {
4165  MOVStreamContext *msc = st->priv_data;
4166  FFStream *const sti = ffstream(st);
4167  AVIndexEntry *e_old = sti->index_entries;
4168  int nb_old = sti->nb_index_entries;
4169  const AVIndexEntry *e_old_end = e_old + nb_old;
4170  const AVIndexEntry *current = NULL;
4171  MOVCtts *ctts_data_old = msc->ctts_data;
4172  int64_t ctts_index_old = 0;
4173  int64_t ctts_sample_old = 0;
4174  int64_t ctts_count_old = msc->ctts_count;
4175  int64_t edit_list_media_time = 0;
4176  int64_t edit_list_duration = 0;
4177  int64_t frame_duration = 0;
4178  int64_t edit_list_dts_counter = 0;
4179  int64_t edit_list_dts_entry_end = 0;
4180  int64_t edit_list_start_ctts_sample = 0;
4181  int64_t curr_cts;
4182  int64_t curr_ctts = 0;
4183  int64_t empty_edits_sum_duration = 0;
4184  int64_t edit_list_index = 0;
4185  int64_t index;
4186  int flags;
4187  int64_t start_dts = 0;
4188  int64_t edit_list_start_encountered = 0;
4189  int64_t search_timestamp = 0;
4190  int64_t* frame_duration_buffer = NULL;
4191  int num_discarded_begin = 0;
4192  int first_non_zero_audio_edit = -1;
4193  int packet_skip_samples = 0;
4194  MOVIndexRange *current_index_range = NULL;
4195  int found_keyframe_after_edit = 0;
4196  int found_non_empty_edit = 0;
4197 
4198  if (!msc->elst_data || msc->elst_count <= 0 || nb_old <= 0) {
4199  return;
4200  }
4201 
4202  // allocate the index ranges array
4203  msc->index_ranges = av_malloc_array(msc->elst_count + 1,
4204  sizeof(msc->index_ranges[0]));
4205  if (!msc->index_ranges) {
4206  av_log(mov->fc, AV_LOG_ERROR, "Cannot allocate index ranges buffer\n");
4207  return;
4208  }
4209  msc->current_index_range = msc->index_ranges;
4210 
4211  // Clean AVStream from traces of old index
4212  sti->index_entries = NULL;
4214  sti->nb_index_entries = 0;
4215 
4216  // Clean ctts fields of MOVStreamContext
4217  msc->ctts_data = NULL;
4218  msc->ctts_count = 0;
4219  msc->ctts_index = 0;
4220  msc->ctts_sample = 0;
4221  msc->ctts_allocated_size = 0;
4222 
4223  // Reinitialize min_corrected_pts so that it can be computed again.
4224  msc->min_corrected_pts = -1;
4225 
4226  // If the dts_shift is positive (in case of negative ctts values in mov),
4227  // then negate the DTS by dts_shift
4228  if (msc->dts_shift > 0) {
4229  edit_list_dts_entry_end -= msc->dts_shift;
4230  av_log(mov->fc, AV_LOG_DEBUG, "Shifting DTS by %d because of negative CTTS.\n", msc->dts_shift);
4231  }
4232 
4233  start_dts = edit_list_dts_entry_end;
4234 
4235  while (get_edit_list_entry(mov, msc, edit_list_index, &edit_list_media_time,
4236  &edit_list_duration, mov->time_scale)) {
4237  av_log(mov->fc, AV_LOG_DEBUG, "Processing st: %d, edit list %"PRId64" - media time: %"PRId64", duration: %"PRId64"\n",
4238  st->index, edit_list_index, edit_list_media_time, edit_list_duration);
4239  edit_list_index++;
4240  edit_list_dts_counter = edit_list_dts_entry_end;
4241  edit_list_dts_entry_end += edit_list_duration;
4242  num_discarded_begin = 0;
4243  if (!found_non_empty_edit && edit_list_media_time == -1) {
4244  empty_edits_sum_duration += edit_list_duration;
4245  continue;
4246  }
4247  found_non_empty_edit = 1;
4248 
4249  // If we encounter a non-negative edit list reset the skip_samples/start_pad fields and set them
4250  // according to the edit list below.
4251  if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
4252  if (first_non_zero_audio_edit < 0) {
4253  first_non_zero_audio_edit = 1;
4254  } else {
4255  first_non_zero_audio_edit = 0;
4256  }
4257 
4258  if (first_non_zero_audio_edit > 0)
4259  sti->skip_samples = msc->start_pad = 0;
4260  }
4261 
4262  // While reordering frame index according to edit list we must handle properly
4263  // the scenario when edit list entry starts from none key frame.
4264  // We find closest previous key frame and preserve it and consequent frames in index.
4265  // All frames which are outside edit list entry time boundaries will be dropped after decoding.
4266  search_timestamp = edit_list_media_time;
4267  if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
4268  // Audio decoders like AAC need need a decoder delay samples previous to the current sample,
4269  // to correctly decode this frame. Hence for audio we seek to a frame 1 sec. before the
4270  // edit_list_media_time to cover the decoder delay.
4271  search_timestamp = FFMAX(search_timestamp - msc->time_scale, e_old[0].timestamp);
4272  }
4273 
4274  if (find_prev_closest_index(st, e_old, nb_old, ctts_data_old, ctts_count_old, search_timestamp, 0,
4275  &index, &ctts_index_old, &ctts_sample_old) < 0) {
4276  av_log(mov->fc, AV_LOG_WARNING,
4277  "st: %d edit list: %"PRId64" Missing key frame while searching for timestamp: %"PRId64"\n",
4278  st->index, edit_list_index, search_timestamp);
4279  if (find_prev_closest_index(st, e_old, nb_old, ctts_data_old, ctts_count_old, search_timestamp, AVSEEK_FLAG_ANY,
4280  &index, &ctts_index_old, &ctts_sample_old) < 0) {
4281  av_log(mov->fc, AV_LOG_WARNING,
4282  "st: %d edit list %"PRId64" Cannot find an index entry before timestamp: %"PRId64".\n",
4283  st->index, edit_list_index, search_timestamp);
4284  index = 0;
4285  ctts_index_old = 0;
4286  ctts_sample_old = 0;
4287  }
4288  }
4289  current = e_old + index;
4290  edit_list_start_ctts_sample = ctts_sample_old;
4291 
4292  // Iterate over index and arrange it according to edit list
4293  edit_list_start_encountered = 0;
4294  found_keyframe_after_edit = 0;
4295  for (; current < e_old_end; current++, index++) {
4296  // check if frame outside edit list mark it for discard
4297  frame_duration = (current + 1 < e_old_end) ?
4298  ((current + 1)->timestamp - current->timestamp) : edit_list_duration;
4299 
4300  flags = current->flags;
4301 
4302  // frames (pts) before or after edit list
4303  curr_cts = current->timestamp + msc->dts_shift;
4304  curr_ctts = 0;
4305 
4306  if (ctts_data_old && ctts_index_old < ctts_count_old) {
4307  curr_ctts = ctts_data_old[ctts_index_old].duration;
4308  av_log(mov->fc, AV_LOG_TRACE, "stts: %"PRId64" ctts: %"PRId64", ctts_index: %"PRId64", ctts_count: %"PRId64"\n",
4309  curr_cts, curr_ctts, ctts_index_old, ctts_count_old);
4310  curr_cts += curr_ctts;
4311  ctts_sample_old++;
4312  if (ctts_sample_old == ctts_data_old[ctts_index_old].count) {
4313  if (add_ctts_entry(&msc->ctts_data, &msc->ctts_count,
4314  &msc->ctts_allocated_size,
4315  ctts_data_old[ctts_index_old].count - edit_list_start_ctts_sample,
4316  ctts_data_old[ctts_index_old].duration) == -1) {
4317  av_log(mov->fc, AV_LOG_ERROR, "Cannot add CTTS entry %"PRId64" - {%"PRId64", %d}\n",
4318  ctts_index_old,
4319  ctts_data_old[ctts_index_old].count - edit_list_start_ctts_sample,
4320  ctts_data_old[ctts_index_old].duration);
4321  break;
4322  }
4323  ctts_index_old++;
4324  ctts_sample_old = 0;
4325  edit_list_start_ctts_sample = 0;
4326  }
4327  }
4328 
4329  if (curr_cts < edit_list_media_time || curr_cts >= (edit_list_duration + edit_list_media_time)) {
4331  curr_cts < edit_list_media_time && curr_cts + frame_duration > edit_list_media_time &&
4332  first_non_zero_audio_edit > 0) {
4333  packet_skip_samples = edit_list_media_time - curr_cts;
4334  sti->skip_samples += packet_skip_samples;
4335 
4336  // Shift the index entry timestamp by packet_skip_samples to be correct.
4337  edit_list_dts_counter -= packet_skip_samples;
4338  if (edit_list_start_encountered == 0) {
4339  edit_list_start_encountered = 1;
4340  // Make timestamps strictly monotonically increasing for audio, by rewriting timestamps for
4341  // discarded packets.
4342  if (frame_duration_buffer) {
4343  fix_index_entry_timestamps(st, sti->nb_index_entries, edit_list_dts_counter,
4344  frame_duration_buffer, num_discarded_begin);
4345  av_freep(&frame_duration_buffer);
4346  }
4347  }
4348 
4349  av_log(mov->fc, AV_LOG_DEBUG, "skip %d audio samples from curr_cts: %"PRId64"\n", packet_skip_samples, curr_cts);
4350  } else {
4352  av_log(mov->fc, AV_LOG_DEBUG, "drop a frame at curr_cts: %"PRId64" @ %"PRId64"\n", curr_cts, index);
4353 
4354  if (edit_list_start_encountered == 0) {
4355  num_discarded_begin++;
4356  frame_duration_buffer = av_realloc(frame_duration_buffer,
4357  num_discarded_begin * sizeof(int64_t));
4358  if (!frame_duration_buffer) {
4359  av_log(mov->fc, AV_LOG_ERROR, "Cannot reallocate frame duration buffer\n");
4360  break;
4361  }
4362  frame_duration_buffer[num_discarded_begin - 1] = frame_duration;
4363 
4364  // Increment skip_samples for the first non-zero audio edit list
4365  if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
4366  first_non_zero_audio_edit > 0 && st->codecpar->codec_id != AV_CODEC_ID_VORBIS) {
4367  sti->skip_samples += frame_duration;
4368  }
4369  }
4370  }
4371  } else {
4372  if (msc->min_corrected_pts < 0) {
4373  msc->min_corrected_pts = edit_list_dts_counter + curr_ctts + msc->dts_shift;
4374  } else {
4375  msc->min_corrected_pts = FFMIN(msc->min_corrected_pts, edit_list_dts_counter + curr_ctts + msc->dts_shift);
4376  }
4377  if (edit_list_start_encountered == 0) {
4378  edit_list_start_encountered = 1;
4379  // Make timestamps strictly monotonically increasing by rewriting timestamps for
4380  // discarded packets.
4381  if (frame_duration_buffer) {
4382  fix_index_entry_timestamps(st, sti->nb_index_entries, edit_list_dts_counter,
4383  frame_duration_buffer, num_discarded_begin);
4384  av_freep(&frame_duration_buffer);
4385  }
4386  }
4387  }
4388 
4389  if (add_index_entry(st, current->pos, edit_list_dts_counter, current->size,
4390  current->min_distance, flags) == -1) {
4391  av_log(mov->fc, AV_LOG_ERROR, "Cannot add index entry\n");
4392  break;
4393  }
4394 
4395  // Update the index ranges array
4396  if (!current_index_range || index != current_index_range->end) {
4397  current_index_range = current_index_range ? current_index_range + 1
4398  : msc->index_ranges;
4399  current_index_range->start = index;
4400  }
4401  current_index_range->end = index + 1;
4402 
4403  // Only start incrementing DTS in frame_duration amounts, when we encounter a frame in edit list.
4404  if (edit_list_start_encountered > 0) {
4405  edit_list_dts_counter = edit_list_dts_counter + frame_duration;
4406  }
4407 
4408  // Break when found first key frame after edit entry completion
4409  if ((curr_cts + frame_duration >= (edit_list_duration + edit_list_media_time)) &&
4411  if (ctts_data_old) {
4412  // If we have CTTS and this is the first keyframe after edit elist,
4413  // wait for one more, because there might be trailing B-frames after this I-frame
4414  // that do belong to the edit.
4415  if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO && found_keyframe_after_edit == 0) {
4416  found_keyframe_after_edit = 1;
4417  continue;
4418  }
4419  if (ctts_sample_old != 0) {
4420  if (add_ctts_entry(&msc->ctts_data, &msc->ctts_count,
4421  &msc->ctts_allocated_size,
4422  ctts_sample_old - edit_list_start_ctts_sample,
4423  ctts_data_old[ctts_index_old].duration) == -1) {
4424  av_log(mov->fc, AV_LOG_ERROR, "Cannot add CTTS entry %"PRId64" - {%"PRId64", %d}\n",
4425  ctts_index_old, ctts_sample_old - edit_list_start_ctts_sample,
4426  ctts_data_old[ctts_index_old].duration);
4427  break;
4428  }
4429  }
4430  }
4431  break;
4432  }
4433  }
4434  }
4435  // If there are empty edits, then msc->min_corrected_pts might be positive
4436  // intentionally. So we subtract the sum duration of emtpy edits here.
4437  msc->min_corrected_pts -= empty_edits_sum_duration;
4438 
4439  // If the minimum pts turns out to be greater than zero after fixing the index, then we subtract the
4440  // dts by that amount to make the first pts zero.
4441  if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
4442  if (msc->min_corrected_pts > 0) {
4443  av_log(mov->fc, AV_LOG_DEBUG, "Offset DTS by %"PRId64" to make first pts zero.\n", msc->min_corrected_pts);
4444  for (int i = 0; i < sti->nb_index_entries; ++i)
4446  }
4447  }
4448  // Start time should be equal to zero or the duration of any empty edits.
4449  st->start_time = empty_edits_sum_duration;
4450 
4451  // Update av stream length, if it ends up shorter than the track's media duration
4452  st->duration = FFMIN(st->duration, edit_list_dts_entry_end - start_dts);
4453  msc->start_pad = sti->skip_samples;
4454 
4455  // Free the old index and the old CTTS structures
4456  av_free(e_old);
4457  av_free(ctts_data_old);
4458  av_freep(&frame_duration_buffer);
4459 
4460  // Null terminate the index ranges array
4461  current_index_range = current_index_range ? current_index_range + 1
4462  : msc->index_ranges;
4463  current_index_range->start = 0;
4464  current_index_range->end = 0;
4465  msc->current_index = msc->index_ranges[0].start;
4466 }
4467 
4468 static uint32_t get_sgpd_sync_index(const MOVStreamContext *sc, int nal_unit_type)
4469 {
4470  for (uint32_t i = 0; i < sc->sgpd_sync_count; i++)
4471  if (sc->sgpd_sync[i] == HEVC_NAL_CRA_NUT)
4472  return i + 1;
4473  return 0;
4474 }
4475 
4477 {
4478  int k;
4479  int sample_id = 0;
4480  uint32_t cra_index;
4481  MOVStreamContext *sc = st->priv_data;
4482 
4483  if (st->codecpar->codec_id != AV_CODEC_ID_HEVC || !sc->sync_group_count)
4484  return 0;
4485 
4486  /* Build an unrolled index of the samples */
4487  sc->sample_offsets_count = 0;
4488  for (uint32_t i = 0; i < sc->ctts_count; i++) {
4489  if (sc->ctts_data[i].count > INT_MAX - sc->sample_offsets_count)
4490  return AVERROR(ENOMEM);
4491  sc->sample_offsets_count += sc->ctts_data[i].count;
4492  }
4493  av_freep(&sc->sample_offsets);
4495  if (!sc->sample_offsets)
4496  return AVERROR(ENOMEM);
4497  k = 0;
4498  for (uint32_t i = 0; i < sc->ctts_count; i++)
4499  for (int j = 0; j < sc->ctts_data[i].count; j++)
4500  sc->sample_offsets[k++] = sc->ctts_data[i].duration;
4501 
4502  /* The following HEVC NAL type reveal the use of open GOP sync points
4503  * (TODO: BLA types may also be concerned) */
4504  cra_index = get_sgpd_sync_index(sc, HEVC_NAL_CRA_NUT); /* Clean Random Access */
4505  if (!cra_index)
4506  return 0;
4507 
4508  /* Build a list of open-GOP key samples */
4509  sc->open_key_samples_count = 0;
4510  for (uint32_t i = 0; i < sc->sync_group_count; i++)
4511  if (sc->sync_group[i].index == cra_index) {
4512  if (sc->sync_group[i].count > INT_MAX - sc->open_key_samples_count)
4513  return AVERROR(ENOMEM);
4515  }
4516  av_freep(&sc->open_key_samples);
4518  if (!sc->open_key_samples)
4519  return AVERROR(ENOMEM);
4520  k = 0;
4521  for (uint32_t i = 0; i < sc->sync_group_count; i++) {
4522  const MOVSbgp *sg = &sc->sync_group[i];
4523  if (sg->index == cra_index)
4524  for (uint32_t j = 0; j < sg->count; j++)
4525  sc->open_key_samples[k++] = sample_id;
4526  if (sg->count > INT_MAX - sample_id)
4527  return AVERROR_PATCHWELCOME;
4528  sample_id += sg->count;
4529  }
4530 
4531  /* Identify the minimal time step between samples */
4532  sc->min_sample_duration = UINT_MAX;
4533  for (uint32_t i = 0; i < sc->stts_count; i++)
4535 
4536  return 0;
4537 }
4538 
4539 static void mov_build_index(MOVContext *mov, AVStream *st)
4540 {
4541  MOVStreamContext *sc = st->priv_data;
4542  FFStream *const sti = ffstream(st);
4543  int64_t current_offset;
4544  int64_t current_dts = 0;
4545  unsigned int stts_index = 0;
4546  unsigned int stsc_index = 0;
4547  unsigned int stss_index = 0;
4548  unsigned int stps_index = 0;
4549  unsigned int i, j;
4550  uint64_t stream_size = 0;
4551  MOVCtts *ctts_data_old = sc->ctts_data;
4552  unsigned int ctts_count_old = sc->ctts_count;
4553 
4554  int ret = build_open_gop_key_points(st);
4555  if (ret < 0)
4556  return;
4557 
4558  if (sc->elst_count) {
4559  int i, edit_start_index = 0, multiple_edits = 0;
4560  int64_t empty_duration = 0; // empty duration of the first edit list entry
4561  int64_t start_time = 0; // start time of the media
4562 
4563  for (i = 0; i < sc->elst_count; i++) {
4564  const MOVElst *e = &sc->elst_data[i];
4565  if (i == 0 && e->time == -1) {
4566  /* if empty, the first entry is the start time of the stream
4567  * relative to the presentation itself */
4568  empty_duration = e->duration;
4569  edit_start_index = 1;
4570  } else if (i == edit_start_index && e->time >= 0) {
4571  start_time = e->time;
4572  } else {
4573  multiple_edits = 1;
4574  }
4575  }
4576 
4577  if (multiple_edits && !mov->advanced_editlist) {
4579  av_log(mov->fc, AV_LOG_WARNING, "multiple edit list entries, "
4580  "not supported in fragmented MP4 files\n");
4581  else
4582  av_log(mov->fc, AV_LOG_WARNING, "multiple edit list entries, "
4583  "Use -advanced_editlist to correctly decode otherwise "
4584  "a/v desync might occur\n");
4585  }
4586 
4587  /* adjust first dts according to edit list */
4588  if ((empty_duration || start_time) && mov->time_scale > 0) {
4589  if (empty_duration)
4590  empty_duration = av_rescale(empty_duration, sc->time_scale, mov->time_scale);
4591 
4592  if (av_sat_sub64(start_time, empty_duration) != start_time - (uint64_t)empty_duration)
4593  av_log(mov->fc, AV_LOG_WARNING, "start_time - empty_duration is not representable\n");
4594 
4595  sc->time_offset = start_time - (uint64_t)empty_duration;
4597  if (!mov->advanced_editlist)
4598  current_dts = -sc->time_offset;
4599  }
4600 
4601  if (!multiple_edits && !mov->advanced_editlist &&
4603  sc->start_pad = start_time;
4604  }
4605 
4606  /* only use old uncompressed audio chunk demuxing when stts specifies it */
4607  if (!(st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
4608  sc->stts_count == 1 && sc->stts_data[0].duration == 1)) {
4609  unsigned int current_sample = 0;
4610  unsigned int stts_sample = 0;
4611  unsigned int sample_size;
4612  unsigned int distance = 0;
4613  unsigned int rap_group_index = 0;
4614  unsigned int rap_group_sample = 0;
4615  int rap_group_present = sc->rap_group_count && sc->rap_group;
4616  int key_off = (sc->keyframe_count && sc->keyframes[0] > 0) || (sc->stps_count && sc->stps_data[0] > 0);
4617 
4618  current_dts -= sc->dts_shift;
4619 
4620  if (!sc->sample_count || sti->nb_index_entries)
4621  return;
4622  if (sc->sample_count >= UINT_MAX / sizeof(*sti->index_entries) - sti->nb_index_entries)
4623  return;
4624  if (av_reallocp_array(&sti->index_entries,
4625  sti->nb_index_entries + sc->sample_count,
4626  sizeof(*sti->index_entries)) < 0) {
4627  sti->nb_index_entries = 0;
4628  return;
4629  }
4630  sti->index_entries_allocated_size = (sti->nb_index_entries + sc->sample_count) * sizeof(*sti->index_entries);
4631 
4632  if (ctts_data_old) {
4633  // Expand ctts entries such that we have a 1-1 mapping with samples
4634  if (sc->sample_count >= UINT_MAX / sizeof(*sc->ctts_data))
4635  return;
4636  sc->ctts_count = 0;
4637  sc->ctts_allocated_size = 0;
4639  sc->sample_count * sizeof(*sc->ctts_data));
4640  if (!sc->ctts_data) {
4641  av_free(ctts_data_old);
4642  return;
4643  }
4644 
4645  memset((uint8_t*)(sc->ctts_data), 0, sc->ctts_allocated_size);
4646 
4647  for (i = 0; i < ctts_count_old &&
4648  sc->ctts_count < sc->sample_count; i++)
4649  for (j = 0; j < ctts_data_old[i].count &&
4650  sc->ctts_count < sc->sample_count; j++)
4651  add_ctts_entry(&sc->ctts_data, &sc->ctts_count,
4652  &sc->ctts_allocated_size, 1,
4653  ctts_data_old[i].duration);
4654  av_free(ctts_data_old);
4655  }
4656 
4657  for (i = 0; i < sc->chunk_count; i++) {
4658  int64_t next_offset = i+1 < sc->chunk_count ? sc->chunk_offsets[i+1] : INT64_MAX;
4659  current_offset = sc->chunk_offsets[i];
4660  while (mov_stsc_index_valid(stsc_index, sc->stsc_count) &&
4661  i + 1 == sc->stsc_data[stsc_index + 1].first)
4662  stsc_index++;
4663 
4664  if (next_offset > current_offset && sc->sample_size>0 && sc->sample_size < sc->stsz_sample_size &&
4665  sc->stsc_data[stsc_index].count * (int64_t)sc->stsz_sample_size > next_offset - current_offset) {
4666  av_log(mov->fc, AV_LOG_WARNING, "STSZ sample size %d invalid (too large), ignoring\n", sc->stsz_sample_size);
4667  sc->stsz_sample_size = sc->sample_size;
4668  }
4669  if (sc->stsz_sample_size>0 && sc->stsz_sample_size < sc->sample_size) {
4670  av_log(mov->fc, AV_LOG_WARNING, "STSZ sample size %d invalid (too small), ignoring\n", sc->stsz_sample_size);
4671  sc->stsz_sample_size = sc->sample_size;
4672  }
4673 
4674  for (j = 0; j < sc->stsc_data[stsc_index].count; j++) {
4675  int keyframe = 0;
4676  if (current_sample >= sc->sample_count) {
4677  av_log(mov->fc, AV_LOG_ERROR, "wrong sample count\n");
4678  return;
4679  }
4680 
4681  if (!sc->keyframe_absent && (!sc->keyframe_count || current_sample+key_off == sc->keyframes[stss_index])) {
4682  keyframe = 1;
4683  if (stss_index + 1 < sc->keyframe_count)
4684  stss_index++;
4685  } else if (sc->stps_count && current_sample+key_off == sc->stps_data[stps_index]) {
4686  keyframe = 1;
4687  if (stps_index + 1 < sc->stps_count)
4688  stps_index++;
4689  }
4690  if (rap_group_present && rap_group_index < sc->rap_group_count) {
4691  if (sc->rap_group[rap_group_index].index > 0)
4692  keyframe = 1;
4693  if (++rap_group_sample == sc->rap_group[rap_group_index].count) {
4694  rap_group_sample = 0;
4695  rap_group_index++;
4696  }
4697  }
4698  if (sc->keyframe_absent
4699  && !sc->stps_count
4700  && !rap_group_present
4701  && (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO || (i==0 && j==0)))
4702  keyframe = 1;
4703  if (keyframe)
4704  distance = 0;
4705  sample_size = sc->stsz_sample_size > 0 ? sc->stsz_sample_size : sc->sample_sizes[current_sample];
4706  if (current_offset > INT64_MAX - sample_size) {
4707  av_log(mov->fc, AV_LOG_ERROR, "Current offset %"PRId64" or sample size %u is too large\n",
4708  current_offset,
4709  sample_size);
4710  return;
4711  }
4712 
4713  if (sc->pseudo_stream_id == -1 ||
4714  sc->stsc_data[stsc_index].id - 1 == sc->pseudo_stream_id) {
4715  AVIndexEntry *e;
4716  if (sample_size > 0x3FFFFFFF) {
4717  av_log(mov->fc, AV_LOG_ERROR, "Sample size %u is too large\n", sample_size);
4718  return;
4719  }
4720  e = &sti->index_entries[sti->nb_index_entries++];
4721  e->pos = current_offset;
4722  e->timestamp = current_dts;
4723  e->size = sample_size;
4724  e->min_distance = distance;
4725  e->flags = keyframe ? AVINDEX_KEYFRAME : 0;
4726  av_log(mov->fc, AV_LOG_TRACE, "AVIndex stream %d, sample %u, offset %"PRIx64", dts %"PRId64", "
4727  "size %u, distance %u, keyframe %d\n", st->index, current_sample,
4728  current_offset, current_dts, sample_size, distance, keyframe);
4729  if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && sti->nb_index_entries < 100)
4730  ff_rfps_add_frame(mov->fc, st, current_dts);
4731  }
4732 
4733  current_offset += sample_size;
4734  stream_size += sample_size;
4735 
4736  current_dts += sc->stts_data[stts_index].duration;
4737 
4738  distance++;
4739  stts_sample++;
4740  current_sample++;
4741  if (stts_index + 1 < sc->stts_count && stts_sample == sc->stts_data[stts_index].count) {
4742  stts_sample = 0;
4743  stts_index++;
4744  }
4745  }
4746  }
4747  if (st->duration > 0)
4748  st->codecpar->bit_rate = stream_size*8*sc->time_scale/st->duration;
4749  } else {
4750  unsigned chunk_samples, total = 0;
4751 
4752  if (!sc->chunk_count)
4753  return;
4754 
4755  // compute total chunk count
4756  for (i = 0; i < sc->stsc_count; i++) {
4757  unsigned count, chunk_count;
4758 
4759  chunk_samples = sc->stsc_data[i].count;
4760  if (i != sc->stsc_count - 1 &&
4761  sc->samples_per_frame && chunk_samples % sc->samples_per_frame) {
4762  av_log(mov->fc, AV_LOG_ERROR, "error unaligned chunk\n");
4763  return;
4764  }
4765 
4766  if (sc->samples_per_frame >= 160) { // gsm
4767  count = chunk_samples / sc->samples_per_frame;
4768  } else if (sc->samples_per_frame > 1) {
4769  unsigned samples = (1024/sc->samples_per_frame)*sc->samples_per_frame;
4770  count = (chunk_samples+samples-1) / samples;
4771  } else {
4772  count = (chunk_samples+1023) / 1024;
4773  }
4774 
4775  if (mov_stsc_index_valid(i, sc->stsc_count))
4776  chunk_count = sc->stsc_data[i+1].first - sc->stsc_data[i].first;
4777  else
4778  chunk_count = sc->chunk_count - (sc->stsc_data[i].first - 1);
4779  total += chunk_count * count;
4780  }
4781 
4782  av_log(mov->fc, AV_LOG_TRACE, "chunk count %u\n", total);
4783  if (total >= UINT_MAX / sizeof(*sti->index_entries) - sti->nb_index_entries)
4784  return;
4785  if (av_reallocp_array(&sti->index_entries,
4786  sti->nb_index_entries + total,
4787  sizeof(*sti->index_entries)) < 0) {
4788  sti->nb_index_entries = 0;
4789  return;
4790  }
4791  sti->index_entries_allocated_size = (sti->nb_index_entries + total) * sizeof(*sti->index_entries);
4792 
4793  // populate index
4794  for (i = 0; i < sc->chunk_count; i++) {
4795  current_offset = sc->chunk_offsets[i];
4796  if (mov_stsc_index_valid(stsc_index, sc->stsc_count) &&
4797  i + 1 == sc->stsc_data[stsc_index + 1].first)
4798  stsc_index++;
4799  chunk_samples = sc->stsc_data[stsc_index].count;
4800 
4801  while (chunk_samples > 0) {
4802  AVIndexEntry *e;
4803  unsigned size, samples;
4804 
4805  if (sc->samples_per_frame > 1 && !sc->bytes_per_frame) {
4807  "Zero bytes per frame, but %d samples per frame",
4808  sc->samples_per_frame);
4809  return;
4810  }
4811 
4812  if (sc->samples_per_frame >= 160) { // gsm
4813  samples = sc->samples_per_frame;
4814  size = sc->bytes_per_frame;
4815  } else {
4816  if (sc->samples_per_frame > 1) {
4817  samples = FFMIN((1024 / sc->samples_per_frame)*
4818  sc->samples_per_frame, chunk_samples);
4820  } else {
4821  samples = FFMIN(1024, chunk_samples);
4822  size = samples * sc->sample_size;
4823  }
4824  }
4825 
4826  if (sti->nb_index_entries >= total) {
4827  av_log(mov->fc, AV_LOG_ERROR, "wrong chunk count %u\n", total);
4828  return;
4829  }
4830  if (size > 0x3FFFFFFF) {
4831  av_log(mov->fc, AV_LOG_ERROR, "Sample size %u is too large\n", size);
4832  return;
4833  }
4834  e = &sti->index_entries[sti->nb_index_entries++];
4835  e->pos = current_offset;
4836  e->timestamp = current_dts;
4837  e->size = size;
4838  e->min_distance = 0;
4839  e->flags = AVINDEX_KEYFRAME;
4840  av_log(mov->fc, AV_LOG_TRACE, "AVIndex stream %d, chunk %u, offset %"PRIx64", dts %"PRId64", "
4841  "size %u, duration %u\n", st->index, i, current_offset, current_dts,
4842  size, samples);
4843 
4844  current_offset += size;
4845  current_dts += samples;
4846  chunk_samples -= samples;
4847  }
4848  }
4849  }
4850 
4851  if (!mov->ignore_editlist && mov->advanced_editlist) {
4852  // Fix index according to edit lists.
4853  mov_fix_index(mov, st);
4854  }
4855 
4856  // Update start time of the stream.
4858  st->start_time = sti->index_entries[0].timestamp + sc->dts_shift;
4859  if (sc->ctts_data) {
4860  st->start_time += sc->ctts_data[0].duration;
4861  }
4862  }
4863 
4864  mov_estimate_video_delay(mov, st);
4865 }
4866 
4867 static int test_same_origin(const char *src, const char *ref) {
4868  char src_proto[64];
4869  char ref_proto[64];
4870  char src_auth[256];
4871  char ref_auth[256];
4872  char src_host[256];
4873  char ref_host[256];
4874  int src_port=-1;
4875  int ref_port=-1;
4876 
4877  av_url_split(src_proto, sizeof(src_proto), src_auth, sizeof(src_auth), src_host, sizeof(src_host), &src_port, NULL, 0, src);
4878  av_url_split(ref_proto, sizeof(ref_proto), ref_auth, sizeof(ref_auth), ref_host, sizeof(ref_host), &ref_port, NULL, 0, ref);
4879 
4880  if (strlen(src) == 0) {
4881  return -1;
4882  } else if (strlen(src_auth) + 1 >= sizeof(src_auth) ||
4883  strlen(ref_auth) + 1 >= sizeof(ref_auth) ||
4884  strlen(src_host) + 1 >= sizeof(src_host) ||
4885  strlen(ref_host) + 1 >= sizeof(ref_host)) {
4886  return 0;
4887  } else if (strcmp(src_proto, ref_proto) ||
4888  strcmp(src_auth, ref_auth) ||
4889  strcmp(src_host, ref_host) ||
4890  src_port != ref_port) {
4891  return 0;
4892  } else
4893  return 1;
4894 }
4895 
4896 static int mov_open_dref(MOVContext *c, AVIOContext **pb, const char *src, MOVDref *ref)
4897 {
4898  /* try relative path, we do not try the absolute because it can leak information about our
4899  system to an attacker */
4900  if (ref->nlvl_to > 0 && ref->nlvl_from > 0) {
4901  char filename[1025];
4902  const char *src_path;
4903  int i, l;
4904 
4905  /* find a source dir */
4906  src_path = strrchr(src, '/');
4907  if (src_path)
4908  src_path++;
4909  else
4910  src_path = src;
4911 
4912  /* find a next level down to target */
4913  for (i = 0, l = strlen(ref->path) - 1; l >= 0; l--)
4914  if (ref->path[l] == '/') {
4915  if (i == ref->nlvl_to - 1)
4916  break;
4917  else
4918  i++;
4919  }
4920 
4921  /* compose filename if next level down to target was found */
4922  if (i == ref->nlvl_to - 1 && src_path - src < sizeof(filename)) {
4923  memcpy(filename, src, src_path - src);
4924  filename[src_path - src] = 0;
4925 
4926  for (i = 1; i < ref->nlvl_from; i++)
4927  av_strlcat(filename, "../", sizeof(filename));
4928 
4929  av_strlcat(filename, ref->path + l + 1, sizeof(filename));
4930  if (!c->use_absolute_path) {
4931  int same_origin = test_same_origin(src, filename);
4932 
4933  if (!same_origin) {
4934  av_log(c->fc, AV_LOG_ERROR,
4935  "Reference with mismatching origin, %s not tried for security reasons, "
4936  "set demuxer option use_absolute_path to allow it anyway\n",
4937  ref->path);
4938  return AVERROR(ENOENT);
4939  }
4940 
4941  if (strstr(ref->path + l + 1, "..") ||
4942  strstr(ref->path + l + 1, ":") ||
4943  (ref->nlvl_from > 1 && same_origin < 0) ||
4944  (filename[0] == '/' && src_path == src))
4945  return AVERROR(ENOENT);
4946  }
4947 
4948  if (strlen(filename) + 1 == sizeof(filename))
4949  return AVERROR(ENOENT);
4950  if (!c->fc->io_open(c->fc, pb, filename, AVIO_FLAG_READ, NULL))
4951  return 0;
4952  }
4953  } else if (c->use_absolute_path) {
4954  av_log(c->fc, AV_LOG_WARNING, "Using absolute path on user request, "
4955  "this is a possible security issue\n");
4956  if (!c->fc->io_open(c->fc, pb, ref->path, AVIO_FLAG_READ, NULL))
4957  return 0;
4958  } else {
4959  av_log(c->fc, AV_LOG_ERROR,
4960  "Absolute path %s not tried for security reasons, "
4961  "set demuxer option use_absolute_path to allow absolute paths\n",
4962  ref->path);
4963  }
4964 
4965  return AVERROR(ENOENT);
4966 }
4967 
4969 {
4970  if (sc->time_scale <= 0) {
4971  av_log(c->fc, AV_LOG_WARNING, "stream %d, timescale not set\n", sc->ffindex);
4972  sc->time_scale = c->time_scale;
4973  if (sc->time_scale <= 0)
4974  sc->time_scale = 1;
4975  }
4976 }
4977 
4978 #if CONFIG_IAMFDEC
4979 static int mov_update_iamf_streams(MOVContext *c, const AVStream *st)
4980 {
4981  const MOVStreamContext *sc = st->priv_data;
4982  const IAMFContext *iamf = &sc->iamf->iamf;
4983 
4984  for (int i = 0; i < iamf->nb_audio_elements; i++) {
4985  const AVStreamGroup *stg = NULL;
4986 
4987  for (int j = 0; j < c->fc->nb_stream_groups; j++)
4988  if (c->fc->stream_groups[j]->id == iamf->audio_elements[i]->audio_element_id)
4989  stg = c->fc->stream_groups[j];
4990  av_assert0(stg);
4991 
4992  for (int j = 0; j < stg->nb_streams; j++) {
4993  const FFStream *sti = cffstream(st);
4994  AVStream *out = stg->streams[j];
4995  FFStream *out_sti = ffstream(stg->streams[j]);
4996 
4997  out->codecpar->bit_rate = 0;
4998 
4999  if (out == st)
5000  continue;
5001 
5002  out->time_base = st->time_base;
5003  out->start_time = st->start_time;
5004  out->duration = st->duration;
5005  out->nb_frames = st->nb_frames;
5006  out->discard = st->discard;
5007 
5008  av_assert0(!out_sti->index_entries);
5010  if (!out_sti->index_entries)
5011  return AVERROR(ENOMEM);
5012 
5014  out_sti->nb_index_entries = sti->nb_index_entries;
5015  out_sti->skip_samples = sti->skip_samples;
5016  memcpy(out_sti->index_entries, sti->index_entries, sti->index_entries_allocated_size);
5017  }
5018  }
5019 
5020  return 0;
5021 }
5022 #endif
5023 
5024 static int sanity_checks(void *log_obj, MOVStreamContext *sc, int index)
5025 {
5026  if ((sc->chunk_count && (!sc->stts_count || !sc->stsc_count ||
5027  (!sc->sample_size && !sc->sample_count))) ||
5028  (!sc->chunk_count && sc->sample_count)) {
5029  av_log(log_obj, AV_LOG_ERROR, "stream %d, missing mandatory atoms, broken header\n",
5030  index);
5031  return 1;
5032  }
5033 
5034  if (sc->stsc_count && sc->stsc_data[ sc->stsc_count - 1 ].first > sc->chunk_count) {
5035  av_log(log_obj, AV_LOG_ERROR, "stream %d, contradictionary STSC and STCO\n",
5036  index);
5037  return 2;
5038  }
5039  return 0;
5040 }
5041 
5043 {
5044  AVStream *st;
5045  MOVStreamContext *sc;
5046  int ret;
5047 
5048  st = avformat_new_stream(c->fc, NULL);
5049  if (!st) return AVERROR(ENOMEM);
5050  st->id = -1;
5051  sc = av_mallocz(sizeof(MOVStreamContext));
5052  if (!sc) return AVERROR(ENOMEM);
5053 
5054  st->priv_data = sc;
5056  sc->ffindex = st->index;
5057  c->trak_index = st->index;
5058  sc->tref_flags = 0;
5059  sc->tref_id = -1;
5060  sc->refcount = 1;
5061 
5062  if ((ret = mov_read_default(c, pb, atom)) < 0)
5063  return ret;
5064 
5065  c->trak_index = -1;
5066 
5067  // Here stsc refers to a chunk not described in stco. This is technically invalid,
5068  // but we can overlook it (clearing stsc) whenever stts_count == 0 (indicating no samples).
5069  if (!sc->chunk_count && !sc->stts_count && sc->stsc_count) {
5070  sc->stsc_count = 0;
5071  av_freep(&sc->stsc_data);
5072  }
5073 
5074  ret = sanity_checks(c->fc, sc, st->index);
5075  if (ret)
5076  return ret > 1 ? AVERROR_INVALIDDATA : 0;
5077 
5078  fix_timescale(c, sc);
5079 
5080  avpriv_set_pts_info(st, 64, 1, sc->time_scale);
5081 
5082  /*
5083  * Advanced edit list support does not work with fragemented MP4s, which
5084  * have stsc, stsz, stco, and stts with zero entries in the moov atom.
5085  * In these files, trun atoms may be streamed in.
5086  */
5087  if (!sc->stts_count && c->advanced_editlist) {
5088 
5089  av_log(c->fc, AV_LOG_VERBOSE, "advanced_editlist does not work with fragmented "
5090  "MP4. disabling.\n");
5091  c->advanced_editlist = 0;
5092  c->advanced_editlist_autodisabled = 1;
5093  }
5094 
5095  mov_build_index(c, st);
5096 
5097 #if CONFIG_IAMFDEC
5098  if (sc->iamf) {
5099  ret = mov_update_iamf_streams(c, st);
5100  if (ret < 0)
5101  return ret;
5102  }
5103 #endif
5104 
5105  if (sc->dref_id-1 < sc->drefs_count && sc->drefs[sc->dref_id-1].path) {
5106  MOVDref *dref = &sc->drefs[sc->dref_id - 1];
5107  if (c->enable_drefs) {
5108  if (mov_open_dref(c, &sc->pb, c->fc->url, dref) < 0)
5109  av_log(c->fc, AV_LOG_ERROR,
5110  "stream %d, error opening alias: path='%s', dir='%s', "
5111  "filename='%s', volume='%s', nlvl_from=%d, nlvl_to=%d\n",
5112  st->index, dref->path, dref->dir, dref->filename,
5113  dref->volume, dref->nlvl_from, dref->nlvl_to);
5114  } else {
5115  av_log(c->fc, AV_LOG_WARNING,
5116  "Skipped opening external track: "
5117  "stream %d, alias: path='%s', dir='%s', "
5118  "filename='%s', volume='%s', nlvl_from=%d, nlvl_to=%d."
5119  "Set enable_drefs to allow this.\n",
5120  st->index, dref->path, dref->dir, dref->filename,
5121  dref->volume, dref->nlvl_from, dref->nlvl_to);
5122  }
5123  } else {
5124  sc->pb = c->fc->pb;
5125  sc->pb_is_copied = 1;
5126  }
5127 
5128  if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
5129  if (sc->h_spacing && sc->v_spacing)
5131  sc->h_spacing, sc->v_spacing, INT_MAX);
5132  if (!st->sample_aspect_ratio.num && st->codecpar->width && st->codecpar->height &&
5133  sc->height && sc->width &&
5134  (st->codecpar->width != sc->width || st->codecpar->height != sc->height)) {
5136  (int64_t)st->codecpar->height * sc->width,
5137  (int64_t)st->codecpar->width * sc->height, INT_MAX);
5138  }
5139 
5140 #if FF_API_R_FRAME_RATE
5141  if (sc->stts_count == 1 || (sc->stts_count == 2 && sc->stts_data[1].count == 1))
5143  sc->time_scale, sc->stts_data[0].duration, INT_MAX);
5144 #endif
5145  }
5146 
5147  // done for ai5q, ai52, ai55, ai1q, ai12 and ai15.
5148  if (!st->codecpar->extradata_size && st->codecpar->codec_id == AV_CODEC_ID_H264 &&
5149  TAG_IS_AVCI(st->codecpar->codec_tag)) {
5151  if (ret < 0)
5152  return ret;
5153  }
5154 
5155  switch (st->codecpar->codec_id) {
5156 #if CONFIG_H261_DECODER
5157  case AV_CODEC_ID_H261:
5158 #endif
5159 #if CONFIG_H263_DECODER
5160  case AV_CODEC_ID_H263:
5161 #endif
5162 #if CONFIG_MPEG4_DECODER
5163  case AV_CODEC_ID_MPEG4:
5164 #endif
5165  st->codecpar->width = 0; /* let decoder init width/height */
5166  st->codecpar->height= 0;
5167  break;
5168  }
5169 
5170  // If the duration of the mp3 packets is not constant, then they could need a parser
5171  if (st->codecpar->codec_id == AV_CODEC_ID_MP3
5172  && sc->stts_count > 3
5173  && sc->stts_count*10 > st->nb_frames
5174  && sc->time_scale == st->codecpar->sample_rate) {
5176  }
5177  /* Do not need those anymore. */
5178  av_freep(&sc->chunk_offsets);
5179  av_freep(&sc->sample_sizes);
5180  av_freep(&sc->keyframes);
5181  av_freep(&sc->stts_data);
5182  av_freep(&sc->stps_data);
5183  av_freep(&sc->elst_data);
5184  av_freep(&sc->rap_group);
5185  av_freep(&sc->sync_group);
5186  av_freep(&sc->sgpd_sync);
5187 
5188  return 0;
5189 }
5190 
5192 {
5193  int ret;
5194  c->itunes_metadata = 1;
5195  ret = mov_read_default(c, pb, atom);
5196  c->itunes_metadata = 0;
5197  return ret;
5198 }
5199 
5201 {
5202  uint32_t count;
5203  uint32_t i;
5204 
5205  if (atom.size < 8)
5206  return 0;
5207 
5208  avio_skip(pb, 4);
5209  count = avio_rb32(pb);
5210  atom.size -= 8;
5211  if (count >= UINT_MAX / sizeof(*c->meta_keys)) {
5212  av_log(c->fc, AV_LOG_ERROR,
5213  "The 'keys' atom with the invalid key count: %"PRIu32"\n", count);
5214  return AVERROR_INVALIDDATA;
5215  }
5216 
5217  c->meta_keys_count = count + 1;
5218  c->meta_keys = av_mallocz(c->meta_keys_count * sizeof(*c->meta_keys));
5219  if (!c->meta_keys)
5220  return AVERROR(ENOMEM);
5221 
5222  for (i = 1; i <= count; ++i) {
5223  uint32_t key_size = avio_rb32(pb);
5224  uint32_t type = avio_rl32(pb);
5225  if (key_size < 8 || key_size > atom.size) {
5226  av_log(c->fc, AV_LOG_ERROR,
5227  "The key# %"PRIu32" in meta has invalid size:"
5228  "%"PRIu32"\n", i, key_size);
5229  return AVERROR_INVALIDDATA;
5230  }
5231  atom.size -= key_size;
5232  key_size -= 8;
5233  if (type != MKTAG('m','d','t','a')) {
5234  avio_skip(pb, key_size);
5235  continue;
5236  }
5237  c->meta_keys[i] = av_mallocz(key_size + 1);
5238  if (!c->meta_keys[i])
5239  return AVERROR(ENOMEM);
5240  avio_read(pb, c->meta_keys[i], key_size);
5241  }
5242 
5243  return 0;
5244 }
5245 
5247 {
5248  int64_t end = av_sat_add64(avio_tell(pb), atom.size);
5249  uint8_t *key = NULL, *val = NULL, *mean = NULL;
5250  int i;
5251  int ret = 0;
5252  AVStream *st;
5253  MOVStreamContext *sc;
5254 
5255  if (c->fc->nb_streams < 1)
5256  return 0;
5257  st = c->fc->streams[c->fc->nb_streams-1];
5258  sc = st->priv_data;
5259 
5260  for (i = 0; i < 3; i++) {
5261  uint8_t **p;
5262  uint32_t len, tag;
5263 
5264  if (end - avio_tell(pb) <= 12)
5265  break;
5266 
5267  len = avio_rb32(pb);
5268  tag = avio_rl32(pb);
5269  avio_skip(pb, 4); // flags
5270 
5271  if (len < 12 || len - 12 > end - avio_tell(pb))
5272  break;
5273  len -= 12;
5274 
5275  if (tag == MKTAG('m', 'e', 'a', 'n'))
5276  p = &mean;
5277  else if (tag == MKTAG('n', 'a', 'm', 'e'))
5278  p = &key;
5279  else if (tag == MKTAG('d', 'a', 't', 'a') && len > 4) {
5280  avio_skip(pb, 4);
5281  len -= 4;
5282  p = &val;
5283  } else
5284  break;
5285 
5286  if (*p)
5287  break;
5288 
5289  *p = av_malloc(len + 1);
5290  if (!*p) {
5291  ret = AVERROR(ENOMEM);
5292  break;
5293  }
5294  ret = ffio_read_size(pb, *p, len);
5295  if (ret < 0) {
5296  av_freep(p);
5297  break;
5298  }
5299  (*p)[len] = 0;
5300  }
5301 
5302  if (mean && key && val) {
5303  if (strcmp(key, "iTunSMPB") == 0) {
5304  int priming, remainder, samples;
5305  if(sscanf(val, "%*X %X %X %X", &priming, &remainder, &samples) == 3){
5306  if(priming>0 && priming<16384)
5307  sc->start_pad = priming;
5308  }
5309  }
5310  if (strcmp(key, "cdec") != 0) {
5311  av_dict_set(&c->fc->metadata, key, val,
5313  key = val = NULL;
5314  }
5315  } else {
5316  av_log(c->fc, AV_LOG_VERBOSE,
5317  "Unhandled or malformed custom metadata of size %"PRId64"\n", atom.size);
5318  }
5319 
5320  avio_seek(pb, end, SEEK_SET);
5321  av_freep(&key);
5322  av_freep(&val);
5323  av_freep(&mean);
5324  return ret;
5325 }
5326 
5328 {
5329  MOVStreamContext *sc;
5330  AVStream *st;
5331 
5332  st = avformat_new_stream(c->fc, NULL);
5333  if (!st)
5334  return AVERROR(ENOMEM);
5335  sc = av_mallocz(sizeof(MOVStreamContext));
5336  if (!sc)
5337  return AVERROR(ENOMEM);
5338 
5339  item->st = st;
5340  st->id = item->item_id;
5341  st->priv_data = sc;
5343  st->codecpar->codec_id = mov_codec_id(st, item->type);
5344  sc->id = st->id;
5345  sc->ffindex = st->index;
5346  st->avg_frame_rate.num = st->avg_frame_rate.den = 1;
5347  st->time_base.num = st->time_base.den = 1;
5348  st->nb_frames = 1;
5349  sc->time_scale = 1;
5350  sc->pb = c->fc->pb;
5351  sc->pb_is_copied = 1;
5352  sc->refcount = 1;
5353 
5354  if (item->name)
5355  av_dict_set(&st->metadata, "title", item->name, 0);
5356 
5357  // Populate the necessary fields used by mov_build_index.
5358  sc->stsc_count = 1;
5359  sc->stsc_data = av_malloc_array(1, sizeof(*sc->stsc_data));
5360  if (!sc->stsc_data)
5361  return AVERROR(ENOMEM);
5362  sc->stsc_data[0].first = 1;
5363  sc->stsc_data[0].count = 1;
5364  sc->stsc_data[0].id = 1;
5365  sc->chunk_count = 1;
5366  sc->chunk_offsets = av_malloc_array(1, sizeof(*sc->chunk_offsets));
5367  if (!sc->chunk_offsets)
5368  return AVERROR(ENOMEM);
5369  sc->sample_count = 1;
5370  sc->sample_sizes = av_malloc_array(1, sizeof(*sc->sample_sizes));
5371  if (!sc->sample_sizes)
5372  return AVERROR(ENOMEM);
5373  sc->stts_count = 1;
5374  sc->stts_data = av_malloc_array(1, sizeof(*sc->stts_data));
5375  if (!sc->stts_data)
5376  return AVERROR(ENOMEM);
5377  sc->stts_data[0].count = 1;
5378  // Not used for still images. But needed by mov_build_index.
5379  sc->stts_data[0].duration = 0;
5380 
5381  return 0;
5382 }
5383 
5385 {
5386  while (atom.size > 8) {
5387  uint32_t tag;
5388  if (avio_feof(pb))
5389  return AVERROR_EOF;
5390  tag = avio_rl32(pb);
5391  atom.size -= 4;
5392  if (tag == MKTAG('h','d','l','r')) {
5393  avio_seek(pb, -8, SEEK_CUR);
5394  atom.size += 8;
5395  return mov_read_default(c, pb, atom);
5396  }
5397  }
5398  return 0;
5399 }
5400 
5401 // return 1 when matrix is identity, 0 otherwise
5402 #define IS_MATRIX_IDENT(matrix) \
5403  ( (matrix)[0][0] == (1 << 16) && \
5404  (matrix)[1][1] == (1 << 16) && \
5405  (matrix)[2][2] == (1 << 30) && \
5406  !(matrix)[0][1] && !(matrix)[0][2] && \
5407  !(matrix)[1][0] && !(matrix)[1][2] && \
5408  !(matrix)[2][0] && !(matrix)[2][1])
5409 
5411 {
5412  int i, j, e;
5413  int width;
5414  int height;
5415  int display_matrix[3][3];
5416  int res_display_matrix[3][3] = { { 0 } };
5417  AVStream *st;
5418  MOVStreamContext *sc;
5419  int version;
5420  int flags;
5421 
5422  if (c->fc->nb_streams < 1)
5423  return 0;
5424  st = c->fc->streams[c->fc->nb_streams-1];
5425  sc = st->priv_data;
5426 
5427  // Each stream (trak) should have exactly 1 tkhd. This catches bad files and
5428  // avoids corrupting AVStreams mapped to an earlier tkhd.
5429  if (st->id != -1)
5430  return AVERROR_INVALIDDATA;
5431 
5432  version = avio_r8(pb);
5433  flags = avio_rb24(pb);
5435 
5436  if (version == 1) {
5437  avio_rb64(pb);
5438  avio_rb64(pb);
5439  } else {
5440  avio_rb32(pb); /* creation time */
5441  avio_rb32(pb); /* modification time */
5442  }
5443  st->id = (int)avio_rb32(pb); /* track id (NOT 0 !)*/
5444  sc->id = st->id;
5445  avio_rb32(pb); /* reserved */
5446 
5447  /* highlevel (considering edits) duration in movie timebase */
5448  (version == 1) ? avio_rb64(pb) : avio_rb32(pb);
5449  avio_rb32(pb); /* reserved */
5450  avio_rb32(pb); /* reserved */
5451 
5452  avio_rb16(pb); /* layer */
5453  avio_rb16(pb); /* alternate group */
5454  avio_rb16(pb); /* volume */
5455  avio_rb16(pb); /* reserved */
5456 
5457  //read in the display matrix (outlined in ISO 14496-12, Section 6.2.2)
5458  // they're kept in fixed point format through all calculations
5459  // save u,v,z to store the whole matrix in the AV_PKT_DATA_DISPLAYMATRIX
5460  // side data, but the scale factor is not needed to calculate aspect ratio
5461  for (i = 0; i < 3; i++) {
5462  display_matrix[i][0] = avio_rb32(pb); // 16.16 fixed point
5463  display_matrix[i][1] = avio_rb32(pb); // 16.16 fixed point
5464  display_matrix[i][2] = avio_rb32(pb); // 2.30 fixed point
5465  }
5466 
5467  width = avio_rb32(pb); // 16.16 fixed point track width
5468  height = avio_rb32(pb); // 16.16 fixed point track height
5469  sc->width = width >> 16;
5470  sc->height = height >> 16;
5471 
5472  // apply the moov display matrix (after the tkhd one)
5473  for (i = 0; i < 3; i++) {
5474  const int sh[3] = { 16, 16, 30 };
5475  for (j = 0; j < 3; j++) {
5476  for (e = 0; e < 3; e++) {
5477  res_display_matrix[i][j] +=
5478  ((int64_t) display_matrix[i][e] *
5479  c->movie_display_matrix[e][j]) >> sh[e];
5480  }
5481  }
5482  }
5483 
5484  // save the matrix when it is not the default identity
5485  if (!IS_MATRIX_IDENT(res_display_matrix)) {
5486  av_freep(&sc->display_matrix);
5487  sc->display_matrix = av_malloc(sizeof(int32_t) * 9);
5488  if (!sc->display_matrix)
5489  return AVERROR(ENOMEM);
5490 
5491  for (i = 0; i < 3; i++)
5492  for (j = 0; j < 3; j++)
5493  sc->display_matrix[i * 3 + j] = res_display_matrix[i][j];
5494  }
5495 
5496  // transform the display width/height according to the matrix
5497  // to keep the same scale, use [width height 1<<16]
5498  if (width && height && sc->display_matrix) {
5499  double disp_transform[2];
5500 
5501  for (i = 0; i < 2; i++)
5502  disp_transform[i] = hypot(sc->display_matrix[0 + i],
5503  sc->display_matrix[3 + i]);
5504 
5505  if (disp_transform[0] > 1 && disp_transform[1] > 1 &&
5506  disp_transform[0] < (1<<24) && disp_transform[1] < (1<<24) &&
5507  fabs((disp_transform[0] / disp_transform[1]) - 1.0) > 0.01)
5509  disp_transform[0] / disp_transform[1],
5510  INT_MAX);
5511  }
5512  return 0;
5513 }
5514 
5516 {
5517  MOVFragment *frag = &c->fragment;
5518  MOVTrackExt *trex = NULL;
5519  int flags, track_id, i;
5520  MOVFragmentStreamInfo * frag_stream_info;
5521 
5522  avio_r8(pb); /* version */
5523  flags = avio_rb24(pb);
5524 
5525  track_id = avio_rb32(pb);
5526  if (!track_id)
5527  return AVERROR_INVALIDDATA;
5528  for (i = 0; i < c->trex_count; i++)
5529  if (c->trex_data[i].track_id == track_id) {
5530  trex = &c->trex_data[i];
5531  break;
5532  }
5533  if (!trex) {
5534  av_log(c->fc, AV_LOG_WARNING, "could not find corresponding trex (id %u)\n", track_id);
5535  return 0;
5536  }
5537  c->fragment.found_tfhd = 1;
5538  frag->track_id = track_id;
5539  set_frag_stream(&c->frag_index, track_id);
5540 
5543  frag->moof_offset : frag->implicit_offset;
5544  frag->stsd_id = flags & MOV_TFHD_STSD_ID ? avio_rb32(pb) : trex->stsd_id;
5545 
5547  avio_rb32(pb) : trex->duration;
5548  frag->size = flags & MOV_TFHD_DEFAULT_SIZE ?
5549  avio_rb32(pb) : trex->size;
5550  frag->flags = flags & MOV_TFHD_DEFAULT_FLAGS ?
5551  avio_rb32(pb) : trex->flags;
5552  av_log(c->fc, AV_LOG_TRACE, "frag flags 0x%x\n", frag->flags);
5553 
5554  frag_stream_info = get_current_frag_stream_info(&c->frag_index);
5555  if (frag_stream_info) {
5556  frag_stream_info->next_trun_dts = AV_NOPTS_VALUE;
5557  frag_stream_info->stsd_id = frag->stsd_id;
5558  }
5559  return 0;
5560 }
5561 
5563 {
5564  unsigned i, num;
5565  void *new_tracks;
5566 
5567  num = atom.size / 4;
5568  if (!(new_tracks = av_malloc_array(num, sizeof(int))))
5569  return AVERROR(ENOMEM);
5570 
5571  av_free(c->chapter_tracks);
5572  c->chapter_tracks = new_tracks;
5573  c->nb_chapter_tracks = num;
5574 
5575  for (i = 0; i < num && !pb->eof_reached; i++)
5576  c->chapter_tracks[i] = avio_rb32(pb);
5577 
5578  c->nb_chapter_tracks = i;
5579 
5580  return 0;
5581 }
5582 
5584 {
5585  MOVTrackExt *trex;
5586  int err;
5587 
5588  if ((uint64_t)c->trex_count+1 >= UINT_MAX / sizeof(*c->trex_data))
5589  return AVERROR_INVALIDDATA;
5590  if ((err = av_reallocp_array(&c->trex_data, c->trex_count + 1,
5591  sizeof(*c->trex_data))) < 0) {
5592  c->trex_count = 0;
5593  return err;
5594  }
5595 
5596  c->fc->duration = AV_NOPTS_VALUE; // the duration from mvhd is not representing the whole file when fragments are used.
5597 
5598  trex = &c->trex_data[c->trex_count++];
5599  avio_r8(pb); /* version */
5600  avio_rb24(pb); /* flags */
5601  trex->track_id = avio_rb32(pb);
5602  trex->stsd_id = avio_rb32(pb);
5603  trex->duration = avio_rb32(pb);
5604  trex->size = avio_rb32(pb);
5605  trex->flags = avio_rb32(pb);
5606  return 0;
5607 }
5608 
5610 {
5611  MOVFragment *frag = &c->fragment;
5612  AVStream *st = NULL;
5613  MOVStreamContext *sc;
5614  int version, i;
5615  MOVFragmentStreamInfo * frag_stream_info;
5616  int64_t base_media_decode_time;
5617 
5618  for (i = 0; i < c->fc->nb_streams; i++) {
5619  sc = c->fc->streams[i]->priv_data;
5620  if (sc->id == frag->track_id) {
5621  st = c->fc->streams[i];
5622  break;
5623  }
5624  }
5625  if (!st) {
5626  av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %u\n", frag->track_id);
5627  return 0;
5628  }
5629  sc = st->priv_data;
5630  if (sc->pseudo_stream_id + 1 != frag->stsd_id && sc->pseudo_stream_id != -1)
5631  return 0;
5632  version = avio_r8(pb);
5633  avio_rb24(pb); /* flags */
5634  if (version) {
5635  base_media_decode_time = avio_rb64(pb);
5636  } else {
5637  base_media_decode_time = avio_rb32(pb);
5638  }
5639 
5640  frag_stream_info = get_current_frag_stream_info(&c->frag_index);
5641  if (frag_stream_info)
5642  frag_stream_info->tfdt_dts = base_media_decode_time;
5643  sc->track_end = base_media_decode_time;
5644 
5645  return 0;
5646 }
5647 
5649 {
5650  MOVFragment *frag = &c->fragment;
5651  AVStream *st = NULL;
5652  FFStream *sti = NULL;
5653  MOVStreamContext *sc;
5654  MOVCtts *ctts_data;
5655  uint64_t offset;
5656  int64_t dts, pts = AV_NOPTS_VALUE;
5657  int data_offset = 0;
5658  unsigned entries, first_sample_flags = frag->flags;
5659  int flags, distance, i;
5660  int64_t prev_dts = AV_NOPTS_VALUE;
5661  int next_frag_index = -1, index_entry_pos;
5662  size_t requested_size;
5663  size_t old_ctts_allocated_size;
5664  AVIndexEntry *new_entries;
5665  MOVFragmentStreamInfo * frag_stream_info;
5666 
5667  if (!frag->found_tfhd) {
5668  av_log(c->fc, AV_LOG_ERROR, "trun track id unknown, no tfhd was found\n");
5669  return AVERROR_INVALIDDATA;
5670  }
5671 
5672  for (i = 0; i < c->fc->nb_streams; i++) {
5673  sc = c->fc->streams[i]->priv_data;
5674  if (sc->id == frag->track_id) {
5675  st = c->fc->streams[i];
5676  sti = ffstream(st);
5677  break;
5678  }
5679  }
5680  if (!st) {
5681  av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %u\n", frag->track_id);
5682  return 0;
5683  }
5684  sc = st->priv_data;
5685  if (sc->pseudo_stream_id+1 != frag->stsd_id && sc->pseudo_stream_id != -1)
5686  return 0;
5687 
5688  // Find the next frag_index index that has a valid index_entry for
5689  // the current track_id.
5690  //
5691  // A valid index_entry means the trun for the fragment was read
5692  // and it's samples are in index_entries at the given position.
5693  // New index entries will be inserted before the index_entry found.
5694  index_entry_pos = sti->nb_index_entries;
5695  for (i = c->frag_index.current + 1; i < c->frag_index.nb_items; i++) {
5696  frag_stream_info = get_frag_stream_info(&c->frag_index, i, frag->track_id);
5697  if (frag_stream_info && frag_stream_info->index_entry >= 0) {
5698  next_frag_index = i;
5699  index_entry_pos = frag_stream_info->index_entry;
5700  break;
5701  }
5702  }
5703  av_assert0(index_entry_pos <= sti->nb_index_entries);
5704 
5705  avio_r8(pb); /* version */
5706  flags = avio_rb24(pb);
5707  entries = avio_rb32(pb);
5708  av_log(c->fc, AV_LOG_TRACE, "flags 0x%x entries %u\n", flags, entries);
5709 
5710  if ((uint64_t)entries+sc->ctts_count >= UINT_MAX/sizeof(*sc->ctts_data))
5711  return AVERROR_INVALIDDATA;
5712  if (flags & MOV_TRUN_DATA_OFFSET) data_offset = avio_rb32(pb);
5713  if (flags & MOV_TRUN_FIRST_SAMPLE_FLAGS) first_sample_flags = avio_rb32(pb);
5714 
5715  frag_stream_info = get_current_frag_stream_info(&c->frag_index);
5716  if (frag_stream_info) {
5717  if (frag_stream_info->next_trun_dts != AV_NOPTS_VALUE) {
5718  dts = frag_stream_info->next_trun_dts - sc->time_offset;
5719  } else if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE &&
5720  c->use_mfra_for == FF_MOV_FLAG_MFRA_PTS) {
5721  pts = frag_stream_info->first_tfra_pts;
5722  av_log(c->fc, AV_LOG_DEBUG, "found mfra time %"PRId64
5723  ", using it for pts\n", pts);
5724  } else if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE &&
5725  c->use_mfra_for == FF_MOV_FLAG_MFRA_DTS) {
5726  dts = frag_stream_info->first_tfra_pts;
5727  av_log(c->fc, AV_LOG_DEBUG, "found mfra time %"PRId64
5728  ", using it for dts\n", pts);
5729  } else {
5730  int has_tfdt = frag_stream_info->tfdt_dts != AV_NOPTS_VALUE;
5731  int has_sidx = frag_stream_info->sidx_pts != AV_NOPTS_VALUE;
5732  int fallback_tfdt = !c->use_tfdt && !has_sidx && has_tfdt;
5733  int fallback_sidx = c->use_tfdt && !has_tfdt && has_sidx;
5734 
5735  if (fallback_sidx) {
5736  av_log(c->fc, AV_LOG_DEBUG, "use_tfdt set but no tfdt found, using sidx instead\n");
5737  }
5738  if (fallback_tfdt) {
5739  av_log(c->fc, AV_LOG_DEBUG, "use_tfdt not set but no sidx found, using tfdt instead\n");
5740  }
5741 
5742  if (has_tfdt && c->use_tfdt || fallback_tfdt) {
5743  dts = frag_stream_info->tfdt_dts - sc->time_offset;
5744  av_log(c->fc, AV_LOG_DEBUG, "found tfdt time %"PRId64
5745  ", using it for dts\n", dts);
5746  } else if (has_sidx && !c->use_tfdt || fallback_sidx) {
5747  // FIXME: sidx earliest_presentation_time is *PTS*, s.b.
5748  // pts = frag_stream_info->sidx_pts;
5749  dts = frag_stream_info->sidx_pts - sc->time_offset;
5750  av_log(c->fc, AV_LOG_DEBUG, "found sidx time %"PRId64
5751  ", using it for dts\n", frag_stream_info->sidx_pts);
5752  } else {
5753  dts = sc->track_end - sc->time_offset;
5754  av_log(c->fc, AV_LOG_DEBUG, "found track end time %"PRId64
5755  ", using it for dts\n", dts);
5756  }
5757  }
5758  } else {
5759  dts = sc->track_end - sc->time_offset;
5760  av_log(c->fc, AV_LOG_DEBUG, "found track end time %"PRId64
5761  ", using it for dts\n", dts);
5762  }
5763  offset = frag->base_data_offset + data_offset;
5764  distance = 0;
5765  av_log(c->fc, AV_LOG_TRACE, "first sample flags 0x%x\n", first_sample_flags);
5766 
5767  // realloc space for new index entries
5768  if ((uint64_t)sti->nb_index_entries + entries >= UINT_MAX / sizeof(AVIndexEntry)) {
5769  entries = UINT_MAX / sizeof(AVIndexEntry) - sti->nb_index_entries;
5770  av_log(c->fc, AV_LOG_ERROR, "Failed to add index entry\n");
5771  }
5772  if (entries == 0)
5773  return 0;
5774 
5775  requested_size = (sti->nb_index_entries + entries) * sizeof(AVIndexEntry);
5776  new_entries = av_fast_realloc(sti->index_entries,
5778  requested_size);
5779  if (!new_entries)
5780  return AVERROR(ENOMEM);
5781  sti->index_entries= new_entries;
5782 
5783  requested_size = (sti->nb_index_entries + entries) * sizeof(*sc->ctts_data);
5784  old_ctts_allocated_size = sc->ctts_allocated_size;
5785  ctts_data = av_fast_realloc(sc->ctts_data, &sc->ctts_allocated_size,
5786  requested_size);
5787  if (!ctts_data)
5788  return AVERROR(ENOMEM);
5789  sc->ctts_data = ctts_data;
5790 
5791  // In case there were samples without ctts entries, ensure they get
5792  // zero valued entries. This ensures clips which mix boxes with and
5793  // without ctts entries don't pickup uninitialized data.
5794  memset((uint8_t*)(sc->ctts_data) + old_ctts_allocated_size, 0,
5795  sc->ctts_allocated_size - old_ctts_allocated_size);
5796 
5797  if (index_entry_pos < sti->nb_index_entries) {
5798  // Make hole in index_entries and ctts_data for new samples
5799  memmove(sti->index_entries + index_entry_pos + entries,
5800  sti->index_entries + index_entry_pos,
5801  sizeof(*sti->index_entries) *
5802  (sti->nb_index_entries - index_entry_pos));
5803  memmove(sc->ctts_data + index_entry_pos + entries,
5804  sc->ctts_data + index_entry_pos,
5805  sizeof(*sc->ctts_data) * (sc->ctts_count - index_entry_pos));
5806  if (index_entry_pos < sc->current_sample) {
5807  sc->current_sample += entries;
5808  }
5809  }
5810 
5811  sti->nb_index_entries += entries;
5812  sc->ctts_count = sti->nb_index_entries;
5813 
5814  // Record the index_entry position in frag_index of this fragment
5815  if (frag_stream_info) {
5816  frag_stream_info->index_entry = index_entry_pos;
5817  if (frag_stream_info->index_base < 0)
5818  frag_stream_info->index_base = index_entry_pos;
5819  }
5820 
5821  if (index_entry_pos > 0)
5822  prev_dts = sti->index_entries[index_entry_pos-1].timestamp;
5823 
5824  for (i = 0; i < entries && !pb->eof_reached; i++) {
5825  unsigned sample_size = frag->size;
5826  int sample_flags = i ? frag->flags : first_sample_flags;
5827  unsigned sample_duration = frag->duration;
5828  unsigned ctts_duration = 0;
5829  int keyframe = 0;
5830  int index_entry_flags = 0;
5831 
5832  if (flags & MOV_TRUN_SAMPLE_DURATION) sample_duration = avio_rb32(pb);
5833  if (flags & MOV_TRUN_SAMPLE_SIZE) sample_size = avio_rb32(pb);
5834  if (flags & MOV_TRUN_SAMPLE_FLAGS) sample_flags = avio_rb32(pb);
5835  if (flags & MOV_TRUN_SAMPLE_CTS) ctts_duration = avio_rb32(pb);
5836 
5837  mov_update_dts_shift(sc, ctts_duration, c->fc);
5838  if (pts != AV_NOPTS_VALUE) {
5839  dts = pts - sc->dts_shift;
5840  if (flags & MOV_TRUN_SAMPLE_CTS) {
5841  dts -= ctts_duration;
5842  } else {
5843  dts -= sc->time_offset;
5844  }
5845  av_log(c->fc, AV_LOG_DEBUG,
5846  "pts %"PRId64" calculated dts %"PRId64
5847  " sc->dts_shift %d ctts.duration %d"
5848  " sc->time_offset %"PRId64
5849  " flags & MOV_TRUN_SAMPLE_CTS %d\n",
5850  pts, dts,
5851  sc->dts_shift, ctts_duration,
5853  pts = AV_NOPTS_VALUE;
5854  }
5855 
5856  keyframe =
5857  !(sample_flags & (MOV_FRAG_SAMPLE_FLAG_IS_NON_SYNC |
5859  if (keyframe) {
5860  distance = 0;
5861  index_entry_flags |= AVINDEX_KEYFRAME;
5862  }
5863  // Fragments can overlap in time. Discard overlapping frames after
5864  // decoding.
5865  if (prev_dts >= dts)
5866  index_entry_flags |= AVINDEX_DISCARD_FRAME;
5867 
5868  sti->index_entries[index_entry_pos].pos = offset;
5869  sti->index_entries[index_entry_pos].timestamp = dts;
5870  sti->index_entries[index_entry_pos].size = sample_size;
5871  sti->index_entries[index_entry_pos].min_distance = distance;
5872  sti->index_entries[index_entry_pos].flags = index_entry_flags;
5873 
5874  sc->ctts_data[index_entry_pos].count = 1;
5875  sc->ctts_data[index_entry_pos].duration = ctts_duration;
5876  index_entry_pos++;
5877 
5878  av_log(c->fc, AV_LOG_TRACE, "AVIndex stream %d, sample %d, offset %"PRIx64", dts %"PRId64", "
5879  "size %u, distance %d, keyframe %d\n", st->index,
5880  index_entry_pos, offset, dts, sample_size, distance, keyframe);
5881  distance++;
5882  if (av_sat_add64(dts, sample_duration) != dts + (uint64_t)sample_duration)
5883  return AVERROR_INVALIDDATA;
5884  if (!sample_size)
5885  return AVERROR_INVALIDDATA;
5886  dts += sample_duration;
5887  offset += sample_size;
5888  sc->data_size += sample_size;
5889 
5890  if (sample_duration <= INT64_MAX - sc->duration_for_fps &&
5891  1 <= INT_MAX - sc->nb_frames_for_fps
5892  ) {
5893  sc->duration_for_fps += sample_duration;
5894  sc->nb_frames_for_fps ++;
5895  }
5896  }
5897  if (frag_stream_info)
5898  frag_stream_info->next_trun_dts = dts + sc->time_offset;
5899  if (i < entries) {
5900  // EOF found before reading all entries. Fix the hole this would
5901  // leave in index_entries and ctts_data
5902  int gap = entries - i;
5903  memmove(sti->index_entries + index_entry_pos,
5904  sti->index_entries + index_entry_pos + gap,
5905  sizeof(*sti->index_entries) *
5906  (sti->nb_index_entries - (index_entry_pos + gap)));
5907  memmove(sc->ctts_data + index_entry_pos,
5908  sc->ctts_data + index_entry_pos + gap,
5909  sizeof(*sc->ctts_data) *
5910  (sc->ctts_count - (index_entry_pos + gap)));
5911 
5912  sti->nb_index_entries -= gap;
5913  sc->ctts_count -= gap;
5914  if (index_entry_pos < sc->current_sample) {
5915  sc->current_sample -= gap;
5916  }
5917  entries = i;
5918  }
5919 
5920  // The end of this new fragment may overlap in time with the start
5921  // of the next fragment in index_entries. Mark the samples in the next
5922  // fragment that overlap with AVINDEX_DISCARD_FRAME
5923  prev_dts = AV_NOPTS_VALUE;
5924  if (index_entry_pos > 0)
5925  prev_dts = sti->index_entries[index_entry_pos-1].timestamp;
5926  for (int i = index_entry_pos; i < sti->nb_index_entries; i++) {
5927  if (prev_dts < sti->index_entries[i].timestamp)
5928  break;
5930  }
5931 
5932  // If a hole was created to insert the new index_entries into,
5933  // the index_entry recorded for all subsequent moof must
5934  // be incremented by the number of entries inserted.
5935  fix_frag_index_entries(&c->frag_index, next_frag_index,
5936  frag->track_id, entries);
5937 
5938  if (pb->eof_reached) {
5939  av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted TRUN atom\n");
5940  return AVERROR_EOF;
5941  }
5942 
5943  frag->implicit_offset = offset;
5944 
5945  sc->track_end = dts + sc->time_offset;
5946  if (st->duration < sc->track_end)
5947  st->duration = sc->track_end;
5948 
5949  return 0;
5950 }
5951 
5953 {
5954  int64_t stream_size = avio_size(pb);
5955  int64_t offset = av_sat_add64(avio_tell(pb), atom.size), pts, timestamp;
5956  uint8_t version, is_complete;
5957  int64_t offadd;
5958  unsigned i, j, track_id, item_count;
5959  AVStream *st = NULL;
5960  AVStream *ref_st = NULL;
5961  MOVStreamContext *sc, *ref_sc = NULL;
5962  AVRational timescale;
5963 
5964  version = avio_r8(pb);
5965  if (version > 1) {
5966  avpriv_request_sample(c->fc, "sidx version %u", version);
5967  return 0;
5968  }
5969 
5970  avio_rb24(pb); // flags
5971 
5972  track_id = avio_rb32(pb); // Reference ID
5973  for (i = 0; i < c->fc->nb_streams; i++) {
5974  sc = c->fc->streams[i]->priv_data;
5975  if (sc->id == track_id) {
5976  st = c->fc->streams[i];
5977  break;
5978  }
5979  }
5980  if (!st) {
5981  av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %d\n", track_id);
5982  return 0;
5983  }
5984 
5985  sc = st->priv_data;
5986 
5987  timescale = av_make_q(1, avio_rb32(pb));
5988 
5989  if (timescale.den <= 0) {
5990  av_log(c->fc, AV_LOG_ERROR, "Invalid sidx timescale 1/%d\n", timescale.den);
5991  return AVERROR_INVALIDDATA;
5992  }
5993 
5994  if (version == 0) {
5995  pts = avio_rb32(pb);
5996  offadd= avio_rb32(pb);
5997  } else {
5998  pts = avio_rb64(pb);
5999  offadd= avio_rb64(pb);
6000  }
6001  if (av_sat_add64(offset, offadd) != offset + (uint64_t)offadd)
6002  return AVERROR_INVALIDDATA;
6003 
6004  offset += (uint64_t)offadd;
6005 
6006  avio_rb16(pb); // reserved
6007 
6008  item_count = avio_rb16(pb);
6009  if (item_count == 0)
6010  return AVERROR_INVALIDDATA;
6011 
6012  for (i = 0; i < item_count; i++) {
6013  int index;
6014  MOVFragmentStreamInfo * frag_stream_info;
6015  uint32_t size = avio_rb32(pb);
6016  uint32_t duration = avio_rb32(pb);
6017  if (size & 0x80000000) {
6018  avpriv_request_sample(c->fc, "sidx reference_type 1");
6019  return AVERROR_PATCHWELCOME;
6020  }
6021  avio_rb32(pb); // sap_flags
6022  timestamp = av_rescale_q(pts, timescale, st->time_base);
6023 
6025  frag_stream_info = get_frag_stream_info(&c->frag_index, index, track_id);
6026  if (frag_stream_info)
6027  frag_stream_info->sidx_pts = timestamp;
6028 
6029  if (av_sat_add64(offset, size) != offset + (uint64_t)size ||
6030  av_sat_add64(pts, duration) != pts + (uint64_t)duration
6031  )
6032  return AVERROR_INVALIDDATA;
6033  offset += size;
6034  pts += duration;
6035  }
6036 
6037  st->duration = sc->track_end = pts;
6038 
6039  sc->has_sidx = 1;
6040 
6041  // See if the remaining bytes are just an mfra which we can ignore.
6042  is_complete = offset == stream_size;
6043  if (!is_complete && (pb->seekable & AVIO_SEEKABLE_NORMAL) && stream_size > 0 ) {
6044  int64_t ret;
6045  int64_t original_pos = avio_tell(pb);
6046  if (!c->have_read_mfra_size) {
6047  if ((ret = avio_seek(pb, stream_size - 4, SEEK_SET)) < 0)
6048  return ret;
6049  c->mfra_size = avio_rb32(pb);
6050  c->have_read_mfra_size = 1;
6051  if ((ret = avio_seek(pb, original_pos, SEEK_SET)) < 0)
6052  return ret;
6053  }
6054  if (offset == stream_size - c->mfra_size)
6055  is_complete = 1;
6056  }
6057 
6058  if (is_complete) {
6059  // Find first entry in fragment index that came from an sidx.
6060  // This will pretty much always be the first entry.
6061  for (i = 0; i < c->frag_index.nb_items; i++) {
6062  MOVFragmentIndexItem * item = &c->frag_index.item[i];
6063  for (j = 0; ref_st == NULL && j < item->nb_stream_info; j++) {
6064  MOVFragmentStreamInfo * si;
6065  si = &item->stream_info[j];
6066  if (si->sidx_pts != AV_NOPTS_VALUE) {
6067  ref_st = c->fc->streams[j];
6068  ref_sc = ref_st->priv_data;
6069  break;
6070  }
6071  }
6072  }
6073  if (ref_st) for (i = 0; i < c->fc->nb_streams; i++) {
6074  st = c->fc->streams[i];
6075  sc = st->priv_data;
6076  if (!sc->has_sidx) {
6077  st->duration = sc->track_end = av_rescale(ref_st->duration, sc->time_scale, ref_sc->time_scale);
6078  }
6079  }
6080 
6081  c->frag_index.complete = 1;
6082  }
6083 
6084  return 0;
6085 }
6086 
6087 /* this atom should be null (from specs), but some buggy files put the 'moov' atom inside it... */
6088 /* like the files created with Adobe Premiere 5.0, for samples see */
6089 /* http://graphics.tudelft.nl/~wouter/publications/soundtests/ */
6091 {
6092  int err;
6093 
6094  if (atom.size < 8)
6095  return 0; /* continue */
6096  if (avio_rb32(pb) != 0) { /* 0 sized mdat atom... use the 'wide' atom size */
6097  avio_skip(pb, atom.size - 4);
6098  return 0;
6099  }
6100  atom.type = avio_rl32(pb);
6101  atom.size -= 8;
6102  if (atom.type != MKTAG('m','d','a','t')) {
6103  avio_skip(pb, atom.size);
6104  return 0;
6105  }
6106  err = mov_read_mdat(c, pb, atom);
6107  return err;
6108 }
6109 
6111 {
6112 #if CONFIG_ZLIB
6113  FFIOContext ctx;
6114  uint8_t *cmov_data;
6115  uint8_t *moov_data; /* uncompressed data */
6116  long cmov_len, moov_len;
6117  int ret = -1;
6118 
6119  avio_rb32(pb); /* dcom atom */
6120  if (avio_rl32(pb) != MKTAG('d','c','o','m'))
6121  return AVERROR_INVALIDDATA;
6122  if (avio_rl32(pb) != MKTAG('z','l','i','b')) {
6123  av_log(c->fc, AV_LOG_ERROR, "unknown compression for cmov atom !\n");
6124  return AVERROR_INVALIDDATA;
6125  }
6126  avio_rb32(pb); /* cmvd atom */
6127  if (avio_rl32(pb) != MKTAG('c','m','v','d'))
6128  return AVERROR_INVALIDDATA;
6129  moov_len = avio_rb32(pb); /* uncompressed size */
6130  cmov_len = atom.size - 6 * 4;
6131 
6132  cmov_data = av_malloc(cmov_len);
6133  if (!cmov_data)
6134  return AVERROR(ENOMEM);
6135  moov_data = av_malloc(moov_len);
6136  if (!moov_data) {
6137  av_free(cmov_data);
6138  return AVERROR(ENOMEM);
6139  }
6140  ret = ffio_read_size(pb, cmov_data, cmov_len);
6141  if (ret < 0)
6142  goto free_and_return;
6143 
6145  if (uncompress (moov_data, (uLongf *) &moov_len, (const Bytef *)cmov_data, cmov_len) != Z_OK)
6146  goto free_and_return;
6147  ffio_init_read_context(&ctx, moov_data, moov_len);
6148  ctx.pub.seekable = AVIO_SEEKABLE_NORMAL;
6149  atom.type = MKTAG('m','o','o','v');
6150  atom.size = moov_len;
6151  ret = mov_read_default(c, &ctx.pub, atom);
6152 free_and_return:
6153  av_free(moov_data);
6154  av_free(cmov_data);
6155  return ret;
6156 #else
6157  av_log(c->fc, AV_LOG_ERROR, "this file requires zlib support compiled in\n");
6158  return AVERROR(ENOSYS);
6159 #endif
6160 }
6161 
6162 /* edit list atom */
6164 {
6165  MOVStreamContext *sc;
6166  int i, edit_count, version;
6167  int64_t elst_entry_size;
6168 
6169  if (c->fc->nb_streams < 1 || c->ignore_editlist)
6170  return 0;
6171  sc = c->fc->streams[c->fc->nb_streams-1]->priv_data;
6172 
6173  version = avio_r8(pb); /* version */
6174  avio_rb24(pb); /* flags */
6175  edit_count = avio_rb32(pb); /* entries */
6176  atom.size -= 8;
6177 
6178  elst_entry_size = version == 1 ? 20 : 12;
6179  if (atom.size != edit_count * elst_entry_size) {
6180  if (c->fc->strict_std_compliance >= FF_COMPLIANCE_STRICT) {
6181  av_log(c->fc, AV_LOG_ERROR, "Invalid edit list entry_count: %d for elst atom of size: %"PRId64" bytes.\n",
6182  edit_count, atom.size + 8);
6183  return AVERROR_INVALIDDATA;
6184  } else {
6185  edit_count = atom.size / elst_entry_size;
6186  if (edit_count * elst_entry_size != atom.size) {
6187  av_log(c->fc, AV_LOG_WARNING, "ELST atom of %"PRId64" bytes, bigger than %d entries.\n", atom.size, edit_count);
6188  }
6189  }
6190  }
6191 
6192  if (!edit_count)
6193  return 0;
6194  if (sc->elst_data)
6195  av_log(c->fc, AV_LOG_WARNING, "Duplicated ELST atom\n");
6196  av_free(sc->elst_data);
6197  sc->elst_count = 0;
6198  sc->elst_data = av_malloc_array(edit_count, sizeof(*sc->elst_data));
6199  if (!sc->elst_data)
6200  return AVERROR(ENOMEM);
6201 
6202  av_log(c->fc, AV_LOG_TRACE, "track[%u].edit_count = %i\n", c->fc->nb_streams - 1, edit_count);
6203  for (i = 0; i < edit_count && atom.size > 0 && !pb->eof_reached; i++) {
6204  MOVElst *e = &sc->elst_data[i];
6205 
6206  if (version == 1) {
6207  e->duration = avio_rb64(pb);
6208  e->time = avio_rb64(pb);
6209  atom.size -= 16;
6210  } else {
6211  e->duration = avio_rb32(pb); /* segment duration */
6212  e->time = (int32_t)avio_rb32(pb); /* media time */
6213  atom.size -= 8;
6214  }
6215  e->rate = avio_rb32(pb) / 65536.0;
6216  atom.size -= 4;
6217  av_log(c->fc, AV_LOG_TRACE, "duration=%"PRId64" time=%"PRId64" rate=%f\n",
6218  e->duration, e->time, e->rate);
6219 
6220  if (e->time < 0 && e->time != -1 &&
6221  c->fc->strict_std_compliance >= FF_COMPLIANCE_STRICT) {
6222  av_log(c->fc, AV_LOG_ERROR, "Track %d, edit %d: Invalid edit list media time=%"PRId64"\n",
6223  c->fc->nb_streams-1, i, e->time);
6224  return AVERROR_INVALIDDATA;
6225  }
6226  if (e->duration < 0) {
6227  av_log(c->fc, AV_LOG_ERROR, "Track %d, edit %d: Invalid edit list duration=%"PRId64"\n",
6228  c->fc->nb_streams-1, i, e->duration);
6229  return AVERROR_INVALIDDATA;
6230  }
6231  }
6232  sc->elst_count = i;
6233 
6234  return 0;
6235 }
6236 
6238 {
6239  MOVStreamContext *sc;
6240 
6241  if (c->fc->nb_streams < 1)
6242  return AVERROR_INVALIDDATA;
6243  sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
6244  sc->timecode_track = avio_rb32(pb);
6245  return 0;
6246 }
6247 
6249 {
6250  AVStream *st;
6251  int version, color_range, color_primaries, color_trc, color_space;
6252 
6253  if (c->fc->nb_streams < 1)
6254  return 0;
6255  st = c->fc->streams[c->fc->nb_streams - 1];
6256 
6257  if (atom.size < 5) {
6258  av_log(c->fc, AV_LOG_ERROR, "Empty VP Codec Configuration box\n");
6259  return AVERROR_INVALIDDATA;
6260  }
6261 
6262  version = avio_r8(pb);
6263  if (version != 1) {
6264  av_log(c->fc, AV_LOG_WARNING, "Unsupported VP Codec Configuration box version %d\n", version);
6265  return 0;
6266  }
6267  avio_skip(pb, 3); /* flags */
6268 
6269  avio_skip(pb, 2); /* profile + level */
6270  color_range = avio_r8(pb); /* bitDepth, chromaSubsampling, videoFullRangeFlag */
6271  color_primaries = avio_r8(pb);
6272  color_trc = avio_r8(pb);
6273  color_space = avio_r8(pb);
6274  if (avio_rb16(pb)) /* codecIntializationDataSize */
6275  return AVERROR_INVALIDDATA;
6276 
6279  if (!av_color_transfer_name(color_trc))
6280  color_trc = AVCOL_TRC_UNSPECIFIED;
6281  if (!av_color_space_name(color_space))
6282  color_space = AVCOL_SPC_UNSPECIFIED;
6283 
6286  st->codecpar->color_trc = color_trc;
6287  st->codecpar->color_space = color_space;
6288 
6289  return 0;
6290 }
6291 
6293 {
6294  MOVStreamContext *sc;
6295  int i, version;
6296 
6297  if (c->fc->nb_streams < 1)
6298  return AVERROR_INVALIDDATA;
6299 
6300  sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
6301 
6302  if (atom.size < 5) {
6303  av_log(c->fc, AV_LOG_ERROR, "Empty Mastering Display Metadata box\n");
6304  return AVERROR_INVALIDDATA;
6305  }
6306 
6307  version = avio_r8(pb);
6308  if (version) {
6309  av_log(c->fc, AV_LOG_WARNING, "Unsupported Mastering Display Metadata box version %d\n", version);
6310  return 0;
6311  }
6312  if (sc->mastering) {
6313  av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicate Mastering Display Metadata\n");
6314  return 0;
6315  }
6316 
6317  avio_skip(pb, 3); /* flags */
6318 
6320  if (!sc->mastering)
6321  return AVERROR(ENOMEM);
6322 
6323  for (i = 0; i < 3; i++) {
6324  sc->mastering->display_primaries[i][0] = av_make_q(avio_rb16(pb), 1 << 16);
6325  sc->mastering->display_primaries[i][1] = av_make_q(avio_rb16(pb), 1 << 16);
6326  }
6327  sc->mastering->white_point[0] = av_make_q(avio_rb16(pb), 1 << 16);
6328  sc->mastering->white_point[1] = av_make_q(avio_rb16(pb), 1 << 16);
6329 
6330  sc->mastering->max_luminance = av_make_q(avio_rb32(pb), 1 << 8);
6331  sc->mastering->min_luminance = av_make_q(avio_rb32(pb), 1 << 14);
6332 
6333  sc->mastering->has_primaries = 1;
6334  sc->mastering->has_luminance = 1;
6335 
6336  return 0;
6337 }
6338 
6340 {
6341  MOVStreamContext *sc;
6342  const int mapping[3] = {1, 2, 0};
6343  const int chroma_den = 50000;
6344  const int luma_den = 10000;
6345  int i;
6346 
6347  if (c->fc->nb_streams < 1)
6348  return AVERROR_INVALIDDATA;
6349 
6350  sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
6351 
6352  if (atom.size < 24) {
6353  av_log(c->fc, AV_LOG_ERROR, "Invalid Mastering Display Color Volume box\n");
6354  return AVERROR_INVALIDDATA;
6355  }
6356 
6357  if (sc->mastering) {
6358  av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicate Mastering Display Color Volume\n");
6359  return 0;
6360  }
6361 
6363  if (!sc->mastering)
6364  return AVERROR(ENOMEM);
6365 
6366  for (i = 0; i < 3; i++) {
6367  const int j = mapping[i];
6368  sc->mastering->display_primaries[j][0] = av_make_q(avio_rb16(pb), chroma_den);
6369  sc->mastering->display_primaries[j][1] = av_make_q(avio_rb16(pb), chroma_den);
6370  }
6371  sc->mastering->white_point[0] = av_make_q(avio_rb16(pb), chroma_den);
6372  sc->mastering->white_point[1] = av_make_q(avio_rb16(pb), chroma_den);
6373 
6374  sc->mastering->max_luminance = av_make_q(avio_rb32(pb), luma_den);
6375  sc->mastering->min_luminance = av_make_q(avio_rb32(pb), luma_den);
6376 
6377  sc->mastering->has_luminance = 1;
6378  sc->mastering->has_primaries = 1;
6379 
6380  return 0;
6381 }
6382 
6384 {
6385  MOVStreamContext *sc;
6386  int version;
6387 
6388  if (c->fc->nb_streams < 1)
6389  return AVERROR_INVALIDDATA;
6390 
6391  sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
6392 
6393  if (atom.size < 5) {
6394  av_log(c->fc, AV_LOG_ERROR, "Empty Content Light Level box\n");
6395  return AVERROR_INVALIDDATA;
6396  }
6397 
6398  version = avio_r8(pb);
6399  if (version) {
6400  av_log(c->fc, AV_LOG_WARNING, "Unsupported Content Light Level box version %d\n", version);
6401  return 0;
6402  }
6403  avio_skip(pb, 3); /* flags */
6404 
6405  if (sc->coll){
6406  av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicate COLL\n");
6407  return 0;
6408  }
6409 
6411  if (!sc->coll)
6412  return AVERROR(ENOMEM);
6413 
6414  sc->coll->MaxCLL = avio_rb16(pb);
6415  sc->coll->MaxFALL = avio_rb16(pb);
6416 
6417  return 0;
6418 }
6419 
6421 {
6422  MOVStreamContext *sc;
6423 
6424  if (c->fc->nb_streams < 1)
6425  return AVERROR_INVALIDDATA;
6426 
6427  sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
6428 
6429  if (atom.size < 4) {
6430  av_log(c->fc, AV_LOG_ERROR, "Empty Content Light Level Info box\n");
6431  return AVERROR_INVALIDDATA;
6432  }
6433 
6434  if (sc->coll){
6435  av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicate CLLI/COLL\n");
6436  return 0;
6437  }
6438 
6440  if (!sc->coll)
6441  return AVERROR(ENOMEM);
6442 
6443  sc->coll->MaxCLL = avio_rb16(pb);
6444  sc->coll->MaxFALL = avio_rb16(pb);
6445 
6446  return 0;
6447 }
6448 
6450 {
6451  MOVStreamContext *sc;
6452  const int illuminance_den = 10000;
6453  const int ambient_den = 50000;
6454  if (c->fc->nb_streams < 1)
6455  return AVERROR_INVALIDDATA;
6456  sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
6457  if (atom.size < 6) {
6458  av_log(c->fc, AV_LOG_ERROR, "Empty Ambient Viewing Environment Info box\n");
6459  return AVERROR_INVALIDDATA;
6460  }
6461  if (sc->ambient){
6462  av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicate AMVE\n");
6463  return 0;
6464  }
6466  if (!sc->ambient)
6467  return AVERROR(ENOMEM);
6468  sc->ambient->ambient_illuminance = av_make_q(avio_rb32(pb), illuminance_den);
6469  sc->ambient->ambient_light_x = av_make_q(avio_rb16(pb), ambient_den);
6470  sc->ambient->ambient_light_y = av_make_q(avio_rb16(pb), ambient_den);
6471  return 0;
6472 }
6473 
6475 {
6476  AVStream *st;
6477  MOVStreamContext *sc;
6478  enum AVStereo3DType type;
6479  int mode;
6480 
6481  if (c->fc->nb_streams < 1)
6482  return 0;
6483 
6484  st = c->fc->streams[c->fc->nb_streams - 1];
6485  sc = st->priv_data;
6486 
6487  if (atom.size < 5) {
6488  av_log(c->fc, AV_LOG_ERROR, "Empty stereoscopic video box\n");
6489  return AVERROR_INVALIDDATA;
6490  }
6491 
6492  if (sc->stereo3d)
6493  return AVERROR_INVALIDDATA;
6494 
6495  avio_skip(pb, 4); /* version + flags */
6496 
6497  mode = avio_r8(pb);
6498  switch (mode) {
6499  case 0:
6500  type = AV_STEREO3D_2D;
6501  break;
6502  case 1:
6504  break;
6505  case 2:
6507  break;
6508  default:
6509  av_log(c->fc, AV_LOG_WARNING, "Unknown st3d mode value %d\n", mode);
6510  return 0;
6511  }
6512 
6514  if (!sc->stereo3d)
6515  return AVERROR(ENOMEM);
6516 
6517  sc->stereo3d->type = type;
6518  return 0;
6519 }
6520 
6522 {
6523  AVStream *st;
6524  MOVStreamContext *sc;
6525  int size, version, layout;
6526  int32_t yaw, pitch, roll;
6527  uint32_t l = 0, t = 0, r = 0, b = 0;
6528  uint32_t tag, padding = 0;
6529  enum AVSphericalProjection projection;
6530 
6531  if (c->fc->nb_streams < 1)
6532  return 0;
6533 
6534  st = c->fc->streams[c->fc->nb_streams - 1];
6535  sc = st->priv_data;
6536 
6537  if (atom.size < 8) {
6538  av_log(c->fc, AV_LOG_ERROR, "Empty spherical video box\n");
6539  return AVERROR_INVALIDDATA;
6540  }
6541 
6542  size = avio_rb32(pb);
6543  if (size <= 12 || size > atom.size)
6544  return AVERROR_INVALIDDATA;
6545 
6546  tag = avio_rl32(pb);
6547  if (tag != MKTAG('s','v','h','d')) {
6548  av_log(c->fc, AV_LOG_ERROR, "Missing spherical video header\n");
6549  return 0;
6550  }
6551  version = avio_r8(pb);
6552  if (version != 0) {
6553  av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
6554  version);
6555  return 0;
6556  }
6557  avio_skip(pb, 3); /* flags */
6558  avio_skip(pb, size - 12); /* metadata_source */
6559 
6560  size = avio_rb32(pb);
6561  if (size > atom.size)
6562  return AVERROR_INVALIDDATA;
6563 
6564  tag = avio_rl32(pb);
6565  if (tag != MKTAG('p','r','o','j')) {
6566  av_log(c->fc, AV_LOG_ERROR, "Missing projection box\n");
6567  return 0;
6568  }
6569 
6570  size = avio_rb32(pb);
6571  if (size > atom.size)
6572  return AVERROR_INVALIDDATA;
6573 
6574  tag = avio_rl32(pb);
6575  if (tag != MKTAG('p','r','h','d')) {
6576  av_log(c->fc, AV_LOG_ERROR, "Missing projection header box\n");
6577  return 0;
6578  }
6579  version = avio_r8(pb);
6580  if (version != 0) {
6581  av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
6582  version);
6583  return 0;
6584  }
6585  avio_skip(pb, 3); /* flags */
6586 
6587  /* 16.16 fixed point */
6588  yaw = avio_rb32(pb);
6589  pitch = avio_rb32(pb);
6590  roll = avio_rb32(pb);
6591 
6592  size = avio_rb32(pb);
6593  if (size > atom.size)
6594  return AVERROR_INVALIDDATA;
6595 
6596  tag = avio_rl32(pb);
6597  version = avio_r8(pb);
6598  if (version != 0) {
6599  av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
6600  version);
6601  return 0;
6602  }
6603  avio_skip(pb, 3); /* flags */
6604  switch (tag) {
6605  case MKTAG('c','b','m','p'):
6606  layout = avio_rb32(pb);
6607  if (layout) {
6608  av_log(c->fc, AV_LOG_WARNING,
6609  "Unsupported cubemap layout %d\n", layout);
6610  return 0;
6611  }
6612  projection = AV_SPHERICAL_CUBEMAP;
6613  padding = avio_rb32(pb);
6614  break;
6615  case MKTAG('e','q','u','i'):
6616  t = avio_rb32(pb);
6617  b = avio_rb32(pb);
6618  l = avio_rb32(pb);
6619  r = avio_rb32(pb);
6620 
6621  if (b >= UINT_MAX - t || r >= UINT_MAX - l) {
6622  av_log(c->fc, AV_LOG_ERROR,
6623  "Invalid bounding rectangle coordinates "
6624  "%"PRIu32",%"PRIu32",%"PRIu32",%"PRIu32"\n", l, t, r, b);
6625  return AVERROR_INVALIDDATA;
6626  }
6627 
6628  if (l || t || r || b)
6629  projection = AV_SPHERICAL_EQUIRECTANGULAR_TILE;
6630  else
6631  projection = AV_SPHERICAL_EQUIRECTANGULAR;
6632  break;
6633  default:
6634  av_log(c->fc, AV_LOG_ERROR, "Unknown projection type: %s\n", av_fourcc2str(tag));
6635  return 0;
6636  }
6637 
6639  if (!sc->spherical)
6640  return AVERROR(ENOMEM);
6641 
6642  sc->spherical->projection = projection;
6643 
6644  sc->spherical->yaw = yaw;
6645  sc->spherical->pitch = pitch;
6646  sc->spherical->roll = roll;
6647 
6648  sc->spherical->padding = padding;
6649 
6650  sc->spherical->bound_left = l;
6651  sc->spherical->bound_top = t;
6652  sc->spherical->bound_right = r;
6653  sc->spherical->bound_bottom = b;
6654 
6655  return 0;
6656 }
6657 
6659 {
6660  AVStream *st;
6661  MOVStreamContext *sc;
6662  int size;
6663  uint32_t tag;
6664  enum AVSphericalProjection projection;
6665 
6666  if (c->fc->nb_streams < 1)
6667  return 0;
6668 
6669  st = c->fc->streams[c->fc->nb_streams - 1];
6670  sc = st->priv_data;
6671 
6672  if (atom.size != 16) {
6673  av_log(c->fc, AV_LOG_ERROR, "Invalid size for proj box: %"PRIu64"\n", atom.size);
6674  return AVERROR_INVALIDDATA;
6675  }
6676 
6677  size = avio_rb32(pb);
6678  if (size != 16) {
6679  av_log(c->fc, AV_LOG_ERROR, "Invalid size for prji box: %d\n", size);
6680  return AVERROR_INVALIDDATA;
6681  }
6682 
6683  tag = avio_rl32(pb);
6684  if (tag != MKTAG('p','r','j','i')) {
6685  av_log(c->fc, AV_LOG_ERROR, "Invalid child box of proj box: 0x%08X\n", tag);
6686  return AVERROR_INVALIDDATA;
6687  }
6688 
6689  avio_skip(pb, 1); // version
6690  avio_skip(pb, 3); // flags
6691 
6692  tag = avio_rl32(pb);
6693  switch (tag) {
6694  case MKTAG('r','e','c','t'):
6695  projection = AV_SPHERICAL_RECTILINEAR;
6696  break;
6697  case MKTAG('e','q','u','i'):
6698  projection = AV_SPHERICAL_EQUIRECTANGULAR;
6699  break;
6700  case MKTAG('h','e','q','u'):
6701  projection = AV_SPHERICAL_HALF_EQUIRECTANGULAR;
6702  break;
6703  case MKTAG('f','i','s','h'):
6704  projection = AV_SPHERICAL_FISHEYE;
6705  break;
6706  default:
6707  av_log(c->fc, AV_LOG_ERROR, "Invalid projection type in prji box: 0x%08X\n", tag);
6708  return AVERROR_INVALIDDATA;
6709  }
6710 
6712  if (!sc->spherical)
6713  return AVERROR(ENOMEM);
6714 
6715  sc->spherical->projection = projection;
6716 
6717  return 0;
6718 }
6719 
6721 {
6722  AVStream *st;
6723  MOVStreamContext *sc;
6724  int size, flags = 0;
6725  int64_t remaining;
6726  uint32_t tag, baseline = 0;
6729  enum AVStereo3DPrimaryEye primary_eye = AV_PRIMARY_EYE_NONE;
6730  AVRational horizontal_disparity_adjustment = { 0, 1 };
6731 
6732  if (c->fc->nb_streams < 1)
6733  return 0;
6734 
6735  st = c->fc->streams[c->fc->nb_streams - 1];
6736  sc = st->priv_data;
6737 
6738  remaining = atom.size;
6739  while (remaining > 0) {
6740  size = avio_rb32(pb);
6741  if (size < 8 || size > remaining ) {
6742  av_log(c->fc, AV_LOG_ERROR, "Invalid child size in eyes box\n");
6743  return AVERROR_INVALIDDATA;
6744  }
6745 
6746  tag = avio_rl32(pb);
6747  switch (tag) {
6748  case MKTAG('s','t','r','i'): {
6749  int has_right, has_left;
6750  uint8_t tmp;
6751  if (size != 13) {
6752  av_log(c->fc, AV_LOG_ERROR, "Invalid size of stri box: %d\n", size);
6753  return AVERROR_INVALIDDATA;
6754  }
6755  avio_skip(pb, 1); // version
6756  avio_skip(pb, 3); // flags
6757 
6758  tmp = avio_r8(pb);
6759 
6760  // eye_views_reversed
6761  if (tmp & 8) {
6763  }
6764  // has_additional_views
6765  if (tmp & 4) {
6766  // skip...
6767  }
6768 
6769  has_right = tmp & 2; // has_right_eye_view
6770  has_left = tmp & 1; // has_left_eye_view
6771 
6772  if (has_left && has_right)
6773  view = AV_STEREO3D_VIEW_PACKED;
6774  else if (has_left)
6775  view = AV_STEREO3D_VIEW_LEFT;
6776  else if (has_right)
6777  view = AV_STEREO3D_VIEW_RIGHT;
6778  if (has_left || has_right)
6780 
6781  break;
6782  }
6783  case MKTAG('h','e','r','o'): {
6784  int tmp;
6785  if (size != 13) {
6786  av_log(c->fc, AV_LOG_ERROR, "Invalid size of hero box: %d\n", size);
6787  return AVERROR_INVALIDDATA;
6788  }
6789  avio_skip(pb, 1); // version
6790  avio_skip(pb, 3); // flags
6791 
6792  tmp = avio_r8(pb);
6793  if (tmp == 0)
6794  primary_eye = AV_PRIMARY_EYE_NONE;
6795  else if (tmp == 1)
6796  primary_eye = AV_PRIMARY_EYE_LEFT;
6797  else if (tmp == 2)
6798  primary_eye = AV_PRIMARY_EYE_RIGHT;
6799  else
6800  av_log(c->fc, AV_LOG_WARNING, "Unknown hero eye type: %d\n", tmp);
6801 
6802  break;
6803  }
6804  case MKTAG('c','a','m','s'): {
6805  uint32_t subtag;
6806  int subsize;
6807  if (size != 24) {
6808  av_log(c->fc, AV_LOG_ERROR, "Invalid size of cams box: %d\n", size);
6809  return AVERROR_INVALIDDATA;
6810  }
6811 
6812  subsize = avio_rb32(pb);
6813  if (subsize != 16) {
6814  av_log(c->fc, AV_LOG_ERROR, "Invalid size of blin box: %d\n", size);
6815  return AVERROR_INVALIDDATA;
6816  }
6817 
6818  subtag = avio_rl32(pb);
6819  if (subtag != MKTAG('b','l','i','n')) {
6820  av_log(c->fc, AV_LOG_ERROR, "Expected blin box, got 0x%08X\n", subtag);
6821  return AVERROR_INVALIDDATA;
6822  }
6823 
6824  avio_skip(pb, 1); // version
6825  avio_skip(pb, 3); // flags
6826 
6827  baseline = avio_rb32(pb);
6828 
6829  break;
6830  }
6831  case MKTAG('c','m','f','y'): {
6832  uint32_t subtag;
6833  int subsize;
6834  int32_t adjustment;
6835  if (size != 24) {
6836  av_log(c->fc, AV_LOG_ERROR, "Invalid size of cmfy box: %d\n", size);
6837  return AVERROR_INVALIDDATA;
6838  }
6839 
6840  subsize = avio_rb32(pb);
6841  if (subsize != 16) {
6842  av_log(c->fc, AV_LOG_ERROR, "Invalid size of dadj box: %d\n", size);
6843  return AVERROR_INVALIDDATA;
6844  }
6845 
6846  subtag = avio_rl32(pb);
6847  if (subtag != MKTAG('d','a','d','j')) {
6848  av_log(c->fc, AV_LOG_ERROR, "Expected dadj box, got 0x%08X\n", subtag);
6849  return AVERROR_INVALIDDATA;
6850  }
6851 
6852  avio_skip(pb, 1); // version
6853  avio_skip(pb, 3); // flags
6854 
6855  adjustment = (int32_t) avio_rb32(pb);
6856 
6857  horizontal_disparity_adjustment.num = (int) adjustment;
6858  horizontal_disparity_adjustment.den = 10000;
6859 
6860  break;
6861  }
6862  default:
6863  av_log(c->fc, AV_LOG_WARNING, "Unknown tag in eyes: 0x%08X\n", tag);
6864  avio_skip(pb, size - 8);
6865  break;
6866  }
6867  remaining -= size;
6868  }
6869 
6870  if (remaining != 0) {
6871  av_log(c->fc, AV_LOG_ERROR, "Broken eyes box\n");
6872  return AVERROR_INVALIDDATA;
6873  }
6874 
6875  if (type == AV_STEREO3D_2D)
6876  return 0;
6877 
6878  if (!sc->stereo3d) {
6880  if (!sc->stereo3d)
6881  return AVERROR(ENOMEM);
6882  }
6883 
6884  sc->stereo3d->flags = flags;
6885  sc->stereo3d->type = type;
6886  sc->stereo3d->view = view;
6887  sc->stereo3d->primary_eye = primary_eye;
6888  sc->stereo3d->baseline = baseline;
6889  sc->stereo3d->horizontal_disparity_adjustment = horizontal_disparity_adjustment;
6890 
6891  return 0;
6892 }
6893 
6895 {
6896  int size;
6897  int64_t remaining;
6898  uint32_t tag;
6899 
6900  if (c->fc->nb_streams < 1)
6901  return 0;
6902 
6903  if (atom.size < 8) {
6904  av_log(c->fc, AV_LOG_ERROR, "Empty video extension usage box\n");
6905  return AVERROR_INVALIDDATA;
6906  }
6907 
6908  remaining = atom.size;
6909  while (remaining > 0) {
6910  size = avio_rb32(pb);
6911  if (size < 8 || size > remaining ) {
6912  av_log(c->fc, AV_LOG_ERROR, "Invalid child size in vexu box\n");
6913  return AVERROR_INVALIDDATA;
6914  }
6915 
6916  tag = avio_rl32(pb);
6917  switch (tag) {
6918  case MKTAG('p','r','o','j'): {
6919  MOVAtom proj = { tag, size - 8 };
6920  int ret = mov_read_vexu_proj(c, pb, proj);
6921  if (ret < 0)
6922  return ret;
6923  break;
6924  }
6925  case MKTAG('e','y','e','s'): {
6926  MOVAtom eyes = { tag, size - 8 };
6927  int ret = mov_read_eyes(c, pb, eyes);
6928  if (ret < 0)
6929  return ret;
6930  break;
6931  }
6932  default:
6933  av_log(c->fc, AV_LOG_WARNING, "Unknown tag in vexu: 0x%08X\n", tag);
6934  avio_skip(pb, size - 8);
6935  break;
6936  }
6937  remaining -= size;
6938  }
6939 
6940  if (remaining != 0) {
6941  av_log(c->fc, AV_LOG_ERROR, "Broken vexu box\n");
6942  return AVERROR_INVALIDDATA;
6943  }
6944 
6945  return 0;
6946 }
6947 
6949 {
6950  AVStream *st;
6951  MOVStreamContext *sc;
6952 
6953  if (c->fc->nb_streams < 1)
6954  return 0;
6955 
6956  st = c->fc->streams[c->fc->nb_streams - 1];
6957  sc = st->priv_data;
6958 
6959  if (atom.size != 4) {
6960  av_log(c->fc, AV_LOG_ERROR, "Invalid size of hfov box: %"PRIu64"\n", atom.size);
6961  return AVERROR_INVALIDDATA;
6962  }
6963 
6964 
6965  if (!sc->stereo3d) {
6967  if (!sc->stereo3d)
6968  return AVERROR(ENOMEM);
6969  }
6970 
6972  sc->stereo3d->horizontal_field_of_view.den = 1000; // thousands of a degree
6973 
6974  return 0;
6975 }
6976 
6978 {
6979  int ret = 0;
6980  uint8_t *buffer = av_malloc(len + 1);
6981  const char *val;
6982 
6983  if (!buffer)
6984  return AVERROR(ENOMEM);
6985  buffer[len] = '\0';
6986 
6987  ret = ffio_read_size(pb, buffer, len);
6988  if (ret < 0)
6989  goto out;
6990 
6991  /* Check for mandatory keys and values, try to support XML as best-effort */
6992  if (!sc->spherical &&
6993  av_stristr(buffer, "<GSpherical:StitchingSoftware>") &&
6994  (val = av_stristr(buffer, "<GSpherical:Spherical>")) &&
6995  av_stristr(val, "true") &&
6996  (val = av_stristr(buffer, "<GSpherical:Stitched>")) &&
6997  av_stristr(val, "true") &&
6998  (val = av_stristr(buffer, "<GSpherical:ProjectionType>")) &&
6999  av_stristr(val, "equirectangular")) {
7001  if (!sc->spherical)
7002  goto out;
7003 
7005 
7006  if (av_stristr(buffer, "<GSpherical:StereoMode>") && !sc->stereo3d) {
7007  enum AVStereo3DType mode;
7008 
7009  if (av_stristr(buffer, "left-right"))
7011  else if (av_stristr(buffer, "top-bottom"))
7013  else
7014  mode = AV_STEREO3D_2D;
7015 
7017  if (!sc->stereo3d)
7018  goto out;
7019 
7020  sc->stereo3d->type = mode;
7021  }
7022 
7023  /* orientation */
7024  val = av_stristr(buffer, "<GSpherical:InitialViewHeadingDegrees>");
7025  if (val)
7026  sc->spherical->yaw = strtol(val, NULL, 10) * (1 << 16);
7027  val = av_stristr(buffer, "<GSpherical:InitialViewPitchDegrees>");
7028  if (val)
7029  sc->spherical->pitch = strtol(val, NULL, 10) * (1 << 16);
7030  val = av_stristr(buffer, "<GSpherical:InitialViewRollDegrees>");
7031  if (val)
7032  sc->spherical->roll = strtol(val, NULL, 10) * (1 << 16);
7033  }
7034 
7035 out:
7036  av_free(buffer);
7037  return ret;
7038 }
7039 
7041 {
7042  AVStream *st;
7043  MOVStreamContext *sc;
7044  int64_t ret;
7045  AVUUID uuid;
7046  static const AVUUID uuid_isml_manifest = {
7047  0xa5, 0xd4, 0x0b, 0x30, 0xe8, 0x14, 0x11, 0xdd,
7048  0xba, 0x2f, 0x08, 0x00, 0x20, 0x0c, 0x9a, 0x66
7049  };
7050  static const AVUUID uuid_xmp = {
7051  0xbe, 0x7a, 0xcf, 0xcb, 0x97, 0xa9, 0x42, 0xe8,
7052  0x9c, 0x71, 0x99, 0x94, 0x91, 0xe3, 0xaf, 0xac
7053  };
7054  static const AVUUID uuid_spherical = {
7055  0xff, 0xcc, 0x82, 0x63, 0xf8, 0x55, 0x4a, 0x93,
7056  0x88, 0x14, 0x58, 0x7a, 0x02, 0x52, 0x1f, 0xdd,
7057  };
7058 
7059  if (atom.size < AV_UUID_LEN || atom.size >= FFMIN(INT_MAX, SIZE_MAX))
7060  return AVERROR_INVALIDDATA;
7061 
7062  if (c->fc->nb_streams < 1)
7063  return 0;
7064  st = c->fc->streams[c->fc->nb_streams - 1];
7065  sc = st->priv_data;
7066 
7067  ret = ffio_read_size(pb, uuid, AV_UUID_LEN);
7068  if (ret < 0)
7069  return ret;
7070  if (av_uuid_equal(uuid, uuid_isml_manifest)) {
7071  uint8_t *buffer, *ptr;
7072  char *endptr;
7073  size_t len = atom.size - AV_UUID_LEN;
7074 
7075  if (len < 4) {
7076  return AVERROR_INVALIDDATA;
7077  }
7078  ret = avio_skip(pb, 4); // zeroes
7079  len -= 4;
7080 
7081  buffer = av_mallocz(len + 1);
7082  if (!buffer) {
7083  return AVERROR(ENOMEM);
7084  }
7085  ret = ffio_read_size(pb, buffer, len);
7086  if (ret < 0) {
7087  av_free(buffer);
7088  return ret;
7089  }
7090 
7091  ptr = buffer;
7092  while ((ptr = av_stristr(ptr, "systemBitrate=\""))) {
7093  ptr += sizeof("systemBitrate=\"") - 1;
7094  c->bitrates_count++;
7095  c->bitrates = av_realloc_f(c->bitrates, c->bitrates_count, sizeof(*c->bitrates));
7096  if (!c->bitrates) {
7097  c->bitrates_count = 0;
7098  av_free(buffer);
7099  return AVERROR(ENOMEM);
7100  }
7101  errno = 0;
7102  ret = strtol(ptr, &endptr, 10);
7103  if (ret < 0 || errno || *endptr != '"') {
7104  c->bitrates[c->bitrates_count - 1] = 0;
7105  } else {
7106  c->bitrates[c->bitrates_count - 1] = ret;
7107  }
7108  }
7109 
7110  av_free(buffer);
7111  } else if (av_uuid_equal(uuid, uuid_xmp)) {
7112  uint8_t *buffer;
7113  size_t len = atom.size - AV_UUID_LEN;
7114  if (c->export_xmp) {
7115  buffer = av_mallocz(len + 1);
7116  if (!buffer) {
7117  return AVERROR(ENOMEM);
7118  }
7119  ret = ffio_read_size(pb, buffer, len);
7120  if (ret < 0) {
7121  av_free(buffer);
7122  return ret;
7123  }
7124  buffer[len] = '\0';
7125  av_dict_set(&c->fc->metadata, "xmp",
7127  } else {
7128  // skip all uuid atom, which makes it fast for long uuid-xmp file
7129  ret = avio_skip(pb, len);
7130  if (ret < 0)
7131  return ret;
7132  }
7133  } else if (av_uuid_equal(uuid, uuid_spherical)) {
7134  size_t len = atom.size - AV_UUID_LEN;
7135  ret = mov_parse_uuid_spherical(sc, pb, len);
7136  if (ret < 0)
7137  return ret;
7138  if (!sc->spherical)
7139  av_log(c->fc, AV_LOG_WARNING, "Invalid spherical metadata found\n");
7140  }
7141 
7142  return 0;
7143 }
7144 
7146 {
7147  int ret;
7148  uint8_t content[16];
7149 
7150  if (atom.size < 8)
7151  return 0;
7152 
7153  ret = ffio_read_size(pb, content, FFMIN(sizeof(content), atom.size));
7154  if (ret < 0)
7155  return ret;
7156 
7157  if ( !c->found_moov
7158  && !c->found_mdat
7159  && !memcmp(content, "Anevia\x1A\x1A", 8)
7160  && c->use_mfra_for == FF_MOV_FLAG_MFRA_AUTO) {
7161  c->use_mfra_for = FF_MOV_FLAG_MFRA_PTS;
7162  }
7163 
7164  return 0;
7165 }
7166 
7168 {
7169  uint32_t format = avio_rl32(pb);
7170  MOVStreamContext *sc;
7171  enum AVCodecID id;
7172  AVStream *st;
7173 
7174  if (c->fc->nb_streams < 1)
7175  return 0;
7176  st = c->fc->streams[c->fc->nb_streams - 1];
7177  sc = st->priv_data;
7178 
7179  switch (sc->format)
7180  {
7181  case MKTAG('e','n','c','v'): // encrypted video
7182  case MKTAG('e','n','c','a'): // encrypted audio
7183  id = mov_codec_id(st, format);
7184  if (st->codecpar->codec_id != AV_CODEC_ID_NONE &&
7185  st->codecpar->codec_id != id) {
7186  av_log(c->fc, AV_LOG_WARNING,
7187  "ignoring 'frma' atom of '%.4s', stream has codec id %d\n",
7188  (char*)&format, st->codecpar->codec_id);
7189  break;
7190  }
7191 
7192  st->codecpar->codec_id = id;
7193  sc->format = format;
7194  break;
7195 
7196  default:
7197  if (format != sc->format) {
7198  av_log(c->fc, AV_LOG_WARNING,
7199  "ignoring 'frma' atom of '%.4s', stream format is '%.4s'\n",
7200  (char*)&format, (char*)&sc->format);
7201  }
7202  break;
7203  }
7204 
7205  return 0;
7206 }
7207 
7208 /**
7209  * Gets the current encryption info and associated current stream context. If
7210  * we are parsing a track fragment, this will return the specific encryption
7211  * info for this fragment; otherwise this will return the global encryption
7212  * info for the current stream.
7213  */
7215 {
7216  MOVFragmentStreamInfo *frag_stream_info;
7217  AVStream *st;
7218  int i;
7219 
7220  frag_stream_info = get_current_frag_stream_info(&c->frag_index);
7221  if (frag_stream_info) {
7222  for (i = 0; i < c->fc->nb_streams; i++) {
7223  *sc = c->fc->streams[i]->priv_data;
7224  if ((*sc)->id == frag_stream_info->id) {
7225  st = c->fc->streams[i];
7226  break;
7227  }
7228  }
7229  if (i == c->fc->nb_streams)
7230  return 0;
7231  *sc = st->priv_data;
7232 
7233  if (!frag_stream_info->encryption_index) {
7234  // If this stream isn't encrypted, don't create the index.
7235  if (!(*sc)->cenc.default_encrypted_sample)
7236  return 0;
7237  frag_stream_info->encryption_index = av_mallocz(sizeof(*frag_stream_info->encryption_index));
7238  if (!frag_stream_info->encryption_index)
7239  return AVERROR(ENOMEM);
7240  }
7241  *encryption_index = frag_stream_info->encryption_index;
7242  return 1;
7243  } else {
7244  // No current track fragment, using stream level encryption info.
7245 
7246  if (c->fc->nb_streams < 1)
7247  return 0;
7248  st = c->fc->streams[c->fc->nb_streams - 1];
7249  *sc = st->priv_data;
7250 
7251  if (!(*sc)->cenc.encryption_index) {
7252  // If this stream isn't encrypted, don't create the index.
7253  if (!(*sc)->cenc.default_encrypted_sample)
7254  return 0;
7255  (*sc)->cenc.encryption_index = av_mallocz(sizeof(*frag_stream_info->encryption_index));
7256  if (!(*sc)->cenc.encryption_index)
7257  return AVERROR(ENOMEM);
7258  }
7259 
7260  *encryption_index = (*sc)->cenc.encryption_index;
7261  return 1;
7262  }
7263 }
7264 
7266 {
7267  int i, ret;
7268  unsigned int subsample_count;
7269  AVSubsampleEncryptionInfo *subsamples;
7270 
7271  if (!sc->cenc.default_encrypted_sample) {
7272  av_log(c->fc, AV_LOG_ERROR, "Missing schm or tenc\n");
7273  return AVERROR_INVALIDDATA;
7274  }
7275 
7276  if (sc->cenc.per_sample_iv_size || use_subsamples) {
7278  if (!*sample)
7279  return AVERROR(ENOMEM);
7280  } else
7281  *sample = NULL;
7282 
7283  if (sc->cenc.per_sample_iv_size != 0) {
7284  if ((ret = ffio_read_size(pb, (*sample)->iv, sc->cenc.per_sample_iv_size)) < 0) {
7285  av_log(c->fc, AV_LOG_ERROR, "failed to read the initialization vector\n");
7287  *sample = NULL;
7288  return ret;
7289  }
7290  }
7291 
7292  if (use_subsamples) {
7293  subsample_count = avio_rb16(pb);
7294  av_free((*sample)->subsamples);
7295  (*sample)->subsamples = av_calloc(subsample_count, sizeof(*subsamples));
7296  if (!(*sample)->subsamples) {
7298  *sample = NULL;
7299  return AVERROR(ENOMEM);
7300  }
7301 
7302  for (i = 0; i < subsample_count && !pb->eof_reached; i++) {
7303  (*sample)->subsamples[i].bytes_of_clear_data = avio_rb16(pb);
7304  (*sample)->subsamples[i].bytes_of_protected_data = avio_rb32(pb);
7305  }
7306 
7307  if (pb->eof_reached) {
7308  av_log(c->fc, AV_LOG_ERROR, "hit EOF while reading sub-sample encryption info\n");
7310  *sample = NULL;
7311  return AVERROR_INVALIDDATA;
7312  }
7313  (*sample)->subsample_count = subsample_count;
7314  }
7315 
7316  return 0;
7317 }
7318 
7320 {
7321  AVEncryptionInfo **encrypted_samples;
7322  MOVEncryptionIndex *encryption_index;
7323  MOVStreamContext *sc;
7324  int use_subsamples, ret;
7325  unsigned int sample_count, i, alloc_size = 0;
7326 
7327  ret = get_current_encryption_info(c, &encryption_index, &sc);
7328  if (ret != 1)
7329  return ret;
7330 
7331  if (encryption_index->nb_encrypted_samples) {
7332  // This can happen if we have both saio/saiz and senc atoms.
7333  av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in senc\n");
7334  return 0;
7335  }
7336 
7337  avio_r8(pb); /* version */
7338  use_subsamples = avio_rb24(pb) & 0x02; /* flags */
7339 
7340  sample_count = avio_rb32(pb);
7341  if (sample_count >= INT_MAX / sizeof(*encrypted_samples))
7342  return AVERROR(ENOMEM);
7343 
7344  for (i = 0; i < sample_count; i++) {
7345  unsigned int min_samples = FFMIN(FFMAX(i + 1, 1024 * 1024), sample_count);
7346  encrypted_samples = av_fast_realloc(encryption_index->encrypted_samples, &alloc_size,
7347  min_samples * sizeof(*encrypted_samples));
7348  if (encrypted_samples) {
7349  encryption_index->encrypted_samples = encrypted_samples;
7350 
7352  c, pb, sc, &encryption_index->encrypted_samples[i], use_subsamples);
7353  } else {
7354  ret = AVERROR(ENOMEM);
7355  }
7356  if (pb->eof_reached) {
7357  av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading senc\n");
7358  if (ret >= 0)
7359  av_encryption_info_free(encryption_index->encrypted_samples[i]);
7361  }
7362 
7363  if (ret < 0) {
7364  for (; i > 0; i--)
7365  av_encryption_info_free(encryption_index->encrypted_samples[i - 1]);
7366  av_freep(&encryption_index->encrypted_samples);
7367  return ret;
7368  }
7369  }
7370  encryption_index->nb_encrypted_samples = sample_count;
7371 
7372  return 0;
7373 }
7374 
7376 {
7377  AVEncryptionInfo **sample, **encrypted_samples;
7378  int64_t prev_pos;
7379  size_t sample_count, sample_info_size, i;
7380  int ret = 0;
7381  unsigned int alloc_size = 0;
7382 
7383  if (encryption_index->nb_encrypted_samples)
7384  return 0;
7385  sample_count = encryption_index->auxiliary_info_sample_count;
7386  if (encryption_index->auxiliary_offsets_count != 1) {
7387  av_log(c->fc, AV_LOG_ERROR, "Multiple auxiliary info chunks are not supported\n");
7388  return AVERROR_PATCHWELCOME;
7389  }
7390  if (sample_count >= INT_MAX / sizeof(*encrypted_samples))
7391  return AVERROR(ENOMEM);
7392 
7393  prev_pos = avio_tell(pb);
7394  if (!(pb->seekable & AVIO_SEEKABLE_NORMAL) ||
7395  avio_seek(pb, encryption_index->auxiliary_offsets[0], SEEK_SET) != encryption_index->auxiliary_offsets[0]) {
7396  av_log(c->fc, AV_LOG_INFO, "Failed to seek for auxiliary info, will only parse senc atoms for encryption info\n");
7397  goto finish;
7398  }
7399 
7400  for (i = 0; i < sample_count && !pb->eof_reached; i++) {
7401  unsigned int min_samples = FFMIN(FFMAX(i + 1, 1024 * 1024), sample_count);
7402  encrypted_samples = av_fast_realloc(encryption_index->encrypted_samples, &alloc_size,
7403  min_samples * sizeof(*encrypted_samples));
7404  if (!encrypted_samples) {
7405  ret = AVERROR(ENOMEM);
7406  goto finish;
7407  }
7408  encryption_index->encrypted_samples = encrypted_samples;
7409 
7410  sample = &encryption_index->encrypted_samples[i];
7411  sample_info_size = encryption_index->auxiliary_info_default_size
7412  ? encryption_index->auxiliary_info_default_size
7413  : encryption_index->auxiliary_info_sizes[i];
7414 
7415  ret = mov_read_sample_encryption_info(c, pb, sc, sample, sample_info_size > sc->cenc.per_sample_iv_size);
7416  if (ret < 0)
7417  goto finish;
7418  }
7419  if (pb->eof_reached) {
7420  av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading auxiliary info\n");
7422  } else {
7423  encryption_index->nb_encrypted_samples = sample_count;
7424  }
7425 
7426 finish:
7427  avio_seek(pb, prev_pos, SEEK_SET);
7428  if (ret < 0) {
7429  for (; i > 0; i--) {
7430  av_encryption_info_free(encryption_index->encrypted_samples[i - 1]);
7431  }
7432  av_freep(&encryption_index->encrypted_samples);
7433  }
7434  return ret;
7435 }
7436 
7438 {
7439  MOVEncryptionIndex *encryption_index;
7440  MOVStreamContext *sc;
7441  int ret;
7442  unsigned int sample_count, aux_info_type, aux_info_param;
7443 
7444  ret = get_current_encryption_info(c, &encryption_index, &sc);
7445  if (ret != 1)
7446  return ret;
7447 
7448  if (encryption_index->nb_encrypted_samples) {
7449  // This can happen if we have both saio/saiz and senc atoms.
7450  av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in saiz\n");
7451  return 0;
7452  }
7453 
7454  if (encryption_index->auxiliary_info_sample_count) {
7455  av_log(c->fc, AV_LOG_ERROR, "Duplicate saiz atom\n");
7456  return AVERROR_INVALIDDATA;
7457  }
7458 
7459  avio_r8(pb); /* version */
7460  if (avio_rb24(pb) & 0x01) { /* flags */
7461  aux_info_type = avio_rb32(pb);
7462  aux_info_param = avio_rb32(pb);
7463  if (sc->cenc.default_encrypted_sample) {
7464  if (aux_info_type != sc->cenc.default_encrypted_sample->scheme) {
7465  av_log(c->fc, AV_LOG_DEBUG, "Ignoring saiz box with non-zero aux_info_type\n");
7466  return 0;
7467  }
7468  if (aux_info_param != 0) {
7469  av_log(c->fc, AV_LOG_DEBUG, "Ignoring saiz box with non-zero aux_info_type_parameter\n");
7470  return 0;
7471  }
7472  } else {
7473  // Didn't see 'schm' or 'tenc', so this isn't encrypted.
7474  if ((aux_info_type == MKBETAG('c','e','n','c') ||
7475  aux_info_type == MKBETAG('c','e','n','s') ||
7476  aux_info_type == MKBETAG('c','b','c','1') ||
7477  aux_info_type == MKBETAG('c','b','c','s')) &&
7478  aux_info_param == 0) {
7479  av_log(c->fc, AV_LOG_ERROR, "Saw encrypted saiz without schm/tenc\n");
7480  return AVERROR_INVALIDDATA;
7481  } else {
7482  return 0;
7483  }
7484  }
7485  } else if (!sc->cenc.default_encrypted_sample) {
7486  // Didn't see 'schm' or 'tenc', so this isn't encrypted.
7487  return 0;
7488  }
7489 
7490  encryption_index->auxiliary_info_default_size = avio_r8(pb);
7491  sample_count = avio_rb32(pb);
7492 
7493  if (encryption_index->auxiliary_info_default_size == 0) {
7494  if (sample_count == 0)
7495  return AVERROR_INVALIDDATA;
7496 
7497  encryption_index->auxiliary_info_sizes = av_malloc(sample_count);
7498  if (!encryption_index->auxiliary_info_sizes)
7499  return AVERROR(ENOMEM);
7500 
7501  ret = avio_read(pb, encryption_index->auxiliary_info_sizes, sample_count);
7502  if (ret != sample_count) {
7503  av_freep(&encryption_index->auxiliary_info_sizes);
7504 
7505  if (ret >= 0)
7507  av_log(c->fc, AV_LOG_ERROR, "Failed to read the auxiliary info, %s\n",
7508  av_err2str(ret));
7509  return ret;
7510  }
7511  }
7512  encryption_index->auxiliary_info_sample_count = sample_count;
7513 
7514  if (encryption_index->auxiliary_offsets_count) {
7515  return mov_parse_auxiliary_info(c, sc, pb, encryption_index);
7516  }
7517 
7518  return 0;
7519 }
7520 
7522 {
7523  uint64_t *auxiliary_offsets;
7524  MOVEncryptionIndex *encryption_index;
7525  MOVStreamContext *sc;
7526  int i, ret;
7527  unsigned int version, entry_count, aux_info_type, aux_info_param;
7528  unsigned int alloc_size = 0;
7529 
7530  ret = get_current_encryption_info(c, &encryption_index, &sc);
7531  if (ret != 1)
7532  return ret;
7533 
7534  if (encryption_index->nb_encrypted_samples) {
7535  // This can happen if we have both saio/saiz and senc atoms.
7536  av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in saio\n");
7537  return 0;
7538  }
7539 
7540  if (encryption_index->auxiliary_offsets_count) {
7541  av_log(c->fc, AV_LOG_ERROR, "Duplicate saio atom\n");
7542  return AVERROR_INVALIDDATA;
7543  }
7544 
7545  version = avio_r8(pb); /* version */
7546  if (avio_rb24(pb) & 0x01) { /* flags */
7547  aux_info_type = avio_rb32(pb);
7548  aux_info_param = avio_rb32(pb);
7549  if (sc->cenc.default_encrypted_sample) {
7550  if (aux_info_type != sc->cenc.default_encrypted_sample->scheme) {
7551  av_log(c->fc, AV_LOG_DEBUG, "Ignoring saio box with non-zero aux_info_type\n");
7552  return 0;
7553  }
7554  if (aux_info_param != 0) {
7555  av_log(c->fc, AV_LOG_DEBUG, "Ignoring saio box with non-zero aux_info_type_parameter\n");
7556  return 0;
7557  }
7558  } else {
7559  // Didn't see 'schm' or 'tenc', so this isn't encrypted.
7560  if ((aux_info_type == MKBETAG('c','e','n','c') ||
7561  aux_info_type == MKBETAG('c','e','n','s') ||
7562  aux_info_type == MKBETAG('c','b','c','1') ||
7563  aux_info_type == MKBETAG('c','b','c','s')) &&
7564  aux_info_param == 0) {
7565  av_log(c->fc, AV_LOG_ERROR, "Saw encrypted saio without schm/tenc\n");
7566  return AVERROR_INVALIDDATA;
7567  } else {
7568  return 0;
7569  }
7570  }
7571  } else if (!sc->cenc.default_encrypted_sample) {
7572  // Didn't see 'schm' or 'tenc', so this isn't encrypted.
7573  return 0;
7574  }
7575 
7576  entry_count = avio_rb32(pb);
7577  if (entry_count >= INT_MAX / sizeof(*auxiliary_offsets))
7578  return AVERROR(ENOMEM);
7579 
7580  for (i = 0; i < entry_count && !pb->eof_reached; i++) {
7581  unsigned int min_offsets = FFMIN(FFMAX(i + 1, 1024), entry_count);
7582  auxiliary_offsets = av_fast_realloc(
7583  encryption_index->auxiliary_offsets, &alloc_size,
7584  min_offsets * sizeof(*auxiliary_offsets));
7585  if (!auxiliary_offsets) {
7586  av_freep(&encryption_index->auxiliary_offsets);
7587  return AVERROR(ENOMEM);
7588  }
7589  encryption_index->auxiliary_offsets = auxiliary_offsets;
7590 
7591  if (version == 0) {
7592  encryption_index->auxiliary_offsets[i] = avio_rb32(pb);
7593  } else {
7594  encryption_index->auxiliary_offsets[i] = avio_rb64(pb);
7595  }
7596  if (c->frag_index.current >= 0) {
7597  encryption_index->auxiliary_offsets[i] += c->fragment.base_data_offset;
7598  }
7599  }
7600 
7601  if (pb->eof_reached) {
7602  av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading saio\n");
7603  av_freep(&encryption_index->auxiliary_offsets);
7604  return AVERROR_INVALIDDATA;
7605  }
7606 
7607  encryption_index->auxiliary_offsets_count = entry_count;
7608 
7609  if (encryption_index->auxiliary_info_sample_count) {
7610  return mov_parse_auxiliary_info(c, sc, pb, encryption_index);
7611  }
7612 
7613  return 0;
7614 }
7615 
7617 {
7618  AVEncryptionInitInfo *info, *old_init_info;
7619  uint8_t **key_ids;
7620  AVStream *st;
7621  const AVPacketSideData *old_side_data;
7622  uint8_t *side_data, *extra_data;
7623  size_t side_data_size;
7624  int ret = 0;
7625  unsigned int version, kid_count, extra_data_size, alloc_size = 0;
7626 
7627  if (c->fc->nb_streams < 1)
7628  return 0;
7629  st = c->fc->streams[c->fc->nb_streams-1];
7630 
7631  version = avio_r8(pb); /* version */
7632  avio_rb24(pb); /* flags */
7633 
7634  info = av_encryption_init_info_alloc(/* system_id_size */ 16, /* num_key_ids */ 0,
7635  /* key_id_size */ 16, /* data_size */ 0);
7636  if (!info)
7637  return AVERROR(ENOMEM);
7638 
7639  if ((ret = ffio_read_size(pb, info->system_id, 16)) < 0) {
7640  av_log(c->fc, AV_LOG_ERROR, "Failed to read the system id\n");
7641  goto finish;
7642  }
7643 
7644  if (version > 0) {
7645  kid_count = avio_rb32(pb);
7646  if (kid_count >= INT_MAX / sizeof(*key_ids)) {
7647  ret = AVERROR(ENOMEM);
7648  goto finish;
7649  }
7650 
7651  for (unsigned int i = 0; i < kid_count && !pb->eof_reached; i++) {
7652  unsigned int min_kid_count = FFMIN(FFMAX(i + 1, 1024), kid_count);
7653  key_ids = av_fast_realloc(info->key_ids, &alloc_size,
7654  min_kid_count * sizeof(*key_ids));
7655  if (!key_ids) {
7656  ret = AVERROR(ENOMEM);
7657  goto finish;
7658  }
7659  info->key_ids = key_ids;
7660 
7661  info->key_ids[i] = av_mallocz(16);
7662  if (!info->key_ids[i]) {
7663  ret = AVERROR(ENOMEM);
7664  goto finish;
7665  }
7666  info->num_key_ids = i + 1;
7667 
7668  if ((ret = ffio_read_size(pb, info->key_ids[i], 16)) < 0) {
7669  av_log(c->fc, AV_LOG_ERROR, "Failed to read the key id\n");
7670  goto finish;
7671  }
7672  }
7673 
7674  if (pb->eof_reached) {
7675  av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading pssh\n");
7677  goto finish;
7678  }
7679  }
7680 
7681  extra_data_size = avio_rb32(pb);
7682  extra_data = av_malloc(extra_data_size);
7683  if (!extra_data) {
7684  ret = AVERROR(ENOMEM);
7685  goto finish;
7686  }
7687  ret = avio_read(pb, extra_data, extra_data_size);
7688  if (ret != extra_data_size) {
7689  av_free(extra_data);
7690 
7691  if (ret >= 0)
7693  goto finish;
7694  }
7695 
7696  av_freep(&info->data); // malloc(0) may still allocate something.
7697  info->data = extra_data;
7698  info->data_size = extra_data_size;
7699 
7700  // If there is existing initialization data, append to the list.
7703  if (old_side_data) {
7704  old_init_info = av_encryption_init_info_get_side_data(old_side_data->data, old_side_data->size);
7705  if (old_init_info) {
7706  // Append to the end of the list.
7707  for (AVEncryptionInitInfo *cur = old_init_info;; cur = cur->next) {
7708  if (!cur->next) {
7709  cur->next = info;
7710  break;
7711  }
7712  }
7713  info = old_init_info;
7714  } else {
7715  // Assume existing side-data will be valid, so the only error we could get is OOM.
7716  ret = AVERROR(ENOMEM);
7717  goto finish;
7718  }
7719  }
7720 
7721  side_data = av_encryption_init_info_add_side_data(info, &side_data_size);
7722  if (!side_data) {
7723  ret = AVERROR(ENOMEM);
7724  goto finish;
7725  }
7729  side_data, side_data_size, 0))
7730  av_free(side_data);
7731 
7732 finish:
7734  return ret;
7735 }
7736 
7738 {
7739  AVStream *st;
7740  MOVStreamContext *sc;
7741 
7742  if (c->fc->nb_streams < 1)
7743  return 0;
7744  st = c->fc->streams[c->fc->nb_streams-1];
7745  sc = st->priv_data;
7746 
7747  if (sc->pseudo_stream_id != 0) {
7748  av_log(c->fc, AV_LOG_ERROR, "schm boxes are only supported in first sample descriptor\n");
7749  return AVERROR_PATCHWELCOME;
7750  }
7751 
7752  if (atom.size < 8)
7753  return AVERROR_INVALIDDATA;
7754 
7755  avio_rb32(pb); /* version and flags */
7756 
7757  if (!sc->cenc.default_encrypted_sample) {
7759  if (!sc->cenc.default_encrypted_sample) {
7760  return AVERROR(ENOMEM);
7761  }
7762  }
7763 
7765  return 0;
7766 }
7767 
7769 {
7770  AVStream *st;
7771  MOVStreamContext *sc;
7772  unsigned int version, pattern, is_protected, iv_size;
7773 
7774  if (c->fc->nb_streams < 1)
7775  return 0;
7776  st = c->fc->streams[c->fc->nb_streams-1];
7777  sc = st->priv_data;
7778 
7779  if (sc->pseudo_stream_id != 0) {
7780  av_log(c->fc, AV_LOG_ERROR, "tenc atom are only supported in first sample descriptor\n");
7781  return AVERROR_PATCHWELCOME;
7782  }
7783 
7784  if (!sc->cenc.default_encrypted_sample) {
7786  if (!sc->cenc.default_encrypted_sample) {
7787  return AVERROR(ENOMEM);
7788  }
7789  }
7790 
7791  if (atom.size < 20)
7792  return AVERROR_INVALIDDATA;
7793 
7794  version = avio_r8(pb); /* version */
7795  avio_rb24(pb); /* flags */
7796 
7797  avio_r8(pb); /* reserved */
7798  pattern = avio_r8(pb);
7799 
7800  if (version > 0) {
7801  sc->cenc.default_encrypted_sample->crypt_byte_block = pattern >> 4;
7802  sc->cenc.default_encrypted_sample->skip_byte_block = pattern & 0xf;
7803  }
7804 
7805  is_protected = avio_r8(pb);
7806  if (is_protected && !sc->cenc.encryption_index) {
7807  // The whole stream should be by-default encrypted.
7809  if (!sc->cenc.encryption_index)
7810  return AVERROR(ENOMEM);
7811  }
7812  sc->cenc.per_sample_iv_size = avio_r8(pb);
7813  if (sc->cenc.per_sample_iv_size != 0 && sc->cenc.per_sample_iv_size != 8 &&
7814  sc->cenc.per_sample_iv_size != 16) {
7815  av_log(c->fc, AV_LOG_ERROR, "invalid per-sample IV size value\n");
7816  return AVERROR_INVALIDDATA;
7817  }
7818  if (avio_read(pb, sc->cenc.default_encrypted_sample->key_id, 16) != 16) {
7819  av_log(c->fc, AV_LOG_ERROR, "failed to read the default key ID\n");
7820  return AVERROR_INVALIDDATA;
7821  }
7822 
7823  if (is_protected && !sc->cenc.per_sample_iv_size) {
7824  iv_size = avio_r8(pb);
7825  if (iv_size != 8 && iv_size != 16) {
7826  av_log(c->fc, AV_LOG_ERROR, "invalid default_constant_IV_size in tenc atom\n");
7827  return AVERROR_INVALIDDATA;
7828  }
7829 
7830  if (avio_read(pb, sc->cenc.default_encrypted_sample->iv, iv_size) != iv_size) {
7831  av_log(c->fc, AV_LOG_ERROR, "failed to read the default IV\n");
7832  return AVERROR_INVALIDDATA;
7833  }
7834  }
7835 
7836  return 0;
7837 }
7838 
7840 {
7841  AVStream *st;
7842  int last, type, size, ret;
7843  uint8_t buf[4];
7844 
7845  if (c->fc->nb_streams < 1)
7846  return 0;
7847  st = c->fc->streams[c->fc->nb_streams-1];
7848 
7849  if ((uint64_t)atom.size > (1<<30) || atom.size < 42)
7850  return AVERROR_INVALIDDATA;
7851 
7852  /* Check FlacSpecificBox version. */
7853  if (avio_r8(pb) != 0)
7854  return AVERROR_INVALIDDATA;
7855 
7856  avio_rb24(pb); /* Flags */
7857 
7858  if (avio_read(pb, buf, sizeof(buf)) != sizeof(buf)) {
7859  av_log(c->fc, AV_LOG_ERROR, "failed to read FLAC metadata block header\n");
7860  return pb->error < 0 ? pb->error : AVERROR_INVALIDDATA;
7861  }
7862  flac_parse_block_header(buf, &last, &type, &size);
7863 
7865  av_log(c->fc, AV_LOG_ERROR, "STREAMINFO must be first FLACMetadataBlock\n");
7866  return AVERROR_INVALIDDATA;
7867  }
7868 
7869  ret = ff_get_extradata(c->fc, st->codecpar, pb, size);
7870  if (ret < 0)
7871  return ret;
7872 
7873  if (!last)
7874  av_log(c->fc, AV_LOG_WARNING, "non-STREAMINFO FLACMetadataBlock(s) ignored\n");
7875 
7876  return 0;
7877 }
7878 
7880 {
7881  int i, ret;
7882  int bytes_of_protected_data;
7883 
7884  if (!sc->cenc.aes_ctr) {
7885  /* initialize the cipher */
7886  sc->cenc.aes_ctr = av_aes_ctr_alloc();
7887  if (!sc->cenc.aes_ctr) {
7888  return AVERROR(ENOMEM);
7889  }
7890 
7891  ret = av_aes_ctr_init(sc->cenc.aes_ctr, c->decryption_key);
7892  if (ret < 0) {
7893  return ret;
7894  }
7895  }
7896 
7898 
7899  if (!sample->subsample_count) {
7900  /* decrypt the whole packet */
7902  return 0;
7903  }
7904 
7905  for (i = 0; i < sample->subsample_count; i++) {
7906  if (sample->subsamples[i].bytes_of_clear_data + sample->subsamples[i].bytes_of_protected_data > size) {
7907  av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n");
7908  return AVERROR_INVALIDDATA;
7909  }
7910 
7911  /* skip the clear bytes */
7912  input += sample->subsamples[i].bytes_of_clear_data;
7913  size -= sample->subsamples[i].bytes_of_clear_data;
7914 
7915  /* decrypt the encrypted bytes */
7916 
7917  bytes_of_protected_data = sample->subsamples[i].bytes_of_protected_data;
7918  av_aes_ctr_crypt(sc->cenc.aes_ctr, input, input, bytes_of_protected_data);
7919 
7920  input += bytes_of_protected_data;
7921  size -= bytes_of_protected_data;
7922  }
7923 
7924  if (size > 0) {
7925  av_log(c->fc, AV_LOG_ERROR, "leftover packet bytes after subsample processing\n");
7926  return AVERROR_INVALIDDATA;
7927  }
7928 
7929  return 0;
7930 }
7931 
7933 {
7934  int i, ret;
7935  int num_of_encrypted_blocks;
7936  uint8_t iv[16];
7937 
7938  if (!sc->cenc.aes_ctx) {
7939  /* initialize the cipher */
7940  sc->cenc.aes_ctx = av_aes_alloc();
7941  if (!sc->cenc.aes_ctx) {
7942  return AVERROR(ENOMEM);
7943  }
7944 
7945  ret = av_aes_init(sc->cenc.aes_ctx, c->decryption_key, 16 * 8, 1);
7946  if (ret < 0) {
7947  return ret;
7948  }
7949  }
7950 
7951  memcpy(iv, sample->iv, 16);
7952 
7953  /* whole-block full sample encryption */
7954  if (!sample->subsample_count) {
7955  /* decrypt the whole packet */
7956  av_aes_crypt(sc->cenc.aes_ctx, input, input, size/16, iv, 1);
7957  return 0;
7958  }
7959 
7960  for (i = 0; i < sample->subsample_count; i++) {
7961  if (sample->subsamples[i].bytes_of_clear_data + sample->subsamples[i].bytes_of_protected_data > size) {
7962  av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n");
7963  return AVERROR_INVALIDDATA;
7964  }
7965 
7966  if (sample->subsamples[i].bytes_of_protected_data % 16) {
7967  av_log(c->fc, AV_LOG_ERROR, "subsample BytesOfProtectedData is not a multiple of 16\n");
7968  return AVERROR_INVALIDDATA;
7969  }
7970 
7971  /* skip the clear bytes */
7972  input += sample->subsamples[i].bytes_of_clear_data;
7973  size -= sample->subsamples[i].bytes_of_clear_data;
7974 
7975  /* decrypt the encrypted bytes */
7976  num_of_encrypted_blocks = sample->subsamples[i].bytes_of_protected_data/16;
7977  if (num_of_encrypted_blocks > 0) {
7978  av_aes_crypt(sc->cenc.aes_ctx, input, input, num_of_encrypted_blocks, iv, 1);
7979  }
7980  input += sample->subsamples[i].bytes_of_protected_data;
7981  size -= sample->subsamples[i].bytes_of_protected_data;
7982  }
7983 
7984  if (size > 0) {
7985  av_log(c->fc, AV_LOG_ERROR, "leftover packet bytes after subsample processing\n");
7986  return AVERROR_INVALIDDATA;
7987  }
7988 
7989  return 0;
7990 }
7991 
7993 {
7994  int i, ret, rem_bytes;
7995  uint8_t *data;
7996 
7997  if (!sc->cenc.aes_ctr) {
7998  /* initialize the cipher */
7999  sc->cenc.aes_ctr = av_aes_ctr_alloc();
8000  if (!sc->cenc.aes_ctr) {
8001  return AVERROR(ENOMEM);
8002  }
8003 
8004  ret = av_aes_ctr_init(sc->cenc.aes_ctr, c->decryption_key);
8005  if (ret < 0) {
8006  return ret;
8007  }
8008  }
8009 
8011 
8012  /* whole-block full sample encryption */
8013  if (!sample->subsample_count) {
8014  /* decrypt the whole packet */
8016  return 0;
8017  } else if (!sample->crypt_byte_block && !sample->skip_byte_block) {
8018  av_log(c->fc, AV_LOG_ERROR, "pattern encryption is not present in 'cens' scheme\n");
8019  return AVERROR_INVALIDDATA;
8020  }
8021 
8022  for (i = 0; i < sample->subsample_count; i++) {
8023  if (sample->subsamples[i].bytes_of_clear_data + sample->subsamples[i].bytes_of_protected_data > size) {
8024  av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n");
8025  return AVERROR_INVALIDDATA;
8026  }
8027 
8028  /* skip the clear bytes */
8029  input += sample->subsamples[i].bytes_of_clear_data;
8030  size -= sample->subsamples[i].bytes_of_clear_data;
8031 
8032  /* decrypt the encrypted bytes */
8033  data = input;
8034  rem_bytes = sample->subsamples[i].bytes_of_protected_data;
8035  while (rem_bytes > 0) {
8036  if (rem_bytes < 16*sample->crypt_byte_block) {
8037  break;
8038  }
8039  av_aes_ctr_crypt(sc->cenc.aes_ctr, data, data, 16*sample->crypt_byte_block);
8040  data += 16*sample->crypt_byte_block;
8041  rem_bytes -= 16*sample->crypt_byte_block;
8042  data += FFMIN(16*sample->skip_byte_block, rem_bytes);
8043  rem_bytes -= FFMIN(16*sample->skip_byte_block, rem_bytes);
8044  }
8045  input += sample->subsamples[i].bytes_of_protected_data;
8046  size -= sample->subsamples[i].bytes_of_protected_data;
8047  }
8048 
8049  if (size > 0) {
8050  av_log(c->fc, AV_LOG_ERROR, "leftover packet bytes after subsample processing\n");
8051  return AVERROR_INVALIDDATA;
8052  }
8053 
8054  return 0;
8055 }
8056 
8058 {
8059  int i, ret, rem_bytes;
8060  uint8_t iv[16];
8061  uint8_t *data;
8062 
8063  if (!sc->cenc.aes_ctx) {
8064  /* initialize the cipher */
8065  sc->cenc.aes_ctx = av_aes_alloc();
8066  if (!sc->cenc.aes_ctx) {
8067  return AVERROR(ENOMEM);
8068  }
8069 
8070  ret = av_aes_init(sc->cenc.aes_ctx, c->decryption_key, 16 * 8, 1);
8071  if (ret < 0) {
8072  return ret;
8073  }
8074  }
8075 
8076  /* whole-block full sample encryption */
8077  if (!sample->subsample_count) {
8078  /* decrypt the whole packet */
8079  memcpy(iv, sample->iv, 16);
8080  av_aes_crypt(sc->cenc.aes_ctx, input, input, size/16, iv, 1);
8081  return 0;
8082  } else if (!sample->crypt_byte_block && !sample->skip_byte_block) {
8083  av_log(c->fc, AV_LOG_ERROR, "pattern encryption is not present in 'cbcs' scheme\n");
8084  return AVERROR_INVALIDDATA;
8085  }
8086 
8087  for (i = 0; i < sample->subsample_count; i++) {
8088  if (sample->subsamples[i].bytes_of_clear_data + sample->subsamples[i].bytes_of_protected_data > size) {
8089  av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n");
8090  return AVERROR_INVALIDDATA;
8091  }
8092 
8093  /* skip the clear bytes */
8094  input += sample->subsamples[i].bytes_of_clear_data;
8095  size -= sample->subsamples[i].bytes_of_clear_data;
8096 
8097  /* decrypt the encrypted bytes */
8098  memcpy(iv, sample->iv, 16);
8099  data = input;
8100  rem_bytes = sample->subsamples[i].bytes_of_protected_data;
8101  while (rem_bytes > 0) {
8102  if (rem_bytes < 16*sample->crypt_byte_block) {
8103  break;
8104  }
8105  av_aes_crypt(sc->cenc.aes_ctx, data, data, sample->crypt_byte_block, iv, 1);
8106  data += 16*sample->crypt_byte_block;
8107  rem_bytes -= 16*sample->crypt_byte_block;
8108  data += FFMIN(16*sample->skip_byte_block, rem_bytes);
8109  rem_bytes -= FFMIN(16*sample->skip_byte_block, rem_bytes);
8110  }
8111  input += sample->subsamples[i].bytes_of_protected_data;
8112  size -= sample->subsamples[i].bytes_of_protected_data;
8113  }
8114 
8115  if (size > 0) {
8116  av_log(c->fc, AV_LOG_ERROR, "leftover packet bytes after subsample processing\n");
8117  return AVERROR_INVALIDDATA;
8118  }
8119 
8120  return 0;
8121 }
8122 
8124 {
8125  if (sample->scheme == MKBETAG('c','e','n','c') && !sample->crypt_byte_block && !sample->skip_byte_block) {
8126  return cenc_scheme_decrypt(c, sc, sample, input, size);
8127  } else if (sample->scheme == MKBETAG('c','b','c','1') && !sample->crypt_byte_block && !sample->skip_byte_block) {
8128  return cbc1_scheme_decrypt(c, sc, sample, input, size);
8129  } else if (sample->scheme == MKBETAG('c','e','n','s')) {
8130  return cens_scheme_decrypt(c, sc, sample, input, size);
8131  } else if (sample->scheme == MKBETAG('c','b','c','s')) {
8132  return cbcs_scheme_decrypt(c, sc, sample, input, size);
8133  } else {
8134  av_log(c->fc, AV_LOG_ERROR, "invalid encryption scheme\n");
8135  return AVERROR_INVALIDDATA;
8136  }
8137 }
8138 
8140 {
8141  int current = frag_index->current;
8142 
8143  if (!frag_index->nb_items)
8144  return NULL;
8145 
8146  // Check frag_index->current is the right one for pkt. It can out of sync.
8147  if (current >= 0 && current < frag_index->nb_items) {
8148  if (frag_index->item[current].moof_offset < pkt->pos &&
8149  (current + 1 == frag_index->nb_items ||
8150  frag_index->item[current + 1].moof_offset > pkt->pos))
8151  return get_frag_stream_info(frag_index, current, id);
8152  }
8153 
8154 
8155  for (int i = 0; i < frag_index->nb_items; i++) {
8156  if (frag_index->item[i].moof_offset > pkt->pos)
8157  break;
8158  current = i;
8159  }
8160  frag_index->current = current;
8161  return get_frag_stream_info(frag_index, current, id);
8162 }
8163 
8164 static int cenc_filter(MOVContext *mov, AVStream* st, MOVStreamContext *sc, AVPacket *pkt, int current_index)
8165 {
8166  MOVFragmentStreamInfo *frag_stream_info;
8167  MOVEncryptionIndex *encryption_index;
8168  AVEncryptionInfo *encrypted_sample;
8169  int encrypted_index, ret;
8170 
8171  frag_stream_info = get_frag_stream_info_from_pkt(&mov->frag_index, pkt, sc->id);
8172  encrypted_index = current_index;
8173  encryption_index = NULL;
8174  if (frag_stream_info) {
8175  // Note this only supports encryption info in the first sample descriptor.
8176  if (frag_stream_info->stsd_id == 1) {
8177  if (frag_stream_info->encryption_index) {
8178  encrypted_index = current_index - frag_stream_info->index_base;
8179  encryption_index = frag_stream_info->encryption_index;
8180  } else {
8181  encryption_index = sc->cenc.encryption_index;
8182  }
8183  }
8184  } else {
8185  encryption_index = sc->cenc.encryption_index;
8186  }
8187 
8188  if (encryption_index) {
8189  if (encryption_index->auxiliary_info_sample_count &&
8190  !encryption_index->nb_encrypted_samples) {
8191  av_log(mov->fc, AV_LOG_ERROR, "saiz atom found without saio\n");
8192  return AVERROR_INVALIDDATA;
8193  }
8194  if (encryption_index->auxiliary_offsets_count &&
8195  !encryption_index->nb_encrypted_samples) {
8196  av_log(mov->fc, AV_LOG_ERROR, "saio atom found without saiz\n");
8197  return AVERROR_INVALIDDATA;
8198  }
8199 
8200  encrypted_sample = NULL;
8201  if (!encryption_index->nb_encrypted_samples) {
8202  // Full-sample encryption with default settings.
8203  encrypted_sample = sc->cenc.default_encrypted_sample;
8204  } else if (encrypted_index >= 0 && encrypted_index < encryption_index->nb_encrypted_samples) {
8205  // Per-sample setting override.
8206  encrypted_sample = encryption_index->encrypted_samples[encrypted_index];
8207  if (!encrypted_sample) {
8208  encrypted_sample = sc->cenc.default_encrypted_sample;
8209  }
8210  }
8211 
8212  if (!encrypted_sample) {
8213  av_log(mov->fc, AV_LOG_ERROR, "Incorrect number of samples in encryption info\n");
8214  return AVERROR_INVALIDDATA;
8215  }
8216 
8217  if (mov->decryption_key) {
8218  return cenc_decrypt(mov, sc, encrypted_sample, pkt->data, pkt->size);
8219  } else {
8220  size_t size;
8221  uint8_t *side_data = av_encryption_info_add_side_data(encrypted_sample, &size);
8222  if (!side_data)
8223  return AVERROR(ENOMEM);
8225  if (ret < 0)
8226  av_free(side_data);
8227  return ret;
8228  }
8229  }
8230 
8231  return 0;
8232 }
8233 
8235 {
8236  const int OPUS_SEEK_PREROLL_MS = 80;
8237  int ret;
8238  AVStream *st;
8239  size_t size;
8240  uint16_t pre_skip;
8241 
8242  if (c->fc->nb_streams < 1)
8243  return 0;
8244  st = c->fc->streams[c->fc->nb_streams-1];
8245 
8246  if ((uint64_t)atom.size > (1<<30) || atom.size < 11)
8247  return AVERROR_INVALIDDATA;
8248 
8249  /* Check OpusSpecificBox version. */
8250  if (avio_r8(pb) != 0) {
8251  av_log(c->fc, AV_LOG_ERROR, "unsupported OpusSpecificBox version\n");
8252  return AVERROR_INVALIDDATA;
8253  }
8254 
8255  /* OpusSpecificBox size plus magic for Ogg OpusHead header. */
8256  size = atom.size + 8;
8257 
8258  if ((ret = ff_alloc_extradata(st->codecpar, size)) < 0)
8259  return ret;
8260 
8261  AV_WL32A(st->codecpar->extradata, MKTAG('O','p','u','s'));
8262  AV_WL32A(st->codecpar->extradata + 4, MKTAG('H','e','a','d'));
8263  AV_WB8(st->codecpar->extradata + 8, 1); /* OpusHead version */
8264  avio_read(pb, st->codecpar->extradata + 9, size - 9);
8265 
8266  /* OpusSpecificBox is stored in big-endian, but OpusHead is
8267  little-endian; aside from the preceeding magic and version they're
8268  otherwise currently identical. Data after output gain at offset 16
8269  doesn't need to be bytewapped. */
8270  pre_skip = AV_RB16A(st->codecpar->extradata + 10);
8271  AV_WL16A(st->codecpar->extradata + 10, pre_skip);
8272  AV_WL32A(st->codecpar->extradata + 12, AV_RB32A(st->codecpar->extradata + 12));
8273  AV_WL16A(st->codecpar->extradata + 16, AV_RB16A(st->codecpar->extradata + 16));
8274 
8275  st->codecpar->initial_padding = pre_skip;
8277  (AVRational){1, 1000},
8278  (AVRational){1, 48000});
8279 
8280  return 0;
8281 }
8282 
8284 {
8285  AVStream *st;
8286  unsigned format_info;
8287  int channel_assignment, channel_assignment1, channel_assignment2;
8288  int ratebits;
8289  uint64_t chmask;
8290 
8291  if (c->fc->nb_streams < 1)
8292  return 0;
8293  st = c->fc->streams[c->fc->nb_streams-1];
8294 
8295  if (atom.size < 10)
8296  return AVERROR_INVALIDDATA;
8297 
8298  format_info = avio_rb32(pb);
8299 
8300  ratebits = (format_info >> 28) & 0xF;
8301  channel_assignment1 = (format_info >> 15) & 0x1F;
8302  channel_assignment2 = format_info & 0x1FFF;
8303  if (channel_assignment2)
8304  channel_assignment = channel_assignment2;
8305  else
8306  channel_assignment = channel_assignment1;
8307 
8308  st->codecpar->frame_size = 40 << (ratebits & 0x7);
8309  st->codecpar->sample_rate = mlp_samplerate(ratebits);
8310 
8312  chmask = truehd_layout(channel_assignment);
8314 
8315  return 0;
8316 }
8317 
8319 {
8320  AVStream *st;
8321  uint8_t buf[ISOM_DVCC_DVVC_SIZE];
8322  int ret;
8323  int64_t read_size = atom.size;
8324 
8325  if (c->fc->nb_streams < 1)
8326  return 0;
8327  st = c->fc->streams[c->fc->nb_streams-1];
8328 
8329  // At most 24 bytes
8330  read_size = FFMIN(read_size, ISOM_DVCC_DVVC_SIZE);
8331 
8332  if ((ret = ffio_read_size(pb, buf, read_size)) < 0)
8333  return ret;
8334 
8335  return ff_isom_parse_dvcc_dvvc(c->fc, st, buf, read_size);
8336 }
8337 
8339 {
8340  AVStream *st;
8341  uint8_t *buf;
8342  int ret, old_size, num_arrays;
8343 
8344  if (c->fc->nb_streams < 1)
8345  return 0;
8346  st = c->fc->streams[c->fc->nb_streams-1];
8347 
8348  if (!st->codecpar->extradata_size)
8349  // TODO: handle lhvC when present before hvcC
8350  return 0;
8351 
8352  if (atom.size < 6 || st->codecpar->extradata_size < 23)
8353  return AVERROR_INVALIDDATA;
8354 
8356  if (!buf)
8357  return AVERROR(ENOMEM);
8358  memset(buf + atom.size, 0, AV_INPUT_BUFFER_PADDING_SIZE);
8359 
8360  ret = ffio_read_size(pb, buf, atom.size);
8361  if (ret < 0) {
8362  av_free(buf);
8363  av_log(c->fc, AV_LOG_WARNING, "lhvC atom truncated\n");
8364  return 0;
8365  }
8366 
8367  num_arrays = buf[5];
8368  old_size = st->codecpar->extradata_size;
8369  atom.size -= 8 /* account for mov_realloc_extradata offseting */
8370  + 6 /* lhvC bytes before the arrays*/;
8371 
8372  ret = mov_realloc_extradata(st->codecpar, atom);
8373  if (ret < 0) {
8374  av_free(buf);
8375  return ret;
8376  }
8377 
8378  st->codecpar->extradata[22] += num_arrays;
8379  memcpy(st->codecpar->extradata + old_size, buf + 6, atom.size + 8);
8380 
8382 
8383  av_free(buf);
8384  return 0;
8385 }
8386 
8388 {
8389  AVFormatContext *ctx = c->fc;
8390  AVStream *st = NULL;
8391  AVBPrint scheme_buf, value_buf;
8392  int64_t scheme_str_len = 0, value_str_len = 0;
8393  int version, flags, ret = AVERROR_BUG;
8394  int64_t size = atom.size;
8395 
8396  if (atom.size < 6)
8397  // 4 bytes for version + flags, 2x 1 byte for null
8398  return AVERROR_INVALIDDATA;
8399 
8400  if (c->fc->nb_streams < 1)
8401  return 0;
8402  st = c->fc->streams[c->fc->nb_streams-1];
8403 
8404  version = avio_r8(pb);
8405  flags = avio_rb24(pb);
8406  size -= 4;
8407 
8408  if (version != 0 || flags != 0) {
8410  "Unsupported 'kind' box with version %d, flags: %x",
8411  version, flags);
8412  return AVERROR_INVALIDDATA;
8413  }
8414 
8415  av_bprint_init(&scheme_buf, 0, AV_BPRINT_SIZE_UNLIMITED);
8416  av_bprint_init(&value_buf, 0, AV_BPRINT_SIZE_UNLIMITED);
8417 
8418  if ((scheme_str_len = ff_read_string_to_bprint_overwrite(pb, &scheme_buf,
8419  size)) < 0) {
8420  ret = scheme_str_len;
8421  goto cleanup;
8422  }
8423 
8424  if (scheme_str_len + 1 >= size) {
8425  // we need to have another string, even if nullptr.
8426  // we check with + 1 since we expect that if size was not hit,
8427  // an additional null was read.
8429  goto cleanup;
8430  }
8431 
8432  size -= scheme_str_len + 1;
8433 
8434  if ((value_str_len = ff_read_string_to_bprint_overwrite(pb, &value_buf,
8435  size)) < 0) {
8436  ret = value_str_len;
8437  goto cleanup;
8438  }
8439 
8440  if (value_str_len == size) {
8441  // in case of no trailing null, box is not valid.
8443  goto cleanup;
8444  }
8445 
8447  "%s stream %d KindBox(scheme: %s, value: %s)\n",
8449  st->index,
8450  scheme_buf.str, value_buf.str);
8451 
8452  for (int i = 0; ff_mov_track_kind_table[i].scheme_uri; i++) {
8454  if (!av_strstart(scheme_buf.str, map.scheme_uri, NULL))
8455  continue;
8456 
8457  for (int j = 0; map.value_maps[j].disposition; j++) {
8458  const struct MP4TrackKindValueMapping value_map = map.value_maps[j];
8459  if (!av_strstart(value_buf.str, value_map.value, NULL))
8460  continue;
8461 
8462  st->disposition |= value_map.disposition;
8463  }
8464  }
8465 
8466  ret = 0;
8467 
8468 cleanup:
8469 
8470  av_bprint_finalize(&scheme_buf, NULL);
8471  av_bprint_finalize(&value_buf, NULL);
8472 
8473  return ret;
8474 }
8475 
8477 {
8478  AVStream *st;
8479  AVChannelLayout ch_layout = { 0 };
8480  int ret, i, version, type;
8481  int ambisonic_order, channel_order, normalization, channel_count;
8482  int ambi_channels, non_diegetic_channels;
8483 
8484  if (c->fc->nb_streams < 1)
8485  return 0;
8486 
8487  st = c->fc->streams[c->fc->nb_streams - 1];
8488 
8489  if (atom.size < 16) {
8490  av_log(c->fc, AV_LOG_ERROR, "SA3D audio box too small\n");
8491  return AVERROR_INVALIDDATA;
8492  }
8493 
8494  version = avio_r8(pb);
8495  if (version) {
8496  av_log(c->fc, AV_LOG_WARNING, "Unsupported SA3D box version %d\n", version);
8497  return 0;
8498  }
8499 
8500  type = avio_r8(pb);
8501  if (type & 0x7f) {
8502  av_log(c->fc, AV_LOG_WARNING,
8503  "Unsupported ambisonic type %d\n", type & 0x7f);
8504  return 0;
8505  }
8506  non_diegetic_channels = (type >> 7) * 2; // head_locked_stereo
8507 
8508  ambisonic_order = avio_rb32(pb);
8509 
8510  channel_order = avio_r8(pb);
8511  if (channel_order) {
8512  av_log(c->fc, AV_LOG_WARNING,
8513  "Unsupported channel_order %d\n", channel_order);
8514  return 0;
8515  }
8516 
8517  normalization = avio_r8(pb);
8518  if (normalization) {
8519  av_log(c->fc, AV_LOG_WARNING,
8520  "Unsupported normalization %d\n", normalization);
8521  return 0;
8522  }
8523 
8524  channel_count = avio_rb32(pb);
8525  if (ambisonic_order < 0 || ambisonic_order > 31 ||
8526  channel_count != ((ambisonic_order + 1LL) * (ambisonic_order + 1LL) +
8527  non_diegetic_channels)) {
8528  av_log(c->fc, AV_LOG_ERROR,
8529  "Invalid number of channels (%d / %d)\n",
8530  channel_count, ambisonic_order);
8531  return 0;
8532  }
8533  ambi_channels = channel_count - non_diegetic_channels;
8534 
8535  ret = av_channel_layout_custom_init(&ch_layout, channel_count);
8536  if (ret < 0)
8537  return 0;
8538 
8539  for (i = 0; i < channel_count; i++) {
8540  unsigned channel = avio_rb32(pb);
8541 
8542  if (channel >= channel_count) {
8543  av_log(c->fc, AV_LOG_ERROR, "Invalid channel index (%d / %d)\n",
8544  channel, ambisonic_order);
8545  av_channel_layout_uninit(&ch_layout);
8546  return 0;
8547  }
8548  if (channel >= ambi_channels)
8549  ch_layout.u.map[i].id = channel - ambi_channels;
8550  else
8551  ch_layout.u.map[i].id = AV_CHAN_AMBISONIC_BASE + channel;
8552  }
8553 
8555  if (ret < 0) {
8556  av_channel_layout_uninit(&ch_layout);
8557  return 0;
8558  }
8559 
8561  st->codecpar->ch_layout = ch_layout;
8562 
8563  return 0;
8564 }
8565 
8567 {
8568  AVStream *st;
8569  int version;
8570 
8571  if (c->fc->nb_streams < 1)
8572  return 0;
8573 
8574  st = c->fc->streams[c->fc->nb_streams - 1];
8575 
8576  if (atom.size < 5) {
8577  av_log(c->fc, AV_LOG_ERROR, "Empty SAND audio box\n");
8578  return AVERROR_INVALIDDATA;
8579  }
8580 
8581  version = avio_r8(pb);
8582  if (version) {
8583  av_log(c->fc, AV_LOG_WARNING, "Unsupported SAND box version %d\n", version);
8584  return 0;
8585  }
8586 
8588 
8589  return 0;
8590 }
8591 
8592 static int rb_size(AVIOContext *pb, int64_t *value, int size)
8593 {
8594  if (size == 0)
8595  *value = 0;
8596  else if (size == 1)
8597  *value = avio_r8(pb);
8598  else if (size == 2)
8599  *value = avio_rb16(pb);
8600  else if (size == 4)
8601  *value = avio_rb32(pb);
8602  else if (size == 8) {
8603  *value = avio_rb64(pb);
8604  if (*value < 0)
8605  return -1;
8606  } else
8607  return -1;
8608  return size;
8609 }
8610 
8612 {
8613  avio_rb32(pb); // version & flags.
8614  c->primary_item_id = avio_rb16(pb);
8615  av_log(c->fc, AV_LOG_TRACE, "pitm: primary_item_id %d\n", c->primary_item_id);
8616  return atom.size;
8617 }
8618 
8620 {
8621  c->idat_offset = avio_tell(pb);
8622  return 0;
8623 }
8624 
8626 {
8627  HEIFItem **heif_item;
8628  int version, offset_size, length_size, base_offset_size, index_size;
8629  int item_count, extent_count;
8630  int64_t base_offset, extent_offset, extent_length;
8631  uint8_t value;
8632 
8633  if (c->found_iloc) {
8634  av_log(c->fc, AV_LOG_INFO, "Duplicate iloc box found\n");
8635  return 0;
8636  }
8637 
8638  version = avio_r8(pb);
8639  avio_rb24(pb); // flags.
8640 
8641  value = avio_r8(pb);
8642  offset_size = (value >> 4) & 0xF;
8643  length_size = value & 0xF;
8644  value = avio_r8(pb);
8645  base_offset_size = (value >> 4) & 0xF;
8646  index_size = !version ? 0 : (value & 0xF);
8647  if (index_size) {
8648  avpriv_report_missing_feature(c->fc, "iloc: index_size != 0");
8649  return AVERROR_PATCHWELCOME;
8650  }
8651  item_count = (version < 2) ? avio_rb16(pb) : avio_rb32(pb);
8652 
8653  heif_item = av_realloc_array(c->heif_item, FFMAX(item_count, c->nb_heif_item), sizeof(*c->heif_item));
8654  if (!heif_item)
8655  return AVERROR(ENOMEM);
8656  c->heif_item = heif_item;
8657  if (item_count > c->nb_heif_item)
8658  memset(&c->heif_item[c->nb_heif_item], 0,
8659  sizeof(*c->heif_item) * (item_count - c->nb_heif_item));
8660  c->nb_heif_item = FFMAX(c->nb_heif_item, item_count);
8661 
8662  av_log(c->fc, AV_LOG_TRACE, "iloc: item_count %d\n", item_count);
8663  for (int i = 0; i < item_count; i++) {
8664  HEIFItem *item = c->heif_item[i];
8665  int item_id = (version < 2) ? avio_rb16(pb) : avio_rb32(pb);
8666  int offset_type = (version > 0) ? avio_rb16(pb) & 0xf : 0;
8667 
8668  if (avio_feof(pb))
8669  return AVERROR_INVALIDDATA;
8670  if (offset_type > 1) {
8671  avpriv_report_missing_feature(c->fc, "iloc offset type %d", offset_type);
8672  return AVERROR_PATCHWELCOME;
8673  }
8674 
8675  avio_rb16(pb); // data_reference_index.
8676  if (rb_size(pb, &base_offset, base_offset_size) < 0)
8677  return AVERROR_INVALIDDATA;
8678  extent_count = avio_rb16(pb);
8679  if (extent_count > 1) {
8680  // For still AVIF images, we only support one extent item.
8681  avpriv_report_missing_feature(c->fc, "iloc: extent_count > 1");
8682  return AVERROR_PATCHWELCOME;
8683  }
8684 
8685  if (rb_size(pb, &extent_offset, offset_size) < 0 ||
8686  rb_size(pb, &extent_length, length_size) < 0 ||
8687  base_offset > INT64_MAX - extent_offset)
8688  return AVERROR_INVALIDDATA;
8689 
8690  if (!item)
8691  item = c->heif_item[i] = av_mallocz(sizeof(*item));
8692  if (!item)
8693  return AVERROR(ENOMEM);
8694 
8695  item->item_id = item_id;
8696 
8697  if (offset_type == 1)
8698  item->is_idat_relative = 1;
8699  item->extent_length = extent_length;
8700  item->extent_offset = base_offset + extent_offset;
8701  av_log(c->fc, AV_LOG_TRACE, "iloc: item_idx %d, offset_type %d, "
8702  "extent_offset %"PRId64", extent_length %"PRId64"\n",
8703  i, offset_type, item->extent_offset, item->extent_length);
8704  }
8705 
8706  c->found_iloc = 1;
8707  return atom.size;
8708 }
8709 
8710 static int mov_read_infe(MOVContext *c, AVIOContext *pb, MOVAtom atom, int idx)
8711 {
8712  HEIFItem *item;
8713  AVBPrint item_name;
8714  int64_t size = atom.size;
8715  uint32_t item_type;
8716  int item_id;
8717  int version, ret;
8718 
8719  version = avio_r8(pb);
8720  avio_rb24(pb); // flags.
8721  size -= 4;
8722  if (size < 0)
8723  return AVERROR_INVALIDDATA;
8724 
8725  if (version < 2) {
8726  avpriv_report_missing_feature(c->fc, "infe version < 2");
8727  avio_skip(pb, size);
8728  return 1;
8729  }
8730 
8731  item_id = version > 2 ? avio_rb32(pb) : avio_rb16(pb);
8732  avio_rb16(pb); // item_protection_index
8733  item_type = avio_rl32(pb);
8734  size -= 8;
8735  if (size < 1)
8736  return AVERROR_INVALIDDATA;
8737 
8740  if (ret < 0) {
8742  return ret;
8743  }
8744 
8745  av_log(c->fc, AV_LOG_TRACE, "infe: item_id %d, item_type %s, item_name %s\n",
8746  item_id, av_fourcc2str(item_type), item_name.str);
8747 
8748  size -= ret + 1;
8749  if (size > 0)
8750  avio_skip(pb, size);
8751 
8752  item = c->heif_item[idx];
8753  if (!item)
8754  item = c->heif_item[idx] = av_mallocz(sizeof(*item));
8755  if (!item)
8756  return AVERROR(ENOMEM);
8757 
8758  if (ret)
8759  av_bprint_finalize(&item_name, &c->heif_item[idx]->name);
8760  c->heif_item[idx]->item_id = item_id;
8761  c->heif_item[idx]->type = item_type;
8762 
8763  switch (item_type) {
8764  case MKTAG('a','v','0','1'):
8765  case MKTAG('h','v','c','1'):
8766  ret = heif_add_stream(c, c->heif_item[idx]);
8767  if (ret < 0)
8768  return ret;
8769  break;
8770  }
8771 
8772  return 0;
8773 }
8774 
8776 {
8777  HEIFItem **heif_item;
8778  int entry_count;
8779  int version, got_stream = 0, ret, i;
8780 
8781  if (c->found_iinf) {
8782  av_log(c->fc, AV_LOG_WARNING, "Duplicate iinf box found\n");
8783  return 0;
8784  }
8785 
8786  version = avio_r8(pb);
8787  avio_rb24(pb); // flags.
8788  entry_count = version ? avio_rb32(pb) : avio_rb16(pb);
8789 
8790  heif_item = av_realloc_array(c->heif_item, FFMAX(entry_count, c->nb_heif_item), sizeof(*c->heif_item));
8791  if (!heif_item)
8792  return AVERROR(ENOMEM);
8793  c->heif_item = heif_item;
8794  if (entry_count > c->nb_heif_item)
8795  memset(&c->heif_item[c->nb_heif_item], 0,
8796  sizeof(*c->heif_item) * (entry_count - c->nb_heif_item));
8797  c->nb_heif_item = FFMAX(c->nb_heif_item, entry_count);
8798 
8799  for (i = 0; i < entry_count; i++) {
8800  MOVAtom infe;
8801 
8802  if (avio_feof(pb)) {
8804  goto fail;
8805  }
8806  infe.size = avio_rb32(pb) - 8;
8807  infe.type = avio_rl32(pb);
8808  ret = mov_read_infe(c, pb, infe, i);
8809  if (ret < 0)
8810  goto fail;
8811  if (!ret)
8812  got_stream = 1;
8813  }
8814 
8815  c->found_iinf = got_stream;
8816  return 0;
8817 fail:
8818  for (; i >= 0; i--) {
8819  HEIFItem *item = c->heif_item[i];
8820 
8821  if (!item)
8822  continue;
8823 
8824  av_freep(&item->name);
8825  if (!item->st)
8826  continue;
8827 
8828  mov_free_stream_context(c->fc, item->st);
8829  ff_remove_stream(c->fc, item->st);
8830  item->st = NULL;
8831  }
8832  return ret;
8833 }
8834 
8836 {
8837  HEIFItem *item = NULL;
8838  HEIFGrid *grid;
8839  int entries, i;
8840  int from_item_id = version ? avio_rb32(pb) : avio_rb16(pb);
8841 
8842  for (int i = 0; i < c->nb_heif_grid; i++) {
8843  if (c->heif_grid[i].item->item_id == from_item_id) {
8844  av_log(c->fc, AV_LOG_ERROR, "More than one 'dimg' box "
8845  "referencing the same Derived Image item\n");
8846  return AVERROR_INVALIDDATA;
8847  }
8848  }
8849  for (int i = 0; i < c->nb_heif_item; i++) {
8850  if (!c->heif_item[i] || c->heif_item[i]->item_id != from_item_id)
8851  continue;
8852  item = c->heif_item[i];
8853 
8854  switch (item->type) {
8855  case MKTAG('g','r','i','d'):
8856  case MKTAG('i','o','v','l'):
8857  break;
8858  default:
8859  avpriv_report_missing_feature(c->fc, "Derived Image item of type %s",
8860  av_fourcc2str(item->type));
8861  return 0;
8862  }
8863  break;
8864  }
8865  if (!item) {
8866  av_log(c->fc, AV_LOG_ERROR, "Missing grid information\n");
8867  return AVERROR_INVALIDDATA;
8868  }
8869 
8870  grid = av_realloc_array(c->heif_grid, c->nb_heif_grid + 1U,
8871  sizeof(*c->heif_grid));
8872  if (!grid)
8873  return AVERROR(ENOMEM);
8874  c->heif_grid = grid;
8875  grid = &grid[c->nb_heif_grid++];
8876 
8877  entries = avio_rb16(pb);
8878  grid->tile_id_list = av_malloc_array(entries, sizeof(*grid->tile_id_list));
8879  grid->tile_item_list = av_calloc(entries, sizeof(*grid->tile_item_list));
8880  if (!grid->tile_id_list || !grid->tile_item_list)
8881  return AVERROR(ENOMEM);
8882  /* 'to' item ids */
8883  for (i = 0; i < entries; i++)
8884  grid->tile_id_list[i] = version ? avio_rb32(pb) : avio_rb16(pb);
8885  grid->nb_tiles = entries;
8886  grid->item = item;
8887 
8888  av_log(c->fc, AV_LOG_TRACE, "dimg: from_item_id %d, entries %d\n",
8889  from_item_id, entries);
8890 
8891  return 0;
8892 }
8893 
8895 {
8896  int entries;
8897  int to_item_id, from_item_id = version ? avio_rb32(pb) : avio_rb16(pb);
8898 
8899  entries = avio_rb16(pb);
8900  if (entries > 1) {
8901  avpriv_request_sample(c->fc, "thmb in iref referencing several items");
8902  return AVERROR_PATCHWELCOME;
8903  }
8904  /* 'to' item ids */
8905  to_item_id = version ? avio_rb32(pb) : avio_rb16(pb);
8906 
8907  if (to_item_id != c->primary_item_id)
8908  return 0;
8909 
8910  c->thmb_item_id = from_item_id;
8911 
8912  av_log(c->fc, AV_LOG_TRACE, "thmb: from_item_id %d, entries %d\n",
8913  from_item_id, entries);
8914 
8915  return 0;
8916 }
8917 
8919 {
8920  int version = avio_r8(pb);
8921  avio_rb24(pb); // flags
8922  atom.size -= 4;
8923 
8924  if (version > 1) {
8925  av_log(c->fc, AV_LOG_WARNING, "Unknown iref box version %d\n", version);
8926  return 0;
8927  }
8928 
8929  while (atom.size) {
8930  uint32_t type, size = avio_rb32(pb);
8931  int64_t next = avio_tell(pb);
8932 
8933  if (size < 14 || next < 0 || next > INT64_MAX - size)
8934  return AVERROR_INVALIDDATA;
8935 
8936  next += size - 4;
8937  type = avio_rl32(pb);
8938  switch (type) {
8939  case MKTAG('d','i','m','g'):
8941  break;
8942  case MKTAG('t','h','m','b'):
8944  break;
8945  default:
8946  av_log(c->fc, AV_LOG_DEBUG, "Unknown iref type %s size %"PRIu32"\n",
8947  av_fourcc2str(type), size);
8948  }
8949 
8950  atom.size -= size;
8951  avio_seek(pb, next, SEEK_SET);
8952  }
8953  return 0;
8954 }
8955 
8957 {
8958  HEIFItem *item;
8959  uint32_t width, height;
8960 
8961  avio_r8(pb); /* version */
8962  avio_rb24(pb); /* flags */
8963  width = avio_rb32(pb);
8964  height = avio_rb32(pb);
8965 
8966  av_log(c->fc, AV_LOG_TRACE, "ispe: item_id %d, width %u, height %u\n",
8967  c->cur_item_id, width, height);
8968 
8969  item = heif_cur_item(c);
8970  if (item) {
8971  item->width = width;
8972  item->height = height;
8973  }
8974 
8975  return 0;
8976 }
8977 
8979 {
8980  typedef struct MOVAtoms {
8981  FFIOContext b;
8982  uint32_t type;
8983  int64_t size;
8984  uint8_t *data;
8985  } MOVAtoms;
8986  MOVAtoms *atoms = NULL;
8987  MOVAtom a;
8988  unsigned count;
8989  int nb_atoms = 0;
8990  int version, flags;
8991  int ret;
8992 
8993  a.size = avio_rb32(pb);
8994  a.type = avio_rl32(pb);
8995 
8996  if (a.size < 8 || a.type != MKTAG('i','p','c','o'))
8997  return AVERROR_INVALIDDATA;
8998 
8999  a.size -= 8;
9000  while (a.size >= 8) {
9001  MOVAtoms *ref = av_dynarray2_add((void**)&atoms, &nb_atoms, sizeof(MOVAtoms), NULL);
9002  if (!ref) {
9003  ret = AVERROR(ENOMEM);
9004  goto fail;
9005  }
9006  ref->data = NULL;
9007  ref->size = avio_rb32(pb);
9008  ref->type = avio_rl32(pb);
9009  if (ref->size > a.size || ref->size < 8)
9010  break;
9011  ref->data = av_malloc(ref->size);
9012  if (!ref->data) {
9014  goto fail;
9015  }
9016  av_log(c->fc, AV_LOG_TRACE, "ipco: index %d, box type %s\n", nb_atoms, av_fourcc2str(ref->type));
9017  avio_seek(pb, -8, SEEK_CUR);
9018  if (avio_read(pb, ref->data, ref->size) != ref->size) {
9020  goto fail;
9021  }
9022  ffio_init_read_context(&ref->b, ref->data, ref->size);
9023  a.size -= ref->size;
9024  }
9025 
9026  if (a.size) {
9028  goto fail;
9029  }
9030 
9031  a.size = avio_rb32(pb);
9032  a.type = avio_rl32(pb);
9033 
9034  if (a.size < 8 || a.type != MKTAG('i','p','m','a')) {
9036  goto fail;
9037  }
9038 
9039  version = avio_r8(pb);
9040  flags = avio_rb24(pb);
9041  count = avio_rb32(pb);
9042 
9043  for (int i = 0; i < count; i++) {
9044  int item_id = version ? avio_rb32(pb) : avio_rb16(pb);
9045  int assoc_count = avio_r8(pb);
9046 
9047  if (avio_feof(pb)) {
9049  goto fail;
9050  }
9051 
9052  for (int j = 0; j < assoc_count; j++) {
9053  MOVAtoms *ref;
9054  int index = avio_r8(pb) & 0x7f;
9055  if (flags & 1) {
9056  index <<= 8;
9057  index |= avio_r8(pb);
9058  }
9059  if (index > nb_atoms || index <= 0) {
9061  goto fail;
9062  }
9063  ref = &atoms[--index];
9064 
9065  av_log(c->fc, AV_LOG_TRACE, "ipma: property_index %d, item_id %d, item_type %s\n",
9066  index + 1, item_id, av_fourcc2str(ref->type));
9067 
9068  c->cur_item_id = item_id;
9069 
9070  ret = mov_read_default(c, &ref->b.pub,
9071  (MOVAtom) { .size = ref->size,
9072  .type = MKTAG('i','p','c','o') });
9073  if (ret < 0)
9074  goto fail;
9075  ffio_init_read_context(&ref->b, ref->data, ref->size);
9076  }
9077  }
9078 
9079  ret = 0;
9080 fail:
9081  c->cur_item_id = -1;
9082  for (int i = 0; i < nb_atoms; i++)
9083  av_free(atoms[i].data);
9084  av_free(atoms);
9085 
9086  return ret;
9087 }
9088 
9090 { MKTAG('A','C','L','R'), mov_read_aclr },
9091 { MKTAG('A','P','R','G'), mov_read_avid },
9092 { MKTAG('A','A','L','P'), mov_read_avid },
9093 { MKTAG('A','R','E','S'), mov_read_ares },
9094 { MKTAG('a','v','s','s'), mov_read_avss },
9095 { MKTAG('a','v','1','C'), mov_read_glbl },
9096 { MKTAG('c','h','p','l'), mov_read_chpl },
9097 { MKTAG('c','o','6','4'), mov_read_stco },
9098 { MKTAG('c','o','l','r'), mov_read_colr },
9099 { MKTAG('c','t','t','s'), mov_read_ctts }, /* composition time to sample */
9100 { MKTAG('d','i','n','f'), mov_read_default },
9101 { MKTAG('D','p','x','E'), mov_read_dpxe },
9102 { MKTAG('d','r','e','f'), mov_read_dref },
9103 { MKTAG('e','d','t','s'), mov_read_default },
9104 { MKTAG('e','l','s','t'), mov_read_elst },
9105 { MKTAG('e','n','d','a'), mov_read_enda },
9106 { MKTAG('f','i','e','l'), mov_read_fiel },
9107 { MKTAG('a','d','r','m'), mov_read_adrm },
9108 { MKTAG('f','t','y','p'), mov_read_ftyp },
9109 { MKTAG('g','l','b','l'), mov_read_glbl },
9110 { MKTAG('h','d','l','r'), mov_read_hdlr },
9111 { MKTAG('i','l','s','t'), mov_read_ilst },
9112 { MKTAG('j','p','2','h'), mov_read_jp2h },
9113 { MKTAG('m','d','a','t'), mov_read_mdat },
9114 { MKTAG('m','d','h','d'), mov_read_mdhd },
9115 { MKTAG('m','d','i','a'), mov_read_default },
9116 { MKTAG('m','e','t','a'), mov_read_meta },
9117 { MKTAG('m','i','n','f'), mov_read_default },
9118 { MKTAG('m','o','o','f'), mov_read_moof },
9119 { MKTAG('m','o','o','v'), mov_read_moov },
9120 { MKTAG('m','v','e','x'), mov_read_default },
9121 { MKTAG('m','v','h','d'), mov_read_mvhd },
9122 { MKTAG('S','M','I',' '), mov_read_svq3 },
9123 { MKTAG('a','l','a','c'), mov_read_alac }, /* alac specific atom */
9124 { MKTAG('a','v','c','C'), mov_read_glbl },
9125 { MKTAG('p','a','s','p'), mov_read_pasp },
9126 { MKTAG('c','l','a','p'), mov_read_clap },
9127 { MKTAG('s','b','a','s'), mov_read_sbas },
9128 { MKTAG('s','i','d','x'), mov_read_sidx },
9129 { MKTAG('s','t','b','l'), mov_read_default },
9130 { MKTAG('s','t','c','o'), mov_read_stco },
9131 { MKTAG('s','t','p','s'), mov_read_stps },
9132 { MKTAG('s','t','r','f'), mov_read_strf },
9133 { MKTAG('s','t','s','c'), mov_read_stsc },
9134 { MKTAG('s','t','s','d'), mov_read_stsd }, /* sample description */
9135 { MKTAG('s','t','s','s'), mov_read_stss }, /* sync sample */
9136 { MKTAG('s','t','s','z'), mov_read_stsz }, /* sample size */
9137 { MKTAG('s','t','t','s'), mov_read_stts },
9138 { MKTAG('s','t','z','2'), mov_read_stsz }, /* compact sample size */
9139 { MKTAG('s','d','t','p'), mov_read_sdtp }, /* independent and disposable samples */
9140 { MKTAG('t','k','h','d'), mov_read_tkhd }, /* track header */
9141 { MKTAG('t','f','d','t'), mov_read_tfdt },
9142 { MKTAG('t','f','h','d'), mov_read_tfhd }, /* track fragment header */
9143 { MKTAG('t','r','a','k'), mov_read_trak },
9144 { MKTAG('t','r','a','f'), mov_read_default },
9145 { MKTAG('t','r','e','f'), mov_read_default },
9146 { MKTAG('t','m','c','d'), mov_read_tmcd },
9147 { MKTAG('c','h','a','p'), mov_read_chap },
9148 { MKTAG('t','r','e','x'), mov_read_trex },
9149 { MKTAG('t','r','u','n'), mov_read_trun },
9150 { MKTAG('u','d','t','a'), mov_read_default },
9151 { MKTAG('w','a','v','e'), mov_read_wave },
9152 { MKTAG('e','s','d','s'), mov_read_esds },
9153 { MKTAG('d','a','c','3'), mov_read_dac3 }, /* AC-3 info */
9154 { MKTAG('d','e','c','3'), mov_read_dec3 }, /* EAC-3 info */
9155 { MKTAG('d','d','t','s'), mov_read_ddts }, /* DTS audio descriptor */
9156 { MKTAG('w','i','d','e'), mov_read_wide }, /* place holder */
9157 { MKTAG('w','f','e','x'), mov_read_wfex },
9158 { MKTAG('c','m','o','v'), mov_read_cmov },
9159 { MKTAG('c','h','a','n'), mov_read_chan }, /* channel layout from quicktime */
9160 { MKTAG('c','h','n','l'), mov_read_chnl }, /* channel layout from ISO-14496-12 */
9161 { MKTAG('d','v','c','1'), mov_read_dvc1 },
9162 { MKTAG('s','g','p','d'), mov_read_sgpd },
9163 { MKTAG('s','b','g','p'), mov_read_sbgp },
9164 { MKTAG('h','v','c','C'), mov_read_glbl },
9165 { MKTAG('v','v','c','C'), mov_read_glbl },
9166 { MKTAG('u','u','i','d'), mov_read_uuid },
9167 { MKTAG('C','i','n', 0x8e), mov_read_targa_y216 },
9168 { MKTAG('f','r','e','e'), mov_read_free },
9169 { MKTAG('-','-','-','-'), mov_read_custom },
9170 { MKTAG('s','i','n','f'), mov_read_default },
9171 { MKTAG('f','r','m','a'), mov_read_frma },
9172 { MKTAG('s','e','n','c'), mov_read_senc },
9173 { MKTAG('s','a','i','z'), mov_read_saiz },
9174 { MKTAG('s','a','i','o'), mov_read_saio },
9175 { MKTAG('p','s','s','h'), mov_read_pssh },
9176 { MKTAG('s','c','h','m'), mov_read_schm },
9177 { MKTAG('s','c','h','i'), mov_read_default },
9178 { MKTAG('t','e','n','c'), mov_read_tenc },
9179 { MKTAG('d','f','L','a'), mov_read_dfla },
9180 { MKTAG('s','t','3','d'), mov_read_st3d }, /* stereoscopic 3D video box */
9181 { MKTAG('s','v','3','d'), mov_read_sv3d }, /* spherical video box */
9182 { MKTAG('v','e','x','u'), mov_read_vexu }, /* video extension usage */
9183 { MKTAG('h','f','o','v'), mov_read_hfov },
9184 { MKTAG('d','O','p','s'), mov_read_dops },
9185 { MKTAG('d','m','l','p'), mov_read_dmlp },
9186 { MKTAG('S','m','D','m'), mov_read_smdm },
9187 { MKTAG('C','o','L','L'), mov_read_coll },
9188 { MKTAG('v','p','c','C'), mov_read_vpcc },
9189 { MKTAG('m','d','c','v'), mov_read_mdcv },
9190 { MKTAG('c','l','l','i'), mov_read_clli },
9191 { MKTAG('d','v','c','C'), mov_read_dvcc_dvvc },
9192 { MKTAG('d','v','v','C'), mov_read_dvcc_dvvc },
9193 { MKTAG('d','v','w','C'), mov_read_dvcc_dvvc },
9194 { MKTAG('k','i','n','d'), mov_read_kind },
9195 { MKTAG('S','A','3','D'), mov_read_SA3D }, /* ambisonic audio box */
9196 { MKTAG('S','A','N','D'), mov_read_SAND }, /* non diegetic audio box */
9197 { MKTAG('i','l','o','c'), mov_read_iloc },
9198 { MKTAG('p','c','m','C'), mov_read_pcmc }, /* PCM configuration box */
9199 { MKTAG('p','i','t','m'), mov_read_pitm },
9200 { MKTAG('e','v','c','C'), mov_read_glbl },
9201 { MKTAG('i','d','a','t'), mov_read_idat },
9202 { MKTAG('i','r','e','f'), mov_read_iref },
9203 { MKTAG('i','s','p','e'), mov_read_ispe },
9204 { MKTAG('i','p','r','p'), mov_read_iprp },
9205 { MKTAG('i','i','n','f'), mov_read_iinf },
9206 { MKTAG('a','m','v','e'), mov_read_amve }, /* ambient viewing environment box */
9207 { MKTAG('l','h','v','C'), mov_read_lhvc },
9208 { MKTAG('l','v','c','C'), mov_read_glbl },
9209 #if CONFIG_IAMFDEC
9210 { MKTAG('i','a','c','b'), mov_read_iacb },
9211 #endif
9212 { 0, NULL }
9213 };
9214 
9216 {
9217  int64_t total_size = 0;
9218  MOVAtom a;
9219  int i;
9220 
9221  if (c->atom_depth > 10) {
9222  av_log(c->fc, AV_LOG_ERROR, "Atoms too deeply nested\n");
9223  return AVERROR_INVALIDDATA;
9224  }
9225  c->atom_depth ++;
9226 
9227  if (atom.size < 0)
9228  atom.size = INT64_MAX;
9229  while (total_size <= atom.size - 8) {
9230  int (*parse)(MOVContext*, AVIOContext*, MOVAtom) = NULL;
9231  a.size = avio_rb32(pb);
9232  a.type = avio_rl32(pb);
9233  if (avio_feof(pb))
9234  break;
9235  if (((a.type == MKTAG('f','r','e','e') && c->moov_retry) ||
9236  a.type == MKTAG('h','o','o','v')) &&
9237  a.size >= 8 &&
9238  c->fc->strict_std_compliance < FF_COMPLIANCE_STRICT) {
9239  uint32_t type;
9240  avio_skip(pb, 4);
9241  type = avio_rl32(pb);
9242  if (avio_feof(pb))
9243  break;
9244  avio_seek(pb, -8, SEEK_CUR);
9245  if (type == MKTAG('m','v','h','d') ||
9246  type == MKTAG('c','m','o','v')) {
9247  av_log(c->fc, AV_LOG_ERROR, "Detected moov in a free or hoov atom.\n");
9248  a.type = MKTAG('m','o','o','v');
9249  }
9250  }
9251  if (atom.type != MKTAG('r','o','o','t') &&
9252  atom.type != MKTAG('m','o','o','v')) {
9253  if (a.type == MKTAG('t','r','a','k') ||
9254  a.type == MKTAG('m','d','a','t')) {
9255  av_log(c->fc, AV_LOG_ERROR, "Broken file, trak/mdat not at top-level\n");
9256  avio_skip(pb, -8);
9257  c->atom_depth --;
9258  return 0;
9259  }
9260  }
9261  total_size += 8;
9262  if (a.size == 1 && total_size + 8 <= atom.size) { /* 64 bit extended size */
9263  a.size = avio_rb64(pb) - 8;
9264  total_size += 8;
9265  }
9266  av_log(c->fc, AV_LOG_TRACE, "type:'%s' parent:'%s' sz: %"PRId64" %"PRId64" %"PRId64"\n",
9267  av_fourcc2str(a.type), av_fourcc2str(atom.type), a.size, total_size, atom.size);
9268  if (a.size == 0) {
9269  a.size = atom.size - total_size + 8;
9270  }
9271  if (a.size < 0)
9272  break;
9273  a.size -= 8;
9274  if (a.size < 0)
9275  break;
9276  a.size = FFMIN(a.size, atom.size - total_size);
9277 
9278  for (i = 0; mov_default_parse_table[i].type; i++)
9279  if (mov_default_parse_table[i].type == a.type) {
9281  break;
9282  }
9283 
9284  // container is user data
9285  if (!parse && (atom.type == MKTAG('u','d','t','a') ||
9286  atom.type == MKTAG('i','l','s','t')))
9288 
9289  // Supports parsing the QuickTime Metadata Keys.
9290  // https://developer.apple.com/library/mac/documentation/QuickTime/QTFF/Metadata/Metadata.html
9291  if (!parse && c->found_hdlr_mdta &&
9292  atom.type == MKTAG('m','e','t','a') &&
9293  a.type == MKTAG('k','e','y','s') &&
9294  c->meta_keys_count == 0) {
9295  parse = mov_read_keys;
9296  }
9297 
9298  if (!parse) { /* skip leaf atoms data */
9299  avio_skip(pb, a.size);
9300  } else {
9301  int64_t start_pos = avio_tell(pb);
9302  int64_t left;
9303  int err = parse(c, pb, a);
9304  if (err < 0) {
9305  c->atom_depth --;
9306  return err;
9307  }
9308  if (c->found_moov && c->found_mdat && a.size <= INT64_MAX - start_pos &&
9309  ((!(pb->seekable & AVIO_SEEKABLE_NORMAL) || c->fc->flags & AVFMT_FLAG_IGNIDX || c->frag_index.complete) ||
9310  start_pos + a.size == avio_size(pb))) {
9311  if (!(pb->seekable & AVIO_SEEKABLE_NORMAL) || c->fc->flags & AVFMT_FLAG_IGNIDX || c->frag_index.complete)
9312  c->next_root_atom = start_pos + a.size;
9313  c->atom_depth --;
9314  return 0;
9315  }
9316  left = a.size - avio_tell(pb) + start_pos;
9317  if (left > 0) /* skip garbage at atom end */
9318  avio_skip(pb, left);
9319  else if (left < 0) {
9320  av_log(c->fc, AV_LOG_WARNING,
9321  "overread end of atom '%s' by %"PRId64" bytes\n",
9322  av_fourcc2str(a.type), -left);
9323  avio_seek(pb, left, SEEK_CUR);
9324  }
9325  }
9326 
9327  total_size += a.size;
9328  }
9329 
9330  if (total_size < atom.size && atom.size < 0x7ffff)
9331  avio_skip(pb, atom.size - total_size);
9332 
9333  c->atom_depth --;
9334  return 0;
9335 }
9336 
9337 static int mov_probe(const AVProbeData *p)
9338 {
9339  int64_t offset;
9340  uint32_t tag;
9341  int score = 0;
9342  int moov_offset = -1;
9343 
9344  /* check file header */
9345  offset = 0;
9346  for (;;) {
9347  int64_t size;
9348  int minsize = 8;
9349  /* ignore invalid offset */
9350  if ((offset + 8ULL) > (unsigned int)p->buf_size)
9351  break;
9352  size = AV_RB32(p->buf + offset);
9353  if (size == 1 && offset + 16 <= (unsigned int)p->buf_size) {
9354  size = AV_RB64(p->buf+offset + 8);
9355  minsize = 16;
9356  } else if (size == 0) {
9357  size = p->buf_size - offset;
9358  }
9359  if (size < minsize) {
9360  offset += 4;
9361  continue;
9362  }
9363  tag = AV_RL32(p->buf + offset + 4);
9364  switch(tag) {
9365  /* check for obvious tags */
9366  case MKTAG('m','o','o','v'):
9367  moov_offset = offset + 4;
9368  case MKTAG('m','d','a','t'):
9369  case MKTAG('p','n','o','t'): /* detect movs with preview pics like ew.mov and april.mov */
9370  case MKTAG('u','d','t','a'): /* Packet Video PVAuthor adds this and a lot of more junk */
9371  case MKTAG('f','t','y','p'):
9372  if (tag == MKTAG('f','t','y','p') &&
9373  ( AV_RL32(p->buf + offset + 8) == MKTAG('j','p','2',' ')
9374  || AV_RL32(p->buf + offset + 8) == MKTAG('j','p','x',' ')
9375  || AV_RL32(p->buf + offset + 8) == MKTAG('j','x','l',' ')
9376  )) {
9377  score = FFMAX(score, 5);
9378  } else {
9379  score = AVPROBE_SCORE_MAX;
9380  }
9381  break;
9382  /* those are more common words, so rate then a bit less */
9383  case MKTAG('e','d','i','w'): /* xdcam files have reverted first tags */
9384  case MKTAG('w','i','d','e'):
9385  case MKTAG('f','r','e','e'):
9386  case MKTAG('j','u','n','k'):
9387  case MKTAG('p','i','c','t'):
9388  score = FFMAX(score, AVPROBE_SCORE_MAX - 5);
9389  break;
9390  case MKTAG(0x82,0x82,0x7f,0x7d):
9391  score = FFMAX(score, AVPROBE_SCORE_EXTENSION - 5);
9392  break;
9393  case MKTAG('s','k','i','p'):
9394  case MKTAG('u','u','i','d'):
9395  case MKTAG('p','r','f','l'):
9396  /* if we only find those cause probedata is too small at least rate them */
9397  score = FFMAX(score, AVPROBE_SCORE_EXTENSION);
9398  break;
9399  }
9400  if (size > INT64_MAX - offset)
9401  break;
9402  offset += size;
9403  }
9404  if (score > AVPROBE_SCORE_MAX - 50 && moov_offset != -1) {
9405  /* moov atom in the header - we should make sure that this is not a
9406  * MOV-packed MPEG-PS */
9407  offset = moov_offset;
9408 
9409  while (offset < (p->buf_size - 16)) { /* Sufficient space */
9410  /* We found an actual hdlr atom */
9411  if (AV_RL32(p->buf + offset ) == MKTAG('h','d','l','r') &&
9412  AV_RL32(p->buf + offset + 8) == MKTAG('m','h','l','r') &&
9413  AV_RL32(p->buf + offset + 12) == MKTAG('M','P','E','G')) {
9414  av_log(NULL, AV_LOG_WARNING, "Found media data tag MPEG indicating this is a MOV-packed MPEG-PS.\n");
9415  /* We found a media handler reference atom describing an
9416  * MPEG-PS-in-MOV, return a
9417  * low score to force expanding the probe window until
9418  * mpegps_probe finds what it needs */
9419  return 5;
9420  } else {
9421  /* Keep looking */
9422  offset += 2;
9423  }
9424  }
9425  }
9426 
9427  return score;
9428 }
9429 
9430 // must be done after parsing all trak because there's no order requirement
9432 {
9433  MOVContext *mov = s->priv_data;
9434  MOVStreamContext *sc;
9435  int64_t cur_pos;
9436  int i, j;
9437  int chapter_track;
9438 
9439  for (j = 0; j < mov->nb_chapter_tracks; j++) {
9440  AVStream *st = NULL;
9441  FFStream *sti = NULL;
9442  chapter_track = mov->chapter_tracks[j];
9443  for (i = 0; i < s->nb_streams; i++) {
9444  sc = mov->fc->streams[i]->priv_data;
9445  if (sc->id == chapter_track) {
9446  st = s->streams[i];
9447  break;
9448  }
9449  }
9450  if (!st) {
9451  av_log(s, AV_LOG_ERROR, "Referenced QT chapter track not found\n");
9452  continue;
9453  }
9454  sti = ffstream(st);
9455 
9456  sc = st->priv_data;
9457  cur_pos = avio_tell(sc->pb);
9458 
9459  if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
9461  if (!st->attached_pic.data && sti->nb_index_entries) {
9462  // Retrieve the first frame, if possible
9463  AVIndexEntry *sample = &sti->index_entries[0];
9464  if (avio_seek(sc->pb, sample->pos, SEEK_SET) != sample->pos) {
9465  av_log(s, AV_LOG_ERROR, "Failed to retrieve first frame\n");
9466  goto finish;
9467  }
9468 
9469  if (ff_add_attached_pic(s, st, sc->pb, NULL, sample->size) < 0)
9470  goto finish;
9471  }
9472  } else {
9475  st->discard = AVDISCARD_ALL;
9476  for (int i = 0; i < sti->nb_index_entries; i++) {
9477  AVIndexEntry *sample = &sti->index_entries[i];
9478  int64_t end = i+1 < sti->nb_index_entries ? sti->index_entries[i+1].timestamp : st->duration;
9479  uint8_t *title;
9480  uint16_t ch;
9481  int len, title_len;
9482 
9483  if (end < sample->timestamp) {
9484  av_log(s, AV_LOG_WARNING, "ignoring stream duration which is shorter than chapters\n");
9485  end = AV_NOPTS_VALUE;
9486  }
9487 
9488  if (avio_seek(sc->pb, sample->pos, SEEK_SET) != sample->pos) {
9489  av_log(s, AV_LOG_ERROR, "Chapter %d not found in file\n", i);
9490  goto finish;
9491  }
9492 
9493  // the first two bytes are the length of the title
9494  len = avio_rb16(sc->pb);
9495  if (len > sample->size-2)
9496  continue;
9497  title_len = 2*len + 1;
9498  if (!(title = av_mallocz(title_len)))
9499  goto finish;
9500 
9501  // The samples could theoretically be in any encoding if there's an encd
9502  // atom following, but in practice are only utf-8 or utf-16, distinguished
9503  // instead by the presence of a BOM
9504  if (!len) {
9505  title[0] = 0;
9506  } else {
9507  ch = avio_rb16(sc->pb);
9508  if (ch == 0xfeff)
9509  avio_get_str16be(sc->pb, len, title, title_len);
9510  else if (ch == 0xfffe)
9511  avio_get_str16le(sc->pb, len, title, title_len);
9512  else {
9513  AV_WB16(title, ch);
9514  if (len == 1 || len == 2)
9515  title[len] = 0;
9516  else
9517  avio_get_str(sc->pb, INT_MAX, title + 2, len - 1);
9518  }
9519  }
9520 
9521  avpriv_new_chapter(s, i, st->time_base, sample->timestamp, end, title);
9522  av_freep(&title);
9523  }
9524  }
9525 finish:
9526  avio_seek(sc->pb, cur_pos, SEEK_SET);
9527  }
9528 }
9529 
9531  int64_t value, int flags)
9532 {
9533  AVTimecode tc;
9534  char buf[AV_TIMECODE_STR_SIZE];
9535  AVRational rate = st->avg_frame_rate;
9536  int ret = av_timecode_init(&tc, rate, flags, 0, s);
9537  if (ret < 0)
9538  return ret;
9539  av_dict_set(&st->metadata, "timecode",
9540  av_timecode_make_string(&tc, buf, value), 0);
9541  return 0;
9542 }
9543 
9545 {
9546  MOVStreamContext *sc = st->priv_data;
9547  FFStream *const sti = ffstream(st);
9548  char buf[AV_TIMECODE_STR_SIZE];
9549  int64_t cur_pos = avio_tell(sc->pb);
9550  int hh, mm, ss, ff, drop;
9551 
9552  if (!sti->nb_index_entries)
9553  return -1;
9554 
9555  avio_seek(sc->pb, sti->index_entries->pos, SEEK_SET);
9556  avio_skip(s->pb, 13);
9557  hh = avio_r8(s->pb);
9558  mm = avio_r8(s->pb);
9559  ss = avio_r8(s->pb);
9560  drop = avio_r8(s->pb);
9561  ff = avio_r8(s->pb);
9562  snprintf(buf, AV_TIMECODE_STR_SIZE, "%02d:%02d:%02d%c%02d",
9563  hh, mm, ss, drop ? ';' : ':', ff);
9564  av_dict_set(&st->metadata, "timecode", buf, 0);
9565 
9566  avio_seek(sc->pb, cur_pos, SEEK_SET);
9567  return 0;
9568 }
9569 
9571 {
9572  MOVStreamContext *sc = st->priv_data;
9573  FFStream *const sti = ffstream(st);
9574  int flags = 0;
9575  int64_t cur_pos = avio_tell(sc->pb);
9576  int64_t value;
9577  AVRational tc_rate = st->avg_frame_rate;
9578  int tmcd_nb_frames = sc->tmcd_nb_frames;
9579  int rounded_tc_rate;
9580 
9581  if (!sti->nb_index_entries)
9582  return -1;
9583 
9584  if (!tc_rate.num || !tc_rate.den || !tmcd_nb_frames)
9585  return -1;
9586 
9587  avio_seek(sc->pb, sti->index_entries->pos, SEEK_SET);
9588  value = avio_rb32(s->pb);
9589 
9590  if (sc->tmcd_flags & 0x0001) flags |= AV_TIMECODE_FLAG_DROPFRAME;
9591  if (sc->tmcd_flags & 0x0002) flags |= AV_TIMECODE_FLAG_24HOURSMAX;
9592  if (sc->tmcd_flags & 0x0004) flags |= AV_TIMECODE_FLAG_ALLOWNEGATIVE;
9593 
9594  /* Assume Counter flag is set to 1 in tmcd track (even though it is likely
9595  * not the case) and thus assume "frame number format" instead of QT one.
9596  * No sample with tmcd track can be found with a QT timecode at the moment,
9597  * despite what the tmcd track "suggests" (Counter flag set to 0 means QT
9598  * format). */
9599 
9600  /* 60 fps content have tmcd_nb_frames set to 30 but tc_rate set to 60, so
9601  * we multiply the frame number with the quotient.
9602  * See tickets #9492, #9710. */
9603  rounded_tc_rate = (tc_rate.num + tc_rate.den / 2LL) / tc_rate.den;
9604  /* Work around files where tmcd_nb_frames is rounded down from frame rate
9605  * instead of up. See ticket #5978. */
9606  if (tmcd_nb_frames == tc_rate.num / tc_rate.den &&
9607  s->strict_std_compliance < FF_COMPLIANCE_STRICT)
9608  tmcd_nb_frames = rounded_tc_rate;
9609  value = av_rescale(value, rounded_tc_rate, tmcd_nb_frames);
9610 
9612 
9613  avio_seek(sc->pb, cur_pos, SEEK_SET);
9614  return 0;
9615 }
9616 
9618  int i;
9619  if (!index || !*index) return;
9620  for (i = 0; i < (*index)->nb_encrypted_samples; i++) {
9621  av_encryption_info_free((*index)->encrypted_samples[i]);
9622  }
9623  av_freep(&(*index)->encrypted_samples);
9624  av_freep(&(*index)->auxiliary_info_sizes);
9625  av_freep(&(*index)->auxiliary_offsets);
9626  av_freep(index);
9627 }
9628 
9630 {
9631  MOVStreamContext *sc = st->priv_data;
9632 
9633  if (!sc || --sc->refcount) {
9634  st->priv_data = NULL;
9635  return;
9636  }
9637 
9638  av_freep(&sc->ctts_data);
9639  for (int i = 0; i < sc->drefs_count; i++) {
9640  av_freep(&sc->drefs[i].path);
9641  av_freep(&sc->drefs[i].dir);
9642  }
9643  av_freep(&sc->drefs);
9644 
9645  sc->drefs_count = 0;
9646 
9647  if (!sc->pb_is_copied)
9648  ff_format_io_close(s, &sc->pb);
9649 
9650  sc->pb = NULL;
9651  av_freep(&sc->chunk_offsets);
9652  av_freep(&sc->stsc_data);
9653  av_freep(&sc->sample_sizes);
9654  av_freep(&sc->keyframes);
9655  av_freep(&sc->stts_data);
9656  av_freep(&sc->sdtp_data);
9657  av_freep(&sc->stps_data);
9658  av_freep(&sc->elst_data);
9659  av_freep(&sc->rap_group);
9660  av_freep(&sc->sync_group);
9661  av_freep(&sc->sgpd_sync);
9662  av_freep(&sc->sample_offsets);
9663  av_freep(&sc->open_key_samples);
9664  av_freep(&sc->display_matrix);
9665  av_freep(&sc->index_ranges);
9666 
9667  if (sc->extradata)
9668  for (int i = 0; i < sc->stsd_count; i++)
9669  av_free(sc->extradata[i]);
9670  av_freep(&sc->extradata);
9671  av_freep(&sc->extradata_size);
9672 
9676 
9677  av_freep(&sc->stereo3d);
9678  av_freep(&sc->spherical);
9679  av_freep(&sc->mastering);
9680  av_freep(&sc->coll);
9681  av_freep(&sc->ambient);
9682 
9683 #if CONFIG_IAMFDEC
9684  if (sc->iamf)
9686 #endif
9687  av_freep(&sc->iamf);
9688 }
9689 
9691 {
9692  MOVContext *mov = s->priv_data;
9693  int i, j;
9694 
9695  for (i = 0; i < s->nb_streams; i++) {
9696  AVStream *st = s->streams[i];
9697 
9699  }
9700 
9701  av_freep(&mov->dv_demux);
9703  mov->dv_fctx = NULL;
9704 
9705  if (mov->meta_keys) {
9706  for (i = 1; i < mov->meta_keys_count; i++) {
9707  av_freep(&mov->meta_keys[i]);
9708  }
9709  av_freep(&mov->meta_keys);
9710  }
9711 
9712  av_freep(&mov->trex_data);
9713  av_freep(&mov->bitrates);
9714 
9715  for (i = 0; i < mov->frag_index.nb_items; i++) {
9717  for (j = 0; j < mov->frag_index.item[i].nb_stream_info; j++) {
9718  mov_free_encryption_index(&frag[j].encryption_index);
9719  }
9721  }
9722  av_freep(&mov->frag_index.item);
9723 
9724  av_freep(&mov->aes_decrypt);
9725  av_freep(&mov->chapter_tracks);
9726  for (i = 0; i < mov->nb_heif_item; i++) {
9727  if (!mov->heif_item[i])
9728  continue;
9729  av_freep(&mov->heif_item[i]->name);
9730  av_freep(&mov->heif_item[i]);
9731  }
9732  av_freep(&mov->heif_item);
9733  for (i = 0; i < mov->nb_heif_grid; i++) {
9734  av_freep(&mov->heif_grid[i].tile_id_list);
9736  }
9737  av_freep(&mov->heif_grid);
9738 
9739  return 0;
9740 }
9741 
9742 static int tmcd_is_referenced(AVFormatContext *s, int tmcd_id)
9743 {
9744  int i;
9745 
9746  for (i = 0; i < s->nb_streams; i++) {
9747  AVStream *st = s->streams[i];
9748  MOVStreamContext *sc = st->priv_data;
9749 
9750  if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO &&
9751  sc->timecode_track == tmcd_id)
9752  return 1;
9753  }
9754  return 0;
9755 }
9756 
9757 /* look for a tmcd track not referenced by any video track, and export it globally */
9759 {
9760  int i;
9761 
9762  for (i = 0; i < s->nb_streams; i++) {
9763  AVStream *st = s->streams[i];
9764 
9765  if (st->codecpar->codec_tag == MKTAG('t','m','c','d') &&
9766  !tmcd_is_referenced(s, i + 1)) {
9767  AVDictionaryEntry *tcr = av_dict_get(st->metadata, "timecode", NULL, 0);
9768  if (tcr) {
9769  av_dict_set(&s->metadata, "timecode", tcr->value, 0);
9770  break;
9771  }
9772  }
9773  }
9774 }
9775 
9776 static int read_tfra(MOVContext *mov, AVIOContext *f)
9777 {
9778  int version, fieldlength, i, j;
9779  int64_t pos = avio_tell(f);
9780  uint32_t size = avio_rb32(f);
9781  unsigned track_id, item_count;
9782 
9783  if (avio_rb32(f) != MKBETAG('t', 'f', 'r', 'a')) {
9784  return 1;
9785  }
9786  av_log(mov->fc, AV_LOG_VERBOSE, "found tfra\n");
9787 
9788  version = avio_r8(f);
9789  avio_rb24(f);
9790  track_id = avio_rb32(f);
9791  fieldlength = avio_rb32(f);
9792  item_count = avio_rb32(f);
9793  for (i = 0; i < item_count; i++) {
9794  int64_t time, offset;
9795  int index;
9796  MOVFragmentStreamInfo * frag_stream_info;
9797 
9798  if (avio_feof(f)) {
9799  return AVERROR_INVALIDDATA;
9800  }
9801 
9802  if (version == 1) {
9803  time = avio_rb64(f);
9804  offset = avio_rb64(f);
9805  } else {
9806  time = avio_rb32(f);
9807  offset = avio_rb32(f);
9808  }
9809 
9810  // The first sample of each stream in a fragment is always a random
9811  // access sample. So it's entry in the tfra can be used as the
9812  // initial PTS of the fragment.
9813  index = update_frag_index(mov, offset);
9814  frag_stream_info = get_frag_stream_info(&mov->frag_index, index, track_id);
9815  if (frag_stream_info &&
9816  frag_stream_info->first_tfra_pts == AV_NOPTS_VALUE)
9817  frag_stream_info->first_tfra_pts = time;
9818 
9819  for (j = 0; j < ((fieldlength >> 4) & 3) + 1; j++)
9820  avio_r8(f);
9821  for (j = 0; j < ((fieldlength >> 2) & 3) + 1; j++)
9822  avio_r8(f);
9823  for (j = 0; j < ((fieldlength >> 0) & 3) + 1; j++)
9824  avio_r8(f);
9825  }
9826 
9827  avio_seek(f, pos + size, SEEK_SET);
9828  return 0;
9829 }
9830 
9832 {
9833  int64_t stream_size = avio_size(f);
9834  int64_t original_pos = avio_tell(f);
9835  int64_t seek_ret;
9836  int ret = -1;
9837  if ((seek_ret = avio_seek(f, stream_size - 4, SEEK_SET)) < 0) {
9838  ret = seek_ret;
9839  goto fail;
9840  }
9841  c->mfra_size = avio_rb32(f);
9842  c->have_read_mfra_size = 1;
9843  if (!c->mfra_size || c->mfra_size > stream_size) {
9844  av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (unreasonable size)\n");
9845  goto fail;
9846  }
9847  if ((seek_ret = avio_seek(f, -((int64_t) c->mfra_size), SEEK_CUR)) < 0) {
9848  ret = seek_ret;
9849  goto fail;
9850  }
9851  if (avio_rb32(f) != c->mfra_size) {
9852  av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (size mismatch)\n");
9853  goto fail;
9854  }
9855  if (avio_rb32(f) != MKBETAG('m', 'f', 'r', 'a')) {
9856  av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (tag mismatch)\n");
9857  goto fail;
9858  }
9859  av_log(c->fc, AV_LOG_VERBOSE, "stream has mfra\n");
9860  do {
9861  ret = read_tfra(c, f);
9862  if (ret < 0)
9863  goto fail;
9864  } while (!ret);
9865  ret = 0;
9866  c->frag_index.complete = 1;
9867 fail:
9868  seek_ret = avio_seek(f, original_pos, SEEK_SET);
9869  if (seek_ret < 0) {
9870  av_log(c->fc, AV_LOG_ERROR,
9871  "failed to seek back after looking for mfra\n");
9872  ret = seek_ret;
9873  }
9874  return ret;
9875 }
9876 
9877 static int read_image_grid(AVFormatContext *s, const HEIFGrid *grid,
9878  AVStreamGroupTileGrid *tile_grid)
9879 {
9880  MOVContext *c = s->priv_data;
9881  const HEIFItem *item = grid->item;
9882  int64_t offset = 0, pos = avio_tell(s->pb);
9883  int x = 0, y = 0, i = 0;
9884  int tile_rows, tile_cols;
9885  int flags, size;
9886 
9887  if (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL)) {
9888  av_log(c->fc, AV_LOG_INFO, "grid box with non seekable input\n");
9889  return AVERROR_PATCHWELCOME;
9890  }
9891  if (item->is_idat_relative) {
9892  if (!c->idat_offset) {
9893  av_log(c->fc, AV_LOG_ERROR, "missing idat box required by the image grid\n");
9894  return AVERROR_INVALIDDATA;
9895  }
9896  offset = c->idat_offset;
9897  }
9898 
9899  avio_seek(s->pb, item->extent_offset + offset, SEEK_SET);
9900 
9901  avio_r8(s->pb); /* version */
9902  flags = avio_r8(s->pb);
9903 
9904  tile_rows = avio_r8(s->pb) + 1;
9905  tile_cols = avio_r8(s->pb) + 1;
9906  /* actual width and height of output image */
9907  tile_grid->width = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
9908  tile_grid->height = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
9909 
9910  av_log(c->fc, AV_LOG_TRACE, "grid: grid_rows %d grid_cols %d output_width %d output_height %d\n",
9911  tile_rows, tile_cols, tile_grid->width, tile_grid->height);
9912 
9913  avio_seek(s->pb, pos, SEEK_SET);
9914 
9915  size = tile_rows * tile_cols;
9916  tile_grid->nb_tiles = grid->nb_tiles;
9917 
9918  if (tile_grid->nb_tiles != size)
9919  return AVERROR_INVALIDDATA;
9920 
9921  for (int i = 0; i < tile_cols; i++)
9922  tile_grid->coded_width += grid->tile_item_list[i]->width;
9923  for (int i = 0; i < size; i += tile_cols)
9924  tile_grid->coded_height += grid->tile_item_list[i]->height;
9925 
9926  tile_grid->offsets = av_calloc(tile_grid->nb_tiles, sizeof(*tile_grid->offsets));
9927  if (!tile_grid->offsets)
9928  return AVERROR(ENOMEM);
9929 
9930  while (y < tile_grid->coded_height) {
9931  int left_col = i;
9932 
9933  while (x < tile_grid->coded_width) {
9934  if (i == tile_grid->nb_tiles)
9935  return AVERROR_INVALIDDATA;
9936 
9937  tile_grid->offsets[i].idx = i;
9938  tile_grid->offsets[i].horizontal = x;
9939  tile_grid->offsets[i].vertical = y;
9940 
9941  x += grid->tile_item_list[i++]->width;
9942  }
9943 
9944  if (x > tile_grid->coded_width) {
9945  av_log(c->fc, AV_LOG_ERROR, "Non uniform HEIF tiles\n");
9946  return AVERROR_INVALIDDATA;
9947  }
9948 
9949  x = 0;
9950  y += grid->tile_item_list[left_col]->height;
9951  }
9952 
9953  if (y > tile_grid->coded_height || i != tile_grid->nb_tiles) {
9954  av_log(c->fc, AV_LOG_ERROR, "Non uniform HEIF tiles\n");
9955  return AVERROR_INVALIDDATA;
9956  }
9957 
9958  return 0;
9959 }
9960 
9961 static int read_image_iovl(AVFormatContext *s, const HEIFGrid *grid,
9962  AVStreamGroupTileGrid *tile_grid)
9963 {
9964  MOVContext *c = s->priv_data;
9965  const HEIFItem *item = grid->item;
9966  uint16_t canvas_fill_value[4];
9967  int64_t offset = 0, pos = avio_tell(s->pb);
9968  int ret = 0, flags;
9969 
9970  if (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL)) {
9971  av_log(c->fc, AV_LOG_INFO, "iovl box with non seekable input\n");
9972  return AVERROR_PATCHWELCOME;
9973  }
9974  if (item->is_idat_relative) {
9975  if (!c->idat_offset) {
9976  av_log(c->fc, AV_LOG_ERROR, "missing idat box required by the image overlay\n");
9977  return AVERROR_INVALIDDATA;
9978  }
9979  offset = c->idat_offset;
9980  }
9981 
9982  avio_seek(s->pb, item->extent_offset + offset, SEEK_SET);
9983 
9984  avio_r8(s->pb); /* version */
9985  flags = avio_r8(s->pb);
9986 
9987  for (int i = 0; i < 4; i++)
9988  canvas_fill_value[i] = avio_rb16(s->pb);
9989  av_log(c->fc, AV_LOG_TRACE, "iovl: canvas_fill_value { %u, %u, %u, %u }\n",
9990  canvas_fill_value[0], canvas_fill_value[1],
9991  canvas_fill_value[2], canvas_fill_value[3]);
9992  for (int i = 0; i < 4; i++)
9993  tile_grid->background[i] = canvas_fill_value[i];
9994 
9995  /* actual width and height of output image */
9996  tile_grid->width =
9997  tile_grid->coded_width = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
9998  tile_grid->height =
9999  tile_grid->coded_height = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
10000  av_log(c->fc, AV_LOG_TRACE, "iovl: output_width %d, output_height %d\n",
10001  tile_grid->width, tile_grid->height);
10002 
10003  tile_grid->nb_tiles = grid->nb_tiles;
10004  tile_grid->offsets = av_malloc_array(tile_grid->nb_tiles, sizeof(*tile_grid->offsets));
10005  if (!tile_grid->offsets) {
10006  ret = AVERROR(ENOMEM);
10007  goto fail;
10008  }
10009 
10010  for (int i = 0; i < tile_grid->nb_tiles; i++) {
10011  tile_grid->offsets[i].idx = grid->tile_item_list[i]->st->index;
10012  tile_grid->offsets[i].horizontal = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
10013  tile_grid->offsets[i].vertical = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
10014  av_log(c->fc, AV_LOG_TRACE, "iovl: stream_idx[%d] %u, "
10015  "horizontal_offset[%d] %d, vertical_offset[%d] %d\n",
10016  i, tile_grid->offsets[i].idx,
10017  i, tile_grid->offsets[i].horizontal, i, tile_grid->offsets[i].vertical);
10018  }
10019 
10020 fail:
10021  avio_seek(s->pb, pos, SEEK_SET);
10022 
10023  return ret;
10024 }
10025 
10027 {
10028  MOVContext *mov = s->priv_data;
10029 
10030  for (int i = 0; i < mov->nb_heif_grid; i++) {
10032  AVStreamGroupTileGrid *tile_grid;
10033  const HEIFGrid *grid = &mov->heif_grid[i];
10034  int err, loop = 1;
10035 
10036  if (!stg)
10037  return AVERROR(ENOMEM);
10038 
10039  stg->id = grid->item->item_id;
10040  tile_grid = stg->params.tile_grid;
10041 
10042  for (int j = 0; j < grid->nb_tiles; j++) {
10043  int tile_id = grid->tile_id_list[j];
10044  int k;
10045 
10046  for (k = 0; k < mov->nb_heif_item; k++) {
10047  HEIFItem *item = mov->heif_item[k];
10048  AVStream *st;
10049 
10050  if (!item || item->item_id != tile_id)
10051  continue;
10052  st = item->st;
10053  if (!st) {
10054  av_log(s, AV_LOG_WARNING, "HEIF item id %d from grid id %d doesn't "
10055  "reference a stream\n",
10056  tile_id, grid->item->item_id);
10057  ff_remove_stream_group(s, stg);
10058  loop = 0;
10059  break;
10060  }
10061 
10062  grid->tile_item_list[j] = item;
10063 
10064  err = avformat_stream_group_add_stream(stg, st);
10065  if (err < 0 && err != AVERROR(EEXIST))
10066  return err;
10067 
10068  if (item->item_id != mov->primary_item_id)
10070  break;
10071  }
10072 
10073  if (k == mov->nb_heif_item) {
10074  av_assert0(loop);
10075  av_log(s, AV_LOG_WARNING, "HEIF item id %d referenced by grid id %d doesn't "
10076  "exist\n",
10077  tile_id, grid->item->item_id);
10078  ff_remove_stream_group(s, stg);
10079  loop = 0;
10080  }
10081  if (!loop)
10082  break;
10083  }
10084 
10085  if (!loop)
10086  continue;
10087 
10088  switch (grid->item->type) {
10089  case MKTAG('g','r','i','d'):
10090  err = read_image_grid(s, grid, tile_grid);
10091  break;
10092  case MKTAG('i','o','v','l'):
10093  err = read_image_iovl(s, grid, tile_grid);
10094  break;
10095  default:
10096  av_assert0(0);
10097  }
10098  if (err < 0)
10099  return err;
10100 
10101 
10102  if (grid->item->name)
10103  av_dict_set(&stg->metadata, "title", grid->item->name, 0);
10104  if (grid->item->item_id == mov->primary_item_id)
10106  }
10107 
10108  return 0;
10109 }
10110 
10112 {
10113  MOVContext *mov = s->priv_data;
10114  int err;
10115 
10116  for (int i = 0; i < mov->nb_heif_item; i++) {
10117  HEIFItem *item = mov->heif_item[i];
10118  MOVStreamContext *sc;
10119  AVStream *st;
10120  int64_t offset = 0;
10121 
10122  if (!item)
10123  continue;
10124  if (!item->st) {
10125  if (item->item_id == mov->thmb_item_id) {
10126  av_log(s, AV_LOG_ERROR, "HEIF thumbnail doesn't reference a stream\n");
10127  return AVERROR_INVALIDDATA;
10128  }
10129  continue;
10130  }
10131  if (item->is_idat_relative) {
10132  if (!mov->idat_offset) {
10133  av_log(s, AV_LOG_ERROR, "Missing idat box for item %d\n", item->item_id);
10134  return AVERROR_INVALIDDATA;
10135  }
10136  offset = mov->idat_offset;
10137  }
10138 
10139  st = item->st;
10140  sc = st->priv_data;
10141  st->codecpar->width = item->width;
10142  st->codecpar->height = item->height;
10143 
10144  err = sanity_checks(s, sc, item->item_id);
10145  if (err)
10146  return AVERROR_INVALIDDATA;
10147 
10148  sc->sample_sizes[0] = item->extent_length;
10149  sc->chunk_offsets[0] = item->extent_offset + offset;
10150 
10151  if (item->item_id == mov->primary_item_id)
10153 
10154  mov_build_index(mov, st);
10155  }
10156 
10157  if (mov->nb_heif_grid) {
10158  err = mov_parse_tiles(s);
10159  if (err < 0)
10160  return err;
10161  }
10162 
10163  return 0;
10164 }
10165 
10167  int first_index)
10168 {
10169  MOVStreamContext *sc = st->priv_data;
10170 
10171  if (sc->tref_id < 0)
10172  return NULL;
10173 
10174  for (int i = first_index; i < s->nb_streams; i++)
10175  if (s->streams[i]->id == sc->tref_id)
10176  return s->streams[i];
10177 
10178  return NULL;
10179 }
10180 
10182 {
10183  MOVContext *mov = s->priv_data;
10184  AVIOContext *pb = s->pb;
10185  int j, err;
10186  MOVAtom atom = { AV_RL32("root") };
10187  int i;
10188 
10189  if (mov->decryption_key_len != 0 && mov->decryption_key_len != AES_CTR_KEY_SIZE) {
10190  av_log(s, AV_LOG_ERROR, "Invalid decryption key len %d expected %d\n",
10192  return AVERROR(EINVAL);
10193  }
10194 
10195  mov->fc = s;
10196  mov->trak_index = -1;
10197  mov->thmb_item_id = -1;
10198  mov->primary_item_id = -1;
10199  mov->cur_item_id = -1;
10200  /* .mov and .mp4 aren't streamable anyway (only progressive download if moov is before mdat) */
10201  if (pb->seekable & AVIO_SEEKABLE_NORMAL)
10202  atom.size = avio_size(pb);
10203  else
10204  atom.size = INT64_MAX;
10205 
10206  /* check MOV header */
10207  do {
10208  if (mov->moov_retry)
10209  avio_seek(pb, 0, SEEK_SET);
10210  if ((err = mov_read_default(mov, pb, atom)) < 0) {
10211  av_log(s, AV_LOG_ERROR, "error reading header\n");
10212  return err;
10213  }
10214  } while ((pb->seekable & AVIO_SEEKABLE_NORMAL) &&
10215  !mov->found_moov && (!mov->found_iloc || !mov->found_iinf) && !mov->moov_retry++);
10216  if (!mov->found_moov && !mov->found_iloc && !mov->found_iinf) {
10217  av_log(s, AV_LOG_ERROR, "moov atom not found\n");
10218  return AVERROR_INVALIDDATA;
10219  }
10220  av_log(mov->fc, AV_LOG_TRACE, "on_parse_exit_offset=%"PRId64"\n", avio_tell(pb));
10221 
10222  if (mov->found_iloc && mov->found_iinf) {
10223  err = mov_parse_heif_items(s);
10224  if (err < 0)
10225  return err;
10226  }
10227  // prevent iloc and iinf boxes from being parsed while reading packets.
10228  // this is needed because an iinf box may have been parsed but ignored
10229  // for having old infe boxes which create no streams.
10230  mov->found_iloc = mov->found_iinf = 1;
10231 
10232  if (pb->seekable & AVIO_SEEKABLE_NORMAL) {
10233  if (mov->nb_chapter_tracks > 0 && !mov->ignore_chapters)
10235  for (i = 0; i < s->nb_streams; i++)
10236  if (s->streams[i]->codecpar->codec_tag == AV_RL32("tmcd")) {
10237  mov_read_timecode_track(s, s->streams[i]);
10238  } else if (s->streams[i]->codecpar->codec_tag == AV_RL32("rtmd")) {
10239  mov_read_rtmd_track(s, s->streams[i]);
10240  }
10241  }
10242 
10243  /* copy timecode metadata from tmcd tracks to the related video streams */
10244  for (i = 0; i < s->nb_streams; i++) {
10245  AVStream *st = s->streams[i];
10246  MOVStreamContext *sc = st->priv_data;
10247  if (sc->timecode_track > 0) {
10248  AVDictionaryEntry *tcr;
10249  int tmcd_st_id = -1;
10250 
10251  for (j = 0; j < s->nb_streams; j++) {
10252  MOVStreamContext *sc2 = s->streams[j]->priv_data;
10253  if (sc2->id == sc->timecode_track)
10254  tmcd_st_id = j;
10255  }
10256 
10257  if (tmcd_st_id < 0 || tmcd_st_id == i)
10258  continue;
10259  tcr = av_dict_get(s->streams[tmcd_st_id]->metadata, "timecode", NULL, 0);
10260  if (tcr)
10261  av_dict_set(&st->metadata, "timecode", tcr->value, 0);
10262  }
10263  }
10265 
10266  /* Create LCEVC stream groups. */
10267  for (i = 0; i < s->nb_streams; i++) {
10268  AVStreamGroup *stg;
10269  AVStream *st = s->streams[i];
10270  AVStream *st_base;
10271  MOVStreamContext *sc = st->priv_data;
10272 
10273  /* Find an enhancement stream. */
10274  if (st->codecpar->codec_id != AV_CODEC_ID_LCEVC ||
10276  continue;
10277 
10279 
10281  if (!stg)
10282  return AVERROR(ENOMEM);
10283 
10284  stg->id = st->id;
10285  stg->params.lcevc->width = st->codecpar->width;
10286  stg->params.lcevc->height = st->codecpar->height;
10287  st->codecpar->width = 0;
10288  st->codecpar->height = 0;
10289 
10290  j = 0;
10291  while (st_base = mov_find_reference_track(s, st, j)) {
10292  err = avformat_stream_group_add_stream(stg, st_base);
10293  if (err < 0)
10294  return err;
10295 
10296  j = st_base->index + 1;
10297  }
10298  if (!j) {
10299  av_log(s, AV_LOG_ERROR, "Failed to find base stream for enhancement stream\n");
10300  return AVERROR_INVALIDDATA;
10301  }
10302 
10303  err = avformat_stream_group_add_stream(stg, st);
10304  if (err < 0)
10305  return err;
10306 
10307  stg->params.lcevc->lcevc_index = stg->nb_streams - 1;
10308  }
10309 
10310  for (i = 0; i < s->nb_streams; i++) {
10311  AVStream *st = s->streams[i];
10312  FFStream *const sti = ffstream(st);
10313  MOVStreamContext *sc = st->priv_data;
10314  fix_timescale(mov, sc);
10315  if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
10316  st->codecpar->codec_id == AV_CODEC_ID_AAC) {
10317  sti->skip_samples = sc->start_pad;
10318  }
10319  if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && sc->nb_frames_for_fps > 0 && sc->duration_for_fps > 0)
10321  sc->time_scale*(int64_t)sc->nb_frames_for_fps, sc->duration_for_fps, INT_MAX);
10323  if (st->codecpar->width <= 0 || st->codecpar->height <= 0) {
10324  st->codecpar->width = sc->width;
10325  st->codecpar->height = sc->height;
10326  }
10328  if ((err = mov_rewrite_dvd_sub_extradata(st)) < 0)
10329  return err;
10330  }
10331  }
10332  if (mov->handbrake_version &&
10333  mov->handbrake_version <= 1000000*0 + 1000*10 + 2 && // 0.10.2
10334  st->codecpar->codec_id == AV_CODEC_ID_MP3) {
10335  av_log(s, AV_LOG_VERBOSE, "Forcing full parsing for mp3 stream\n");
10337  }
10338  }
10339 
10340  if (mov->trex_data || mov->use_mfra_for > 0) {
10341  for (i = 0; i < s->nb_streams; i++) {
10342  AVStream *st = s->streams[i];
10343  MOVStreamContext *sc = st->priv_data;
10344  if (sc->duration_for_fps > 0) {
10345  /* Akin to sc->data_size * 8 * sc->time_scale / sc->duration_for_fps but accounting for overflows. */
10347  if (st->codecpar->bit_rate == INT64_MIN) {
10348  av_log(s, AV_LOG_WARNING, "Overflow during bit rate calculation %"PRId64" * 8 * %d\n",
10349  sc->data_size, sc->time_scale);
10350  st->codecpar->bit_rate = 0;
10351  if (s->error_recognition & AV_EF_EXPLODE)
10352  return AVERROR_INVALIDDATA;
10353  }
10354  }
10355  }
10356  }
10357 
10358  for (i = 0; i < mov->bitrates_count && i < s->nb_streams; i++) {
10359  if (mov->bitrates[i]) {
10360  s->streams[i]->codecpar->bit_rate = mov->bitrates[i];
10361  }
10362  }
10363 
10365 
10366  for (i = 0; i < s->nb_streams; i++) {
10367  AVStream *st = s->streams[i];
10368  MOVStreamContext *sc = st->priv_data;
10369 
10370  switch (st->codecpar->codec_type) {
10371  case AVMEDIA_TYPE_AUDIO:
10372  err = ff_replaygain_export(st, s->metadata);
10373  if (err < 0)
10374  return err;
10375  break;
10376  case AVMEDIA_TYPE_VIDEO:
10377  if (sc->display_matrix) {
10380  (uint8_t*)sc->display_matrix, sizeof(int32_t) * 9, 0))
10381  return AVERROR(ENOMEM);
10382 
10383  sc->display_matrix = NULL;
10384  }
10385  if (sc->stereo3d) {
10388  (uint8_t *)sc->stereo3d, sc->stereo3d_size, 0))
10389  return AVERROR(ENOMEM);
10390 
10391  sc->stereo3d = NULL;
10392  }
10393  if (sc->spherical) {
10396  (uint8_t *)sc->spherical, sc->spherical_size, 0))
10397  return AVERROR(ENOMEM);
10398 
10399  sc->spherical = NULL;
10400  }
10401  if (sc->mastering) {
10404  (uint8_t *)sc->mastering, sc->mastering_size, 0))
10405  return AVERROR(ENOMEM);
10406 
10407  sc->mastering = NULL;
10408  }
10409  if (sc->coll) {
10412  (uint8_t *)sc->coll, sc->coll_size, 0))
10413  return AVERROR(ENOMEM);
10414 
10415  sc->coll = NULL;
10416  }
10417  if (sc->ambient) {
10420  (uint8_t *) sc->ambient, sc->ambient_size, 0))
10421  return AVERROR(ENOMEM);
10422 
10423  sc->ambient = NULL;
10424  }
10425  break;
10426  }
10427  }
10429 
10430  for (i = 0; i < mov->frag_index.nb_items; i++)
10431  if (mov->frag_index.item[i].moof_offset <= mov->fragment.moof_offset)
10432  mov->frag_index.item[i].headers_read = 1;
10433 
10434  return 0;
10435 }
10436 
10438 {
10440  int64_t best_dts = INT64_MAX;
10441  int i;
10442  MOVContext *mov = s->priv_data;
10443  int no_interleave = !mov->interleaved_read || !(s->pb->seekable & AVIO_SEEKABLE_NORMAL);
10444  for (i = 0; i < s->nb_streams; i++) {
10445  AVStream *avst = s->streams[i];
10446  FFStream *const avsti = ffstream(avst);
10447  MOVStreamContext *msc = avst->priv_data;
10448  if (msc->pb && msc->current_sample < avsti->nb_index_entries) {
10449  AVIndexEntry *current_sample = &avsti->index_entries[msc->current_sample];
10450  int64_t dts = av_rescale(current_sample->timestamp, AV_TIME_BASE, msc->time_scale);
10451  uint64_t dtsdiff = best_dts > dts ? best_dts - (uint64_t)dts : ((uint64_t)dts - best_dts);
10452  av_log(s, AV_LOG_TRACE, "stream %d, sample %d, dts %"PRId64"\n", i, msc->current_sample, dts);
10453  if (!sample || (no_interleave && current_sample->pos < sample->pos) ||
10454  ((s->pb->seekable & AVIO_SEEKABLE_NORMAL) &&
10455  ((msc->pb != s->pb && dts < best_dts) || (msc->pb == s->pb && dts != AV_NOPTS_VALUE &&
10456  ((dtsdiff <= AV_TIME_BASE && current_sample->pos < sample->pos) ||
10457  (dtsdiff > AV_TIME_BASE && dts < best_dts && mov->interleaved_read)))))) {
10458  sample = current_sample;
10459  best_dts = dts;
10460  *st = avst;
10461  }
10462  }
10463  }
10464  return sample;
10465 }
10466 
10467 static int should_retry(AVIOContext *pb, int error_code) {
10468  if (error_code == AVERROR_EOF || avio_feof(pb))
10469  return 0;
10470 
10471  return 1;
10472 }
10473 
10474 static int mov_switch_root(AVFormatContext *s, int64_t target, int index)
10475 {
10476  int ret;
10477  MOVContext *mov = s->priv_data;
10478 
10479  if (index >= 0 && index < mov->frag_index.nb_items)
10480  target = mov->frag_index.item[index].moof_offset;
10481  if (avio_seek(s->pb, target, SEEK_SET) != target) {
10482  av_log(mov->fc, AV_LOG_ERROR, "root atom offset 0x%"PRIx64": partial file\n", target);
10483  return AVERROR_INVALIDDATA;
10484  }
10485 
10486  mov->next_root_atom = 0;
10487  if (index < 0 || index >= mov->frag_index.nb_items)
10488  index = search_frag_moof_offset(&mov->frag_index, target);
10489  if (index < mov->frag_index.nb_items &&
10490  mov->frag_index.item[index].moof_offset == target) {
10491  if (index + 1 < mov->frag_index.nb_items)
10492  mov->next_root_atom = mov->frag_index.item[index + 1].moof_offset;
10493  if (mov->frag_index.item[index].headers_read)
10494  return 0;
10495  mov->frag_index.item[index].headers_read = 1;
10496  }
10497 
10498  mov->found_mdat = 0;
10499 
10500  ret = mov_read_default(mov, s->pb, (MOVAtom){ AV_RL32("root"), INT64_MAX });
10501  if (ret < 0)
10502  return ret;
10503  if (avio_feof(s->pb))
10504  return AVERROR_EOF;
10505  av_log(s, AV_LOG_TRACE, "read fragments, offset 0x%"PRIx64"\n", avio_tell(s->pb));
10506 
10507  return 1;
10508 }
10509 
10511 {
10512  MOVStreamContext *sc = st->priv_data;
10513  uint8_t *side, *extradata;
10514  int extradata_size;
10515 
10516  /* Save the current index. */
10517  sc->last_stsd_index = sc->stsc_data[sc->stsc_index].id - 1;
10518 
10519  /* Notify the decoder that extradata changed. */
10520  extradata_size = sc->extradata_size[sc->last_stsd_index];
10521  extradata = sc->extradata[sc->last_stsd_index];
10522  if (st->discard != AVDISCARD_ALL && extradata_size > 0 && extradata) {
10525  extradata_size);
10526  if (!side)
10527  return AVERROR(ENOMEM);
10528  memcpy(side, extradata, extradata_size);
10529  }
10530 
10531  return 0;
10532 }
10533 
10534 static int get_eia608_packet(AVIOContext *pb, AVPacket *pkt, int src_size)
10535 {
10536  /* We can't make assumptions about the structure of the payload,
10537  because it may include multiple cdat and cdt2 samples. */
10538  const uint32_t cdat = AV_RB32("cdat");
10539  const uint32_t cdt2 = AV_RB32("cdt2");
10540  int ret, out_size = 0;
10541 
10542  /* a valid payload must have size, 4cc, and at least 1 byte pair: */
10543  if (src_size < 10)
10544  return AVERROR_INVALIDDATA;
10545 
10546  /* avoid an int overflow: */
10547  if ((src_size - 8) / 2 >= INT_MAX / 3)
10548  return AVERROR_INVALIDDATA;
10549 
10550  ret = av_new_packet(pkt, ((src_size - 8) / 2) * 3);
10551  if (ret < 0)
10552  return ret;
10553 
10554  /* parse and re-format the c608 payload in one pass. */
10555  while (src_size >= 10) {
10556  const uint32_t atom_size = avio_rb32(pb);
10557  const uint32_t atom_type = avio_rb32(pb);
10558  const uint32_t data_size = atom_size - 8;
10559  const uint8_t cc_field =
10560  atom_type == cdat ? 1 :
10561  atom_type == cdt2 ? 2 :
10562  0;
10563 
10564  /* account for bytes consumed for atom size and type. */
10565  src_size -= 8;
10566 
10567  /* make sure the data size stays within the buffer boundaries. */
10568  if (data_size < 2 || data_size > src_size) {
10570  break;
10571  }
10572 
10573  /* make sure the data size is consistent with N byte pairs. */
10574  if (data_size % 2 != 0) {
10576  break;
10577  }
10578 
10579  if (!cc_field) {
10580  /* neither cdat or cdt2 ... skip it */
10581  avio_skip(pb, data_size);
10582  src_size -= data_size;
10583  continue;
10584  }
10585 
10586  for (uint32_t i = 0; i < data_size; i += 2) {
10587  pkt->data[out_size] = (0x1F << 3) | (1 << 2) | (cc_field - 1);
10588  pkt->data[out_size + 1] = avio_r8(pb);
10589  pkt->data[out_size + 2] = avio_r8(pb);
10590  out_size += 3;
10591  src_size -= 2;
10592  }
10593  }
10594 
10595  if (src_size > 0)
10596  /* skip any remaining unread portion of the input payload */
10597  avio_skip(pb, src_size);
10598 
10600  return ret;
10601 }
10602 
10604  int64_t current_index, AVPacket *pkt)
10605 {
10606  MOVStreamContext *sc = st->priv_data;
10607 
10608  pkt->stream_index = sc->ffindex;
10609  pkt->dts = sample->timestamp;
10610  if (sample->flags & AVINDEX_DISCARD_FRAME) {
10612  }
10613  if (sc->ctts_data && sc->ctts_index < sc->ctts_count) {
10615  /* update ctts context */
10616  sc->ctts_sample++;
10617  if (sc->ctts_index < sc->ctts_count &&
10618  sc->ctts_data[sc->ctts_index].count == sc->ctts_sample) {
10619  sc->ctts_index++;
10620  sc->ctts_sample = 0;
10621  }
10622  } else {
10623  int64_t next_dts = (sc->current_sample < ffstream(st)->nb_index_entries) ?
10625 
10626  if (next_dts >= pkt->dts)
10627  pkt->duration = next_dts - pkt->dts;
10628  pkt->pts = pkt->dts;
10629  }
10630 
10631  if (sc->sdtp_data && sc->current_sample <= sc->sdtp_count) {
10632  uint8_t sample_flags = sc->sdtp_data[sc->current_sample - 1];
10633  uint8_t sample_is_depended_on = (sample_flags >> 2) & 0x3;
10634  pkt->flags |= sample_is_depended_on == MOV_SAMPLE_DEPENDENCY_NO ? AV_PKT_FLAG_DISPOSABLE : 0;
10635  }
10636  pkt->flags |= sample->flags & AVINDEX_KEYFRAME ? AV_PKT_FLAG_KEY : 0;
10637  pkt->pos = sample->pos;
10638 
10639  /* Multiple stsd handling. */
10640  if (sc->stsc_data) {
10641  if (sc->stsc_data[sc->stsc_index].id > 0 &&
10642  sc->stsc_data[sc->stsc_index].id - 1 < sc->stsd_count &&
10643  sc->stsc_data[sc->stsc_index].id - 1 != sc->last_stsd_index) {
10644  int ret = mov_change_extradata(st, pkt);
10645  if (ret < 0)
10646  return ret;
10647  }
10648 
10649  /* Update the stsc index for the next sample */
10650  sc->stsc_sample++;
10651  if (mov_stsc_index_valid(sc->stsc_index, sc->stsc_count) &&
10652  mov_get_stsc_samples(sc, sc->stsc_index) == sc->stsc_sample) {
10653  sc->stsc_index++;
10654  sc->stsc_sample = 0;
10655  }
10656  }
10657 
10658  return 0;
10659 }
10660 
10662 {
10663  MOVContext *mov = s->priv_data;
10664  MOVStreamContext *sc;
10666  AVStream *st = NULL;
10667  int64_t current_index;
10668  int ret;
10669  mov->fc = s;
10670  retry:
10671  sample = mov_find_next_sample(s, &st);
10672  if (!sample || (mov->next_root_atom && sample->pos > mov->next_root_atom)) {
10673  if (!mov->next_root_atom)
10674  return AVERROR_EOF;
10675  if ((ret = mov_switch_root(s, mov->next_root_atom, -1)) < 0)
10676  return ret;
10677  goto retry;
10678  }
10679  sc = st->priv_data;
10680  /* must be done just before reading, to avoid infinite loop on sample */
10681  current_index = sc->current_index;
10683 
10684  if (mov->next_root_atom) {
10685  sample->pos = FFMIN(sample->pos, mov->next_root_atom);
10686  sample->size = FFMIN(sample->size, (mov->next_root_atom - sample->pos));
10687  }
10688 
10689  if (st->discard != AVDISCARD_ALL) {
10690  int64_t ret64 = avio_seek(sc->pb, sample->pos, SEEK_SET);
10691  if (ret64 != sample->pos) {
10692  av_log(mov->fc, AV_LOG_ERROR, "stream %d, offset 0x%"PRIx64": partial file\n",
10693  sc->ffindex, sample->pos);
10694  if (should_retry(sc->pb, ret64)) {
10696  } else if (ret64 < 0) {
10697  return (int)ret64;
10698  }
10699  return AVERROR_INVALIDDATA;
10700  }
10701 
10702  if (st->discard == AVDISCARD_NONKEY && !(sample->flags & AVINDEX_KEYFRAME)) {
10703  av_log(mov->fc, AV_LOG_DEBUG, "Nonkey frame from stream %d discarded due to AVDISCARD_NONKEY\n", sc->ffindex);
10704  goto retry;
10705  }
10706 
10707  if (st->codecpar->codec_id == AV_CODEC_ID_EIA_608 && sample->size > 8)
10708  ret = get_eia608_packet(sc->pb, pkt, sample->size);
10709 #if CONFIG_IAMFDEC
10710  else if (sc->iamf) {
10711  int64_t pts, dts, pos, duration;
10712  int flags, size = sample->size;
10713  ret = mov_finalize_packet(s, st, sample, current_index, pkt);
10714  pts = pkt->pts; dts = pkt->dts;
10715  pos = pkt->pos; flags = pkt->flags;
10716  duration = pkt->duration;
10717  while (!ret && size > 0) {
10718  ret = ff_iamf_read_packet(s, sc->iamf, sc->pb, size, pkt);
10719  if (ret < 0) {
10720  if (should_retry(sc->pb, ret))
10722  return ret;
10723  }
10724  size -= ret;
10725  pkt->pts = pts; pkt->dts = dts;
10726  pkt->pos = pos; pkt->flags |= flags;
10727  pkt->duration = duration;
10728  ret = ff_buffer_packet(s, pkt);
10729  }
10730  if (!ret)
10731  return FFERROR_REDO;
10732  }
10733 #endif
10734  else
10735  ret = av_get_packet(sc->pb, pkt, sample->size);
10736  if (ret < 0) {
10737  if (should_retry(sc->pb, ret)) {
10739  }
10740  return ret;
10741  }
10742 #if CONFIG_DV_DEMUXER
10743  if (mov->dv_demux && sc->dv_audio_container) {
10746  if (ret < 0)
10747  return ret;
10749  if (ret < 0)
10750  return ret;
10751  }
10752 #endif
10753  if (sc->has_palette) {
10754  uint8_t *pal;
10755 
10757  if (!pal) {
10758  av_log(mov->fc, AV_LOG_ERROR, "Cannot append palette to packet\n");
10759  } else {
10760  memcpy(pal, sc->palette, AVPALETTE_SIZE);
10761  sc->has_palette = 0;
10762  }
10763  }
10764  if (st->codecpar->codec_id == AV_CODEC_ID_MP3 && !ffstream(st)->need_parsing && pkt->size > 4) {
10765  if (ff_mpa_check_header(AV_RB32(pkt->data)) < 0)
10767  }
10768  }
10769 
10770  ret = mov_finalize_packet(s, st, sample, current_index, pkt);
10771  if (ret < 0)
10772  return ret;
10773 
10774  if (st->discard == AVDISCARD_ALL)
10775  goto retry;
10776 
10777  if (mov->aax_mode)
10778  aax_filter(pkt->data, pkt->size, mov);
10779 
10780  ret = cenc_filter(mov, st, sc, pkt, current_index);
10781  if (ret < 0) {
10782  return ret;
10783  }
10784 
10785  return 0;
10786 }
10787 
10789 {
10790  MOVContext *mov = s->priv_data;
10791  int index;
10792 
10793  if (!mov->frag_index.complete)
10794  return 0;
10795 
10796  index = search_frag_timestamp(s, &mov->frag_index, st, timestamp);
10797  if (index < 0)
10798  index = 0;
10799  if (!mov->frag_index.item[index].headers_read)
10800  return mov_switch_root(s, -1, index);
10801  if (index + 1 < mov->frag_index.nb_items)
10802  mov->next_root_atom = mov->frag_index.item[index + 1].moof_offset;
10803 
10804  return 0;
10805 }
10806 
10807 static int is_open_key_sample(const MOVStreamContext *sc, int sample)
10808 {
10809  // TODO: a bisect search would scale much better
10810  for (int i = 0; i < sc->open_key_samples_count; i++) {
10811  const int oks = sc->open_key_samples[i];
10812  if (oks == sample)
10813  return 1;
10814  if (oks > sample) /* list is monotically increasing so we can stop early */
10815  break;
10816  }
10817  return 0;
10818 }
10819 
10820 /*
10821  * Some key sample may be key frames but not IDR frames, so a random access to
10822  * them may not be allowed.
10823  */
10824 static int can_seek_to_key_sample(AVStream *st, int sample, int64_t requested_pts)
10825 {
10826  MOVStreamContext *sc = st->priv_data;
10827  FFStream *const sti = ffstream(st);
10828  int64_t key_sample_dts, key_sample_pts;
10829 
10830  if (st->codecpar->codec_id != AV_CODEC_ID_HEVC)
10831  return 1;
10832 
10833  if (sample >= sc->sample_offsets_count)
10834  return 1;
10835 
10836  key_sample_dts = sti->index_entries[sample].timestamp;
10837  key_sample_pts = key_sample_dts + sc->sample_offsets[sample] + sc->dts_shift;
10838 
10839  /*
10840  * If the sample needs to be presented before an open key sample, they may
10841  * not be decodable properly, even though they come after in decoding
10842  * order.
10843  */
10844  if (is_open_key_sample(sc, sample) && key_sample_pts > requested_pts)
10845  return 0;
10846 
10847  return 1;
10848 }
10849 
10850 static int mov_seek_stream(AVFormatContext *s, AVStream *st, int64_t timestamp, int flags)
10851 {
10852  MOVStreamContext *sc = st->priv_data;
10853  FFStream *const sti = ffstream(st);
10854  int sample, time_sample, ret, next_ts, requested_sample;
10855  unsigned int i;
10856 
10857  // Here we consider timestamp to be PTS, hence try to offset it so that we
10858  // can search over the DTS timeline.
10859  timestamp -= (sc->min_corrected_pts + sc->dts_shift);
10860 
10861  ret = mov_seek_fragment(s, st, timestamp);
10862  if (ret < 0)
10863  return ret;
10864 
10865  for (;;) {
10866  sample = av_index_search_timestamp(st, timestamp, flags);
10867  av_log(s, AV_LOG_TRACE, "stream %d, timestamp %"PRId64", sample %d\n", st->index, timestamp, sample);
10868  if (sample < 0 && sti->nb_index_entries && timestamp < sti->index_entries[0].timestamp)
10869  sample = 0;
10870  if (sample < 0) /* not sure what to do */
10871  return AVERROR_INVALIDDATA;
10872 
10873  if (!sample || can_seek_to_key_sample(st, sample, timestamp))
10874  break;
10875 
10876  next_ts = timestamp - FFMAX(sc->min_sample_duration, 1);
10877  requested_sample = av_index_search_timestamp(st, next_ts, flags);
10878 
10879  // If we've reached a different sample trying to find a good pts to
10880  // seek to, give up searching because we'll end up seeking back to
10881  // sample 0 on every seek.
10882  if (sample != requested_sample && !can_seek_to_key_sample(st, requested_sample, next_ts))
10883  break;
10884 
10885  timestamp = next_ts;
10886  }
10887 
10889  av_log(s, AV_LOG_TRACE, "stream %d, found sample %d\n", st->index, sc->current_sample);
10890  /* adjust ctts index */
10891  if (sc->ctts_data) {
10892  time_sample = 0;
10893  for (i = 0; i < sc->ctts_count; i++) {
10894  int next = time_sample + sc->ctts_data[i].count;
10895  if (next > sc->current_sample) {
10896  sc->ctts_index = i;
10897  sc->ctts_sample = sc->current_sample - time_sample;
10898  break;
10899  }
10900  time_sample = next;
10901  }
10902  }
10903 
10904  /* adjust stsd index */
10905  if (sc->chunk_count) {
10906  time_sample = 0;
10907  for (i = 0; i < sc->stsc_count; i++) {
10908  int64_t next = time_sample + mov_get_stsc_samples(sc, i);
10909  if (next > sc->current_sample) {
10910  sc->stsc_index = i;
10911  sc->stsc_sample = sc->current_sample - time_sample;
10912  break;
10913  }
10914  av_assert0(next == (int)next);
10915  time_sample = next;
10916  }
10917  }
10918 
10919  return sample;
10920 }
10921 
10923 {
10924  MOVStreamContext *sc = st->priv_data;
10925  FFStream *const sti = ffstream(st);
10926  int64_t first_ts = sti->index_entries[0].timestamp;
10928  int64_t off;
10929 
10931  return 0;
10932 
10933  /* compute skip samples according to stream start_pad, seek ts and first ts */
10934  off = av_rescale_q(ts - first_ts, st->time_base,
10935  (AVRational){1, st->codecpar->sample_rate});
10936  return FFMAX(sc->start_pad - off, 0);
10937 }
10938 
10939 static int mov_read_seek(AVFormatContext *s, int stream_index, int64_t sample_time, int flags)
10940 {
10941  MOVContext *mc = s->priv_data;
10942  AVStream *st;
10943  FFStream *sti;
10944  int sample;
10945  int i;
10946 
10947  if (stream_index >= s->nb_streams)
10948  return AVERROR_INVALIDDATA;
10949 
10950  st = s->streams[stream_index];
10951  sti = ffstream(st);
10952  sample = mov_seek_stream(s, st, sample_time, flags);
10953  if (sample < 0)
10954  return sample;
10955 
10956  if (mc->seek_individually) {
10957  /* adjust seek timestamp to found sample timestamp */
10958  int64_t seek_timestamp = sti->index_entries[sample].timestamp;
10960 
10961  for (i = 0; i < s->nb_streams; i++) {
10962  AVStream *const st = s->streams[i];
10963  FFStream *const sti = ffstream(st);
10964  int64_t timestamp;
10965 
10966  if (stream_index == i)
10967  continue;
10968 
10969  timestamp = av_rescale_q(seek_timestamp, s->streams[stream_index]->time_base, st->time_base);
10970  sample = mov_seek_stream(s, st, timestamp, flags);
10971  if (sample >= 0)
10973  }
10974  } else {
10975  for (i = 0; i < s->nb_streams; i++) {
10976  MOVStreamContext *sc;
10977  st = s->streams[i];
10978  sc = st->priv_data;
10979  mov_current_sample_set(sc, 0);
10980  }
10981  while (1) {
10982  MOVStreamContext *sc;
10984  if (!entry)
10985  return AVERROR_INVALIDDATA;
10986  sc = st->priv_data;
10987  if (sc->ffindex == stream_index && sc->current_sample == sample)
10988  break;
10990  }
10991  }
10992  return 0;
10993 }
10994 
10995 #define OFFSET(x) offsetof(MOVContext, x)
10996 #define FLAGS AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM
10997 static const AVOption mov_options[] = {
10998  {"use_absolute_path",
10999  "allow using absolute path when opening alias, this is a possible security issue",
11000  OFFSET(use_absolute_path), AV_OPT_TYPE_BOOL, {.i64 = 0},
11001  0, 1, FLAGS},
11002  {"seek_streams_individually",
11003  "Seek each stream individually to the closest point",
11004  OFFSET(seek_individually), AV_OPT_TYPE_BOOL, { .i64 = 1 },
11005  0, 1, FLAGS},
11006  {"ignore_editlist", "Ignore the edit list atom.", OFFSET(ignore_editlist), AV_OPT_TYPE_BOOL, {.i64 = 0},
11007  0, 1, FLAGS},
11008  {"advanced_editlist",
11009  "Modify the AVIndex according to the editlists. Use this option to decode in the order specified by the edits.",
11010  OFFSET(advanced_editlist), AV_OPT_TYPE_BOOL, {.i64 = 1},
11011  0, 1, FLAGS},
11012  {"ignore_chapters", "", OFFSET(ignore_chapters), AV_OPT_TYPE_BOOL, {.i64 = 0},
11013  0, 1, FLAGS},
11014  {"use_mfra_for",
11015  "use mfra for fragment timestamps",
11016  OFFSET(use_mfra_for), AV_OPT_TYPE_INT, {.i64 = FF_MOV_FLAG_MFRA_AUTO},
11018  .unit = "use_mfra_for"},
11019  {"auto", "auto", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_AUTO}, 0, 0,
11020  FLAGS, .unit = "use_mfra_for" },
11021  {"dts", "dts", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_DTS}, 0, 0,
11022  FLAGS, .unit = "use_mfra_for" },
11023  {"pts", "pts", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_PTS}, 0, 0,
11024  FLAGS, .unit = "use_mfra_for" },
11025  {"use_tfdt", "use tfdt for fragment timestamps", OFFSET(use_tfdt), AV_OPT_TYPE_BOOL, {.i64 = 1},
11026  0, 1, FLAGS},
11027  { "export_all", "Export unrecognized metadata entries", OFFSET(export_all),
11028  AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = FLAGS },
11029  { "export_xmp", "Export full XMP metadata", OFFSET(export_xmp),
11030  AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = FLAGS },
11031  { "activation_bytes", "Secret bytes for Audible AAX files", OFFSET(activation_bytes),
11033  { "audible_key", "AES-128 Key for Audible AAXC files", OFFSET(audible_key),
11035  { "audible_iv", "AES-128 IV for Audible AAXC files", OFFSET(audible_iv),
11037  { "audible_fixed_key", // extracted from libAAX_SDK.so and AAXSDKWin.dll files!
11038  "Fixed key used for handling Audible AAX files", OFFSET(audible_fixed_key),
11039  AV_OPT_TYPE_BINARY, {.str="77214d4b196a87cd520045fd20a51d67"},
11040  .flags = AV_OPT_FLAG_DECODING_PARAM },
11041  { "decryption_key", "The media decryption key (hex)", OFFSET(decryption_key), AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM },
11042  { "enable_drefs", "Enable external track support.", OFFSET(enable_drefs), AV_OPT_TYPE_BOOL,
11043  {.i64 = 0}, 0, 1, FLAGS },
11044  { "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 },
11045  { "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 },
11046 
11047  { NULL },
11048 };
11049 
11050 static const AVClass mov_class = {
11051  .class_name = "mov,mp4,m4a,3gp,3g2,mj2",
11052  .item_name = av_default_item_name,
11053  .option = mov_options,
11054  .version = LIBAVUTIL_VERSION_INT,
11055 };
11056 
11058  .p.name = "mov,mp4,m4a,3gp,3g2,mj2",
11059  .p.long_name = NULL_IF_CONFIG_SMALL("QuickTime / MOV"),
11060  .p.priv_class = &mov_class,
11061  .p.extensions = "mov,mp4,m4a,3gp,3g2,mj2,psp,m4b,ism,ismv,isma,f4v,avif,heic,heif",
11063  .priv_data_size = sizeof(MOVContext),
11064  .flags_internal = FF_INFMT_FLAG_INIT_CLEANUP,
11065  .read_probe = mov_probe,
11070 };
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:42
MOVStreamContext::ctts_allocated_size
unsigned int ctts_allocated_size
Definition: isom.h:181
item_name
item_name
Definition: libkvazaar.c:319
AV_CODEC_ID_PCM_S16LE
@ AV_CODEC_ID_PCM_S16LE
Definition: codec_id.h:328
MOVStreamContext::cenc
struct MOVStreamContext::@384 cenc
mov_read_chpl
static int mov_read_chpl(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:592
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:7167
mov_read_meta
static int mov_read_meta(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5384
AV_CODEC_ID_EIA_608
@ AV_CODEC_ID_EIA_608
Definition: codec_id.h:560
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:429
MOVContext::found_iloc
int found_iloc
'iloc' atom has been found
Definition: isom.h:303
AV_CODEC_ID_MACE6
@ AV_CODEC_ID_MACE6
Definition: codec_id.h:450
MOVFragmentStreamInfo::first_tfra_pts
int64_t first_tfra_pts
Definition: isom.h:136
ff_rfps_add_frame
int ff_rfps_add_frame(AVFormatContext *ic, AVStream *st, int64_t ts)
add frame for rfps calculation.
Definition: demux.c:2286
read_image_iovl
static int read_image_iovl(AVFormatContext *s, const HEIFGrid *grid, AVStreamGroupTileGrid *tile_grid)
Definition: mov.c:9961
AV_PRIMARY_EYE_RIGHT
@ AV_PRIMARY_EYE_RIGHT
Right eye.
Definition: stereo3d.h:188
AVMEDIA_TYPE_SUBTITLE
@ AVMEDIA_TYPE_SUBTITLE
Definition: avutil.h:204
AVIAMFSubmix::elements
AVIAMFSubmixElement ** elements
Array of submix elements.
Definition: iamf.h:561
skip_bits_long
static void skip_bits_long(GetBitContext *s, int n)
Skips the specified number of bits.
Definition: get_bits.h:278
AVStreamGroup::params
union AVStreamGroup::@363 params
Group type-specific parameters.
AV_LOG_WARNING
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:186
AV_BPRINT_SIZE_UNLIMITED
#define AV_BPRINT_SIZE_UNLIMITED
MOV_TFHD_DEFAULT_FLAGS
#define MOV_TFHD_DEFAULT_FLAGS
Definition: isom.h:383
PUT_UTF8
#define PUT_UTF8(val, tmp, PUT_BYTE)
Definition: common.h:541
AV_TIMECODE_STR_SIZE
#define AV_TIMECODE_STR_SIZE
Definition: timecode.h:33
av_aes_init
int av_aes_init(AVAES *a, const uint8_t *key, int key_bits, int decrypt)
Initialize an AVAES context.
Definition: aes.c:201
AV_CODEC_ID_PCM_F32BE
@ AV_CODEC_ID_PCM_F32BE
Definition: codec_id.h:348
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:273
MOVStreamContext::audio_cid
int16_t audio_cid
stsd audio compression id
Definition: isom.h:211
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:373
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:8234
can_seek_to_key_sample
static int can_seek_to_key_sample(AVStream *st, int sample, int64_t requested_pts)
Definition: mov.c:10824
AV_CODEC_ID_ADPCM_IMA_QT
@ AV_CODEC_ID_ADPCM_IMA_QT
Definition: codec_id.h:367
entry
#define entry
Definition: aom_film_grain_template.c:66
AVFMT_NO_BYTE_SEEK
#define AVFMT_NO_BYTE_SEEK
Format does not allow seeking by bytes.
Definition: avformat.h:487
AV_EF_EXPLODE
#define AV_EF_EXPLODE
abort decoding on minor error detection
Definition: defs.h:51
AVStreamGroup::id
int64_t id
Group type-specific group ID.
Definition: avformat.h:1140
AV_CODEC_ID_AC3
@ AV_CODEC_ID_AC3
Definition: codec_id.h:443
HEIFItem::name
char * name
Definition: isom.h:280
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:233
MOVStreamContext::height
int height
tkhd height
Definition: isom.h:219
MOVContext::moov_retry
int moov_retry
Definition: isom.h:331
MOV_TRUN_SAMPLE_FLAGS
#define MOV_TRUN_SAMPLE_FLAGS
Definition: isom.h:391
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:319
mix
static int mix(int c0, int c1)
Definition: 4xm.c:716
MOVStreamContext::last_stsd_index
int last_stsd_index
Definition: isom.h:248
ff_ac3_channel_layout_tab
const uint16_t ff_ac3_channel_layout_tab[8]
Map audio coding mode (acmod) to channel layout mask.
Definition: ac3_channel_layout_tab.h:31
r
const char * r
Definition: vf_curves.c:127
AVERROR
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later. That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another. Frame references ownership and permissions
opt.h
MOV_TKHD_FLAG_ENABLED
#define MOV_TKHD_FLAG_ENABLED
Definition: isom.h:404
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:1156
AVFMT_SHOW_IDS
#define AVFMT_SHOW_IDS
Show format stream IDs numbers.
Definition: avformat.h:477
AVSphericalMapping::projection
enum AVSphericalProjection projection
Projection type.
Definition: spherical.h:98
AV_WL32
#define AV_WL32(p, v)
Definition: intreadwrite.h:422
AV_STREAM_GROUP_PARAMS_LCEVC
@ AV_STREAM_GROUP_PARAMS_LCEVC
Definition: avformat.h:1115
MOVStreamContext::extradata
uint8_t ** extradata
extradata array (and size) for multiple stsd
Definition: isom.h:246
mov_class
static const AVClass mov_class
Definition: mov.c:11050
AVSphericalMapping::bound_bottom
uint32_t bound_bottom
Distance from the bottom edge.
Definition: spherical.h:182
MOVStreamContext::open_key_samples
int * open_key_samples
Definition: isom.h:238
AVUUID
uint8_t AVUUID[AV_UUID_LEN]
Definition: uuid.h:60
out
FILE * out
Definition: movenc.c:55
MOVFragmentStreamInfo
Definition: isom.h:133
AVFieldOrder
AVFieldOrder
Definition: defs.h:200
mov_read_targa_y216
static int mov_read_targa_y216(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2222
mov_read_chnl
static int mov_read_chnl(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1186
mov_read_moof
static int mov_read_moof(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1776
av_bprint_init
void av_bprint_init(AVBPrint *buf, unsigned size_init, unsigned size_max)
Definition: bprint.c:69
cb
static double cb(void *priv, double x, double y)
Definition: vf_geq.c:247
ctype
#define ctype
Definition: afir_template.c:46
AV_PKT_DATA_FRAME_CROPPING
@ AV_PKT_DATA_FRAME_CROPPING
The number of pixels to discard from the top/bottom/left/right border of the decoded frame to obtain ...
Definition: packet.h:340
AVCodecParameters
This struct describes the properties of an encoded stream.
Definition: codec_par.h:47
AVFMT_FLAG_IGNIDX
#define AVFMT_FLAG_IGNIDX
Ignore index.
Definition: avformat.h:1440
sanity_checks
static int sanity_checks(void *log_obj, MOVStreamContext *sc, int index)
Definition: mov.c:5024
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:9742
AV_PKT_DATA_NEW_EXTRADATA
@ AV_PKT_DATA_NEW_EXTRADATA
The AV_PKT_DATA_NEW_EXTRADATA is used to notify the codec or the format that the extradata buffer was...
Definition: packet.h:56
IAMFAudioElement::nb_substreams
unsigned int nb_substreams
Definition: iamf.h:99
AVStream::priv_data
void * priv_data
Definition: avformat.h:773
AVERROR_EOF
#define AVERROR_EOF
End of file.
Definition: error.h:57
AV_DISPOSITION_ATTACHED_PIC
#define AV_DISPOSITION_ATTACHED_PIC
The stream is stored in the file as an attached picture/"cover art" (e.g.
Definition: avformat.h:674
AVStream::discard
enum AVDiscard discard
Selects which packets can be discarded at will and do not need to be demuxed.
Definition: avformat.h:819
AV_FIELD_PROGRESSIVE
@ AV_FIELD_PROGRESSIVE
Definition: defs.h:202
mov_options
static const AVOption mov_options[]
Definition: mov.c:10997
mov_codec_id
static int mov_codec_id(AVStream *st, uint32_t format)
Definition: mov.c:2571
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:236
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:8625
AVMasteringDisplayMetadata::display_primaries
AVRational display_primaries[3][2]
CIE 1931 xy chromaticity coords of color primaries (r, g, b order).
Definition: mastering_display_metadata.h:42
AV_PKT_FLAG_DISCARD
#define AV_PKT_FLAG_DISCARD
Flag is used to discard packets which are required to maintain valid decoder state but are not requir...
Definition: packet.h:601
AVMasteringDisplayMetadata::has_luminance
int has_luminance
Flag indicating whether the luminance (min_ and max_) have been set.
Definition: mastering_display_metadata.h:67
get_bits_long
static unsigned int get_bits_long(GetBitContext *s, int n)
Read 0-32 bits.
Definition: get_bits.h:421
int64_t
long long int64_t
Definition: coverity.c:34
output
filter_frame For filters that do not use the this method is called when a frame is pushed to the filter s input It can be called at any time except in a reentrant way If the input frame is enough to produce output
Definition: filter_design.txt:225
mov_read_alac
static int mov_read_alac(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2194
test_same_origin
static int test_same_origin(const char *src, const char *ref)
Definition: mov.c:4867
cbcs_scheme_decrypt
static int cbcs_scheme_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
Definition: mov.c:8057
MOVFragment::base_data_offset
uint64_t base_data_offset
Definition: isom.h:98
MOVStreamContext
Definition: isom.h:167
AVChannelLayout::map
AVChannelCustom * map
This member must be used when the channel order is AV_CHANNEL_ORDER_CUSTOM.
Definition: channel_layout.h:362
MOVStreamContext::stsc_data
MOVStsc * stsc_data
Definition: isom.h:184
ff_buffer_packet
int ff_buffer_packet(AVFormatContext *s, AVPacket *pkt)
Definition: demux.c:609
IS_MATRIX_IDENT
#define IS_MATRIX_IDENT(matrix)
Definition: mov.c:5402
AVStreamGroup::disposition
int disposition
Stream group disposition - a combination of AV_DISPOSITION_* flags.
Definition: avformat.h:1198
dict_internal.h
av_unused
#define av_unused
Definition: attributes.h:131
AV_DISPOSITION_DEFAULT
#define AV_DISPOSITION_DEFAULT
The stream should be chosen by default among other streams of the same type, unless the user has expl...
Definition: avformat.h:621
mov_update_dts_shift
static void mov_update_dts_shift(MOVStreamContext *sc, int duration, void *logctx)
Definition: mov.c:3628
MOVStreamContext::spherical
AVSphericalMapping * spherical
Definition: isom.h:255
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:120
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:2199
AV_RB32A
#define AV_RB32A(p)
Definition: intreadwrite.h:575
MOVContext::primary_item_id
int primary_item_id
Definition: isom.h:356
MOVContext::found_moov
int found_moov
'moov' atom has been found
Definition: isom.h:302
tmp
static uint8_t tmp[11]
Definition: aes_ctr.c:28
mov_read_custom
static int mov_read_custom(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5246
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:1355
HEIFGrid::nb_tiles
int nb_tiles
Definition: isom.h:294
ID3v1_GENRE_MAX
#define ID3v1_GENRE_MAX
Definition: id3v1.h:29
MOVSbgp
Definition: isom.h:115
MOVCtts
Definition: isom.h:62
AVPacketSideData
This structure stores auxiliary information for decoding, presenting, or otherwise processing the cod...
Definition: packet.h:390
mov_read_extradata
static int mov_read_extradata(MOVContext *c, AVIOContext *pb, MOVAtom atom, enum AVCodecID codec_id)
Definition: mov.c:2168
AVCOL_RANGE_JPEG
@ AVCOL_RANGE_JPEG
Full range content.
Definition: pixfmt.h:686
mpegaudiodecheader.h
MOVStreamContext::rap_group_count
unsigned int rap_group_count
Definition: isom.h:230
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:286
mov_read_mvhd
static int mov_read_mvhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1878
mov_read_idat
static int mov_read_idat(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:8619
AVPacket::data
uint8_t * data
Definition: packet.h:539
MOVContext::found_mdat
int found_mdat
'mdat' atom has been found
Definition: isom.h:305
MOVStreamContext::drefs_count
unsigned drefs_count
Definition: isom.h:212
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:2214
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:314
parse
static int parse(AVCodecParserContext *s, AVCodecContext *avctx, const uint8_t **poutbuf, int *poutbuf_size, const uint8_t *buf, int buf_size)
Definition: vp3_parser.c:23
mov_read_stps
static int mov_read_stps(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:3285
MOVContext::bitrates
int * bitrates
bitrates read before streams creation
Definition: isom.h:329
b
#define b
Definition: input.c:41
AVCOL_TRC_UNSPECIFIED
@ AVCOL_TRC_UNSPECIFIED
Definition: pixfmt.h:583
MOVContext::interleaved_read
int interleaved_read
Definition: isom.h:364
mov_read_tkhd
static int mov_read_tkhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5410
MOVElst::rate
float rate
Definition: isom.h:76
AVStream::avg_frame_rate
AVRational avg_frame_rate
Average framerate.
Definition: avformat.h:837
table
static const uint16_t table[]
Definition: prosumer.c:203
spherical.h
mov_read_colr
static int mov_read_colr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2032
data
const char data[16]
Definition: mxf.c:148
set_last_stream_little_endian
static void set_last_stream_little_endian(AVFormatContext *fc)
Definition: mov.c:1917
mov_read_strf
static int mov_read_strf(MOVContext *c, AVIOContext *pb, MOVAtom atom)
An strf atom is a BITMAPINFOHEADER struct.
Definition: mov.c:2484
AV_CODEC_ID_ALAC
@ AV_CODEC_ID_ALAC
Definition: codec_id.h:456
HEIFItem::st
AVStream * st
Definition: isom.h:279
yuv_to_rgba
static uint32_t yuv_to_rgba(uint32_t ycbcr)
Definition: mov.c:2802
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:421
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:7375
mov_seek_stream
static int mov_seek_stream(AVFormatContext *s, AVStream *st, int64_t timestamp, int flags)
Definition: mov.c:10850
mov_read_saio
static int mov_read_saio(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:7521
mov_get_stsc_samples
static int64_t mov_get_stsc_samples(MOVStreamContext *sc, unsigned int index)
Definition: mov.c:3270
ff_get_wav_header
int ff_get_wav_header(void *logctx, AVIOContext *pb, AVCodecParameters *par, int size, int big_endian)
Definition: riffdec.c:95
AV_LOG_VERBOSE
#define AV_LOG_VERBOSE
Detailed information.
Definition: log.h:196
ff_codec_wav_tags
const AVCodecTag ff_codec_wav_tags[]
Definition: riff.c:519
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:3827
MOVFragmentIndexItem::moof_offset
int64_t moof_offset
Definition: isom.h:147
MOVStreamContext::spherical_size
size_t spherical_size
Definition: isom.h:256
mov_change_extradata
static int mov_change_extradata(AVStream *st, AVPacket *pkt)
Definition: mov.c:10510
fc
#define fc(width, name, range_min, range_max)
Definition: cbs_av1.c:472
MOVStreamContext::tref_id
int tref_id
Definition: isom.h:216
MP4TrackKindMapping::scheme_uri
const char * scheme_uri
Definition: isom.h:466
AVINDEX_DISCARD_FRAME
#define AVINDEX_DISCARD_FRAME
Definition: avformat.h:611
AVPacket::duration
int64_t duration
Duration of this packet in AVStream->time_base units, 0 if unknown.
Definition: packet.h:557
AVCodecParameters::codec_tag
uint32_t codec_tag
Additional information about the codec (corresponds to the AVI FOURCC).
Definition: codec_par.h:59
AV_SPHERICAL_EQUIRECTANGULAR_TILE
@ AV_SPHERICAL_EQUIRECTANGULAR_TILE
Video represents a portion of a sphere mapped on a flat surface using equirectangular projection.
Definition: spherical.h:68
AVStereo3D::baseline
uint32_t baseline
The distance between the centres of the lenses of the camera system, in micrometers.
Definition: stereo3d.h:228
MOVDref::dir
char * dir
Definition: isom.h:82
mov_current_sample_set
static void mov_current_sample_set(MOVStreamContext *sc, int current_sample)
Definition: mov.c:4135
mathematics.h
AVDictionary
Definition: dict.c:34
ffio_init_read_context
void ffio_init_read_context(FFIOContext *s, const uint8_t *buffer, int buffer_size)
Wrap a buffer in an AVIOContext for reading.
Definition: aviobuf.c:99
AV_PKT_FLAG_DISPOSABLE
#define AV_PKT_FLAG_DISPOSABLE
Flag is used to indicate packets that contain frames that can be discarded by the decoder.
Definition: packet.h:613
AVProbeData::buf_size
int buf_size
Size of buf except extra allocated bytes.
Definition: avformat.h:454
AVChannelLayout::order
enum AVChannelOrder order
Channel order used in this layout.
Definition: channel_layout.h:316
FFMAX
#define FFMAX(a, b)
Definition: macros.h:47
MOVAtom
Definition: isom.h:88
AVStreamGroupTileGrid::vertical
int vertical
Offset in pixels from the top edge of the canvas where the tile should be placed.
Definition: avformat.h:1036
iamf_parse.h
mov_read_moov
static int mov_read_moov(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1528
FFNABS
#define FFNABS(a)
Negative Absolute value.
Definition: common.h:83
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:424
mov_read_esds
static int mov_read_esds(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:841
MOVStreamContext::sample_count
unsigned int sample_count
Definition: isom.h:195
MOVTrackExt::flags
unsigned flags
Definition: isom.h:112
AVChannelLayout::nb_channels
int nb_channels
Number of channels in this layout.
Definition: channel_layout.h:321
HEIFItem::height
int height
Definition: isom.h:285
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:182
AV_CODEC_ID_R10K
@ AV_CODEC_ID_R10K
Definition: codec_id.h:197
heif_cur_item
static HEIFItem * heif_cur_item(MOVContext *c)
Get the current item in the parsing process.
Definition: mov.c:194
av_encryption_init_info_get_side_data
AVEncryptionInitInfo * av_encryption_init_info_get_side_data(const uint8_t *side_data, size_t side_data_size)
Creates a copy of the AVEncryptionInitInfo that is contained in the given side data.
Definition: encryption_info.c:231
AV_STEREO3D_VIEW_RIGHT
@ AV_STEREO3D_VIEW_RIGHT
Frame contains only the right view.
Definition: stereo3d.h:163
MOVContext::advanced_editlist_autodisabled
int advanced_editlist_autodisabled
Definition: isom.h:323
avio_size
int64_t avio_size(AVIOContext *s)
Get the filesize.
Definition: aviobuf.c:323
av_strlcatf
size_t av_strlcatf(char *dst, size_t size, const char *fmt,...)
Definition: avstring.c:103
mov_read_stco
static int mov_read_stco(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2506
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:6894
FFIOContext
Definition: avio_internal.h:28
AV_PKT_FLAG_KEY
#define AV_PKT_FLAG_KEY
The packet contains a keyframe.
Definition: packet.h:594
init_get_bits
static int init_get_bits(GetBitContext *s, const uint8_t *buffer, int bit_size)
Initialize GetBitContext.
Definition: get_bits.h:514
MOVStreamContext::aes_ctr
struct AVAESCTR * aes_ctr
Definition: isom.h:268
cenc_filter
static int cenc_filter(MOVContext *mov, AVStream *st, MOVStreamContext *sc, AVPacket *pkt, int current_index)
Definition: mov.c:8164
mov_read_sdtp
static int mov_read_sdtp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:3594
mov_read_jp2h
static int mov_read_jp2h(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2204
AV_STEREO3D_UNSPEC
@ AV_STEREO3D_UNSPEC
Video is stereoscopic but the packing is unspecified.
Definition: stereo3d.h:143
AVIndexEntry
Definition: avformat.h:602
AV_WB64
#define AV_WB64(p, v)
Definition: intreadwrite.h:429
MOVStreamContext::dv_audio_container
int dv_audio_container
Definition: isom.h:209
AV_CODEC_ID_AMR_WB
@ AV_CODEC_ID_AMR_WB
Definition: codec_id.h:422
mov_read_tfhd
static int mov_read_tfhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5515
AV_CODEC_ID_BIN_DATA
@ AV_CODEC_ID_BIN_DATA
Definition: codec_id.h:590
av_malloc
#define av_malloc(s)
Definition: tableprint_vlc.h:30
OPUS_SEEK_PREROLL_MS
#define OPUS_SEEK_PREROLL_MS
Definition: oggparseopus.c:36
AV_CODEC_ID_H261
@ AV_CODEC_ID_H261
Definition: codec_id.h:55
IAMFMixPresentation::cmix
const AVIAMFMixPresentation * cmix
Definition: iamf.h:108
mov_read_wide
static int mov_read_wide(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6090
AVINDEX_KEYFRAME
#define AVINDEX_KEYFRAME
Definition: avformat.h:610
AV_FIELD_BT
@ AV_FIELD_BT
Bottom coded first, top displayed first.
Definition: defs.h:206
MOVStreamContext::stsd_count
int stsd_count
Definition: isom.h:249
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:200
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:335
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:381
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:183
MOVStreamContext::has_palette
int has_palette
Definition: isom.h:224
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:163
AVPacketSideData::size
size_t size
Definition: packet.h:392
get_bits
static unsigned int get_bits(GetBitContext *s, int n)
Read 1-25 bits.
Definition: get_bits.h:335
ff_remove_stream
void ff_remove_stream(AVFormatContext *s, AVStream *st)
Remove a stream from its AVFormatContext and free it.
Definition: avformat.c:118
OFFSET
#define OFFSET(x)
Definition: mov.c:10995
HEIFGrid::tile_item_list
HEIFItem ** tile_item_list
Definition: isom.h:292
AV_FIELD_TT
@ AV_FIELD_TT
Top coded_first, top displayed first.
Definition: defs.h:203
ff_iamf_read_packet
int ff_iamf_read_packet(AVFormatContext *s, IAMFDemuxContext *c, AVIOContext *pb, int max_size, AVPacket *pkt)
Definition: iamf_reader.c:279
AV_STEREO3D_VIEW_PACKED
@ AV_STEREO3D_VIEW_PACKED
Frame contains two packed views.
Definition: stereo3d.h:153
MOVStreamContext::nb_frames_for_fps
int nb_frames_for_fps
Definition: isom.h:242
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:860
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:1466
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:3341
av_packet_add_side_data
int av_packet_add_side_data(AVPacket *pkt, enum AVPacketSideDataType type, uint8_t *data, size_t size)
Wrap an existing array as a packet side data.
Definition: packet.c:197
MOVStreamContext::mastering
AVMasteringDisplayMetadata * mastering
Definition: isom.h:257
AV_CODEC_ID_SPEEX
@ AV_CODEC_ID_SPEEX
Definition: codec_id.h:475
AV_FOURCC_MAX_STRING_SIZE
#define AV_FOURCC_MAX_STRING_SIZE
Definition: avutil.h:343
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:419
MOVFragmentIndexItem::current
int current
Definition: isom.h:149
AVFMT_SEEK_TO_PTS
#define AVFMT_SEEK_TO_PTS
Seeking is based on PTS.
Definition: avformat.h:503
AV_CODEC_ID_PCM_S16BE
@ AV_CODEC_ID_PCM_S16BE
Definition: codec_id.h:329
mov_read_mdhd
static int mov_read_mdhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1832
mov_read_ctts
static int mov_read_ctts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:3639
MOVTrackExt
Definition: isom.h:107
MOV_FRAG_SAMPLE_FLAG_IS_NON_SYNC
#define MOV_FRAG_SAMPLE_FLAG_IS_NON_SYNC
Definition: isom.h:395
fail
#define fail()
Definition: checkasm.h:188
mov_read_aclr
static int mov_read_aclr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2279
AVSEEK_FLAG_ANY
#define AVSEEK_FLAG_ANY
seek to any frame, even non-keyframes
Definition: avformat.h:2479
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:96
AVStreamGroupTileGrid
AVStreamGroupTileGrid holds information on how to combine several independent images on a single canv...
Definition: avformat.h:987
MOVContext::decryption_key
uint8_t * decryption_key
Definition: isom.h:349
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:281
av_shrink_packet
void av_shrink_packet(AVPacket *pkt, int size)
Reduce packet size, correctly zeroing padding.
Definition: packet.c:113
timecode.h
get_current_frag_stream_info
static MOVFragmentStreamInfo * get_current_frag_stream_info(MOVFragmentIndex *frag_index)
Definition: mov.c:1585
MOVStreamContext::ctts_index
int ctts_index
Definition: isom.h:191
GetBitContext
Definition: get_bits.h:108
MOVStreamContext::mastering_size
size_t mastering_size
Definition: isom.h:258
AVStreamGroupTileGrid::coded_width
int coded_width
Width of the canvas.
Definition: avformat.h:1002
av_iamf_audio_element_free
void av_iamf_audio_element_free(AVIAMFAudioElement **paudio_element)
Free an AVIAMFAudioElement and all its contents.
Definition: iamf.c:336
FFStream::index_entries_allocated_size
unsigned int index_entries_allocated_size
Definition: internal.h:252
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:6449
mov_read_enda
static int mov_read_enda(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1946
mov_read_chap
static int mov_read_chap(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5562
MOVParseTableEntry
Definition: mov.c:80
avio_tell
static av_always_inline int64_t avio_tell(AVIOContext *s)
ftell() equivalent for AVIOContext.
Definition: avio.h:494
MOV_TRUN_SAMPLE_DURATION
#define MOV_TRUN_SAMPLE_DURATION
Definition: isom.h:389
val
static double val(void *priv, double ch)
Definition: aeval.c:77
MOVCtts::duration
int duration
Definition: isom.h:64
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:297
AV_DISPOSITION_TIMED_THUMBNAILS
#define AV_DISPOSITION_TIMED_THUMBNAILS
The stream is sparse, and contains thumbnail images, often corresponding to chapter markers.
Definition: avformat.h:679
AVStreamGroupTileGrid::coded_height
int coded_height
Width of the canvas.
Definition: avformat.h:1008
pts
static int64_t pts
Definition: transcode_aac.c:644
MOVStreamContext::v_spacing
int v_spacing
pasp vSpacing
Definition: isom.h:221
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:441
AVStream::duration
int64_t duration
Decoding: duration of the stream, in stream time base.
Definition: avformat.h:807
AVAmbientViewingEnvironment::ambient_illuminance
AVRational ambient_illuminance
Environmental illuminance of the ambient viewing environment in lux.
Definition: ambient_viewing_environment.h:40
ss
#define ss(width, name, subs,...)
Definition: cbs_vp9.c:202
MOVStreamContext::width
int width
tkhd width
Definition: isom.h:218
MOVContext::meta_keys
char ** meta_keys
Definition: isom.h:308
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:247
AVIAMFAudioElement::audio_element_type
enum AVIAMFAudioElementType audio_element_type
Audio element type as defined in section 3.6 of IAMF.
Definition: iamf.h:388
loop
static int loop
Definition: ffplay.c:335
ff_data_to_hex
char * ff_data_to_hex(char *buf, const uint8_t *src, int size, int lowercase)
Write hexadecimal string corresponding to given binary data.
Definition: utils.c:448
update_frag_index
static int update_frag_index(MOVContext *c, int64_t offset)
Definition: mov.c:1700
AVRational::num
int num
Numerator.
Definition: rational.h:59
MOVStreamContext::keyframes
int * keyframes
Definition: isom.h:199
MOVEncryptionIndex::auxiliary_info_sample_count
size_t auxiliary_info_sample_count
Definition: isom.h:127
AV_FIELD_TB
@ AV_FIELD_TB
Top coded first, bottom displayed first.
Definition: defs.h:205
AVStream::attached_pic
AVPacket attached_pic
For streams with AV_DISPOSITION_ATTACHED_PIC disposition, this packet will contain the attached pictu...
Definition: avformat.h:846
MOVStsc::id
int id
Definition: isom.h:70
mov_read_saiz
static int mov_read_saiz(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:7437
MOV_FRAG_SAMPLE_FLAG_DEPENDS_YES
#define MOV_FRAG_SAMPLE_FLAG_DEPENDS_YES
Definition: isom.h:402
MOVContext::idat_offset
int64_t idat_offset
Definition: isom.h:363
MOV_TRUN_DATA_OFFSET
#define MOV_TRUN_DATA_OFFSET
Definition: isom.h:387
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:189
mov_read_ares
static int mov_read_ares(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2236
mov_read_adrm
static int mov_read_adrm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1342
av_get_bits_per_sample
int av_get_bits_per_sample(enum AVCodecID codec_id)
Return codec bits per sample.
Definition: utils.c:550
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:156
AV_CODEC_ID_PCM_S8
@ AV_CODEC_ID_PCM_S8
Definition: codec_id.h:332
avassert.h
FLAC_METADATA_TYPE_STREAMINFO
@ FLAC_METADATA_TYPE_STREAMINFO
Definition: flac.h:46
avio_rb32
unsigned int avio_rb32(AVIOContext *s)
Definition: aviobuf.c:761
AV_LOG_TRACE
#define AV_LOG_TRACE
Extremely verbose debugging, useful for libav* development.
Definition: log.h:206
MOVStreamContext::stsc_sample
int stsc_sample
Definition: isom.h:186
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:180
AV_CODEC_ID_MACE3
@ AV_CODEC_ID_MACE3
Definition: codec_id.h:449
MOVTrackExt::track_id
unsigned track_id
Definition: isom.h:108
mov_free_encryption_index
static void mov_free_encryption_index(MOVEncryptionIndex **index)
Definition: mov.c:9617
AV_CH_LOW_FREQUENCY
#define AV_CH_LOW_FREQUENCY
Definition: channel_layout.h:175
duration
int64_t duration
Definition: movenc.c:65
MOVEncryptionIndex::auxiliary_offsets
uint64_t * auxiliary_offsets
Absolute seek position.
Definition: isom.h:129
read_packet
static int read_packet(void *opaque, uint8_t *buf, int buf_size)
Definition: avio_read_callback.c:42
AV_FIELD_UNKNOWN
@ AV_FIELD_UNKNOWN
Definition: defs.h:201
MOVStreamContext::dts_shift
int dts_shift
dts shift when ctts is negative
Definition: isom.h:222
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:222
AVCodecParameters::frame_size
int frame_size
Audio only.
Definition: codec_par.h:195
avio_get_str16le
int avio_get_str16le(AVIOContext *pb, int maxlen, char *buf, int buflen)
Read a UTF-16 string from pb and convert it to UTF-8.
mov_metadata_track_or_disc_number
static int mov_metadata_track_or_disc_number(MOVContext *c, AVIOContext *pb, unsigned len, const char *key)
Definition: mov.c:91
av_dict_get
AVDictionaryEntry * av_dict_get(const AVDictionary *m, const char *key, const AVDictionaryEntry *prev, int flags)
Get a dictionary entry with matching key.
Definition: dict.c:62
AES_CTR_KEY_SIZE
#define AES_CTR_KEY_SIZE
Definition: aes_ctr.h:35
MOVStreamContext::stsd_version
int stsd_version
Definition: isom.h:250
AV_STREAM_GROUP_PARAMS_IAMF_MIX_PRESENTATION
@ AV_STREAM_GROUP_PARAMS_IAMF_MIX_PRESENTATION
Definition: avformat.h:1113
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:116
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:439
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:6383
s
#define s(width, name)
Definition: cbs_vp9.c:198
MOVFragmentStreamInfo::encryption_index
MOVEncryptionIndex * encryption_index
Definition: isom.h:142
mov_read_trak
static int mov_read_trak(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5042
IAMFSubStream::audio_substream_id
unsigned int audio_substream_id
Definition: iamf.h:83
MOVContext::fc
AVFormatContext * fc
Definition: isom.h:299
MOV_TFHD_DEFAULT_BASE_IS_MOOF
#define MOV_TFHD_DEFAULT_BASE_IS_MOOF
Definition: isom.h:385
av_new_packet
int av_new_packet(AVPacket *pkt, int size)
Allocate the payload of a packet and initialize its fields with default values.
Definition: packet.c:98
AV_CODEC_ID_BMP
@ AV_CODEC_ID_BMP
Definition: codec_id.h:130
AV_CODEC_ID_EVC
@ AV_CODEC_ID_EVC
Definition: codec_id.h:321
IAMFLayer::substream_count
unsigned int substream_count
Definition: iamf.h:78
MOV_TFHD_DEFAULT_DURATION
#define MOV_TFHD_DEFAULT_DURATION
Definition: isom.h:381
ALAC_EXTRADATA_SIZE
#define ALAC_EXTRADATA_SIZE
DRM_BLOB_SIZE
#define DRM_BLOB_SIZE
Definition: mov.c:1340
MOVStreamContext::sample_offsets_count
int sample_offsets_count
Definition: isom.h:237
MOVCtts::count
unsigned int count
Definition: isom.h:63
MOVStreamContext::drefs
MOVDref * drefs
Definition: isom.h:213
av_realloc_array
void * av_realloc_array(void *ptr, size_t nmemb, size_t size)
Definition: mem.c:217
format
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample format(the sample packing is implied by the sample format) and sample rate. The lists are not just lists
AVInputFormat::name
const char * name
A comma separated list of short names for the format.
Definition: avformat.h:553
MOVContext::aes_decrypt
struct AVAES * aes_decrypt
Definition: isom.h:348
g
const char * g
Definition: vf_curves.c:128
AVProbeData::buf
unsigned char * buf
Buffer must have AVPROBE_PADDING_SIZE of extra allocated bytes filled with zero.
Definition: avformat.h:453
AVSphericalMapping::bound_top
uint32_t bound_top
Distance from the top edge.
Definition: spherical.h:180
AVMEDIA_TYPE_AUDIO
@ AVMEDIA_TYPE_AUDIO
Definition: avutil.h:202
AV_CODEC_ID_VP9
@ AV_CODEC_ID_VP9
Definition: codec_id.h:220
MOVFragmentIndex::nb_items
int nb_items
Definition: isom.h:158
AVCodecParameters::width
int width
Video only.
Definition: codec_par.h:134
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:116
AV_CODEC_ID_MP2
@ AV_CODEC_ID_MP2
Definition: codec_id.h:440
MOV_TRUN_FIRST_SAMPLE_FLAGS
#define MOV_TRUN_FIRST_SAMPLE_FLAGS
Definition: isom.h:388
av_q2d
static double av_q2d(AVRational a)
Convert an AVRational to a double.
Definition: rational.h:104
AVIndexEntry::size
int size
Definition: avformat.h:613
av_channel_layout_from_mask
int av_channel_layout_from_mask(AVChannelLayout *channel_layout, uint64_t mask)
Initialize a native channel layout from a bitmask indicating which channels are present.
Definition: channel_layout.c:247
MOVStreamContext::keyframe_absent
int keyframe_absent
Definition: isom.h:197
info
MIPS optimizations info
Definition: mips.txt:2
MOVStts::duration
unsigned int duration
Definition: isom.h:59
MOVStreamContext::coll_size
size_t coll_size
Definition: isom.h:260
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:4055
AVIndexEntry::timestamp
int64_t timestamp
Timestamp in AVStream.time_base units, preferably the time from which on correctly decoded frames are...
Definition: avformat.h:604
av_assert0
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:40
MOVStreamContext::min_corrected_pts
int64_t min_corrected_pts
minimum Composition time shown by the edits excluding empty edits.
Definition: isom.h:202
ffio_read_leb
unsigned int ffio_read_leb(AVIOContext *s)
Read a unsigned integer coded as a variable number of up to eight little-endian bytes,...
Definition: aviobuf.c:927
tile_cols
int tile_cols
Definition: av1_levels.c:73
MOVStreamContext::sdtp_count
unsigned int sdtp_count
Definition: isom.h:178
mov_read_lhvc
static int mov_read_lhvc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:8338
AV_LOG_DEBUG
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:201
AVPacketSideData::data
uint8_t * data
Definition: packet.h:391
ctx
AVFormatContext * ctx
Definition: movenc.c:49
hevc.h
get_bits.h
limits.h
mov_read_sidx
static int mov_read_sidx(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5952
AV_PKT_DATA_STEREO3D
@ AV_PKT_DATA_STEREO3D
This side data should be associated with a video stream and contains Stereoscopic 3D information in f...
Definition: packet.h:111
av_rescale_q
int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq)
Rescale a 64-bit integer by 2 rational numbers.
Definition: mathematics.c:142
ff_iamfdec_read_descriptors
int ff_iamfdec_read_descriptors(IAMFContext *c, AVIOContext *pb, int max_size, void *log_ctx)
Definition: iamf_parse.c:1096
FFStream::display_aspect_ratio
AVRational display_aspect_ratio
display aspect ratio (0 if unknown)
Definition: internal.h:368
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:10437
AV_CODEC_ID_TARGA_Y216
@ AV_CODEC_ID_TARGA_Y216
Definition: codec_id.h:256
AVIndexEntry::min_distance
int min_distance
Minimum distance between this and the previous keyframe, used to avoid unneeded searching.
Definition: avformat.h:614
mov_read_dvcc_dvvc
static int mov_read_dvcc_dvvc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:8318
MOVParseTableEntry::parse
int(* parse)(MOVContext *ctx, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:82
codec_id
enum AVCodecID codec_id
Definition: vaapi_decode.c:394
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:179
color_range
color_range
Definition: vf_selectivecolor.c:43
AVMEDIA_TYPE_DATA
@ AVMEDIA_TYPE_DATA
Opaque data information usually continuous.
Definition: avutil.h:203
mov_read_udta_string
static int mov_read_udta_string(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:345
mov_read_stss
static int mov_read_stss(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:3326
mov_read_ddts
static int mov_read_ddts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1114
mov_read_uuid
static int mov_read_uuid(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:7040
AVCOL_PRI_UNSPECIFIED
@ AVCOL_PRI_UNSPECIFIED
Definition: pixfmt.h:558
MOVTrackExt::duration
unsigned duration
Definition: isom.h:110
AV_CODEC_ID_H264
@ AV_CODEC_ID_H264
Definition: codec_id.h:79
av_content_light_metadata_alloc
AVContentLightMetadata * av_content_light_metadata_alloc(size_t *size)
Allocate an AVContentLightMetadata structure and set its fields to default values.
Definition: mastering_display_metadata.c:72
av_sha_final
void av_sha_final(AVSHA *ctx, uint8_t *digest)
Finish hashing and output digest value.
Definition: sha.c:347
MOVStreamContext::current_sample
int current_sample
Definition: isom.h:203
MOVFragmentStreamInfo::sidx_pts
int64_t sidx_pts
Definition: isom.h:135
MAX_REORDER_DELAY
#define MAX_REORDER_DELAY
Definition: mov.c:4054
MOVFragmentIndex::current
int current
Definition: isom.h:157
MOVEncryptionIndex::encrypted_samples
AVEncryptionInfo ** encrypted_samples
Definition: isom.h:124
mov_read_close
static int mov_read_close(AVFormatContext *s)
Definition: mov.c:9690
MOVAtom::size
int64_t size
Definition: isom.h:90
MOVStreamContext::refcount
int refcount
Definition: isom.h:169
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:445
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:255
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:6110
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:7265
FFStream::need_parsing
enum AVStreamParseType need_parsing
Definition: internal.h:386
MOVStreamContext::keyframe_count
unsigned int keyframe_count
Definition: isom.h:198
mov_read_SAND
static int mov_read_SAND(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:8566
IAMFAudioElement::audio_element_id
unsigned int audio_element_id
Definition: iamf.h:96
AVDISCARD_ALL
@ AVDISCARD_ALL
discard all
Definition: defs.h:221
AVFormatContext
Format I/O context.
Definition: avformat.h:1287
av_realloc_f
#define av_realloc_f(p, o, n)
Definition: tableprint_vlc.h:32
mov_read_stts
static int mov_read_stts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:3474
MOVStreamContext::index_ranges
MOVIndexRange * index_ranges
Definition: isom.h:205
DDTS_SIZE
#define DDTS_SIZE
internal.h
MOVTrackExt::stsd_id
unsigned stsd_id
Definition: isom.h:109
AVStreamGroupLCEVC::height
int height
Height of the final image for presentation.
Definition: avformat.h:1107
set_frag_stream
static void set_frag_stream(MOVFragmentIndex *frag_index, int id)
Definition: mov.c:1565
mov_read_free
static int mov_read_free(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:7145
mov_realloc_extradata
static int mov_realloc_extradata(AVCodecParameters *par, MOVAtom atom)
Definition: mov.c:2131
AVStream::codecpar
AVCodecParameters * codecpar
Codec parameters associated with this stream.
Definition: avformat.h:771
LIBAVUTIL_VERSION_INT
#define LIBAVUTIL_VERSION_INT
Definition: version.h:85
AVSEEK_FLAG_BACKWARD
#define AVSEEK_FLAG_BACKWARD
Definition: avformat.h:2477
read_header
static int read_header(FFV1Context *f)
Definition: ffv1dec.c:535
aes.h
AVClass
Describe the class of an AVClass context structure.
Definition: log.h:66
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:321
result
and forward the result(frame or status change) to the corresponding input. If nothing is possible
fabs
static __device__ float fabs(float a)
Definition: cuda_runtime.h:182
AVStream::time_base
AVRational time_base
This is the fundamental unit of time (in seconds) in terms of which frame timestamps are represented.
Definition: avformat.h:787
NULL
#define NULL
Definition: coverity.c:32
sha.h
truehd_layout
static uint64_t truehd_layout(int chanmap)
Definition: mlp_parse.h:105
MOVDref
Definition: isom.h:79
AVERROR_PATCHWELCOME
#define AVERROR_PATCHWELCOME
Not yet implemented in FFmpeg, patches welcome.
Definition: error.h:64
AV_CODEC_ID_AV1
@ AV_CODEC_ID_AV1
Definition: codec_id.h:280
MOVStreamContext::ctts_count
unsigned int ctts_count
Definition: isom.h:180
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:461
mov_read_ftyp
static int mov_read_ftyp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1480
AV_WB16
#define AV_WB16(p, v)
Definition: intreadwrite.h:401
MOVContext::nb_heif_grid
int nb_heif_grid
Definition: isom.h:361
read_image_grid
static int read_image_grid(AVFormatContext *s, const HEIFGrid *grid, AVStreamGroupTileGrid *tile_grid)
Definition: mov.c:9877
MOVElst
Definition: isom.h:73
av_aes_ctr_alloc
struct AVAESCTR * av_aes_ctr_alloc(void)
Allocate an AVAESCTR context.
Definition: aes_ctr.c:40
flac_parse_block_header
static av_always_inline void flac_parse_block_header(const uint8_t *block_header, int *last, int *type, int *size)
Parse the metadata block parameters from the header.
Definition: flac.h:63
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:3710
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:710
mov_probe
static int mov_probe(const AVProbeData *p)
Definition: mov.c:9337
AVPALETTE_SIZE
#define AVPALETTE_SIZE
Definition: pixfmt.h:32
MOVDref::nlvl_to
int16_t nlvl_to
Definition: isom.h:85
get_eia608_packet
static int get_eia608_packet(AVIOContext *pb, AVPacket *pkt, int src_size)
Definition: mov.c:10534
AV_CODEC_ID_DVD_SUBTITLE
@ AV_CODEC_ID_DVD_SUBTITLE
Definition: codec_id.h:550
AVIndexEntry::flags
int flags
Definition: avformat.h:612
MOVStreamContext::time_offset
int64_t time_offset
time offset of the edit list entries
Definition: isom.h:201
mov_read_smdm
static int mov_read_smdm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6292
av_default_item_name
const char * av_default_item_name(void *ptr)
Return the context name.
Definition: log.c:237
AVStereo3D::horizontal_disparity_adjustment
AVRational horizontal_disparity_adjustment
Relative shift of the left and right images, which changes the zero parallax plane.
Definition: stereo3d.h:234
avio_rb64
uint64_t avio_rb64(AVIOContext *s)
Definition: aviobuf.c:908
av_aes_crypt
void av_aes_crypt(AVAES *a, uint8_t *dst, const uint8_t *src, int count, uint8_t *iv, int decrypt)
Encrypt or decrypt a buffer using a previously initialized context.
Definition: aes.c:169
MOVStreamContext::current_index_range
MOVIndexRange * current_index_range
Definition: isom.h:206
mov_open_dref
static int mov_open_dref(MOVContext *c, AVIOContext **pb, const char *src, MOVDref *ref)
Definition: mov.c:4896
FFStream::nb_index_entries
int nb_index_entries
Definition: internal.h:251
AVProbeData
This structure contains the data a format has to probe a file.
Definition: avformat.h:451
av_aes_alloc
struct AVAES * av_aes_alloc(void)
Allocate an AVAES context.
Definition: aes.c:35
TAG_IS_AVCI
#define TAG_IS_AVCI(tag)
Definition: isom.h:415
IAMFSubStream
Definition: iamf.h:82
MOVStreamContext::timecode_track
int timecode_track
Definition: isom.h:217
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:7737
AVStream::metadata
AVDictionary * metadata
Definition: avformat.h:828
FLAC_STREAMINFO_SIZE
#define FLAC_STREAMINFO_SIZE
Definition: flac.h:32
av_color_primaries_name
const char * av_color_primaries_name(enum AVColorPrimaries primaries)
Definition: pixdesc.c:3299
FF_MOV_FLAG_MFRA_DTS
#define FF_MOV_FLAG_MFRA_DTS
Definition: isom.h:438
MOV_SAMPLE_DEPENDENCY_NO
#define MOV_SAMPLE_DEPENDENCY_NO
Definition: isom.h:411
mov_read_iref_thmb
static int mov_read_iref_thmb(MOVContext *c, AVIOContext *pb, int version)
Definition: mov.c:8894
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
AV_DISPOSITION_MULTILAYER
#define AV_DISPOSITION_MULTILAYER
The video stream contains multiple layers, e.g.
Definition: avformat.h:718
MOVFragmentStreamInfo::index_base
int index_base
Definition: isom.h:140
MOVStreamContext::rap_group
MOVSbgp * rap_group
Definition: isom.h:231
AV_CODEC_ID_QDM2
@ AV_CODEC_ID_QDM2
Definition: codec_id.h:459
mov_read_ilst
static int mov_read_ilst(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5191
AV_CH_FRONT_CENTER
#define AV_CH_FRONT_CENTER
Definition: channel_layout.h:174
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:8139
get_sgpd_sync_index
static uint32_t get_sgpd_sync_index(const MOVStreamContext *sc, int nal_unit_type)
Definition: mov.c:4468
mov_read_fiel
static int mov_read_fiel(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2097
MOV_MP4_TTML_TAG
#define MOV_MP4_TTML_TAG
Definition: isom.h:456
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:379
MOVFragmentStreamInfo::stsd_id
int stsd_id
Definition: isom.h:143
MOVStreamContext::open_key_samples_count
int open_key_samples_count
Definition: isom.h:239
HEIFItem
Definition: isom.h:278
ff_codec_movaudio_tags
const AVCodecTag ff_codec_movaudio_tags[]
Definition: isom_tags.c:298
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:1218
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:116
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:2786
cid
uint16_t cid
Definition: mxfenc.c:2264
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:2996
MOVStts
Definition: isom.h:57
AVAudioServiceType
AVAudioServiceType
Definition: defs.h:224
AV_CODEC_ID_MPEG1VIDEO
@ AV_CODEC_ID_MPEG1VIDEO
Definition: codec_id.h:53
AV_CODEC_ID_GSM
@ AV_CODEC_ID_GSM
as in Berlin toast format
Definition: codec_id.h:458
AVStream::nb_frames
int64_t nb_frames
number of frames in this stream if known or 0
Definition: avformat.h:809
AVCodecID
AVCodecID
Identify the syntax and semantics of the bitstream.
Definition: codec_id.h:49
av_packet_side_data_get
const AVPacketSideData * av_packet_side_data_get(const AVPacketSideData *sd, int nb_sd, enum AVPacketSideDataType type)
Get side information from a side data array.
Definition: packet.c:656
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:480
should_retry
static int should_retry(AVIOContext *pb, int error_code)
Definition: mov.c:10467
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:525
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:552
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:1310
MOVContext::dv_demux
DVDemuxContext * dv_demux
Definition: isom.h:310
AV_CODEC_ID_AAC
@ AV_CODEC_ID_AAC
Definition: codec_id.h:442
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:8476
mov_read_elst
static int mov_read_elst(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6163
MOVEncryptionIndex::auxiliary_info_default_size
uint8_t auxiliary_info_default_size
Definition: isom.h:128
AV_STREAM_GROUP_PARAMS_TILE_GRID
@ AV_STREAM_GROUP_PARAMS_TILE_GRID
Definition: avformat.h:1114
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:10181
AV_CODEC_ID_QCELP
@ AV_CODEC_ID_QCELP
Definition: codec_id.h:464
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:7932
avio_rl32
unsigned int avio_rl32(AVIOContext *s)
Definition: aviobuf.c:730
MOVStreamContext::tref_flags
unsigned tref_flags
Definition: isom.h:215
AVDISCARD_NONKEY
@ AVDISCARD_NONKEY
discard all frames except keyframes
Definition: defs.h:220
MOVFragment::flags
unsigned flags
Definition: isom.h:104
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:340
mov_read_wave
static int mov_read_wave(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2327
AV_SPHERICAL_CUBEMAP
@ AV_SPHERICAL_CUBEMAP
Video frame is split into 6 faces of a cube, and arranged on a 3x2 layout.
Definition: spherical.h:61
avio_rb24
unsigned int avio_rb24(AVIOContext *s)
Definition: aviobuf.c:754
ff_mpa_check_header
static int ff_mpa_check_header(uint32_t header)
Definition: mpegaudiodecheader.h:62
MOVStreamContext::aes_ctx
struct AVAES * aes_ctx
Definition: isom.h:269
MOV_TREF_FLAG_ENHANCEMENT
#define MOV_TREF_FLAG_ENHANCEMENT
Definition: isom.h:413
cens_scheme_decrypt
static int cens_scheme_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
Definition: mov.c:7992
MOVContext::handbrake_version
int handbrake_version
Definition: isom.h:317
mov_free_stream_context
static void mov_free_stream_context(AVFormatContext *s, AVStream *st)
Definition: mov.c:9629
AVPacket::size
int size
Definition: packet.h:540
MOVStreamContext::ctts_sample
int ctts_sample
Definition: isom.h:192
NULL_IF_CONFIG_SMALL
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
Definition: internal.h:94
ff_codec_get_id
enum AVCodecID ff_codec_get_id(const AVCodecTag *tags, unsigned int tag)
Definition: utils.c:133
avformat_alloc_context
AVFormatContext * avformat_alloc_context(void)
Allocate an AVFormatContext.
Definition: options.c:161
MOVFragmentIndexItem
Definition: isom.h:146
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:7214
AVIOContext::seekable
int seekable
A combination of AVIO_SEEKABLE_ flags or 0 when the stream is not seekable.
Definition: avio.h:261
av_aes_ctr_init
int av_aes_ctr_init(struct AVAESCTR *a, const uint8_t *key)
Initialize an AVAESCTR context.
Definition: aes_ctr.c:73
height
#define height
Definition: dsp.h:85
qtpalette.h
av_bprint_finalize
int av_bprint_finalize(AVBPrint *buf, char **ret_str)
Finalize a print buffer.
Definition: bprint.c:240
AVChannelLayout
An AVChannelLayout holds information about the channel layout of audio data.
Definition: channel_layout.h:311
FFStream
Definition: internal.h:193
mov_read_dref
static int mov_read_dref(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:631
mov_current_sample_dec
static void mov_current_sample_dec(MOVStreamContext *sc)
Definition: mov.c:4123
AVSphericalMapping::bound_right
uint32_t bound_right
Distance from the right edge.
Definition: spherical.h:181
MOVStsc::first
int first
Definition: isom.h:68
dst
uint8_t ptrdiff_t const uint8_t ptrdiff_t int intptr_t intptr_t int int16_t * dst
Definition: dsp.h:83
find_prev_closest_index
static int find_prev_closest_index(AVStream *st, AVIndexEntry *e_old, int nb_old, MOVCtts *ctts_data, int64_t ctts_count, int64_t timestamp_pts, int flag, int64_t *index, int64_t *ctts_index, int64_t *ctts_sample)
Find the closest previous frame to the timestamp_pts, in e_old index entries.
Definition: mov.c:3873
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:194
FF_MOV_FLAG_MFRA_AUTO
#define FF_MOV_FLAG_MFRA_AUTO
Definition: isom.h:437
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:425
MOVStreamContext::sgpd_sync
uint8_t * sgpd_sync
Definition: isom.h:234
start_time
static int64_t start_time
Definition: ffplay.c:326
uuid.h
mov_read_trun
static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5648
MOVStreamContext::stereo3d_size
size_t stereo3d_size
Definition: isom.h:254
avio_get_str
int avio_get_str(AVIOContext *pb, int maxlen, char *buf, int buflen)
Read a string from pb into buf.
Definition: aviobuf.c:866
mov_read_iprp
static int mov_read_iprp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:8978
av_sha_update
void av_sha_update(struct AVSHA *ctx, const uint8_t *data, size_t len)
Update hash value.
Definition: sha.c:315
sample
#define sample
Definition: flacdsp_template.c:44
hypot
static av_const double hypot(double x, double y)
Definition: libm.h:366
AV_CODEC_ID_H263
@ AV_CODEC_ID_H263
Definition: codec_id.h:56
MOV_TFHD_STSD_ID
#define MOV_TFHD_STSD_ID
Definition: isom.h:380
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:1167
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:3184
AV_WL32A
#define AV_WL32A(p, v)
Definition: intreadwrite.h:571
av_reallocp
int av_reallocp(void *ptr, size_t size)
Allocate, reallocate, or free a block of memory through a pointer to a pointer.
Definition: mem.c:188
ff_get_qtpalette
int ff_get_qtpalette(int codec_id, AVIOContext *pb, uint32_t *palette)
Retrieve the palette (or "color table" in QuickTime terms), either from the video sample description,...
Definition: qtpalette.c:323
AV_NOPTS_VALUE
#define AV_NOPTS_VALUE
Undefined timestamp value.
Definition: avutil.h:248
MKBETAG
#define MKBETAG(a, b, c, d)
Definition: macros.h:56
AV_CODEC_ID_QDMC
@ AV_CODEC_ID_QDMC
Definition: codec_id.h:490
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:73
AV_RB32
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_WL16 uint64_t_TMPL AV_WB64 unsigned int_TMPL AV_RB32
Definition: bytestream.h:96
avpriv_report_missing_feature
void avpriv_report_missing_feature(void *avc, const char *msg,...) av_printf_format(2
Log a generic warning message about a missing feature.
av_aes_ctr_set_full_iv
void av_aes_ctr_set_full_iv(struct AVAESCTR *a, const uint8_t *iv)
Forcefully change the "full" 16-byte iv, including the counter.
Definition: aes_ctr.c:52
AVStreamGroup::iamf_audio_element
struct AVIAMFAudioElement * iamf_audio_element
Definition: avformat.h:1154
MOVStreamContext::coll
AVContentLightMetadata * coll
Definition: isom.h:259
aes_ctr.h
AVChannelLayout::u
union AVChannelLayout::@419 u
Details about which channels are present in this layout.
ff_format_io_close
int ff_format_io_close(AVFormatContext *s, AVIOContext **pb)
Definition: avformat.c:951
mov_parse_heif_items
static int mov_parse_heif_items(AVFormatContext *s)
Definition: mov.c:10111
HEIFItem::is_idat_relative
int is_idat_relative
Definition: isom.h:287
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:3970
MOVDref::path
char * path
Definition: isom.h:81
mov_current_sample_inc
static void mov_current_sample_inc(MOVStreamContext *sc)
Definition: mov.c:4111
AVStream::sample_aspect_ratio
AVRational sample_aspect_ratio
sample aspect ratio (0 if unknown)
Definition: avformat.h:826
FFInputFormat::p
AVInputFormat p
The public AVInputFormat.
Definition: demux.h:41
dovi_isom.h
AVPacket::dts
int64_t dts
Decompression timestamp in AVStream->time_base units; the time at which the packet is decompressed.
Definition: packet.h:538
mov_read_vexu_proj
static int mov_read_vexu_proj(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6658
fix_timescale
static void fix_timescale(MOVContext *c, MOVStreamContext *sc)
Definition: mov.c:4968
avio_r8
int avio_r8(AVIOContext *s)
Definition: aviobuf.c:603
IAMFAudioElement::substreams
IAMFSubStream * substreams
Definition: iamf.h:98
AVSphericalMapping::padding
uint32_t padding
Number of pixels to pad from the edge of each cube face.
Definition: spherical.h:194
a
The reader does not expect b to be semantically here and if the code is changed by maybe adding a a division or other the signedness will almost certainly be mistaken To avoid this confusion a new type was SUINT is the C unsigned type but it holds a signed int to use the same example SUINT a
Definition: undefined.txt:41
av_channel_layout_retype
int av_channel_layout_retype(AVChannelLayout *channel_layout, enum AVChannelOrder order, int flags)
Change the AVChannelOrder of a channel layout.
Definition: channel_layout.c:880
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:9215
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:457
ffio_ensure_seekback
int ffio_ensure_seekback(AVIOContext *s, int64_t buf_size)
Ensures that the requested seekback buffer size will be available.
Definition: aviobuf.c:1023
AVStreamGroupTileGrid::nb_tiles
unsigned int nb_tiles
Amount of tiles in the grid.
Definition: avformat.h:995
av_packet_side_data_add
AVPacketSideData * av_packet_side_data_add(AVPacketSideData **psd, int *pnb_sd, enum AVPacketSideDataType type, void *data, size_t size, int flags)
Wrap existing data as packet side data.
Definition: packet.c:699
mov_read_packet
static int mov_read_packet(AVFormatContext *s, AVPacket *pkt)
Definition: mov.c:10661
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:1099
AVStreamGroup::lcevc
struct AVStreamGroupLCEVC * lcevc
Definition: avformat.h:1157
attributes.h
AV_CODEC_ID_LCEVC
@ AV_CODEC_ID_LCEVC
Definition: codec_id.h:592
MOVEncryptionIndex::auxiliary_offsets_count
size_t auxiliary_offsets_count
Definition: isom.h:130
AVPacket::flags
int flags
A combination of AV_PKT_FLAG values.
Definition: packet.h:545
av_dict_free
void av_dict_free(AVDictionary **pm)
Free all the memory allocated for an AVDictionary struct and all keys and values.
Definition: dict.c:223
av_encryption_info_free
void av_encryption_info_free(AVEncryptionInfo *info)
Frees the given encryption info object.
Definition: encryption_info.c:82
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:10166
AVSubsampleEncryptionInfo
This file is part of FFmpeg.
Definition: encryption_info.h:25
MOVFragmentIndexItem::stream_info
MOVFragmentStreamInfo * stream_info
Definition: isom.h:151
version
version
Definition: libkvazaar.c:321
AV_STREAM_GROUP_PARAMS_IAMF_AUDIO_ELEMENT
@ AV_STREAM_GROUP_PARAMS_IAMF_AUDIO_ELEMENT
Definition: avformat.h:1112
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:1188
ff_rfps_calculate
void ff_rfps_calculate(AVFormatContext *ic)
Definition: demux.c:2347
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:458
mov_read_clli
static int mov_read_clli(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6420
MOVStreamContext::chunk_offsets
int64_t * chunk_offsets
Definition: isom.h:175
AVStreamGroup::iamf_mix_presentation
struct AVIAMFMixPresentation * iamf_mix_presentation
Definition: avformat.h:1155
MOVFragmentIndex::item
MOVFragmentIndexItem * item
Definition: isom.h:159
AV_LOG_INFO
#define AV_LOG_INFO
Standard information.
Definition: log.h:191
MOVStreamContext::iamf
struct IAMFDemuxContext * iamf
Definition: isom.h:275
FFERROR_REDO
#define FFERROR_REDO
Returned by demuxers to indicate that data was consumed but discarded (ignored streams or junk data).
Definition: demux.h:171
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:227
MOVContext::decryption_key_len
int decryption_key_len
Definition: isom.h:350
av_aes_ctr_free
void av_aes_ctr_free(struct AVAESCTR *a)
Release an AVAESCTR context.
Definition: aes_ctr.c:83
av_mastering_display_metadata_alloc_size
AVMasteringDisplayMetadata * av_mastering_display_metadata_alloc_size(size_t *size)
Allocate an AVMasteringDisplayMetadata structure and set its fields to default values.
Definition: mastering_display_metadata.c:44
mov_read_dfla
static int mov_read_dfla(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:7839
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:9089
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:85
flag
#define flag(name)
Definition: cbs_av1.c:474
mov_metadata_creation_time
static void mov_metadata_creation_time(MOVContext *c, AVIOContext *pb, AVDictionary **metadata, int version)
Definition: mov.c:1802
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:138
MOVStreamContext::stsc_index
unsigned int stsc_index
Definition: isom.h:185
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:7768
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:3264
mov_finalize_packet
static int mov_finalize_packet(AVFormatContext *s, AVStream *st, AVIndexEntry *sample, int64_t current_index, AVPacket *pkt)
Definition: mov.c:10603
MOVIndexRange
Definition: isom.h:162
mov_read_seek
static int mov_read_seek(AVFormatContext *s, int stream_index, int64_t sample_time, int flags)
Definition: mov.c:10939
bprint.h
MOVContext::advanced_editlist
int advanced_editlist
Definition: isom.h:322
MOVStreamContext::time_scale
int time_scale
Definition: isom.h:200
mlp_parse.h
mac_to_unicode
static const uint32_t mac_to_unicode[128]
Definition: mov.c:150
AVStreamGroupTileGrid::width
int width
Width of the final image for presentation.
Definition: avformat.h:1072
MOVStreamContext::bytes_per_frame
unsigned int bytes_per_frame
Definition: isom.h:207
AVSphericalMapping::roll
int32_t roll
Rotation around the forward vector [-180, 180].
Definition: spherical.h:140
IAMFContext::nb_audio_elements
int nb_audio_elements
Definition: iamf.h:132
MOVIndexRange::end
int64_t end
Definition: isom.h:164
AV_CODEC_ID_NONE
@ AV_CODEC_ID_NONE
Definition: codec_id.h:50
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:256
AVPacket::pts
int64_t pts
Presentation timestamp in AVStream->time_base units; the time at which the decompressed packet will b...
Definition: packet.h:532
avio_internal.h
mov_read_trex
static int mov_read_trex(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5583
search_frag_timestamp
static int search_frag_timestamp(AVFormatContext *s, MOVFragmentIndex *frag_index, AVStream *st, int64_t timestamp)
Definition: mov.c:1675
HEIFItem::width
int width
Definition: isom.h:284
FLAGS
#define FLAGS
Definition: mov.c:10996
MOVStreamContext::stereo3d
AVStereo3D * stereo3d
Definition: isom.h:253
AVStreamGroupTileGrid::offsets
struct AVStreamGroupTileGrid::@362 * offsets
An nb_tiles sized array of offsets in pixels from the topleft edge of the canvas, indicating where ea...
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:4163
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:7616
MOVDref::volume
char volume[28]
Definition: isom.h:83
mov_read_stsd
static int mov_read_stsd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:3119
internal.h
AV_SPHERICAL_FISHEYE
@ AV_SPHERICAL_FISHEYE
Fisheye projection (Apple).
Definition: spherical.h:84
AVCodecParameters::height
int height
Definition: codec_par.h:135
mov_rewrite_dvd_sub_extradata
static int mov_rewrite_dvd_sub_extradata(AVStream *st)
Definition: mov.c:2818
AV_TIME_BASE
#define AV_TIME_BASE
Internal time base represented as integer.
Definition: avutil.h:254
MOVStreamContext::stps_count
unsigned int stps_count
Definition: isom.h:187
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:574
rb_size
static int rb_size(AVIOContext *pb, int64_t *value, int size)
Definition: mov.c:8592
AVStereo3DPrimaryEye
AVStereo3DPrimaryEye
List of possible primary eyes.
Definition: stereo3d.h:174
av_malloc_array
#define av_malloc_array(a, b)
Definition: tableprint_vlc.h:31
AV_CODEC_ID_CAVS
@ AV_CODEC_ID_CAVS
Definition: codec_id.h:139
ff_mov_read_stsd_entries
int ff_mov_read_stsd_entries(MOVContext *c, AVIOContext *pb, int entries)
Definition: mov.c:3022
AV_FIELD_BB
@ AV_FIELD_BB
Bottom coded first, bottom displayed first.
Definition: defs.h:204
AV_PKT_DATA_ICC_PROFILE
@ AV_PKT_DATA_ICC_PROFILE
ICC profile data consisting of an opaque octet buffer following the format described by ISO 15076-1.
Definition: packet.h:271
AV_STEREO3D_TOPBOTTOM
@ AV_STEREO3D_TOPBOTTOM
Views are on top of each other.
Definition: stereo3d.h:76
MOVFragment::duration
unsigned duration
Definition: isom.h:102
AVIAMFMixPresentation
Information on how to render and mix one or more AVIAMFAudioElement to generate the final audio outpu...
Definition: iamf.h:609
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:196
MOVContext::frag_index
MOVFragmentIndex frag_index
Definition: isom.h:335
mov_read_vpcc
static int mov_read_vpcc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6248
AV_CODEC_ID_PCM_F64BE
@ AV_CODEC_ID_PCM_F64BE
Definition: codec_id.h:350
AV_CODEC_ID_HEVC
@ AV_CODEC_ID_HEVC
Definition: codec_id.h:226
value
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf default value
Definition: writing_filters.txt:86
av_url_split
void av_url_split(char *proto, int proto_size, char *authorization, int authorization_size, char *hostname, int hostname_size, int *port_ptr, char *path, int path_size, const char *url)
Split a URL string into components.
Definition: utils.c:351
MOVStreamContext::dref_id
int dref_id
Definition: isom.h:214
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:1761
mov_finalize_stsd_codec
static int mov_finalize_stsd_codec(MOVContext *c, AVIOContext *pb, AVStream *st, MOVStreamContext *sc)
Definition: mov.c:2896
AV_CH_FRONT_LEFT
#define AV_CH_FRONT_LEFT
Definition: channel_layout.h:172
AV_CODEC_ID_PCM_S32BE
@ AV_CODEC_ID_PCM_S32BE
Definition: codec_id.h:337
mov_read_mdcv
static int mov_read_mdcv(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6339
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:1332
AV_CODEC_ID_VC1
@ AV_CODEC_ID_VC1
Definition: codec_id.h:122
demux.h
AV_DISPOSITION_DEPENDENT
#define AV_DISPOSITION_DEPENDENT
The stream is intended to be mixed with another stream before presentation.
Definition: avformat.h:709
MOVStreamContext::pb
AVIOContext * pb
Definition: isom.h:168
mov_read_keys
static int mov_read_keys(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:5200
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:182
len
int len
Definition: vorbis_enc_data.h:426
AV_CODEC_ID_JPEG2000
@ AV_CODEC_ID_JPEG2000
Definition: codec_id.h:140
MOVFragment::size
unsigned size
Definition: isom.h:103
MOV_TFHD_DEFAULT_SIZE
#define MOV_TFHD_DEFAULT_SIZE
Definition: isom.h:382
AVCOL_SPC_UNSPECIFIED
@ AVCOL_SPC_UNSPECIFIED
Definition: pixfmt.h:612
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:4539
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:2322
AVSHA
hash context
Definition: sha.c:35
AVCOL_RANGE_MPEG
@ AVCOL_RANGE_MPEG
Narrow or limited range content.
Definition: pixfmt.h:669
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:137
AV_IAMF_AUDIO_ELEMENT_TYPE_SCENE
@ AV_IAMF_AUDIO_ELEMENT_TYPE_SCENE
Definition: iamf.h:346
AVCodecParameters::field_order
enum AVFieldOrder field_order
Video only.
Definition: codec_par.h:161
av_get_packet
int av_get_packet(AVIOContext *s, AVPacket *pkt, int size)
Allocate and read the payload of a packet and initialize its fields with default values.
Definition: utils.c:91
mov_read_iinf
static int mov_read_iinf(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:8775
ff_read_string_to_bprint_overwrite
int64_t ff_read_string_to_bprint_overwrite(AVIOContext *s, struct AVBPrint *bp, int64_t max_len)
Read a whole null-terminated string of text from AVIOContext to an AVBPrint buffer overwriting its co...
Definition: aviobuf.c:860
AVStreamGroupTileGrid::horizontal
int horizontal
Offset in pixels from the left edge of the canvas where the tile should be placed.
Definition: avformat.h:1031
get_stream_info_time
static int64_t get_stream_info_time(MOVFragmentStreamInfo *frag_stream_info)
Definition: mov.c:1625
MP4TrackKindValueMapping
Definition: isom.h:460
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:4011
AV_WB8
#define AV_WB8(p, d)
Definition: intreadwrite.h:392
MOVStreamContext::chunk_count
unsigned int chunk_count
Definition: isom.h:174
MOVStreamContext::data_size
int64_t data_size
Definition: isom.h:225
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:261
mov_read_tmcd
static int mov_read_tmcd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6237
mov_chan.h
AVStream::disposition
int disposition
Stream disposition - a combination of AV_DISPOSITION_* flags.
Definition: avformat.h:817
MOVStreamContext::ambient_size
size_t ambient_size
Definition: isom.h:262
tag
uint32_t tag
Definition: movenc.c:1879
AVStream::id
int id
Format-specific stream ID.
Definition: avformat.h:760
ret
ret
Definition: filter_design.txt:187
AVStream
Stream structure.
Definition: avformat.h:748
AV_LOG_FATAL
#define AV_LOG_FATAL
Something went wrong and recovery is not possible.
Definition: log.h:174
HEIFItem::extent_length
int64_t extent_length
Definition: isom.h:282
MOVEncryptionIndex::nb_encrypted_samples
unsigned int nb_encrypted_samples
Definition: isom.h:123
mov_read_senc
static int mov_read_senc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:7319
avio_seek
int64_t avio_seek(AVIOContext *s, int64_t offset, int whence)
fseek() equivalent for AVIOContext.
Definition: aviobuf.c:231
FFSWAP
#define FFSWAP(type, a, b)
Definition: macros.h:52
AVClass::class_name
const char * class_name
The name of the class; usually it is the same name as the context structure type to which the AVClass...
Definition: log.h:71
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:177
AVSphericalMapping::pitch
int32_t pitch
Rotation around the right vector [-90, 90].
Definition: spherical.h:139
AVStreamGroup::metadata
AVDictionary * metadata
Metadata that applies to the whole group.
Definition: avformat.h:1168
avio_rb16
unsigned int avio_rb16(AVIOContext *s)
Definition: aviobuf.c:746
AVStereo3D::type
enum AVStereo3DType type
How views are packed within the video.
Definition: stereo3d.h:207
MOVSbgp::index
unsigned int index
Definition: isom.h:117
MOVContext::chapter_tracks
int * chapter_tracks
Definition: isom.h:318
cdt2
static const int16_t cdt2[8]
Definition: truemotion1data.h:43
AVSTREAM_PARSE_HEADERS
@ AVSTREAM_PARSE_HEADERS
Only parse headers, do not repack.
Definition: avformat.h:594
pos
unsigned int pos
Definition: spdifenc.c:414
avformat.h
MOVFragment::implicit_offset
uint64_t implicit_offset
Definition: isom.h:100
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:706
AV_AUDIO_SERVICE_TYPE_KARAOKE
@ AV_AUDIO_SERVICE_TYPE_KARAOKE
Definition: defs.h:233
mov_read_dmlp
static int mov_read_dmlp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:8283
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:210
MOVContext::time_scale
int time_scale
Definition: isom.h:300
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:5609
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:5327
search_frag_moof_offset
static int search_frag_moof_offset(MOVFragmentIndex *frag_index, int64_t offset)
Definition: mov.c:1601
MOVFragment
Definition: isom.h:95
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:10474
MOVContext::use_mfra_for
int use_mfra_for
Definition: isom.h:332
AVEncryptionInfo
This describes encryption info for a packet.
Definition: encryption_info.h:43
add_ctts_entry
static int64_t add_ctts_entry(MOVCtts **ctts_data, unsigned int *ctts_count, unsigned int *allocated_size, int count, int duration)
Append a new ctts entry to ctts_data.
Definition: mov.c:4027
MOVStreamContext::encryption_index
MOVEncryptionIndex * encryption_index
Definition: isom.h:272
MIN_DATA_ENTRY_BOX_SIZE
#define MIN_DATA_ENTRY_BOX_SIZE
Definition: mov.c:630
AVStreamGroup
Definition: avformat.h:1121
av_get_media_type_string
const char * av_get_media_type_string(enum AVMediaType media_type)
Return a string describing the media_type enum, NULL if media_type is unknown.
Definition: utils.c:28
IAMFMixPresentation
Definition: iamf.h:107
AVStream::index
int index
stream index in AVFormatContext
Definition: avformat.h:754
avpriv_dv_init_demux
DVDemuxContext * avpriv_dv_init_demux(AVFormatContext *s)
Definition: dv.c:726
mov_seek_fragment
static int mov_seek_fragment(AVFormatContext *s, AVStream *st, int64_t timestamp)
Definition: mov.c:10788
ff_configure_buffers_for_index
void ff_configure_buffers_for_index(AVFormatContext *s, int64_t time_tolerance)
Definition: seek.c:174
mov_parse_stsd_video
static void mov_parse_stsd_video(MOVContext *c, AVIOContext *pb, AVStream *st, MOVStreamContext *sc)
Definition: mov.c:2611
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:220
mov_read_dec3
static int mov_read_dec3(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1071
get_frag_time
static int64_t get_frag_time(AVFormatContext *s, AVStream *dst_st, MOVFragmentIndex *frag_index, int index)
Definition: mov.c:1635
MOVStreamContext::sample_size
unsigned int sample_size
may contain value calculated from stsd or value from stsz atom
Definition: isom.h:193
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:1175
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:243
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:3766
MOVFragment::moof_offset
uint64_t moof_offset
Definition: isom.h:99
AVIO_SEEKABLE_NORMAL
#define AVIO_SEEKABLE_NORMAL
Seeking works like for a local file.
Definition: avio.h:41
av_packet_new_side_data
uint8_t * av_packet_new_side_data(AVPacket *pkt, enum AVPacketSideDataType type, size_t size)
Allocate new information of a packet.
Definition: packet.c:231
buffer
the frame and frame reference mechanism is intended to as much as expensive copies of that data while still allowing the filters to produce correct results The data is stored in buffers represented by AVFrame structures Several references can point to the same frame buffer
Definition: filter_design.txt:49
mov_read_glbl
static int mov_read_glbl(MOVContext *c, AVIOContext *pb, MOVAtom atom)
This function reads atom content and puts data in extradata without tag nor size unlike mov_read_extr...
Definition: mov.c:2384
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:6977
MOVTrackExt::size
unsigned size
Definition: isom.h:111
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:126
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:311
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:437
AV_CODEC_ID_DVAUDIO
@ AV_CODEC_ID_DVAUDIO
Definition: codec_id.h:446
avformat_free_context
void avformat_free_context(AVFormatContext *s)
Free an AVFormatContext and all its streams.
Definition: avformat.c:145
MOVContext::aax_mode
unsigned int aax_mode
'aax' file has been detected
Definition: isom.h:337
mov_read_sv3d
static int mov_read_sv3d(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6521
avio_read
int avio_read(AVIOContext *s, unsigned char *buf, int size)
Read size bytes from AVIOContext into buf.
Definition: aviobuf.c:612
mov_aaxc_crypto
static int mov_aaxc_crypto(MOVContext *c)
Definition: mov.c:1441
mov_get_skip_samples
static int64_t mov_get_skip_samples(AVStream *st, int sample)
Definition: mov.c:10922
MOVFragmentIndex
Definition: isom.h:154
mov_read_infe
static int mov_read_infe(MOVContext *c, AVIOContext *pb, MOVAtom atom, int idx)
Definition: mov.c:8710
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:112
AVStream::r_frame_rate
AVRational r_frame_rate
Real base framerate of the stream.
Definition: avformat.h:914
MOVStreamContext::track_end
int64_t track_end
used for dts generation in fragmented movie files
Definition: isom.h:228
MOVStreamContext::sgpd_sync_count
uint32_t sgpd_sync_count
Definition: isom.h:235
MOVContext::fragment
MOVFragment fragment
current fragment in moof atom
Definition: isom.h:313
AVIndexEntry::pos
int64_t pos
Definition: avformat.h:603
AVIOContext::eof_reached
int eof_reached
true if was unable to read due to error or eof
Definition: avio.h:238
mov_metadata_int8_bypass_padding
static int mov_metadata_int8_bypass_padding(MOVContext *c, AVIOContext *pb, unsigned len, const char *key)
Definition: mov.c:111
AVStreamGroupLCEVC::width
int width
Width of the final stream for presentation.
Definition: avformat.h:1103
MOVDref::type
uint32_t type
Definition: isom.h:80
samples
Filter the word “frame” indicates either a video frame or a group of audio samples
Definition: filter_design.txt:8
mean
static float mean(const float *input, int size)
Definition: vf_nnedi.c:866
mov_read_covr
static int mov_read_covr(MOVContext *c, AVIOContext *pb, int type, int len)
Definition: mov.c:231
MOVParseTableEntry::type
uint32_t type
Definition: mov.c:81
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:270
ff_codec_movsubtitle_tags
const AVCodecTag ff_codec_movsubtitle_tags[]
Definition: isom.c:75
av_mul_q
AVRational av_mul_q(AVRational b, AVRational c)
Multiply two rationals.
Definition: rational.c:80
AVPacket::stream_index
int stream_index
Definition: packet.h:541
av_clip_uint8
#define av_clip_uint8
Definition: common.h:106
MOVFragmentIndexItem::nb_stream_info
int nb_stream_info
Definition: isom.h:150
avio_skip
int64_t avio_skip(AVIOContext *s, int64_t offset)
Skip given number of bytes forward.
Definition: aviobuf.c:318
export_orphan_timecode
static void export_orphan_timecode(AVFormatContext *s)
Definition: mov.c:9758
mov_read_sbas
static int mov_read_sbas(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2455
MOVStreamContext::has_sidx
int has_sidx
Definition: isom.h:266
AV_CH_FRONT_RIGHT
#define AV_CH_FRONT_RIGHT
Definition: channel_layout.h:173
av_aes_ctr_crypt
void av_aes_ctr_crypt(struct AVAESCTR *a, uint8_t *dst, const uint8_t *src, int count)
Process a buffer using a previously initialized context.
Definition: aes_ctr.c:107
mov_metadata_gnre
static int mov_metadata_gnre(MOVContext *c, AVIOContext *pb, unsigned len, const char *key)
Definition: mov.c:134
AV_PKT_DATA_ENCRYPTION_INFO
@ AV_PKT_DATA_ENCRYPTION_INFO
This side data contains encryption info for how to decrypt the packet.
Definition: packet.h:252
FFStream::index_entries
AVIndexEntry * index_entries
Only used if the format does not support seeking natively.
Definition: internal.h:249
av_dict_set_int
int av_dict_set_int(AVDictionary **pm, const char *key, int64_t value, int flags)
Convenience wrapper for av_dict_set() that converts the value to a string and stores it.
Definition: dict.c:167
mov_read_dpxe
static int mov_read_dpxe(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2209
AVIAMFSubmix::nb_elements
unsigned int nb_elements
Number of elements in the submix.
Definition: iamf.h:568
MOVFragmentStreamInfo::id
int id
Definition: isom.h:134
AVIO_FLAG_READ
#define AVIO_FLAG_READ
read-only
Definition: avio.h:617
AV_PKT_DATA_AUDIO_SERVICE_TYPE
@ AV_PKT_DATA_AUDIO_SERVICE_TYPE
This side data should be associated with an audio stream and corresponds to enum AVAudioServiceType.
Definition: packet.h:117
av_spherical_alloc
AVSphericalMapping * av_spherical_alloc(size_t *size)
Allocate a AVSphericalVideo structure and initialize its fields to default values.
Definition: spherical.c:26
AV_OPT_FLAG_DECODING_PARAM
#define AV_OPT_FLAG_DECODING_PARAM
A generic parameter which can be set by the user for demuxing or decoding.
Definition: opt.h:356
MOVContext::thmb_item_id
int thmb_item_id
Definition: isom.h:362
mov_read_rtmd_track
static int mov_read_rtmd_track(AVFormatContext *s, AVStream *st)
Definition: mov.c:9544
AVMEDIA_TYPE_VIDEO
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:201
read_probe
static int read_probe(const AVProbeData *p)
Definition: cdg.c:30
MOVStreamContext::pb_is_copied
int pb_is_copied
Definition: isom.h:170
AV_CODEC_ID_PCM_S32LE
@ AV_CODEC_ID_PCM_S32LE
Definition: codec_id.h:336
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:10026
mem.h
MOVElst::time
int64_t time
Definition: isom.h:75
HEIFGrid
Definition: isom.h:290
mov_read_iref_dimg
static int mov_read_iref_dimg(MOVContext *c, AVIOContext *pb, int version)
Definition: mov.c:8835
mov_read_pcmc
static int mov_read_pcmc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:1955
build_open_gop_key_points
static int build_open_gop_key_points(AVStream *st)
Definition: mov.c:4476
mov_parse_stsd_audio
static void mov_parse_stsd_audio(MOVContext *c, AVIOContext *pb, AVStream *st, MOVStreamContext *sc)
Definition: mov.c:2669
IAMFContext::mix_presentations
IAMFMixPresentation ** mix_presentations
Definition: iamf.h:133
AV_CODEC_ID_PCM_U8
@ AV_CODEC_ID_PCM_U8
Definition: codec_id.h:333
MOVContext::trak_index
int trak_index
Index of the current 'trak'.
Definition: isom.h:307
mov_read_timecode_track
static int mov_read_timecode_track(AVFormatContext *s, AVStream *st)
Definition: mov.c:9570
HEIFGrid::item
HEIFItem * item
Definition: isom.h:291
AVSphericalMapping::bound_left
uint32_t bound_left
Distance from the left edge.
Definition: spherical.h:179
mov_read_mac_string
static int mov_read_mac_string(MOVContext *c, AVIOContext *pb, int len, char *dst, int dstlen)
Definition: mov.c:169
MOVEncryptionIndex::auxiliary_info_sizes
uint8_t * auxiliary_info_sizes
Definition: isom.h:126
MOVFragment::stsd_id
unsigned stsd_id
Definition: isom.h:101
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:293
avpriv_request_sample
#define avpriv_request_sample(...)
Definition: tableprint_vlc.h:36
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:445
AV_CHANNEL_LAYOUT_MONO
#define AV_CHANNEL_LAYOUT_MONO
Definition: channel_layout.h:386
AV_CODEC_ID_PCM_F64LE
@ AV_CODEC_ID_PCM_F64LE
Definition: codec_id.h:351
AVStreamGroupTileGrid::height
int height
Height of the final image for presentation.
Definition: avformat.h:1082
AVStereo3D::view
enum AVStereo3DView view
Determines which views are packed.
Definition: stereo3d.h:217
read_tfra
static int read_tfra(MOVContext *mov, AVIOContext *f)
Definition: mov.c:9776
av_free
#define av_free(p)
Definition: tableprint_vlc.h:33
AVDictionaryEntry
Definition: dict.h:89
av_add_q
AVRational av_add_q(AVRational b, AVRational c)
Add two rationals.
Definition: rational.c:93
AVCodecParameters::codec_id
enum AVCodecID codec_id
Specific type of the encoded data (the codec used).
Definition: codec_par.h:55
AVStereo3DView
AVStereo3DView
List of possible view types.
Definition: stereo3d.h:149
AVPacket
This structure stores compressed data.
Definition: packet.h:516
AVContentLightMetadata::MaxFALL
unsigned MaxFALL
Max average light level per frame (cd/m^2).
Definition: mastering_display_metadata.h:116
mov_read_hfov
static int mov_read_hfov(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6948
AV_OPT_TYPE_BOOL
@ AV_OPT_TYPE_BOOL
Underlying C type is int.
Definition: opt.h:327
cr
static double cr(void *priv, double x, double y)
Definition: vf_geq.c:248
MOVStreamContext::stps_data
unsigned * stps_data
partial sync sample for mpeg-2 open gop
Definition: isom.h:188
AV_CODEC_ID_ADPCM_IMA_WAV
@ AV_CODEC_ID_ADPCM_IMA_WAV
Definition: codec_id.h:368
MOVContext::nb_heif_item
int nb_heif_item
Definition: isom.h:359
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:34
av_dict_set
int av_dict_set(AVDictionary **pm, const char *key, const char *value, int flags)
Set the given entry in *pm, overwriting an existing entry.
Definition: dict.c:88
riff.h
av_dict_copy
int av_dict_copy(AVDictionary **dst, const AVDictionary *src, int flags)
Copy entries from one AVDictionary struct into another.
Definition: dict.c:237
av_encryption_info_alloc
AVEncryptionInfo * av_encryption_info_alloc(uint32_t subsample_count, uint32_t key_id_size, uint32_t iv_size)
Allocates an AVEncryptionInfo structure and sub-pointers to hold the given number of subsamples.
Definition: encryption_info.c:41
AVPacket::pos
int64_t pos
byte position in stream, -1 if unknown
Definition: packet.h:559
FFInputFormat
Definition: demux.h:37
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:6720
AV_CODEC_ID_ILBC
@ AV_CODEC_ID_ILBC
Definition: codec_id.h:499
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:105
MOV_TRUN_SAMPLE_SIZE
#define MOV_TRUN_SAMPLE_SIZE
Definition: isom.h:390
MOVStreamContext::tmcd_flags
uint32_t tmcd_flags
tmcd track flags
Definition: isom.h:226
int32_t
int32_t
Definition: audioconvert.c:56
MOVAtom::type
uint32_t type
Definition: isom.h:89
distance
static float distance(float x, float y, int band)
Definition: nellymoserenc.c:231
AVSTREAM_PARSE_FULL
@ AVSTREAM_PARSE_FULL
full parsing and repack
Definition: avformat.h:593
parse_timecode_in_framenum_format
static int parse_timecode_in_framenum_format(AVFormatContext *s, AVStream *st, int64_t value, int flags)
Definition: mov.c:9530
MOVStreamContext::tmcd_nb_frames
uint8_t tmcd_nb_frames
tmcd number of frames per tick / second
Definition: isom.h:227
AVIAMFSubmixElement
Submix element as defined in section 3.7 of IAMF.
Definition: iamf.h:446
replaygain.h
MOVFragmentIndexItem::headers_read
int headers_read
Definition: isom.h:148
AV_CODEC_ID_VP8
@ AV_CODEC_ID_VP8
Definition: codec_id.h:192
flags
#define flags(name, subs,...)
Definition: cbs_av1.c:482
AVERROR_BUG
#define AVERROR_BUG
Internal bug, also see AVERROR_BUG2.
Definition: error.h:52
MOVStreamContext::start_pad
int start_pad
amount of samples to skip due to enc-dec delay
Definition: isom.h:229
MP4TrackKindValueMapping::value
const char * value
Definition: isom.h:462
AVStereo3DType
AVStereo3DType
List of possible 3D Types.
Definition: stereo3d.h:48
MOVDref::filename
char filename[64]
Definition: isom.h:84
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:69
AV_CODEC_ID_PCM_F32LE
@ AV_CODEC_ID_PCM_F32LE
Definition: codec_id.h:349
ff_mov_demuxer
const FFInputFormat ff_mov_demuxer
Definition: mov.c:11057
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:58
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
MOVStreamContext::display_matrix
int32_t * display_matrix
Definition: isom.h:252
MOVContext::heif_grid
HEIFGrid * heif_grid
Definition: isom.h:360
MOVStreamContext::min_sample_duration
uint32_t min_sample_duration
Definition: isom.h:240
MOVStreamContext::current_index
int64_t current_index
Definition: isom.h:204
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
MOVFragmentStreamInfo::index_entry
int index_entry
Definition: isom.h:141
cenc_decrypt
static int cenc_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
Definition: mov.c:8123
MOVStreamContext::format
uint32_t format
Definition: isom.h:264
MKTAG
#define MKTAG(a, b, c, d)
Definition: macros.h:55
ffio_read_size
int ffio_read_size(AVIOContext *s, unsigned char *buf, int size)
Read size bytes from AVIOContext into buf.
Definition: aviobuf.c:662
MOVStreamContext::sync_group_count
unsigned int sync_group_count
Definition: isom.h:232
MOVContext::bitrates_count
int bitrates_count
Definition: isom.h:330
AV_CODEC_ID_VORBIS
@ AV_CODEC_ID_VORBIS
Definition: codec_id.h:445
AVDictionaryEntry::value
char * value
Definition: dict.h:91
AVStream::start_time
int64_t start_time
Decoding: pts of the first frame of the stream in presentation order, in stream time base.
Definition: avformat.h:797
MOVStreamContext::id
int id
AVStream id.
Definition: isom.h:171
MOVStreamContext::samples_per_frame
unsigned int samples_per_frame
Definition: isom.h:208
MOVElst::duration
int64_t duration
Definition: isom.h:74
ac3tab.h
avstring.h
mov_read_ispe
static int mov_read_ispe(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:8956
width
#define width
Definition: dsp.h:85
AVAmbientViewingEnvironment::ambient_light_y
AVRational ambient_light_y
Normalized y chromaticity coordinate of the environmental ambient light in the nominal viewing enviro...
Definition: ambient_viewing_environment.h:54
mov_read_iref
static int mov_read_iref(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:8918
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:1233
mov_read_mfra
static int mov_read_mfra(MOVContext *c, AVIOContext *f)
Definition: mov.c:9831
AV_CODEC_ID_FLV1
@ AV_CODEC_ID_FLV1
Definition: codec_id.h:73
mov_metadata_int8_no_padding
static int mov_metadata_int8_no_padding(MOVContext *c, AVIOContext *pb, unsigned len, const char *key)
Definition: mov.c:125
flac.h
AVStreamGroupTileGrid::idx
unsigned int idx
Index of the stream in the group this tile references.
Definition: avformat.h:1026
AVTimecode
Definition: timecode.h:41
get_frag_stream_info
static MOVFragmentStreamInfo * get_frag_stream_info(MOVFragmentIndex *frag_index, int index, int id)
Definition: mov.c:1546
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:8387
MOVContext::heif_item
HEIFItem ** heif_item
Definition: isom.h:358
MOVStreamContext::stts_count
unsigned int stts_count
Definition: isom.h:176
MOV_TRUN_SAMPLE_CTS
#define MOV_TRUN_SAMPLE_CTS
Definition: isom.h:392
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:455
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:341
mov_read_st3d
static int mov_read_st3d(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:6474
is_open_key_sample
static int is_open_key_sample(const MOVStreamContext *sc, int sample)
Definition: mov.c:10807
mov_read_dvc1
static int mov_read_dvc1(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:2430
MOVStreamContext::elst_count
unsigned int elst_count
Definition: isom.h:190
av_color_transfer_name
const char * av_color_transfer_name(enum AVColorTransferCharacteristic transfer)
Definition: pixdesc.c:3320
avpriv_dict_set_timestamp
int avpriv_dict_set_timestamp(AVDictionary **dict, const char *key, int64_t timestamp)
Set a dictionary value to an ISO-8601 compliant timestamp string.
Definition: dict.c:278
AVChannelCustom::id
enum AVChannel id
Definition: channel_layout.h:276
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:2146
AV_WL16A
#define AV_WL16A(p, v)
Definition: intreadwrite.h:557
AV_RB64
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_WL16 uint64_t_TMPL AV_RB64
Definition: bytestream.h:95
AVSphericalMapping::yaw
int32_t yaw
Rotation around the up vector [-180, 180].
Definition: spherical.h:138
src
#define src
Definition: vp8dsp.c:248
mov_read_chapters
static void mov_read_chapters(AVFormatContext *s)
Definition: mov.c:9431
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:271
MOVContext::cur_item_id
int cur_item_id
Definition: isom.h:357
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:103
AVFMT_EVENT_FLAG_METADATA_UPDATED
#define AVFMT_EVENT_FLAG_METADATA_UPDATED
Definition: avformat.h:1664
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:326
MOVContext::found_iinf
int found_iinf
'iinf' atom has been found
Definition: isom.h:304
MOVContext::meta_keys_count
unsigned meta_keys_count
Definition: isom.h:309
avcodec_parameters_copy
int avcodec_parameters_copy(AVCodecParameters *dst, const AVCodecParameters *src)
Copy the contents of src to dst.
Definition: codec_par.c:106
iamf_reader.h
AVStreamGroupTileGrid::background
uint8_t background[4]
The pixel value per channel in RGBA format used if no pixel of any tile is located at a particular pi...
Definition: avformat.h:1046
MOVStreamContext::palette
uint32_t palette[256]
Definition: isom.h:223
cenc_scheme_decrypt
static int cenc_scheme_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
Definition: mov.c:7879
MOVFragment::track_id
unsigned track_id
Definition: isom.h:97
mov_read_hdlr
static int mov_read_hdlr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:775
mov_parse_stsd_data
static int mov_parse_stsd_data(MOVContext *c, AVIOContext *pb, AVStream *st, MOVStreamContext *sc, int64_t size)
Definition: mov.c:2850
AV_CH_SIDE_LEFT
#define AV_CH_SIDE_LEFT
Definition: channel_layout.h:181
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:345
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:244
mov_read_pitm
static int mov_read_pitm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:8611
MOVContext::ignore_chapters
int ignore_chapters
Definition: isom.h:324
mov_read_dac3
static int mov_read_dac3(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:846
MP4TrackKindMapping
Definition: isom.h:465
ff_alloc_extradata
int ff_alloc_extradata(AVCodecParameters *par, int size)
Allocate extradata with additional AV_INPUT_BUFFER_PADDING_SIZE at end which is always set to 0.
Definition: utils.c:227
AV_DISPOSITION_NON_DIEGETIC
#define AV_DISPOSITION_NON_DIEGETIC
The stream is intended to be mixed with a spatial audio track.
Definition: avformat.h:686
avio_feof
int avio_feof(AVIOContext *s)
Similar to feof() but also returns nonzero on read errors.
Definition: aviobuf.c:346
mc
#define mc
Definition: vf_colormatrix.c:100
MOVStreamContext::ffindex
int ffindex
AVStream index.
Definition: isom.h:172
HEIFItem::extent_offset
int64_t extent_offset
Definition: isom.h:283
mov_read_stsz
static int mov_read_stsz(MOVContext *c, AVIOContext *pb, MOVAtom atom)
Definition: mov.c:3381